Prusa Slicer 2.6.0
Loading...
Searching...
No Matches
Slic3r::GUI::Selection Class Reference

#include <src/slic3r/GUI/Selection.hpp>

+ Collaboration diagram for Slic3r::GUI::Selection:

Classes

struct  Cache
 
class  Clipboard
 
struct  Planes
 
struct  VolumeCache
 

Public Types

enum  EMode : unsigned char { Volume , Instance }
 
enum  EType : unsigned char {
  Invalid , Empty , WipeTower , SingleModifier ,
  MultipleModifier , SingleVolume , MultipleVolume , SingleFullObject ,
  MultipleFullObject , SingleFullInstance , MultipleFullInstance , Mixed
}
 
enum class  EUniformScaleRequiredReason : unsigned char {
  NotRequired , InstanceNotAxisAligned_World , VolumeNotAxisAligned_World , VolumeNotAxisAligned_Instance ,
  MultipleSelection
}
 
enum class  SyncRotationType { NONE = 0 , GENERAL = 1 , RESET = 2 }
 
typedef std::set< unsigned int > IndicesList
 
typedef std::map< unsigned int, VolumeCacheVolumesCache
 
typedef std::set< int > InstanceIdxsList
 
typedef std::map< int, InstanceIdxsListObjectIdxsToInstanceIdxsMap
 

Public Member Functions

 Selection ()
 
void set_volumes (GLVolumePtrs *volumes)
 
bool init ()
 
bool is_enabled () const
 
void set_enabled (bool enable)
 
Modelget_model () const
 
void set_model (Model *model)
 
EMode get_mode () const
 
void set_mode (EMode mode)
 
void add (unsigned int volume_idx, bool as_single_selection=true, bool check_for_already_contained=false)
 
void remove (unsigned int volume_idx)
 
void add_object (unsigned int object_idx, bool as_single_selection=true)
 
void remove_object (unsigned int object_idx)
 
void add_instance (unsigned int object_idx, unsigned int instance_idx, bool as_single_selection=true)
 
void remove_instance (unsigned int object_idx, unsigned int instance_idx)
 
void add_volume (unsigned int object_idx, unsigned int volume_idx, int instance_idx, bool as_single_selection=true)
 
void remove_volume (unsigned int object_idx, unsigned int volume_idx)
 
void add_volumes (EMode mode, const std::vector< unsigned int > &volume_idxs, bool as_single_selection=true)
 
void remove_volumes (EMode mode, const std::vector< unsigned int > &volume_idxs)
 
void add_all ()
 
void remove_all ()
 
void set_deserialized (EMode mode, const std::vector< std::pair< size_t, size_t > > &volumes_and_instances)
 
void instances_changed (const std::vector< size_t > &instance_ids_selected)
 
void volumes_changed (const std::vector< size_t > &map_volume_old_to_new)
 
void clear ()
 
bool is_empty () const
 
bool is_wipe_tower () const
 
bool is_any_modifier () const
 
bool is_single_modifier () const
 
bool is_multiple_modifier () const
 
bool is_single_full_instance () const
 
bool is_multiple_full_instance () const
 
bool is_single_full_object () const
 
bool is_multiple_full_object () const
 
bool is_single_volume () const
 
bool is_multiple_volume () const
 
bool is_any_volume () const
 
bool is_any_connector () const
 
bool is_any_cut_volume () const
 
bool is_mixed () const
 
bool is_from_single_instance () const
 
bool is_from_single_object () const
 
bool is_sla_compliant () const
 
bool is_instance_mode () const
 
bool is_single_volume_or_modifier () const
 
bool is_single_volume_instance () const
 
bool is_single_text () const
 
bool contains_volume (unsigned int volume_idx) const
 
bool contains_all_volumes (const std::vector< unsigned int > &volume_idxs) const
 
bool contains_any_volume (const std::vector< unsigned int > &volume_idxs) const
 
bool contains_sinking_volumes (bool ignore_modifiers=true) const
 
bool matches (const std::vector< unsigned int > &volume_idxs) const
 
int get_object_idx () const
 
int get_instance_idx () const
 
const InstanceIdxsListget_instance_idxs () const
 
const IndicesListget_volume_idxs () const
 
const GLVolumeget_volume (unsigned int volume_idx) const
 
const GLVolumeget_first_volume () const
 
GLVolumeget_volume (unsigned int volume_idx)
 
const ObjectIdxsToInstanceIdxsMapget_content () const
 
unsigned int volumes_count () const
 
const BoundingBoxf3get_bounding_box () const
 
const BoundingBoxf3get_unscaled_instance_bounding_box () const
 
const BoundingBoxf3get_scaled_instance_bounding_box () const
 
const BoundingBoxf3get_full_unscaled_instance_bounding_box () const
 
const BoundingBoxf3get_full_scaled_instance_bounding_box () const
 
const BoundingBoxf3get_full_unscaled_instance_local_bounding_box () const
 
const std::pair< BoundingBoxf3, Transform3d > & get_bounding_box_in_current_reference_system () const
 
std::pair< BoundingBoxf3, Transform3dget_bounding_box_in_reference_system (ECoordinatesType type) const
 
BoundingBoxf get_screen_space_bounding_box ()
 
void setup_cache ()
 
void translate (const Vec3d &displacement, TransformationType transformation_type)
 
void rotate (const Vec3d &rotation, TransformationType transformation_type)
 
void flattening_rotate (const Vec3d &normal)
 
void scale (const Vec3d &scale, TransformationType transformation_type)
 
void scale_to_fit_print_volume (const BuildVolume &volume)
 
void scale_and_translate (const Vec3d &scale, const Vec3d &world_translation, TransformationType transformation_type)
 
void mirror (Axis axis, TransformationType transformation_type)
 
void reset_skew ()
 
void translate (unsigned int object_idx, unsigned int instance_idx, const Vec3d &displacement)
 
int bake_transform_if_needed () const
 
void erase ()
 
void render (float scale_factor=1.0)
 
void render_sidebar_hints (const std::string &sidebar_field)
 
bool requires_local_axes () const
 
void copy_to_clipboard ()
 
void paste_from_clipboard ()
 
const Clipboardget_clipboard () const
 
std::vector< unsigned int > get_volume_idxs_from_object (unsigned int object_idx) const
 
std::vector< unsigned int > get_volume_idxs_from_instance (unsigned int object_idx, unsigned int instance_idx) const
 
std::vector< unsigned int > get_volume_idxs_from_volume (unsigned int object_idx, unsigned int instance_idx, unsigned int volume_idx) const
 
std::vector< unsigned int > get_missing_volume_idxs_from (const std::vector< unsigned int > &volume_idxs) const
 
std::vector< unsigned int > get_unselected_volume_idxs_from (const std::vector< unsigned int > &volume_idxs) const
 
std::set< unsigned int > get_object_idxs () const
 
void synchronize_unselected_instances (SyncRotationType sync_rotation_type)
 
void synchronize_unselected_volumes ()
 

Private Member Functions

void update_valid ()
 
void update_type ()
 
void set_caches ()
 
void do_add_volume (unsigned int volume_idx)
 
void do_add_volumes (const std::vector< unsigned int > &volume_idxs)
 
void do_remove_volume (unsigned int volume_idx)
 
void do_remove_instance (unsigned int object_idx, unsigned int instance_idx)
 
void do_remove_object (unsigned int object_idx)
 
void set_bounding_boxes_dirty ()
 
void render_synchronized_volumes ()
 
void render_bounding_box (const BoundingBoxf3 &box, const Transform3d &trafo, const ColorRGB &color)
 
void render_selected_volumes () const
 
void render_bounding_box (const BoundingBoxf3 &box, float *color) const
 
void render_sidebar_position_hints (const std::string &sidebar_field, GLShaderProgram &shader, const Transform3d &matrix)
 
void render_sidebar_rotation_hints (const std::string &sidebar_field, GLShaderProgram &shader, const Transform3d &matrix)
 
void render_sidebar_scale_hints (const std::string &sidebar_field, GLShaderProgram &shader, const Transform3d &matrix)
 
void render_sidebar_layers_hints (const std::string &sidebar_field, GLShaderProgram &shader)
 
void ensure_on_bed ()
 
void ensure_not_below_bed ()
 
bool is_from_fully_selected_instance (unsigned int volume_idx) const
 
void paste_volumes_from_clipboard ()
 
void paste_objects_from_clipboard ()
 
void transform_instance_relative (GLVolume &volume, const VolumeCache &volume_data, TransformationType transformation_type, const Transform3d &transform, const Vec3d &world_pivot)
 
void transform_volume_relative (GLVolume &volume, const VolumeCache &volume_data, TransformationType transformation_type, const Transform3d &transform, const Vec3d &world_pivot)
 

Private Attributes

GLVolumePtrsm_volumes
 
Modelm_model
 
bool m_enabled
 
bool m_valid
 
EMode m_mode
 
EType m_type
 
IndicesList m_list
 
Cache m_cache
 
Clipboard m_clipboard
 
std::optional< BoundingBoxf3m_bounding_box
 
std::optional< BoundingBoxf3m_unscaled_instance_bounding_box
 
std::optional< BoundingBoxf3m_scaled_instance_bounding_box
 
std::optional< BoundingBoxf3m_full_unscaled_instance_bounding_box
 
std::optional< BoundingBoxf3m_full_scaled_instance_bounding_box
 
std::optional< BoundingBoxf3m_full_unscaled_instance_local_bounding_box
 
std::optional< std::pair< BoundingBoxf3, Transform3d > > m_bounding_box_in_current_reference_system
 
CoordAxes m_axes
 
GLModel m_arrow
 
GLModel m_curved_arrow
 
GLModel m_box
 
Planes m_planes
 
float m_scale_factor
 

Detailed Description


Class Documentation

◆ Slic3r::GUI::Selection::Cache

struct Slic3r::GUI::Selection::Cache
+ Collaboration diagram for Slic3r::GUI::Selection::Cache:
Class Members
ObjectIdxsToInstanceIdxsMap content
Vec3d dragging_center
vector< unsigned int > sinking_volumes
VolumesCache volumes_data

◆ Slic3r::GUI::Selection::Planes

struct Slic3r::GUI::Selection::Planes
+ Collaboration diagram for Slic3r::GUI::Selection::Planes:
Class Members
array< Vec3f, 2 > check_points { Vec3f::Zero(), Vec3f::Zero() }
array< GLModel, 2 > models

Member Typedef Documentation

◆ IndicesList

typedef std::set<unsigned int> Slic3r::GUI::Selection::IndicesList

◆ InstanceIdxsList

◆ ObjectIdxsToInstanceIdxsMap

◆ VolumesCache

typedef std::map<unsigned int, VolumeCache> Slic3r::GUI::Selection::VolumesCache

Member Enumeration Documentation

◆ EMode

enum Slic3r::GUI::Selection::EMode : unsigned char
Enumerator
Volume 
Instance 
36 {
37 Volume,
39 };
@ Instance
Definition Selection.hpp:38
@ Volume
Definition Selection.hpp:37

◆ EType

enum Slic3r::GUI::Selection::EType : unsigned char
Enumerator
Invalid 
Empty 
WipeTower 
SingleModifier 
MultipleModifier 
SingleVolume 
MultipleVolume 
SingleFullObject 
MultipleFullObject 
SingleFullInstance 
MultipleFullInstance 
Mixed 
42 {
43 Invalid,
44 Empty,
54 Mixed
55 };
@ MultipleVolume
Definition Selection.hpp:49
@ SingleVolume
Definition Selection.hpp:48
@ MultipleFullInstance
Definition Selection.hpp:53
@ MultipleModifier
Definition Selection.hpp:47
@ Invalid
Definition Selection.hpp:43
@ SingleModifier
Definition Selection.hpp:46
@ Empty
Definition Selection.hpp:44
@ WipeTower
Definition Selection.hpp:45
@ MultipleFullObject
Definition Selection.hpp:51
@ SingleFullObject
Definition Selection.hpp:50
@ SingleFullInstance
Definition Selection.hpp:52
@ Mixed
Definition Selection.hpp:54

◆ EUniformScaleRequiredReason

◆ SyncRotationType

Enumerator
NONE 
GENERAL 
RESET 
401 {
402 // Do not synchronize rotation. Either not rotating at all, or rotating by world Z axis.
403 NONE = 0,
404 // Synchronize after rotation by an axis not parallel with Z.
405 GENERAL = 1,
406 // Synchronize after rotation reset.
407 RESET = 2
408 };

Constructor & Destructor Documentation

◆ Selection()

Slic3r::GUI::Selection::Selection ( )
103 : m_volumes(nullptr)
104 , m_model(nullptr)
105 , m_enabled(false)
107 , m_type(Empty)
108 , m_valid(false)
109 , m_scale_factor(1.0f)
110{
113 m_axes.set_stem_length(20.0f);
116}
void set_stem_length(float length)
Definition CoordAxes.hpp:32
void set_stem_radius(float radius)
Definition CoordAxes.hpp:28
void set_tip_length(float length)
Definition CoordAxes.hpp:40
void set_tip_radius(float radius)
Definition CoordAxes.hpp:36
void set_bounding_boxes_dirty()
Definition Selection.hpp:384
GLVolumePtrs * m_volumes
Definition Selection.hpp:147
CoordAxes m_axes
Definition Selection.hpp:184
EMode m_mode
Definition Selection.hpp:153
bool m_enabled
Definition Selection.hpp:151
float m_scale_factor
Definition Selection.hpp:195
EType m_type
Definition Selection.hpp:154
bool m_valid
Definition Selection.hpp:152
Model * m_model
Definition Selection.hpp:149

References m_axes, set_bounding_boxes_dirty(), Slic3r::GUI::CoordAxes::set_stem_length(), Slic3r::GUI::CoordAxes::set_stem_radius(), Slic3r::GUI::CoordAxes::set_tip_length(), and Slic3r::GUI::CoordAxes::set_tip_radius().

+ Here is the call graph for this function:

Member Function Documentation

◆ add()

void Slic3r::GUI::Selection::add ( unsigned int  volume_idx,
bool  as_single_selection = true,
bool  check_for_already_contained = false 
)
144{
145 if (!m_valid || (unsigned int)m_volumes->size() <= volume_idx)
146 return;
147
148 const GLVolume* volume = (*m_volumes)[volume_idx];
149
150 if (wxGetApp().plater()->printer_technology() == ptSLA && volume->is_modifier &&
151 m_model->objects[volume->object_idx()]->volumes[volume->volume_idx()]->is_modifier())
152 return;
153
154 // wipe tower is already selected
155 if (is_wipe_tower() && volume->is_wipe_tower)
156 return;
157
158 bool keep_instance_mode = (m_mode == Instance) && !as_single_selection;
159 bool already_contained = check_for_already_contained && contains_volume(volume_idx);
160
161 // resets the current list if needed
162 bool needs_reset = as_single_selection && !already_contained;
163 needs_reset |= volume->is_wipe_tower;
164 needs_reset |= is_wipe_tower() && !volume->is_wipe_tower;
165 needs_reset |= as_single_selection && !is_any_modifier() && volume->is_modifier;
166 needs_reset |= is_any_modifier() && !volume->is_modifier;
167
168 if (!already_contained || needs_reset) {
169 wxGetApp().plater()->take_snapshot(_L("Selection-Add"), UndoRedo::SnapshotType::Selection);
170
171 if (needs_reset)
172 clear();
173
174 if (!keep_instance_mode)
175 m_mode = volume->is_modifier ? Volume : Instance;
176 }
177 else
178 // keep current mode
179 return;
180
181 switch (m_mode)
182 {
183 case Volume:
184 {
185 if (volume->volume_idx() >= 0 && (is_empty() || volume->instance_idx() == get_instance_idx()))
186 do_add_volume(volume_idx);
187
188 break;
189 }
190 case Instance:
191 {
192 Plater::SuppressSnapshots suppress(wxGetApp().plater());
193 add_instance(volume->object_idx(), volume->instance_idx(), as_single_selection);
194 break;
195 }
196 }
197
198 update_type();
200}
bool is_wipe_tower() const
Definition Selection.hpp:241
void update_type()
Definition Selection.cpp:1814
void do_add_volume(unsigned int volume_idx)
Definition Selection.cpp:2033
bool is_empty() const
Definition Selection.hpp:240
int get_instance_idx() const
Definition Selection.cpp:646
void clear()
Definition Selection.cpp:442
void add_instance(unsigned int object_idx, unsigned int instance_idx, bool as_single_selection=true)
Definition Selection.cpp:269
bool is_any_modifier() const
Definition Selection.hpp:242
bool contains_volume(unsigned int volume_idx) const
Definition Selection.hpp:263
ModelObjectPtrs objects
Definition Model.hpp:1254
static PrinterTechnology printer_technology()
Definition GUI_Factories.cpp:30
static Plater * plater()
Definition GUI_Factories.cpp:174
@ ptSLA
Definition Config.hpp:209
IGL_INLINE void volume(const Eigen::MatrixBase< DerivedV > &V, const Eigen::MatrixBase< DerivedT > &T, Eigen::PlainObjectBase< Derivedvol > &vol)
Definition volume.cpp:15
#define _L(s)
Definition I18N.hpp:3

References _L, add_instance(), clear(), contains_volume(), do_add_volume(), get_instance_idx(), Instance, is_any_modifier(), is_empty(), is_wipe_tower(), m_mode, m_model, m_valid, m_volumes, Slic3r::Model::objects, Slic3r::GUI::plater(), Slic3r::GUI::printer_technology(), Slic3r::ptSLA, Slic3r::UndoRedo::Selection, set_bounding_boxes_dirty(), update_type(), and Volume.

Referenced by Slic3r::GUI::GLCanvas3D::on_mouse(), and Slic3r::GUI::Plater::priv::reload_all_from_disk().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ add_all()

void Slic3r::GUI::Selection::add_all ( )
382{
383 if (!m_valid)
384 return;
385
386 unsigned int count = 0;
387 for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) {
388 if (!(*m_volumes)[i]->is_wipe_tower)
389 ++count;
390 }
391
392 if ((unsigned int)m_list.size() == count)
393 return;
394
395 wxGetApp().plater()->take_snapshot(_(L("Selection-Add All")), UndoRedo::SnapshotType::Selection);
396
398 clear();
399
400 for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) {
401 if (!(*m_volumes)[i]->is_wipe_tower)
402 do_add_volume(i);
403 }
404
405 update_type();
407}
IndicesList m_list
Definition Selection.hpp:156
#define _(msgid)
Definition getopt.c:87
IGL_INLINE void count(const Eigen::SparseMatrix< XType > &X, const int dim, Eigen::SparseVector< SType > &S)
Definition count.cpp:12
#define L(s)
Definition I18N.hpp:18

References _, clear(), do_add_volume(), Instance, L, m_list, m_mode, m_valid, m_volumes, Slic3r::UndoRedo::Selection, set_bounding_boxes_dirty(), and update_type().

Referenced by Slic3r::GUI::GLCanvas3D::select_all().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ add_instance()

void Slic3r::GUI::Selection::add_instance ( unsigned int  object_idx,
unsigned int  instance_idx,
bool  as_single_selection = true 
)
270{
271 if (!m_valid)
272 return;
273
274 const std::vector<unsigned int> volume_idxs = get_volume_idxs_from_instance(object_idx, instance_idx);
275 if ((!as_single_selection && contains_all_volumes(volume_idxs)) ||
276 (as_single_selection && matches(volume_idxs)))
277 return;
278
279 wxGetApp().plater()->take_snapshot(_L("Selection-Add Instance"), UndoRedo::SnapshotType::Selection);
280
281 // resets the current list if needed
282 if (as_single_selection)
283 clear();
284
286
287 do_add_volumes(volume_idxs);
288
289 update_type();
291}
void do_add_volumes(const std::vector< unsigned int > &volume_idxs)
Definition Selection.cpp:2042
std::vector< unsigned int > get_volume_idxs_from_instance(unsigned int object_idx, unsigned int instance_idx) const
Definition Selection.cpp:1748
bool contains_all_volumes(const std::vector< unsigned int > &volume_idxs) const
Definition Selection.cpp:596
bool matches(const std::vector< unsigned int > &volume_idxs) const
Definition Selection.cpp:627

References _L, clear(), contains_all_volumes(), do_add_volumes(), get_volume_idxs_from_instance(), Instance, m_mode, m_valid, matches(), Slic3r::UndoRedo::Selection, set_bounding_boxes_dirty(), and update_type().

Referenced by add(), Slic3r::GUI::GLCanvas3D::SLAView::render_switch_button(), and Slic3r::GUI::GLCanvas3D::SLAView::select_full_instance().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ add_object()

void Slic3r::GUI::Selection::add_object ( unsigned int  object_idx,
bool  as_single_selection = true 
)
233{
234 if (!m_valid)
235 return;
236
237 std::vector<unsigned int> volume_idxs = get_volume_idxs_from_object(object_idx);
238 if ((!as_single_selection && contains_all_volumes(volume_idxs)) ||
239 (as_single_selection && matches(volume_idxs)))
240 return;
241
242 wxGetApp().plater()->take_snapshot(_L("Selection-Add Object"), UndoRedo::SnapshotType::Selection);
243
244 // resets the current list if needed
245 if (as_single_selection)
246 clear();
247
249
250 do_add_volumes(volume_idxs);
251
252 update_type();
254}
std::vector< unsigned int > get_volume_idxs_from_object(unsigned int object_idx) const
Definition Selection.cpp:1729

References _L, clear(), contains_all_volumes(), do_add_volumes(), get_volume_idxs_from_object(), Instance, m_mode, m_valid, matches(), Slic3r::UndoRedo::Selection, set_bounding_boxes_dirty(), and update_type().

Referenced by Slic3r::GUI::GLGizmoSimplify::add_simplify_suggestion_notification(), Slic3r::GUI::Plater::convert_unit(), Slic3r::GUI::Plater::cut(), Slic3r::GUI::Plater::priv::load_files(), and Slic3r::GUI::Plater::priv::split_object().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ add_volume()

void Slic3r::GUI::Selection::add_volume ( unsigned int  object_idx,
unsigned int  volume_idx,
int  instance_idx,
bool  as_single_selection = true 
)
307{
308 if (!m_valid)
309 return;
310
311 std::vector<unsigned int> volume_idxs = get_volume_idxs_from_volume(object_idx, instance_idx, volume_idx);
312 if ((!as_single_selection && contains_all_volumes(volume_idxs)) ||
313 (as_single_selection && matches(volume_idxs)))
314 return;
315
316 // resets the current list if needed
317 if (as_single_selection)
318 clear();
319
320 m_mode = Volume;
321
322 do_add_volumes(volume_idxs);
323
324 update_type();
326}
std::vector< unsigned int > get_volume_idxs_from_volume(unsigned int object_idx, unsigned int instance_idx, unsigned int volume_idx) const
Definition Selection.cpp:1759

References clear(), contains_all_volumes(), do_add_volumes(), get_volume_idxs_from_volume(), m_mode, m_valid, matches(), set_bounding_boxes_dirty(), update_type(), and Volume.

Referenced by Slic3r::GUI::Plater::convert_unit().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ add_volumes()

void Slic3r::GUI::Selection::add_volumes ( EMode  mode,
const std::vector< unsigned int > &  volume_idxs,
bool  as_single_selection = true 
)
344{
345 if (!m_valid)
346 return;
347
348 if ((!as_single_selection && contains_all_volumes(volume_idxs)) ||
349 (as_single_selection && matches(volume_idxs)))
350 return;
351
352 // resets the current list if needed
353 if (as_single_selection)
354 clear();
355
356 m_mode = mode;
357 for (unsigned int i : volume_idxs) {
358 if (i < (unsigned int)m_volumes->size())
359 do_add_volume(i);
360 }
361
362 update_type();
364}
IGL_INLINE void mode(const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > &X, const int d, Eigen::Matrix< T, Eigen::Dynamic, 1 > &M)
Definition mode.cpp:14

References clear(), contains_all_volumes(), do_add_volume(), m_mode, m_valid, m_volumes, matches(), set_bounding_boxes_dirty(), and update_type().

Referenced by Slic3r::GUI::GLCanvas3D::on_mouse(), Slic3r::GUI::GLCanvas3D::SLAView::render_switch_button(), and Slic3r::GUI::ObjectList::update_selections_on_canvas().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ bake_transform_if_needed()

