Design: in-canvas gizmos for Draft/Cut + operand highlight for Boolean/Sweep/Loft

Closes the gizmo-parity gap (bd snaporca-4h5): the five solid features that were
card-only now give in-canvas feedback like their siblings.

Draft — angle-arc drag gizmo (clone of the Revolve gizmo): once a side face is
picked, a cyan arc anchored at the face centroid shows the taper angle; drag the
tip or type the angle, the live ghost tapers with it. Axis = world +Z (the neutral
pull direction), clamped [-89, 89].

Cut — plane offset-arrow + cutting-plane rectangle (clone of the Shell arrow, adds
a wire rectangle in the cut plane sized to the target body bbox). The arrow drags
the signed offset along the plane normal; the rectangle rides at the cut position;
the ghost splits live. (Also covers bd snaporca-1gh / snaporca-mmr.)

Boolean / Sweep / Loft — operand highlighting (new by-index highlight infra):
- Boolean tints the target body teal-green and the tool body orange (per-index
  body tint added to the DesignCanvas GLVolume colour loop + set_operand_bodies).
- Sweep tints the profile sketch cyan and the path sketch magenta.
- Loft tints every selected profile sketch green.
  Sketch tints reuse the DisplaySketch overlay via a feature-index -> colour map
  (sketch_hl_color); DisplaySketch struct unchanged. All self-gate by active tool
  and clear on close_tool.

Wiring mirrors the existing gizmo pattern 1:1 (m_*_active / render_* / set_* /
clear_* / update_* in refresh_preview / DesignCanvas passthroughs / render dispatch
+ on_mouse drag branch). Both forks; DesignSketchTool.{cpp,hpp} + DesignCanvas.hpp
+ DesignPanel.hpp byte-identical across forks. Built clean on both. Draft, Cut and
Boolean highlight live-verified on :10; Sweep/Loft sketch tint is code-complete and
build-clean (visual check pending — needs hand-drawn profile/path sketches).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BVzKmX6Y1aEteit1HTXG4Q
This commit is contained in:
Tommaso Bianchi
2026-07-01 10:19:33 +02:00
co-authored by Claude Opus 4.8
parent 8cbf5b393b
commit 5a005d4728
6 changed files with 476 additions and 4 deletions
+17 -1
View File
@@ -130,6 +130,18 @@ public:
void clear_revolve_gizmo();
bool revolving() const;
void set_on_revolve_angle_changed(std::function<void(double)> cb);
// Visual Draft angle-arc gizmo: the panel feeds the face centroid + face normal + angle while
// its Draft card is open; drag/edit fire the angle callback.
void set_draft_gizmo(const Vec3d& face_centroid, const Vec3d& face_normal, double angle);
void clear_draft_gizmo();
bool drafting() const;
void set_on_draft_angle_changed(std::function<void(double)> cb);
// Visual Cut gizmo: plane-rectangle preview + draggable normal offset arrow while
// the Cut card is open; drag fires the offset callback.
void set_cut_gizmo(const SketchPlane& plane, double offset, const Vec3d& body_center, double half_extent);
void clear_cut_gizmo();
bool cutting() const;
void set_on_cut_offset_changed(std::function<void(double)> cb);
// Visual Pattern gizmo: the panel feeds the (world XY) plane + target body centroid + mode +
// count/dir/spacing/angle while its Pattern card is open; drag/edit fire the value callback.
void begin_pattern_gizmo(const SketchPlane& plane, const Vec3d& body_centroid, bool circular,
@@ -157,9 +169,11 @@ public:
void set_on_undo_redo(std::function<void(bool /*redo*/)> cb); // Ctrl+Z / Ctrl+Shift+Z
// Persistently draw committed sketches (un-consumed ones stay visible).
void set_display_sketches(std::vector<DesignSketchTool::DisplaySketch> ds);
void set_highlight_sketches(std::vector<std::pair<int, ColorRGBA>> hl);
void set_datum_planes(std::vector<SketchPlane> planes,
std::vector<Vec2d> sizes = {}); // draw datum/reference planes (u/v extents)
std::vector<Vec2d> sizes = {}); // draw datum/reference planes (u/v extents)
void set_body_highlight(bool on); // tint the solid when its feature is tree-selected
void set_operand_bodies(int target_body, int tool_body); // -1,-1 clears
void set_body_translucent(bool on); // render the solid see-through (fillet/chamfer preview)
void set_body_hidden(bool on); // preview-only: hide base bodies, show only the result ghost
void set_on_move_exit(std::function<void()> cb); // right-click finished the move-body gizmo
@@ -229,6 +243,8 @@ private:
Model m_model;
bool m_first_frame{true};
bool m_body_selected{false}; // tree selected a body feature → tint the solid
int m_hl_body_target{-1};
int m_hl_body_tool{-1};
bool m_body_translucent{false};// fillet/chamfer preview → render the body see-through
bool m_body_hidden{false}; // preview-only mode → hide base bodies, ghost = the result
std::vector<bool> m_body_visible; // per-body visibility (empty => all visible)