#7464 - Fixed 'Export as .stl' scaling not applied on scaled object instances

This commit is contained in:
enricoturri1966 2021-12-14 10:21:31 +01:00
parent dc3da0b626
commit 296041da38

View File

@ -5707,23 +5707,26 @@ void Plater::export_stl(bool extended, bool selection_only)
return; return;
// Following lambda generates a combined mesh for export with normals pointing outwards. // 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; TriangleMesh mesh;
for (const ModelVolume *v : mo->volumes) for (const ModelVolume* v : mo.volumes)
if (v->is_model_part()) { if (v->is_model_part()) {
TriangleMesh vol_mesh(v->mesh()); TriangleMesh vol_mesh(v->mesh());
vol_mesh.transform(v->get_matrix(), true); vol_mesh.transform(v->get_matrix(), true);
mesh.merge(vol_mesh); mesh.merge(vol_mesh);
} }
if (instances) { if (instance_id == -1) {
TriangleMesh vols_mesh(mesh); TriangleMesh vols_mesh(mesh);
mesh = TriangleMesh(); mesh = TriangleMesh();
for (const ModelInstance *i : mo->instances) { for (const ModelInstance* i : mo.instances) {
TriangleMesh m = vols_mesh; TriangleMesh m = vols_mesh;
m.transform(i->get_matrix(), true); m.transform(i->get_matrix(), true);
mesh.merge(m); mesh.merge(m);
} }
} }
else if (0 <= instance_id && instance_id < mo.instances.size())
mesh.transform(mo.instances[instance_id]->get_matrix(), true);
return mesh; return mesh;
}; };
@ -5732,14 +5735,8 @@ void Plater::export_stl(bool extended, bool selection_only)
if (selection_only) { if (selection_only) {
const ModelObject* model_object = p->model.objects[obj_idx]; const ModelObject* model_object = p->model.objects[obj_idx];
if (selection.get_mode() == Selection::Instance) if (selection.get_mode() == Selection::Instance)
{ mesh = selection.is_single_full_object() ? mesh_to_export(*model_object, -1) : mesh_to_export(*model_object, selection.get_instance_idx());
if (selection.is_single_full_object()) else {
mesh = mesh_to_export(model_object, true);
else
mesh = mesh_to_export(model_object, false);
}
else
{
const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin()); const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());
mesh = model_object->volumes[volume->volume_idx()]->mesh(); mesh = model_object->volumes[volume->volume_idx()]->mesh();
mesh.transform(volume->get_volume_transformation().get_matrix(), true); mesh.transform(volume->get_volume_transformation().get_matrix(), true);
@ -5747,69 +5744,62 @@ void Plater::export_stl(bool extended, bool selection_only)
} }
} }
else { else {
for (const ModelObject *o : p->model.objects) for (const ModelObject* o : p->model.objects) {
mesh.merge(mesh_to_export(o, true)); mesh.merge(mesh_to_export(*o, -1));
} }
} }
else }
{ else {
// This is SLA mode, all objects have only one volume. // This is SLA mode, all objects have only one volume.
// However, we must have a look at the backend to load // However, we must have a look at the backend to load
// hollowed mesh and/or supports // hollowed mesh and/or supports
const PrintObjects& objects = p->sla_print.objects(); const PrintObjects& objects = p->sla_print.objects();
for (const SLAPrintObject* object : objects) for (const SLAPrintObject* object : objects) {
{
const ModelObject* model_object = object->model_object(); const ModelObject* model_object = object->model_object();
if (selection_only) { if (selection_only) {
if (model_object->id() != p->model.objects[obj_idx]->id()) if (model_object->id() != p->model.objects[obj_idx]->id())
continue; continue;
} }
Transform3d mesh_trafo_inv = object->trafo().inverse(); const Transform3d mesh_trafo_inv = object->trafo().inverse();
bool is_left_handed = object->is_left_handed(); const bool is_left_handed = object->is_left_handed();
TriangleMesh pad_mesh; TriangleMesh pad_mesh;
bool has_pad_mesh = extended && object->has_mesh(slaposPad); const bool has_pad_mesh = extended && object->has_mesh(slaposPad);
if (has_pad_mesh) if (has_pad_mesh) {
{
pad_mesh = object->get_mesh(slaposPad); pad_mesh = object->get_mesh(slaposPad);
pad_mesh.transform(mesh_trafo_inv); pad_mesh.transform(mesh_trafo_inv);
} }
TriangleMesh supports_mesh; TriangleMesh supports_mesh;
bool has_supports_mesh = extended && object->has_mesh(slaposSupportTree); const bool has_supports_mesh = extended && object->has_mesh(slaposSupportTree);
if (has_supports_mesh) if (has_supports_mesh) {
{
supports_mesh = object->get_mesh(slaposSupportTree); supports_mesh = object->get_mesh(slaposSupportTree);
supports_mesh.transform(mesh_trafo_inv); supports_mesh.transform(mesh_trafo_inv);
} }
const std::vector<SLAPrintObject::Instance>& obj_instances = object->instances(); const std::vector<SLAPrintObject::Instance>& 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(), 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; }); [&obj_instance](const ModelInstance *mi) { return mi->id() == obj_instance.instance_id; });
assert(it != model_object->instances.end()); assert(it != model_object->instances.end());
if (it != model_object->instances.end()) if (it != model_object->instances.end()) {
{ const bool one_inst_only = selection_only && ! selection.is_single_full_object();
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 const Transform3d& inst_transform = one_inst_only
? Transform3d::Identity() ? Transform3d::Identity()
: object->model_object()->instances[instance_idx]->get_transformation().get_matrix(); : object->model_object()->instances[instance_idx]->get_transformation().get_matrix();
TriangleMesh inst_mesh; TriangleMesh inst_mesh;
if (has_pad_mesh) if (has_pad_mesh) {
{
TriangleMesh inst_pad_mesh = pad_mesh; TriangleMesh inst_pad_mesh = pad_mesh;
inst_pad_mesh.transform(inst_transform, is_left_handed); inst_pad_mesh.transform(inst_transform, is_left_handed);
inst_mesh.merge(inst_pad_mesh); inst_mesh.merge(inst_pad_mesh);
} }
if (has_supports_mesh) if (has_supports_mesh) {
{
TriangleMesh inst_supports_mesh = supports_mesh; TriangleMesh inst_supports_mesh = supports_mesh;
inst_supports_mesh.transform(inst_transform, is_left_handed); inst_supports_mesh.transform(inst_transform, is_left_handed);
inst_mesh.merge(inst_supports_mesh); inst_mesh.merge(inst_supports_mesh);