int Slic3r::GUI::Selection::bake_transform_if_needed ( ) const
1388{
1389 if ((is_single_full_instance() && wxGetApp().obj_manipul()->is_world_coordinates()) ||
1390 (is_single_volume_or_modifier() && !wxGetApp().obj_manipul()->is_local_coordinates())) {
1391 // Verify whether the instance rotation is multiples of 90 degrees, so that the scaling in world coordinates is possible.
1392 // all volumes in the selection belongs to the same instance, any of them contains the needed instance data, so we take the first one
1393 const GLVolume& volume = *get_first_volume();
1394 bool needs_baking = false;
1396 // Is the instance angle close to a multiple of 90 degrees?
1397 needs_baking |= !Geometry::is_rotation_ninety_degrees(volume.get_instance_rotation());
1398 // Are all volumes angles close to a multiple of 90 degrees?
1399 for (unsigned int id : get_volume_idxs()) {
1400 if (needs_baking)
1401 break;
1402 needs_baking |= !Geometry::is_rotation_ninety_degrees(get_volume(id)->get_volume_rotation());
1403 }
1404 }
1405 else if (is_single_volume_or_modifier()) {
1406 // is the volume angle close to a multiple of 90 degrees?
1407 needs_baking |= !Geometry::is_rotation_ninety_degrees(volume.get_volume_rotation());
1408 if (wxGetApp().obj_manipul()->is_world_coordinates())
1409 // Is the instance angle close to a multiple of 90 degrees?
1410 needs_baking |= !Geometry::is_rotation_ninety_degrees(volume.get_instance_rotation());
1411 }
1412
1413 if (needs_baking) {
1414 MessageDialog dlg((wxWindow*)wxGetApp().mainframe,
1415 _L("The currently manipulated object is tilted or contains tilted parts (rotation angles are not multiples of 90°). "
1416 "Non-uniform scaling of tilted objects is only possible in non-local coordinate systems, "
1417 "once the rotation is embedded into the object coordinates.") + "\n" +
1418 _L("This operation is irreversible.") + "\n" +
1419 _L("Do you want to proceed?"),
1420 SLIC3R_APP_NAME,
1421 wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION);
1422 if (dlg.ShowModal() != wxID_YES)
1423 return -1;
1424
1425 wxGetApp().plater()->take_snapshot(_("Bake transform"));
1426
1427 // Bake the rotation into the meshes of the object.
1428 wxGetApp().model().objects[volume.composite_id.object_id]->bake_xy_rotation_into_meshes(volume.composite_id.instance_id);
1429 // Update the 3D scene, selections etc.
1430 wxGetApp().plater()->update();
1431 return 0;
1432 }
1433 }
1434
1435 return 1;
1436}
const IndicesList & get_volume_idxs() const
Definition Selection.hpp:290
bool is_single_full_instance() const
Definition Selection.cpp:535
const GLVolume * get_first_volume() const
Definition Selection.hpp:292
const GLVolume * get_volume(unsigned int volume_idx) const
Definition Selection.cpp:663
bool is_single_volume_or_modifier() const
Definition Selection.hpp:259
bool is_rotation_ninety_degrees(double a)
Definition Geometry.hpp:487

References _, _L, get_first_volume(), get_volume(), get_volume_idxs(), Slic3r::Geometry::is_rotation_ninety_degrees(), is_single_full_instance(), and is_single_volume_or_modifier().

+ Here is the call graph for this function:

◆ clear()

void Slic3r::GUI::Selection::clear ( )
443{
444 if (!m_valid)
445 return;
446
447 if (m_list.empty())
448 return;
449
450 // ensure that the volumes get the proper color before next call to render (expecially needed for transparent volumes)
451 for (unsigned int i : m_list) {
452 GLVolume& volume = *(*m_volumes)[i];
453 volume.selected = false;
454 volume.set_render_color(volume.color.is_transparent());
455 }
456
457 m_list.clear();
458
459 update_type();
461
462 // this happens while the application is closing
463 if (wxGetApp().obj_manipul() == nullptr)
464 return;
465
466 // resets the cache in the sidebar
467 wxGetApp().obj_manipul()->reset_cache();
468
469 // #et_FIXME fake KillFocus from sidebar
470 wxGetApp().plater()->canvas3D()->handle_sidebar_focus_event("", false);
471}

References m_list, m_valid, set_bounding_boxes_dirty(), and update_type().

Referenced by add(), add_all(), add_instance(), add_object(), Slic3r::GUI::GLGizmoSimplify::add_simplify_suggestion_notification(), add_volume(), add_volumes(), Slic3r::GUI::Plater::priv::load_files(), Slic3r::GUI::Plater::priv::reload_all_from_disk(), remove_all(), Slic3r::GUI::GLCanvas3D::reset_volumes(), Slic3r::GUI::Plater::priv::split_object(), and Slic3r::GUI::ObjectList::update_selections_on_canvas().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ contains_all_volumes()

bool Slic3r::GUI::Selection::contains_all_volumes ( const std::vector< unsigned int > &  volume_idxs) const
597{
598 for (unsigned int i : volume_idxs) {
599 if (m_list.find(i) == m_list.end())
600 return false;
601 }
602
603 return true;
604}

References m_list.

Referenced by add_instance(), add_object(), add_volume(), add_volumes(), and Slic3r::GUI::ObjectList::update_selections_on_canvas().

+ Here is the caller graph for this function:

◆ contains_any_volume()

bool Slic3r::GUI::Selection::contains_any_volume ( const std::vector< unsigned int > &  volume_idxs) const
607{
608 for (unsigned int i : volume_idxs) {
609 if (m_list.find(i) != m_list.end())
610 return true;
611 }
612
613 return false;
614}

References m_list.

◆ contains_sinking_volumes()

bool Slic3r::GUI::Selection::contains_sinking_volumes ( bool  ignore_modifiers = true) const
617{
618 for (const GLVolume* v : *m_volumes) {
619 if (!ignore_modifiers || !v->is_modifier) {
620 if (v->is_sinking())
621 return true;
622 }
623 }
624 return false;
625}

References m_volumes.

Referenced by Slic3r::GUI::GLGizmoMeasure::on_is_activable().

+ Here is the caller graph for this function:

◆ contains_volume()

bool Slic3r::GUI::Selection::contains_volume ( unsigned int  volume_idx) const
inline
263{ return m_list.find(volume_idx) != m_list.end(); }

References m_list.

Referenced by add(), Slic3r::GUI::GLGizmoMeasure::on_mouse(), Slic3r::GUI::GLCanvas3D::on_mouse(), Slic3r::GUI::GLCanvas3D::reload_scene(), and remove().

+ Here is the caller graph for this function:

◆ copy_to_clipboard()

void Slic3r::GUI::Selection::copy_to_clipboard ( )
1663{
1664 if (!m_valid)
1665 return;
1666
1668
1669 for (const ObjectIdxsToInstanceIdxsMap::value_type& object : m_cache.content) {
1670 ModelObject* src_object = m_model->objects[object.first];
1671 ModelObject* dst_object = m_clipboard.add_object();
1672 dst_object->name = src_object->name;
1673 dst_object->input_file = src_object->input_file;
1674 dst_object->config.assign_config(src_object->config);
1675 dst_object->sla_support_points = src_object->sla_support_points;
1676 dst_object->sla_points_status = src_object->sla_points_status;
1677 dst_object->sla_drain_holes = src_object->sla_drain_holes;
1678 dst_object->layer_config_ranges = src_object->layer_config_ranges; // #ys_FIXME_experiment
1679 dst_object->layer_height_profile.assign(src_object->layer_height_profile);
1680 dst_object->origin_translation = src_object->origin_translation;
1681
1682 for (int i : object.second) {
1683 dst_object->add_instance(*src_object->instances[i]);
1684 }
1685
1686 for (unsigned int i : m_list) {
1687 // Copy the ModelVolumes only for the selected GLVolumes of the 1st selected instance.
1688 const GLVolume* volume = (*m_volumes)[i];
1689 if (volume->object_idx() == object.first && volume->instance_idx() == *object.second.begin()) {
1690 int volume_idx = volume->volume_idx();
1691 if (0 <= volume_idx && volume_idx < (int)src_object->volumes.size()) {
1692 ModelVolume* src_volume = src_object->volumes[volume_idx];
1693 ModelVolume* dst_volume = dst_object->add_volume(*src_volume);
1694 dst_volume->set_new_unique_id();
1695 }
1696 else
1697 assert(false);
1698 }
1699 }
1700 }
1701
1703}
void set_mode(Selection::EMode mode)
Definition Selection.hpp:128
void reset()
Definition Selection.cpp:77
ModelObject * add_object()
Definition Selection.cpp:87
Cache m_cache
Definition Selection.hpp:157
Clipboard m_clipboard
Definition Selection.hpp:158
std::string name
Definition Model.hpp:330

References Slic3r::ModelObject::add_instance(), Slic3r::GUI::Selection::Clipboard::add_object(), Slic3r::ModelObject::add_volume(), Slic3r::LayerHeightProfile::assign(), Slic3r::ModelConfig::assign_config(), Slic3r::ModelObject::config, Slic3r::GUI::Selection::Cache::content, Slic3r::ModelObject::input_file, Slic3r::ModelObject::instances, Slic3r::ModelObject::layer_config_ranges, Slic3r::ModelObject::layer_height_profile, m_cache, m_clipboard, m_list, m_mode, m_model, m_valid, Slic3r::ModelObject::name, Slic3r::Model::objects, Slic3r::ModelObject::origin_translation, Slic3r::GUI::Selection::Clipboard::reset(), Slic3r::GUI::Selection::Clipboard::set_mode(), Slic3r::ModelVolume::set_new_unique_id(), Slic3r::ModelObject::sla_drain_holes, Slic3r::ModelObject::sla_points_status, Slic3r::ModelObject::sla_support_points, and Slic3r::ModelObject::volumes.

+ Here is the call graph for this function:

◆ do_add_volume()

void Slic3r::GUI::Selection::do_add_volume ( unsigned int  volume_idx)
private
2034{
2035 m_list.insert(volume_idx);
2036 GLVolume* v = (*m_volumes)[volume_idx];
2037 v->selected = true;
2038 if (v->hover == GLVolume::HS_Select || v->hover == GLVolume::HS_Deselect)
2039 v->hover = GLVolume::HS_Hover;
2040}
@ HS_Select
Definition 3DScene.hpp:67
@ HS_Hover
Definition 3DScene.hpp:66
@ HS_Deselect
Definition 3DScene.hpp:68

References Slic3r::GLVolume::hover, Slic3r::GLVolume::HS_Deselect, Slic3r::GLVolume::HS_Hover, Slic3r::GLVolume::HS_Select, and m_list.

Referenced by add(), add_all(), add_volumes(), do_add_volumes(), instances_changed(), and set_deserialized().

+ Here is the caller graph for this function:

◆ do_add_volumes()

void Slic3r::GUI::Selection::do_add_volumes ( const std::vector< unsigned int > &  volume_idxs)
private
2043{
2044 for (unsigned int i : volume_idxs)
2045 {
2046 if (i < (unsigned int)m_volumes->size())
2047 do_add_volume(i);
2048 }
2049}

References do_add_volume(), and m_volumes.

Referenced by add_instance(), add_object(), and add_volume().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ do_remove_instance()

void Slic3r::GUI::Selection::do_remove_instance ( unsigned int  object_idx,
unsigned int  instance_idx 
)
private
2063{
2064 for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) {
2065 GLVolume* v = (*m_volumes)[i];
2066 if (v->object_idx() == (int)object_idx && v->instance_idx() == (int)instance_idx)
2068 }
2069}
void do_remove_volume(unsigned int volume_idx)
Definition Selection.cpp:2051

References do_remove_volume(), Slic3r::GLVolume::instance_idx(), m_volumes, and Slic3r::GLVolume::object_idx().

Referenced by remove(), and remove_instance().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ do_remove_object()

void Slic3r::GUI::Selection::do_remove_object ( unsigned int  object_idx)
private
2072{
2073 for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) {
2074 GLVolume* v = (*m_volumes)[i];
2075 if (v->object_idx() == (int)object_idx)
2077 }
2078}

References do_remove_volume(), m_volumes, and Slic3r::GLVolume::object_idx().

Referenced by remove_object().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ do_remove_volume()

void Slic3r::GUI::Selection::do_remove_volume ( unsigned int  volume_idx)
private
2052{
2053 IndicesList::iterator v_it = m_list.find(volume_idx);
2054 if (v_it == m_list.end())
2055 return;
2056
2057 m_list.erase(v_it);
2058
2059 (*m_volumes)[volume_idx]->selected = false;
2060}

References m_list.

Referenced by do_remove_instance(), do_remove_object(), remove(), remove_volume(), and remove_volumes().

+ Here is the caller graph for this function:

◆ ensure_not_below_bed()

void Slic3r::GUI::Selection::ensure_not_below_bed ( )
private
2750{
2751 typedef std::map<std::pair<int, int>, double> InstancesToZMap;
2752 InstancesToZMap instances_max_z;
2753
2754 for (size_t i = 0; i < m_volumes->size(); ++i) {
2755 GLVolume* volume = (*m_volumes)[i];
2756 if (!volume->is_wipe_tower && !volume->is_modifier) {
2757 const double max_z = volume->transformed_convex_hull_bounding_box().max.z();
2758 const std::pair<int, int> instance = std::make_pair(volume->object_idx(), volume->instance_idx());
2759 InstancesToZMap::iterator it = instances_max_z.find(instance);
2760 if (it == instances_max_z.end())
2761 it = instances_max_z.insert({ instance, -DBL_MAX }).first;
2762
2763 it->second = std::max(it->second, max_z);
2764 }
2765 }
2766
2767 if (is_any_volume()) {
2768 for (unsigned int i : m_list) {
2769 GLVolume& volume = *(*m_volumes)[i];
2770 const std::pair<int, int> instance = std::make_pair(volume.object_idx(), volume.instance_idx());
2771 InstancesToZMap::const_iterator it = instances_max_z.find(instance);
2772 const double z_shift = SINKING_MIN_Z_THRESHOLD - it->second;
2773 if (it != instances_max_z.end() && z_shift > 0.0)
2774 volume.set_volume_offset(Z, volume.get_volume_offset(Z) + z_shift);
2775 }
2776 }
2777 else {
2778 for (GLVolume* volume : *m_volumes) {
2779 const std::pair<int, int> instance = std::make_pair(volume->object_idx(), volume->instance_idx());
2780 InstancesToZMap::const_iterator it = instances_max_z.find(instance);
2781 if (it != instances_max_z.end() && it->second < SINKING_MIN_Z_THRESHOLD)
2782 volume->set_instance_offset(Z, volume->get_instance_offset(Z) + SINKING_MIN_Z_THRESHOLD - it->second);
2783 }
2784 }
2785}
bool is_any_volume() const
Definition Selection.hpp:251
static const double SINKING_MIN_Z_THRESHOLD
Definition Model.hpp:1410
@ Z
Definition libslic3r.h:100

References is_any_volume(), m_list, m_volumes, Slic3r::SINKING_MIN_Z_THRESHOLD, and Slic3r::Z.

Referenced by erase(), and translate().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ensure_on_bed()

void Slic3r::GUI::Selection::ensure_on_bed ( )
private
2723{
2724 typedef std::map<std::pair<int, int>, double> InstancesToZMap;
2725 InstancesToZMap instances_min_z;
2726
2727 for (size_t i = 0; i < m_volumes->size(); ++i) {
2728 GLVolume* volume = (*m_volumes)[i];
2729 if (!volume->is_wipe_tower && !volume->is_modifier &&
2730 std::find(m_cache.sinking_volumes.begin(), m_cache.sinking_volumes.end(), i) == m_cache.sinking_volumes.end()) {
2731 const double min_z = volume->transformed_convex_hull_bounding_box().min.z();
2732 std::pair<int, int> instance = std::make_pair(volume->object_idx(), volume->instance_idx());
2733 InstancesToZMap::iterator it = instances_min_z.find(instance);
2734 if (it == instances_min_z.end())
2735 it = instances_min_z.insert(InstancesToZMap::value_type(instance, DBL_MAX)).first;
2736
2737 it->second = std::min(it->second, min_z);
2738 }
2739 }
2740
2741 for (GLVolume* volume : *m_volumes) {
2742 std::pair<int, int> instance = std::make_pair(volume->object_idx(), volume->instance_idx());
2743 InstancesToZMap::iterator it = instances_min_z.find(instance);
2744 if (it != instances_min_z.end())
2745 volume->set_instance_offset(Z, volume->get_instance_offset(Z) - it->second);
2746 }
2747}
std::vector< unsigned int > sinking_volumes
Definition Selection.hpp:143

References m_cache, m_volumes, Slic3r::GUI::Selection::Cache::sinking_volumes, and Slic3r::Z.

Referenced by reset_skew(), and scale_and_translate().

+ Here is the caller graph for this function:

◆ erase()

void Slic3r::GUI::Selection::erase ( )
1439{
1440 if (!m_valid)
1441 return;
1442
1444 wxGetApp().obj_list()->delete_from_model_and_list(ItemType::itObject, get_object_idx(), 0);
1445 else if (is_multiple_full_object()) {
1446 std::vector<ItemForDelete> items;
1447 items.reserve(m_cache.content.size());
1448 for (ObjectIdxsToInstanceIdxsMap::iterator it = m_cache.content.begin(); it != m_cache.content.end(); ++it) {
1449 items.emplace_back(ItemType::itObject, it->first, 0);
1450 }
1451 wxGetApp().obj_list()->delete_from_model_and_list(items);
1452 }
1453 else if (is_multiple_full_instance()) {
1454 std::set<std::pair<int, int>> instances_idxs;
1455 for (ObjectIdxsToInstanceIdxsMap::iterator obj_it = m_cache.content.begin(); obj_it != m_cache.content.end(); ++obj_it) {
1456 for (InstanceIdxsList::reverse_iterator inst_it = obj_it->second.rbegin(); inst_it != obj_it->second.rend(); ++inst_it) {
1457 instances_idxs.insert(std::make_pair(obj_it->first, *inst_it));
1458 }
1459 }
1460
1461 std::vector<ItemForDelete> items;
1462 items.reserve(instances_idxs.size());
1463 for (const std::pair<int, int>& i : instances_idxs) {
1464 items.emplace_back(ItemType::itInstance, i.first, i.second);
1465 }
1466 wxGetApp().obj_list()->delete_from_model_and_list(items);
1467 }
1468 else if (is_single_full_instance())
1469 wxGetApp().obj_list()->delete_from_model_and_list(ItemType::itInstance, get_object_idx(), get_instance_idx());
1470 else if (is_mixed()) {
1471 std::set<ItemForDelete> items_set;
1472 std::map<int, int> volumes_in_obj;
1473
1474 for (auto i : m_list) {
1475 const auto gl_vol = (*m_volumes)[i];
1476 const auto glv_obj_idx = gl_vol->object_idx();
1477 const auto model_object = m_model->objects[glv_obj_idx];
1478
1479 if (model_object->instances.size() == 1) {
1480 if (model_object->volumes.size() == 1)
1481 items_set.insert(ItemForDelete(ItemType::itObject, glv_obj_idx, -1));
1482 else {
1483 items_set.insert(ItemForDelete(ItemType::itVolume, glv_obj_idx, gl_vol->volume_idx()));
1484 int idx = (volumes_in_obj.find(glv_obj_idx) == volumes_in_obj.end()) ? 0 : volumes_in_obj.at(glv_obj_idx);
1485 volumes_in_obj[glv_obj_idx] = ++idx;
1486 }
1487 continue;
1488 }
1489
1490 const auto glv_ins_idx = gl_vol->instance_idx();
1491
1492 for (auto obj_ins : m_cache.content) {
1493 if (obj_ins.first == glv_obj_idx) {
1494 if (obj_ins.second.find(glv_ins_idx) != obj_ins.second.end()) {
1495 if (obj_ins.second.size() == model_object->instances.size())
1496 items_set.insert(ItemForDelete(ItemType::itObject, glv_obj_idx, -1));
1497 else
1498 items_set.insert(ItemForDelete(ItemType::itInstance, glv_obj_idx, glv_ins_idx));
1499
1500 break;
1501 }
1502 }
1503 }
1504 }
1505
1506 std::vector<ItemForDelete> items;
1507 items.reserve(items_set.size());
1508 for (const ItemForDelete& i : items_set) {
1509 if (i.type == ItemType::itVolume) {
1510 const int vol_in_obj_cnt = volumes_in_obj.find(i.obj_idx) == volumes_in_obj.end() ? 0 : volumes_in_obj.at(i.obj_idx);
1511 if (vol_in_obj_cnt == (int)m_model->objects[i.obj_idx]->volumes.size()) {
1512 if (i.sub_obj_idx == vol_in_obj_cnt - 1)
1513 items.emplace_back(ItemType::itObject, i.obj_idx, 0);
1514 continue;
1515 }
1516 }
1517 items.emplace_back(i.type, i.obj_idx, i.sub_obj_idx);
1518 }
1519
1520 wxGetApp().obj_list()->delete_from_model_and_list(items);
1521 }
1522 else {
1523 std::set<std::pair<int, int>> volumes_idxs;
1524 for (unsigned int i : m_list) {
1525 const GLVolume* v = (*m_volumes)[i];
1526 // Only remove volumes associated with ModelVolumes from the object list.
1527 // Temporary meshes (SLA supports or pads) are not managed by the object list.
1528 if (v->volume_idx() >= 0)
1529 volumes_idxs.insert(std::make_pair(v->object_idx(), v->volume_idx()));
1530 }
1531
1532 std::vector<ItemForDelete> items;
1533 items.reserve(volumes_idxs.size());
1534 for (const std::pair<int, int>& v : volumes_idxs) {
1535 items.emplace_back(ItemType::itVolume, v.first, v.second);
1536 }
1537
1538 wxGetApp().obj_list()->delete_from_model_and_list(items);
1540 }
1541
1542 GLCanvas3D* canvas = wxGetApp().plater()->canvas3D();
1543 canvas->set_sequential_clearance_as_evaluating();
1544 canvas->set_as_dirty();
1545 canvas->request_extra_frame();
1546}
ObjectIdxsToInstanceIdxsMap content
Definition Selection.hpp:141
int get_object_idx() const
Definition Selection.cpp:641
bool is_multiple_full_instance() const
Definition Selection.hpp:246
bool is_mixed() const
Definition Selection.hpp:254
void ensure_not_below_bed()
Definition Selection.cpp:2749
bool is_single_full_object() const
Definition Selection.hpp:247
bool is_multiple_full_object() const
Definition Selection.hpp:248
@ itObject
Definition ObjectDataViewModel.hpp:24
@ itInstance
Definition ObjectDataViewModel.hpp:27
@ itVolume
Definition ObjectDataViewModel.hpp:25

References Slic3r::GUI::Selection::Cache::content, ensure_not_below_bed(), get_instance_idx(), get_object_idx(), is_mixed(), is_multiple_full_instance(), is_multiple_full_object(), is_single_full_instance(), is_single_full_object(), Slic3r::GUI::itInstance, Slic3r::GUI::itObject, Slic3r::GUI::itVolume, m_cache, m_list, m_model, m_valid, Slic3r::GLVolume::object_idx(), Slic3r::Model::objects, Slic3r::GUI::GLCanvas3D::request_extra_frame(), Slic3r::GUI::GLCanvas3D::set_as_dirty(), Slic3r::GUI::GLCanvas3D::set_sequential_clearance_as_evaluating(), and Slic3r::GLVolume::volume_idx().

Referenced by Slic3r::GUI::GLCanvas3D::delete_selected().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ flattening_rotate()

void Slic3r::GUI::Selection::flattening_rotate ( const Vec3d normal)
1039{
1040 // We get the normal in untransformed coordinates. We must transform it using the instance matrix, find out
1041 // how to rotate the instance so it faces downwards and do the rotation. All that for all selected instances.
1042 // The function assumes that is_from_single_object() holds.
1043 assert(Slic3r::is_approx(normal.norm(), 1.));
1044
1045 if (!m_valid)
1046 return;
1047
1048 for (unsigned int i : m_list) {
1049 GLVolume& v = *(*m_volumes)[i];
1050 // Normal transformed from the object coordinate space to the world coordinate space.
1051 const Geometry::Transformation& old_inst_trafo = v.get_instance_transformation();
1052 const Vec3d tnormal = old_inst_trafo.get_matrix().matrix().block(0, 0, 3, 3).inverse().transpose() * normal;
1053 // Additional rotation to align tnormal with the down vector in the world coordinate space.
1054 const Transform3d rotation_matrix = Transform3d(Eigen::Quaterniond().setFromTwoVectors(tnormal, -Vec3d::UnitZ()));
1055 v.set_instance_transformation(old_inst_trafo.get_offset_matrix() * rotation_matrix * old_inst_trafo.get_matrix_no_offset());
1056 }
1057
1058#if !DISABLE_INSTANCES_SYNCH
1059 // Apply the same transformation also to other instances,
1060 // but respect their possibly diffrent z-rotation.
1061 if (m_mode == Instance)
1063#endif // !DISABLE_INSTANCES_SYNCH
1064
1066}
void synchronize_unselected_instances(SyncRotationType sync_rotation_type)
Definition Selection.cpp:2648
The quaternion class used to represent 3D orientations and rotations.
Definition Quaternion.h:233
Vec< 3, T > normal(const std::array< Vec< 3, T >, 3 > &tri)
Definition Rotfinder.cpp:43
Eigen::Transform< double, 3, Eigen::Affine, Eigen::DontAlign > Transform3d
Definition Point.hpp:81
Eigen::Matrix< double, 3, 1, Eigen::DontAlign > Vec3d
Definition Point.hpp:52
constexpr bool is_approx(Number value, Number test_value, Number precision=EPSILON)
Definition libslic3r.h:271

