Convert a Mesh into a Manifold, retaining its properties and merging only the positions according to the merge vectors. Will throw an error if the result is not an oriented 2-manifold. Will collapse degenerate triangles and unnecessary vertices.
All fields are read, making this structure suitable for a lossless round-trip of data from getMesh(). For multi-material input, use reserveIDs() to set a unique originalID for each material, and sort the materials into triangle runs.
If you copy a manifold, but you want this new copy to have new properties (e.g. a different UV mapping), you can reset its IDs to a new original, meaning it will now be referenced by its descendants instead of the meshes it was built from, allowing you to differentiate the copies when applying your properties to the final result.
This function also condenses all coplanar faces in the relation, and collapses those edges. If you want to have inconsistent properties across these faces, meaning you want to preserve some of these edges, you should instead call GetMesh(), calculate your properties and use these to construct a new manifold.
Curvature is the inverse of the radius of curvature, and signed such that positive is convex and negative is concave. There are two orthogonal principal curvatures at any point on a manifold, with one maximum and the other minimum. Gaussian curvature is their product, while mean curvature is their sum. This approximates them for every vertex and assigns them as vertex properties on the given channels.
The property channel index in which to store the Gaussian curvature. An index < 0 will be ignored (stores nothing). The property set will be automatically expanded to include the channel index specified.
The property channel index in which to store the mean curvature. An index < 0 will be ignored (stores nothing). The property set will be automatically expanded to include the channel index specified.
Fills in vertex properties for normal vectors, calculated from the mesh geometry. Flat faces composed of three or more triangles will remain flat.
The property channel in which to store the X values of the normals. The X, Y, and Z channels will be sequential. The property set will be automatically expanded to include up through normalIdx
Any edges with angles greater than this value will remain sharp, getting different normal vector properties on each side of the edge. By default, no edges are sharp and all normals are shared. With a value of zero, the model is faceted and all normals match their triangle normals, but in this case it would be better not to calculate normals at all.
Returns a Mesh that is designed to easily push into a renderer, including all interleaved vertex properties that may have been input. It also includes relations to all the input meshes that form a part of this result and the transforms applied to each.
Optional
normalIdx: numberIf the original MeshGL inputs that formed this manifold had properties corresponding to normal vectors, you can specify the first of the three consecutive property channels forming the (x, y, z) normals, which will cause this output MeshGL to automatically update these normals according to the applied transforms and front/back side. normalIdx + 3 must be <= numProp, and all original MeshGLs must use the same channels for their normals.
Returns the minimum gap between two manifolds. Returns a float between 0 and searchLength.
Mirror this Manifold over the plane described by the unit form of the given normal vector. If the length of the normal is zero, an empty Manifold is returned. This operation can be chained. Transforms are combined and applied lazily.
The normal vector of the plane to be mirrored over
Returns a cross section representing the projected outline of this object onto the X-Y plane.
Increase the density of the mesh by splitting every edge into n pieces. For instance, with n = 2, each triangle will be split into 4 triangles. These will all be coplanar (and will not be immediately collapsed) unless the Mesh/Manifold has halfedgeTangents specified (e.g. from the Smooth() constructor), in which case the new vertices will be moved to the interpolated surface according to their barycentric coordinates.
The number of pieces to split every edge into. Must be > 1.
Increase the density of the mesh by splitting each edge into pieces of roughly the input length. Interior verts are added to keep the rest of the triangulation edges also of roughly the same length. If halfedgeTangents are present (e.g. from the Smooth() constructor), the new vertices will be moved to the interpolated surface according to their barycentric coordinates.
The length that edges will be broken down to.
Increase the density of the mesh by splitting each edge into pieces such that any point on the resulting triangles is roughly within tolerance of the smoothly curved surface defined by the tangent vectors. This means tightly curving regions will be divided more finely than smoother regions. If halfedgeTangents are not present, the result will simply be a copy of the original. Quads will ignore their interior triangle bisector.
The desired maximum distance between the faceted mesh produced and the exact smoothly curving surface. All vertices are exactly on the surface, within rounding error.
Applies an Euler angle rotation to the manifold, first about the X axis, then Y, then Z, in degrees. We use degrees so that we can minimize rounding error, and eliminate it completely for any multiples of 90 degrees. Additionally, more efficient code paths are used to update the manifold when the transforms only rotate by multiples of 90 degrees. This operation can be chained. Transforms are combined and applied lazily.
[X, Y, Z] rotation in degrees.
Optional
y: numberOptional
z: numberCreate a new copy of this manifold with updated vertex properties by supplying a function that takes the existing position and properties as input. You may specify any number of output properties, allowing creation and removal of channels. Note: undefined behavior will result if you read past the number of input properties or write past the number of output properties.
Returns the cross section of this object parallel to the X-Y plane at the specified height. Using a height equal to the bottom of the bounding box will return the bottom faces, while using a height equal to the top of the bounding box will return empty.
Z-level of slice.
Smooths out the Manifold by filling in the halfedgeTangent vectors. The geometry will remain unchanged until Refine or RefineToLength is called to interpolate the surface. This version uses the supplied vertex normal properties to define the tangent vectors.
The first property channel of the normals. NumProp must be at least normalIdx + 3. Any vertex where multiple normals exist and don't agree will result in a sharp edge.
Smooths out the Manifold by filling in the halfedgeTangent vectors. The geometry will remain unchanged until Refine or RefineToLength is called to interpolate the surface. This version uses the geometry of the triangles and pseudo-normals to define the tangent vectors.
Optional
minSharpAngle: numberdegrees, default 60. Any edges with angles greater than this value will remain sharp. The rest will be smoothed to G1 continuity, with the caveat that flat faces of three or more triangles will always remain flat. With a value of zero, the model is faceted, but in this case there is no point in smoothing.
Optional
minSmoothness: numberrange: 0 - 1, default 0. The smoothness applied to sharp angles. The default gives a hard edge, while values > 0 will give a small fillet on these sharp edges. A value of 1 is equivalent to a minSharpAngle of 180 - all edges will be smooth.
Convenient version of Split() for a half-space.
This vector is normal to the cutting plane and its length does not matter. The first result is in the direction of this vector, the second result is on the opposite side.
The distance of the plane from the origin in the direction of the normal vector.
Returns the tolerance of this Manifold's vertices, which tracks the approximate rounding error over all the transforms and operations that have led to this state. Any triangles that are colinear within this tolerance are considered degenerate and removed. This is the value of ε defining ε-valid.
Removes everything behind the given half-space plane.
This vector is normal to the cutting plane and its length does not matter. The result is in the direction of this vector from the plane.
The distance of the plane from the origin in the direction of the normal vector.
This function does not change the topology, but allows the vertices to be moved according to any arbitrary input function. It is easy to create a function that warps a geometrically valid object into one which overlaps, but that is not checked here, so it is up to the user to choose their function with discretion.
Static
composeConstructs a new manifold from a list of other manifolds. This is a purely topological operation, so care should be taken to avoid creating overlapping results. It is the inverse operation of Decompose().
A list of Manifolds to lazy-union together.
Static
cubeStatic
cylinderA convenience constructor for the common case of extruding a circle. Can also form cones if both radii are specified.
Z-extent
Radius of bottom circle. Must be positive.
Optional
radiusHigh: numberRadius of top circle. Can equal zero. Default is equal to radiusLow.
Optional
circularSegments: numberHow many line segments to use around the circle. Default is calculated by the static Defaults.
Optional
center: booleanSet to true to shift the center to the origin. Default is origin at the bottom.
Static
differenceStatic
extrudeConstructs a manifold from a set of polygons/cross-section by extruding them along the Z-axis.
A set of non-overlapping polygons to extrude.
Z-extent of extrusion.
Optional
nDivisions: numberNumber of extra copies of the crossSection to insert into the shape vertically; especially useful in combination with twistDegrees to avoid interpolation artifacts. Default is none.
Optional
twistDegrees: numberAmount to twist the top crossSection relative to the bottom, interpolated linearly for the divisions in between.
Optional
scaleTop: number | Vec2Amount to scale the top (independently in X and Y). If the scale is {0, 0}, a pure cone is formed with only a single vertex at the top. Default {1, 1}.
Optional
center: booleanIf true, the extrusion is centered on the z-axis through the origin as opposed to resting on the XY plane as is default.
Static
hullStatic
intersectionStatic
levelConstructs a level-set Mesh from the input Signed-Distance Function (SDF). This uses a form of Marching Tetrahedra (akin to Marching Cubes, but better for manifoldness). Instead of using a cubic grid, it uses a body-centered cubic grid (two shifted cubic grids). This means if your function's interior exceeds the given bounds, you will see a kind of egg-crate shape closing off the manifold, which is due to the underlying grid.
The signed-distance function which returns the signed distance of a given point in R^3. Positive values are inside, negative outside.
An axis-aligned box that defines the extent of the grid.
Approximate maximum edge length of the triangles in the final result. This affects grid spacing, and hence has a strong effect on performance.
Optional
level: numberYou can inset your Mesh by using a positive value, or outset it with a negative value.
Optional
tolerance: numberEnsure each vertex is within this distance of the true surface. Defaults to -1, which will return the interpolated crossing-point based on the two nearest grid points. Small positive values will require more sdf evaluations per output vertex.
Static
ofConvert a Mesh into a Manifold, retaining its properties and merging only the positions according to the merge vectors. Will throw an error if the result is not an oriented 2-manifold. Will collapse degenerate triangles and unnecessary vertices.
All fields are read, making this structure suitable for a lossless round-trip of data from getMesh(). For multi-material input, use reserveIDs() to set a unique originalID for each material, and sort the materials into triangle runs.
Static
reserveIDsStatic
revolveConstructs a manifold from a set of polygons/cross-section by revolving them around the Y-axis and then setting this as the Z-axis of the resulting manifold. If the polygons cross the Y-axis, only the part on the positive X side is used. Geometrically valid input will result in geometrically valid output.
A set of non-overlapping polygons to revolve.
Optional
circularSegments: numberNumber of segments along its diameter. Default is calculated by the static Defaults.
Optional
revolveDegrees: numberNumber of degrees to revolve. Default is 360 degrees.
Static
smoothConstructs a smooth version of the input mesh by creating tangents; this method will throw if you have supplied tangents with your mesh already. The actual triangle resolution is unchanged; use the Refine() method to interpolate to a higher-resolution curve.
By default, every edge is calculated for maximum smoothness (very much approximately), attempting to minimize the maximum mean Curvature magnitude. No higher-order derivatives are considered, as the interpolation is independent per triangle, only sharing constraints on their boundaries.
input Mesh.
Optional
sharpenedEdges: Smoothness[]If desired, you can supply a vector of sharpened halfedges, which should in general be a small subset of all halfedges. Order of entries doesn't matter, as each one specifies the desired smoothness (between zero and one, with one the default for all unspecified halfedges) and the halfedge index (3 * triangle index + [0,1,2] where 0 is the edge between triVert 0 and 1, etc).
At a smoothness value of zero, a sharp crease is made. The smoothness is interpolated along each edge, so the specified value should be thought of as an average. Where exactly two sharpened edges meet at a vertex, their tangents are rotated to be colinear so that the sharpened edge can be continuous. Vertices with only one sharpened edge are completely smooth, allowing sharpened edges to smoothly vanish at termination. A single vertex can be sharpened by sharping all edges that are incident on it, allowing cones to be formed.
Static
sphereConstructs a geodesic sphere of a given radius.
Radius of the sphere. Must be positive.
Optional
circularSegments: numberNumber of segments along its diameter. This number will always be rounded up to the nearest factor of four, as this sphere is constructed by refining an octahedron. This means there are a circle of vertices on all three of the axis planes. Default is calculated by the static Defaults.
Static
tetrahedronStatic
union
This library's internal representation of an oriented, 2-manifold, triangle mesh - a simple boundary-representation of a solid object. Use this class to store and operate on solids, and use MeshGL for input and output, or potentially Mesh if only basic geometry is required.
In addition to storing geometric data, a Manifold can also store an arbitrary number of vertex properties. These could be anything, e.g. normals, UV coordinates, colors, etc, but this library is completely agnostic. All properties are merely float values indexed by channel number. It is up to the user to associate channel numbers with meaning.
Manifold allows vertex properties to be shared for efficient storage, or to have multiple property verts associated with a single geometric vertex, allowing sudden property changes, e.g. at Boolean intersections, without sacrificing manifoldness.
Manifolds also keep track of their relationships to their inputs, via OriginalIDs and the faceIDs and transforms accessible through MeshGL. This allows object-level properties to be re-associated with the output after many operations, particularly useful for materials. Since separate object's properties are not mixed, there is no requirement that channels have consistent meaning between different inputs.