forked from 1b-agent/opencadstudio-upstream
Merge PR #1083: implement solid shell workflow
This commit is contained in:
commit
c5503e4758
19 files changed
+851
-115
No files matched your search
+87
-1
@@ -982,7 +982,7 @@ impl OpenCADStudio {
|
||||
"area":planar.curve.is_closed().then(|| planar.curve.enclosed_area().abs())
|
||||
})
|
||||
});
|
||||
out.push(json!({"handle":format!("{:X}",handle.value()),"type":crate::entities::names::ui_name(entity),"bounds":{"min":[bb.min.x,bb.min.y,bb.min.z],"max":[bb.max.x,bb.max.y,bb.max.z]},"curve":curve,"mesh":metrics.map(|m|json!({"vertices":m.metrics.vertices,"triangles":m.metrics.triangles,"surface_area":m.metrics.surface_area,"volume":m.metrics.volume,"centroid":m.metrics.centroid}))}));
|
||||
out.push(json!({"handle":format!("{:X}",handle.value()),"type":crate::entities::names::ui_name(entity),"bounds":{"min":[bb.min.x,bb.min.y,bb.min.z],"max":[bb.max.x,bb.max.y,bb.max.z]},"curve":curve,"mesh":metrics.map(|m|json!({"vertices":m.metrics.vertices,"triangles":m.metrics.triangles,"surface_area":m.metrics.surface_area,"volume":m.metrics.volume,"centroid":m.metrics.centroid,"moment_of_inertia":m.metrics.moment_of_inertia,"principal_directions":m.metrics.principal_directions,"principal_moments":m.metrics.principal_moments,"product_of_inertia":m.metrics.product_of_inertia,"radii_of_gyration":m.metrics.radii_of_gyration}))}));
|
||||
}
|
||||
json!({"ok":true,"document_id":tab.id,"geometry_revision":tab.scene.geometry_epoch,"measurements":out})
|
||||
}
|
||||
@@ -1222,6 +1222,92 @@ mod tests {
|
||||
assert!((curve["length"].as_f64().unwrap() - std::f64::consts::TAU * 2.0).abs() < 1e-9);
|
||||
assert!((curve["area"].as_f64().unwrap() - std::f64::consts::PI * 4.0).abs() < 1e-9);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn control_shell_roundtrips_with_kernel_mass_properties() {
|
||||
let mut app = OpenCADStudio::new_for_test();
|
||||
request(&mut app, json!({"op":"new"}));
|
||||
request(&mut app, json!({"op":"start","cmd":"BOX"}));
|
||||
request(
|
||||
&mut app,
|
||||
json!({"op":"input","kind":"point","point":[0.0,0.0,0.0]}),
|
||||
);
|
||||
request(
|
||||
&mut app,
|
||||
json!({"op":"input","kind":"point","point":[6.0,5.0,0.0]}),
|
||||
);
|
||||
assert_eq!(
|
||||
request(&mut app, json!({"op":"input","kind":"token","text":"4"}))["status"],
|
||||
"completed"
|
||||
);
|
||||
let handle = app.tabs[app.active_tab]
|
||||
.scene
|
||||
.document
|
||||
.entities()
|
||||
.find_map(|entity| {
|
||||
matches!(entity, acadrust::EntityType::Solid3D(_)).then(|| entity.common().handle)
|
||||
})
|
||||
.unwrap();
|
||||
let handle_text = format!("{:X}", handle.value());
|
||||
|
||||
request(&mut app, json!({"op":"select","handles":[handle_text]}));
|
||||
request(&mut app, json!({"op":"start","cmd":"SHELL"}));
|
||||
request(
|
||||
&mut app,
|
||||
json!({"op":"input","kind":"entity","handle":handle_text,"point":[3.0,2.5,4.0]}),
|
||||
);
|
||||
request(&mut app, json!({"op":"input","kind":"enter"}));
|
||||
assert_eq!(
|
||||
request(&mut app, json!({"op":"input","kind":"token","text":"0.5"}))["status"],
|
||||
"completed"
|
||||
);
|
||||
|
||||
let measured = app.control_measure(&json!({"handles":[handle_text]}));
|
||||
let mesh = &measured["measurements"][0]["mesh"];
|
||||
assert!((mesh["volume"].as_f64().unwrap() - 50.0).abs() < 1e-9);
|
||||
assert_eq!(mesh["principal_moments"].as_array().unwrap().len(), 3);
|
||||
assert!(matches!(
|
||||
app.tabs[app.active_tab]
|
||||
.scene
|
||||
.document
|
||||
.solid_history_operation(handle),
|
||||
Some(acadrust::objects::SolidHistoryOperation::Brep(_))
|
||||
));
|
||||
|
||||
assert_eq!(request(&mut app, json!({"op":"undo"}))["ok"], true);
|
||||
let restored = app.control_measure(&json!({"handles":[handle_text]}));
|
||||
assert!(
|
||||
(restored["measurements"][0]["mesh"]["volume"]
|
||||
.as_f64()
|
||||
.unwrap()
|
||||
- 120.0)
|
||||
.abs()
|
||||
< 1e-9
|
||||
);
|
||||
assert_eq!(request(&mut app, json!({"op":"redo"}))["ok"], true);
|
||||
|
||||
let path = std::env::temp_dir().join(format!("ocs-shell-{}.dwg", session_id()));
|
||||
assert_eq!(
|
||||
request(&mut app, json!({"op":"save","path":path}))["ok"],
|
||||
true
|
||||
);
|
||||
request(&mut app, json!({"op":"new"}));
|
||||
assert_eq!(
|
||||
request(&mut app, json!({"op":"open","path":path}))["status"],
|
||||
"completed"
|
||||
);
|
||||
let reopened = app.control_measure(&json!({"handles":[handle_text]}));
|
||||
assert!(
|
||||
(reopened["measurements"][0]["mesh"]["volume"]
|
||||
.as_f64()
|
||||
.unwrap()
|
||||
- 50.0)
|
||||
.abs()
|
||||
< 1e-9
|
||||
);
|
||||
let _ = std::fs::remove_file(path);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn control_retry_is_idempotent_and_stale_state_rejected() {
|
||||
let mut app = OpenCADStudio::new_for_test();
|
||||
|
||||
Reference in new issue
Block a user