JMesh
From Wikipedia the free encyclopedia
This article has multiple issues. Please help improve it or discuss these issues on the talk page. (Learn how and when to remove these template messages)

Filename extension  .jmsh, .bmsh 

Internet media type  application/json 
Type code  TEXT and BINARY 
Developed by  Qianqian Fang 
Initial release  16 September 2020  ^{[1]}
Latest release  1.0 Draft 1 16 September 2020 ^{[2]} 
Type of format  Data interchange 
Extended from  JSON, JData 
Open format?  Yes 
Website  openjdata 
JMesh is a JSONbased portable and extensible file format for the storage and interchange of unstructured geometric data, including discretized geometries such as triangular and tetrahedral meshes, parametric geometries such as NURBS curves and surfaces, and constructive geometries such as constructive solid geometry (CGS) of shape primitives and meshes. Built upon the JData specification, a JMesh file utilizes the JSON and Universal Binary JSON (UBJSON) constructs to serialize and encode geometric data structures, therefore, it can be directly processed by most existing JSON and UBJSON parsers. The JMesh specification defines a list of JSONcompatible constructs to encode geometric data, including Ndimensional (ND) vertices, curves, surfaces, solid elements, shape primitives, their interactions (such as CGS) and spatial relations, together with their associated properties, such as numerical values, colors, normals, materials, textures and other properties related to graphics data manipulation, 3D fabrication, computer graphics rendering and animations.
JMesh file example[edit]
The following mesh (a tetrahedral mesh of a unit cube) contains 8 3D vertices, 12 triangular faces and 6 tetrahedral elements
The above mesh can be stored in the JMesh/JSON format as
{ "_DataInfo_":{ "JMeshVersion":0.5, "CreationTime":"19Dec2021 11:53:43", "Comment":"Created by iso2mesh 1.9.5Rev(http:\/\/iso2mesh.sf.net)" }, "MeshVertex3":[ [0,0,0], [1,0,0], [0,1,0], [1,1,0], [0,0,1], [1,0,1], [0,1,1], [1,1,1] ], "MeshTri3":[ [1,2,4], [1,2,6], [1,3,4], [1,3,7], [1,5,6], [1,5,7], [2,8,4], [2,8,6], [3,8,4], [3,8,7], [5,8,6], [5,8,7] ], "MeshTet4":[ [1,2,4,8], [1,3,4,8], [1,2,6,8], [1,5,6,8], [1,3,7,8], [1,5,7,8] ] }
The optional "_DataInfo_"
record can contain additional metadata according to JData specification.
Instead of using dimensionspecific mesh data constructs, i.e. MeshVertex3
, MeshTri3
, and MeshTet4
, one can also replace those with the corresponding flexible mesh data containers, MeshNode
, MeshSurf
, and MeshElem
, respectively. It is recommended to add "Dimension": 3
in the "_DataInfo_"
metadata header to help parsers correctly process the numerical data in each entry.
Alternatively, according to JMesh and JData specifications, the above JSONstyled 2D arrays can be stored as a structure using JData annotated ND array format to add additional binary data type support, as below
{ "_DataInfo_":{ "JMeshVersion":0.5, "Dimension":3 }, "MeshNode":{ "_ArrayType_":"double", "_ArraySize_":[8,3], "_ArrayData_":[0,0,0,1,0,0,0,1,0,1,1,0,0,0,1,1,0,1,0,1,1,1,1,1] }, "MeshSurf":{ "_ArrayType_":"uint8", "_ArraySize_":[12,3], "_ArrayData_":[1,2,4,1,2,6,1,3,4,1,3,7,1,5,6,1,5,7,2,8,4,2,8,6,3,8,4,3,8,7,5,8,6,5,8,7] }, "MeshElem":{ "_ArrayType_":"uint8", "_ArraySize_":[6,4], "_ArrayData_":[1,2,4,8,1,3,4,8,1,2,6,8,1,5,6,8,1,3,7,8,1,5,7,8] } }
For large mesh data files, recordlevel compression is supported via the JData specification. Just for illustration purposes, the above JMesh data can also be written as
{ "_DataInfo_":{ "JMeshVersion":0.5, "Dimension":3 }, "MeshNode":{ "_ArrayType_":"double", "_ArraySize_":[8,3], "_ArrayZipSize_":[1,24], "_ArrayZipType_":"zlib", "_ArrayZipData_":"eJxjYMAHPtjjlcaQh/GJ1YdLPy51mDQAp2EONQ==" }, "MeshSurf":{ "_ArrayType_":"uint8", "_ArraySize_":[12,3], "_ArrayZipSize_":[1,36], "_ArrayZipType_":"zlib", "_ArrayZipData_":"eJwFwYcNAAAIArAAMv6/2BY8MNBBhQOXOy7aafXi9QEJtwCj" }, "MeshElem":{ "_ArrayType_":"uint8", "_ArraySize_":[6,4], "_ArrayZipSize_":[1,24], "_ArrayZipType_":"zlib", "_ArrayZipData_":"eJxjZGLhYGQGYiY2DkZWIGZmB9LsHAAExABt" } }
where the strings in "_ArrayZipData_"
store the rowmajor serialized, Zlibcompressed and Base64 encoded binary stream of the raw binary array data in the precision specified in _ArrayType_
. Recordlevel data compression may offer significant size reduction in storing large mesh files.
Format Overview[edit]
JMesh syntax[edit]
All JMesh files are JData specification compliant. Same as JData, it has both a textformat based on JSON serialization scheme and a binary format based on the UBJSON serialization scheme.
Nearly all supported mesh data containers (i.e. named JData nodes) can be defined using one of the two forms: an ND array or a structure.
Array form[edit]
For simple data, one can use the "array form" to store the data under a JMesh keyword. In such case, the format of the data must follow the "NDimensional Array Storage Keyword" rules defined in the JData specification. For example, one can store a 1D or 2D array using the direct storage format as
"jmesh_container_1d": [v1,v2,...,vn], "jmesh_container_2d": [ [v11,v12,...,v1n], [v21,v22,...,v2n], ... [vm1,vm2,...,vmn] ]
or using the "annotated storage" format as
"jmesh_container_nd": { "_ArrayType_": "typename", "_ArraySize_": [N1,N2,N3,...], "_ArrayData_": [v1,v2,v3,...] }
Structure form[edit]
One can also use a JData structure to store the primary data as well as to support additional metadata associated with the container. For example, a structurebased container may have the below subfields:
"jmesh_container_struct": { "_DataInfo_":{ ... }, "Data":[ ... ], "Properties": [ ... ] }
Only the "Data"
subfield is required, and it must have the same data stored in the "array form" (either in direct or annotated format) as shown above.
The optional "Properties"
subfield allows one to store additional data with this shape/mesh element. The "Properties"
subfield can be an array or structure with additional subfields.
The optional "_DataInfo_"
is the JData construct for storing metadata associated with this structure. It can be used to store simple metadata, such as data acquisition date, operator name, or version number. The strategies how to split the metadata between _DataInfo_
and Properties
is userdependent.
Summary of JMesh keywords[edit]
Most of the data container keywords associated with discretized geometries have a prefix of "Mesh"
; keywords associated with parametric shape constructs have a prefix of "Shape"
; keywords associated with constructive solid geometries have a prefix "CSG"
. Many of the keywords ends with a numerical value which typically represents the column number of the data when stored in the array format.
 Mesh grouping:
