From b43a21d1be20963c5afb8c6df8f4618c62c8d0e4 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Wed, 14 Mar 2018 16:11:57 +0100 Subject: [PATCH] Extended Print::validate() to check, whether the objects are inside the print volume. --- xs/src/libslic3r/BoundingBox.hpp | 26 +------- xs/src/libslic3r/Model.cpp | 104 ++++++++++++++++++------------- xs/src/libslic3r/Model.hpp | 7 ++- xs/src/libslic3r/Print.cpp | 7 +++ 4 files changed, 73 insertions(+), 71 deletions(-) diff --git a/xs/src/libslic3r/BoundingBox.hpp b/xs/src/libslic3r/BoundingBox.hpp index b425a4e3c..92a2bd451 100644 --- a/xs/src/libslic3r/BoundingBox.hpp +++ b/xs/src/libslic3r/BoundingBox.hpp @@ -100,31 +100,7 @@ public: } bool contains(const BoundingBox3Base& other) const { - if (!contains(other.min)) - return false; - - if (!contains(PointClass(other.max.x, other.min.y, other.min.z))) - return false; - - if (!contains(PointClass(other.max.x, other.max.y, other.min.z))) - return false; - - if (!contains(PointClass(other.min.x, other.max.y, other.min.z))) - return false; - - if (!contains(PointClass(other.min.x, other.min.y, other.max.z))) - return false; - - if (!contains(PointClass(other.max.x, other.min.y, other.max.z))) - return false; - - if (!contains(other.max)) - return false; - - if (!contains(PointClass(other.min.x, other.max.y, other.max.z))) - return false; - - return true; + return contains(other.min) && contains(other.max); } }; diff --git a/xs/src/libslic3r/Model.cpp b/xs/src/libslic3r/Model.cpp index 944bf7743..41bb17ccf 100644 --- a/xs/src/libslic3r/Model.cpp +++ b/xs/src/libslic3r/Model.cpp @@ -233,51 +233,8 @@ BoundingBoxf3 Model::bounding_box() const BoundingBoxf3 Model::transformed_bounding_box() const { BoundingBoxf3 bb; - for (const ModelObject* obj : this->objects) - { - for (const ModelVolume* vol : obj->volumes) - { - if (!vol->modifier) - { - for (const ModelInstance* inst : obj->instances) - { - double c = cos(inst->rotation); - double s = sin(inst->rotation); - - for (int f = 0; f < vol->mesh.stl.stats.number_of_facets; ++f) - { - const stl_facet& facet = vol->mesh.stl.facet_start[f]; - - for (int i = 0; i < 3; ++i) - { - // original point - const stl_vertex& v = facet.vertex[i]; - Pointf3 p((double)v.x, (double)v.y, (double)v.z); - - // scale - p.x *= inst->scaling_factor; - p.y *= inst->scaling_factor; - p.z *= inst->scaling_factor; - - // rotate Z - double x = p.x; - double y = p.y; - p.x = c * x - s * y; - p.y = s * x + c * y; - - // translate - p.x += inst->offset.x; - p.y += inst->offset.y; - - bb.merge(p); - } - } - } - } - } - } - + bb.merge(obj->tight_bounding_box(false)); return bb; } @@ -477,6 +434,15 @@ bool Model::fits_print_volume(const DynamicPrintConfig* config) const return print_volume.contains(transformed_bounding_box()); } +bool Model::fits_print_volume(const FullPrintConfig &config) const +{ + if (objects.empty()) + return true; + BoundingBox bed_box_2D = get_extents(Polygon::new_scale(config.bed_shape.values)); + BoundingBoxf3 print_volume(Pointf3(unscale(bed_box_2D.min.x), unscale(bed_box_2D.min.y), 0.0), Pointf3(unscale(bed_box_2D.max.x), unscale(bed_box_2D.max.y), config.max_print_height)); + return print_volume.contains(transformed_bounding_box()); +} + ModelObject::ModelObject(Model *model, const ModelObject &other, bool copy_volumes) : name(other.name), input_file(other.input_file), @@ -607,7 +573,7 @@ void ModelObject::clear_instances() // Returns the bounding box of the transformed instances. // This bounding box is approximate and not snug. -BoundingBoxf3 ModelObject::bounding_box() +const BoundingBoxf3& ModelObject::bounding_box() { if (! m_bounding_box_valid) { BoundingBoxf3 raw_bbox; @@ -623,6 +589,54 @@ BoundingBoxf3 ModelObject::bounding_box() return m_bounding_box; } +BoundingBoxf3 ModelObject::tight_bounding_box(bool include_modifiers) const +{ + BoundingBoxf3 bb; + + for (const ModelVolume* vol : this->volumes) + { + if (include_modifiers || !vol->modifier) + { + for (const ModelInstance* inst : this->instances) + { + double c = cos(inst->rotation); + double s = sin(inst->rotation); + + for (int f = 0; f < vol->mesh.stl.stats.number_of_facets; ++f) + { + const stl_facet& facet = vol->mesh.stl.facet_start[f]; + + for (int i = 0; i < 3; ++i) + { + // original point + const stl_vertex& v = facet.vertex[i]; + Pointf3 p((double)v.x, (double)v.y, (double)v.z); + + // scale + p.x *= inst->scaling_factor; + p.y *= inst->scaling_factor; + p.z *= inst->scaling_factor; + + // rotate Z + double x = p.x; + double y = p.y; + p.x = c * x - s * y; + p.y = s * x + c * y; + + // translate + p.x += inst->offset.x; + p.y += inst->offset.y; + + bb.merge(p); + } + } + } + } + } + + return bb; +} + // A mesh containing all transformed instances of this object. TriangleMesh ModelObject::mesh() const { diff --git a/xs/src/libslic3r/Model.hpp b/xs/src/libslic3r/Model.hpp index 7ef1803ac..173bf0c1a 100644 --- a/xs/src/libslic3r/Model.hpp +++ b/xs/src/libslic3r/Model.hpp @@ -102,8 +102,12 @@ public: // Returns the bounding box of the transformed instances. // This bounding box is approximate and not snug. - BoundingBoxf3 bounding_box(); + // This bounding box is being cached. + const BoundingBoxf3& bounding_box(); void invalidate_bounding_box() { m_bounding_box_valid = false; } + // Returns a snug bounding box of the transformed instances. + // This bounding box is not being cached. + BoundingBoxf3 tight_bounding_box(bool include_modifiers) const; // A mesh containing all transformed instances of this object. TriangleMesh mesh() const; @@ -278,6 +282,7 @@ public: // Returs true if this model is contained into the print volume defined inside the given config bool fits_print_volume(const DynamicPrintConfig* config) const; + bool fits_print_volume(const FullPrintConfig &config) const; void print_info() const { for (const ModelObject *o : this->objects) o->print_info(); } }; diff --git a/xs/src/libslic3r/Print.cpp b/xs/src/libslic3r/Print.cpp index 1ff764e4a..13f4fab79 100644 --- a/xs/src/libslic3r/Print.cpp +++ b/xs/src/libslic3r/Print.cpp @@ -508,6 +508,13 @@ bool Print::has_skirt() const std::string Print::validate() const { + BoundingBox bed_box_2D = get_extents(Polygon::new_scale(config.bed_shape.values)); + BoundingBoxf3 print_volume(Pointf3(unscale(bed_box_2D.min.x), unscale(bed_box_2D.min.y), 0.0), Pointf3(unscale(bed_box_2D.max.x), unscale(bed_box_2D.max.y), config.max_print_height)); + for (PrintObject *po : this->objects) { + if (! print_volume.contains(po->model_object()->tight_bounding_box(false))) + return "Some objects are outside of the print volume."; + } + if (this->config.complete_objects) { // Check horizontal clearance. {