diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 4663fe447..7dc920517 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -94,7 +94,7 @@ static Transform3d sla_trafo(const ModelObject &model_object) offset(1) = 0.; rotation(2) = 0.; Transform3d trafo = Geometry::assemble_transform(offset, rotation, model_instance.get_scaling_factor(), model_instance.get_mirror()); - if (model_instance.is_left_handed()) + if (model_instance.is_left_handed()) trafo = Eigen::Scaling(Vec3d(-1., 1., 1.)) * trafo; return trafo; } @@ -105,10 +105,10 @@ static std::vector sla_instances(const ModelObject &mo std::vector instances; for (ModelInstance *model_instance : model_object.instances) if (model_instance->is_printable()) { - instances.emplace_back(SLAPrintObject::Instance( + instances.emplace_back( model_instance->id(), Point::new_scale(model_instance->get_offset(X), model_instance->get_offset(Y)), - float(model_instance->get_rotation(Z)))); + float(model_instance->get_rotation(Z))); } return instances; } @@ -317,8 +317,11 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, const DynamicPrintConf it_print_object_status = print_object_status.end(); // Check whether a model part volume was added or removed, their transformations or order changed. bool model_parts_differ = model_volume_list_changed(model_object, model_object_new, ModelVolumeType::MODEL_PART); - bool sla_trafo_differs = model_object.instances.empty() != model_object_new.instances.empty() || - (! model_object.instances.empty() && ! sla_trafo(model_object).isApprox(sla_trafo(model_object_new))); + bool sla_trafo_differs = + model_object.instances.empty() != model_object_new.instances.empty() || + (! model_object.instances.empty() && + (! sla_trafo(model_object).isApprox(sla_trafo(model_object_new)) || + model_object.instances.front()->is_left_handed() != model_object_new.instances.front()->is_left_handed())); if (model_parts_differ || sla_trafo_differs) { // The very first step (the slicing step) is invalidated. One may freely remove all associated PrintObjects. if (it_print_object_status != print_object_status.end()) { @@ -404,7 +407,7 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, const DynamicPrintConf // which is expensive to calculate (especially the raw_mesh() call) print_object->set_trafo(sla_trafo(model_object), model_object.instances.front()->is_left_handed()); - print_object->set_instances(new_instances); + print_object->set_instances(std::move(new_instances)); print_object->config_apply(config, true); print_objects_new.emplace_back(print_object); new_objects = true; @@ -1025,7 +1028,8 @@ void SLAPrint::process() // get polygons for all instances in the object auto get_all_polygons = [flpXY](const ExPolygons& input_polygons, - const std::vector& instances) + const std::vector& instances, + bool is_lefthanded) { ClipperPolygons polygons; polygons.reserve(input_polygons.size() * instances.size()); @@ -1055,9 +1059,19 @@ void SLAPrint::process() auto pfirst = hole.front(); hole.emplace_back(pfirst); } + 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()); + } + } + sl::rotate(poly, double(instances[i].rotation)); sl::translate(poly, ClipperPoint{instances[i].shift(X), instances[i].shift(Y)}); + if (flpXY) { for(auto& p : poly.Contour) std::swap(p.X, p.Y); std::reverse(poly.Contour.begin(), poly.Contour.end()); @@ -1129,14 +1143,15 @@ void SLAPrint::process() const SLAPrintObject *po = record.print_obj(); const ExPolygons &modelslices = record.get_slice(soModel); + bool is_lefth = record.print_obj()->is_left_handed(); if (!modelslices.empty()) { - ClipperPolygons v = get_all_polygons(modelslices, po->instances()); + ClipperPolygons v = get_all_polygons(modelslices, po->instances(), is_lefth); for(ClipperPolygon& p_tmp : v) model_polygons.emplace_back(std::move(p_tmp)); } const ExPolygons &supportslices = record.get_slice(soSupport); if (!supportslices.empty()) { - ClipperPolygons v = get_all_polygons(supportslices, po->instances()); + ClipperPolygons v = get_all_polygons(supportslices, po->instances(), is_lefth); for(ClipperPolygon& p_tmp : v) supports_polygons.emplace_back(std::move(p_tmp)); } } diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp index c0ab616b0..a1e382acb 100644 --- a/src/libslic3r/SLAPrint.hpp +++ b/src/libslic3r/SLAPrint.hpp @@ -246,7 +246,8 @@ protected: m_transformed_rmesh.invalidate([this, &trafo, left_handed](){ m_trafo = trafo; m_left_handed = left_handed; }); } - void set_instances(const std::vector &instances) { m_instances = instances; } + template inline void set_instances(InstVec&& instances) { m_instances = std::forward(instances); } + // Invalidates the step, and its depending steps in SLAPrintObject and SLAPrint. bool invalidate_step(SLAPrintObjectStep step); bool invalidate_all_steps(); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 6c5d222a1..a2f4e0a03 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3306,12 +3306,12 @@ void GLCanvas3D::_resize(unsigned int w, unsigned int h) auto *imgui = wxGetApp().imgui(); imgui->set_display_size((float)w, (float)h); + const float font_size = 1.5f * wxGetApp().em_unit(); #if ENABLE_RETINA_GL - const float scaling = m_retina_helper->get_scale_factor(); + imgui->set_scaling(font_size, 1.0f, m_retina_helper->get_scale_factor()); #else - const float scaling = m_canvas->GetContentScaleFactor(); + imgui->set_scaling(font_size, m_canvas->GetContentScaleFactor(), 1.0f); #endif - imgui->set_scaling(m_canvas->GetFont().GetPixelSize().y, scaling); // ensures that this canvas is current _set_current(); @@ -3945,17 +3945,25 @@ void GLCanvas3D::_render_sla_slices() const if (obj->is_left_handed()) // The polygons are mirrored by X. glsafe(::glScalef(-1.0, 1.0, 1.0)); - glsafe(::glColor3f(1.0f, 0.37f, 0.0f)); glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); - glsafe(::glVertexPointer(3, GL_DOUBLE, 0, (GLdouble*)bottom_obj_triangles.front().data())); - glsafe(::glDrawArrays(GL_TRIANGLES, 0, bottom_obj_triangles.size())); - glsafe(::glVertexPointer(3, GL_DOUBLE, 0, (GLdouble*)top_obj_triangles.front().data())); - glsafe(::glDrawArrays(GL_TRIANGLES, 0, top_obj_triangles.size())); + glsafe(::glColor3f(1.0f, 0.37f, 0.0f)); + if (!bottom_obj_triangles.empty()) { + glsafe(::glVertexPointer(3, GL_DOUBLE, 0, (GLdouble*)bottom_obj_triangles.front().data())); + glsafe(::glDrawArrays(GL_TRIANGLES, 0, bottom_obj_triangles.size())); + } + if (! top_obj_triangles.empty()) { + glsafe(::glVertexPointer(3, GL_DOUBLE, 0, (GLdouble*)top_obj_triangles.front().data())); + glsafe(::glDrawArrays(GL_TRIANGLES, 0, top_obj_triangles.size())); + } glsafe(::glColor3f(1.0f, 0.0f, 0.37f)); - glsafe(::glVertexPointer(3, GL_DOUBLE, 0, (GLdouble*)bottom_sup_triangles.front().data())); - glsafe(::glDrawArrays(GL_TRIANGLES, 0, bottom_sup_triangles.size())); - glsafe(::glVertexPointer(3, GL_DOUBLE, 0, (GLdouble*)top_sup_triangles.front().data())); - glsafe(::glDrawArrays(GL_TRIANGLES, 0, top_sup_triangles.size())); + if (! bottom_sup_triangles.empty()) { + glsafe(::glVertexPointer(3, GL_DOUBLE, 0, (GLdouble*)bottom_sup_triangles.front().data())); + glsafe(::glDrawArrays(GL_TRIANGLES, 0, bottom_sup_triangles.size())); + } + if (! top_sup_triangles.empty()) { + glsafe(::glVertexPointer(3, GL_DOUBLE, 0, (GLdouble*)top_sup_triangles.front().data())); + glsafe(::glDrawArrays(GL_TRIANGLES, 0, top_sup_triangles.size())); + } glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); glsafe(::glPopMatrix()); } diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 0e3fb6c7a..2eb6d985f 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -93,16 +93,19 @@ void ImGuiWrapper::set_display_size(float w, float h) io.DisplayFramebufferScale = ImVec2(1.0f, 1.0f); } -void ImGuiWrapper::set_scaling(float font_size, float scaling) +void ImGuiWrapper::set_scaling(float font_size, float scale_style, float scale_both) { - if (m_font_size == font_size && m_style_scaling == scaling) { + font_size *= scale_both; + scale_style *= scale_both; + + if (m_font_size == font_size && m_style_scaling == scale_style) { return; } m_font_size = font_size; - ImGui::GetStyle().ScaleAllSizes(scaling / m_style_scaling); - m_style_scaling = scaling; + ImGui::GetStyle().ScaleAllSizes(scale_style / m_style_scaling); + m_style_scaling = scale_style; destroy_font(); } diff --git a/src/slic3r/GUI/ImGuiWrapper.hpp b/src/slic3r/GUI/ImGuiWrapper.hpp index 84a60e3d1..c1bf491e1 100644 --- a/src/slic3r/GUI/ImGuiWrapper.hpp +++ b/src/slic3r/GUI/ImGuiWrapper.hpp @@ -35,7 +35,7 @@ public: void set_language(const std::string &language); void set_display_size(float w, float h); - void set_scaling(float font_size, float scaling); + void set_scaling(float font_size, float scale_style, float scale_both); bool update_mouse_data(wxMouseEvent &evt); bool update_key_data(wxKeyEvent &evt);