ocs_doc_api: outstanding methods — loft + bulge-arc polyline profiles

- Loft{profiles} op (append-only); executor resolves each profile to curve sets
  all-or-nothing; backend loft() -> brep::loft on XY plane; facade solids().loft.
- entity_to_profile_curves: convert LwVertex.bulge to geom2d::Curve::Arc via
  bulge_arc_segment (theta = 4*atan(bulge)), so bulged polyline profiles sweep
  correctly instead of erroring Unsupported.
- spec loft; api_reference + binding_schema regenerated; mocks + baseline.
- Tests: loft_two_profiles_produces_solid, bulge_arc_polyline_profile_converts_to_arc
  (semicircle radius=5 for bulge=1) -> 612 host lib + 3 consistency green.
This commit is contained in:
Sebastian committed 2026-09-06 10:44:37 +02:00
1 parent 46a5922520
commit e216a7bf94
13 files changed
+176 -21

No files matched your search

+16
View File
@@ -253,6 +253,22 @@ pub fn apply_op<B: DocApiBackend>(b: &mut B, op: Operation) -> ApiResult<Receipt
b.finalize_op();
OpOutcome::NewId(id)
}
Operation::Loft { profiles } => {
// Resolve every profile to its curve set BEFORE push_undo (all-or-nothing).
if profiles.len() < 2 {
return Err(ApiError::validation(name, "loft needs >= 2 profiles"));
}
let mut sections = Vec::with_capacity(profiles.len());
for (i, p) in profiles.iter().enumerate() {
let curves = profile_curves(b, *p, name)
.map_err(|e| at_index(name, i, e))?;
sections.push(curves);
}
b.push_undo(name);
let id = b.loft(&sections)?;
b.finalize_op();
OpOutcome::NewId(id)
}
};
Ok(Receipt {
outcome: Some(outcome),