From 296041da38273fbf0053d6e338bf5a2bb51d030d Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 14 Dec 2021 10:21:31 +0100 Subject: [PATCH] #7464 - Fixed 'Export as .stl' scaling not applied on scaled object instances --- src/slic3r/GUI/Plater.cpp | 62 ++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 36 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index b3ec46425..89d74f7bb 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -5707,23 +5707,26 @@ void Plater::export_stl(bool extended, bool selection_only) return; // Following lambda generates a combined mesh for export with normals pointing outwards. - auto mesh_to_export = [](const ModelObject* mo, bool instances) -> TriangleMesh { + auto mesh_to_export = [](const ModelObject& mo, int instance_id) { TriangleMesh mesh; - for (const ModelVolume *v : mo->volumes) + for (const ModelVolume* v : mo.volumes) if (v->is_model_part()) { TriangleMesh vol_mesh(v->mesh()); vol_mesh.transform(v->get_matrix(), true); mesh.merge(vol_mesh); } - if (instances) { + if (instance_id == -1) { TriangleMesh vols_mesh(mesh); mesh = TriangleMesh(); - for (const ModelInstance *i : mo->instances) { + for (const ModelInstance* i : mo.instances) { TriangleMesh m = vols_mesh; m.transform(i->get_matrix(), true); mesh.merge(m); } } + else if (0 <= instance_id && instance_id < mo.instances.size()) + mesh.transform(mo.instances[instance_id]->get_matrix(), true); + return mesh; }; @@ -5732,14 +5735,8 @@ void Plater::export_stl(bool extended, bool selection_only) if (selection_only) { const ModelObject* model_object = p->model.objects[obj_idx]; if (selection.get_mode() == Selection::Instance) - { - if (selection.is_single_full_object()) - mesh = mesh_to_export(model_object, true); - else - mesh = mesh_to_export(model_object, false); - } - else - { + mesh = selection.is_single_full_object() ? mesh_to_export(*model_object, -1) : mesh_to_export(*model_object, selection.get_instance_idx()); + else { const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin()); mesh = model_object->volumes[volume->volume_idx()]->mesh(); mesh.transform(volume->get_volume_transformation().get_matrix(), true); @@ -5747,69 +5744,62 @@ void Plater::export_stl(bool extended, bool selection_only) } } else { - for (const ModelObject *o : p->model.objects) - mesh.merge(mesh_to_export(o, true)); + for (const ModelObject* o : p->model.objects) { + mesh.merge(mesh_to_export(*o, -1)); + } } } - else - { + else { // This is SLA mode, all objects have only one volume. // However, we must have a look at the backend to load // hollowed mesh and/or supports const PrintObjects& objects = p->sla_print.objects(); - for (const SLAPrintObject* object : objects) - { + for (const SLAPrintObject* object : objects) { const ModelObject* model_object = object->model_object(); if (selection_only) { if (model_object->id() != p->model.objects[obj_idx]->id()) continue; } - Transform3d mesh_trafo_inv = object->trafo().inverse(); - bool is_left_handed = object->is_left_handed(); + const Transform3d mesh_trafo_inv = object->trafo().inverse(); + const bool is_left_handed = object->is_left_handed(); TriangleMesh pad_mesh; - bool has_pad_mesh = extended && object->has_mesh(slaposPad); - if (has_pad_mesh) - { + const bool has_pad_mesh = extended && object->has_mesh(slaposPad); + if (has_pad_mesh) { pad_mesh = object->get_mesh(slaposPad); pad_mesh.transform(mesh_trafo_inv); } TriangleMesh supports_mesh; - bool has_supports_mesh = extended && object->has_mesh(slaposSupportTree); - if (has_supports_mesh) - { + const bool has_supports_mesh = extended && object->has_mesh(slaposSupportTree); + if (has_supports_mesh) { supports_mesh = object->get_mesh(slaposSupportTree); supports_mesh.transform(mesh_trafo_inv); } const std::vector& obj_instances = object->instances(); - for (const SLAPrintObject::Instance& obj_instance : obj_instances) - { + for (const SLAPrintObject::Instance& obj_instance : obj_instances) { auto it = std::find_if(model_object->instances.begin(), model_object->instances.end(), [&obj_instance](const ModelInstance *mi) { return mi->id() == obj_instance.instance_id; }); assert(it != model_object->instances.end()); - if (it != model_object->instances.end()) - { - bool one_inst_only = selection_only && ! selection.is_single_full_object(); + if (it != model_object->instances.end()) { + const bool one_inst_only = selection_only && ! selection.is_single_full_object(); - int instance_idx = it - model_object->instances.begin(); + const int instance_idx = it - model_object->instances.begin(); const Transform3d& inst_transform = one_inst_only ? Transform3d::Identity() : object->model_object()->instances[instance_idx]->get_transformation().get_matrix(); TriangleMesh inst_mesh; - if (has_pad_mesh) - { + if (has_pad_mesh) { TriangleMesh inst_pad_mesh = pad_mesh; inst_pad_mesh.transform(inst_transform, is_left_handed); inst_mesh.merge(inst_pad_mesh); } - if (has_supports_mesh) - { + if (has_supports_mesh) { TriangleMesh inst_supports_mesh = supports_mesh; inst_supports_mesh.transform(inst_transform, is_left_handed); inst_mesh.merge(inst_supports_mesh);