MeshGroup
,MeshObject
,MeshPart
 Vertices:
MeshVertex1
,MeshVertex2
,MeshVertex3
,MeshVertex4
 Lines:
MeshLine
,MeshEdge
,MeshBSpline2D
 Surfaces:
MeshTri3
,MeshQuad4
,MeshPLC
,MeshNURBS
 Solid:
MeshTet4
,MeshHex8
,MeshPyramid5
,MeshTet10
 Flexible containers:
MeshNode
,MeshSurf
,MeshPoly
,MeshElem
 CSG operators:
CSGObject
,CSGUnion
,CSGIntersect
,CSGSubtract
 Texture:
Texture1D
,Texture2D
,Texture3D
 2D shape primitives:
ShapeBox2
,ShapeDisc2
,ShapeEllipse
,ShapeLine2
,ShapeArrow2
,ShapeAnnulus
,ShapeGrid2
 3D shape primitives:
ShapeLine3
,ShapePlane3
,ShapeBox3
,ShapeDisc3
,ShapeGrid3
,ShapeSphere
,ShapeCylinder
,ShapeEllipsoid
,ShapeTorus
,ShapeCone
,ShapeConeFrustum
,ShapeSphereShell
,ShapeSphereSegment
 Extrusion and revolving:
ShapeExtrude2D
,ShapeExtrude3D
,ShapeRevolve3D
 Properties:
