diff --git a/src/libslic3r/ExPolygon.cpp b/src/libslic3r/ExPolygon.cpp index 00bb4ffe4e..f9c470450c 100644 --- a/src/libslic3r/ExPolygon.cpp +++ b/src/libslic3r/ExPolygon.cpp @@ -310,16 +310,15 @@ ExPolygon::medial_axis(double max_width, double min_width, Polylines* polylines) polylines->insert(polylines->end(), tp.begin(), tp.end()); } -void -ExPolygon::get_trapezoids(Polygons* polygons) const +/* +void ExPolygon::get_trapezoids(Polygons* polygons) const { ExPolygons expp; expp.push_back(*this); boost::polygon::get_trapezoids(*polygons, expp); } -void -ExPolygon::get_trapezoids(Polygons* polygons, double angle) const +void ExPolygon::get_trapezoids(Polygons* polygons, double angle) const { ExPolygon clone = *this; clone.rotate(PI/2 - angle, Point(0,0)); @@ -327,12 +326,12 @@ ExPolygon::get_trapezoids(Polygons* polygons, double angle) const for (Polygons::iterator polygon = polygons->begin(); polygon != polygons->end(); ++polygon) polygon->rotate(-(PI/2 - angle), Point(0,0)); } +*/ // This algorithm may return more trapezoids than necessary // (i.e. it may break a single trapezoid in several because // other parts of the object have x coordinates in the middle) -void -ExPolygon::get_trapezoids2(Polygons* polygons) const +void ExPolygon::get_trapezoids2(Polygons* polygons) const { // get all points of this ExPolygon Points pp = *this; @@ -370,8 +369,7 @@ ExPolygon::get_trapezoids2(Polygons* polygons) const } } -void -ExPolygon::get_trapezoids2(Polygons* polygons, double angle) const +void ExPolygon::get_trapezoids2(Polygons* polygons, double angle) const { ExPolygon clone = *this; clone.rotate(PI/2 - angle, Point(0,0)); @@ -382,8 +380,7 @@ ExPolygon::get_trapezoids2(Polygons* polygons, double angle) const // While this triangulates successfully, it's NOT a constrained triangulation // as it will create more vertices on the boundaries than the ones supplied. -void -ExPolygon::triangulate(Polygons* polygons) const +void ExPolygon::triangulate(Polygons* polygons) const { // first make trapezoids Polygons trapezoids; @@ -394,8 +391,8 @@ ExPolygon::triangulate(Polygons* polygons) const polygon->triangulate_convex(polygons); } -void -ExPolygon::triangulate_pp(Polygons* polygons) const +/* +void ExPolygon::triangulate_pp(Polygons* polygons) const { // convert polygons std::list input; @@ -452,9 +449,113 @@ ExPolygon::triangulate_pp(Polygons* polygons) const polygons->push_back(p); } } +*/ -void -ExPolygon::triangulate_p2t(Polygons* polygons) const +std::list expoly_to_polypartition_input(const ExPolygon &ex) +{ + std::list input; + // contour + { + input.emplace_back(); + TPPLPoly &p = input.back(); + p.Init(int(ex.contour.points.size())); + for (const Point &point : ex.contour.points) { + size_t i = &point - &ex.contour.points.front(); + p[i].x = point(0); + p[i].y = point(1); + } + p.SetHole(false); + } + // holes + for (const Polygon &hole : ex.holes) { + input.emplace_back(); + TPPLPoly &p = input.back(); + p.Init(hole.points.size()); + for (const Point &point : hole.points) { + size_t i = &point - &hole.points.front(); + p[i].x = point(0); + p[i].y = point(1); + } + p.SetHole(true); + } + return input; +} + +std::list expoly_to_polypartition_input(const ExPolygons &expps) +{ + std::list input; + for (const ExPolygon &ex : expps) { + // contour + { + input.emplace_back(); + TPPLPoly &p = input.back(); + p.Init(int(ex.contour.points.size())); + for (const Point &point : ex.contour.points) { + size_t i = &point - &ex.contour.points.front(); + p[i].x = point(0); + p[i].y = point(1); + } + p.SetHole(false); + } + // holes + for (const Polygon &hole : ex.holes) { + input.emplace_back(); + TPPLPoly &p = input.back(); + p.Init(hole.points.size()); + for (const Point &point : hole.points) { + size_t i = &point - &hole.points.front(); + p[i].x = point(0); + p[i].y = point(1); + } + p.SetHole(true); + } + } + return input; +} + +std::vector polypartition_output_to_triangles(const std::list &output) +{ + size_t num_triangles = 0; + for (const TPPLPoly &poly : output) + if (poly.GetNumPoints() >= 3) + num_triangles += (size_t)poly.GetNumPoints() - 2; + std::vector triangles; + triangles.reserve(triangles.size() + num_triangles * 3); + for (const TPPLPoly &poly : output) { + long num_points = poly.GetNumPoints(); + if (num_points >= 3) { + const TPPLPoint *pt0 = &poly[0]; + const TPPLPoint *pt1 = nullptr; + const TPPLPoint *pt2 = &poly[1]; + for (long i = 2; i < num_points; ++ i) { + pt1 = pt2; + pt2 = &poly[i]; + triangles.emplace_back(coord_t(pt0->x), coord_t(pt0->y)); + triangles.emplace_back(coord_t(pt1->x), coord_t(pt1->y)); + triangles.emplace_back(coord_t(pt2->x), coord_t(pt2->y)); + } + } + } + return triangles; +} + +void ExPolygon::triangulate_pp(Points *triangles) const +{ + ExPolygons expp = union_ex(simplify_polygons(to_polygons(*this), true)); + std::list input = expoly_to_polypartition_input(expp); + // perform triangulation + std::list output; + int res = TPPLPartition().Triangulate_MONO(&input, &output); +// int TPPLPartition::Triangulate_EC(TPPLPolyList *inpolys, TPPLPolyList *triangles) { + if (res != 1) + throw std::runtime_error("Triangulation failed"); + *triangles = polypartition_output_to_triangles(output); +} + +// Uses the Poly2tri library maintained by Jan Niklas Hasse @jhasse // https://github.com/jhasse/poly2tri +// See https://github.com/jhasse/poly2tri/blob/master/README.md for the limitations of the library! +// No duplicate points are allowed, no very close points, holes must not touch outer contour etc. +void ExPolygon::triangulate_p2t(Polygons* polygons) const { ExPolygons expp = simplify_polygons_ex(*this, true); @@ -478,16 +579,21 @@ ExPolygon::triangulate_p2t(Polygons* polygons) const } // perform triangulation - cdt.Triangulate(); - std::vector triangles = cdt.GetTriangles(); - - for (std::vector::const_iterator triangle = triangles.begin(); triangle != triangles.end(); ++triangle) { - Polygon p; - for (int i = 0; i <= 2; ++i) { - p2t::Point* point = (*triangle)->GetPoint(i); - p.points.push_back(Point(point->x, point->y)); + try { + cdt.Triangulate(); + std::vector triangles = cdt.GetTriangles(); + + for (std::vector::const_iterator triangle = triangles.begin(); triangle != triangles.end(); ++triangle) { + Polygon p; + for (int i = 0; i <= 2; ++i) { + p2t::Point* point = (*triangle)->GetPoint(i); + p.points.push_back(Point(point->x, point->y)); + } + polygons->push_back(p); } - polygons->push_back(p); + } catch (const std::runtime_error & /* err */) { + assert(false); + // just ignore, don't triangulate } for (p2t::Point *ptr : ContourPoints) @@ -495,8 +601,7 @@ ExPolygon::triangulate_p2t(Polygons* polygons) const } } -Lines -ExPolygon::lines() const +Lines ExPolygon::lines() const { Lines lines = this->contour.lines(); for (Polygons::const_iterator h = this->holes.begin(); h != this->holes.end(); ++h) { diff --git a/src/libslic3r/ExPolygon.hpp b/src/libslic3r/ExPolygon.hpp index 4833ee49ec..afbc0931e7 100644 --- a/src/libslic3r/ExPolygon.hpp +++ b/src/libslic3r/ExPolygon.hpp @@ -6,6 +6,9 @@ #include "Polyline.hpp" #include +// polygon class of the polypartition library +class TPPLPoly; + namespace Slic3r { class ExPolygon; @@ -55,12 +58,13 @@ public: void simplify(double tolerance, ExPolygons* expolygons) const; void medial_axis(double max_width, double min_width, ThickPolylines* polylines) const; void medial_axis(double max_width, double min_width, Polylines* polylines) const; - void get_trapezoids(Polygons* polygons) const; - void get_trapezoids(Polygons* polygons, double angle) const; +// void get_trapezoids(Polygons* polygons) const; +// void get_trapezoids(Polygons* polygons, double angle) const; void get_trapezoids2(Polygons* polygons) const; void get_trapezoids2(Polygons* polygons, double angle) const; void triangulate(Polygons* polygons) const; - void triangulate_pp(Polygons* polygons) const; + // Triangulate into triples of points. + void triangulate_pp(Points *triangles) const; void triangulate_p2t(Polygons* polygons) const; Lines lines() const; }; @@ -297,6 +301,10 @@ extern std::vector get_extents_vector(const ExPolygons &polygons); extern bool remove_sticks(ExPolygon &poly); +extern std::list expoly_to_polypartition_input(const ExPolygons &expp); +extern std::list expoly_to_polypartition_input(const ExPolygon &ex); +extern std::vector polypartition_output_to_triangles(const std::list &output); + } // namespace Slic3r // start Boost diff --git a/src/libslic3r/TriangleMesh.cpp b/src/libslic3r/TriangleMesh.cpp index ff8c202894..4648b95c0e 100644 --- a/src/libslic3r/TriangleMesh.cpp +++ b/src/libslic3r/TriangleMesh.cpp @@ -41,7 +41,7 @@ namespace Slic3r { -TriangleMesh::TriangleMesh(const Pointf3s &points, const std::vector& facets ) +TriangleMesh::TriangleMesh(const Pointf3s &points, const std::vector& facets) : repaired(false) { stl_initialize(&this->stl); diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index c6265f2756..6e2cbc588f 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -1995,7 +1995,7 @@ bool GLBed::on_init_from_file(const std::string& filename, bool useVBOs) { model = Model::read_from_file(filename); } - catch (std::exception &e) + catch (std::exception & /* ex */) { return false; } @@ -2014,7 +2014,7 @@ bool GLBed::on_init_from_file(const std::string& filename, bool useVBOs) else m_volume.indexed_vertex_array.load_mesh_flat_shading(mesh); - float color[4] = { 0.235f, 0.235, 0.235f, 1.0f }; + float color[4] = { 0.235f, 0.235f, 0.235f, 1.0f }; set_color(color, 4); m_volume.bounding_box = m_volume.indexed_vertex_array.bounding_box(); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 63b9864b71..9c3a29536a 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2,6 +2,7 @@ #include "GLCanvas3D.hpp" #include "admesh/stl.h" +#include "polypartition.h" #include "libslic3r/libslic3r.h" #include "libslic3r/ClipperUtils.hpp" #include "libslic3r/PrintConfig.hpp" @@ -6538,6 +6539,219 @@ void GLCanvas3D::_render_camera_target() const } #endif // ENABLE_SHOW_CAMERA_TARGET +class TessWrapper { +public: + static Pointf3s tesselate(const ExPolygon &expoly, double z_, bool flipped_) + { + z = z_; + flipped = flipped_; + triangles.clear(); + intersection_points.clear(); + std::vector coords; + { + size_t num_coords = expoly.contour.points.size(); + for (const Polygon &poly : expoly.holes) + num_coords += poly.points.size(); + coords.reserve(num_coords * 3); + } + GLUtesselator *tess = gluNewTess(); // create a tessellator + // register callback functions + gluTessCallback(tess, GLU_TESS_BEGIN, (void(__stdcall*)(void))tessBeginCB); + gluTessCallback(tess, GLU_TESS_END, (void(__stdcall*)(void))tessEndCB); + gluTessCallback(tess, GLU_TESS_ERROR, (void(__stdcall*)(void))tessErrorCB); + gluTessCallback(tess, GLU_TESS_VERTEX, (void(__stdcall*)())tessVertexCB); + gluTessCallback(tess, GLU_TESS_COMBINE, (void (__stdcall*)(void))tessCombineCB); + gluTessBeginPolygon(tess, 0); // with NULL data + gluTessBeginContour(tess); + for (const Point &pt : expoly.contour.points) { + coords.emplace_back(unscale(pt[0])); + coords.emplace_back(unscale(pt[1])); + coords.emplace_back(0.); + gluTessVertex(tess, &coords[coords.size() - 3], &coords[coords.size() - 3]); + } + gluTessEndContour(tess); + for (const Polygon &poly : expoly.holes) { + gluTessBeginContour(tess); + for (const Point &pt : poly.points) { + coords.emplace_back(unscale(pt[0])); + coords.emplace_back(unscale(pt[1])); + coords.emplace_back(0.); + gluTessVertex(tess, &coords[coords.size() - 3], &coords[coords.size() - 3]); + } + gluTessEndContour(tess); + } + gluTessEndPolygon(tess); + gluDeleteTess(tess); + return std::move(triangles); + } + +private: + static void tessBeginCB(GLenum which) + { + assert(which == GL_TRIANGLES || which == GL_TRIANGLE_FAN || which == GL_TRIANGLE_STRIP); + if (!(which == GL_TRIANGLES || which == GL_TRIANGLE_FAN || which == GL_TRIANGLE_STRIP)) + printf("Co je to za haluz!?\n"); + primitive_type = which; + num_points = 0; + } + + static void tessEndCB() + { + num_points = 0; + } + + static void tessVertexCB(const GLvoid *data) + { + if (data == nullptr) + return; + const GLdouble *ptr = (const GLdouble*)data; + ++ num_points; + if (num_points == 1) { + memcpy(pt0, ptr, sizeof(GLdouble) * 3); + } else if (num_points == 2) { + memcpy(pt1, ptr, sizeof(GLdouble) * 3); + } else { + bool flip = flipped; + if (primitive_type == GL_TRIANGLE_STRIP && num_points == 4) { + flip = !flip; + num_points = 2; + } + triangles.emplace_back(pt0[0], pt0[1], z); + if (flip) { + triangles.emplace_back(ptr[0], ptr[1], z); + triangles.emplace_back(pt1[0], pt1[1], z); + } else { + triangles.emplace_back(pt1[0], pt1[1], z); + triangles.emplace_back(ptr[0], ptr[1], z); + } + if (primitive_type == GL_TRIANGLE_STRIP) { + memcpy(pt0, pt1, sizeof(GLdouble) * 3); + memcpy(pt1, ptr, sizeof(GLdouble) * 3); + } else if (primitive_type == GL_TRIANGLE_FAN) { + memcpy(pt1, ptr, sizeof(GLdouble) * 3); + } else { + assert(which == GL_TRIANGLES); + assert(num_points == 3); + num_points = 0; + } + } + } + + static void tessCombineCB(const GLdouble newVertex[3], const GLdouble *neighborVertex[4], const GLfloat neighborWeight[4], GLdouble **outData) + { + intersection_points.emplace_back(newVertex[0], newVertex[1], newVertex[2]); + *outData = intersection_points.back().data(); + } + + static void tessErrorCB(GLenum errorCode) + { + const GLubyte *errorStr; + errorStr = gluErrorString(errorCode); + printf("Error: %s\n", (const char*)errorStr); + } + + static GLenum primitive_type; + static GLdouble pt0[3]; + static GLdouble pt1[3]; + static int num_points; + static Pointf3s triangles; + static std::deque intersection_points; + static double z; + static bool flipped; +}; + +GLenum TessWrapper::primitive_type; +GLdouble TessWrapper::pt0[3]; +GLdouble TessWrapper::pt1[3]; +int TessWrapper::num_points; +Pointf3s TessWrapper::triangles; +std::deque TessWrapper::intersection_points; +double TessWrapper::z; +bool TessWrapper::flipped; + +static Pointf3s triangulate_expolygons(const ExPolygons &polys, coordf_t z, bool flip) +{ + Pointf3s triangles; +#if 0 + for (const ExPolygon& poly : polys) { + Polygons poly_triangles; + // poly.triangulate() is based on a trapezoidal decomposition implemented in an extremely expensive way by clipping the whole input contour with a polygon! + poly.triangulate(&poly_triangles); + // poly.triangulate_p2t() is based on the poly2tri library, which is not quite stable, it often ends up in a nice stack overflow! + // poly.triangulate_p2t(&poly_triangles); + for (const Polygon &t : poly_triangles) + if (flip) { + triangles.emplace_back(to_3d(unscale(t.points[2]), z)); + triangles.emplace_back(to_3d(unscale(t.points[1]), z)); + triangles.emplace_back(to_3d(unscale(t.points[0]), z)); + } else { + triangles.emplace_back(to_3d(unscale(t.points[0]), z)); + triangles.emplace_back(to_3d(unscale(t.points[1]), z)); + triangles.emplace_back(to_3d(unscale(t.points[2]), z)); + } + } +#else + +// for (const ExPolygon &poly : union_ex(simplify_polygons(to_polygons(polys), true))) { + for (const ExPolygon &poly : polys) { + append(triangles, TessWrapper::tesselate(poly, z, flip)); + continue; + + std::list input = expoly_to_polypartition_input(poly); + std::list output; + // int res = TPPLPartition().Triangulate_MONO(&input, &output); + int res = TPPLPartition().Triangulate_EC(&input, &output); + if (res == 1) { + // Triangulation succeeded. Convert to triangles. + size_t num_triangles = 0; + for (const TPPLPoly &poly : output) + if (poly.GetNumPoints() >= 3) + num_triangles += (size_t)poly.GetNumPoints() - 2; + triangles.reserve(triangles.size() + num_triangles * 3); + for (const TPPLPoly &poly : output) { + long num_points = poly.GetNumPoints(); + if (num_points >= 3) { + const TPPLPoint *pt0 = &poly[0]; + const TPPLPoint *pt1 = nullptr; + const TPPLPoint *pt2 = &poly[1]; + for (long i = 2; i < num_points; ++i) { + pt1 = pt2; + pt2 = &poly[i]; + if (flip) { + triangles.emplace_back(unscale(pt2->x), unscale(pt2->y), z); + triangles.emplace_back(unscale(pt1->x), unscale(pt1->y), z); + triangles.emplace_back(unscale(pt0->x), unscale(pt0->y), z); + } else { + triangles.emplace_back(unscale(pt0->x), unscale(pt0->y), z); + triangles.emplace_back(unscale(pt1->x), unscale(pt1->y), z); + triangles.emplace_back(unscale(pt2->x), unscale(pt2->y), z); + } + } + } + } + } else { + // Triangulation by polypartition failed. Use the expensive slow implementation. + Polygons poly_triangles; + // poly.triangulate() is based on a trapezoidal decomposition implemented in an extremely expensive way by clipping the whole input contour with a polygon! + poly.triangulate(&poly_triangles); + // poly.triangulate_p2t() is based on the poly2tri library, which is not quite stable, it often ends up in a nice stack overflow! + // poly.triangulate_p2t(&poly_triangles); + for (const Polygon &t : poly_triangles) + if (flip) { + triangles.emplace_back(to_3d(unscale(t.points[2]), z)); + triangles.emplace_back(to_3d(unscale(t.points[1]), z)); + triangles.emplace_back(to_3d(unscale(t.points[0]), z)); + } else { + triangles.emplace_back(to_3d(unscale(t.points[0]), z)); + triangles.emplace_back(to_3d(unscale(t.points[1]), z)); + triangles.emplace_back(to_3d(unscale(t.points[2]), z)); + } + } + } +#endif + return triangles; +} + void GLCanvas3D::_render_sla_slices() const { if (!m_use_clipping_planes || wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() != ptSLA) @@ -6555,34 +6769,32 @@ void GLCanvas3D::_render_sla_slices() const { const SLAPrintObject* obj = print_objects[i]; - Pointf3s bottom_obj_triangles; - Pointf3s bottom_sup_triangles; - Pointf3s top_obj_triangles; - Pointf3s top_sup_triangles; - double shift_z = obj->get_current_elevation(); double min_z = clip_min_z - shift_z; double max_z = clip_max_z - shift_z; - if (m_sla_caps[0].matches(min_z)) + SlaCap::ObjectIdToTrianglesMap::iterator it_caps_bottom = m_sla_caps[0].triangles.find(i); + SlaCap::ObjectIdToTrianglesMap::iterator it_caps_top = m_sla_caps[1].triangles.find(i); { - SlaCap::ObjectIdToTrianglesMap::const_iterator it = m_sla_caps[0].triangles.find(i); - if (it != m_sla_caps[0].triangles.end()) - { - bottom_obj_triangles = it->second.object; - bottom_sup_triangles = it->second.suppports; - } - } - - if (m_sla_caps[1].matches(max_z)) - { - SlaCap::ObjectIdToTrianglesMap::const_iterator it = m_sla_caps[1].triangles.find(i); - if (it != m_sla_caps[1].triangles.end()) - { - top_obj_triangles = it->second.object; - top_sup_triangles = it->second.suppports; + if (it_caps_bottom == m_sla_caps[0].triangles.end()) + it_caps_bottom = m_sla_caps[0].triangles.emplace(i, SlaCap::Triangles()).first; + if (! m_sla_caps[0].matches(min_z)) { + m_sla_caps[0].z = min_z; + it_caps_bottom->second.object.clear(); + it_caps_bottom->second.supports.clear(); + } + if (it_caps_top == m_sla_caps[1].triangles.end()) + it_caps_top = m_sla_caps[1].triangles.emplace(i, SlaCap::Triangles()).first; + if (! m_sla_caps[1].matches(max_z)) { + m_sla_caps[1].z = max_z; + it_caps_top->second.object.clear(); + it_caps_top->second.supports.clear(); } } + Pointf3s &bottom_obj_triangles = it_caps_bottom->second.object; + Pointf3s &bottom_sup_triangles = it_caps_bottom->second.supports; + Pointf3s &top_obj_triangles = it_caps_top->second.object; + Pointf3s &top_sup_triangles = it_caps_top->second.supports; const std::vector& instances = obj->instances(); struct InstanceTransform @@ -6608,86 +6820,22 @@ void GLCanvas3D::_render_sla_slices() const if (it_min_z != index.end()) { + // calculate model bottom cap if (bottom_obj_triangles.empty() && (it_min_z->second.model_slices_idx < model_slices.size())) - { - // calculate model bottom cap - const ExPolygons& polys = model_slices[it_min_z->second.model_slices_idx]; - for (const ExPolygon& poly : polys) - { - Polygons poly_triangles; - poly.triangulate(&poly_triangles); - for (const Polygon& t : poly_triangles) - { - for (int v = 2; v >= 0; --v) - { - bottom_obj_triangles.emplace_back(to_3d(unscale(t.points[v]), min_z)); - } - } - } - } - + bottom_obj_triangles = triangulate_expolygons(model_slices[it_min_z->second.model_slices_idx], min_z, true); + // calculate support bottom cap if (bottom_sup_triangles.empty() && (it_min_z->second.support_slices_idx < support_slices.size())) - { - // calculate support bottom cap - const ExPolygons& polys = support_slices[it_min_z->second.support_slices_idx]; - for (const ExPolygon& poly : polys) - { - Polygons poly_triangles; - poly.triangulate(&poly_triangles); - for (const Polygon& t : poly_triangles) - { - for (int v = 2; v >= 0; --v) - { - bottom_sup_triangles.emplace_back(to_3d(unscale(t.points[v]), min_z)); - } - } - } - - m_sla_caps[0].triangles.insert(SlaCap::ObjectIdToTrianglesMap::value_type(i, { bottom_obj_triangles, bottom_sup_triangles })); - m_sla_caps[0].z = min_z; - } + bottom_sup_triangles = triangulate_expolygons(support_slices[it_min_z->second.support_slices_idx], min_z, true); } if (it_max_z != index.end()) { + // calculate model top cap if (top_obj_triangles.empty() && (it_max_z->second.model_slices_idx < model_slices.size())) - { - // calculate model top cap - const ExPolygons& polys = model_slices[it_max_z->second.model_slices_idx]; - for (const ExPolygon& poly : polys) - { - Polygons poly_triangles; - poly.triangulate(&poly_triangles); - for (const Polygon& t : poly_triangles) - { - for (int v = 0; v < 3; ++v) - { - top_obj_triangles.emplace_back(to_3d(unscale(t.points[v]), max_z)); - } - } - } - } - + top_obj_triangles = triangulate_expolygons(model_slices[it_max_z->second.model_slices_idx], max_z, false); + // calculate support top cap if (top_sup_triangles.empty() && (it_max_z->second.support_slices_idx < support_slices.size())) - { - // calculate support top cap - const ExPolygons& polys = support_slices[it_max_z->second.support_slices_idx]; - for (const ExPolygon& poly : polys) - { - Polygons poly_triangles; - poly.triangulate(&poly_triangles); - for (const Polygon& t : poly_triangles) - { - for (int v = 0; v < 3; ++v) - { - top_sup_triangles.emplace_back(to_3d(unscale(t.points[v]), max_z)); - } - } - } - } - - m_sla_caps[1].triangles.insert(SlaCap::ObjectIdToTrianglesMap::value_type(i, { top_obj_triangles, top_sup_triangles })); - m_sla_caps[1].z = max_z; + top_sup_triangles = triangulate_expolygons(support_slices[it_max_z->second.support_slices_idx], max_z, false); } } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index ab53d50481..1ca9c234f9 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -790,7 +790,7 @@ private: struct Triangles { Pointf3s object; - Pointf3s suppports; + Pointf3s supports; }; typedef std::map ObjectIdToTrianglesMap; double z; diff --git a/src/slic3r/GUI/GUI.cpp b/src/slic3r/GUI/GUI.cpp index 0ff4ed161a..148285e86e 100644 --- a/src/slic3r/GUI/GUI.cpp +++ b/src/slic3r/GUI/GUI.cpp @@ -245,8 +245,6 @@ void show_info(wxWindow* parent, const wxString& message, const wxString& title) void warning_catcher(wxWindow* parent, const wxString& message) { - if (message == "GLUquadricObjPtr | " + _(L("Attempt to free unreferenced scalar")) ) - return; wxMessageDialog msg(parent, message, _(L("Warning")), wxOK | wxICON_WARNING); msg.ShowModal(); }