mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-12 17:27:52 -06:00
Optimization of Model bounding box routines (avoids copying the mesh),
optimization of the admesh rotate function (also made numerically more robust).
This commit is contained in:
parent
52de3940fe
commit
4c407c8a59
3 changed files with 100 additions and 25 deletions
|
@ -27,7 +27,7 @@
|
||||||
|
|
||||||
#include "stl.h"
|
#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_area(stl_facet *facet);
|
||||||
static float get_volume(stl_file *stl);
|
static float get_volume(stl_file *stl);
|
||||||
|
|
||||||
|
@ -189,13 +189,16 @@ void
|
||||||
stl_rotate_x(stl_file *stl, float angle) {
|
stl_rotate_x(stl_file *stl, float angle) {
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
|
double radian_angle = (angle / 180.0) * M_PI;
|
||||||
|
double c = cos(radian_angle);
|
||||||
|
double s = sin(radian_angle);
|
||||||
|
|
||||||
if (stl->error) return;
|
if (stl->error) return;
|
||||||
|
|
||||||
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
||||||
for(j = 0; j < 3; j++) {
|
for(j = 0; j < 3; j++) {
|
||||||
stl_rotate(&stl->facet_start[i].vertex[j].y,
|
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);
|
stl_get_size(stl);
|
||||||
|
@ -206,13 +209,16 @@ void
|
||||||
stl_rotate_y(stl_file *stl, float angle) {
|
stl_rotate_y(stl_file *stl, float angle) {
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
|
double radian_angle = (angle / 180.0) * M_PI;
|
||||||
|
double c = cos(radian_angle);
|
||||||
|
double s = sin(radian_angle);
|
||||||
|
|
||||||
if (stl->error) return;
|
if (stl->error) return;
|
||||||
|
|
||||||
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
||||||
for(j = 0; j < 3; j++) {
|
for(j = 0; j < 3; j++) {
|
||||||
stl_rotate(&stl->facet_start[i].vertex[j].z,
|
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);
|
stl_get_size(stl);
|
||||||
|
@ -223,13 +229,16 @@ void
|
||||||
stl_rotate_z(stl_file *stl, float angle) {
|
stl_rotate_z(stl_file *stl, float angle) {
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
|
double radian_angle = (angle / 180.0) * M_PI;
|
||||||
|
double c = cos(radian_angle);
|
||||||
|
double s = sin(radian_angle);
|
||||||
|
|
||||||
if (stl->error) return;
|
if (stl->error) return;
|
||||||
|
|
||||||
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
||||||
for(j = 0; j < 3; j++) {
|
for(j = 0; j < 3; j++) {
|
||||||
stl_rotate(&stl->facet_start[i].vertex[j].x,
|
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);
|
stl_get_size(stl);
|
||||||
|
@ -239,17 +248,11 @@ stl_rotate_z(stl_file *stl, float angle) {
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
stl_rotate(float *x, float *y, float angle) {
|
stl_rotate(float *x, float *y, const double c, const double s) {
|
||||||
double r;
|
double xold = *x;
|
||||||
double theta;
|
double yold = *y;
|
||||||
double radian_angle;
|
*x = float(c * xold - s * yold);
|
||||||
|
*y = float(s * xold + c * yold);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
|
|
|
@ -473,7 +473,16 @@ ModelObject::invalidate_bounding_box()
|
||||||
void
|
void
|
||||||
ModelObject::update_bounding_box()
|
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;
|
this->_bounding_box_valid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -509,12 +518,8 @@ ModelObject::raw_bounding_box() const
|
||||||
BoundingBoxf3 bb;
|
BoundingBoxf3 bb;
|
||||||
for (ModelVolumePtrs::const_iterator v = this->volumes.begin(); v != this->volumes.end(); ++v) {
|
for (ModelVolumePtrs::const_iterator v = this->volumes.begin(); v != this->volumes.end(); ++v) {
|
||||||
if ((*v)->modifier) continue;
|
if ((*v)->modifier) continue;
|
||||||
TriangleMesh mesh = (*v)->mesh;
|
|
||||||
|
|
||||||
if (this->instances.empty()) CONFESS("Can't call raw_bounding_box() with no instances");
|
if (this->instances.empty()) CONFESS("Can't call raw_bounding_box() with no instances");
|
||||||
this->instances.front()->transform_mesh(&mesh, true);
|
bb.merge(this->instances.front()->transform_mesh_bounding_box(&(*v)->mesh, true));
|
||||||
|
|
||||||
bb.merge(mesh.bounding_box());
|
|
||||||
}
|
}
|
||||||
return bb;
|
return bb;
|
||||||
}
|
}
|
||||||
|
@ -523,9 +528,12 @@ ModelObject::raw_bounding_box() const
|
||||||
BoundingBoxf3
|
BoundingBoxf3
|
||||||
ModelObject::instance_bounding_box(size_t instance_idx) const
|
ModelObject::instance_bounding_box(size_t instance_idx) const
|
||||||
{
|
{
|
||||||
TriangleMesh mesh = this->raw_mesh();
|
BoundingBoxf3 bb;
|
||||||
this->instances[instance_idx]->transform_mesh(&mesh);
|
for (ModelVolumePtrs::const_iterator v = this->volumes.begin(); v != this->volumes.end(); ++v) {
|
||||||
return mesh.bounding_box();
|
if ((*v)->modifier) continue;
|
||||||
|
bb.merge(this->instances[instance_idx]->transform_mesh_bounding_box(&(*v)->mesh, true));
|
||||||
|
}
|
||||||
|
return bb;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -533,7 +541,10 @@ ModelObject::center_around_origin()
|
||||||
{
|
{
|
||||||
// calculate the displacements needed to
|
// calculate the displacements needed to
|
||||||
// center this object around the origin
|
// 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
|
// first align to origin on XYZ
|
||||||
Vectorf3 vector(-bb.min.x, -bb.min.y, -bb.min.z);
|
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);
|
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
|
void
|
||||||
ModelInstance::transform_polygon(Polygon* polygon) const
|
ModelInstance::transform_polygon(Polygon* polygon) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -215,6 +215,10 @@ public:
|
||||||
|
|
||||||
// To be called on an external mesh
|
// To be called on an external mesh
|
||||||
void transform_mesh(TriangleMesh* mesh, bool dont_translate = false) const;
|
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.
|
// To be called on an external polygon. It does not translate the polygon, only rotates and scales.
|
||||||
void transform_polygon(Polygon* polygon) const;
|
void transform_polygon(Polygon* polygon) const;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue