Shape — Geometry Recognition & Polygon/Triangulation Data
This page documents the geometry-utility and polygon/triangulation public API from Sources/OCCTSwift/Shape.swift (lines 11078–12192). It covers coordinate-system helpers, curve/surface construction utilities, 2D constraint solvers, shape modification tools, and the full polygon and triangulation layer. See the main Shape page for the core B-Rep API.
Topics
- Axis2Placement · ShapeConstruct_Curve extensions · Bisector utilities · GeomLib_Tool — Parameter Finding · GeomLib_IsPlanarSurface · GeomLib_CheckBSplineCurve / Check2dBSplineCurve · GeomLib_Interpolate · GccAna_Circ2d2TanRad · GccAna_Circ2dTanCen · GccAna_Lin2d2Tan · Approx_SameParameter · ShapeUpgrade Curve Splitting · Shape Modifications · Surface Splitting · Curve/Surface Recognition · Polygon2D · Triangulation · Polygon3D · PolygonOnTriangulation · Mesh Node Merging
Axis2Placement
A standalone Swift class wrapping Geom_Axis2Placement — a right-handed 3D coordinate system with an origin, a main (Z) direction, and an X direction. Used to define placement frames for geometry factories.
Axis2Placement.init(origin:normal:xDirection:)
Creates a right-handed 3D axis placement.
public init(origin: SIMD3<Double>, normal: SIMD3<Double>, xDirection: SIMD3<Double>)
- Parameters:
origin— origin point;normal— main (Z) direction;xDirection— X direction (must not be parallel tonormal). - OCCT:
Geom_Axis2Placement(gp_Pnt, gp_Dir main, gp_Dir xDir)viaOCCTAxis2PlacementCreate. - Example:
let ax = Axis2Placement(origin: SIMD3(0, 0, 10), normal: SIMD3(0, 0, 1), xDirection: SIMD3(1, 0, 0))
location
The origin of this placement.
public var location: SIMD3<Double> { get }
- Returns: The origin point.
- OCCT:
Geom_Axis2Placement::LocationviaOCCTAxis2PlacementLocation.
mainDirection
The main (Z) direction of this placement.
public var mainDirection: SIMD3<Double> { get }
- Returns: The main axis direction.
- OCCT:
Geom_Axis2Placement::DirectionviaOCCTAxis2PlacementDirection.
xDirection
The X direction of this placement.
public var xDirection: SIMD3<Double> { get }
- Returns: The X-axis direction.
- OCCT:
Geom_Axis2Placement::XDirectionviaOCCTAxis2PlacementXDirection.
yDirection
The Y direction of this placement (computed from main × X).
public var yDirection: SIMD3<Double> { get }
- Returns: The Y-axis direction.
- OCCT:
Geom_Axis2Placement::YDirectionviaOCCTAxis2PlacementYDirection.
setDirection(_:)
Sets the main (Z) direction in place.
public func setDirection(_ dir: SIMD3<Double>)
- Parameters:
dir— new main direction. - OCCT:
Geom_Axis2Placement::SetDirectionviaOCCTAxis2PlacementSetDirection.
setXDirection(_:)
Sets the X direction in place.
public func setXDirection(_ dir: SIMD3<Double>)
- Parameters:
dir— new X direction (must not be parallel to the main direction). - OCCT:
Geom_Axis2Placement::SetXDirectionviaOCCTAxis2PlacementSetXDirection.
ShapeConstruct_Curve extensions
Extensions on Curve3D and Curve2D that expose ShapeConstruct_Curve utilities for B-Spline conversion and endpoint adjustment.
Curve3D.convertSegmentToBSpline(first:last:precision:)
Converts a segment of this 3D curve to a BSpline using ShapeConstruct_Curve.
public func convertSegmentToBSpline(first: Double, last: Double,
precision: Double = 1e-6) -> Curve3D?
- Parameters:
first— start parameter;last— end parameter;precision— geometric tolerance. - Returns: New
Curve3Das a BSpline, ornilon failure. - OCCT:
ShapeConstruct_Curve::ConvertToBSplineviaOCCTShapeConstructConvertToBSpline3D. - Example:
if let bsp = curve.convertSegmentToBSpline(first: 0, last: 1) { print(bsp.degree) }
Curve3D.adjustEndpoints(start:end:)
Adjusts the 3D curve endpoints to match given 3D points.
public func adjustEndpoints(start: SIMD3<Double>, end: SIMD3<Double>) -> Bool
- Parameters:
start— desired start point;end— desired end point. - Returns:
trueon success. - OCCT:
ShapeConstruct_Curve::AdjustCurveviaOCCTShapeConstructAdjustCurve3D.
Curve2D.convertSegmentToBSpline(first:last:precision:)
Converts a segment of this 2D curve to a BSpline using ShapeConstruct_Curve.
public func convertSegmentToBSpline(first: Double, last: Double,
precision: Double = 1e-6) -> Curve2D?
- Parameters:
first— start parameter;last— end parameter;precision— geometric tolerance. - Returns: New
Curve2Das a BSpline, ornilon failure. - OCCT:
ShapeConstruct_Curve::ConvertToBSplineviaOCCTShapeConstructConvertToBSpline2D.
Curve2D.adjustEndpoints(start:end:)
Adjusts the 2D curve endpoints to match given 2D points.
public func adjustEndpoints(start: (Double, Double), end: (Double, Double)) -> Bool
- Parameters:
start— desired start point as(x, y);end— desired end point as(x, y). - Returns:
trueon success. - OCCT:
ShapeConstruct_Curve::AdjustCurve2dviaOCCTShapeConstructAdjustCurve2D.
Bisector utilities
Free-function bisector utilities and their associated value types.
BisectorPoint
Point on a bisector curve with parameter and distance information.
public struct BisectorPoint {
public let paramOnC1: Double
public let paramOnC2: Double
public let paramOnBis: Double
public let distance: Double
public let x: Double
public let y: Double
public let isInfinite: Bool
}
BisectorIntersection
Result of a bisector-vs-bisector intersection computation.
public struct BisectorIntersection {
public let x: Double
public let y: Double
public let paramOnFirst: Double
public let paramOnSecond: Double
}
bisectorIntersections(a:b:c:d:)
Computes intersections between the perpendicular bisectors of two point pairs.
public func bisectorIntersections(
a: (Double, Double), b: (Double, Double),
c: (Double, Double), d: (Double, Double)
) -> [BisectorIntersection]
The bisector of (a, b) is intersected with the bisector of (c, d). The result is the circumcenter when the two pairs form a triangle.
- Parameters:
a,b— first point pair;c,d— second point pair, all as(x, y). - Returns: Array of intersection points (zero, one, or two).
- OCCT:
Bisector_BisecCC/Bisector_InterviaOCCTBisectorInterPointPoint. - Example:
let hits = bisectorIntersections(a: (0, 0), b: (4, 0), c: (4, 0), d: (2, 3)) // hits[0] is the circumcenter of the triangle
GeomLib_Tool — Parameter Finding
Extensions on Curve3D, Surface, and Curve2D for locating parameter values corresponding to 3D/2D points.
Curve3D.parameterOf(point:maxDistance:)
Finds the parameter of a 3D point on this curve.
public func parameterOf(point: SIMD3<Double>, maxDistance: Double = 1.0) -> Double?
- Parameters:
point— 3D point to locate;maxDistance— maximum allowed distance from the curve. - Returns: Parameter value, or
nilif the point lies farther thanmaxDistancefrom the curve. - OCCT:
GeomLib_Tool::ParameterviaOCCTGeomLibToolParameter3D. - Example:
if let t = curve.parameterOf(point: SIMD3(1, 2, 3), maxDistance: 0.01) { let pt = curve.point(at: t) }
Surface.parametersOf(point:maxDistance:)
Finds the UV parameters of a 3D point on this surface.
public func parametersOf(point: SIMD3<Double>, maxDistance: Double = 1.0) -> (u: Double, v: Double)?
- Parameters:
point— 3D point to locate;maxDistance— maximum allowed distance from the surface. - Returns:
(u, v)parameter tuple, ornilif the point lies farther thanmaxDistance. - OCCT:
GeomLib_Tool::ParametersviaOCCTGeomLibToolParametersSurface. - Example:
let s = Surface.sphere(center: .zero, radius: 5)! if let uv = s.parametersOf(point: SIMD3(5, 0, 0), maxDistance: 0.1) { print(uv.u, uv.v) }
Curve2D.parameterOf(point:maxDistance:)
Finds the parameter of a 2D point on this curve.
public func parameterOf(point: SIMD2<Double>, maxDistance: Double = 1.0) -> Double?
- Parameters:
point— 2D point to locate;maxDistance— maximum allowed distance from the curve. - Returns: Parameter value, or
nilif the point is too far from the curve. - OCCT:
GeomLib_Tool::ParameterviaOCCTGeomLibToolParameter2D.
GeomLib_IsPlanarSurface
Extensions on Surface for planarity testing.
Surface.isPlanar(tolerance:)
Checks if this surface is planar within a given tolerance.
public func isPlanar(tolerance: Double = 1e-7) -> Bool
- Parameters:
tolerance— planarity tolerance. - Returns:
trueif the surface is planar withintolerance. - OCCT:
GeomLib_IsPlanarSurface::IsPlanarviaOCCTGeomLibIsPlanarSurface. - Example:
let plane = Surface.plane(origin: .zero, normal: SIMD3(0, 0, 1))! print(plane.isPlanar()) // true
Surface.planarPlane(tolerance:)
Returns the underlying plane parameters if this surface is planar.
public func planarPlane(tolerance: Double = 1e-7) -> (origin: SIMD3<Double>, normal: SIMD3<Double>, xDirection: SIMD3<Double>)?
- Parameters:
tolerance— planarity tolerance. - Returns: Tuple of
(origin, normal, xDirection)if planar,nilotherwise. - OCCT:
GeomLib_IsPlanarSurface::PlaneviaOCCTGeomLibPlanarSurfacePlane. - Example:
if let plane = surface.planarPlane() { print(plane.normal) }
GeomLib_CheckBSplineCurve / Check2dBSplineCurve
Extensions on Curve3D and Curve2D for detecting and fixing reversed end tangents on BSpline curves.
Curve3D.checkBSplineTangents(tolerance:angularTolerance:)
Checks if this BSpline curve has reversed end tangents.
public func checkBSplineTangents(tolerance: Double = 0.01,
angularTolerance: Double = 0.1) -> (fixFirst: Bool, fixLast: Bool)?
- Parameters:
tolerance— positional tolerance;angularTolerance— angular tolerance in radians. - Returns:
(fixFirst, fixLast)indicating which ends need fixing, ornilif not a BSpline or check failed. - OCCT:
GeomLib_CheckBSplineCurveviaOCCTGeomLibCheckBSpline3D.
Curve3D.fixBSplineTangents(fixFirst:fixLast:tolerance:angularTolerance:)
Fixes reversed end tangents on a BSpline curve.
public func fixBSplineTangents(fixFirst: Bool, fixLast: Bool,
tolerance: Double = 0.01,
angularTolerance: Double = 0.1) -> Curve3D?
- Parameters:
fixFirst— fix the start tangent;fixLast— fix the end tangent;tolerance— positional tolerance;angularTolerance— angular tolerance. - Returns: New
Curve3Dwith corrected tangents, ornilon failure. - OCCT:
GeomLib_CheckBSplineCurve::FixTangentviaOCCTGeomLibFixBSpline3D. - Example:
if let flags = curve.checkBSplineTangents(), (flags.fixFirst || flags.fixLast) { let fixed = curve.fixBSplineTangents(fixFirst: flags.fixFirst, fixLast: flags.fixLast) }
Curve2D.checkBSplineTangents(tolerance:angularTolerance:)
Checks if this 2D BSpline curve has reversed end tangents.
public func checkBSplineTangents(tolerance: Double = 0.01,
angularTolerance: Double = 0.1) -> (fixFirst: Bool, fixLast: Bool)?
- Parameters:
tolerance— positional tolerance;angularTolerance— angular tolerance. - Returns:
(fixFirst, fixLast)flags, ornilif not a BSpline or check failed. - OCCT:
GeomLib_Check2dBSplineCurveviaOCCTGeomLibCheckBSpline2D.
Curve2D.fixBSplineTangents(fixFirst:fixLast:tolerance:angularTolerance:)
Fixes reversed end tangents on a 2D BSpline curve.
public func fixBSplineTangents(fixFirst: Bool, fixLast: Bool,
tolerance: Double = 0.01,
angularTolerance: Double = 0.1) -> Curve2D?
- Parameters:
fixFirst— fix the start tangent;fixLast— fix the end tangent;tolerance— positional tolerance;angularTolerance— angular tolerance. - Returns: Fixed
Curve2D, ornilon failure. - OCCT:
GeomLib_Check2dBSplineCurve::FixTangentviaOCCTGeomLibFixBSpline2D.
GeomLib_Interpolate
Curve3D.polynomialInterpolation(degree:points:parameters:)
Creates a BSpline curve by polynomial interpolation of 3D points at given parameters.
public static func polynomialInterpolation(degree: Int, points: [SIMD3<Double>],
parameters: [Double]) -> Curve3D?
points and parameters must have equal counts (≥ 2). The parameter values define how the polynomial fits progress along the curve.
- Parameters:
degree— polynomial degree;points— interpolation points;parameters— parameter values corresponding to each point. - Returns: Interpolated BSpline
Curve3D, ornilif counts mismatch or interpolation fails. - OCCT:
GeomLib_InterpolateviaOCCTGeomLibInterpolate. - Example:
let pts: [SIMD3<Double>] = [SIMD3(0,0,0), SIMD3(5,3,0), SIMD3(10,0,0)] let params: [Double] = [0, 0.5, 1] if let c = Curve3D.polynomialInterpolation(degree: 2, points: pts, parameters: params) { let pt = c.point(at: 0.25) }
GccAna_Circ2d2TanRad
Free functions and supporting types for computing 2D circles tangent to two lines or through two points with a given radius.
Circle2DSolution
A 2D circle solution returned by circle construction functions.
public struct Circle2DSolution: Sendable {
public let center: SIMD2<Double>
public let radius: Double
}
circlesTangentToLines(_:_:_:_:radius:tolerance:)
Finds circles tangent to two 2D lines with a given radius.
public func circlesTangentToLines(_ l1Origin: SIMD2<Double>, _ l1Direction: SIMD2<Double>,
_ l2Origin: SIMD2<Double>, _ l2Direction: SIMD2<Double>,
radius: Double, tolerance: Double = 1e-6) -> [Circle2DSolution]
- Parameters:
l1Origin,l1Direction— first line (point + direction);l2Origin,l2Direction— second line;radius— required circle radius;tolerance— geometric tolerance. - Returns: Array of up to four
Circle2DSolutionvalues (may be empty if no solution exists). - OCCT:
GccAna_Circ2d2TanRad(Lin+Lin variant) viaOCCTGccAnaCirc2d2TanRadLineLin. - Example:
let circles = circlesTangentToLines(SIMD2(0,0), SIMD2(1,0), SIMD2(0,0), SIMD2(0,1), radius: 3)
circlesThroughPointsWithRadius(_:_:radius:tolerance:)
Finds circles passing through two 2D points with a given radius.
public func circlesThroughPointsWithRadius(_ p1: SIMD2<Double>, _ p2: SIMD2<Double>,
radius: Double,
tolerance: Double = 1e-6) -> [Circle2DSolution]
- Parameters:
p1,p2— two points to pass through;radius— required circle radius;tolerance— geometric tolerance. - Returns: Array of up to two
Circle2DSolutionvalues. - OCCT:
GccAna_Circ2d2TanRad(Pnt+Pnt variant) viaOCCTGccAnaCirc2d2TanRadPntPnt. - Example:
let circles = circlesThroughPointsWithRadius(SIMD2(-3, 0), SIMD2(3, 0), radius: 5)
GccAna_Circ2dTanCen
Free functions for computing 2D circles with a given centre.
circleThroughPointCentered(point:center:)
Finds the circle centered at a given point that passes through another point.
public func circleThroughPointCentered(point: SIMD2<Double>,
center: SIMD2<Double>) -> Circle2DSolution?
- Parameters:
point— a point on the circle;center— the required circle centre. - Returns: A
Circle2DSolution, ornilif no solution exists. - OCCT:
GccAna_Circ2dTanCen(Pnt+Pnt variant) viaOCCTGccAnaCirc2dTanCenPntPnt. - Example:
if let c = circleThroughPointCentered(point: SIMD2(5, 0), center: .zero) { print(c.radius) // 5.0 }
circleTangentToLineCentered(lineOrigin:lineDirection:center:)
Finds the circle centred at a given point that is tangent to a line.
public func circleTangentToLineCentered(lineOrigin: SIMD2<Double>,
lineDirection: SIMD2<Double>,
center: SIMD2<Double>) -> Circle2DSolution?
- Parameters:
lineOrigin— a point on the line;lineDirection— line direction;center— required circle centre. - Returns: A
Circle2DSolution, ornilif no solution exists. - OCCT:
GccAna_Circ2dTanCen(Lin+Pnt variant) viaOCCTGccAnaCirc2dTanCenLinPnt. - Example:
if let c = circleTangentToLineCentered(lineOrigin: SIMD2(0, 3), lineDirection: SIMD2(1, 0), center: SIMD2(2, 0)) { print(c.radius) // 3.0 }
GccAna_Lin2d2Tan
Free functions and supporting types for 2D line construction.
Line2DSolution
A 2D line solution returned by line construction functions.
public struct Line2DSolution: Sendable {
public let origin: SIMD2<Double>
public let direction: SIMD2<Double>
}
lineThroughPoints(_:_:tolerance:)
Finds the line passing through two 2D points.
public func lineThroughPoints(_ p1: SIMD2<Double>, _ p2: SIMD2<Double>,
tolerance: Double = 1e-6) -> Line2DSolution?
- Parameters:
p1,p2— two points;tolerance— geometric tolerance. - Returns: A
Line2DSolution, ornilif the points coincide within tolerance. - OCCT:
GccAna_Lin2d2Tan(Pnt+Pnt variant) viaOCCTGccAnaLin2d2TanPntPnt. - Example:
if let line = lineThroughPoints(SIMD2(0, 0), SIMD2(1, 1)) { print(line.direction) }
linesTangentToCircleThroughPoint(circleCenter:circleRadius:point:tolerance:)
Finds lines tangent to a circle and passing through a given point.
public func linesTangentToCircleThroughPoint(circleCenter: SIMD2<Double>,
circleRadius: Double,
point: SIMD2<Double>,
tolerance: Double = 1e-6) -> [Line2DSolution]
- Parameters:
circleCenter,circleRadius— the circle;point— point the line must pass through;tolerance— geometric tolerance. - Returns: Array of up to two
Line2DSolutionvalues (one if the point lies on the circle). - OCCT:
GccAna_Lin2d2Tan(Circ+Pnt variant) viaOCCTGccAnaLin2d2TanCircPnt. - Example:
let tangents = linesTangentToCircleThroughPoint(circleCenter: .zero, circleRadius: 3, point: SIMD2(5, 0))
Approx_SameParameter
SameParameterResult
Result of a same-parameterisation check between a 3D curve and a 2D curve on a surface.
public struct SameParameterResult: Sendable {
public let isSameParameter: Bool
public let toleranceReached: Double
}
toleranceReached is the maximum distance between the 3D curve and the surface-evaluated 2D curve.
Curve3D.checkSameParameter(curve2D:surface:tolerance:)
Checks if a 2D curve on a surface has the same parameterisation as this 3D curve.
public func checkSameParameter(curve2D: Curve2D, surface: Surface,
tolerance: Double = 1e-6) -> SameParameterResult?
- Parameters:
curve2D— the 2D curve;surface— the surface;tolerance— parameterisation tolerance. - Returns:
SameParameterResult, ornilif the check fails. - OCCT:
Approx_SameParameterviaOCCTApproxSameParameter. - Example:
if let r = curve3d.checkSameParameter(curve2D: pcurve, surface: face.surface!) { print(r.isSameParameter, r.toleranceReached) }
ShapeUpgrade Curve Splitting
Extensions on Curve3D and Curve2D for splitting by continuity and converting to Bezier or arc/segment decompositions.
Curve3D.splitByContinuity(criterion:tolerance:)
Splits this 3D curve at continuity breaks.
public func splitByContinuity(criterion: Int = 2, tolerance: Double = 1e-6) -> [Curve3D]
- Parameters:
criterion— continuity criterion: 0=C0, 1=C1, 2=C2, 3=C3, 4=CN;tolerance— geometric tolerance. - Returns: Array of
Curve3Dsegments; may be a single-element array if no breaks are found. - OCCT:
ShapeUpgrade_SplitCurve3dContinuityviaOCCTSplitCurve3dContinuity. - Example:
let segments = curve.splitByContinuity(criterion: 1)
Curve2D.splitByContinuity(criterion:tolerance:)
Splits this 2D curve at continuity breaks.
public func splitByContinuity(criterion: Int = 2, tolerance: Double = 1e-6) -> [Curve2D]
- Parameters:
criterion— continuity criterion: 0=C0, 1=C1, 2=C2, 3=C3, 4=CN;tolerance— geometric tolerance. - Returns: Array of
Curve2Dsegments. - OCCT:
ShapeUpgrade_SplitCurve2dContinuityviaOCCTSplitCurve2dContinuity.
Curve2D.convertToBezierSegments()
Converts this 2D curve to Bezier segments via ShapeUpgrade.
public func convertToBezierSegments() -> [Curve2D]
- Returns: Array of
Curve2DBezier segments. Returns an empty array on failure. - OCCT:
ShapeUpgrade_ConvertCurve2dToBezierviaOCCTConvertCurve2dToBezier.
Curve2D.approxArcsAndSegments(tolerance:angleTolerance:)
Approximates this 2D curve as a sequence of arcs and line segments.
public func approxArcsAndSegments(tolerance: Double, angleTolerance: Double) -> [Curve2D]
- Parameters:
tolerance— positional approximation tolerance;angleTolerance— angular tolerance in radians. - Returns: Array of
Curve2Darcs and segments. Returns an empty array on failure. - OCCT:
Geom2dConvert_ApproxArcsSegmentsviaOCCTGeom2dConvertApproxArcsSegments.
Shape Modifications
Shape extension methods wrapping BRepTools modification helpers.
Shape.trsfModification(_:a11:a12:a13:a14:a21:a22:a23:a24:a31:a32:a33:a34:)
Applies a 3×4 affine transformation matrix to a shape via BRepTools_TrsfModification.
public static func trsfModification(_ shape: Shape,
a11: Double, a12: Double, a13: Double, a14: Double,
a21: Double, a22: Double, a23: Double, a24: Double,
a31: Double, a32: Double, a33: Double, a34: Double) -> Shape?
The matrix is specified row-major. Supports uniform scaling and rotation but not non-uniform scaling; use gtrsfModification for general affine transforms.
- Parameters:
shape— input shape;a11…a34— row-major 3×4 transformation matrix coefficients. - Returns: Transformed shape, or
nilon failure. - OCCT:
BRepTools_TrsfModificationviaOCCTShapeTrsfModification. - Example:
// Translate by (10, 0, 0) if let moved = Shape.trsfModification(box, a11: 1, a12: 0, a13: 0, a14: 10, a21: 0, a22: 1, a23: 0, a24: 0, a31: 0, a32: 0, a33: 1, a34: 0) { // use moved }
Shape.gtrsfModification(_:a11:a12:a13:a14:a21:a22:a23:a24:a31:a32:a33:a34:)
Applies a general (non-uniform) 3×4 transformation matrix via BRepTools_GTrsfModification.
public static func gtrsfModification(_ shape: Shape,
a11: Double, a12: Double, a13: Double, a14: Double,
a21: Double, a22: Double, a23: Double, a24: Double,
a31: Double, a32: Double, a33: Double, a34: Double) -> Shape?
Supports non-uniform scaling. Convert the shape to NURBS first for non-affine transforms to ensure geometry validity.
- Parameters:
shape— input shape;a11…a34— row-major 3×4 matrix. - Returns: Transformed shape, or
nilon failure. - OCCT:
BRepTools_GTrsfModificationviaOCCTShapeGTrsfModification.
Shape.deepCopy(_:copyGeometry:copyMesh:)
Creates a deep copy of a shape via BRepTools_CopyModification.
public static func deepCopy(_ shape: Shape,
copyGeometry: Bool = true,
copyMesh: Bool = true) -> Shape?
- Parameters:
shape— shape to copy;copyGeometry— whether to copy underlying geometry;copyMesh— whether to copy cached triangulations. - Returns: Independent deep copy, or
nilon failure. - OCCT:
BRepTools_CopyModificationviaOCCTShapeCopyModification. - Example:
if let copy = Shape.deepCopy(original) { // Modifications to copy do not affect original }
Shape.bsplineRestrictionAdvanced(_:approxSurface:approxCurve3d:approxCurve2d:tol3d:tol2d:continuity3d:continuity2d:maxDegree:maxSegments:priorityDegree:convertRational:)
Restricts BSpline degree and segment count in a shape with fine-grained control.
public static func bsplineRestrictionAdvanced(_ shape: Shape,
approxSurface: Bool = true,
approxCurve3d: Bool = true,
approxCurve2d: Bool = true,
tol3d: Double = 0.01,
tol2d: Double = 0.01,
continuity3d: Int = 2,
continuity2d: Int = 2,
maxDegree: Int = 5,
maxSegments: Int = 20,
priorityDegree: Bool = true,
convertRational: Bool = false) -> Shape?
- Parameters:
approxSurface/approxCurve3d/approxCurve2d— which geometry types to process;tol3d/tol2d— tolerances;continuity3d/continuity2d— required continuity (0=C0…6=CN);maxDegree— maximum polynomial degree;maxSegments— maximum segment count;priorityDegree—true= reduce degree first,false= reduce segments first;convertRational— convert rational BSplines to non-rational. - Returns: Restricted shape, or
nilon failure. - OCCT:
ShapeUpgrade_ConvertSurfaceToBSplineSurface/ShapeUpgrade_BSplineRestrictionviaOCCTShapeBSplineRestrictionAdvanced.
Shape.convertToBSplineAdvanced(_:extrusionMode:revolutionMode:offsetMode:planeMode:)
Converts surfaces in a shape to BSpline with per-type control.
public static func convertToBSplineAdvanced(_ shape: Shape,
extrusionMode: Bool = true,
revolutionMode: Bool = true,
offsetMode: Bool = true,
planeMode: Bool = false) -> Shape?
- Parameters:
extrusionMode— convert extrusion surfaces;revolutionMode— convert revolution surfaces;offsetMode— convert offset surfaces;planeMode— convert planes. - Returns: Shape with BSpline surfaces, or
nilon failure. - OCCT:
ShapeUpgrade_ConvertSurfaceToBSplineSurfaceviaOCCTShapeConvertToBSplineAdvanced.
Surface Splitting
Surface extension for splitting surfaces by continuity, angle, or area.
Surface.SplitResult
Result of a surface splitting operation.
public struct SplitResult: Sendable {
public let uSplitCount: Int
public let vSplitCount: Int
}
Surface.splitSurfaceByContinuity(criterion:tolerance:)
Splits this surface at continuity breaks.
public func splitSurfaceByContinuity(criterion: Int, tolerance: Double) -> SplitResult?
- Parameters:
criterion— continuity criterion: 0=C0, 1=G1, 2=C1, 3=G2, 4=C2, 5=C3, 6=CN;tolerance— geometric tolerance. - Returns:
SplitResultwith U and V split counts, ornilif no splits are found. - OCCT:
ShapeUpgrade_SplitSurface/ continuity variant viaOCCTSplitSurfaceContinuity.
Surface.splitByAngle(_:)
Splits this surface where the normal varies by more than a maximum angle.
public func splitByAngle(_ maxAngle: Double) -> SplitResult?
- Parameters:
maxAngle— maximum allowed normal deviation in radians. - Returns:
SplitResult, ornilif no splits are needed. - OCCT:
ShapeUpgrade_SplitSurfaceAngleviaOCCTSplitSurfaceAngle.
Surface.splitByArea(parts:intoSquares:)
Splits this surface into approximately equal-area parts.
public func splitByArea(parts: Int, intoSquares: Bool = false) -> SplitResult?
- Parameters:
parts— desired number of parts;intoSquares— iftrue, target square patches. - Returns:
SplitResult, ornilon failure. - OCCT:
ShapeUpgrade_SplitSurfaceAreaviaOCCTSplitSurfaceArea.
Curve/Surface Recognition
Types and extensions for recognising and converting geometry to analytical (canonical) forms.
CurveToAnalyticalResult
Result of converting a 3D curve to its analytical form.
public struct CurveToAnalyticalResult: Sendable {
public let curve: Curve3D
public let newFirst: Double
public let newLast: Double
public let gap: Double
}
gap is the maximum deviation between the original and the recognized analytical curve.
Curve3D.toAnalytical(tolerance:first:last:)
Attempts to convert this curve to an analytical form (line, circle, ellipse, etc.).
public func toAnalytical(tolerance: Double, first: Double, last: Double) -> CurveToAnalyticalResult?
- Parameters:
tolerance— recognition tolerance;first,last— parameter range to examine. - Returns:
CurveToAnalyticalResultwith the simplified curve and gap, ornilif no analytical form is recognised. - OCCT:
GeomConvert_CurveToAnaCurveviaOCCTGeomConvertCurveToAnalytical. - Example:
if let r = bsplineCurve.toAnalytical(tolerance: 1e-4, first: 0, last: 1) { print(r.curve.curveKind, r.gap) }
Curve3D.arePointsLinear(_:tolerance:)
Checks whether a set of 3D points are collinear within a tolerance.
public static func arePointsLinear(_ points: [SIMD3<Double>],
tolerance: Double) -> (isLinear: Bool, deviation: Double)
- Parameters:
points— array of 3D points;tolerance— collinearity tolerance. - Returns:
(isLinear, deviation)—isLinearindicates collinearity;deviationis the maximum perpendicular distance from the best-fit line. - OCCT:
GeomConvert_ConvType::IsLinearviaOCCTGeomConvertIsLinear. - Example:
let pts: [SIMD3<Double>] = [.zero, SIMD3(1,0,0), SIMD3(2,0,0)] let (linear, dev) = Curve3D.arePointsLinear(pts, tolerance: 1e-6) // linear == true, dev ≈ 0
SurfaceToAnalyticalResult
Result of converting a surface to its analytical form.
public struct SurfaceToAnalyticalResult: Sendable {
public let surface: Surface
public let gap: Double
}
Surface.toAnalyticalWithGap(tolerance:)
Attempts to convert this surface to an analytical form.
public func toAnalyticalWithGap(tolerance: Double) -> SurfaceToAnalyticalResult?
- Parameters:
tolerance— recognition tolerance. - Returns:
SurfaceToAnalyticalResultwith the simplified surface and deviation, ornilif no analytical form is recognised. - OCCT:
GeomConvert_SurfToAnaSurfviaOCCTGeomConvertSurfToAnalytical. - Example:
if let r = bsplineSurface.toAnalyticalWithGap(tolerance: 1e-5) { print(r.surface.surfaceKind, r.gap) }
Surface.toAnalyticalWithGap(tolerance:uMin:uMax:vMin:vMax:)
Attempts to convert this surface to an analytical form within UV bounds.
public func toAnalyticalWithGap(tolerance: Double,
uMin: Double, uMax: Double,
vMin: Double, vMax: Double) -> SurfaceToAnalyticalResult?
- Parameters:
tolerance— recognition tolerance;uMin,uMax,vMin,vMax— UV parameter bounds to consider. - Returns:
SurfaceToAnalyticalResult, ornilon failure. - OCCT:
GeomConvert_SurfToAnaSurf(bounded variant) viaOCCTGeomConvertSurfToAnalyticalBounded.
Surface.isCanonical
Whether this surface is already in a canonical (analytical) form.
public var isCanonical: Bool { get }
- Returns:
trueif the surface is a plane, sphere, cylinder, cone, or torus rather than a BSpline. - OCCT:
GeomConvert_ConvType::IsCanonicalviaOCCTGeomConvertIsCanonical.
Polygon2D
Polygon2D is a standalone Swift class wrapping Poly_Polygon2D — a sequence of 2D points used to represent a parametric-space polygon on a face.
Polygon2D.create(points:)
Creates a 2D polygon from an array of 2D points.
public static func create(points: [SIMD2<Double>]) -> Polygon2D?
- Parameters:
points— ordered sequence of 2D points. - Returns:
Polygon2D, ornilon failure. - OCCT:
Poly_Polygon2DviaOCCTPolyPolygon2DCreate. - Example:
if let poly = Polygon2D.create(points: [SIMD2(0,0), SIMD2(1,0), SIMD2(0.5,1)]) { print(poly.nodeCount) // 3 }
Polygon2D.nodeCount
The number of nodes in this polygon.
public var nodeCount: Int { get }
- OCCT:
Poly_Polygon2D::NbNodesviaOCCTPolyPolygon2DNbNodes.
Polygon2D.node(at:)
Returns the 2D point at a given 0-based index.
public func node(at index: Int) -> SIMD2<Double>?
- Parameters:
index— 0-based node index. - Returns:
SIMD2<Double>position, ornilif the index is out of range. - OCCT:
Poly_Polygon2D::NodesviaOCCTPolyPolygon2DNode.
Polygon2D.nodes()
Returns all nodes.
public func nodes() -> [SIMD2<Double>]
- Returns: Array of all 2D node positions in sequence order.
Polygon2D.deflection
The deflection value associated with this polygon.
public var deflection: Double { get set }
- OCCT:
Poly_Polygon2D::Deflection/SetDeflectionviaOCCTPolyPolygon2DDeflection/OCCTPolyPolygon2DSetDeflection.
Polygon2D.copy()
Creates a deep copy of this polygon.
public func copy() -> Polygon2D?
- Returns: Independent copy, or
nilon failure. - OCCT:
Poly_Polygon2D::CopyviaOCCTPolyPolygon2DCopy.
Triangulation
Triangulation wraps Poly_Triangulation — a 3D mesh defined by node positions and triangle vertex indices. Used as input to TopologyGraph.createTriangulationRep(_:) for populating the cached mesh tier of a graph. Triangle indices are 0-based on the Swift boundary; the bridge converts to OCCT’s 1-based representation internally.
Triangulation.create(nodes:triangles:)
Creates a triangulation from node positions and triangle vertex indices.
public static func create(nodes: [SIMD3<Double>], triangles: [Int]) -> Triangulation?
- Parameters:
nodes— 3D node positions;triangles— triangle vertex indices, 0-based, three per triangle (triangles.countmust be a multiple of 3). - Returns:
Triangulation, ornilif inputs are empty,triangles.countis not a multiple of 3, or any index is out of range. - OCCT:
Poly_Triangulation(nbNodes, nbTriangles)viaOCCTPolyTriangulationCreate. - Example:
let nodes: [SIMD3<Double>] = [SIMD3(0,0,0), SIMD3(1,0,0), SIMD3(0,1,0)] if let tri = Triangulation.create(nodes: nodes, triangles: [0, 1, 2]) { print(tri.triangleCount) // 1 }
Triangulation.nodeCount
The number of nodes.
public var nodeCount: Int { get }
- OCCT:
Poly_Triangulation::NbNodesviaOCCTPolyTriangulationNbNodes.
Triangulation.triangleCount
The number of triangles.
public var triangleCount: Int { get }
- OCCT:
Poly_Triangulation::NbTrianglesviaOCCTPolyTriangulationNbTriangles.
Triangulation.node(at:)
Returns the 3D position of a node at a given 0-based index.
public func node(at index: Int) -> SIMD3<Double>?
- Parameters:
index— 0-based node index. - Returns: Node position, or
nilif out of range. - OCCT:
Poly_Triangulation::NodeviaOCCTPolyTriangulationNode.
Triangulation.triangle(at:)
Returns the three 0-based vertex indices for a triangle.
public func triangle(at index: Int) -> (Int, Int, Int)?
- Parameters:
index— 0-based triangle index. - Returns: Tuple of three 0-based node indices, or
nilif out of range. - OCCT:
Poly_Triangulation::TriangleviaOCCTPolyTriangulationTriangle. - Example:
if let (n0, n1, n2) = tri.triangle(at: 0) { let p0 = tri.node(at: n0) }
Triangulation.deflection
The deflection value of this triangulation.
public var deflection: Double { get set }
- OCCT:
Poly_Triangulation::Deflection/SetDeflectionviaOCCTPolyTriangulationDeflection/OCCTPolyTriangulationSetDeflection.
Polygon3D
Polygon3D wraps Poly_Polygon3D — a sequence of 3D points with optional curve parameters, used to represent an edge approximation in 3D space.
Polygon3D.create(points:)
Creates a 3D polygon from an array of 3D points.
public static func create(points: [SIMD3<Double>]) -> Polygon3D?
- Parameters:
points— ordered sequence of 3D points. - Returns:
Polygon3D, ornilon failure. - OCCT:
Poly_Polygon3DviaOCCTPolyPolygon3DCreate.
Polygon3D.create(points:parameters:)
Creates a 3D polygon with curve parameters.
public static func create(points: [SIMD3<Double>], parameters: [Double]) -> Polygon3D?
- Parameters:
points— ordered 3D points;parameters— corresponding curve parameter values (must have the same count aspoints). - Returns:
Polygon3Dwith parameters, ornilon failure. - OCCT:
Poly_Polygon3D(parameterised overload) viaOCCTPolyPolygon3DCreateWithParams. - Example:
let pts: [SIMD3<Double>] = [SIMD3(0,0,0), SIMD3(5,0,0), SIMD3(10,0,0)] let params: [Double] = [0, 0.5, 1] if let poly = Polygon3D.create(points: pts, parameters: params) { print(poly.hasParameters) // true }
Polygon3D.nodeCount
The number of nodes.
public var nodeCount: Int { get }
- OCCT:
Poly_Polygon3D::NbNodesviaOCCTPolyPolygon3DNbNodes.
Polygon3D.node(at:)
Returns the 3D position at a given 0-based node index.
public func node(at index: Int) -> SIMD3<Double>?
- Parameters:
index— 0-based node index. - Returns: Node position, or
nilif out of range. - OCCT:
Poly_Polygon3D::NodesviaOCCTPolyPolygon3DNode.
Polygon3D.nodes()
Returns all nodes.
public func nodes() -> [SIMD3<Double>]
- Returns: Array of all 3D node positions in sequence order.
Polygon3D.hasParameters
Whether this polygon has curve parameters.
public var hasParameters: Bool { get }
- OCCT:
Poly_Polygon3D::HasParametersviaOCCTPolyPolygon3DHasParameters.
Polygon3D.parameter(at:)
Returns the curve parameter at a given 0-based index.
public func parameter(at index: Int) -> Double
- Parameters:
index— 0-based index. - Returns: The curve parameter value. Returns 0 if
hasParametersisfalse. - OCCT:
Poly_Polygon3D::ParameterviaOCCTPolyPolygon3DParameter.
Polygon3D.deflection
The deflection value of this polygon.
public var deflection: Double { get set }
- OCCT:
Poly_Polygon3D::Deflection/SetDeflectionviaOCCTPolyPolygon3DDeflection/OCCTPolyPolygon3DSetDeflection.
PolygonOnTriangulation
PolygonOnTriangulation wraps Poly_PolygonOnTriangulation — a polygon defined as a sequence of indices into a shared Triangulation, with optional curve parameters. Used to associate an edge’s 2D approximation with a face triangulation.
PolygonOnTriangulation.create(nodeIndices:)
Creates a polygon from node indices into a triangulation.
public static func create(nodeIndices: [Int32]) -> PolygonOnTriangulation?
- Parameters:
nodeIndices— array of 0-based node indices into the associated triangulation. - Returns:
PolygonOnTriangulation, ornilon failure. - OCCT:
Poly_PolygonOnTriangulationviaOCCTPolyPolygonOnTriCreate.
PolygonOnTriangulation.create(nodeIndices:parameters:)
Creates a polygon from node indices with curve parameters.
public static func create(nodeIndices: [Int32], parameters: [Double]) -> PolygonOnTriangulation?
- Parameters:
nodeIndices— 0-based node indices;parameters— corresponding curve parameter values. - Returns:
PolygonOnTriangulationwith parameters, ornilon failure. - OCCT:
Poly_PolygonOnTriangulation(parameterised overload) viaOCCTPolyPolygonOnTriCreateWithParams. - Example:
if let poly = PolygonOnTriangulation.create(nodeIndices: [0, 5, 12], parameters: [0, 0.5, 1]) { print(poly.nodeCount) // 3 }
PolygonOnTriangulation.nodeCount
The number of nodes referenced by this polygon.
public var nodeCount: Int { get }
- OCCT:
Poly_PolygonOnTriangulation::NbNodesviaOCCTPolyPolygonOnTriNbNodes.
PolygonOnTriangulation.nodeIndex(at:)
Returns the triangulation node index at a given 0-based position.
public func nodeIndex(at position: Int) -> Int
- Parameters:
position— 0-based position in the polygon’s node sequence. - Returns: 0-based index into the associated triangulation’s node array.
- OCCT:
Poly_PolygonOnTriangulation::NodeviaOCCTPolyPolygonOnTriNode.
PolygonOnTriangulation.hasParameters
Whether this polygon has curve parameters.
public var hasParameters: Bool { get }
- OCCT:
Poly_PolygonOnTriangulation::HasParametersviaOCCTPolyPolygonOnTriHasParameters.
PolygonOnTriangulation.parameter(at:)
Returns the curve parameter at a given 0-based index.
public func parameter(at index: Int) -> Double
- Parameters:
index— 0-based index. - Returns: The curve parameter value. Returns 0 if
hasParametersisfalse. - OCCT:
Poly_PolygonOnTriangulation::ParameterviaOCCTPolyPolygonOnTriParameter.
PolygonOnTriangulation.deflection
The deflection value of this polygon.
public var deflection: Double { get set }
- OCCT:
Poly_PolygonOnTriangulation::Deflection/SetDeflectionviaOCCTPolyPolygonOnTriDeflection/OCCTPolyPolygonOnTriSetDeflection.
PolygonOnTriangulation.copy()
Creates a deep copy of this polygon.
public func copy() -> PolygonOnTriangulation?
- Returns: Independent copy, or
nilon failure. - OCCT:
Poly_PolygonOnTriangulation::CopyviaOCCTPolyPolygonOnTriCopy.
PolygonOnTriangulation.setNodes(_:)
Overwrites the node-index array in place.
@discardableResult
public func setNodes(_ nodeIndices: [Int32]) -> Bool
The supplied array must have the same length as nodeCount.
- Parameters:
nodeIndices— replacement node index array (same count asnodeCount). - Returns:
trueon success,falseon size mismatch. - OCCT:
Poly_PolygonOnTriangulation::ChangeNodeArrayviaOCCTPolyPolygonOnTriSetNodes.
PolygonOnTriangulation.setParameters(_:)
Overwrites the parameter array in place.
@discardableResult
public func setParameters(_ params: [Double]) -> Bool
Requires hasParameters == true and the array length must equal nodeCount.
- Parameters:
params— replacement parameter array. - Returns:
trueon success,falseifhasParametersisfalseor lengths mismatch. - OCCT:
Poly_PolygonOnTriangulation::ChangeParameterArrayviaOCCTPolyPolygonOnTriSetParameters.
Mesh Node Merging
MergedMeshData
Output of merging triangulation nodes across all faces of a meshed shape.
public struct MergedMeshData: Sendable {
public let vertices: [SIMD3<Float>]
public let normals: [SIMD3<Float>]
public let indices: [UInt32]
public let triangleCount: Int
public let vertexCount: Int
}
Normals are computed per merged vertex using the smoothAngle threshold.
mergedMeshNodes(from:smoothAngle:mergeTolerance:)
Merges nodes from all face triangulations of a meshed shape into a single indexed mesh suitable for GPU upload.
public func mergedMeshNodes(from shape: Shape,
smoothAngle: Double,
mergeTolerance: Double = 0.0) -> MergedMeshData?
- Parameters:
shape— a shape that has been triangulated (e.g., viaMesh.from(shape:));smoothAngle— normal-smoothing angle threshold in radians;mergeTolerance— distance threshold for merging nodes (0 = positional identity only). - Returns:
MergedMeshDatawith interleaved vertex, normal, and index arrays, ornilif the shape has no triangulation or the output would exceed 1 000 000 vertices / 3 000 000 indices. - OCCT:
BRep_Builderface iteration +Poly_TriangulationviaOCCTPolyMergeNodes. - Example:
let shape = Shape.box(dx: 10, dy: 10, dz: 10)! _ = Mesh.from(shape: shape, deflection: 0.1) if let mesh = mergedMeshNodes(from: shape, smoothAngle: .pi / 6) { // Upload mesh.vertices and mesh.indices to a Metal vertex buffer print(mesh.vertexCount, mesh.triangleCount) }