References GENERAL, Slic3r::GLVolume::get_instance_transformation(), Slic3r::Geometry::Transformation::get_matrix(), Slic3r::Geometry::Transformation::get_matrix_no_offset(), Slic3r::Geometry::Transformation::get_offset_matrix(), Instance, Slic3r::is_approx(), m_list, m_mode, m_valid, Eigen::Transform< _Scalar, _Dim, _Mode, _Options >::matrix(), set_bounding_boxes_dirty(), Slic3r::GLVolume::set_instance_transformation(), and synchronize_unselected_instances().

Referenced by Slic3r::GUI::GLGizmoFlatten::on_mouse().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_bounding_box()

const BoundingBoxf3 & Slic3r::GUI::Selection::get_bounding_box ( ) const
674{
675 if (!m_bounding_box.has_value()) {
676 std::optional<BoundingBoxf3>* bbox = const_cast<std::optional<BoundingBoxf3>*>(&m_bounding_box);
677 *bbox = BoundingBoxf3();
678 if (m_valid) {
679 for (unsigned int i : m_list) {
680 (*bbox)->merge((*m_volumes)[i]->transformed_convex_hull_bounding_box());
681 }
682 }
683 }
684 return *m_bounding_box;
685}
std::optional< BoundingBoxf3 > m_bounding_box
Definition Selection.hpp:159

References m_bounding_box, m_list, m_valid, and m_volumes.

Referenced by Slic3r::GUI::GLCanvas3D::_max_bounding_box(), Slic3r::GUI::GLGizmoMeasure::render_dimensioning(), render_sidebar_hints(), render_sidebar_layers_hints(), scale_to_fit_print_volume(), set_caches(), Slic3r::GUI::ObjectManipulation::update_settings_value(), and Slic3r::GUI::GLCanvas3D::zoom_to_selection().

+ Here is the caller graph for this function:

◆ get_bounding_box_in_current_reference_system()

const std::pair< BoundingBoxf3, Transform3d > & Slic3r::GUI::Selection::get_bounding_box_in_current_reference_system ( ) const
787{
788 static int last_coordinates_type = -1;
789
790 assert(!is_empty());
791
792 ECoordinatesType coordinates_type = wxGetApp().obj_manipul()->get_coordinates_type();
793 if (m_mode == Instance && coordinates_type == ECoordinatesType::Local)
794 coordinates_type = ECoordinatesType::World;
795
796 if (last_coordinates_type != int(coordinates_type))
797 const_cast<std::optional<std::pair<BoundingBoxf3, Transform3d>>*>(&m_bounding_box_in_current_reference_system)->reset();
798
800 last_coordinates_type = int(coordinates_type);
801 *const_cast<std::optional<std::pair<BoundingBoxf3, Transform3d>>*>(&m_bounding_box_in_current_reference_system) = get_bounding_box_in_reference_system(coordinates_type);
802 }
803
805}
std::optional< std::pair< BoundingBoxf3, Transform3d > > m_bounding_box_in_current_reference_system
Definition Selection.hpp:178
std::pair< BoundingBoxf3, Transform3d > get_bounding_box_in_reference_system(ECoordinatesType type) const
Definition Selection.cpp:807
ECoordinatesType
Definition GUI_Geometry.hpp:8

References get_bounding_box_in_reference_system(), Instance, is_empty(), Slic3r::GUI::Local, m_bounding_box_in_current_reference_system, m_mode, and Slic3r::GUI::World.

Referenced by get_screen_space_bounding_box(), Slic3r::GUI::GLGizmoRotate::init_data_from_selection(), Slic3r::GUI::GLGizmoMove3D::on_render(), render(), render_sidebar_hints(), scale_and_translate(), Slic3r::GUI::GLGizmoScale3D::update_render_data(), and Slic3r::GUI::ObjectManipulation::update_settings_value().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_bounding_box_in_reference_system()

std::pair< BoundingBoxf3, Transform3d > Slic3r::GUI::Selection::get_bounding_box_in_reference_system ( ECoordinatesType  type) const
808{
809 //
810 // trafo to current reference system
811 //
812 Transform3d trafo;
813 switch (type)
814 {
815 case ECoordinatesType::World: { trafo = Transform3d::Identity(); break; }
817 case ECoordinatesType::Local: { trafo = get_first_volume()->world_matrix(); break; }
818 }
819
820 //
821 // trafo basis in world coordinates
822 //
823 Geometry::Transformation t(trafo);
824 t.reset_scaling_factor();
825 const Transform3d basis_trafo = t.get_matrix_no_offset();
826 std::vector<Vec3d> axes = { Vec3d::UnitX(), Vec3d::UnitY(), Vec3d::UnitZ() };
827 for (size_t i = 0; i < axes.size(); ++i) {
828 axes[i] = basis_trafo * axes[i];
829 }
830
831 //
832 // calculate bounding box aligned to trafo basis
833 //
834 Vec3d min = { DBL_MAX, DBL_MAX, DBL_MAX };
835 Vec3d max = { -DBL_MAX, -DBL_MAX, -DBL_MAX };
836 for (unsigned int id : m_list) {
837 const GLVolume& vol = *get_volume(id);
838 const Transform3d vol_world_rafo = vol.world_matrix();
839 const TriangleMesh* mesh = vol.convex_hull();
840 if (mesh == nullptr)
841 mesh = &m_model->objects[vol.object_idx()]->volumes[vol.volume_idx()]->mesh();
842 assert(mesh != nullptr);
843 for (const stl_vertex& v : mesh->its.vertices) {
844 const Vec3d world_v = vol_world_rafo * v.cast<double>();
845 for (int i = 0; i < 3; ++i) {
846 const double i_comp = world_v.dot(axes[i]);
847 min(i) = std::min(min(i), i_comp);
848 max(i) = std::max(max(i), i_comp);
849 }
850 }
851 }
852 const Vec3d box_size = max - min;
853 const Vec3d half_box_size = 0.5 * box_size;
854 BoundingBoxf3 out_box(-half_box_size, half_box_size);
855 Geometry::Transformation out_trafo(trafo);
856 const Vec3d center = 0.5 * (min + max);
857 out_trafo.set_offset(basis_trafo * center);
858 return { out_box, out_trafo.get_matrix_no_scaling_factor() };
859}
Transform3d world_matrix() const
Definition 3DScene.cpp:295
const Geometry::Transformation & get_instance_transformation() const
Definition 3DScene.hpp:213
const Transform3d & get_matrix() const
Definition Geometry.hpp:437
static EIGEN_DEVICE_FUNC const Transform Identity()
Returns an identity transformation.
Definition Transform.h:539
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half() min(const half &a, const half &b)
Definition Half.h:507
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half() max(const half &a, const half &b)
Definition Half.h:516
static const char axes[]
Definition GUI_ObjectManipulation.cpp:1171

References Slic3r::GUI::axes, Eigen::Transform< _Scalar, _Dim, _Mode, _Options >::cast(), Slic3r::GLVolume::convex_hull(), get_first_volume(), Slic3r::GLVolume::get_instance_transformation(), Slic3r::Geometry::Transformation::get_matrix(), Slic3r::Geometry::Transformation::get_matrix_no_offset(), Slic3r::Geometry::Transformation::get_matrix_no_scaling_factor(), get_volume(), Eigen::Transform< double, 3, Eigen::Affine, Eigen::DontAlign >::Identity(), Slic3r::GUI::Instance, Slic3r::TriangleMesh::its, Slic3r::GUI::Local, m_list, m_model, Slic3r::GLVolume::object_idx(), Slic3r::Model::objects, Slic3r::Geometry::Transformation::reset_scaling_factor(), Slic3r::Geometry::Transformation::set_offset(), indexed_triangle_set::vertices, Slic3r::GLVolume::volume_idx(), Slic3r::GUI::World, and Slic3r::GLVolume::world_matrix().

Referenced by get_bounding_box_in_current_reference_system(), and Slic3r::GUI::GLGizmoRotate::init_data_from_selection().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_clipboard()

const Clipboard & Slic3r::GUI::Selection::get_clipboard ( ) const
inline
356{ return m_clipboard; }

References m_clipboard.

Referenced by Slic3r::GUI::Plater::can_paste_from_clipboard().

+ Here is the caller graph for this function:

◆ get_content()

const ObjectIdxsToInstanceIdxsMap & Slic3r::GUI::Selection::get_content ( ) const
inline
295{ return m_cache.content; }

References Slic3r::GUI::Selection::Cache::content, and m_cache.

Referenced by Slic3r::GUI::RotoptimizeJob::prepare(), Slic3r::GUI::ArrangeJob::prepare_selected(), Slic3r::GUI::GLCanvas3D::SLAView::select_full_instance(), and Slic3r::GUI::ObjectList::update_selections().

+ Here is the caller graph for this function:

◆ get_first_volume()

const GLVolume * Slic3r::GUI::Selection::get_first_volume ( ) const
inline
292{ return get_volume(*m_list.begin()); }

References get_volume(), and m_list.

Referenced by Slic3r::GUI::ObjectManipulation::ObjectManipulation(), Slic3r::GUI::MenuFactory::append_menu_item_edit_text(), bake_transform_if_needed(), Slic3r::GUI::GLGizmoEmboss::calculate_scale(), get_bounding_box_in_reference_system(), Slic3r::GUI::GLGizmoCut3D::get_cut_matrix(), Slic3r::GUI::SceneRaycaster::hit(), Slic3r::GUI::ObjectList::load_generic_subobject(), Slic3r::GUI::ObjectList::load_modifier(), Slic3r::GUI::GLGizmoMove3D::local_transform(), Slic3r::GUI::GLGizmoFlatten::on_register_raycasters_for_picking(), Slic3r::GUI::GLGizmoFlatten::on_render(), Slic3r::GUI::CommonGizmosDataObjects::SelectionInfo::on_update(), Slic3r::GUI::GLGizmoCut3D::process_cut_line(), Slic3r::GUI::Plater::priv::replace_with_stl(), Slic3r::GUI::GLGizmoCut3D::transformed_bounding_box(), Slic3r::GUI::GLGizmoHollow::update_hole_raycasters_for_picking_transform(), Slic3r::GUI::GLGizmoMeasure::update_if_needed(), Slic3r::GUI::GLGizmoSlaSupports::update_point_raycasters_for_picking_transform(), Slic3r::GUI::GLGizmoScale3D::update_render_data(), Slic3r::GUI::ObjectManipulation::update_reset_buttons_visibility(), Slic3r::GUI::ObjectList::update_selections(), and Slic3r::GUI::ObjectManipulation::update_settings_value().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_full_scaled_instance_bounding_box()

const BoundingBoxf3 & Slic3r::GUI::Selection::get_full_scaled_instance_bounding_box ( ) const
749{
750 assert(is_single_full_instance());
751
752 if (!m_full_scaled_instance_bounding_box.has_value()) {
753 std::optional<BoundingBoxf3>* bbox = const_cast<std::optional<BoundingBoxf3>*>(&m_full_scaled_instance_bounding_box);
754 *bbox = BoundingBoxf3();
755 if (m_valid) {
756 for (unsigned int i : m_list) {
757 const GLVolume& volume = *(*m_volumes)[i];
758 Transform3d trafo = volume.get_instance_transformation().get_matrix() * volume.get_volume_transformation().get_matrix();
759 trafo.translation().z() += volume.get_sla_shift_z();
760 (*bbox)->merge(volume.transformed_convex_hull_bounding_box(trafo));
761 }
762 }
763 }
765}
std::optional< BoundingBoxf3 > m_full_scaled_instance_bounding_box
Definition Selection.hpp:172

References is_single_full_instance(), m_full_scaled_instance_bounding_box, m_list, m_valid, and Eigen::Transform< _Scalar, _Dim, _Mode, _Options >::translation().

+ Here is the call graph for this function:

◆ get_full_unscaled_instance_bounding_box()

const BoundingBoxf3 & Slic3r::GUI::Selection::get_full_unscaled_instance_bounding_box ( ) const
730{
731 assert(is_single_full_instance());
732
733 if (!m_full_unscaled_instance_bounding_box.has_value()) {
734 std::optional<BoundingBoxf3>* bbox = const_cast<std::optional<BoundingBoxf3>*>(&m_full_unscaled_instance_bounding_box);
735 *bbox = BoundingBoxf3();
736 if (m_valid) {
737 for (unsigned int i : m_list) {
738 const GLVolume& volume = *(*m_volumes)[i];
739 Transform3d trafo = volume.get_instance_transformation().get_matrix_no_scaling_factor() * volume.get_volume_transformation().get_matrix();
740 trafo.translation().z() += volume.get_sla_shift_z();
741 (*bbox)->merge(volume.transformed_convex_hull_bounding_box(trafo));
742 }
743 }
744 }
746}
std::optional< BoundingBoxf3 > m_full_unscaled_instance_bounding_box
Definition Selection.hpp:169

References is_single_full_instance(), m_full_unscaled_instance_bounding_box, m_list, m_valid, and Eigen::Transform< _Scalar, _Dim, _Mode, _Options >::translation().

Referenced by Slic3r::GUI::ObjectManipulation::change_size_value(), and scale_and_translate().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_full_unscaled_instance_local_bounding_box()

const BoundingBoxf3 & Slic3r::GUI::Selection::get_full_unscaled_instance_local_bounding_box ( ) const
768{
769 assert(is_single_full_instance());
770
772 std::optional<BoundingBoxf3>* bbox = const_cast<std::optional<BoundingBoxf3>*>(&m_full_unscaled_instance_local_bounding_box);
773 *bbox = BoundingBoxf3();
774 if (m_valid) {
775 for (unsigned int i : m_list) {
776 const GLVolume& volume = *(*m_volumes)[i];
777 Transform3d trafo = volume.get_volume_transformation().get_matrix();
778 trafo.translation().z() += volume.get_sla_shift_z();
779 (*bbox)->merge(volume.transformed_convex_hull_bounding_box(trafo));
780 }
781 }
782 }
784}
std::optional< BoundingBoxf3 > m_full_unscaled_instance_local_bounding_box
Definition Selection.hpp:175

References is_single_full_instance(), m_full_unscaled_instance_local_bounding_box, m_list, m_valid, and Eigen::Transform< _Scalar, _Dim, _Mode, _Options >::translation().

Referenced by Slic3r::GUI::ObjectManipulation::change_size_value(), scale_and_translate(), and Slic3r::GUI::ObjectManipulation::update_settings_value().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_instance_idx()

int Slic3r::GUI::Selection::get_instance_idx ( ) const
647{
648 if (m_cache.content.size() == 1) {
649 const InstanceIdxsList& idxs = m_cache.content.begin()->second;
650 if (idxs.size() == 1)
651 return *idxs.begin();
652 }
653
654 return -1;
655}
std::set< int > InstanceIdxsList
Definition Selection.hpp:104

References Slic3r::GUI::Selection::Cache::content, and m_cache.

Referenced by add(), Slic3r::GUI::GLGizmoFlatten::data_changed(), erase(), Slic3r::GUI::CommonGizmosDataObjects::SelectionInfo::get_active_instance(), Slic3r::GUI::GLGizmoCut3D::get_cut_matrix(), Slic3r::GUI::Plater::priv::get_selected_instance_idx(), Slic3r::GUI::GLGizmoPainterBase::gizmo_event(), Slic3r::GUI::Plater::increase_instances(), is_from_single_instance(), is_single_full_instance(), Slic3r::GUI::GLGizmoHollow::on_render(), Slic3r::GUI::GLGizmoSlaSupports::on_render(), paste_volumes_from_clipboard(), Slic3r::GUI::GLGizmoCut3D::perform_cut(), Slic3r::GUI::FillBedJob::prepare(), Slic3r::GUI::GLGizmoCut3D::process_contours(), Slic3r::GUI::GLGizmoPainterBase::render_cursor(), Slic3r::GUI::GLCanvas3D::SLAView::render_switch_button(), Slic3r::GUI::GLGizmoPainterBase::render_triangles(), Slic3r::GUI::GLGizmoMmuSegmentation::render_triangles(), Slic3r::GUI::GLGizmoCut3D::reset_cut_by_contours(), Slic3r::GUI::GLGizmoFdmSupports::select_facets_by_angle(), Slic3r::GUI::Sidebar::show_info_sizer(), Slic3r::GUI::ObjectList::split_instances(), Slic3r::GUI::ObjectList::update_selections(), Slic3r::GUI::ObjectList::update_selections_on_canvas(), update_type(), and Slic3r::GUI::GLGizmoSlaBase::update_volumes().

+ Here is the caller graph for this function:

◆ get_instance_idxs()

const Selection::InstanceIdxsList & Slic3r::GUI::Selection::get_instance_idxs ( ) const
658{
659 assert(m_cache.content.size() == 1);
660 return m_cache.content.begin()->second;
661}

References Slic3r::GUI::Selection::Cache::content, and m_cache.

Referenced by Slic3r::GUI::ObjectList::load_generic_subobject(), Slic3r::GUI::ObjectList::load_modifier(), Slic3r::GUI::ObjectList::split_instances(), and Slic3r::GUI::ObjectList::update_selections().

+ Here is the caller graph for this function:

◆ get_missing_volume_idxs_from()

std::vector< unsigned int > Slic3r::GUI::Selection::get_missing_volume_idxs_from ( const std::vector< unsigned int > &  volume_idxs) const
1775{
1776 std::vector<unsigned int> idxs;
1777
1778 for (unsigned int i : m_list) {
1779 std::vector<unsigned int>::const_iterator it = std::find(volume_idxs.begin(), volume_idxs.end(), i);
1780 if (it == volume_idxs.end())
1781 idxs.push_back(i);
1782 }
1783
1784 return idxs;
1785}

References m_list.

Referenced by Slic3r::GUI::ObjectList::update_selections_on_canvas().

+ Here is the caller graph for this function:

◆ get_mode()

◆ get_model()

◆ get_object_idx()

int Slic3r::GUI::Selection::get_object_idx ( ) const
642{
643 return (m_cache.content.size() == 1) ? m_cache.content.begin()->first : -1;
644}

References Slic3r::GUI::Selection::Cache::content, and m_cache.

Referenced by Slic3r::GUI::MenuFactory::append_menu_item_settings(), Slic3r::GUI::GLGizmoSimplify::apply_simplify(), Slic3r::GUI::GLGizmoEmboss::close(), Slic3r::GUI::GLGizmoEmboss::create_volume(), Slic3r::GUI::GLGizmoFlatten::data_changed(), Slic3r::GUI::GLCanvas3D::do_rotate(), erase(), Slic3r::GUI::GLGizmoCut3D::get_cut_matrix(), Slic3r::GUI::Plater::priv::get_export_file_path(), Slic3r::GUI::get_selected_gl_volume(), Slic3r::GUI::Plater::priv::get_selected_object_idx(), is_any_connector(), is_any_cut_volume(), is_from_single_object(), Slic3r::GUI::ObjectList::is_selected_object_cut(), is_single_full_instance(), Slic3r::GUI::ObjectList::layers_editing(), Slic3r::GUI::ObjectList::load_generic_subobject(), Slic3r::GUI::ObjectList::load_modifier(), Slic3r::GUI::ObjectList::load_shape_object(), Slic3r::GUI::GLGizmoCut3D::on_is_activable(), Slic3r::GUI::GLGizmoCut3D::on_mouse(), Slic3r::GUI::GLGizmoHollow::on_mouse(), Slic3r::GUI::GLGizmoPainterBase::on_mouse(), Slic3r::GUI::GLGizmoSlaSupports::on_mouse(), Slic3r::GUI::GLCanvas3D::on_mouse(), Slic3r::GUI::GLCanvas3D::on_mouse_wheel(), Slic3r::GUI::GLGizmoHollow::on_render(), Slic3r::GUI::GLGizmoSlaSupports::on_render(), Slic3r::GUI::CommonGizmosDataObjects::SelectionInfo::on_update(), Slic3r::GUI::ObjectList::part_selection_changed(), paste_volumes_from_clipboard(), Slic3r::GUI::GLGizmoCut3D::perform_cut(), Slic3r::GUI::GLGizmoCut3D::process_contours(), Slic3r::GUI::GLCanvas3D::SLAView::render_switch_button(), Slic3r::GUI::GLGizmoCut3D::reset_cut_by_contours(), Slic3r::GUI::GLGizmoSlaBase::reslice_until_step(), scale_to_fit_print_volume(), Slic3r::GUI::Sidebar::show_info_sizer(), Slic3r::GUI::ObjectList::split_instances(), Slic3r::GUI::ObjectList::update_selections(), Slic3r::GUI::ObjectList::update_selections_on_canvas(), update_type(), and Slic3r::GUI::GLGizmoSlaBase::update_volumes().

+ Here is the caller graph for this function:

◆ get_object_idxs()

std::set< unsigned int > Slic3r::GUI::Selection::get_object_idxs ( ) const
1800{
1801 std::set<unsigned int> idxs;
1802
1803 for (unsigned int i : m_list)
1804 idxs.emplace((*m_volumes)[i]->object_idx());
1805
1806 return idxs;
1807}

References m_list, and m_volumes.

Referenced by Slic3r::GUI::Plater::priv::can_increase_instances(), and Slic3r::GUI::Plater::set_number_of_copies().

+ Here is the caller graph for this function:

◆ get_scaled_instance_bounding_box()

const BoundingBoxf3 & Slic3r::GUI::Selection::get_scaled_instance_bounding_box ( ) const
709{
710 assert(is_single_full_instance());
711
712 if (!m_scaled_instance_bounding_box.has_value()) {
713 std::optional<BoundingBoxf3>* bbox = const_cast<std::optional<BoundingBoxf3>*>(&m_scaled_instance_bounding_box);
714 *bbox = BoundingBoxf3();
715 if (m_valid) {
716 for (unsigned int i : m_list) {
717 const GLVolume& volume = *(*m_volumes)[i];
718 if (volume.is_modifier)
719 continue;
720 Transform3d trafo = volume.get_instance_transformation().get_matrix() * volume.get_volume_transformation().get_matrix();
721 trafo.translation().z() += volume.get_sla_shift_z();
722 (*bbox)->merge(volume.transformed_convex_hull_bounding_box(trafo));
723 }
724 }
725 }
727}
std::optional< BoundingBoxf3 > m_scaled_instance_bounding_box
Definition Selection.hpp:166

References is_single_full_instance(), m_list, m_scaled_instance_bounding_box, m_valid, and Eigen::Transform< _Scalar, _Dim, _Mode, _Options >::translation().

Referenced by Slic3r::GUI::ObjectManipulation::ObjectManipulation(), and Slic3r::GUI::ObjectManipulation::update_reset_buttons_visibility().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_screen_space_bounding_box()

BoundingBoxf Slic3r::GUI::Selection::get_screen_space_bounding_box ( )
862{
863 BoundingBoxf ss_box;
864 if (!is_empty()) {
865 const auto& [box, box_trafo] = get_bounding_box_in_current_reference_system();
866
867 // vertices
868 std::vector<Vec3d> vertices = {
869 { box.min.x(), box.min.y(), box.min.z() },
870 { box.max.x(), box.min.y(), box.min.z() },
871 { box.max.x(), box.max.y(), box.min.z() },
872 { box.min.x(), box.max.y(), box.min.z() },
873 { box.min.x(), box.min.y(), box.max.z() },
874 { box.max.x(), box.min.y(), box.max.z() },
875 { box.max.x(), box.max.y(), box.max.z() },
876 { box.min.x(), box.max.y(), box.max.z() }
877 };
878
879 const Camera& camera = wxGetApp().plater()->get_camera();
880 const Matrix4d projection_view_matrix = camera.get_projection_matrix().matrix() * camera.get_view_matrix().matrix();
881 const std::array<int, 4>& viewport = camera.get_viewport();
882
883 const double half_w = 0.5 * double(viewport[2]);
884 const double h = double(viewport[3]);
885 const double half_h = 0.5 * h;
886 for (const Vec3d& v : vertices) {
887 const Vec3d world = box_trafo * v;
888 const Vec4d clip = projection_view_matrix * Vec4d(world.x(), world.y(), world.z(), 1.0);
889 const Vec3d ndc = Vec3d(clip.x(), clip.y(), clip.z()) / clip.w();
890 const Vec2d ss = Vec2d(half_w * ndc.x() + double(viewport[0]) + half_w, h - (half_h * ndc.y() + double(viewport[1]) + half_h));
891 ss_box.merge(ss);
892 }
893 }
894
895 return ss_box;
896}
const std::pair< BoundingBoxf3, Transform3d > & get_bounding_box_in_current_reference_system() const
Definition Selection.cpp:786
Eigen::Matrix< double, 4, 1, Eigen::DontAlign > Vec4d
Definition Point.hpp:53
Eigen::Matrix< double, 2, 1, Eigen::DontAlign > Vec2d
Definition Point.hpp:51
Eigen::Matrix< double, 4, 4, Eigen::DontAlign > Matrix4d
Definition Point.hpp:73

