mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE -> Refactoring of SlicingAdaptive to account for volumes' transformation
This commit is contained in:
		
							parent
							
								
									b77ba32bb2
								
							
						
					
					
						commit
						0001ce3dab
					
				
					 5 changed files with 104 additions and 41 deletions
				
			
		|  | @ -224,24 +224,38 @@ std::vector<coordf_t> layer_height_profile_from_ranges( | |||
| 
 | ||||
| // Based on the work of @platsch
 | ||||
| // Fill layer_height_profile by heights ensuring a prescribed maximum cusp height.
 | ||||
| #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
| std::vector<coordf_t> layer_height_profile_adaptive( | ||||
|     const SlicingParameters& slicing_params, | ||||
|     const ModelObject& object) | ||||
| #else | ||||
| std::vector<coordf_t> layer_height_profile_adaptive( | ||||
|     const SlicingParameters     &slicing_params, | ||||
|     const t_layer_config_ranges & /* layer_config_ranges */, | ||||
|     const ModelVolumePtrs		&volumes) | ||||
| #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| { | ||||
| #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
|     // 1) Initialize the SlicingAdaptive class with the object meshes.
 | ||||
|     SlicingAdaptive as; | ||||
|     as.set_slicing_parameters(slicing_params); | ||||
|     for (const ModelVolume *volume : volumes) | ||||
|     as.set_object(object); | ||||
| #else | ||||
|     // 1) Initialize the SlicingAdaptive class with the object meshes.
 | ||||
|     SlicingAdaptive as; | ||||
|     as.set_slicing_parameters(slicing_params); | ||||
|     for (const ModelVolume* volume : volumes) | ||||
|         if (volume->is_model_part()) | ||||
|             as.add_mesh(&volume->mesh()); | ||||
| #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| 
 | ||||
|     as.prepare(); | ||||
| 
 | ||||
|     // 2) Generate layers using the algorithm of @platsch 
 | ||||
|     // loop until we have at least one layer and the max slice_z reaches the object height
 | ||||
|     //FIXME make it configurable
 | ||||
|     // Cusp value: A maximum allowed distance from a corner of a rectangular extrusion to a chrodal line, in mm.
 | ||||
|     const coordf_t cusp_value = 0.2; // $self->config->get_value('cusp_value');
 | ||||
|     const double cusp_value = 0.2; // $self->config->get_value('cusp_value');
 | ||||
| 
 | ||||
|     std::vector<coordf_t> layer_height_profile; | ||||
|     layer_height_profile.push_back(0.); | ||||
|  | @ -250,14 +264,14 @@ std::vector<coordf_t> layer_height_profile_adaptive( | |||
|         layer_height_profile.push_back(slicing_params.first_object_layer_height); | ||||
|         layer_height_profile.push_back(slicing_params.first_object_layer_height); | ||||
|     } | ||||
|     coordf_t slice_z = slicing_params.first_object_layer_height; | ||||
|     coordf_t height  = slicing_params.first_object_layer_height; | ||||
|     double slice_z = slicing_params.first_object_layer_height; | ||||
|     double height  = slicing_params.first_object_layer_height; | ||||
|     int current_facet = 0; | ||||
|     while ((slice_z - height) <= slicing_params.object_print_z_height()) { | ||||
|         height = 999; | ||||
|         // Slic3r::debugf "\n Slice layer: %d\n", $id;
 | ||||
|         // determine next layer height
 | ||||
|         coordf_t cusp_height = as.cusp_height(slice_z, cusp_value, current_facet); | ||||
|         double cusp_height = as.cusp_height((float)slice_z, (float)cusp_value, current_facet); | ||||
|         // check for horizontal features and object size
 | ||||
|         /*
 | ||||
|         if($self->config->get_value('match_horizontal_surfaces')) { | ||||
|  |  | |||
|  | @ -18,8 +18,12 @@ namespace Slic3r | |||
| 
 | ||||
| class PrintConfig; | ||||
| class PrintObjectConfig; | ||||
| #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
| class ModelObject; | ||||
| #else | ||||
| class ModelVolume; | ||||
| typedef std::vector<ModelVolume*> ModelVolumePtrs; | ||||
| #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| 
 | ||||
| // Parameters to guide object slicing and support generation.
 | ||||
| // The slicing parameters account for a raft and whether the 1st object layer is printed with a normal or a bridging flow
 | ||||
|  | @ -138,11 +142,16 @@ extern std::vector<coordf_t> layer_height_profile_from_ranges( | |||
|     const SlicingParameters     &slicing_params, | ||||
|     const t_layer_config_ranges &layer_config_ranges); | ||||
| 
 | ||||
| #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
| extern std::vector<coordf_t> layer_height_profile_adaptive( | ||||
|     const SlicingParameters& slicing_params, | ||||
|     const ModelObject& object); | ||||
| #else | ||||
| extern std::vector<coordf_t> layer_height_profile_adaptive( | ||||
|     const SlicingParameters     &slicing_params, | ||||
|     const t_layer_config_ranges &layer_config_ranges, | ||||
|     const ModelVolumePtrs       &volumes); | ||||
| 
 | ||||
| #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| 
 | ||||
| enum LayerHeightEditActionType : unsigned int { | ||||
|     LAYER_HEIGHT_EDIT_ACTION_INCREASE = 0, | ||||
|  |  | |||
|  | @ -1,16 +1,22 @@ | |||
| #include "libslic3r.h" | ||||
| #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
| #include "Model.hpp" | ||||
| #else | ||||
| #include "TriangleMesh.hpp" | ||||
| #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| #include "SlicingAdaptive.hpp" | ||||
| 
 | ||||
| namespace Slic3r | ||||
| { | ||||
| 
 | ||||
| #if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
| void SlicingAdaptive::clear() | ||||
| { | ||||
| 	m_meshes.clear(); | ||||
|     m_meshes.clear(); | ||||
| 	m_faces.clear(); | ||||
| 	m_face_normal_z.clear(); | ||||
| } | ||||
| #endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| 
 | ||||
| std::pair<float, float> face_z_span(const stl_facet *f) | ||||
| { | ||||
|  | @ -21,21 +27,38 @@ std::pair<float, float> face_z_span(const stl_facet *f) | |||
| 
 | ||||
| void SlicingAdaptive::prepare() | ||||
| { | ||||
| 	// 1) Collect faces of all meshes.
 | ||||
| 	int nfaces_total = 0; | ||||
| 	for (std::vector<const TriangleMesh*>::const_iterator it_mesh = m_meshes.begin(); it_mesh != m_meshes.end(); ++ it_mesh) | ||||
| #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
|     if (m_object == nullptr) | ||||
|         return; | ||||
| 
 | ||||
|     m_faces.clear(); | ||||
|     m_face_normal_z.clear(); | ||||
| 
 | ||||
|     m_mesh = m_object->raw_mesh(); | ||||
|     const ModelInstance* first_instance = m_object->instances.front(); | ||||
|     m_mesh.transform(first_instance->get_matrix(), first_instance->is_left_handed()); | ||||
| 
 | ||||
|     // 1) Collect faces from mesh.
 | ||||
|     m_faces.reserve(m_mesh.stl.stats.number_of_facets); | ||||
|     for (const stl_facet& face : m_mesh.stl.facet_start) | ||||
|         m_faces.emplace_back(&face); | ||||
| #else | ||||
|     // 1) Collect faces of all meshes.
 | ||||
|     int nfaces_total = 0; | ||||
|     for (std::vector<const TriangleMesh*>::const_iterator it_mesh = m_meshes.begin(); it_mesh != m_meshes.end(); ++ it_mesh) | ||||
| 		nfaces_total += (*it_mesh)->stl.stats.number_of_facets; | ||||
| 	m_faces.reserve(nfaces_total); | ||||
| 	for (std::vector<const TriangleMesh*>::const_iterator it_mesh = m_meshes.begin(); it_mesh != m_meshes.end(); ++ it_mesh) | ||||
| 		for (const stl_facet &face : (*it_mesh)->stl.facet_start) | ||||
| 			m_faces.emplace_back(&face); | ||||
|     m_faces.reserve(nfaces_total); | ||||
|     for (std::vector<const TriangleMesh*>::const_iterator it_mesh = m_meshes.begin(); it_mesh != m_meshes.end(); ++ it_mesh) | ||||
|         for (const stl_facet& face : (*it_mesh)->stl.facet_start) | ||||
|             m_faces.emplace_back(&face); | ||||
| #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| 
 | ||||
| 	// 2) Sort faces lexicographically by their Z span.
 | ||||
| 	std::sort(m_faces.begin(), m_faces.end(), [](const stl_facet *f1, const stl_facet *f2) { | ||||
| 		std::pair<float, float> span1 = face_z_span(f1); | ||||
|         std::pair<float, float> span1 = face_z_span(f1); | ||||
| 		std::pair<float, float> span2 = face_z_span(f2); | ||||
| 		return span1 < span2; | ||||
| 	}); | ||||
|         return span1 < span2; | ||||
|     }); | ||||
| 
 | ||||
| 	// 3) Generate Z components of the facet normals.
 | ||||
| 	m_face_normal_z.assign(m_faces.size(), 0.f); | ||||
|  | @ -45,14 +68,14 @@ void SlicingAdaptive::prepare() | |||
| 
 | ||||
| float SlicingAdaptive::cusp_height(float z, float cusp_value, int ¤t_facet) | ||||
| { | ||||
| 	float height = m_slicing_params.max_layer_height; | ||||
| 	float height = (float)m_slicing_params.max_layer_height; | ||||
| 	bool first_hit = false; | ||||
| 	 | ||||
| 	// find all facets intersecting the slice-layer
 | ||||
| 	int ordered_id = current_facet; | ||||
| 	for (; ordered_id < int(m_faces.size()); ++ ordered_id) { | ||||
| 		std::pair<float, float> zspan = face_z_span(m_faces[ordered_id]); | ||||
| 		// facet's minimum is higher than slice_z -> end loop
 | ||||
|         std::pair<float, float> zspan = face_z_span(m_faces[ordered_id]); | ||||
|         // facet's minimum is higher than slice_z -> end loop
 | ||||
| 		if (zspan.first >= z) | ||||
| 			break; | ||||
| 		// facet's maximum is higher than slice_z -> store the first event for next cusp_height call to begin at this point
 | ||||
|  | @ -77,8 +100,8 @@ float SlicingAdaptive::cusp_height(float z, float cusp_value, int ¤t_facet | |||
| 	// check for sloped facets inside the determined layer and correct height if necessary
 | ||||
| 	if (height > m_slicing_params.min_layer_height) { | ||||
| 		for (; ordered_id < int(m_faces.size()); ++ ordered_id) { | ||||
| 			std::pair<float, float> zspan = face_z_span(m_faces[ordered_id]); | ||||
| 			// facet's minimum is higher than slice_z + height -> end loop
 | ||||
|             std::pair<float, float> zspan = face_z_span(m_faces[ordered_id]); | ||||
|             // facet's minimum is higher than slice_z + height -> end loop
 | ||||
| 			if (zspan.first >= z + height) | ||||
| 				break; | ||||
| 
 | ||||
|  | @ -122,19 +145,18 @@ float SlicingAdaptive::cusp_height(float z, float cusp_value, int ¤t_facet | |||
| float SlicingAdaptive::horizontal_facet_distance(float z) | ||||
| { | ||||
| 	for (size_t i = 0; i < m_faces.size(); ++ i) { | ||||
| 		std::pair<float, float> zspan = face_z_span(m_faces[i]); | ||||
| 		// facet's minimum is higher than max forward distance -> end loop
 | ||||
|         std::pair<float, float> zspan = face_z_span(m_faces[i]); | ||||
|         // facet's minimum is higher than max forward distance -> end loop
 | ||||
| 		if (zspan.first > z + m_slicing_params.max_layer_height) | ||||
| 			break; | ||||
| 		// min_z == max_z -> horizontal facet
 | ||||
| 		if (zspan.first > z && zspan.first == zspan.second) | ||||
| 		if ((zspan.first > z) && (zspan.first == zspan.second)) | ||||
| 			return zspan.first - z; | ||||
| 	} | ||||
| 	 | ||||
| 	// objects maximum?
 | ||||
| 	return (z + m_slicing_params.max_layer_height > m_slicing_params.object_print_z_height()) ?  | ||||
| 		std::max<float>(m_slicing_params.object_print_z_height() - z, 0.f) : | ||||
| 		m_slicing_params.max_layer_height; | ||||
| 	return (z + (float)m_slicing_params.max_layer_height > (float)m_slicing_params.object_print_z_height()) ?  | ||||
| 		std::max((float)m_slicing_params.object_print_z_height() - z, 0.f) : (float)m_slicing_params.max_layer_height; | ||||
| } | ||||
| 
 | ||||
| }; // namespace Slic3r
 | ||||
|  |  | |||
|  | @ -5,29 +5,47 @@ | |||
| 
 | ||||
| #include "Slicing.hpp" | ||||
| #include "admesh/stl.h" | ||||
| #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
| #include "TriangleMesh.hpp" | ||||
| #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| 
 | ||||
| namespace Slic3r | ||||
| { | ||||
| 
 | ||||
| #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
| class ModelVolume; | ||||
| #else | ||||
| class TriangleMesh; | ||||
| #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| 
 | ||||
| class SlicingAdaptive | ||||
| { | ||||
| public: | ||||
| 	void clear(); | ||||
| 	void set_slicing_parameters(SlicingParameters params) { m_slicing_params = params; } | ||||
| 	void add_mesh(const TriangleMesh *mesh) { m_meshes.push_back(mesh); } | ||||
| 	void prepare(); | ||||
| #if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
|     void clear(); | ||||
| #endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
|     void set_slicing_parameters(SlicingParameters params) { m_slicing_params = params; } | ||||
| #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
|     void set_object(const ModelObject& object) { m_object = &object; } | ||||
| #else | ||||
|     void add_mesh(const TriangleMesh* mesh) { m_meshes.push_back(mesh); } | ||||
| #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
|     void prepare(); | ||||
| 	float cusp_height(float z, float cusp_value, int ¤t_facet); | ||||
| 	float horizontal_facet_distance(float z); | ||||
| 
 | ||||
| protected: | ||||
| 	SlicingParameters 					m_slicing_params; | ||||
| 
 | ||||
| 	std::vector<const TriangleMesh*>	m_meshes; | ||||
| 	// Collected faces of all meshes, sorted by raising Z of the bottom most face.
 | ||||
| #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
|     const ModelObject*                  m_object; | ||||
|     TriangleMesh                        m_mesh; | ||||
| #else | ||||
|     std::vector<const TriangleMesh*>	m_meshes; | ||||
| #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
|     // Collected faces of all meshes, sorted by raising Z of the bottom most face.
 | ||||
| 	std::vector<const stl_facet*>		m_faces; | ||||
| 	// Z component of face normals, normalized.
 | ||||
|     // Z component of face normals, normalized.
 | ||||
| 	std::vector<float>					m_face_normal_z; | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -266,13 +266,13 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const | |||
|     imgui.text(_(L("Increase/decrease edit area"))); | ||||
|      | ||||
|     ImGui::Separator(); | ||||
|     if (imgui.button(_(L("Reset")))) | ||||
|         wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), SimpleEvent(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE)); | ||||
| 
 | ||||
|     ImGui::SameLine(); | ||||
|     if (imgui.button(_(L("Adaptive")))) | ||||
|         wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), SimpleEvent(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE)); | ||||
| 
 | ||||
|     ImGui::SameLine(); | ||||
|     if (imgui.button(_(L("Reset")))) | ||||
|         wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), SimpleEvent(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE)); | ||||
| 
 | ||||
|     imgui.end(); | ||||
| 
 | ||||
|     ImGui::PopStyleVar(); | ||||
|  | @ -577,8 +577,8 @@ void GLCanvas3D::LayersEditing::reset_layer_height_profile(GLCanvas3D& canvas) | |||
| #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
| void GLCanvas3D::LayersEditing::adaptive_layer_height_profile(GLCanvas3D& canvas) | ||||
| { | ||||
|     const_cast<ModelObject*>(m_model_object)->layer_height_profile.clear(); | ||||
|     m_layer_height_profile = layer_height_profile_adaptive(*m_slicing_parameters, m_model_object->layer_config_ranges, m_model_object->volumes); | ||||
|     m_layer_height_profile = layer_height_profile_adaptive(*m_slicing_parameters, *m_model_object); | ||||
|     const_cast<ModelObject*>(m_model_object)->layer_height_profile = m_layer_height_profile; | ||||
|     m_layers_texture.valid = false; | ||||
|     canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Enrico Turri
						Enrico Turri