Feature fields: a type for each role (Expr, BodyName, FacePick…) (#1273)
Thanks @jijinbei.
This commit is contained in:
1 parent
3333f8a62b
commit
44968dbfe6
59 files changed
+1505
-1043
No files matched your search
@@ -3,6 +3,8 @@
|
||||
use serde_json::Value;
|
||||
use solidcraft_doc::FeatureKind;
|
||||
use solidcraft_doc::expr::Kind;
|
||||
use solidcraft_doc::{BodyName, SketchId};
|
||||
use solidcraft_doc::{Dir, FacePick, Position};
|
||||
use solidcraft_geom::Vec3;
|
||||
|
||||
use super::CommandSpec;
|
||||
@@ -57,11 +59,11 @@ fn coil(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
(Some(n), _, Some(pt)) => (n, pt),
|
||||
(Some(n), Some(h), None) => {
|
||||
let [h] = length_operands(s, [(&h, &unit)]);
|
||||
(n.clone(), format!("({h}) / ({n})"))
|
||||
(n.clone(), format!("({h}) / ({n})").into())
|
||||
}
|
||||
(None, Some(h), Some(pt)) => {
|
||||
let [h, by] = length_operands(s, [(&h, &unit), (&pt, &unit)]);
|
||||
(format!("({h}) / ({by})"), pt)
|
||||
(format!("({h}) / ({by})").into(), pt)
|
||||
}
|
||||
_ => return Err(bad(cmd, "give two of `revolutions`, `height` and `pitch`")),
|
||||
};
|
||||
@@ -91,7 +93,7 @@ fn coil(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
p,
|
||||
FeatureKind::Coil {
|
||||
base,
|
||||
axis,
|
||||
axis: Dir(axis),
|
||||
diameter,
|
||||
pitch,
|
||||
turns,
|
||||
@@ -101,7 +103,7 @@ fn coil(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
start_angle,
|
||||
clockwise,
|
||||
operation,
|
||||
targets: string_list(p, "targets"),
|
||||
targets: string_list(p, "targets").into_iter().map(BodyName).collect(),
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -131,7 +133,7 @@ fn rib_like(s: &mut Session, p: &Value, cmd: &str, web: bool) -> Result<Value> {
|
||||
check_expr(s, d, Kind::Length, cmd, "depth")?;
|
||||
}
|
||||
let flip = bool_(p, "flip").unwrap_or(false);
|
||||
add_feature(s, p, FeatureKind::Rib { sketch, curves, thickness, depth, flip, web })
|
||||
add_feature(s, p, FeatureKind::Rib { sketch: SketchId(sketch), curves, thickness, depth, flip, web })
|
||||
}
|
||||
|
||||
fn rib(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
@@ -212,11 +214,15 @@ fn emboss(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
} else {
|
||||
let inferred = infer_emboss_selection(s, sketch, &profiles, &depth, deboss, &targets)?;
|
||||
if let Some(face) = &inferred {
|
||||
targets = vec![face.body.clone()];
|
||||
targets = vec![face.body.0.clone()];
|
||||
}
|
||||
inferred
|
||||
};
|
||||
add_feature(s, p, FeatureKind::Emboss { sketch, profiles, depth, deboss, targets, face })
|
||||
add_feature(
|
||||
s,
|
||||
p,
|
||||
FeatureKind::Emboss { sketch: SketchId(sketch), profiles, depth, deboss, targets: targets.into_iter().map(BodyName).collect(), face },
|
||||
)
|
||||
}
|
||||
|
||||
fn emboss_selection(s: &Session, selected: &solidcraft_doc::ModelBody, at: Vec3) -> Result<solidcraft_doc::EmbossFace> {
|
||||
@@ -240,7 +246,7 @@ fn emboss_selection(s: &Session, selected: &solidcraft_doc::ModelBody, at: Vec3)
|
||||
return Err(bad(cmd, "cylinder placement is too deep"));
|
||||
}
|
||||
let inverse = solidcraft_doc::mat_inverse(&s.active_component_frame()).ok_or_else(|| bad(cmd, "invalid active frame"))?;
|
||||
Ok(solidcraft_doc::EmbossFace { body: name.to_owned(), at: solidcraft_doc::apply_point(&inverse, at), path, author_path })
|
||||
Ok(solidcraft_doc::EmbossFace { body: name.into(), at: FacePick(solidcraft_doc::apply_point(&inverse, at)), path, author_path })
|
||||
}
|
||||
|
||||
fn check_emboss_positions(s: &Session, sketch: u64, body: &solidcraft_doc::ModelBody, face: &solidcraft_doc::EmbossFace) -> Result<()> {
|
||||
@@ -307,7 +313,7 @@ fn infer_emboss_selection(
|
||||
face.sketch_frame(&placed, s.active_component, sketch_owner, raw).map_err(|e| bad(cmd, e.to_string()))?;
|
||||
check_emboss_positions(s, sketch, selected, &face)?;
|
||||
let author_inverse = solidcraft_doc::mat_inverse(&s.active_component_frame()).ok_or_else(|| bad(cmd, "invalid author frame"))?;
|
||||
face.at = solidcraft_doc::apply_point(&solidcraft_doc::mat_mul(&author_inverse, &body_frame), at);
|
||||
face.at = FacePick(solidcraft_doc::apply_point(&solidcraft_doc::mat_mul(&author_inverse, &body_frame), at));
|
||||
if chosen.is_some() {
|
||||
return Err(bad(cmd, "multiple tangent cylinders match the selected profiles; select a target face or body"));
|
||||
}
|
||||
@@ -341,7 +347,7 @@ fn replace_face(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
None => plane_param(s, p.get("target"), cmd)?,
|
||||
};
|
||||
let body = str_(p, "body").map(str::to_string);
|
||||
add_feature(s, p, FeatureKind::ReplaceFace { faces, target, body })
|
||||
add_feature(s, p, FeatureKind::ReplaceFace { faces: faces.into_iter().map(FacePick).collect(), target, body: body.map(BodyName) })
|
||||
}
|
||||
|
||||
fn align(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
@@ -376,7 +382,18 @@ fn align(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
_ => (None, None),
|
||||
};
|
||||
let flip = bool_(p, "flip").unwrap_or(false);
|
||||
add_feature(s, p, FeatureKind::Align { bodies, from, to, from_normal, to_normal, flip })
|
||||
add_feature(
|
||||
s,
|
||||
p,
|
||||
FeatureKind::Align {
|
||||
bodies: bodies.into_iter().map(BodyName).collect(),
|
||||
from: Position(from),
|
||||
to: Position(to),
|
||||
from_normal: from_normal.map(Dir),
|
||||
to_normal: to_normal.map(Dir),
|
||||
flip,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn remove(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
@@ -389,7 +406,7 @@ fn remove(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
if let Some(b) = bodies.iter().find(|b| st.body(b).is_none()) {
|
||||
return Err(bad(cmd, format!("no body `{b}`")));
|
||||
}
|
||||
add_feature(s, p, FeatureKind::Remove { bodies })
|
||||
add_feature(s, p, FeatureKind::Remove { bodies: bodies.into_iter().map(BodyName).collect() })
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -443,5 +460,14 @@ fn boundary_fill(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
return Err(bad(cmd, "`cells` must list 1…1000 points [x, y, z], one inside each cell"));
|
||||
}
|
||||
let operation = super::features::operation(p, cmd)?;
|
||||
add_feature(s, p, FeatureKind::BoundaryFill { tools, cells, operation, remove_tools: bool_(p, "remove_tools").unwrap_or(false) })
|
||||
add_feature(
|
||||
s,
|
||||
p,
|
||||
FeatureKind::BoundaryFill {
|
||||
tools: tools.into_iter().map(BodyName).collect(),
|
||||
cells: cells.into_iter().map(Position).collect(),
|
||||
operation,
|
||||
remove_tools: bool_(p, "remove_tools").unwrap_or(false),
|
||||
},
|
||||
)
|
||||
}
|
||||
Reference in new issue
Block a user