37#include <unordered_set>
43 assert( aPoly->size() == 1 );
49 bool m_duplicate =
false;
56 bool compareSegs(
const SEG& s1,
const SEG& s2)
const
58 return (s1.
A == s2.
A && s1.
B == s2.
B) || (s1.
A == s2.
B && s1.
B == s2.
A);
64 m_poly->
Segment( m_index ), aOther.m_poly->Segment( aOther.m_index ) );
70 m_poly->
Segment( m_index ), aOther.m_poly->Segment( aOther.m_index ) );
75 std::size_t operator()(
const EDGE& aEdge )
const
77 const auto& a = aEdge.m_poly->Segment( aEdge.m_index );
78 return (std::size_t) ( a.A.x + a.B.x + a.A.y + a.B.y );
84 struct EDGE_LIST_ENTRY
87 EDGE_LIST_ENTRY *
next;
90 std::unordered_set<EDGE, EDGE::HASH> uniqueEdges;
92 auto lc = (*aPoly)[0];
95 auto edgeList = std::make_unique<EDGE_LIST_ENTRY []>( lc.SegmentCount() );
97 for(
int i = 0; i < lc.SegmentCount(); i++)
99 edgeList[i].index = i;
100 edgeList[i].next = &edgeList[ (i != lc.SegmentCount() - 1) ? i + 1 : 0 ];
103 std::unordered_set<EDGE_LIST_ENTRY*> queue;
105 for(
int i = 0; i < lc.SegmentCount(); i++)
108 uniqueEdges.insert( e );
111 for(
int i = 0; i < lc.SegmentCount(); i++)
114 auto it = uniqueEdges.find(e);
115 if (it != uniqueEdges.end() && it->m_index != i )
117 int e1 = it->m_index;
122 int e1_prev = e1 - 1;
124 e1_prev = lc.SegmentCount() - 1;
126 int e2_prev = e2 - 1;
128 e2_prev = lc.SegmentCount() - 1;
130 int e1_next = e1 + 1;
131 if (e1_next == lc.SegmentCount() )
134 int e2_next = e2 + 1;
135 if (e2_next == lc.SegmentCount() )
138 edgeList[e1_prev].next = &edgeList[ e2_next ];
139 edgeList[e2_prev].next = &edgeList[ e1_next ];
140 edgeList[i].next =
nullptr;
141 edgeList[it->m_index].next =
nullptr;
145 for(
int i = 0; i < lc.SegmentCount(); i++)
147 if ( edgeList[i].
next )
148 queue.insert ( &edgeList[i] );
151 auto edgeBuf = std::make_unique<EDGE_LIST_ENTRY* []>( lc.SegmentCount() );
158 auto e_first = (*queue.begin());
166 }
while( e != e_first );
170 for(
int i = 0; i < cnt ;i++)
172 auto p = lc.CPoint(edgeBuf[i]->
index);
174 queue.erase( edgeBuf[i] );
182 bool cw = outl.
Area() > 0.0;
187 aResult->push_back(outl);
191 assert(outline >= 0);
194 std::swap( (*aResult) [0], (*aResult)[outline] );
206 std::string filename;
220 std::atomic<size_t> zonesToTriangulate( 0 );
221 std::atomic<size_t> threadsFinished( 0 );
223 size_t parallelThreadCount = std::max<size_t>( std::thread::hardware_concurrency(), 2 );
224 for(
size_t ii = 0; ii < parallelThreadCount; ++ii )
226 std::thread t = std::thread( [&brd, &zonesToTriangulate, &threadsFinished]() {
227 for(
size_t areaId = zonesToTriangulate.fetch_add( 1 );
228 areaId <
static_cast<size_t>( brd->GetAreaCount() );
229 areaId = zonesToTriangulate.fetch_add( 1 ) )
231 auto zone = brd->GetArea( areaId );
252 poly.triangulatePoly( &poly.
Polygon(i) );
265 while( threadsFinished < parallelThreadCount )
266 std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
275 "polygon_triangulation",
276 "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.
void Show(std::ostream &aStream=std::cerr)
Print the elapsed time (in a suitable unit) to a stream.
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.
Represent a set of closed polygons.
POLYGON & Polygon(int aIndex)
Return the aIndex-th subpolygon in the set.
virtual void CacheTriangulation(bool aSimplify=false, const TASK_SUBMITTER &aSubmitter={})
Build a polygon triangulation, needed to draw a polygon on OpenGL and in some other calculations.
std::vector< SHAPE_LINE_CHAIN > POLYGON
represents a single polygon outline with holes.
void Unfracture()
Convert a single outline slitted ("fractured") polygon into a set ouf outlines with holes.
int OutlineCount() const
Return the number of outlines in the set.
static bool Register(const KI_TEST::UTILITY_PROGRAM &aProgInfo)
Register a utility program factory function against an ID string.
void ignore_unused(const T &)
PCB_LAYER_ID
A quick note on layer IDs:
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)