STEP: open/insert/drag-drop
Import base feature (FeatureKind::Import, timeline type BaseFeature) holding the STEP text and the file's product tree; bodies named from the file. doc.open accepts .step/.stp (any case) as a new design; Insert STEP (FusionImportCommandFromToolbar) adds one to the current design; File menu, SOLID > INSERT, drag-and-drop (insert into a non-empty design, else open), 'solvecraft part.step', MCP open. Features (fillet, hole, sketch-on-face cut, shell) work on imported bodies. Imports are cached so a file is read once per command. Measure tightens its chord tolerance for small radii. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
This commit is contained in:
1 parent
ed611ed7ba
commit
f3dbb12b23
18 files changed
+360
-18
No files matched your search
@@ -361,6 +361,10 @@ pub fn paint(p: &Painter, r: Rect, name: &str, ink: Color32, fill: Color32, acce
|
||||
pen.poly(&[(4.0, 10.0), (4.0, 20.0), (16.0, 20.0), (16.0, 10.0)], pen.fill, ink);
|
||||
pen.arrow((10.0, 14.0), (20.0, 4.0), a);
|
||||
}
|
||||
"import" => {
|
||||
pen.iso_box(4.0, 12.0, 12.0, 7.0, 7.0);
|
||||
pen.arrow((20.0, 3.0), (12.0, 11.0), a);
|
||||
}
|
||||
"home" => {
|
||||
pen.poly(&[(4.0, 12.0), (12.0, 4.0), (20.0, 12.0)], pen.fill, ink);
|
||||
pen.poly(&[(6.0, 12.0), (18.0, 12.0), (18.0, 20.0), (6.0, 20.0)], pen.fill, ink);
|
||||
|
||||
@@ -166,6 +166,12 @@ impl SolveApp {
|
||||
/// that have them, otherwise run it with defaults.
|
||||
pub fn start(&mut self, id: &str) {
|
||||
self.tool = None;
|
||||
if id == "FusionImportCommandFromToolbar" {
|
||||
if let Some(p) = self.services.pick_open.as_ref().and_then(|f| f()) {
|
||||
self.insert_path(&p);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if id == "SketchStop" {
|
||||
let r = self.run(id, json!({}));
|
||||
if r.is_ok()
|
||||
@@ -240,6 +246,25 @@ impl SolveApp {
|
||||
}
|
||||
}
|
||||
|
||||
/// Insert a STEP file's bodies into the current design (an Import base feature).
|
||||
pub fn insert_path(&mut self, path: &str) {
|
||||
if let Ok(r) = self.run("FusionImportCommandFromToolbar", json!({ "path": path })) {
|
||||
self.fit_view();
|
||||
if let Some(w) = r["warnings"].as_array().filter(|w| !w.is_empty()) {
|
||||
self.set_status(format!("imported with {} warning(s): {}", w.len(), w.first().and_then(Value::as_str).unwrap_or("")), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A dropped file: a STEP file joins a design that has features, anything else opens.
|
||||
pub fn drop_path(&mut self, path: &str) {
|
||||
if solvecraft_engine::io::is_step_path(path) && !self.session.doc.features.is_empty() {
|
||||
self.insert_path(path);
|
||||
} else {
|
||||
self.open_path(path);
|
||||
}
|
||||
}
|
||||
|
||||
/// Frame the model at once (programmatic use; the toolbar animates).
|
||||
pub fn fit_view(&mut self) {
|
||||
self.cam_anim = None;
|
||||
@@ -321,7 +346,7 @@ impl SolveApp {
|
||||
for f in ctx.input(|i| i.raw.dropped_files.clone()) {
|
||||
let p = f.path().to_string_lossy().to_string();
|
||||
if !p.is_empty() {
|
||||
self.open_path(&p);
|
||||
self.drop_path(&p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ fn icon_of(k: &FeatureKind) -> &'static str {
|
||||
FeatureKind::Draft { .. } => "draft",
|
||||
FeatureKind::Split { .. } => "split",
|
||||
FeatureKind::Move { .. } => "move",
|
||||
FeatureKind::Import { .. } => "import",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -127,6 +127,10 @@ fn file_menu(app: &mut SolveApp, ctx: &egui::Context) {
|
||||
}
|
||||
close = true;
|
||||
}
|
||||
if item(ui, "Insert STEP…", "") {
|
||||
app.start("FusionImportCommandFromToolbar");
|
||||
close = true;
|
||||
}
|
||||
if item(ui, "Save", "Ctrl+S") {
|
||||
save(app);
|
||||
close = true;
|
||||
|
||||
Reference in new issue
Block a user