mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	FIX: tree support floating branches
Change-Id: Id28324e7676b28a315b03055d941b9876b2b3b5b (cherry picked from commit 8b5d3fae4a476b91caf854cc75d5de36ff984790)
This commit is contained in:
		
							parent
							
								
									2ee113b9da
								
							
						
					
					
						commit
						fae9036f01
					
				
					 1 changed files with 24 additions and 56 deletions
				
			
		|  | @ -1822,6 +1822,24 @@ inline coordf_t calc_branch_radius(coordf_t base_radius, size_t layers_to_top, s | |||
|     return radius; | ||||
| } | ||||
| 
 | ||||
| ExPolygons avoid_object_remove_extra_small_parts(ExPolygons &expolys, const ExPolygons &avoid_region) { | ||||
|     ExPolygons expolys_out; | ||||
|     for (auto expoly : expolys) { | ||||
|         auto  expolys_avoid = diff_ex(expoly, avoid_region); | ||||
|         int   idx_max_area  = -1; | ||||
|         float max_area      = 0; | ||||
|         for (int i = 0; i < expolys_avoid.size(); ++i) { | ||||
|             auto a = expolys_avoid[i].area(); | ||||
|             if (a > max_area) { | ||||
|                 max_area     = a; | ||||
|                 idx_max_area = i; | ||||
|             } | ||||
|         } | ||||
|         if (idx_max_area >= 0) expolys_out.emplace_back(std::move(expolys_avoid[idx_max_area])); | ||||
|     } | ||||
|     return expolys_out; | ||||
| } | ||||
| 
 | ||||
