diff --git a/src/PrusaSlicer.cpp b/src/PrusaSlicer.cpp index c5bbccb24..e600f343c 100644 --- a/src/PrusaSlicer.cpp +++ b/src/PrusaSlicer.cpp @@ -382,7 +382,7 @@ int CLI::run(int argc, char **argv) } else if (opt_key == "align_xy") { const Vec2d &p = m_config.option("align_xy")->value; for (auto &model : m_models) { - BoundingBoxf3 bb = model.bounding_box(); + BoundingBoxf3 bb = model.bounding_box_exact(); // this affects volumes: model.translate(-(bb.min.x() - p.x()), -(bb.min.y() - p.y()), -bb.min.z()); } @@ -423,7 +423,7 @@ int CLI::run(int argc, char **argv) } else if (opt_key == "cut" || opt_key == "cut_x" || opt_key == "cut_y") { std::vector new_models; for (auto &model : m_models) { - model.translate(0, 0, -model.bounding_box().min.z()); // align to z = 0 + model.translate(0, 0, -model.bounding_box_exact().min.z()); // align to z = 0 size_t num_objects = model.objects.size(); for (size_t i = 0; i < num_objects; ++ i) { diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 01b4c5f6f..493741602 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -323,14 +323,30 @@ bool Model::add_default_instances() } // this returns the bounding box of the *transformed* instances -BoundingBoxf3 Model::bounding_box() const +BoundingBoxf3 Model::bounding_box_approx() const { BoundingBoxf3 bb; for (ModelObject *o : this->objects) - bb.merge(o->bounding_box()); + bb.merge(o->bounding_box_approx()); return bb; } +BoundingBoxf3 Model::bounding_box_exact() const +{ + BoundingBoxf3 bb; + for (ModelObject *o : this->objects) + bb.merge(o->bounding_box_exact()); + return bb; +} + +double Model::max_z() const +{ + double z = 0; + for (ModelObject *o : this->objects) + z = std::max(z, o->max_z()); + return z; +} + unsigned int Model::update_print_volume_state(const BuildVolume &build_volume) { unsigned int num_printable = 0; @@ -377,7 +393,7 @@ void Model::duplicate_objects_grid(size_t x, size_t y, coordf_t dist) ModelObject* object = this->objects.front(); object->clear_instances(); - Vec3d ext_size = object->bounding_box().size() + dist * Vec3d::Ones(); + Vec3d ext_size = object->bounding_box_exact().size() + dist * Vec3d::Ones(); for (size_t x_copy = 1; x_copy <= x; ++x_copy) { for (size_t y_copy = 1; y_copy <= y; ++y_copy) { @@ -548,13 +564,13 @@ void Model::adjust_min_z() if (objects.empty()) return; - if (bounding_box().min(2) < 0.0) + if (this->bounding_box_exact().min.z() < 0.0) { for (ModelObject* obj : objects) { if (obj != nullptr) { - coordf_t obj_min_z = obj->bounding_box().min(2); + coordf_t obj_min_z = obj->min_z(); if (obj_min_z < 0.0) obj->translate_instances(Vec3d(0.0, 0.0, -obj_min_z)); } @@ -627,8 +643,11 @@ ModelObject& ModelObject::assign_copy(const ModelObject &rhs) this->printable = rhs.printable; this->origin_translation = rhs.origin_translation; this->cut_id.copy(rhs.cut_id); - m_bounding_box = rhs.m_bounding_box; - m_bounding_box_valid = rhs.m_bounding_box_valid; + m_bounding_box_approx = rhs.m_bounding_box_approx; + m_bounding_box_approx_valid = rhs.m_bounding_box_approx_valid; + m_bounding_box_exact = rhs.m_bounding_box_exact; + m_bounding_box_exact_valid = rhs.m_bounding_box_exact_valid; + m_min_max_z_valid = rhs.m_min_max_z_valid; m_raw_bounding_box = rhs.m_raw_bounding_box; m_raw_bounding_box_valid = rhs.m_raw_bounding_box_valid; m_raw_mesh_bounding_box = rhs.m_raw_mesh_bounding_box; @@ -668,8 +687,11 @@ ModelObject& ModelObject::assign_copy(ModelObject &&rhs) this->layer_height_profile = std::move(rhs.layer_height_profile); this->printable = std::move(rhs.printable); this->origin_translation = std::move(rhs.origin_translation); - m_bounding_box = std::move(rhs.m_bounding_box); - m_bounding_box_valid = std::move(rhs.m_bounding_box_valid); + m_bounding_box_approx = std::move(rhs.m_bounding_box_approx); + m_bounding_box_approx_valid = std::move(rhs.m_bounding_box_approx_valid); + m_bounding_box_exact = std::move(rhs.m_bounding_box_exact); + m_bounding_box_exact_valid = std::move(rhs.m_bounding_box_exact_valid); + m_min_max_z_valid = rhs.m_min_max_z_valid; m_raw_bounding_box = rhs.m_raw_bounding_box; m_raw_bounding_box_valid = rhs.m_raw_bounding_box_valid; m_raw_mesh_bounding_box = rhs.m_raw_mesh_bounding_box; @@ -864,16 +886,73 @@ void ModelObject::clear_instances() // Returns the bounding box of the transformed instances. // This bounding box is approximate and not snug. -const BoundingBoxf3& ModelObject::bounding_box() const +const BoundingBoxf3& ModelObject::bounding_box_approx() const { - if (! m_bounding_box_valid) { - m_bounding_box_valid = true; + if (! m_bounding_box_approx_valid) { + m_bounding_box_approx_valid = true; BoundingBoxf3 raw_bbox = this->raw_mesh_bounding_box(); - m_bounding_box.reset(); + m_bounding_box_approx.reset(); for (const ModelInstance *i : this->instances) - m_bounding_box.merge(i->transform_bounding_box(raw_bbox)); + m_bounding_box_approx.merge(i->transform_bounding_box(raw_bbox)); + } + return m_bounding_box_approx; +} + +// Returns the bounding box of the transformed instances. +// This bounding box is approximate and not snug. +const BoundingBoxf3& ModelObject::bounding_box_exact() const +{ + if (! m_bounding_box_exact_valid) { + m_bounding_box_exact_valid = true; + m_min_max_z_valid = true; + BoundingBoxf3 raw_bbox = this->raw_mesh_bounding_box(); + m_bounding_box_exact.reset(); + for (size_t i = 0; i < this->instances.size(); ++ i) + m_bounding_box_exact.merge(this->instance_bounding_box(i)); + } + return m_bounding_box_exact; +} + +double ModelObject::min_z() const +{ + const_cast(this)->update_min_max_z(); + return m_bounding_box_exact.min.z(); +} + +double ModelObject::max_z() const +{ + const_cast(this)->update_min_max_z(); + return m_bounding_box_exact.max.z(); +} + +void ModelObject::update_min_max_z() +{ + assert(! this->instances.empty()); + if (! m_min_max_z_valid && ! this->instances.empty()) { + m_min_max_z_valid = true; + const Transform3d mat_instance = this->instances.front()->get_transformation().get_matrix(); + double global_min_z = std::numeric_limits::max(); + double global_max_z = - std::numeric_limits::max(); + for (const ModelVolume *v : this->volumes) + if (v->is_model_part()) { + const Transform3d m = mat_instance * v->get_matrix(); + const Vec3d row_z = m.linear().row(2).cast(); + const double shift_z = m.translation().z(); + double this_min_z = std::numeric_limits::max(); + double this_max_z = - std::numeric_limits::max(); + for (const Vec3f &p : v->mesh().its.vertices) { + double z = row_z.dot(p.cast()); + this_min_z = std::min(this_min_z, z); + this_max_z = std::max(this_max_z, z); + } + this_min_z += shift_z; + this_max_z += shift_z; + global_min_z = std::min(global_min_z, this_min_z); + global_max_z = std::max(global_max_z, this_max_z); + } + m_bounding_box_exact.min.z() = global_min_z; + m_bounding_box_exact.max.z() = global_max_z; } - return m_bounding_box; } // A mesh containing all transformed instances of this object. @@ -1031,19 +1110,19 @@ void ModelObject::ensure_on_bed(bool allow_negative_z) if (allow_negative_z) { if (parts_count() == 1) { - const double min_z = get_min_z(); - const double max_z = get_max_z(); + const double min_z = this->min_z(); + const double max_z = this->max_z(); if (min_z >= SINKING_Z_THRESHOLD || max_z < 0.0) z_offset = -min_z; } else { - const double max_z = get_max_z(); + const double max_z = this->max_z(); if (max_z < SINKING_MIN_Z_THRESHOLD) z_offset = SINKING_MIN_Z_THRESHOLD - max_z; } } else - z_offset = -get_min_z(); + z_offset = -this->min_z(); if (z_offset != 0.0) translate_instances(z_offset * Vec3d::UnitZ()); @@ -1070,8 +1149,10 @@ void ModelObject::translate(double x, double y, double z) v->translate(x, y, z); } - if (m_bounding_box_valid) - m_bounding_box.translate(x, y, z); + if (m_bounding_box_approx_valid) + m_bounding_box_approx.translate(x, y, z); + if (m_bounding_box_exact_valid) + m_bounding_box_exact.translate(x, y, z); } void ModelObject::scale(const Vec3d &versor) @@ -1866,32 +1947,6 @@ void ModelObject::bake_xy_rotation_into_meshes(size_t instance_idx) this->invalidate_bounding_box(); } -double ModelObject::get_min_z() const -{ - if (instances.empty()) - return 0.0; - else { - double min_z = DBL_MAX; - for (size_t i = 0; i < instances.size(); ++i) { - min_z = std::min(min_z, get_instance_min_z(i)); - } - return min_z; - } -} - -double ModelObject::get_max_z() const -{ - if (instances.empty()) - return 0.0; - else { - double max_z = -DBL_MAX; - for (size_t i = 0; i < instances.size(); ++i) { - max_z = std::max(max_z, get_instance_max_z(i)); - } - return max_z; - } -} - double ModelObject::get_instance_min_z(size_t instance_idx) const { double min_z = DBL_MAX; @@ -2268,7 +2323,7 @@ void ModelVolume::scale(const Vec3d& scaling_factors) void ModelObject::scale_to_fit(const Vec3d &size) { - Vec3d orig_size = this->bounding_box().size(); + Vec3d orig_size = this->bounding_box_exact().size(); double factor = std::min( size.x() / orig_size.x(), std::min( @@ -2373,37 +2428,6 @@ void ModelInstance::transform_mesh(TriangleMesh* mesh, bool dont_translate) cons #endif // ENABLE_WORLD_COORDINATE } -BoundingBoxf3 ModelInstance::transform_mesh_bounding_box(const TriangleMesh& mesh, bool dont_translate) const -{ - // Rotate around mesh origin. - TriangleMesh copy(mesh); -#if ENABLE_WORLD_COORDINATE - copy.transform(get_transformation().get_rotation_matrix()); -#else - copy.transform(get_matrix(true, false, true, true)); -#endif // ENABLE_WORLD_COORDINATE - BoundingBoxf3 bbox = copy.bounding_box(); - - if (!empty(bbox)) { - // Scale the bounding box along the three axes. - for (unsigned int i = 0; i < 3; ++i) - { - if (std::abs(get_scaling_factor((Axis)i)-1.0) > EPSILON) - { - bbox.min(i) *= get_scaling_factor((Axis)i); - bbox.max(i) *= get_scaling_factor((Axis)i); - } - } - - // Translate the bounding box. - if (! dont_translate) { - bbox.min += get_offset(); - bbox.max += get_offset(); - } - } - return bbox; -} - BoundingBoxf3 ModelInstance::transform_bounding_box(const BoundingBoxf3 &bbox, bool dont_translate) const { #if ENABLE_WORLD_COORDINATE diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 2e0ec3e16..7ab5c2545 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -168,7 +168,7 @@ private: friend class cereal::access; friend class UndoRedo::StackImpl; // Create an object for deserialization, don't allocate IDs for ModelMaterial and its config. - ModelMaterial() : ObjectBase(-1), config(-1), m_model(nullptr) { assert(this->id().invalid()); assert(this->config.id().invalid()); } + ModelMaterial() : ObjectBase(-1), config(-1) { assert(this->id().invalid()); assert(this->config.id().invalid()); } template void serialize(Archive &ar) { assert(this->id().invalid()); assert(this->config.id().invalid()); Internal::StaticSerializationWrapper config_wrapper(config); @@ -343,7 +343,7 @@ public: // The pairs of are packed into a 1D array. LayerHeightProfile layer_height_profile; // Whether or not this object is printable - bool printable; + bool printable { true }; // This vector holds position of selected support points for SLA. The data are // saved in mesh coordinates to allow using them for several instances. @@ -397,11 +397,22 @@ public: void delete_last_instance(); void clear_instances(); - // Returns the bounding box of the transformed instances. - // This bounding box is approximate and not snug. - // This bounding box is being cached. - const BoundingBoxf3& bounding_box() const; - void invalidate_bounding_box() { m_bounding_box_valid = false; m_raw_bounding_box_valid = false; m_raw_mesh_bounding_box_valid = false; } + // Returns the bounding box of the transformed instances. This bounding box is approximate and not snug, it is being cached. + const BoundingBoxf3& bounding_box_approx() const; + // Returns an exact bounding box of the transformed instances. The result it is being cached. + const BoundingBoxf3& bounding_box_exact() const; + // Return minimum / maximum of a printable object transformed into the world coordinate system. + // All instances share the same min / max Z. + double min_z() const; + double max_z() const; + + void invalidate_bounding_box() { + m_bounding_box_approx_valid = false; + m_bounding_box_exact_valid = false; + m_min_max_z_valid = false; + m_raw_bounding_box_valid = false; + m_raw_mesh_bounding_box_valid = false; + } // A mesh containing all transformed instances of this object. TriangleMesh mesh() const; @@ -477,8 +488,6 @@ public: // Rotation and mirroring is being baked in. In case the instance scaling was non-uniform, it is baked in as well. void bake_xy_rotation_into_meshes(size_t instance_idx); - double get_min_z() const; - double get_max_z() const; double get_instance_min_z(size_t instance_idx) const; double get_instance_max_z(size_t instance_idx) const; @@ -500,14 +509,13 @@ public: private: friend class Model; // This constructor assigns new ID to this ModelObject and its config. - explicit ModelObject(Model* model) : m_model(model), printable(true), origin_translation(Vec3d::Zero()), - m_bounding_box_valid(false), m_raw_bounding_box_valid(false), m_raw_mesh_bounding_box_valid(false) + explicit ModelObject(Model* model) : m_model(model), origin_translation(Vec3d::Zero()) { assert(this->id().valid()); assert(this->config.id().valid()); assert(this->layer_height_profile.id().valid()); } - explicit ModelObject(int) : ObjectBase(-1), config(-1), layer_height_profile(-1), m_model(nullptr), printable(true), origin_translation(Vec3d::Zero()), m_bounding_box_valid(false), m_raw_bounding_box_valid(false), m_raw_mesh_bounding_box_valid(false) + explicit ModelObject(int) : ObjectBase(-1), config(-1), layer_height_profile(-1), origin_translation(Vec3d::Zero()) { assert(this->id().invalid()); assert(this->config.id().invalid()); @@ -585,15 +593,18 @@ private: OBJECTBASE_DERIVED_COPY_MOVE_CLONE(ModelObject) // Parent object, owning this ModelObject. Set to nullptr here, so the macros above will have it initialized. - Model *m_model = nullptr; + Model *m_model { nullptr }; // Bounding box, cached. - mutable BoundingBoxf3 m_bounding_box; - mutable bool m_bounding_box_valid; + mutable BoundingBoxf3 m_bounding_box_approx; + mutable bool m_bounding_box_approx_valid { false }; + mutable BoundingBoxf3 m_bounding_box_exact; + mutable bool m_bounding_box_exact_valid { false }; + mutable bool m_min_max_z_valid { false }; mutable BoundingBoxf3 m_raw_bounding_box; - mutable bool m_raw_bounding_box_valid; + mutable bool m_raw_bounding_box_valid { false }; mutable BoundingBoxf3 m_raw_mesh_bounding_box; - mutable bool m_raw_mesh_bounding_box_valid; + mutable bool m_raw_mesh_bounding_box_valid { false }; // Called by Print::apply() to set the model pointer after making a copy. friend class Print; @@ -605,8 +616,7 @@ private: friend class UndoRedo::StackImpl; // Used for deserialization -> Don't allocate any IDs for the ModelObject or its config. ModelObject() : - ObjectBase(-1), config(-1), layer_height_profile(-1), - m_model(nullptr), m_bounding_box_valid(false), m_raw_bounding_box_valid(false), m_raw_mesh_bounding_box_valid(false) { + ObjectBase(-1), config(-1), layer_height_profile(-1) { assert(this->id().invalid()); assert(this->config.id().invalid()); assert(this->layer_height_profile.id().invalid()); @@ -617,12 +627,17 @@ private: Internal::StaticSerializationWrapper layer_heigth_profile_wrapper(layer_height_profile); ar(name, input_file, instances, volumes, config_wrapper, layer_config_ranges, layer_heigth_profile_wrapper, sla_support_points, sla_points_status, sla_drain_holes, printable, origin_translation, - m_bounding_box, m_bounding_box_valid, m_raw_bounding_box, m_raw_bounding_box_valid, m_raw_mesh_bounding_box, m_raw_mesh_bounding_box_valid, + m_bounding_box_approx, m_bounding_box_approx_valid, + m_bounding_box_exact, m_bounding_box_exact_valid, m_min_max_z_valid, + m_raw_bounding_box, m_raw_bounding_box_valid, m_raw_mesh_bounding_box, m_raw_mesh_bounding_box_valid, cut_connectors, cut_id); } // Called by Print::validate() from the UI thread. unsigned int update_instances_print_volume_state(const BuildVolume &build_volume); + + // Called by min_z(), max_z() + void update_min_max_z(); }; enum class EnforcerBlockerType : int8_t { @@ -1106,7 +1121,7 @@ public: // flag showing the position of this instance with respect to the print volume (set by Print::validate() using ModelObject::check_instances_print_volume_state()) ModelInstanceEPrintVolumeState print_volume_state; // Whether or not this instance is printable - bool printable; + bool printable { true }; ModelObject* get_object() const { return this->object; } @@ -1156,9 +1171,7 @@ public: // To be called on an external mesh void transform_mesh(TriangleMesh* mesh, bool dont_translate = false) const; - // Calculate a bounding box of a transformed mesh. To be called on an external mesh. - BoundingBoxf3 transform_mesh_bounding_box(const TriangleMesh& mesh, bool dont_translate = false) const; - // Transform an external bounding box. + // Transform an external bounding box, thus the resulting bounding box is no more snug. BoundingBoxf3 transform_bounding_box(const BoundingBoxf3 &bbox, bool dont_translate = false) const; // Transform an external vector. Vec3d transform_vector(const Vec3d& v, bool dont_translate = false) const; @@ -1201,7 +1214,7 @@ private: ModelObject* object; // Constructor, which assigns a new unique ID. - explicit ModelInstance(ModelObject* object) : print_volume_state(ModelInstancePVS_Inside), printable(true), object(object) { assert(this->id().valid()); } + explicit ModelInstance(ModelObject* object) : print_volume_state(ModelInstancePVS_Inside), object(object) { assert(this->id().valid()); } // Constructor, which assigns a new unique ID. explicit ModelInstance(ModelObject *object, const ModelInstance &other) : m_transformation(other.m_transformation), print_volume_state(ModelInstancePVS_Inside), printable(other.printable), object(object) { assert(this->id().valid() && this->id() != other.id()); } @@ -1316,8 +1329,12 @@ public: void delete_material(t_model_material_id material_id); void clear_materials(); bool add_default_instances(); - // Returns approximate axis aligned bounding box of this model - BoundingBoxf3 bounding_box() const; + // Returns approximate axis aligned bounding box of this model. + BoundingBoxf3 bounding_box_approx() const; + // Returns exact axis aligned bounding box of this model. + BoundingBoxf3 bounding_box_exact() const; + // Return maximum height of all printable objects. + double max_z() const; // Set the print_volume_state of PrintObject::instances, // return total number of printable objects. unsigned int update_print_volume_state(const BuildVolume &build_volume); diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 14c76fefe..efdcb4fc6 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -77,7 +77,7 @@ PrintObject::PrintObject(Print* print, ModelObject* model_object, const Transfor Vec3d bbox_center = bbox.center(); // We may need to rotate the bbox / bbox_center from the original instance to the current instance. double z_diff = Geometry::rotation_diff_z(model_object->instances.front()->get_matrix(), instances.front().model_instance->get_matrix()); - if (std::abs(z_diff) > EPSILON) { + if (std::abs(z_diff) > EPSILON) { auto z_rot = Eigen::AngleAxisd(z_diff, Vec3d::UnitZ()); bbox = bbox.transformed(Transform3d(z_rot)); bbox_center = (z_rot * bbox_center).eval(); @@ -87,6 +87,7 @@ PrintObject::PrintObject(Print* print, ModelObject* model_object, const Transfor m_center_offset = Point::new_scale(bbox_center.x(), bbox_center.y()); // Size of the transformed mesh. This bounding may not be snug in XY plane, but it is snug in Z. m_size = (bbox.size() * (1. / SCALING_FACTOR)).cast(); + m_size.z() = model_object->max_z(); this->set_instances(std::move(instances)); } @@ -1736,7 +1737,7 @@ void PrintObject::update_slicing_parameters() { if (!m_slicing_params.valid) m_slicing_params = SlicingParameters::create_from_config( - this->print()->config(), m_config, this->model_object()->bounding_box().max.z(), this->object_extruders()); + this->print()->config(), m_config, this->model_object()->max_z(), this->object_extruders()); } SlicingParameters PrintObject::slicing_parameters(const DynamicPrintConfig& full_config, const ModelObject& model_object, float object_max_z) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 24f692d11..74f7bf50e 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -2246,7 +2246,7 @@ void GCodeViewer::load_shells(const Print& print) if (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptFFF) { // adds wipe tower's volume - const double max_z = print.objects()[0]->model_object()->get_model()->bounding_box().max(2); + const double max_z = print.objects()[0]->model_object()->get_model()->max_z(); const PrintConfig& config = print.config(); const size_t extruders_count = config.nozzle_diameter.size(); if (extruders_count > 1 && config.wipe_tower && !config.complete_objects) { diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 7df8f5b32..d459c87de 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -140,7 +140,7 @@ void GLCanvas3D::LayersEditing::select_object(const Model &model, int object_id) // Maximum height of an object changes when the object gets rotated or scaled. // Changing maximum height of an object will invalidate the layer heigth editing profile. // m_model_object->bounding_box() is cached, therefore it is cheap even if this method is called frequently. - const float new_max_z = (model_object_new == nullptr) ? 0.0f : static_cast(model_object_new->bounding_box().max.z()); + const float new_max_z = (model_object_new == nullptr) ? 0.0f : static_cast(model_object_new->max_z()); if (m_model_object != model_object_new || this->last_object_id != object_id || m_object_max_z != new_max_z || (model_object_new != nullptr && m_model_object->id() != model_object_new->id())) { m_layer_height_profile.clear(); @@ -1977,7 +1977,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re if (extruders_count > 1 && wt && !co) { // Height of a print (Show at least a slab) - const double height = std::max(m_model->bounding_box().max.z(), 10.0); + const double height = std::max(m_model->max_z(), 10.0); const float x = dynamic_cast(m_config->option("wipe_tower_x"))->value; const float y = dynamic_cast(m_config->option("wipe_tower_y"))->value; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 73617531d..6b9df9217 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3520,7 +3520,7 @@ bool Plater::priv::replace_volume_with_stl(int object_idx, int volume_idx, const ModelObject* old_model_object = model.objects[object_idx]; ModelVolume* old_volume = old_model_object->volumes[volume_idx]; - bool sinking = old_model_object->bounding_box().min.z() < SINKING_Z_THRESHOLD; + bool sinking = old_model_object->min_z() < SINKING_Z_THRESHOLD; ModelObject* new_model_object = new_model.objects.front(); old_model_object->add_volume(*new_model_object->volumes.front()); @@ -3835,7 +3835,7 @@ void Plater::priv::reload_from_disk() ModelObject* old_model_object = model.objects[obj_idx]; ModelVolume* old_volume = old_model_object->volumes[vol_idx]; - bool sinking = old_model_object->bounding_box().min.z() < SINKING_Z_THRESHOLD; + bool sinking = old_model_object->min_z() < SINKING_Z_THRESHOLD; bool has_source = !old_volume->source.input_file.empty() && boost::algorithm::iequals(fs::path(old_volume->source.input_file).filename().string(), fs::path(path).filename().string()); bool has_name = !old_volume->name.empty() && boost::algorithm::iequals(old_volume->name, fs::path(path).filename().string()); @@ -4816,7 +4816,7 @@ bool Plater::priv::layers_height_allowed() const return false; int obj_idx = get_selected_object_idx(); - return 0 <= obj_idx && obj_idx < (int)model.objects.size() && model.objects[obj_idx]->bounding_box().max.z() > SINKING_Z_THRESHOLD && + return 0 <= obj_idx && obj_idx < (int)model.objects.size() && model.objects[obj_idx]->max_z() > SINKING_Z_THRESHOLD && config->opt_bool("variable_layer_height") && view3D->is_layers_editing_allowed(); } @@ -7435,7 +7435,7 @@ void Plater::changed_objects(const std::vector& object_idxs) for (size_t obj_idx : object_idxs) { if (obj_idx < p->model.objects.size()) { - if (p->model.objects[obj_idx]->bounding_box().min.z() >= SINKING_Z_THRESHOLD) + if (p->model.objects[obj_idx]->min_z() >= SINKING_Z_THRESHOLD) // re - align to Z = 0 p->model.objects[obj_idx]->ensure_on_bed(); }