diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 5a05589776..37e1f4a1bc 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -943,7 +943,7 @@ BoundingBoxf3 ModelObject::instance_bounding_box(size_t instance_idx, bool dont_ // Calculate 2D convex hull of of a projection of the transformed printable volumes into the XY plane. // This method is cheap in that it does not make any unnecessary copy of the volume meshes. // This method is used by the auto arrange function. -Polygon ModelObject::convex_hull_2d(const Transform3d &trafo_instance) +Polygon ModelObject::convex_hull_2d(const Transform3d &trafo_instance) const { Points pts; for (const ModelVolume *v : this->volumes) diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 1234102e0f..80187d259f 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -234,7 +234,7 @@ public: // Calculate 2D convex hull of of a projection of the transformed printable volumes into the XY plane. // This method is cheap in that it does not make any unnecessary copy of the volume meshes. // This method is used by the auto arrange function. - Polygon convex_hull_2d(const Transform3d &trafo_instance); + Polygon convex_hull_2d(const Transform3d &trafo_instance) const; #if ENABLE_VOLUMES_CENTERING_FIXES void center_around_origin(bool include_modifiers = true); diff --git a/src/libslic3r/ModelArrange.cpp b/src/libslic3r/ModelArrange.cpp index 54627ba86b..50901da3ac 100644 --- a/src/libslic3r/ModelArrange.cpp +++ b/src/libslic3r/ModelArrange.cpp @@ -1,5 +1,6 @@ #include "ModelArrange.hpp" #include "Model.hpp" +#include "Geometry.hpp" #include "SVG.hpp" #include @@ -551,7 +552,7 @@ ShapeData2D projectModelFromTop(const Slic3r::Model &model) { ret.reserve(s); for(ModelObject* objptr : model.objects) { - if(objptr) { + if (! objptr->instances.empty()) { // TODO export the exact 2D projection. Cannot do it as libnest2d // does not support concave shapes (yet). @@ -572,23 +573,23 @@ ShapeData2D projectModelFromTop(const Slic3r::Model &model) { clpath = Slic3rMultiPoint_to_ClipperPath(p); } + Vec3d rotation0 = objptr->instances.front()->get_rotation(); + rotation0(2) = 0.; for(ModelInstance* objinst : objptr->instances) { - if(objinst) { - ClipperLib::Polygon pn; - pn.Contour = clpath; + ClipperLib::Polygon pn; + pn.Contour = clpath; - // Efficient conversion to item. - Item item(std::move(pn)); + // Efficient conversion to item. + Item item(std::move(pn)); - // Invalid geometries would throw exceptions when arranging - if(item.vertexCount() > 3) { - item.rotation(objinst->get_rotation(Z)); - item.translation({ - ClipperLib::cInt(objinst->get_offset(X)/SCALING_FACTOR), - ClipperLib::cInt(objinst->get_offset(Y)/SCALING_FACTOR) - }); - ret.emplace_back(objinst, item); - } + // Invalid geometries would throw exceptions when arranging + if(item.vertexCount() > 3) { + item.rotation(float(Geometry::rotation_diff_z(rotation0, objinst->get_rotation()))), + item.translation({ + ClipperLib::cInt(objinst->get_offset(X)/SCALING_FACTOR), + ClipperLib::cInt(objinst->get_offset(Y)/SCALING_FACTOR) + }); + ret.emplace_back(objinst, item); } } } diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index c13f0bc2a3..0637ba7f0d 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1139,31 +1139,29 @@ std::string Print::validate() const // Check horizontal clearance. { Polygons convex_hulls_other; - for (const PrintObject *object : m_objects) { + for (const PrintObject *print_object : m_objects) { + assert(! print_object->model_object()->instances.empty()); + assert(! print_object->copies().empty()); // Get convex hull of all meshes assigned to this print object. - Polygon convex_hull; - { - Polygons mesh_convex_hulls; - for (const std::vector &volumes : object->region_volumes) - for (int volume_id : volumes) - mesh_convex_hulls.emplace_back(object->model_object()->volumes[volume_id]->mesh.convex_hull()); - // make a single convex hull for all of them - convex_hull = Slic3r::Geometry::convex_hull(mesh_convex_hulls); - } - // Apply the same transformations we apply to the actual meshes when slicing them. - object->model_object()->instances.front()->transform_polygon(&convex_hull); + ModelInstance *model_instance0 = print_object->model_object()->instances.front(); + Vec3d rotation = model_instance0->get_rotation(); + rotation.z() = 0.; + // Calculate the convex hull of a printable object centered around X=0,Y=0. // Grow convex hull with the clearance margin. // FIXME: Arrangement has different parameters for offsetting (jtMiter, limit 2) // which causes that the warning will be showed after arrangement with the // appropriate object distance. Even if I set this to jtMiter the warning still shows up. - convex_hull = offset(convex_hull, scale_(m_config.extruder_clearance_radius.value)/2, jtRound, scale_(0.1)).front(); + Polygon convex_hull0 = offset( + print_object->model_object()->convex_hull_2d( + Geometry::assemble_transform(Vec3d::Zero(), rotation, model_instance0->get_scaling_factor(), model_instance0->get_mirror())), + scale_(m_config.extruder_clearance_radius.value) / 2., jtRound, scale_(0.1)).front(); // Now we check that no instance of convex_hull intersects any of the previously checked object instances. - for (const Point © : object->m_copies) { - Polygon p = convex_hull; - p.translate(copy); - if (! intersection(convex_hulls_other, p).empty()) + for (const Point © : print_object->m_copies) { + Polygon convex_hull = convex_hull0; + convex_hull.translate(copy); + if (! intersection(convex_hulls_other, convex_hull).empty()) return L("Some objects are too close; your extruder will collide with them."); - polygons_append(convex_hulls_other, p); + polygons_append(convex_hulls_other, convex_hull); } } }