References get_bounding_box_in_current_reference_system(), Slic3r::GUI::Camera::get_projection_matrix(), Slic3r::GUI::Camera::get_view_matrix(), Slic3r::GUI::Camera::get_viewport(), is_empty(), Eigen::Transform< _Scalar, _Dim, _Mode, _Options >::matrix(), and Slic3r::BoundingBoxBase< PointType, APointsType >::merge().

Referenced by Slic3r::GUI::GLCanvas3D::SLAView::render_switch_button().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_unscaled_instance_bounding_box()

const BoundingBoxf3 & Slic3r::GUI::Selection::get_unscaled_instance_bounding_box ( ) const
688{
689 assert(is_single_full_instance());
690
691 if (!m_unscaled_instance_bounding_box.has_value()) {
692 std::optional<BoundingBoxf3>* bbox = const_cast<std::optional<BoundingBoxf3>*>(&m_unscaled_instance_bounding_box);
693 *bbox = BoundingBoxf3();
694 if (m_valid) {
695 for (unsigned int i : m_list) {
696 const GLVolume& volume = *(*m_volumes)[i];
697 if (volume.is_modifier)
698 continue;
699 Transform3d trafo = volume.get_instance_transformation().get_matrix_no_scaling_factor() * volume.get_volume_transformation().get_matrix();
700 trafo.translation().z() += volume.get_sla_shift_z();
701 (*bbox)->merge(volume.transformed_convex_hull_bounding_box(trafo));
702 }
703 }
704 }
706}
std::optional< BoundingBoxf3 > m_unscaled_instance_bounding_box
Definition Selection.hpp:163

References is_single_full_instance(), m_list, m_unscaled_instance_bounding_box, m_valid, and Eigen::Transform< _Scalar, _Dim, _Mode, _Options >::translation().

Referenced by Slic3r::GUI::ObjectManipulation::update_settings_value().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_unselected_volume_idxs_from()

std::vector< unsigned int > Slic3r::GUI::Selection::get_unselected_volume_idxs_from ( const std::vector< unsigned int > &  volume_idxs) const
1788{
1789 std::vector<unsigned int> idxs;
1790
1791 for (unsigned int i : volume_idxs) {
1792 if (m_list.find(i) == m_list.end())
1793 idxs.push_back(i);
1794 }
1795
1796 return idxs;
1797}

References m_list.

Referenced by Slic3r::GUI::ObjectList::update_selections_on_canvas().

+ Here is the caller graph for this function:

◆ get_volume() [1/2]

GLVolume * Slic3r::GUI::Selection::get_volume ( unsigned int  volume_idx)
669{
670 return (m_valid && (volume_idx < (unsigned int)m_volumes->size())) ? (*m_volumes)[volume_idx] : nullptr;
671}

References m_valid, and m_volumes.

◆ get_volume() [2/2]

◆ get_volume_idxs()

◆ get_volume_idxs_from_instance()

std::vector< unsigned int > Slic3r::GUI::Selection::get_volume_idxs_from_instance ( unsigned int  object_idx,
unsigned int  instance_idx 
) const
1749{
1750 std::vector<unsigned int> idxs;
1751 for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) {
1752 const GLVolume* v = (*m_volumes)[i];
1753 if (v->object_idx() == (int)object_idx && v->instance_idx() == (int)instance_idx)
1754 idxs.push_back(i);
1755 }
1756 return idxs;
1757}

References Slic3r::GLVolume::instance_idx(), m_volumes, and Slic3r::GLVolume::object_idx().

Referenced by add_instance(), and Slic3r::GUI::ObjectList::update_selections_on_canvas().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_volume_idxs_from_object()

std::vector< unsigned int > Slic3r::GUI::Selection::get_volume_idxs_from_object ( unsigned int  object_idx) const
1730{
1731 std::vector<unsigned int> idxs;
1732
1733 const PrinterTechnology pt = wxGetApp().plater()->printer_technology();
1734
1735 for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) {
1736 const GLVolume* v = (*m_volumes)[i];
1737 if (v->object_idx() == (int)object_idx) {
1738 if (pt == ptSLA && v->is_modifier &&
1739 m_model->objects[object_idx]->volumes[v->volume_idx()]->is_modifier())
1740 continue;
1741 idxs.push_back(i);
1742 }
1743 }
1744
1745 return idxs;
1746}
PrinterTechnology
Definition Config.hpp:205

References m_model, m_volumes, Slic3r::GLVolume::object_idx(), Slic3r::Model::objects, Slic3r::ptSLA, and Slic3r::GLVolume::volume_idx().

Referenced by add_object(), and Slic3r::GUI::ObjectList::update_selections_on_canvas().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_volume_idxs_from_volume()

std::vector< unsigned int > Slic3r::GUI::Selection::get_volume_idxs_from_volume ( unsigned int  object_idx,
unsigned int  instance_idx,
unsigned int  volume_idx 
) const
1760{
1761 std::vector<unsigned int> idxs;
1762
1763 for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) {
1764 const GLVolume* v = (*m_volumes)[i];
1765 if (v->object_idx() == (int)object_idx && v->volume_idx() == (int)volume_idx) {
1766 if ((int)instance_idx != -1 && v->instance_idx() == (int)instance_idx)
1767 idxs.push_back(i);
1768 }
1769 }
1770
1771 return idxs;
1772}

References Slic3r::GLVolume::instance_idx(), m_volumes, Slic3r::GLVolume::object_idx(), and Slic3r::GLVolume::volume_idx().

Referenced by add_volume(), and Slic3r::GUI::ObjectList::update_selections_on_canvas().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ init()

bool Slic3r::GUI::Selection::init ( )
127{
128 m_arrow.init_from(straight_arrow(10.0f, 5.0f, 5.0f, 10.0f, 1.0f));
129 m_curved_arrow.init_from(circular_arrow(16, 10.0f, 5.0f, 10.0f, 5.0f, 1.0f));
130#if ENABLE_RENDER_SELECTION_CENTER
131 m_vbo_sphere.init_from(its_make_sphere(0.75, PI / 12.0));
132#endif // ENABLE_RENDER_SELECTION_CENTER
133
134 return true;
135}
void init_from(Geometry &&data)
Definition GLModel.cpp:485
GLModel m_arrow
Definition Selection.hpp:185
GLModel m_curved_arrow
Definition Selection.hpp:186
static constexpr double PI
Definition libslic3r.h:58
GLModel::Geometry circular_arrow(unsigned int resolution, float radius, float tip_height, float tip_width, float stem_width, float thickness)
Definition GLModel.cpp:1240
GLModel::Geometry straight_arrow(float tip_width, float tip_height, float stem_width, float stem_height, float thickness)
Definition GLModel.cpp:1404
indexed_triangle_set its_make_sphere(double radius, double fa)
Definition TriangleMesh.cpp:1092

References Slic3r::GUI::circular_arrow(), Slic3r::GUI::GLModel::init_from(), Slic3r::its_make_sphere(), m_arrow, m_curved_arrow, PI, and Slic3r::GUI::straight_arrow().

Referenced by Slic3r::GUI::GLCanvas3D::init().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ instances_changed()

void Slic3r::GUI::Selection::instances_changed ( const std::vector< size_t > &  instance_ids_selected)
475{
476 assert(m_valid);
477 assert(m_mode == Instance);
478 m_list.clear();
479
480 const PrinterTechnology pt = wxGetApp().plater()->printer_technology();
481
482 for (unsigned int volume_idx = 0; volume_idx < (unsigned int)m_volumes->size(); ++ volume_idx) {
483 const GLVolume *volume = (*m_volumes)[volume_idx];
484 if (pt == ptSLA && volume->is_modifier &&
485 m_model->objects[volume->object_idx()]->volumes[volume->volume_idx()]->is_modifier())
486 continue;
487 auto it = std::lower_bound(instance_ids_selected.begin(), instance_ids_selected.end(), volume->geometry_id.second);
488 if (it != instance_ids_selected.end() && *it == volume->geometry_id.second)
489 this->do_add_volume(volume_idx);
490 }
491 update_type();
493}

References do_add_volume(), Instance, m_list, m_mode, m_model, m_valid, m_volumes, Slic3r::Model::objects, Slic3r::ptSLA, set_bounding_boxes_dirty(), and update_type().

Referenced by Slic3r::GUI::GLCanvas3D::reload_scene().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ is_any_connector()

bool Slic3r::GUI::Selection::is_any_connector ( ) const
514{
515 const int obj_idx = get_object_idx();
516
517 if ((is_any_volume() || is_any_modifier() || is_mixed()) && // some solid_part AND/OR modifier is selected
518 obj_idx >= 0 && m_model->objects[obj_idx]->is_cut()) {
519 const ModelVolumePtrs& obj_volumes = m_model->objects[obj_idx]->volumes;
520 for (size_t vol_idx = 0; vol_idx < obj_volumes.size(); vol_idx++)
521 if (obj_volumes[vol_idx]->is_cut_connector())
522 for (const GLVolume* v : *m_volumes)
523 if (v->object_idx() == obj_idx && v->volume_idx() == (int)vol_idx && v->selected)
524 return true;
525 }
526 return false;
527}
if(!(yy_init))
Definition lexer.c:1190
std::vector< ModelVolume * > ModelVolumePtrs
Definition Model.hpp:106

References get_object_idx(), is_any_modifier(), is_any_volume(), is_mixed(), m_model, m_volumes, and Slic3r::Model::objects.

Referenced by Slic3r::GUI::GLGizmoMove3D::on_is_activable(), Slic3r::GUI::GLGizmoRotate3D::on_is_activable(), Slic3r::GUI::GLGizmoScale3D::on_is_activable(), Slic3r::GUI::GLCanvas3D::on_mouse(), and Slic3r::GUI::Plater::priv::on_right_click().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ is_any_cut_volume()

bool Slic3r::GUI::Selection::is_any_cut_volume ( ) const
530{
531 const int obj_idx = get_object_idx();
532 return is_any_volume() && obj_idx >= 0 && m_model->objects[obj_idx]->is_cut();
533}

References get_object_idx(), is_any_volume(), m_model, and Slic3r::Model::objects.

Referenced by Slic3r::GUI::GLGizmoMove3D::on_is_activable(), Slic3r::GUI::GLGizmoRotate3D::on_is_activable(), and Slic3r::GUI::GLGizmoScale3D::on_is_activable().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ is_any_modifier()

bool Slic3r::GUI::Selection::is_any_modifier ( ) const
inline
bool is_multiple_modifier() const
Definition Selection.hpp:244
bool is_single_modifier() const
Definition Selection.hpp:243

References is_multiple_modifier(), and is_single_modifier().

Referenced by add(), is_any_connector(), Slic3r::GUI::ObjectList::part_selection_changed(), and Slic3r::GUI::ObjectList::update_selections().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ is_any_volume()

bool Slic3r::GUI::Selection::is_any_volume ( ) const
inline
251{ return is_single_volume() || is_multiple_volume(); }
bool is_single_volume() const
Definition Selection.hpp:249
bool is_multiple_volume() const
Definition Selection.hpp:250

References is_multiple_volume(), and is_single_volume().

Referenced by ensure_not_below_bed(), is_any_connector(), is_any_cut_volume(), Slic3r::GUI::ObjectList::part_selection_changed(), and Slic3r::GUI::ObjectList::update_selections().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ is_empty()

◆ is_enabled()

bool Slic3r::GUI::Selection::is_enabled ( ) const
inline
203{ return m_enabled; }

References m_enabled.

Referenced by Slic3r::GUI::GLCanvas3D::init().

+ Here is the caller graph for this function:

◆ is_from_fully_selected_instance()

bool Slic3r::GUI::Selection::is_from_fully_selected_instance ( unsigned int  volume_idx) const
private
2788{
2789 struct SameInstance
2790 {
2791 int obj_idx;
2792 int inst_idx;
2793 GLVolumePtrs& volumes;
2794
2795 SameInstance(int obj_idx, int inst_idx, GLVolumePtrs& volumes) : obj_idx(obj_idx), inst_idx(inst_idx), volumes(volumes) {}
2796 bool operator () (unsigned int i) { return (volumes[i]->volume_idx() >= 0) && (volumes[i]->object_idx() == obj_idx) && (volumes[i]->instance_idx() == inst_idx); }
2797 };
2798
2799 if ((unsigned int)m_volumes->size() <= volume_idx)
2800 return false;
2801
2802 GLVolume* volume = (*m_volumes)[volume_idx];
2803 int object_idx = volume->object_idx();
2804 if ((int)m_model->objects.size() <= object_idx)
2805 return false;
2806
2807 unsigned int count = (unsigned int)std::count_if(m_list.begin(), m_list.end(), SameInstance(object_idx, volume->instance_idx(), *m_volumes));
2808
2809 PrinterTechnology pt = wxGetApp().plater()->printer_technology();
2810 const ModelVolumePtrs& volumes = m_model->objects[object_idx]->volumes;
2811 const unsigned int vol_cnt = (unsigned int)std::count_if(volumes.begin(), volumes.end(), [pt](const ModelVolume* volume) { return pt == ptFFF || !volume->is_modifier(); });
2812
2813 return count == vol_cnt;
2814}
@ ptFFF
Definition Config.hpp:207
std::vector< GLVolume * > GLVolumePtrs
Definition 3DScene.hpp:325

References m_list, m_model, m_volumes, Slic3r::Model::objects, and Slic3r::ptFFF.

Referenced by rotate(), and translate().

+ Here is the caller graph for this function:

◆ is_from_single_instance()

bool Slic3r::GUI::Selection::is_from_single_instance ( ) const
inline
255{ return get_instance_idx() != -1; }

References get_instance_idx().

Referenced by Slic3r::GUI::Plater::can_paste_from_clipboard(), Slic3r::GUI::GLGizmoPainterBase::data_changed(), paste_from_clipboard(), requires_local_axes(), transform_instance_relative(), and Slic3r::GUI::ObjectList::update_selections().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ is_from_single_object()

bool Slic3r::GUI::Selection::is_from_single_object ( ) const
567{
568 const int idx = get_object_idx();
569 return 0 <= idx && idx < int(m_model->objects.size());
570}

References get_object_idx(), m_model, and Slic3r::Model::objects.

Referenced by Slic3r::GUI::GLGizmoFlatten::data_changed().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ is_instance_mode()

bool Slic3r::GUI::Selection::is_instance_mode ( ) const
inline
258{ return m_mode == Instance; }

References Instance, and m_mode.

◆ is_mixed()

bool Slic3r::GUI::Selection::is_mixed ( ) const
inline
254{ return m_type == Mixed; }

References m_type, and Mixed.

Referenced by Slic3r::GUI::MenuFactory::append_menu_item_settings(), erase(), is_any_connector(), Slic3r::GUI::ObjectList::part_selection_changed(), and Slic3r::GUI::ObjectList::update_selections().

+ Here is the caller graph for this function:

◆ is_multiple_full_instance()

bool Slic3r::GUI::Selection::is_multiple_full_instance ( ) const
inline
246{ return m_type == MultipleFullInstance; }

References m_type, and MultipleFullInstance.

Referenced by Slic3r::GUI::MenuFactory::append_menu_item_settings(), Slic3r::GUI::ObjectList::can_split_instances(), erase(), Slic3r::GUI::Plater::priv::on_right_click(), Slic3r::GUI::ObjectList::part_selection_changed(), and Slic3r::GUI::ObjectList::update_selections().

+ Here is the caller graph for this function:

◆ is_multiple_full_object()

bool Slic3r::GUI::Selection::is_multiple_full_object ( ) const
inline
248{ return m_type == MultipleFullObject; }

References m_type, and MultipleFullObject.

Referenced by erase(), Slic3r::GUI::ObjectList::part_selection_changed(), and Slic3r::GUI::ObjectList::update_selections().

+ Here is the caller graph for this function:

◆ is_multiple_modifier()

bool Slic3r::GUI::Selection::is_multiple_modifier ( ) const
inline
244{ return m_type == MultipleModifier; }

References m_type, and MultipleModifier.

Referenced by is_any_modifier().

+ Here is the caller graph for this function:

◆ is_multiple_volume()

bool Slic3r::GUI::Selection::is_multiple_volume ( ) const
inline
250{ return m_type == MultipleVolume; }

References m_type, and MultipleVolume.

Referenced by Slic3r::GUI::MenuFactory::append_menu_item_settings(), and is_any_volume().

+ Here is the caller graph for this function:

◆ is_single_full_instance()

bool Slic3r::GUI::Selection::is_single_full_instance ( ) const
536{
538 return true;
539
541 return get_instance_idx() != -1;
542
543 if (m_list.empty() || m_volumes->empty())
544 return false;
545
546 int object_idx = m_valid ? get_object_idx() : -1;
547 if (object_idx < 0 || (int)m_model->objects.size() <= object_idx)
548 return false;
549
550 int instance_idx = (*m_volumes)[*m_list.begin()]->instance_idx();
551
552 std::set<int> volumes_idxs;
553 for (unsigned int i : m_list) {
554 const GLVolume* v = (*m_volumes)[i];
555 if (object_idx != v->object_idx() || instance_idx != v->instance_idx())
556 return false;
557
558 int volume_idx = v->volume_idx();
559 if (volume_idx >= 0)
560 volumes_idxs.insert(volume_idx);
561 }
562
563 return m_model->objects[object_idx]->volumes.size() == volumes_idxs.size();
564}

References get_instance_idx(), get_object_idx(), Slic3r::GLVolume::instance_idx(), m_list, m_model, m_type, m_valid, m_volumes, Slic3r::GLVolume::object_idx(), Slic3r::Model::objects, SingleFullInstance, SingleFullObject, and Slic3r::GLVolume::volume_idx().

Referenced by Slic3r::GUI::ObjectManipulation::ObjectManipulation(), Slic3r::GUI::MenuFactory::append_menu_item_export_stl(), bake_transform_if_needed(), Slic3r::GUI::ObjectList::can_split_instances(), Slic3r::GUI::ObjectManipulation::change_rotation_value(), Slic3r::GUI::ObjectManipulation::change_scale_value(), Slic3r::GUI::ObjectManipulation::change_size_value(), Slic3r::GUI::GLGizmoFlatten::data_changed(), erase(), get_full_scaled_instance_bounding_box(), get_full_unscaled_instance_bounding_box(), get_full_unscaled_instance_local_bounding_box(), get_scaled_instance_bounding_box(), get_unscaled_instance_bounding_box(), Slic3r::GUI::ObjectList::is_instance_or_object_selected(), is_single_volume_instance(), Slic3r::GUI::GLGizmoCut3D::on_is_activable(), Slic3r::GUI::GLGizmoFlatten::on_is_activable(), Slic3r::GUI::GLGizmoHollow::on_is_activable(), Slic3r::GUI::GLGizmoMeasure::on_is_activable(), Slic3r::GUI::GLGizmoPainterBase::on_is_activable(), Slic3r::GUI::GLGizmoSlaSupports::on_is_activable(), Slic3r::GUI::GLGizmoFlatten::on_mouse(), Slic3r::GUI::GLGizmoFlatten::on_render(), Slic3r::GUI::Plater::priv::on_right_click(), Slic3r::GUI::CommonGizmosDataObjects::SelectionInfo::on_update(), Slic3r::GUI::ObjectList::part_selection_changed(), render_sidebar_hints(), scale_and_translate(), scale_to_fit_print_volume(), Slic3r::GUI::ObjectManipulation::Show(), Slic3r::GUI::Sidebar::show_info_sizer(), Slic3r::GUI::GLGizmoScale3D::update_render_data(), Slic3r::GUI::ObjectManipulation::update_reset_buttons_visibility(), Slic3r::GUI::ObjectList::update_selections(), and Slic3r::GUI::ObjectManipulation::update_settings_value().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ is_single_full_object()

◆ is_single_modifier()

bool Slic3r::GUI::Selection::is_single_modifier ( ) const
inline
243{ return m_type == SingleModifier; }

References m_type, and SingleModifier.

Referenced by Slic3r::GUI::MenuFactory::append_menu_item_export_stl(), Slic3r::GUI::SceneRaycaster::hit(), is_any_modifier(), is_single_volume_or_modifier(), and Slic3r::GUI::GLGizmoMeasure::on_is_activable().

+ Here is the caller graph for this function:

◆ is_single_text()

bool Slic3r::GUI::Selection::is_single_text ( ) const
586{
588 return false;
589
590 const GLVolume* gl_volume = (*m_volumes)[*m_list.begin()];
591 const ModelVolume* model_volume = m_model->objects[gl_volume->object_idx()]->volumes[gl_volume->volume_idx()];
592
593 return model_volume && model_volume->text_configuration.has_value();
594}

References is_single_volume_or_modifier(), m_list, m_model, Slic3r::GLVolume::object_idx(), Slic3r::Model::objects, Slic3r::ModelVolume::text_configuration, and Slic3r::GLVolume::volume_idx().

Referenced by Slic3r::GUI::Plater::priv::on_right_click().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ is_single_volume()

◆ is_single_volume_instance()

bool Slic3r::GUI::Selection::is_single_volume_instance ( ) const
inline
260{ return is_single_full_instance() && m_list.size() == 1; }

References is_single_full_instance(), and m_list.

Referenced by Slic3r::GUI::GLGizmoEmboss::on_render().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ is_single_volume_or_modifier()

◆ is_sla_compliant()

bool Slic3r::GUI::Selection::is_sla_compliant ( ) const
573{
574// if (m_mode == Volume)
575// return false;
576
577// for (unsigned int i : m_list) {
578// if ((*m_volumes)[i]->is_modifier)
579// return false;
580// }
581
582 return true;
583}

Referenced by Slic3r::GUI::Plater::can_copy_to_clipboard().

+ Here is the caller graph for this function:

◆ is_wipe_tower()

◆ matches()

bool Slic3r::GUI::Selection::matches ( const std::vector< unsigned int > &  volume_idxs) const
628{
629 unsigned int count = 0;
630
631 for (unsigned int i : volume_idxs) {
632 if (m_list.find(i) != m_list.end())
633 ++count;
634 else
635 return false;
636 }
637
638 return count == (unsigned int)m_list.size();
639}

References m_list.

Referenced by add_instance(), add_object(), add_volume(), and add_volumes().

+ Here is the caller graph for this function:

◆ mirror()

void Slic3r::GUI::Selection::mirror ( Axis  axis,
TransformationType  transformation_type 
)
1205{
1206 const Vec3d mirror((axis == X) ? -1.0 : 1.0, (axis == Y) ? -1.0 : 1.0, (axis == Z) ? -1.0 : 1.0);
1207 scale_and_translate(mirror, Vec3d::Zero(), transformation_type);
1208}
void mirror(Axis axis, TransformationType transformation_type)
Definition Selection.cpp:1204
void scale_and_translate(const Vec3d &scale, const Vec3d &world_translation, TransformationType transformation_type)
Definition Selection.cpp:1210
@ Y
Definition libslic3r.h:99
@ X
Definition libslic3r.h:98

References mirror(), scale_and_translate(), Slic3r::X, Slic3r::Y, and Slic3r::Z.

Referenced by Slic3r::GUI::ObjectManipulation::ObjectManipulation(), mirror(), and Slic3r::GUI::GLCanvas3D::mirror_selection().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ paste_from_clipboard()

void Slic3r::GUI::Selection::paste_from_clipboard ( )
1706{
1707 if (!m_valid || m_clipboard.is_empty())
1708 return;
1709
1710 switch (m_clipboard.get_mode())
1711 {
1712 case Volume:
1713 {
1716
1717 break;
1718 }
1719 case Instance:
1720 {
1721 if (m_mode == Instance)
1723
1724 break;
1725 }
1726 }
1727}
Selection::EMode get_mode() const
Definition Selection.hpp:127
bool is_empty() const
Definition Selection.cpp:82
void paste_volumes_from_clipboard()
Definition Selection.cpp:2816
void paste_objects_from_clipboard()
Definition Selection.cpp:2885
bool is_from_single_instance() const
Definition Selection.hpp:255

