void ModelObject::center_around_origin() { // calculate the displacements needed to // center this object around the origin 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); // then center it on XY Sizef3 size = bb.size(); vector.x -= size.x/2; vector.y -= size.y/2; this->translate(vector); this->origin_translation.translate(vector); if (!this->instances.empty()) { for (ModelInstancePtrs::const_iterator i = this->instances.begin(); i != this->instances.end(); ++i) { // apply rotation and scaling to vector as well before translating instance, // in order to leave final position unaltered Vectorf3 v = vector.negative(); v.rotate((*i)->rotation, (*i)->offset); v.scale((*i)->scaling_factor); (*i)->offset.translate(v.x, v.y); } this->invalidate_bounding_box(); } }
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; }
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; }
// this returns the bounding box of the *transformed* instances BoundingBoxf3 Model::bounding_box() const { BoundingBoxf3 bb; for (ModelObjectPtrs::const_iterator o = this->objects.begin(); o != this->objects.end(); ++o) { bb.merge((*o)->bounding_box()); } return bb; }
// this returns the bounding box of the *transformed* given instance BoundingBoxf3 ModelObject::instance_bounding_box(size_t instance_idx) const { 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; }
BoundingBoxf3 ModelObject::raw_bounding_box() const { BoundingBoxf3 bb; for (ModelVolumePtrs::const_iterator v = this->volumes.begin(); v != this->volumes.end(); ++v) { if ((*v)->modifier) continue; if (this->instances.empty()) CONFESS("Can't call raw_bounding_box() with no instances"); bb.merge(this->instances.front()->transform_mesh_bounding_box(&(*v)->mesh, true)); } return bb; }
void ModelObject::align_to_ground() { // calculate the displacements needed to // center this object around the origin BoundingBoxf3 bb; for (const ModelVolume* v : this->volumes) if (!v->modifier) bb.merge(v->mesh.bounding_box()); this->translate(0, 0, -bb.min.z); this->origin_translation.translate(0, 0, -bb.min.z); }
void ModelObject::update_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; }
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); double cx = cos(this->x_rotation); double sx = sin(this->x_rotation); double cy = cos(this->y_rotation); double sy = sin(this->y_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; double zold = v.z; // Rotation around x axis. v.z = float(sx * yold + cx * zold); yold = v.y = float(cx * yold - sx * zold); zold = v.z; // Rotation around y axis. v.x = float(cy * xold + sy * zold); v.z = float(-sy * xold + cy * zold); xold = v.x; // Rotation around z axis. v.x = float(c * xold - s * yold); v.y = float(s * xold + c * yold); v.x *= this->scaling_factor * this->scaling_vector.x; v.y *= this->scaling_factor * this->scaling_vector.y; v.z *= this->scaling_factor * this->scaling_vector.z; if (!dont_translate) { v.x += this->offset.x; v.y += this->offset.y; } out.merge(v); } return out; }
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); double cx = cos(this->x_rotation); double sx = sin(this->x_rotation); double cy = cos(this->y_rotation); double sy = sin(this->y_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; double zold = v.z; // Rotation around x axis. v.z = float(sx * yold + cx * zold); yold = v.y = float(cx * yold - sx * zold); zold = v.z; // Rotation around y axis. v.x = float(cy * xold + sy * zold); v.z = float(-sy * xold + cy * zold); xold = v.x; // Rotation around z axis. v.x = float(c * xold - s * yold); v.y = float(s * xold + c * yold); v.x *= float(this->scaling_factor * this->scaling_vector.x); v.y *= float(this->scaling_factor * this->scaling_vector.y); v.z *= float(this->scaling_factor * this->scaling_vector.z); if (!dont_translate) { v.x += this->offset.x; v.y += this->offset.y; if (this->y_rotation || this->x_rotation) v.z += -(mesh->stl.stats.min.z); } bbox.merge(Pointf3(v.x, v.y, v.z)); } } return bbox; }