From cf2f16d864e1493ee57b803af6576f13dac6f29e Mon Sep 17 00:00:00 2001 From: bubnikv Date: Mon, 5 Aug 2019 17:49:21 +0200 Subject: [PATCH] Fixed Model::convert_multipart_object() for STLs (regression from 8e2af5151dcf6f102b65981ff5aa56c2dfda5a2a). Removed Model::s_auto_extruder_id and related, as it is a Perl interfacing legacy. Fixed a typo in asserts introduced in the preceding commit. --- src/libslic3r/Model.cpp | 119 ++++++++++++------------------------- src/libslic3r/Model.hpp | 10 +--- src/slic3r/GUI/3DScene.hpp | 4 +- src/slic3r/GUI/Plater.cpp | 2 +- 4 files changed, 43 insertions(+), 92 deletions(-) diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 76ef9ecca..479a8f994 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -21,8 +21,6 @@ namespace Slic3r { -unsigned int Model::s_auto_extruder_id = 1; - Model& Model::assign_copy(const Model &rhs) { this->copy_id(rhs); @@ -485,9 +483,20 @@ bool Model::looks_like_multipart_object() const return false; } +// Generate next extruder ID string, in the range of (1, max_extruders). +static inline std::string auto_extruder_id(unsigned int max_extruders, unsigned int &cntr) +{ + char str_extruder[64]; + sprintf(str_extruder, "%ud", cntr + 1); + if (++ cntr == max_extruders) + cntr = 0; + return str_extruder; +} + void Model::convert_multipart_object(unsigned int max_extruders) { - if (this->objects.empty()) + assert(this->objects.size() >= 2); + if (this->objects.size() < 2) return; ModelObject* object = new ModelObject(this); @@ -495,58 +504,32 @@ void Model::convert_multipart_object(unsigned int max_extruders) object->name = this->objects.front()->name; //FIXME copy the config etc? - reset_auto_extruder_id(); - - bool is_single_object = (this->objects.size() == 1); - - for (const ModelObject* o : this->objects) - { - for (const ModelVolume* v : o->volumes) - { - if (is_single_object) - { - // If there is only one object, just copy the volumes - ModelVolume* new_v = object->add_volume(*v); - if (new_v != nullptr) - { - new_v->name = o->name; - new_v->config.set_deserialize("extruder", get_auto_extruder_id_as_string(max_extruders)); - new_v->translate(-o->origin_translation); - } - } - else - { - // If there are more than one object, put all volumes together - // Each object may contain any number of volumes and instances - // The volumes transformations are relative to the object containing them... - int counter = 1; - for (const ModelInstance* i : o->instances) - { - ModelVolume* new_v = object->add_volume(*v); - if (new_v != nullptr) - { - new_v->name = o->name + "_" + std::to_string(counter++); - new_v->config.set_deserialize("extruder", get_auto_extruder_id_as_string(max_extruders)); - new_v->translate(-o->origin_translation); - // ...so, transform everything to a common reference system (world) - new_v->set_transformation(i->get_transformation() * v->get_transformation()); - } - } + unsigned int extruder_counter = 0; + for (const ModelObject* o : this->objects) + for (const ModelVolume* v : o->volumes) { + // If there are more than one object, put all volumes together + // Each object may contain any number of volumes and instances + // The volumes transformations are relative to the object containing them... + Geometry::Transformation trafo_volume = v->get_transformation(); + // Revert the centering operation. + trafo_volume.set_offset(trafo_volume.get_offset() - o->origin_translation); + int counter = 1; + auto copy_volume = [o, max_extruders, &counter, &extruder_counter](ModelVolume *new_v) { + assert(new_v != nullptr); + new_v->name = o->name + "_" + std::to_string(counter++); + new_v->config.set_deserialize("extruder", auto_extruder_id(max_extruders, extruder_counter)); + return new_v; + }; + if (o->instances.empty()) { + copy_volume(object->add_volume(*v))->set_transformation(trafo_volume); + } else { + for (const ModelInstance* i : o->instances) + // ...so, transform everything to a common reference system (world) + copy_volume(object->add_volume(*v))->set_transformation(i->get_transformation() * trafo_volume); } } - } - - if (is_single_object) - { - // If there is only one object, keep its instances - for (const ModelInstance* i : this->objects.front()->instances) - { - object->add_instance(*i); - } - } - else - // If there are more than one object, create a single instance - object->add_instance(); + // If there are more than one object, create a single instance + object->add_instance(); this->clear_objects(); this->objects.push_back(object); @@ -571,32 +554,6 @@ void Model::adjust_min_z() } } -unsigned int Model::get_auto_extruder_id(unsigned int max_extruders) -{ - unsigned int id = s_auto_extruder_id; - if (id > max_extruders) { - // The current counter is invalid, likely due to switching the printer profiles - // to a profile with a lower number of extruders. - reset_auto_extruder_id(); - id = s_auto_extruder_id; - } else if (++ s_auto_extruder_id > max_extruders) { - reset_auto_extruder_id(); - } - return id; -} - -std::string Model::get_auto_extruder_id_as_string(unsigned int max_extruders) -{ - char str_extruder[64]; - sprintf(str_extruder, "%ud", get_auto_extruder_id(max_extruders)); - return str_extruder; -} - -void Model::reset_auto_extruder_id() -{ - s_auto_extruder_id = 1; -} - // Propose a filename including path derived from the ModelObject's input path. // If object's name is filled in, use the object name, otherwise use the input name. std::string Model::propose_export_file_name_and_path() const @@ -1661,7 +1618,7 @@ size_t ModelVolume::split(unsigned int max_extruders) size_t ivolume = std::find(this->object->volumes.begin(), this->object->volumes.end(), this) - this->object->volumes.begin(); std::string name = this->name; - Model::reset_auto_extruder_id(); + unsigned int extruder_counter = 0; Vec3d offset = this->get_offset(); for (TriangleMesh *mesh : meshptrs) { @@ -1680,7 +1637,7 @@ size_t ModelVolume::split(unsigned int max_extruders) this->object->volumes[ivolume]->center_geometry_after_creation(); this->object->volumes[ivolume]->translate(offset); this->object->volumes[ivolume]->name = name + "_" + std::to_string(idx + 1); - this->object->volumes[ivolume]->config.set_deserialize("extruder", Model::get_auto_extruder_id_as_string(max_extruders)); + this->object->volumes[ivolume]->config.set_deserialize("extruder", auto_extruder_id(max_extruders, extruder_counter)); delete mesh; ++ idx; } diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index a3281e522..2513bdd05 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -721,8 +721,6 @@ private: // all objects may share mutliple materials. class Model final : public ObjectBase { - static unsigned int s_auto_extruder_id; - public: // Materials are owned by a model and referenced by objects through t_model_material_id. // Single material may be shared by multiple models. @@ -791,14 +789,10 @@ public: void print_info() const { for (const ModelObject *o : this->objects) o->print_info(); } - static unsigned int get_auto_extruder_id(unsigned int max_extruders); - static std::string get_auto_extruder_id_as_string(unsigned int max_extruders); - static void reset_auto_extruder_id(); - // Propose an output file name & path based on the first printable object's name and source input file's path. - std::string propose_export_file_name_and_path() const; + std::string propose_export_file_name_and_path() const; // Propose an output path, replace extension. The new_extension shall contain the initial dot. - std::string propose_export_file_name_and_path(const std::string &new_extension) const; + std::string propose_export_file_name_and_path(const std::string &new_extension) const; private: explicit Model(int) : ObjectBase(-1) { assert(this->id().invalid()); }; diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 3d89a3a5f..06797ea95 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -81,7 +81,7 @@ public: assert(vertices_and_normals_interleaved_VBO_id == 0); assert(triangle_indices_VBO_id == 0); assert(quad_indices_VBO_id == 0); - assert(rhs.vertices_and_normals_interleaved == 0); + assert(rhs.vertices_and_normals_interleaved_VBO_id == 0); assert(rhs.triangle_indices_VBO_id == 0); assert(rhs.quad_indices_VBO_id == 0); this->vertices_and_normals_interleaved = rhs.vertices_and_normals_interleaved; @@ -99,7 +99,7 @@ public: assert(vertices_and_normals_interleaved_VBO_id == 0); assert(triangle_indices_VBO_id == 0); assert(quad_indices_VBO_id == 0); - assert(rhs.vertices_and_normals_interleaved == 0); + assert(rhs.vertices_and_normals_interleaved_VBO_id == 0); assert(rhs.triangle_indices_VBO_id == 0); assert(rhs.quad_indices_VBO_id == 0); this->vertices_and_normals_interleaved = std::move(rhs.vertices_and_normals_interleaved); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 23beb0962..dddf479eb 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2302,7 +2302,7 @@ std::vector Plater::priv::load_files(const std::vector& input_ } } - if (new_model != nullptr) { + if (new_model != nullptr && new_model->objects.size() > 1) { wxMessageDialog dlg(q, _(L( "Multiple objects were loaded for a multi-material printer.\n" "Instead of considering them as multiple objects, should I consider\n"