Browse Source

Model: Improved function looks_like_multipart_object().
Check transformed bounding boxes of loaded objects instead of z_min of bounding boxes.
+ BoundingBox: added function shares_boundary() to detect if bounding boxes shares some boundary.

Fix for #11547 - .3mf files with similar sized components aren't being defined as multi-part objects

YuSanka 1 year ago
parent
commit
65525b0616
2 changed files with 22 additions and 9 deletions
  1. 10 0
      src/libslic3r/BoundingBox.hpp
  2. 12 9
      src/libslic3r/Model.cpp

+ 10 - 0
src/libslic3r/BoundingBox.hpp

@@ -147,6 +147,16 @@ public:
         return this->min.x() < other.max.x() && this->max.x() > other.min.x() && this->min.y() < other.max.y() && this->max.y() > other.min.y() && 
             this->min.z() < other.max.z() && this->max.z() > other.min.z();
     }
+
+    // Shares some boundary.
+    bool shares_boundary(const BoundingBox3Base<PointType>& other) const {
+        return is_approx(this->min.x(), other.max.x()) ||
+               is_approx(this->max.x(), other.min.x()) ||
+               is_approx(this->min.y(), other.max.y()) ||
+               is_approx(this->max.y(), other.min.y()) ||
+               is_approx(this->min.z(), other.max.z()) ||
+               is_approx(this->max.z(), other.min.z());
+    }
 };
 
 // Will prevent warnings caused by non existing definition of template in hpp

+ 12 - 9
src/libslic3r/Model.cpp

@@ -425,18 +425,21 @@ bool Model::looks_like_multipart_object() const
 {
     if (this->objects.size() <= 1)
         return false;
-    double zmin = std::numeric_limits<double>::max();
+
+    BoundingBoxf3 tbb;
+
     for (const ModelObject *obj : this->objects) {
         if (obj->volumes.size() > 1 || obj->config.keys().size() > 1)
             return false;
-        for (const ModelVolume *vol : obj->volumes) {
-            double zmin_this = vol->mesh().bounding_box().min(2);
-            if (zmin == std::numeric_limits<double>::max())
-                zmin = zmin_this;
-            else if (std::abs(zmin - zmin_this) > EPSILON)
-                // The volumes don't share zmin.
-                return true;
-        }
+
+        BoundingBoxf3 bb_this = obj->volumes[0]->mesh().bounding_box();
+        BoundingBoxf3 tbb_this = obj->instances[0]->transform_bounding_box(bb_this);
+
+        if (!tbb.defined)
+            tbb = tbb_this;
+        else if (tbb.intersects(tbb_this) || tbb.shares_boundary(tbb_this))
+            // The volumes has intersects bounding boxes or share some boundary
+            return true;
     }
     return false;
 }