mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Tech ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS - Enable detection of collision with circular printbed in backend
This commit is contained in:
		
							parent
							
								
									430c7a69b3
								
							
						
					
					
						commit
						13ef817a99
					
				
					 6 changed files with 111 additions and 53 deletions
				
			
		|  | @ -26,6 +26,37 @@ | |||
| 
 | ||||
| namespace Slic3r { | ||||
| 
 | ||||
| #if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS | ||||
| ModelInstanceEPrintVolumeState printbed_collision_state(const Polygon& printbed_shape, double print_volume_height, const Polygon& obj_hull_2d, double obj_min_z, double obj_max_z) | ||||
| { | ||||
|     static const double Z_TOLERANCE = -1e10; | ||||
| 
 | ||||
|     const Polygons intersection_polys = intersection(printbed_shape, obj_hull_2d); | ||||
|     const bool contained_xy = !intersection_polys.empty() && Geometry::are_approx(intersection_polys.front(), obj_hull_2d); | ||||
|     const bool contained_z = Z_TOLERANCE < obj_min_z && obj_max_z < print_volume_height; | ||||
|     if (contained_xy && contained_z) | ||||
|         return ModelInstancePVS_Inside; | ||||
| 
 | ||||
|     const bool intersects_xy = !contained_xy && !intersection_polys.empty(); | ||||
|     const bool intersects_z = !contained_z && obj_min_z < print_volume_height&& Z_TOLERANCE < obj_max_z; | ||||
|     if (intersects_xy || intersects_z) | ||||
|         return ModelInstancePVS_Partly_Outside; | ||||
| 
 | ||||
|     return ModelInstancePVS_Fully_Outside; | ||||
| } | ||||
| 
 | ||||
| ModelInstanceEPrintVolumeState printbed_collision_state(const Polygon& printbed_shape, double print_volume_height, const BoundingBoxf3& box) | ||||
| { | ||||
|     const Polygon box_hull_2d({ | ||||
|         { scale_(box.min.x()), scale_(box.min.y()) }, | ||||
|         { scale_(box.max.x()), scale_(box.min.y()) }, | ||||
|         { scale_(box.max.x()), scale_(box.max.y()) }, | ||||
|         { scale_(box.min.x()), scale_(box.max.y()) } | ||||
|         }); | ||||
|     return printbed_collision_state(printbed_shape, print_volume_height, box_hull_2d, box.min.z(), box.max.z()); | ||||
| } | ||||
| #endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
 | ||||
| 
 | ||||
| Model& Model::assign_copy(const Model &rhs) | ||||
| { | ||||
|     this->copy_id(rhs); | ||||
|  | @ -330,13 +361,23 @@ BoundingBoxf3 Model::bounding_box() const | |||
|     return bb; | ||||
| } | ||||
| 
 | ||||
| unsigned int Model::update_print_volume_state(const BoundingBoxf3 &print_volume)  | ||||
| #if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS | ||||
| unsigned int Model::update_print_volume_state(const Polygon& printbed_shape, double print_volume_height) | ||||
| { | ||||
|     unsigned int num_printable = 0; | ||||
|     for (ModelObject* model_object : this->objects) | ||||
|         num_printable += model_object->check_instances_print_volume_state(printbed_shape, print_volume_height); | ||||
|     return num_printable; | ||||
| } | ||||
| #else | ||||
| unsigned int Model::update_print_volume_state(const BoundingBoxf3 &print_volume) | ||||
| { | ||||
|     unsigned int num_printable = 0; | ||||
|     for (ModelObject *model_object : this->objects) | ||||
|         num_printable += model_object->check_instances_print_volume_state(print_volume); | ||||
|     return num_printable; | ||||
| } | ||||
| #endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
 | ||||
| 
 | ||||
| bool Model::center_instances_around_point(const Vec2d &point) | ||||
| { | ||||
|  | @ -1513,6 +1554,40 @@ double ModelObject::get_instance_max_z(size_t instance_idx) const | |||
|     return max_z + inst->get_offset(Z); | ||||
| } | ||||
| 
 | ||||
| #if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS | ||||
| unsigned int ModelObject::check_instances_print_volume_state(const Polygon& printbed_shape, double print_volume_height) | ||||
| { | ||||
|     unsigned int num_printable = 0; | ||||
|     enum { | ||||
|         INSIDE = 1, | ||||
|         OUTSIDE = 2 | ||||
|     }; | ||||
|     for (ModelInstance* model_instance : this->instances) { | ||||
|         unsigned int inside_outside = 0; | ||||
|         for (const ModelVolume* vol : this->volumes) | ||||
|             if (vol->is_model_part()) { | ||||
| #if ENABLE_FIX_SINKING_OBJECT_OUT_OF_BED_DETECTION | ||||
|                 const BoundingBoxf3 bb = vol->mesh().transformed_bounding_box(model_instance->get_matrix() * vol->get_matrix(), 0.0); | ||||
| #else | ||||
|                 const BoundingBoxf3 bb = vol->get_convex_hull().transformed_bounding_box(model_instance->get_matrix() * vol->get_matrix()); | ||||
| #endif // ENABLE_FIX_SINKING_OBJECT_OUT_OF_BED_DETECTION
 | ||||
|                 ModelInstanceEPrintVolumeState state = printbed_collision_state(printbed_shape, print_volume_height, bb); | ||||
|                 if (state == ModelInstancePVS_Inside) | ||||
|                     inside_outside |= INSIDE; | ||||
|                 else if (state == ModelInstancePVS_Fully_Outside) | ||||
|                     inside_outside |= OUTSIDE; | ||||
|                 else | ||||
|                     inside_outside |= INSIDE | OUTSIDE; | ||||
|             } | ||||
|         model_instance->print_volume_state = | ||||
|             (inside_outside == (INSIDE | OUTSIDE)) ? ModelInstancePVS_Partly_Outside : | ||||
|             (inside_outside == INSIDE) ? ModelInstancePVS_Inside : ModelInstancePVS_Fully_Outside; | ||||
|         if (inside_outside == INSIDE) | ||||
|             ++num_printable; | ||||
|     } | ||||
|     return num_printable; | ||||
| } | ||||
| #else | ||||
| unsigned int ModelObject::check_instances_print_volume_state(const BoundingBoxf3& print_volume) | ||||
| { | ||||
|     unsigned int num_printable = 0; | ||||
|  | @ -1544,6 +1619,7 @@ unsigned int ModelObject::check_instances_print_volume_state(const BoundingBoxf3 | |||
|     } | ||||
|     return num_printable; | ||||
| } | ||||
| #endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
 | ||||
| 
 | ||||
| void ModelObject::print_info() const | ||||
| { | ||||
|  |  | |||
|  | @ -367,7 +367,11 @@ public: | |||
|     double get_instance_max_z(size_t instance_idx) const; | ||||
| 
 | ||||
|     // Called by Print::validate() from the UI thread.
 | ||||
| #if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS | ||||
|     unsigned int check_instances_print_volume_state(const Polygon& printbed_shape, double print_volume_height); | ||||
| #else | ||||
|     unsigned int check_instances_print_volume_state(const BoundingBoxf3& print_volume); | ||||
| #endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
 | ||||
| 
 | ||||
|     // Print object statistics to console.
 | ||||
|     void print_info() const; | ||||
|  | @ -904,6 +908,14 @@ enum ModelInstanceEPrintVolumeState : unsigned char | |||
|     ModelInstanceNum_BedStates | ||||
| }; | ||||
| 
 | ||||
| #if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS | ||||
| // return the state of the given object's volume (extrusion along z of obj_hull_2d from obj_min_z to obj_max_z)
 | ||||
| // with respect to the given print volume (extrusion along z of printbed_shape from zero to print_volume_height)
 | ||||
| ModelInstanceEPrintVolumeState printbed_collision_state(const Polygon& printbed_shape, double print_volume_height, const Polygon& obj_hull_2d, double obj_min_z, double obj_max_z); | ||||
| // return the state of the given box
 | ||||
| // with respect to the given print volume (extrusion along z of printbed_shape from zero to print_volume_height)
 | ||||
| ModelInstanceEPrintVolumeState printbed_collision_state(const Polygon& printbed_shape, double print_volume_height, const BoundingBoxf3& box); | ||||
| #endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
 | ||||
| 
 | ||||
| // A single instance of a ModelObject.
 | ||||
| // Knows the affine transformation of an object.
 | ||||
|  | @ -1109,8 +1121,12 @@ public: | |||
|     BoundingBoxf3 bounding_box() const; | ||||
|     // Set the print_volume_state of PrintObject::instances, 
 | ||||
|     // return total number of printable objects.
 | ||||
| #if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS | ||||
|     unsigned int  update_print_volume_state(const Polygon& printbed_shape, double print_volume_height); | ||||
| #else | ||||
|     unsigned int  update_print_volume_state(const BoundingBoxf3 &print_volume); | ||||
| 	// Returns true if any ModelObject was modified.
 | ||||
| #endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
 | ||||
|     // Returns true if any ModelObject was modified.
 | ||||
|     bool 		  center_instances_around_point(const Vec2d &point); | ||||
|     void 		  translate(coordf_t x, coordf_t y, coordf_t z) { for (ModelObject *o : this->objects) o->translate(x, y, z); } | ||||
|     TriangleMesh  mesh() const; | ||||
|  |  | |||
|  | @ -67,37 +67,6 @@ void glAssertRecentCallImpl(const char* file_name, unsigned int line, const char | |||
| 
 | ||||
| namespace Slic3r { | ||||
| 
 | ||||
| #if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS | ||||
| ModelInstanceEPrintVolumeState printbed_collision_state(const Polygon& printbed_shape, double print_volume_height, const Polygon& obj_hull_2d, double obj_min_z, double obj_max_z) | ||||
| { | ||||
|     static const double Z_TOLERANCE = -1e10; | ||||
| 
 | ||||
|     const Polygons intersection_polys = intersection(printbed_shape, obj_hull_2d); | ||||
|     const bool contained_xy = !intersection_polys.empty() && Geometry::are_approx(intersection_polys.front(), obj_hull_2d); | ||||
|     const bool contained_z = Z_TOLERANCE < obj_min_z && obj_max_z < print_volume_height; | ||||
|     if (contained_xy && contained_z) | ||||
|         return ModelInstancePVS_Inside; | ||||
| 
 | ||||
|     const bool intersects_xy = !contained_xy && !intersection_polys.empty(); | ||||
|     const bool intersects_z = !contained_z && obj_min_z < print_volume_height && Z_TOLERANCE < obj_max_z; | ||||
|     if (intersects_xy || intersects_z) | ||||
|         return ModelInstancePVS_Partly_Outside; | ||||
| 
 | ||||
|     return ModelInstancePVS_Fully_Outside; | ||||
| } | ||||
| 
 | ||||
| ModelInstanceEPrintVolumeState printbed_collision_state(const Polygon& printbed_shape, double print_volume_height, const BoundingBoxf3& box) | ||||
| { | ||||
|     const Polygon box_hull_2d({ | ||||
|         { scale_(box.min.x()), scale_(box.min.y()) }, | ||||
|         { scale_(box.max.x()), scale_(box.min.y()) }, | ||||
|         { scale_(box.max.x()), scale_(box.max.y()) }, | ||||
|         { scale_(box.min.x()), scale_(box.max.y()) } | ||||
|         }); | ||||
|     return printbed_collision_state(printbed_shape, print_volume_height, box_hull_2d, box.min.z(), box.max.z()); | ||||
| } | ||||
| #endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
 | ||||
| 
 | ||||
| #if ENABLE_SMOOTH_NORMALS | ||||
| static void smooth_normals_corner(TriangleMesh& mesh, std::vector<stl_normal>& normals) | ||||
| { | ||||
|  |  | |||
|  | @ -41,15 +41,6 @@ enum ModelInstanceEPrintVolumeState : unsigned char; | |||
| // Return appropriate color based on the ModelVolume.
 | ||||
| std::array<float, 4> color_from_model_volume(const ModelVolume& model_volume); | ||||
| 
 | ||||
| #if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS | ||||
| // return the state of given object volume (extrusion along z of obj_hull_2d by obj_height)
 | ||||
| // with respect to the given print volume (extrusion along z of printbed_shape by print_volume_height)
 | ||||
| ModelInstanceEPrintVolumeState printbed_collision_state(const Polygon& printbed_shape, double print_volume_height, const Polygon& obj_hull_2d, double obj_min_z, double obj_max_z); | ||||
| // return the state of given box
 | ||||
| // with respect to the given print volume (extrusion along z of printbed_shape by print_volume_height)
 | ||||
| ModelInstanceEPrintVolumeState printbed_collision_state(const Polygon& printbed_shape, double print_volume_height, const BoundingBoxf3& box); | ||||
| #endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
 | ||||
| 
 | ||||
| // A container for interleaved arrays of 3D vertices and normals,
 | ||||
| // possibly indexed by triangles and / or quads.
 | ||||
| class GLIndexedVertexArray { | ||||
|  |  | |||
|  | @ -5014,17 +5014,16 @@ void GLCanvas3D::_render_background() const | |||
|             use_error_color &= _is_any_volume_outside(); | ||||
|         else { | ||||
| #if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS | ||||
|             const ConfigOptionPoints* opt = dynamic_cast<const ConfigOptionPoints*>(m_config->option("bed_shape")); | ||||
|             const Polygon bed_poly = offset(Polygon::new_scale(opt->values), static_cast<float>(scale_(BedEpsilon))).front(); | ||||
|             const float bed_height = m_config->opt_float("max_print_height"); | ||||
|             const ModelInstanceEPrintVolumeState state = printbed_collision_state(bed_poly, bed_height, m_gcode_viewer.get_paths_bounding_box()); | ||||
| //            const BoundingBoxf3& paths_volume = m_gcode_viewer.get_paths_bounding_box();
 | ||||
| //            Polygon paths_hull_2d;
 | ||||
| //            paths_hull_2d.append({ scale_(paths_volume.min.x()), scale_(paths_volume.min.y()) });
 | ||||
| //            paths_hull_2d.append({ scale_(paths_volume.max.x()), scale_(paths_volume.min.y()) });
 | ||||
| //            paths_hull_2d.append({ scale_(paths_volume.max.x()), scale_(paths_volume.max.y()) });
 | ||||
| //            paths_hull_2d.append({ scale_(paths_volume.min.x()), scale_(paths_volume.max.y()) });
 | ||||
| //            const ModelInstanceEPrintVolumeState state = printbed_collision_state(bed_poly, bed_height, paths_hull_2d, paths_volume.min.z(), paths_volume.max.z());
 | ||||
|             ModelInstanceEPrintVolumeState state; | ||||
|             if (m_gcode_viewer.has_data()) { | ||||
|                 const ConfigOptionPoints* opt = dynamic_cast<const ConfigOptionPoints*>(m_config->option("bed_shape")); | ||||
|                 const Polygon bed_poly = offset(Polygon::new_scale(opt->values), static_cast<float>(scale_(BedEpsilon))).front(); | ||||
|                 const float bed_height = m_config->opt_float("max_print_height"); | ||||
|                 state = printbed_collision_state(bed_poly, bed_height, m_gcode_viewer.get_paths_bounding_box()); | ||||
|             } | ||||
|             else | ||||
|                 state = ModelInstancePVS_Inside; | ||||
| 
 | ||||
|             use_error_color &= state != ModelInstancePVS_Inside; | ||||
| #else | ||||
|             const BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3(); | ||||
|  |  | |||
|  | @ -2946,12 +2946,19 @@ void Plater::priv::schedule_background_process() | |||
| 
 | ||||
| void Plater::priv::update_print_volume_state() | ||||
| { | ||||
| #if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS | ||||
|     const ConfigOptionPoints* opt = dynamic_cast<const ConfigOptionPoints*>(this->config->option("bed_shape")); | ||||
|     const Polygon bed_poly = offset(Polygon::new_scale(opt->values), static_cast<float>(scale_(BedEpsilon))).front(); | ||||
|     const float bed_height = this->config->opt_float("max_print_height"); | ||||
|     this->q->model().update_print_volume_state(bed_poly, bed_height); | ||||
| #else | ||||
|     BoundingBox     bed_box_2D = get_extents(Polygon::new_scale(this->config->opt<ConfigOptionPoints>("bed_shape")->values)); | ||||
|     BoundingBoxf3   print_volume(unscale(bed_box_2D.min(0), bed_box_2D.min(1), 0.0), unscale(bed_box_2D.max(0), bed_box_2D.max(1), scale_(this->config->opt_float("max_print_height")))); | ||||
|     // Allow the objects to protrude below the print bed, only the part of the object above the print bed will be sliced.
 | ||||
|     print_volume.offset(BedEpsilon); | ||||
|     print_volume.min(2) = -1e10; | ||||
|     this->q->model().update_print_volume_state(print_volume); | ||||
| #endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 enricoturri1966
						enricoturri1966