References Slic3r::GUI::Selection::Clipboard::get_mode(), Instance, Slic3r::GUI::Selection::Clipboard::is_empty(), is_from_single_instance(), m_clipboard, m_mode, m_valid, paste_objects_from_clipboard(), paste_volumes_from_clipboard(), and Volume.

+ Here is the call graph for this function:

◆ paste_objects_from_clipboard()

void Slic3r::GUI::Selection::paste_objects_from_clipboard ( )
private
2886{
2887#ifdef _DEBUG
2889#endif /* _DEBUG */
2890
2891 std::vector<size_t> object_idxs;
2892 const ModelObjectPtrs& src_objects = m_clipboard.get_objects();
2893 for (const ModelObject* src_object : src_objects)
2894 {
2895 ModelObject* dst_object = m_model->add_object(*src_object);
2896 double offset = wxGetApp().plater()->canvas3D()->get_size_proportional_to_max_bed_size(0.05);
2897 Vec3d displacement(offset, offset, 0.0);
2898 for (ModelInstance* inst : dst_object->instances)
2899 {
2900 inst->set_offset(inst->get_offset() + displacement);
2901 }
2902
2903 object_idxs.push_back(m_model->objects.size() - 1);
2904#ifdef _DEBUG
2906#endif /* _DEBUG */
2907 }
2908
2909 wxGetApp().obj_list()->paste_objects_into_list(object_idxs);
2910
2911#ifdef _DEBUG
2913#endif /* _DEBUG */
2914}
const ModelObjectPtrs & get_objects() const
Definition Selection.cpp:97
ModelObject * add_object()
Definition Model.cpp:189
void check_model_ids_validity(const Model &model)
Definition Model.cpp:2623
Slic3r::Polygons offset(const Slic3r::Polygon &polygon, const float delta, ClipperLib::JoinType joinType, double miterLimit)
Definition ClipperUtils.cpp:416
std::vector< ModelObject * > ModelObjectPtrs
Definition Model.hpp:105

References Slic3r::Model::add_object(), Slic3r::check_model_ids_validity(), Slic3r::GUI::Selection::Clipboard::get_objects(), Slic3r::ModelObject::instances, m_clipboard, m_model, Slic3r::Model::objects, and Slic3r::offset().

Referenced by paste_from_clipboard().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ paste_volumes_from_clipboard()

void Slic3r::GUI::Selection::paste_volumes_from_clipboard ( )
private
2817{
2818#ifdef _DEBUG
2820#endif /* _DEBUG */
2821
2822 int dst_obj_idx = get_object_idx();
2823 if ((dst_obj_idx < 0) || ((int)m_model->objects.size() <= dst_obj_idx))
2824 return;
2825
2826 ModelObject* dst_object = m_model->objects[dst_obj_idx];
2827
2828 int dst_inst_idx = get_instance_idx();
2829 if ((dst_inst_idx < 0) || ((int)dst_object->instances.size() <= dst_inst_idx))
2830 return;
2831
2832 ModelObject* src_object = m_clipboard.get_object(0);
2833 if (src_object != nullptr)
2834 {
2835 ModelInstance* dst_instance = dst_object->instances[dst_inst_idx];
2836 BoundingBoxf3 dst_instance_bb = dst_object->instance_bounding_box(dst_inst_idx);
2837 Transform3d src_matrix = src_object->instances[0]->get_transformation().get_matrix_no_offset();
2838 Transform3d dst_matrix = dst_instance->get_transformation().get_matrix_no_offset();
2839 bool from_same_object = (src_object->input_file == dst_object->input_file) && src_matrix.isApprox(dst_matrix);
2840
2841 // used to keep relative position of multivolume selections when pasting from another object
2842 BoundingBoxf3 total_bb;
2843
2844 ModelVolumePtrs volumes;
2845 for (ModelVolume* src_volume : src_object->volumes)
2846 {
2847 ModelVolume* dst_volume = dst_object->add_volume(*src_volume);
2848 dst_volume->set_new_unique_id();
2849 if (from_same_object)
2850 {
2851// // if the volume comes from the same object, apply the offset in world system
2852// double offset = wxGetApp().plater()->canvas3D()->get_size_proportional_to_max_bed_size(0.05);
2853// dst_volume->translate(dst_matrix.inverse() * Vec3d(offset, offset, 0.0));
2854 }
2855 else
2856 {
2857 // if the volume comes from another object, apply the offset as done when adding modifiers
2858 // see ObjectList::load_generic_subobject()
2859 total_bb.merge(dst_volume->mesh().bounding_box().transformed(src_volume->get_matrix()));
2860 }
2861
2862 volumes.push_back(dst_volume);
2863#ifdef _DEBUG
2865#endif /* _DEBUG */
2866 }
2867
2868 // keeps relative position of multivolume selections
2869 if (!from_same_object)
2870 {
2871 for (ModelVolume* v : volumes)
2872 {
2873 v->set_offset((v->get_offset() - total_bb.center()) + dst_matrix.inverse() * (Vec3d(dst_instance_bb.max(0), dst_instance_bb.min(1), dst_instance_bb.min(2)) + 0.5 * total_bb.size() - dst_instance->get_transformation().get_offset()));
2874 }
2875 }
2876
2877 wxGetApp().obj_list()->paste_volumes_into_list(dst_obj_idx, volumes);
2878 }
2879
2880#ifdef _DEBUG
2882#endif /* _DEBUG */
2883}
ModelObject * get_object(unsigned int id)
Definition Selection.cpp:92
ModelInstancePtrs instances
Definition Model.hpp:334
EIGEN_DEVICE_FUNC bool isApprox(const Transform &other, const typename NumTraits< Scalar >::Real &prec=NumTraits< Scalar >::dummy_precision()) const
Definition Transform.h:647

References Slic3r::ModelObject::add_volume(), Slic3r::TriangleMesh::bounding_box(), Slic3r::BoundingBox3Base< PointType >::center(), Slic3r::check_model_ids_validity(), get_instance_idx(), Slic3r::Geometry::Transformation::get_matrix_no_offset(), Slic3r::GUI::Selection::Clipboard::get_object(), get_object_idx(), Slic3r::Geometry::Transformation::get_offset(), Slic3r::ModelInstance::get_transformation(), Slic3r::ModelObject::input_file, Slic3r::ModelObject::instance_bounding_box(), Slic3r::ModelObject::instances, Eigen::Transform< _Scalar, _Dim, _Mode, _Options >::inverse(), Eigen::Transform< _Scalar, _Dim, _Mode, _Options >::isApprox(), m_clipboard, m_model, Slic3r::BoundingBoxBase< PointType, APointsType >::max, Slic3r::BoundingBox3Base< PointType >::merge(), Slic3r::ModelVolume::mesh(), Slic3r::BoundingBoxBase< PointType, APointsType >::min, Slic3r::Model::objects, Slic3r::ModelVolume::set_new_unique_id(), Slic3r::BoundingBox3Base< PointType >::size(), Slic3r::BoundingBoxf3::transformed(), and Slic3r::ModelObject::volumes.

Referenced by paste_from_clipboard().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ remove()

void Slic3r::GUI::Selection::remove ( unsigned int  volume_idx)
203{
204 if (!m_valid || (unsigned int)m_volumes->size() <= volume_idx)
205 return;
206
207 if (!contains_volume(volume_idx))
208 return;
209
210 wxGetApp().plater()->take_snapshot(_L("Selection-Remove"), UndoRedo::SnapshotType::Selection);
211
212 GLVolume* volume = (*m_volumes)[volume_idx];
213
214 switch (m_mode)
215 {
216 case Volume:
217 {
218 do_remove_volume(volume_idx);
219 break;
220 }
221 case Instance:
222 {
223 do_remove_instance(volume->object_idx(), volume->instance_idx());
224 break;
225 }
226 }
227
228 update_type();
230}
void do_remove_instance(unsigned int object_idx, unsigned int instance_idx)
Definition Selection.cpp:2062

References _L, contains_volume(), do_remove_instance(), do_remove_volume(), Instance, m_mode, m_valid, m_volumes, Slic3r::UndoRedo::Selection, set_bounding_boxes_dirty(), update_type(), and Volume.

Referenced by Slic3r::GUI::GLCanvas3D::on_mouse().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ remove_all()

void Slic3r::GUI::Selection::remove_all ( )
410{
411 if (!m_valid)
412 return;
413
414 if (is_empty())
415 return;
416
417// Not taking the snapshot with non-empty Redo stack will likely be more confusing than losing the Redo stack.
418// Let's wait for user feedback.
419// if (!wxGetApp().plater()->can_redo())
420 wxGetApp().plater()->take_snapshot(_L("Selection-Remove All"), UndoRedo::SnapshotType::Selection);
421
423 clear();
424}

References _L, clear(), Instance, is_empty(), m_mode, m_valid, and Slic3r::UndoRedo::Selection.

Referenced by Slic3r::GUI::GLCanvas3D::deselect_all(), and Slic3r::GUI::ObjectList::update_selections_on_canvas().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ remove_instance()

void Slic3r::GUI::Selection::remove_instance ( unsigned int  object_idx,
unsigned int  instance_idx 
)
294{
295 if (!m_valid)
296 return;
297
298 wxGetApp().plater()->take_snapshot(_L("Selection-Remove Instance"), UndoRedo::SnapshotType::Selection);
299
300 do_remove_instance(object_idx, instance_idx);
301
302 update_type();
304}

References _L, do_remove_instance(), m_valid, Slic3r::UndoRedo::Selection, set_bounding_boxes_dirty(), and update_type().

+ Here is the call graph for this function:

◆ remove_object()

void Slic3r::GUI::Selection::remove_object ( unsigned int  object_idx)
257{
258 if (!m_valid)
259 return;
260
261 wxGetApp().plater()->take_snapshot(_L("Selection-Remove Object"), UndoRedo::SnapshotType::Selection);
262
263 do_remove_object(object_idx);
264
265 update_type();
267}
void do_remove_object(unsigned int object_idx)
Definition Selection.cpp:2071

References _L, do_remove_object(), m_valid, Slic3r::UndoRedo::Selection, set_bounding_boxes_dirty(), and update_type().

+ Here is the call graph for this function:

◆ remove_volume()

void Slic3r::GUI::Selection::remove_volume ( unsigned int  object_idx,
unsigned int  volume_idx 
)
329{
330 if (!m_valid)
331 return;
332
333 for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) {
334 GLVolume* v = (*m_volumes)[i];
335 if (v->object_idx() == (int)object_idx && v->volume_idx() == (int)volume_idx)
337 }
338
339 update_type();
341}

References do_remove_volume(), m_valid, m_volumes, Slic3r::GLVolume::object_idx(), set_bounding_boxes_dirty(), update_type(), and Slic3r::GLVolume::volume_idx().

+ Here is the call graph for this function:

◆ remove_volumes()

void Slic3r::GUI::Selection::remove_volumes ( EMode  mode,
const std::vector< unsigned int > &  volume_idxs 
)
367{
368 if (!m_valid)
369 return;
370
371 m_mode = mode;
372 for (unsigned int i : volume_idxs) {
373 if (i < (unsigned int)m_volumes->size())
375 }
376
377 update_type();
379}

References do_remove_volume(), m_mode, m_valid, m_volumes, set_bounding_boxes_dirty(), and update_type().

Referenced by scale_to_fit_print_volume(), and Slic3r::GUI::ObjectList::update_selections_on_canvas().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ render()

void Slic3r::GUI::Selection::render ( float  scale_factor = 1.0)
1549{
1550 if (!m_valid || is_empty())
1551 return;
1552
1553 m_scale_factor = scale_factor;
1554 // render cumulative bounding box of selected volumes
1555 const auto& [box, trafo] = get_bounding_box_in_current_reference_system();
1556 render_bounding_box(box, trafo, ColorRGB::WHITE());
1558}
static const ColorRGB WHITE()
Definition Color.hpp:65
void render_bounding_box(const BoundingBoxf3 &box, const Transform3d &trafo, const ColorRGB &color)
Definition Selection.cpp:2118
void render_synchronized_volumes()
Definition Selection.cpp:2080

References get_bounding_box_in_current_reference_system(), is_empty(), m_scale_factor, m_valid, render_bounding_box(), render_synchronized_volumes(), and Slic3r::ColorRGB::WHITE().

+ Here is the call graph for this function:

◆ render_bounding_box() [1/2]

void Slic3r::GUI::Selection::render_bounding_box ( const BoundingBoxf3 box,
const Transform3d trafo,
const ColorRGB color 
)
private
2119{
2120 const BoundingBoxf3& curr_box = m_box.get_bounding_box();
2121
2122 if (!m_box.is_initialized() || !is_approx(box.min, curr_box.min) || !is_approx(box.max, curr_box.max)) {
2123 m_box.reset();
2124
2125 const Vec3f b_min = box.min.cast<float>();
2126 const Vec3f b_max = box.max.cast<float>();
2127 const Vec3f size = 0.2f * box.size().cast<float>();
2128
2129 GLModel::Geometry init_data;
2131 init_data.reserve_vertices(48);
2132 init_data.reserve_indices(48);
2133
2134 // vertices
2135 init_data.add_vertex(Vec3f(b_min.x(), b_min.y(), b_min.z()));
2136 init_data.add_vertex(Vec3f(b_min.x() + size.x(), b_min.y(), b_min.z()));
2137 init_data.add_vertex(Vec3f(b_min.x(), b_min.y(), b_min.z()));
2138 init_data.add_vertex(Vec3f(b_min.x(), b_min.y() + size.y(), b_min.z()));
2139 init_data.add_vertex(Vec3f(b_min.x(), b_min.y(), b_min.z()));
2140 init_data.add_vertex(Vec3f(b_min.x(), b_min.y(), b_min.z() + size.z()));
2141
2142 init_data.add_vertex(Vec3f(b_max.x(), b_min.y(), b_min.z()));
2143 init_data.add_vertex(Vec3f(b_max.x() - size.x(), b_min.y(), b_min.z()));
2144 init_data.add_vertex(Vec3f(b_max.x(), b_min.y(), b_min.z()));
2145 init_data.add_vertex(Vec3f(b_max.x(), b_min.y() + size.y(), b_min.z()));
2146 init_data.add_vertex(Vec3f(b_max.x(), b_min.y(), b_min.z()));
2147 init_data.add_vertex(Vec3f(b_max.x(), b_min.y(), b_min.z() + size.z()));
2148
2149 init_data.add_vertex(Vec3f(b_max.x(), b_max.y(), b_min.z()));
2150 init_data.add_vertex(Vec3f(b_max.x() - size.x(), b_max.y(), b_min.z()));
2151 init_data.add_vertex(Vec3f(b_max.x(), b_max.y(), b_min.z()));
2152 init_data.add_vertex(Vec3f(b_max.x(), b_max.y() - size.y(), b_min.z()));
2153 init_data.add_vertex(Vec3f(b_max.x(), b_max.y(), b_min.z()));
2154 init_data.add_vertex(Vec3f(b_max.x(), b_max.y(), b_min.z() + size.z()));
2155
2156 init_data.add_vertex(Vec3f(b_min.x(), b_max.y(), b_min.z()));
2157 init_data.add_vertex(Vec3f(b_min.x() + size.x(), b_max.y(), b_min.z()));
2158 init_data.add_vertex(Vec3f(b_min.x(), b_max.y(), b_min.z()));
2159 init_data.add_vertex(Vec3f(b_min.x(), b_max.y() - size.y(), b_min.z()));
2160 init_data.add_vertex(Vec3f(b_min.x(), b_max.y(), b_min.z()));
2161 init_data.add_vertex(Vec3f(b_min.x(), b_max.y(), b_min.z() + size.z()));
2162
2163 init_data.add_vertex(Vec3f(b_min.x(), b_min.y(), b_max.z()));
2164 init_data.add_vertex(Vec3f(b_min.x() + size.x(), b_min.y(), b_max.z()));
2165 init_data.add_vertex(Vec3f(b_min.x(), b_min.y(), b_max.z()));
2166 init_data.add_vertex(Vec3f(b_min.x(), b_min.y() + size.y(), b_max.z()));
2167 init_data.add_vertex(Vec3f(b_min.x(), b_min.y(), b_max.z()));
2168 init_data.add_vertex(Vec3f(b_min.x(), b_min.y(), b_max.z() - size.z()));
2169
2170 init_data.add_vertex(Vec3f(b_max.x(), b_min.y(), b_max.z()));
2171 init_data.add_vertex(Vec3f(b_max.x() - size.x(), b_min.y(), b_max.z()));
2172 init_data.add_vertex(Vec3f(b_max.x(), b_min.y(), b_max.z()));
2173 init_data.add_vertex(Vec3f(b_max.x(), b_min.y() + size.y(), b_max.z()));
2174 init_data.add_vertex(Vec3f(b_max.x(), b_min.y(), b_max.z()));
2175 init_data.add_vertex(Vec3f(b_max.x(), b_min.y(), b_max.z() - size.z()));
2176
2177 init_data.add_vertex(Vec3f(b_max.x(), b_max.y(), b_max.z()));
2178 init_data.add_vertex(Vec3f(b_max.x() - size.x(), b_max.y(), b_max.z()));
2179 init_data.add_vertex(Vec3f(b_max.x(), b_max.y(), b_max.z()));
2180 init_data.add_vertex(Vec3f(b_max.x(), b_max.y() - size.y(), b_max.z()));
2181 init_data.add_vertex(Vec3f(b_max.x(), b_max.y(), b_max.z()));
2182 init_data.add_vertex(Vec3f(b_max.x(), b_max.y(), b_max.z() - size.z()));
2183
2184 init_data.add_vertex(Vec3f(b_min.x(), b_max.y(), b_max.z()));
2185 init_data.add_vertex(Vec3f(b_min.x() + size.x(), b_max.y(), b_max.z()));
2186 init_data.add_vertex(Vec3f(b_min.x(), b_max.y(), b_max.z()));
2187 init_data.add_vertex(Vec3f(b_min.x(), b_max.y() - size.y(), b_max.z()));
2188 init_data.add_vertex(Vec3f(b_min.x(), b_max.y(), b_max.z()));
2189 init_data.add_vertex(Vec3f(b_min.x(), b_max.y(), b_max.z() - size.z()));
2190
2191 // indices
2192 for (unsigned int i = 0; i < 48; ++i) {
2193 init_data.add_index(i);
2194 }
2195
2196 m_box.init_from(std::move(init_data));
2197 }
2198
2199 glsafe(::glEnable(GL_DEPTH_TEST));
2200
2201#if ENABLE_GL_CORE_PROFILE
2202 if (!OpenGLManager::get_gl_info().is_core_profile())
2203 glsafe(::glLineWidth(2.0f * m_scale_factor));
2204
2205 GLShaderProgram* shader = OpenGLManager::get_gl_info().is_core_profile() ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat");
2206#else
2207 glsafe(::glLineWidth(2.0f * m_scale_factor));
2208 GLShaderProgram* shader = wxGetApp().get_shader("flat");
2209#endif // ENABLE_GL_CORE_PROFILE
2210 if (shader == nullptr)
2211 return;
2212
2213 shader->start_using();
2214 const Camera& camera = wxGetApp().plater()->get_camera();
2215 shader->set_uniform("view_model_matrix", camera.get_view_matrix() * trafo);
2216 shader->set_uniform("projection_matrix", camera.get_projection_matrix());
2217#if ENABLE_GL_CORE_PROFILE
2218 const std::array<int, 4>& viewport = camera.get_viewport();
2219 shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3])));
2220 shader->set_uniform("width", 1.5f);
2221 shader->set_uniform("gap_size", 0.0f);
2222#endif // ENABLE_GL_CORE_PROFILE
2223 m_box.set_color(to_rgba(color));
2224 m_box.render();
2225 shader->stop_using();
2226}
#define glsafe(cmd)
Definition 3DScene.hpp:25
const BoundingBoxf3 & get_bounding_box() const
Definition GLModel.hpp:245
void reset()
Definition GLModel.cpp:697
void render()
Definition GLModel.cpp:755
bool is_initialized() const
Definition GLModel.hpp:242
void set_color(const ColorRGBA &color)
Definition GLModel.hpp:234
bool is_core_profile() const
Definition OpenGLManager.hpp:52
static const GLInfo & get_gl_info()
Definition OpenGLManager.hpp:141
GLModel m_box
Definition Selection.hpp:187
ColorRGBA to_rgba(const ColorRGB &other_rgb)
Definition Color.cpp:379
Eigen::Matrix< float, 3, 1, Eigen::DontAlign > Vec3f
Definition Point.hpp:49
constexpr auto size(const C &c) -> decltype(c.size())
Definition span.hpp:183

References Slic3r::GUI::GLModel::Geometry::format, Slic3r::GUI::GLModel::get_bounding_box(), Slic3r::GUI::OpenGLManager::get_gl_info(), Slic3r::GUI::Camera::get_projection_matrix(), Slic3r::GUI::Camera::get_view_matrix(), Slic3r::GUI::Camera::get_viewport(), glsafe, Slic3r::GUI::GLModel::init_from(), Slic3r::is_approx(), Slic3r::GUI::OpenGLManager::GLInfo::is_core_profile(), Slic3r::GUI::GLModel::is_initialized(), Slic3r::GUI::GLModel::Geometry::Lines, m_box, m_scale_factor, Slic3r::BoundingBoxBase< PointType, APointsType >::max, Slic3r::BoundingBoxBase< PointType, APointsType >::min, Slic3r::GUI::GLModel::Geometry::P3, Slic3r::GUI::GLModel::render(), Slic3r::GUI::GLModel::reset(), Slic3r::GUI::GLModel::set_color(), Slic3r::GLShaderProgram::set_uniform(), Slic3r::BoundingBox3Base< PointType >::size(), Slic3r::GLShaderProgram::start_using(), Slic3r::GLShaderProgram::stop_using(), and Slic3r::to_rgba().

Referenced by render(), and render_synchronized_volumes().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ render_bounding_box() [2/2]

void Slic3r::GUI::Selection::render_bounding_box ( const BoundingBoxf3 box,
float *  color 
) const
private

◆ render_selected_volumes()

void Slic3r::GUI::Selection::render_selected_volumes ( ) const
private

◆ render_sidebar_hints()

void Slic3r::GUI::Selection::render_sidebar_hints ( const std::string &  sidebar_field)
1590{
1591 if (sidebar_field.empty())
1592 return;
1593
1594 GLShaderProgram* shader = wxGetApp().get_shader(boost::starts_with(sidebar_field, "layer") ? "flat" : "gouraud_light");
1595 if (shader == nullptr)
1596 return;
1597
1598 shader->start_using();
1599
1600 glsafe(::glEnable(GL_DEPTH_TEST));
1601 glsafe(::glDisable(GL_CULL_FACE));
1602
1603 const Transform3d base_matrix = Geometry::translation_transform(get_bounding_box().center());
1604 Transform3d orient_matrix = Transform3d::Identity();
1605
1606 const Vec3d center = get_bounding_box().center();
1607 Vec3d axes_center = center;
1608
1609 if (!boost::starts_with(sidebar_field, "layer")) {
1610 shader->set_uniform("emission_factor", 0.05f);
1611 if (is_single_full_instance() && !wxGetApp().obj_manipul()->is_world_coordinates()) {
1612 orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation_matrix();
1613 axes_center = (*m_volumes)[*m_list.begin()]->get_instance_offset();
1614 }
1615 else if (is_single_volume_or_modifier()) {
1616 if (!wxGetApp().obj_manipul()->is_world_coordinates()) {
1617 if (wxGetApp().obj_manipul()->is_local_coordinates()) {
1618 orient_matrix = get_bounding_box_in_current_reference_system().second;
1619 orient_matrix.translation() = Vec3d::Zero();
1620 }
1621 else {
1622 orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation_matrix();
1623 axes_center = (*m_volumes)[*m_list.begin()]->get_instance_offset();
1624 }
1625 }
1626 }
1627 else {
1628 if (requires_local_axes())
1629 orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation_matrix();
1630 }
1631 }
1632
1633 if (!boost::starts_with(sidebar_field, "layer"))
1634 glsafe(::glClear(GL_DEPTH_BUFFER_BIT));
1635
1636 if (!boost::starts_with(sidebar_field, "layer"))
1637 shader->set_uniform("emission_factor", 0.1f);
1638
1639 if (boost::starts_with(sidebar_field, "position"))
1640 render_sidebar_position_hints(sidebar_field, *shader, base_matrix * orient_matrix);
1641 else if (boost::starts_with(sidebar_field, "rotation"))
1642 render_sidebar_rotation_hints(sidebar_field, *shader, base_matrix * orient_matrix);
1643 else if (boost::starts_with(sidebar_field, "scale") || boost::starts_with(sidebar_field, "size"))
1644 render_sidebar_scale_hints(sidebar_field, *shader, base_matrix * orient_matrix);
1645 else if (boost::starts_with(sidebar_field, "layer"))
1646 render_sidebar_layers_hints(sidebar_field, *shader);
1647
1648 if (!boost::starts_with(sidebar_field, "layer")) {
1649 if (wxGetApp().obj_manipul()->is_instance_coordinates())
1650 m_axes.render(Geometry::translation_transform(axes_center) * orient_matrix, 0.25f);
1651 }
1652
1653 glsafe(::glEnable(GL_CULL_FACE));
1654 shader->stop_using();
1655}
PointType center() const
Definition BoundingBox.cpp:203
void render(const Transform3d &trafo, float emission_factor=0.0f)
Definition CoordAxes.cpp:19
void render_sidebar_scale_hints(const std::string &sidebar_field, GLShaderProgram &shader, const Transform3d &matrix)
Definition Selection.cpp:2295
bool requires_local_axes() const
Definition Selection.cpp:1657
void render_sidebar_rotation_hints(const std::string &sidebar_field, GLShaderProgram &shader, const Transform3d &matrix)
Definition Selection.cpp:2263
void render_sidebar_position_hints(const std::string &sidebar_field, GLShaderProgram &shader, const Transform3d &matrix)
Definition Selection.cpp:2233
const BoundingBoxf3 & get_bounding_box() const
Definition Selection.cpp:673
void render_sidebar_layers_hints(const std::string &sidebar_field, GLShaderProgram &shader)
Definition Selection.cpp:2328
void translation_transform(Transform3d &transform, const Vec3d &translation)
Definition Geometry.cpp:328

