diff --git a/resources/icons/cog.svg b/resources/icons/cog.svg
new file mode 100644
index 000000000..07adb6610
--- /dev/null
+++ b/resources/icons/cog.svg
@@ -0,0 +1,17 @@
+
+
+
diff --git a/resources/icons/cooling.svg b/resources/icons/cooling.svg
new file mode 100644
index 000000000..b5d80e434
--- /dev/null
+++ b/resources/icons/cooling.svg
@@ -0,0 +1,25 @@
+
+
+
diff --git a/resources/icons/funnel.svg b/resources/icons/funnel.svg
new file mode 100644
index 000000000..8877722e3
--- /dev/null
+++ b/resources/icons/funnel.svg
@@ -0,0 +1,15 @@
+
+
+
diff --git a/resources/icons/infill.svg b/resources/icons/infill.svg
new file mode 100644
index 000000000..fcb1f99c9
--- /dev/null
+++ b/resources/icons/infill.svg
@@ -0,0 +1,33 @@
+
+
+
diff --git a/resources/icons/note.svg b/resources/icons/note.svg
new file mode 100644
index 000000000..c14214201
--- /dev/null
+++ b/resources/icons/note.svg
@@ -0,0 +1,25 @@
+
+
+
diff --git a/resources/icons/output+page_white.svg b/resources/icons/output+page_white.svg
new file mode 100644
index 000000000..ec1518f25
--- /dev/null
+++ b/resources/icons/output+page_white.svg
@@ -0,0 +1,21 @@
+
+
+
diff --git a/resources/icons/printer.svg b/resources/icons/printer.svg
new file mode 100644
index 000000000..91e103ec7
--- /dev/null
+++ b/resources/icons/printer.svg
@@ -0,0 +1,14 @@
+
+
+
diff --git a/resources/icons/skirt+brim.svg b/resources/icons/skirt+brim.svg
new file mode 100644
index 000000000..9242761b6
--- /dev/null
+++ b/resources/icons/skirt+brim.svg
@@ -0,0 +1,19 @@
+
+
+
diff --git a/resources/icons/spool.svg b/resources/icons/spool.svg
new file mode 100644
index 000000000..840365938
--- /dev/null
+++ b/resources/icons/spool.svg
@@ -0,0 +1,21 @@
+
+
+
diff --git a/resources/icons/support.svg b/resources/icons/support.svg
new file mode 100644
index 000000000..65c7592c8
--- /dev/null
+++ b/resources/icons/support.svg
@@ -0,0 +1,25 @@
+
+
+
diff --git a/resources/icons/time.svg b/resources/icons/time.svg
new file mode 100644
index 000000000..5d8f23cfc
--- /dev/null
+++ b/resources/icons/time.svg
@@ -0,0 +1,16 @@
+
+
+
diff --git a/resources/icons/wrench.svg b/resources/icons/wrench.svg
new file mode 100644
index 000000000..7966da8d8
--- /dev/null
+++ b/resources/icons/wrench.svg
@@ -0,0 +1,24 @@
+
+
+
diff --git a/src/libslic3r/ClipperUtils.cpp b/src/libslic3r/ClipperUtils.cpp
index f00e908ce..4c6e542f4 100644
--- a/src/libslic3r/ClipperUtils.cpp
+++ b/src/libslic3r/ClipperUtils.cpp
@@ -120,7 +120,7 @@ Slic3r::Polygon ClipperPath_to_Slic3rPolygon(const ClipperLib::Path &input)
{
Polygon retval;
for (ClipperLib::Path::const_iterator pit = input.begin(); pit != input.end(); ++pit)
- retval.points.push_back(Point( (*pit).X, (*pit).Y ));
+ retval.points.emplace_back(pit->X, pit->Y);
return retval;
}
@@ -128,7 +128,7 @@ Slic3r::Polyline ClipperPath_to_Slic3rPolyline(const ClipperLib::Path &input)
{
Polyline retval;
for (ClipperLib::Path::const_iterator pit = input.begin(); pit != input.end(); ++pit)
- retval.points.push_back(Point( (*pit).X, (*pit).Y ));
+ retval.points.emplace_back(pit->X, pit->Y);
return retval;
}
@@ -137,7 +137,7 @@ Slic3r::Polygons ClipperPaths_to_Slic3rPolygons(const ClipperLib::Paths &input)
Slic3r::Polygons retval;
retval.reserve(input.size());
for (ClipperLib::Paths::const_iterator it = input.begin(); it != input.end(); ++it)
- retval.push_back(ClipperPath_to_Slic3rPolygon(*it));
+ retval.emplace_back(ClipperPath_to_Slic3rPolygon(*it));
return retval;
}
@@ -146,7 +146,7 @@ Slic3r::Polylines ClipperPaths_to_Slic3rPolylines(const ClipperLib::Paths &input
Slic3r::Polylines retval;
retval.reserve(input.size());
for (ClipperLib::Paths::const_iterator it = input.begin(); it != input.end(); ++it)
- retval.push_back(ClipperPath_to_Slic3rPolyline(*it));
+ retval.emplace_back(ClipperPath_to_Slic3rPolyline(*it));
return retval;
}
@@ -171,7 +171,7 @@ Slic3rMultiPoint_to_ClipperPath(const MultiPoint &input)
{
ClipperLib::Path retval;
for (Points::const_iterator pit = input.points.begin(); pit != input.points.end(); ++pit)
- retval.push_back(ClipperLib::IntPoint( (*pit)(0), (*pit)(1) ));
+ retval.emplace_back((*pit)(0), (*pit)(1));
return retval;
}
@@ -181,7 +181,7 @@ Slic3rMultiPoint_to_ClipperPath_reversed(const Slic3r::MultiPoint &input)
ClipperLib::Path output;
output.reserve(input.points.size());
for (Slic3r::Points::const_reverse_iterator pit = input.points.rbegin(); pit != input.points.rend(); ++pit)
- output.push_back(ClipperLib::IntPoint( (*pit)(0), (*pit)(1) ));
+ output.emplace_back((*pit)(0), (*pit)(1));
return output;
}
@@ -189,7 +189,7 @@ ClipperLib::Paths Slic3rMultiPoints_to_ClipperPaths(const Polygons &input)
{
ClipperLib::Paths retval;
for (Polygons::const_iterator it = input.begin(); it != input.end(); ++it)
- retval.push_back(Slic3rMultiPoint_to_ClipperPath(*it));
+ retval.emplace_back(Slic3rMultiPoint_to_ClipperPath(*it));
return retval;
}
@@ -197,7 +197,7 @@ ClipperLib::Paths Slic3rMultiPoints_to_ClipperPaths(const Polylines &input)
{
ClipperLib::Paths retval;
for (Polylines::const_iterator it = input.begin(); it != input.end(); ++it)
- retval.push_back(Slic3rMultiPoint_to_ClipperPath(*it));
+ retval.emplace_back(Slic3rMultiPoint_to_ClipperPath(*it));
return retval;
}
@@ -226,7 +226,7 @@ ClipperLib::Paths _offset(ClipperLib::Paths &&input, ClipperLib::EndType endType
ClipperLib::Paths _offset(ClipperLib::Path &&input, ClipperLib::EndType endType, const float delta, ClipperLib::JoinType joinType, double miterLimit)
{
ClipperLib::Paths paths;
- paths.push_back(std::move(input));
+ paths.emplace_back(std::move(input));
return _offset(std::move(paths), endType, delta, joinType, miterLimit);
}
@@ -585,7 +585,7 @@ Polylines _clipper_pl(ClipperLib::ClipType clipType, const Polygons &subject, co
Polylines polylines;
polylines.reserve(subject.size());
for (Polygons::const_iterator polygon = subject.begin(); polygon != subject.end(); ++polygon)
- polylines.push_back(*polygon); // implicit call to split_at_first_point()
+ polylines.emplace_back(polygon->operator Polyline()); // implicit call to split_at_first_point()
// perform clipping
Polylines retval = _clipper_pl(clipType, polylines, clip, safety_offset_);
@@ -643,7 +643,7 @@ _clipper_ln(ClipperLib::ClipType clipType, const Lines &subject, const Polygons
// convert Polylines to Lines
Lines retval;
for (Polylines::const_iterator polyline = polylines.begin(); polyline != polylines.end(); ++polyline)
- retval.push_back(*polyline);
+ retval.emplace_back(polyline->operator Line());
return retval;
}
@@ -673,7 +673,7 @@ void traverse_pt(ClipperLib::PolyNodes &nodes, Polygons* retval)
ordering_points.reserve(nodes.size());
for (ClipperLib::PolyNodes::const_iterator it = nodes.begin(); it != nodes.end(); ++it) {
Point p((*it)->Contour.front().X, (*it)->Contour.front().Y);
- ordering_points.push_back(p);
+ ordering_points.emplace_back(p);
}
// perform the ordering
@@ -684,7 +684,7 @@ void traverse_pt(ClipperLib::PolyNodes &nodes, Polygons* retval)
for (ClipperLib::PolyNodes::iterator it = ordered_nodes.begin(); it != ordered_nodes.end(); ++it) {
// traverse the next depth
traverse_pt((*it)->Childs, retval);
- retval->push_back(ClipperPath_to_Slic3rPolygon((*it)->Contour));
+ retval->emplace_back(ClipperPath_to_Slic3rPolygon((*it)->Contour));
if ((*it)->IsHole()) retval->back().reverse(); // ccw
}
}
@@ -791,8 +791,8 @@ Polygons top_level_islands(const Slic3r::Polygons &polygons)
Polygons out;
out.reserve(polytree.ChildCount());
for (int i = 0; i < polytree.ChildCount(); ++i)
- out.push_back(ClipperPath_to_Slic3rPolygon(polytree.Childs[i]->Contour));
+ out.emplace_back(ClipperPath_to_Slic3rPolygon(polytree.Childs[i]->Contour));
return out;
}
-}
\ No newline at end of file
+}
diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp
index b5b9a008d..ba898d9d5 100644
--- a/src/libslic3r/Model.cpp
+++ b/src/libslic3r/Model.cpp
@@ -1187,8 +1187,9 @@ ModelObjectPtrs ModelObject::cut(size_t instance, coordf_t z, bool keep_upper, b
else {
TriangleMesh upper_mesh, lower_mesh;
- // Transform the mesh by the combined transformation matrix
- volume->mesh.transform(instance_matrix * volume_matrix);
+ // Transform the mesh by the combined transformation matrix.
+ // Flip the triangles in case the composite transformation is left handed.
+ volume->mesh.transform(instance_matrix * volume_matrix, true);
// Perform cut
TriangleMeshSlicer tms(&volume->mesh);
diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp
index 6c04c7781..42c6fbf75 100644
--- a/src/libslic3r/PrintObject.cpp
+++ b/src/libslic3r/PrintObject.cpp
@@ -1790,15 +1790,16 @@ std::vector PrintObject::_slice_volumes(const std::vector &z,
if (! volumes.empty()) {
// Compose mesh.
//FIXME better to perform slicing over each volume separately and then to use a Boolean operation to merge them.
- TriangleMesh mesh;
- for (const ModelVolume *v : volumes)
- {
- TriangleMesh vol_mesh(v->mesh);
- vol_mesh.transform(v->get_matrix());
+ TriangleMesh mesh(volumes.front()->mesh);
+ mesh.transform(volumes.front()->get_matrix(), true);
+ for (size_t idx_volume = 1; idx_volume < volumes.size(); ++ idx_volume) {
+ const ModelVolume &model_volume = *volumes[idx_volume];
+ TriangleMesh vol_mesh(model_volume.mesh);
+ vol_mesh.transform(model_volume.get_matrix(), true);
mesh.merge(vol_mesh);
}
if (mesh.stl.stats.number_of_facets > 0) {
- mesh.transform(m_trafo);
+ mesh.transform(m_trafo, true);
// apply XY shift
mesh.translate(- unscale(m_copies_shift(0)), - unscale(m_copies_shift(1)), 0);
// perform actual slicing
@@ -1819,9 +1820,9 @@ std::vector PrintObject::_slice_volume(const std::vector &z,
// Compose mesh.
//FIXME better to perform slicing over each volume separately and then to use a Boolean operation to merge them.
TriangleMesh mesh(volume.mesh);
- mesh.transform(volume.get_matrix());
+ mesh.transform(volume.get_matrix(), true);
if (mesh.stl.stats.number_of_facets > 0) {
- mesh.transform(m_trafo);
+ mesh.transform(m_trafo, true);
// apply XY shift
mesh.translate(- unscale(m_copies_shift(0)), - unscale(m_copies_shift(1)), 0);
// perform actual slicing
diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp
index 7dc920517..809b32d90 100644
--- a/src/libslic3r/SLAPrint.cpp
+++ b/src/libslic3r/SLAPrint.cpp
@@ -1041,31 +1041,37 @@ void SLAPrint::process()
{
ClipperPolygon poly;
+ // We need to reverse if flpXY OR is_lefthanded is true but
+ // not if both are true which is a logical inequality (XOR)
+ bool needreverse = flpXY != is_lefthanded;
+
// should be a move
poly.Contour.reserve(polygon.contour.size() + 1);
- for(auto& p : polygon.contour.points)
- poly.Contour.emplace_back(p.x(), p.y());
-
- auto pfirst = poly.Contour.front();
- poly.Contour.emplace_back(pfirst);
+ auto& cntr = polygon.contour.points;
+ if(needreverse)
+ for(auto it = cntr.rbegin(); it != cntr.rend(); ++it)
+ poly.Contour.emplace_back(it->x(), it->y());
+ else
+ for(auto& p : cntr)
+ poly.Contour.emplace_back(p.x(), p.y());
for(auto& h : polygon.holes) {
poly.Holes.emplace_back();
auto& hole = poly.Holes.back();
hole.reserve(h.points.size() + 1);
- for(auto& p : h.points) hole.emplace_back(p.x(), p.y());
- auto pfirst = hole.front(); hole.emplace_back(pfirst);
+ if(needreverse)
+ for(auto& p : h.points)
+ hole.emplace_back(p.x(), p.y());
+ else
+ for(auto it = h.points.rbegin(); it != h.points.rend(); ++it)
+ hole.emplace_back(it->x(), it->y());
}
if(is_lefthanded) {
for(auto& p : poly.Contour) p.X = -p.X;
- std::reverse(poly.Contour.begin(), poly.Contour.end());
- for(auto& h : poly.Holes) {
- for(auto& p : h) p.X = -p.X;
- std::reverse(h.begin(), h.end());
- }
+ for(auto& h : poly.Holes) for(auto& p : h) p.X = -p.X;
}
sl::rotate(poly, double(instances[i].rotation));
@@ -1074,12 +1080,7 @@ void SLAPrint::process()
if (flpXY) {
for(auto& p : poly.Contour) std::swap(p.X, p.Y);
- std::reverse(poly.Contour.begin(), poly.Contour.end());
-
- for(auto& h : poly.Holes) {
- for(auto& p : h) std::swap(p.X, p.Y);
- std::reverse(h.begin(), h.end());
- }
+ for(auto& h : poly.Holes) for(auto& p : h) std::swap(p.X, p.Y);
}
polygons.emplace_back(std::move(poly));
diff --git a/src/libslic3r/TriangleMesh.cpp b/src/libslic3r/TriangleMesh.cpp
index c145380c9..0d9a79978 100644
--- a/src/libslic3r/TriangleMesh.cpp
+++ b/src/libslic3r/TriangleMesh.cpp
@@ -314,10 +314,15 @@ void TriangleMesh::mirror(const Axis &axis)
stl_invalidate_shared_vertices(&this->stl);
}
-void TriangleMesh::transform(const Transform3d& t)
+void TriangleMesh::transform(const Transform3d& t, bool fix_left_handed)
{
stl_transform(&stl, t);
stl_invalidate_shared_vertices(&stl);
+ if (fix_left_handed && t.matrix().block(0, 0, 3, 3).determinant() < 0.) {
+ // Left handed transformation is being applied. It is a good idea to flip the faces and their normals.
+ this->repair();
+ stl_reverse_all_facets(&stl);
+ }
}
void TriangleMesh::align_to_origin()
diff --git a/src/libslic3r/TriangleMesh.hpp b/src/libslic3r/TriangleMesh.hpp
index a65a4be75..527846f9d 100644
--- a/src/libslic3r/TriangleMesh.hpp
+++ b/src/libslic3r/TriangleMesh.hpp
@@ -49,7 +49,7 @@ public:
void mirror_x() { this->mirror(X); }
void mirror_y() { this->mirror(Y); }
void mirror_z() { this->mirror(Z); }
- void transform(const Transform3d& t);
+ void transform(const Transform3d& t, bool fix_left_handed = false);
void align_to_origin();
void rotate(double angle, Point* center);
TriangleMeshPtrs split() const;
diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp
index 224bb802e..c0dcc659d 100644
--- a/src/slic3r/GUI/GUI_ObjectList.cpp
+++ b/src/slic3r/GUI/GUI_ObjectList.cpp
@@ -507,7 +507,6 @@ void ObjectList::key_event(wxKeyEvent& event)
|| event.GetKeyCode() == WXK_BACK
#endif //__WXOSX__
) {
- printf("WXK_BACK\n");
remove();
}
else if (wxGetKeyState(wxKeyCode('A')) && wxGetKeyState(WXK_SHIFT))
diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp
index 6c8fdcab7..61e98d542 100644
--- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp
+++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp
@@ -179,7 +179,7 @@ void ObjectManipulation::update_settings_value(const Selection& selection)
changed_box = true;
}
if (changed_box || !m_cache.instance.matches_instance(instance_idx) || !m_cache.scale.isApprox(100.0 * m_new_scale))
- m_new_size = volume->get_instance_transformation().get_matrix(true, true) * m_cache.instance.box_size;
+ m_new_size = (volume->get_instance_transformation().get_matrix(true, true) * m_cache.instance.box_size).cwiseAbs();
}
else
// this should never happen
@@ -209,7 +209,7 @@ void ObjectManipulation::update_settings_value(const Selection& selection)
m_new_position = volume->get_volume_offset();
m_new_rotation = volume->get_volume_rotation();
m_new_scale = volume->get_volume_scaling_factor();
- m_new_size = volume->get_volume_transformation().get_matrix(true, true) * volume->bounding_box.size();
+ m_new_size = (volume->get_volume_transformation().get_matrix(true, true) * volume->bounding_box.size()).cwiseAbs();
m_new_enabled = true;
}
else if (wxGetApp().obj_list()->multiple_selection())
diff --git a/src/slic3r/GUI/GUI_ObjectSettings.cpp b/src/slic3r/GUI/GUI_ObjectSettings.cpp
index 4c0879ad3..cd995bc09 100644
--- a/src/slic3r/GUI/GUI_ObjectSettings.cpp
+++ b/src/slic3r/GUI/GUI_ObjectSettings.cpp
@@ -85,7 +85,8 @@ void ObjectSettings::update_settings_list()
#endif // __WXMSW__
btn->Bind(wxEVT_BUTTON, [opt_key, config, this](wxEvent &event) {
config->erase(opt_key);
- wxTheApp->CallAfter([this]() {
+ wxGetApp().obj_list()->part_settings_changed();
+ wxTheApp->CallAfter([this]() {
wxWindowUpdateLocker noUpdates(m_parent);
update_settings_list();
m_parent->Layout();
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp
index d0e0651be..cb52bccde 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp
@@ -329,8 +329,12 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
m_canvas_width = m_parent.get_canvas_size().get_width();
m_canvas_height = m_parent.get_canvas_size().get_height();
}
- else
- select_point(m_hover_id);
+ else {
+ if (m_editing_mode_cache[m_hover_id].selected)
+ unselect_point(m_hover_id);
+ else
+ select_point(m_hover_id);
+ }
return true;
}
@@ -562,12 +566,12 @@ void GLGizmoSlaSupports::on_render_input_window(float x, float y, float bottom_l
RENDER_AGAIN:
m_imgui->set_next_window_pos(x, y, ImGuiCond_Always);
- const ImVec2 window_size(m_imgui->scaled(15.f, 16.5f));
+ const ImVec2 window_size(m_imgui->scaled(17.f, 18.f));
ImGui::SetNextWindowPos(ImVec2(x, y - std::max(0.f, y+window_size.y-bottom_limit) ));
ImGui::SetNextWindowSize(ImVec2(window_size));
m_imgui->set_next_window_bg_alpha(0.5f);
- m_imgui->begin(on_get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
+ m_imgui->begin(on_get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse);
ImGui::PushItemWidth(100.0f);
@@ -788,6 +792,19 @@ void GLGizmoSlaSupports::select_point(int i)
}
+void GLGizmoSlaSupports::unselect_point(int i)
+{
+ m_editing_mode_cache[i].selected = false;
+ m_selection_empty = true;
+ for (const CacheEntry& ce : m_editing_mode_cache) {
+ if (ce.selected) {
+ m_selection_empty = false;
+ break;
+ }
+ }
+}
+
+
void GLGizmoSlaSupports::editing_mode_discard_changes()
{
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp
index 95af05fd5..126aeab6e 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp
@@ -94,6 +94,7 @@ private:
NoPoints,
};
void select_point(int i);
+ void unselect_point(int i);
void editing_mode_apply_changes();
void editing_mode_discard_changes();
void editing_mode_reload_cache();
diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp
index 2eb6d985f..03c83cf51 100644
--- a/src/slic3r/GUI/ImGuiWrapper.cpp
+++ b/src/slic3r/GUI/ImGuiWrapper.cpp
@@ -341,13 +341,11 @@ bool ImGuiWrapper::want_any_input() const
void ImGuiWrapper::init_font()
{
- const float font_size = m_font_size * m_style_scaling;
-
destroy_font();
ImGuiIO& io = ImGui::GetIO();
io.Fonts->Clear();
- ImFont* font = io.Fonts->AddFontFromFileTTF((Slic3r::resources_dir() + "/fonts/NotoSans-Regular.ttf").c_str(), font_size, nullptr, m_glyph_ranges);
+ ImFont* font = io.Fonts->AddFontFromFileTTF((Slic3r::resources_dir() + "/fonts/NotoSans-Regular.ttf").c_str(), m_font_size, nullptr, m_glyph_ranges);
if (font == nullptr) {
font = io.Fonts->AddFontDefault();
if (font == nullptr) {
diff --git a/src/slic3r/GUI/ImGuiWrapper.hpp b/src/slic3r/GUI/ImGuiWrapper.hpp
index c1bf491e1..b593054c4 100644
--- a/src/slic3r/GUI/ImGuiWrapper.hpp
+++ b/src/slic3r/GUI/ImGuiWrapper.hpp
@@ -45,8 +45,8 @@ public:
void new_frame();
void render();
- float scaled(float x) const { return x * m_font_size * m_style_scaling; }
- ImVec2 scaled(float x, float y) const { return ImVec2(x * m_font_size * m_style_scaling, y * m_font_size * m_style_scaling); }
+ float scaled(float x) const { return x * m_font_size; }
+ ImVec2 scaled(float x, float y) const { return ImVec2(x * m_font_size, y * m_font_size); }
ImVec2 calc_text_size(const wxString &text);
void set_next_window_pos(float x, float y, int flag);
diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp
index bcf9bb61c..0ae6199e1 100644
--- a/src/slic3r/GUI/Selection.cpp
+++ b/src/slic3r/GUI/Selection.cpp
@@ -109,21 +109,26 @@ void Selection::add(unsigned int volume_idx, bool as_single_selection)
if (is_wipe_tower() && volume->is_wipe_tower)
return;
+ bool keep_instance_mode = (m_mode == Instance) && !as_single_selection && (is_single_full_instance() || is_multiple_full_instance());
+
// resets the current list if needed
bool needs_reset = as_single_selection;
needs_reset |= volume->is_wipe_tower;
needs_reset |= is_wipe_tower() && !volume->is_wipe_tower;
- needs_reset |= !is_modifier() && volume->is_modifier;
+ needs_reset |= !keep_instance_mode && !is_modifier() && volume->is_modifier;
needs_reset |= is_modifier() && !volume->is_modifier;
if (needs_reset)
clear();
if (!contains_volume(volume_idx))
- m_mode = volume->is_modifier ? Volume : Instance;
+ {
+ if (!keep_instance_mode)
+ m_mode = volume->is_modifier ? Volume : Instance;
+ }
else
- // keep current mode
- return;
+ // keep current mode
+ return;
switch (m_mode)
{
@@ -1143,16 +1148,12 @@ void Selection::update_type()
}
if (modifiers_count == 0)
- {
m_type = MultipleVolume;
- requires_disable = true;
- }
else if (modifiers_count == (unsigned int)m_list.size())
- {
m_type = MultipleModifier;
- requires_disable = true;
- }
}
+
+ requires_disable = true;
}
else if ((selected_instances_count > 1) && (selected_instances_count * volumes_count == (unsigned int)m_list.size()))
{