mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -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" | ||||
| 
 | ||||
| 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 | ||||
|  |  | |||
|  | @ -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 | ||||
| { | ||||
|  |  | |||
|  | @ -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; | ||||
|      | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bubnikv
						bubnikv