Shape — Measurement, Sub-Shapes & Local Operations
This page covers the measurement, decomposition, healing, and local-operation APIs on Shape (source lines 4955–6935). For the core primitives, Boolean operations, and transforms, see the main Shape page.
Topics
- Sub-Shape Extraction · Fuse and Blend · Multi-Edge Evolving Fillet · Per-Face Variable Offset · Free Boundary Analysis · Pipe Feature · Semi-Infinite Extrusion · Prism Until Face · Inertia Properties · Extended Distance · Find Surface · Shape Surgery · Plane Detection · Closed Edge Splitting · Geometry Conversion · Face Restriction · Solid Construction / 2D Fillet / Point Cloud · Face Subdivision · Curve-on-Surface Check · Edge Connection · Self-Intersection Detection · Bezier Conversion · Edge Concavity Analysis · Geometric Edge Selection · Local Prism / Volume Inertia · Local Revolution · Draft Prism · Constrained Filling · Shape Validity Checking · Local Operations / Validation / Fixing / Extrema · ShapeAnalysis FreeBoundsProperties
Sub-Shape Extraction (v0.38.0)
solidCount
Number of solid sub-shapes in this shape.
public var solidCount: Int { get }
- OCCT:
BRep_Builder/TopExp_Explorer(viaOCCTShapeGetSolidCount). - Example:
let box = Shape.box(dx: 10, dy: 10, dz: 10)! print(box.solidCount) // 1
solids
Extract all solid sub-shapes.
public var solids: [Shape] { get }
- Returns: Array of solid sub-shapes; empty if none.
- OCCT:
TopExp_ExplorerwithTopAbs_SOLID. - Example:
let compound = Shape.compound([box1, box2]) let all = compound.solids // [box1, box2]
shellCount
Number of shell sub-shapes.
public var shellCount: Int { get }
- OCCT:
OCCTShapeGetShellCount.
outerShell
The outer shell of this solid.
public var outerShell: Shape? { get }
For a solid with internal voids (multiple shells), returns the shell bounding the outer body, distinguishing it from inner void shells. Returns nil if the shape is not a solid or has no shell.
- Returns: The outer shell, or
nilif the shape is not a solid or has no shell. - OCCT:
BRepClass3d::OuterShell. - Example:
if let outer = hollowSolid.outerShell { print(outer.faceCount) }
innerShells
Inner (void / cavity) shells of this solid — every shell except outerShell.
public var innerShells: [Shape] { get }
- Returns: Empty for a solid with no internal voids, or for a non-solid.
- OCCT:
OCCTShapeInnerShells. - Example:
let cavities = part.innerShells print("cavity count: \(cavities.count)")
shells
Extract all shell sub-shapes.
public var shells: [Shape] { get }
- Returns: Array of all shell sub-shapes (inner and outer).
- OCCT:
TopExp_ExplorerwithTopAbs_SHELL(viaOCCTShapeGetShells).
wireCount
Number of wire sub-shapes.
public var wireCount: Int { get }
- OCCT:
OCCTShapeGetWireCount.
wires
Extract all wire sub-shapes.
public var wires: [Shape] { get }
- Returns: Array of wire sub-shapes; empty if none.
- OCCT:
TopExp_ExplorerwithTopAbs_WIRE(viaOCCTShapeGetWires).
Fuse and Blend (v0.38.0)
fusedAndBlended(with:radius:)
Fuse with another shape and fillet the intersection edges.
public func fusedAndBlended(with other: Shape, radius: Double) -> Shape?
- Parameters:
other— Shape to fuse with.radius— Fillet radius applied to intersection edges after fusion.
- Returns: Fused and filleted shape, or
nilon failure. - OCCT:
BRepAlgoAPI_Fuse+BRepFilletAPI_MakeFillet. - Example:
if let result = boxA.fusedAndBlended(with: boxB, radius: 2.0) { print(result.isValid) }
cutAndBlended(with:radius:)
Cut another shape from this shape and fillet the intersection edges.
public func cutAndBlended(with other: Shape, radius: Double) -> Shape?
- Parameters:
other— Shape to cut from this shape.radius— Fillet radius applied to intersection edges after cutting.
- Returns: Cut and filleted shape, or
nilon failure. - OCCT:
BRepAlgoAPI_Cut+BRepFilletAPI_MakeFillet.
Multi-Edge Evolving Fillet (v0.38.0)
EvolvingFilletEdge
Describes an evolving radius along an edge for filleting.
public struct EvolvingFilletEdge: Sendable {
public var edgeIndex: Int
public var radiusPoints: [(parameter: Double, radius: Double)]
public init(edgeIndex: Int, radiusPoints: [(parameter: Double, radius: Double)])
}
edgeIndex— 1-based edge index.radiusPoints— Array of(parameter, radius)pairs defining the radius evolution along the edge.
filletEvolving(_:)
Apply evolving-radius fillets to multiple edges simultaneously.
public func filletEvolving(_ edges: [EvolvingFilletEdge]) -> Shape?
- Parameters:
edges— Array of edge specifications with radius evolution; must not be empty. - Returns: Filleted shape, or
nilon failure. - OCCT:
BRepFilletAPI_MakeFilletwith evolving law (viaOCCTShapeFilletEvolving). - Example:
let spec = EvolvingFilletEdge(edgeIndex: 1, radiusPoints: [(0.0, 1.0), (1.0, 3.0)]) if let filled = box.filletEvolving([spec]) { print(filled.isValid) }
Per-Face Variable Offset (v0.38.0)
offsetPerFace(defaultOffset:faceOffsets:tolerance:joinType:)
Offset a shape with different distances per face.
public func offsetPerFace(defaultOffset: Double,
faceOffsets: [Int: Double],
tolerance: Double = 1e-3,
joinType: OffsetJoinType = .arc) -> Shape?
- Parameters:
defaultOffset— Default offset distance applied to all faces not listed infaceOffsets.faceOffsets— Dictionary mapping 1-based face indices to custom offset distances.tolerance— Offset tolerance.joinType— Join strategy for offset gaps (.arcor.intersection).
- Returns: Offset shape, or
nilon failure. - OCCT:
BRepOffsetAPI_MakeThickSolid(viaOCCTShapeOffsetPerFace). - Example:
if let result = solid.offsetPerFace(defaultOffset: 1.0, faceOffsets: [1: 2.0, 3: 0.5]) { print(result.isValid) }
Free Boundary Analysis (v0.39.0)
FreeBoundsResult
Result of free boundary analysis.
public struct FreeBoundsResult: Sendable {
public let wires: Shape
public let closedCount: Int
public let openCount: Int
}
wires— Compound shape containing all free boundary wires.closedCount— Number of closed free boundary wires.openCount— Number of open free boundary wires.
freeBounds(sewingTolerance:)
Analyze free boundary wires (open edges not shared by two faces).
public func freeBounds(sewingTolerance: Double = 1e-6) -> FreeBoundsResult?
Free boundaries indicate gaps in a shell. A watertight shell has no free boundaries.
- Parameters:
sewingTolerance— Tolerance for grouping free edges into wires. - Returns: Free bounds result, or
nilif no free boundaries are found. - OCCT:
ShapeAnalysis_FreeBounds. - Example:
if let fb = shell.freeBounds() { print("open gaps: \(fb.openCount)") }
fixedFreeBounds(sewingTolerance:closingTolerance:)
Fix free boundary wires by closing gaps.
public func fixedFreeBounds(sewingTolerance: Double = 1e-6,
closingTolerance: Double = 1e-4) -> (shape: Shape, fixedCount: Int)?
- Parameters:
sewingTolerance— Tolerance for sewing free edges.closingTolerance— Maximum distance to close a gap.
- Returns: Tuple of
(fixed shape, number of wires fixed), ornilon failure. - OCCT:
ShapeFix_Shape/ShapeAnalysis_FreeBounds(viaOCCTShapeFixFreeBounds).
Pipe Feature (v0.39.0)
pipeFeature(profile:sketchFaceIndex:spine:fuse:)
Create a pipe feature by sweeping a profile along a spine, fused with or cut from this shape.
public func pipeFeature(profile: Shape, sketchFaceIndex: Int,
spine: Wire, fuse: Bool = true) -> Shape?
- Parameters:
profile— Profile shape (face) to sweep along the spine.sketchFaceIndex— 0-based index of the face on this shape where the profile sits.spine— Wire defining the sweep path.fuse— Iftrue, adds material; iffalse, removes material.
- Returns: Modified shape, or
nilon failure. - OCCT:
BRepFeat_MakePipe(viaOCCTShapePipeFeatureFromProfile).
Semi-Infinite Extrusion (v0.39.0)
extrudedSemiInfinite(direction:infinite:)
Extrude a shape semi-infinitely in a direction.
public func extrudedSemiInfinite(direction: SIMD3<Double>, infinite: Bool = false) -> Shape?
Creates a solid that extends infinitely in one direction from the profile. Useful for half-spaces and trimming operations.
- Parameters:
direction— Direction of extrusion.infinite— Iftrue, extrude in both directions (fully infinite); iffalse, extrude in one direction (semi-infinite).
- Returns: Extruded shape, or
nilon failure. - OCCT:
BRepPrimAPI_MakeHalfSpace/BRepBuilderAPI_MakeSolid(viaOCCTShapeExtrudeSemiInfinite).
Prism Until Face (v0.39.0)
prismUntilFace(profile:sketchFaceIndex:direction:fuse:untilFaceIndex:)
Extrude a profile until it reaches a target face, with automatic fuse/cut.
public func prismUntilFace(profile: Shape, sketchFaceIndex: Int,
direction: SIMD3<Double>, fuse: Bool = true,
untilFaceIndex: Int? = nil) -> Shape?
Uses BRepFeat_MakePrism which handles the until-face computation more robustly than a simple extrusion + Boolean.
- Parameters:
profile— Profile face to extrude.sketchFaceIndex— 0-based face index on this shape where the profile sits.direction— Extrusion direction.fuse— Iftrue, adds material; iffalse, removes material.untilFaceIndex— 0-based face index on this shape where extrusion stops. Passnilfor thru-all.
- Returns: Modified shape, or
nilon failure. - OCCT:
BRepFeat_MakePrism(viaOCCTShapePrismUntilFace).
Inertia Properties (v0.40.0)
InertiaProperties
Volume-based (or surface-area-based) inertia properties.
public struct InertiaProperties {
public let mass: Double
public let centerOfMass: SIMD3<Double>
public let inertiaMatrix: [Double]
public let principalMoments: SIMD3<Double>
public let principalAxes: (SIMD3<Double>, SIMD3<Double>, SIMD3<Double>)
public let hasSymmetryAxis: Bool
public let hasSymmetryPoint: Bool
}
mass— Volume (forinertiaProperties()) or surface area (forsurfaceInertiaProperties()).inertiaMatrix— 9-element row-major 3×3 inertia tensor[Ixx, Ixy, Ixz, Iyx, Iyy, Iyz, Izx, Izy, Izz].principalAxes— Three unit vectors for the principal axes of inertia.
inertiaProperties()
Compute volume-based inertia properties.
public func inertiaProperties() -> InertiaProperties?
- Returns: Inertia properties, or
nilif computation fails. - OCCT:
BRepGProp::VolumeProperties(viaOCCTShapeInertiaProperties). - Example:
if let props = solid.inertiaProperties() { print("volume: \(props.mass)") print("center of mass: \(props.centerOfMass)") }
surfaceInertiaProperties()
Compute surface-area-based inertia properties.
public func surfaceInertiaProperties() -> InertiaProperties?
The mass field contains total surface area rather than volume.
- Returns: Inertia properties, or
nilif computation fails. - OCCT:
BRepGProp::SurfaceProperties(viaOCCTShapeSurfaceInertiaProperties).
Extended Distance (v0.40.0)
DistanceSolution
A closest-point solution between two shapes.
public struct DistanceSolution {
public let point1: SIMD3<Double>
public let point2: SIMD3<Double>
public let distance: Double
}
allDistanceSolutions(to:maxSolutions:)
Compute all distance extrema solutions between this shape and another.
public func allDistanceSolutions(to other: Shape, maxSolutions: Int = 32) -> [DistanceSolution]?
Returns all extremal point pairs (not just the minimum). Useful for finding multiple closest/farthest point pairs.
- Parameters:
other— The other shape.maxSolutions— Maximum number of solutions to return.
- Returns: Array of distance solutions, or
nilon failure. - OCCT:
BRepExtrema_DistShapeShape(viaOCCTShapeAllDistanceSolutions). - Example:
if let solutions = shapeA.allDistanceSolutions(to: shapeB) { let min = solutions.min(by: { $0.distance < $1.distance }) print("minimum distance: \(min?.distance ?? 0)") }
isInside(_:)
Check if this shape is fully contained inside another shape.
public func isInside(_ container: Shape) -> Bool?
- Parameters:
container— The potential container shape. - Returns:
trueif this shape is inside the container;nilon failure. - OCCT:
BRepExtrema_DistShapeShapeinner solution detection (viaOCCTShapeIsInnerDistance).
DistanceSupportType
Support type for a distance solution point.
public enum DistanceSupportType: Int32, Sendable {
case vertex = 0
case onEdge = 1
case inFace = 2
}
DistanceSolutionDetail
Detailed parametric info for a distance solution.
public struct DistanceSolutionDetail: Sendable {
public let supportType1: DistanceSupportType
public let supportType2: DistanceSupportType
public let paramEdge1: Double
public let paramEdge2: Double
public let paramFaceUV1: (u: Double, v: Double)
public let paramFaceUV2: (u: Double, v: Double)
}
distanceSolutionDetail(to:solutionIndex:)
Get detailed parametric info for a specific distance solution.
public func distanceSolutionDetail(to other: Shape, solutionIndex: Int) -> DistanceSolutionDetail?
Returns the support type (vertex/edge/face) and parametric location for each closest point. Use in conjunction with allDistanceSolutions(to:) to obtain the solution index.
- Parameters:
other— The other shape.solutionIndex— 0-based index into the solutions returned byallDistanceSolutions(to:).
- Returns: Detail struct, or
nilon failure. - OCCT:
BRepExtrema_DistShapeShape(viaOCCTShapeDistanceSolutionDetail).
Find Surface (v0.40.0)
findSurfaceEx(tolerance:onlyPlane:)
Find the underlying geometric surface shared by a shape’s edges.
public func findSurfaceEx(tolerance: Double = 1e-6, onlyPlane: Bool = false) -> Surface?
Analyzes the edges of a shape to determine if they lie on a common geometric surface.
- Parameters:
tolerance— Tolerance for surface detection.onlyPlane— Iftrue, only look for planar surfaces.
- Returns: The underlying surface, or
nilif none found. - OCCT:
BRepLib_FindSurface(viaOCCTShapeFindSurfaceEx). - Example:
if let surf = wire.findSurfaceEx(onlyPlane: true) { print(surf.surfaceKind) // .plane }
Shape Surgery (v0.41.0)
removingSubShapes(_:)
Remove sub-shapes from this shape surgically.
public func removingSubShapes(_ subShapes: [Shape]) -> Shape?
Uses BRepTools_ReShape to remove faces, edges, or vertices while preserving the remaining topology.
- Parameters:
subShapes— Sub-shapes to remove. - Returns: Shape with sub-shapes removed, or
nilon failure. - OCCT:
BRepTools_ReShape(viaOCCTShapeRemoveSubShapes).
replacingSubShapes(_:)
Replace sub-shapes within this shape.
public func replacingSubShapes(_ replacements: [(old: Shape, new: Shape)]) -> Shape?
- Parameters:
replacements— Array of(old, new)shape pairs. - Returns: Shape with replacements applied, or
nilon failure. - OCCT:
BRepTools_ReShape(viaOCCTShapeReplaceSubShapes).
Plane Detection (v0.41.0)
DetectedPlane
Result of plane detection.
public struct DetectedPlane {
public let normal: SIMD3<Double>
public let origin: SIMD3<Double>
}
findPlane(tolerance:)
Find if this shape’s edges lie in a plane.
public func findPlane(tolerance: Double = 1e-6) -> DetectedPlane?
- Parameters:
tolerance— Tolerance for planarity check. - Returns: Detected plane, or
nilif the shape is not planar. - OCCT:
BRepBuilderAPI_FindPlane(viaOCCTShapeFindPlane). - Example:
if let plane = wire.findPlane() { print("normal: \(plane.normal)") }
Closed Edge Splitting (v0.41.0)
dividedClosedEdges(splitPoints:)
Split closed (periodic) edges in the shape.
public func dividedClosedEdges(splitPoints: Int = 1) -> Shape?
Periodic edges (like circles) can cause issues in some algorithms. This splits each closed edge into segments.
- Parameters:
splitPoints— Number of split points per closed edge (default1, which doubles the edge count). - Returns: Shape with closed edges split, or
nilon failure. - OCCT:
ShapeUpgrade_ShapeDivideAngle/BRep_Builder(viaOCCTShapeDivideClosedEdges).
Geometry Conversion (v0.41.0)
withSurfacesAsBSpline(extrusion:revolution:offset:plane:)
Convert all surfaces to BSpline form.
public func withSurfacesAsBSpline(extrusion: Bool = true, revolution: Bool = true,
offset: Bool = true, plane: Bool = false) -> Shape?
- Parameters:
extrusion— Convert extrusion surfaces (defaulttrue).revolution— Convert revolution surfaces (defaulttrue).offset— Convert offset surfaces (defaulttrue).plane— Convert planar surfaces (defaultfalse).
- Returns: Shape with converted surfaces, or
nilon failure. - OCCT:
ShapeCustom::ConvertToBSpline(viaOCCTShapeCustomConvertToBSpline).
withSurfacesAsRevolution()
Convert surfaces to revolution form where possible.
public func withSurfacesAsRevolution() -> Shape?
- Returns: Shape with surfaces converted to surfaces of revolution, or
nilon failure. - OCCT:
ShapeCustom::ConvertToRevolution(viaOCCTShapeCustomConvertToRevolution).
Face Restriction (v0.41.0)
faceRestricted(by:)
Create restricted faces from a face and wire boundaries.
public func faceRestricted(by boundaries: [Wire]) -> [Shape]?
Uses BRepAlgo_FaceRestrictor to build faces on the underlying surface of this shape’s first face, bounded by the given wires.
- Parameters:
boundaries— Wire boundaries that define the restricted regions. - Returns: Array of restricted face shapes (up to 64), or
nilon failure. - OCCT:
BRepAlgo_FaceRestrictor(viaOCCTShapeFaceRestrict).
Solid Construction, 2D Fillet and Point Cloud (v0.42.0)
solidFromShells(_:)
Create a solid from one or more shell shapes.
public static func solidFromShells(_ shells: [Shape]) -> Shape?
The first shape provides the outer shell; additional shapes provide cavity (inner) shells.
- Parameters:
shells— Array of shapes containing shells; must not be empty. - Returns: Solid shape, or
nilon failure. - OCCT:
BRepBuilderAPI_MakeSolid(viaOCCTSolidFromShells). - Example:
if let solid = Shape.solidFromShells([outerShell, innerShell]) { print(solid.isValid) }
fillet2D(vertexIndices:radii:)
Apply 2D fillets (rounded corners) to a planar face at specified vertices.
public func fillet2D(vertexIndices: [Int], radii: [Double]) -> Shape?
- Parameters:
vertexIndices— 0-based indices of vertices to fillet.radii— Fillet radius for each vertex; must matchvertexIndicescount.
- Returns: Modified shape with fillets, or
nilon failure. - OCCT:
BRepFilletAPI_MakeFillet2d(viaOCCTFace2DFillet). - Note:
vertexIndicesandradiimust have equal length; mismatch returnsnil.
chamfer2D(edgePairs:distances:)
Apply 2D chamfers (angled cuts) to a planar face between adjacent edge pairs.
public func chamfer2D(edgePairs: [(Int, Int)], distances: [Double]) -> Shape?
- Parameters:
edgePairs— Array of(edge1Index, edge2Index)pairs (0-based) identifying adjacent edges.distances— Chamfer distance for each edge pair.
- Returns: Modified shape with chamfers, or
nilon failure. - OCCT:
BRepFilletAPI_MakeFillet2d(viaOCCTFace2DChamfer).
PointCloudGeometry
Classification of a point cloud’s geometric arrangement.
public enum PointCloudGeometry {
case point(SIMD3<Double>)
case linear(origin: SIMD3<Double>, direction: SIMD3<Double>)
case planar(origin: SIMD3<Double>, normal: SIMD3<Double>)
case space
}
.point— All points are coincident..linear— Points are collinear..planar— Points are coplanar..space— Points are dispersed in 3D space.
analyzePointCloud(_:tolerance:)
Analyze a set of 3D points to determine their geometric arrangement.
public static func analyzePointCloud(_ points: [SIMD3<Double>], tolerance: Double = 1e-6) -> PointCloudGeometry?
- Parameters:
points— Array of 3D points (minimum 1).tolerance— Tolerance for classification.
- Returns: Classification result, or
nilon failure. - OCCT:
GProp_PEquation(viaOCCTAnalyzePointCloud). - Example:
let pts: [SIMD3<Double>] = [.init(0,0,0), .init(1,0,0), .init(2,0,0)] if case .linear(let o, let d) = Shape.analyzePointCloud(pts) { print("line direction: \(d)") }
Face Subdivision (v0.43.0)
dividedByArea(maxArea:)
Subdivide faces whose area exceeds a maximum threshold.
public func dividedByArea(maxArea: Double) -> Shape?
- Parameters:
maxArea— Maximum face area; faces larger than this are split. - Returns: Shape with subdivided faces, or
nilon failure. - OCCT:
ShapeUpgrade_ShapeDivideArea(viaOCCTShapeDivideByArea).
dividedByParts(_:)
Subdivide faces into a target number of parts.
public func dividedByParts(_ parts: Int) -> Shape?
- Parameters:
parts— Target number of parts per face. - Returns: Shape with subdivided faces, or
nilon failure. - OCCT:
ShapeUpgrade_ShapeDivideAreain splitting-by-number mode (viaOCCTShapeDivideByParts).
SmallFaceInfo
Result of small/degenerate face analysis.
public struct SmallFaceInfo: Sendable {
public let isSpotFace: Bool
public let isStripFace: Bool
public let isTwisted: Bool
public let spotLocation: SIMD3<Double>?
}
isSpotFace— Face collapsed to a point.isStripFace— Face with negligible width.isTwisted— Face with twisted geometry.spotLocation— Location of a spot face (only set whenisSpotFaceistrue).
checkSmallFaces(tolerance:)
Check faces for degenerate conditions (spot, strip, twisted).
public func checkSmallFaces(tolerance: Double = 1e-6) -> [SmallFaceInfo]
Returns only faces that have at least one degenerate condition.
- Parameters:
tolerance— Analysis tolerance. - Returns: Array of degenerate face descriptions; empty if none found.
- OCCT:
ShapeAnalysis_CheckSmallFace(viaOCCTShapeCheckSmallFaces).
purgedLocations
Purge problematic location datums from the shape.
public var purgedLocations: Shape? { get }
Removes negative-scale and non-unit-scale transforms from the shape and all sub-shapes. Useful for cleaning imported geometry from STEP/IGES files.
- Returns: Cleaned shape, or
nilif purge was unnecessary or failed. - OCCT:
BRepLib::SameParameter/ transform purge (viaOCCTShapePurgeLocations).
Curve-on-Surface Check
CurveOnSurfaceCheck
Result of a curve-on-surface consistency check.
public struct CurveOnSurfaceCheck {
public let maxDistance: Double
public let maxParameter: Double
}
maxDistance— Maximum deviation between 3D edge curves and their pcurves on faces.maxParameter— Curve parameter where the maximum deviation occurs.
curveOnSurfaceCheck
Check edge-on-surface consistency.
public var curveOnSurfaceCheck: CurveOnSurfaceCheck? { get }
Examines all edge-face pairs in the shape and reports the maximum deviation between each edge’s 3D curve and its parametric curve (pcurve) on the face surface.
- Returns: Check result, or
nilif the check fails. - OCCT:
BRep_Tool::CurveOnSurface/ShapeAnalysis_Edge(viaOCCTShapeCheckCurveOnSurface).
Edge Connection
connectedEdges
Connect edges by merging shared vertices in the shape.
public var connectedEdges: Shape? { get }
Identifies edges that share geometric positions and merges their vertices. Useful for healing imported geometry where topologically disconnected edges actually meet at the same point.
- Returns: Shape with connected edges, or
nilon failure. - OCCT:
ShapeFix_EdgeConnect(viaOCCTShapeConnectEdges).
Self-Intersection Detection (v0.45.0)
SelfIntersectionResult
Result of a self-intersection check.
public struct SelfIntersectionResult: Sendable {
public let overlapCount: Int
public let isDone: Bool
}
selfIntersection(tolerance:meshDeflection:)
Check the shape for self-intersection using BVH-accelerated triangle mesh overlap.
public func selfIntersection(tolerance: Double = 0.001,
meshDeflection: Double = 0.5) -> SelfIntersectionResult?
Meshes the shape and detects overlapping triangle pairs.
- Parameters:
tolerance— Tolerance for detecting intersections.meshDeflection— Mesh deflection for triangulation.
- Returns: Self-intersection result, or
nilif the check failed. - OCCT:
BRepExtrema_SelfIntersection(viaOCCTShapeSelfIntersection). - Example:
if let si = shape.selfIntersection() { print("overlapping pairs: \(si.overlapCount)") }
Bezier Conversion
convertedToBezier
Convert all curves and surfaces in the shape to Bezier representations.
public var convertedToBezier: Shape? { get }
Replaces BSpline curves and surfaces with their Bezier equivalents. Converts 2D/3D curves, surfaces, lines, circles, conics, planes, revolutions, extrusions, and BSpline entities.
- Returns: Shape with Bezier geometry, or
nilon failure. - OCCT:
ShapeUpgrade_ShapeConvertToBezier(viaOCCTShapeConvertToBezier).
Edge Concavity Analysis (v0.46.0)
EdgeConcavity
Edge concavity type from BRepOffset_Analyse.
public enum EdgeConcavity: Sendable {
case convex
case concave
case tangent
}
.convex— Edge connects two faces at a convex angle (e.g., outer corner of a box)..concave— Edge connects two faces at a concave angle (e.g., inner corner of a groove)..tangent— Edge connects two faces with a smooth (tangent) transition.
edgeConcavities(angle:)
Classify all edges by their concavity type.
public func edgeConcavities(angle: Double = 0.01) -> [(Edge, EdgeConcavity)]?
Analyzes the angles between adjacent faces at each edge.
- Parameters:
angle— Threshold angle (radians) for tangent classification. - Returns: Array of
(edge, concavity)pairs in edge order, ornilon error. - OCCT:
BRepOffset_Analyse(viaOCCTShapeAnalyzeEdgeConcavity).
edgeConcavityCount(_:angle:)
Count edges of a specific concavity type.
public func edgeConcavityCount(_ type: EdgeConcavity, angle: Double = 0.01) -> Int?
- Parameters:
type— Concavity type to count.angle— Threshold angle (radians) for tangent classification.
- Returns: Count of matching edges, or
nilon error. - OCCT:
BRepOffset_Analyse(viaOCCTShapeCountEdgeConcavity).
Geometric Edge Selection (v1.2.1)
edges(where:)
Select edges of this shape that satisfy a geometric predicate.
public func edges(where predicate: (Edge) -> Bool) -> [Edge]
A robust alternative to picking edges by raw index from edges() — the index shifts when model parameters change, whereas a geometric predicate keeps selecting the right edge.
- Parameters:
predicate— Returnstruefor edges to keep. - Returns: The matching edges (possibly empty), each with a valid index.
- Example:
// Round only long edges (> 50 mm) let targets = bracket.edges { $0.length > 50 } let rounded = bracket.filleted(edges: targets, radius: 2)
concaveEdges(angle:)
The concave edges of this solid (interior angle > 180°).
public func concaveEdges(angle: Double = 0.01) -> [Edge]
Concave edges are typically the ones you want to fillet to add material to an inside corner.
- Parameters:
angle— Threshold (radians) below which an edge counts as tangent rather than concave. - Returns: The concave edges, or an empty array if none or on error.
- Example:
let rounded = bracket.filleted(edges: bracket.concaveEdges(), radius: 3)
convexEdges(angle:)
The convex edges of this solid (interior angle < 180°).
public func convexEdges(angle: Double = 0.01) -> [Edge]
Convex edges are the outer corners of a part, typically the ones you want to chamfer or round.
- Parameters:
angle— Threshold (radians) below which an edge counts as tangent rather than convex. - Returns: The convex edges, or an empty array if none or on error.
edges(parallelTo:tolerance:)
Select straight edges whose direction is parallel to a given axis.
public func edges(parallelTo axis: SIMD3<Double>, tolerance: Double = 1e-4) -> [Edge]
Only line edges are considered (curved edges have no single direction). The test is sign-agnostic: edges pointing along +axis or -axis both match.
- Parameters:
axis— The reference direction (need not be unit length).tolerance— Maximum sine of the angle between edge and axis.
- Returns: The matching straight edges, each with a valid index.
- Example:
// Round every vertical edge of an extruded prism let verticals = part.edges(parallelTo: SIMD3(0, 0, 1)) let rounded = part.filleted(edges: verticals, radius: 2)
edges(inBounds:_:)
Select edges fully contained within an axis-aligned bounding region.
public func edges(inBounds min: SIMD3<Double>, _ max: SIMD3<Double>) -> [Edge]
An edge matches when its entire bounding box lies inside the box spanned by min...max (inclusive).
- Parameters:
min— Lower corner of the region.max— Upper corner of the region.
- Returns: The contained edges, each with a valid index.
Local Prism and Volume Inertia (v0.46.0)
localPrism(direction:)
Create a local prism (extrusion) from this shape along a direction.
public func localPrism(direction: SIMD3<Double>) -> Shape?
Uses LocOpe_Prism which tracks generated shapes for each input sub-shape.
- Parameters:
direction— Direction and distance of extrusion. - Returns: Extruded shape, or
nilon failure. - OCCT:
LocOpe_Prism(viaOCCTLocOpePrism).
localPrism(direction:translation:)
Create a local prism with an additional translation.
public func localPrism(direction: SIMD3<Double>, translation: SIMD3<Double>) -> Shape?
- Parameters:
direction— Primary direction and distance of extrusion.translation— Secondary translation vector.
- Returns: Extruded shape, or
nilon failure. - OCCT:
LocOpe_Prism(viaOCCTLocOpePrismWithTranslation).
VolumeInertia
Volume inertia properties of a solid shape.
public struct VolumeInertia: Sendable {
public let volume: Double
public let centerOfMass: SIMD3<Double>
public let inertiaTensor: [Double]
public let principalMoments: SIMD3<Double>
public let principalAxes: (SIMD3<Double>, SIMD3<Double>, SIMD3<Double>)
public let gyrationRadii: SIMD3<Double>
}
inertiaTensor— 9-element row-major 3×3 inertia tensor.gyrationRadii— Radii of gyration about the three principal axes.
volumeInertia
Compute volume inertia properties of this shape.
public var volumeInertia: VolumeInertia? { get }
- Returns: Volume inertia result, or
nilon error. - OCCT:
BRepGProp::VolumeProperties(viaOCCTShapeVolumeInertia). - Example:
if let vi = solid.volumeInertia { print("volume: \(vi.volume)") print("gyration radii: \(vi.gyrationRadii)") }
SurfaceInertia
Surface inertia properties of a shape.
public struct SurfaceInertia: Sendable {
public let area: Double
public let centerOfMass: SIMD3<Double>
public let inertiaTensor: [Double]
public let principalMoments: SIMD3<Double>
}
surfaceInertia
Compute surface (area) inertia properties of this shape.
public var surfaceInertia: SurfaceInertia? { get }
- Returns: Surface inertia result, or
nilon error. - OCCT:
BRepGProp::SurfaceProperties(viaOCCTShapeSurfaceInertia).
Local Revolution (v0.47.0)
localRevolution(axisOrigin:axisDirection:angle:)
Create a revolved shape by rotating a profile around an axis.
public func localRevolution(axisOrigin: SIMD3<Double>,
axisDirection: SIMD3<Double>,
angle: Double) -> Shape?
Uses LocOpe_Revol for local revolution operations with shape tracking.
- Parameters:
axisOrigin— Origin point of the rotation axis.axisDirection— Direction of the rotation axis.angle— Rotation angle in radians.
- Returns: Revolved shape, or
nilon failure. - OCCT:
LocOpe_Revol(viaOCCTLocOpeRevol).
localRevolution(axisOrigin:axisDirection:angle:angularOffset:)
Create a revolved shape with an angular offset.
public func localRevolution(axisOrigin: SIMD3<Double>,
axisDirection: SIMD3<Double>,
angle: Double,
angularOffset: Double) -> Shape?
- Parameters:
axisOrigin— Origin point of the rotation axis.axisDirection— Direction of the rotation axis.angle— Rotation angle in radians.angularOffset— Angular offset for positioning in radians.
- Returns: Revolved shape, or
nilon failure. - OCCT:
LocOpe_Revol(viaOCCTLocOpeRevolWithOffset).
Draft Prism (v0.47.0)
These methods are on Face, not Shape.
Face.draftPrism(height1:height2:angle:)
Create a draft prism (tapered extrusion) from this face.
public func draftPrism(height1: Double, height2: Double, angle: Double) -> Shape?
- Parameters:
height1— First height.height2— Second height.angle— Draft angle in radians.
- Returns: Draft prism shape, or
nilon failure. - OCCT:
LocOpe_DPrism(viaOCCTLocOpeDPrism).
Face.draftPrism(height:angle:)
Create a draft prism with a single height.
public func draftPrism(height: Double, angle: Double) -> Shape?
- Parameters:
height— Extrusion height.angle— Draft angle in radians.
- Returns: Draft prism shape, or
nilon failure. - OCCT:
LocOpe_DPrism(viaOCCTLocOpeDPrismSingleHeight).
Constrained Filling (v0.47.0)
ConstrainedFillInfo
Information about a constrained-fill BSpline surface.
public struct ConstrainedFillInfo: Sendable {
public let uDegree: Int
public let vDegree: Int
public let uPoles: Int
public let vPoles: Int
}
constrainedFill(edge1:edge2:edge3:edge4:maxDegree:maxSegments:)
Create a surface by filling a region bounded by 3 or 4 edge curves.
public static func constrainedFill(edge1: Edge, edge2: Edge, edge3: Edge,
edge4: Edge? = nil,
maxDegree: Int = 8,
maxSegments: Int = 15) -> Shape?
- Parameters:
edge1,edge2,edge3— Required boundary edges.edge4— Optional fourth boundary edge; passnilfor a 3-sided fill.maxDegree— Maximum BSpline degree.maxSegments— Maximum number of segments.
- Returns: Face shape built on the filled BSpline surface, or
nilon failure. - OCCT:
GeomFill_ConstrainedFilling(viaOCCTGeomFillConstrained).
constrainedFillInfo
Get BSpline surface info from a constrained fill result.
public var constrainedFillInfo: ConstrainedFillInfo? { get }
- Returns: Surface info (degrees and pole counts), or
nilif not a BSpline surface. - OCCT:
Geom_BSplineSurface(viaOCCTGeomFillConstrainedInfo).
Shape Validity Checking (v0.47.0)
CheckStatus
Shape check error status codes from BRepCheck.
public enum CheckStatus: Int32, Sendable, CaseIterable {
case noError = 0
case invalidPointOnCurve = 1
case invalidPointOnCurveOnSurface = 2
case invalidPointOnSurface = 3
case no3DCurve = 4
case multiple3DCurve = 5
case invalid3DCurve = 6
case noCurveOnSurface = 7
case invalidCurveOnSurface = 8
case invalidCurveOnClosedSurface = 9
case invalidSameRangeFlag = 10
case invalidSameParameterFlag = 11
case invalidDegeneratedFlag = 12
case freeEdge = 13
case invalidMultiConnexity = 14
case invalidRange = 15
case emptyWire = 16
case redundantEdge = 17
case selfIntersectingWire = 18
case noSurface = 19
case invalidWire = 20
case redundantWire = 21
case intersectingWires = 22
case invalidImbricationOfWires = 23
case emptyShell = 24
case redundantFace = 25
case invalidImbricationOfShells = 26
case unorientableShape = 27
case notClosed = 28
case notConnected = 29
case subshapeNotInShape = 30
case badOrientation = 31
case badOrientationOfSubshape = 32
case invalidPolygonOnTriangulation = 33
case invalidToleranceValue = 34
case enclosedRegion = 35
case checkFail = 36
}
CheckResult
Result of a shape validity check.
public struct CheckResult: Sendable {
public let isValid: Bool
public let errorCount: Int
public let firstError: CheckStatus?
}
checkResult
Check the overall validity of this shape.
public var checkResult: CheckResult { get }
- Returns: Check result with validity flag, error count, and first error code.
- OCCT:
BRepCheck_Analyzer(viaOCCTCheckShape). - Example:
let cr = shape.checkResult if !cr.isValid, let err = cr.firstError { print("invalid: \(err)") }
detailedCheckStatuses
Get detailed error status codes for this shape.
public var detailedCheckStatuses: [CheckStatus] { get }
Returns all individual error codes found during validation. Useful for diagnosing exactly what’s wrong with an invalid shape.
- Returns: Array of check status codes; empty if valid.
- OCCT:
BRepCheck_Analyzer(viaOCCTCheckShapeDetailed).
Face.faceCheckResult
Check the validity of this face using BRepCheck_Face.
public var faceCheckResult: Shape.CheckResult { get }
More targeted than Shape.checkResult — includes wire intersection checks and face-specific validation.
- Returns: Check result.
- OCCT:
BRepCheck_Face(viaOCCTCheckFace).
Local Operations, Validation, Fixing and Extrema (v0.48.0)
localPipe(along:)
Perform a pipe sweep of this shape along a wire spine with shape tracking.
public func localPipe(along spine: Wire) -> Shape?
- Parameters:
spine— Wire spine to sweep along. - Returns: Swept shape, or
nilon failure. - OCCT:
LocOpe_Pipe(viaOCCTLocOpePipe).
localLinearForm(direction:from:to:)
Perform a linear form (translation sweep) of this shape with shape tracking.
public func localLinearForm(direction: SIMD3<Double>,
from start: SIMD3<Double>,
to end: SIMD3<Double>) -> Shape?
- Parameters:
direction— Direction vector of the sweep.start— Start point of the sweep.end— End point of the sweep.
- Returns: Swept shape, or
nilon failure. - OCCT:
LocOpe_LinearForm(viaOCCTLocOpeLinearForm).
localRevolutionForm(axisOrigin:axisDirection:angle:)
Perform a revolution form of this shape with shape tracking.
public func localRevolutionForm(axisOrigin: SIMD3<Double>,
axisDirection: SIMD3<Double>,
angle: Double) -> Shape?
- Parameters:
axisOrigin— Origin point of the rotation axis.axisDirection— Direction of the rotation axis.angle— Rotation angle in radians.
- Returns: Revolved shape, or
nilon failure. - OCCT:
LocOpe_RevolutionForm(viaOCCTLocOpeRevolutionForm).
splitFace(at:with:)
Split a face of this shape by adding a wire on it.
public func splitFace(at faceIndex: Int, with wire: Wire) -> Shape?
- Parameters:
faceIndex— 0-based index of the face to split.wire— Wire lying on the face that defines the split.
- Returns: Modified shape with the face split, or
nilon failure. - OCCT:
LocOpe_SplitShape(viaOCCTLocOpeSplitShapeByWire).
splitEdge(at:parameter:)
Split an edge of this shape at a parameter.
public func splitEdge(at edgeIndex: Int, parameter: Double) -> Shape?
- Parameters:
edgeIndex— 0-based index of the edge to split.parameter— Parameter along the edge (0.0–1.0) where the split occurs.
- Returns: The split edge parts as a compound, or
nilon failure. - OCCT:
LocOpe_SplitShape(viaOCCTLocOpeSplitShapeByVertex).
splitDrafts(faceIndex:wire:direction:planeOrigin:planeNormal:angle:)
Split a face with draft angles on both sides of a wire.
public func splitDrafts(faceIndex: Int, wire: Wire,
direction: SIMD3<Double>,
planeOrigin: SIMD3<Double>,
planeNormal: SIMD3<Double>,
angle: Double) -> Shape?
- Parameters:
faceIndex— 0-based index of the face to split.wire— Wire defining the split line.direction— Extraction direction.planeOrigin— Origin of the neutral plane.planeNormal— Normal of the neutral plane.angle— Draft angle in radians.
- Returns: Modified shape with draft, or
nilon failure. - OCCT:
LocOpe_SplitDrafts(viaOCCTLocOpeSplitDrafts). - Note:
LocOpe_SplitDrafts::Perform()can throw on incompatible geometry; the bridge wraps it in a try-catch.
commonEdges(with:)
Find edges in common between this shape and another.
public func commonEdges(with other: Shape) -> [Edge]
- Parameters:
other— Shape to compare with. - Returns: Array of common edges (up to 100).
- OCCT:
LocOpe_FindEdges(viaOCCTLocOpeFindEdges).
edgesInFace(at:)
Find edges of this shape that lie in a specific face.
public func edgesInFace(at faceIndex: Int) -> [Edge]
- Parameters:
faceIndex— 0-based index of the face to check. - Returns: Array of edges found in the face (up to 100).
- OCCT:
LocOpe_FindEdgesInFace(viaOCCTLocOpeFindEdgesInFace).
CSIntersection
Result of a curve-shape intersection.
public struct CSIntersection: Sendable {
public let point: SIMD3<Double>
public let parameter: Double
public let faceUV: SIMD2<Double>
}
intersectLine(origin:direction:) (LocOpe_CSIntersector variant)
Intersect a line with this shape to find intersection points.
public func intersectLine(origin: SIMD3<Double>, direction: SIMD3<Double>) -> [CSIntersection]
- Parameters:
origin— Line origin.direction— Line direction.
- Returns: Array of intersection points with curve parameters and face UV coordinates.
- OCCT:
LocOpe_CSIntersector(viaOCCTLocOpeCSIntersectLine). - Note: This overload returns
[CSIntersection]with face UV. A separateIntCurvesFace-backed overload in v0.61.0 returns[LineFaceIntersection].
analyzeValidity(geometryChecks:)
Perform comprehensive validity analysis on this shape.
public func analyzeValidity(geometryChecks: Bool = true) -> Bool
- Parameters:
geometryChecks— Whether to include geometry-level checks. - Returns:
trueif the shape is valid. - OCCT:
BRepCheck_Analyzer(viaOCCTBRepCheckAnalyzerIsValid).
TopAbs_ShapeEnum
Sub-shape type specifier.
public enum TopAbs_ShapeEnum: Int32, Sendable {
case compound = 0, compsolid = 1, solid = 2, shell = 3
case face = 4, wire = 5, edge = 6, vertex = 7
}
isSubShapeValid(type:at:)
Check if a specific sub-shape is valid within this shape’s context.
public func isSubShapeValid(type: TopAbs_ShapeEnum, at index: Int) -> Bool
- Parameters:
type— Type of sub-shape to check.index— 0-based index of the sub-shape.
- Returns:
trueif the sub-shape is valid. - OCCT:
BRepCheck_Analyzer(viaOCCTBRepCheckSubShapeValid).
checkEdge(at:)
Check validity of an edge by index.
public func checkEdge(at index: Int) -> CheckResult
- Parameters:
index— 0-based edge index. - Returns: Check result for the specified edge.
- OCCT:
BRepCheck_Edge(viaOCCTCheckEdge).
checkWire(at:)
Check validity of a wire by index.
public func checkWire(at index: Int) -> CheckResult
- OCCT:
BRepCheck_Wire(viaOCCTCheckWire).
checkShell(at:)
Check validity of a shell by index.
public func checkShell(at index: Int) -> CheckResult
- OCCT:
BRepCheck_Shell(viaOCCTCheckShell).
checkVertex(at:)
Check validity of a vertex by index.
public func checkVertex(at index: Int) -> CheckResult
- OCCT:
BRepCheck_Vertex(viaOCCTCheckVertex).
limitTolerance(min:max:)
Limit all tolerances in this shape to a given range.
@discardableResult
public func limitTolerance(min: Double, max: Double) -> Bool
- Parameters:
min— Minimum tolerance.max— Maximum tolerance.
- Returns:
trueif any tolerance was changed. - OCCT:
ShapeFix_ShapeTolerance::LimitTolerance(viaOCCTShapeFixLimitTolerance).
setTolerance(_:)
Set all tolerances in this shape to a specific value.
public func setTolerance(_ tolerance: Double)
- Parameters:
tolerance— Tolerance value to set on all sub-shapes. - OCCT:
ShapeFix_ShapeTolerance::SetTolerance(viaOCCTShapeFixSetTolerance).
splitCommonVertices()
Split vertices that are shared between edges in incompatible ways.
public func splitCommonVertices() -> Shape?
- Returns: Fixed shape, or
nilon failure. - OCCT:
ShapeFix_SplitCommonVertex(viaOCCTShapeFixSplitCommonVertex).
connectedFaces(tolerance:)
Connect adjacent faces in this shape’s shell.
public func connectedFaces(tolerance: Double = 1e-4) -> Shape?
- Parameters:
tolerance— Connection tolerance. - Returns: Fixed shape with connected faces, or
nilon failure. - OCCT:
ShapeFix_FaceConnect(viaOCCTShapeFixFaceConnect).
fixEdgeSameParameter(tolerance:)
Fix same-parameter inconsistencies on all edges.
@discardableResult
public func fixEdgeSameParameter(tolerance: Double = 0) -> Int
- Parameters:
tolerance— Fixing tolerance (0 = default). - Returns: Number of edges fixed.
- OCCT:
ShapeFix_Edge::FixSameParameter(viaOCCTShapeFixEdgeSameParameter).
fixEdgeVertexTolerance()
Fix vertex tolerance issues on all edges.
@discardableResult
public func fixEdgeVertexTolerance() -> Int
- Returns: Number of edges fixed.
- OCCT:
ShapeFix_Edge::FixVertexTolerance(viaOCCTShapeFixEdgeVertexTolerance).
fixWireVertices(precision:)
Fix vertex issues in all wires of this shape.
@discardableResult
public func fixWireVertices(precision: Double = 1e-4) -> Int
- Parameters:
precision— Precision for fixing. - Returns: Number of fixes applied.
- OCCT:
ShapeFix_WireVertex(viaOCCTShapeFixWireVertex).
EdgeEdgeExtrema
Result of edge-edge distance extrema computation.
public struct EdgeEdgeExtrema: Sendable {
public let distance: Double
public let paramOnEdge1: Double
public let paramOnEdge2: Double
public let pointOnEdge1: SIMD3<Double>
public let pointOnEdge2: SIMD3<Double>
public let isParallel: Bool
public let solutionCount: Int
}
edgeEdgeExtrema(edgeIndex1:other:edgeIndex2:)
Compute distance extrema between two edges by index.
public func edgeEdgeExtrema(edgeIndex1: Int, other: Shape, edgeIndex2: Int) -> EdgeEdgeExtrema?
- Parameters:
edgeIndex1— 0-based index of the first edge in this shape.other— Shape containing the second edge.edgeIndex2— 0-based index of the second edge inother.
- Returns: Extrema result, or
nilif no solutions or if edges are parallel. - OCCT:
BRepExtrema_ExtCC(viaOCCTBRepExtremaExtCC). - Note: Returns
nilwhen edges are parallel (isParallel == true). ChecksolutionCount > 0guards this in the bridge.
PointFaceExtrema
Result of point-face distance extrema computation.
public struct PointFaceExtrema: Sendable {
public let distance: Double
public let faceUV: SIMD2<Double>
public let pointOnFace: SIMD3<Double>
public let solutionCount: Int
}
pointFaceExtrema(point:faceIndex:)
Compute distance from a point to a face.
public func pointFaceExtrema(point: SIMD3<Double>, faceIndex: Int) -> PointFaceExtrema?
- Parameters:
point— 3D point.faceIndex— 0-based face index in this shape.
- Returns: Extrema result, or
nilon failure. - OCCT:
BRepExtrema_ExtPF(viaOCCTBRepExtremaExtPF).
FaceFaceExtrema
Result of face-face distance extrema computation.
public struct FaceFaceExtrema: Sendable {
public let distance: Double
public let face1UV: SIMD2<Double>
public let face2UV: SIMD2<Double>
public let pointOnFace1: SIMD3<Double>
public let pointOnFace2: SIMD3<Double>
public let solutionCount: Int
}
faceFaceExtrema(faceIndex1:other:faceIndex2:)
Compute distance extrema between two faces.
public func faceFaceExtrema(faceIndex1: Int, other: Shape, faceIndex2: Int) -> FaceFaceExtrema?
- Parameters:
faceIndex1— 0-based index of the first face in this shape.other— Shape containing the second face.faceIndex2— 0-based index of the second face inother.
- Returns: Extrema result, or
nilon failure. - OCCT:
BRepExtrema_ExtFF(viaOCCTBRepExtremaExtFF).
dividedClosedFaces(splitPoints:)
Divide closed (wrapping) faces in this shape.
public func dividedClosedFaces(splitPoints: Int = 1) -> Shape?
Uses ShapeUpgrade_ShapeDivideClosed to split faces that wrap completely around (e.g., the lateral face of a cylinder).
- Parameters:
splitPoints— Number of split points per closed face. - Returns: Shape with divided faces, or
nilon failure. - OCCT:
ShapeUpgrade_ShapeDivideClosed(viaOCCTShapeUpgradeDivideClosed).
ContinuityLevel
Continuity level for shape division.
public enum ContinuityLevel: Int32, Sendable {
case c0 = 0, c1 = 1, c2 = 2, c3 = 3, cn = 4, g1 = 5, g2 = 6
}
dividedByContinuity(criterion:tolerance:)
Divide this shape at continuity breaks.
public func dividedByContinuity(criterion: ContinuityLevel = .c1, tolerance: Double = 1e-4) -> Shape?
Splits faces and edges at points where the geometry drops below the required continuity level.
- Parameters:
criterion— Minimum required continuity level.tolerance— Tolerance for continuity check.
- Returns: Divided shape, or
nilif no divisions needed or on failure. - OCCT:
ShapeUpgrade_ShapeDivideContinuity(viaOCCTShapeUpgradeDivideContinuity).
PointEdgeExtrema
Result of point-edge distance extrema computation.
public struct PointEdgeExtrema: Sendable {
public let distance: Double
public let parameter: Double
public let pointOnEdge: SIMD3<Double>
public let solutionCount: Int
}
pointEdgeExtrema(point:edgeIndex:)
Compute minimum distance from a point to an edge of this shape.
public func pointEdgeExtrema(point: SIMD3<Double>, edgeIndex: Int) -> PointEdgeExtrema?
- Parameters:
point— 3D point.edgeIndex— 0-based edge index.
- Returns: Extrema result, or
nilon failure. - OCCT:
BRepExtrema_ExtPC(viaOCCTBRepExtremaExtPC).
EdgeFaceExtrema
Result of edge-face distance extrema computation.
public struct EdgeFaceExtrema: Sendable {
public let distance: Double
public let paramOnEdge: Double
public let faceUV: SIMD2<Double>
public let pointOnEdge: SIMD3<Double>
public let pointOnFace: SIMD3<Double>
public let isParallel: Bool
public let solutionCount: Int
}
edgeFaceExtrema(edgeIndex:other:faceIndex:)
Compute distance extrema between an edge and a face.
public func edgeFaceExtrema(edgeIndex: Int, other: Shape, faceIndex: Int) -> EdgeFaceExtrema?
- Parameters:
edgeIndex— 0-based edge index in this shape.other— Shape containing the face.faceIndex— 0-based face index inother.
- Returns: Extrema result, or
nilif parallel or computation fails. - OCCT:
BRepExtrema_ExtCF(viaOCCTBRepExtremaExtCF). - Note: When
isParallelistrue, the returned struct has zero distance andsolutionCount == 0.
removeSmallSolids(volumeThreshold:)
Remove small solids from this shape based on volume threshold.
public func removeSmallSolids(volumeThreshold: Double) -> Shape?
- Parameters:
volumeThreshold— Solids with volume below this threshold are removed. - Returns: Shape with small solids removed, or
nilon failure. - OCCT:
ShapeFix_FixSmallSolid(viaOCCTShapeFixRemoveSmallSolids).
mergeSmallSolids(widthFactorThreshold:)
Merge small solids into adjacent larger solids.
public func mergeSmallSolids(widthFactorThreshold: Double) -> Shape?
Small solids are merged into their neighbors rather than removed.
- Parameters:
widthFactorThreshold— Width factor below which solids are merged. - Returns: Shape with small solids merged, or
nilon failure. - OCCT:
ShapeFix_FixSmallSolid(viaOCCTShapeFixMergeSmallSolids).
BSplineContinuity
Continuity requirement for BSpline restriction.
public enum BSplineContinuity: Int32, Sendable {
case c0 = 0, c1 = 1, c2 = 2, c3 = 3
}
bsplineRestriction(tol3d:tol2d:maxDegree:maxSegments:continuity3d:continuity2d:degreePriority:rational:)
Simplify BSpline surfaces and curves by restricting degree and segment count.
public func bsplineRestriction(
tol3d: Double = 0.01, tol2d: Double = 0.01,
maxDegree: Int = 8, maxSegments: Int = 100,
continuity3d: BSplineContinuity = .c1, continuity2d: BSplineContinuity = .c1,
degreePriority: Bool = true, rational: Bool = false
) -> Shape?
- Parameters:
tol3d— 3D approximation tolerance.tol2d— 2D approximation tolerance.maxDegree— Maximum BSpline degree.maxSegments— Maximum number of segments.continuity3d— 3D continuity requirement.continuity2d— 2D continuity requirement.degreePriority— Iftrue, prioritize degree reduction over segment reduction.rational— Allow rational BSplines.
- Returns: Simplified shape, or
nilon failure. - OCCT:
ShapeCustom::BSplineRestriction(viaOCCTShapeCustomBSplineRestriction).
ShapeAnalysis FreeBoundsProperties
FreeBoundInfo
Properties of a single free bound (boundary wire).
public struct FreeBoundInfo: Sendable {
public let area: Double
public let perimeter: Double
public let ratio: Double
public let width: Double
public let notchCount: Int
}
ratio—area / perimeter²(shape factor).
FreeBoundsAnalysis
Summary result of free bounds analysis.
public struct FreeBoundsAnalysis: Sendable {
public let totalCount: Int
public let closedCount: Int
public let openCount: Int
}
freeBoundsAnalysis(tolerance:)
Analyze free bounds (boundary wires) of this shape.
public func freeBoundsAnalysis(tolerance: Double) -> FreeBoundsAnalysis
Free bounds are edges that belong to only one face.
- Parameters:
tolerance— Sewing tolerance for finding free bounds. - Returns: Analysis summary with closed and open bound counts.
- OCCT:
ShapeAnalysis_FreeBoundsProperties(viaOCCTFreeBoundsAnalyze). - Example:
let fb = shell.freeBoundsAnalysis(tolerance: 1e-6) print("open: \(fb.openCount), closed: \(fb.closedCount)")
closedFreeBoundInfo(tolerance:index:)
Get properties of a closed free bound.
public func closedFreeBoundInfo(tolerance: Double, index: Int) -> FreeBoundInfo?
- Parameters:
tolerance— Same tolerance used forfreeBoundsAnalysis(tolerance:).index— 0-based index of the closed free bound.
- Returns: Properties, or
nilif the index is out of range. - OCCT:
ShapeAnalysis_FreeBoundsProperties(viaOCCTFreeBoundsGetClosedBoundInfo).
openFreeBoundInfo(tolerance:index:)
Get properties of an open free bound.
public func openFreeBoundInfo(tolerance: Double, index: Int) -> FreeBoundInfo?
- Parameters:
tolerance— Same tolerance used forfreeBoundsAnalysis(tolerance:).index— 0-based index of the open free bound.
- Returns: Properties, or
nilif the index is out of range. - OCCT:
ShapeAnalysis_FreeBoundsProperties(viaOCCTFreeBoundsGetOpenBoundInfo).
closedFreeBoundWire(tolerance:index:)
Get the wire shape of a closed free bound.
public func closedFreeBoundWire(tolerance: Double, index: Int) -> Shape?
- Parameters:
tolerance— Same tolerance used forfreeBoundsAnalysis(tolerance:).index— 0-based index of the closed free bound.
- Returns: Wire as a
Shape, ornilif the index is out of range. - OCCT:
ShapeAnalysis_FreeBoundsProperties(viaOCCTFreeBoundsGetClosedBoundWire).
openFreeBoundWire(tolerance:index:)
Get the wire shape of an open free bound.
public func openFreeBoundWire(tolerance: Double, index: Int) -> Shape?
- Parameters:
tolerance— Same tolerance used forfreeBoundsAnalysis(tolerance:).index— 0-based index of the open free bound.
- Returns: Wire as a
Shape, ornilif the index is out of range. - OCCT:
ShapeAnalysis_FreeBoundsProperties(viaOCCTFreeBoundsGetOpenBoundWire).