References Slic3r::BoundingBox3Base< PointType >::center(), get_bounding_box(), get_bounding_box_in_current_reference_system(), glsafe, Eigen::Transform< double, 3, Eigen::Affine, Eigen::DontAlign >::Identity(), is_single_full_instance(), is_single_volume_or_modifier(), m_axes, m_list, Slic3r::GUI::CoordAxes::render(), render_sidebar_layers_hints(), render_sidebar_position_hints(), render_sidebar_rotation_hints(), render_sidebar_scale_hints(), requires_local_axes(), Slic3r::GLShaderProgram::set_uniform(), Slic3r::GLShaderProgram::start_using(), Slic3r::GLShaderProgram::stop_using(), Eigen::Transform< _Scalar, _Dim, _Mode, _Options >::translation(), and Slic3r::Geometry::translation_transform().

+ Here is the call graph for this function:

◆ render_sidebar_layers_hints()

void Slic3r::GUI::Selection::render_sidebar_layers_hints ( const std::string &  sidebar_field,
GLShaderProgram shader 
)
private
2329{
2330 static const float Margin = 10.0f;
2331
2332 std::string field = sidebar_field;
2333
2334 // extract max_z
2335 std::string::size_type pos = field.rfind("_");
2336 if (pos == std::string::npos)
2337 return;
2338
2339 const float max_z = float(string_to_double_decimal_point(field.substr(pos + 1)));
2340
2341 // extract min_z
2342 field = field.substr(0, pos);
2343 pos = field.rfind("_");
2344 if (pos == std::string::npos)
2345 return;
2346
2347 const float min_z = float(string_to_double_decimal_point(field.substr(pos + 1)));
2348
2349 // extract type
2350 field = field.substr(0, pos);
2351 pos = field.rfind("_");
2352 if (pos == std::string::npos)
2353 return;
2354
2355 const int type = std::stoi(field.substr(pos + 1));
2356
2357 const BoundingBoxf3& box = get_bounding_box();
2358
2359 // view dependend order of rendering to keep correct transparency
2360 const bool camera_on_top = wxGetApp().plater()->get_camera().is_looking_downward();
2361 const float z1 = camera_on_top ? min_z : max_z;
2362 const float z2 = camera_on_top ? max_z : min_z;
2363
2364 const Vec3f p1 = { float(box.min.x()) - Margin, float(box.min.y()) - Margin, z1 };
2365 const Vec3f p2 = { float(box.max.x()) + Margin, float(box.max.y()) + Margin, z2 };
2366
2367 glsafe(::glEnable(GL_DEPTH_TEST));
2368 glsafe(::glDisable(GL_CULL_FACE));
2369 glsafe(::glEnable(GL_BLEND));
2370 glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
2371
2372 if (!m_planes.models[0].is_initialized() || !is_approx(m_planes.check_points[0], p1)) {
2373 m_planes.check_points[0] = p1;
2374 m_planes.models[0].reset();
2375
2376 GLModel::Geometry init_data;
2378 init_data.reserve_vertices(4);
2379 init_data.reserve_indices(6);
2380
2381 // vertices
2382 init_data.add_vertex(Vec3f(p1.x(), p1.y(), z1));
2383 init_data.add_vertex(Vec3f(p2.x(), p1.y(), z1));
2384 init_data.add_vertex(Vec3f(p2.x(), p2.y(), z1));
2385 init_data.add_vertex(Vec3f(p1.x(), p2.y(), z1));
2386
2387 // indices
2388 init_data.add_triangle(0, 1, 2);
2389 init_data.add_triangle(2, 3, 0);
2390
2391 m_planes.models[0].init_from(std::move(init_data));
2392 }
2393
2394 if (!m_planes.models[1].is_initialized() || !is_approx(m_planes.check_points[1], p2)) {
2395 m_planes.check_points[1] = p2;
2396 m_planes.models[1].reset();
2397
2398 GLModel::Geometry init_data;
2400 init_data.reserve_vertices(4);
2401 init_data.reserve_indices(6);
2402
2403 // vertices
2404 init_data.add_vertex(Vec3f(p1.x(), p1.y(), z2));
2405 init_data.add_vertex(Vec3f(p2.x(), p1.y(), z2));
2406 init_data.add_vertex(Vec3f(p2.x(), p2.y(), z2));
2407 init_data.add_vertex(Vec3f(p1.x(), p2.y(), z2));
2408
2409 // indices
2410 init_data.add_triangle(0, 1, 2);
2411 init_data.add_triangle(2, 3, 0);
2412
2413 m_planes.models[1].init_from(std::move(init_data));
2414 }
2415
2416 const Camera& camera = wxGetApp().plater()->get_camera();
2417 shader.set_uniform("view_model_matrix", camera.get_view_matrix());
2418 shader.set_uniform("projection_matrix", camera.get_projection_matrix());
2419
2420 m_planes.models[0].set_color((camera_on_top && type == 1) || (!camera_on_top && type == 2) ? SOLID_PLANE_COLOR : TRANSPARENT_PLANE_COLOR);
2421 m_planes.models[0].render();
2422 m_planes.models[1].set_color((camera_on_top && type == 2) || (!camera_on_top && type == 1) ? SOLID_PLANE_COLOR : TRANSPARENT_PLANE_COLOR);
2423 m_planes.models[1].render();
2424
2425 glsafe(::glEnable(GL_CULL_FACE));
2426 glsafe(::glDisable(GL_BLEND));
2427}
static const Slic3r::ColorRGBA TRANSPARENT_PLANE_COLOR
Definition Selection.cpp:30
static const Slic3r::ColorRGBA SOLID_PLANE_COLOR
Definition Selection.cpp:29
std::array< GLModel, 2 > models
Definition Selection.hpp:191
std::array< Vec3f, 2 > check_points
Definition Selection.hpp:190
Planes m_planes
Definition Selection.hpp:193
Vec3d pos(const Pt &p)
Definition ReprojectPointsOnMesh.hpp:14
double string_to_double_decimal_point(const std::string_view str, size_t *pos)
Definition LocalesUtils.cpp:64

References Slic3r::GUI::GLModel::Geometry::add_triangle(), Slic3r::GUI::GLModel::Geometry::add_vertex(), Slic3r::GUI::Selection::Planes::check_points, Slic3r::GUI::GLModel::Geometry::format, get_bounding_box(), Slic3r::GUI::Camera::get_projection_matrix(), Slic3r::GUI::Camera::get_view_matrix(), glsafe, Slic3r::is_approx(), m_planes, Slic3r::BoundingBoxBase< PointType, APointsType >::max, Slic3r::BoundingBoxBase< PointType, APointsType >::min, Slic3r::GUI::Selection::Planes::models, Slic3r::GUI::GLModel::Geometry::P3, Slic3r::GUI::GLModel::Geometry::reserve_indices(), Slic3r::GUI::GLModel::Geometry::reserve_vertices(), Slic3r::GLShaderProgram::set_uniform(), SOLID_PLANE_COLOR, Slic3r::string_to_double_decimal_point(), TRANSPARENT_PLANE_COLOR, and Slic3r::GUI::GLModel::Geometry::Triangles.

Referenced by render_sidebar_hints().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ render_sidebar_position_hints()

void Slic3r::GUI::Selection::render_sidebar_position_hints ( const std::string &  sidebar_field,
GLShaderProgram shader,
const Transform3d matrix 
)
private
2234{
2235 const Camera& camera = wxGetApp().plater()->get_camera();
2236 const Transform3d& view_matrix = camera.get_view_matrix();
2237 shader.set_uniform("projection_matrix", camera.get_projection_matrix());
2238
2239 if (boost::ends_with(sidebar_field, "x")) {
2240 const Transform3d model_matrix = matrix * Geometry::rotation_transform(-0.5 * PI * Vec3d::UnitZ());
2241 shader.set_uniform("view_model_matrix", view_matrix * model_matrix);
2242 const Matrix3d view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose();
2243 shader.set_uniform("view_normal_matrix", view_normal_matrix);
2245 m_arrow.render();
2246 }
2247 else if (boost::ends_with(sidebar_field, "y")) {
2248 shader.set_uniform("view_model_matrix", view_matrix * matrix);
2249 shader.set_uniform("view_normal_matrix", (Matrix3d)Matrix3d::Identity());
2251 m_arrow.render();
2252 }
2253 else if (boost::ends_with(sidebar_field, "z")) {
2254 const Transform3d model_matrix = matrix * Geometry::rotation_transform(0.5 * PI * Vec3d::UnitX());
2255 shader.set_uniform("view_model_matrix", view_matrix * model_matrix);
2256 const Matrix3d view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose();
2257 shader.set_uniform("view_normal_matrix", view_normal_matrix);
2259 m_arrow.render();
2260 }
2261}
static std::string get_color(wxColour colour)
Definition ConfigSnapshotDialog.cpp:34
void rotation_transform(Transform3d &transform, const Vec3d &rotation)
Definition Geometry.cpp:341
Eigen::Matrix< double, 3, 3, Eigen::DontAlign > Matrix3d
Definition Point.hpp:71

References Slic3r::GUI::get_color(), Slic3r::GUI::Camera::get_projection_matrix(), Slic3r::GUI::Camera::get_view_matrix(), m_arrow, Eigen::Transform< _Scalar, _Dim, _Mode, _Options >::matrix(), PI, Slic3r::GUI::GLModel::render(), Slic3r::Geometry::rotation_transform(), Slic3r::GUI::GLModel::set_color(), Slic3r::GLShaderProgram::set_uniform(), Slic3r::X, Slic3r::Y, and Slic3r::Z.

Referenced by render_sidebar_hints().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ render_sidebar_rotation_hints()

void Slic3r::GUI::Selection::render_sidebar_rotation_hints ( const std::string &  sidebar_field,
GLShaderProgram shader,
const Transform3d matrix 
)
private
2264{
2265 auto render_sidebar_rotation_hint = [this](GLShaderProgram& shader, const Transform3d& view_matrix, const Transform3d& model_matrix) {
2266 shader.set_uniform("view_model_matrix", view_matrix * model_matrix);
2267 Matrix3d view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose();
2268 shader.set_uniform("view_normal_matrix", view_normal_matrix);
2270 const Transform3d matrix = model_matrix * Geometry::rotation_transform(PI * Vec3d::UnitZ());
2271 shader.set_uniform("view_model_matrix", view_matrix * matrix);
2272 view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * matrix.matrix().block(0, 0, 3, 3).inverse().transpose();
2273 shader.set_uniform("view_normal_matrix", view_normal_matrix);
2275 };
2276
2277 const Camera& camera = wxGetApp().plater()->get_camera();
2278 const Transform3d& view_matrix = camera.get_view_matrix();
2279 shader.set_uniform("projection_matrix", camera.get_projection_matrix());
2280
2281 if (boost::ends_with(sidebar_field, "x")) {
2283 render_sidebar_rotation_hint(shader, view_matrix, matrix * Geometry::rotation_transform(0.5 * PI * Vec3d::UnitY()));
2284 }
2285 else if (boost::ends_with(sidebar_field, "y")) {
2287 render_sidebar_rotation_hint(shader, view_matrix, matrix * Geometry::rotation_transform(-0.5 * PI * Vec3d::UnitX()));
2288 }
2289 else if (boost::ends_with(sidebar_field, "z")) {
2291 render_sidebar_rotation_hint(shader, view_matrix, matrix);
2292 }
2293}

References Slic3r::GUI::get_color(), Slic3r::GUI::Camera::get_projection_matrix(), Slic3r::GUI::Camera::get_view_matrix(), m_curved_arrow, Eigen::Transform< _Scalar, _Dim, _Mode, _Options >::matrix(), PI, Slic3r::GUI::GLModel::render(), Slic3r::Geometry::rotation_transform(), Slic3r::GUI::GLModel::set_color(), Slic3r::GLShaderProgram::set_uniform(), Slic3r::X, Slic3r::Y, and Slic3r::Z.

Referenced by render_sidebar_hints().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ render_sidebar_scale_hints()

void Slic3r::GUI::Selection::render_sidebar_scale_hints ( const std::string &  sidebar_field,
GLShaderProgram shader,
const Transform3d matrix 
)
private
2296{
2297 const bool uniform_scale = wxGetApp().obj_manipul()->get_uniform_scaling();
2298
2299 auto render_sidebar_scale_hint = [this, uniform_scale](Axis axis, GLShaderProgram& shader, const Transform3d& view_matrix, const Transform3d& model_matrix) {
2300 m_arrow.set_color(uniform_scale ? UNIFORM_SCALE_COLOR : get_color(axis));
2301 Transform3d matrix = model_matrix * Geometry::translation_transform(5.0 * Vec3d::UnitY());
2302 shader.set_uniform("view_model_matrix", view_matrix * matrix);
2303 Matrix3d view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * matrix.matrix().block(0, 0, 3, 3).inverse().transpose();
2304 shader.set_uniform("view_normal_matrix", view_normal_matrix);
2305 m_arrow.render();
2306
2307 matrix = model_matrix * Geometry::translation_transform(-5.0 * Vec3d::UnitY()) * Geometry::rotation_transform(PI * Vec3d::UnitZ());
2308 shader.set_uniform("view_model_matrix", view_matrix * matrix);
2309 view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * matrix.matrix().block(0, 0, 3, 3).inverse().transpose();
2310 shader.set_uniform("view_normal_matrix", view_normal_matrix);
2311 m_arrow.render();
2312 };
2313
2314 const Camera& camera = wxGetApp().plater()->get_camera();
2315 const Transform3d& view_matrix = camera.get_view_matrix();
2316 shader.set_uniform("projection_matrix", camera.get_projection_matrix());
2317
2318 if (boost::ends_with(sidebar_field, "x") || uniform_scale)
2319 render_sidebar_scale_hint(X, shader, view_matrix, matrix * Geometry::rotation_transform(-0.5 * PI * Vec3d::UnitZ()));
2320
2321 if (boost::ends_with(sidebar_field, "y") || uniform_scale)
2322 render_sidebar_scale_hint(Y, shader, view_matrix, matrix);
2323
2324 if (boost::ends_with(sidebar_field, "z") || uniform_scale)
2325 render_sidebar_scale_hint(Z, shader, view_matrix, matrix * Geometry::rotation_transform(0.5 * PI * Vec3d::UnitX()));
2326}
static const Slic3r::ColorRGBA UNIFORM_SCALE_COLOR
Definition Selection.cpp:28
Axis
Definition libslic3r.h:97

References Slic3r::GUI::get_color(), Slic3r::GUI::Camera::get_projection_matrix(), Slic3r::GUI::Camera::get_view_matrix(), m_arrow, Eigen::Transform< _Scalar, _Dim, _Mode, _Options >::matrix(), PI, Slic3r::GUI::GLModel::render(), Slic3r::Geometry::rotation_transform(), Slic3r::GUI::GLModel::set_color(), Slic3r::GLShaderProgram::set_uniform(), Slic3r::Geometry::translation_transform(), UNIFORM_SCALE_COLOR, Slic3r::X, Slic3r::Y, and Slic3r::Z.

Referenced by render_sidebar_hints().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ render_synchronized_volumes()

void Slic3r::GUI::Selection::render_synchronized_volumes ( )
private
2081{
2082 if (m_mode == Instance)
2083 return;
2084
2085 const ECoordinatesType coordinates_type = wxGetApp().obj_manipul()->get_coordinates_type();
2086 BoundingBoxf3 box;
2087 Transform3d trafo;
2088
2089 for (unsigned int i : m_list) {
2090 const GLVolume& volume = *(*m_volumes)[i];
2091 int object_idx = volume.object_idx();
2092 int volume_idx = volume.volume_idx();
2093 for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j) {
2094 if (i == j)
2095 continue;
2096
2097 const GLVolume& v = *(*m_volumes)[j];
2098 if (v.object_idx() != object_idx || v.volume_idx() != volume_idx)
2099 continue;
2100
2101 if (coordinates_type == ECoordinatesType::World) {
2102 box = v.transformed_convex_hull_bounding_box();
2103 trafo = Transform3d::Identity();
2104 }
2105 else if (coordinates_type == ECoordinatesType::Local) {
2106 box = v.bounding_box();
2107 trafo = v.world_matrix();
2108 }
2109 else {
2110 box = v.transformed_convex_hull_bounding_box(v.get_volume_transformation().get_matrix());
2111 trafo = v.get_instance_transformation().get_matrix();
2112 }
2114 }
2115 }
2116}
static const ColorRGB YELLOW()
Definition Color.hpp:64

References Slic3r::GLVolume::bounding_box(), Slic3r::GLVolume::get_instance_transformation(), Slic3r::Geometry::Transformation::get_matrix(), Slic3r::GLVolume::get_volume_transformation(), Eigen::Transform< double, 3, Eigen::Affine, Eigen::DontAlign >::Identity(), Instance, Slic3r::GUI::Local, m_list, m_mode, m_volumes, Slic3r::GLVolume::object_idx(), render_bounding_box(), Slic3r::GLVolume::transformed_convex_hull_bounding_box(), Slic3r::GLVolume::volume_idx(), Slic3r::GUI::World, Slic3r::GLVolume::world_matrix(), and Slic3r::ColorRGB::YELLOW().

Referenced by render().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ requires_local_axes()

bool Slic3r::GUI::Selection::requires_local_axes ( ) const
1658{
1659 return m_mode == Volume && is_from_single_instance();
1660}

References is_from_single_instance(), m_mode, and Volume.

Referenced by render_sidebar_hints().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ reset_skew()

void Slic3r::GUI::Selection::reset_skew ( )
1285{
1286 if (!m_valid)
1287 return;
1288
1289 for (unsigned int i : m_list) {
1290 GLVolume& v = *(*m_volumes)[i];
1291 const VolumeCache& volume_data = m_cache.volumes_data[i];
1292 Geometry::Transformation inst_trafo = volume_data.get_instance_transform();
1293 Geometry::Transformation vol_trafo = volume_data.get_volume_transform();
1294 Geometry::Transformation world_trafo = inst_trafo * vol_trafo;
1295 if (world_trafo.has_skew()) {
1296 if (!inst_trafo.has_skew() && !vol_trafo.has_skew()) {
1297 // <W> = [I][V]
1298 world_trafo.reset_offset();
1299 world_trafo.reset_skew();
1300 v.set_volume_transformation(vol_trafo.get_offset_matrix() * inst_trafo.get_matrix_no_offset().inverse() * world_trafo.get_matrix());
1301 }
1302 else {
1303 // <W> = <I><V>
1304 // <W> = <I>[V]
1305 // <W> = [I]<V>
1306 if (inst_trafo.has_skew()) {
1307 inst_trafo.reset_skew();
1308 v.set_instance_transformation(inst_trafo);
1309 }
1310 if (vol_trafo.has_skew()) {
1311 vol_trafo.reset_skew();
1312 v.set_volume_transformation(vol_trafo);
1313 }
1314 }
1315 }
1316 else {
1317 // [W] = [I][V]
1318 // [W] = <I><V>
1319 if (inst_trafo.has_skew()) {
1320 inst_trafo.reset_skew();
1321 v.set_instance_transformation(inst_trafo);
1322 }
1323 if (vol_trafo.has_skew()) {
1324 vol_trafo.reset_skew();
1325 v.set_volume_transformation(vol_trafo);
1326 }
1327 }
1328 }
1329
1330#if !DISABLE_INSTANCES_SYNCH
1331 if (m_mode == Instance)
1332 // even if there is no rotation, we pass SyncRotationType::GENERAL to force
1333 // synchronize_unselected_instances() to remove skew from the other instances
1335 else if (m_mode == Volume)
1337#endif // !DISABLE_INSTANCES_SYNCH
1338
1339 ensure_on_bed();
1341 wxGetApp().plater()->canvas3D()->requires_check_outside_state();
1342}
void synchronize_unselected_volumes()
Definition Selection.cpp:2697
void ensure_on_bed()
Definition Selection.cpp:2722
VolumesCache volumes_data
Definition Selection.hpp:135

References ensure_on_bed(), GENERAL, Slic3r::GUI::Selection::VolumeCache::get_instance_transform(), Slic3r::Geometry::Transformation::get_matrix(), Slic3r::Geometry::Transformation::get_matrix_no_offset(), Slic3r::Geometry::Transformation::get_offset_matrix(), Slic3r::GUI::Selection::VolumeCache::get_volume_transform(), Slic3r::Geometry::Transformation::has_skew(), Instance, Eigen::Transform< _Scalar, _Dim, _Mode, _Options >::inverse(), m_cache, m_list, m_mode, m_valid, Slic3r::Geometry::Transformation::reset_offset(), Slic3r::Geometry::Transformation::reset_skew(), set_bounding_boxes_dirty(), Slic3r::GLVolume::set_instance_transformation(), Slic3r::GLVolume::set_volume_transformation(), synchronize_unselected_instances(), synchronize_unselected_volumes(), Volume, and Slic3r::GUI::Selection::Cache::volumes_data.

Referenced by Slic3r::GUI::ObjectManipulation::ObjectManipulation().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ rotate()

