Precomputed mesh format¶
The precomputed mesh format maps uint64 keys to corresponding 3-d triangulated meshes.
Commonly, these meshes represent the surfaces of the segmented objects in a 3-d segmentation volume.
The are two variants of the mesh format:
Multi-resolution mesh format (preferred even for single-resolution meshes)
Note
A mesh may be associated with a precomputed segmentation
volume via the
mesh
metadata property.
Multi-resolution mesh format¶
Multi-resolution meshes are represented as a directory tree containing the following data:
info
file in JSON format specifying themetadata
.For each segment ID for which there is a mesh representation:
a manifest file that specifies the levels of detail and octree decomposition for the object;
a mesh fragment data file specifying an encoded mesh representation corresponding to each octree node.
The actual storage of the manifest and mesh fragment data depends on whether the unsharded or sharded variant of the format is used.
info
metadata file¶
- json PrecomputedMultiresolutionMesh : object¶
Precomputed multi-resolution mesh metadata
- Required members:¶
-
@type :
"neuroglancer_multilod_draco"
¶ Precomputed data kind.
- vertex_quantization_bits : integer¶
Number of bits needed to represent each vertex position coordinate within a mesh fragment.
Must be
10
or16
.
-
transform : array[
12
] of number¶ 4x3 homogeneous coordinate transform matrix in row-major order from the stored model coordinate space to the model coordinate space.
- lod_scale_multiplier : number¶
Factor by which the
lod_scales
values in each manifest are multiplied.
-
@type :
- Optional members:¶
- sharding : PrecomputedSharding¶
Sharding parameters.
If specified, indicates that the manifests and fragments are stored in sharded format. If unspecified, the manifests and fragments are stored in unsharded format as separate files.
- segment_properties : string¶
Relative path to the directory containing associated segment properties.
Note
This association does not apply transitively when this mesh dataset itself is referenced via the precomputed volume
mesh
metadata property. Instead, the associated segment properties must be specified directly in the volume metadata.
Encoded manifest format¶
For each segment ID for which there is a mesh representation, there is an encoded manifest in the following format:
chunk_shape
: 3x float32le, specifies thex
,y
, andz
extents of finest octree node in the “stored model” coordinate space.grid_origin
: 3x float32le, specifies thex
,y
, andz
origin of the octree decomposition in the “stored model” coordinate space.num_lods
: uint32le, specifies the number of levels of detail.lod_scales
:num_lods
float32le, specifies the scale in “stored model” spatial units corresponding to each level of detail. Each scale value is multiplied by thelod_scale_multiplier
metadata property.vertex_offsets
:num_lods*3
float32le, as a C order[num_lods, 3]
array specifying an offset (in the “stored model” coordinate space) to add to vertex positions for each level of detail.num_fragments_per_lod
:num_lods
uint32le, specifies the number of fragments (octree nodes) for each level of detail.For each
lod
in the range[0, num_lods)
:fragment_positions
:num_fragments_per_lod[lod]*3
uint32le, C order[3, numFragments_per_lod[lod]]
array specifying thex
,y
, andz
coordinates of the octree nodes for the givenlod
. The node positions must be inx
,y
,z
Z-curve order. The node corresponds to the axis-aligned bounding box within the “stored model” coordinate space with an origin of:grid_origin + [x, y, z] * chunk_shape * (2**lod)
and a shape ofchunk_shape * (2**lod)
.fragment_offsets
:num_fragments_per_lod[lod]
uint32le, specifies the size in bytes of the encoded mesh fragment in the [mesh fragment data file](#multi-resolution-mesh-fragment-data-file-format) corresponding to each octree node in thefragment_positions
array. The starting offset of the encoded mesh data corresponding to a given octree node is equal to the sum of all priorfragment_offsets
values.
Encoded mesh fragment data¶
The mesh fragment data files consist of the concatenation of the encoded mesh
data for all octree nodes specified in the manifest file, in the same order the
nodes are specified in the manifest, starting with lod
0. Each mesh fragment
is a Draco-encoded triangular mesh with a
3-component integer vertex position attribute. Each position component j
must be a value x
in the range [0, 2**vertex_quantization_bits)
, which
corresponds to a “stored model” coordinate of:
grid_origin[j] +
vertex_offsets[lod,j] +
chunk_shape[j] * (2**lod) * (fragmentPosition[j] +
x / ((2**vertex_quantization_bits)-1))
Note
The built-in Draco attribute quantization is not supported.
Each mesh fragment for lod > 0
must be partitioned by a 2x2x2
grid such
that no triangle crosses a grid boundary (but may be incident to a grid
boundary).
Unsharded format¶
In the unsharded variant of the format, the manifest of each object is stored
as a separate file under the name <segment-id>.index
, and the mesh
fragment data is stored under the name <segment-id>
, where
<segment-id>
is the base-10 string representation of the segment ID.
These files are stored in the same directory as the info
metadata file.
Sharded variant¶
In the sharded variant of the format, the manifest of each object is stored in sharded format using the segment ID as the key.
The shard data is stored in the same directory as the info
metadata
file. The mesh fragment data for each object is located immediately before the
encoded manifest in the same shard data file. The starting offset within that
shard data file is not specified explicitly but may be computed from the
starting offset of the manifest file and the sum of the mesh fragment sizes
specified in the manifest.
Note
From the perspective of the sharded format as a plain key-value store, the encoded manifests are the values and the mesh fragment data is effectively stored in what would normally be considered unused space.
Note
The mesh fragment data is always stored without additional compression,
regardless of the data_encoding
parameter.
Legacy single-resolution mesh format¶
In addition to the multi-resolution mesh format, an older single-resolution mesh format is also supported.
This format consists of a directory containing:
an (optional) info metadata file in JSON-format,
manifest files in JSON format named
segment-id:0
, wheresegment-id
is the base-10 string representation of the uint64 segment ID;mesh fragment files with arbitrary names specified in the manifest files.
Note
Unlike the multi-resolution format, this legacy mesh format does not support a sharded storage representation.
info
metadata file¶
The info
metadata file, if present, must be in JSON format with the
following schema:
- json PrecomputedLegacyMesh : object¶
Precomputed legacy single-resolution mesh metadata
- Optional members:¶
- segment_properties : string¶
Relative path to the directory containing associated segment properties.
Note
This association does not apply transitively when this mesh dataset itself is referenced via the precomputed volume
mesh
metadata property. Instead, the associated segment properties must be specified directly in the volume metadata.
Note
The info
metadata file is optional but strongly recommended. If there
is no info
metadata file, the mesh format cannot be auto-detected and
instead must be specified by an explicit data source URL of the form:
KVSTORE-URL/|neuroglancer-precomputed:#type=mesh
.
Manifest files¶
The segment-id:0
manifest files are in JSON format with the following
schema:
- json PrecomputedLegacyMeshManifest : object¶
Precomputed legacy single-resolution mesh manifest
In the simplest case, each object mesh may be stored as a single fragment, meaning each manifest specifies just a single mesh fragment filename. In general, though, the mesh may be split into one or more separate fragments (e.g. corresponding to chunks of the volume).
Mesh fragment files¶
Each fragment file is specified in the following binary format:
The file begins with a little-endian 32-bit unsigned integer
num_vertices
specifying the number of vertices.The
[x, y, z]
vertex positions (as nanometer offsets within the global coordinate frame) are stored as little-endian single precision/binary32 floating point values starting at an offset of4
bytes from the start of the file (immediately after thenum_vertices
value) and ending at a byte offset of4 + 4 * 3 * num_vertices
. The x, y, and z components of the vertex positions are interleaved, i.e.[x0, y0, z0, x1, y1, z1, ...]
.The number of triangles is inferred as the number of remaining bytes in the file after the vertex position data divided by 12 (the number of remaining bytes must be a multiple of 12). The triangles are specified as an array of interleaved triplets
[a, b, c]
of vertex indices. The vertex indices are encoded as little-endian 32-bit unsigned integers.