1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
|
#ifndef slic3r_GLCanvas3D_hpp_
#define slic3r_GLCanvas3D_hpp_
#include <stddef.h>
#include <memory>
#include <chrono>
#include <cstdint>
#include "GLToolbar.hpp"
#include "Event.hpp"
#include "Selection.hpp"
#include "Gizmos/GLGizmosManager.hpp"
#include "GUI_ObjectLayers.hpp"
#include "GLSelectionRectangle.hpp"
#include "MeshUtils.hpp"
#include "libslic3r/GCode/GCodeProcessor.hpp"
#include "GCodeViewer.hpp"
#include "libslic3r/Slicing.hpp"
#include <float.h>
#include <wx/timer.h>
class wxSizeEvent;
class wxIdleEvent;
class wxKeyEvent;
class wxMouseEvent;
class wxTimerEvent;
class wxPaintEvent;
class wxGLCanvas;
class wxGLContext;
// Support for Retina OpenGL on Mac OS.
// wxGTK3 seems to simulate OSX behavior in regard to HiDPI scaling support, enable it as well.
#define ENABLE_RETINA_GL (__APPLE__ || __WXGTK3__)
namespace Slic3r {
struct Camera;
class BackgroundSlicingProcess;
struct ThumbnailData;
class ModelObject;
class ModelInstance;
class PrintObject;
class Print;
class SLAPrint;
namespace CustomGCode { struct Item; }
namespace GUI {
#if ENABLE_RETINA_GL
class RetinaHelper;
#endif
class Size
{
int m_width;
int m_height;
float m_scale_factor;
public:
Size();
Size(int width, int height, float scale_factor = 1.0);
int get_width() const;
void set_width(int width);
int get_height() const;
void set_height(int height);
int get_scale_factor() const;
void set_scale_factor(int height);
};
class RenderTimerEvent : public wxEvent
{
public:
RenderTimerEvent(wxEventType type, wxTimer& timer)
: wxEvent(timer.GetId(), type),
m_timer(&timer)
{
SetEventObject(timer.GetOwner());
}
int GetInterval() const { return m_timer->GetInterval(); }
wxTimer& GetTimer() const { return *m_timer; }
virtual wxEvent* Clone() const { return new RenderTimerEvent(*this); }
virtual wxEventCategory GetEventCategory() const { return wxEVT_CATEGORY_TIMER; }
private:
wxTimer* m_timer;
};
wxDECLARE_EVENT(EVT_GLCANVAS_OBJECT_SELECT, SimpleEvent);
using Vec2dEvent = Event<Vec2d>;
// _bool_ value is used as a indicator of selection in the 3DScene
using RBtnEvent = Event<std::pair<Vec2d, bool>>;
template <size_t N> using Vec2dsEvent = ArrayEvent<Vec2d, N>;
using Vec3dEvent = Event<Vec3d>;
template <size_t N> using Vec3dsEvent = ArrayEvent<Vec3d, N>;
using HeightProfileSmoothEvent = Event<HeightProfileSmoothingParams>;
wxDECLARE_EVENT(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_RIGHT_CLICK, RBtnEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_REMOVE_OBJECT, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_ARRANGE, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_SELECT_ALL, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_QUESTION_MARK, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_INCREASE_INSTANCES, Event<int>); // data: +1 => increase, -1 => decrease
wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_MOVED, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_FORCE_UPDATE, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_WIPETOWER_MOVED, Vec3dEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_ROTATED, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_SCALED, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3dEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, Event<bool>);
wxDECLARE_EVENT(EVT_GLCANVAS_UPDATE_GEOMETRY, Vec3dsEvent<2>);
wxDECLARE_EVENT(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_UPDATE_BED_SHAPE, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_TAB, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_RESETGIZMOS, SimpleEvent);
#if ENABLE_ARROW_KEYS_WITH_SLIDERS
wxDECLARE_EVENT(EVT_GLCANVAS_MOVE_SLIDERS, wxKeyEvent);
#else
wxDECLARE_EVENT(EVT_GLCANVAS_MOVE_LAYERS_SLIDER, wxKeyEvent);
#endif // ENABLE_ARROW_KEYS_WITH_SLIDERS
wxDECLARE_EVENT(EVT_GLCANVAS_EDIT_COLOR_CHANGE, wxKeyEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_JUMP_TO, wxKeyEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_UNDO, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_COLLAPSE_SIDEBAR, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, Event<float>);
wxDECLARE_EVENT(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, HeightProfileSmoothEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_RELOAD_FROM_DISK, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_RENDER_TIMER, wxTimerEvent/*RenderTimerEvent*/);
class GLCanvas3D
{
static const double DefaultCameraZoomToBoxMarginFactor;
class LayersEditing
{
public:
enum EState : unsigned char
{
Unknown,
Editing,
Completed,
Num_States
};
static const float THICKNESS_BAR_WIDTH;
private:
bool m_enabled;
unsigned int m_z_texture_id;
// Not owned by LayersEditing.
const DynamicPrintConfig *m_config;
// ModelObject for the currently selected object (Model::objects[last_object_id]).
const ModelObject *m_model_object;
// Maximum z of the currently selected object (Model::objects[last_object_id]).
float m_object_max_z;
// Owned by LayersEditing.
SlicingParameters *m_slicing_parameters;
std::vector<double> m_layer_height_profile;
bool m_layer_height_profile_modified;
mutable float m_adaptive_quality;
mutable HeightProfileSmoothingParams m_smooth_params;
static float s_overelay_window_width;
class LayersTexture
{
public:
LayersTexture() : width(0), height(0), levels(0), cells(0), valid(false) {}
// Texture data
std::vector<char> data;
// Width of the texture, top level.
size_t width;
// Height of the texture, top level.
size_t height;
// For how many levels of detail is the data allocated?
size_t levels;
// Number of texture cells allocated for the height texture.
size_t cells;
// Does it need to be refreshed?
bool valid;
};
LayersTexture m_layers_texture;
public:
EState state;
float band_width;
//float strength;
int last_object_id;
float last_z;
LayerHeightEditActionType last_action;
LayersEditing();
~LayersEditing();
void init();
void set_config(const DynamicPrintConfig* config);
void select_object(const Model &model, int object_id);
bool is_allowed() const;
bool is_enabled() const;
void set_enabled(bool enabled);
void render_overlay(const GLCanvas3D& canvas) const;
void render_volumes(const GLCanvas3D& canvas, const GLVolumeCollection& volumes) const;
void adjust_layer_height_profile();
void accept_changes(GLCanvas3D& canvas);
void reset_layer_height_profile(GLCanvas3D& canvas);
void adaptive_layer_height_profile(GLCanvas3D& canvas, float quality_factor);
void smooth_layer_height_profile(GLCanvas3D& canvas, const HeightProfileSmoothingParams& smoothing_params);
static float get_cursor_z_relative(const GLCanvas3D& canvas);
static bool bar_rect_contains(const GLCanvas3D& canvas, float x, float y);
static Rect get_bar_rect_screen(const GLCanvas3D& canvas);
static Rect get_bar_rect_viewport(const GLCanvas3D& canvas);
static float get_overlay_window_width() { return LayersEditing::s_overelay_window_width; }
float object_max_z() const { return m_object_max_z; }
std::string get_tooltip(const GLCanvas3D& canvas) const;
private:
bool is_initialized() const;
void generate_layer_height_texture();
void render_active_object_annotations(const GLCanvas3D& canvas, const Rect& bar_rect) const;
void render_profile(const Rect& bar_rect) const;
void update_slicing_parameters();
static float thickness_bar_width(const GLCanvas3D &canvas);
};
struct Mouse
{
struct Drag
{
static const Point Invalid_2D_Point;
static const Vec3d Invalid_3D_Point;
static const int MoveThresholdPx;
Point start_position_2D;
Vec3d start_position_3D;
int move_volume_idx;
bool move_requires_threshold;
Point move_start_threshold_position_2D;
public:
Drag();
};
bool dragging;
Vec2d position;
Vec3d scene_position;
Drag drag;
bool ignore_left_up;
Mouse();
void set_start_position_2D_as_invalid() { drag.start_position_2D = Drag::Invalid_2D_Point; }
void set_start_position_3D_as_invalid() { drag.start_position_3D = Drag::Invalid_3D_Point; }
void set_move_start_threshold_position_2D_as_invalid() { drag.move_start_threshold_position_2D = Drag::Invalid_2D_Point; }
bool is_start_position_2D_defined() const { return (drag.start_position_2D != Drag::Invalid_2D_Point); }
bool is_start_position_3D_defined() const { return (drag.start_position_3D != Drag::Invalid_3D_Point); }
bool is_move_start_threshold_position_2D_defined() const { return (drag.move_start_threshold_position_2D != Drag::Invalid_2D_Point); }
bool is_move_threshold_met(const Point& mouse_pos) const {
return (std::abs(mouse_pos(0) - drag.move_start_threshold_position_2D(0)) > Drag::MoveThresholdPx)
|| (std::abs(mouse_pos(1) - drag.move_start_threshold_position_2D(1)) > Drag::MoveThresholdPx);
}
};
struct SlaCap
{
struct Triangles
{
Pointf3s object;
Pointf3s supports;
};
typedef std::map<unsigned int, Triangles> ObjectIdToTrianglesMap;
double z;
ObjectIdToTrianglesMap triangles;
SlaCap() { reset(); }
void reset() { z = DBL_MAX; triangles.clear(); }
bool matches(double z) const { return this->z == z; }
};
class WarningTexture : public GUI::GLTexture
{
public:
WarningTexture();
enum Warning {
ObjectOutside,
ToolpathOutside,
SlaSupportsOutside,
SomethingNotShown,
PrintWarning,
ObjectClashed
};
// Sets a warning of the given type to be active/inactive. If several warnings are active simultaneously,
// only the last one is shown (decided by the order in the enum above).
void activate(WarningTexture::Warning warning, bool state, const GLCanvas3D& canvas, std::string str_override = "");
void render(const GLCanvas3D& canvas) const;
// function used to get an information for rescaling of the warning
void msw_rescale(const GLCanvas3D& canvas);
inline static bool m_freeze = false;
private:
static const unsigned char Background_Color[3];
static const unsigned char Opacity;
int m_original_width;
int m_original_height;
// information for rescaling of the warning legend
std::string m_msg_text = "";
bool m_is_colored_red{ false };
// Information about which warnings are currently active.
std::vector<Warning> m_warnings;
// Generates the texture with given text.
bool generate(const std::string& msg, const GLCanvas3D& canvas, bool compress, bool red_colored = false);
};
#if ENABLE_RENDER_STATISTICS
class RenderStats
{
std::queue<std::pair<int64_t, int64_t>> m_frames;
int64_t m_curr_total{ 0 };
public:
void add_frame(int64_t frame) {
int64_t now = GLCanvas3D::timestamp_now();
if (!m_frames.empty() && now - m_frames.front().first > 1000) {
m_curr_total -= m_frames.front().second;
m_frames.pop();
}
m_curr_total += frame;
m_frames.push({ now, frame });
}
int64_t get_average() const { return m_frames.empty() ? 0 : m_curr_total / m_frames.size(); }
};
#endif // ENABLE_RENDER_STATISTICS
class Labels
{
bool m_enabled{ false };
bool m_shown{ false };
GLCanvas3D& m_canvas;
public:
explicit Labels(GLCanvas3D& canvas) : m_canvas(canvas) {}
void enable(bool enable) { m_enabled = enable; }
void show(bool show) { m_shown = m_enabled ? show : false; }
bool is_shown() const { return m_shown; }
void render(const std::vector<const ModelInstance*>& sorted_instances) const;
};
class Tooltip
{
std::string m_text;
std::chrono::steady_clock::time_point m_start_time;
// Indicator that the mouse is inside an ImGUI dialog, therefore the tooltip should be suppressed.
bool m_in_imgui = false;
public:
bool is_empty() const { return m_text.empty(); }
void set_text(const std::string& text);
void render(const Vec2d& mouse_position, GLCanvas3D& canvas) const;
// Indicates that the mouse is inside an ImGUI dialog, therefore the tooltip should be suppressed.
void set_in_imgui(bool b) { m_in_imgui = b; }
bool is_in_imgui() const { return m_in_imgui; }
};
class Slope
{
bool m_enabled{ false };
bool m_dialog_shown{ false };
GLCanvas3D& m_canvas;
GLVolumeCollection& m_volumes;
static float s_window_width;
public:
Slope(GLCanvas3D& canvas, GLVolumeCollection& volumes) : m_canvas(canvas), m_volumes(volumes) {}
void enable(bool enable) { m_enabled = enable; }
bool is_enabled() const { return m_enabled; }
void use(bool use) { m_volumes.set_slope_active(m_enabled ? use : false); }
bool is_used() const { return m_volumes.is_slope_active(); }
void set_normal_angle(float angle_in_deg) const {
m_volumes.set_slope_normal_z(-::cos(Geometry::deg2rad(90.0f - angle_in_deg)));
}
static float get_window_width() { return s_window_width; };
};
class RenderTimer : public wxTimer {
private:
virtual void Notify() override;
};
public:
enum ECursorType : unsigned char
{
Standard,
Cross
};
struct ArrangeSettings
{
float distance = 6.;
// float distance_seq_print = 6.; // Used when sequential print is ON
// float distance_sla = 6.;
float accuracy = 0.65f; // Unused currently
bool enable_rotation = false;
};
static void set_warning_freeze(bool freeze) { WarningTexture::m_freeze = freeze; }
private:
wxGLCanvas* m_canvas;
wxGLContext* m_context;
#if ENABLE_RETINA_GL
std::unique_ptr<RetinaHelper> m_retina_helper;
#endif
bool m_in_render;
WarningTexture m_warning_texture;
wxTimer m_timer;
LayersEditing m_layers_editing;
Mouse m_mouse;
mutable GLGizmosManager m_gizmos;
mutable GLToolbar m_main_toolbar;
mutable GLToolbar m_undoredo_toolbar;
ClippingPlane m_clipping_planes[2];
mutable ClippingPlane m_camera_clipping_plane;
bool m_use_clipping_planes;
mutable SlaCap m_sla_caps[2];
std::string m_sidebar_field;
// when true renders an extra frame by not resetting m_dirty to false
// see request_extra_frame()
bool m_extra_frame_requested;
int m_extra_frame_requested_delayed { std::numeric_limits<int>::max() };
bool m_event_handlers_bound{ false };
bool m_show_objects = true;
mutable GLVolumeCollection m_volumes;
bool m_show_gcode = true;
GCodeViewer m_gcode_viewer;
RenderTimer m_render_timer;
int64_t m_render_timer_start;
Selection m_selection;
const DynamicPrintConfig* m_config;
Model* m_model;
BackgroundSlicingProcess *m_process;
// Screen is only refreshed from the OnIdle handler if it is dirty.
bool m_dirty;
bool m_initialized;
bool m_apply_zoom_to_volumes_filter;
mutable std::vector<int> m_hover_volume_idxs;
bool m_picking_enabled;
bool m_moving_enabled;
bool m_dynamic_background_enabled;
bool m_multisample_allowed;
bool m_moving;
bool m_tab_down;
ECursorType m_cursor_type;
GLSelectionRectangle m_rectangle_selection;
// Following variable is obsolete and it should be safe to remove it.
// I just don't want to do it now before a release (Lukas Matena 24.3.2019)
bool m_render_sla_auxiliaries;
std::string m_color_by;
bool m_reload_delayed;
#if ENABLE_RENDER_PICKING_PASS
bool m_show_picking_texture;
#endif // ENABLE_RENDER_PICKING_PASS
#if ENABLE_RENDER_STATISTICS
RenderStats m_render_stats;
#endif // ENABLE_RENDER_STATISTICS
mutable int m_imgui_undo_redo_hovered_pos{ -1 };
mutable int m_mouse_wheel {0};
int m_selected_extruder;
Labels m_labels;
mutable Tooltip m_tooltip;
mutable bool m_tooltip_enabled{ true };
Slope m_slope;
ArrangeSettings m_arrange_settings_fff, m_arrange_settings_sla,
m_arrange_settings_fff_seq_print;
PrinterTechnology current_printer_technology() const;
template<class Self>
static auto & get_arrange_settings(Self *self)
{
PrinterTechnology ptech = self->current_printer_technology();
auto *ptr = &self->m_arrange_settings_fff;
if (ptech == ptSLA) {
ptr = &self->m_arrange_settings_sla;
} else if (ptech == ptFFF) {
auto co_opt = self->m_config->template option<ConfigOptionBool>("complete_objects");
if (co_opt && co_opt->value) {
ptr = &self->m_arrange_settings_fff_seq_print;
} else {
ptr = &self->m_arrange_settings_fff;
}
}
return *ptr;
}
ArrangeSettings &get_arrange_settings() { return get_arrange_settings(this); }
void load_arrange_settings();
public:
explicit GLCanvas3D(wxGLCanvas* canvas);
~GLCanvas3D();
bool is_initialized() const { return m_initialized; }
void set_context(wxGLContext* context) { m_context = context; }
wxGLCanvas* get_wxglcanvas() { return m_canvas; }
const wxGLCanvas* get_wxglcanvas() const { return m_canvas; }
bool init();
void post_event(wxEvent &&event);
void set_as_dirty();
void set_items_show(bool show_objects, bool show_gcode);
unsigned int get_volumes_count() const;
const GLVolumeCollection& get_volumes() const { return m_volumes; }
void reset_volumes(bool is_destroying = false);
int check_volumes_outside_state() const;
void reset_gcode_toolpaths() { m_gcode_viewer.reset(); }
const GCodeViewer::SequentialView& get_gcode_sequential_view() const { return m_gcode_viewer.get_sequential_view(); }
void update_gcode_sequential_view_current(unsigned int first, unsigned int last) { m_gcode_viewer.update_sequential_view_current(first, last); }
void toggle_sla_auxiliaries_visibility(bool visible, const ModelObject* mo = nullptr, int instance_idx = -1);
void toggle_model_objects_visibility(bool visible, const ModelObject* mo = nullptr, int instance_idx = -1);
void update_instance_printable_state_for_object(size_t obj_idx);
void update_instance_printable_state_for_objects(std::vector<size_t>& object_idxs);
void set_config(const DynamicPrintConfig* config);
void set_process(BackgroundSlicingProcess* process);
void set_model(Model* model);
const Model* get_model() const { return m_model; }
const Selection& get_selection() const { return m_selection; }
Selection& get_selection() { return m_selection; }
const GLGizmosManager& get_gizmos_manager() const { return m_gizmos; }
GLGizmosManager& get_gizmos_manager() { return m_gizmos; }
void bed_shape_changed();
void set_clipping_plane(unsigned int id, const ClippingPlane& plane)
{
if (id < 2)
{
m_clipping_planes[id] = plane;
m_sla_caps[id].reset();
}
}
void reset_clipping_planes_cache() { m_sla_caps[0].triangles.clear(); m_sla_caps[1].triangles.clear(); }
void set_use_clipping_planes(bool use) { m_use_clipping_planes = use; }
void set_color_by(const std::string& value);
void refresh_camera_scene_box();
BoundingBoxf3 volumes_bounding_box() const;
BoundingBoxf3 scene_bounding_box() const;
bool is_layers_editing_enabled() const;
bool is_layers_editing_allowed() const;
bool is_search_pressed() const;
void reset_layer_height_profile();
void adaptive_layer_height_profile(float quality_factor);
void smooth_layer_height_profile(const HeightProfileSmoothingParams& smoothing_params);
bool is_reload_delayed() const;
void enable_layers_editing(bool enable);
void enable_legend_texture(bool enable);
void enable_picking(bool enable);
void enable_moving(bool enable);
void enable_gizmos(bool enable);
void enable_selection(bool enable);
void enable_main_toolbar(bool enable);
void enable_undoredo_toolbar(bool enable);
void enable_dynamic_background(bool enable);
void enable_labels(bool enable) { m_labels.enable(enable); }
void enable_slope(bool enable) { m_slope.enable(enable); }
void allow_multisample(bool allow);
void zoom_to_bed();
void zoom_to_volumes();
void zoom_to_selection();
void zoom_to_gcode();
void select_view(const std::string& direction);
void update_volumes_colors_by_extruder();
bool is_dragging() const { return m_gizmos.is_dragging() || m_moving; }
void render();
// printable_only == false -> render also non printable volumes as grayed
// parts_only == false -> render also sla support and pad
void render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool show_bed, bool transparent_background) const;
void select_all();
void deselect_all();
void delete_selected();
void ensure_on_bed(unsigned int object_idx);
bool is_gcode_legend_enabled() const { return m_gcode_viewer.is_legend_enabled(); }
GCodeViewer::EViewType get_gcode_view_type() const { return m_gcode_viewer.get_view_type(); }
const std::vector<double>& get_gcode_layers_zs() const;
std::vector<double> get_volumes_print_zs(bool active_only) const;
unsigned int get_gcode_options_visibility_flags() const { return m_gcode_viewer.get_options_visibility_flags(); }
void set_gcode_options_visibility_from_flags(unsigned int flags);
unsigned int get_toolpath_role_visibility_flags() const { return m_gcode_viewer.get_toolpath_role_visibility_flags(); }
void set_toolpath_role_visibility_flags(unsigned int flags);
void set_toolpath_view_type(GCodeViewer::EViewType type);
void set_volumes_z_range(const std::array<double, 2>& range);
void set_toolpaths_z_range(const std::array<unsigned int, 2>& range);
std::vector<int> load_object(const ModelObject& model_object, int obj_idx, std::vector<int> instance_idxs);
std::vector<int> load_object(const Model& model, int obj_idx);
void mirror_selection(Axis axis);
void reload_scene(bool refresh_immediately, bool force_full_scene_refresh = false);
void load_gcode_preview(const GCodeProcessor::Result& gcode_result);
void refresh_gcode_preview(const GCodeProcessor::Result& gcode_result, const std::vector<std::string>& str_tool_colors);
#if ENABLE_RENDER_PATH_REFRESH_AFTER_OPTIONS_CHANGE
void refresh_gcode_preview_render_paths();
#endif // ENABLE_RENDER_PATH_REFRESH_AFTER_OPTIONS_CHANGE
void set_gcode_view_preview_type(GCodeViewer::EViewType type) { return m_gcode_viewer.set_view_type(type); }
GCodeViewer::EViewType get_gcode_view_preview_type() const { return m_gcode_viewer.get_view_type(); }
void load_sla_preview();
void load_preview(const std::vector<std::string>& str_tool_colors, const std::vector<CustomGCode::Item>& color_print_values);
void bind_event_handlers();
void unbind_event_handlers();
void on_size(wxSizeEvent& evt);
void on_idle(wxIdleEvent& evt);
void on_char(wxKeyEvent& evt);
void on_key(wxKeyEvent& evt);
void on_mouse_wheel(wxMouseEvent& evt);
void on_timer(wxTimerEvent& evt);
void on_render_timer(wxTimerEvent& evt);
void on_mouse(wxMouseEvent& evt);
void on_paint(wxPaintEvent& evt);
void on_set_focus(wxFocusEvent& evt);
Size get_canvas_size() const;
Vec2d get_local_mouse_position() const;
void set_tooltip(const std::string& tooltip) const;
// the following methods add a snapshot to the undo/redo stack, unless the given string is empty
void do_move(const std::string& snapshot_type);
void do_rotate(const std::string& snapshot_type);
void do_scale(const std::string& snapshot_type);
void do_flatten(const Vec3d& normal, const std::string& snapshot_type);
void do_mirror(const std::string& snapshot_type);
void update_gizmos_on_off_state();
void reset_all_gizmos() { m_gizmos.reset_all_states(); }
void handle_sidebar_focus_event(const std::string& opt_key, bool focus_on);
void handle_layers_data_focus_event(const t_layer_height_range range, const EditorType type);
void update_ui_from_settings();
int get_move_volume_id() const { return m_mouse.drag.move_volume_idx; }
int get_first_hover_volume_idx() const { return m_hover_volume_idxs.empty() ? -1 : m_hover_volume_idxs.front(); }
void set_selected_extruder(int extruder) { m_selected_extruder = extruder;}
class WipeTowerInfo {
protected:
Vec2d m_pos = {std::nan(""), std::nan("")};
double m_rotation = 0.;
BoundingBoxf m_bb;
friend class GLCanvas3D;
public:
inline operator bool() const
{
return !std::isnan(m_pos.x()) && !std::isnan(m_pos.y());
}
inline const Vec2d& pos() const { return m_pos; }
inline double rotation() const { return m_rotation; }
inline const Vec2d bb_size() const { return m_bb.size(); }
void apply_wipe_tower() const;
};
WipeTowerInfo get_wipe_tower_info() const;
// Returns the view ray line, in world coordinate, at the given mouse position.
Linef3 mouse_ray(const Point& mouse_pos);
void set_mouse_as_dragging() { m_mouse.dragging = true; }
bool is_mouse_dragging() const { return m_mouse.dragging; }
double get_size_proportional_to_max_bed_size(double factor) const;
void set_cursor(ECursorType type);
void msw_rescale();
void request_extra_frame() { m_extra_frame_requested = true; }
void request_extra_frame_delayed(int miliseconds);
int get_main_toolbar_item_id(const std::string& name) const { return m_main_toolbar.get_item_id(name); }
void force_main_toolbar_left_action(int item_id) { m_main_toolbar.force_left_action(item_id, *this); }
void force_main_toolbar_right_action(int item_id) { m_main_toolbar.force_right_action(item_id, *this); }
void update_tooltip_for_settings_item_in_main_toolbar();
bool has_toolpaths_to_export() const;
void export_toolpaths_to_obj(const char* filename) const;
void mouse_up_cleanup();
bool are_labels_shown() const { return m_labels.is_shown(); }
void show_labels(bool show) { m_labels.show(show); }
bool is_using_slope() const { return m_slope.is_used(); }
void use_slope(bool use) { m_slope.use(use); }
void set_slope_normal_angle(float angle_in_deg) { m_slope.set_normal_angle(angle_in_deg); } void show_print_warning(std::string str) {
if (str.empty())
m_warning_texture.activate(WarningTexture::Warning::PrintWarning, false, *this);
else
m_warning_texture.activate(WarningTexture::Warning::PrintWarning, true, *this, str);
}
ArrangeSettings get_arrange_settings() const
{
const ArrangeSettings &settings = get_arrange_settings(this);
ArrangeSettings ret = settings;
return ret;
}
void set_arrange_settings(const DynamicPrintConfig& conf, PrinterTechnology tech);
// Timestamp for FPS calculation and notification fade-outs.
static int64_t timestamp_now() {
#ifdef _WIN32
// Cheaper on Windows, calls GetSystemTimeAsFileTime()
return wxGetUTCTimeMillis().GetValue();
#else
// calls clock()
return wxGetLocalTimeMillis().GetValue();
#endif
}
private:
bool _is_shown_on_screen() const;
bool _init_toolbars();
bool _init_main_toolbar();
bool _init_undoredo_toolbar();
bool _init_view_toolbar();
bool _init_collapse_toolbar();
bool _set_current();
void _resize(unsigned int w, unsigned int h);
BoundingBoxf3 _max_bounding_box(bool include_gizmos, bool include_bed_model) const;
void _zoom_to_box(const BoundingBoxf3& box, double margin_factor = DefaultCameraZoomToBoxMarginFactor);
void _update_camera_zoom(double zoom);
void _refresh_if_shown_on_screen();
void _picking_pass() const;
void _rectangular_selection_picking_pass() const;
void _render_background() const;
void _render_bed(bool bottom, bool show_axes) const;
void _render_objects() const;
void _render_gcode() const;
void _render_selection() const;
#if ENABLE_RENDER_SELECTION_CENTER
void _render_selection_center() const;
#endif // ENABLE_RENDER_SELECTION_CENTER
void _check_and_update_toolbar_icon_scale() const;
void _render_overlays() const;
void _render_warning_texture() const;
void _render_volumes_for_picking() const;
void _render_current_gizmo() const;
void _render_gizmos_overlay() const;
void _render_main_toolbar() const;
void _render_undoredo_toolbar() const;
void _render_collapse_toolbar() const;
void _render_view_toolbar() const;
#if ENABLE_SHOW_CAMERA_TARGET
void _render_camera_target() const;
#endif // ENABLE_SHOW_CAMERA_TARGET
void _render_sla_slices() const;
void _render_selection_sidebar_hints() const;
bool _render_undo_redo_stack(const bool is_undo, float pos_x) const;
bool _render_search_list(float pos_x) const;
bool _render_arrange_menu(float pos_x);
void _render_thumbnail_internal(ThumbnailData& thumbnail_data, bool printable_only, bool parts_only, bool show_bed, bool transparent_background) const;
// render thumbnail using an off-screen framebuffer
void _render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool show_bed, bool transparent_background) const;
// render thumbnail using an off-screen framebuffer when GLEW_EXT_framebuffer_object is supported
void _render_thumbnail_framebuffer_ext(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool show_bed, bool transparent_background) const;
// render thumbnail using the default framebuffer
void _render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool show_bed, bool transparent_background) const;
void _update_volumes_hover_state() const;
void _perform_layer_editing_action(wxMouseEvent* evt = nullptr);
// Convert the screen space coordinate to an object space coordinate.
// If the Z screen space coordinate is not provided, a depth buffer value is substituted.
Vec3d _mouse_to_3d(const Point& mouse_pos, float* z = nullptr);
// Convert the screen space coordinate to world coordinate on the bed.
Vec3d _mouse_to_bed_3d(const Point& mouse_pos);
void _start_timer();
void _stop_timer();
// Create 3D thick extrusion lines for a skirt and brim.
// Adds a new Slic3r::GUI::3DScene::Volume to volumes.
void _load_print_toolpaths();
// Create 3D thick extrusion lines for object forming extrusions.
// Adds a new Slic3r::GUI::3DScene::Volume to $self->volumes,
// one for perimeters, one for infill and one for supports.
void _load_print_object_toolpaths(const PrintObject& print_object, const std::vector<std::string>& str_tool_colors,
const std::vector<CustomGCode::Item>& color_print_values);
// Create 3D thick extrusion lines for wipe tower extrusions
void _load_wipe_tower_toolpaths(const std::vector<std::string>& str_tool_colors);
// Load SLA objects and support structures for objects, for which the slaposSliceSupports step has been finished.
void _load_sla_shells();
void _update_toolpath_volumes_outside_state();
void _update_sla_shells_outside_state();
void _show_warning_texture_if_needed(WarningTexture::Warning warning);
// generates a warning texture containing the given message
void _set_warning_texture(WarningTexture::Warning warning, bool state);
bool _is_any_volume_outside() const;
// updates the selection from the content of m_hover_volume_idxs
void _update_selection_from_hover();
bool _deactivate_undo_redo_toolbar_items();
bool _deactivate_search_toolbar_item();
bool _activate_search_toolbar_item();
bool _deactivate_collapse_toolbar_items();
bool _deactivate_arrange_menu();
float get_overlay_window_width() { return LayersEditing::get_overlay_window_width(); }
static std::vector<float> _parse_colors(const std::vector<std::string>& colors);
public:
const Print* fff_print() const;
const SLAPrint* sla_print() const;
};
} // namespace GUI
} // namespace Slic3r
#endif // slic3r_GLCanvas3D_hpp_
|