20 #include <boost/unordered_set.hpp> 50 int a_polyOffsetIter);
68 std::vector<Pt3d> m_outside;
69 std::vector<std::vector<Pt3d>> m_inside;
76 MePolyPaverToMeshPtsImpl()
80 , m_polyEnvelopeArea(0)
85 bool PolyToMeshPts(
const std::vector<Pt3d>& a_outPoly,
86 const std::vector<std::vector<Pt3d>>& a_inPolys,
89 std::vector<Pt3d>& a_meshPts)
override;
93 void SetRedistributor(BSHP<MePolyRedistributePts> a_)
override { m_externalRedist = a_; }
97 void AddPolygonToMeshPoints(
const Poly& a_poly,
bool a_first);
98 void DoPave(
const Poly& a_poly);
99 void CleanPave(
const Poly& a_poly);
100 void RedistributePts();
101 void ClassifyPolys();
102 double AreaFromPolyStack();
104 BSHP<VecPt3d> m_meshPts;
105 std::list<Poly> m_polyStack;
106 BSHP<MePolyOffsetter> m_offsetter;
107 BSHP<MePolyCleaner> m_cleaner;
108 BSHP<MePolyRedistributePts> m_redist;
109 BSHP<MePolyRedistributePts> m_externalRedist;
112 double m_polyEnvelopeArea;
113 int m_polyOffsetIter;
114 boost::unordered_set<std::pair<double, double>> m_ptHash;
116 std::vector<MePolyOffsetterOutput> m_offsetOutputs;
127 BSHP<MePolyPaverToMeshPts> ret(
new MePolyPaverToMeshPtsImpl);
133 MePolyPaverToMeshPts::MePolyPaverToMeshPts()
139 MePolyPaverToMeshPts::~MePolyPaverToMeshPts()
161 bool MePolyPaverToMeshPtsImpl::PolyToMeshPts(
const std::vector<Pt3d>& a_outPoly,
162 const std::vector<std::vector<Pt3d>>& a_inPolys,
165 std::vector<Pt3d>& a_meshPts)
170 if (a_outPoly.empty())
172 for (
size_t i = 0; i < a_inPolys.size(); ++i)
174 if (a_inPolys[i].empty())
178 m_polyStack.push_back(Poly());
179 m_polyStack.back().m_outside = a_outPoly;
180 m_polyStack.back().m_inside = a_inPolys;
181 m_polyStack.back().m_iter = 1;
186 a_meshPts.swap(*m_meshPts);
193 void MePolyPaverToMeshPtsImpl::Setup()
196 m_meshPts = BSHP<VecPt3d>(
new VecPt3d());
199 m_polyEnvelopeArea = AreaFromPolyStack();
200 if (!m_externalRedist)
203 m_redist->SetSizeFuncFromPoly(m_polyStack.front().m_outside, m_polyStack.front().m_inside,
207 m_redist = m_externalRedist;
212 void MePolyPaverToMeshPtsImpl::TearDown()
226 void MePolyPaverToMeshPtsImpl::ProcessStack()
231 std::list<Poly>::iterator it(m_polyStack.begin());
233 while (it != m_polyStack.end())
237 m_polyOffsetIter = p.m_iter;
250 AddPolygonToMeshPoints(p, first);
254 m_polyStack.erase(it);
255 it = m_polyStack.begin();
258 area = AreaFromPolyStack();
259 prog.ProgressStatus(1.0 - (area / m_polyEnvelopeArea));
266 void MePolyPaverToMeshPtsImpl::AddPolygonToMeshPoints(
const Poly& a_poly,
bool 269 auto itEnd = m_ptHash.end();
270 std::pair<double, double> pt;
271 for (
size_t i = 0; i < a_poly.m_outside.size(); ++i)
273 pt.first = a_poly.m_outside[i].x;
274 pt.second = a_poly.m_outside[i].y;
275 if (m_ptHash.find(pt) == itEnd)
278 m_meshPts->push_back(a_poly.m_outside[i]);
281 for (
size_t i = 0; i < a_poly.m_inside.size(); ++i)
283 for (
size_t j = 0; j < a_poly.m_inside[i].size(); ++j)
285 pt.first = a_poly.m_inside[i][j].x;
286 pt.second = a_poly.m_inside[i][j].y;
287 if (m_ptHash.find(pt) == itEnd)
290 m_meshPts->push_back(a_poly.m_inside[i][j]);
329 void MePolyPaverToMeshPtsImpl::DoPave(
const Poly& a_poly)
331 m_offsetOutputs.clear();
335 std::vector<Pt3d> pts;
337 m_offsetter->Offset(a_poly.m_outside, pOut, offsetOut, m_xyTol);
338 m_offsetOutputs.push_back(offsetOut);
341 for (
size_t i = 0; i < a_poly.m_inside.size(); ++i)
343 m_offsetter->Offset(a_poly.m_inside[i], pIn, offsetOut, m_xyTol);
344 m_offsetOutputs.push_back(offsetOut);
351 void MePolyPaverToMeshPtsImpl::CleanPave(
const Poly& a_poly)
353 m_cleaner->SetOriginalOutsidePolygon(a_poly.m_outside);
356 m_cleaner->IntersectCleanInPolys(m_offsetOutputs, out, m_xyTol);
359 m_cleaner->IntersectCleanInOutPolys(out, out2, m_xyTol);
360 m_offsetOutputs.clear();
361 m_offsetOutputs.push_back(out2);
367 void MePolyPaverToMeshPtsImpl::RedistributePts()
374 m_offsetOutputs[0] = o;
383 void MePolyPaverToMeshPtsImpl::ClassifyPolys()
385 if (m_offsetOutputs[0].m_pts.empty())
388 std::vector<std::vector<size_t>> polys;
393 std::vector<Pt3d>& pts(m_offsetOutputs[0].m_pts);
395 p.m_iter = m_polyOffsetIter + 1;
396 for (
size_t i = 0; i < polys.size(); ++i)
398 p.m_outside.resize(0);
399 p.m_inside.resize(0);
401 std::vector<size_t>& oLoop(m_offsetOutputs[0].m_loops[polys[i][0]]);
402 for (
size_t j = 0; j < oLoop.size(); ++j)
404 p.m_outside.push_back(pts[oLoop[j]]);
407 for (
size_t j = 1; j < polys[i].size(); ++j)
409 std::vector<size_t>& iLoop(m_offsetOutputs[0].m_loops[polys[i][j]]);
410 p.m_inside.push_back(std::vector<Pt3d>());
411 for (
size_t k = 0; k < iLoop.size(); ++k)
413 p.m_inside.back().push_back(pts[iLoop[k]]);
417 m_polyStack.push_back(p);
424 static double iEnvelopeArea(
const std::vector<Pt3d>& a_pts)
427 Pt3d pMin(XM_DBL_HIGHEST),
429 for (
size_t i = 0; i < a_pts.size(); ++i)
433 area = (pMax.x - pMin.x) * (pMax.y - pMin.y);
439 double MePolyPaverToMeshPtsImpl::AreaFromPolyStack()
443 std::list<Poly>::iterator it(m_polyStack.begin()), itEnd(m_polyStack.end());
444 for (; it != itEnd; ++it)
447 area += iEnvelopeArea(p.m_outside);
499 std::vector<Pt3d> outPoly = {{0, 1, 0}, {0, 2, 0}, {0, 3, 0}, {0, 4, 0}, {1, 4, 0}, {2, 4, 0},
500 {3, 4, 0}, {4, 4, 0}, {4, 3, 0}, {4, 2, 0}, {4, 1, 0}, {4, 0, 0},
501 {3, 0, 0}, {2, 0, 0}, {1, 0, 0}, {0, 0, 0}};
502 std::vector<std::vector<Pt3d>> inPoly;
503 MePolyPaverToMeshPtsImpl paver;
504 double bias(1), tol(1e-9);
505 std::vector<Pt3d> outPts;
506 paver.PolyToMeshPts(outPoly, inPoly, bias, tol, outPts);
507 std::vector<Pt3d> basePts = {
508 {0.0, 1.0, 0.0}, {0.0, 2.0, 0.0}, {0.0, 3.0, 0.0}, {0.0, 4.0, 0.0},
509 {1.0, 4.0, 0.0}, {2.0, 4.0, 0.0}, {3.0, 4.0, 0.0}, {4.0, 4.0, 0.0},
510 {4.0, 3.0, 0.0}, {4.0, 2.0, 0.0}, {4.0, 1.0, 0.0}, {4.0, 0.0, 0.0},
511 {3.0, 0.0, 0.0}, {2.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0},
512 {0.8660, 0.8660, 0.0}, {0.8660, 1.8740, 0.0}, {0.8660, 2.8820, 0.0}, {1.6220, 3.1340, 0.0},
513 {2.6300, 3.1340, 0.0}, {3.1340, 2.6300, 0.0}, {3.1340, 1.6220, 0.0}, {2.8820, 0.8660, 0.0},
514 {1.8740, 0.8660, 0.0}, {2.3148, 1.7390, 0.0}, {1.7390, 2.0535, 0.0}, {2.3323, 2.3802, 0.0}};
538 std::vector<Pt3d> outPoly = {{0, 1, 0}, {0, 2, 0}, {0, 3, 0}, {0, 4, 0}, {1, 4, 0}, {2, 4, 0},
539 {3, 4, 0}, {4, 4, 0}, {4, 3, 0}, {4, 2, 0}, {4, 1, 0}, {4, 0, 0},
540 {3, 0, 0}, {2, 0, 0}, {1, 0, 0}, {0, 0, 0}};
541 std::vector<std::vector<Pt3d>> inPoly;
542 std::vector<Pt3d> tmp = {{2.25, 2, 0}, {2.25, 2.25, 0}, {2, 2.25, 0}, {2, 2, 0}};
543 inPoly.push_back(tmp);
544 MePolyPaverToMeshPtsImpl paver;
545 double bias(1), tol(1e-9);
546 std::vector<Pt3d> outPts;
547 paver.PolyToMeshPts(outPoly, inPoly, bias, tol, outPts);
548 std::vector<Pt3d> basePts = {
549 {0.0, 1.0, 0.0}, {0.0, 2.0, 0.0}, {0.0, 3.0, 0.0}, {0.0, 4.0, 0.0},
550 {1.0, 4.0, 0.0}, {2.0, 4.0, 0.0}, {3.0, 4.0, 0.0}, {4.0, 4.0, 0.0},
551 {4.0, 3.0, 0.0}, {4.0, 2.0, 0.0}, {4.0, 1.0, 0.0}, {4.0, 0.0, 0.0},
552 {3.0, 0.0, 0.0}, {2.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0},
553 {2.25, 2.0, 0.0}, {2.25, 2.25, 0.0}, {2.0, 2.25, 0.0}, {2.0, 2.0, 0.0},
554 {0.8660, 0.8660, 0.0}, {0.8660, 1.7951, 0.0}, {0.8660, 2.7070, 0.0}, {1.3659, 3.1340, 0.0},
555 {2.2505, 3.1340, 0.0}, {3.1340, 3.1224, 0.0}, {3.1340, 2.2316, 0.0}, {3.1340, 1.3448, 0.0},
556 {2.6848, 0.8660, 0.0}, {1.7732, 0.8660, 0.0}, {1.7835, 2.1250, 0.0}, {2.0069, 1.7912, 0.0},
557 {2.4260, 1.8985, 0.0}, {2.4335, 2.3440, 0.0}, {2.0093, 2.4589, 0.0}};
void ClassifyPolys(const MePolyOffsetterOutput &a_input, std::vector< std::vector< size_t >> &a_output)
calls implementation
static BSHP< MePolyOffsetter > New()
Creates a BufferPoly class.
static BSHP< MePolyRedistributePts > New()
Creates an instance of this class.
void mePolyPaverRedistribute(BSHP< MePolyRedistributePts > a_redist, const MePolyOffsetterOutput &a_input, MePolyOffsetterOutput &a_out, int a_polyOffsetIter)
Free function access an implement method that needs to be hidden from the public interface.
static BSHP< MePolyPaverToMeshPts > New()
Creates a new instance of this class.
void testCase2()
tests the figure below
convenience class for holding output data from the MePolyOffsetter
Intersect polygons that are a result of the paving process.
polytype
enum to identify types of polygons created by this class
void testCase1()
tests the figure below
static BSHP< MePolyCleaner > New()
Creates a new instance of this class.
void testCreateClass()
tests creating a class
Generates mesh node locations by paving a polygon.
void gmAddToExtents(const Pt3d &a_pt, Pt3d &a_min, Pt3d &a_max)
std::vector< Pt3d > VecPt3d