mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-18 22:42:37 +00:00
Design: port the Orca-widget rebuild and the mouse-press fix from snaporca
Mirrors snaporca-cad a016dffb48 + 4b828c4798 so the two forks do not drift:
- Sidebar on Orca's widget set: ComboBox for all 25 pickers, StaticBox
frames for the tool cards / feature tree / bodies list, framed double
spins, and no stack of full-width action buttons (Prepare's left panel
is parameters only).
- Toolbar: document group + undo/redo + mode-gated tools, commit far
right, ordered via keyed slots, at Prepare's 40 px / 4 px geometry.
- Polygon options and a new Move/Rotate card (distance, axis, angle) in
the sidebar instead of inline in the toolbar row.
- DesignSketchTool: stop consuming the LeftDown over a solid. Orca starts
a rotate drag on the press, so swallowing it killed orbit/pan whenever a
body was on screen. The pick now resolves on LeftUp within 4 px.
DesignSketchTool.{cpp,hpp} were byte-identical across the forks and are
copied verbatim. DesignPanel.cpp needed one hand-merge: mainline's
DropDown is Item-based (DropDown::Item{text,tip,icon}, DropDown(items&))
where snaporca passes parallel vectors, so feat_dropdown/ToolFlyout keep
the mainline form. Checked field-by-field against this fork's
Widgets/DropDown.hpp.
scripts/docker-iter-build.sh: mount the root CMakeLists.txt and cmake/
rather than inheriting the baked copies, which silently drops the
SLIC3R_CAD gate, and stop defaulting to snaporca's build volume - sharing
it made the two forks overwrite each other's cache and binary.
NOT COMPILED. This fork needs Eigen 5.0.1 (find_package(Eigen3 5.0.1
REQUIRED)) while the available snaporca-deps image supplies 3.3, so it
needs its own deps build to verify. The behaviour above was verified only
on the snaporca side.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BVzKmX6Y1aEteit1HTXG4Q
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
f4469b8450
commit
b3e7d65cca
@@ -19,13 +19,19 @@ set -euo pipefail
|
||||
|
||||
REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
IMAGE="${IMAGE:-snaporca-deps}"
|
||||
BUILD_VOL="${BUILD_VOL:-snaporca_buildcache}"
|
||||
BUILD_VOL="${BUILD_VOL:-orcacad_buildcache}"
|
||||
|
||||
echo "REPO=$REPO IMAGE=$IMAGE BUILD_VOL=$BUILD_VOL"
|
||||
|
||||
# The root CMakeLists.txt and cmake/ must be mounted too, not taken from the baked image:
|
||||
# they carry the build-time gates (e.g. SLIC3R_CAD -> add_definitions(-DSLIC3R_CAD)) that the
|
||||
# mounted headers are compiled against. With a stale baked copy the gate silently stays off and
|
||||
# the build fails with "class GLCanvas3D has no member named set_design_sketch_tool".
|
||||
docker run --rm \
|
||||
-v "$REPO/src":/OrcaSlicer/src \
|
||||
-v "$REPO/resources":/OrcaSlicer/resources \
|
||||
-v "$REPO/CMakeLists.txt":/OrcaSlicer/CMakeLists.txt \
|
||||
-v "$REPO/cmake":/OrcaSlicer/cmake \
|
||||
-v "$BUILD_VOL":/OrcaSlicer/build \
|
||||
"$IMAGE" \
|
||||
bash -lc 'cd /OrcaSlicer && ./build_linux.sh -sr'
|
||||
|
||||
+647
-387
File diff suppressed because it is too large
Load Diff
@@ -12,7 +12,8 @@
|
||||
|
||||
#include "libslic3r/CadDocument.hpp"
|
||||
|
||||
class wxChoice;
|
||||
class ComboBox; // Orca dropdown (Widgets/ComboBox.hpp) — replaces wxChoice everywhere here
|
||||
class StaticBox; // Orca rounded card frame (Widgets/StaticBox.hpp)
|
||||
class wxCheckBox;
|
||||
class wxCheckListBox;
|
||||
class wxSpinCtrl;
|
||||
@@ -178,7 +179,7 @@ private:
|
||||
int resolve_extrude_sketch() const;
|
||||
// Plane pickers: fill a choice with XY/XZ/YZ + the document's datum planes, and
|
||||
// map a choice row back to the actual SketchPlane (rows 0-2 base, 3+ datum).
|
||||
void populate_plane_choices(wxChoice* c) const;
|
||||
void populate_plane_choices(ComboBox* c) const;
|
||||
SketchPlane plane_from_choice(int row) const;
|
||||
// True when Extrude should build only the click-selected loop (a region of the
|
||||
// resolved sketch is selected and it carries entities).
|
||||
@@ -212,6 +213,18 @@ private:
|
||||
std::map<int, std::function<void()>> m_keys_sketch;
|
||||
std::map<int, std::function<void()>> m_keys_feature;
|
||||
|
||||
StaticBox* m_tree_box{nullptr}; // framed feature-tree section
|
||||
StaticBox* m_parts_box{nullptr}; // framed bodies section (hidden while empty)
|
||||
StaticBox* m_cards{nullptr}; // one framed panel holding every tool dialog (one visible at a time)
|
||||
void update_cards_frame(); // show that frame iff some card inside it is visible
|
||||
void show_polygon_card(bool show);
|
||||
void show_move_card(bool show);
|
||||
void apply_move_card(); // numeric move/rotate -> same xform the gizmo builds
|
||||
void push_polygon_params();
|
||||
wxSizer* m_tb_commit{nullptr}; // far-right Commit to Plate, beside Confirm/Cancel
|
||||
wxSizer* m_tb_doc{nullptr}; // toolbar document/view actions (new, commit, export, section, place)
|
||||
wxSizer* m_box_move{nullptr}; // Move/Rotate numeric options (distance, axis, angle)
|
||||
wxSizer* m_box_polygon{nullptr}; // Polygon tool options (sides / circumscribed)
|
||||
wxSizer* m_box_sketch{nullptr};
|
||||
wxSizer* m_box_extrude{nullptr};
|
||||
wxSizer* m_box_dressup{nullptr};
|
||||
@@ -235,6 +248,8 @@ private:
|
||||
|
||||
// Onshape-style dialog-card title rows (icon + bold feature name), retitled
|
||||
// per tool in open_tool() (edit-mode shows the feature's actual name).
|
||||
wxStaticText* m_hdr_polygon{nullptr};
|
||||
wxStaticText* m_hdr_move{nullptr};
|
||||
wxStaticText* m_hdr_sketch{nullptr};
|
||||
// Onshape sketch-entry card (plane/orientation) that opens on "New sketch" and
|
||||
// persists until Finish (Phase 3).
|
||||
@@ -281,18 +296,23 @@ private:
|
||||
// Owns the themed DropDown flyouts (and the item vectors they hold by ref).
|
||||
std::vector<std::shared_ptr<void>> m_flyout_keepalive;
|
||||
wxCheckBox* m_construction{nullptr}; // sketch-mode construction toggle
|
||||
wxSpinCtrlDouble* m_move_dx{nullptr}; // Move/Rotate card: world translation
|
||||
wxSpinCtrlDouble* m_move_dy{nullptr};
|
||||
wxSpinCtrlDouble* m_move_dz{nullptr};
|
||||
ComboBox* m_move_axis{nullptr}; // rotation axis: X/Y/Z
|
||||
wxSpinCtrlDouble* m_move_angle{nullptr}; // rotation angle (deg)
|
||||
wxSpinCtrl* m_sides{nullptr}; // polygon sides
|
||||
wxCheckBox* m_poly_circ{nullptr}; // polygon circumscribed toggle
|
||||
CheckBox* m_poly_circ{nullptr}; // polygon circumscribed toggle (Orca teal check)
|
||||
|
||||
wxChoice* m_draw_plane{nullptr};
|
||||
wxChoice* m_shape{nullptr};
|
||||
wxChoice* m_plane{nullptr};
|
||||
wxChoice* m_mode{nullptr};
|
||||
ComboBox* m_draw_plane{nullptr};
|
||||
ComboBox* m_shape{nullptr};
|
||||
ComboBox* m_plane{nullptr};
|
||||
ComboBox* m_mode{nullptr};
|
||||
wxSpinCtrlDouble* m_width{nullptr};
|
||||
wxSpinCtrlDouble* m_height{nullptr};
|
||||
wxSpinCtrlDouble* m_radius{nullptr};
|
||||
wxSpinCtrlDouble* m_distance{nullptr};
|
||||
wxChoice* m_extrude_end{nullptr}; // Blind/Symmetric/TwoSided/ThroughAll/UpTo*
|
||||
ComboBox* m_extrude_end{nullptr}; // Blind/Symmetric/TwoSided/ThroughAll/UpTo*
|
||||
wxSpinCtrlDouble* m_distance2{nullptr}; // second-side depth (Two-sided)
|
||||
wxSpinCtrlDouble* m_taper{nullptr}; // draft angle (deg)
|
||||
CheckBox* m_flip{nullptr}; // reverse extrude direction
|
||||
@@ -303,50 +323,50 @@ private:
|
||||
// Revolve controls (sweep a sketch profile about an in-plane axis).
|
||||
wxStaticText* m_revolve_sketch_label{nullptr};
|
||||
wxSpinCtrlDouble* m_revolve_angle{nullptr};
|
||||
wxChoice* m_revolve_axis{nullptr}; // 0 = plane X, 1 = plane Y
|
||||
wxChoice* m_revolve_mode{nullptr}; // New/Add/Cut/Intersect
|
||||
ComboBox* m_revolve_axis{nullptr}; // 0 = plane X, 1 = plane Y
|
||||
ComboBox* m_revolve_mode{nullptr}; // New/Add/Cut/Intersect
|
||||
CheckBox* m_revolve_flip{nullptr};
|
||||
int m_revolve_sketch_ref{-1};
|
||||
|
||||
// Sweep controls (sweep a profile sketch along a path sketch).
|
||||
wxStaticText* m_sweep_profile_label{nullptr};
|
||||
wxChoice* m_sweep_path{nullptr}; // path Sketch picker (feature index in client data)
|
||||
wxChoice* m_sweep_mode{nullptr}; // New/Add/Cut/Intersect
|
||||
ComboBox* m_sweep_path{nullptr}; // path Sketch picker (feature index in client data)
|
||||
ComboBox* m_sweep_mode{nullptr}; // New/Add/Cut/Intersect
|
||||
int m_sweep_profile_ref{-1};
|
||||
int m_sweep_path_ref{-1}; // path Sketch feature index (for re-edit pre-select)
|
||||
|
||||
// Loft controls (skin a solid through 2+ ordered profile Sketches).
|
||||
wxCheckListBox* m_loft_list{nullptr}; // every Sketch; check 2+ in list order = profiles
|
||||
CheckBox* m_loft_ruled{nullptr}; // ruled (straight) vs smooth sections
|
||||
wxChoice* m_loft_mode{nullptr}; // New/Add/Cut/Intersect
|
||||
ComboBox* m_loft_mode{nullptr}; // New/Add/Cut/Intersect
|
||||
std::vector<int> m_loft_sketch_idx; // feature index for each row in m_loft_list
|
||||
std::vector<int> m_loft_refs; // chosen profile refs (for re-edit pre-check)
|
||||
|
||||
// Pattern controls (replicate the target body: linear or circular).
|
||||
wxChoice* m_pattern_type{nullptr}; // 0 = Linear, 1 = Circular
|
||||
ComboBox* m_pattern_type{nullptr}; // 0 = Linear, 1 = Circular
|
||||
wxSpinCtrlDouble* m_pattern_count{nullptr}; // total instances incl. seed
|
||||
wxSpinCtrlDouble* m_pattern_spacing{nullptr}; // linear step (mm)
|
||||
wxChoice* m_pattern_dir{nullptr}; // linear direction: 0 = plane X, 1 = plane Y
|
||||
ComboBox* m_pattern_dir{nullptr}; // linear direction: 0 = plane X, 1 = plane Y
|
||||
wxSpinCtrlDouble* m_pattern_angle{nullptr}; // circular total angle (deg)
|
||||
// Boolean controls (combine two existing bodies).
|
||||
wxChoice* m_bool_op{nullptr}; // 0 = Union, 1 = Subtract, 2 = Intersect
|
||||
wxChoice* m_bool_target{nullptr}; // body that survives (selection == body index)
|
||||
wxChoice* m_bool_tool{nullptr}; // body consumed (selection == body index)
|
||||
ComboBox* m_bool_op{nullptr}; // 0 = Union, 1 = Subtract, 2 = Intersect
|
||||
ComboBox* m_bool_target{nullptr}; // body that survives (selection == body index)
|
||||
ComboBox* m_bool_tool{nullptr}; // body consumed (selection == body index)
|
||||
CheckBox* m_bool_keep{nullptr}; // keep the tool body after the op
|
||||
wxSpinCtrlDouble* m_bool_tol{nullptr}; // OCCT fuzzy tolerance (mm); robust cut on near-coincident faces
|
||||
|
||||
// Plane Cut (split-by-plane): a reference plane + offset splits the target body into
|
||||
// two separate bodies (both pieces kept).
|
||||
wxChoice* m_cut_plane{nullptr}; // XY/XZ/YZ + datum planes (cut plane)
|
||||
wxChoice* m_cut_target{nullptr}; // body to cut (selection == body index)
|
||||
ComboBox* m_cut_plane{nullptr}; // XY/XZ/YZ + datum planes (cut plane)
|
||||
ComboBox* m_cut_target{nullptr}; // body to cut (selection == body index)
|
||||
wxSpinCtrlDouble* m_cut_offset{nullptr}; // offset along the plane normal (mm)
|
||||
// Datum plane controls (derive a selectable sketch plane: offset + tilt from a base).
|
||||
wxChoice* m_plane_base{nullptr}; // 0=XY,1=XZ,2=YZ, 3+N = Nth datum plane
|
||||
ComboBox* m_plane_base{nullptr}; // 0=XY,1=XZ,2=YZ, 3+N = Nth datum plane
|
||||
wxSpinCtrlDouble* m_plane_offset{nullptr}; // offset along base normal (mm)
|
||||
wxSpinCtrlDouble* m_plane_tilt{nullptr}; // tilt about a base axis (deg) / Angle / Tangent angle
|
||||
wxChoice* m_plane_tilt_axis{nullptr}; // 0 = base X, 1 = base Y
|
||||
ComboBox* m_plane_tilt_axis{nullptr}; // 0 = base X, 1 = base Y
|
||||
// Plane construction method + contextual face/edge reference picks (Onshape/Fusion parity).
|
||||
wxChoice* m_plane_type{nullptr}; // PlaneType: Offset/Angle/Midplane/Tangent/TwoEdges/Coincident
|
||||
ComboBox* m_plane_type{nullptr}; // PlaneType: Offset/Angle/Midplane/Tangent/TwoEdges/Coincident
|
||||
wxButton* m_plane_pick_faceA{nullptr}; wxStaticText* m_plane_faceA_lbl{nullptr};
|
||||
wxButton* m_plane_pick_faceB{nullptr}; wxStaticText* m_plane_faceB_lbl{nullptr};
|
||||
wxButton* m_plane_pick_edgeA{nullptr}; wxStaticText* m_plane_edgeA_lbl{nullptr};
|
||||
@@ -372,11 +392,11 @@ private:
|
||||
// -1 = ordinary sketch/loop extrude. Set when opening the Extrude card, consumed on add.
|
||||
int m_extrude_face_src{-1};
|
||||
|
||||
wxChoice* m_dressup_type{nullptr};
|
||||
wxChoice* m_face_group{nullptr};
|
||||
ComboBox* m_dressup_type{nullptr};
|
||||
ComboBox* m_face_group{nullptr};
|
||||
wxSpinCtrlDouble* m_dressup_size{nullptr};
|
||||
|
||||
wxChoice* m_hole_plane{nullptr};
|
||||
ComboBox* m_hole_plane{nullptr};
|
||||
wxSpinCtrlDouble* m_hole_diameter{nullptr};
|
||||
wxSpinCtrlDouble* m_hole_depth{nullptr};
|
||||
CheckBox* m_hole_through{nullptr};
|
||||
@@ -393,8 +413,8 @@ private:
|
||||
bool m_hole_has_bounds{false};
|
||||
double m_hole_umin{0}, m_hole_umax{0}, m_hole_vmin{0}, m_hole_vmax{0};
|
||||
|
||||
wxChoice* m_thread_plane{nullptr};
|
||||
wxChoice* m_thread_std{nullptr}; // standard designation (M6, 1/4-20 UNC, ...)
|
||||
ComboBox* m_thread_plane{nullptr};
|
||||
ComboBox* m_thread_std{nullptr}; // standard designation (M6, 1/4-20 UNC, ...)
|
||||
wxSpinCtrlDouble* m_thread_radius{nullptr};
|
||||
wxSpinCtrlDouble* m_thread_pitch{nullptr};
|
||||
wxSpinCtrlDouble* m_thread_height{nullptr};
|
||||
@@ -449,7 +469,7 @@ private:
|
||||
bool m_section_on{false};
|
||||
double m_section_cut_z{0.0};
|
||||
bool m_section_upper{false}; // false = keep lower half, true = upper
|
||||
Button* m_section_flip_btn{nullptr}; // enabled only while the section is on
|
||||
ScalableButton* m_section_flip_btn{nullptr}; // toolbar action; enabled only while the section is on
|
||||
void toggle_section_view(); // Section View button / X: on <-> off
|
||||
void flip_section_view(); // Flip button / F: opposite half
|
||||
void update_section_flip_btn(); // enable the Flip button iff the section is on
|
||||
|
||||
@@ -7641,7 +7641,21 @@ bool DesignSketchTool::on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (!evt.LeftDown()) return false;
|
||||
// Click vs drag. Consuming the LeftDown here killed camera orbit/pan the moment a
|
||||
// solid was on screen: Orca starts a rotate drag on the press, so swallowing it meant
|
||||
// the canvas never began one. (A SpaceMouse kept working — it never goes through
|
||||
// wxMouseEvent.) Remember the press, let it fall through so the canvas can orbit, and
|
||||
// resolve the pick on release only if the pointer stayed put.
|
||||
if (evt.LeftDown()) {
|
||||
m_pick_press_x = evt.GetX();
|
||||
m_pick_press_y = evt.GetY();
|
||||
m_pick_pending = true;
|
||||
return false;
|
||||
}
|
||||
if (!(evt.LeftUp() && m_pick_pending)) return false;
|
||||
m_pick_pending = false;
|
||||
if (std::abs(evt.GetX() - m_pick_press_x) + std::abs(evt.GetY() - m_pick_press_y) > 4)
|
||||
return false; // it was a drag: the canvas already orbited, don't also select
|
||||
// Committed-sketch loop pick is computed FIRST. A click that lands on a loop's
|
||||
// STROKE (edge) selects that loop even when it lies on a solid face — so a sketch
|
||||
// drawn ON a face can be selected and extruded/cut (Onshape engraving workflow).
|
||||
|
||||
@@ -96,6 +96,11 @@ public:
|
||||
struct DisplaySketch { std::vector<SketchEntity> entities; SketchPlane plane; int feature{-1}; };
|
||||
void set_display_sketches(std::vector<DisplaySketch> ds) { m_display_sketches = std::move(ds); }
|
||||
void set_highlight_sketches(std::vector<std::pair<int, ColorRGBA>> hl) { m_hl_sketches = std::move(hl); }
|
||||
// Solid pick is resolved on LeftUp (see on_mouse): consuming the press broke orbit/pan.
|
||||
int m_pick_press_x = 0;
|
||||
int m_pick_press_y = 0;
|
||||
bool m_pick_pending = false;
|
||||
|
||||
bool has_display() const { return m_active || !m_display_sketches.empty()
|
||||
|| (m_solid_bodies != nullptr && !m_solid_bodies->empty())
|
||||
|| !m_datum_planes.empty()
|
||||
|
||||
Reference in New Issue
Block a user