forked from 1b-agent/opencadstudio-upstream
Merge pull request #988 from gianlucafiore/fix/offset-trim-pickfirst
fix(offset, trim): preserve source layers and preselected cutting edges
This commit is contained in:
6 files changed
+88
-12
No files matched your search
@@ -840,6 +840,10 @@ impl OpenCADStudio {
|
||||
|
||||
fn apply_cmd_result_inner(&mut self, result: CmdResult) -> Task<Message> {
|
||||
let i = self.active_tab;
|
||||
let preserve_commit_layer = self.tabs[i]
|
||||
.active_cmd
|
||||
.as_ref()
|
||||
.is_some_and(|command| command.preserve_commit_layer());
|
||||
match result {
|
||||
CmdResult::NeedPoint => {
|
||||
// ATTEDIT finished its entity pick: hand the chosen block off to
|
||||
@@ -935,7 +939,11 @@ impl OpenCADStudio {
|
||||
);
|
||||
let association_enabled =
|
||||
self.tabs[i].scene.document.header.dimension_associativity == 2;
|
||||
let committed = self.commit_entity_handle(entity);
|
||||
let committed = if preserve_commit_layer {
|
||||
self.commit_entity_handle_preserve_layer(entity)
|
||||
} else {
|
||||
self.commit_entity_handle(entity)
|
||||
};
|
||||
if is_associative_dimension && association_enabled {
|
||||
if let Some(handle) = committed {
|
||||
let sources = self.tabs[i]
|
||||
@@ -973,7 +981,11 @@ impl OpenCADStudio {
|
||||
.all(|entity| self.delta_add_safe(i, entity));
|
||||
let pending = self.begin_undo(i, label, entities.len(), delta_safe);
|
||||
for entity in entities {
|
||||
self.commit_entity(entity);
|
||||
if preserve_commit_layer {
|
||||
let _ = self.commit_entity_handle_preserve_layer(entity);
|
||||
} else {
|
||||
self.commit_entity(entity);
|
||||
}
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.tabs[i].scene.clear_preview_wire();
|
||||
|
||||
+11
-1
@@ -1238,8 +1238,18 @@ impl OpenCADStudio {
|
||||
.map(|e| (h, e))
|
||||
})
|
||||
.collect();
|
||||
let initial_edges: Vec<acadrust::Handle> = self.tabs[i]
|
||||
.scene
|
||||
.selected_entities()
|
||||
.into_iter()
|
||||
.filter_map(|(handle, entity)| {
|
||||
crate::modules::draw::modify::trim::is_trim_boundary_entity(&entity)
|
||||
.then_some(handle)
|
||||
})
|
||||
.collect();
|
||||
let all_entities: Vec<_> = entities.into_iter().map(|(_, e)| e).collect();
|
||||
let new_cmd = TrimCommand::new(all_entities);
|
||||
let new_cmd =
|
||||
TrimCommand::with_cutting_edges(all_entities, initial_edges);
|
||||
self.command_line.push_info(&new_cmd.prompt());
|
||||
self.tabs[i].active_cmd = Some(Box::new(new_cmd));
|
||||
}
|
||||
|
||||
+22
-3
@@ -2596,14 +2596,33 @@ impl OpenCADStudio {
|
||||
&mut self,
|
||||
entity: acadrust::EntityType,
|
||||
) -> Option<Handle> {
|
||||
self.commit_entity_handle_with_dimension_policy(entity, false)
|
||||
self.commit_entity_handle_with_policies(entity, false, false)
|
||||
}
|
||||
|
||||
/// Commit an entity, optionally preserving its source dimension style.
|
||||
pub(super) fn commit_entity_handle_with_dimension_policy(
|
||||
&mut self,
|
||||
entity: acadrust::EntityType,
|
||||
preserve_dimension_layer_and_style: bool,
|
||||
) -> Option<Handle> {
|
||||
self.commit_entity_handle_with_policies(
|
||||
entity,
|
||||
preserve_dimension_layer_and_style,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
pub(super) fn commit_entity_handle_preserve_layer(
|
||||
&mut self,
|
||||
entity: acadrust::EntityType,
|
||||
) -> Option<Handle> {
|
||||
self.commit_entity_handle_with_policies(entity, false, true)
|
||||
}
|
||||
|
||||
fn commit_entity_handle_with_policies(
|
||||
&mut self,
|
||||
mut entity: acadrust::EntityType,
|
||||
preserve_dimension_layer_and_style: bool,
|
||||
preserve_entity_layer: bool,
|
||||
) -> Option<Handle> {
|
||||
let i = self.active_tab;
|
||||
let tracks_dimension_chain = matches!(
|
||||
@@ -2692,7 +2711,7 @@ impl OpenCADStudio {
|
||||
};
|
||||
if let Some(layer) = explicit_mleader_layer {
|
||||
entity.as_entity_mut().set_layer(layer);
|
||||
} else {
|
||||
} else if !preserve_entity_layer {
|
||||
let layer = &self.tabs[i].active_layer;
|
||||
if layer != "0" || entity.as_entity().layer().is_empty() {
|
||||
entity.as_entity_mut().set_layer(layer.clone());
|
||||
|
||||
@@ -1734,6 +1734,11 @@ impl InputKind {
|
||||
}
|
||||
|
||||
pub trait CadCommand: Send {
|
||||
/// Keep the layer already carried by entities committed by this command
|
||||
/// instead of replacing it with the current drawing layer.
|
||||
fn preserve_commit_layer(&self) -> bool {
|
||||
false
|
||||
}
|
||||
/// Short name shown in the command line prompt, e.g. `"LINE"`.
|
||||
#[allow(dead_code)]
|
||||
fn name(&self) -> &'static str;
|
||||
|
||||
@@ -514,6 +514,9 @@ impl OffsetCommand {
|
||||
}
|
||||
|
||||
impl CadCommand for OffsetCommand {
|
||||
fn preserve_commit_layer(&self) -> bool {
|
||||
true
|
||||
}
|
||||
fn name(&self) -> &'static str {
|
||||
"OFFSET"
|
||||
}
|
||||
|
||||
@@ -149,7 +149,22 @@ impl Geo {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_trim_boundary_entity(entity: &EntityType) -> bool {
|
||||
matches!(
|
||||
entity,
|
||||
EntityType::Line(_)
|
||||
| EntityType::Arc(_)
|
||||
| EntityType::Circle(_)
|
||||
| EntityType::Ellipse(_)
|
||||
| EntityType::Ray(_)
|
||||
| EntityType::XLine(_)
|
||||
| EntityType::Spline(_)
|
||||
| EntityType::LwPolyline(_)
|
||||
| EntityType::Polyline(_)
|
||||
| EntityType::Polyline2D(_)
|
||||
| EntityType::Polyline3D(_)
|
||||
)
|
||||
}
|
||||
fn build_geos(entities: &[EntityType]) -> Vec<Geo> {
|
||||
let mut out = Vec::new();
|
||||
for e in entities {
|
||||
@@ -2169,21 +2184,33 @@ pub struct TrimCommand {
|
||||
|
||||
impl TrimCommand {
|
||||
pub fn new(all_entities: Vec<EntityType>) -> Self {
|
||||
Self::with_cutting_edges(all_entities, Vec::new())
|
||||
}
|
||||
|
||||
pub fn with_cutting_edges(
|
||||
all_entities: Vec<EntityType>,
|
||||
initial_edges: Vec<Handle>,
|
||||
) -> Self {
|
||||
let all_entities: Vec<EntityType> = all_entities
|
||||
.iter()
|
||||
.map(entity_with_lwpolyline_world_xy)
|
||||
.collect();
|
||||
|
||||
let entity_index = ModifyEntityIndex::build(&all_entities);
|
||||
let geos = build_geos(&all_entities);
|
||||
Self {
|
||||
|
||||
let mut cmd = Self {
|
||||
all_entities,
|
||||
entity_index,
|
||||
geos,
|
||||
geos: Vec::new(),
|
||||
mode: TrimMode::Pick,
|
||||
edge_set: Vec::new(),
|
||||
edge_set: initial_edges,
|
||||
implied_edges: false,
|
||||
shift: false,
|
||||
}
|
||||
};
|
||||
|
||||
cmd.rebuild_geos();
|
||||
|
||||
cmd
|
||||
}
|
||||
|
||||
/// Boundary geometry from the edge selection (or everything when none),
|
||||
|
||||
Reference in new issue
Block a user