void Slic3r::GUI::Selection::rotate ( const Vec3d rotation,
TransformationType  transformation_type 
)
957{
958 if (!m_valid)
959 return;
960
961 assert(transformation_type.relative() || (transformation_type.absolute() && transformation_type.local()));
962
963 for (unsigned int i : m_list) {
964 Transform3d rotation_matrix = Geometry::rotation_transform(rotation);
965 GLVolume& v = *(*m_volumes)[i];
966 const VolumeCache& volume_data = m_cache.volumes_data[i];
967 const Geometry::Transformation& inst_trafo = volume_data.get_instance_transform();
968 if (m_mode == Instance && !is_wipe_tower()) {
970 if (transformation_type.instance()) {
971 // ensure that the instance rotates as a rigid body
972 Transform3d inst_rotation_matrix = inst_trafo.get_rotation_matrix();
973 if (inst_trafo.is_left_handed()) {
974 Geometry::TransformationSVD inst_svd(inst_trafo);
975 inst_rotation_matrix = inst_svd.u * inst_svd.v.transpose();
976 // ensure the rotation has the proper direction
977 if (!rotation.normalized().cwiseAbs().isApprox(Vec3d::UnitX()))
978 rotation_matrix = rotation_matrix.inverse();
979 }
980
981 const Transform3d inst_matrix_no_offset = inst_trafo.get_matrix_no_offset();
982 rotation_matrix = inst_matrix_no_offset.inverse() * inst_rotation_matrix * rotation_matrix * inst_rotation_matrix.inverse() * inst_matrix_no_offset;
983
984 // rotate around selection center
985 const Vec3d inst_pivot = inst_trafo.get_matrix_no_offset().inverse() * (m_cache.dragging_center - inst_trafo.get_offset());
986 rotation_matrix = Geometry::translation_transform(inst_pivot) * rotation_matrix * Geometry::translation_transform(-inst_pivot);
987 }
988 transform_instance_relative(v, volume_data, transformation_type, rotation_matrix, m_cache.dragging_center);
989 }
990 else {
992 assert(transformation_type.world());
993 transform_volume_relative(v, volume_data, transformation_type, rotation_matrix, m_cache.dragging_center);
994 }
995 else {
996 if (transformation_type.instance()) {
997 // ensure that the volume rotates as a rigid body
998 const Transform3d inst_scale_matrix = inst_trafo.get_scaling_factor_matrix();
999 rotation_matrix = inst_scale_matrix.inverse() * rotation_matrix * inst_scale_matrix;
1000 }
1001 else {
1002 if (transformation_type.local()) {
1003 // ensure that the volume rotates as a rigid body
1004 const Geometry::Transformation& vol_trafo = volume_data.get_volume_transform();
1005 const Transform3d vol_matrix_no_offset = vol_trafo.get_matrix_no_offset();
1006 const Transform3d inst_scale_matrix = inst_trafo.get_scaling_factor_matrix();
1007 Transform3d vol_rotation_matrix = vol_trafo.get_rotation_matrix();
1008 if (vol_trafo.is_left_handed()) {
1009 Geometry::TransformationSVD vol_svd(vol_trafo);
1010 vol_rotation_matrix = vol_svd.u * vol_svd.v.transpose();
1011 // ensure the rotation has the proper direction
1012 if (!rotation.normalized().cwiseAbs().isApprox(Vec3d::UnitX()))
1013 rotation_matrix = rotation_matrix.inverse();
1014 }
1015 rotation_matrix = vol_matrix_no_offset.inverse() * inst_scale_matrix.inverse() * vol_rotation_matrix * rotation_matrix *
1016 vol_rotation_matrix.inverse() * inst_scale_matrix * vol_matrix_no_offset;
1017 }
1018 }
1019 transform_volume_relative(v, volume_data, transformation_type, rotation_matrix, m_cache.dragging_center);
1020 }
1021 }
1022 }
1023
1024#if !DISABLE_INSTANCES_SYNCH
1025 if (m_mode == Instance) {
1026 int rot_axis_max = 0;
1027 rotation.cwiseAbs().maxCoeff(&rot_axis_max);
1029 }
1030 else if (m_mode == Volume)
1032#endif // !DISABLE_INSTANCES_SYNCH
1033
1035 wxGetApp().plater()->canvas3D()->requires_check_outside_state();
1036}
void transform_volume_relative(GLVolume &volume, const VolumeCache &volume_data, TransformationType transformation_type, const Transform3d &transform, const Vec3d &world_pivot)
Definition Selection.cpp:2933
void transform_instance_relative(GLVolume &volume, const VolumeCache &volume_data, TransformationType transformation_type, const Transform3d &transform, const Vec3d &world_pivot)
Definition Selection.cpp:2916
bool is_from_fully_selected_instance(unsigned int volume_idx) const
Definition Selection.cpp:2787
Vec3d dragging_center
Definition Selection.hpp:137
SyncRotationType
Definition Selection.hpp:401
EIGEN_DEVICE_FUNC Transform inverse(TransformTraits traits=(TransformTraits) Mode) const
Definition Transform.h:1202

References Slic3r::GUI::TransformationType::absolute(), Slic3r::GUI::Selection::Cache::dragging_center, GENERAL, Slic3r::GUI::Selection::VolumeCache::get_instance_transform(), Slic3r::Geometry::Transformation::get_matrix_no_offset(), Slic3r::Geometry::Transformation::get_offset(), Slic3r::Geometry::Transformation::get_rotation_matrix(), Slic3r::Geometry::Transformation::get_scaling_factor_matrix(), Slic3r::GUI::Selection::VolumeCache::get_volume_transform(), Slic3r::GUI::TransformationType::instance(), Instance, Eigen::Transform< _Scalar, _Dim, _Mode, _Options >::inverse(), is_from_fully_selected_instance(), Slic3r::Geometry::Transformation::is_left_handed(), is_single_volume_or_modifier(), is_wipe_tower(), Slic3r::GUI::TransformationType::local(), m_cache, m_list, m_mode, m_valid, NONE, Slic3r::GUI::TransformationType::relative(), Slic3r::Geometry::rotation_transform(), set_bounding_boxes_dirty(), synchronize_unselected_instances(), synchronize_unselected_volumes(), transform_instance_relative(), transform_volume_relative(), Slic3r::Geometry::translation_transform(), Slic3r::Geometry::TransformationSVD::u, Slic3r::Geometry::TransformationSVD::v, Volume, Slic3r::GUI::Selection::Cache::volumes_data, and Slic3r::GUI::TransformationType::world().

Referenced by Slic3r::GUI::ObjectManipulation::change_rotation_value(), Slic3r::GUI::GLGizmoEmboss::do_rotate(), Slic3r::GUI::GLCanvas3D::on_key(), Slic3r::GUI::GLGizmoRotate3D::on_mouse(), and Slic3r::GUI::GLGizmoEmboss::on_mouse_for_rotation().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ scale()

void Slic3r::GUI::Selection::scale ( const Vec3d scale,
TransformationType  transformation_type 
)
1069{
1070 scale_and_translate(scale, Vec3d::Zero(), transformation_type);
1071}
void scale(const Vec3d &scale, TransformationType transformation_type)
Definition Selection.cpp:1068

References scale(), and scale_and_translate().

Referenced by Slic3r::GUI::ObjectManipulation::do_scale(), Slic3r::GUI::ObjectManipulation::do_size(), Slic3r::GUI::GLGizmoScale3D::on_mouse(), Slic3r::GUI::GLGizmoMeasure::render_dimensioning(), scale(), scale_and_translate(), and scale_to_fit_print_volume().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ scale_and_translate()

void Slic3r::GUI::Selection::scale_and_translate ( const Vec3d scale,
const Vec3d world_translation,
TransformationType  transformation_type 
)
1211{
1212 if (!m_valid)
1213 return;
1214
1215 Vec3d relative_scale = scale;
1216 if (transformation_type.absolute()) {
1217 // converts to relative scale
1218 if (m_mode == Instance) {
1220 BoundingBoxf3 current_box = get_bounding_box_in_current_reference_system().first;
1221 BoundingBoxf3 original_box;
1222 if (transformation_type.world())
1224 else
1226
1227 relative_scale = original_box.size().cwiseProduct(scale).cwiseQuotient(current_box.size());
1228 }
1229 }
1230 transformation_type.set_relative();
1231 }
1232
1233 for (unsigned int i : m_list) {
1234 GLVolume& v = *(*m_volumes)[i];
1235 const VolumeCache& volume_data = m_cache.volumes_data[i];
1236 const Geometry::Transformation& inst_trafo = volume_data.get_instance_transform();
1237
1238 if (m_mode == Instance) {
1239 if (transformation_type.instance()) {
1240 const Vec3d world_inst_pivot = m_cache.dragging_center - inst_trafo.get_offset();
1241 const Vec3d local_inst_pivot = inst_trafo.get_matrix_no_offset().inverse() * world_inst_pivot;
1242 Matrix3d inst_rotation, inst_scale;
1243 inst_trafo.get_matrix().computeRotationScaling(&inst_rotation, &inst_scale);
1244 const Transform3d offset_trafo = Geometry::translation_transform(inst_trafo.get_offset() + world_translation);
1245 const Transform3d scale_trafo = Transform3d(inst_scale) * Geometry::scale_transform(relative_scale);
1246 v.set_instance_transformation(Geometry::translation_transform(world_inst_pivot) * offset_trafo * Transform3d(inst_rotation) * scale_trafo * Geometry::translation_transform(-local_inst_pivot));
1247 }
1248 else
1249 transform_instance_relative(v, volume_data, transformation_type, Geometry::translation_transform(world_translation) * Geometry::scale_transform(relative_scale), m_cache.dragging_center);
1250 }
1251 else {
1253 assert(transformation_type.world());
1254 transform_volume_relative(v, volume_data, transformation_type, Geometry::translation_transform(world_translation) * Geometry::scale_transform(scale), m_cache.dragging_center);
1255 }
1256 else {
1257 transformation_type.set_independent();
1258 Vec3d translation;
1259 if (transformation_type.local())
1260 translation = volume_data.get_volume_transform().get_matrix_no_offset().inverse() * inst_trafo.get_matrix_no_offset().inverse() * world_translation;
1261 else if (transformation_type.instance())
1262 translation = inst_trafo.get_matrix_no_offset().inverse() * world_translation;
1263 else
1264 translation = world_translation;
1266 }
1267 }
1268 }
1269
1270#if !DISABLE_INSTANCES_SYNCH
1271 if (m_mode == Instance)
1272 // even if there is no rotation, we pass SyncRotationType::GENERAL to force
1273 // synchronize_unselected_instances() to apply the scale to the other instances
1275 else if (m_mode == Volume)
1277#endif // !DISABLE_INSTANCES_SYNCH
1278
1279 ensure_on_bed();
1281 wxGetApp().plater()->canvas3D()->requires_check_outside_state();
1282}
const BoundingBoxf3 & get_full_unscaled_instance_bounding_box() const
Definition Selection.cpp:729
const BoundingBoxf3 & get_full_unscaled_instance_local_bounding_box() const
Definition Selection.cpp:767
void scale_transform(Transform3d &transform, double scale)
Definition Geometry.cpp:354

References Slic3r::GUI::TransformationType::absolute(), Eigen::Transform< _Scalar, _Dim, _Mode, _Options >::computeRotationScaling(), Slic3r::GUI::Selection::Cache::dragging_center, ensure_on_bed(), GENERAL, get_bounding_box_in_current_reference_system(), get_full_unscaled_instance_bounding_box(), get_full_unscaled_instance_local_bounding_box(), Slic3r::GUI::Selection::VolumeCache::get_instance_transform(), Slic3r::Geometry::Transformation::get_matrix(), Slic3r::Geometry::Transformation::get_matrix_no_offset(), Slic3r::Geometry::Transformation::get_offset(), Slic3r::GUI::Selection::VolumeCache::get_volume_transform(), Slic3r::GUI::TransformationType::instance(), Instance, Eigen::Transform< _Scalar, _Dim, _Mode, _Options >::inverse(), is_single_full_instance(), is_single_volume_or_modifier(), Slic3r::GUI::TransformationType::local(), m_cache, m_list, m_mode, m_valid, scale(), Slic3r::Geometry::scale_transform(), set_bounding_boxes_dirty(), Slic3r::GUI::TransformationType::set_independent(), Slic3r::GLVolume::set_instance_transformation(), Slic3r::GUI::TransformationType::set_relative(), Slic3r::BoundingBox3Base< PointType >::size(), synchronize_unselected_instances(), synchronize_unselected_volumes(), transform_instance_relative(), transform_volume_relative(), Slic3r::Geometry::translation_transform(), Volume, Slic3r::GUI::Selection::Cache::volumes_data, and Slic3r::GUI::TransformationType::world().

Referenced by mirror(), Slic3r::GUI::GLGizmoScale3D::on_mouse(), and scale().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ scale_to_fit_print_volume()

void Slic3r::GUI::Selection::scale_to_fit_print_volume ( const BuildVolume volume)
1074{
1075 auto fit = [this](double s, Vec3d offset, bool undoredo_snapshot) {
1076 if (s <= 0.0 || s == 1.0)
1077 return false;
1078
1079 if (undoredo_snapshot)
1080 wxGetApp().plater()->take_snapshot(_L("Scale To Fit"));
1081
1082 TransformationType type;
1083 type.set_world();
1084 type.set_relative();
1085 type.set_joint();
1086
1087 // apply scale
1088 setup_cache();
1089 scale(s * Vec3d::Ones(), type);
1090 wxGetApp().plater()->canvas3D()->do_scale(""); // avoid storing another snapshot
1091
1092 // center selection on print bed
1093 setup_cache();
1094 offset.z() = -get_bounding_box().min.z();
1095 TransformationType trafo_type;
1096 trafo_type.set_relative();
1097 translate(offset, trafo_type);
1098 wxGetApp().plater()->canvas3D()->do_move(""); // avoid storing another snapshot
1099
1100 wxGetApp().obj_manipul()->set_dirty();
1101 return undoredo_snapshot;
1102 };
1103
1104 auto fit_rectangle = [this, fit](const BuildVolume& volume, bool undoredo_snapshot, double* max_height = nullptr) {
1105 const BoundingBoxf3 print_volume = volume.bounding_volume();
1106 Vec3d print_volume_size = print_volume.size();
1107 print_volume_size.z() = (max_height != nullptr) ? *max_height : volume.max_print_height();
1108
1109 // adds 1/100th of a mm on both xy sides to avoid false out of print volume detections due to floating-point roundings
1110 Vec3d box_size = get_bounding_box().size();
1111 box_size.x() += 0.02;
1112 box_size.y() += 0.02;
1113
1114 const double sx = print_volume_size.x() / box_size.x();
1115 const double sy = print_volume_size.y() / box_size.y();
1116 const double sz = print_volume_size.z() / box_size.z();
1117
1118 return fit(std::min(sx, std::min(sy, sz)), print_volume.center() - get_bounding_box().center(), undoredo_snapshot);
1119 };
1120
1121 auto fit_circle = [this, fit](const BuildVolume& volume, bool undoredo_snapshot, double* max_height = nullptr) {
1122 const Geometry::Circled& print_circle = volume.circle();
1123 double print_circle_radius = unscale<double>(print_circle.radius);
1124
1125 if (print_circle_radius == 0.0)
1126 return false;
1127
1128 Points points;
1129 double max_z = 0.0;
1130 for (unsigned int i : m_list) {
1131 const GLVolume& v = *(*m_volumes)[i];
1132 TriangleMesh hull_3d = *v.convex_hull();
1133 hull_3d.transform(v.world_matrix());
1134 max_z = std::max(max_z, hull_3d.bounding_box().size().z());
1135 const Polygon hull_2d = hull_3d.convex_hull();
1136 points.insert(points.end(), hull_2d.begin(), hull_2d.end());
1137 }
1138
1139 if (points.empty())
1140 return false;
1141
1143 // adds 1/100th of a mm on all sides to avoid false out of print volume detections due to floating-point roundings
1144 const double circle_radius = unscale<double>(circle.radius) + 0.01;
1145
1146 if (circle_radius == 0.0 || max_z == 0.0)
1147 return false;
1148
1149 const double print_volume_max_z = (max_height != nullptr) ? *max_height : volume.max_print_height();
1150 const double s = std::min(print_circle_radius / circle_radius, print_volume_max_z / max_z);
1151 const Vec3d sel_center = get_bounding_box().center();
1152 const Vec3d offset = s * (Vec3d(unscale<double>(circle.center.x()), unscale<double>(circle.center.y()), 0.5 * max_z) - sel_center);
1153 const Vec3d print_center = { unscale<double>(print_circle.center.x()), unscale<double>(print_circle.center.y()), 0.5 * volume.max_print_height() };
1154 return fit(s, print_center - (sel_center + offset), undoredo_snapshot);
1155 };
1156
1157 if (is_empty() || m_mode == Volume)
1158 return;
1159
1160 assert(is_single_full_instance());
1161
1162 // used to keep track whether the undo/redo snapshot has already been taken
1163 bool undoredo_snapshot = false;
1164
1165 if (wxGetApp().plater()->printer_technology() == ptSLA) {
1166 // remove SLA auxiliary volumes from the selection to ensure that the proper bounding box is calculated
1167 std::vector<unsigned int> to_remove;
1168 for (unsigned int i : m_list) {
1169 if ((*m_volumes)[i]->volume_idx() < 0)
1170 to_remove.push_back(i);
1171 }
1172
1173 if (!to_remove.empty())
1174 remove_volumes(m_mode, to_remove);
1175 }
1176
1177 switch (volume.type())
1178 {
1179 case BuildVolume::Type::Rectangle: { undoredo_snapshot = fit_rectangle(volume, !undoredo_snapshot); break; }
1180 case BuildVolume::Type::Circle: { undoredo_snapshot = fit_circle(volume, !undoredo_snapshot); break; }
1181 default: { break; }
1182 }
1183
1184 if (wxGetApp().plater()->printer_technology() == ptFFF) {
1185 // check whether the top layer exceeds the maximum height of the print volume
1186 // and, in case, reduce the scale accordingly
1187 const auto [slicing_parameters, profile] = wxGetApp().plater()->canvas3D()->get_layers_height_data(get_object_idx());
1188 auto layers = generate_object_layers(slicing_parameters, profile);
1189 auto layers_it = layers.rbegin();
1190 while (layers_it != layers.rend() && *layers_it > volume.bounding_volume().max.z()) {
1191 ++layers_it;
1192 }
1193 if (layers_it != layers.rbegin() && layers_it != layers.rend()) {
1194 switch (volume.type())
1195 {
1196 case BuildVolume::Type::Rectangle: { fit_rectangle(volume, !undoredo_snapshot, &(*layers_it)); break; }
1197 case BuildVolume::Type::Circle: { fit_circle(volume, !undoredo_snapshot, &(*layers_it)); break; }
1198 default: { break; }
1199 }
1200 }
1201 }
1202}
PointType size() const
Definition BoundingBox.cpp:153
PointType min
Definition BoundingBox.hpp:16
void translate(const Vec3d &displacement, TransformationType transformation_type)
Definition Selection.cpp:906
void remove_volumes(EMode mode, const std::vector< unsigned int > &volume_idxs)
Definition Selection.cpp:366
void setup_cache()
Definition Selection.cpp:898
Circle< Vector > smallest_enclosing_circle_welzl(const Points &points, const typename Vector::Scalar epsilon)
Definition Circle.hpp:142
Circle< Vec2d > Circled
Definition Circle.hpp:91
max_print_height((ConfigOptionFloat, display_width))((ConfigOptionFloat
std::vector< coordf_t > generate_object_layers(const SlicingParameters &slicing_params, const std::vector< coordf_t > &layer_height_profile)
Definition Slicing.cpp:595
std::vector< Point, PointsAllocator< Point > > Points
Definition Point.hpp:58
Slic3r::Polygon Polygon
Definition Emboss.cpp:34

References _L, Slic3r::MultiPoint::begin(), Slic3r::TriangleMesh::bounding_box(), Slic3r::BoundingBox3Base< PointType >::center(), Slic3r::Geometry::Circle< Vector >::center, Slic3r::BuildVolume::Circle, Slic3r::TriangleMesh::convex_hull(), Slic3r::GLVolume::convex_hull(), Slic3r::MultiPoint::end(), Slic3r::generate_object_layers(), get_bounding_box(), get_object_idx(), is_empty(), is_single_full_instance(), m_list, m_mode, m_volumes, Slic3r::BoundingBoxBase< PointType, APointsType >::min, Slic3r::offset(), Slic3r::GUI::plater(), Slic3r::GUI::printer_technology(), Slic3r::ptFFF, Slic3r::ptSLA, Slic3r::Geometry::Circle< Vector >::radius, Slic3r::BuildVolume::Rectangle, remove_volumes(), scale(), Slic3r::GUI::TransformationType::set_joint(), Slic3r::GUI::TransformationType::set_relative(), Slic3r::GUI::TransformationType::set_world(), setup_cache(), Slic3r::BoundingBox3Base< PointType >::size(), Slic3r::Geometry::smallest_enclosing_circle_welzl(), Slic3r::TriangleMesh::transform(), translate(), Volume, and Slic3r::GLVolume::world_matrix().

+ Here is the call graph for this function:

◆ set_bounding_boxes_dirty()

◆ set_caches()

void Slic3r::GUI::Selection::set_caches ( )
private
2021{
2022 m_cache.volumes_data.clear();
2023 m_cache.sinking_volumes.clear();
2024 for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) {
2025 const GLVolume& v = *(*m_volumes)[i];
2026 m_cache.volumes_data.emplace(i, VolumeCache(v.get_volume_transformation(), v.get_instance_transformation()));
2027 if (v.is_sinking())
2028 m_cache.sinking_volumes.push_back(i);
2029 }
2031}

References Slic3r::BoundingBox3Base< PointType >::center(), Slic3r::GUI::Selection::Cache::dragging_center, get_bounding_box(), Slic3r::GLVolume::get_instance_transformation(), Slic3r::GLVolume::get_volume_transformation(), Slic3r::GLVolume::is_sinking(), m_cache, m_volumes, Slic3r::GUI::Selection::Cache::sinking_volumes, and Slic3r::GUI::Selection::Cache::volumes_data.

Referenced by setup_cache().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ set_deserialized()

void Slic3r::GUI::Selection::set_deserialized ( EMode  mode,
const std::vector< std::pair< size_t, size_t > > &  volumes_and_instances 
)
427{
428 if (! m_valid)
429 return;
430
431 m_mode = mode;
432 for (unsigned int i : m_list)
433 (*m_volumes)[i]->selected = false;
434 m_list.clear();
435 for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++ i)
436 if (std::binary_search(volumes_and_instances.begin(), volumes_and_instances.end(), (*m_volumes)[i]->geometry_id))
437 do_add_volume(i);
438 update_type();
440}

References do_add_volume(), m_list, m_mode, m_valid, m_volumes, set_bounding_boxes_dirty(), and update_type().

+ Here is the call graph for this function:

◆ set_enabled()

void Slic3r::GUI::Selection::set_enabled ( bool  enable)
inline
204{ m_enabled = enable; }

References m_enabled.

Referenced by Slic3r::GUI::GLCanvas3D::enable_selection().

+ Here is the caller graph for this function:

◆ set_mode()

void Slic3r::GUI::Selection::set_mode ( EMode  mode)
inline
210{ m_mode = mode; }

References m_mode.

Referenced by Slic3r::GUI::View3D::init().

+ Here is the caller graph for this function:

◆ set_model()

void Slic3r::GUI::Selection::set_model ( Model model)
138{
139 m_model = model;
140 update_valid();
141}
void update_valid()
Definition Selection.cpp:1809

References m_model, and update_valid().

Referenced by Slic3r::GUI::GLCanvas3D::set_model().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ set_volumes()

void Slic3r::GUI::Selection::set_volumes ( GLVolumePtrs volumes)
120{
121 m_volumes = volumes;
122 update_valid();
123}

References m_volumes, and update_valid().

Referenced by Slic3r::GUI::GLCanvas3D::GLCanvas3D().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setup_cache()

void Slic3r::GUI::Selection::setup_cache ( )
899{
900 if (!m_valid)
901 return;
902
903 set_caches();
904}
void set_caches()
Definition Selection.cpp:2020

References m_valid, and set_caches().

Referenced by Slic3r::GUI::ObjectManipulation::ObjectManipulation(), Slic3r::GUI::ObjectManipulation::change_position_value(), Slic3r::GUI::ObjectManipulation::change_rotation_value(), Slic3r::GUI::GLGizmoEmboss::do_rotate(), Slic3r::GUI::ObjectManipulation::do_scale(), Slic3r::GUI::ObjectManipulation::do_size(), Slic3r::GUI::GLGizmoEmboss::do_translate(), Slic3r::GUI::GLCanvas3D::mirror_selection(), Slic3r::GUI::GLCanvas3D::on_key(), Slic3r::GUI::GLCanvas3D::on_mouse(), Slic3r::GUI::GLGizmoMeasure::render_dimensioning(), scale_to_fit_print_volume(), and Slic3r::GUI::GLGizmoBase::use_grabbers().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ synchronize_unselected_instances()

