Flat Array to Indexed Mesh Converter
Convert flat vertex arrays into simplicial-complex indexed meshes with positions and cells. Supports deduplication, 3D preview, and export.
About
Raw geometry data from GPU buffers, OBJ parsers, or procedural generators often arrives as a flat array of floating-point numbers. Each consecutive triplet represents one vertex component (x, y, z), and each consecutive group of three vertices defines one triangle face. This flat layout duplicates shared vertices at every face boundary, inflating memory and preventing adjacency queries. The reindex operation reconstructs an indexed mesh: a deduplicated positions array and a cells array of index triples. Without deduplication, the cell count equals N9 where N is the flat array length, and every vertex gets a unique index.
This tool parses your flat vertex data, validates divisibility constraints, and outputs a simplicial-complex-style indexed mesh compatible with modules like simplicial-complex and unindex-mesh. Enable vertex deduplication to merge coincident points within a configurable epsilon tolerance (default 1eā6). The tool approximates deduplication using spatial hashing. Note: deduplication forces hard edges to become smooth. If you need hard edges, leave deduplication off and use the raw indexed output with unindex-mesh downstream.
Formulas
The reindex algorithm operates in two phases. Phase 1 groups the flat array into positions and cells without deduplication. Phase 2 (optional) merges coincident vertices.
Given flat array A of length N, with stride s = 3 and face size f = 3:
Vertex count: V = Ns
Face count: F = Vf
Constraint: N mod (s Ć f) = 0
Position i: Pi = [A[i ā s], A[i ā s + 1], A[i ā s + 2]]
Cell j: Cj = [j ā f, j ā f + 1, j ā f + 2]
Deduplication: Two vertices Pa and Pb are merged when:
ā(xa ā xb)2 + (ya ā yb)2 + (za ā zb)2 < ε
Where A is the input flat array, N is its length, s is the component stride (2 for 2D, 3 for 3D), f is the face size (3 for triangles), Pi is the i-th position vector, Cj is the j-th cell (triangle), and ε is the merge tolerance.
Reference Data
| Term | Definition | Typical Value / Format |
|---|---|---|
| Flat Vertex Array | Sequential x, y, z floats for every vertex of every face | [xā,yā,zā, xā,yā,zā, ā¦] |
| Stride | Number of components per vertex | 3 (XYZ) or 2 (XY) |
| Face Size | Vertices per face (triangles) | 3 |
| Positions Array | Deduplicated or raw list of [x, y, z] arrays | [[0,0,0],[1,0,0],ā¦] |
| Cells Array | Index triples referencing positions | [[0,1,2],[3,4,5],ā¦] |
| Simplicial Complex | Topological mesh representation: vertices + index arrays | Used by simplicial-complex npm module |
| Epsilon (ε) | Distance threshold for merging coincident vertices | 1eā6 |
| Winding Order | Vertex ordering defining face normal direction | CCW (counter-clockwise) is standard |
| Vertex Count (flat) | N3 where N = array length | Must be integer |
| Face Count | N9 for 3D triangles | Must be integer |
| Index Buffer | GPU-side representation of cells | Uint16 or Uint32 |
| Hard Edge | Edge where adjacent faces do NOT share vertex indices | Preserved without dedup |
| Smooth Edge | Edge where adjacent faces share vertex indices | Created by dedup |
| Spatial Hash | Grid-based lookup for nearby vertices | Cell size = ε |
| Memory Saving | Ratio of deduplicated vs flat vertex count | Cube: 8 vs 36 vertices (78% reduction) |
| OBJ Format | Text-based 3D format using indexed faces | v 0 0 0 + f 1 2 3 |
| STL Format | Flat triangle format (no indexing) | Typical input source for this tool |
| glTF Accessor | Typed array view into binary buffer | Uses indexed meshes natively |
Frequently Asked Questions
positions and cells arrays (simplicial-complex format). It also provides an OBJ export with v lines for positions and f lines for faces (1-indexed). Both can be copied to clipboard or downloaded as files.