Shape. Builders & Boolean Internals I
These members are low-level OCCT builder and algorithm wrappers, polyhedral geometry, history tracking, 2D fillet engines, shell/solid builders, Boolean splitters, ray/contour intersection, mesh utilities, and surface-fill algorithms, exposed directly on Shape. See the main Shape page for the core topology, transform, and measurement API (free-boundary analysis is on the Shape, Measurement page).
Topics
- v0.50 Polyhedral Distance / History / Wire-Vertex / Nearest Plane · v0.51 BRepLib_MakeSolid / GC Transforms / ChFi2d_AnaFilletAlgo · BRepFill_Generator / AdvancedEvolved / OffsetWire / Draft / Pipe / CompatibleWires · ChFi2d_FilletAlgo · BRepTools_Substitution · ShapeUpgrade_ShellSewing · LocOpe_BuildShape · BOPAlgo Splitter / ArgumentAnalyzer · IntCurvesFace Intersection · Contap Contour Analysis · BRepMesh_Deflection · BRepBuilderAPI_MakeShapeOnMesh · GeomPlate_Surface · CellsBuilder · BRepLib_MakeEdge / MakeFace / MakeShell / ToolTriangulatedShape / PointCloudShape · BRepBuilderAPI_MakeEdge2d · BRepTools_Modifier + NurbsConvert · ShapeCustom_Direct / TrsfModification · LocOpe Builders · CPnts_UniformDeflection · IntCurvesFace_ShapeIntersector · GeomLProp_CLProps / SLProps · BRepOffset_SimpleOffset · Approx_CurvilinearParameter · GeomInt_IntSS · Contap_Contour · BRepFeat_Builder · GeomFill Trihedron Laws / Coons / Curved / CoonsAlgPatch
v0.50 Polyhedral Distance / History / Wire-Vertex / Nearest Plane
PolyhedralDistance
Result of an approximate (mesh-based) distance query.
public struct PolyhedralDistance {
public let distance: Double
public let point1: SIMD3<Double>
public let point2: SIMD3<Double>
}
- Fields:
distance, approximate distance;point1, closest point on the first shape;point2, closest point on the second shape.
Shape.PolyhedralDistance.point2
polyhedralDistance(to:)
Compute fast polyhedral (approximate) distance to another shape.
public func polyhedralDistance(to other: Shape) -> PolyhedralDistance?
Both shapes must be meshed (have triangulation). Faster than exact distance but less precise.
- Parameters:
other, the shape to measure against. - Returns:
PolyhedralDistance, ornilif either shape has no triangulation or computation fails. - OCCT:
BRepExtrema_PolyviaOCCTShapePolyhedralDistance. - Example:
if let d = box.polyhedralDistance(to: sphere) { print(d.distance) }
History
Shape modification history for tracking what happened during operations.
public class History {
public init?()
public func addModified(initial: Shape, modified: Shape)
public func addGenerated(initial: Shape, generated: Shape)
public func remove(_ shape: Shape)
public func isRemoved(_ shape: Shape) -> Bool
public var hasModified: Bool { get }
public var hasGenerated: Bool { get }
public var hasRemoved: Bool { get }
public func modifiedCount(of shape: Shape) -> Int
public func generatedCount(of shape: Shape) -> Int
}
A reference-counted history store wrapping OCCTHistoryRef. Freed in deinit.
- OCCT:
BRepTools_History/OCCTHistory*bridge family.
History.init?()
Create an empty history object.
public init?()
- Returns: New
History, ornilif the underlying handle cannot be allocated. - OCCT:
OCCTHistoryCreate.
addModified(initial:modified:)
Record that an initial shape was modified into a new shape.
public func addModified(initial: Shape, modified: Shape)
- OCCT:
OCCTHistoryAddModified.
addGenerated(initial:generated:)
Record that an initial shape produced a new generated shape.
public func addGenerated(initial: Shape, generated: Shape)
- OCCT:
OCCTHistoryAddGenerated.
remove(_:)
Record that a shape was removed during the operation.
public func remove(_ shape: Shape)
- OCCT:
OCCTHistoryRemove.
isRemoved(_:)
Check whether a shape was recorded as removed.
public func isRemoved(_ shape: Shape) -> Bool
- OCCT:
OCCTHistoryIsRemoved.
hasModified, hasGenerated, hasRemoved
Whether any modifications / generations / removals were recorded.
public var hasModified: Bool { get }
public var hasGenerated: Bool { get }
public var hasRemoved: Bool { get }
- OCCT:
OCCTHistoryHasModified,OCCTHistoryHasGenerated,OCCTHistoryHasRemoved.
modifiedCount(of:)
Number of shapes the given initial shape was modified to.
public func modifiedCount(of shape: Shape) -> Int
- OCCT:
OCCTHistoryModifiedCount.
generatedCount(of:)
Number of shapes generated from the given initial shape.
public func generatedCount(of shape: Shape) -> Int
- OCCT:
OCCTHistoryGeneratedCount.
WireVertexAnalysis
Result of wire vertex connectivity analysis.
public struct WireVertexAnalysis {
public let edgeCount: Int
public let isDone: Bool
}
WireVertexStatus
Vertex connection status codes.
public enum WireVertexStatus: Int32 {
case sameVertex = 0
case sameCoords = 1
case close = 2
case end = 3
case start = 4
case intersection = 5
case disjoined = -1
case unknown = -2
}
| case | meaning |
|---|---|
.sameVertex | The two vertices are the same OCCT vertex (shared, not merely coincident). |
.sameCoords | The two vertices sit at the same coordinates but are distinct OCCT vertices. |
.close | The vertices are within the analysis precision but not coincident. |
.end | The vertex is at the end of the wire (last vertex, open wire). |
.start | The vertex is at the start of the wire (first vertex, open wire). |
.intersection | The vertex lies at a self-intersection of the wire. |
.disjoined | No connection could be established for this vertex. |
.unknown | The bridge returned a code this wrapper does not recognise. |
(Per-case anchors below, for cross-reference; the table above has the actual meaning of each.)
unknown
wireVertexAnalysis(precision:)
Analyze wire vertex connections for gaps, overlaps, and intersections.
public func wireVertexAnalysis(precision: Double = 0.01) -> WireVertexAnalysis
- Parameters:
precision, tolerance for vertex comparison. - Returns:
WireVertexAnalysiswith edge count and a completion flag. - OCCT:
ShapeAnalysis_WireVertexviaOCCTShapeWireVertexAnalysis. - Example:
let a = wire.wireVertexAnalysis(precision: 1e-4) print(a.edgeCount, a.isDone)
wireVertexStatus(precision:index:)
Get the status of a specific vertex in a wire.
public func wireVertexStatus(precision: Double = 0.01, index: Int) -> WireVertexStatus
- Parameters:
precision, analysis tolerance;index, 0-based vertex index. - Returns:
WireVertexStatuscase, or.unknownfor unrecognised codes. - OCCT:
OCCTShapeWireVertexStatus.
NearestPlane
Result of least-squares plane fitting.
public struct NearestPlane {
public let normal: SIMD3<Double>
public let origin: SIMD3<Double>
public let maxDeviation: Double
}
- Fields:
normal, fitted plane normal;origin, a point on the plane;maxDeviation, maximum distance from any input point to the fitted plane.
maxDeviation
Shape.nearestPlane(to:)
Fit the nearest plane to a set of 3D points using least-squares.
public static func nearestPlane(to points: [SIMD3<Double>]) -> NearestPlane?
- Parameters:
points, array of at least 3 points. - Returns:
NearestPlane, ornilif fewer than 3 points are provided or the fit is refused, see the refusal rule below. - OCCT:
ShapeAnalysis_Geom::NearestPlane, which analyses the cloud withGProp_PEquationand builds the plane through its barycentre normal to the principal axis of least extent (viaOCCTShapeNearestPlane).gp_Plnis the out-parameter that carries the answer back, not the algorithm. - A non-nil result is not a planarity test.
ShapeAnalysis_Geom::NearestPlanerefuses only when the smallest principal extent is at least half of one of the other two. On a 10 x 10 sheet that means it answers for every thickness up to 5 and refuses above it, so a cloud that is nowhere near planar still gets a plane. Measured on the pinned kernel (Scripts/repro/1399-refman-coverage-unlaned/probe-healing-transcript.txt): one corner of a 10 x 10 square lifted 8 units out of plane fits, withmaxDeviation2.13; the eight corners of a cube are refused. Gate onmaxDeviation, which is the largest distance from any input point to the returned plane, rather than on the result being non-nil. - Example:
let pts: [SIMD3<Double>] = [SIMD3(0,0,0), SIMD3(1,0,0), SIMD3(0,1,0)] if let plane = Shape.nearestPlane(to: pts) { print(plane.normal) // ≈ (0, 0, 1) }
v0.51 BRepLib_MakeSolid / GC Transforms / ChFi2d_AnaFilletAlgo
Shape.solidFromShell(_:)
Create a solid from a shell shape using BRepLib_MakeSolid.
public static func solidFromShell(_ shell: Shape) -> Shape?
- Parameters:
shell, a shape containing a closed shell (e.g. fromshellFromSurface). - Returns: Solid shape, or
nilon failure. - OCCT:
BRepLib_MakeSolidviaOCCTShapeMakeSolidFromShell. - Example:
if let solid = Shape.solidFromShell(myShell) { print(solid.isValid) }
mirroredAboutPoint(_:)
Mirror this shape about a point (point symmetry / inversion).
public func mirroredAboutPoint(_ point: SIMD3<Double>) -> Shape?
- Parameters:
point, centre of the point mirror. - Returns: Mirrored shape, or
nilon failure. - OCCT:
gp_Trsfpoint mirror viaOCCTShapeMirrorAboutPoint. - Example:
let inverted = box.mirroredAboutPoint(SIMD3(5, 0, 0))
mirroredAboutAxis(origin:direction:)
Mirror this shape about an axis line.
public func mirroredAboutAxis(origin: SIMD3<Double>, direction: SIMD3<Double>) -> Shape?
- Parameters:
origin, a point on the axis;direction, axis direction. - Returns: Mirrored shape, or
nilon failure. - OCCT:
gp_Trsfaxis mirror viaOCCTShapeMirrorAboutAxis.
scaledAboutPoint(_:factor:)
Scale this shape about a specific centre point.
public func scaledAboutPoint(_ center: SIMD3<Double>, factor: Double) -> Shape?
Unlike scaled(by:) which scales about the origin, this scales about the given point.
- Parameters:
center, centre of scaling;factor, scale factor. - Returns: Scaled shape, or
nilon failure. - OCCT:
gp_Trsfscale viaOCCTShapeScaleAboutPoint.
translated(from:to:)
Translate this shape by the vector from one point to another.
public func translated(from: SIMD3<Double>, to: SIMD3<Double>) -> Shape?
- Parameters:
from, start of the translation vector;to, end of the translation vector. - Returns: Translated shape, or
nilon failure. - OCCT:
GC_MakeTranslation(gp_Pnt, gp_Pnt)→gp_Trsf+BRepBuilderAPI_Transform, viaOCCTShapeTranslateByPoints.
AnaFilletResult
Result of a 2D analytical fillet operation.
public struct AnaFilletResult {
public let fillet: Shape
public let edge1: Shape
public let edge2: Shape
}
- Fields:
fillet, the arc edge;edge1,edge2, trimmed input edges.
edge2
Shape.anaFillet(edge1:edge2:planeOrigin:planeNormal:radius:) (Shape overload)
Compute a 2D analytical fillet between two edge shapes.
public static func anaFillet(
edge1: Shape,
edge2: Shape,
planeOrigin: SIMD3<Double> = .zero,
planeNormal: SIMD3<Double> = SIMD3(0, 0, 1),
radius: Double
) -> AnaFilletResult?
Uses ChFi2d_AnaFilletAlgo for fast exact fillet computation in a plane. Supports only line and arc-of-circle edges.
- Parameters:
edge1,edge2, edge shapes;planeOrigin, a point on the working plane;planeNormal, plane normal;radius, fillet radius. - Returns:
AnaFilletResult, ornilif computation fails. - OCCT:
ChFi2d_AnaFilletAlgoviaOCCTChFi2dAnaFillet. - Example:
if let r = Shape.anaFillet(edge1: e1, edge2: e2, radius: 2) { // r.fillet, r.edge1, r.edge2 }
Shape.anaFillet(edge1:edge2:planeOrigin:planeNormal:radius:) (Edge overload)
Convenience overload accepting Edge objects directly.
public static func anaFillet(
edge1: Edge, edge2: Edge,
planeOrigin: SIMD3<Double> = .zero,
planeNormal: SIMD3<Double> = SIMD3(0, 0, 1),
radius: Double
) -> AnaFilletResult?
- OCCT:
ChFi2d_AnaFilletAlgo(viaShape.fromEdgeconversion thenOCCTChFi2dAnaFillet).
Shape.anaFillet(wire:edgeIndex:planeOrigin:planeNormal:radius:)
Compute a 2D analytical fillet between two adjacent edges of a wire.
public static func anaFillet(
wire: Wire, edgeIndex: Int = 0,
planeOrigin: SIMD3<Double> = .zero,
planeNormal: SIMD3<Double> = SIMD3(0, 0, 1),
radius: Double
) -> AnaFilletResult?
Edge indices are 0-based; the fillet is computed between edges[edgeIndex] and edges[edgeIndex + 1].
- Parameters:
wire, source wire;edgeIndex, index of the first edge; remaining parameters as above. - Returns:
AnaFilletResult, ornilif indices are out of range or fillet fails. - OCCT:
ChFi2d_AnaFilletAlgo.
BRepFill_Generator / AdvancedEvolved / OffsetWire / Draft / Pipe / CompatibleWires
Shape.ruledShell(from:)
Create a ruled shell by lofting between multiple wire sections.
public static func ruledShell(from wires: [Wire]) -> Shape?
Each pair of adjacent wires generates a ruled surface between them. Wires should have the same number of edges for best results.
- Parameters:
wires, at least 2 wires. - Returns: Shell shape, or
nilon failure. - OCCT:
BRepFill_GeneratorviaOCCTBRepFillGenerator. - Example:
let bottom = Wire.rectangle(width: 10, height: 10)! let top = Wire.circle(origin: SIMD3(0, 0, 5), radius: 5)! if let shell = Shape.ruledShell(from: [bottom, top]) { }
Shape.advancedEvolved(spine:profile:tolerance:solid:)
Create an evolved solid from a spine wire and profile wire.
public static func advancedEvolved(
spine: Wire, profile: Wire,
tolerance: Double = 1e-3, solid: Bool = true
) -> Shape?
The profile is oriented perpendicular to the spine at each point and swept along it.
- Parameters:
spine, sweep path;profile, cross-section;tolerance, geometric tolerance;solid, produce a solid whentrue. - Returns: Evolved shape, or
nilon failure. - OCCT:
BRepFill_AdvancedEvolvedviaOCCTBRepFillAdvancedEvolved.
Shape.offsetWire(face:offset:)
Offset a planar wire on its face.
public static func offsetWire(face: Face, offset: Double) -> Shape?
Positive offset expands outward; negative shrinks inward.
- Parameters:
face, face containing the wire to offset;offset, signed offset distance. - Returns: Offset wire shape, or
nilon failure. - OCCT:
BRepFill_OffsetWireviaOCCTBRepFillOffsetWire.
Shape.draft(wire:direction:angle:length:)
Create a draft surface from a wire along a direction with a taper angle.
public static func draft(
wire: Wire, direction: SIMD3<Double>,
angle: Double, length: Double
) -> Shape?
The wire is projected along direction for length, with faces tapered at angle from the direction.
- Parameters:
wire, base profile;direction, draft direction;angle, taper angle in radians;length, draft length. - Returns: Draft shape, or
nilon failure. - OCCT:
BRepFill_DraftviaOCCTBRepFillDraft.
PipeSweepResult
Result of a pipe sweep operation.
public struct PipeSweepResult {
public let shape: Shape
public let errorOnSurface: Double
}
- Fields:
shape, the swept pipe;errorOnSurface, surface approximation error.
Shape.pipeSweep(spine:profile:)
Create a pipe sweep of a profile along a spine with error reporting.
public static func pipeSweep(spine: Wire, profile: Wire) -> PipeSweepResult?
Sweeps the profile wire along the spine wire using a corrected Frenet trihedron.
- Parameters:
spine, sweep path;profile, cross-section wire. - Returns:
PipeSweepResult, ornilon failure. - OCCT:
BRepFill_PipeviaOCCTBRepFillPipe. - Example:
if let result = Shape.pipeSweep(spine: path, profile: circle) { print(result.errorOnSurface) }
Shape.compatibleWires(_:)
Make wires compatible for lofting (same number of edges, consistently oriented).
public static func compatibleWires(_ wires: [Wire]) -> [Wire]?
Resamples wires so they have the same edge count and orientation, which improves lofting quality.
- Parameters:
wires, at least 2 wires to normalize. - Returns: Array of compatible
Wireobjects, ornilon failure. - OCCT:
BRepFill_CompatibleWiresviaOCCTBRepFillCompatibleWires.
ChFi2d_FilletAlgo
FilletAlgoResult
Result of a 2D iterative fillet operation.
public struct FilletAlgoResult {
public let fillet: Shape
public let edge1: Shape
public let edge2: Shape
public let resultCount: Int
}
- Fields:
fillet, the arc edge;edge1,edge2, trimmed edges;resultCount, number of fillet solutions found.
resultCount
Shape.filletAlgo(edge1:edge2:planeOrigin:planeNormal:radius:) (Shape overload)
Compute a 2D iterative fillet between two edge shapes in a plane.
public static func filletAlgo(
edge1: Shape, edge2: Shape,
planeOrigin: SIMD3<Double> = .zero,
planeNormal: SIMD3<Double> = SIMD3(0, 0, 1),
radius: Double
) -> FilletAlgoResult?
Uses ChFi2d_FilletAlgo which supports general edge types, unlike anaFillet which is limited to lines and arcs.
- Parameters:
edge1,edge2, edge shapes;planeOrigin,planeNormal, working plane;radius, fillet radius. - Returns:
FilletAlgoResult, ornilon failure. - OCCT:
ChFi2d_FilletAlgoviaOCCTChFi2dFilletAlgo.
Shape.filletAlgo(edge1:edge2:planeOrigin:planeNormal:radius:) (Edge overload)
Convenience overload accepting Edge objects directly.
public static func filletAlgo(
edge1: Edge, edge2: Edge,
planeOrigin: SIMD3<Double> = .zero,
planeNormal: SIMD3<Double> = SIMD3(0, 0, 1),
radius: Double
) -> FilletAlgoResult?
- OCCT:
ChFi2d_FilletAlgo.
Shape.filletAlgo(wire:edgeIndex:planeOrigin:planeNormal:radius:)
Compute a 2D iterative fillet between two adjacent edges of a wire.
public static func filletAlgo(
wire: Wire, edgeIndex: Int = 0,
planeOrigin: SIMD3<Double> = .zero,
planeNormal: SIMD3<Double> = SIMD3(0, 0, 1),
radius: Double
) -> FilletAlgoResult?
- Parameters:
wire, source wire;edgeIndex, 0-based index of the first edge. - Returns:
FilletAlgoResult, ornilif indices are out of range or fillet fails. - OCCT:
ChFi2d_FilletAlgo.
BRepTools_Substitution
substituted(replacing:with:)
Substitute a topological sub-shape within this shape and rebuild the parent.
public func substituted(replacing oldSubShape: Shape, with newSubShape: Shape) -> Shape?
Replaces a vertex, edge, or face with another sub-shape and rebuilds the containing topology.
- Parameters:
oldSubShape, the sub-shape to replace;newSubShape, the replacement. - Returns: Modified shape, or
nilon failure. - OCCT:
BRepTools_SubstitutionviaOCCTBRepToolsSubstitute.
ShapeUpgrade_ShellSewing
shellSewing(tolerance:)
Sew disconnected shells in this shape.
public func shellSewing(tolerance: Double = 1e-6) -> Shape?
Connects shells that share edges within the given tolerance.
- Parameters:
tolerance, sewing tolerance (default1e-6). - Returns: Sewn shape, or
nilon failure. - OCCT:
ShapeUpgrade_ShellSewingviaOCCTShapeUpgradeShellSewing.
LocOpe_BuildShape
builtFromFaces()
Build a shape from the faces of this shape.
public func builtFromFaces() -> Shape?
Extracts all faces and reconstructs them into a shell or solid.
- Returns: Rebuilt shape, or
nilon failure. - OCCT:
LocOpe_BuildShapeviaOCCTLocOpeBuildShape.
BOPAlgo Splitter / ArgumentAnalyzer
Shape.split(objects:by:)
Split shapes by tool shapes using BOPAlgo_Splitter.
public static func split(objects: [Shape], by tools: [Shape]) -> Shape?
Partitions the object shapes using the tool shapes as cutting geometry. All fragments are returned in a single compound.
- Parameters:
objects, shapes to be split;tools, cutting tools. - Returns: Compound of all split fragments, or
nilon failure. - OCCT:
BOPAlgo_SplitterviaOCCTBOPAlgoSplit. - Example:
let fragments = Shape.split(objects: [block], by: [cuttingPlane])
BooleanOperation
Boolean operation type for argument analysis.
public enum BooleanOperation: Int32 {
case fuse = 0
case common = 1
case cut = 2
case cut21 = 3
case section = 4
}
BooleanOperation.fuse
Union: the two shapes merged into one, keeping all material from both.
case fuse = 0
- OCCT:
BOPAlgo_FUSE.
BooleanOperation.common
Intersection: only the material shared by both shapes.
case common = 1
- OCCT:
BOPAlgo_COMMON.
BooleanOperation.cut
Subtraction: shape1 minus shape2, the material of the first shape with the second shape’s volume removed.
case cut = 2
- OCCT:
BOPAlgo_CUT.
BooleanOperation.cut21
Reversed subtraction: shape2 minus shape1. The same pairing as .cut with the roles of object and tool swapped, not a distinct third kind of cut.
case cut21 = 3
- OCCT:
BOPAlgo_CUT21.
BooleanOperation.section
Section: the intersection curves and points where the two shapes’ boundaries cross, not a solid result.
case section = 4
- OCCT:
BOPAlgo_SECTION.
Shape.analyzeBoolean(_:_:operation:)
Analyze whether two shapes are valid for a Boolean operation.
public static func analyzeBoolean(_ shape1: Shape, _ shape2: Shape,
operation: BooleanOperation = .fuse) -> Bool
Checks for self-intersection, small edges, and argument type compatibility.
- Parameters:
shape1, object shape;shape2, tool shape;operation, the operation to validate. - Returns:
trueif the shapes pass validation for the given operation. - OCCT:
BOPAlgo_ArgumentAnalyzerviaOCCTBOPAlgoAnalyzeArguments.
IntCurvesFace Intersection
LineFaceIntersection
Result of a line-face intersection.
public struct LineFaceIntersection {
public let point: SIMD3<Double>
public let parameter: Double
}
- Fields:
point, 3D intersection point;parameter, line parameter at intersection.
intersectLine(origin:direction:paramRange:)
Intersect a line with this shape (must be a face).
public func intersectLine(origin: SIMD3<Double>, direction: SIMD3<Double>,
paramRange: ClosedRange<Double> = -1000...1000) -> [LineFaceIntersection]
- Parameters:
origin, line origin;direction, line direction;paramRange, parameter bounds on the line. - Returns: Array of intersection results (may be empty).
- OCCT:
IntCurvesFace_IntersectorviaOCCTIntersectLineFace. - Example:
let hits = face.intersectLine(origin: SIMD3(0, 0, -10), direction: SIMD3(0, 0, 1))
Contap Contour Analysis
ContourType
Contour type from analytical contour computation.
public enum ContourType: Int32 {
case line = 0
case circle = 1
case other = 2
}
| Case | Meaning |
|---|---|
.other | The contour is neither a line nor a circle (an analytical form the analysis does not further classify). |
Shape.ContourType.other
ContourResult
Result of an analytical contour computation.
public struct ContourResult {
public let type: ContourType
public let count: Int
public let data: [Double]
}
- Fields:
type, contour geometry kind;count, number of contours;data, raw parameters (for circles: centre xyz + radius,data[0...3]; for lines: location xyz + direction xyz per contour, 6 doubles each).contourSphereDir/contourSphereEyealways report at most one contour, sodataholds 8 doubles.contourCylinderDircan report two tangent lines (count == 2, the ordinary, non-degenerate case, since a cylinder’s silhouette against a non-axis-parallel view direction is always a pair of tangent rulings, never one), sodataholds 12 doubles: line 1 atdata[0...5], line 2 atdata[6...11].
data
Shape.contourSphereDir(center:radius:direction:)
Compute the silhouette contour of a sphere for an orthographic view direction.
public static func contourSphereDir(center: SIMD3<Double>, radius: Double,
direction: SIMD3<Double>) -> ContourResult?
- Parameters:
center, sphere centre;radius, sphere radius;direction, orthographic view direction. - Returns:
ContourResult, ornilon failure. - OCCT:
Contap_ContAnaviaOCCTContapSphereDir.
Shape.contourCylinderDir(origin:axis:radius:direction:)
Compute the silhouette contour of a cylinder for an orthographic view direction.
A cylinder’s silhouette against a non-axis-parallel view direction is always the pair of tangent rulings either side of the axis: count is 2, never 1. Both lines are returned in data, 6 doubles each (location xyz + direction xyz): line 1 at data[0...5], line 2 at data[6...11].
if let result = Shape.contourCylinderDir(
origin: SIMD3(0, 0, 0), axis: SIMD3(0, 0, 1),
radius: 5, direction: SIMD3(1, 0, 0)),
result.count == 2 {
let line1Location = SIMD3(result.data[0], result.data[1], result.data[2])
let line2Location = SIMD3(result.data[6], result.data[7], result.data[8])
}
public static func contourCylinderDir(origin: SIMD3<Double>, axis: SIMD3<Double>,
radius: Double, direction: SIMD3<Double>) -> ContourResult?
- Parameters:
origin, cylinder axis origin;axis, axis direction;radius, radius;direction, view direction. - Returns:
ContourResult, ornilon failure. - OCCT:
Contap_ContAnaviaOCCTContapCylinderDir.
Shape.contourSphereEye(center:radius:eye:)
Compute the silhouette contour of a sphere for a perspective eye point.
public static func contourSphereEye(center: SIMD3<Double>, radius: Double,
eye: SIMD3<Double>) -> ContourResult?
- Parameters:
center, sphere centre;radius, sphere radius;eye, perspective eye point. - Returns:
ContourResult, ornilon failure. - OCCT:
Contap_ContAnaviaOCCTContapSphereEye.
BRepMesh_Deflection
computeAbsoluteDeflection(relativeDeflection:maxShapeSize:)
Convert a relative deflection value to an absolute deflection for meshing.
public func computeAbsoluteDeflection(relativeDeflection: Double, maxShapeSize: Double) -> Double?
- Parameters:
relativeDeflection, relative deflection;maxShapeSize, maximum dimension of the shape. - Returns: Absolute deflection, or
nilif computation fails (negative result from bridge). - OCCT:
BRepMesh_DeflectionviaOCCTComputeAbsoluteDeflection.
Shape.deflectionIsConsistent(current:required:allowDecrease:ratio:)
Check whether a mesh deflection is consistent with requirements.
public static func deflectionIsConsistent(current: Double, required: Double,
allowDecrease: Bool = false,
ratio: Double = 0.1) -> Bool
- Parameters:
current, current deflection;required, required deflection;allowDecrease, permit finer mesh than required;ratio, comparison ratio (0–1). - Returns:
trueif the current deflection is acceptable. - OCCT:
BRepMesh_Deflection::IsConsistentviaOCCTDeflectionIsConsistent.
BRepBuilderAPI_MakeShapeOnMesh
Shape.fromMesh(points:triangles:)
Build a topological shape from a triangulated mesh.
public static func fromMesh(points: [SIMD3<Double>], triangles: [(Int32, Int32, Int32)]) -> Shape?
- Parameters:
points, mesh vertices;triangles, index triples using 1-based indices intopoints. - Returns: Shape from the mesh, or
nilon failure. - OCCT:
BRepBuilderAPI_MakeShapeOnMeshviaOCCTShapeFromMesh. - Example:
let pts: [SIMD3<Double>] = [SIMD3(0,0,0), SIMD3(1,0,0), SIMD3(0,1,0)] let tris: [(Int32, Int32, Int32)] = [(1, 2, 3)] let shape = Shape.fromMesh(points: pts, triangles: tris)
GeomPlate_Surface
Shape.plateSurface(points:tolerance:maxDegree:maxSegments:)
Build a smooth plate surface through point constraints.
public static func plateSurface(points: [SIMD3<Double>], tolerance: Double = 1e-3,
maxDegree: Int = 8, maxSegments: Int = 20) -> Shape?
Creates a smooth BSpline surface that passes through or near the given points. Useful for surfaces from scattered point data.
- Parameters:
points, 3D points to fit;tolerance, approximation tolerance;maxDegree, max BSpline degree;maxSegments, max BSpline segments. - Returns: Face with plate surface, or
nilon failure. - OCCT:
GeomPlate_BuildPlateSurface+GeomPlate_MakeApproxviaOCCTGeomPlateSurface.
CellsBuilder
Builder for Boolean cell operations. Partitions input shapes into cells (volumetric fragments), assigns material IDs, and lets you select which cells to include in the result. The class is a standalone final class, not a member of Shape.
CellsBuilder.init?(shapes:)
Create a CellsBuilder by partitioning a set of input shapes into cells.
public init?(shapes: [Shape])
- Parameters:
shapes, input shapes to partition. - Returns:
CellsBuilder, ornilif partitioning fails. - OCCT:
BOPAlgo_CellsBuilderviaOCCTCellsBuilderCreate.
addAllToResult(material:)
Add all split cells to the result with a given material ID.
public func addAllToResult(material: Int32 = 0)
- Parameters:
material, material ID to assign (default0). - OCCT:
OCCTCellsBuilderAddAllToResult.
removeAllFromResult()
Remove all cells from the current result.
public func removeAllFromResult()
- OCCT:
OCCTCellsBuilderRemoveAllFromResult.
removeInternalBoundaries()
Merge adjacent cells that share the same material ID, removing internal faces.
public func removeInternalBoundaries()
- OCCT:
BOPAlgo_CellsBuilder::RemoveInternalBoundariesviaOCCTCellsBuilderRemoveInternalBoundaries.
result()
Get the current result shape.
public func result() -> Shape?
- Returns: Result compound shape, or
nilif no cells have been added. - OCCT:
OCCTCellsBuilderGetResult. - Example:
if let cb = CellsBuilder(shapes: [box, sphere]) { cb.addAllToResult(material: 1) cb.removeInternalBoundaries() let merged = cb.result() }
BRepLib_MakeEdge / MakeFace / MakeShell / ToolTriangulatedShape / PointCloudShape
Shape.edgeFromLine(origin:direction:p1:p2:)
Create an edge from a line with parameter bounds.
public static func edgeFromLine(
origin: SIMD3<Double>,
direction: SIMD3<Double>,
p1: Double,
p2: Double
) -> Shape?
- Parameters:
origin, line origin point;direction, line direction;p1,p2, parameter bounds. - Returns: Edge shape, or
nilon failure. - OCCT:
BRepLib_MakeEdge(gp_Lin, p1, p2)viaOCCTBRepLibMakeEdgeFromLine.
Shape.edgeFromPoints(_:_:)
Create an edge from two 3D points.
public static func edgeFromPoints(_ p1: SIMD3<Double>, _ p2: SIMD3<Double>) -> Shape?
- Parameters:
p1,p2, start and end points. - Returns: Edge shape, or
nilon failure. - OCCT:
BRepLib_MakeEdge(gp_Pnt, gp_Pnt)viaOCCTBRepLibMakeEdgeFromPoints.
Shape.edgeFromCircle(center:axis:radius:p1:p2:)
Create an edge from a circle arc with parameter bounds.
public static func edgeFromCircle(
center: SIMD3<Double>,
axis: SIMD3<Double>,
radius: Double,
p1: Double,
p2: Double
) -> Shape?
- Parameters:
center, circle centre;axis, normal axis;radius, radius;p1,p2, angular bounds in radians. - Returns: Edge shape, or
nilon failure. - OCCT:
BRepLib_MakeEdge(gp_Circ, p1, p2)viaOCCTBRepLibMakeEdgeFromCircle.
Shape.faceFromPlane(origin:normal:uRange:vRange:tolerance:)
Create a face from a plane surface with UV bounds.
public static func faceFromPlane(
origin: SIMD3<Double>,
normal: SIMD3<Double>,
uRange: ClosedRange<Double>,
vRange: ClosedRange<Double>,
tolerance: Double = 1e-6
) -> Shape?
- Parameters:
origin, point on the plane;normal, plane normal;uRange,vRange, parameter bounds;tolerance, vertex tolerance. - Returns: Face shape, or
nilon failure. - OCCT:
BRepLib_MakeFace(gp_Pln, ...)viaOCCTBRepLibMakeFaceFromPlane. - Note:
Shape.faceFromPlane(origin:normal:uBounds:vBounds:tolerance:)(see “Document-Mesh-Fixing”) now delegates to this overload (#841), the two were added independently and always drove the sameBRepLib_MakeFaceengine.
Shape.faceFromCylinder(origin:axis:radius:uRange:vRange:tolerance:)
Create a face from a cylindrical surface with UV bounds.
public static func faceFromCylinder(
origin: SIMD3<Double>,
axis: SIMD3<Double>,
radius: Double,
uRange: ClosedRange<Double>,
vRange: ClosedRange<Double>,
tolerance: Double = 1e-6
) -> Shape?
- Parameters:
origin, axis origin;axis, axis direction;radius, cylinder radius;uRange, angular bounds (radians);vRange, axial bounds;tolerance, vertex tolerance. - Returns: Face shape, or
nilon failure. - OCCT:
BRepLib_MakeFace(Geom_CylindricalSurface, ...)viaOCCTBRepLibMakeFaceFromCylinder(buildsGeom_CylindricalSurface(gp_Ax2, radius); notgp_Cylinder). - Note:
Shape.faceFromCylinder(origin:axis:radius:uBounds:vBounds:tolerance:)(see “Document-Mesh-Fixing”) now delegates to this overload (#841), see the siblingfaceFromPlanenote above.
Shape.shellFromPlane(origin:normal:uRange:vRange:)
Create a shell from a plane surface with UV bounds.
public static func shellFromPlane(
origin: SIMD3<Double>,
normal: SIMD3<Double>,
uRange: ClosedRange<Double>,
vRange: ClosedRange<Double>
) -> Shape?
- Parameters:
origin, point on the plane;normal, plane normal;uRange,vRange, parameter bounds. - Returns: Shell shape, or
nilon failure. - OCCT:
BRepLib_MakeShell(Handle(Geom_Plane), uMin, uMax, vMin, vMax)viaOCCTBRepLibMakeShellFromPlane.
computeNormals()
Compute normals on the triangulation of all faces in this shape.
public func computeNormals() -> Bool
The shape must be meshed first.
- Returns:
trueif normals were computed successfully. - OCCT:
BRepLib_ToolTriangulatedShape::ComputeNormalsviaOCCTBRepLibComputeNormals.
PointCloudResult
Point cloud positions and normals.
public struct PointCloudResult: Sendable {
public let points: [SIMD3<Double>]
public let normals: [SIMD3<Double>]
}
pointCloudByTriangulation()
Generate a point cloud from this shape’s triangulation.
public func pointCloudByTriangulation() -> PointCloudResult?
The shape must be meshed first. One point and normal per triangulation node.
- Returns:
PointCloudResult, ornilif the shape has no triangulation or generation fails. - OCCT:
BRepLib_PointCloudShape::GeneratePointsByTriangulationviaOCCTBRepLibPointCloudByTriangulation.
pointCloudByDensity(_:)
Generate a point cloud from this shape by density (points per unit area).
public func pointCloudByDensity(_ density: Double) -> PointCloudResult?
The shape must be meshed first.
- Parameters:
density, target number of points per unit area. - Returns:
PointCloudResult, ornilon failure. - OCCT:
BRepLib_PointCloudShape::GeneratePointsByDensityviaOCCTBRepLibPointCloudByDensity.
BRepBuilderAPI_MakeEdge2d
Shape.edge2d(from:to:)
Create a 2D edge from two 2D points.
public static func edge2d(from p1: SIMD2<Double>, to p2: SIMD2<Double>) -> Shape?
- Parameters:
p1,p2, start and end points in 2D. - Returns: 2D edge shape, or
nilon failure. - OCCT:
BRepBuilderAPI_MakeEdge2d(gp_Pnt2d, gp_Pnt2d)viaOCCTMakeEdge2dFromPoints.
Shape.edge2dFromCircle(center:direction:radius:p1:p2:)
Create a 2D edge from a circle arc with parameter bounds.
public static func edge2dFromCircle(
center: SIMD2<Double>,
direction: SIMD2<Double>,
radius: Double,
p1: Double,
p2: Double
) -> Shape?
- Parameters:
center, 2D circle centre;direction, orientation;radius, radius;p1,p2, angular bounds. - Returns: 2D edge shape, or
nilon failure. - OCCT:
BRepBuilderAPI_MakeEdge2d(gp_Circ2d, p1, p2)viaOCCTMakeEdge2dFromCircle. - Note:
radiusmust be positive (#553).BRepBuilderAPI_MakeEdge2dreports success for a zero radius and hands back a zero-length edge with both vertices at the centre, so the radius is checked before OCCT sees it. A non-positive radius returns nil.
Shape.edge2dFromLine(origin:direction:p1:p2:)
Create a 2D edge from a line with parameter bounds.
public static func edge2dFromLine(
origin: SIMD2<Double>,
direction: SIMD2<Double>,
p1: Double,
p2: Double
) -> Shape?
- Parameters:
origin, 2D line origin;direction, line direction;p1,p2, parameter bounds. - Returns: 2D edge shape, or
nilon failure. - OCCT:
BRepBuilderAPI_MakeEdge2d(gp_Lin2d, p1, p2)viaOCCTMakeEdge2dFromLine.
BRepTools_Modifier + NurbsConvert
nurbsConvertViaModifier()
Convert this shape to NURBS using BRepTools_Modifier with BRepTools_NurbsConvertModification, skipping Shape.convertedToNURBS()’s vertex-tolerance correction pass.
public func nurbsConvertViaModifier() -> Shape?
This drives the exact same BRepTools_Modifier + BRepTools_NurbsConvertModification pair Shape.convertedToNURBS() (BRepBuilderAPI_NurbsConvert) uses internally, it is that method’s own implementation minus its final CorrectVertexTol() step, not an independent conversion mechanism. CorrectVertexTol() raises a vertex’s tolerance to cover any edge meeting it that the NURBS conversion enlarged, so this method’s result can carry a vertex whose tolerance is smaller than an edge meeting it, a real, silent conversion-fidelity gap .isValid will not catch (#836).
- Returns: NURBS-converted shape, or
nilon failure. - OCCT:
BRepTools_Modifier+BRepTools_NurbsConvertModificationviaOCCTBRepToolsModifierNurbsConvert. - Note: Prefer
Shape.convertedToNURBS()for ordinary NURBS conversion; use this variant only when you need the bare modifier pipeline directly (e.g. composing it with otherBRepTools_Modificationpasses) and will apply your own vertex-tolerance correction afterward.
ShapeCustom_Direct / TrsfModification
directModification()
Orient face normals outward using ShapeCustom_DirectModification.
public func directModification() -> Shape?
- Returns: Shape with consistently outward-oriented face normals, or
nilon failure. - OCCT:
ShapeCustom_DirectModificationviaOCCTShapeCustomDirectModification.
trsfModificationScale(_:)
Apply a uniform scale with proper tolerance handling via ShapeCustom_TrsfModification.
public func trsfModificationScale(_ scaleFactor: Double) -> Shape?
Unlike the basic scaled(by:) transform, this propagates tolerance updates correctly through the topology.
- Parameters:
scaleFactor, uniform scale factor. - Returns: Scaled shape, or
nilon failure. - OCCT:
ShapeCustom_TrsfModificationviaOCCTShapeCustomTrsfModificationScale.
LocOpe Builders
buildWires(faceIndex:)
Build wires from the edges of one face, or of the whole shape.
public func buildWires(faceIndex: Int32 = -1) -> [Shape]?
- Parameters:
faceIndex, 0-based face index, asFace.indexandface(at:)use. Any negative value means every edge of the shape. - Returns: Array of wire shapes, or
nilon failure. - Example:
let box = Shape.box(origin: .zero, width: 10, height: 10, depth: 10)! let allEdges = box.buildWires(faceIndex: -1)! // every edge of the box let firstFace = box.buildWires(faceIndex: 0)! // just face 0's edges - Note: #541 moved this off 1-based and moved the “all edges” sentinel from
0, which collided with the first face’s own index and left that face unaddressable. - OCCT:
LocOpe_BuildWiresviaOCCTLocOpeBuildWires.
splitByWireOnFace(_:faceIndex:)
Split a face of this shape by projecting a wire onto it.
public func splitByWireOnFace(_ wire: Shape, faceIndex: Int32) -> Shape?
- Parameters:
wire, the splitting wire shape;faceIndex, 0-based index of the face to split, asFace.indexandface(at:)use. It was 1-based until #541, so face 0 could not be named at all and the accepted domain was1...faceCountrather than0..<faceCount. - Returns: Modified shape with the face split, or
nilon failure. - OCCT:
LocOpe_WiresOnShape+LocOpe_SpliterviaOCCTLocOpeSplitByWireOnFace. - Note: Only the first wire of
wireis used. Passing a shape that holds several wires splits by one of them and silently ignores the rest; call once per wire. (#443 audit)
curveShapeIntersect(origin:direction:)
Intersect a line with this shape and return parameter values on the line.
public func curveShapeIntersect(
origin: SIMD3<Double>,
direction: SIMD3<Double>
) -> [Double]?
- Parameters:
origin, line origin;direction, line direction. - Returns: Array of parameter values where the line intersects the shape, or
nilon failure. - OCCT:
LocOpe_CurveShapeIntersectorviaOCCTLocOpeCurveShapeIntersectLine. - Note: Parameters only, the point/face each hit’s
LocOpe_PntFacealso carries is never read. For the 3D point, the face struck, or curve input, seeShapeRayIntersection(BRepIntCurveSurface_Inter), a separate, richer intersector added independently and not a drop-in replacement (#852).
CPnts_UniformDeflection
DeflectionResult
Discretization result with parameters and 3D points.
public struct DeflectionResult: Sendable {
public let parameters: [Double]
public let points: [SIMD3<Double>]
}
uniformDeflection(_:)
Discretize an edge by uniform deflection over its full parameter range.
public func uniformDeflection(_ deflection: Double) -> DeflectionResult?
- Parameters:
deflection, maximum chord deflection. - Returns:
DeflectionResult, ornilon failure. - OCCT:
CPnts_UniformDeflectionviaOCCTCPntsUniformDeflection. NotGCPnts_UniformDeflection, which this repo also wraps, behindCurve3D.drawDeflectionandCurve2D.drawDeflection. - Example:
if let d = edge.uniformDeflection(0.1) { // d.points, evenly deflection-spaced 3D samples }
uniformDeflection(_:range:)
Discretize an edge by uniform deflection within a parameter range.
public func uniformDeflection(_ deflection: Double, range: ClosedRange<Double>) -> DeflectionResult?
- Parameters:
deflection, maximum chord deflection;range, parameter range to sample. - Returns:
DeflectionResult, ornilon failure. - OCCT:
CPnts_UniformDeflectionwith an explicit(U1, U2)range viaOCCTCPntsUniformDeflectionRange.
IntCurvesFace_ShapeIntersector
RayIntersection
Ray-shape intersection result.
public struct RayIntersection: Sendable {
public let point: SIMD3<Double>
public let parameter: Double
}
- Fields:
point, 3D hit point;parameter, parameter on the ray.
rayIntersect(origin:direction:)
Intersect a ray with all faces of this shape.
public func rayIntersect(
origin: SIMD3<Double>,
direction: SIMD3<Double>
) -> [RayIntersection]?
- Parameters:
origin, ray origin;direction, ray direction. - Returns: Array of intersections sorted by parameter, or
nilon failure (empty shape, no triangulation, etc.). - OCCT:
IntCurvesFace_ShapeIntersectorviaOCCTIntCurvesFaceShapeIntersect. - Example:
if let hits = solid.rayIntersect(origin: SIMD3(0, 0, -10), direction: SIMD3(0, 0, 1)) { let entry = hits.first }
rayIntersectNearest(origin:direction:)
Find the nearest intersection of a ray with this shape.
public func rayIntersectNearest(
origin: SIMD3<Double>,
direction: SIMD3<Double>
) -> RayIntersection?
- Parameters:
origin, ray origin;direction, ray direction. - Returns: Nearest
RayIntersection, ornilif no intersection is found. - OCCT:
IntCurvesFace_ShapeIntersector(nearest) viaOCCTIntCurvesFaceShapeIntersectNearest.
GeomLProp_CLProps / SLProps
These types are declared at module scope (not nested in Shape), then used via Shape methods.
CurveLocalProperties
Local curve properties at a parameter point.
public struct CurveLocalProperties: Sendable {
public let point: SIMD3<Double>
public let tangent: SIMD3<Double>?
public let normal: SIMD3<Double>?
public let centerOfCurvature: SIMD3<Double>?
public let curvature: Double
}
tangentandnormalarenilat inflection or degenerate points;centerOfCurvatureisnilwhen curvature ≈ 0.
SurfaceLocalProperties
Local surface properties at a (U,V) parameter point.
public struct SurfaceLocalProperties: Sendable {
public let point: SIMD3<Double>
public let normal: SIMD3<Double>?
public let tangentU: SIMD3<Double>?
public let tangentV: SIMD3<Double>?
public let maxCurvature: Double
public let minCurvature: Double
public let meanCurvature: Double
public let gaussianCurvature: Double
public let curvatureDefined: Bool
public let isUmbilic: Bool
}
SurfaceLocalProperties.point
The 3D point on the surface at the evaluated (U,V) parameter.
SurfaceLocalProperties.normal
Unit surface normal at the parameter point, or nil where the normal is undefined (e.g. a singular point such as a cone’s apex or a sphere’s pole).
SurfaceLocalProperties.tangentU
Unit tangent vector along the surface’s U parametric direction, or nil where the first U-derivative is degenerate.
SurfaceLocalProperties.tangentV
Unit tangent vector along the surface’s V parametric direction, or nil where the first V-derivative is degenerate.
SurfaceLocalProperties.maxCurvature
The larger of the two principal curvatures at the point (GeomLProp_SLProps::MaxCurvature()). 0 and meaningless unless curvatureDefined is true.
SurfaceLocalProperties.minCurvature
The smaller of the two principal curvatures at the point (GeomLProp_SLProps::MinCurvature()). 0 and meaningless unless curvatureDefined is true.
SurfaceLocalProperties.meanCurvature
The mean curvature: the average of maxCurvature and minCurvature.
SurfaceLocalProperties.gaussianCurvature
The Gaussian curvature: the product of maxCurvature and minCurvature.
SurfaceLocalProperties.curvatureDefined
Whether maxCurvature, minCurvature, meanCurvature, and gaussianCurvature mean anything.
They are all 0 where curvature is undefined (a cone’s apex, a sphere’s pole, any point with no defined normal), which is indistinguishable from a genuinely flat point without this flag.
SurfaceLocalProperties.isUmbilic
Whether the point is umbilic: the two principal curvatures are equal, so the surface curves identically in every tangent direction. Every point of a sphere or a plane is umbilic; a generic point on a cylinder is not.
curveLocalProps(at:)
Compute curve local properties at a parameter on an edge shape.
public func curveLocalProps(at param: Double) -> CurveLocalProperties
- Parameters:
param, curve parameter. - Returns:
CurveLocalPropertiesat the given parameter. - OCCT:
GeomLProp_CLPropsviaOCCTGeomLPropCLProps. - Example:
let props = edge.curveLocalProps(at: 0.5) if let t = props.tangent { print(t) }
surfaceLocalProps(u:v:)
Compute surface local properties at (U,V) on a face shape.
public func surfaceLocalProps(u: Double, v: Double) -> SurfaceLocalProperties
- Parameters:
u,v, surface parameters. - Returns:
SurfaceLocalPropertiesat the given parameter point. - OCCT:
GeomLProp_SLPropsviaOCCTGeomLPropSLProps. - Example:
let props = face.surfaceLocalProps(u: 0.0, v: 0.0) print(props.gaussianCurvature)
BRepOffset_SimpleOffset
simpleOffsetShape(distance:tolerance:)
Create a simple surface offset of this shape.
public func simpleOffsetShape(distance: Double, tolerance: Double = 1e-3) -> Shape?
- Parameters:
distance, offset distance;tolerance, geometric tolerance. - Returns: Offset shape, or
nilon failure. - OCCT:
BRepOffset_SimpleOffsetviaOCCTBRepOffsetSimpleOffset.
Approx_CurvilinearParameter
curvilinearParameter(tolerance:maxDegree:maxSegments:)
Reparameterize an edge curve by arc length, returning a BSpline edge.
public func curvilinearParameter(tolerance: Double = 1e-3, maxDegree: Int = 8, maxSegments: Int = 50) -> Shape?
- Parameters:
tolerance, approximation tolerance;maxDegree, max BSpline degree;maxSegments, max segment count. - Returns: Edge with arc-length parameterization, or
nilon failure. - OCCT:
Approx_CurvilinearParameterviaOCCTApproxCurvilinearParameter.
GeomInt_IntSS
SurfaceIntersectionResult
Surface-surface intersection result (reference-counted class).
public class SurfaceIntersectionResult {
public var curveCount: Int { get }
public func curve(_ index: Int) -> Shape?
public var pointCount: Int { get }
public func point(_ index: Int) -> SIMD3<Double>
}
- Members:
curveCount, number of intersection curves;curve(_:), 1-based curve retrieval as an edge shape;pointCount, number of isolated points;point(_:), 1-based point retrieval. - OCCT:
GeomInt_IntSSviaOCCTGeomIntSS*.
SurfaceIntersectionResult.curveCount
Shape.surfaceSurfaceIntersection(face1:face2:tolerance:)
Compute the surface-surface intersection between two face shapes.
public static func surfaceSurfaceIntersection(face1: Shape, face2: Shape, tolerance: Double = 1e-6) -> SurfaceIntersectionResult?
- Parameters:
face1,face2, face shapes;tolerance, intersection tolerance. - Returns:
SurfaceIntersectionResult, ornilif no intersection or construction fails. - OCCT:
GeomInt_IntSSviaOCCTGeomIntSSCreate. - Example:
if let r = Shape.surfaceSurfaceIntersection(face1: f1, face2: f2) { for i in 1...r.curveCount { let curve = r.curve(i) } }
Contap_Contour
ContourLineType
Contour line type from Contap_Contour analysis.
public enum ContourLineType: Int32, Sendable {
case line = 0
case circle = 1
case walking = 2
case restriction = 3
}
| case | meaning |
|---|---|
.line | The contour line is a straight line. |
.circle | The contour line is a circular arc. |
.walking | The contour line was computed by point-by-point walking (no analytic form found). |
.restriction | The contour line lies on a face boundary (restriction curve). |
(Per-case anchors below, for cross-reference; the table above has the actual meaning of each.)
restriction
ContapContourResult
Contour computation result (reference-counted class).
public class ContapContourResult {
public var lineCount: Int { get }
public func lineType(_ line: Int) -> ContourLineType?
public func geometry(line: Int) -> ContourGeometry?
public func pointCount(line: Int) -> Int
public func point(line: Int, index: Int) -> SIMD3<Double>
public func points(line: Int) -> [SIMD3<Double>]
public func arcRange(line: Int) -> ClosedRange<Double>?
public func arcPoint(line: Int, parameter: Double) -> SIMD2<Double>?
public func vertexCount(line: Int) -> Int
public func vertex(line: Int, index: Int) -> ContourVertex?
public func vertices(line: Int) -> [ContourVertex]
}
- All indices are 1-based.
- OCCT:
Contap_ContourviaOCCTContapContour*.
pointCount, point and points answer for .walking lines only. Contap_Line::NbPnts() and Contap_Line::Point(Index) both open with if (typL != Contap_Walking) { throw Standard_DomainError(); } (Contap_Line.lxx), so on a .line, .circle or .restriction contour pointCount is 0, points is [], and point(line:index:) returns SIMD3(0, 0, 0), a zero rather than a measurement. Check lineType(_:) first.
That is not an edge case: a cylinder’s lateral face viewed along (1, 0, 0) gives two .line contours, and neither has a reachable point.
Added in #1635: geometry(line:) reads the type first and returns the accessor that applies, so an analytic contour has geometry. vertexCount/vertex/vertices are Contap_Line::NbVertex()/Vertex(Index), which are valid on every type, and arcRange/arcPoint evaluate a .restriction contour’s boundary arc. Measured across all four types in Scripts/repro/1635-contap-analytic-geometry/.
ContourGeometry
The geometry of one contour line, in whichever form Contap_Line holds it.
public enum ContourGeometry: Sendable {
case line(origin: SIMD3<Double>, direction: SIMD3<Double>)
case circle(
center: SIMD3<Double>, axis: SIMD3<Double>, xDirection: SIMD3<Double>, radius: Double)
case walking(points: [SIMD3<Double>])
case restriction(parameterRange: ClosedRange<Double>)
}
| case | OCCT accessor | what it is |
|---|---|---|
.line | Contap_Line::Line() | a tangent ruling, as an infinite gp_Lin; the stretch on the face is delimited by the line’s vertices |
.circle | Contap_Line::Circle() | a silhouette circle, as a gp_Circ |
.walking | Contap_Line::Point(Index) | a numerically traced contour, in 3D |
.restriction | Contap_Line::Arc() | a stretch of the face’s own boundary, as the arc’s parameter range |
ContourVertex
A vertex on a contour line (Contap_Point). Unlike the traced points, vertices exist on every contour type: a cylinder’s tangent ruling has two, where it meets the face’s boundary.
public struct ContourVertex: Sendable {
public let point: SIMD3<Double>
public let uv: SIMD2<Double>
public let parameterOnLine: Double
public let parameterOnArc: Double?
public let isFaceVertex: Bool
public let isMultiple: Bool
public let isInternal: Bool
}
point:Contap_Point::Value().uv:Contap_Point::Parameters(), in the face’s UV space.parameterOnLine:Contap_Point::ParameterOnLine().parameterOnArc:Contap_Point::ParameterOnArc(), ornilwhen the vertex sits on no arc.nilrather than zero, becauseParameterOnArc()throwsStandard_DomainErrorwhenIsOnArc()is false and zero is a valid parameter.isFaceVertex:Contap_Point::IsVertex(), the point is a vertex of the original face.isMultiple:Contap_Point::IsMultiple(), the point belongs to several contour lines.isInternal:Contap_Point::IsInternal(), the contour is tangent to the restriction here.
ContapContourResult.geometry(line:)
The geometry of a contour line (1-based index), in whichever form Contap_Line holds it.
public func geometry(line: Int) -> ContourGeometry?
- Returns: the geometry, or
nilwhen the index is out of range or the contour failed. - OCCT:
Contap_Line::TypeContour(), thenLine(),Circle(),Point(Index)orArc(). - Example:
// A cylinder's lateral face, viewed across its axis: two tangent rulings. if let contour = face.contapContourDirection(SIMD3(1, 0, 0)), contour.lineCount > 0 { for line in 1...contour.lineCount { switch contour.geometry(line: line) { case let .line(origin, direction): print("ruling through \(origin) along \(direction)") case let .circle(center, axis, _, radius): print("silhouette circle r=\(radius) at \(center) about \(axis)") case let .walking(points): print("traced contour, \(points.count) points") case let .restriction(range): print("boundary arc over \(range)") case nil: break } } }
ContapContourResult.arcRange(line:)
The parameter range of the face-boundary arc a .restriction contour follows.
public func arcRange(line: Int) -> ClosedRange<Double>?
- Returns: the range, or
nilwhen the line is not.restriction, the index is out of range, orContap_Line::Arc()is a null handle. - OCCT:
Contap_Line::Arc(), thenAdaptor2d_Curve2d::FirstParameter/LastParameter.
ContapContourResult.arcPoint(line:parameter:)
A point on that arc, in the face’s UV space.
public func arcPoint(line: Int, parameter: Double) -> SIMD2<Double>?
- Parameters:
line, 1-based contour line index;parameter, a value fromarcRange(line:). - Returns: the UV point, or
nilon the same refusals asarcRange(line:). - OCCT:
Adaptor2d_Curve2d::Value. - Example:
if let range = contour.arcRange(line: 1), let uv = contour.arcPoint(line: 1, parameter: range.lowerBound) { print(uv) }
ContapContourResult.vertexCount(line:)
The number of vertices on a contour line (1-based index). Valid on every contour type, unlike pointCount(line:).
public func vertexCount(line: Int) -> Int
- OCCT:
Contap_Line::NbVertex().
ContapContourResult.vertex(line:index:)
A vertex on a contour line (1-based indices).
public func vertex(line: Int, index: Int) -> ContourVertex?
- Returns: the vertex, or
nilwhen either index is out of range. - OCCT:
Contap_Line::Vertex(Index).
ContapContourResult.vertices(line:)
Every vertex on a contour line (1-based line index).
public func vertices(line: Int) -> [ContourVertex]
- OCCT:
Contap_Line::NbVertex()andVertex(Index).
ContapContourResult.lineCount
The number of contour lines found by the analysis.
public var lineCount: Int { get }
- OCCT:
OCCTContapContourLineCount.
ContapContourResult.lineType(_:)
The type of a contour line (1-based index): an analytic .line or .circle, a numerically traced .walking line, or a .restriction line lying along the face’s own boundary.
public func lineType(_ line: Int) -> ContourLineType?
- Returns: The
ContourLineType, orniliflineis out of range. -
OCCT:
OCCTContapContourLineType. - All indices are 1-based.
- OCCT:
Contap_ContourviaOCCTContapContour*.
contapContourDirection(_:)
Compute contour lines on a face with an orthographic projection direction.
public func contapContourDirection(_ direction: SIMD3<Double>) -> ContapContourResult?
- Parameters:
direction, orthographic view direction. - Returns:
ContapContourResultif contours are found, ornilotherwise. - OCCT:
Contap_Contour(dir)viaOCCTContapContourDirection.
contapContourEye(_:)
Compute contour lines on a face with a perspective eye point.
public func contapContourEye(_ eye: SIMD3<Double>) -> ContapContourResult?
- Parameters:
eye, perspective eye point. - Returns:
ContapContourResultif contours are found, ornilotherwise. - OCCT:
Contap_Contour(eye)viaOCCTContapContourEye.
BRepFeat_Builder
featFuse(with:)
Feature-based fuse (union) of this shape with tool, via BRepFeat_Builder. Runs the full local-operation pipeline (Init → SetOperation → Perform → PerformResult), so the returned shape is the real geometric union, matching BRepAlgoAPI_Fuse on the same pair. For a plain fuse there is nothing to select, so unlike featCut(with:) the whole tool is always kept.
public func featFuse(with tool: Shape) -> Shape?
let box = Shape.box(origin: SIMD3(0, 0, 0), width: 10, height: 10, depth: 10)!
let sphere = Shape.sphere(center: SIMD3(5, 5, 10), radius: 5)!
let fused = box.featFuse(with: sphere)
print(fused?.volume ?? 0) // 1261.799388
- Parameters:
tool, the shape to fuse into this one. - Returns: The union shape, or
nilon failure. - OCCT:
BRepFeat_Builder(fuse mode) viaOCCTBRepFeatBuilderFuse.
featCut(with:)
Feature-based cut (subtraction) of tool from this shape, via BRepFeat_Builder. Runs the full local-operation pipeline (Init → SetOperation → Perform → PerformResult) and keeps no parts of the split tool, so the returned shape is the real geometric difference, matching BRepAlgoAPI_Cut on the same pair.
public func featCut(with tool: Shape) -> Shape?
let box = Shape.box(origin: SIMD3(0, 0, 0), width: 10, height: 10, depth: 10)!
let sphere = Shape.sphere(center: SIMD3(5, 5, 10), radius: 5)!
let cut = box.featCut(with: sphere)
print(cut?.volume ?? 0) // 738.200612
- Parameters:
tool, the shape to subtract from this one. - Returns: The difference shape, or
nilon failure. - OCCT:
BRepFeat_Builder(cut mode) viaOCCTBRepFeatBuilderCut.
GeomFill Trihedron Laws / Coons / Curved / CoonsAlgPatch
TrihedronFrame
Tangent, normal, binormal frame at a curve parameter.
public struct TrihedronFrame: Sendable {
public let tangent: SIMD3<Double>
public let normal: SIMD3<Double>
public let binormal: SIMD3<Double>
}
- Fields:
tangent, unit tangent vector;normal, unit normal vector;binormal, unit binormal vector (tangent × normal).
binormal
draftTrihedron(at:biNormal:angle:)
Evaluate a draft trihedron frame on an edge at a parameter.
public func draftTrihedron(at param: Double, biNormal: SIMD3<Double>, angle: Double) -> TrihedronFrame?
- Parameters:
param, curve parameter;biNormal, fixed bi-normal direction;angle, draft angle in radians. - Returns:
TrihedronFrame, ornilif the tangent is degenerate. - OCCT:
GeomFill_DraftTrihedronviaOCCTGeomFillDraftTrihedron.
discreteTrihedron(at:)
Evaluate a discrete trihedron frame on an edge at a parameter.
public func discreteTrihedron(at param: Double) -> TrihedronFrame?
- Parameters:
param, curve parameter. - Returns:
TrihedronFrame, ornilif the tangent is degenerate. - OCCT:
GeomFill_DiscreteTrihedronviaOCCTGeomFillDiscreteTrihedron.
correctedFrenet(at:)
Evaluate a corrected Frenet frame on an edge at a parameter.
public func correctedFrenet(at param: Double) -> TrihedronFrame?
- Parameters:
param, curve parameter. - Returns:
TrihedronFrame, ornilif the tangent is degenerate. - OCCT:
GeomFill_CorrectedFrenetviaOCCTGeomFillCorrectedFrenet.
FillingPoleGrid
Pole grid result from GeomFill_Coons or GeomFill_Curved.
public struct FillingPoleGrid: Sendable {
public let poles: [SIMD3<Double>]
public let nbU: Int
public let nbV: Int
}
- Fields:
poles, control points in row-major (U-major) order;nbU,nbV, grid dimensions.
FillingPoleGrid.poles
Control points of the fitted patch, flattened in row-major (U-major) order: nbU * nbV points total.
public let poles: [SIMD3<Double>]
FillingPoleGrid.nbU
Number of control points along the U direction of the grid.
public let nbU: Int
FillingPoleGrid.nbV
Number of control points along the V direction of the grid.
public let nbV: Int
Shape.coonsFilling(boundary1:boundary2:boundary3:boundary4:)
Compute a Coons filling pole grid from four boundary point arrays.
public static func coonsFilling(
boundary1: [SIMD3<Double>], boundary2: [SIMD3<Double>],
boundary3: [SIMD3<Double>], boundary4: [SIMD3<Double>]
) -> FillingPoleGrid?
All four boundary arrays must have the same length (≥ 2). The result is a BSpline control-point grid, not a Shape, use Surface.bspline(...) to construct a surface from it.
- Parameters:
boundary1–boundary4, point arrays for the four boundaries of the patch. - Returns:
FillingPoleGrid, ornilif sizes are mismatched or computation fails. - OCCT:
GeomFill_CoonsviaOCCTGeomFillCoonsPoles.
Shape.curvedFilling(boundary1:boundary2:boundary3:boundary4:)
Compute a curved filling pole grid from four boundary point arrays.
public static func curvedFilling(
boundary1: [SIMD3<Double>], boundary2: [SIMD3<Double>],
boundary3: [SIMD3<Double>], boundary4: [SIMD3<Double>]
) -> FillingPoleGrid?
Similar to coonsFilling but uses GeomFill_Curved which preserves surface curvature better for curved boundaries.
- Parameters:
boundary1–boundary4, point arrays for the four boundaries. - Returns:
FillingPoleGrid, ornilon failure. - OCCT:
GeomFill_CurvedviaOCCTGeomFillCurvedPoles.
Shape.coonsAlgPatch(edge1:edge2:edge3:edge4:evalU:evalV:)
Evaluate a Coons algorithmic patch from four boundary edges at a UV grid.
public static func coonsAlgPatch(
edge1: Shape, edge2: Shape, edge3: Shape, edge4: Shape,
evalU: Int = 10, evalV: Int = 10
) -> [SIMD3<Double>]?
Returns evaluated 3D points over a evalU × evalV parameter grid. Indices in the result are in row-major order (U-major).
- Parameters:
edge1–edge4, boundary edge shapes;evalU,evalV, sampling count in each direction. - Returns: Flat array of
evalU × evalV3D points, ornilif all points are degenerate. - OCCT:
GeomFill_CoonsAlgPatchviaOCCTGeomFillCoonsAlgPatchEval. - Example:
if let pts = Shape.coonsAlgPatch(edge1: e1, edge2: e2, edge3: e3, edge4: e4, evalU: 5, evalV: 5) { // pts.count == 25 }