xmsstamper  1.0
XmSlopedAbutmentUtil.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 
17 // 4. External library headers
18 
19 // 5. Shared code headers
20 #include <xmscore/misc/XmError.h>
22 #include <xmscore/misc/xmstype.h>
28 
29 // 6. Non-shared code headers
30 
31 //----- Forward declarations ---------------------------------------------------
32 
33 //----- External globals -------------------------------------------------------
34 
35 //----- Namespace declaration --------------------------------------------------
36 
37 namespace xms
38 {
39 //----- Constants / Enumerations -----------------------------------------------
40 
41 //----- Classes / Structs ------------------------------------------------------
42 
46 {
47 public:
50 
51  virtual void DoConvertTo3d(bool a_first, XmStamperIo& a_io, XmStamper3dPts& a_3dpts) override;
52  virtual void GetEndCapEndPoints(cs3dPtIdx& a_ptIdx,
53  VecInt& a_firstEndCapEndPts,
54  VecInt& a_lastEndCapEndPts,
55  XmStamperIo& a_io) override;
56  virtual void GetEndCapBreakLines(XmStamperIo& a_io,
57  cs3dPtIdx& a_ptIdx,
58  VecInt& a_blTypes) override;
59 
61  enum { SA_LEFT = 0, SA_RIGHT };
63  bool Setup();
67  void InterpolateCrossSections(int a_side);
68  void ConvertTo3d(int a_side);
70 
71  bool m_first;
90  double m_angleCenterLine = 0.0;
93  double m_angleLeftTransition = 0.0;
96  double m_angleLeftIncrement = 0.0;
97  int m_nDivLeft = 0;
98  double m_angleRightTransition = 0.0;
103  double m_angleRightIncrement = 0.0;
104  int m_nDivRight = 0;
105  std::vector<XmStampCrossSection> m_interpLeft;
108  std::vector<XmStampCrossSection> m_interpRight;
113 };
114 
119 //------------------------------------------------------------------------------
121 //------------------------------------------------------------------------------
122 XmSlopedAbutmentUtilImpl::XmSlopedAbutmentUtilImpl()
123 : m_first(true)
124 , m_io(nullptr)
125 , m_3dpts(nullptr)
126 {
127 } // XmSlopedAbutmentUtilImpl::XmSlopedAbutmentUtilImpl
128 //------------------------------------------------------------------------------
130 //------------------------------------------------------------------------------
131 XmSlopedAbutmentUtilImpl::~XmSlopedAbutmentUtilImpl()
132 {
133 } // XmSlopedAbutmentUtilImpl::~XmSlopedAbutmentUtilImpl
134 //------------------------------------------------------------------------------
140 //------------------------------------------------------------------------------
142  XmStamperIo& a_io,
143  XmStamper3dPts& a_3dpts)
144 {
145  m_first = a_first;
146  m_io = &a_io;
147  m_3dpts = &a_3dpts;
148 
149  XM_ENSURE_TRUE(a_io.m_centerLine.size() > 1);
150  XM_ENSURE_TRUE(a_3dpts.m_xsPts.m_left.size() > 1);
151  XM_ENSURE_TRUE(a_3dpts.m_xsPts.m_right.size() > 1);
152  double maxX = a_io.m_firstEndCap.m_slopedAbutment.m_maxX;
153  if (!a_first)
155  XM_ENSURE_TRUE(maxX > 0);
156 
157  if (a_first)
158  m_cap = a_io.m_firstEndCap;
159  else
160  m_cap = a_io.m_lastEndCap;
163  XM_ENSURE_TRUE(m_sa.m_slope.size() > 1); // return if no slope defined
164 
165  Setup();
166  InterpolateCrossSections(SA_LEFT);
167  InterpolateCrossSections(SA_RIGHT);
168  ConvertTo3d(SA_LEFT);
169  ConvertTo3d(SA_RIGHT);
170 } // XmSlopedAbutmentUtilImpl::DoConvert
171 //------------------------------------------------------------------------------
174 //------------------------------------------------------------------------------
176 {
177  if (m_first)
178  {
179  m_cs = m_io->m_cs[0];
180  m_pt1 = m_io->m_centerLine[0];
181  m_pt2 = m_io->m_centerLine[1];
182 
184  size_t ix = static_cast<size_t>(m_cs.m_idxLeftShoulder);
185  if (ix > 0)
186  {
187  ix--;
188  XM_ENSURE_TRUE(!m_3dpts->m_xsPts.m_left.empty(), false);
189  XM_ENSURE_TRUE(ix < m_3dpts->m_xsPts.m_left[0].size(), false);
191  }
192  ix = static_cast<size_t>(m_cs.m_idxRightShoulder);
193  if (ix > 0)
194  {
195  ix--;
196  XM_ENSURE_TRUE(!m_3dpts->m_xsPts.m_right.empty(), false);
197  XM_ENSURE_TRUE(ix < m_3dpts->m_xsPts.m_right[0].size(), false);
199  }
200  }
201  else
202  {
203  m_cs = m_io->m_cs.back();
204  m_pt2 = m_io->m_centerLine.back();
205  size_t ix = m_io->m_centerLine.size() - 2;
207 
209  ix = static_cast<size_t>(m_cs.m_idxLeftShoulder);
210  if (ix > 0)
211  {
212  ix--;
213  XM_ENSURE_TRUE(!m_3dpts->m_xsPts.m_left.empty(), false);
214  XM_ENSURE_TRUE(ix < m_3dpts->m_xsPts.m_left.back().size(), false);
216  }
217  ix = static_cast<size_t>(m_cs.m_idxRightShoulder);
218  if (ix > 0)
219  {
220  ix--;
221  XM_ENSURE_TRUE(!m_3dpts->m_xsPts.m_right.empty(), false);
222  XM_ENSURE_TRUE(ix < m_3dpts->m_xsPts.m_right.back().size(), false);
224  }
225  }
229  return true;
230 } // XmSlopedAbutmentUtilImpl::Setup
231 //------------------------------------------------------------------------------
234 //------------------------------------------------------------------------------
236 {
239  VecPt3d pts(m_sa.m_slope);
240  XM_ENSURE_TRUE(pts.size() > 1, false);
241  // extend to the max x
242  double x1 = pts[pts.size() - 2].x;
243  double x2 = pts.back().x;
244  double x3 = m_sa.m_maxX;
245  if (x3 > x2)
246  {
247  double z1 = pts[pts.size() - 2].y;
248  double z2 = pts.back().y;
249  double z3 = ((x3 - x1) / (x2 - x1) * (z2 - z1)) + z1;
250  Pt3d p(x3, z3);
251  pts.back() = p;
252  }
254  return true;
255 } // XmSlopedAbutmentUtilImpl::SlopedAbutmentTo2dCrossSection
256 //------------------------------------------------------------------------------
259 //------------------------------------------------------------------------------
261 {
263  size_t ix = static_cast<size_t>(m_cs.m_idxLeftShoulder);
264  double x = m_cs.m_left[ix].x;
265  for (size_t i = ix; i < m_cs.m_left.size(); ++i)
266  {
267  m_csLeft.m_left.push_back(m_cs.m_left[i]);
268  m_csLeft.m_left.back().x -= x;
269  }
271 
272  ix = static_cast<size_t>(m_cs.m_idxRightShoulder);
273  x = m_cs.m_right[ix].x;
274  for (size_t i = ix; i < m_cs.m_right.size(); ++i)
275  {
276  m_csRight.m_right.push_back(m_cs.m_right[i]);
277  m_csRight.m_right.back().x -= x;
278  }
280 } // XmSlopedAbutmentUtilImpl::EndCapCrossSectionShouldersTo2dCrossSection
281 //------------------------------------------------------------------------------
283 //------------------------------------------------------------------------------
285 {
286  Pt3d vector = gmCreateVector(m_pt2, m_pt1);
287  double mag;
288  gmComponentMagnitudes(&vector.x, &vector.y, &mag, &m_angleCenterLine, true);
290 
291  if (m_first)
292  {
295  }
296  else
297  {
300  }
301  m_nDivLeft = static_cast<int>(m_angleLeftTransition / 15.0);
303  m_nDivRight = static_cast<int>(m_angleRightTransition / 15.0);
305 } // XmSlopedAbutmentUtilImpl::ComputeTransitionAngles
306 //------------------------------------------------------------------------------
311 //------------------------------------------------------------------------------
313 {
314  BSHP<XmStampInterpCrossSection> interp = XmStampInterpCrossSection::New();
315 
316  double angleFactor(-1.0);
317 
318  // left side
319  int nDiv = m_nDivLeft;
321  double maxLen = next.m_leftMax;
322  std::vector<XmStampCrossSection>* vCs = &m_interpLeft;
323  double angleIncrement = m_angleLeftIncrement;
324  VecDbl* vAngles = &m_interpAnglesLeft;
325  if (a_side == SA_RIGHT)
326  {
327  angleFactor = 1.0;
328  nDiv = m_nDivRight;
329  next = m_csRight;
330  maxLen = next.m_rightMax;
331  vCs = &m_interpRight;
332  angleIncrement = m_angleRightIncrement;
333  vAngles = &m_interpAnglesRight;
334  }
335  XmStampCrossSection saXsect = m_saXsect;
336  double saMaxLen = saXsect.m_leftMax;
337  EnsureCrossSectionAtMaxX(saXsect);
338  XmUtil::ScaleCrossSectionXvals(saXsect, 1 / saMaxLen);
340  XmUtil::ScaleCrossSectionXvals(next, 1 / maxLen);
341 
342  if (!m_first)
343  angleFactor *= -1.0;
345  vCs->push_back(m_saXsect);
346  vAngles->push_back(m_angleCenterLine);
347  for (int i = 1; i < nDiv; ++i)
348  {
349  double percent = (static_cast<double>(i)) / nDiv;
350  interp->InterpCs(saXsect, next, percent, cs);
351  double len = saMaxLen + percent * (maxLen - saMaxLen);
353  vCs->push_back(cs);
354  double angle = m_angleCenterLine + (i * angleIncrement * angleFactor);
355  vAngles->push_back(angle);
356  }
357 } // XmSlopedAbutmentUtilImpl::InterpolateCrossSections
358 //------------------------------------------------------------------------------
361 //------------------------------------------------------------------------------
363 {
364  stXs3dPts* xs3dPtr(&m_3dpts->m_first_endcap);
365  if (!m_first)
366  xs3dPtr = &m_3dpts->m_last_endcap;
367  VecPt3d2d* vPtr(&xs3dPtr->m_left);
368 
369  std::vector<XmStampCrossSection>* vCs(&m_interpLeft);
370  VecDbl* angles(&m_interpAnglesLeft);
371  // left shoulder location
372  Pt3d p0 = m_leftShoulder3d;
373 
374  if (a_side == SA_RIGHT)
375  {
376  vCs = &m_interpRight;
377  angles = &m_interpAnglesRight;
378  p0 = m_rightShoulder3d;
379  vPtr = &xs3dPtr->m_right;
380  }
381 
382  VecPt3d2d& out3dPts(*vPtr);
383  for (size_t i = 0; i < vCs->size(); ++i)
384  {
385  XmStampCrossSection& cs((*vCs)[i]);
386  double angleRad((*angles)[i] * XM_PI / 180.0);
387  if (!m_first)
388  angleRad += XM_PI;
389  double maxX(cs.m_leftMax);
390  VecPt3d* vPtr(&cs.m_left);
391  if (a_side == SA_RIGHT)
392  {
393  maxX = cs.m_rightMax;
394  vPtr = &cs.m_right;
395  }
396  VecPt3d& pts(*vPtr);
397  XmUtil::ConvertXsPointsTo3d(p0, pts, maxX, angleRad, out3dPts);
398  }
399 } // XmSlopedAbutmentUtilImpl::ConvertTo3d
400 //------------------------------------------------------------------------------
403 //------------------------------------------------------------------------------
405 {
408 } // XmSlopedAbutmentUtilImpl::EnsureCrossSectionAtMaxX
409 //------------------------------------------------------------------------------
415 //------------------------------------------------------------------------------
417  VecInt& a_firstEndCapEndPts,
418  VecInt& a_lastEndCapEndPts,
419  XmStamperIo& a_io)
420 {
421  if (a_io.m_lastEndCap.m_type == 1)
422  { // last end cap
423  {
424  VecInt2d& vLeft(a_ptIdx.m_last_end_cap.m_left);
425  auto it = vLeft.rbegin();
426  auto end = vLeft.rend();
427  for (; it != end; ++it)
428  {
429  if (!it->empty())
430  a_lastEndCapEndPts.push_back(it->back());
431  }
432  }
433  {
434  VecInt2d& vRight(a_ptIdx.m_last_end_cap.m_right);
435  auto it = vRight.begin();
436  auto end = vRight.end();
437  for (; it != end; ++it)
438  {
439  if (!it->empty())
440  a_lastEndCapEndPts.push_back(it->back());
441  }
442  }
443  }
444  if (a_io.m_firstEndCap.m_type == 1)
445  { // first end cap
446  {
447  VecInt2d& vRight(a_ptIdx.m_first_end_cap.m_right);
448  auto it = vRight.rbegin();
449  auto end = vRight.rend();
450  for (; it != end; ++it)
451  {
452  if (!it->empty())
453  a_firstEndCapEndPts.push_back(it->back());
454  }
455  }
456  {
457  VecInt2d& vLeft(a_ptIdx.m_first_end_cap.m_left);
458  auto it = vLeft.begin();
459  auto end = vLeft.end();
460  for (; it != end; ++it)
461  {
462  if (!it->empty())
463  a_firstEndCapEndPts.push_back(it->back());
464  }
465  }
466  }
467 } // XmSlopedAbutmentUtilImpl::GetEndCapEndPoints
468 //------------------------------------------------------------------------------
473 //------------------------------------------------------------------------------
475  cs3dPtIdx& a_ptIdx,
476  VecInt& a_blTypes)
477 {
478  VecInt2d& b(a_io.m_outBreakLines);
479  bool firstIsSlopedAbutment(a_io.m_firstEndCap.m_type == 1);
480  bool lastIsSlopedAbutment(a_io.m_lastEndCap.m_type == 1);
481  // get endcap end points
482  VecInt firstEndCapEndPts, lastEndCapEndPts;
483  GetEndCapEndPoints(a_ptIdx, firstEndCapEndPts, lastEndCapEndPts, a_io);
484  int ix;
485  if (firstIsSlopedAbutment)
486  {
487  ix = a_ptIdx.m_xsPts.m_right.front().back();
488  firstEndCapEndPts.insert(firstEndCapEndPts.begin(), ix);
489  ix = a_ptIdx.m_xsPts.m_left.front().back();
490  firstEndCapEndPts.push_back(ix);
491  b.push_back(firstEndCapEndPts);
492  a_blTypes.push_back(XmBreaklines::BL_END);
493  }
494  if (lastIsSlopedAbutment)
495  {
496  ix = a_ptIdx.m_xsPts.m_left.back().back();
497  lastEndCapEndPts.insert(lastEndCapEndPts.begin(), ix);
498  ix = a_ptIdx.m_xsPts.m_right.back().back();
499  lastEndCapEndPts.push_back(ix);
500  b.push_back(lastEndCapEndPts);
501  a_blTypes.push_back(XmBreaklines::BL_END);
502  }
503 
504  // get other endcap breaklines
505  auto myLambda = [](VecInt2d& v2d, int ix, VecInt2d& outbl, VecInt& type) {
506  for (size_t i = 0; i < v2d.size(); ++i)
507  {
508  VecInt& v(v2d[i]);
509  VecInt bl(1, ix);
510  bl.insert(bl.begin(), v.rbegin(), v.rend());
511  outbl.push_back(bl);
512  type.push_back(XmBreaklines::BL_XSECT);
513  }
514  };
515 
516  int leftShoulder, rightShoulder;
517  if (firstIsSlopedAbutment)
518  {
519  // get left shoulder index for first xsect
520  leftShoulder = a_io.m_cs.front().m_idxLeftShoulder;
521  ix = a_ptIdx.m_xsPts.m_left.front()[leftShoulder - 1];
522  myLambda(a_ptIdx.m_first_end_cap.m_left, ix, b, a_blTypes);
523  // get right shoulder index for first xsect
524  rightShoulder = a_io.m_cs.front().m_idxRightShoulder;
525  ix = a_ptIdx.m_xsPts.m_right.front()[rightShoulder - 1];
526  myLambda(a_ptIdx.m_first_end_cap.m_right, ix, b, a_blTypes);
527  }
528 
529  if (lastIsSlopedAbutment)
530  {
531  // left shoulder index for last cross section
532  leftShoulder = a_io.m_cs.back().m_idxLeftShoulder;
533  ix = a_ptIdx.m_xsPts.m_left.back()[leftShoulder - 1];
534  myLambda(a_ptIdx.m_last_end_cap.m_left, ix, b, a_blTypes);
535  // right shoulder index for last cross section
536  rightShoulder = a_io.m_cs.back().m_idxLeftShoulder;
537  ix = a_ptIdx.m_xsPts.m_right.back()[rightShoulder - 1];
538  myLambda(a_ptIdx.m_last_end_cap.m_right, ix, b, a_blTypes);
539  }
540 } // XmSlopedAbutmentUtilImpl::GetEndCapBreakLines
541 
542 //------------------------------------------------------------------------------
544 //------------------------------------------------------------------------------
545 XmSlopedAbutmentUtil::XmSlopedAbutmentUtil()
546 {
547 } // XmSlopedAbutmentUtil::XmSlopedAbutmentUtil
548 //------------------------------------------------------------------------------
550 //------------------------------------------------------------------------------
551 XmSlopedAbutmentUtil::~XmSlopedAbutmentUtil()
552 {
553 } // XmSlopedAbutmentUtil::~XmSlopedAbutmentUtil
554 //------------------------------------------------------------------------------
557 //------------------------------------------------------------------------------
558 BSHP<XmSlopedAbutmentUtil> XmSlopedAbutmentUtil::New()
559 {
560  BSHP<XmSlopedAbutmentUtil> p(new XmSlopedAbutmentUtilImpl());
561  return p;
562 } // StBathemetryIntersector::New
563 
564 } // namespace xms
virtual void GetEndCapBreakLines(XmStamperIo &a_io, cs3dPtIdx &a_ptIdx, VecInt &a_blTypes) override
breaklines from the end cap
Abutment definition for feature stamp end cap.
Definition: XmStamperIo.h:77
XmStamperIo * m_io
io class that has the stamping inputs
std::vector< int > VecInt
static BSHP< XmStampInterpCrossSection > New()
Creates a XmStampInterpCrossSection class.
void EnsureCrossSectionAtMaxX(XmStampCrossSection &a_xs)
Makes sure the cross section goes to the maxX value.
VecPt3d m_left
left side of the cross section
Definition: XmStamperIo.h:156
VecPt3d2d m_right
3d locations of cross section points
Pt3d m_leftShoulder3d
location of the left shoulder in 3d
int m_idxRightShoulder
index to the shoulder point in the m_right vector
Definition: XmStamperIo.h:162
bool Setup()
Sets up variables to perform the conversion.
XmStamper3dPts * m_3dpts
class that holds the 3d points from the stamp coversion
VecInt2d m_outBreakLines
break lines that are honored in the TIN
Definition: XmStamperIo.h:205
std::vector< double > VecDbl
Implementaion of stSlopedAbutment.
stXs3dPts m_last_endcap
3d locations of the last end cap
XmStamperEndCap m_firstEndCap
end cap at beginnig of polyline
Definition: XmStamperIo.h:195
csPtIdx m_last_end_cap
helper struct to store point indexes
double m_leftMax
max x value for left side
Definition: XmStamperIo.h:157
End cap definition for feature stamp.
Definition: XmStamperIo.h:120
static BSHP< XmSlopedAbutmentUtil > New()
Creates a XmSlopedAbutmentUtil class.
void EndCapCrossSectionShouldersTo2dCrossSection()
Makes 2d cross sections from the end cap cross section but only includes the points from the shoulder...
static void EnsureVectorAtMaxX(VecPt3d &a_pts, double a_maxX)
Makes sure the cross section goes to the maxX value.
Definition: XmUtil.cpp:94
Pt3d m_rightShoulder3d
location of the right shoulder in 3d
class to hold 3d points for a cross section
double m_maxX
max distance from center line
Definition: XmStamperIo.h:86
std::vector< VecInt > VecInt2d
XmStamperEndCap m_lastEndCap
end cap at end of polyline
Definition: XmStamperIo.h:197
bool SlopedAbutmentTo2dCrossSection()
Sets up variables to perform the conversion.
virtual void GetEndCapEndPoints(cs3dPtIdx &a_ptIdx, VecInt &a_firstEndCapEndPts, VecInt &a_lastEndCapEndPts, XmStamperIo &a_io) override
creates a breakline representing the outer polygon of the stamp
Pt3d m_pt1
the first of 2 points defining the direction of the center line at this end cap
XmStampCrossSection m_saXsect
a 2d cross section built from the sloped abutment info
helper struct to store point indexes
VecDbl m_interpAnglesRight
angles for the interpolated left cross sections
#define XM_ENSURE_TRUE(...)
void gmComponentMagnitudes(double *a_x, double *a_y, double *a_mag, double *a_dir, bool a_tomagdir)
XmSlopedAbutment m_sa
copy of the sloped abutment
std::vector< XmStampCrossSection > m_interpRight
interpolated cross sections for the right side transition
stXs3dPts m_first_endcap
3d locations of first end cap
double m_rightMax
max x value for right side
Definition: XmStamperIo.h:161
class to hold 3d points generated by the stamping operation
VecPt3d m_right
right side of the cross section
Definition: XmStamperIo.h:160
int m_type
type of end cap: 0- guidebank, 1- sloped abutment, 2- wing wall
Definition: XmStamperIo.h:129
void ConvertTo3d(int a_side)
Converts interpolated cross sections to 3d.
Stamping inputs/outputs class.
Definition: XmStamperIo.h:171
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
csPtIdx m_xsPts
helper struct to store point indexes
std::vector< VecPt3d > VecPt3d2d
Pt3d gmCreateVector(const Pt3d &a_p1, const Pt3d &a_p2)
#define XM_PI
Converts sloped abutment to 3d points.
csPtIdx m_first_end_cap
helper struct to store point indexes
void ComputeTransitionAngles()
Sets up variables to perform the conversion.
Cross section definition for stamping.
Definition: XmStamperIo.h:142
std::vector< XmStampCrossSection > m_cs
cross sections along the polyLine
Definition: XmStamperIo.h:193
bool m_first
flag indicating if this is from the first end of the stamp
VecPt3d2d m_left
3d locations of cross section points
double m_angle
degrees from -45 to 45
Definition: XmStamperIo.h:130
stXs3dPts m_xsPts
3d locations of cross section points
VecPt3d m_slope
x,y pairs defining slope from center line
Definition: XmStamperIo.h:87
XmStamperEndCap m_cap
copy of the end cap
void InterpolateCrossSections(int a_side)
Interpolates cross sections to define the transition between the sloped abutment and the end cap cros...
Pt3d m_pt2
the second of 2 points defining the direction of the center line at this end cap
double m_angleCenterLine
the direction of the center line at the end cap;
VecInt2d m_right
indexes of cross section points
VecInt2d m_left
indexes of cross section points
virtual void DoConvertTo3d(bool a_first, XmStamperIo &a_io, XmStamper3dPts &a_3dpts) override
Converts an end cap to 3d pts defining the geometry.
XmSlopedAbutment m_slopedAbutment
sloped abutment definition
Definition: XmStamperIo.h:132
std::vector< XmStampCrossSection > m_interpLeft
interpolated cross sections for the left side transition
std::vector< Pt3d > VecPt3d
static void ScaleCrossSectionXvals(XmStampCrossSection &a_xs, double a_factor)
Converts interpolated cross sections to 3d.
Definition: XmUtil.cpp:80
VecPt3d m_centerLine
Definition: XmStamperIo.h:189