* WIP deep rename (not for push) * WIP2 * WIP3 * WIP4 wxs fix * rustfmt * Rename the remaining identifiers in merged crash-report code Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT --------- Co-authored-by: Claude Opus 5.5 <[email protected]>
38 lines
1.5 KiB
Rust
38 lines
1.5 KiB
Rust
//! Parametric reconstruction of imported mechanical mesh bodies.
|
|
|
|
use serde_json::Value;
|
|
use solidcraft_doc::FeatureKind;
|
|
use solidcraft_doc::expr::Kind;
|
|
|
|
use super::{
|
|
CommandSpec,
|
|
features::{add_feature, check_expr},
|
|
};
|
|
use crate::{
|
|
Result, Session,
|
|
params::{bad, expr, str_},
|
|
};
|
|
|
|
pub static COMMANDS: &[CommandSpec] = &[
|
|
CommandSpec::new("mesh.convert", "Convert Mesh", convert)
|
|
.at("MESH", "MODIFY")
|
|
.icon("import")
|
|
.params("body: mesh body name; tolerance?: length expression (default 0.05 mm): reconstruct a closed constant-section mechanical mesh as editable planar and cylindrical faces, with a parametric timeline feature; name?"),
|
|
];
|
|
|
|
fn convert(s: &mut Session, p: &Value) -> Result<Value> {
|
|
let cmd = "mesh.convert";
|
|
let body = str_(p, "body").filter(|b| !b.trim().is_empty()).ok_or_else(|| bad(cmd, "select a mesh body"))?;
|
|
let state = s.model.state();
|
|
let source = state.body(body).ok_or_else(|| bad(cmd, format!("no body `{body}`")))?;
|
|
if !source.body.is_mesh() {
|
|
return Err(bad(cmd, "select a mesh body"));
|
|
}
|
|
if s.doc.model_body_component(source) != s.active_component {
|
|
return Err(bad(cmd, "activate the mesh body's component before converting it"));
|
|
}
|
|
let tolerance = expr(p, "tolerance").unwrap_or_else(|| "0.05 mm".into());
|
|
check_expr(s, &tolerance, Kind::Length, cmd, "tolerance")?;
|
|
add_feature(s, p, FeatureKind::MeshConvert { body: body.into(), tolerance })
|
|
}
|