JMesh
JMesh is a JSON-based 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 JSON-compatible constructs to encode geometric data, including N-dimensional (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 exampleThe following mesh (a tetrahedral mesh of a unit cube) contains 8 3-D 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":"19-Dec-2021 11:53:43",
"Comment":"Created by iso2mesh 1.9.5-Rev(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 Instead of using dimension-specific mesh data constructs, i.e. Alternatively, according to JMesh and JData specifications, the above JSON-styled 2-D arrays can be stored as a structure using JData annotated N-D 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, record-level 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 Format OverviewJMesh syntaxAll JMesh files are JData specification compliant. Same as JData, it has both a text-format 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 N-D array or a structure. Array formFor 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 "N-Dimensional Array Storage Keyword" rules defined in the JData specification. For example, one can store a 1-D or 2-D 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 formOne 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 structure-based container may have the below subfields: "jmesh_container_struct": {
"_DataInfo_":{
...
},
"Data":[
...
],
"Properties": [
...
]
}
Only the The optional The optional Summary of JMesh keywordsMost of the data container keywords associated with discretized geometries have a prefix of
Vertices
"MeshVertex1": [x1,x2,x3,...]
"MeshVertex2": [
[x1,y1],
[x2,y2],
[x3,y3],
...
]
"MeshVertex3": [
[x1,y1,z1],
[x2,y2,z2],
[x3,y3,z3],
...
]
Line segments and curves
"MeshPolyLine": [N1, N2, N3, ... ]
"MeshEdge": [
[N11,N12],
[N21,N22],
[N31,N32],
...
]
Surfaces
"MeshTri3": [
[N11, N12, N13],
[N21, N22, N23],
[N31, N32, N33],
...
]
"MeshQuad4": [
[N11, N12, N13, N14],
[N21, N22, N23, N24],
[N31, N32, N33, N24],
...
]
"MeshPLC": [
[N11, N12, N13, ...],
[N21, N22, N23, N24, ...],
[N31, N32, N33, N34, ..., ...],
...
]
Solid Elements
"MeshTet4": [
[N11, N12, N13, N14],
[N21, N22, N23, N24],
[N31, N32, N33, N34],
...
]
"MeshHex8": [
[N11, N12, N13, ..., N18],
[N21, N22, N23, ..., N28],
[N31, N32, N33, ..., N28],
...
]
"MeshPyramid5": [
[N11, N12, N13, ..., N15],
[N21, N22, N23, ..., N25],
[N31, N32, N33, ..., N25],
...
]
"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 [N1, N2, N3, N4, N12, N13, N14, N22, N23, N34] Flexible mesh data containersFlexible mesh data containers allow one to encode a wide range of mesh data using a simple 2-D array.
"MeshNode": [
[x11, y11, z11, ..., w1D, ..., v11, v12, ..., v1P],
[x21, y21, z21, ..., w2D, ..., v21, v22, ..., v2P],
[x31, y31, z31, ..., w3D, ..., v31, v32, ..., v3P],
...
]
"MeshSurf": [
[N11, N11, ..., N1K, ..., v11, v12, ..., v1P],
[N21, N21, ..., N2K, ..., v21, v22, ..., v2P],
[N31, N31, ..., N3K, ..., v31, v32, ..., v3P],
...
]
"MeshPoly": [
[N11, N12, N13, ..., {properties}],
[N21, N22, N23, N24, ...],
[N31, N32, N33, N34, ..., ..., [properties] ],
...
]
"MeshElem": [
[N11, N11, ..., N1K, ..., v11, v12, ..., v1P],
[N21, N21, ..., N2K, ..., v21, v22, ..., v2P],
[N31, N31, ..., N3K, ..., v31, v32, ..., v3P],
...
]
Shape primitives
"ShapeBox2": {"O": [x0,y0], "P": [x1,y1]}
"ShapeDisc2": {"O": [x0,y0], "R": r}
"ShapeEllipse": {"O": [x0,y0], "R": [r1,r2], "Angle":theta0}
"ShapeLine2": {"O": [x0,y0], "V": [v1,v2]}
"ShapeArrow2": {"O": [x0,y0], "V": [v1,v2], "Size": s}
"ShapeAnnulus": {"O": [x0,y0], "R": [r1,r2]}
"ShapeGrid2": {"O": [x0,y0], "P": [x1,y1], "Step": [Nx,Ny]}
"ShapeLine3": {"O": [x0,y0,z0], "V": [v1,v2,v3]}
"ShapePlane3": {"O": [x0,y0,z0], "N": [v1,v2,v3]}
"ShapeBox3": {"O": [x0,y0,z0], "P": [x1,y1,z1]}
"ShapeDisc3": {"O": [x0,y0,z0], "R": r, "N": [v1,v2,v3]}
"ShapeGrid3": {"O": [x0,y0,z0], "P": [x1,y1,z1], "Step": [Nx,Ny,Nz]}
"ShapeSphere": {"O": [x0,y0,z0], "R": r}
"ShapeCylinder": {"O": [x0,y0,z0], "P": [x1,y1,z1], "R": r}
"ShapeEllipsoid": {"O": [x0,y0,z0], "R": [rx,ry,rz], "Angle": [theta0, phi0]}
"ShapeTorus": {"O": [x0,y0,z0], "R": r1, "Rtube": r2, "N": [v1,v2,v3]}
"ShapeCone": {"O": [x0,y0,z0], "P": [x1,y1,z1], "R": r}
Software libraryBecause JMesh specification is defined base on the JData specification, it shares the same underlying data serialization formats, i.e. JSON for text-based JMesh files (.jmsh) and BJData/UBJSON for binary-based JMesh files (.bmsh). Most existing JSON parsers can readily parse the text-based 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 3-D mesh generation toolbox - via the See alsoReferences
External links |