This turned out to be quite a huge release with a lot of new features and fixes.
- Most important features are related to new hexagon grid implementations.
- Bitbybit now supports mesh-mesh, triangle-triangle, polyline-polyline and line-line intersections.
- You can now convert entities between different kernels in these orders OCCT > JSCAD / OCCT > MANIFOLD / JSCAD > MANIFOLD / MANIFOLD > JSCAD.
FULL LIST OF FEATURES
OpenCascade (OCCT) Operations:
- bitbybit.occt.shapes.face.subdivideToHexagonWires: Divides a given face (a bounded surface) of an OpenCascade (OCCT) shape into a pattern of hexagonal cells. The output is a collection of wire shapes (polylines or loops) representing the boundaries of these hexagonal cells. If face has curvatures, those are followed by wires. It supports various patternization parameters.
- bitbybit.occt.shapes.face.subdivideToHexagonHoles: Takes a face (a bounded surface) of an OpenCascade (OCCT) shape and creates a pattern of hexagonal holes within it. The result is typically the original face with the hexagonal areas removed. It supports various patternization parameters.
- bitbybit.occt.shapes.face.hexagonsInGrid: Creates a grid pattern of hexagonal shapes using OpenCascade (OCCT). Unlike wire.hexagonsInGrid, this function returns the hexagons as actual face shapes (flat planar surfaces bounded by the hexagonal outlines).
- bitbybit.occt.shapes.wire.hexagonsInGrid: Creates a grid pattern of hexagonal shapes using OpenCascade (OCCT). The output consists of wires (boundary outlines) of the hexagons, arranged in a grid.
- bitbybit.occt.shapeFacesToPolygonPoints: Creates very simple mesh representation from the B-Rep representation given the precision. These representations can be easily converted to JSCAD or MANIFOLD kernel meshes
- bitbybit.occt.booleans.meshMeshIntersectionWires: Performs a boolean intersection operation between the triangle meshes derived from two OpenCascade (OCCT) shapes. Allows specifying different meshing precision for each shape. The algorithm intersects these generated meshes and returns the intersection geometry as a collection of wire shapes (polylines or polygons) representing the intersection curves.
- bitbybit.occt.booleans.meshMeshIntersectionPoints: Performs a boolean intersection operation between the triangle meshes derived from two OpenCascade (OCCT) shapes, potentially using different meshing precisions. This algorithm intersects the meshes and returns only the distinct points that lie on the intersection curves.
- bitbybit.occt.booleans.meshMeshIntersectionOfShapesWires: Performs mesh-based boolean intersection between a primary OpenCascade (OCCT) shape and a list of other OCCT shapes. Each shape can have its own meshing precision. The algorithm intersects the mesh of the primary shape with the meshes of all other shapes and returns the combined intersection geometry as a collection of wire shapes.
- bitbybit.occt.booleans.meshMeshIntersectionOfShapesPoints: Performs mesh-based boolean intersection between a primary OpenCascade (OCCT) shape and a list of other OCCT shapes, allowing individual meshing precisions. Intersects the meshes and returns the distinct points lying on the combined intersection curves.
Manifold Operations:
- bitbybit.manifold.manifold.shapes.fromPolygonPoints: Constructs a 3D shape within the Manifold geometry kernel from a list of polygons, where each polygon is defined by an ordered list of its triangle points. This allows creating Manifold models from simpler polygonal data.
- bitbybit.manifold.toPolygonPoints: Converts a 3D model created with the Manifold geometry library into a collection of polygons defined by their vertex points. This extracts the mesh data from the Manifold shape.
JSCAD Operations:
- bitbybit.jscad.toPolygonPoints: Converts a 3D model created with the JSCAD library into a simpler representation: a collection of polygons, where each polygon is defined by a list of its vertex points. This effectively extracts the mesh data from the JSCAD shape.
Mesh Operations:
- bitbybit.mesh.signedDistanceToPlane: Calculates the shortest distance from a point (e.g., a mesh vertex) to a defined plane. The distance is 'signed', meaning it's positive if the point is on one side of the plane (typically the side pointed to by the plane's normal) and negative if on the other.
- bitbybit.mesh.calculateTrianglePlane: Determines the mathematical definition of the infinite plane on which a given triangle (defined by its three vertices) lies.
- bitbybit.mesh.triangleTriangleIntersection: Detects whether two triangles in 3D space intersect. If they do, it can compute the line segment representing their intersection.
- bitbybit.mesh.meshMeshIntersectionSegments: Computes the intersection between two 3D meshes. The result is returned as a collection of individual line segments, representing where the faces (triangles) of one mesh penetrate the faces of the other.
- bitbybit.mesh.meshMeshIntersectionPolylines: Computes the intersection between two 3D meshes. Similar to meshMeshIntersectionSegments, but attempts to connect the intersection segments into continuous polylines (chains of connected line segments), providing a more structured representation of the intersection paths or loops.
- bitbybit.mesh.meshMeshIntersectionPoints: Computes the distinct points where the surfaces of two distinct 3D meshes intersect each other.
Point Operations:
- bitbybit.point.twoPointsAlmostEqual: Determines if two 3D points are located at virtually the same position, within a predefined small tolerance. This is essential for comparing point locations reliably, accounting for potential floating-point inaccuracies.
- bitbybit.point.stretchPointsDirFromCenter: Moves a collection of points radially outward from, or inward towards, a specified center point. Each point is moved along the direction vector from the center to the point itself, scaled by a given factor. A factor > 1 stretches points away, 0 < factor < 1 pulls them closer, and factor < 0 reflects them through the center.
- bitbybit.point.hexGridScaledToFit: Generates a grid of hexagonal cells (with pointy or flat tops) arranged within a specified rectangular boundary. The size of the individual hexagons is automatically scaled so that the overall grid fits exactly within the given width and height dimensions. Returns both the center points of the hexagons and the vertices defining each hexagonal polygon.
- bitbybit.point.sortPoints: Sorts a list of 3D points based on their coordinates. The sorting order is primarily by the X coordinate, then by the Y coordinate for points with the same X, and finally by the Z coordinate for points with the same X and Y. This is known as lexicographical sorting.
- bitbybit.point.maxFilletRadius: Calculates the largest possible radius for a circular fillet (rounded corner) that can be smoothly inserted at a corner formed by two connected line segments (sharing endpoint C). The fillet arc must be tangent to both segments and lie entirely between them without extending beyond their original lengths.
- bitbybit.point.maxFilletRadiusHalfLine: Calculates the largest possible radius for a circular fillet at a corner C, with an additional constraint: the points where the fillet arc touches the two segments (P1-C and P2-C) must lie within the first half of each segment's length, measured from the corner C. This ensures the fillet doesn't consume too much of the segment length.
- bitbybit.point.maxFilletsHalfLine: Applies the 'half-line' fillet calculation (maxFilletRadiusHalfLine) to every internal corner of a shape defined by a sequence of points (potentially forming a polyline). If the shape is marked as closed, it also calculates the fillet radius for the corners connecting the last point back to the first. Returns the maximum possible fillet radius for each corner under the half-line constraint.
- bitbybit.point.safestPointsMaxFilletHalfLine: Analyzes a collection of points (potentially forming multiple corners or polylines) and determines the single largest fillet radius that can be safely applied uniformly to all potential corners using the 'half-line' constraint (maxFilletRadiusHalfLine). This 'safest' radius is the minimum value among all the maximum possible fillet radii calculated for each individual corner, ensuring no fillet overlaps or violates constraints when applied globally.
Line Operations:
- bitbybit.line.lineToSegment: Converts line data structure {start: [number, number, number], end: [number, number, number]} to segment [[number, number, number], [number, number, number]].
- bitbybit.line.linesToSegments: Converts a collection of line representations into their corresponding segments.
- bitbybit.line.segmentToLine: Converts segment representation to line representation.
- bitbybit.line.segmentsToLines: Converts segments to lines.
- bitbybit.line.lineLineIntersection: Calculates the point where two lines in 3D space intersect, if such a point exists. Can look for intersections beyond start and end points if they exist.
Polyline Operations:
- bitbybit.polyline.sortSegmentsIntoPolylines: Takes a collection of disconnected line segments in the form of [[number, number, number], [number, number, number]] and attempts to connect them end-to-end (head-to-tail) based on proximity of endpoints, forming one or more continuous polylines. Useful for organizing fragmented geometric data into coherent paths.
- bitbybit.polyline.polylineToLines: Deconstructs a polyline (a sequence of connected line segments) into a collection of infinite lines, where each line corresponds to one of the segments of the polyline.
- bitbybit.polyline.polylineToSegments: Deconstructs a polyline into its individual component line segments.
- bitbybit.polyline.polylineSelfIntersection: Finds all points where a single polyline intersects with itself. Useful for identifying loops or complex path interactions.
- bitbybit.polyline.twoPolylineIntersection: Finds all intersection points between two distinct polylines.
- bitbybit.polyline.maxFilletsHalfLine: Calculates the maximum possible fillet radius for each corner of a given polyline, using the 'half-line' constraint (tangency points within the first half of segments measured from the corner). For closed polylines, includes corners connecting the last segment to the first. Returns a list of maximum radii, one for each corner.
- bitbybit.polyline.safestFilletRadius: Calculates the single largest fillet radius that can be safely applied uniformly to all corners of a given polyline, using the 'half-line' constraint. This 'safest' radius is determined by finding the minimum value among all the maximum possible fillet radii calculated for each individual corner of the polyline using polyline.maxFilletsHalfLine.
Vector Operations:
- bitbybit.vector.lengthSq: Calculates the squared length (magnitude) of a vector. This is computationally cheaper than calculating the actual length (bitbybit.vector.length) as it avoids the square root operation, making it useful for performance-sensitive comparisons of vector magnitudes or distances.
- bitbybit.vector.length: Computes the geometric length (also known as magnitude or Euclidean norm) of a 3D vector.
Verb NURBS Operations:
- bitbybit.verb.curve.convertLinesToNurbsCurves: Converts a collection of simple line representations (e.g., defined by start/end points) into their equivalent representations as NURBS (Non-Uniform Rational B-Splines) curves using the Verb NURBS library.
- bitbybit.verb.curve.convertLineToNurbsCurve: Converts a single simple line representation into its equivalent representation as a NURBS curve using the Verb NURBS library.
- bitbybit.verb.curve.convertPolylineToNurbsCurve: Converts a polyline (a sequence of connected line segments) into a single NURBS curve that passes through the vertices of the polyline, using the Verb NURBS library.
- bitbybit.verb.curve.convertPolylinesToNurbsCurves: Converts a collection of polylines into their corresponding NURBS curve representations using the Verb NURBS library.