mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-20 07:11:12 -06:00 
			
		
		
		
	Add the full source of BambuStudio
using version 1.0.10
This commit is contained in:
		
							parent
							
								
									30bcadab3e
								
							
						
					
					
						commit
						1555904bef
					
				
					 3771 changed files with 1251328 additions and 0 deletions
				
			
		
							
								
								
									
										144
									
								
								src/libslic3r/InternalBridgeDetector.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								src/libslic3r/InternalBridgeDetector.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,144 @@ | |||
| #include "InternalBridgeDetector.hpp" | ||||
| #include "ClipperUtils.hpp" | ||||
| #include "Geometry.hpp" | ||||
| #include <algorithm> | ||||
| 
 | ||||
| namespace Slic3r { | ||||
| 
 | ||||
| InternalBridgeDetector::InternalBridgeDetector( | ||||
|     ExPolygon _internal_bridge, const ExPolygons& _fill_no_overlap, coord_t _spacing) : | ||||
|     fill_no_overlap(_fill_no_overlap), | ||||
|     spacing(_spacing) | ||||
| { | ||||
|     this->internal_bridge_infill.push_back(std::move(_internal_bridge)); | ||||
|     initialize(); | ||||
| } | ||||
| 
 | ||||
| //#define INTERNAL_BRIDGE_DETECTOR_DEBUG_TO_SVG
 | ||||
| 
 | ||||
| void InternalBridgeDetector::initialize() | ||||
| { | ||||
|     Polygons grown = offset(this->internal_bridge_infill, float(this->spacing)); | ||||
|     this->m_anchor_regions = diff_ex(grown, offset(this->fill_no_overlap, 10.f)); | ||||
| 
 | ||||
| #ifdef INTERNAL_BRIDGE_DETECTOR_DEBUG_TO_SVG | ||||
|     static int irun = 0; | ||||
|     BoundingBox bbox_svg; | ||||
| 
 | ||||
|     bbox_svg.merge(get_extents(this->internal_bridge_infill)); | ||||
|     bbox_svg.merge(get_extents(this->fill_no_overlap)); | ||||
|     bbox_svg.merge(get_extents(this->m_anchor_regions)); | ||||
|     { | ||||
|         std::stringstream stri; | ||||
|         stri << "InternalBridgeDetector_" << irun << ".svg"; | ||||
|         SVG svg(stri.str(), bbox_svg); | ||||
|         svg.draw(to_polylines(this->internal_bridge_infill), "blue"); | ||||
|         svg.draw(to_polylines(this->fill_no_overlap), "yellow"); | ||||
|         svg.draw(to_polylines(m_anchor_regions), "red"); | ||||
|         svg.Close(); | ||||
|     } | ||||
|     ++ irun; | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| bool InternalBridgeDetector::detect_angle() | ||||
| { | ||||
|     if (this->m_anchor_regions.empty()) | ||||
|         return false; | ||||
| 
 | ||||
|     std::vector<InternalBridgeDirection> candidates; | ||||
|     std::vector<double> angles = bridge_direction_candidates(); | ||||
|     candidates.reserve(angles.size()); | ||||
|     for (size_t i = 0; i < angles.size(); ++ i) | ||||
|         candidates.emplace_back(InternalBridgeDirection(angles[i])); | ||||
| 
 | ||||
|     Polygons clip_area = offset(this->internal_bridge_infill, 0.5f * float(this->spacing)); | ||||
| 
 | ||||
|     bool have_coverage = false; | ||||
|     for (size_t i_angle = 0; i_angle < candidates.size(); ++ i_angle) | ||||
|     { | ||||
|         const double angle = candidates[i_angle].angle; | ||||
| 
 | ||||
|         Lines lines; | ||||
|         { | ||||
|             BoundingBox bbox = get_extents_rotated(this->m_anchor_regions, - angle); | ||||
|             // Cover the region with line segments.
 | ||||
|             lines.reserve((bbox.max(1) - bbox.min(1) + this->spacing) / this->spacing); | ||||
|             double s = sin(angle); | ||||
|             double c = cos(angle); | ||||
| 
 | ||||
|             for (coord_t y = bbox.min(1); y <= bbox.max(1); y += this->spacing) | ||||
|                 lines.push_back(Line( | ||||
|                     Point((coord_t)round(c * bbox.min(0) - s * y), (coord_t)round(c * y + s * bbox.min(0))), | ||||
|                     Point((coord_t)round(c * bbox.max(0) - s * y), (coord_t)round(c * y + s * bbox.max(0))))); | ||||
|         } | ||||
| 
 | ||||
|         double total_length = 0; | ||||
|         double anchored_length = 0; | ||||
|         double max_length = 0; | ||||
|         { | ||||
|             Lines clipped_lines = intersection_ln(lines, clip_area); | ||||
|             for (size_t i = 0; i < clipped_lines.size(); ++i) { | ||||
|                 const Line &line = clipped_lines[i]; | ||||
|                 double len = line.length(); | ||||
|                 total_length += len; | ||||
|                 if (expolygons_contain(this->m_anchor_regions, line.a) && expolygons_contain(this->m_anchor_regions, line.b)) { | ||||
|                     // This line could be anchored.
 | ||||
|                     anchored_length += len; | ||||
|                     max_length = std::max(max_length, len); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         if (anchored_length == 0.) | ||||
|             continue; | ||||
| 
 | ||||
|         have_coverage = true; | ||||
| 
 | ||||
|         candidates[i_angle].coverage = anchored_length/total_length; | ||||
|         candidates[i_angle].max_length = max_length; | ||||
|     } | ||||
| 
 | ||||
|     if (! have_coverage) | ||||
|         return false; | ||||
| 
 | ||||
|     std::sort(candidates.begin(), candidates.end()); | ||||
|     size_t i_best = 0; | ||||
|     this->angle = candidates[i_best].angle; | ||||
|     if (this->angle >= PI) | ||||
|         this->angle -= PI; | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| std::vector<double> InternalBridgeDetector::bridge_direction_candidates() const | ||||
| { | ||||
|     std::vector<double> angles; | ||||
|     for (int i = 0; i <= PI/this->resolution; ++i) | ||||
|         angles.push_back(i * this->resolution); | ||||
| 
 | ||||
|     // we also test angles of each bridge contour
 | ||||
|     { | ||||
|         Lines lines = to_lines(this->internal_bridge_infill); | ||||
|         for (Lines::const_iterator line = lines.begin(); line != lines.end(); ++line) | ||||
|             angles.push_back(line->direction()); | ||||
|     } | ||||
| 
 | ||||
|     // remove duplicates
 | ||||
|     double min_resolution = PI/180.0; | ||||
|     std::sort(angles.begin(), angles.end()); | ||||
|     for (size_t i = 1; i < angles.size(); ++i) { | ||||
|         if (Slic3r::Geometry::directions_parallel(angles[i], angles[i-1], min_resolution)) { | ||||
|             angles.erase(angles.begin() + i); | ||||
|             --i; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (Slic3r::Geometry::directions_parallel(angles.front(), angles.back(), min_resolution)) | ||||
|         angles.pop_back(); | ||||
| 
 | ||||
|     return angles; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 lane.wei
						lane.wei