diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 900397f70..81ed392c2 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -819,14 +819,27 @@ TriangleMesh ModelObject::full_raw_mesh() const BoundingBoxf3 ModelObject::raw_bounding_box() const { BoundingBoxf3 bb; +#if ENABLE_GENERIC_SUBPARTS_PLACEMENT + if (this->instances.empty()) + throw std::invalid_argument("Can't call raw_bounding_box() with no instances"); + + const Transform3d& inst_matrix = this->instances.front()->get_transformation().get_matrix(true); +#endif // ENABLE_GENERIC_SUBPARTS_PLACEMENT for (const ModelVolume *v : this->volumes) if (v->is_model_part()) { +#if !ENABLE_GENERIC_SUBPARTS_PLACEMENT if (this->instances.empty()) throw std::invalid_argument("Can't call raw_bounding_box() with no instances"); +#endif // !ENABLE_GENERIC_SUBPARTS_PLACEMENT TriangleMesh vol_mesh(v->mesh); +#if ENABLE_GENERIC_SUBPARTS_PLACEMENT + vol_mesh.transform(inst_matrix * v->get_matrix()); + bb.merge(vol_mesh.bounding_box()); +#else vol_mesh.transform(v->get_matrix()); bb.merge(this->instances.front()->transform_mesh_bounding_box(vol_mesh, true)); +#endif // ENABLE_GENERIC_SUBPARTS_PLACEMENT } return bb; } @@ -835,13 +848,21 @@ BoundingBoxf3 ModelObject::raw_bounding_box() const BoundingBoxf3 ModelObject::instance_bounding_box(size_t instance_idx, bool dont_translate) const { BoundingBoxf3 bb; +#if ENABLE_GENERIC_SUBPARTS_PLACEMENT + const Transform3d& inst_matrix = this->instances[instance_idx]->get_transformation().get_matrix(dont_translate); +#endif // ENABLE_GENERIC_SUBPARTS_PLACEMENT for (ModelVolume *v : this->volumes) { if (v->is_model_part()) { TriangleMesh mesh(v->mesh); +#if ENABLE_GENERIC_SUBPARTS_PLACEMENT + mesh.transform(inst_matrix * v->get_matrix()); + bb.merge(mesh.bounding_box()); +#else mesh.transform(v->get_matrix()); bb.merge(this->instances[instance_idx]->transform_mesh_bounding_box(mesh, dont_translate)); +#endif // ENABLE_GENERIC_SUBPARTS_PLACEMENT } } return bb; diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 629407ee2..3d63f781c 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -58,3 +58,5 @@ #define ENABLE_NEW_EULER_ANGLES (1 && ENABLE_1_42_0_ALPHA4) // Added minimum threshold for click and drag movements #define ENABLE_MOVE_MIN_THRESHOLD (1 && ENABLE_1_42_0_ALPHA4) +// Modified initial default placement of generic subparts +#define ENABLE_GENERIC_SUBPARTS_PLACEMENT (1 && ENABLE_1_42_0_ALPHA4) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 77906fe0d..24aa5e45c 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -895,9 +895,29 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const int auto new_volume = (*m_objects)[obj_idx]->add_volume(mesh); new_volume->set_type(static_cast(type)); +#if !ENABLE_GENERIC_SUBPARTS_PLACEMENT new_volume->set_offset(Vec3d(0.0, 0.0, (*m_objects)[obj_idx]->origin_translation(2) - mesh.stl.stats.min(2))); +#endif // !ENABLE_GENERIC_SUBPARTS_PLACEMENT new_volume->center_geometry(); +#if ENABLE_GENERIC_SUBPARTS_PLACEMENT + const GLCanvas3D::Selection& selection = wxGetApp().plater()->canvas3D()->get_selection(); + int instance_idx = selection.get_instance_idx(); + if (instance_idx != -1) + { + const GLVolume* v = selection.get_volume(*selection.get_volume_idxs().begin()); + const Transform3d& inst_m = v->get_instance_transformation().get_matrix(true); + TriangleMesh vol_mesh(mesh); + vol_mesh.transform(inst_m); + Vec3d vol_shift = -vol_mesh.bounding_box().center(); + vol_mesh.translate((float)vol_shift(0), (float)vol_shift(1), (float)vol_shift(2)); + Vec3d world_mesh_bb_size = vol_mesh.bounding_box().size(); + BoundingBoxf3 inst_bb = (*m_objects)[obj_idx]->instance_bounding_box(instance_idx); + Vec3d world_target = Vec3d(inst_bb.max(0), inst_bb.min(1), inst_bb.min(2)) + 0.5 * world_mesh_bb_size; + new_volume->set_offset(inst_m.inverse() * (world_target - v->get_instance_offset())); + } +#endif // ENABLE_GENERIC_SUBPARTS_PLACEMENT + new_volume->name = name; // set a default extruder value, since user can't add it manually new_volume->config.set_key_value("extruder", new ConfigOptionInt(0));