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;
4344const 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+
4654GLGizmosManager::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}
0 commit comments