Skip to content

Commit 90286e5

Browse files
authored
Merge pull request #3 from phil-QS/pr/plugin-gizmo
feat: add runtime plugin gizmo slot
2 parents c4b536f + eea80a8 commit 90286e5

6 files changed

Lines changed: 52 additions & 1 deletion

File tree

.github/workflows/build_all.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ on:
44
push:
55
branches:
66
- main
7+
- xgo
78
- release/*
89
paths:
910
- 'deps/**'
@@ -18,6 +19,7 @@ on:
1819
pull_request:
1920
branches:
2021
- main
22+
- xgo
2123
- release/*
2224
paths:
2325
- 'deps/**'

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,8 @@ endfunction()
899899
# libslic3r, OrcaSlicer GUI and the OrcaSlicer executable.
900900
add_subdirectory(deps_src)
901901
add_subdirectory(src)
902+
# Plugin extension hook — absent in xgo/upstream PR branch, present only in x3d branch.
903+
include("${CMAKE_SOURCE_DIR}/x3d_root.cmake" OPTIONAL)
902904
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT OrcaSlicer_app_gui)
903905

904906
add_dependencies(gettext_make_pot hintsToPot)

src/slic3r/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,3 +807,6 @@ endif ()
807807

808808
# Add a definition so that we can tell we are compiling slic3r.
809809
target_compile_definitions(libslic3r_gui PRIVATE SLIC3R_CURRENTLY_COMPILING_GUI_MODULE)
810+
811+
# Plugin extension hook — absent in xgo/upstream PR branch, present only in x3d branch.
812+
include("${CMAKE_CURRENT_SOURCE_DIR}/x3d_plugin.cmake" OPTIONAL)

src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,9 +312,10 @@ class GLGizmoPainterBase : public GLGizmoBase
312312

313313
TriangleSelector::ClippingPlane get_clipping_plane_in_volume_coordinates(const Transform3d &trafo) const;
314314

315-
private:
315+
protected:
316316
std::vector<std::vector<ProjectedMousePosition>> get_projected_mouse_positions(const Vec2d &mouse_position, double resolution, const std::vector<Transform3d> &trafo_matrices) const;
317317

318+
private:
318319
std::vector<ProjectedHeightRange> get_projected_height_range(const Vec2d& mouse_position, double resolution, const std::vector<const ModelVolume*>& part_volumes, const std::vector<Transform3d>& trafo_matrices) const;
319320

320321
bool is_mesh_point_clipped(const Vec3d& point, const Transform3d& trafo) const;
@@ -381,6 +382,18 @@ class GLGizmoPainterBase : public GLGizmoBase
381382
friend class ::Slic3r::GUI::GLGizmoMmuSegmentation;
382383
};
383384

385+
// Plugin interface: custom gizmos registered at runtime via pluginSpriteFactory
386+
class IGLSprite : public GLGizmoPainterBase {
387+
public:
388+
using GLGizmoPainterBase::GLGizmoPainterBase;
389+
virtual void set_icon(bool is_dark) = 0;
390+
virtual bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down) = 0;
391+
};
392+
393+
using IGLSpriteFactory = IGLSprite*(*)(GLCanvas3D&);
394+
395+
// Returns a reference to the global factory slot — safe to call before main().
396+
IGLSpriteFactory& get_plugin_factory_slot();
384397

385398
} // namespace Slic3r::GUI
386399

src/slic3r/GUI/Gizmos/GLGizmosManager.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "libslic3r/libslic3r.h"
22
#include "GLGizmosManager.hpp"
3+
#include "slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp"
34
#include "slic3r/GUI/GLCanvas3D.hpp"
45
#include "slic3r/GUI/3DScene.hpp"
56
#include "slic3r/GUI/Camera.hpp"
@@ -43,6 +44,13 @@ const float GLGizmosManager::Default_Icons_Size = 40;
4344
const float GLGizmosManager::Default_Icons_Size = 64;
4445
#endif
4546

47+
// Function-local static — guaranteed to be initialized on first call, before any use.
48+
// Safe to call from QAgentAutoRegister constructor (before main).
49+
IGLSpriteFactory& get_plugin_factory_slot() {
50+
static IGLSpriteFactory s_factory = nullptr;
51+
return s_factory;
52+
}
53+
4654
GLGizmosManager::GLGizmosManager(GLCanvas3D& parent)
4755
: m_parent(parent)
4856
, m_enabled(false)
@@ -131,6 +139,7 @@ void GLGizmosManager::switch_gizmos_icon_filename()
131139
m_background_texture.texture.load_from_file(resources_dir() + "/images/" + m_background_texture.metadata.filename, false, GLTexture::SingleThreaded, false);
132140

133141
for (auto& gizmo : m_gizmos) {
142+
if (!gizmo) continue; // nullptr = unregistered plugin slot, skip
134143
gizmo->on_change_color_mode(m_is_dark);
135144
switch (gizmo->get_sprite_id())
136145
{
@@ -176,6 +185,10 @@ void GLGizmosManager::switch_gizmos_icon_filename()
176185
case (EType::BrimEars):
177186
gizmo->set_icon_filename(m_is_dark ? "toolbar_brimears_dark.svg" : "toolbar_brimears.svg");
178187
break;
188+
case (EType::CustomEType):
189+
if (auto* sprite = dynamic_cast<IGLSprite*>(gizmo.get()))
190+
sprite->set_icon(m_is_dark);
191+
break;
179192
}
180193

181194
}
@@ -219,6 +232,14 @@ bool GLGizmosManager::init()
219232
m_gizmos.emplace_back(new GLGizmoAssembly(m_parent, m_is_dark ? "toolbar_assembly_dark.svg" : "toolbar_assembly.svg", EType::Assembly));
220233
m_gizmos.emplace_back(new GLGizmoSimplify(m_parent, "reduce_triangles.svg", EType::Simplify));
221234
m_gizmos.emplace_back(new GLGizmoBrimEars(m_parent, m_is_dark ? "toolbar_brimears_dark.svg" : "toolbar_brimears.svg", EType::BrimEars));
235+
if (auto* factory = get_plugin_factory_slot()) {
236+
if (auto* sprite = factory(m_parent))
237+
m_gizmos.emplace_back(sprite);
238+
else
239+
m_gizmos.emplace_back(nullptr);
240+
} else {
241+
m_gizmos.emplace_back(nullptr);
242+
}
222243
//m_gizmos.emplace_back(new GLGizmoSlaSupports(m_parent, "sla_supports.svg", sprite_id++));
223244
//m_gizmos.emplace_back(new GLGizmoFaceDetector(m_parent, "face recognition.svg", sprite_id++));
224245
//m_gizmos.emplace_back(new GLGizmoHollow(m_parent, "hollow.svg", sprite_id++));
@@ -228,6 +249,7 @@ bool GLGizmosManager::init()
228249
m_assemble_view_data.reset(new AssembleViewDataPool(&m_parent));
229250

230251
for (auto& gizmo : m_gizmos) {
252+
if (!gizmo) continue; // nullptr = unregistered plugin slot, skip
231253
if (! gizmo->init()) {
232254
m_gizmos.clear();
233255
return false;
@@ -528,6 +550,11 @@ bool GLGizmosManager::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_p
528550
return dynamic_cast<GLGizmoMeshBoolean*>(m_gizmos[MeshBoolean].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down);
529551
else if (m_current == BrimEars)
530552
return dynamic_cast<GLGizmoBrimEars*>(m_gizmos[BrimEars].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down);
553+
else if (m_current == CustomEType && CustomEType < (int)m_gizmos.size()) {
554+
if (auto* sprite = dynamic_cast<IGLSprite*>(m_gizmos[CustomEType].get()))
555+
return sprite->gizmo_event(action, mouse_position, shift_down, alt_down, control_down);
556+
return false;
557+
}
531558
else
532559
return false;
533560
}

src/slic3r/GUI/Gizmos/GLGizmosManager.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ struct Snapshot;
2424

2525
namespace GUI {
2626

27+
// Forward declaration — full definition in GLGizmoPainterBase.hpp
28+
class IGLSprite;
29+
2730
class GLCanvas3D;
2831
class ClippingPlane;
2932
enum class SLAGizmoEventType : unsigned char;
@@ -94,6 +97,7 @@ class GLGizmosManager : public Slic3r::ObjectBase
9497
// BBS
9598
//FaceRecognition,
9699
//Hollow,
100+
CustomEType, // plugin gizmo slot — index must match position in m_gizmos vector
97101
Undefined,
98102
};
99103

0 commit comments

Comments
 (0)