void Slic3r::GUI::Selection::synchronize_unselected_instances ( SyncRotationType  sync_rotation_type)
2649{
2650 std::set<unsigned int> done; // prevent processing volumes twice
2651 done.insert(m_list.begin(), m_list.end());
2652 for (unsigned int i : m_list) {
2653 if (done.size() == m_volumes->size())
2654 break;
2655 const GLVolume* volume_i = (*m_volumes)[i];
2656 if (volume_i->is_wipe_tower)
2657 continue;
2658
2659 const int object_idx = volume_i->object_idx();
2660 const int instance_idx = volume_i->instance_idx();
2661 const Transform3d& curr_inst_trafo_i = volume_i->get_instance_transformation().get_matrix();
2662 const Transform3d& old_inst_trafo_i = m_cache.volumes_data[i].get_instance_transform().get_matrix();
2663 bool mirrored = is_left_handed(curr_inst_trafo_i) != is_left_handed(old_inst_trafo_i);
2664// bool mirrored = curr_inst_trafo_i.linear().determinant() * old_inst_trafo_i.linear().determinant() < 0;
2665
2666 // Process unselected instances.
2667 for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j) {
2668 if (done.size() == m_volumes->size())
2669 break;
2670 if (done.find(j) != done.end())
2671 continue;
2672 GLVolume* volume_j = (*m_volumes)[j];
2673 if (volume_j->object_idx() != object_idx || volume_j->instance_idx() == instance_idx)
2674 continue;
2675 const Transform3d& old_inst_trafo_j = m_cache.volumes_data[j].get_instance_transform().get_matrix();
2676 assert(is_rotation_xy_synchronized(old_inst_trafo_i, old_inst_trafo_j));
2677 Transform3d new_inst_trafo_j = volume_j->get_instance_transformation().get_matrix();
2678 if (sync_rotation_type == SyncRotationType::RESET) {
2679 Geometry::Transformation new_inst_trafo_j_no_rotation(new_inst_trafo_j);
2680 new_inst_trafo_j_no_rotation.reset_rotation();
2681 new_inst_trafo_j = new_inst_trafo_j_no_rotation.get_matrix();
2682 }
2683 else if (sync_rotation_type != SyncRotationType::NONE || mirrored)
2684 new_inst_trafo_j.linear() = (old_inst_trafo_j.linear() * old_inst_trafo_i.linear().inverse()) * curr_inst_trafo_i.linear();
2685 if (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() != ptSLA)
2686 new_inst_trafo_j.translation().z() = curr_inst_trafo_i.translation().z();
2687 assert(is_rotation_xy_synchronized(curr_inst_trafo_i, new_inst_trafo_j));
2688 volume_j->set_instance_transformation(new_inst_trafo_j);
2689 done.insert(j);
2690 }
2691 }
2692#ifndef NDEBUG
2694#endif /* NDEBUG */
2695}
static volatile int done
Definition bitbang.c:50
static bool is_rotation_xy_synchronized(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to)
Definition Selection.cpp:2562
static bool is_left_handed(const Transform3d::ConstLinearPart &m)
Definition Selection.cpp:2551
static void verify_instances_rotation_synchronized(const Model &model, const GLVolumePtrs &volumes)
Definition Selection.cpp:2624

References done, Slic3r::GLVolume::get_instance_transformation(), Slic3r::Geometry::Transformation::get_matrix(), Slic3r::GLVolume::instance_idx(), Slic3r::GUI::is_left_handed(), Slic3r::GUI::is_rotation_xy_synchronized(), Eigen::Transform< _Scalar, _Dim, _Mode, _Options >::linear(), m_cache, m_list, m_model, m_volumes, NONE, Slic3r::GLVolume::object_idx(), Slic3r::ptSLA, RESET, Slic3r::Geometry::Transformation::reset_rotation(), Slic3r::GLVolume::set_instance_transformation(), Eigen::Transform< _Scalar, _Dim, _Mode, _Options >::translation(), Slic3r::GUI::verify_instances_rotation_synchronized(), and Slic3r::GUI::Selection::Cache::volumes_data.

Referenced by Slic3r::GUI::ObjectManipulation::ObjectManipulation(), flattening_rotate(), reset_skew(), rotate(), scale_and_translate(), and translate().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ synchronize_unselected_volumes()

void Slic3r::GUI::Selection::synchronize_unselected_volumes ( )
2698{
2699 for (unsigned int i : m_list) {
2700 const GLVolume* volume = (*m_volumes)[i];
2701 if (volume->is_wipe_tower)
2702 continue;
2703
2704 const int object_idx = volume->object_idx();
2705 const int volume_idx = volume->volume_idx();
2706 const Geometry::Transformation& trafo = volume->get_volume_transformation();
2707
2708 // Process unselected volumes.
2709 for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j) {
2710 if (j == i)
2711 continue;
2712
2713 GLVolume* v = (*m_volumes)[j];
2714 if (v->object_idx() != object_idx || v->volume_idx() != volume_idx)
2715 continue;
2716
2717 v->set_volume_transformation(trafo);
2718 }
2719 }
2720}

References m_list, m_volumes, Slic3r::GLVolume::object_idx(), Slic3r::GLVolume::set_volume_transformation(), and Slic3r::GLVolume::volume_idx().

Referenced by Slic3r::GUI::ObjectManipulation::ObjectManipulation(), reset_skew(), rotate(), scale_and_translate(), and translate().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ transform_instance_relative()

void Slic3r::GUI::Selection::transform_instance_relative ( GLVolume volume,
const VolumeCache volume_data,
TransformationType  transformation_type,
const Transform3d transform,
const Vec3d world_pivot 
)
private
2918{
2919 assert(transformation_type.relative());
2920
2921 const Geometry::Transformation& inst_trafo = volume_data.get_instance_transform();
2922 if (transformation_type.world()) {
2923 const Vec3d inst_pivot = transformation_type.independent() && !is_from_single_instance() ? inst_trafo.get_offset() : world_pivot;
2925 volume.set_instance_transformation(trafo * inst_trafo.get_matrix());
2926 }
2927 else if (transformation_type.instance())
2928 volume.set_instance_transformation(inst_trafo.get_matrix() * transform);
2929 else
2930 assert(false);
2931}
Linef3 transform(const Linef3 &line, const Transform3d &t)
Definition Line.cpp:10

References Slic3r::GUI::Selection::VolumeCache::get_instance_transform(), Slic3r::Geometry::Transformation::get_matrix(), Slic3r::Geometry::Transformation::get_offset(), Slic3r::GUI::TransformationType::independent(), Slic3r::GUI::TransformationType::instance(), is_from_single_instance(), Slic3r::GUI::TransformationType::relative(), Slic3r::transform(), Slic3r::Geometry::translation_transform(), and Slic3r::GUI::TransformationType::world().

Referenced by rotate(), scale_and_translate(), and translate().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ transform_volume_relative()

void Slic3r::GUI::Selection::transform_volume_relative ( GLVolume volume,
const VolumeCache volume_data,
TransformationType  transformation_type,
const Transform3d transform,
const Vec3d world_pivot 
)
private
2935{
2936 assert(transformation_type.relative());
2937
2938 const Geometry::Transformation& vol_trafo = volume_data.get_volume_transform();
2939 const Geometry::Transformation& inst_trafo = volume_data.get_instance_transform();
2940
2941 if (transformation_type.world()) {
2942 const Vec3d inst_pivot = transformation_type.independent() ? vol_trafo.get_offset() : (Vec3d)(inst_trafo.get_matrix().inverse() * world_pivot);
2943 const Transform3d inst_matrix_no_offset = inst_trafo.get_matrix_no_offset();
2944 const Transform3d trafo = Geometry::translation_transform(inst_pivot) * inst_matrix_no_offset.inverse() * transform * inst_matrix_no_offset * Geometry::translation_transform(-inst_pivot);
2945 volume.set_volume_transformation(trafo * vol_trafo.get_matrix());
2946 }
2947 else if (transformation_type.instance()) {
2948 const Vec3d inst_pivot = transformation_type.independent() ? vol_trafo.get_offset() : (Vec3d)(inst_trafo.get_matrix().inverse() * world_pivot);
2950 volume.set_volume_transformation(trafo * vol_trafo.get_matrix());
2951 }
2952 else if (transformation_type.local())
2953 volume.set_volume_transformation(vol_trafo.get_matrix() * transform);
2954 else
2955 assert(false);
2956}

References Slic3r::GUI::Selection::VolumeCache::get_instance_transform(), Slic3r::Geometry::Transformation::get_matrix(), Slic3r::Geometry::Transformation::get_matrix_no_offset(), Slic3r::Geometry::Transformation::get_offset(), Slic3r::GUI::Selection::VolumeCache::get_volume_transform(), Slic3r::GUI::TransformationType::independent(), Slic3r::GUI::TransformationType::instance(), Eigen::Transform< _Scalar, _Dim, _Mode, _Options >::inverse(), Slic3r::GUI::TransformationType::local(), Slic3r::GUI::TransformationType::relative(), Slic3r::transform(), Slic3r::Geometry::translation_transform(), and Slic3r::GUI::TransformationType::world().

Referenced by rotate(), scale_and_translate(), and translate().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ translate() [1/2]

void Slic3r::GUI::Selection::translate ( const Vec3d displacement,
TransformationType  transformation_type 
)
907{
908 if (!m_valid)
909 return;
910
911 // Emboss use translate in local coordinate
912 assert(transformation_type.relative() ||
913 transformation_type.local());
914
915 for (unsigned int i : m_list) {
916 GLVolume& v = *(*m_volumes)[i];
917 const VolumeCache& volume_data = m_cache.volumes_data[i];
918 if (m_mode == Instance && !is_wipe_tower()) {
920 if (transformation_type.instance()) {
921 const Geometry::Transformation& inst_trafo = volume_data.get_instance_transform();
922 v.set_instance_offset(inst_trafo.get_offset() + inst_trafo.get_rotation_matrix() * displacement);
923 }
924 else
925 transform_instance_relative(v, volume_data, transformation_type, Geometry::translation_transform(displacement), m_cache.dragging_center);
926 }
927 else {
928 if (transformation_type.local() && transformation_type.absolute()) {
929 const Geometry::Transformation& vol_trafo = volume_data.get_volume_transform();
930 const Geometry::Transformation& inst_trafo = volume_data.get_instance_transform();
931 v.set_volume_offset(vol_trafo.get_offset() + inst_trafo.get_scaling_factor_matrix().inverse() * vol_trafo.get_rotation_matrix() * displacement);
932 }
933 else {
934 Vec3d relative_disp = displacement;
935 if (transformation_type.instance())
936 relative_disp = volume_data.get_instance_scale_matrix().inverse() * relative_disp;
937
938 transform_volume_relative(v, volume_data, transformation_type, Geometry::translation_transform(relative_disp), m_cache.dragging_center);
939 }
940 }
941 }
942
943#if !DISABLE_INSTANCES_SYNCH
944 if (m_mode == Instance)
946 else if (m_mode == Volume)
948#endif // !DISABLE_INSTANCES_SYNCH
949
952 wxGetApp().plater()->canvas3D()->requires_check_outside_state();
953}

References Slic3r::GUI::TransformationType::absolute(), Slic3r::GUI::Selection::Cache::dragging_center, ensure_not_below_bed(), Slic3r::GUI::Selection::VolumeCache::get_instance_scale_matrix(), Slic3r::GUI::Selection::VolumeCache::get_instance_transform(), Slic3r::Geometry::Transformation::get_offset(), Slic3r::Geometry::Transformation::get_rotation_matrix(), Slic3r::Geometry::Transformation::get_scaling_factor_matrix(), Slic3r::GUI::Selection::VolumeCache::get_volume_transform(), Slic3r::GUI::TransformationType::instance(), Instance, Eigen::Transform< _Scalar, _Dim, _Mode, _Options >::inverse(), is_from_fully_selected_instance(), is_wipe_tower(), Slic3r::GUI::TransformationType::local(), m_cache, m_list, m_mode, m_valid, NONE, Slic3r::GUI::TransformationType::relative(), set_bounding_boxes_dirty(), Slic3r::GLVolume::set_instance_offset(), Slic3r::GLVolume::set_volume_offset(), synchronize_unselected_instances(), synchronize_unselected_volumes(), transform_instance_relative(), transform_volume_relative(), Slic3r::Geometry::translation_transform(), Volume, and Slic3r::GUI::Selection::Cache::volumes_data.

Referenced by Slic3r::GUI::ObjectManipulation::change_position_value(), Slic3r::GUI::GLCanvas3D::do_mirror(), Slic3r::GUI::GLCanvas3D::do_move(), Slic3r::GUI::GLCanvas3D::do_reset_skew(), Slic3r::GUI::GLCanvas3D::do_rotate(), Slic3r::GUI::GLCanvas3D::do_scale(), Slic3r::GUI::GLGizmoEmboss::do_translate(), Slic3r::GUI::GLGizmoMove3D::on_dragging(), Slic3r::GUI::GLCanvas3D::on_key(), Slic3r::GUI::GLCanvas3D::on_mouse(), and scale_to_fit_print_volume().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ translate() [2/2]

void Slic3r::GUI::Selection::translate ( unsigned int  object_idx,
unsigned int  instance_idx,
const Vec3d displacement 
)
1345{
1346 if (!m_valid)
1347 return;
1348
1349 for (unsigned int i : m_list) {
1350 GLVolume& v = *(*m_volumes)[i];
1351 if (v.object_idx() == (int)object_idx && v.instance_idx() == (int)instance_idx)
1352 v.set_instance_transformation(Geometry::translation_transform(displacement) * v.get_instance_transformation().get_matrix());
1353 }
1354
1355 std::set<unsigned int> done; // prevent processing volumes twice
1356 done.insert(m_list.begin(), m_list.end());
1357
1358 for (unsigned int i : m_list) {
1359 if (done.size() == m_volumes->size())
1360 break;
1361
1362 if ((*m_volumes)[i]->is_wipe_tower)
1363 continue;
1364
1365 const int object_idx = (*m_volumes)[i]->object_idx();
1366
1367 // Process unselected volumes of the object.
1368 for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j) {
1369 if (done.size() == m_volumes->size())
1370 break;
1371
1372 if (done.find(j) != done.end())
1373 continue;
1374
1375 GLVolume& v = *(*m_volumes)[j];
1376 if (v.object_idx() != object_idx || v.instance_idx() != (int)instance_idx)
1377 continue;
1378
1379 v.set_instance_transformation(Geometry::translation_transform(displacement) * v.get_instance_transformation().get_matrix());
1380 done.insert(j);
1381 }
1382 }
1383
1385}

References done, Slic3r::GLVolume::get_instance_transformation(), Slic3r::Geometry::Transformation::get_matrix(), Slic3r::GLVolume::instance_idx(), m_list, m_valid, m_volumes, Slic3r::GLVolume::object_idx(), set_bounding_boxes_dirty(), Slic3r::GLVolume::set_instance_transformation(), and Slic3r::Geometry::translation_transform().

+ Here is the call graph for this function:

◆ update_type()

void Slic3r::GUI::Selection::update_type ( )
private
1815{
1816 m_cache.content.clear();
1817 m_type = Mixed;
1818
1819 for (unsigned int i : m_list) {
1820 const GLVolume* volume = (*m_volumes)[i];
1821 int obj_idx = volume->object_idx();
1822 int inst_idx = volume->instance_idx();
1823 ObjectIdxsToInstanceIdxsMap::iterator obj_it = m_cache.content.find(obj_idx);
1824 if (obj_it == m_cache.content.end())
1825 obj_it = m_cache.content.insert(ObjectIdxsToInstanceIdxsMap::value_type(obj_idx, InstanceIdxsList())).first;
1826
1827 obj_it->second.insert(inst_idx);
1828 }
1829
1830 bool requires_disable = false;
1831
1832 if (!m_valid)
1833 m_type = Invalid;
1834 else {
1835 if (m_list.empty())
1836 m_type = Empty;
1837 else if (m_list.size() == 1) {
1838 const GLVolume* first = (*m_volumes)[*m_list.begin()];
1839 if (first->is_wipe_tower)
1840 m_type = WipeTower;
1841 else if (first->is_modifier) {
1843 requires_disable = true;
1844 }
1845 else {
1846 const ModelObject* model_object = m_model->objects[first->object_idx()];
1847 unsigned int volumes_count = (unsigned int)model_object->volumes.size();
1848 unsigned int instances_count = (unsigned int)model_object->instances.size();
1849 if (volumes_count * instances_count == 1) {
1851 // ensures the correct mode is selected
1852 m_mode = Instance;
1853 }
1854 else if (volumes_count == 1) { // instances_count > 1
1856 // ensures the correct mode is selected
1857 m_mode = Instance;
1858 }
1859 else {
1861 requires_disable = true;
1862 }
1863 }
1864 }
1865 else {
1866 unsigned int sla_volumes_count = 0;
1867 // Note: sla_volumes_count is a count of the selected sla_volumes per object instead of per instance, like a model_volumes_count is
1868 for (unsigned int i : m_list) {
1869 if ((*m_volumes)[i]->volume_idx() < 0)
1870 ++sla_volumes_count;
1871 }
1872
1873 if (m_cache.content.size() == 1) // single object
1874 {
1875 const ModelObject* model_object = m_model->objects[m_cache.content.begin()->first];
1876 unsigned int model_volumes_count = (unsigned int)model_object->volumes.size();
1877
1878 unsigned int instances_count = (unsigned int)model_object->instances.size();
1879 unsigned int selected_instances_count = (unsigned int)m_cache.content.begin()->second.size();
1880 if (model_volumes_count * instances_count + sla_volumes_count == (unsigned int)m_list.size()) {
1882 // ensures the correct mode is selected
1883 m_mode = Instance;
1884 }
1885 else if (selected_instances_count == 1) {
1886 if (model_volumes_count + sla_volumes_count == (unsigned int)m_list.size()) {
1888 // ensures the correct mode is selected
1889 m_mode = Instance;
1890 }
1891 else {
1892 unsigned int modifiers_count = 0;
1893 for (unsigned int i : m_list) {
1894 if ((*m_volumes)[i]->is_modifier)
1895 ++modifiers_count;
1896 }
1897
1898 if (modifiers_count == 0)
1900 else if (modifiers_count == (unsigned int)m_list.size())
1902
1903 requires_disable = true;
1904 }
1905 }
1906 else if (selected_instances_count > 1 && selected_instances_count * model_volumes_count + sla_volumes_count == (unsigned int)m_list.size()) {
1908 // ensures the correct mode is selected
1909 m_mode = Instance;
1910 }
1911 }
1912 else {
1913 unsigned int sels_cntr = 0;
1914 for (ObjectIdxsToInstanceIdxsMap::iterator it = m_cache.content.begin(); it != m_cache.content.end(); ++it) {
1915 const ModelObject* model_object = m_model->objects[it->first];
1916 unsigned int volumes_count = (unsigned int)model_object->volumes.size();
1917 unsigned int instances_count = (unsigned int)model_object->instances.size();
1918 sels_cntr += volumes_count * instances_count;
1919 }
1920 if (sels_cntr + sla_volumes_count == (unsigned int)m_list.size()) {
1922 // ensures the correct mode is selected
1923 m_mode = Instance;
1924 }
1925 }
1926 }
1927 }
1928
1929 int object_idx = get_object_idx();
1930 int instance_idx = get_instance_idx();
1931 for (GLVolume* v : *m_volumes) {
1932 v->disabled = requires_disable ? (v->object_idx() != object_idx) || (v->instance_idx() != instance_idx) : false;
1933 }
1934
1935#if ENABLE_SELECTION_DEBUG_OUTPUT
1936 std::cout << "Selection: ";
1937 std::cout << "mode: ";
1938 switch (m_mode)
1939 {
1940 case Volume:
1941 {
1942 std::cout << "Volume";
1943 break;
1944 }
1945 case Instance:
1946 {
1947 std::cout << "Instance";
1948 break;
1949 }
1950 }
1951
1952 std::cout << " - type: ";
1953
1954 switch (m_type)
1955 {
1956 case Invalid:
1957 {
1958 std::cout << "Invalid" << std::endl;
1959 break;
1960 }
1961 case Empty:
1962 {
1963 std::cout << "Empty" << std::endl;
1964 break;
1965 }
1966 case WipeTower:
1967 {
1968 std::cout << "WipeTower" << std::endl;
1969 break;
1970 }
1971 case SingleModifier:
1972 {
1973 std::cout << "SingleModifier" << std::endl;
1974 break;
1975 }
1976 case MultipleModifier:
1977 {
1978 std::cout << "MultipleModifier" << std::endl;
1979 break;
1980 }
1981 case SingleVolume:
1982 {
1983 std::cout << "SingleVolume" << std::endl;
1984 break;
1985 }
1986 case MultipleVolume:
1987 {
1988 std::cout << "MultipleVolume" << std::endl;
1989 break;
1990 }
1991 case SingleFullObject:
1992 {
1993 std::cout << "SingleFullObject" << std::endl;
1994 break;
1995 }
1996 case MultipleFullObject:
1997 {
1998 std::cout << "MultipleFullObject" << std::endl;
1999 break;
2000 }
2001 case SingleFullInstance:
2002 {
2003 std::cout << "SingleFullInstance" << std::endl;
2004 break;
2005 }
2007 {
2008 std::cout << "MultipleFullInstance" << std::endl;
2009 break;
2010 }
2011 case Mixed:
2012 {
2013 std::cout << "Mixed" << std::endl;
2014 break;
2015 }
2016 }
2017#endif // ENABLE_SELECTION_DEBUG_OUTPUT
2018}
unsigned int volumes_count() const
Definition Selection.hpp:297

References Slic3r::GUI::Selection::Cache::content, Empty, get_instance_idx(), get_object_idx(), Instance, Slic3r::ModelObject::instances, Invalid, m_cache, m_list, m_mode, m_model, m_type, m_valid, m_volumes, Mixed, MultipleFullInstance, MultipleFullObject, MultipleModifier, MultipleVolume, Slic3r::GLVolume::object_idx(), Slic3r::Model::objects, SingleFullInstance, SingleFullObject, SingleModifier, SingleVolume, Volume, Slic3r::ModelObject::volumes, volumes_count(), and WipeTower.

Referenced by add(), add_all(), add_instance(), add_object(), add_volume(), add_volumes(), clear(), instances_changed(), remove(), remove_instance(), remove_object(), remove_volume(), remove_volumes(), set_deserialized(), and volumes_changed().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ update_valid()

void Slic3r::GUI::Selection::update_valid ( )
private
1810{
1811 m_valid = (m_volumes != nullptr) && (m_model != nullptr);
1812}

References m_model, m_valid, and m_volumes.

Referenced by set_model(), and set_volumes().

+ Here is the caller graph for this function:

◆ volumes_changed()

void Slic3r::GUI::Selection::volumes_changed ( const std::vector< size_t > &  map_volume_old_to_new)
498{
499 assert(m_valid);
500 assert(m_mode == Volume);
501 IndicesList list_new;
502 for (unsigned int idx : m_list)
503 if (map_volume_old_to_new[idx] != size_t(-1)) {
504 unsigned int new_idx = (unsigned int)map_volume_old_to_new[idx];
505 (*m_volumes)[new_idx]->selected = true;
506 list_new.insert(new_idx);
507 }
508 m_list = std::move(list_new);
509 update_type();
511}
std::set< unsigned int > IndicesList
Definition Selection.hpp:33

References m_list, m_mode, m_valid, set_bounding_boxes_dirty(), update_type(), and Volume.

Referenced by Slic3r::GUI::GLCanvas3D::reload_scene().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ volumes_count()

unsigned int Slic3r::GUI::Selection::volumes_count ( ) const
inline
297{ return (unsigned int)m_list.size(); }

References m_list.

Referenced by Slic3r::GUI::MenuFactory::append_menu_item_edit_text(), and update_type().

+ Here is the caller graph for this function:

Member Data Documentation

◆ m_arrow

GLModel Slic3r::GUI::Selection::m_arrow
private

◆ m_axes

CoordAxes Slic3r::GUI::Selection::m_axes
private

Referenced by Selection(), and render_sidebar_hints().

◆ m_bounding_box

std::optional<BoundingBoxf3> Slic3r::GUI::Selection::m_bounding_box
private

◆ m_bounding_box_in_current_reference_system

std::optional<std::pair<BoundingBoxf3, Transform3d> > Slic3r::GUI::Selection::m_bounding_box_in_current_reference_system
private

◆ m_box

GLModel Slic3r::GUI::Selection::m_box
private

Referenced by render_bounding_box().

◆ m_cache

◆ m_clipboard

◆ m_curved_arrow

GLModel Slic3r::GUI::Selection::m_curved_arrow
private

◆ m_enabled

bool Slic3r::GUI::Selection::m_enabled
private

Referenced by is_enabled(), and set_enabled().

◆ m_full_scaled_instance_bounding_box

std::optional<BoundingBoxf3> Slic3r::GUI::Selection::m_full_scaled_instance_bounding_box
private

◆ m_full_unscaled_instance_bounding_box

std::optional<BoundingBoxf3> Slic3r::GUI::Selection::m_full_unscaled_instance_bounding_box
private

◆ m_full_unscaled_instance_local_bounding_box

std::optional<BoundingBoxf3> Slic3r::GUI::Selection::m_full_unscaled_instance_local_bounding_box
private

◆ m_list

◆ m_mode

◆ m_model

◆ m_planes

Planes Slic3r::GUI::Selection::m_planes
private

◆ m_scale_factor

float Slic3r::GUI::Selection::m_scale_factor
private

Referenced by render(), and render_bounding_box().

◆ m_scaled_instance_bounding_box

std::optional<BoundingBoxf3> Slic3r::GUI::Selection::m_scaled_instance_bounding_box
private

◆ m_type

◆ m_unscaled_instance_bounding_box

std::optional<BoundingBoxf3> Slic3r::GUI::Selection::m_unscaled_instance_bounding_box
private

◆ m_valid

◆ m_volumes


The documentation for this class was generated from the following files: