Link Search Menu Expand Document

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

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, a Shape that has already been meshed. deflection, linear deflection used for auto-triangulation if the shape is not yet meshed; default 0.1.
  • Returns: A CoherentTriangulation populated from the face’s triangulation, or nil if 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: true on 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: true on success.
  • OCCT: Poly_CoherentTriangulation::RemoveTriangle.

triangleCount

Number of triangles in the coherent triangulation.

public var triangleCount: Int { get }
  • OCCT: Poly_CoherentTriangulation::NTriangles.

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: true if 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), or nil on 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, or nil if 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: true to cap the result into a solid.
  • Returns: The evolved Shape, or nil if 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 OffsetAncestors instance, or nil if 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, or nil if 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’s theDeflection). 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/.point2 are the first-appended solution, not guaranteed to be the minimal one. Default 1e-7 (Precision::Confusion()), OCCT’s own default (#1544).
  • Returns: A DistanceSSResult containing .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; default 0.001.
    • computeCG: whether to compute the centre of gravity; default true.
  • Returns: A VinertGKResult with .mass, .errorReached, and an optional .center.
  • OCCT: BRepGProp_VinertGK.
  • Note: This method operates on a face shape. The .mass field 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. .center is nil when the contribution is 0, and when computeCG was false; both used to report (0,0,0), which is indistinguishable from a real centroid at the origin (#609). .errorReached is BRepGProp_VinertGK::GetErrorReached(); it used to be hardcoded to 0.0 on 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-exact 0.0, far below what floating-point cancellation reaches for a real integral, ~1e-14 at best); see the doc comment on VinertGKResult in Shape+Analysis.swift for the full investigation. There is no .absoluteError: OCCT declares GetAbsolutError() on the same class but never defines it, so calling it fails to link, and deriving one from .errorReached * .mass would 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. If curve wraps a null Geom_Curve handle, it is silently dropped instead of added (#710 defensive hardening; no public Curve3D factory can produce that state today), and there is no curveCount/isValid signal 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 a curveIndex passed to poles(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: true on 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 StretchFillResult containing pole grid dimensions and the flat pole array, or nil if 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: true on 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 matrix is a flat 9-element row-major 3×3 rotation matrix and translation is the origin offset, or nil on 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: true on 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, or nil on 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: true on 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, or nil on 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; default 0.
    • tolerance: positional tolerance; default 1e-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 NSections instance, or nil on 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 returns nil instead of crashing the underlying GeomFill_AppSurf solver, 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 AppSurfResult on success, or nil if 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 tolerance ShapeFix_ComposeShell::Init receives; uPatches and vPatches, the grid, each at least 1.
  • Returns: A Shape, the composed shell, or nil if the receiver is not a face, carries no surface, a patch count is below 1, or Perform() fails.
  • OCCT: ShapeFix_ComposeShell over a ShapeExtend_CompositeSurface of Geom_RectangularTrimmedSurface patches, initialised with ShapeExtend_Natural (via OCCTShapeFixComposeShell). The bridge sets a ShapeBuild_ReShape context before Perform(), because 8.0.0p1 null-derefs without one.
  • Note: ShapeExtend_Parametrisation is not a parameter. Because the patches are sub-ranges of the face’s own surface, ShapeExtend_Natural reproduces 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, or nil if 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, nil if matrix.count != 12. #835 (PR #864 review): before this, transformed(matrix:), transformed(byMatrix:), and gTransformed(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, or nil if the operation fails.
  • OCCT: BRepBuilderAPI_GTransform, gp_GTrsf.
  • Note: The layout convention differs from transformed(matrix:)’s Matrix12Grouped, this method takes the same INTERLEAVED layout as transformed(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, nil if matrix.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 Shape containing the intersection edges/wires, or nil on failure.
  • OCCT: BRepAlgoAPI_Section with 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; default 0.
  • Returns: The split compound Shape, or nil on 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, or nil on failure.
  • OCCT: BRepAlgoAPI_Cut with 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_CN sub-piece lengths, with the final narrow piece handed to GCPnts_AbscissaPoint. The edge is read through a BRepAdaptor_Curve, whose constructor dereferences a null shape, so a null shape (from Shape.nullified) used to crash the process here; it answers 0 now (#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.0 on failure. Arc length is otherwise always non-negative, so this is an unambiguous sentinel; it used to be 0, which a genuinely zero-length edge also measures (#548).
  • OCCT: BRepAdaptor_Curve + GCPnts_AbscissaPoint::Length per GeomAbs_CN interval, 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.0 if a bound is not finite or the computation fails.
  • OCCT: GCPnts_AbscissaPoint::Length per GeomAbs_CN interval, subdivided to convergence, the same measurement as edgeArcLength (#603).
  • Note: .nan and ±.infinity are 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 edge 0 (a NaN upper bound) or the edge’s whole length (a NaN lower one), see Curve3D.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 the Curve3D/Curve2D spellings, 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 the BRepAdaptor_Curve constructor behind the measurement; it answers -1.0 now (#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 walk edgeParameterAtArcLength makes. A null shape (from Shape.nullified) used to crash the process in the BRepAdaptor_Curve constructor behind both halves; it answers 0 now (#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 and 0.5 genuinely 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 (from Shape.nullified) used to crash the process in that constructor; it answers 0...0 now (#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 (from Shape.nullified) used to crash the process in the BRepAdaptor_Curve constructor; it answers SIMD3(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 (from Shape.nullified) used to crash the process in the BRepAdaptor_Curve constructor; it answers -1 now, 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_OBB via BRepBndLib::AddOBB.

maxEdgeTolerance

Maximum tolerance across all edges in this shape.

public var maxEdgeTolerance: Double { get }
  • OCCT: ShapeAnalysis_ShapeTolerance::Tolerance(shape, 1, TopAbs_EDGE) (via OCCTShapeMaxEdgeTolerance). Not BRep_Tool::MaxTolerance, which this entry also used to name and which the bridge does not call here; that one is wrapped separately as maxTolerance(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 a TopTools_IndexedDataMapOfShapeListOfShape, then true as soon as one edge has fewer than two faces (via OCCTShapeHasFreeEdges). Neither ShapeAnalysis_FreeBounds nor BRepCheck_Analyzer, which this entry used to name and neither of which is called here. This is a pure incidence count, so unlike freeBounds(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 nil for a face, wire, edge, vertex or open shell.
  • OCCT: GProp_GProps via BRepGProp::VolumeProperties with OnlyClosed = true, plus a Mass() 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: surfaceInertia for 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; false gives a shell.
    • isRuled: true uses ruled (linear) surfaces between sections; false (default) uses BSpline.
    • precision: 3D tolerance; default 1e-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: true on success.
  • OCCT: BRepOffsetAPI_ThruSections::Build.

shape (ThruSectionsBuilder)

The result shape after a successful build().

public var shape: Shape? { get }
  • Returns: The lofted Shape, or nil unless a build() 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 multiple build() 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. The ShapeFix_Shape constructor accepts a null shape and returns; Perform() is the half that dereferences it, so a fixer built on a null shape (from Shape.nullified) used to crash the process on the later perform() call. The fixer is now built empty for a null shape: the three setters become no-ops, perform() answers false, shape answers nil, and both status overloads answer false (#1035, measured in Scripts/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: true if any fix was applied.
  • OCCT: ShapeFix_Shape::Perform. Answers false without 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, or nil if perform() has not been called or produced nothing.
  • OCCT: ShapeFix_Shape::Shape. Answers nil when 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, see ShapeFixStatus below for the flag space and the ShapeFix_Shape meaning table.
  • Returns: true if 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: true if the queried status flag is set; false for any type outside 1...3, there is no way to ask through this overload whether a specific DONEi/FAILi sub-flag fired.
  • OCCT: ShapeFix_Shape::Status.
  • Note: Legacy. Prefer the ShapeFixStatus overload 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 own status(Int) exposed only 3 of the 19 ordinals, and FaceFixer’s previous local Status enum shifted everything from .fail1 through .done by one ordinal. FaceFixer.Status is 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 Curve2D and its first/last parameter range, or nil if 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_Shape integer: 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_Shape integer 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, or nil if 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 nil on 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, or nil if 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 nil on 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, OCCT TopAbs_ShapeEnum integer: 4=FACE, 6=EDGE, 7=VERTEX.
  • OCCT: BRep_Tool::MaxTolerance(shape, TopAbs_ShapeEnum) (via OCCTBRepToolMaxTolerance). Not ShapeAnalysis_ShapeTolerance, which this entry also used to name and which is not in this chain; that one backs maxEdgeTolerance instead. 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_ShapeEnum ordinal, the same convention ShapeType’s raw values use, and the one Shape.maxTolerance(type:)’s ShapeType overload (see “Document-Mesh-Fixing”) passes through unchanged. It is NOT the same as that method’s legacy Int overload, which uses a different, compressed 0/1/2 encoding 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 Shape containing the section edges/wires, or nil on failure.
  • OCCT: BRepAlgoAPI_Section with an internal gp_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 Shape containing the section edges, or nil on failure.
  • OCCT: BRepAlgoAPI_Section with a Geom_Surface tool.

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 Curve2D and its parameter range, or nil if 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 nil if 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, or nil if 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 nil if 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: true on success.
  • OCCT: BRep_Tool::SetUVPoints(edge, face, first, last) (via OCCTBRepToolSetUVPoints). Not a “setter overload of BRep_Tool::UVPoints”, and not BRep_Builder, which this entry named until #808: SetUVPoints is its own static and writes through the edge’s BRep_CurveOnSurface representation 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.