19 #include <boost/make_shared.hpp> 73 BSHP<GmMultiPolyIntersector>
97 m_tin->GetExtents(pMin, pMax);
98 double len =
Mdist(pMin.
x, pMin.
y, pMax.
x, pMax.
y);
105 XmBathymetryIntersectorImpl::~XmBathymetryIntersectorImpl()
127 std::vector<XmStampCrossSection> vXs, ioXs(a_io.
m_cs);
128 if (ioXs.size() != line.size())
129 ioXs.resize(line.size());
130 for (
size_t i = 1; i < line.size(); ++i)
132 Pt3d &p0(line[i - 1]), &p1(line[i]);
134 vXs.push_back(ioXs[i - 1]);
135 m_intersect->TraverseLineSegment(p0.x, p0.y, p1.
x, p1.
y, triIds, tVals);
136 for (
size_t j = 0; j < triIds.size(); ++j)
143 int idx0(tris[idx]), idx1(tris[idx + 1]), idx2(tris[idx + 2]);
151 line1.push_back(iPt);
159 line1.push_back(line.back());
160 vXs.push_back(ioXs.back());
175 std::vector<XmStamperIo>& a_vIo)
184 for (
auto& i : ptLoc)
186 if (i != 1 || i != -2)
194 for (
auto& i : ptLoc)
196 if (i != -1 || i != -2)
215 for (
size_t i = start + 1; idx == 0 && i < ptLoc.size(); ++i)
224 Pt3d &p0(cl[start]), &p1(cl[idx]), pt;
226 pt = p0 - ((p0 - p1) * 10 *
m_xyTol);
228 pt = p1 - ((p1 - p0) * 10 *
m_xyTol);
243 io.
m_cs.resize(idx - start + 1);
248 for (
size_t j = 0, i = start; i <= idx; ++i, ++j)
256 if (start == lastIdx)
271 a_ptLocation.assign(a_pts.size(), -2);
280 for (
size_t i = 0; i < a_pts.size(); ++i)
284 m_intersect->TraverseLineSegment(p0.
x, p0.
y, p0.
x, p0.
y, triIds, tVals);
288 int idx =
m_triIds[triIds.front() - 1];
290 int idx0(tris[idx]), idx1(tris[idx + 1]), idx2(tris[idx + 2]);
292 Pt3d nrm(0, 0, 1), orig, bary, &pt0(pts[idx0]), &pt1(pts[idx1]), &pt2(pts[idx2]);
295 gmBaryPrepare(&pt0, &pt1, &pt2, &nrm, &orig, coef, &dir,
true);
297 double interpZ = pt0.z * bary.
x + pt1.z * bary.
y + pt2.
z * bary.
z;
298 if (
EQ_TOL(interpZ, p0.
z, FLT_EPSILON))
300 else if (interpZ > p0.
z)
301 a_ptLocation[i] = -1;
362 for (
size_t i = 0; i < cl.size(); ++i)
365 line.reserve(xs[i].size() + 1);
366 line.push_back(cl[i]);
367 for (
auto& p : xs[i])
370 line.erase(line.begin());
386 ptFlags.resize(pts.size(),
true);
392 BSHP<VecInt> tPtr(
new VecInt());
395 tPtr->reserve(tmp.size());
396 for (
const auto& t : tmp)
397 tPtr->push_back((
int)t);
399 tSearch->TrisToSearch(
m_stamp->PointsPtr(), tPtr);
400 for (
size_t i = 0; i < pts.size(); ++i)
402 if (
XM_NONE == tSearch->TriContainingPt(pts[i]))
412 triFlags.resize(tris.size() / 3, 0);
413 for (
size_t i = 0, cnt = 0; i < tris.size(); i += 3, ++cnt)
415 int ix0(tris[i + 0]), ix1(tris[i + 1]), ix2(tris[i + 2]);
416 if (ptFlags[ix0] || ptFlags[ix1] || ptFlags[ix2])
421 else if (!triFlags[cnt])
423 pMin = XM_DBL_HIGHEST;
424 pMax = XM_DBL_LOWEST;
428 tSearch->TriEnvelopesOverlap(pMin, pMax, tIdxes);
439 for (
size_t i = 0, cnt = 0; i < tris.size(); i += 3)
441 if (!triFlags[i / 3])
457 polys[cnt][0] = tris[i + 0];
458 polys[cnt][1] = tris[i + 1];
459 polys[cnt][2] = tris[i + 2];
463 BSHP<GmMultiPolyIntersectionSorterTerse> sorterTerse =
464 boost::make_shared<GmMultiPolyIntersectionSorterTerse>();
465 BSHP<GmMultiPolyIntersectionSorter> sorter = BDPC<GmMultiPolyIntersectionSorter>(sorterTerse);
481 line1.push_back(line[0]);
482 for (
size_t i = 1; !done && i < line.size(); ++i)
484 Pt3d &p0(line[i - 1]), &p1(line[i]);
485 m_intersect->TraverseLineSegment(p0.x, p0.y, p1.
x, p1.
y, triIds, tVals);
486 for (
size_t j = 0; !done && j < triIds.size(); ++j)
494 int idx0(tris[idx]), idx1(tris[idx + 1]), idx2(tris[idx + 2]);
496 Pt3d &t0(pts[idx0]), &t1(pts[idx1]), &t2(pts[idx2]);
501 line1.push_back(iPt);
520 int leftShoulder = a_io.
m_cs[0].m_idxLeftShoulder;
521 int rightShoulder = a_io.
m_cs[0].m_idxRightShoulder;
527 leftShoulder = a_io.
m_cs.back().m_idxLeftShoulder;
528 rightShoulder = a_io.
m_cs.back().m_idxRightShoulder;
538 if (leftShoulder - 1 < (
int)xsLeft->size())
539 ls = (*xsLeft)[leftShoulder - 1];
546 if (rightShoulder - 1 < (
int)xsRight->size())
547 rs = (*xsRight)[rightShoulder - 1];
563 int leftShoulder = a_io.
m_cs[0].m_idxLeftShoulder;
564 int rightShoulder = a_io.
m_cs[0].m_idxRightShoulder;
571 leftShoulder = a_io.
m_cs.back().m_idxLeftShoulder;
572 rightShoulder = a_io.
m_cs.back().m_idxRightShoulder;
584 cl.insert(cl.end(), clPtr->begin(), clPtr->end());
586 if (cl.back() != clPtr->back())
600 vCl.resize(lPtr->size(), vCl.back());
620 XmBathymetryIntersector::XmBathymetryIntersector()
626 XmBathymetryIntersector::~XmBathymetryIntersector()
658 pts[3].z = pts[4].z = pts[7].z = pts[8].z = 10.0;
660 io.
m_centerLine = {{7.5, -1, 5}, {7.5, 9, 5}, {15, 6, 5}};
664 VecPt3d basePts = {{7.5, -1, 5}, {7.5, 2.5, 5}, {7.5, 9, 5}, {12.5, 7, 5}, {15, 6, 5}};
675 pts[3].z = pts[4].z = pts[7].z = pts[8].z = 10.0;
680 xpts.
m_xsPts.
m_left[0] = {{6, 9, 11}, {7, 9, 11}, {8, 9, 11}, {9, 9, 9}};
684 VecPt3d basePts = {{6, 9, 11}, {7, 9, 11}, {8, 9, 11}, {8.5, 9, 10}};
696 VecPt3d pts = {{0, 0, 0}, {4, 6, 0}, {5, 5, 11}, {6, 6, -1}, {9, 9, 9.9}};
699 VecInt baseLoc = {-2, 0, 1, -2, 1};
704 pts[3].z = pts[4].z = pts[7].z = pts[8].z = 10.0;
707 baseLoc = {-2, -1, 1, -2, -1};
726 std::vector<XmStamperIo> vIo;
728 TS_ASSERT_EQUALS(1, vIo.size());
731 VecPt3d basePts = {{7.5, 1.083, 5}, {9.199, 2.5, 5}};
738 TS_ASSERT_EQUALS(2, vIo.size());
741 VecPt3d basePts = {{5, -1, 5}, {7.5, 1.083, 5}};
743 basePts = {{9.199, 2.5, 5}, {11, 4, 5}};
751 TS_ASSERT_EQUALS(0, vIo.size());
755 TS_ASSERT_EQUALS(1, vIo.size());
761 TS_ASSERT_EQUALS(0, vIo.size());
792 tin->Points() = {{5, 0, 0}, {10, 0, 0}, {0, 5, 0}, {5, 5, 0}, {10, 5, 0},
793 {15, 5, 0}, {0, 10, 0}, {5, 10, 0}, {10, 10, 0}, {5, 15, 0}};
794 tin->Triangles() = {0, 3, 2, 0, 1, 3, 1, 4, 3, 1, 5, 4, 2, 3, 6,
795 3, 7, 6, 4, 8, 7, 4, 5, 8, 6, 7, 9, 7, 8, 9};
796 tin->BuildTrisAdjToPts();
void testClassifyPoints()
Tests point classification compared to the TIN (on, below, above, outside)
std::vector< int > VecInt
double m_xyTol
xy tolerance for geometry comparisons
BSHP< TrTin > trBuildTin()
Builds a simple TIN with a hole in the middle.
VecPt3d2d m_right
3d locations of cross section points
void testIntersectCenterLine()
Tests Intersecting center line with TIN.
int gmCartToBary(const Pt3d *cart, const Pt3d *orig, double coef[6], int dir, Pt3d *bary)
static BSHP< XmBathymetryIntersector > New(BSHP< TrTin > a_tin, BSHP< TrTin > a_stamp)
Creates a XmStampInterpCrossSection class.
void testCreateClass()
Tests XmBathymetryIntersectorUnitTests.
virtual void IntersectCenterLine(XmStamperIo &a_io) override
Intersects the center line from a feature stamp operation with the bathemetry. This can potentially c...
bool gmEqualPointsXY(double x1, double y1, double x2, double y2, double tolerance)
std::vector< double > VecDbl
Implementaion of XmBathymetryIntersector.
VecInt m_triIds
the ids of the triangles in the intersector
stXs3dPts m_last_endcap
3d locations of the last end cap
XmStamperEndCap m_firstEndCap
end cap at beginnig of polyline
static BSHP< GmTriSearch > New()
static boost::shared_ptr< GmMultiPolyIntersector > New(const std::vector< Pt3d > &a_points, const std::vector< std::vector< int > > &a_polys, boost::shared_ptr< GmMultiPolyIntersectionSorter > a_sorter, int a_startingId=1)
int gmIntersectTriangleAndLineSegment(const Pt3d &a_pt1, const Pt3d &a_pt2, const Pt3d &a_t0, const Pt3d &a_t1, const Pt3d &a_t2, Pt3d &a_IntersectPt)
End cap definition for feature stamp.
BSHP< TrTin > m_stamp
TIN of the stamp.
Pt3d m_max
max x,y,z of stamp
void ClassifyPoints(VecPt3d &a_pts, VecInt &a_ptLocation)
Intersects the center line from a feature stamp operation with the bathemetry. This can potentially c...
VecPt3d m_centerLine
only used by guidebank
Intersects a feature stamp with a TIN.
void IntersectGuideBank(XmStamperIo &a_io, XmStamper3dPts &a_pts, bool a_first)
Intersects sloped abutment end cap cross section points.
BSHP< GmMultiPolyIntersector > m_intersect
polygon intersector for intersecting objects with the bathemetry TIN
boost::dynamic_bitset< size_t > DynBitset
std::vector< VecInt > VecInt2d
XmStamperEndCap m_lastEndCap
end cap at end of polyline
virtual void IntersectEndCaps(XmStamperIo &a_io, XmStamper3dPts &a_pts) override
Intersects end cap cross section points. When a cross section intersects the bathemetry it stops at t...
static BSHP< TrTin > New()
void Intersect3dPts(VecPt3d &a_pts)
Intersects a line with a surface.
#define XM_ENSURE_TRUE(...)
void IntersectSlopedAbutment(XmStamperIo &a_io, XmStamper3dPts &a_pts, bool a_first)
Intersects sloped abutment end cap cross section points.
XmBathymetryIntersectorImpl(BSHP< TrTin > a_tin, BSHP< TrTin > a_stamp)
int gmBaryPrepare(const Pt3d *p1, const Pt3d *p2, const Pt3d *p3, const Pt3d *norm, Pt3d *orig, double coef[6], int *dir, bool flag)
stXs3dPts m_first_endcap
3d locations of first end cap
class to hold 3d points generated by the stamping operation
void CreateIntersector()
Creates a multi poly intersector if one does not exist.
int m_type
type of end cap: 0- guidebank, 1- sloped abutment, 2- wing wall
void IntersectXsectSide(VecPt3d &a_cl, VecPt3d2d &a_side)
Intersects left or right side of a cross section with bathymetry.
bool EQ_TOL(const _T &A, const _U &B, const _V &tolerance)
Stamping inputs/outputs class.
std::vector< VecPt3d > VecPt3d2d
void testIntersectXsects()
Tests Intersecting cross sections with TIN.
virtual void IntersectXsects(XmStamper3dPts &a_pts) override
Intersects cross section points. When a cross section intersects the bathemetry it stops at that loca...
Cross section definition for stamping.
void testDescomposeCenterLine()
Splits up a center line based on intersections.
std::vector< XmStampCrossSection > m_cs
cross sections along the polyLine
double Mdist(_T x1, _U y1, _V x2, _W y2)
VecPt3d2d m_left
3d locations of cross section points
stXs3dPts m_xsPts
3d locations of cross section points
void gmAddToExtents(const Pt3d &a_pt, Pt3d &a_min, Pt3d &a_max)
BSHP< TrTin > m_tin
TIN defining Bathemetry surface.
Pt3d m_min
min x,y,z of stamp
int m_stampingType
Stamping type 0 - Cut, 1 - Fill, 2 - Both.
virtual void DecomposeCenterLine(XmStamperIo &a_io, std::vector< XmStamperIo > &a_vIo) override
Intersects the center line from a feature stamp operation with the bathemetry. This can potentially c...
std::vector< Pt3d > VecPt3d