DistanceConvention::Unsupported currently covers three curve families, and one of them does not belong there: a polyline has an exact closed-form arc length, unlike an ellipse or a B-spline.
What refuses today
let curve = Curve3::Polyline(Polyline3 {
points: vec![
Point3::new(0.0, 0.0, 0.0),
Point3::new(3.0, 4.0, 0.0), // 5 m
Point3::new(3.0, 4.0, 12.0), // 12 m
],
closed: false,
});
ev.distance_convention(&curve); // Unsupported
ev.point_at(&curve, CurveMeasure::Distance(5.0));
// Err(Unsupported { backend: "axiolid-evaluate", operation: CurveEvaluation })
The answer at 5 m is exactly (3, 4, 0). No integral, no iteration.
Why the three families are not alike
The shipped rationale groups them together:
Ellipse, BSpline and Polyline have no closed-form arc length (the ellipse needs an elliptic integral), so distance is refused rather than approximated behind an exact-looking signature.
That is right for two of them and wrong for the third.
| Family |
Arc length |
Cost |
Ellipse |
incomplete elliptic integral of the second kind |
genuinely transcendental |
BSpline |
no closed form; needs quadrature + numeric inversion |
genuinely iterative |
Polyline |
finite sum of segment lengths |
exact, O(n) |
A polyline is an ordered point list. Locating a distance is a running sum until the interval is found, then one linear interpolation. Every operation is already exact in Scalar; the only transcendental is the sqrt in each segment length, which Line already relies on and reports as ArcLength3d.
The inconsistency is visible within the current table: Curve3::Line reports ArcLength3d via d / |direction|. A polyline is a sequence of lines. Refusing the sequence while accepting each element is hard to justify from exactness.
Why it matters downstream
IFC4x3 allows IfcLinearPlacement.PlacementRelTo to be any IfcCurve, not only an alignment centreline. IfcPolyline and IfcIndexedPolyCurve are common as basis curves for simple linear referencing -- a kerb line, a fence run, a utility trace -- where nobody authored a full horizontal/vertical alignment.
For those we currently refuse by type rather than place the product, and the refusal is not a statement about the file: the geometry is exactly locatable, the capability is just declared absent.
Ellipse and BSpline we are happy to keep refusing. Neither appears as an alignment basis curve in practice, and an approximation there would be a worse answer than a refusal.
Suggested shape
Polyline reports ArcLength3d and is evaluable by distance. No new enum variant, no trait change, no change for existing callers -- a family moves out of Unsupported.
Three edges worth pinning, because each has a wrong answer that looks plausible:
- A seam is ambiguous. At a vertex the tangent is two-valued. Picking the outgoing segment is defensible; leaving it undefined is not.
frame_at at a seam has the same question, and it matters more there, because a sign at a kink would silently take one of two headings.
- Degenerate segments. Repeated identical points give a zero-length segment and a zero tangent. Skipping them changes the parameterisation; refusing is cleaner than normalising a zero vector.
closed: true. The wrap segment from last point back to first is real length. Whether distance may exceed the open length, and whether it wraps, should be stated rather than discovered.
What we are NOT asking for
Not arc-length reparameterisation in general. BSpline would need quadrature plus Newton inversion, with tolerance and convergence policy attached -- that is a real design decision with exactness tradeoffs, and it should stay refused until someone has a concrete need. This issue is only the family where the exact answer is a sum.
Our side
ifc-geometry reaches this through CurveEvaluator behind a non-default feature, so nothing is needed from us beyond widening one dispatch arm once the convention changes. Verified against 0.2.1: the contract wiring, the CurveMeasure distinction and the reference-up frame_at all work end to end for the Elevated path.
Happy to take the implementation if you would rather review than write it.
DistanceConvention::Unsupportedcurrently covers three curve families, and one of them does not belong there: a polyline has an exact closed-form arc length, unlike an ellipse or a B-spline.What refuses today
The answer at 5 m is exactly
(3, 4, 0). No integral, no iteration.Why the three families are not alike
The shipped rationale groups them together:
That is right for two of them and wrong for the third.
EllipseBSplinePolylineA polyline is an ordered point list. Locating a distance is a running sum until the interval is found, then one linear interpolation. Every operation is already exact in
Scalar; the only transcendental is thesqrtin each segment length, whichLinealready relies on and reports asArcLength3d.The inconsistency is visible within the current table:
Curve3::LinereportsArcLength3dviad / |direction|. A polyline is a sequence of lines. Refusing the sequence while accepting each element is hard to justify from exactness.Why it matters downstream
IFC4x3 allows
IfcLinearPlacement.PlacementRelToto be anyIfcCurve, not only an alignment centreline.IfcPolylineandIfcIndexedPolyCurveare common as basis curves for simple linear referencing -- a kerb line, a fence run, a utility trace -- where nobody authored a full horizontal/vertical alignment.For those we currently refuse by type rather than place the product, and the refusal is not a statement about the file: the geometry is exactly locatable, the capability is just declared absent.
EllipseandBSplinewe are happy to keep refusing. Neither appears as an alignment basis curve in practice, and an approximation there would be a worse answer than a refusal.Suggested shape
PolylinereportsArcLength3dand is evaluable by distance. No new enum variant, no trait change, no change for existing callers -- a family moves out ofUnsupported.Three edges worth pinning, because each has a wrong answer that looks plausible:
frame_atat a seam has the same question, and it matters more there, because a sign at a kink would silently take one of two headings.closed: true. The wrap segment from last point back to first is real length. Whether distance may exceed the open length, and whether it wraps, should be stated rather than discovered.What we are NOT asking for
Not arc-length reparameterisation in general.
BSplinewould need quadrature plus Newton inversion, with tolerance and convergence policy attached -- that is a real design decision with exactness tradeoffs, and it should stay refused until someone has a concrete need. This issue is only the family where the exact answer is a sum.Our side
ifc-geometryreaches this throughCurveEvaluatorbehind a non-default feature, so nothing is needed from us beyond widening one dispatch arm once the convention changes. Verified against0.2.1: the contract wiring, theCurveMeasuredistinction and the reference-upframe_atall work end to end for theElevatedpath.Happy to take the implementation if you would rather review than write it.