mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 20:51:12 -06:00 
			
		
		
		
	Fixing the infill order for concentric infill to outside-in.
Relies to: Concentric Fill Start Point - New Feature Request #4948 Feature Request: Archimedean Chords - Option to define direction of travel (Inside-Out or Outside-In) #5214
This commit is contained in:
		
							parent
							
								
									746729e4fa
								
							
						
					
					
						commit
						3c9f3d2b66
					
				
					 5 changed files with 21 additions and 36 deletions
				
			
		|  | @ -716,45 +716,33 @@ static void traverse_pt_noholes(const ClipperLib::PolyNodes &nodes, Polygons *ou | |||
|     }); | ||||
| } | ||||
| 
 | ||||
| static void traverse_pt_old(ClipperLib::PolyNodes &nodes, Polygons* retval) | ||||
| static void traverse_pt_outside_in(const ClipperLib::PolyNodes &nodes, Polygons *retval) | ||||
| { | ||||
|     /* use a nearest neighbor search to order these children
 | ||||
|        TODO: supply start_near to chained_path() too? */ | ||||
|      | ||||
|     // collect ordering points
 | ||||
|     Points ordering_points; | ||||
|     ordering_points.reserve(nodes.size()); | ||||
|     for (ClipperLib::PolyNodes::const_iterator it = nodes.begin(); it != nodes.end(); ++it) { | ||||
|         Point p((*it)->Contour.front().X, (*it)->Contour.front().Y); | ||||
|         ordering_points.push_back(p); | ||||
|     } | ||||
|      | ||||
|     // perform the ordering
 | ||||
|     ClipperLib::PolyNodes ordered_nodes = chain_clipper_polynodes(ordering_points, nodes); | ||||
|      | ||||
|     // push results recursively
 | ||||
|     for (ClipperLib::PolyNodes::iterator it = ordered_nodes.begin(); it != ordered_nodes.end(); ++it) { | ||||
|     for (const ClipperLib::PolyNode *node : nodes) | ||||
|         ordering_points.emplace_back(node->Contour.front().X, node->Contour.front().Y); | ||||
| 
 | ||||
|     // Perform the ordering, push results recursively.
 | ||||
|     //FIXME pass the last point to chain_clipper_polynodes?
 | ||||
|     for (const ClipperLib::PolyNode *node : chain_clipper_polynodes(ordering_points, nodes)) { | ||||
|         retval->emplace_back(ClipperPath_to_Slic3rPolygon(node->Contour)); | ||||
|         if (node->IsHole())  | ||||
|             // Orient a hole, which is clockwise oriented, to CCW.
 | ||||
|             retval->back().reverse(); | ||||
|         // traverse the next depth
 | ||||
|         traverse_pt_old((*it)->Childs, retval); | ||||
|         retval->push_back(ClipperPath_to_Slic3rPolygon((*it)->Contour)); | ||||
|         if ((*it)->IsHole()) retval->back().reverse();  // ccw
 | ||||
|         traverse_pt_outside_in(node->Childs, retval); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| Polygons union_pt_chained(const Polygons &subject, bool safety_offset_) | ||||
| Polygons union_pt_chained_outside_in(const Polygons &subject, bool safety_offset_) | ||||
| { | ||||
|     ClipperLib::PolyTree polytree = union_pt(subject, safety_offset_); | ||||
|      | ||||
|     Polygons retval; | ||||
|     traverse_pt_old(polytree.Childs, &retval); | ||||
|     traverse_pt_outside_in(polytree.Childs, &retval); | ||||
|     return retval; | ||||
|      | ||||
| // TODO: This needs to be tested:
 | ||||
| //    ClipperLib::PolyTree polytree = union_pt(subject, safety_offset_);
 | ||||
|      | ||||
| //    Polygons retval;
 | ||||
| //    traverse_pt_noholes(polytree.Childs, &retval);
 | ||||
| //    return retval;
 | ||||
| } | ||||
| 
 | ||||
| Polygons simplify_polygons(const Polygons &subject, bool preserve_collinear) | ||||
|  |  | |||
|  | @ -219,7 +219,7 @@ ClipperLib::PolyTree union_pt(const Slic3r::ExPolygons &subject, bool safety_off | |||
| ClipperLib::PolyTree union_pt(Slic3r::Polygons &&subject, bool safety_offset_ = false); | ||||
| ClipperLib::PolyTree union_pt(Slic3r::ExPolygons &&subject, bool safety_offset_ = false); | ||||
| 
 | ||||
| Slic3r::Polygons union_pt_chained(const Slic3r::Polygons &subject, bool safety_offset_ = false); | ||||
| Slic3r::Polygons union_pt_chained_outside_in(const Slic3r::Polygons &subject, bool safety_offset_ = false); | ||||
| 
 | ||||
| ClipperLib::PolyNodes order_nodes(const ClipperLib::PolyNodes &nodes); | ||||
| 
 | ||||
|  |  | |||
|  | @ -24,22 +24,22 @@ void FillConcentric::_fill_surface_single( | |||
|         this->spacing = unscale<double>(distance); | ||||
|     } | ||||
| 
 | ||||
|     Polygons loops = (Polygons)expolygon; | ||||
|     Polygons loops = to_polygons(std::move(expolygon)); | ||||
|     Polygons last  = loops; | ||||
|     while (! last.empty()) { | ||||
|         last = offset2(last, -(distance + min_spacing/2), +min_spacing/2); | ||||
|         loops.insert(loops.end(), last.begin(), last.end()); | ||||
|         append(loops, last); | ||||
|     } | ||||
| 
 | ||||
|     // generate paths from the outermost to the innermost, to avoid
 | ||||
|     // adhesion problems of the first central tiny loops
 | ||||
|     loops = union_pt_chained(loops, false); | ||||
|     loops = union_pt_chained_outside_in(loops, false); | ||||
|      | ||||
|     // split paths using a nearest neighbor search
 | ||||
|     size_t iPathFirst = polylines_out.size(); | ||||
|     Point last_pos(0, 0); | ||||
|     for (const Polygon &loop : loops) { | ||||
|         polylines_out.push_back(loop.split_at_index(last_pos.nearest_point_index(loop.points))); | ||||
|         polylines_out.emplace_back(loop.split_at_index(last_pos.nearest_point_index(loop.points))); | ||||
|         last_pos = polylines_out.back().last_point(); | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -8,7 +8,7 @@ namespace Slic3r { | |||
| class FillConcentric : public Fill | ||||
| { | ||||
| public: | ||||
|     ~FillConcentric() override {} | ||||
|     ~FillConcentric() override = default; | ||||
| 
 | ||||
| protected: | ||||
|     Fill* clone() const override { return new FillConcentric(*this); }; | ||||
|  |  | |||
|  | @ -1851,10 +1851,7 @@ void Print::_make_brim() | |||
|         } | ||||
|         polygons_append(loops, offset(islands, -0.5f * float(flow.scaled_spacing()))); | ||||
|     } | ||||
|     loops = union_pt_chained(loops, false); | ||||
|     // The function above produces ordering well suited for concentric infill (from outside to inside).
 | ||||
|     // For Brim, the ordering should be reversed (from inside to outside).
 | ||||
|     std::reverse(loops.begin(), loops.end()); | ||||
|     loops = union_pt_chained_outside_in(loops, false); | ||||
| 
 | ||||
|     // If there is a possibility that brim intersects skirt, go through loops and split those extrusions
 | ||||
|     // The result is either the original Polygon or a list of Polylines
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Vojtech Bubnik
						Vojtech Bubnik