Shape. Advanced Sweeps & API Completions
This page documents the advanced sweep, fill, proximity, and B-Rep query members of Shape from the v0.79.0–v0.128.0 range. For the primary Shape type overview, constructors, and boolean/transform/topology operations see the main Shape page (forthcoming as Shape.md).
Topics
- CoherentTriangulation · BRepFill_Evolved · BRepFill_OffsetAncestors · BRepExtrema_DistanceSS · BRepGProp_VinertGK · GeomFill_Profiler · GeomFill_Stretch · GeomFill_LocationDraft · GeomFill_GuideTrihedronAC · GeomFill_GuideTrihedronPlan · GeomFill_SectionPlacement · BRepFill_NSections · GeomFill_AppSurf · ShapeFix_ComposeShell · Transform, Boolean & Shape Query expansions (v0.115.0) · ThruSections builder · ShapeFixer builder · BRep_Tool completions v0.126.0 · Section with plane/surface & polygon queries v0.127.0 · BRep_Tool completions v0.128.0
CoherentTriangulation
Mutable coherent triangulation for mesh editing operations, wrapping Poly_CoherentTriangulation.
CoherentTriangulation.create()
Creates an empty coherent triangulation.
public static func create() -> CoherentTriangulation
- Returns: A new empty
CoherentTriangulation. - OCCT:
Poly_CoherentTriangulation(default constructor). - Example:
let ct = CoherentTriangulation.create()
CoherentTriangulation.createFromMesh(_:deflection:)
Creates a coherent triangulation from the triangulation of the first face of a meshed shape.
public static func createFromMesh(_ shape: Shape, deflection: Double = 0.1) -> CoherentTriangulation?
- Parameters:
shape, aShapethat has already been meshed.deflection, linear deflection used for auto-triangulation if the shape is not yet meshed; default0.1. - Returns: A
CoherentTriangulationpopulated from the face’s triangulation, ornilif the shape has no triangulation. - OCCT:
Poly_CoherentTriangulation,BRep_Tool::Triangulation. - Example:
let box = Shape.box(width: 10, height: 10, depth: 10)! if let ct = CoherentTriangulation.createFromMesh(box) { print(ct.triangleCount) }
setNode(x:y:z:)
Adds a node at the given coordinates.
public func setNode(x: Double, y: Double, z: Double) -> Int
- Returns: The 0-based index of the newly created node.
- OCCT:
Poly_CoherentTriangulation::SetNode. - Example:
let ct = CoherentTriangulation.create() let i0 = ct.setNode(x: 0, y: 0, z: 0)
addTriangle(_:_:_:)
Adds a triangle from three 0-based node indices.
@discardableResult
public func addTriangle(_ n0: Int, _ n1: Int, _ n2: Int) -> Bool
- Returns:
trueon success. - OCCT:
Poly_CoherentTriangulation::AddTriangle. - Example:
let ok = ct.addTriangle(0, 1, 2)
removeTriangle(at:)
Removes a triangle by its 0-based index.
@discardableResult
public func removeTriangle(at index: Int) -> Bool
- Returns:
trueon success. - OCCT:
Poly_CoherentTriangulation::RemoveTriangle.
triangleCount
Number of triangles in the coherent triangulation.
public var triangleCount: Int { get }
- OCCT:
Poly_CoherentTriangulation::NTriangles.
computeLinks()
Computes edge links between adjacent triangles.
public func computeLinks() -> Int
- Returns: The number of links computed.
- OCCT:
Poly_CoherentTriangulation::ComputeLinks.
linkCount
Number of edge links. Call computeLinks() first.
public var linkCount: Int { get }
- OCCT:
Poly_CoherentTriangulation::NLinks.
setDeflection(_:)
Sets the deflection value on the triangulation.
public func setDeflection(_ value: Double)
- OCCT:
Poly_CoherentTriangulation::SetDeflection.
deflection
The current deflection value of the triangulation.
public var deflection: Double { get }
- OCCT:
Poly_CoherentTriangulation::Deflection.
removeDegenerated(tolerance:)
Removes degenerated triangles whose area is below the given tolerance.
@discardableResult
public func removeDegenerated(tolerance: Double) -> Bool
- Returns:
trueif any degenerated triangles were removed. - OCCT:
Poly_CoherentTriangulation::RemoveDegenerated.
getResult()
Converts the coherent triangulation back to standard node/triangle counts.
public func getResult() -> (nodeCount: Int, triangleCount: Int)?
- Returns: A tuple of
(nodeCount, triangleCount), ornilon failure. - OCCT:
Poly_CoherentTriangulation.
nodeCoords(at:)
Gets the coordinates of a node by its 1-based index (after calling getResult()).
public func nodeCoords(at index: Int) -> (x: Double, y: Double, z: Double)?
- Returns: The
(x, y, z)coordinates of the node, ornilif the index is out of range. - OCCT:
Poly_CoherentTriangulation.
BRepFill_Evolved
Shape.evolved(spineFace:profileWire:axisOrigin:axisNormal:axisXDir:joinType:makeSolid:)
Creates an evolved shape by sweeping a 2D wire profile along the boundary of a planar face.
public static func evolved(spineFace: Shape, profileWire: Shape,
axisOrigin: SIMD3<Double> = SIMD3(0, 0, 0),
axisNormal: SIMD3<Double> = SIMD3(0, 0, 1),
axisXDir: SIMD3<Double> = SIMD3(1, 0, 0),
joinType: Int = 0, makeSolid: Bool = false) -> Shape?
- Parameters:
spineFace: planar face whose boundary edges define the sweep path.profileWire: 2D wire cross-section to sweep.axisOrigin,axisNormal,axisXDir, coordinate system of the profile plane; defaults to the XY plane at the origin.joinType: join strategy between adjacent sweep segments:0=Arc (round),1=Tangent,2=Intersection.makeSolid:trueto cap the result into a solid.
- Returns: The evolved
Shape, ornilif the operation fails. - OCCT:
BRepFill_Evolved. - Example:
let face = Shape.box(width: 20, height: 10, depth: 1)! let profile = Shape.fromWire(Wire.rectangle(width: 2, height: 2)!)! if let evo = Shape.evolved(spineFace: face, profileWire: profile) { print(evo.isValid) }
BRepFill_OffsetAncestors
Traces the ancestry of edges in an offset wire back to the original face edges. Wraps BRepFill_OffsetAncestors.
| Member | Kind | Meaning |
|---|---|---|
handle | internal stored property | The opaque OCCTOffsetAncestorsRef this wrapper owns; released in deinit. |
OffsetAncestors.create(face:offset:joinType:)
Creates an offset-ancestors tracker for a face offset by the given distance.
public static func create(face: Shape, offset: Double, joinType: Int = 0) -> OffsetAncestors?
- Parameters:
face: the source face.offset: signed offset distance.joinType:0=Arc,1=Tangent,2=Intersection.
- Returns: An
OffsetAncestorsinstance, ornilif the operation fails. - OCCT:
BRepFill_OffsetAncestors.
isDone
Whether the offset and ancestry computation succeeded.
public var isDone: Bool { get }
- OCCT:
BRepFill_OffsetAncestors::IsDone.
hasAncestor(_:)
Checks if an offset edge has a recorded ancestor.
public func hasAncestor(_ edge: Shape) -> Bool
- OCCT:
BRepFill_OffsetAncestors::HasAncestor.
ancestor(of:)
Returns the original edge that gave rise to the given offset edge.
public func ancestor(of edge: Shape) -> Shape?
- Returns: The ancestor
Shape, ornilif the edge has no recorded ancestor. - OCCT:
BRepFill_OffsetAncestors::Ancestor. - Example:
if let oa = OffsetAncestors.create(face: myFace, offset: 2.0), oa.isDone { for edge in offsetWireEdges { if let orig = oa.ancestor(of: edge) { print("traced") } } }
BRepExtrema_DistanceSS
distanceSS(to:deflection:)
Computes the minimum distance between two sub-shapes.
public func distanceSS(to other: Shape, deflection: Double = 1e-7) -> DistanceSSResult
- Parameters:
other: the second shape.deflection: maximum deviation of an extreme distance from the true minimum for it to be folded into the solution set (BRepExtrema_DistanceSS’stheDeflection). A numeric-tie tolerance, not a spatial search radius: raising it does not sample more finely, it widens how many near-minimum extrema get reported as “solutions” alongside the true one, and.point1/.point2are the first-appended solution, not guaranteed to be the minimal one. Default1e-7(Precision::Confusion()), OCCT’s own default (#1544).
- Returns: A
DistanceSSResultcontaining.distance,.point1,.point2,.solutionCount, and.isDone. - OCCT:
BRepExtrema_DistanceSS. - Example:
let a = Shape.box(width: 5, height: 5, depth: 5)! let b = Shape.box(width: 5, height: 5, depth: 5)!.translated(by: SIMD3(10, 0, 0))! let r = a.distanceSS(to: b) if r.isDone { print(r.distance) }
DistanceSSResult
Result struct returned by distanceSS(to:deflection:).
public struct DistanceSSResult {
public let distance: Double
public let point1: SIMD3<Double>
public let point2: SIMD3<Double>
public let solutionCount: Int
public let isDone: Bool
}
BRepGProp_VinertGK
vinertGK(location:tolerance:computeCG:)
Computes volume inertia properties of a face using Gauss-Kronrod numerical integration.
public func vinertGK(location: SIMD3<Double> = SIMD3(0, 0, 0),
tolerance: Double = 0.001, computeCG: Bool = true) -> VinertGKResult
- Parameters:
location: the reference point for inertia computation; defaults to the origin.tolerance: relative integration error bound; default0.001.computeCG: whether to compute the centre of gravity; defaulttrue.
- Returns: A
VinertGKResultwith.mass,.errorReached, and an optional.center. - OCCT:
BRepGProp_VinertGK. - Note: This method operates on a face shape. The
.massfield is the signed volume contribution, and stays non-optional because a zero contribution is a real answer that a caller summing over a shell needs..centerisnilwhen the contribution is 0, and whencomputeCGwasfalse; both used to report (0,0,0), which is indistinguishable from a real centroid at the origin (#609)..errorReachedisBRepGProp_VinertGK::GetErrorReached(); it used to be hardcoded to0.0on every call (#732). It is not unconditionally relative: OCCT divides the raw quadrature residual by|.mass|only when|.mass|clears an internal, near-machine-epsilon floor, and returns the undivided residual as-is below it, a distinction the return value gives no way to tell apart. That second branch could not be pinned by a test through the public API (measured: the floor needs|.mass|to underflow to essentially bit-exact0.0, far below what floating-point cancellation reaches for a real integral, ~1e-14at best); see the doc comment onVinertGKResultinShape+Analysis.swiftfor the full investigation. There is no.absoluteError: OCCT declaresGetAbsolutError()on the same class but never defines it, so calling it fails to link, and deriving one from.errorReached * .masswould go wrong exactly in that same near-zero-mass branch, so the field was removed rather than kept as a second silent zero. - Example:
let box = Shape.box(width: 10, height: 10, depth: 10)! let face = Shape.fromFace(box.faces()[0])! let gi = face.vinertGK() print(gi.mass, gi.center as Any)
VinertGKResult
Result struct returned by vinertGK(location:tolerance:computeCG:).
public struct VinertGKResult {
public let mass: Double
public let errorReached: Double
public let center: SIMD3<Double>?
}
| Field | Meaning |
|---|---|
errorReached | Actual relative error the Gauss-Kronrod integration achieved, for comparison against the requested tolerance. |
Shape.VinertGKResult.errorReached
GeomFill_Profiler
CurveProfiler homogenizes a set of Curve3D values into a single compatible BSpline representation, which is a prerequisite for multi-section surface operations. Wraps GeomFill_Profiler.
| Member | Kind | Meaning |
|---|---|---|
handle | internal stored property | The opaque OCCTGeomFillProfilerRef this wrapper owns; released in deinit. |
CurveProfiler.create()
Creates a new, empty curve profiler.
public static func create() -> CurveProfiler
- OCCT:
GeomFill_Profiler.
addCurve(_:)
Adds a curve to the profiler.
public func addCurve(_ curve: Curve3D)
- Returns:
Void. Ifcurvewraps a nullGeom_Curvehandle, it is silently dropped instead of added (#710 defensive hardening; no publicCurve3Dfactory can produce that state today), and there is nocurveCount/isValidsignal at the call site itself. A drop only shows up indirectly: the profiler ends up holding one fewer curve than the caller believes it added, so acurveIndexpassed topoles(curveIndex:)that counted the dropped curve addresses the wrong curve (or is out of range and returns[]). - OCCT:
GeomFill_Profiler::AddCurve.
perform(tolerance:)
Performs the homogenization of all added curves.
@discardableResult
public func perform(tolerance: Double = 1e-6) -> Bool
- Returns:
trueon success. - OCCT:
GeomFill_Profiler::Perform.
degree
Degree of the resulting homogenized BSpline curves.
public var degree: Int { get }
- OCCT:
GeomFill_Profiler::Degree.
poleCount
Number of poles per homogenized curve.
public var poleCount: Int { get }
- OCCT:
GeomFill_Profiler::NbPoles.
knotCount
Number of knots in the homogenized representation.
public var knotCount: Int { get }
- OCCT:
GeomFill_Profiler::NbKnots.
isPeriodic
Whether the homogenized curves are periodic.
public var isPeriodic: Bool { get }
- OCCT:
GeomFill_Profiler::IsPeriodic.
poles(curveIndex:)
Returns the poles for a specific curve (1-based index) after perform().
public func poles(curveIndex: Int) -> [SIMD3<Double>]
- Parameters:
curveIndex, 1-based index of the curve. - Returns: An array of 3D pole positions, or empty if not computed or index is out of range.
- OCCT:
GeomFill_Profiler::Poles.
knotsAndMults()
Returns the knot vector and multiplicities of the homogenized representation.
public func knotsAndMults() -> (knots: [Double], mults: [Int])
- Returns: A tuple of parallel arrays; empty arrays on failure or before
perform(). - OCCT:
GeomFill_Profiler::KnotsAndMults. - Example:
let profiler = CurveProfiler.create() profiler.addCurve(c1) profiler.addCurve(c2) if profiler.perform() { let (knots, mults) = profiler.knotsAndMults() print(knots) }
GeomFill_Stretch
Surface.stretchFill(p1:p2:p3:p4:)
Creates a BSpline surface by stretch-filling from four ordered boundary point arrays.
public static func stretchFill(p1: [SIMD3<Double>], p2: [SIMD3<Double>],
p3: [SIMD3<Double>], p4: [SIMD3<Double>]) -> StretchFillResult?
- Parameters:
p1–p4, four boundary polylines, all of equal length ≥ 2. The order is: bottom, right, top, left (or equivalent opposing boundary pairs). - Returns: A
StretchFillResultcontaining pole grid dimensions and the flat pole array, ornilif the arrays have mismatched lengths, are too short, or the algorithm fails. - OCCT:
GeomFill_Stretch. - Example:
let p1: [SIMD3<Double>] = [SIMD3(0,0,0), SIMD3(10,0,0)] let p2: [SIMD3<Double>] = [SIMD3(10,0,0), SIMD3(10,10,0)] let p3: [SIMD3<Double>] = [SIMD3(10,10,0), SIMD3(0,10,0)] let p4: [SIMD3<Double>] = [SIMD3(0,10,0), SIMD3(0,0,0)] if let r = Surface.stretchFill(p1: p1, p2: p2, p3: p3, p4: p4) { print(r.nbUPoles, r.nbVPoles) }
StretchFillResult
Result struct returned by Surface.stretchFill(p1:p2:p3:p4:).
public struct StretchFillResult {
public let nbUPoles: Int
public let nbVPoles: Int
public let isRational: Bool
public let poles: [SIMD3<Double>]
}
The poles array is laid out in row-major order: poles[i * nbVPoles + j] gives the pole at (i, j).
GeomFill_LocationDraft
LocationDraft implements a draft-angle location law for pipe/sweep operations. It positions a profile along a path while applying a specified taper angle. Wraps GeomFill_LocationDraft.
LocationDraft.create(direction:angle:)
Creates a draft location law with a draft direction and angle.
public static func create(direction: SIMD3<Double>, angle: Double) -> LocationDraft
- Parameters:
direction, the draft direction vector.angle, draft angle in radians. - OCCT:
GeomFill_LocationDraft.
setCurve(_:)
Sets the sweep path curve on the location law.
@discardableResult
public func setCurve(_ curve: Curve3D) -> Bool
- Returns:
trueon success. - OCCT:
GeomFill_LocationDraft::SetCurve.
evaluate(at:)
Evaluates the location frame (rotation matrix + translation) at a path parameter.
public func evaluate(at param: Double) -> (matrix: [Double], translation: SIMD3<Double>)?
- Returns: A tuple where
matrixis a flat 9-element row-major 3×3 rotation matrix andtranslationis the origin offset, ornilon failure. - OCCT:
GeomFill_LocationDraft::D0.
setAngle(_:)
Updates the draft angle (radians).
public func setAngle(_ angle: Double)
- OCCT:
GeomFill_LocationDraft::SetAngle.
direction
The current draft direction vector.
public var direction: SIMD3<Double> { get }
- OCCT:
GeomFill_LocationDraft::Direction. - Example:
let ld = LocationDraft.create(direction: SIMD3(0, 0, 1), angle: 0.1) ld.setCurve(spine) if let frame = ld.evaluate(at: 0.5) { print(frame.translation) }
GeomFill_GuideTrihedronAC
GuideTrihedronAC computes an arc-length-corrected Frenet-like trihedron along a sweep path guided by an auxiliary curve. Wraps GeomFill_GuideTrihedronAC.
GuideTrihedronAC.create(guideCurve:)
Creates a guide trihedron law using an arc-length correction guide.
public static func create(guideCurve: Curve3D) -> GuideTrihedronAC
- Parameters:
guideCurve, the guide curve that influences the trihedron orientation. - OCCT:
GeomFill_GuideTrihedronAC.
setCurve(_:) (GuideTrihedronAC)
Sets the sweep path curve.
@discardableResult
public func setCurve(_ curve: Curve3D) -> Bool
- Returns:
trueon success. - OCCT:
GeomFill_GuideTrihedronAC::SetCurve.
evaluate(at:) (GuideTrihedronAC)
Evaluates the trihedron frame at the given path parameter.
public func evaluate(at param: Double) -> (tangent: SIMD3<Double>, normal: SIMD3<Double>, binormal: SIMD3<Double>)?
- Returns: The tangent, normal, and binormal vectors at
param, ornilon failure. - OCCT:
GeomFill_GuideTrihedronAC::D0. - Example:
let gta = GuideTrihedronAC.create(guideCurve: guide) gta.setCurve(spine) if let frame = gta.evaluate(at: 0.0) { print(frame.tangent) }
GeomFill_GuideTrihedronPlan
GuideTrihedronPlan computes a planar guide trihedron for sweep operations, keeping the profile in planes normal to the guide. Wraps GeomFill_GuideTrihedronPlan.
| Member | Kind | Meaning |
|---|---|---|
handle | internal stored property | The opaque OCCTGuideTrihedronPlanRef this wrapper owns; released in deinit. |
GuideTrihedronPlan.create(guideCurve:)
Creates a planar guide trihedron law from a guide curve.
public static func create(guideCurve: Curve3D) -> GuideTrihedronPlan
- OCCT:
GeomFill_GuideTrihedronPlan.
setCurve(_:) (GuideTrihedronPlan)
Sets the sweep path curve.
@discardableResult
public func setCurve(_ curve: Curve3D) -> Bool
- Returns:
trueon success. - OCCT:
GeomFill_GuideTrihedronPlan::SetCurve.
evaluate(at:) (GuideTrihedronPlan)
Evaluates the trihedron frame at the given path parameter.
public func evaluate(at param: Double) -> (tangent: SIMD3<Double>, normal: SIMD3<Double>, binormal: SIMD3<Double>)?
- Returns: The tangent, normal, and binormal vectors at
param, ornilon failure. - OCCT:
GeomFill_GuideTrihedronPlan::D0.
GeomFill_SectionPlacement
Curve3D.sectionPlacement(section:direction:draftAngle:tolerance:)
Places a section curve optimally onto a path curve using a draft location law, returning the closest-approach parameters and geometry.
public func sectionPlacement(section: Curve3D,
direction: SIMD3<Double> = SIMD3(0, 0, 1),
draftAngle: Double = 0,
tolerance: Double = 1e-3) -> SectionPlacementResult
Called on the path curve (self).
- Parameters:
section: the profile curve to place.direction: draft direction; defaults to +Z.draftAngle: taper angle in radians; default0.tolerance: positional tolerance; default1e-3.
- Returns: A
SectionPlacementResult(always returned; check.isDone). - OCCT:
GeomFill_SectionPlacement. - Example:
let r = spine.sectionPlacement(section: profile) if r.isDone { print(r.parameterOnPath, r.distance) }
SectionPlacementResult
Result struct returned by sectionPlacement(section:direction:draftAngle:tolerance:).
public struct SectionPlacementResult {
public let parameterOnPath: Double
public let parameterOnSection: Double
public let distance: Double
public let angle: Double
public let isDone: Bool
}
| Field | Meaning |
|---|---|
parameterOnPath | Parameter on the sweep path where the section was placed. |
parameterOnSection | Parameter on the section curve itself corresponding to that placement point. |
distance | Distance between the path point and the section curve at the placement. |
angle | Draft angle actually achieved at the placement. |
isDone | true if GeomFill_SectionPlacement::Perform succeeded. |
(Per-field anchors below, for cross-reference; the table above has the actual meaning of each.)
parameterOnSection
BRepFill_NSections
NSections encodes an N-section law describing how a set of wire cross-sections varies along a sweep or loft. Wraps BRepFill_NSections.
NSections.create(wires:)
Creates an N-section law from an array of wire shapes.
public static func create(wires: [Shape]) -> NSections?
- Parameters:
wires, two or more wire shapes representing the cross-section sequence. - Returns: An
NSectionsinstance, ornilon failure. - OCCT:
BRepFill_NSections.
lawCount
Number of section laws (one per wire pair interval).
public var lawCount: Int { get }
- OCCT:
BRepFill_NSections::NbLaw.
isConstant
Whether the section is constant (all wires are identical).
public var isConstant: Bool { get }
- OCCT:
BRepFill_NSections::IsConstant.
isVertex
Whether the section degenerates to a point vertex.
public var isVertex: Bool { get }
- OCCT:
BRepFill_NSections::IsVertex. - Example:
if let ns = NSections.create(wires: [w1, w2, w3]) { print(ns.lawCount, ns.isConstant) }
GeomFill_AppSurf
Surface.appSurf(curves:degMin:degMax:tol3d:tol2d:)
Approximates a BSpline surface from a sequence of section curves.
public static func appSurf(curves: [Curve3D], degMin: Int = 3, degMax: Int = 8,
tol3d: Double = 1e-3, tol2d: Double = 1e-3) -> AppSurfResult?
- Parameters:
curves: ordered section curves to interpolate/approximate. Requires at least 2 (#644); fewer returnsnilinstead of crashing the underlyingGeomFill_AppSurfsolver, which is never driven with fewer than 2 sections anywhere in the kernel.degMin,degMax, minimum and maximum allowed BSpline degree.tol3d,tol2d, 3D and 2D fitting tolerances.
- Returns: An
AppSurfResulton success, ornilif the algorithm fails or fewer than 2 curves are given. - OCCT:
GeomFill_AppSurf. - Example:
if let r = Surface.appSurf(curves: [c1, c2, c3]) { print(r.uDegree, r.vDegree, r.nbUPoles, r.nbVPoles) }
AppSurfResult
Result struct returned by Surface.appSurf(curves:degMin:degMax:tol3d:tol2d:).
public struct AppSurfResult {
public let uDegree: Int
public let vDegree: Int
public let nbUPoles: Int
public let nbVPoles: Int
public let nbUKnots: Int
public let nbVKnots: Int
public let isDone: Bool
}
ShapeFix_ComposeShell
composeShell(precision:uPatches:vPatches:)
Splits a face along the joint lines of a composite surface, and rebuilds its wires.
public func composeShell(precision: Double = 1e-6,
uPatches: Int = 1,
vPatches: Int = 1) -> Shape?
The grid is the face’s own surface tiled uPatches x vPatches over the face’s UV box, as Geom_RectangularTrimmedSurface patches, so subdividing needs no extra caller input. ShapeFix_ComposeShell cuts along the joints between patches, which is why the defaults, a 1 x 1 grid, split nothing: one face goes in and one comes out. That was the only behaviour available until #1638, so the defaults preserve it exactly.
Measured (Scripts/repro/1638/transcript.txt), on a 10 x 10 planar face and on a cylinder’s lateral face:
| grid | planar face out | cylinder wall out |
|---|---|---|
| 1 x 1 | 1 | 1 |
| 2 x 1 | 2 | 2 |
| 1 x 2 | 2 | 2 |
| 3 x 2 | 6 |
Even at 1 x 1 the call does the wire rebuild: ShapeFix_ComposeShell re-splits and re-orders the face’s wires against the surface and returns them as a shell, which repairs seam and degenerate-edge ordering on a face whose boundary has drifted. To subdivide a whole shape rather than one face, dividedByNumber(_:) and dividedByArea(maxArea:) are the shape-level tools.
- Parameters:
precision, the toleranceShapeFix_ComposeShell::Initreceives;uPatchesandvPatches, the grid, each at least 1. - Returns: A
Shape, the composed shell, ornilif the receiver is not a face, carries no surface, a patch count is below 1, orPerform()fails. - OCCT:
ShapeFix_ComposeShellover aShapeExtend_CompositeSurfaceofGeom_RectangularTrimmedSurfacepatches, initialised withShapeExtend_Natural(viaOCCTShapeFixComposeShell). The bridge sets aShapeBuild_ReShapecontext beforePerform(), because 8.0.0p1 null-derefs without one. - Note:
ShapeExtend_Parametrisationis not a parameter. Because the patches are sub-ranges of the face’s own surface,ShapeExtend_Naturalreproduces the face’s own parametrisation exactly and the face’s pcurves line up with the composite’s global UV; the other two modes renumber the joints away from the pcurves the face already carries. - Example:
if let face = Shape.cylinder(radius: 5, height: 10)?.subShapes(ofType: .face).first, let quarters = face.composeShell(uPatches: 4) { print(quarters.subShapes(ofType: .face).count) // 4, quarter cylinders }
Transform, Boolean & Shape Query expansions (v0.115.0)
transformed(matrix:)
Applies a rigid transformation (rotation + translation) described by a Matrix12Grouped matrix (GROUPED layout, see Matrix12Grouped in Document-Analysis-Builders.md).
public func transformed(matrix: Matrix12Grouped) -> Shape?
- Returns: The transformed
Shape, ornilif the operation fails. - OCCT:
BRepBuilderAPI_Transform,gp_Trsf. - Example:
// Identity rotation, translate by (5, 0, 0) if let m = Matrix12Grouped([1,0,0, 0,1,0, 0,0,1, 5,0,0]), let moved = box.transformed(matrix: m) { print(moved.isValid) } - Deprecated overload:
transformed(matrix: [Double]) -> Shape?still exists (@available(*, deprecated)) for source compatibility,nilifmatrix.count != 12. #835 (PR #864 review): before this,transformed(matrix:),transformed(byMatrix:), andgTransformed(matrix:)all took a plain[Double]distinguished only by which method you called, so a caller could silently garble a transform by feeding one method’s array shape to another. Passing the wrong type is now a compile error.
gTransformed(matrix:)
Applies a general affine transformation (supports non-uniform scaling/shear) described by a TransformMatrix3D matrix (INTERLEAVED layout, see TransformMatrix3D in Document-Analysis-Builders.md).
public func gTransformed(matrix: TransformMatrix3D) -> Shape?
- Returns: The transformed
Shape, ornilif the operation fails. - OCCT:
BRepBuilderAPI_GTransform,gp_GTrsf. - Note: The layout convention differs from
transformed(matrix:)’sMatrix12Grouped, this method takes the same INTERLEAVED layout astransformed(byMatrix:)instead: each row is[r_i0, r_i1, r_i2, t_i]. - Deprecated overload:
gTransformed(matrix: [Double]) -> Shape?still exists (@available(*, deprecated)) for source compatibility,nilifmatrix.count != 12. See #835 above.
section(with:tolerance:)
Computes a boolean section with a fuzzy tolerance.
public func section(with other: Shape, tolerance: Double) -> Shape?
- Parameters:
other, the tool shape.tolerance, fuzzy coincidence tolerance. - Returns: A
Shapecontaining the intersection edges/wires, ornilon failure. - OCCT:
BRepAlgoAPI_Sectionwith fuzzy value.
split(tools:tolerance:)
Splits this shape by multiple tool shapes simultaneously.
public func split(tools: [Shape], tolerance: Double = 0) -> Shape?
- Parameters:
tools, array of splitting shapes.tolerance, fuzzy tolerance; default0. - Returns: The split compound
Shape, ornilon failure. - OCCT:
BRepAlgoAPI_Splitter.
BooleanHistoryResult
Result struct for boolean operations with change-history flags.
public struct BooleanHistoryResult: Sendable {
public let shape: Shape
public let hasDeleted: Bool
public let hasModified: Bool
public let hasGenerated: Bool
}
| Field | Meaning |
|---|---|
hasDeleted | true if the operation deleted at least one sub-shape from the input with no surviving descendant. |
hasGenerated | true if the operation generated at least one new sub-shape with no ancestor in the input. |
Shape.BooleanHistoryResult.hasGenerated
subtractedWithHistory(_:tolerance:)
Performs a boolean subtraction and returns change-history flags alongside the result shape.
public func subtractedWithHistory(_ tool: Shape, tolerance: Double = 0) -> BooleanHistoryResult?
- Returns: A
BooleanHistoryResult, ornilon failure. - OCCT:
BRepAlgoAPI_Cutwith history builder. - Example:
if let r = solid.subtractedWithHistory(hole) { print(r.hasModified, r.shape.isValid) }
defeature(faces:tolerance:), the overload whose tolerance parameter BRepAlgoAPI_Defeaturing::Build never read (it forwards the input shape, the faces, the history flag and the parallel flag to BOPAlgo_RemoveFeatures, and nothing else. BOPAlgo_Options’ inherited fuzzy value is stored and never read, as its own header states outright: “the other options of the base class are not supported here and will have no effect”; measured across tolerances from 1e-7 to 100 against a BRepAlgoAPI_Cut control in Scripts/repro/497-defeaturing-fuzzy-inert/, #497), was deprecated and removed at v2.0.0 (#784). Use defeature(faces:).
triangulationNodeCount
Number of triangulation nodes on a face.
public var triangulationNodeCount: Int32 { get }
- OCCT:
BRep_Tool::Triangulation→Poly_Triangulation::NbNodes.
triangulationTriangleCount
Number of triangles in the face triangulation.
public var triangulationTriangleCount: Int32 { get }
- OCCT:
Poly_Triangulation::NbTriangles.
triangulationDeflection
The deflection value stored on the face triangulation.
public var triangulationDeflection: Double { get }
- OCCT:
Poly_Triangulation::Deflection.
triangulationNode(at:)
Returns the 3D coordinates of a triangulation node by its 1-based index.
public func triangulationNode(at index: Int32) -> SIMD3<Double>
- OCCT:
Poly_Triangulation::Node.
triangulationTriangle(at:)
Returns the three 1-based node indices of a triangle by its 1-based index.
public func triangulationTriangle(at index: Int32) -> (Int32, Int32, Int32)
- OCCT:
Poly_Triangulation::Triangle.
triangulationHasNormals
Whether the face triangulation stores per-node normals.
public var triangulationHasNormals: Bool { get }
- OCCT:
Poly_Triangulation::HasNormals.
triangulationNormal(at:)
Returns the normal vector at a triangulation node by its 1-based index.
public func triangulationNormal(at index: Int32) -> SIMD3<Double>
- OCCT:
Poly_Triangulation::Normal.
triangulationHasUVNodes
Whether the face triangulation stores per-node UV coordinates.
public var triangulationHasUVNodes: Bool { get }
- OCCT:
Poly_Triangulation::HasUVNodes.
triangulationUVNode(at:)
Returns the UV coordinates of a triangulation node by its 1-based index.
public func triangulationUVNode(at index: Int32) -> SIMD2<Double>
- OCCT:
Poly_Triangulation::UVNode.
edgeParameterAtArcLength(_:from:)
Finds the curve parameter on this edge at the given arc length from a start parameter.
public func edgeParameterAtArcLength(_ arcLength: Double, from startParam: Double) -> Double
- OCCT: the accumulated
GeomAbs_CNsub-piece lengths, with the final narrow piece handed toGCPnts_AbscissaPoint. The edge is read through aBRepAdaptor_Curve, whose constructor dereferences a null shape, so a null shape (fromShape.nullified) used to crash the process here; it answers0now (#1035). - Note: Shares the subdivided measurement with
edgeArcLength, so the two agree on the same edge. OCCT’s own root finder inverts one Gauss quadrature over[startParam, u], which on an elliptical edge disagreed with an accurate length by up to 1% in arc (#603).
edgeArcLength
The total arc length of this edge.
public var edgeArcLength: Double { get }
A null shape (from Shape.nullified) used to crash the process in the BRepAdaptor_Curve constructor behind this measurement; it answers the -1.0 failure sentinel now (#1035, measured in Scripts/repro/1035-unwrap-guard/).
- Returns: Arc length in model units, or
-1.0on failure. Arc length is otherwise always non-negative, so this is an unambiguous sentinel; it used to be0, which a genuinely zero-length edge also measures (#548). - OCCT:
BRepAdaptor_Curve+GCPnts_AbscissaPoint::LengthperGeomAbs_CNinterval, subdivided until two successive levels agree to 1e-9 relative (#603). - Note: An elliptical edge measured 1.485% long before #603, one Gauss quadrature over the edge’s whole domain. A straight or circular edge is unaffected (closed form).
edgeArcLength(from:to:)
Computes the arc length of this edge between two parameter values.
public func edgeArcLength(from u1: Double, to u2: Double) -> Double
- Parameters:
u1/u2, parameter range, either order. Both must be finite. - Returns: Arc length in model units, or
-1.0if a bound is not finite or the computation fails. - OCCT:
GCPnts_AbscissaPoint::LengthperGeomAbs_CNinterval, subdivided to convergence, the same measurement asedgeArcLength(#603). - Note:
.nanand±.infinityare rejected before OCCT sees them. This entry point used to hand a NaN bound’s result straight back: on a straight edge that was NaN itself, and on a multi-span edge0(a NaN upper bound) or the edge’s whole length (a NaN lower one), seeCurve3D.length(from:to:)for the mechanism (#548). - Note: A range reaching outside the edge’s parameter domain measures the part of it that lies on the edge (a range wholly outside measures
0); a closed periodic edge covers a whole period and so measures the whole range, winding. Shared with theCurve3D/Curve2Dspellings, so an edge and the curve it was built from answer identically (#600). - Note: A null shape (from
Shape.nullified) used to crash the process in theBRepAdaptor_Curveconstructor behind the measurement; it answers-1.0now (#1035). - Example:
let edge = Shape.edgeFromPoints(SIMD3(0, 0, 0), SIMD3(10, 0, 0))! let d = edge.edgeAdaptorDomain let half = edge.edgeArcLength(from: d.lowerBound, to: (d.lowerBound + d.upperBound) / 2) // half == 5.0
edgeParameterAtFraction(_:)
Returns the curve parameter at a fractional position (0–1) along the total edge length.
public func edgeParameterAtFraction(_ fraction: Double) -> Double
- OCCT:
edgeArcLength’s subdivided total, then the same walkedgeParameterAtArcLengthmakes. A null shape (fromShape.nullified) used to crash the process in theBRepAdaptor_Curveconstructor behind both halves; it answers0now (#1035). - Note: Both halves were biased by the same single quadrature before #603, and the two errors cancelled; both are accurate now, so
edgeParameterAtFraction(1.0)still lands on the edge’s last parameter and0.5genuinely halves the arc (it split an elliptical edge 0.74% off centre).
edgeAdaptorDomain
The parameter domain [first, last] of the edge curve via BRepAdaptor_Curve.
public var edgeAdaptorDomain: ClosedRange<Double> { get }
- OCCT:
BRepAdaptor_Curve::FirstParameter,LastParameter. A null shape (fromShape.nullified) used to crash the process in that constructor; it answers0...0now (#1035).
edgeAdaptorValue(at:)
Evaluates the edge curve at a parameter, returning the 3D point.
public func edgeAdaptorValue(at param: Double) -> SIMD3<Double>
- OCCT:
BRepAdaptor_Curve::Value. A null shape (fromShape.nullified) used to crash the process in theBRepAdaptor_Curveconstructor; it answersSIMD3(0, 0, 0)now (#1035).
edgeAdaptorCurveType
The curve type of the edge as a GeomAbs_CurveType integer (0=Line, 1=Circle, etc.).
public var edgeAdaptorCurveType: Int32 { get }
- OCCT:
BRepAdaptor_Curve::GetType. A null shape (fromShape.nullified) used to crash the process in theBRepAdaptor_Curveconstructor; it answers-1now, the value this already returned when the type could not be read (#1035).
faceAdaptorBounds
The UV parameter bounds of a face surface via BRepAdaptor_Surface.
public var faceAdaptorBounds: (uMin: Double, uMax: Double, vMin: Double, vMax: Double) { get }
- OCCT:
BRepAdaptor_Surface::FirstUParameter,LastUParameter,FirstVParameter,LastVParameter.
faceAdaptorValue(u:v:)
Evaluates the face surface at (u, v), returning the 3D point.
public func faceAdaptorValue(u: Double, v: Double) -> SIMD3<Double>
- OCCT:
BRepAdaptor_Surface::Value.
faceAdaptorSurfaceType
The surface type of the face as a GeomAbs_SurfaceType integer (0=Plane, 1=Cylinder, etc.).
public var faceAdaptorSurfaceType: Int32 { get }
- OCCT:
BRepAdaptor_Surface::GetType.
obbVolume
Volume of the oriented bounding box (OBB) of this shape.
public var obbVolume: Double { get }
- OCCT:
Bnd_OBBviaBRepBndLib::AddOBB.
maxEdgeTolerance
Maximum tolerance across all edges in this shape.
public var maxEdgeTolerance: Double { get }
- OCCT:
ShapeAnalysis_ShapeTolerance::Tolerance(shape, 1, TopAbs_EDGE)(viaOCCTShapeMaxEdgeTolerance). NotBRep_Tool::MaxTolerance, which this entry also used to name and which the bridge does not call here; that one is wrapped separately asmaxTolerance(subShapeType:). (#808)
maxFaceTolerance
Maximum tolerance across all faces in this shape.
public var maxFaceTolerance: Double { get }
- OCCT:
ShapeAnalysis_ShapeTolerance.
maxVertexTolerance
Maximum tolerance across all vertices in this shape.
public var maxVertexTolerance: Double { get }
- OCCT:
ShapeAnalysis_ShapeTolerance.
hasFreeEdges
Whether this shape contains free (non-shared) edges.
public var hasFreeEdges: Bool { get }
- OCCT:
TopExp::MapShapesAndAncestors(shape, TopAbs_EDGE, TopAbs_FACE, map)into aTopTools_IndexedDataMapOfShapeListOfShape, then true as soon as one edge has fewer than two faces (viaOCCTShapeHasFreeEdges). NeitherShapeAnalysis_FreeBoundsnorBRepCheck_Analyzer, which this entry used to name and neither of which is called here. This is a pure incidence count, so unlikefreeBounds(sewingTolerance:)it applies no tolerance and chains nothing into wires. (#808)
hasFreeWires
Whether this shape contains free (non-shared) wires.
public var hasFreeWires: Bool { get }
- OCCT:
TopExp::MapShapesAndAncestors, reporting any child with no parent.
hasFreeFaces
Whether this shape contains free (non-shared) faces.
public var hasFreeFaces: Bool { get }
- OCCT:
TopExp::MapShapesAndAncestors, reporting any child with no parent.
boundingDiagonal
Length of the axis-aligned bounding box diagonal.
public var boundingDiagonal: Double { get }
- OCCT:
BRepBndLib::Add,Bnd_Box::CornerMin/CornerMax.
centroid
Volumetric centroid of this shape, or nil when the shape encloses no volume.
public var centroid: SIMD3<Double>? { get }
- Returns: The volume centroid, or
nilfor a face, wire, edge, vertex or open shell. - OCCT:
GProp_GPropsviaBRepGProp::VolumePropertieswithOnlyClosed = true, plus aMass()test. - Was non-optional before #609, and outside the volume domain it returned the shape’s location origin rather than a recognisable zero: a face moved to (100,200,300) reported exactly that, and moved again reported (200,400,600). No caller could defend itself with
if c == .zero. - See also:
surfaceInertiafor an area centroid,linearProperties()for a length centroid,vertices()for a vertex position.
totalEdgeLength
Sum of arc lengths of all edges in this shape.
public var totalEdgeLength: Double { get }
- OCCT:
BRepGProp::LinearProperties,GProp_GProps::Mass.
ThruSections builder (v0.115.0)
ThruSectionsBuilder drives BRepOffsetAPI_ThruSections through a builder pattern, providing full control over smoothing, degree, and continuity before building.
ThruSectionsBuilder.init(isSolid:isRuled:precision:)
Creates a loft builder.
public init(isSolid: Bool = true, isRuled: Bool = false, precision: Double = 1e-6)
- Parameters:
isSolid:true(default) caps the ends to produce a solid;falsegives a shell.isRuled:trueuses ruled (linear) surfaces between sections;false(default) uses BSpline.precision: 3D tolerance; default1e-6.
- OCCT:
BRepOffsetAPI_ThruSections. - Note: Mixing closed and open profiles causes a SIGSEGV inside OCCT (
BRepFill_CompatibleWires). A source patch shipped with this xcframework guards the iterator; still, ensure all profiles have the same open/closed status.
addWire(_:) (ThruSectionsBuilder)
Adds a wire profile as the next cross-section.
public func addWire(_ wire: Shape)
- OCCT:
BRepOffsetAPI_ThruSections::AddWire.
addVertex(_:) (ThruSectionsBuilder)
Adds a vertex (degenerate point) as a tip section.
public func addVertex(_ vertex: Shape)
- OCCT:
BRepOffsetAPI_ThruSections::AddVertex.
setSmoothing(_:)
Enables or disables smoothing of the loft surface.
public func setSmoothing(_ smoothing: Bool)
- OCCT:
BRepOffsetAPI_ThruSections::SetSmoothing.
setMaxDegree(_:)
Sets the maximum BSpline degree used for the loft.
public func setMaxDegree(_ maxDeg: Int)
- OCCT:
BRepOffsetAPI_ThruSections::SetMaxDegree.
setContinuity(_:) (ThruSectionsBuilder)
Sets the desired continuity of the lofted surface.
public func setContinuity(_ continuity: Int)
- Parameters:
continuity,0=C0,1=C1,2=C2. - OCCT:
BRepOffsetAPI_ThruSections::SetContinuity.
build() (ThruSectionsBuilder)
Executes the loft algorithm.
@discardableResult
public func build() -> Bool
- Returns:
trueon success. - OCCT:
BRepOffsetAPI_ThruSections::Build.
shape (ThruSectionsBuilder)
The result shape after a successful build().
public var shape: Shape? { get }
- Returns: The lofted
Shape, ornilunless abuild()call has succeeded since the most recent change to this builder’s sections (addWire(_:)/addVertex(_:)) or settings (setSmoothing(_:),setMaxDegree(_:),setContinuity(_:),checkCompatibility(_:),setParType(_:),setCriteriumWeight(w1:w2:w3:)), every one of those invalidates a prior successful build’s result, including on a builder reused across multiplebuild()calls. - OCCT:
BRepOffsetAPI_ThruSections::Shape. - Example:
let builder = ThruSectionsBuilder(isSolid: true) builder.addWire(bottomWire) builder.addWire(topWire) builder.setSmoothing(true) if builder.build(), let loft = builder.shape { print(loft.isValid) }
ShapeFixer builder (v0.115.0)
ShapeFixer provides configurable shape repair via ShapeFix_Shape, exposing precision, tolerance bounds, and per-fix status reporting.
ShapeFixer.init(shape:)
Creates a fixer for the given shape.
public init(shape: Shape)
- OCCT:
ShapeFix_Shape. TheShapeFix_Shapeconstructor accepts a null shape and returns;Perform()is the half that dereferences it, so a fixer built on a null shape (fromShape.nullified) used to crash the process on the laterperform()call. The fixer is now built empty for a null shape: the three setters become no-ops,perform()answersfalse,shapeanswersnil, and bothstatusoverloads answerfalse(#1035, measured inScripts/repro/1035-unwrap-guard/).
setPrecision(_:) (ShapeFixer)
Sets the working precision for repair algorithms.
public func setPrecision(_ precision: Double)
- OCCT:
ShapeFix_Root::SetPrecision.
setMaxTolerance(_:)
Sets the upper bound on tolerances that the fixer may assign.
public func setMaxTolerance(_ maxTol: Double)
- OCCT:
ShapeFix_Root::SetMaxTolerance.
setMinTolerance(_:)
Sets the lower bound on tolerances that the fixer may assign.
public func setMinTolerance(_ minTol: Double)
- OCCT:
ShapeFix_Root::SetMinTolerance.
perform() (ShapeFixer)
Runs all applicable shape-fixing algorithms.
@discardableResult
public func perform() -> Bool
- Returns:
trueif any fix was applied. - OCCT:
ShapeFix_Shape::Perform. Answersfalsewithout calling OCCT when the fixer was built on a null shape, which used to crash the process here (#1035).
shape (ShapeFixer)
The repaired shape after perform().
public var shape: Shape? { get }
- Returns: The fixed
Shape, ornilifperform()has not been called or produced nothing. - OCCT:
ShapeFix_Shape::Shape. Answersnilwhen the fixer was built on a null shape (#1035).
status(_:) (ShapeFixStatus overload)
Queries whether a specific ShapeExtend_Status flag is set after perform(), the full granularity ShapeFix_Shape::Status actually reports, not just the three combined flags the legacy Int overload below exposes (#849).
public func status(_ status: ShapeFixStatus) -> Bool
- Parameters:
status, seeShapeFixStatusbelow for the flag space and theShapeFix_Shapemeaning table. - Returns:
trueif the queried status flag is set. - OCCT:
ShapeFix_Shape::Status. - Example:
let fixer = ShapeFixer(shape: badShape) fixer.setPrecision(1e-4) fixer.perform() if fixer.status(.done3) { /* some free face was fixed */ }
status(_:) (Int overload, legacy)
Queries the fix result status via an undocumented 1/2/3 remap.
public func status(_ type: Int) -> Bool
- Parameters:
type,1=OK (no fix needed),2=DONE (fix applied),3=FAIL (fix attempted but failed). - Returns:
trueif the queried status flag is set;falsefor anytypeoutside1...3, there is no way to ask through this overload whether a specificDONEi/FAILi sub-flag fired. - OCCT:
ShapeFix_Shape::Status. - Note: Legacy. Prefer the
ShapeFixStatusoverload above (#849). Kept unchanged for source compatibility. - Example:
let fixer = ShapeFixer(shape: badShape) fixer.setPrecision(1e-4) fixer.perform() if let fixed = fixer.shape { print(fixer.status(2)) } // true = something was fixed
ShapeFixStatus
A status flag from OCCT’s ShapeExtend_Status enum, the flag space every ShapeFix_Root subclass (ShapeFix_Shape, ShapeFix_Face, ShapeFix_Wire, …) reports its fix result through. DONE1…DONE8 and FAIL1…FAIL8 are per-class: each subclass assigns its own meaning to the numbered slots, and a slot it does not use is simply never set. Shared by ShapeFixer.status(_:) above and FaceFixer.status(_:) (see Document-Mesh-Fixing.md), each with its own meaning table.
public enum ShapeFixStatus: Int32, Sendable, CaseIterable {
case ok = 0
case done1 = 1, done2, done3, done4, done5, done6, done7, done8
case done = 9
case fail1 = 10, fail2, fail3, fail4, fail5, fail6, fail7, fail8
case fail = 18
}
Raw values mirror the real OCCT ordinals exactly (ShapeExtend_Status.hxx, pinned V8_0_1):
| Case | Raw | Meaning for ShapeFix_Shape |
|---|---|---|
.ok | 0 | The shape needed no fix at all. |
.done1 | 1 | Some free edges were fixed. |
.done2 | 2 | Some free wires were fixed. |
.done3 | 3 | Some free faces were fixed. |
.done4 | 4 | Some free shells were fixed. |
.done5 | 5 | Some free solids were fixed. |
.done6 | 6 | Shapes in a compound were fixed. |
.done7 | 7 | Not assigned by ShapeFix_Shape. |
.done8 | 8 | Not assigned by ShapeFix_Shape. |
.done | 9 | Any .done1….done8 flag is set: something was fixed. |
.fail1….fail8 | 10…17 | Not assigned by ShapeFix_Shape. |
.fail | 18 | Any .fail1….fail8 flag is set: some pass failed. |
- Note: #849, this replaces a previous pair of independently-wrong encodings:
ShapeFixer’s ownstatus(Int)exposed only 3 of the 19 ordinals, andFaceFixer’s previous localStatusenum shifted everything from.fail1through.doneby one ordinal.FaceFixer.Statusis now a typealias for this type.
BRep_Tool completions (v0.126.0)
Shape.curveOnSurface(edge:face:)
Returns the 2D parametric curve (pcurve) of an edge on a face, with its parameter range.
public static func curveOnSurface(edge: Shape, face: Shape) -> (curve: Curve2D, first: Double, last: Double)?
- Returns: A tuple of the 2D
Curve2Dand itsfirst/lastparameter range, ornilif no pcurve exists. - OCCT:
BRep_Tool::CurveOnSurface.
Shape.hasContinuity(edge:face1:face2:)
Checks whether an edge has recorded continuity regularity between two adjacent faces.
public static func hasContinuity(edge: Shape, face1: Shape, face2: Shape) -> Bool
- OCCT:
BRep_Tool::HasContinuity.
Shape.continuity(edge:face1:face2:)
Returns the continuity order of an edge between two faces as a GeomAbs_Shape integer.
public static func continuity(edge: Shape, face1: Shape, face2: Shape) -> Int
- Returns:
GeomAbs_Shapeinteger:0=C0,1=G1,2=C1,3=G2,4=C2,5=C3,6=CN. - OCCT:
BRep_Tool::Continuity.
Shape.hasAnyContinuity(edge:)
Checks whether an edge has any recorded continuity on any pair of its surfaces.
public static func hasAnyContinuity(edge: Shape) -> Bool
- OCCT:
BRep_Tool::HasContinuity(any-surface overload).
Shape.maxContinuity(edge:)
Returns the maximum continuity of an edge across all surface pairs it belongs to.
public static func maxContinuity(edge: Shape) -> Int
- Returns: The highest
GeomAbs_Shapeinteger found. - OCCT:
BRep_Tool::MaxContinuity.
Shape.isDegenerated(edge:)
Returns true if the edge is degenerated (collapsed to a point in 3D).
public static func isDegenerated(edge: Shape) -> Bool
- OCCT:
BRep_Tool::Degenerated.
Shape.naturalRestriction(face:)
Returns the value of the NaturalRestriction flag on a face.
public static func naturalRestriction(face: Shape) -> Bool
A face with natural restriction uses the full parameter domain of its surface as its boundary without additional wire loops.
- OCCT:
BRep_Tool::NaturalRestriction.
Shape.rangeOnFace(edge:face:)
Returns the parameter range of an edge’s pcurve on a given face.
public static func rangeOnFace(edge: Shape, face: Shape) -> (first: Double, last: Double)?
- Returns: The
(first, last)parameter range, ornilif no pcurve exists. - OCCT:
BRep_Tool::Range.
Shape.parameterOnFace(vertex:edge:face:)
Returns the parameter of a vertex on the pcurve of an edge on a face.
public static func parameterOnFace(vertex: Shape, edge: Shape, face: Shape) -> Double?
- Returns: The parameter value, or
nilon failure. - OCCT:
BRep_Tool::Parameter.
Shape.parametersOnFace(vertex:face:)
Returns the UV parameters of a vertex on a face.
public static func parametersOnFace(vertex: Shape, face: Shape) -> (u: Double, v: Double)?
- Returns: The
(u, v)parameter pair, ornilif the vertex does not lie on the face. - OCCT:
BRep_Tool::Parameters.
Shape.uvPoints(edge:face:)
Returns the UV coordinates at both endpoints of an edge on a face.
public static func uvPoints(edge: Shape, face: Shape) -> (firstU: Double, firstV: Double, lastU: Double, lastV: Double)?
- Returns: Four UV values describing the start and end 2D positions, or
nilon failure. - OCCT:
BRep_Tool::UVPoints.
maxTolerance(subShapeType:)
Returns the maximum tolerance of all sub-shapes of the specified type within this shape.
public func maxTolerance(subShapeType: Int) -> Double
- Parameters:
subShapeType, OCCTTopAbs_ShapeEnuminteger:4=FACE,6=EDGE,7=VERTEX. - OCCT:
BRep_Tool::MaxTolerance(shape, TopAbs_ShapeEnum)(viaOCCTBRepToolMaxTolerance). NotShapeAnalysis_ShapeTolerance, which this entry also used to name and which is not in this chain; that one backsmaxEdgeToleranceinstead. The same wrong pairing appeared on both entries with the two classes the wrong way round; #808 corrected both. - Note: This is the real
TopAbs_ShapeEnumordinal, the same conventionShapeType’s raw values use, and the oneShape.maxTolerance(type:)’sShapeTypeoverload (see “Document-Mesh-Fixing”) passes through unchanged. It is NOT the same as that method’s legacyIntoverload, which uses a different, compressed0/1/2encoding for the same idea (#833).
Section with plane/surface & BRep_Tool Polygon queries (v0.127.0)
sectionWithPlane(normal:origin:)
Computes the section (intersection edges) of this shape with a plane.
public func sectionWithPlane(normal: SIMD3<Double>, origin: SIMD3<Double>) -> Shape?
- Parameters:
normal, outward normal of the cutting plane.origin, any point on the plane. - Returns: A
Shapecontaining the section edges/wires, ornilon failure. - OCCT:
BRepAlgoAPI_Sectionwith an internalgp_Pln. - Example:
if let section = solid.sectionWithPlane(normal: SIMD3(0,0,1), origin: SIMD3(0,0,5)) { print(section.edges.count) }
sectionWithSurface(_:)
Computes the section (intersection curves) of this shape with an arbitrary surface.
public func sectionWithSurface(_ surface: Surface) -> Shape?
- Returns: A
Shapecontaining the section edges, ornilon failure. - OCCT:
BRepAlgoAPI_Sectionwith aGeom_Surfacetool.
Shape.curveOnPlane(edge:surface:)
Returns the 2D projection of an edge onto a planar surface, with parameter range.
public static func curveOnPlane(edge: Shape, surface: Surface) -> (curve: Curve2D, first: Double, last: Double)?
- Returns: A
Curve2Dand its parameter range, ornilif projection fails. - OCCT:
BRep_Tool::CurveOnPlane.
Shape.polygon3D(edge:)
Returns the 3D polygon of a meshed edge (discrete approximation from triangulation).
public static func polygon3D(edge: Shape) -> [SIMD3<Double>]?
The shape must have been meshed (mesh(deflection:)) before calling this.
- Returns: An ordered array of 3D points along the edge, or
nilif no polygon is stored. - OCCT:
BRep_Tool::Polygon3D,Poly_Polygon3D::Nodes.
Shape.polygonOnTriangulation(edge:)
Returns the triangulation-node indices of a meshed edge as a 1-based index array.
public static func polygonOnTriangulation(edge: Shape) -> [Int]?
The shape must have been meshed first.
- Returns: An array of 1-based indices into the parent face’s
Poly_Triangulation, ornilif not available. - OCCT:
BRep_Tool::PolygonOnTriangulation,Poly_PolygonOnTriangulation::Nodes.
BRep_Tool completions (v0.128.0)
Shape.isClosedOnFace(edge:face:)
Checks whether an edge is topologically closed on a face (i.e., the edge has two pcurves on the face with opposing orientations).
public static func isClosedOnFace(edge: Shape, face: Shape) -> Bool
- OCCT:
BRep_Tool::IsClosed.
Shape.polygonOnSurface(edge:face:)
Returns the 2D polygon (UV) of a meshed edge on a face.
public static func polygonOnSurface(edge: Shape, face: Shape) -> [SIMD2<Double>]?
The shape must have been meshed first.
- Returns: An ordered array of 2D UV points, or
nilif not available. - OCCT:
BRep_Tool::PolygonOnSurface,Poly_Polygon2D::Nodes.
Shape.setUVPoints(edge:face:first:last:)
Sets the UV endpoint coordinates of an edge on a face (updates the stored 2D boundary).
@discardableResult
public static func setUVPoints(edge: Shape, face: Shape,
first: SIMD2<Double>, last: SIMD2<Double>) -> Bool
- Returns:
trueon success. - OCCT:
BRep_Tool::SetUVPoints(edge, face, first, last)(viaOCCTBRepToolSetUVPoints). Not a “setter overload ofBRep_Tool::UVPoints”, and notBRep_Builder, which this entry named until #808:SetUVPointsis its own static and writes through the edge’sBRep_CurveOnSurfacerepresentation directly. (#808) - Example:
let ok = Shape.setUVPoints(edge: e, face: f, first: SIMD2(0, 0), last: SIMD2(1, 0))
Bnd_OBB
OBB wraps OCCT’s Bnd_OBB: an oriented (rotated) bounding box, as opposed to the axis-aligned box Shape.bounds returns. Construct directly from a center, local axes, and half-sizes, or via OBB.fromShape(_:).
public final class OBB: @unchecked Sendable
| Member | Kind | Meaning |
|---|---|---|
handle | internal stored property | The opaque OCCTOBBRef this wrapper owns; released in deinit. |