forked from 1b-agent/opencadstudio-upstream
Harden parametric sketch constraints
This commit is contained in:
1 parent
41c07e9858
commit
9b58ca8a93
101 files changed
+3128
-13767
No files matched your search
+19
-52
@@ -1,12 +1,11 @@
|
||||
use super::{
|
||||
document::{
|
||||
DeltaSnapshot, HistorySnapshot, ObjectEntryDelta, ObjectVisibilitySnapshot,
|
||||
PendingHistorySnapshot, SketchConstraintsEntryDelta, SketchConstraintsSnapshot,
|
||||
StructureSnapshot, TableEntryDelta,
|
||||
PendingHistorySnapshot, SketchConstraintsEntryDelta, StructureSnapshot, TableEntryDelta,
|
||||
},
|
||||
OpenCADStudio,
|
||||
};
|
||||
use crate::scene::{ChangeKind, ObjectIsolationState};
|
||||
use crate::scene::ObjectIsolationState;
|
||||
use acadrust::{EntityType, Handle};
|
||||
use rustc_hash::{FxHashMap, FxHashSet as HashSet};
|
||||
use std::sync::Arc;
|
||||
@@ -185,40 +184,6 @@ impl OpenCADStudio {
|
||||
);
|
||||
}
|
||||
|
||||
/// Design doc §5.1/§9: makes a persistent-constraint add/remove
|
||||
/// undoable. `before` is the scope's constraint set captured *before*
|
||||
/// the caller's edit (by the caller, since this fn only sees "now");
|
||||
/// `after` is read fresh here, so call this once the edit is done.
|
||||
pub(super) fn push_sketch_constraints_history(
|
||||
&mut self,
|
||||
i: usize,
|
||||
label: impl Into<String>,
|
||||
scope: crate::scene::sketch_constraints::SketchScope,
|
||||
before: Option<crate::scene::sketch_constraints::SketchConstraintSet>,
|
||||
) {
|
||||
self.finish_pending_history(i);
|
||||
let after = self.tabs[i].scene.sketch_constraint_set(scope).cloned();
|
||||
self.push_undo_entry(
|
||||
i,
|
||||
HistorySnapshot::SketchConstraints(SketchConstraintsSnapshot { scope, before, after, label: label.into() }),
|
||||
);
|
||||
}
|
||||
|
||||
fn apply_sketch_constraints_state(&mut self, i: usize, snapshot: &SketchConstraintsSnapshot, undo: bool) {
|
||||
let state = if undo { snapshot.before.clone() } else { snapshot.after.clone() };
|
||||
let scene = &mut self.tabs[i].scene;
|
||||
let set = state.unwrap_or_else(|| crate::scene::sketch_constraints::SketchConstraintSet::new(snapshot.scope));
|
||||
// The restored set's geometry may be stale (e.g. redo re-adds a
|
||||
// constraint whose entities moved via other edits since) — resolve
|
||||
// every entity it references, same as a fresh add would.
|
||||
let touched: Vec<Handle> = set.constraints.iter().flat_map(|c| c.refs.iter().map(|r| r.entity)).collect();
|
||||
*scene.sketch_constraint_set_mut(snapshot.scope) = set;
|
||||
if !touched.is_empty() {
|
||||
let changes: Vec<(Handle, ChangeKind)> = touched.into_iter().map(|h| (h, ChangeKind::Modified)).collect();
|
||||
scene.bump_entities(&changes);
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn push_entity_group_history(
|
||||
&mut self,
|
||||
i: usize,
|
||||
@@ -261,6 +226,7 @@ impl OpenCADStudio {
|
||||
active_layer: None,
|
||||
structure: (!objects.is_empty()).then_some(StructureSnapshot::Objects(objects)),
|
||||
sketch_constraints: Vec::new(),
|
||||
named_parameters: None,
|
||||
label: label.into(),
|
||||
};
|
||||
self.push_undo_entry(i, HistorySnapshot::Delta(Box::new(delta)));
|
||||
@@ -371,6 +337,7 @@ impl OpenCADStudio {
|
||||
.then_some((pending.active_layer, active_layer_after)),
|
||||
structure: structure_changed.then_some(StructureSnapshot::Full(pending.structure_before)),
|
||||
sketch_constraints: Vec::new(),
|
||||
named_parameters: None,
|
||||
label: pending.label,
|
||||
};
|
||||
self.push_undo_entry(i, HistorySnapshot::Delta(Box::new(delta)));
|
||||
@@ -479,6 +446,7 @@ impl OpenCADStudio {
|
||||
active_layer: None,
|
||||
structure: Some(StructureSnapshot::Layers(entries)),
|
||||
sketch_constraints: Vec::new(),
|
||||
named_parameters: None,
|
||||
label: pending.label,
|
||||
};
|
||||
self.push_undo_entry(i, HistorySnapshot::Delta(Box::new(delta)));
|
||||
@@ -535,6 +503,7 @@ impl OpenCADStudio {
|
||||
active_layer: None,
|
||||
structure: Some(StructureSnapshot::TextStyles(entries)),
|
||||
sketch_constraints: Vec::new(),
|
||||
named_parameters: None,
|
||||
label: pending.label,
|
||||
};
|
||||
self.push_undo_entry(i, HistorySnapshot::Delta(Box::new(delta)));
|
||||
@@ -591,6 +560,7 @@ impl OpenCADStudio {
|
||||
active_layer: None,
|
||||
structure: Some(StructureSnapshot::DimStyles(entries)),
|
||||
sketch_constraints: Vec::new(),
|
||||
named_parameters: None,
|
||||
label: pending.label,
|
||||
};
|
||||
self.push_undo_entry(i, HistorySnapshot::Delta(Box::new(delta)));
|
||||
@@ -655,6 +625,7 @@ impl OpenCADStudio {
|
||||
active_layer: None,
|
||||
structure: Some(StructureSnapshot::Objects(entries)),
|
||||
sketch_constraints: Vec::new(),
|
||||
named_parameters: None,
|
||||
label: pending.label,
|
||||
};
|
||||
self.push_undo_entry(i, HistorySnapshot::Delta(Box::new(delta)));
|
||||
@@ -689,6 +660,7 @@ impl OpenCADStudio {
|
||||
object_handles,
|
||||
}),
|
||||
sketch_constraints: Vec::new(),
|
||||
named_parameters: None,
|
||||
label: "STYLE".to_string(),
|
||||
};
|
||||
self.push_undo_entry(i, HistorySnapshot::Delta(Box::new(delta)));
|
||||
@@ -769,7 +741,8 @@ impl OpenCADStudio {
|
||||
pending.label
|
||||
);
|
||||
}
|
||||
let (entity_before, object_before, sketch_constraints_before) = rec.into_recorded_images();
|
||||
let (entity_before, object_before, sketch_constraints_before, named_parameters_before) =
|
||||
rec.into_recorded_images();
|
||||
let entities: Vec<(Handle, Option<Arc<EntityType>>, Option<Arc<EntityType>>)> = entity_before
|
||||
.into_iter()
|
||||
.map(|(h, before)| {
|
||||
@@ -803,6 +776,10 @@ impl OpenCADStudio {
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
let named_parameters = named_parameters_before.and_then(|before| {
|
||||
let after = self.tabs[i].scene.named_parameters().clone();
|
||||
(before != after).then_some((before, after))
|
||||
});
|
||||
let selected_after = self.tabs[i].scene.selected.iter().copied().collect();
|
||||
let dirty_after = self.tabs[i].dirty;
|
||||
let mut structure = pending.structure_before.map(StructureSnapshot::Full);
|
||||
@@ -839,6 +816,7 @@ impl OpenCADStudio {
|
||||
active_layer: None,
|
||||
structure,
|
||||
sketch_constraints,
|
||||
named_parameters,
|
||||
label: pending.label,
|
||||
};
|
||||
self.push_undo_entry(i, HistorySnapshot::Delta(Box::new(delta)));
|
||||
@@ -971,6 +949,9 @@ impl OpenCADStudio {
|
||||
let value = if undo { &entry.before } else { &entry.after };
|
||||
*scene.sketch_constraint_set_mut(entry.scope) = value.clone();
|
||||
}
|
||||
if let Some((before, after)) = &d.named_parameters {
|
||||
scene.named_parameters = if undo { before } else { after }.clone();
|
||||
}
|
||||
let (sel, dirty) = if undo {
|
||||
(&d.selected_before, d.dirty_before)
|
||||
} else {
|
||||
@@ -1168,13 +1149,6 @@ impl OpenCADStudio {
|
||||
.redo_stack
|
||||
.push(HistorySnapshot::ObjectVisibility(v));
|
||||
}
|
||||
HistorySnapshot::SketchConstraints(s) => {
|
||||
self.apply_sketch_constraints_state(i, &s, true);
|
||||
self.tabs[i]
|
||||
.history
|
||||
.redo_stack
|
||||
.push(HistorySnapshot::SketchConstraints(s));
|
||||
}
|
||||
}
|
||||
}
|
||||
self.finish_history_apply(i, had_full, layer_panel_changed, &changes);
|
||||
@@ -1230,13 +1204,6 @@ impl OpenCADStudio {
|
||||
.undo_stack
|
||||
.push(HistorySnapshot::ObjectVisibility(v));
|
||||
}
|
||||
HistorySnapshot::SketchConstraints(s) => {
|
||||
self.apply_sketch_constraints_state(i, &s, false);
|
||||
self.tabs[i]
|
||||
.history
|
||||
.undo_stack
|
||||
.push(HistorySnapshot::SketchConstraints(s));
|
||||
}
|
||||
}
|
||||
}
|
||||
self.finish_history_apply(i, had_full, layer_panel_changed, &changes);
|
||||
|
||||
Reference in new issue
Block a user