diff options
author | Enrico Turri <enricoturri@seznam.cz> | 2018-08-15 13:50:06 +0300 |
---|---|---|
committer | Enrico Turri <enricoturri@seznam.cz> | 2018-08-15 13:50:06 +0300 |
commit | 4d98d321996de6e6d036403c319b6ef044144dcd (patch) | |
tree | c46a910b2e397fc239e89fb18599a8e2234fdb21 /xs/src | |
parent | 211790f8c35a7f950fddb95839a7b1009470a6ac (diff) |
Use of bounding box of rotated 3D convex hull for out of print volume detection
Diffstat (limited to 'xs/src')
-rw-r--r-- | xs/src/libslic3r/Format/3mf.cpp | 1 | ||||
-rw-r--r-- | xs/src/libslic3r/Format/AMF.cpp | 1 | ||||
-rw-r--r-- | xs/src/libslic3r/Model.cpp | 129 | ||||
-rw-r--r-- | xs/src/libslic3r/Model.hpp | 36 | ||||
-rw-r--r-- | xs/src/libslic3r/TriangleMesh.cpp | 133 | ||||
-rw-r--r-- | xs/src/libslic3r/TriangleMesh.hpp | 6 | ||||
-rw-r--r-- | xs/src/slic3r/GUI/3DScene.cpp | 76 | ||||
-rw-r--r-- | xs/src/slic3r/GUI/3DScene.hpp | 16 | ||||
-rw-r--r-- | xs/src/slic3r/GUI/GLCanvas3D.cpp | 2 | ||||
-rw-r--r-- | xs/src/slic3r/GUI/GLGizmo.cpp | 14 | ||||
-rw-r--r-- | xs/src/slic3r/GUI/GLGizmo.hpp | 2 |
11 files changed, 276 insertions, 140 deletions
diff --git a/xs/src/libslic3r/Format/3mf.cpp b/xs/src/libslic3r/Format/3mf.cpp index dd3500eba..5de1d26c5 100644 --- a/xs/src/libslic3r/Format/3mf.cpp +++ b/xs/src/libslic3r/Format/3mf.cpp @@ -1491,6 +1491,7 @@ namespace Slic3r { stl_get_size(&stl); volume->mesh.repair(); + volume->calculate_convex_hull(); // apply volume's name and config data for (const Metadata& metadata : volume_data.metadata) diff --git a/xs/src/libslic3r/Format/AMF.cpp b/xs/src/libslic3r/Format/AMF.cpp index 600aa6cd9..886bbae97 100644 --- a/xs/src/libslic3r/Format/AMF.cpp +++ b/xs/src/libslic3r/Format/AMF.cpp @@ -406,6 +406,7 @@ void AMFParserContext::endElement(const char * /* name */) } stl_get_size(&stl); m_volume->mesh.repair(); + m_volume->calculate_convex_hull(); m_volume_facets.clear(); m_volume = nullptr; break; diff --git a/xs/src/libslic3r/Model.cpp b/xs/src/libslic3r/Model.cpp index f9936537f..23d447748 100644 --- a/xs/src/libslic3r/Model.cpp +++ b/xs/src/libslic3r/Model.cpp @@ -17,6 +17,11 @@ #include "SVG.hpp" #include <Eigen/Dense> +static const float UNIT_MATRIX[] = { 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f }; + namespace Slic3r { unsigned int Model::s_auto_extruder_id = 1; @@ -235,14 +240,6 @@ BoundingBoxf3 Model::bounding_box() const return bb; } -BoundingBoxf3 Model::transformed_bounding_box() const -{ - BoundingBoxf3 bb; - for (const ModelObject* obj : this->objects) - bb.merge(obj->tight_bounding_box(false)); - return bb; -} - void Model::center_instances_around_point(const Pointf &point) { // BoundingBoxf3 bb = this->bounding_box(); @@ -623,54 +620,6 @@ const BoundingBoxf3& ModelObject::bounding_box() const return m_bounding_box; } -BoundingBoxf3 ModelObject::tight_bounding_box(bool include_modifiers) const -{ - BoundingBoxf3 bb; - - for (const ModelVolume* vol : this->volumes) - { - if (include_modifiers || !vol->modifier) - { - for (const ModelInstance* inst : this->instances) - { - double c = cos(inst->rotation); - double s = sin(inst->rotation); - - for (int f = 0; f < vol->mesh.stl.stats.number_of_facets; ++f) - { - const stl_facet& facet = vol->mesh.stl.facet_start[f]; - - for (int i = 0; i < 3; ++i) - { - // original point - const stl_vertex& v = facet.vertex[i]; - Pointf3 p((double)v.x, (double)v.y, (double)v.z); - - // scale - p.x *= inst->scaling_factor; - p.y *= inst->scaling_factor; - p.z *= inst->scaling_factor; - - // rotate Z - double x = p.x; - double y = p.y; - p.x = c * x - s * y; - p.y = s * x + c * y; - - // translate - p.x += inst->offset.x; - p.y += inst->offset.y; - - bb.merge(p); - } - } - } - } - } - - return bb; -} - // A mesh containing all transformed instances of this object. TriangleMesh ModelObject::mesh() const { @@ -755,15 +704,22 @@ void ModelObject::center_around_origin() void ModelObject::translate(coordf_t x, coordf_t y, coordf_t z) { for (ModelVolume *v : this->volumes) + { v->mesh.translate(float(x), float(y), float(z)); - if (m_bounding_box_valid) + v->m_convex_hull.translate(float(x), float(y), float(z)); + } + + if (m_bounding_box_valid) m_bounding_box.translate(x, y, z); } void ModelObject::scale(const Pointf3 &versor) { for (ModelVolume *v : this->volumes) + { v->mesh.scale(versor); + v->m_convex_hull.scale(versor); + } // reset origin translation since it doesn't make sense anymore this->origin_translation = Pointf3(0,0,0); this->invalidate_bounding_box(); @@ -774,6 +730,7 @@ void ModelObject::rotate(float angle, const Axis &axis) for (ModelVolume *v : this->volumes) { v->mesh.rotate(angle, axis); + v->m_convex_hull.rotate(angle, axis); } center_around_origin(); @@ -790,6 +747,7 @@ void ModelObject::transform(const float* matrix3x4) for (ModelVolume* v : volumes) { v->mesh.transform(matrix3x4); + v->m_convex_hull.transform(matrix3x4); } origin_translation = Pointf3(0.0, 0.0, 0.0); @@ -799,8 +757,12 @@ void ModelObject::transform(const float* matrix3x4) void ModelObject::mirror(const Axis &axis) { for (ModelVolume *v : this->volumes) + { v->mesh.mirror(axis); - this->origin_translation = Pointf3(0,0,0); + v->m_convex_hull.mirror(axis); + } + + this->origin_translation = Pointf3(0, 0, 0); this->invalidate_bounding_box(); } @@ -904,45 +866,20 @@ void ModelObject::split(ModelObjectPtrs* new_objects) void ModelObject::check_instances_print_volume_state(const BoundingBoxf3& print_volume) { - for (ModelVolume* vol : this->volumes) + for (const ModelVolume* vol : this->volumes) { if (!vol->modifier) { for (ModelInstance* inst : this->instances) { - BoundingBoxf3 bb; - - double c = cos(inst->rotation); - double s = sin(inst->rotation); - - for (int f = 0; f < vol->mesh.stl.stats.number_of_facets; ++f) - { - const stl_facet& facet = vol->mesh.stl.facet_start[f]; + std::vector<float> world_mat(UNIT_MATRIX, std::end(UNIT_MATRIX)); + Eigen::Transform<float, 3, Eigen::Affine> m = Eigen::Transform<float, 3, Eigen::Affine>::Identity(); + m.translate(Eigen::Vector3f((float)inst->offset.x, (float)inst->offset.y, 0.0f)); + m.rotate(Eigen::AngleAxisf(inst->rotation, Eigen::Vector3f::UnitZ())); + m.scale(inst->scaling_factor); + ::memcpy((void*)world_mat.data(), (const void*)m.data(), 16 * sizeof(float)); - for (int i = 0; i < 3; ++i) - { - // original point - const stl_vertex& v = facet.vertex[i]; - Pointf3 p((double)v.x, (double)v.y, (double)v.z); - - // scale - p.x *= inst->scaling_factor; - p.y *= inst->scaling_factor; - p.z *= inst->scaling_factor; - - // rotate Z - double x = p.x; - double y = p.y; - p.x = c * x - s * y; - p.y = s * x + c * y; - - // translate - p.x += inst->offset.x; - p.y += inst->offset.y; - - bb.merge(p); - } - } + BoundingBoxf3 bb = vol->get_convex_hull().transformed_bounding_box(world_mat); if (print_volume.contains(bb)) inst->print_volume_state = ModelInstance::PVS_Inside; @@ -1025,6 +962,16 @@ ModelMaterial* ModelVolume::assign_unique_material() return model->add_material(this->_material_id); } +void ModelVolume::calculate_convex_hull() +{ + m_convex_hull = mesh.convex_hull_3d(); +} + +const TriangleMesh& ModelVolume::get_convex_hull() const +{ + return m_convex_hull; +} + // Split this volume, append the result to the object owning this volume. // Return the number of volumes created from this one. // This is useful to assign different materials to different volumes of an object. diff --git a/xs/src/libslic3r/Model.hpp b/xs/src/libslic3r/Model.hpp index 4c650f0de..23af9fb1c 100644 --- a/xs/src/libslic3r/Model.hpp +++ b/xs/src/libslic3r/Model.hpp @@ -105,9 +105,6 @@ public: // This bounding box is being cached. const BoundingBoxf3& bounding_box() const; void invalidate_bounding_box() { m_bounding_box_valid = false; } - // Returns a snug bounding box of the transformed instances. - // This bounding box is not being cached. - BoundingBoxf3 tight_bounding_box(bool include_modifiers) const; // A mesh containing all transformed instances of this object. TriangleMesh mesh() const; @@ -157,6 +154,10 @@ private: class ModelVolume { friend class ModelObject; + + // The convex hull of this model's mesh. + TriangleMesh m_convex_hull; + public: std::string name; // The triangular model. @@ -180,19 +181,32 @@ public: ModelMaterial* assign_unique_material(); + void calculate_convex_hull(); + const TriangleMesh& get_convex_hull() const; + private: // Parent object owning this ModelVolume. ModelObject* object; t_model_material_id _material_id; - ModelVolume(ModelObject *object, const TriangleMesh &mesh) : mesh(mesh), modifier(false), object(object) {} - ModelVolume(ModelObject *object, TriangleMesh &&mesh) : mesh(std::move(mesh)), modifier(false), object(object) {} - ModelVolume(ModelObject *object, const ModelVolume &other) : - name(other.name), mesh(other.mesh), config(other.config), modifier(other.modifier), object(object) - { this->material_id(other.material_id()); } - ModelVolume(ModelObject *object, const ModelVolume &other, const TriangleMesh &&mesh) : + ModelVolume(ModelObject *object, const TriangleMesh &mesh) : mesh(mesh), modifier(false), object(object) + { + if (mesh.stl.stats.number_of_facets > 1) + calculate_convex_hull(); + } + ModelVolume(ModelObject *object, TriangleMesh &&mesh, TriangleMesh &&convex_hull) : mesh(std::move(mesh)), m_convex_hull(std::move(convex_hull)), modifier(false), object(object) {} + ModelVolume(ModelObject *object, const ModelVolume &other) : + name(other.name), mesh(other.mesh), m_convex_hull(other.m_convex_hull), config(other.config), modifier(other.modifier), object(object) + { + this->material_id(other.material_id()); + } + ModelVolume(ModelObject *object, const ModelVolume &other, const TriangleMesh &&mesh) : name(other.name), mesh(std::move(mesh)), config(other.config), modifier(other.modifier), object(object) - { this->material_id(other.material_id()); } + { + this->material_id(other.material_id()); + if (mesh.stl.stats.number_of_facets > 1) + calculate_convex_hull(); + } }; // A single instance of a ModelObject. @@ -285,8 +299,6 @@ public: bool add_default_instances(); // Returns approximate axis aligned bounding box of this model BoundingBoxf3 bounding_box() const; - // Returns tight axis aligned bounding box of this model - BoundingBoxf3 transformed_bounding_box() const; void center_instances_around_point(const Pointf &point); void translate(coordf_t x, coordf_t y, coordf_t z) { for (ModelObject *o : this->objects) o->translate(x, y, z); } TriangleMesh mesh() const; diff --git a/xs/src/libslic3r/TriangleMesh.cpp b/xs/src/libslic3r/TriangleMesh.cpp index 45e4b6f5d..fc72a45aa 100644 --- a/xs/src/libslic3r/TriangleMesh.cpp +++ b/xs/src/libslic3r/TriangleMesh.cpp @@ -1,6 +1,9 @@ #include "TriangleMesh.hpp" #include "ClipperUtils.hpp" #include "Geometry.hpp" +#include "qhull/src/libqhullcpp/Qhull.h" +#include "qhull/src/libqhullcpp/QhullFacetList.h" +#include "qhull/src/libqhullcpp/QhullVertexSet.h" #include <cmath> #include <deque> #include <queue> @@ -15,6 +18,8 @@ #include <tbb/parallel_for.h> +#include <Eigen/Dense> + #if 0 #define DEBUG #define _DEBUG @@ -597,6 +602,134 @@ TriangleMesh::bounding_box() const return bb; } +BoundingBoxf3 TriangleMesh::transformed_bounding_box(const std::vector<float>& matrix) const +{ + bool has_shared = (stl.v_shared != nullptr); + if (!has_shared) + stl_generate_shared_vertices(&stl); + + unsigned int vertices_count = (stl.stats.shared_vertices > 0) ? (unsigned int)stl.stats.shared_vertices : 3 * (unsigned int)stl.stats.number_of_facets; + + if (vertices_count == 0) + return BoundingBoxf3(); + + Eigen::MatrixXf src_vertices(3, vertices_count); + + if (stl.stats.shared_vertices > 0) + { + stl_vertex* vertex_ptr = stl.v_shared; + for (int i = 0; i < stl.stats.shared_vertices; ++i) + { + src_vertices(0, i) = vertex_ptr->x; + src_vertices(1, i) = vertex_ptr->y; + src_vertices(2, i) = vertex_ptr->z; + vertex_ptr += 1; + } + } + else + { + stl_facet* facet_ptr = stl.facet_start; + unsigned int v_id = 0; + while (facet_ptr < stl.facet_start + stl.stats.number_of_facets) + { + for (int i = 0; i < 3; ++i) + { + src_vertices(0, v_id) = facet_ptr->vertex[i].x; + src_vertices(1, v_id) = facet_ptr->vertex[i].y; + src_vertices(2, v_id) = facet_ptr->vertex[i].z; + } + facet_ptr += 1; + ++v_id; + } + } + + if (!has_shared && (stl.stats.shared_vertices > 0)) + stl_invalidate_shared_vertices(&stl); + + Eigen::Transform<float, 3, Eigen::Affine> m; + ::memcpy((void*)m.data(), (const void*)matrix.data(), 16 * sizeof(float)); + + Eigen::MatrixXf dst_vertices(3, vertices_count); + dst_vertices = m * src_vertices.colwise().homogeneous(); + + float min_x = dst_vertices(0, 0); + float max_x = dst_vertices(0, 0); + float min_y = dst_vertices(1, 0); + float max_y = dst_vertices(1, 0); + float min_z = dst_vertices(2, 0); + float max_z = dst_vertices(2, 0); + + for (int i = 1; i < vertices_count; ++i) + { + min_x = std::min(min_x, dst_vertices(0, i)); + max_x = std::max(max_x, dst_vertices(0, i)); + min_y = std::min(min_y, dst_vertices(1, i)); + max_y = std::max(max_y, dst_vertices(1, i)); + min_z = std::min(min_z, dst_vertices(2, i)); + max_z = std::max(max_z, dst_vertices(2, i)); + } + + return BoundingBoxf3(Pointf3((coordf_t)min_x, (coordf_t)min_y, (coordf_t)min_z), Pointf3((coordf_t)max_x, (coordf_t)max_y, (coordf_t)max_z)); +} + +TriangleMesh TriangleMesh::convex_hull_3d() const +{ + // Helper struct for qhull: + struct PointForQHull{ + PointForQHull(float x_p, float y_p, float z_p) : x((realT)x_p), y((realT)y_p), z((realT)z_p) {} + realT x, y, z; + }; + std::vector<PointForQHull> src_vertices; + + // We will now fill the vector with input points for computation: + stl_facet* facet_ptr = stl.facet_start; + while (facet_ptr < stl.facet_start + stl.stats.number_of_facets) + { + for (int i = 0; i < 3; ++i) + { + const stl_vertex& v = facet_ptr->vertex[i]; + src_vertices.emplace_back(v.x, v.y, v.z); + } + + facet_ptr += 1; + } + + // The qhull call: + orgQhull::Qhull qhull; + qhull.disableOutputStream(); // we want qhull to be quiet + try + { + qhull.runQhull("", 3, (int)src_vertices.size(), (const realT*)(src_vertices.data()), "Qt"); + } + catch (...) + { + std::cout << "Unable to create convex hull" << std::endl; + return TriangleMesh(); + } + + // Let's collect results: + Pointf3s det_vertices; + std::vector<Point3> facets; + auto facet_list = qhull.facetList().toStdVector(); + for (const orgQhull::QhullFacet& facet : facet_list) + { // iterate through facets + orgQhull::QhullVertexSet vertices = facet.vertices(); + for (int i = 0; i < 3; ++i) + { // iterate through facet's vertices + + orgQhull::QhullPoint p = vertices[i].point(); + const float* coords = p.coordinates(); + det_vertices.emplace_back(coords[0], coords[1], coords[2]); + } + unsigned int size = (unsigned int)det_vertices.size(); + facets.emplace_back(size - 3, size - 2, size - 1); + } + + TriangleMesh output_mesh(det_vertices, facets); + output_mesh.repair(); + return output_mesh; +} + void TriangleMesh::require_shared_vertices() { diff --git a/xs/src/libslic3r/TriangleMesh.hpp b/xs/src/libslic3r/TriangleMesh.hpp index c700784a5..6ab52efe2 100644 --- a/xs/src/libslic3r/TriangleMesh.hpp +++ b/xs/src/libslic3r/TriangleMesh.hpp @@ -55,6 +55,10 @@ public: ExPolygons horizontal_projection() const; Polygon convex_hull(); BoundingBoxf3 bounding_box() const; + // Returns the bbox of this TriangleMesh transformed by the given matrix + BoundingBoxf3 transformed_bounding_box(const std::vector<float>& matrix) const; + // Returns the convex hull of this TriangleMesh + TriangleMesh convex_hull_3d() const; void reset_repair_stats(); bool needed_repair() const; size_t facets_count() const; @@ -66,7 +70,7 @@ public: // Count disconnected triangle patches. size_t number_of_patches() const; - stl_file stl; + mutable stl_file stl; bool repaired; private: diff --git a/xs/src/slic3r/GUI/3DScene.cpp b/xs/src/slic3r/GUI/3DScene.cpp index 3f01eb20c..0709271b8 100644 --- a/xs/src/slic3r/GUI/3DScene.cpp +++ b/xs/src/slic3r/GUI/3DScene.cpp @@ -202,7 +202,8 @@ const float GLVolume::SELECTED_OUTSIDE_COLOR[4] = { 0.19f, 0.58f, 1.0f, 1.0f }; GLVolume::GLVolume(float r, float g, float b, float a) : m_angle_z(0.0f) , m_scale_factor(1.0f) - , m_dirty(true) + , m_transformed_bounding_box_dirty(true) + , m_transformed_convex_hull_bounding_box_dirty(true) , composite_id(-1) , select_group_id(-1) , drag_group_id(-1) @@ -219,8 +220,6 @@ GLVolume::GLVolume(float r, float g, float b, float a) , tverts_range(0, size_t(-1)) , qverts_range(0, size_t(-1)) { - m_world_mat = std::vector<float>(UNIT_MATRIX, std::end(UNIT_MATRIX)); - color[0] = r; color[1] = g; color[2] = b; @@ -264,45 +263,76 @@ const Pointf3& GLVolume::get_origin() const void GLVolume::set_origin(const Pointf3& origin) { - m_origin = origin; - m_dirty = true; + if (m_origin != origin) + { + m_origin = origin; + m_transformed_bounding_box_dirty = true; + m_transformed_convex_hull_bounding_box_dirty = true; + } } void GLVolume::set_angle_z(float angle_z) { - m_angle_z = angle_z; - m_dirty = true; + if (m_angle_z != angle_z) + { + m_angle_z = angle_z; + m_transformed_bounding_box_dirty = true; + m_transformed_convex_hull_bounding_box_dirty = true; + } } void GLVolume::set_scale_factor(float scale_factor) { - m_scale_factor = scale_factor; - m_dirty = true; + if (m_scale_factor != scale_factor) + { + m_scale_factor = scale_factor; + m_transformed_bounding_box_dirty = true; + m_transformed_convex_hull_bounding_box_dirty = true; + } } -const std::vector<float>& GLVolume::world_matrix() const +void GLVolume::set_convex_hull(const TriangleMesh& convex_hull) { - if (m_dirty) - { - Eigen::Transform<float, 3, Eigen::Affine> m = Eigen::Transform<float, 3, Eigen::Affine>::Identity(); - m.translate(Eigen::Vector3f((float)m_origin.x, (float)m_origin.y, (float)m_origin.z)); - m.rotate(Eigen::AngleAxisf(m_angle_z, Eigen::Vector3f::UnitZ())); - m.scale(m_scale_factor); - ::memcpy((void*)m_world_mat.data(), (const void*)m.data(), 16 * sizeof(float)); - m_dirty = false; - } + m_convex_hull = convex_hull; +} - return m_world_mat; +std::vector<float> GLVolume::world_matrix() const +{ + std::vector<float> world_mat(UNIT_MATRIX, std::end(UNIT_MATRIX)); + Eigen::Transform<float, 3, Eigen::Affine> m = Eigen::Transform<float, 3, Eigen::Affine>::Identity(); + m.translate(Eigen::Vector3f((float)m_origin.x, (float)m_origin.y, (float)m_origin.z)); + m.rotate(Eigen::AngleAxisf(m_angle_z, Eigen::Vector3f::UnitZ())); + m.scale(m_scale_factor); + ::memcpy((void*)world_mat.data(), (const void*)m.data(), 16 * sizeof(float)); + return world_mat; } BoundingBoxf3 GLVolume::transformed_bounding_box() const { - if (m_dirty) + if (m_transformed_bounding_box_dirty) + { m_transformed_bounding_box = bounding_box.transformed(world_matrix()); + m_transformed_bounding_box_dirty = false; + } return m_transformed_bounding_box; } +BoundingBoxf3 GLVolume::transformed_convex_hull_bounding_box() const +{ + if (m_transformed_convex_hull_bounding_box_dirty) + { + if (m_convex_hull.stl.stats.number_of_facets > 0) + m_transformed_convex_hull_bounding_box = m_convex_hull.transformed_bounding_box(world_matrix()); + else + m_transformed_convex_hull_bounding_box = bounding_box.transformed(world_matrix()); + + m_transformed_convex_hull_bounding_box_dirty = false; + } + + return m_transformed_convex_hull_bounding_box; +} + void GLVolume::set_range(double min_z, double max_z) { this->qverts_range.first = 0; @@ -629,6 +659,7 @@ std::vector<int> GLVolumeCollection::load_object( if (!model_volume->modifier) { + v.set_convex_hull(model_volume->get_convex_hull()); v.layer_height_texture = layer_height_texture; if (extruder_id != -1) v.extruder_id = extruder_id; @@ -716,6 +747,7 @@ int GLVolumeCollection::load_wipe_tower_preview( v.drag_group_id = obj_idx * 1000; v.is_wipe_tower = true; v.shader_outside_printer_detection_enabled = ! size_unknown; + v.set_convex_hull(mesh.convex_hull_3d()); return int(this->volumes.size() - 1); } @@ -803,7 +835,7 @@ bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, M { if ((volume != nullptr) && !volume->is_modifier) { - const BoundingBoxf3& bb = volume->transformed_bounding_box(); + const BoundingBoxf3& bb = volume->transformed_convex_hull_bounding_box(); bool contained = print_volume.contains(bb); all_contained &= contained; diff --git a/xs/src/slic3r/GUI/3DScene.hpp b/xs/src/slic3r/GUI/3DScene.hpp index a552b32a7..1265bc20d 100644 --- a/xs/src/slic3r/GUI/3DScene.hpp +++ b/xs/src/slic3r/GUI/3DScene.hpp @@ -260,12 +260,16 @@ private: float m_angle_z; // Scale factor of the volume to be rendered. float m_scale_factor; - // World matrix of the volume to be rendered. - std::vector<float> m_world_mat; // Bounding box of this volume, in unscaled coordinates. mutable BoundingBoxf3 m_transformed_bounding_box; - // Whether or not is needed to recalculate the world matrix. - mutable bool m_dirty; + // Whether or not is needed to recalculate the transformed bounding box. + mutable bool m_transformed_bounding_box_dirty; + // Convex hull of the original mesh, if any. + TriangleMesh m_convex_hull; + // Bounding box of this volume, in unscaled coordinates. + mutable BoundingBoxf3 m_transformed_convex_hull_bounding_box; + // Whether or not is needed to recalculate the transformed convex hull bounding box. + mutable bool m_transformed_convex_hull_bounding_box_dirty; public: @@ -323,13 +327,15 @@ public: void set_origin(const Pointf3& origin); void set_angle_z(float angle_z); void set_scale_factor(float scale_factor); + void set_convex_hull(const TriangleMesh& convex_hull); int object_idx() const { return this->composite_id / 1000000; } int volume_idx() const { return (this->composite_id / 1000) % 1000; } int instance_idx() const { return this->composite_id % 1000; } - const std::vector<float>& world_matrix() const; + std::vector<float> world_matrix() const; BoundingBoxf3 transformed_bounding_box() const; + BoundingBoxf3 transformed_convex_hull_bounding_box() const; bool empty() const { return this->indexed_vertex_array.empty(); } bool indexed() const { return this->indexed_vertex_array.indexed(); } diff --git a/xs/src/slic3r/GUI/GLCanvas3D.cpp b/xs/src/slic3r/GUI/GLCanvas3D.cpp index ab4095e6f..92bde34ce 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.cpp @@ -3243,7 +3243,7 @@ BoundingBoxf3 GLCanvas3D::_selected_volumes_bounding_box() const { for (const GLVolume* volume : selected_volumes) { - bb.merge(volume->transformed_bounding_box()); + bb.merge(volume->transformed_convex_hull_bounding_box()); } } diff --git a/xs/src/slic3r/GUI/GLGizmo.cpp b/xs/src/slic3r/GUI/GLGizmo.cpp index 47b01e8a2..7207022bd 100644 --- a/xs/src/slic3r/GUI/GLGizmo.cpp +++ b/xs/src/slic3r/GUI/GLGizmo.cpp @@ -189,7 +189,7 @@ GLGizmoRotate::GLGizmoRotate() , m_angle_z(0.0f) , m_center(Pointf(0.0, 0.0)) , m_radius(0.0f) - , m_keep_radius(false) + , m_keep_initial_values(false) { } @@ -229,7 +229,7 @@ bool GLGizmoRotate::on_init() void GLGizmoRotate::on_set_state() { - m_keep_radius = (m_state == On) ? false : true; + m_keep_initial_values = (m_state == On) ? false : true; } void GLGizmoRotate::on_update(const Pointf& mouse_pos) @@ -255,19 +255,19 @@ void GLGizmoRotate::on_update(const Pointf& mouse_pos) void GLGizmoRotate::on_refresh() { - m_keep_radius = false; + m_keep_initial_values = false; } void GLGizmoRotate::on_render(const BoundingBoxf3& box) const { ::glDisable(GL_DEPTH_TEST); - const Pointf3& size = box.size(); - m_center = box.center(); - if (!m_keep_radius) + if (!m_keep_initial_values) { + const Pointf3& size = box.size(); + m_center = box.center(); m_radius = Offset + ::sqrt(sqr(0.5f * size.x) + sqr(0.5f * size.y)); - m_keep_radius = true; + m_keep_initial_values = true; } ::glLineWidth(2.0f); diff --git a/xs/src/slic3r/GUI/GLGizmo.hpp b/xs/src/slic3r/GUI/GLGizmo.hpp index 506b3972e..839969090 100644 --- a/xs/src/slic3r/GUI/GLGizmo.hpp +++ b/xs/src/slic3r/GUI/GLGizmo.hpp @@ -101,7 +101,7 @@ class GLGizmoRotate : public GLGizmoBase mutable Pointf m_center; mutable float m_radius; - mutable bool m_keep_radius; + mutable bool m_keep_initial_values; public: GLGizmoRotate(); |