Link Search Menu Expand Document

Shape — Builders & Boolean Internals II

Continuation of the low-level builder and algorithm wrappers on Shape — covering GeomFill sweep/evolved-section, projection, offset, iso-curve evaluation, parameter transfer, boolean section/feature removal, shape build/extend/upgrade utilities, 2D vector math, topological transition analysis, GeomFill trihedrons, 2D polygon interference, analytical 2D circle construction, IntTools intersection, BOPAlgo builders, BRepFeat split/hole/glue, LocOpe split/glue, and 2D chamfer/fillet APIs.

See also: Shape (index).

Topics


GeomFill_Sweep

Shape.geomFillSweep(path:section:)

Sweep a section edge along a path edge to create a surface face.

public static func geomFillSweep(path: Shape, section: Shape) -> Shape?
  • Parameters: path — edge defining the sweep path. section — edge defining the cross-section profile.
  • Returns: A Shape wrapping the swept face, or nil on failure, including when GeomFill_Sweep fits the surface but misses its own 1e-4 tolerance (ErrorOnSurface()); a surface reported IsDone() is not necessarily within the tolerance it was built at, so this is checked rather than assumed (#597).
  • OCCT: GeomFill_Sweep
  • Example:
    if let face = Shape.geomFillSweep(path: pathEdge, section: sectionEdge) {
        // face is a swept surface
    }
    

GeomFill_EvolvedSection

evolvedSectionInfo()

Get evolved section info for an edge curve.

public func evolvedSectionInfo() -> EvolvedSectionInfo
  • Returns: EvolvedSectionInfo with nbPoles, nbKnots, degree, and isRational.
  • OCCT: GeomFill_EvolvedSection
  • Example:
    let info = edge.evolvedSectionInfo()
    print(info.degree, info.isRational)
    

EvolvedSectionInfo.nbPoles

Number of BSpline control poles in the evolved section curve.

EvolvedSectionInfo.nbKnots

Number of BSpline knots in the evolved section curve.


ProjLib_ComputeApprox

projectOntoSurface(_:tolerance:)

Project this edge’s 3D curve onto a face’s surface, returning an edge-on-surface.

public func projectOntoSurface(_ face: Shape, tolerance: Double = 1e-3) -> Shape?
  • Parameters: face — target face. tolerance — approximation tolerance.
  • Returns: Projected edge as shape, or nil on failure.
  • OCCT: ProjLib_ComputeApprox
  • Example:
    if let proj = edge.projectOntoSurface(face) { }
    

projectOntoPolarSurface(_:tolerance:)

Project this edge’s 3D curve onto a polar surface (sphere, torus).

public func projectOntoPolarSurface(_ face: Shape, tolerance: Double = 1e-3) -> Shape?
  • Parameters: face — polar face. tolerance — approximation tolerance.
  • Returns: Projected edge as shape, or nil on failure.
  • OCCT: ProjLib_ComputeApproxOnPolarSurface
  • Example:
    if let proj = edge.projectOntoPolarSurface(sphereFace) { }
    

BRepOffset_Offset

offsetFace(distance:)

Offset a face by a distance, creating a new offset face.

public func offsetFace(distance: Double) -> Shape?
  • Parameters: distance — signed offset amount; positive moves along the face normal.
  • Returns: Offset face, or nil on failure.
  • OCCT: BRepOffset_Offset
  • Example:
    if let off = face.offsetFace(distance: 2.0) { }
    

Adaptor3d_IsoCurve

uIsoCurvePoints(u:count:)

Evaluate sample points along a U-iso curve on a face.

public func uIsoCurvePoints(u: Double, count: Int = 20) -> [SIMD3<Double>]
  • Parameters: u — U parameter value. count — number of sample points, a request honoured within 1...Sampling.maximumSampleCount (10,000,000); outside that range the result is empty (#558).
  • Returns: Array of 3D points along the iso curve.
  • OCCT: Adaptor3d_IsoCurve (iso kind 0 = U)
  • Example:
    let pts = face.uIsoCurvePoints(u: 0.5, count: 50)
    

vIsoCurvePoints(v:count:)

Evaluate sample points along a V-iso curve on a face.

public func vIsoCurvePoints(v: Double, count: Int = 20) -> [SIMD3<Double>]
  • Parameters: v — V parameter value. count — number of sample points, a request honoured within 1...Sampling.maximumSampleCount (10,000,000); outside that range the result is empty (#558).
  • Returns: Array of 3D points along the iso curve.
  • OCCT: Adaptor3d_IsoCurve (iso kind 1 = V)
  • Example:
    let pts = face.vIsoCurvePoints(v: 0.25)
    

uIsoCurveEdge(u:vMin:vMax:)

Extract a U-iso curve from a face as an edge.

public func uIsoCurveEdge(u: Double, vMin: Double, vMax: Double) -> Shape?
  • Parameters: u — U parameter. vMin/vMax — V parameter range for the edge.
  • Returns: Edge shape representing the iso curve, or nil on failure.
  • OCCT: Adaptor3d_IsoCurve
  • Example:
    if let e = face.uIsoCurveEdge(u: 0.5, vMin: 0, vMax: 1) { }
    

vIsoCurveEdge(v:uMin:uMax:)

Extract a V-iso curve from a face as an edge.

public func vIsoCurveEdge(v: Double, uMin: Double, uMax: Double) -> Shape?
  • Parameters: v — V parameter. uMin/uMax — U parameter range for the edge.
  • Returns: Edge shape representing the iso curve, or nil on failure.
  • OCCT: Adaptor3d_IsoCurve
  • Example:
    if let e = face.vIsoCurveEdge(v: 0.5, uMin: 0, uMax: 1) { }
    

ShapeAnalysis_TransferParametersProj

transferParameterToFace(_:face:)

Transfer a parameter from edge to face coordinate system via projection.

public func transferParameterToFace(_ param: Double, face: Shape) -> Double
  • Parameters: param — edge parameter. face — face to transfer into.
  • Returns: Corresponding parameter in the face’s coordinate system.
  • OCCT: ShapeAnalysis_TransferParametersProj (toFace = true)
  • Example:
    let faceParam = edge.transferParameterToFace(0.5, face: face)
    

transferParameterFromFace(_:face:)

Transfer a parameter from face to edge coordinate system via projection.

public func transferParameterFromFace(_ param: Double, face: Shape) -> Double
  • Parameters: param — face parameter. face — face to transfer from.
  • Returns: Corresponding parameter in the edge’s coordinate system.
  • OCCT: ShapeAnalysis_TransferParametersProj (toFace = false)
  • Example:
    let edgeParam = edge.transferParameterFromFace(0.5, face: face)
    

BOPAlgo_RemoveFeatures

removeFeatures(faces:) was defeature(faces:) under a second name: BRepAlgoAPI_Defeaturing, which defeature(faces:) drives, is an API wrapper over BOPAlgo_RemoveFeatures, and both spellings drove one algorithm object with identical defaults, measured byte-for-byte identical on every case including the refusals (see Scripts/repro/536-defeature-removefeatures-unify/). Deprecated as a forward to defeature(faces:) in #536, removeFeatures(faces:) was removed at v2.0.0 (#784); use defeature(faces:).

let faces = solid.subShapes(ofType: .face)
if let cleaned = solid.defeature(faces: [faces[2]]) { }

BOPAlgo_Section

section(with:)

Compute section (intersection curves/vertices) between this shape and tools.

public func section(with tools: [Shape]) -> Shape?
  • Parameters: tools — tool shapes to intersect with this shape.
  • Returns: Compound of intersection edges and vertices, or nil on failure.
  • OCCT: BOPAlgo_Section
  • Example:
    if let sect = solid.section(with: [plane]) { }
    

Shape.section(shapes:)

Compute section between multiple shapes (static variant).

public static func section(shapes: [Shape]) -> Shape?
  • Parameters: shapes — at least 2 shapes; all are treated as equal arguments.
  • Returns: Compound of intersection edges and vertices, or nil on failure (requires ≥ 2 shapes).
  • OCCT: BOPAlgo_Section
  • Example:
    if let sect = Shape.section(shapes: [box, sphere]) { }
    

ShapeBuild_Edge

copyEdge(sharePCurves:)

Copy an edge, optionally sharing its PCurves with the original.

public func copyEdge(sharePCurves: Bool = true) -> Shape?
  • Parameters: sharePCurves — if true, the copy shares PCurves with the original edge.
  • Returns: Copied edge as shape, or nil on failure.
  • OCCT: ShapeBuild_Edge::Copy
  • Example:
    if let copy = edge.copyEdge() { }
    

copyEdgeReplacingVertices(startVertex:endVertex:)

Copy an edge, replacing its start and/or end vertices.

public func copyEdgeReplacingVertices(startVertex: Shape?, endVertex: Shape?) -> Shape?
  • Parameters: startVertex — new start vertex, or nil to keep original. endVertex — new end vertex, or nil to keep original.
  • Returns: Edge with replaced vertices, or nil on failure.
  • OCCT: ShapeBuild_Edge::CopyReplaceVertices
  • Example:
    if let e = edge.copyEdgeReplacingVertices(startVertex: v1, endVertex: nil) { }
    

setEdgeRange3d(first:last:)

Set the 3D parameter range on this edge shape.

public func setEdgeRange3d(first: Double, last: Double)
  • Parameters: first — start parameter. last — end parameter.
  • OCCT: ShapeBuild_Edge::SetRange3d
  • Example:
    edge.setEdgeRange3d(first: 0, last: 1)
    

buildEdgeCurve3d()

Rebuild the 3D curve of an edge from its PCurves.

@discardableResult
public func buildEdgeCurve3d() -> Bool
  • Returns: true if the curve was rebuilt successfully.
  • OCCT: ShapeBuild_Edge::BuildCurve3d
  • Example:
    edge.buildEdgeCurve3d()
    

removeEdgeCurve3d()

Remove the 3D curve from this edge.

public func removeEdgeCurve3d()
  • OCCT: ShapeBuild_Edge::RemoveCurve3d
  • Example:
    edge.removeEdgeCurve3d()
    

copyEdgeRanges(from:)

Copy parameter ranges from another edge to this edge.

public func copyEdgeRanges(from source: Shape)
  • Parameters: source — edge from which to copy ranges.
  • OCCT: ShapeBuild_Edge::CopyRanges
  • Example:
    edge.copyEdgeRanges(from: sourceEdge)
    

copyEdgePCurves(from:)

Copy PCurves from another edge to this edge.

public func copyEdgePCurves(from source: Shape)
  • Parameters: source — edge from which to copy PCurves.
  • OCCT: ShapeBuild_Edge::CopyPCurves
  • Example:
    edge.copyEdgePCurves(from: sourceEdge)
    

removeEdgePCurve(onFace:)

Remove the PCurve from this edge for a given face.

public func removeEdgePCurve(onFace face: Shape)
  • Parameters: face — the face whose PCurve should be removed from this edge.
  • OCCT: ShapeBuild_Edge::RemovePCurve
  • Example:
    edge.removeEdgePCurve(onFace: face)
    

reassignEdgePCurve(from:to:)

Reassign a PCurve from one face to another.

@discardableResult
public func reassignEdgePCurve(from oldFace: Shape, to newFace: Shape) -> Bool
  • Parameters: oldFace — face that currently holds the PCurve. newFace — destination face.
  • Returns: true if reassignment succeeded.
  • OCCT: ShapeBuild_Edge::ReassignPCurve
  • Example:
    edge.reassignEdgePCurve(from: oldFace, to: newFace)
    

ShapeBuild_Vertex

combineVertex(with:tolFactor:)

Combine this vertex shape with another at their average position.

public func combineVertex(with other: Shape, tolFactor: Double = 1.0001) -> Shape?
  • Parameters: other — vertex to combine with. tolFactor — tolerance scale factor.
  • Returns: Combined vertex as shape, or nil on failure.
  • OCCT: ShapeBuild_Vertex::CombineVertex
  • Example:
    if let v = v1.combineVertex(with: v2) { }
    

Shape.combineVertices(point1:tol1:point2:tol2:tolFactor:)

Create a vertex by combining two 3D points with tolerances.

public static func combineVertices(
    point1: SIMD3<Double>, tol1: Double,
    point2: SIMD3<Double>, tol2: Double,
    tolFactor: Double = 1.0001
) -> Shape?
  • Parameters: point1/tol1 — first point and its tolerance. point2/tol2 — second point and its tolerance. tolFactor — scale factor applied to the combined tolerance.
  • Returns: Combined vertex, or nil on failure.
  • OCCT: ShapeBuild_Vertex::CombineVertex (from points)
  • Example:
    if let v = Shape.combineVertices(point1: .zero, tol1: 1e-7, point2: SIMD3(0,0,0.001), tol2: 1e-7) { }
    

ShapeExtend_Explorer

ShapeFilterType

Shape type enum for filtering compounds.

public enum ShapeFilterType: Int32, Sendable {
    case compound = 0, compsolid = 1, solid = 2, shell = 3
    case face = 4, wire = 5, edge = 6, vertex = 7
}

Matches TopAbs_ShapeEnum values used by ShapeExtend_Explorer.


ShapeFilterType.compsolid

A compound solid: several solids sharing faces, treated as a single connected shape (TopAbs_COMPSOLID).

case compsolid = 1

sortedCompound(type:explore:)

Filter this compound, extracting only sub-shapes of the specified type.

public func sortedCompound(type: ShapeFilterType, explore: Bool = true) -> Shape?
  • Parameters: type — target shape type. explore — if true, recurse into sub-compounds.
  • Returns: Compound of matching sub-shapes, or nil on failure.
  • OCCT: ShapeExtend_Explorer::SortedCompound
  • Example:
    if let faces = compound.sortedCompound(type: .face) { }
    

predominantShapeType(lookInsideCompounds:)

Get the predominant shape type in this compound.

public func predominantShapeType(lookInsideCompounds: Bool = true) -> ShapeFilterType
  • Parameters: lookInsideCompounds — if true, inspect sub-compounds.
  • Returns: The most-common ShapeFilterType found.
  • OCCT: ShapeExtend_Explorer::ShapeType
  • Example:
    let t = compound.predominantShapeType()
    

ShapeUpgrade_FaceDivide

divideFace()

Divide a face using surface segmentation.

public func divideFace() -> Shape?
  • Returns: Divided shape, or nil on failure.
  • OCCT: ShapeUpgrade_FaceDivide
  • Example:
    if let divided = face.divideFace() { }
    

ShapeUpgrade_WireDivide

divideWire(onFace:)

Divide a wire on a face.

public func divideWire(onFace face: Shape) -> Shape?
  • Parameters: face — face the wire lies on.
  • Returns: Divided wire as shape, or nil on failure.
  • OCCT: ShapeUpgrade_WireDivide
  • Example:
    if let w = wire.divideWire(onFace: face) { }
    

ShapeUpgrade_EdgeDivide

EdgeDivideResult

Result of an edge divide analysis.

public struct EdgeDivideResult: Sendable {
    public let hasCurve2d: Bool
    public let hasCurve3d: Bool
}
Field Meaning
hasCurve2d true if the edge carries a 2D (pcurve) representation on the analysed face.
hasCurve3d true if the edge carries a 3D curve representation.

Shape.EdgeDivideResult.hasCurve2d


analyzeEdgeDivide(onFace:)

Analyze an edge for potential division on a face.

public func analyzeEdgeDivide(onFace face: Shape) -> EdgeDivideResult?
  • Parameters: face — face context for the edge.
  • Returns: Analysis result indicating 2D/3D curve presence, or nil on failure.
  • OCCT: ShapeUpgrade_EdgeDivide::Compute
  • Example:
    if let r = edge.analyzeEdgeDivide(onFace: face) {
        print(r.hasCurve3d)
    }
    

ShapeUpgrade_ClosedEdgeDivide

canDivideClosedEdge(onFace:)

Check if a closed (seam) edge can be divided on a face.

public func canDivideClosedEdge(onFace face: Shape) -> Bool
  • Parameters: face — face context.
  • Returns: true if the edge is closed and divisible.
  • OCCT: ShapeUpgrade_ClosedEdgeDivide::Compute
  • Example:
    if edge.canDivideClosedEdge(onFace: face) { }
    

ShapeUpgrade_FixSmallCurves

fixSmallCurves(tolerance:)

Fix small curves in this shape.

public func fixSmallCurves(tolerance: Double = 1e-6) -> Shape?
  • Parameters: tolerance — threshold below which curves are considered small.
  • Returns: Fixed shape, or nil on failure.
  • OCCT: ShapeUpgrade_FixSmallCurves
  • Example:
    if let fixed = shape.fixSmallCurves() { }
    

ShapeUpgrade_FixSmallBezierCurves

fixSmallBezierCurves(tolerance:)

Fix small Bezier curves in this shape.

public func fixSmallBezierCurves(tolerance: Double = 1e-6) -> Shape?
  • Parameters: tolerance — detection threshold.
  • Returns: Fixed shape, or nil on failure.
  • OCCT: ShapeUpgrade_FixSmallBezierCurves
  • Example:
    if let fixed = shape.fixSmallBezierCurves() { }
    

ShapeUpgrade_ConvertCurve3dToBezier

convertCurves3dToBezier(lineMode:circleMode:conicMode:)

Convert 3D curves in this shape to Bezier representation.

public func convertCurves3dToBezier(lineMode: Bool = true, circleMode: Bool = true,
                                     conicMode: Bool = true) -> Shape?
  • Parameters: lineMode — convert line segments. circleMode — convert circles. conicMode — convert other conics.
  • Returns: Shape with Bezier curves, or nil on failure.
  • OCCT: ShapeUpgrade_ConvertCurve3dToBezier
  • Example:
    if let bez = shape.convertCurves3dToBezier(lineMode: false) { }
    

ShapeUpgrade_ConvertSurfaceToBezierBasis

convertSurfacesToBezier(planeMode:revolutionMode:extrusionMode:bsplineMode:)

Convert surfaces in this shape to Bezier patches.

public func convertSurfacesToBezier(planeMode: Bool = true, revolutionMode: Bool = true,
                                     extrusionMode: Bool = true, bsplineMode: Bool = true) -> Shape?
  • Parameters: planeMode — convert planes. revolutionMode — convert revolution surfaces. extrusionMode — convert extrusions. bsplineMode — convert BSpline surfaces.
  • Returns: Shape with Bezier surfaces, or nil on failure.
  • OCCT: ShapeUpgrade_ConvertSurfaceToBezierBasis
  • Example:
    if let bez = shape.convertSurfacesToBezier(bsplineMode: false) { }
    

2D Vector/Direction Utilities & LProp

Shape.vector2DAngle(a:b:)

Signed angle between two 2D vectors, in radians (range −π to π).

public static func vector2DAngle(a: SIMD2<Double>, b: SIMD2<Double>) -> Double
  • OCCT: gp_Vec2d::Angle
  • Example:
    let angle = Shape.vector2DAngle(a: SIMD2(1, 0), b: SIMD2(0, 1))  // π/2
    

Shape.vector2DCross(a:b:)

Cross product of two 2D vectors (scalar Z component).

public static func vector2DCross(a: SIMD2<Double>, b: SIMD2<Double>) -> Double
  • OCCT: gp_Vec2d::Crossed
  • Example:
    let z = Shape.vector2DCross(a: SIMD2(1, 0), b: SIMD2(0, 1))  // 1.0
    

Shape.vector2DDot(a:b:)

Dot product of two 2D vectors.

public static func vector2DDot(a: SIMD2<Double>, b: SIMD2<Double>) -> Double
  • OCCT: gp_Vec2d::Dot
  • Example:
    let d = Shape.vector2DDot(a: SIMD2(1, 0), b: SIMD2(0.5, 0.5))
    

Shape.vector2DMagnitude(_:)

Magnitude of a 2D vector.

public static func vector2DMagnitude(_ v: SIMD2<Double>) -> Double
  • OCCT: gp_Vec2d::Magnitude
  • Example:
    let m = Shape.vector2DMagnitude(SIMD2(3, 4))  // 5.0
    

Shape.vector2DNormalized(_:)

Return a normalized copy of a 2D vector.

public static func vector2DNormalized(_ v: SIMD2<Double>) -> SIMD2<Double>
  • OCCT: gp_Vec2d::Normalized
  • Example:
    let n = Shape.vector2DNormalized(SIMD2(3, 4))
    

Shape.direction2DNormalized(_:)

Create a normalized 2D direction from components.

public static func direction2DNormalized(_ v: SIMD2<Double>) -> SIMD2<Double>
  • OCCT: gp_Dir2d constructor (normalizes on construction)
  • Example:
    let d = Shape.direction2DNormalized(SIMD2(1, 1))
    

Shape.direction2DAngle(a:b:)

Signed angle between two 2D directions, in radians.

public static func direction2DAngle(a: SIMD2<Double>, b: SIMD2<Double>) -> Double
  • OCCT: gp_Dir2d::Angle
  • Example:
    let angle = Shape.direction2DAngle(a: SIMD2(1, 0), b: SIMD2(0, 1))
    

Shape.direction2DCross(a:b:)

Cross product of two 2D directions.

public static func direction2DCross(a: SIMD2<Double>, b: SIMD2<Double>) -> Double
  • OCCT: gp_Dir2d::Crossed
  • Example:
    let z = Shape.direction2DCross(a: SIMD2(1, 0), b: SIMD2(0, 1))
    

CurvaturePointType

Type of a special curvature point found by LProp analysis.

public enum CurvaturePointType: Int32 {
    case inflection = 0
    case minimumCurvature = 1
    case maximumCurvature = 2
}
case meaning
.inflection Parameter where curvature changes sign.
.minimumCurvature Parameter at a local minimum of curvature.
.maximumCurvature Parameter at a local maximum of curvature.

(Per-case anchors below, for cross-reference; the table above has the actual meaning of each.)

maximumCurvature


CurvatureSpecialPoint

A special point on a curve at a given parameter.

public struct CurvatureSpecialPoint {
    public let parameter: Double
    public let type: CurvaturePointType
}

Shape.analyticCurvaturePoints(curveType:first:last:)

Compute curvature special points (inflections, min/max curvature) for an analytic curve type.

public static func analyticCurvaturePoints(curveType: Int32, first: Double,
                                            last: Double) -> [CurvatureSpecialPoint]
  • Parameters: curveType — 0=Line, 1=Circle, 2=Ellipse, 3=Hyperbola, 4=Parabola. first/last — parameter domain.
  • Returns: Array of special points; empty if none found.
  • OCCT: LProp_AnalyticCurInf
  • Example:
    let pts = Shape.analyticCurvaturePoints(curveType: 2, first: 0, last: .pi)
    

TopTrans Surface Transition

TopologicalState

OCCT TopAbs_State mapping.

public enum TopologicalState: Int32, Sendable {
    case `in` = 0, out = 1, on = 2, unknown = 3
}

The point or curve lies strictly inside the boundary for `in` (TopAbs_IN, not independently documented below since `-escaped keyword case names aren’t headings this project’s own tooling resolves).

TopologicalState.out

The point or curve lies strictly outside the boundary (TopAbs_OUT).

case out = 1

TopologicalState.on

The point or curve lies exactly on the boundary element itself (TopAbs_ON).

case on = 2

TopologicalState.unknown

The transition analysis could not determine a state (TopAbs_UNKNOWN).

case unknown = 3

SurfaceTransitionResult

Result of a surface or curve transition analysis.

public struct SurfaceTransitionResult: Sendable {
    public let stateBefore: TopologicalState
    public let stateAfter: TopologicalState
}

SurfaceTransitionResult.stateBefore

The TopologicalState immediately before the curve crosses the surface or boundary element.

public let stateBefore: TopologicalState

SurfaceTransitionResult.stateAfter

The TopologicalState immediately after the curve crosses the surface or boundary element.

public let stateAfter: TopologicalState

Shape.surfaceTransition(tangent:normal:surfaceNormal:tolerance:surfaceOrientation:boundaryOrientation:)

Analyze topological state before and after a curve crosses a surface boundary.

public static func surfaceTransition(
    tangent: SIMD3<Double>, normal: SIMD3<Double>,
    surfaceNormal: SIMD3<Double>, tolerance: Double = 1e-6,
    surfaceOrientation: Int = 0, boundaryOrientation: Int = 0
) -> SurfaceTransitionResult
  • Parameters: tangent — curve tangent at crossing. normal — boundary normal. surfaceNormal — normal of the crossed surface. tolerance — angular tolerance. surfaceOrientation/boundaryOrientation — 0=FORWARD, 1=REVERSED.
  • Returns: States before and after the surface crossing.
  • OCCT: TopTrans_SurfaceTransition
  • Example:
    let r = Shape.surfaceTransition(tangent: t, normal: n, surfaceNormal: sn)
    

Shape.surfaceTransitionWithCurvature(...)

Extended surface transition analysis that accounts for surface curvature.

public static func surfaceTransitionWithCurvature(
    tangent: SIMD3<Double>, normal: SIMD3<Double>,
    maxDirection: SIMD3<Double>, minDirection: SIMD3<Double>,
    maxCurvature: Double, minCurvature: Double,
    surfaceNormal: SIMD3<Double>,
    surfaceMaxDirection: SIMD3<Double>, surfaceMinDirection: SIMD3<Double>,
    surfaceMaxCurvature: Double, surfaceMinCurvature: Double,
    tolerance: Double = 1e-6,
    surfaceOrientation: Int = 0, boundaryOrientation: Int = 0
) -> SurfaceTransitionResult
  • Parameters: Principal curvature directions and magnitudes for both the boundary and the surface at the crossing point, plus tangent and normals.
  • Returns: States before and after.
  • OCCT: TopTrans_SurfaceTransition (with curvature)
  • Example:
    let r = Shape.surfaceTransitionWithCurvature(
        tangent: t, normal: n,
        maxDirection: md, minDirection: nd,
        maxCurvature: k1, minCurvature: k2,
        surfaceNormal: sn,
        surfaceMaxDirection: smd, surfaceMinDirection: snd,
        surfaceMaxCurvature: sk1, surfaceMinCurvature: sk2)
    

TopTrans Curve Transition

Shape.curveTransition(tangent:boundaryTangent:boundaryNormal:curvature:tolerance:surfaceOrientation:boundaryOrientation:)

Analyze topological state before and after a curve crosses a boundary element.

public static func curveTransition(
    tangent: SIMD3<Double>,
    boundaryTangent: SIMD3<Double>, boundaryNormal: SIMD3<Double>,
    curvature: Double = 0.0, tolerance: Double = 1e-6,
    surfaceOrientation: Int = 0, boundaryOrientation: Int = 0
) -> SurfaceTransitionResult
  • Parameters: tangent — curve tangent. boundaryTangent/boundaryNormal — boundary element geometry. curvature — boundary curvature (0 for straight boundary).
  • Returns: SurfaceTransitionResult with before/after states.
  • OCCT: TopTrans_CurveTransition
  • Example:
    let r = Shape.curveTransition(tangent: t, boundaryTangent: bt, boundaryNormal: bn)
    

Shape.curveTransitionWithCurvature(tangent:curveNormal:curveCurvature:boundaryTangent:boundaryNormal:surfaceCurvature:tolerance:surfaceOrientation:boundaryOrientation:)

Curve transition analysis accounting for boundary curve curvature.

public static func curveTransitionWithCurvature(
    tangent: SIMD3<Double>,
    curveNormal: SIMD3<Double>, curveCurvature: Double,
    boundaryTangent: SIMD3<Double>, boundaryNormal: SIMD3<Double>,
    surfaceCurvature: Double, tolerance: Double = 1e-6,
    surfaceOrientation: Int = 0, boundaryOrientation: Int = 0
) -> SurfaceTransitionResult
  • Returns: SurfaceTransitionResult with before/after states.
  • OCCT: TopTrans_CurveTransition (with curvature)
  • Example:
    let r = Shape.curveTransitionWithCurvature(
        tangent: t, curveNormal: cn, curveCurvature: kc,
        boundaryTangent: bt, boundaryNormal: bn, surfaceCurvature: ks)
    

GeomFill Trihedrons

frenetTrihedron(at:)

Evaluate a Frenet trihedron on an edge at a parameter.

public func frenetTrihedron(at param: Double) -> (tangent: SIMD3<Double>, normal: SIMD3<Double>, binormal: SIMD3<Double>)?
  • Parameters: param — curve parameter.
  • Returns: Tuple of tangent, normal, binormal, or nil if the trihedron cannot be computed (e.g. inflection point).
  • OCCT: GeomFill_Frenet
  • Example:
    if let f = edge.frenetTrihedron(at: 0.5) {
        print(f.tangent, f.normal, f.binormal)
    }
    

constantBiNormalTrihedron(at:biNormal:)

Evaluate a constant-binormal trihedron on an edge at a parameter.

public func constantBiNormalTrihedron(at param: Double, biNormal: SIMD3<Double>) -> (tangent: SIMD3<Double>, normal: SIMD3<Double>, binormal: SIMD3<Double>)?
  • Parameters: param — curve parameter. biNormal — fixed binormal direction.
  • Returns: Trihedron tuple, or nil on failure.
  • OCCT: GeomFill_ConstantBiNormal
  • Example:
    if let f = edge.constantBiNormalTrihedron(at: 0.5, biNormal: SIMD3(0, 0, 1)) { }
    

Shape.fixedTrihedron(tangent:normal:at:)

Evaluate a fixed (constant) trihedron at any parameter.

public static func fixedTrihedron(tangent: SIMD3<Double>, normal: SIMD3<Double>, at param: Double = 0) -> (tangent: SIMD3<Double>, normal: SIMD3<Double>, binormal: SIMD3<Double>)
  • Parameters: tangent/normal — fixed trihedron directions. param — parameter (unused geometrically; for API consistency).
  • Returns: Trihedron tuple (binormal = tangent × normal).
  • OCCT: GeomFill_Fixed
  • Example:
    let f = Shape.fixedTrihedron(tangent: SIMD3(1,0,0), normal: SIMD3(0,1,0))
    

darbouxTrihedron(onFace:at:)

Evaluate a Darboux trihedron on an edge lying on a face.

public func darbouxTrihedron(onFace face: Shape, at param: Double) -> (tangent: SIMD3<Double>, normal: SIMD3<Double>, binormal: SIMD3<Double>)?
  • Parameters: face — the supporting face. param — curve parameter.
  • Returns: Darboux frame (tangent, surface normal, binormal), or nil on failure.
  • OCCT: GeomFill_Darboux
  • Example:
    if let f = edge.darbouxTrihedron(onFace: face, at: 0.5) { }
    

Polygon Interference

PolygonIntersection

Result of 2D polygon interference computation.

public struct PolygonIntersection: Sendable {
    public let points: [SIMD2<Double>]
}

Shape.polygonInterference(poly1:poly2:)

Compute intersection points between two 2D polylines.

public static func polygonInterference(
    poly1: [SIMD2<Double>], poly2: [SIMD2<Double>]
) -> PolygonIntersection
  • Parameters: poly1/poly2 — ordered arrays of 2D vertices defining each polyline.
  • Returns: PolygonIntersection with intersection points (may be empty).
  • OCCT: Intf_InterferencePolygon2d
  • Example:
    let result = Shape.polygonInterference(poly1: pts1, poly2: pts2)
    

Shape.polygonSelfInterference(polygon:)

Compute self-intersection points of a 2D polyline.

public static func polygonSelfInterference(
    polygon: [SIMD2<Double>]
) -> PolygonIntersection
  • Parameters: polygon — ordered 2D vertices.
  • Returns: Self-intersection points.
  • OCCT: Intf_InterferencePolygon2d (self-interference mode)
  • Example:
    let result = Shape.polygonSelfInterference(polygon: pts)
    

GccAna_Circ2d3Tan

Circle2DSolution

A circle solution from a GccAna tangency solver.

public struct Circle2DSolution: Sendable {
    public let centerX: Double
    public let centerY: Double
    public let radius: Double
}

Circle2DSolution.centerX

X coordinate of the solution circle’s center.

public let centerX: Double

Circle2DSolution.centerY

Y coordinate of the solution circle’s center.

public let centerY: Double

Circle2DSolution.radius

Radius of the solution circle.

public let radius: Double

Shape.circleThrough3Points(p1:p2:p3:tolerance:)

Find circles through 3 points (circumscribed circle).

public static func circleThrough3Points(
    p1: SIMD2<Double>, p2: SIMD2<Double>, p3: SIMD2<Double>,
    tolerance: Double = 1e-6
) -> [Circle2DSolution]
  • Returns: Array of circle solutions (typically 0 or 1).
  • OCCT: GccAna_Circ2d3Tan (3 points)
  • Example:
    let sols = Shape.circleThrough3Points(p1: SIMD2(0,0), p2: SIMD2(1,0), p3: SIMD2(0,1))
    

Shape.circleTangent3Lines(l1Point:l1Dir:l2Point:l2Dir:l3Point:l3Dir:tolerance:)

Find circles tangent to 3 lines.

public static func circleTangent3Lines(
    l1Point: SIMD2<Double>, l1Dir: SIMD2<Double>,
    l2Point: SIMD2<Double>, l2Dir: SIMD2<Double>,
    l3Point: SIMD2<Double>, l3Dir: SIMD2<Double>,
    tolerance: Double = 1e-6
) -> [Circle2DSolution]
  • Returns: Array of up to 8 tangent circles.
  • OCCT: GccAna_Circ2d3Tan (3 lines)
  • Example:
    let sols = Shape.circleTangent3Lines(
        l1Point: .zero, l1Dir: SIMD2(1,0),
        l2Point: SIMD2(0,1), l2Dir: SIMD2(1,0),
        l3Point: .zero, l3Dir: SIMD2(0,1))
    

Shape.circleTangent3Circles(c1Center:c1Radius:c2Center:c2Radius:c3Center:c3Radius:tolerance:)

Find circles tangent to 3 circles (Apollonius problem).

public static func circleTangent3Circles(
    c1Center: SIMD2<Double>, c1Radius: Double,
    c2Center: SIMD2<Double>, c2Radius: Double,
    c3Center: SIMD2<Double>, c3Radius: Double,
    tolerance: Double = 1e-6
) -> [Circle2DSolution]
  • Returns: Array of up to 8 solution circles.
  • OCCT: GccAna_Circ2d3Tan (3 circles)
  • Note: every radius must be positive (#553). A zero-radius argument is a point, and the solver does not answer the point question when it is given one: measured, it returns each solution twice, because tangency to a circle of radius zero satisfies the enclosing and the outside qualifier at once. Use circleTangent2CirclesPoint, circleTangentCircle2Points or circleThrough3Points to name a point as a point. A non-positive radius returns an empty array.
  • Example:
    let sols = Shape.circleTangent3Circles(
        c1Center: SIMD2(-2,0), c1Radius: 1,
        c2Center: SIMD2(2,0), c2Radius: 1,
        c3Center: SIMD2(0,2), c3Radius: 1)
    

Shape.circleTangent2CirclesPoint(c1Center:c1Radius:c2Center:c2Radius:point:tolerance:)

Find circles tangent to 2 circles and passing through 1 point.

public static func circleTangent2CirclesPoint(
    c1Center: SIMD2<Double>, c1Radius: Double,
    c2Center: SIMD2<Double>, c2Radius: Double,
    point: SIMD2<Double>, tolerance: Double = 1e-6
) -> [Circle2DSolution]
  • OCCT: GccAna_Circ2d3Tan (2 circles + point)
  • Note: both radii must be positive (#553). With a zero radius the solution set comes back padded with repeats: measured, four solutions holding two distinct circles.
  • Example:
    let sols = Shape.circleTangent2CirclesPoint(
        c1Center: .zero, c1Radius: 1,
        c2Center: SIMD2(3,0), c2Radius: 1,
        point: SIMD2(1.5, 2))
    

Shape.circleTangentCircle2Points(circleCenter:circleRadius:p1:p2:tolerance:)

Find circles tangent to 1 circle and passing through 2 points.

public static func circleTangentCircle2Points(
    circleCenter: SIMD2<Double>, circleRadius: Double,
    p1: SIMD2<Double>, p2: SIMD2<Double>, tolerance: Double = 1e-6
) -> [Circle2DSolution]
  • OCCT: GccAna_Circ2d3Tan (circle + 2 points)
  • Note: circleRadius must be positive (#553). This is the case where reading a zero-radius circle as a point fails outright: measured, the solver finds nothing at all, where circleThrough3Points on the same three positions finds the circle through them.
  • Example:
    let sols = Shape.circleTangentCircle2Points(
        circleCenter: .zero, circleRadius: 1,
        p1: SIMD2(3,0), p2: SIMD2(0,3))
    

Shape.circleTangent2LinesPoint(l1Point:l1Dir:l2Point:l2Dir:point:tolerance:)

Find circles tangent to 2 lines and passing through 1 point.

public static func circleTangent2LinesPoint(
    l1Point: SIMD2<Double>, l1Dir: SIMD2<Double>,
    l2Point: SIMD2<Double>, l2Dir: SIMD2<Double>,
    point: SIMD2<Double>, tolerance: Double = 1e-6
) -> [Circle2DSolution]
  • OCCT: GccAna_Circ2d3Tan (2 lines + point)
  • Example:
    let sols = Shape.circleTangent2LinesPoint(
        l1Point: .zero, l1Dir: SIMD2(1,0),
        l2Point: .zero, l2Dir: SIMD2(0,1),
        point: SIMD2(2,2))
    

IntTools

CommonPartType

Type of an edge-edge or edge-face intersection common part.

public enum CommonPartType: Int32, Sendable {
    case vertex = 0
    case edge = 1
}

CommonPart

A single intersection common part from IntTools.

public struct CommonPart: Sendable {
    public let type: CommonPartType
    public let param1Range: (first: Double, last: Double)
    public let param2Range: (first: Double, last: Double)
    public let point: SIMD3<Double>
}
field meaning
type .vertex or .edge: the kind of intersection found.
param1Range Parameter range (first, last) on the first edge; equal endpoints for a vertex intersection.
param2Range Parameter range (first, last) on the second edge; equal endpoints for a vertex intersection.
point Representative 3D point of the intersection.

(Per-field anchors below, for cross-reference; the table above has the actual meaning of each.)

param2Range


edgeEdgeIntersection(with:)

Intersect two edges to find common vertices and edge overlaps.

public func edgeEdgeIntersection(with other: Shape) -> [CommonPart]?
  • Parameters: other — second edge.
  • Returns: Array of common parts, or nil if intersection failed.
  • OCCT: IntTools_EdgeEdge
  • Example:
    if let parts = e1.edgeEdgeIntersection(with: e2) {
        for p in parts { print(p.type, p.point) }
    }
    

edgeFaceIntersection(with:)

Intersect an edge with a face to find common vertices and edge overlaps.

public func edgeFaceIntersection(with face: Shape) -> [CommonPart]?
  • Parameters: face — face to intersect with.
  • Returns: Array of common parts, or nil on failure.
  • OCCT: IntTools_EdgeFace
  • Example:
    if let parts = edge.edgeFaceIntersection(with: face) { }
    

FaceFaceCurve

An intersection curve from a face-face intersection.

public struct FaceFaceCurve: Sendable {
    public let start: SIMD3<Double>?
    public let end: SIMD3<Double>?
}

FaceFaceCurve.start

Start point of the intersection curve, or nil if the curve is unbounded.

public let start: SIMD3<Double>?

FaceFaceCurve.end

End point of the intersection curve, or nil if the curve is unbounded.

public let end: SIMD3<Double>?

FaceFacePoint

An intersection point from a face-face intersection.

public struct FaceFacePoint: Sendable {
    public let pointOnFace1: SIMD3<Double>
    public let pointOnFace2: SIMD3<Double>
}

FaceFacePoint.pointOnFace1

The coincident point’s coordinates as evaluated on the first face.

public let pointOnFace1: SIMD3<Double>

FaceFacePoint.pointOnFace2

The coincident point’s coordinates as evaluated on the second face.

public let pointOnFace2: SIMD3<Double>

FaceFaceResult

Result of a face-face intersection.

public struct FaceFaceResult: Sendable {
    public let curves: [FaceFaceCurve]
    public let points: [FaceFacePoint]
    public let isTangent: Bool
}
Field Meaning
curves Intersection curves between the two faces.
isTangent true if the two faces are tangent at the intersection rather than transversally crossing.

Shape.FaceFaceResult.isTangent


faceFaceIntersection(with:tolerance:)

Intersect two faces to find intersection curves and points.

public func faceFaceIntersection(with other: Shape, tolerance: Double = 1e-7) -> FaceFaceResult?
  • Parameters: other — second face. tolerance — approximation tolerance.
  • Returns: FaceFaceResult, or nil on failure.
  • OCCT: IntTools_FaceFace
  • Example:
    if let r = f1.faceFaceIntersection(with: f2) {
        print(r.curves.count, r.isTangent)
    }
    

classifyPoint2d(u:v:tolerance:)

Classify a UV point relative to a face boundary in parameter space.

public func classifyPoint2d(u: Double, v: Double, tolerance: Double = 1e-7) -> OCCTSwift.PointClassification
  • Parameters: u/v — UV coordinates. tolerance — classification tolerance.
  • Returns: .inside, .onBoundary, .outside, or .unknown.
  • OCCT: IntTools_FClass2d::Perform
  • Example:
    let c = face.classifyPoint2d(u: 0.5, v: 0.5)
    

isHole(tolerance:)

Check if a face represents a hole (inner-wire orientation).

public func isHole(tolerance: Double = 1e-7) -> Bool
  • Returns: true if the face is classified as a hole.
  • OCCT: IntTools_FClass2d (IsHole query)
  • Example:
    if face.isHole() { }
    

BOPAlgo Builder

buildFaces(from:)

Build faces from edges that lie on this face’s surface.

public func buildFaces(from edges: [Shape]) -> [Shape]?
  • Parameters: edges — edge shapes on this face’s surface.
  • Returns: Array of result face shapes, or nil on failure.
  • OCCT: BOPAlgo_BuilderFace
  • Example:
    if let faces = face.buildFaces(from: edges) { }
    

Shape.buildSolids(from:)

Build solids from a closed set of faces.

public static func buildSolids(from faces: [Shape]) -> [Shape]?
  • Parameters: faces — face shapes forming closed volumes.
  • Returns: Array of result solid shapes, or nil on failure.
  • OCCT: BOPAlgo_BuilderSolid
  • Example:
    if let solids = Shape.buildSolids(from: faces) { }
    

splitShell()

Split a shell into connected components.

public func splitShell() -> [Shape]?
  • Returns: Array of shell shapes (one per connected component), or nil on failure.
  • OCCT: BOPAlgo_ShellSplitter
  • Example:
    if let shells = shell.splitShell() { }
    

edgesToWires(tolerance:)

Connect a compound of edges into wires.

public func edgesToWires(tolerance: Double = 1e-7) -> Shape?
  • Parameters: tolerance — edge connection tolerance.
  • Returns: Compound of wires, or nil on failure.
  • OCCT: BOPAlgo_Tools::EdgesToWires
  • Example:
    if let wires = edgeCompound.edgesToWires() { }
    

wiresToFaces(tolerance:)

Build planar faces from a compound of wires.

public func wiresToFaces(tolerance: Double = 1e-7) -> Shape?
  • Parameters: tolerance — face building tolerance.
  • Returns: Compound of faces, or nil on failure.
  • OCCT: BOPAlgo_Tools::WiresToFaces
  • Example:
    if let faces = wireCompound.wiresToFaces() { }
    

BOPTools

Shape.normalOnEdge(edge:face:)

Get the normal to a face at an edge location.

public static func normalOnEdge(edge: Shape, face: Shape) -> SIMD3<Double>?
  • Parameters: edge — edge on the face. face — containing face.
  • Returns: Unit normal direction, or nil on failure.
  • OCCT: BOPTools_AlgoTools3D::GetNormalToFaceOnEdge
  • Example:
    if let n = Shape.normalOnEdge(edge: e, face: f) { }
    

pointInFace()

Find a point strictly inside this face.

public func pointInFace() -> SIMD3<Double>?
  • Returns: A 3D point in the interior of this face, or nil on failure.
  • OCCT: BOPTools_AlgoTools3D::PointInFace
  • Example:
    if let pt = face.pointInFace() { }
    

isEmpty

Check if this shape has no sub-shapes.

public var isEmpty: Bool { get }
  • OCCT: BOPTools_AlgoTools3D::IsEmptyShape
  • Example:
    if shape.isEmpty { }
    

isOpenShell

Check if this shell is open (not all edges shared by two faces).

public var isOpenShell: Bool { get }
  • OCCT: BOPTools_AlgoTools::IsOpenShell
  • Example:
    if shell.isOpenShell { }
    

IntTools_BeanFaceIntersector

BeanFaceIntersection

Result of an edge-face coincidence check.

public struct BeanFaceIntersection: Sendable {
    public let ranges: [(first: Double, last: Double)]
    public let minSquareDistance: Double
}
field meaning
ranges Coincident (first, last) parameter ranges on the edge curve where it lies on the face.
minSquareDistance Minimum squared distance between the edge curve and the face surface.

(Per-field anchors below, for cross-reference; the table above has the actual meaning of each.)

minSquareDistance


Shape.beanFaceIntersect(edge:face:)

Find coincident parameter ranges where an edge lies on a face surface.

public static func beanFaceIntersect(edge: Shape, face: Shape) -> BeanFaceIntersection?
  • Parameters: edge — edge curve to test. face — face surface to test against.
  • Returns: Ranges of coincidence and minimum squared distance, or nil on failure.
  • OCCT: IntTools_BeanFaceIntersector
  • Example:
    if let r = Shape.beanFaceIntersect(edge: e, face: f) {
        print(r.ranges.count, r.minSquareDistance)
    }
    

BOPAlgo_WireSplitter

Shape.makeWire(from:)

Assemble edges into a connected wire using BOPAlgo_WireSplitter.

public static func makeWire(from edges: [Shape]) -> Shape?
  • Parameters: edges — array of edge shapes to connect.
  • Returns: Result wire as shape, or nil on failure.
  • OCCT: BOPAlgo_WireSplitter::MakeWire
  • Example:
    if let wire = Shape.makeWire(from: [e1, e2, e3]) { }
    

BRepFeat_SplitShape

splitByEdge(_:onFace:)

Split this shape by adding an edge to a face.

public func splitByEdge(_ edge: Shape, onFace face: Shape) -> Shape?
  • Parameters: edge — edge to add as a split line. face — face the edge lies on.
  • Returns: Result shape with the split face, or nil on failure.
  • OCCT: BRepFeat_SplitShape
  • Example:
    if let split = solid.splitByEdge(e, onFace: face) { }
    

splitByWire(_:onFace:)

Split this shape by adding a wire to a face.

public func splitByWire(_ wire: Shape, onFace face: Shape) -> Shape?
  • Parameters: wire — wire to split along. face — face the wire lies on.
  • Returns: Result shape with split face, or nil on failure.
  • OCCT: BRepFeat_SplitShape
  • Example:
    if let split = solid.splitByWire(w, onFace: face) { }
    

SplitShapeResult

Result of a multi-pair split-shape operation.

public struct SplitShapeResult: Sendable {
    public let shape: Shape
    public let leftFaces: [Shape]
    public let rightFaces: [Shape]
}

SplitShapeResult.shape

The resulting shape after all edge-on-face pairs have been split in.

public let shape: Shape

SplitShapeResult.leftFaces

The faces BRepFeat_SplitShape::Left() classified as lying on the left side of the splitting edges.

public let leftFaces: [Shape]

SplitShapeResult.rightFaces

The faces BRepFeat_SplitShape::Right() classified as lying on the right side of the splitting edges.

public let rightFaces: [Shape]

splitWithSides(edgesOnFaces:)

Split this shape with multiple edge-on-face pairs, returning left/right face classifications.

public func splitWithSides(edgesOnFaces: [(edge: Shape, face: Shape)]) -> SplitShapeResult?
  • Parameters: edgesOnFaces — array of (edge, face) pairs; each edge is added to the corresponding face.
  • Returns: Split result with the resulting shape and left/right face arrays, or nil on failure.
  • OCCT: BRepFeat_SplitShape with Left()/Right() queries
  • Example:
    if let r = solid.splitWithSides(edgesOnFaces: [(edge: e, face: f)]) {
        print(r.leftFaces.count, r.rightFaces.count)
    }
    

BRepFeat_MakeCylindricalHole

OCCT’s dedicated feature-drilling operator. It wants a solid: every extent but .throughAll reports .invalidPlacement for a shell or a face.

This is a different contract from drilled(at:direction:radius:depth:), not a better one — #496 measured six requests where the two disagree. Reach for this family when the solid’s own faces should bound the hole, or when you need a diagnosis of why a drill is impossible; reach for drilled when the hole starts where you say it starts, when the input is not a solid, or when an over-long depth should simply drill through. Full measurements: Scripts/repro/496-drill-hole-contracts/.

radius must exceed Precision::Confusion (1e-7) for every spelling below. Under that, OCCT reports BRepFeat_NoError and hands back the undrilled input, so the bridge rejects it (#496).

CylindricalHoleExtent

How a feature-drilled hole is bounded. The five modes are not interchangeable.

public enum CylindricalHoleExtent: Sendable, Equatable {
    case throughAll
    case untilEnd
    case thruNext
    case blind(depth: Double)
    case range(from: Double, to: Double)
}
case OCCT bounded by
.throughAll Perform(R) nothing — an infinite cylinder, both ways along the axis. The origin anchors the axis; it is not where the hole starts. The only extent that tolerates a non-solid input.
.untilEnd PerformUntilEnd(R) the stock’s own first and last faces along the axis. The forward-bounded through hole most callers reach for .throughAll expecting.
.thruNext PerformThruNext(R) the next face after the origin.
.blind(depth:) PerformBlind(R, depth) depth, measured from the axis origin. The only extent that can report .holeTooLong: a depth that would leave the far side of the stock is refused rather than drilled through.
.range(from:to:) Perform(R, PFrom, PTo) the entry/exit face pair the parameter window selects.

.range is the subtle one: the window chooses a face pair, it does not trim the cut. A window lying strictly inside one body still drills all the way through that body; a window naming no face pair (the gap between two plates) is .invalidPlacement. Its use is picking which body to drill in a stack — a window over one plate drills that plate, one spanning several drills all of them.

On a stack, every extent that bounds the hole by the stock’s own faces drills every body the axis crosses: .untilEnd, a spanning .range, .throughAll and drilled(at:…) all agree. Until the kernel patch carried for #532 they did not — .untilEnd, .range and .blind(depth:) reported .noError while removing no material at all, because OCCT selected which piece of its drilling tool to keep from the cut result rather than from the split tool.

The three cases the table above covers are .thruNext, .untilEnd, .range(from:to:) and .blind(depth:); .blind bores to a fixed depth from the placement, and .range is the one whose two parameters are measured along the axis rather than from the face.

bridgeParameters (var bridgeParameters: (mode: Int32, p0: Double, p1: Double)) is internal, not public API: it is the (mode, p0, p1) triple the bridge call reads, one row per case above.


cylindricalHole(axisOrigin:axisDirection:radius:extent:)

Drill a cylindrical hole bounded by extent.

public func cylindricalHole(axisOrigin: SIMD3<Double>, axisDirection: SIMD3<Double>,
                            radius: Double, extent: CylindricalHoleExtent) -> Shape?
  • Parameters: axisOrigin — hole axis origin. axisDirection — hole axis direction, any non-zero vector. radius — hole radius, above Precision::Confusion. extent — where the hole stops.
  • Returns: Shape with hole, or nil on failure. Ask cylindricalHoleStatus(…extent:) when you need to know why; nil collapses every reason into one.
  • OCCT: BRepFeat_MakeCylindricalHole::Perform / PerformUntilEnd / PerformThruNext / PerformBlind, per extent
  • Example:
    let plate = Shape.box(width: 50, height: 50, depth: 20)!
    let origin = SIMD3<Double>(0, 0, 15)   // 5mm above the top face
    let axis = SIMD3<Double>(0, 0, -1)
    
    // Bounded by the plate's own entry and exit faces:
    let through = plate.cylindricalHole(axisOrigin: origin, axisDirection: axis,
                                        radius: 5, extent: .untilEnd)
    
    // A 6mm-deep blind hole, measured from the origin — so 1mm into the plate:
    let blind = plate.cylindricalHole(axisOrigin: origin, axisDirection: axis,
                                      radius: 5, extent: .blind(depth: 6))
    

cylindricalHoleStatus(axisOrigin:axisDirection:radius:extent:)

Ask what the matching drill would report, without building the result.

public func cylindricalHoleStatus(axisOrigin: SIMD3<Double>, axisDirection: SIMD3<Double>,
                                  radius: Double,
                                  extent: CylindricalHoleExtent) -> CylindricalHoleStatus

The extent is part of the question, because the answer depends on it: a radius wider than the whole solid is .noError for .throughAll and .invalidPlacement for .thruNext, and .holeTooLong exists only under .blind(depth:).

  • Returns: .noError if and only if cylindricalHole(…extent:) would return a shape for the same request.
  • OCCT: BRepFeat_MakeCylindricalHole::Status after the matching Perform*
  • Example:
    let origin = SIMD3<Double>(0, 0, 11), axis = SIMD3<Double>(0, 0, -1)
    if plate.cylindricalHoleStatus(axisOrigin: origin, axisDirection: axis,
                                   radius: 5, extent: .blind(depth: 100)) == .holeTooLong {
        // too deep for this stock — drill it through instead
    }
    

CylindricalHoleStatus

Status result for a cylindrical hole operation.

public enum CylindricalHoleStatus: Int32, Sendable {
    case noError = 0
    case invalidPlacement = 1
    case holeTooLong = 2
    case unknown = 3
}
  • .invalidPlacement also covers a request with no axis direction, or a radius at or below Precision::Confusion.
  • .holeTooLong is reachable only through .blind(depth:).

CylindricalHoleStatus.noError

The request is drillable.

case noError = 0

CylindricalHoleStatus.invalidPlacement

The axis does not meet the shape in a way this extent can use, including a request with no axis direction, or a radius at or below Precision::Confusion.

case invalidPlacement = 1

CylindricalHoleStatus.holeTooLong

A .blind(depth:) depth that would leave the far side of the stock. Only that extent produces this status.

case holeTooLong = 2

CylindricalHoleStatus.unknown

OCCT raised something the bridge does not recognise.

case unknown = 3

cylindricalHole(axisOrigin:axisDirection:radius:)

Drill a through cylindrical hole in this shape. Convenience for extent: .throughAll.

public func cylindricalHole(axisOrigin: SIMD3<Double>, axisDirection: SIMD3<Double>, radius: Double) -> Shape?
  • Parameters: axisOrigin — hole axis origin. axisDirection — hole axis direction. radius — hole radius.
  • Returns: Shape with hole, or nil on failure.
  • OCCT: BRepFeat_MakeCylindricalHole::Perform — an infinite cylinder both ways along the axis. For a hole bounded by the stock’s own faces, use extent: .untilEnd.
  • Example:
    if let holed = solid.cylindricalHole(axisOrigin: .zero, axisDirection: SIMD3(0,0,1), radius: 5) { }
    

cylindricalHoleBlind(axisOrigin:axisDirection:radius:depth:)

Drill a blind cylindrical hole to a specified depth. Convenience for extent: .blind(depth:).

public func cylindricalHoleBlind(axisOrigin: SIMD3<Double>, axisDirection: SIMD3<Double>, radius: Double, depth: Double) -> Shape?
  • Parameters: depth — hole depth, measured from the axis origin.
  • Returns: Shape with blind hole, or nil on failure — including a depth that would leave the far side of the stock, which is refused rather than drilled through (.holeTooLong).
  • OCCT: BRepFeat_MakeCylindricalHole::PerformBlind
  • Example:
    if let holed = solid.cylindricalHoleBlind(axisOrigin: .zero, axisDirection: SIMD3(0,0,1), radius: 5, depth: 10) { }
    

cylindricalHoleThruNext(axisOrigin:axisDirection:radius:)

Drill a cylindrical hole through to the next face encountered. Convenience for extent: .thruNext.

public func cylindricalHoleThruNext(axisOrigin: SIMD3<Double>, axisDirection: SIMD3<Double>, radius: Double) -> Shape?
  • Returns: Shape with hole stopping at the first inner face, or nil on failure.
  • OCCT: BRepFeat_MakeCylindricalHole::PerformThruNext
  • Example:
    if let holed = solid.cylindricalHoleThruNext(axisOrigin: .zero, axisDirection: SIMD3(0,1,0), radius: 3) { }
    

cylindricalHoleStatus(axisOrigin:axisDirection:radius:)

Check whether a through-all cylindrical hole can be drilled, without modifying the shape.

public func cylindricalHoleStatus(axisOrigin: SIMD3<Double>, axisDirection: SIMD3<Double>, radius: Double) -> CylindricalHoleStatus

Answers for .throughAll only. Pass the extent you are actually about to drill to cylindricalHoleStatus(…extent:) — this spelling reports .noError for requests that cylindricalHoleThruNext and cylindricalHoleBlind then refuse.

  • Returns: A CylindricalHoleStatus indicating through-all feasibility.
  • OCCT: BRepFeat_MakeCylindricalHole (status query)
  • Example:
    let s = solid.cylindricalHoleStatus(axisOrigin: .zero, axisDirection: SIMD3(0,0,1), radius: 5)
    if s == .noError { }
    

BRepFeat_Gluer

glue(_:facePairs:)

Glue another shape onto this shape by binding matching face pairs.

public func glue(_ gluedShape: Shape, facePairs: [(base: Shape, glued: Shape)]) -> Shape?
  • Parameters: gluedShape — shape to merge onto this one. facePairs — matching face pairs: base from this shape, glued from gluedShape.
  • Returns: Glued result shape, or nil on failure.
  • OCCT: BRepFeat_Gluer
  • Example:
    if let r = base.glue(toAttach, facePairs: [(base: bf, glued: gf)]) { }
    

LocOpe_WiresOnShape + LocOpe_Spliter

LocOpeSplitResult

Result of a LocOpe_Spliter operation.

public struct LocOpeSplitResult: Sendable {
    public let shape: Shape
    public let directLeftFaces: [Shape]
}

LocOpeSplitResult.shape

The resulting shape after all wire-on-face pairs have been split in.

public let shape: Shape

LocOpeSplitResult.directLeftFaces

The faces LocOpe_Spliter::DirectLeft() classified as lying directly to the left of the splitting wires.

public let directLeftFaces: [Shape]

locOpeSplit(wiresOnFaces:)

Split this shape by projecting wires onto specific faces using LocOpe_Spliter.

public func locOpeSplit(wiresOnFaces: [(wire: Shape, face: Shape)]) -> LocOpeSplitResult?
  • Parameters: wiresOnFaces — pairs binding each wire to the face it lies on.
  • Returns: Split result with direct-left faces, or nil on failure.
  • OCCT: LocOpe_WiresOnShape + LocOpe_Spliter
  • Note: Each pair contributes only the first wire of its wire shape. A pair whose shape holds several wires binds one of them and ignores the rest; give each wire its own pair. A pair whose shape holds no wire at all is skipped silently. (#443 audit)
  • Example:
    if let r = solid.locOpeSplit(wiresOnFaces: [(wire: w, face: f)]) {
        print(r.directLeftFaces.count)
    }
    

locOpeSplitAuto(wires:)

Split this shape by automatically projecting wires onto faces.

public func locOpeSplitAuto(wires: [Shape]) -> Shape?
  • Parameters: wires — wires to project and split by; faces are determined automatically.
  • Returns: Result shape, or nil on failure.
  • OCCT: LocOpe_WiresOnShape::BindAll + LocOpe_Spliter
  • Example:
    if let r = solid.locOpeSplitAuto(wires: [w]) { }
    

LocOpe_Gluer

locOpeGlue(_:facePairs:edgePairs:)

Glue another shape onto this shape using LocOpe_Gluer with optional edge binding.

public func locOpeGlue(_ gluedShape: Shape,
                       facePairs: [(base: Shape, glued: Shape)],
                       edgePairs: [(base: Shape, glued: Shape)] = []) -> Shape?
  • Parameters: gluedShape — shape to glue. facePairs — at least one required matching face pair. edgePairs — optional edge pairs for precise alignment.
  • Returns: Result shape, or nil on failure (including empty facePairs).
  • OCCT: LocOpe_Gluer
  • Example:
    if let r = base.locOpeGlue(toGlue, facePairs: [(base: bf, glued: gf)]) { }
    

ChFi2d_Builder

All ChFi2d_Builder methods operate exclusively on planar faces, not solids. Extract the target face first if working from a solid.

addFillet2d(vertexIndex:radius:)

Add a 2D fillet at a vertex on a planar face.

public func addFillet2d(vertexIndex: Int, radius: Double) -> Shape?
  • Parameters: vertexIndex — 0-based vertex index. radius — fillet radius.
  • Returns: Result face with fillet, or nil if the shape is not a planar face.
  • OCCT: ChFi2d_Builder::AddFillet
  • Example:
    let face = solid.subShapes(ofType: .face)[0]
    if let filleted = face.addFillet2d(vertexIndex: 0, radius: 1.0) { }
    

addChamfer2d(edge1Index:edge2Index:d1:d2:)

Add a 2D chamfer between two edges on a planar face.

public func addChamfer2d(edge1Index: Int, edge2Index: Int, d1: Double, d2: Double) -> Shape?
  • Parameters: edge1Index/edge2Index — 0-based edge indices. d1/d2 — chamfer distances on each edge.
  • Returns: Result face with chamfer, or nil on failure.
  • OCCT: ChFi2d_Builder::AddChamfer
  • Example:
    if let ch = face.addChamfer2d(edge1Index: 0, edge2Index: 1, d1: 1.0, d2: 1.0) { }
    

addChamfer2dAngle(edgeIndex:vertexIndex:distance:angle:)

Add a 2D chamfer defined by distance and angle on a planar face.

public func addChamfer2dAngle(edgeIndex: Int, vertexIndex: Int, distance: Double, angle: Double) -> Shape?
  • Parameters: edgeIndex — reference edge. vertexIndex — vertex to chamfer. distance — distance on the edge. angle — chamfer angle in radians.
  • Returns: Result face with chamfer, or nil on failure.
  • OCCT: ChFi2d_Builder::AddChamfer (distance + angle)
  • Example:
    if let ch = face.addChamfer2dAngle(edgeIndex: 0, vertexIndex: 1, distance: 1.0, angle: .pi/4) { }
    

modifyFillet2d(originalFace:filletEdgeIndex:newRadius:)

Modify an existing fillet radius on a face.

public func modifyFillet2d(originalFace: Shape, filletEdgeIndex: Int, newRadius: Double) -> Shape?
  • Parameters: originalFace — face before the fillet was added. filletEdgeIndex — 0-based index of the fillet edge in self. newRadius — new fillet radius.
  • Returns: Result face with modified fillet, or nil on failure.
  • OCCT: ChFi2d_Builder::ModifyFillet
  • Example:
    if let modified = filletedFace.modifyFillet2d(originalFace: original, filletEdgeIndex: 0, newRadius: 2.0) { }
    

removeFillet2d(originalFace:filletEdgeIndex:)

Remove a fillet from a face, restoring the original corner.

public func removeFillet2d(originalFace: Shape, filletEdgeIndex: Int) -> Shape?
  • Parameters: originalFace — face before the fillet. filletEdgeIndex — 0-based fillet edge index in self.
  • Returns: Face with fillet removed, or nil on failure.
  • OCCT: ChFi2d_Builder::RemoveFillet
  • Example:
    if let r = filletedFace.removeFillet2d(originalFace: original, filletEdgeIndex: 0) { }
    

removeChamfer2d(originalFace:chamferEdgeIndex:)

Remove a chamfer from a face.

public func removeChamfer2d(originalFace: Shape, chamferEdgeIndex: Int) -> Shape?
  • Parameters: originalFace — face before the chamfer. chamferEdgeIndex — 0-based chamfer edge index in self.
  • Returns: Face with chamfer removed, or nil on failure.
  • OCCT: ChFi2d_Builder::RemoveChamfer
  • Example:
    if let r = chamferedFace.removeChamfer2d(originalFace: original, chamferEdgeIndex: 0) { }
    

ChFi2d_ChamferAPI

Chamfer2DEdgeResult

Result of a standalone 2D chamfer between two edges.

public struct Chamfer2DEdgeResult: Sendable {
    public let chamferEdge: Shape
    public let modifiedEdge1: Shape
    public let modifiedEdge2: Shape
}

Chamfer2DEdgeResult.chamferEdge

The new chamfer edge connecting the two trimmed originals.

public let chamferEdge: Shape

Chamfer2DEdgeResult.modifiedEdge1

edge1, trimmed back by d1 to meet the chamfer edge.

public let modifiedEdge1: Shape

Chamfer2DEdgeResult.modifiedEdge2

edge2, trimmed back by d2 to meet the chamfer edge.

public let modifiedEdge2: Shape

Shape.chamfer2dEdges(edge1:edge2:d1:d2:)

Create a chamfer between two linear edges using ChFi2d_ChamferAPI.

public static func chamfer2dEdges(edge1: Shape, edge2: Shape, d1: Double, d2: Double) -> Chamfer2DEdgeResult?
  • Parameters: edge1/edge2 — linear edges sharing a vertex. d1/d2 — chamfer distances on each edge.
  • Returns: Chamfer2DEdgeResult with chamfer edge and trimmed originals, or nil on failure.
  • OCCT: ChFi2d_ChamferAPI
  • Example:
    if let r = Shape.chamfer2dEdges(edge1: e1, edge2: e2, d1: 1.0, d2: 1.0) {
        let chamfer = r.chamferEdge
    }
    

ChFi2d_FilletAPI

Fillet2DEdgeResult

Result of a standalone 2D fillet between two edges.

public struct Fillet2DEdgeResult: Sendable {
    public let filletEdge: Shape
    public let modifiedEdge1: Shape
    public let modifiedEdge2: Shape
    public let solutionCount: Int
}
Field Meaning
filletEdge The new fillet arc edge.
modifiedEdge1 edge1, trimmed to meet the fillet arc.
modifiedEdge2 edge2, trimmed to meet the fillet arc.

Shape.Fillet2DEdgeResult.modifiedEdge2


Shape.fillet2dEdges(edge1:edge2:planeNormal:radius:nearPoint:)

Create a fillet between two edges in a plane using ChFi2d_FilletAPI.

public static func fillet2dEdges(edge1: Shape, edge2: Shape,
                                 planeNormal: SIMD3<Double>,
                                 radius: Double,
                                 nearPoint: SIMD3<Double>) -> Fillet2DEdgeResult?
  • Parameters: edge1/edge2 — edges to fillet. planeNormal — normal of the plane containing the edges. radius — fillet radius. nearPoint — point near the desired fillet location, used to select among multiple solutions.
  • Returns: Fillet2DEdgeResult with the fillet arc, trimmed edges, and solution count, or nil on failure.
  • OCCT: ChFi2d_FilletAPI (selects analytical or iterative algorithm automatically)
  • Example:
    if let r = Shape.fillet2dEdges(
        edge1: e1, edge2: e2,
        planeNormal: SIMD3(0, 0, 1),
        radius: 2.0,
        nearPoint: SIMD3(1, 1, 0)) {
        print(r.solutionCount)
    }
    

FilletSurf_Builder

FilletSurfaceInfo

Geometry information for one computed fillet surface.

public struct FilletSurfaceInfo: Sendable {
    public let surface: Surface
    public let supportFace1: Shape
    public let supportFace2: Shape
    public let tolerance: Double
    public let firstParameter: Double
    public let lastParameter: Double
    public let startStatus: Int
    public let endStatus: Int
}
Field Meaning
supportFace1 The first of the two original faces this fillet surface blends between.
supportFace2 The second of the two original faces this fillet surface blends between.
tolerance Geometric tolerance achieved for this fillet surface.
startStatus FilletSurf_Builder status code at the fillet’s start extremity (0 = ok, 1 = not ok, 2 = partial).
endStatus FilletSurf_Builder status code at the fillet’s end extremity (0 = ok, 1 = not ok, 2 = partial).

Shape.FilletSurfaceInfo.endStatus


FilletSurfaceResult

Result of FilletSurf_Builder computation.

public struct FilletSurfaceResult: Sendable {
    public let surfaces: [FilletSurfaceInfo]
    public let status: Int  // 0=ok, 1=notOk, 2=partial
}
Field Meaning
surfaces One FilletSurfaceInfo per requested edge that produced a fillet surface.

Shape.FilletSurfaceResult.surfaces


filletSurfaces(edges:radius:)

Compute fillet surface geometry on this shape without modifying its topology.

public func filletSurfaces(edges: [Shape], radius: Double) -> FilletSurfaceResult?
  • Parameters: edges — edges to fillet. radius — fillet radius.
  • Returns: FilletSurfaceResult with NURBS fillet surfaces and support faces, or nil on total failure. status == 1 with an empty surfaces array also maps to nil.
  • OCCT: FilletSurf_Builder
  • Note: Returns raw surface geometry only; does not produce a new solid. Use Shape.filleted(edges:radius:) to produce a filleted solid.
  • Example:
    if let r = solid.filletSurfaces(edges: [e1, e2], radius: 1.0) {
        for info in r.surfaces {
            print(info.surface, info.tolerance)
        }
    }