Color
,Normal
,Size
,Label
,Value
Vertices[edit]
"MeshVertex1"
defines a 1D position vector. It must be defined as an Nby1 or 1byN numerical vector, where N equals to the total number of vertices. The values in this vector shall be the coordinates of the 1D vertices.
"MeshVertex1": [x1,x2,x3,...]
"MeshVertex2"
defines a 2D position vector. It must be defined as an Nby2 numerical array where N is the total number of vertices. Each row of this array contains the coordinates of the vertex.
"MeshVertex2": [ [x1,y1], [x2,y2], [x3,y3], ... ]
"MeshVertex3"
defines a 3D position vector. Similar to MeshVertex2, it must be defined as an Nby3 numerical array.
"MeshVertex3": [ [x1,y1,z1], [x2,y2,z2], [x3,y3,z3], ... ]
Line segments and curves[edit]
"MeshPolyLine"
defines a set of line segments using an ordered 1D list of node indices (starting from 1). It must be defined by an 1byN or Nby1 vector of integers. If an index is 0, it marks the end of the current line segment and starts a new line segment from the next index.
"MeshPolyLine": [N1, N2, N3, ... ]
"MeshEdge"
defines a set of line segments using a 2D array with a pair of node indices in each row of the array. It must be defined by an Nby2 integer array, where N is the total number of edges.
"MeshEdge": [ [N11,N12], [N21,N22], [N31,N32], ... ]
Surfaces[edit]
"MeshTri3"
defines a discretized surface made of triangles with a triplet of node indices in each row of the array. It must be defined by an Nby3 integer array, where N is the total number of triangles.
"MeshTri3": [ [N11, N12, N13], [N21, N22, N23], [N31, N32, N33], ... ]
"MeshQuad4"
defines a discretized surface made of quadrilateral with a quadruplet of node indices in each row of the array. It must be defined by an Nby4 integer array, where N is the total number of quadrilaterals.
"MeshQuad4": [ [N11, N12, N13, N14], [N21, N22, N23, N24], [N31, N32, N33, N24], ... ]
"MeshPLC"
defines a discretized surface made of polygons (piecewise linear complex) of uniform or varied edge sizes. It must be defined by an array with elements of integer vectors of equal or varied lengths.
"MeshPLC": [ [N11, N12, N13, ...], [N21, N22, N23, N24, ...], [N31, N32, N33, N34, ..., ...], ... ]
Solid Elements[edit]
"MeshTet4"
defines a discretized volumetric domain made of tetrahedral elements, with each element made of a quadruplet of node indices. It must be defined by an Nby4 integer array, where N is the total number of tetrahedra.
"MeshTet4": [ [N11, N12, N13, N14], [N21, N22, N23, N24], [N31, N32, N33, N34], ... ]
"MeshHex8"
defines a discretized volumetric domain made of 8node hexahedral elements, with each element specified by a 8tuple node index. It must be defined by an Nby8 integer array, where N is the total number of hexahedra.
"MeshHex8": [ [N11, N12, N13, ..., N18], [N21, N22, N23, ..., N28], [N31, N32, N33, ..., N28], ... ]
"MeshPyramid5"
defines a discretized volumetric domain made of 5node pyramid elements, with each element specified by a 5tuple node index. It must be defined by an Nby5 integer array, where N is the total number of pyramid.
"MeshPyramid5": [ [N11, N12, N13, ..., N15], [N21, N22, N23, ..., N25], [N31, N32, N33, ..., N25], ... ]
"MeshTet10"
defines a discretized volumetric domain made of 10node straightline tetrahedral elements, with each element specified by a 10tuple node index. It must be defined by an Nby10 integer array, where N is the total number of 10node tetrahedra.
"MeshTet10": [ [N11, N12, N13, ..., N1_10], [N21, N22, N23, ..., N2_10], [N31, N32, N33, ..., N2_10], ... ]
The first 4 columns of the array specifies the indices of the 4 vertices of the tetrahedron, identical to "MeshTet4"
, and the last 6 columns of the array specifies the midedge node indices, sorted in the below order:
[N1, N2, N3, N4, N12, N13, N14, N22, N23, N34]
Flexible mesh data containers[edit]
Flexible mesh data containers allow one to encode a wide range of mesh data using a simple 2D array.
"MeshNode"
defines a flexible container for the storage of vertex coordinates and the associated properties. It must be defined by an NbyM array, where N is the number of vertices, and M is the number of coordinates (D) plus the number of numerical properties (P) attached along each vertex, i.e. M = D + P
"MeshNode": [ [x11, y11, z11, ..., w1D, ..., v11, v12, ..., v1P], [x21, y21, z21, ..., w2D, ..., v21, v22, ..., v2P], [x31, y31, z31, ..., w3D, ..., v31, v32, ..., v3P], ... ]
"MeshSurf"
defines a flexible container for the storage of fixnodelength surface patches and the associated properties. It must be defined by an NbyM array, where N is the number of surface elements, and M is the number of vertices per element (K) plus the number of numerical properties (P) attached along each vertex, i.e. M = K + P
"MeshSurf": [ [N11, N11, ..., N1K, ..., v11, v12, ..., v1P], [N21, N21, ..., N2K, ..., v21, v22, ..., v2P], [N31, N31, ..., N3K, ..., v31, v32, ..., v3P], ... ]
"MeshPoly"
defines a flexible container for the storage of variablenodelength surface patches and the associated properties. Similar to"MeshPLC"
, it must be defined by an array with elements of integer vectors, but it can contain additional metadata in each element. For each vector representing a surface patch, the first nonnumerical entry, for example, a structure or subarray, of the vector marks the start of the property data.
"MeshPoly": [ [N11, N12, N13, ..., {properties}], [N21, N22, N23, N24, ...], [N31, N32, N33, N34, ..., ..., [properties] ], ... ]
"MeshElem"
defines a flexible container for the storage of volumetric elements and the associated properties. It must be defined by an NbyM array, where N is the number of surface elements, and M is the number of vertices per element (K) plus the number of numerical properties (P) attached along each vertex, i.e. M = K + P
"MeshElem": [ [N11, N11, ..., N1K, ..., v11, v12, ..., v1P], [N21, N21, ..., N2K, ..., v21, v22, ..., v2P], [N31, N31, ..., N3K, ..., v31, v32, ..., v3P], ... ]
Shape primitives[edit]
 ShapeBox2: A 2D axisalignedboundingbox (AABB) defined by the two diagonal points ("O" as one end and "P" as the other end)
