manifold-3d
Version:
Geometry library for topological robustness
1,322 lines (1,183 loc) • 60.7 kB
TypeScript
/**
* The core WASM bindings with no frills.
*
* @packageDocumentation
* @primaryExport
* @group none
* @see {@link "Using Manifold" | Using Manifold}
* @see {@link "Manifold Examples" | Manifold Examples}
*/
/**
* A three dimensional box, aligned to the coordinate system.
*
* @see {@link Manifold.boundingBox}
* @see {@link Manifold.levelSet}
*/
export declare type Box = {
min: Vec3,
max: Vec3
};
/**
* Two-dimensional cross sections guaranteed to be without self-intersections,
* or overlaps between polygons (from construction onwards). This class makes
* use of the Clipper2 library for polygon clipping (boolean) and offsetting
* operations.
*
* @see {@link https://manifoldcad.org/docs/html/classmanifold_1_1_cross_section.html | C++ API: CrossSection Class Reference}
* @see {@link https://www.angusj.com/clipper2/Docs/Overview.htm | Clipper2 - Polygon Clipping Offsetting & Triangulating}
* @group Basics
*/
export declare class CrossSection {
/**
* Create a 2d cross-section from a set of contours (complex polygons). A
* boolean union operation (with Positive filling rule by default) is
* performed to combine overlapping polygons and ensure the resulting
* CrossSection is free of intersections.
*
* @param contours A set of closed paths describing zero or more complex
* polygons.
* @param fillRule The filling rule used to interpret polygon sub-regions in
* contours.
* @group Basics
*/
constructor(contours: Polygons, fillRule?: FillRule);
// Shapes
/**
* Constructs a square with the given XY dimensions. By default it is
* positioned in the first quadrant, touching the origin. If any dimensions in
* size are negative, or if all are zero, an empty Manifold will be returned.
*
* @param size The X, and Y dimensions of the square.
* @param center Set to true to shift the center to the origin.
* @group Constructors
*/
static square(size?: Readonly<Vec2>|number, center?: boolean): CrossSection;
/**
* Constructs a circle of a given radius.
*
* @param radius Radius of the circle. Must be positive.
* @param circularSegments Number of segments along its diameter. Default is
* calculated by the static Quality defaults according to the radius.
* @group Constructors
*/
static circle(radius: number, circularSegments?: number): CrossSection;
// Extrusions (2d to 3d manifold)
/**
* Constructs a manifold by extruding the cross-section along Z-axis.
*
* @param height Z-extent of extrusion.
* @param nDivisions Number 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.
* @param twistDegrees Amount to twist the top crossSection relative to the
* bottom, interpolated linearly for the divisions in between.
* @param scaleTop Amount 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}.
* @param center If true, the extrusion is centered on the z-axis through the
* origin
* as opposed to resting on the XY plane as is default.
* @group Transformations
*/
extrude(
height: number, nDivisions?: number, twistDegrees?: number,
scaleTop?: Readonly<Vec2>|number, center?: boolean): Manifold;
/**
* Constructs a manifold by revolving this cross-section around its Y-axis and
* then setting this as the Z-axis of the resulting manifold. If the contours
* cross the Y-axis, only the part on the positive X side is used.
* Geometrically valid input will result in geometrically valid output.
*
* @param circularSegments Number of segments along its diameter. Default is
* calculated by the static Defaults.
* @group Transformations
*/
revolve(circularSegments?: number, revolveDegrees?: number): Manifold;
// Transformations
/**
* Transform this CrossSection in space. Stored in column-major order. This
* operation can be chained. Transforms are combined and applied lazily.
*
* @param m The affine transformation matrix to apply to all the vertices. The
* last row is ignored.
* @group Transformations
*/
transform(m: Mat3): CrossSection;
/**
* Move this CrossSection in space. This operation can be chained. Transforms
* are combined and applied lazily.
*
* @param v The vector to add to every vertex.
* @group Transformations
*/
translate(v: Readonly<Vec2>): CrossSection;
translate(x: number, y?: number): CrossSection;
/**
* Applies a (Z-axis) rotation to the CrossSection, in degrees. This operation
* can be chained. Transforms are combined and applied lazily.
*
* @param degrees degrees about the Z-axis to rotate.
* @group Transformations
*/
rotate(degrees: number): CrossSection;
/**
* Scale this CrossSection in space. This operation can be chained. Transforms
* are combined and applied lazily.
*
* @param v The vector to multiply every vertex by per component.
* @group Transformations
*/
scale(v: Readonly<Vec2>|number): CrossSection;
/**
* Mirror this CrossSection over the arbitrary axis described by the unit form
* of the given vector. If the length of the vector is zero, an empty
* CrossSection is returned. This operation can be chained. Transforms are
* combined and applied lazily.
*
* @param ax the axis to be mirrored over
* @group Transformations
*/
mirror(ax: Readonly<Vec2>): CrossSection;
/**
* Move the vertices of this CrossSection (creating a new one) according to
* any arbitrary input function, followed by a union operation (with a
* Positive fill rule) that ensures any introduced intersections are not
* included in the result.
*
* @param warpFunc A function that modifies a given vertex position.
* @group Transformations
*/
warp(warpFunc: (vert: Vec2) => void): CrossSection;
/**
* Inflate the contours in CrossSection by the specified delta, handling
* corners according to the given JoinType.
*
* @param delta Positive deltas will cause the expansion of outlining contours
* to expand, and retraction of inner (hole) contours. Negative deltas will
* have the opposite effect.
* @param joinType The join type specifying the treatment of contour joins
* (corners). Defaults to Round
* @param miterLimit The maximum distance in multiples of delta that vertices
* can be offset from their original positions with before squaring is
* applied, **when the join type is Miter** (default is 2, which is the
* minimum allowed). See the [Clipper2
* MiterLimit](http://www.angusj.com/clipper2/Docs/Units/Clipper.Offset/Classes/ClipperOffset/Properties/MiterLimit.htm)
* page for a visual example.
* @param circularSegments Number of segments per 360 degrees of
* <B>JoinType::Round</B> corners (roughly, the number of vertices that
* will be added to each contour). Default is calculated by the static Quality
* defaults according to the radius.
* @group Transformations
*/
offset(
delta: number, joinType?: JoinType, miterLimit?: number,
circularSegments?: number): CrossSection;
/**
* Remove vertices from the contours in this CrossSection that are less than
* the specified distance epsilon from an imaginary line that passes through
* its two adjacent vertices. Near duplicate vertices and collinear points
* will be removed at lower epsilons, with elimination of line segments
* becoming increasingly aggressive with larger epsilons.
*
* It is recommended to apply this function following Offset, in order to
* clean up any spurious tiny line segments introduced that do not improve
* quality in any meaningful way. This is particularly important if further
* offseting operations are to be performed, which would compound the issue.
*
* @param epsilon minimum distance vertices must diverge from the hypothetical
* outline without them in order to be included in the output (default
* 1e-6)
* @group Transformations
*/
simplify(epsilon?: number): CrossSection;
// Clipping Operations
/**
* Boolean union
* @group Boolean
*/
add(other: CrossSection|Polygons): CrossSection;
/**
* Boolean difference
* @group Boolean
*/
subtract(other: CrossSection|Polygons): CrossSection;
/**
* Boolean intersection
* @group Boolean
*/
intersect(other: CrossSection|Polygons): CrossSection;
/**
* Boolean union of the cross-sections a and b
* @group Boolean
*/
static union(a: CrossSection|Polygons, b: CrossSection|Polygons):
CrossSection;
/**
* Boolean difference of the cross-section b from the cross-section a
* @group Boolean
*/
static difference(a: CrossSection|Polygons, b: CrossSection|Polygons):
CrossSection;
/**
* Boolean intersection of the cross-sections a and b
* @group Boolean
*/
static intersection(a: CrossSection|Polygons, b: CrossSection|Polygons):
CrossSection;
/**
* Boolean union of a list of cross-sections
* @group Boolean
*/
static union(polygons: readonly(CrossSection|Polygons)[]): CrossSection;
/**
* Boolean difference of the tail of a list of cross-sections from its head
* @group Boolean
*/
static difference(polygons: readonly(CrossSection|Polygons)[]): CrossSection;
/**
* Boolean intersection of a list of cross-sections
*/
static intersection(polygons: readonly(CrossSection|Polygons)[]):
CrossSection;
// Convex Hulls
/**
* Compute the convex hull of the contours in this CrossSection.
* @group Convex Hull
*/
hull(): CrossSection;
/**
* Compute the convex hull of all points in a list of polygons/cross-sections.
* @group Convex Hull
*/
static hull(polygons: readonly(CrossSection|Polygons)[]): CrossSection;
// Topological Operations
/**
* Construct a CrossSection from a vector of other Polygons (batch
* boolean union).
* @group Boolean
*/
static compose(polygons: readonly(CrossSection|Polygons)[]): CrossSection;
/**
* This operation returns a vector of CrossSections that are topologically
* disconnected, each containing one outline contour with zero or more
* holes.
* @group Constructors
*/
decompose(): CrossSection[];
// Polygon Conversion
/**
* Create a 2d cross-section from a set of contours (complex polygons). A
* boolean union operation (with Positive filling rule by default) is
* performed to combine overlapping polygons and ensure the resulting
* CrossSection is free of intersections.
*
* @param contours A set of closed paths describing zero or more complex
* polygons.
* @param fillRule The filling rule used to interpret polygon sub-regions in
* contours.
* @group Input & Output
*/
static ofPolygons(contours: Polygons, fillRule?: FillRule): CrossSection;
/**
* Return the contours of this CrossSection as a list of simple polygons.
* @group Input & Output
*/
toPolygons(): SimplePolygon[];
// Properties
/**
* Return the total area covered by complex polygons making up the
* CrossSection.
* @group Information
*/
area(): number;
/**
* Does the CrossSection (not) have any contours?
* @group Information
*/
isEmpty(): boolean;
/**
* The number of vertices in the CrossSection.
* @group Information
*/
numVert(): number;
/**
* The number of contours in the CrossSection.
* @group Information
*/
numContour(): number;
/**
* Returns the axis-aligned bounding rectangle of all the CrossSection's
* vertices.
* @group Information
*/
bounds(): Rect;
// Memory
/**
* Frees the WASM memory of this CrossSection, since these cannot be
* garbage-collected automatically.
* @group Basics
*/
delete(): void;
}
/**
* @see {@link Manifold.status}
*/
export declare type ErrorStatus = 'NoError'|'NonFiniteVertex'|'NotManifold'|
'VertexOutOfBounds'|'PropertiesWrongLength'|'MissingPositionProperties'|
'MergeVectorsDifferentLengths'|'MergeIndexOutOfBounds'|
'TransformWrongLength'|'RunIndexWrongLength'|'FaceIDWrongLength'|
'InvalidConstruction'|'ResultTooLarge'|'InvalidTangents'|'Cancelled';
/**
* Observe and control a long-running Manifold evaluation. Attach to a
* Manifold via Manifold.withContext(); the next eager op invoked on the
* result (status(), one of the refine* family, hull(), or minkowskiSum() /
* minkowskiDifference()) snapshots the ctx and reports progress / observes
* cancellation through it. Deferred ops (Boolean, transforms, batch ops)
* ignore any attached ctx. Safe to read/write from any thread/worker.
*
* Cancellation is permanent for a Manifold: once cancelled and detected,
* the Manifold's status becomes 'Cancelled' and stays 'Cancelled'.
*/
export declare interface ExecutionContext {
/** Request cancellation. Can be called from any context. Idempotent. */
cancel(): void;
/** Has cancellation been requested? */
cancelled(): boolean;
/**
* Normalized progress in [0, 1]. Monotonic within an evaluation.
* Returns 1 when no work has been scheduled (interpreted as trivially
* complete -- e.g. a single-leaf manifold has nothing to evaluate).
*/
progress(): number;
// Memory
/**
* Frees the WASM memory of this ExecutionContext, since these cannot be
* garbage-collected automatically.
* @group Basics
*/
delete(): void;
}
export declare type FillRule = 'EvenOdd'|'NonZero'|'Positive'|'Negative';
/**
* Determine the result of the {@link setMinCircularAngle},
* {@link setMinCircularEdgeLength}, and {@link setCircularSegments} defaults.
*
* @param radius For a given radius of circle, determine how many default
* segments there will be.
*/
export declare function getCircularSegments(radius: number): number;
export declare type JoinType = 'Square'|'Round'|'Miter';
/**
* 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.
*
* @see {@link https://manifoldcad.org/docs/html/classmanifold_1_1_manifold.html | C++ API: Manifold Class Reference}
* @group Basics
*/
export declare class Manifold {
/**
* 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.
*
* @group Basics
*/
constructor(mesh: Mesh);
// Shapes
/**
* Constructs a tetrahedron centered at the origin with one vertex at (1,1,1)
* and the rest at similarly symmetric points.
* @group Constructors
*/
static tetrahedron(): Manifold;
/**
* Constructs a unit cube (edge lengths all one), by default in the first
* octant, touching the origin.
*
* @param size The X, Y, and Z dimensions of the box.
* @param center Set to true to shift the center to the origin.
* @group Constructors
*/
static cube(size?: Readonly<Vec3>|number, center?: boolean): Manifold;
/**
* A convenience constructor for the common case of extruding a circle. Can
* also form cones if both radii are specified.
*
* @param height Z-extent
* @param radiusLow Radius of bottom circle. Must be positive.
* @param radiusHigh Radius of top circle. Can equal zero. Default is equal to
* radiusLow.
* @param circularSegments How many line segments to use around the circle.
* Default is calculated by the static Defaults.
* @param center Set to true to shift the center to the origin. Default is
* origin at the bottom.
* @group Constructors
*/
static cylinder(
height: number, radiusLow: number, radiusHigh?: number,
circularSegments?: number, center?: boolean): Manifold;
/**
* Constructs a geodesic sphere of a given radius.
*
* @param radius Radius of the sphere. Must be positive.
* @param circularSegments Number 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.
* @group Constructors
*/
static sphere(radius: number, circularSegments?: number): Manifold;
// Extrusions from 2d shapes
/**
* Constructs a manifold from a set of polygons/cross-section by extruding
* them along the Z-axis.
*
* @param polygons A set of non-overlapping polygons to extrude.
* @param height Z-extent of extrusion.
* @param nDivisions Number 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.
* @param twistDegrees Amount to twist the top crossSection relative to the
* bottom, interpolated linearly for the divisions in between.
* @param scaleTop Amount 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}.
* @param center If true, the extrusion is centered on the z-axis through the
* origin
* as opposed to resting on the XY plane as is default.
* @group Polygons
*/
static extrude(
polygons: CrossSection|Polygons, height: number, nDivisions?: number,
twistDegrees?: number, scaleTop?: Readonly<Vec2>|number,
center?: boolean): Manifold;
/**
* Constructs 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.
*
* @param polygons A set of non-overlapping polygons to revolve.
* @param circularSegments Number of segments along its diameter. Default is
* calculated by the static Defaults.
* @param revolveDegrees Number of degrees to revolve. Default is 360 degrees.
* @group Polygons
*/
static revolve(
polygons: CrossSection|Polygons, circularSegments?: number,
revolveDegrees?: number): Manifold;
// Mesh Conversion
/**
* 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.
* @group Input & Output
*/
static ofMesh(mesh: Mesh): Manifold;
/**
* Constructs 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.
*
* @param mesh input Mesh.
* @param sharpenedEdges 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.
*
* @group Smoothing
*/
static smooth(mesh: Mesh, sharpenedEdges?: readonly Smoothness[]): Manifold;
// Signed Distance Functions
/**
* Constructs 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.
*
* @param sdf The signed-distance function which returns the signed distance
* of
* a given point in R^3. Positive values are inside, negative outside.
* @param bounds An axis-aligned box that defines the extent of the grid.
* @param edgeLength Approximate maximum edge length of the triangles in the
* final result. This affects grid spacing, and hence has a strong effect on
* performance.
* @param level You can inset your Mesh by using a positive value, or outset
* it with a negative value.
* @param tolerance Ensure 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.
* @group Constructors
*/
static levelSet(
sdf: (point: Vec3) => number, bounds: Box, edgeLength: number,
level?: number, tolerance?: number): Manifold;
// Transformations
/**
* Transform this Manifold in space. Stored in column-major order. This
* operation can be chained. Transforms are combined and applied lazily.
*
* @param m The affine transformation matrix to apply to all the vertices. The
* last row is ignored.
* @group Transformations
*/
transform(m: Mat4): Manifold;
/**
* Move this Manifold in space. This operation can be chained. Transforms are
* combined and applied lazily.
*
* @param v The vector to add to every vertex.
* @group Transformations
*/
translate(v: Readonly<Vec3>): Manifold;
translate(x: number, y?: number, z?: number): Manifold;
/**
* Applies an Euler or Tait-Bryan angle rotation to the manifold. This
* operation can be chained. Transforms are combined and applied lazily.
*
* 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.
*
* From the reference frame of the model being rotated, rotations are applied
* in *z-y'-x"* order. That is yaw first, then pitch and finally roll.
*
* From the global reference frame, a model will be rotated in *x-y-z* order.
* That is about the global X axis, then global Y axis, and finally global Z.
*
* @param v [X, Y, Z] rotation in degrees.
* @group Transformations
*/
rotate(v: Readonly<Vec3>): Manifold;
rotate(x: number, y?: number, z?: number): Manifold;
/**
* Scale this Manifold in space. This operation can be chained. Transforms are
* combined and applied lazily.
*
* @param v The vector to multiply every vertex by per component.
* @group Transformations
*/
scale(v: Readonly<Vec3>|number): Manifold;
/**
* 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.
*
* @param normal The normal vector of the plane to be mirrored over
* @group Transformations
*/
mirror(normal: Readonly<Vec3>): Manifold;
/**
* 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.
*
* @param warpFunc A function that modifies a given vertex position.
* @group Transformations
*/
warp(warpFunc: (vert: Vec3) => void): Manifold;
/**
* Batch version of warp(). The callback receives a flat array of xyzxyz...
* (length = count * 3) and may modify it in-place.
*/
warpBatch(warpFunc: (verts: Float64Array, count: number) => void): Manifold;
/**
* 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.
*
* @param normalIdx 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. Default is 0, the standard slot.
* Non-zero values are retained for compatibility and will not be supported
* in a future release.
* @group Smoothing
*/
smoothByNormals(normalIdx?: number): Manifold;
/**
* 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.
*
* @param minSharpAngle degrees, default 52.5. 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.
*
* @param minSmoothness range: 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.
* @group Smoothing
*/
smoothOut(minSharpAngle?: number, minSmoothness?: number): Manifold;
/**
* 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.
*
* @param n The number of pieces to split every edge into. Must be > 1.
* @group Smoothing
*/
refine(n: number): Manifold;
/**
* 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.
*
* @param length The length that edges will be broken down to.
* @group Smoothing
*/
refineToLength(length: number): Manifold;
/**
* 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.
*
* @param tolerance 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.
* @group Smoothing
*/
refineToTolerance(tolerance: number): Manifold;
/**
* Create 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.
*
* @param numProp The new number of properties per vertex.
* @param propFunc A function that modifies the properties of a given vertex.
* @group Properties
*/
setProperties(
numProp: number,
propFunc: (newProp: number[], position: Vec3, oldProp: number[]) => void):
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.
*
* @param gaussianIdx 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.
* @param meanIdx 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.
* @group Properties
*/
calculateCurvature(gaussianIdx: number, meanIdx: number): Manifold;
/**
* Fills in vertex properties for normal vectors, calculated from the mesh
* geometry. Flat faces composed of three or more triangles will remain flat.
*
* @param normalIdx 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 + 2. Default is
* 0, the standard slot; in that case the Manifold records the recording so
* a subsequent getMesh() without an explicit normalIdx returns solid-frame
* normals. Non-zero values are retained for compatibility and will not be
* supported in a future release.
*
* @param minSharpAngle 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.
* @group Properties
*/
calculateNormals(normalIdx?: number, minSharpAngle?: number): Manifold;
// Boolean Operations
/**
* Boolean union
*
* @group Boolean
*/
add(other: Manifold): Manifold;
/**
* Boolean difference
*
* @group Boolean
*/
subtract(other: Manifold): Manifold;
/**
* Boolean intersection
*
* @group Boolean
*/
intersect(other: Manifold): Manifold;
/**
* Boolean union of the manifolds a and b
*
* @group Boolean
*/
static union(a: Manifold, b: Manifold): Manifold;
/**
* Boolean difference of the manifold b from the manifold a
*
* @group Boolean
*/
static difference(a: Manifold, b: Manifold): Manifold;
/**
* Boolean intersection of the manifolds a and b
*
* @group Boolean
*/
static intersection(a: Manifold, b: Manifold): Manifold;
/**
* Boolean union of a list of manifolds
*
* @group Boolean
*/
static union(manifolds: readonly Manifold[]): Manifold;
/**
* Boolean difference of the tail of a list of manifolds from its head
*
* @group Boolean
*/
static difference(manifolds: readonly Manifold[]): Manifold;
/**
* Boolean intersection of a list of manifolds
*
* @group Boolean
*/
static intersection(manifolds: readonly Manifold[]): Manifold;
/**
* Split cuts this manifold in two using the cutter manifold. The first result
* is the intersection, second is the difference. This is more efficient than
* doing them separately.
*
* @param cutter
* @group Boolean
*/
split(cutter: Manifold): [Manifold, Manifold];
/**
* Convenient version of Split() for a half-space.
*
* @param normal 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.
* @param originOffset The distance of the plane from the origin in the
* direction of the normal vector.
* @group Boolean
*/
splitByPlane(normal: Readonly<Vec3>, originOffset: number):
[Manifold, Manifold];
/**
* Removes everything behind the given half-space plane.
*
* @param normal 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.
* @param originOffset The distance of the plane from the origin in the
* direction of the normal vector.
*
* @group Boolean
*/
trimByPlane(normal: Readonly<Vec3>, originOffset: number): Manifold;
/**
* Compute the minkowski sum of this manifold with another.
* This corresponds to the morphological dilation of the manifold.
*
* @param other The other manifold to minkowski sum to this one.
* @group Boolean
*/
minkowskiSum(other: Manifold): Manifold;
/**
* Subtract the sweep of the other manifold across this manifold's surface.
* This corresponds to the morphological erosion of the manifold.
*
* @param other The other manifold to minkowski subtract from this one.
* @group Boolean
*/
minkowskiDifference(other: Manifold): Manifold;
/**
* 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.
*
* @param height Z-level of slice.
* @group Polygons
*/
slice(height: number): CrossSection;
/**
* Returns a cross section representing the projected outline of this object
* onto the X-Y plane.
*
* @group Polygons
*/
project(): CrossSection;
// Convex Hulls
/**
* Compute the convex hull of all points in this Manifold.
*
* @group Convex Hull
*/
hull(): Manifold;
/**
* Compute the convex hull of all points contained within a set of Manifolds
* and point vectors.
*
* @group Convex Hull
*/
static hull(points: readonly(Manifold|Vec3)[]): Manifold;
// Topological Operations
/**
* Constructs 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().
*
* @param manifolds A list of Manifolds to lazy-union together.
* @deprecated Please use {@link add} or {@link union} instead.
* @group Constructors
*/
static compose(manifolds: readonly Manifold[]): Manifold;
/**
* This operation returns a vector of Manifolds that are topologically
* disconnected. If everything is connected, the vector is length one,
* containing a copy of the original. It is the inverse operation of
* Compose().
*
* @group Constructors
*/
decompose(): Manifold[];
// Property Access
/**
* Does the Manifold have any triangles?
* @group Information
*/
isEmpty(): boolean;
/**
* The number of vertices in the Manifold.
* @group Information
*/
numVert(): number;
/**
* The number of triangles in the Manifold.
* @group Information
*/
numTri(): number;
/**
* The number of edges in the Manifold.
* @group Information
*/
numEdge(): number;
/**
* The number of properties per vertex in the Manifold.
* @group Information
*/
numProp(): number;
/**
* The number of property vertices in the Manifold. This will always be >=
* numVert, as some physical vertices may be duplicated to account for
* different properties on different neighboring triangles.
* @group Information
*/
numPropVert(): number
/**
* Returns the axis-aligned bounding box of all the Manifold's vertices.
* @group Information
*/
boundingBox(): Box;
/**
* 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](https://github.com/elalish/manifold/wiki/Manifold-Library#definition-of-%CE%B5-valid).
* @group Information
*/
tolerance(): number;
/**
* Return a copy of the manifold with the set tolerance value.
* This performs mesh simplification when the tolerance value is increased.
* @group Transformations
*/
setTolerance(tolerance: number): Manifold;
/**
* Return a copy of the manifold simplified to the given tolerance, but with
* its actual tolerance value unchanged. The result will contain a subset of
* the original verts and all surfaces will have moved by less than tolerance.
*
* @param tolerance The maximum distance between the original and simplified
* meshes. If not given or is less than the current tolerance, the current
* tolerance is used.
* @group Transformations
*/
simplify(tolerance?: number): Manifold;
/**
* The genus is a topological property of the manifold, representing the
* number of "handles". A sphere is 0, torus 1, etc. It is only meaningful for
* a single mesh, so it is best to call Decompose() first.
* @group Information
*/
genus(): number;
/**
* Returns the surface area of the manifold.
*
* @group Measurement
*/
surfaceArea(): number;
/**
* Returns the volume of the manifold.
*
* @group Measurement
*/
volume(): number;
/**
* Returns the minimum gap between two manifolds. Returns a float between
* 0 and searchLength.
*
* @group Measurement
*/
minGap(other: Manifold, searchLength: number): number;
/**
* Cast a ray segment, returning all hits sorted by distance.
*
* @param origin The start point of the ray segment.
* @param endpoint The end point of the ray segment.
* @returns Array of RayHit sorted by distance, empty on miss.
*
* @group Spatial Queries
*/
rayCast(origin: Vec3, endpoint: Vec3): RayHit[];
/**
* Returns the reason for an input Mesh producing an empty Manifold. This
* Status will carry on through operations like NaN propogation, ensuring an
* errored mesh doesn't get mysteriously lost. Empty meshes may still show
* NoError, for instance the intersection of non-overlapping meshes.
*
* @group Information
*/
status(): ErrorStatus;
/**
* Returns a copy of this Manifold with the given ExecutionContext attached.
* The attachment is consumed by the next eager op invoked on the result:
* status() for a deferred CSG tree, refine() / refineToLength() /
* refineToTolerance(), hull(), or minkowskiSum() / minkowskiDifference().
* Deferred ops (Boolean operators, transforms, batch ops) ignore any
* attached ctx and produce a result with no attached ctx. See
* ExecutionContext for the full model.
*
* @group Information
*/
withContext(ctx: ExecutionContext): Manifold;
// Export
/**
* 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.
*
* @param normalIdx If 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.
* @group Input & Output
*/
getMesh(normalIdx?: number): Mesh;
// ID Management
/**
* 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.
*
* @group Mesh ID
*/
asOriginal(): Manifold;
/**
* If this mesh is an original, this returns its ID that can be referenced
* by product manifolds. If this manifold is a product, this
* returns -1.
*
* @group Mesh ID
*/
originalID(): number;
/**
* Returns the first of n sequential new unique mesh IDs for marking sets of
* triangles that can be looked up after further operations. Assign to
* Mesh.runOriginalID vector.
*
* @group Mesh ID
*/
static reserveIDs(count: number): number;
// Memory
/**
* Frees the WASM memory of this Manifold, since these cannot be
* garbage-collected automatically.
* @group Basics
*/
delete(): void;
}
export declare interface ManifoldToplevel {
CrossSection: typeof CrossSection;
Manifold: typeof Manifold;
Mesh: typeof Mesh;
triangulate: typeof triangulate;
setMinCircularAngle: typeof setMinCircularAngle;
setMinCircularEdgeLength: typeof setMinCircularEdgeLength;
setCircularSegments: typeof setCircularSegments;
getCircularSegments: typeof getCircularSegments;
resetToCircularDefaults: typeof resetToCircularDefaults;
setup: () => void;
}
/**
* 3x3 matrix stored in column-major order.
*/
export declare type Mat3 = [
number,
number,
number,
number,
number,
number,
number,
number,
number,
];
/**
* 4x4 matrix stored in column-major order.
*/
export declare type Mat4 = [
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
];
/**
* An alternative to Mesh for output suitable for pushing into graphics
* libraries directly. This may not be manifold since the verts are duplicated
* along property boundaries that do not match. The additional merge vectors
* store this missing information, allowing the manifold to be reconstructed.
*
* @see {@link https://manifoldcad.org/docs/html/structmanifold_1_1_mesh_g_l_p.html | C++ API: MeshGLP< Precision, I > Struct Template Reference}
* @group Input & Output
* @internal
*/
export declare class Mesh {
constructor(options: MeshOptions);
/**
* Number of properties per vertex, always >= 3.
*/
numProp: number;
/**
* Flat, GL-style interleaved list of all vertex properties: propVal =
* vertProperties[vert * numProp + propIdx]. The first three properties are
* always the position x, y, z.
*/
vertProperties: Float32Array;
/**
* The vertex indices of the three triangle corners in CCW (from the outside)
* order, for each triangle.
*/
triVerts: Uint32Array;
/**
* Optional: A list of only the vertex indicies that need to be merged to
* reconstruct the manifold.
*/
mergeFrom