xmsstamper  1.0
XmStamper.cpp
Go to the documentation of this file.
1 //------------------------------------------------------------------------------
6 //------------------------------------------------------------------------------
7 
8 //----- Included files ---------------------------------------------------------
9 
10 // 1. Precompiled header
11 
12 // 2. My own header
14 
15 // 3. Standard library headers
16 #include <algorithm>
17 #include <fstream>
18 #include <iostream>
19 
20 // 4. External library headers
21 
22 // 5. Shared code headers
23 #include <xmscore/math/math.h>
24 #include <xmscore/misc/XmError.h> // XM_ENSURE_TRUE
25 #include <xmscore/misc/xmstype.h> // XM_NODATA
28 #include <xmscore/misc/Observer.h>
40 #include <xmscore/misc/XmConst.h>
41 
42 // 6. Non-shared code headers
43 
44 //----- Forward declarations ---------------------------------------------------
45 
46 //----- External globals -------------------------------------------------------
47 
48 //----- Namespace declaration --------------------------------------------------
49 namespace xms
50 {
51 //----- Constants / Enumerations -----------------------------------------------
52 
53 //----- Classes / Structs ------------------------------------------------------
54 
56 class XmStamperImpl : public XmStamper
57 {
58 public:
59  XmStamperImpl();
60  ~XmStamperImpl();
61 
62  virtual void DoStamp(XmStamperIo& a_io) override;
63 
64  //------------------------------------------------------------------------------
67  //------------------------------------------------------------------------------
68  virtual const VecPt3d& GetPoints() override { return *m_outPts; }
69  //------------------------------------------------------------------------------
72  //------------------------------------------------------------------------------
73  virtual const VecInt2d& GetSegments() override { return m_breaklines; }
74  //------------------------------------------------------------------------------
77  //------------------------------------------------------------------------------
78  virtual const VecInt& GetBreaklineTypes() override { return m_blTypes; }
79 
80  //------------------------------------------------------------------------------
83  //------------------------------------------------------------------------------
84  virtual void SetObserver(BSHP<Observer> a_) override { m_observer = a_; }
85 
86  BSHP<Observer> m_observer;
88  std::vector<XmStamperIo> m_vIo;
92  BSHP<XmStampInterpCrossSection> m_interp;
94  BSHP<XmBathymetryIntersector> m_intersect;
96  BSHP<XmBreaklines> m_breaklineCreator;
97  BSHP<VecPt3d> m_outPts;
100  bool m_error;
101  BSHP<TrTin> m_tin;
104  BSHP<VecPt3d> m_curPts;
107 
108  void WriteInputsForDebug();
109  bool InputErrorsFound();
111  void GetStampBounds();
114  void DecomposeCenterLine();
116  void ConvertEndCapsTo3d();
117  void IntersectWithTin();
118  bool CreateOutputs();
119  void AddCrossSectionPointsToArray(stXs3dPts& a_csPts, VecPt3d& a_pts, csPtIdx& a_ptIdx);
120  bool CreateBreakLines(cs3dPtIdx& a_ptIdx);
121  void AppendTinAndBreakLines(bool a_errors);
122  void Convert3dPtsToVec();
123 };
124 namespace
125 {
126 //------------------------------------------------------------------------------
136 //------------------------------------------------------------------------------
137 bool iInterpTinToRaster(const boost::shared_ptr<const TrTin> &a_tin, XmStampRaster &a_raster,
138  int a_stampingType = 2)
139 {
140  XM_ENSURE_TRUE(a_tin != nullptr, false);
141  BSHP<InterpLinear> interp = InterpLinear::New();
142  BSHP<VecPt3d> pts(new VecPt3d());
143  *pts = a_tin->Points();
144  BSHP<VecInt> tris(new VecInt());
145  *tris = a_tin->Triangles();
146  interp->SetPtsTris(pts, tris);
147  interp->SetExtrapVal(XM_NODATA);
148  int rasterSize = static_cast<int>(a_raster.m_vals.size());
149  for (int i = 0; i < rasterSize; ++i)
150  {
151  float val = interp->InterpToPt(Pt3d(a_raster.GetLocationFromCellIndex(i)));
152  if (!EQ_TOL(val, XM_NODATA, XM_ZERO_TOL))
153  {
154  // Take the stamp value if the raster has none, regardless of stamping type.
155  if (EQ_TOL(a_raster.m_vals[i], a_raster.m_noData, XM_ZERO_TOL))
156  {
157  a_raster.m_vals[i] = val;
158  }
159  else if (a_stampingType == 0) // Cut stamp, take the minimum
160  {
161  a_raster.m_vals[i] = std::min(double(val), a_raster.m_vals[i]);
162  }
163  else if (a_stampingType == 1) // Fill stamp, take the maximum
164  {
165  a_raster.m_vals[i] = std::max(double(val), a_raster.m_vals[i]);
166  }
167  else // Both, always stamp the feature object
168  {
169  a_raster.m_vals[i] = val;
170  }
171  }
172  }
173  return true;
174 } // iInterpTinToRaster
175 }
181 //------------------------------------------------------------------------------
183 //------------------------------------------------------------------------------
184 XmStamperImpl::XmStamperImpl()
185 : m_observer()
186 , m_io()
187 , m_interp(XmStampInterpCrossSection::New())
188 , m_outPts(new VecPt3d())
189 , m_error(false)
190 {
191 } // XmStamperImpl::XmStamperImpl
192 //------------------------------------------------------------------------------
194 //------------------------------------------------------------------------------
195 XmStamperImpl::~XmStamperImpl()
196 {
197 } // XmStamperImpl::~XmStamperImpl
198 //------------------------------------------------------------------------------
202 //------------------------------------------------------------------------------
204 {
205  m_io = a_io;
206  m_io.m_outTin.reset();
207  m_io.m_outBreakLines.clear();
208 
210 
211  if (InputErrorsFound())
212  return;
213 
215 
219 
220  for (auto& io : m_vIo)
221  {
222  m_io = io;
224 
228  bool rval = CreateOutputs();
229  AppendTinAndBreakLines(!rval);
230  }
231 
233  {
234  m_error = m_breaklineCreator->BreaklinesIntersect(m_breaklines, *m_outPts);
235  if (m_error)
236  {
237  XM_LOG(xmlog::warning, "Intersection found in stamp outputs. Stamping operation aborted.");
238  }
239  }
240 
241  if (!m_error)
242  {
244  a_io.m_outTin = m_tin;
245  if (!a_io.m_raster.m_vals.empty())
246  {
247  iInterpTinToRaster(a_io.m_outTin, a_io.m_raster, a_io.m_stampingType);
248  }
249  }
250 
251 } // XmStamperImpl::DoStamp
252 //------------------------------------------------------------------------------
254 //------------------------------------------------------------------------------
256 {
257  std::fstream os;
258  os.open("c:\\temp\\xmsstamper_DoStamp_SaveInputs.dbg", std::fstream::in);
259  if (os.good())
260  {
261  std::ofstream os("c:\\temp\\xmsng_StamperIo.txt");
262  m_io.WriteToFile(os, "STAMPER_IO_VERSION_1");
263  }
264 } // WriteInputsForDebug
265 //------------------------------------------------------------------------------
268 //------------------------------------------------------------------------------
270 {
271  XM_ENSURE_TRUE(m_io.m_centerLine.size() > 1, true);
272  XM_ENSURE_TRUE(m_io.m_centerLine.size() == m_io.m_cs.size(), true);
273  // make sure that at least one cross section has data
274  if (!m_interp->ValidCrossSectionsExist(m_io))
275  {
276  XM_LOG(xmlog::warning, "No valid cross sections defined. Aborting stamp operation.");
277  return true;
278  }
279 
280  return false;
281 } // XmStamperImpl::InputErrorsFound
282 //------------------------------------------------------------------------------
284 //------------------------------------------------------------------------------
286 {
287  m_intersect.reset();
288  if (m_io.m_bathymetry)
289  {
290  XmStamperIo tmp(m_io);
291 
296  CreateOutputs();
297 
298  // get the boundary of the stamp
299  GetStampBounds();
300 
302  m_intersect->IntersectCenterLine(m_io);
303 
304  m_io = tmp;
305  }
306 } // XmStamperImpl::IntersectCenterLineWithBathemetry
307 //------------------------------------------------------------------------------
309 //------------------------------------------------------------------------------
311 {
312  m_stampBoundsMax = XM_DBL_LOWEST;
313  m_stampBoundsMin = XM_DBL_HIGHEST;
314 
315  auto myLamda = [](stXs3dPts& pts, Pt3d& a_min, Pt3d& a_max) {
316  for (auto& p : pts.m_centerLine)
317  gmAddToExtents(p, a_min, a_max);
318  for (auto& v : pts.m_left)
319  {
320  for (auto& p : v)
321  gmAddToExtents(p, a_min, a_max);
322  }
323  for (auto& v : pts.m_right)
324  {
325  for (auto& p : v)
326  gmAddToExtents(p, a_min, a_max);
327  }
328  };
329 
333 } // XmStamperImpl::IntersectCenterLineWithBathemetry
334 //------------------------------------------------------------------------------
336 //------------------------------------------------------------------------------
338 {
339  if (m_intersect)
340  {
341  m_intersect->IntersectCenterLine(m_io);
342  }
343 } // XmStamperImpl::IntersectCenterLineWithBathemetry
344 //------------------------------------------------------------------------------
347 //------------------------------------------------------------------------------
349 {
350  m_interp->InterpMissingCrossSections(m_io);
351 } // XmStamperImpl::InterpolateMissingCrossSections
352 //------------------------------------------------------------------------------
354 //------------------------------------------------------------------------------
356 {
357  m_vIo.push_back(m_io);
358  if (!m_intersect)
359  return;
360  m_intersect->DecomposeCenterLine(m_io, m_vIo);
361 } // XmStamperImpl::DecomposeCenterLine
362 //------------------------------------------------------------------------------
364 //------------------------------------------------------------------------------
366 {
367  for (size_t i = 0; i < m_io.m_cs.size(); ++i)
368  {
369  XmStampCrossSection& cs(m_io.m_cs[i]);
370  Pt3d p(m_io.m_centerLine[i]);
371  double leftAngle, rightAngle;
372  XmUtil::GetAnglesFromCenterLine(i, m_io.m_centerLine, leftAngle, rightAngle);
375  }
376 } // XmStamperImpl::ConvertCrossSectionsTo3d
377 //------------------------------------------------------------------------------
379 //------------------------------------------------------------------------------
381 {
383 
384  BSHP<XmStampEndCap> cap = XmStampEndCap::New();
385  cap->RotateEndCapCrossSections(m_io, m_3dpts.m_xsPts.m_left, m_3dpts.m_xsPts.m_right);
386  // convert the end cap to 3D points
387  cap->ConvertTo3dPts(m_io, m_3dpts);
388 } // XmStamperImpl::ConvertEndCapsTo3d
389 //------------------------------------------------------------------------------
391 //------------------------------------------------------------------------------
393 {
394  if (!m_io.m_bathymetry)
395  return;
396 
397  // intersect the left and right side xsects
399  m_intersect->IntersectXsects(m_3dpts);
400  m_3dpts.m_xsPts.m_centerLine.clear();
401 
402  // intersect endcap points
403  m_intersect->IntersectEndCaps(m_io, m_3dpts);
404 } // XmStamperImpl::IntersectWithTin
405 //------------------------------------------------------------------------------
408 //------------------------------------------------------------------------------
410 {
412 
413  // define the breaklines
415  return false;
416 
417  // Triangulate
419  m_io.m_outTin->SetPoints(m_curPts);
420  TrTriangulatorPoints client(m_io.m_outTin->Points(), m_io.m_outTin->Triangles(),
421  &m_io.m_outTin->TrisAdjToPts());
422  client.SetObserver(m_observer);
423  if (!client.Triangulate())
424  return false;
425 
426  // force in the breaklines
427  BSHP<TrBreaklineAdder> bl = TrBreaklineAdder::New();
428  bl->SetTin(m_io.m_outTin);
429  bl->AddBreaklines(m_io.m_outBreakLines);
430 
431  // delete triangles outside the outer boundary
432  BSHP<TrOuterTriangleDeleter> deleter = TrOuterTriangleDeleter::New();
433  VecInt2d poly(1, m_breaklineCreator->GetOuterPolygon());
434  deleter->Delete(poly, m_io.m_outTin);
435 
436  return true;
437 } // XmStamperImpl::CreateOutputs
438 //------------------------------------------------------------------------------
440 //------------------------------------------------------------------------------
442 {
443  m_ptIdx = cs3dPtIdx();
444  // put all of the points into 1 array for the output TIN
445  m_curPts = BSHP<VecPt3d>(new VecPt3d());
446  for (const auto& p : m_io.m_centerLine)
447  {
448  m_ptIdx.m_centerLine.push_back((int)m_curPts->size());
449  m_curPts->push_back(p);
450  }
454 } // XmStamperImpl::Convert3dPtsToVec
455 
456 //------------------------------------------------------------------------------
461 //------------------------------------------------------------------------------
463  VecPt3d& a_pts,
464  csPtIdx& a_ptIdx)
465 {
466  for (const auto& v : a_csPts.m_left)
467  {
468  a_ptIdx.m_left.push_back(VecInt());
469  for (const auto& p : v)
470  {
471  a_ptIdx.m_left.back().push_back((int)a_pts.size());
472  a_pts.push_back(p);
473  }
474  }
475  for (const auto& v : a_csPts.m_right)
476  {
477  a_ptIdx.m_right.push_back(VecInt());
478  for (const auto& p : v)
479  {
480  a_ptIdx.m_right.back().push_back((int)a_pts.size());
481  a_pts.push_back(p);
482  }
483  }
484  for (const auto p : a_csPts.m_centerLine)
485  {
486  a_ptIdx.m_centerLine.push_back((int)a_pts.size());
487  a_pts.push_back(p);
488  }
489 } // XmStamperImpl::AddCrossSectionPointsToArray
490 //------------------------------------------------------------------------------
494 //------------------------------------------------------------------------------
496 {
497  m_breaklineCreator.reset();
499 
500  bool rval = m_breaklineCreator->CreateBreaklines(m_io, a_ptIdx, m_blTypes);
501  return rval;
502 } // XmStamperImpl::CreateBreakLines
503 //------------------------------------------------------------------------------
506 //------------------------------------------------------------------------------
508 {
509  if (!m_tin)
510  {
511  m_tin = m_io.m_outTin;
513  m_outPts = m_tin->PointsPtr();
514  }
515  else if (m_io.m_outTin)
516  {
517  // get the number of points in the current TIN
518  int nPts = (int)m_outPts->size();
519  // add the points from the current TIN
520  m_outPts->reserve(nPts + m_io.m_outTin->Points().size());
521  {
522  auto beg = m_io.m_outTin->Points().begin();
523  auto end = m_io.m_outTin->Points().end();
524  m_outPts->insert(m_outPts->end(), beg, end);
525  }
526  // add the triangles after updating indices
527  for (auto& t : m_io.m_outTin->Triangles())
528  t += nPts;
529 
530  {
531  auto e1 = m_tin->Triangles().end();
532  auto beg = m_io.m_outTin->Triangles().begin();
533  auto end = m_io.m_outTin->Triangles().end();
534  m_tin->Triangles().insert(e1, beg, end);
535  }
536 
537  // update indices on breaklines
538  for (auto& b : m_io.m_outBreakLines)
539  {
540  for (auto& i : b)
541  i += nPts;
542  }
543  {
544  auto e1 = m_breaklines.end();
545  auto beg = m_io.m_outBreakLines.begin();
546  auto end = m_io.m_outBreakLines.end();
547  m_breaklines.insert(e1, beg, end);
548  }
549  }
550  if (a_errors)
551  m_error = true;
552 } // XmStamperImpl::AppendTinAndBreakLines
553 
554 //------------------------------------------------------------------------------
557 //------------------------------------------------------------------------------
558 BSHP<XmStamper> XmStamper::New()
559 {
560  BSHP<XmStamper> stamper(new XmStamperImpl);
561  return stamper;
562 } // XmStamper::New
563 //------------------------------------------------------------------------------
565 //------------------------------------------------------------------------------
566 XmStamper::XmStamper()
567 {
568 } // XmStamper::XmStamper
569 //------------------------------------------------------------------------------
571 //------------------------------------------------------------------------------
572 XmStamper::~XmStamper()
573 {
574 } // XmStamper::~XmStamper
575 
576 } // namespace xms
static boost::shared_ptr< TrBreaklineAdder > New()
#define XM_LOG(A, B)
static BSHP< XmStamper > New()
Creates a XmStamper class.
Definition: XmStamper.cpp:558
static BSHP< XmStampEndCap > New()
Creates a XmStampInterpCrossSection class.
bool CreateBreakLines(cs3dPtIdx &a_ptIdx)
Creates breaklines that will be honored in the TIN.
Definition: XmStamper.cpp:495
void IntersectWithTin()
Intersects the feature stampe with the elevation TIN.
Definition: XmStamper.cpp:392
std::vector< int > VecInt
BSHP< TrTin > m_bathymetry
underlying bathymetry
Definition: XmStamperIo.h:199
VecPt3d m_left
left side of the cross section
Definition: XmStamperIo.h:156
VecPt3d2d m_right
3d locations of cross section points
static BSHP< XmBathymetryIntersector > New(BSHP< TrTin > a_tin, BSHP< TrTin > a_stamp)
Creates a XmStampInterpCrossSection class.
VecInt2d m_outBreakLines
break lines that are honored in the TIN
Definition: XmStamperIo.h:205
bool CreateOutputs()
Creates the output TIN and breaklines.
Definition: XmStamper.cpp:409
Pt3d m_stampBoundsMin
min x,y,z of stamp
Definition: XmStamper.cpp:102
BSHP< TrTin > m_tin
tin created by the stamp operation
Definition: XmStamper.cpp:101
VecInt m_centerLine
used by guidebank
stXs3dPts m_last_endcap
3d locations of the last end cap
Pt3d GetLocationFromCellIndex(const int a_index) const
Gets the location of the cell center from the zero-based cell index.
XmStamper3dPts m_3dpts
3d locations of the stamp operation
Definition: XmStamper.cpp:98
csPtIdx m_last_end_cap
helper struct to store point indexes
double m_leftMax
max x value for left side
Definition: XmStamperIo.h:157
void AddCrossSectionPointsToArray(stXs3dPts &a_csPts, VecPt3d &a_pts, csPtIdx &a_ptIdx)
puts cross section points into a single array to be used by a TIN
Definition: XmStamper.cpp:462
Performs a feature stamp operation The result of the operation is a TIN and a list of breakline segme...
Definition: XmStamper.cpp:56
Pt3d m_stampBoundsMax
max x,y,z of stamp
Definition: XmStamper.cpp:103
virtual const VecPt3d & GetPoints() override
returns the point locations created by the stamp operation.
Definition: XmStamper.cpp:68
void DecomposeCenterLine()
Decomposes the centerline (more help needed)
Definition: XmStamper.cpp:355
XmStampRaster m_raster
Input/output raster to stamp the resulting elevations onto this raster.
Definition: XmStamperIo.h:207
BSHP< XmBathymetryIntersector > m_intersect
class to intersect the feature stamp with bathemetry
Definition: XmStamper.cpp:94
void AppendTinAndBreakLines(bool a_errors)
appends to the output TIN and breaklines
Definition: XmStamper.cpp:507
void WriteInputsForDebug()
Writes the XmStamperIo class to a file for debugging.
Definition: XmStamper.cpp:255
BSHP< Observer > m_observer
progress observer
Definition: XmStamper.cpp:86
VecPt3d m_centerLine
only used by guidebank
class to hold 3d points for a cross section
std::vector< VecInt > VecInt2d
BSHP< XmBreaklines > m_breaklineCreator
class to create breaklines
Definition: XmStamper.cpp:96
void IntersectCenterLineWithBathemetry()
Intersects the center line with the bathemetry.
Definition: XmStamper.cpp:337
BSHP< XmStampInterpCrossSection > m_interp
Definition: XmStamper.cpp:92
virtual void DoStamp(XmStamperIo &a_io) override
Performs the feature stamping operation.
Definition: XmStamper.cpp:203
virtual void SetObserver(BSHP< Observer > a_)
static BSHP< TrTin > New()
static void GetAnglesFromCenterLine(size_t a_idx, const VecPt3d &a_cl, double &a_leftAngle, double &a_rightAngle)
Gets the angles of the left and right cross sections relative to the centerline.
Definition: XmUtil.cpp:153
void InterpolateMissingCrossSections()
Interpolates cross sections for any points that do not have a cross section specified.
Definition: XmStamper.cpp:348
cs3dPtIdx m_ptIdx
indexes of point created from stamp
Definition: XmStamper.cpp:105
helper struct to store point indexes
bool InputErrorsFound()
Checks for input errors.
Definition: XmStamper.cpp:269
void CreateBathymetryIntersector()
Creates the intersector for the bathymetry.
Definition: XmStamper.cpp:285
int m_noData
NO DATA value for the raster (typically XM_NODATA)
Definition: XmStamperIo.h:48
#define XM_ENSURE_TRUE(...)
BSHP< VecPt3d > m_curPts
the output points
Definition: XmStamper.cpp:104
std::vector< double > m_vals
Definition: XmStamperIo.h:46
std::vector< XmStamperIo > m_vIo
vector of stampers to break up center line where intersections occur
Definition: XmStamper.cpp:89
stXs3dPts m_first_endcap
3d locations of first end cap
double m_rightMax
max x value for right side
Definition: XmStamperIo.h:161
BSHP< TrTin > m_outTin
Definition: XmStamperIo.h:203
class to hold 3d points generated by the stamping operation
XmStamperIo m_io
Definition: XmStamper.cpp:87
VecPt3d m_right
right side of the cross section
Definition: XmStamperIo.h:160
bool m_error
flag to indicate that an error has occurred processing the stamp
Definition: XmStamper.cpp:100
bool EQ_TOL(const _T &A, const _U &B, const _V &tolerance)
virtual const VecInt2d & GetSegments() override
returns breaklines created by the stamp operation.
Definition: XmStamper.cpp:73
Stamping inputs/outputs class.
Definition: XmStamperIo.h:171
void WriteToFile(std::ofstream &a_file, const std::string &a_cardName) const
Writes the XmStamperIo class information to a file.
static void ConvertXsPointsTo3d(const Pt3d &a_cl, const VecPt3d &a_pts, double a_maxX, double a_angle, VecPt3d2d &a_3dpts)
Converts the left or right portion of a cross section data to 3d point locations using the angle from...
Definition: XmUtil.cpp:49
static boost::shared_ptr< TrOuterTriangleDeleter > New()
void ConvertCrossSectionsTo3d()
Converts the cross section data to 3d point locations.
Definition: XmStamper.cpp:365
csPtIdx m_xsPts
helper struct to store point indexes
void GetStampBounds()
Gets the bounds of the stamp.
Definition: XmStamper.cpp:310
virtual const VecInt & GetBreaklineTypes() override
Definition: XmStamper.cpp:78
csPtIdx m_first_end_cap
helper struct to store point indexes
static BSHP< InterpLinear > New()
Cross section definition for stamping.
Definition: XmStamperIo.h:142
void Convert3dPtsToVec()
puts all of the generated 3d points into one vector
Definition: XmStamper.cpp:441
std::vector< XmStampCrossSection > m_cs
cross sections along the polyLine
Definition: XmStamperIo.h:193
VecPt3d2d m_left
3d locations of cross section points
void ConvertEndCapsTo3d()
Converts the cross section data to 3d point locations.
Definition: XmStamper.cpp:380
Raster defined using a non-rotated cartesian axis for use in XmStamper.
Definition: XmStamperIo.h:33
stXs3dPts m_xsPts
3d locations of cross section points
helper struct to store point indexes
Performs a feature stamp operation.
Definition: XmStamper.h:38
VecInt2d m_breaklines
breaklines
Definition: XmStamper.cpp:99
void gmAddToExtents(const Pt3d &a_pt, Pt3d &a_min, Pt3d &a_max)
virtual void SetObserver(BSHP< Observer > a_) override
Definition: XmStamper.cpp:84
VecInt2d m_right
indexes of cross section points
VecInt2d m_left
indexes of cross section points
static BSHP< XmBreaklines > New()
Creates a XmStampInterpCrossSection class.
VecInt m_centerLine
indexes of cross section points
int m_stampingType
Stamping type 0 - Cut, 1 - Fill, 2 - Both.
Definition: XmStamperIo.h:191
BSHP< VecPt3d > m_outPts
the output points
Definition: XmStamper.cpp:97
VecInt m_blTypes
type of breakline
Definition: XmStamper.cpp:106
std::vector< Pt3d > VecPt3d
VecPt3d m_centerLine
Definition: XmStamperIo.h:189