"ShapeBox2": {"O":[x0,y0], "P": [x1,y1]}
 ShapeDisc2: A 2D disc defined by the center ("O") and radius "r"
"ShapeDisc2": {"O":[x0,y0], "R": r}
 ShapeEllipse: A 2D ellipse defined by the center ("O"), x and y axes in the unrotated coordinate system ("rx" and "ry"), and rotation angle "theta0"
"ShapeEllipse": {"O":[x0,y0], "R": [r1,r2], "Angle":theta0}
 ShapeLine2: A 2D line defined by one point along the line ("O"), and a 2D vector ("V") aligns with the direction of the line
"ShapeLine2": {"O":[x0,y0], "V": [v1,v2]}
 ShapeArrow2: A 2D arrow object defined by one point along the line ("O"), and a 2D vector ("V") aligns with the direction of the line, and the arrowhead size is indicated by scalar "s"
"ShapeArrow2": {"O":[x0,y0], "V": [v1,v2], "Size": s}
 ShapeAnnulus: A 2D annulus defined by the center ("O"), and the outer radius (r1) and inner radius (r2)
"ShapeAnnulus": {"O":[x0,y0], "R": [r1,r2]}
 ShapeGrid2: A 2D grid defined by the one end of the diagonal line ("O"), and the other end ("P"); the numbers of segments along the first and second coordinates are indicated by "Nx" and "Ny", respectively
