Fixed update of backend after the changes introduced with b3010a817b (Do not allow objects to be placed fully below bed) and pop object on the bed when only one part is left

This commit is contained in:
enricoturri1966 2021-08-25 12:39:46 +02:00
parent 3fc4cc84a7
commit 38cd7fea65
4 changed files with 58 additions and 11 deletions

View File

@ -956,9 +956,22 @@ void ModelObject::center_around_origin(bool include_modifiers)
void ModelObject::ensure_on_bed(bool allow_negative_z)
{
const double min_z = get_min_z();
if (!allow_negative_z || min_z > SINKING_Z_THRESHOLD)
translate_instances({ 0.0, 0.0, -min_z });
double z_offset = 0.0;
if (allow_negative_z) {
if (volumes.size() == 1)
z_offset = -get_min_z();
else {
const double max_z = get_max_z();
if (max_z < SINKING_MIN_Z_THRESHOLD)
z_offset = SINKING_MIN_Z_THRESHOLD - max_z;
}
}
else
z_offset = -get_min_z();
if (z_offset != 0.0)
translate_instances(z_offset * Vec3d::UnitZ());
}
void ModelObject::translate_instances(const Vec3d& vector)
@ -1429,6 +1442,19 @@ double ModelObject::get_min_z() const
}
}
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;
@ -1450,6 +1476,27 @@ double ModelObject::get_instance_min_z(size_t instance_idx) const
return min_z + inst->get_offset(Z);
}
double ModelObject::get_instance_max_z(size_t instance_idx) const
{
double max_z = -DBL_MAX;
const ModelInstance* inst = instances[instance_idx];
const Transform3d& mi = inst->get_matrix(true);
for (const ModelVolume* v : volumes) {
if (!v->is_model_part())
continue;
const Transform3d mv = mi * v->get_matrix();
const TriangleMesh& hull = v->get_convex_hull();
for (const stl_facet& facet : hull.stl.facet_start)
for (int i = 0; i < 3; ++i)
max_z = std::max(max_z, (mv * facet.vertex[i].cast<double>()).z());
}
return max_z + inst->get_offset(Z);
}
unsigned int ModelObject::check_instances_print_volume_state(const BoundingBoxf3& print_volume)
{
unsigned int num_printable = 0;

View File

@ -358,7 +358,9 @@ public:
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;
// Called by Print::validate() from the UI thread.
unsigned int check_instances_print_volume_state(const BoundingBoxf3& print_volume);

View File

@ -1920,16 +1920,15 @@ bool ObjectList::del_subobject_from_object(const int obj_idx, const int idx, con
if (vol->is_model_part())
++solid_cnt;
if (volume->is_model_part() && solid_cnt == 1) {
Slic3r::GUI::show_error(nullptr, _(L("From Object List You can't delete the last solid part from object.")));
Slic3r::GUI::show_error(nullptr, _L("From Object List You can't delete the last solid part from object."));
return false;
}
take_snapshot(_(L("Delete Subobject")));
take_snapshot(_L("Delete Subobject"));
object->delete_volume(idx);
if (object->volumes.size() == 1)
{
if (object->volumes.size() == 1) {
const auto last_volume = object->volumes[0];
if (!last_volume->config.empty()) {
object->config.apply(last_volume->config);
@ -1948,11 +1947,11 @@ bool ObjectList::del_subobject_from_object(const int obj_idx, const int idx, con
}
else if (type == itInstance) {
if (object->instances.size() == 1) {
Slic3r::GUI::show_error(nullptr, _(L("Last instance of an object cannot be deleted.")));
Slic3r::GUI::show_error(nullptr, _L("Last instance of an object cannot be deleted."));
return false;
}
take_snapshot(_(L("Delete Instance")));
take_snapshot(_L("Delete Instance"));
object->delete_instance(idx);
}
else

View File

@ -6200,8 +6200,7 @@ void Plater::changed_object(int obj_idx)
if (obj_idx < 0)
return;
// recenter and re - align to Z = 0
auto model_object = p->model.objects[obj_idx];
model_object->ensure_on_bed(this->p->printer_technology != ptSLA);
p->model.objects[obj_idx]->ensure_on_bed(p->printer_technology != ptSLA);
if (this->p->printer_technology == ptSLA) {
// Update the SLAPrint from the current Model, so that the reload_scene()
// pulls the correct data, update the 3D scene.