Reconstruct constant-section meshes as parametric solids

This commit is contained in:
lillith authored and bherbruck committed 2026-10-12 10:06:42 -04:00
1 parent 417511367c
commit df4c8a2994
19 files changed
+717 -12

No files matched your search

+1
View File
@@ -329,6 +329,7 @@ impl FeatureKind {
| FeatureKind::Thicken { .. }
| FeatureKind::Import { .. }
| FeatureKind::MeshImport { .. }
| FeatureKind::MeshConvert { .. }
| FeatureKind::BodyTransfer { .. } => {}
FeatureKind::Patch { edges, .. } | FeatureKind::SurfaceExtend { edges, .. } => edges.iter_mut().for_each(pt),
FeatureKind::SurfaceTrim { plane, tool, keep, .. } => {
+5 -3
View File
@@ -356,9 +356,11 @@ impl crate::Feature {
mapped_name(n, bodies);
}
}
K::Split { body, .. } | K::SheetConvert { body, .. } | K::SurfaceExtend { body, .. } | K::SurfaceTrim { body, .. } => {
mapped_name(body, bodies)
}
K::Split { body, .. }
| K::SheetConvert { body, .. }
| K::SurfaceExtend { body, .. }
| K::SurfaceTrim { body, .. }
| K::MeshConvert { body, .. } => mapped_name(body, bodies),
_ => {}
}
match &mut self.kind {
+10 -2
View File
@@ -883,8 +883,12 @@ pub enum FeatureKind {
#[serde(default, skip_serializing_if = "Vec::is_empty")]
components: Vec<solvecraft_kernel::StepNode>,
},
/// A non-parametric base feature: mesh bodies imported from a 3MF or STL file (kept in the
/// design). Mesh bodies render, measure, move and export; solid features cannot use them.
/// Rebuild an upstream constant-section mesh with analytic planar/cylindrical faces.
MeshConvert {
body: String,
tolerance: String,
},
/// Mesh bodies imported from a 3MF or STL file, embedded in the design.
MeshImport {
/// Source file name (display only).
file: String,
@@ -1162,6 +1166,7 @@ impl FeatureKind {
| K::Move { .. }
| K::Import { .. }
| K::MeshImport { .. }
| K::MeshConvert { .. }
| K::BodyTransfer { .. } => Vec::new(),
}
}
@@ -1247,6 +1252,7 @@ impl FeatureKind {
FeatureKind::SurfaceExtend { .. } => "ExtendFeature",
FeatureKind::Import { .. } => "BaseFeature",
FeatureKind::MeshImport { .. } => "MeshFeature",
FeatureKind::MeshConvert { .. } => "MeshConvertFeature",
}
}
/// Default name prefix (`Extrude` → `Extrude1`).
@@ -1312,6 +1318,7 @@ impl FeatureKind {
FeatureKind::SurfaceExtend { .. } => "Extend",
FeatureKind::Import { .. } => "Import",
FeatureKind::MeshImport { .. } => "Mesh",
FeatureKind::MeshConvert { .. } => "ConvertMesh",
}
}
/// Every expression the feature uses.
@@ -1520,6 +1527,7 @@ impl FeatureKind {
FeatureKind::ReplaceFace { target, .. } => plane_exprs(target, &mut v),
FeatureKind::Align { .. } | FeatureKind::Remove { .. } | FeatureKind::BoundaryFill { .. } | FeatureKind::DeleteFace { .. } => {}
FeatureKind::Stitch { tolerance, .. } => v.push(tolerance),
FeatureKind::MeshConvert { tolerance, .. } => v.push(tolerance),
FeatureKind::Thicken { thickness, .. } => v.push(thickness),
FeatureKind::SurfaceTrim { plane, .. } => plane_exprs(plane, &mut v),
FeatureKind::SurfaceExtend { distance, .. } => v.push(distance),
+14
View File
@@ -3299,6 +3299,20 @@ fn eval_feature(doc: &Document, vals: &BTreeMap<String, Value>, f: &Feature, st:
}
Ok(())
}
FeatureKind::MeshConvert { body, tolerance } => {
let tolerance = val(vals, tolerance, Kind::Length)?;
let index = st.bodies.iter().position(|b| &b.name == body).ok_or_else(|| DocError::Unknown(format!("body `{body}`")))?;
let source = st.bodies.get(index).ok_or_else(|| DocError::Unknown(format!("body `{body}`")))?;
if doc.model_body_component(source) != f.component {
return Err(DocError::Invalid("activate the mesh body's component before converting it".into()));
}
let converted = kernel::convert_prismatic_mesh(&source.body, tolerance)?;
let converted = converted.with_color(source.body.color());
let result = ModelBody::new(source.name.clone(), converted, f.id);
let target = st.bodies.get_mut(index).ok_or_else(|| DocError::Unknown(format!("body `{body}`")))?;
*target = result;
Ok(())
}
FeatureKind::MeshImport { meshes, .. } => {
for (k, (name, b)) in mesh_bodies(meshes)?.into_iter().enumerate() {
let name = copy_body_name(st, f, k, &name);
+1
View File
@@ -259,6 +259,7 @@ impl FeatureKind {
}
FeatureKind::ReplaceFace { target, .. } => plane_inputs_mut(target, &mut v),
FeatureKind::Stitch { tolerance, .. } => v.push(("Tolerance", tolerance, L)),
FeatureKind::MeshConvert { tolerance, .. } => v.push(("Tolerance", tolerance, L)),
FeatureKind::Thicken { thickness, .. } => v.push(("Thickness", thickness, L)),
FeatureKind::SurfaceTrim { plane, .. } => plane_inputs_mut(plane, &mut v),
FeatureKind::SurfaceExtend { distance, .. } => v.push(("Distance", distance, L)),