"ShapeGrid2": {"O":[x0,y0], "P": [x1,y1], "Step":[Nx,Ny]}
 ShapeLine3: A 3D line defined by one point along the line ("O"), and a 3D vector ("V") aligns with the direction of the line
"ShapeLine3": {"O":[x0,y0,z0], "V": [v1,v2,v3]}
 ShapePlane3: A 3D plane defined by one point along the line ("O"), and a 3D vector ("N") pointing to the normal direction of the plane
"ShapePlane3": {"O":[x0,y0,z0], "N": [v1,v2,v3]}
 ShapeBox3: A 3D axisalignedboundingbox (AABB) defined by the two diagonal points ("O" as one end and "P" as the other end)
"ShapeBox3": {"O":[x0,y0,z0], "P": [x1,y1,z1]}
 ShapeDisc3: A 3D disc defined by the center ("O") and radius "R"; the normal direction of the disc is specified in "N"
"ShapeDisc3": {"O":[x0,y0,z0], "R": r, "N"=[v1,v2,v3]}
 ShapeGrid3: A 3D grid defined by the one end of the diagonal line ("O"), and the other end ("P"); the numbers of segments along the x/y/z coordinates are indicated by "Nx", "Ny" and "Nz", respectively
"ShapeGrid3": {"O":[x0,y0,z0], "P": [x1,y1,z1], "Step":[Nx,Ny,Nz]}
 ShapeSphere: A 3D sphere defined by the center ("O") and radius "r"
"ShapeSphere": {"O":[x0,y0,z0], "R": r}
 ShapeCylinder: A 3D cylinder defined by one end of the cylindrical axis ("O") and the other end of the axis "P"; the radius of the cylinder is specified in "r"
"ShapeCylinder": {"O":[x0,y0,z0], "P":[x1,y1,z1], "R": r}
 ShapeEllipsoid: A 3D ellipsoid defined by the center position ("O"), x, y and z axes in the prerotated coordinate system (rx, ry, rz), and the azimuthal rotation angle theta0 and zenith rotation angle phi0
"ShapeEllipsoid": {"O":[x0,y0,z0], "R": [rx,ry,rz], "Angle":[theta0, phi0]}
 ShapeTorus: A 3D torus defined by the center of the torus ("O"), the radius of the torus (r1) and the tube radius (r2) and the normal direction vector "N"
"ShapeTorus": {"O":[x0,y0,z0], "R": r1, "Rtube": r2, "N":[v1,v2,v3]}
 ShapeCone: A 3D cone defined by the center of the bottom circle of the cone ("O"), the radius of the bottom circle (r) and the tip position "P"
"ShapeCone": {"O":[x0,y0,z0], "P": [x1,y1,z1], "R": r}
Software library[edit]
Because JMesh specification is defined base on the JData specification, it shares the same underlying data serialization formats, i.e. JSON for textbased JMesh files (.jmsh) and BJData/UBJSON for binarybased JMesh files (.bmsh). Most existing JSON parsers can readily parse the textbased JMesh files, and similarly, existing UBJSON parsers can be used to parse .bmsh files without modification.
In MATLAB/GNU Octave, saving mesh data to the JMesh format is supported in Iso2Mesh  a 3D mesh generation toolbox  via the savejmesh
function.
See also[edit]
References[edit]
 ^ "JMesh Specification  Version 1 Draft 1". GitHub. 14 March 2022.
 ^ "NeuroJSON/jmesh". GitHub. 14 March 2022.