forked from 1b-agent/opencadstudio-upstream
fix(paste): pasted associative hatches follow the pasted boundary
Paste (and WBLOCK, which shares the kernel) kept the source boundary handles, so the pasted hatch stayed tied to the original outline or to unrelated handles in another drawing. The COPY remap now lives at the document level and runs for both. Refs #1370 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
71b300cc44
commit
3754426361
3 files changed
+39
-28
No files matched your search
@@ -543,6 +543,9 @@ pub(crate) fn paste_entities_kernel(
|
||||
handle_map.insert(source.common().handle, copied);
|
||||
}
|
||||
}
|
||||
// A pasted associative hatch follows the pasted boundary, or drops the
|
||||
// association when the boundary was not pasted with it. (#1370)
|
||||
crate::scene::remap_hatch_associations(doc, &handle_map);
|
||||
let leader_links: Vec<(Handle, Handle)> = entities
|
||||
.iter()
|
||||
.filter_map(|source| {
|
||||
|
||||
+35
-27
@@ -720,6 +720,39 @@ pub(crate) fn boundary_entities_from_sources(
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// A duplicated associative hatch must follow the duplicated boundary, not the
|
||||
/// source one — otherwise editing the source regenerates the duplicate onto
|
||||
/// the source's outline and it seems to vanish. A path whose boundary was not
|
||||
/// duplicated along loses its association. `handle_map` maps source handles
|
||||
/// to their duplicates (COPY and paste both build one). (#1370)
|
||||
pub(crate) fn remap_hatch_associations(
|
||||
doc: &mut codec::CadDocument,
|
||||
handle_map: &rustc_hash::FxHashMap<Handle, Handle>,
|
||||
) -> bool {
|
||||
let mut touched = false;
|
||||
for © in handle_map.values() {
|
||||
let Some(EntityType::Hatch(hatch)) = doc.get_entity_mut(copy) else {
|
||||
continue;
|
||||
};
|
||||
if !hatch.is_associative {
|
||||
continue;
|
||||
}
|
||||
for path in &mut hatch.paths {
|
||||
if path.boundary_handles.iter().all(|source| handle_map.contains_key(source)) {
|
||||
for source in &mut path.boundary_handles {
|
||||
*source = handle_map[source];
|
||||
}
|
||||
} else {
|
||||
path.boundary_handles.clear();
|
||||
path.flags.set_external(false);
|
||||
}
|
||||
}
|
||||
hatch.is_associative = hatch.paths.iter().any(|path| !path.boundary_handles.is_empty());
|
||||
touched = true;
|
||||
}
|
||||
touched
|
||||
}
|
||||
|
||||
impl Scene {
|
||||
pub(crate) fn replace_hatch_association(&mut self,handle:Handle,paths:Vec<codec::entities::BoundaryPath>) {
|
||||
let Some(EntityType::Hatch(hatch))=self.document.get_entity_mut(handle) else{return;};
|
||||
@@ -729,37 +762,12 @@ impl Scene {
|
||||
self.refresh_fill_model(handle);
|
||||
}
|
||||
|
||||
/// A copied associative hatch must follow the copied boundary, not the
|
||||
/// source one — otherwise editing the source regenerates the copy onto the
|
||||
/// source's outline and the copy seems to vanish. A path whose boundary
|
||||
/// was not copied along loses its association. (#1370)
|
||||
/// COPY's half of [`remap_hatch_associations`], plus the cache it feeds.
|
||||
pub(crate) fn copy_hatch_associations(
|
||||
&mut self,
|
||||
handle_map: &rustc_hash::FxHashMap<Handle, Handle>,
|
||||
) {
|
||||
let mut touched = false;
|
||||
for © in handle_map.values() {
|
||||
let Some(EntityType::Hatch(hatch)) = self.document.get_entity_mut(copy) else {
|
||||
continue;
|
||||
};
|
||||
if !hatch.is_associative {
|
||||
continue;
|
||||
}
|
||||
for path in &mut hatch.paths {
|
||||
if path.boundary_handles.iter().all(|source| handle_map.contains_key(source)) {
|
||||
for source in &mut path.boundary_handles {
|
||||
*source = handle_map[source];
|
||||
}
|
||||
} else {
|
||||
path.boundary_handles.clear();
|
||||
path.flags.set_external(false);
|
||||
}
|
||||
}
|
||||
hatch.is_associative =
|
||||
hatch.paths.iter().any(|path| !path.boundary_handles.is_empty());
|
||||
touched = true;
|
||||
}
|
||||
if touched {
|
||||
if remap_hatch_associations(&mut self.document, handle_map) {
|
||||
self.associative_hatch_source_cache.borrow_mut().take();
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@ mod parametric_solve;
|
||||
pub(crate) use boundary::{
|
||||
boundary_entities, boundary_entities_from_sources, boundary_faces, boundary_polyline_entities,
|
||||
exact_hatch_paths, hatch_boundary_rings, hatch_path_directions, hatch_path_ring,
|
||||
ring_source_handles, separated_hatch_path_groups, BoundarySource,
|
||||
remap_hatch_associations, ring_source_handles, separated_hatch_path_groups, BoundarySource,
|
||||
};
|
||||
|
||||
// Parallel tessellation free functions live in `convert::tess` (alongside the
|
||||
|
||||
Reference in new issue
Block a user