Follow-up to 3349644964
Reworked handling of approximate / snug bounding boxes at Model / ModelObject / PrintObject Further optimized, so that the bounding boxes are not recalculated unnecesarilly.
This commit is contained in:
parent
3349644964
commit
906671fbba
5 changed files with 50 additions and 19 deletions
|
@ -918,4 +918,30 @@ double rotation_diff_z(const Transform3d &trafo_from, const Transform3d &trafo_t
|
|||
return atan2(vx.y(), vx.x());
|
||||
}
|
||||
|
||||
bool trafos_differ_in_rotation_by_z_and_mirroring_by_xy_only(const Transform3d &t1, const Transform3d &t2)
|
||||
{
|
||||
if (std::abs(t1.translation().z() - t2.translation().z()) > EPSILON)
|
||||
// One of the object is higher than the other above the build plate (or below the build plate).
|
||||
return false;
|
||||
Matrix3d m1 = t1.matrix().block<3, 3>(0, 0);
|
||||
Matrix3d m2 = t2.matrix().block<3, 3>(0, 0);
|
||||
Matrix3d m = m2.inverse() * m1;
|
||||
Vec3d z = m.block<3, 1>(0, 2);
|
||||
if (std::abs(z.x()) > EPSILON || std::abs(z.y()) > EPSILON || std::abs(z.z() - 1.) > EPSILON)
|
||||
// Z direction or length changed.
|
||||
return false;
|
||||
// Z still points in the same direction and it has the same length.
|
||||
Vec3d x = m.block<3, 1>(0, 0);
|
||||
Vec3d y = m.block<3, 1>(0, 1);
|
||||
if (std::abs(x.z()) > EPSILON || std::abs(y.z()) > EPSILON)
|
||||
return false;
|
||||
double lx2 = x.squaredNorm();
|
||||
double ly2 = y.squaredNorm();
|
||||
if (lx2 - 1. > EPSILON * EPSILON || ly2 - 1. > EPSILON * EPSILON)
|
||||
return false;
|
||||
// Verify whether the vectors x, y are still perpendicular.
|
||||
double d = x.dot(y);
|
||||
return std::abs(d * d) < EPSILON * lx2 * ly2;
|
||||
}
|
||||
|
||||
}} // namespace Slic3r::Geometry
|
||||
|
|
|
@ -584,6 +584,13 @@ inline bool is_rotation_ninety_degrees(const Vec3d &rotation)
|
|||
return is_rotation_ninety_degrees(rotation.x()) && is_rotation_ninety_degrees(rotation.y()) && is_rotation_ninety_degrees(rotation.z());
|
||||
}
|
||||
|
||||
// Returns true if one transformation may be converted into another transformation by
|
||||
// rotation around Z and by mirroring in X / Y only. Two objects sharing such transformation
|
||||
// may share support structures and they share Z height.
|
||||
bool trafos_differ_in_rotation_by_z_and_mirroring_by_xy_only(const Transform3d &t1, const Transform3d &t2);
|
||||
inline bool trafos_differ_in_rotation_by_z_and_mirroring_by_xy_only(const Transformation &t1, const Transformation &t2)
|
||||
{ return trafos_differ_in_rotation_by_z_and_mirroring_by_xy_only(t1.get_matrix(), t2.get_matrix()); }
|
||||
|
||||
template <class Tout = double, class Tin>
|
||||
std::pair<Tout, Tout> dir_to_spheric(const Vec<3, Tin> &n, Tout norm = 1.)
|
||||
{
|
||||
|
|
|
@ -643,15 +643,7 @@ 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_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;
|
||||
m_raw_mesh_bounding_box_valid = rhs.m_raw_mesh_bounding_box_valid;
|
||||
this->copy_transformation_caches(rhs);
|
||||
|
||||
this->clear_volumes();
|
||||
this->volumes.reserve(rhs.volumes.size());
|
||||
|
@ -687,15 +679,7 @@ 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_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;
|
||||
m_raw_mesh_bounding_box_valid = rhs.m_raw_mesh_bounding_box_valid;
|
||||
this->copy_transformation_caches(rhs);
|
||||
|
||||
this->clear_volumes();
|
||||
this->volumes = std::move(rhs.volumes);
|
||||
|
|
|
@ -606,6 +606,19 @@ private:
|
|||
mutable BoundingBoxf3 m_raw_mesh_bounding_box;
|
||||
mutable bool m_raw_mesh_bounding_box_valid { false };
|
||||
|
||||
// Only use this method if now the source and dest ModelObjects are equal, for example they were synchronized by Print::apply().
|
||||
void copy_transformation_caches(const ModelObject &src) {
|
||||
m_bounding_box_approx = src.m_bounding_box_approx;
|
||||
m_bounding_box_approx_valid = src.m_bounding_box_approx_valid;
|
||||
m_bounding_box_exact = src.m_bounding_box_exact;
|
||||
m_bounding_box_exact_valid = src.m_bounding_box_exact_valid;
|
||||
m_min_max_z_valid = src.m_min_max_z_valid;
|
||||
m_raw_bounding_box = src.m_raw_bounding_box;
|
||||
m_raw_bounding_box_valid = src.m_raw_bounding_box_valid;
|
||||
m_raw_mesh_bounding_box = src.m_raw_mesh_bounding_box;
|
||||
m_raw_mesh_bounding_box_valid = src.m_raw_mesh_bounding_box_valid;
|
||||
}
|
||||
|
||||
// Called by Print::apply() to set the model pointer after making a copy.
|
||||
friend class Print;
|
||||
friend class SLAPrint;
|
||||
|
|
|
@ -1250,7 +1250,6 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
|
|||
l->get_transformation().get_matrix().isApprox(r->get_transformation().get_matrix()); })) {
|
||||
// If some of the instances changed, the bounding box of the updated ModelObject is likely no more valid.
|
||||
// This is safe as the ModelObject's bounding box is only accessed from this function, which is called from the main thread only.
|
||||
model_object.invalidate_bounding_box();
|
||||
// Synchronize the content of instances.
|
||||
auto new_instance = model_object_new.instances.begin();
|
||||
for (auto old_instance = model_object.instances.begin(); old_instance != model_object.instances.end(); ++ old_instance, ++ new_instance) {
|
||||
|
@ -1259,6 +1258,8 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
|
|||
(*old_instance)->printable = (*new_instance)->printable;
|
||||
}
|
||||
}
|
||||
// Source / dest object share the same bounding boxes, just copy them.
|
||||
model_object.copy_transformation_caches(model_object_new);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue