diff --git a/xs/src/admesh/util.c b/xs/src/admesh/util.c index f29ba1614..4ecb76e79 100644 --- a/xs/src/admesh/util.c +++ b/xs/src/admesh/util.c @@ -27,7 +27,7 @@ #include "stl.h" -static void stl_rotate(float *x, float *y, float angle); +static void stl_rotate(float *x, float *y, const double c, const double s); static float get_area(stl_facet *facet); static float get_volume(stl_file *stl); @@ -189,13 +189,16 @@ void stl_rotate_x(stl_file *stl, float angle) { int i; int j; + double radian_angle = (angle / 180.0) * M_PI; + double c = cos(radian_angle); + double s = sin(radian_angle); if (stl->error) return; for(i = 0; i < stl->stats.number_of_facets; i++) { for(j = 0; j < 3; j++) { stl_rotate(&stl->facet_start[i].vertex[j].y, - &stl->facet_start[i].vertex[j].z, angle); + &stl->facet_start[i].vertex[j].z, c, s); } } stl_get_size(stl); @@ -206,13 +209,16 @@ void stl_rotate_y(stl_file *stl, float angle) { int i; int j; + double radian_angle = (angle / 180.0) * M_PI; + double c = cos(radian_angle); + double s = sin(radian_angle); if (stl->error) return; for(i = 0; i < stl->stats.number_of_facets; i++) { for(j = 0; j < 3; j++) { stl_rotate(&stl->facet_start[i].vertex[j].z, - &stl->facet_start[i].vertex[j].x, angle); + &stl->facet_start[i].vertex[j].x, c, s); } } stl_get_size(stl); @@ -223,13 +229,16 @@ void stl_rotate_z(stl_file *stl, float angle) { int i; int j; + double radian_angle = (angle / 180.0) * M_PI; + double c = cos(radian_angle); + double s = sin(radian_angle); if (stl->error) return; for(i = 0; i < stl->stats.number_of_facets; i++) { for(j = 0; j < 3; j++) { stl_rotate(&stl->facet_start[i].vertex[j].x, - &stl->facet_start[i].vertex[j].y, angle); + &stl->facet_start[i].vertex[j].y, c, s); } } stl_get_size(stl); @@ -239,17 +248,11 @@ stl_rotate_z(stl_file *stl, float angle) { static void -stl_rotate(float *x, float *y, float angle) { - double r; - double theta; - double radian_angle; - - radian_angle = (angle / 180.0) * M_PI; - - r = sqrt((*x **x) + (*y **y)); - theta = atan2(*y, *x); - *x = r * cos(theta + radian_angle); - *y = r * sin(theta + radian_angle); +stl_rotate(float *x, float *y, const double c, const double s) { + double xold = *x; + double yold = *y; + *x = float(c * xold - s * yold); + *y = float(s * xold + c * yold); } extern void diff --git a/xs/src/libslic3r/Model.cpp b/xs/src/libslic3r/Model.cpp index 5db9066a6..e4a4c48a8 100644 --- a/xs/src/libslic3r/Model.cpp +++ b/xs/src/libslic3r/Model.cpp @@ -473,7 +473,16 @@ ModelObject::invalidate_bounding_box() void ModelObject::update_bounding_box() { - this->_bounding_box = this->mesh().bounding_box(); +// this->_bounding_box = this->mesh().bounding_box(); + BoundingBoxf3 raw_bbox; + for (ModelVolumePtrs::const_iterator v = this->volumes.begin(); v != this->volumes.end(); ++v) { + if ((*v)->modifier) continue; + raw_bbox.merge((*v)->mesh.bounding_box()); + } + BoundingBoxf3 bb; + for (ModelInstancePtrs::const_iterator i = this->instances.begin(); i != this->instances.end(); ++i) + bb.merge((*i)->transform_bounding_box(raw_bbox)); + this->_bounding_box = bb; this->_bounding_box_valid = true; } @@ -509,12 +518,8 @@ ModelObject::raw_bounding_box() const BoundingBoxf3 bb; for (ModelVolumePtrs::const_iterator v = this->volumes.begin(); v != this->volumes.end(); ++v) { if ((*v)->modifier) continue; - TriangleMesh mesh = (*v)->mesh; - if (this->instances.empty()) CONFESS("Can't call raw_bounding_box() with no instances"); - this->instances.front()->transform_mesh(&mesh, true); - - bb.merge(mesh.bounding_box()); + bb.merge(this->instances.front()->transform_mesh_bounding_box(&(*v)->mesh, true)); } return bb; } @@ -523,9 +528,12 @@ ModelObject::raw_bounding_box() const BoundingBoxf3 ModelObject::instance_bounding_box(size_t instance_idx) const { - TriangleMesh mesh = this->raw_mesh(); - this->instances[instance_idx]->transform_mesh(&mesh); - return mesh.bounding_box(); + BoundingBoxf3 bb; + for (ModelVolumePtrs::const_iterator v = this->volumes.begin(); v != this->volumes.end(); ++v) { + if ((*v)->modifier) continue; + bb.merge(this->instances[instance_idx]->transform_mesh_bounding_box(&(*v)->mesh, true)); + } + return bb; } void @@ -533,7 +541,10 @@ ModelObject::center_around_origin() { // calculate the displacements needed to // center this object around the origin - BoundingBoxf3 bb = this->raw_mesh().bounding_box(); + BoundingBoxf3 bb; + for (ModelVolumePtrs::const_iterator v = this->volumes.begin(); v != this->volumes.end(); ++v) + if (! (*v)->modifier) + bb.merge((*v)->mesh.bounding_box()); // first align to origin on XYZ Vectorf3 vector(-bb.min.x, -bb.min.y, -bb.min.z); @@ -775,6 +786,63 @@ ModelInstance::transform_mesh(TriangleMesh* mesh, bool dont_translate) const mesh->translate(this->offset.x, this->offset.y, 0); } +BoundingBoxf3 ModelInstance::transform_mesh_bounding_box(const TriangleMesh* mesh, bool dont_translate) const +{ + // rotate around mesh origin + double c = cos(this->rotation); + double s = sin(this->rotation); + BoundingBoxf3 bbox; + for (int i = 0; i < mesh->stl.stats.number_of_facets; ++ i) { + const stl_facet &facet = mesh->stl.facet_start[i]; + for (int j = 0; j < 3; ++ j) { + stl_vertex v = facet.vertex[j]; + double xold = v.x; + double yold = v.y; + v.x = float(c * xold - s * yold); + v.y = float(s * xold + c * yold); + v.x *= float(this->scaling_factor); + v.y *= float(this->scaling_factor); + v.z *= float(this->scaling_factor); + if (!dont_translate) { + v.x += this->offset.x; + v.y += this->offset.y; + } + bbox.merge(Pointf3(v.x, v.y, v.z)); + } + } + return bbox; +} + +BoundingBoxf3 ModelInstance::transform_bounding_box(const BoundingBoxf3 &bbox, bool dont_translate) const +{ + // rotate around mesh origin + double c = cos(this->rotation); + double s = sin(this->rotation); + Pointf3 pts[4] = { + bbox.min, + bbox.max, + Pointf3(bbox.min.x, bbox.max.y, bbox.min.z), + Pointf3(bbox.max.x, bbox.min.y, bbox.max.z) + }; + BoundingBoxf3 out; + for (int i = 0; i < 4; ++ i) { + Pointf3 &v = pts[i]; + double xold = v.x; + double yold = v.y; + v.x = float(c * xold - s * yold); + v.y = float(s * xold + c * yold); + v.x *= this->scaling_factor; + v.y *= this->scaling_factor; + v.z *= this->scaling_factor; + if (!dont_translate) { + v.x += this->offset.x; + v.y += this->offset.y; + } + out.merge(v); + } + return out; +} + void ModelInstance::transform_polygon(Polygon* polygon) const { diff --git a/xs/src/libslic3r/Model.hpp b/xs/src/libslic3r/Model.hpp index 60405f6f6..b2a9d0b53 100644 --- a/xs/src/libslic3r/Model.hpp +++ b/xs/src/libslic3r/Model.hpp @@ -215,6 +215,10 @@ public: // To be called on an external mesh void transform_mesh(TriangleMesh* mesh, bool dont_translate = false) const; + // Calculate a bounding box of a transformed mesh. To be called on an external mesh. + BoundingBoxf3 transform_mesh_bounding_box(const TriangleMesh* mesh, bool dont_translate = false) const; + // Transform an external bounding box. + BoundingBoxf3 transform_bounding_box(const BoundingBoxf3 &bbox, bool dont_translate = false) const; // To be called on an external polygon. It does not translate the polygon, only rotates and scales. void transform_polygon(Polygon* polygon) const;