mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Add min z height orientation search
This commit is contained in:
		
							parent
							
								
									caf8ef4aab
								
							
						
					
					
						commit
						74edeb147b
					
				
					 3 changed files with 93 additions and 4 deletions
				
			
		|  | @ -442,4 +442,92 @@ Vec2d find_least_supports_rotation(const ModelObject &      mo, | |||
|     return {rot[0], rot[1]}; | ||||
| } | ||||
| 
 | ||||
| inline BoundingBoxf3 bounding_box_with_tr(const indexed_triangle_set& its, const Transform3f &tr) | ||||
| { | ||||
|     if (its.vertices.empty()) | ||||
|         return {}; | ||||
| 
 | ||||
|     Vec3f bmin = tr * its.vertices.front(), bmax = tr * its.vertices.front(); | ||||
| 
 | ||||
|     for (const Vec3f &p : its.vertices) { | ||||
|         Vec3f pp = tr * p; | ||||
|         bmin = pp.cwiseMin(bmin); | ||||
|         bmax = pp.cwiseMax(bmax); | ||||
|     } | ||||
| 
 | ||||
|     return {bmin.cast<double>(), bmax.cast<double>()}; | ||||
| } | ||||
| 
 | ||||
| Vec2d find_min_z_height_rotation(const ModelObject &mo, const RotOptimizeParams ¶ms) | ||||
| { | ||||
|     static const unsigned MAX_TRIES = 1000; | ||||
| 
 | ||||
|     // return value
 | ||||
|     XYRotation rot; | ||||
| 
 | ||||
|     // We will use only one instance of this converted mesh to examine different
 | ||||
|     // rotations
 | ||||
|     TriangleMesh mesh = get_mesh_to_rotate(mo); | ||||
| 
 | ||||
|     // To keep track of the number of iterations
 | ||||
|     unsigned status = 0; | ||||
| 
 | ||||
|     // The maximum number of iterations
 | ||||
|     auto max_tries = unsigned(params.accuracy() * MAX_TRIES); | ||||
| 
 | ||||
|     auto &statuscb = params.statuscb(); | ||||
| 
 | ||||
|     // call status callback with zero, because we are at the start
 | ||||
|     statuscb(status); | ||||
| 
 | ||||
|     auto statusfn = [&statuscb, &status, &max_tries] { | ||||
|         // report status
 | ||||
|         statuscb(unsigned(++status * 100.0/max_tries) ); | ||||
|     }; | ||||
| 
 | ||||
|     auto stopcond = [&statuscb] { | ||||
|         return ! statuscb(-1); | ||||
|     }; | ||||
| 
 | ||||
|     TriangleMesh chull = mesh.convex_hull_3d(); | ||||
|     chull.require_shared_vertices(); | ||||
|     auto inputs = reserve_vector<XYRotation>(chull.its.indices.size()); | ||||
|     auto rotcmp = [](const XYRotation &r1, const XYRotation &r2) { | ||||
|         double xdiff = r1[X] - r2[X], ydiff = r1[Y] - r2[Y]; | ||||
|         return std::abs(xdiff) < EPSILON ? ydiff < 0. : xdiff < 0.; | ||||
|     }; | ||||
|     auto eqcmp = [](const XYRotation &r1, const XYRotation &r2) { | ||||
|         double xdiff = r1[X] - r2[X], ydiff = r1[Y] - r2[Y]; | ||||
|         return std::abs(xdiff) < EPSILON  && std::abs(ydiff) < EPSILON; | ||||
|     }; | ||||
| 
 | ||||
|     for (size_t fi = 0; fi < chull.its.indices.size(); ++fi) { | ||||
|         Facestats fc{get_triangle_vertices(chull, fi)}; | ||||
| 
 | ||||
|         auto q = Eigen::Quaternionf{}.FromTwoVectors(fc.normal, DOWN); | ||||
|         XYRotation rot = from_transform3f(Transform3f::Identity() * q); | ||||
| 
 | ||||
|         auto it = std::lower_bound(inputs.begin(), inputs.end(), rot, rotcmp); | ||||
| 
 | ||||
|         if (it == inputs.end() || !eqcmp(*it, rot)) | ||||
|             inputs.insert(it, rot); | ||||
|     } | ||||
| 
 | ||||
|     inputs.shrink_to_fit(); | ||||
|     max_tries = inputs.size(); | ||||
| 
 | ||||
|     // If the model can be placed on the bed directly, we only need to
 | ||||
|     // check the 3D convex hull face rotations.
 | ||||
| 
 | ||||
|     auto objfn = [&chull, &statusfn](const XYRotation &rot) { | ||||
|         statusfn(); | ||||
|         Transform3f tr = to_transform3f(rot); | ||||
|         return bounding_box_with_tr(chull.its, tr).size().z(); | ||||
|     }; | ||||
| 
 | ||||
|     rot = find_min_score<2>(objfn, inputs.begin(), inputs.end(), stopcond); | ||||
| 
 | ||||
|     return {rot[0], rot[1]}; | ||||
| } | ||||
| 
 | ||||
| }} // namespace Slic3r::sla
 | ||||
|  |  | |||
|  | @ -63,7 +63,8 @@ Vec2d find_best_misalignment_rotation(const ModelObject &modelobj, | |||
| Vec2d find_least_supports_rotation(const ModelObject &modelobj, | ||||
|                                    const RotOptimizeParams & = {}); | ||||
| 
 | ||||
| double find_Z_fit_to_bed_rotation(const ModelObject &mo, const BoundingBox &bed); | ||||
| Vec2d find_min_z_height_rotation(const ModelObject &mo, | ||||
|                                  const RotOptimizeParams ¶ms = {}); | ||||
| 
 | ||||
| } // namespace sla
 | ||||
| } // namespace Slic3r
 | ||||
|  |  | |||
|  | @ -27,9 +27,9 @@ class RotoptimizeJob : public PlaterJob | |||
|               "structures.\nNote that this method will try to find the best surface of the object " | ||||
|               "for touching the print bed if no elevation is set.")}, | ||||
|            // Just a min area bounding box that is done for all methods anyway.
 | ||||
|            {L("Smallest bounding box (Z axis only)"), | ||||
|             nullptr, | ||||
|             L("Rotate the object only in Z axis to have the smallest bounding box.")}}; | ||||
|            {L("Smallest Z height"), | ||||
|             sla::find_min_z_height_rotation, | ||||
|             L("Rotate the model to have least z height for faster print time.")}}; | ||||
| 
 | ||||
|     size_t m_method_id = 0; | ||||
|     float  m_accuracy  = 0.75; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 tamasmeszaros
						tamasmeszaros