| void TreeSupport::draw_circles(const std::vector<std::vector<Node*>>& contact_nodes) | ||||
| { | ||||
|     const PrintObjectConfig &config = m_object->config(); | ||||
|  | @ -1898,7 +1916,6 @@ void TreeSupport::draw_circles(const std::vector<std::vector<Node*>>& contact_no | |||
| 
 | ||||
|                 //Draw the support areas and add the roofs appropriately to the support roof instead of normal areas.
 | ||||
|                 ts_layer->lslices.reserve(contact_nodes[layer_nr].size()); | ||||
| #if 1 | ||||
|                 for (const Node* p_node : contact_nodes[layer_nr]) | ||||
|                 { | ||||
|                     if (print->canceled()) | ||||
|  | @ -1949,59 +1966,7 @@ void TreeSupport::draw_circles(const std::vector<std::vector<Node*>>& contact_no | |||
|                     if (layer_nr < brim_skirt_layers) | ||||
|                         ts_layer->lslices.emplace_back(area); | ||||
|                 } | ||||
| #else | ||||
|                 // some nodes may not have radius set
 | ||||
|                 for (Node* p_node : contact_nodes[layer_nr]) | ||||
|                 { | ||||
|                     size_t layers_to_top = p_node->distance_to_top;// std::min(node.distance_to_top, (size_t)300);
 | ||||
|                     double scale = static_cast<double>(layers_to_top + 1) / tip_layers; | ||||
|                     scale = layers_to_top < tip_layers ? (0.5 + scale / 2) : (1 + static_cast<double>(layers_to_top - tip_layers) * diameter_angle_scale_factor); | ||||
|                     p_node->radius = scale * branch_radius; | ||||
|                 } | ||||
|                 { | ||||
|                     // now this method is extremely slow. Need to optimize the speed before we can use it.
 | ||||
|                     Polygons layer_contours = std::move(m_ts_data->get_contours_with_holes(layer_nr)); | ||||
|                     std::vector<double> radiis; | ||||
|                     std::vector<bool> is_interface; | ||||
|                     //Polygons lines = spanning_tree_to_polygon(m_spanning_trees[layer_nr], layer_contours, layer_nr, radiis);
 | ||||
|                     Polygons lines = contact_nodes_to_polygon(contact_nodes[layer_nr], layer_contours, layer_nr, radiis, is_interface); | ||||
| 
 | ||||
|                     for (int k = 0; k < lines.size(); k++) { | ||||
|                         auto line = lines[k]; | ||||
|                         double radius = radiis[k]; | ||||
|                         Polygons line_expanded; | ||||
|                         if (line.size() == 1) | ||||
|                         { | ||||
|                             Polygon circle; | ||||
|                             double scale = radiis[k] / branch_radius; | ||||
|                             for (auto iter = branch_circle.points.begin(); iter != branch_circle.points.end(); iter++) | ||||
|                             { | ||||
|                                 Point corner = (*iter) * scale; | ||||
|                                 circle.append(line.first_point() + corner); | ||||
|                             } | ||||
|                             line_expanded.emplace_back(circle); | ||||
|                         } | ||||
|                         else { | ||||
|                             line_expanded = offset(line, scale_(radius), jtRound, scale_(g_config_tree_support_collision_resolution)); | ||||
|                         } | ||||
|                         if (line_expanded.empty()) | ||||
|                             continue; | ||||
|                         if (is_interface[k]) | ||||
|                             roof_areas.emplace_back(line_expanded[0]); | ||||
|                         else | ||||
|                             base_areas.emplace_back(line_expanded[0]); | ||||
|                         if (layer_nr < brim_skirt_layers) | ||||
|                             ts_layer->lslices.emplace_back(line_expanded[0]); | ||||
| 
 | ||||
|                         //if (radius > config.support_base_pattern_spacing * 2)
 | ||||
|                         //    ts_layer->need_infill = true;
 | ||||
|                     } | ||||
| 
 | ||||
| #ifdef SUPPORT_TREE_DEBUG_TO_SVG | ||||
|                     draw_contours_and_nodes_to_svg( layer_nr, base_areas, to_expolygons(lines), m_ts_data->m_layer_outlines_below[layer_nr], {}, {}, "circles", { "lines","base_areas","outlines" }); | ||||
| #endif | ||||
|                 } | ||||
| #endif | ||||
|                 ts_layer->lslices = std::move(union_ex(ts_layer->lslices)); | ||||
| 
 | ||||
|                 //Must update bounding box which is used in avoid crossing perimeter
 | ||||
|  | @ -2020,15 +1985,18 @@ void TreeSupport::draw_circles(const std::vector<std::vector<Node*>>& contact_no | |||
| 
 | ||||
|                 // avoid object
 | ||||
|                 auto avoid_region_interface = m_ts_data->get_collision(m_ts_data->m_xy_distance, layer_nr); | ||||
|                 roof_areas = std::move(diff_ex(roof_areas, avoid_region_interface)); | ||||
|                 roof_1st_layer = std::move(diff_ex(roof_1st_layer, avoid_region_interface)); | ||||
|                 //roof_areas = std::move(diff_ex(roof_areas, avoid_region_interface));
 | ||||
|                 //roof_1st_layer = std::move(diff_ex(roof_1st_layer, avoid_region_interface));
 | ||||
|                 roof_areas = avoid_object_remove_extra_small_parts(roof_areas, avoid_region_interface); | ||||
|                 roof_1st_layer = avoid_object_remove_extra_small_parts(roof_1st_layer, avoid_region_interface); | ||||
| 
 | ||||
|                 // roof_1st_layer and roof_areas may intersect, so need to subtract roof_areas from roof_1st_layer
 | ||||
|                 roof_1st_layer = std::move(diff_ex(roof_1st_layer, roof_areas)); | ||||
| 
 | ||||
|                 // let supports touch objects when brim is on
 | ||||
|                 auto avoid_region = m_ts_data->get_collision((layer_nr == 0 && has_brim) ? config.brim_object_gap : m_ts_data->m_xy_distance, layer_nr); | ||||
|                 base_areas = std::move(diff_ex(base_areas, avoid_region)); | ||||
|                 // base_areas = std::move(diff_ex(base_areas, avoid_region));
 | ||||
|                 base_areas = avoid_object_remove_extra_small_parts(base_areas, avoid_region); | ||||
|                 base_areas = std::move(diff_ex(base_areas, roof_areas)); | ||||
|                 base_areas = std::move(diff_ex(base_areas, roof_1st_layer)); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Arthur
						Arthur