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
This commit is contained in:
YuSanka 2024-01-11 11:02:53 +01:00
parent 7d31f8c0ba
commit 65525b0616
2 changed files with 22 additions and 9 deletions

View File

@ -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

View File

@ -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;
}