41#include <unordered_set>
47 assert( aPoly->size() == 1 );
53 bool m_duplicate =
false;
60 bool compareSegs(
const SEG& s1,
const SEG& s2)
const
62 return (s1.
A == s2.
A && s1.
B == s2.
B) || (s1.
A == s2.
B && s1.
B == s2.
A);
68 m_poly->
Segment( m_index ), aOther.m_poly->Segment( aOther.m_index ) );
74 m_poly->
Segment( m_index ), aOther.m_poly->Segment( aOther.m_index ) );
79 std::size_t operator()(
const EDGE& aEdge )
const
81 const auto& a = aEdge.m_poly->Segment( aEdge.m_index );
82 return (std::size_t) ( a.A.x + a.B.x + a.A.y + a.B.y );
88 struct EDGE_LIST_ENTRY
91 EDGE_LIST_ENTRY *
next;
94 std::unordered_set<EDGE, EDGE::HASH> uniqueEdges;
96 auto lc = (*aPoly)[0];
99 auto edgeList = std::make_unique<EDGE_LIST_ENTRY []>( lc.SegmentCount() );
101 for(
int i = 0; i < lc.SegmentCount(); i++)
103 edgeList[i].index = i;
104 edgeList[i].next = &edgeList[ (i != lc.SegmentCount() - 1) ? i + 1 : 0 ];
107 std::unordered_set<EDGE_LIST_ENTRY*> queue;
109 for(
int i = 0; i < lc.SegmentCount(); i++)
112 uniqueEdges.insert( e );
115 for(
int i = 0; i < lc.SegmentCount(); i++)
118 auto it = uniqueEdges.find(e);
119 if (it != uniqueEdges.end() && it->m_index != i )
121 int e1 = it->m_index;
126 int e1_prev = e1 - 1;
128 e1_prev = lc.SegmentCount() - 1;
130 int e2_prev = e2 - 1;
132 e2_prev = lc.SegmentCount() - 1;
134 int e1_next = e1 + 1;
135 if (e1_next == lc.SegmentCount() )
138 int e2_next = e2 + 1;
139 if (e2_next == lc.SegmentCount() )
142 edgeList[e1_prev].next = &edgeList[ e2_next ];
143 edgeList[e2_prev].next = &edgeList[ e1_next ];
144 edgeList[i].next =
nullptr;
145 edgeList[it->m_index].next =
nullptr;
149 for(
int i = 0; i < lc.SegmentCount(); i++)
151 if ( edgeList[i].
next )
152 queue.insert ( &edgeList[i] );
155 auto edgeBuf = std::make_unique<EDGE_LIST_ENTRY* []>( lc.SegmentCount() );
162 auto e_first = (*queue.begin());
170 }
while( e != e_first );
174 for(
int i = 0; i < cnt ;i++)
176 auto p = lc.
CPoint(edgeBuf[i]->index);
178 queue.erase( edgeBuf[i] );
186 bool cw = outl.
Area() > 0.0;
191 aResult->push_back(outl);
195 assert(outline >= 0);
198 std::swap( (*aResult) [0], (*aResult)[outline] );
210 std::string filename;
224 std::atomic<size_t> zonesToTriangulate( 0 );
225 std::atomic<size_t> threadsFinished( 0 );
227 size_t parallelThreadCount = std::max<size_t>( std::thread::hardware_concurrency(), 2 );
228 for(
size_t ii = 0; ii < parallelThreadCount; ++ii )
230 std::thread t = std::thread( [&brd, &zonesToTriangulate, &threadsFinished]() {
231 for(
size_t areaId = zonesToTriangulate.fetch_add( 1 );
232 areaId <
static_cast<size_t>( brd->GetAreaCount() );
233 areaId = zonesToTriangulate.fetch_add( 1 ) )
235 auto zone = brd->GetArea( areaId );
240 for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() )
242 SHAPE_POLY_SET poly = *zone->GetFilledPolysList( layer );
244 poly.CacheTriangulation();
246 ignore_unused( poly );
248 PROF_TIMER unfrac(
"unfrac");
249 poly.Unfracture( SHAPE_POLY_SET::PM_FAST );
252 PROF_TIMER triangulate(
"triangulate");
254 for(int i =0; i< poly.OutlineCount(); i++)
256 poly.triangulatePoly( &poly.Polygon(i) );
269 while( threadsFinished < parallelThreadCount )
270 std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
279 "polygon_triangulation",
280 "Process polygon triangulation on a PCB",
bool operator==(const wxAuiPaneInfo &aLhs, const wxAuiPaneInfo &aRhs)
General utilities for PCB file IO for QA programs.
bool operator!=(const BOM_FIELD &lhs, const BOM_FIELD &rhs)
A small class to help profiling.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
SEG Segment(int aIndex) const
Return a copy of the aIndex-th segment in the line chain.
double Area(bool aAbsolute=true) const
Return the area of this chain.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
std::vector< SHAPE_LINE_CHAIN > POLYGON
represents a single polygon outline with holes.
static bool Register(const KI_TEST::UTILITY_PROGRAM &aProgInfo)
Register a utility program factory function against an ID string.
std::unique_ptr< BOARD > ReadBoardFromFileOrStream(const std::string &aFilename, std::istream &aFallback)
Read a board from a file, or another stream, as appropriate.
@ TOOL_SPECIFIC
Tools can define their own statuses from here onwards.
int polygon_triangulation_main(int argc, char *argv[])
void unfracture(SHAPE_POLY_SET::POLYGON *aPoly, SHAPE_POLY_SET::POLYGON *aResult)