Skip to content

Add Ctrl+D duplicate tool to sketcher - #369

Open
knipknap wants to merge 3 commits into
mainfrom
feat/sketcher-duplicate
Open

Add Ctrl+D duplicate tool to sketcher#369
knipknap wants to merge 3 commits into
mainfrom
feat/sketcher-duplicate

Conversation

@knipknap

Copy link
Copy Markdown
Contributor

Prerequisite

⚠️ This PR is based on #366 (feat/sketcher-mirror-tools), which must be merged to main first. Please merge that PR before this one.

Summary

Adds Ctrl+D in the sketcher to duplicate the selected entities and constraints in-place, following the same conventions as the mirror tools from #366:

  • Selected entities and their points are copied with fresh IDs.
  • Internal constraints (all references within the selection) are duplicated and remapped to the copies.
  • Constraints referencing geometry outside the selection are dropped (not copied), matching the mirror tools' boundary behavior.
  • Fixed points (e.g. the origin) are duplicated as regular movable points so the copy can be moved independently.
  • After duplicating, only the duplicates are selected; undo removes them and restores the previous state.

Hit-testing z-order fix

While testing it turned out that dragging after a duplicate grabbed the original line instead of the duplicate on top. Root cause: SketchHitTester iterated entities/points in list order, while rendering draws in list order too — so overlapping geometry was hit-tested bottom-first while being drawn top-last. Hit testing now iterates in reverse draw order so topmost geometry wins (nearest point still wins over a merely tied one).

Key changes

  • DuplicateCommand (sketcher/core/commands/duplicate.py) with pure prepare() resolution, deepcopy-based duplication and ID remapping
  • SketchElement.duplicate_selection() re-selects the new copies
  • Ctrl+D handled in SketchEditor.handle_key_press
  • Reverse draw-order iteration for entity/point hit tests in hittest.py
  • 21 new tests covering command behavior, undo, and hit-test z-order

Add Mirror Vertically and Mirror Horizontally toolbar buttons that
mirror the current selection in-place across the bounding-box center.
Constraints spanning the selection boundary are dropped; internal
constraints are preserved. Chirality-sensitive constraints
(AngleConstraint) are negated or dropped if expression-based.

Key changes:
- MirrorCommand with MirrorAxis/MirrorDirection enum
- Polymorphic Entity.mirror() (Bezier flips cp deltas, Arc toggles
  clockwise)
- Polymorphic Constraint.mirror() / is_mirror_compatible()
  (AngleConstraint negates signed value)
- Constraint.get_referenced_point_ids()/get_referenced_entity_ids()
  refactored from depends_on_* for reuse
- Bezier.get_state()/set_state() extended to include cp1/cp2 for
  snapshot-based undo
- SHOW_IN_PIE flag on SketchTool to exclude mirror from pie menu
- Toolbar buttons after fill color selector with separator
- 24 unit tests covering prepare, execute, undo, and all edge cases

Refs #358
Ctrl+D duplicates the current selection in-place: selected entities
and their points are copied with fresh IDs, internal constraints
(all references within the selection) are copied and remapped to the
duplicates. Constraints referencing geometry outside the selection
are not copied, matching the mirror tools' behavior. Fixed points
(e.g. the origin) are duplicated as movable points. After
duplicating, only the copies are selected. Undo removes the
duplicates and restores the previous state.

Also fixes a hit-testing z-order issue: entities and points were
hit-tested in list order while rendering draws in list order, so
overlapping geometry (e.g. fresh duplicates drawn on top) picked the
wrong item on click/drag. Hit testing now iterates in reverse draw
order so topmost geometry wins.

Key changes:
- DuplicateCommand with prepare() for pure parameter resolution,
  deepcopy-based duplication and ID remapping
- SketchElement.duplicate_selection() re-selects the new copies
- Ctrl+D handled in SketchEditor key handling
- Hit testing in hittest.py reversed to respect z-order
- 21 new tests (command behavior, undo, hit-test z-order)

Based on feat/sketcher-mirror-tools (#366), which must be merged to
main first.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant