Merge remote-tracking branch 'origin/main' into feat/profiles-by-curve-ids
# Conflicts: # crates/doc/src/lib.rs # crates/sketch/src/lib.rs
This commit is contained in:
commit
184e301c46
180 files changed
+29315
-1568
No files matched your search
@@ -17,7 +17,7 @@ pub static COMMANDS: &[CommandSpec] = &[
|
||||
CommandSpec::new("solid.revolve", "Revolve", revolve)
|
||||
.at("SOLID", "CREATE")
|
||||
.icon("revolve")
|
||||
.params("axis: sketch line id | x | y (sketch axes) | X|Y|Z (world); angle?: expr (default 360 deg); angle2?: expr (Two Sides: the other side's angle); direction?: symmetric (angle split either side); to?: [x,y,z] (To Object: turn until that face, vertex or point); sketch?, profiles? | face: [x,y,z] (a planar body face as the profile), operation?, targets?, name?, body_name?"),
|
||||
.params("axis: sketch line id | x | y (sketch axes) | X|Y|Z (world); angle?: expr (default 360 deg); angle2?: expr (Two Sides: the other side's angle); direction?: symmetric (angle split either side, independent of axis direction); convention?: sketch_normal|legacy_axis_start (default sketch_normal; legacy retains older angular starts); to?: [x,y,z] (To Object: turn until that face, vertex or point); sketch?, profiles? | face: [x,y,z] (a planar body face as the profile), operation?, targets?, name?, body_name?"),
|
||||
CommandSpec::new("solid.sweep", "Sweep", sweep)
|
||||
.at("SOLID", "CREATE")
|
||||
.icon("sweep")
|
||||
@@ -147,7 +147,7 @@ pub fn auto_operation(s: &Session, p: &Value) -> Option<&'static str> {
|
||||
let bodies: Vec<_> = st
|
||||
.bodies
|
||||
.iter()
|
||||
.filter(|b| if parts.is_empty() { s.doc.body_component(&b.name, b.feature) == s.active_component } else { parts.contains(&b.name) })
|
||||
.filter(|b| if parts.is_empty() { s.doc.model_body_component(b) == s.active_component } else { parts.contains(&b.name) })
|
||||
.collect();
|
||||
if bodies.is_empty() {
|
||||
return Some("new");
|
||||
@@ -328,7 +328,24 @@ pub(super) fn add_feature(s: &mut Session, p: &Value, kind: FeatureKind) -> Resu
|
||||
};
|
||||
let face_names = {
|
||||
let pts = kind.face_points();
|
||||
if pts.is_empty() { Vec::new() } else { solvecraft_doc::naming::face_names_at(&s.model.state(), &pts) }
|
||||
if let FeatureKind::Emboss { face: Some(face), .. } = &kind {
|
||||
let state = s.model.state();
|
||||
let body = state.body(&face.body).ok_or_else(|| EngineError::Other("selected cylinder body no longer exists".into()))?;
|
||||
let frame = face.body_frame(&s.doc, body).map_err(|e| EngineError::Other(e.to_string()))?;
|
||||
let inverse = solvecraft_doc::mat_inverse(&frame).ok_or_else(|| EngineError::Other("invalid cylinder placement".into()))?;
|
||||
let at = solvecraft_doc::apply_point(&solvecraft_doc::mat_mul(&inverse, &s.active_component_frame()), face.at);
|
||||
let mut scoped = solvecraft_doc::ModelState::default();
|
||||
scoped.bodies.push(body.clone());
|
||||
let names = solvecraft_doc::naming::face_names_at(&scoped, &[at]);
|
||||
if names.len() != 1 || names.first().is_none_or(|name| name.is_empty()) {
|
||||
return Err(EngineError::Other("selected cylinder face has no persistent identity".into()));
|
||||
}
|
||||
names
|
||||
} else if pts.is_empty() {
|
||||
Vec::new()
|
||||
} else {
|
||||
solvecraft_doc::naming::face_names_at(&s.model.state(), &pts)
|
||||
}
|
||||
};
|
||||
let participants = string_list(p, "participants");
|
||||
if participants.len() > 10_000 || participants.iter().any(|b| b != "*" && s.model.state().body(b).is_none()) {
|
||||
@@ -472,6 +489,10 @@ fn revolve(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
};
|
||||
let symmetric =
|
||||
matches!(str_(p, "direction").map(str::to_ascii_lowercase).as_deref(), Some("symmetric")) || bool_(p, "symmetric").unwrap_or(false);
|
||||
let convention = match p.get("convention") {
|
||||
None => solvecraft_doc::RevolveConvention::SketchNormal,
|
||||
Some(value) => serde_json::from_value(value.clone()).map_err(|_| bad(cmd, "`convention` must be sketch_normal or legacy_axis_start"))?,
|
||||
};
|
||||
let kind = FeatureKind::Revolve {
|
||||
sketch,
|
||||
profiles,
|
||||
@@ -481,6 +502,7 @@ fn revolve(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
targets: string_list(p, "targets"),
|
||||
angle2,
|
||||
symmetric,
|
||||
convention,
|
||||
to,
|
||||
};
|
||||
add_feature(s, p, kind)
|
||||
@@ -717,7 +739,7 @@ fn combine(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
if bool_(p, "new_component").unwrap_or(false) {
|
||||
let name = str_(p, "component_name").map(str::to_string).unwrap_or_else(|| format!("{target} Combined"));
|
||||
let c = s.execute("component.create", &json!({"name": name, "activate": false}))?;
|
||||
s.execute("component.move_bodies", &json!({"bodies": [target], "component": c["component"]}))?;
|
||||
super::component::transfer_constructor_result(s, &json!({"bodies": [target], "component": c["component"]}))?;
|
||||
out["component"] = c["component"].clone();
|
||||
}
|
||||
Ok(out)
|
||||
@@ -1332,3 +1354,7 @@ fn offset_face(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
#[cfg(test)]
|
||||
#[path = "patterns_tests.rs"]
|
||||
mod patterns_tests;
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "revolve_convention_tests.rs"]
|
||||
mod revolve_convention_tests;
|
||||
Reference in new issue
Block a user