xmsstamper  1.0
XmGuideBankUtil.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 <cmath>
17 
18 // 4. External library headers
19 
20 // 5. Shared code headers
21 #include <xmscore/misc/XmError.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 
60  void GuideBankCenterLine();
62  void CrossSectionTo3dPts();
63  void GuideBankEndCap();
64  void BreakLinesAddCenterLine(XmStamperIo& a_io, cs3dPtIdx& a_ptIdx, VecInt& a_blTypes);
65  void BreakLinesAddEndPoints(XmStamperIo& a_io, cs3dPtIdx& a_ptIdx, VecInt& a_blTypes);
66  void BreakLinesAddCrossSections(XmStamperIo& a_io, cs3dPtIdx& a_ptIdx, VecInt& a_blTypes);
67  void BreakLinesAddEndCap(XmStamperIo& a_io, cs3dPtIdx& a_ptIdx, VecInt& a_blTypes);
68  void BreakLinesAddShoulders(XmStamperIo& a_io, cs3dPtIdx& a_ptIdx, VecInt& a_blTypes);
69 
70  bool m_first;
73 
76 };
77 
82 //------------------------------------------------------------------------------
84 //------------------------------------------------------------------------------
85 XmGuideBankUtilImpl::XmGuideBankUtilImpl()
86 : m_first(true)
87 , m_io(nullptr)
88 , m_3dpts(nullptr)
89 {
90 } // XmGuideBankUtilImpl::XmGuideBankUtilImpl
91 //------------------------------------------------------------------------------
93 //------------------------------------------------------------------------------
94 XmGuideBankUtilImpl::~XmGuideBankUtilImpl()
95 {
96 } // XmGuideBankUtilImpl::~XmGuideBankUtilImpl
97 //------------------------------------------------------------------------------
103 //------------------------------------------------------------------------------
105 {
106  m_first = a_first;
107  m_io = &a_io;
108  m_3dpts = &a_3dpts;
109  XM_ENSURE_TRUE(m_io->m_centerLine.size() > 1);
110 
114  GuideBankEndCap();
115 
116  // FillOutputs();
117 } // XmGuideBankUtilImpl::DoConvert
118 //------------------------------------------------------------------------------
120 //------------------------------------------------------------------------------
122 {
123  // get the 2 points from the stamp centerline so we can get the angle of the
124  // guidebank centerline
125  Pt3d p0, p1;
126  XmStamperEndCap cap;
127  double angleFactor(1);
128  if (m_first)
129  {
130  p0 = m_io->m_centerLine[0];
131  p1 = m_io->m_centerLine[1];
132  cap = m_io->m_firstEndCap;
133  if (cap.m_guidebank.m_side == 0)
134  angleFactor = -1.0; // LEFT SIDE
135  }
136  else
137  {
138  p0 = m_io->m_centerLine.back();
139  size_t ix = m_io->m_centerLine.size() - 2;
140  p1 = m_io->m_centerLine[ix];
141  cap = m_io->m_lastEndCap;
142  if (cap.m_guidebank.m_side == 1)
143  angleFactor = -1.0; // RIGHT SIDE
144  }
145  double relMajorAngle = (90.0 + cap.m_angle) * angleFactor;
146  double relMinorAngle = 90.0 * angleFactor;
147 
148  Pt3d vec = gmCreateVector(p1, p0);
149  double mag(0), centerLineAngle(0);
150  gmComponentMagnitudes(&vec.x, &vec.y, &mag, &centerLineAngle, true);
151 
152  // get the angle for the major axis of the guidebank
153  double majorAngle = centerLineAngle + relMajorAngle;
154  majorAngle = gmConvertAngleToBetween0And360(majorAngle);
155  // get the angle for the minor axis of the guidebank
156  double minorAngle = majorAngle + relMinorAngle;
157  minorAngle = gmConvertAngleToBetween0And360(minorAngle);
158 
159  // calculate the locations of the centerline points
160 
161  // calculate dx and dy based on the minor axis
162  XmGuidebank& gb(cap.m_guidebank);
163  double dy(0), dx = gb.m_radius2 / (double)(gb.m_nPts - 1);
164  double dx1, dy1;
165  gmComponentMagnitudes(&dx1, &dy1, &dx, &minorAngle, false);
166  double prevdx2(0), prevdy2(0.0);
167  VecPt3d pts(gb.m_nPts, p0);
168  for (int iPt = 1; iPt < gb.m_nPts; ++iPt)
169  {
170  // calculate the dx and dy based on the major axis
171  dy = gb.m_radius1 * sqrt(1.0 - pow(gb.m_radius2 - dx * iPt, 2.0) / pow(gb.m_radius2, 2.0));
172  double dx2(0), dy2(0);
173  gmComponentMagnitudes(&dx2, &dy2, &dy, &majorAngle, false);
174 
175  pts[iPt].x = pts[iPt - 1].x + dx1 + (dx2 - prevdx2);
176  pts[iPt].y = pts[iPt - 1].y + dy1 + (dy2 - prevdy2);
177  prevdx2 = dx2;
178  prevdy2 = dy2;
179  }
180 
181  m_centerline = pts;
182  pts.erase(pts.begin());
183  if (m_first)
185  else
187 
188 } // XmGuideBankUtilImpl::GuideBankCenterLine
189 //------------------------------------------------------------------------------
191 //------------------------------------------------------------------------------
193 {
194  XmStamperEndCap cap;
196  if (m_first)
197  {
198  cap = m_io->m_firstEndCap;
199  cs = m_io->m_cs[0];
200  // we need to swap the sides of the cross section
201  XmStampCrossSection c1 = cs;
204  cs.m_left = c1.m_right;
205  cs.m_right = c1.m_left;
206  cs.m_leftMax = c1.m_rightMax;
207  cs.m_rightMax = c1.m_leftMax;
208  }
209  else
210  {
211  cap = m_io->m_lastEndCap;
212  cs = m_io->m_cs.back();
213  }
214  XmGuidebank& gb(cap.m_guidebank);
215  // adjust the cross section for guide bank width
216  double halfWidth = gb.m_width / 2;
217 
218  auto myLambda = [](double halfWidth, int idx, VecPt3d& v, double& maxX) {
219  if (idx < (int)v.size())
220  {
221  double oldHalfWidth = v[idx].x;
222  double factor = halfWidth / oldHalfWidth;
223  for (int i = 0; i < idx; ++i)
224  {
225  v[i].x *= factor;
226  }
227  factor = oldHalfWidth - halfWidth;
228  for (int i = idx; i < (int)v.size(); ++i)
229  {
230  v[i].x -= factor;
231  }
232  maxX -= factor;
234  }
235  };
236 
237  // adjust left
238  myLambda(halfWidth, cs.m_idxLeftShoulder, cs.m_left, cs.m_leftMax);
239  // adjust right
240  myLambda(halfWidth, cs.m_idxRightShoulder, cs.m_right, cs.m_rightMax);
241  m_cs = cs;
242 } // XmGuideBankUtilImpl::AdjustEndCapCrossSection
243 //------------------------------------------------------------------------------
245 //------------------------------------------------------------------------------
247 {
250  if (!m_first)
251  {
252  left = &m_3dpts->m_last_endcap.m_left;
253  right = &m_3dpts->m_last_endcap.m_right;
254  }
255  for (size_t i = 1; i < m_centerline.size(); ++i)
256  {
257  Pt3d& p(m_centerline[i]);
258  double leftAngle, rightAngle;
259  XmUtil::GetAnglesFromCenterLine(i, m_centerline, leftAngle, rightAngle);
260  XmUtil::ConvertXsPointsTo3d(p, cs.m_left, cs.m_leftMax, leftAngle, *left);
261  XmUtil::ConvertXsPointsTo3d(p, cs.m_right, cs.m_rightMax, rightAngle, *right);
262  }
263 } // XmGuideBankUtilImpl::CrossSectionTo3dPts
264 //------------------------------------------------------------------------------
266 //------------------------------------------------------------------------------
268 {
269  XM_ENSURE_TRUE(m_centerline.size() > 1);
270  // average the left and right side to make the cross section that extends
271  // out along the center line of the guidebank
272  XmStampCrossSection leftCs(m_cs), rightCs(m_cs);
273  double leftLen = leftCs.m_leftMax;
274  double rightLen = rightCs.m_rightMax;
275  leftCs.m_idxRightShoulder = leftCs.m_idxLeftShoulder;
276  leftCs.m_right = leftCs.m_left;
277  leftCs.m_rightMax = leftCs.m_leftMax;
278  rightCs.m_idxLeftShoulder = rightCs.m_idxRightShoulder;
279  rightCs.m_left = rightCs.m_right;
280  rightCs.m_leftMax = rightCs.m_rightMax;
281  XmUtil::ScaleCrossSectionXvals(leftCs, 1 / leftCs.m_leftMax);
282  XmUtil::ScaleCrossSectionXvals(rightCs, 1 / rightCs.m_rightMax);
283 
284  double factor(1);
285  // get vector for end of center line
286  size_t ix = m_centerline.size() - 2;
287  Pt3d p0(m_centerline.back()), p1(m_centerline[ix]);
288  Pt3d vec = gmCreateVector(p0, p1);
289  double mag(0), clAngle(0);
290  gmComponentMagnitudes(&vec.x, &vec.y, &mag, &clAngle, true);
291  double startAngle = clAngle + (90.0 * factor);
292  ;
293  startAngle = gmConvertAngleToBetween0And360(startAngle);
294 
295  auto myLambda = [](VecPt3d& pts, VecPt3d& v, double angle, Pt3d& p0, double factor) {
296  pts.assign(v.size() - 1, p0);
297  for (size_t i = 1; i < v.size(); ++i)
298  {
299  Pt3d d;
300  gmComponentMagnitudes(&d.x, &d.y, &v[i].x, &angle, false);
301  pts[i - 1].x = p0.x - (d.x * factor);
302  pts[i - 1].y = p0.y - (d.y * factor);
303  pts[i - 1].z = v[i].y;
304  }
305  };
306 
307  // interpolate cross sections
308  BSHP<XmStampInterpCrossSection> interp = XmStampInterpCrossSection::New();
309  VecDbl vLen(11);
310  std::vector<XmStampCrossSection> vCs(11);
311  double incr = 1.0 / 12.0, percent(0);
312  double angle = startAngle;
313  // add to the left
314  VecPt3d2d* leftpts3d(&m_3dpts->m_first_endcap.m_left);
315  if (!m_first)
316  leftpts3d = &m_3dpts->m_last_endcap.m_left;
317  // interp the lengths and cross sections
318  for (int i = 0; i < 11; ++i)
319  {
320  percent += incr;
321  angle -= 15.0;
322  angle = gmConvertAngleToBetween0And360(angle);
323 
324  vLen[i] = leftLen + percent * (leftLen - rightLen);
325  interp->InterpCs(leftCs, rightCs, percent, vCs[i]);
326  XmUtil::ScaleCrossSectionXvals(vCs[i], vLen[i]);
327 
328  VecPt3d pts;
329  myLambda(pts, vCs[i].m_left, angle, p0, factor);
330  leftpts3d->push_back(pts);
331  }
332 } // XmGuideBankUtilImpl::GuideBankEndCap
333 //------------------------------------------------------------------------------
339 //------------------------------------------------------------------------------
341  VecInt& a_firstEndCapEndPts,
342  VecInt& a_lastEndCapEndPts,
343  XmStamperIo& a_io)
344 {
345  // utility functions
346  auto myLambda_AddEndPtsForward = [](VecInt& a_endPts, VecInt2d& a_pts2d) {
347  auto it = a_pts2d.begin();
348  auto end = a_pts2d.end();
349  for (; it != end; ++it)
350  {
351  if (!it->empty())
352  a_endPts.push_back(it->back());
353  }
354  };
355  auto myLambda_AddEndPtsReverse = [](VecInt& a_endPts, VecInt2d& a_pts2d) {
356  auto it = a_pts2d.rbegin();
357  auto end = a_pts2d.rend();
358  for (; it != end; ++it)
359  {
360  if (!it->empty())
361  a_endPts.push_back(it->back());
362  }
363  };
364  auto myLambda_AddEndPtsLastXs = [](VecInt& a_endPts, int a_clPtIdx, VecInt2d& a_pts2dReverse,
365  VecInt2d& a_pts2dForward) {
366  { // reverse add pts from cross section at end of guidebank that intersected bathymetry
367  // skip the first point because it was already added
368  VecInt& pts(a_pts2dReverse.back());
369  auto it = pts.rbegin();
370  it++;
371  auto end = pts.rend();
372  a_endPts.insert(a_endPts.end(), it, end);
373  }
374  a_endPts.push_back(a_clPtIdx);
375  { // forward add pts from cross section at end of guidebank that intersected bathymetry
376  // skip the last point because it will be added later
377  VecInt& pts(a_pts2dForward.back());
378  auto it = pts.begin();
379  auto end = pts.end();
380  end--;
381  a_endPts.insert(a_endPts.end(), it, end);
382  }
383  };
384 
385  if (a_io.m_lastEndCap.m_type == 0)
386  { // last end cap
387  VecInt& cl(a_ptIdx.m_last_end_cap.m_centerLine);
388  myLambda_AddEndPtsForward(a_lastEndCapEndPts, a_ptIdx.m_last_end_cap.m_left);
389  // if the guidebank was cut off because of an intersection then we need to
390  // use the last cross section also
391  if (!cl.empty() && cl.size() == a_ptIdx.m_last_end_cap.m_left.size())
392  {
393  myLambda_AddEndPtsLastXs(a_lastEndCapEndPts, cl.back(), a_ptIdx.m_last_end_cap.m_left,
394  a_ptIdx.m_last_end_cap.m_right);
395  }
396  myLambda_AddEndPtsReverse(a_lastEndCapEndPts, a_ptIdx.m_last_end_cap.m_right);
397  }
398  if (a_io.m_firstEndCap.m_type == 0)
399  { // first end cap
400  VecInt& cl(a_ptIdx.m_first_end_cap.m_centerLine);
401  myLambda_AddEndPtsForward(a_firstEndCapEndPts, a_ptIdx.m_first_end_cap.m_right);
402  // if the guidebank was cut off because of an intersection then we need to
403  // use the last cross section also
404  if (!cl.empty() && cl.size() == a_ptIdx.m_last_end_cap.m_left.size())
405  {
406  myLambda_AddEndPtsLastXs(a_lastEndCapEndPts, cl.back(), a_ptIdx.m_last_end_cap.m_right,
407  a_ptIdx.m_last_end_cap.m_left);
408  }
409  myLambda_AddEndPtsReverse(a_firstEndCapEndPts, a_ptIdx.m_first_end_cap.m_left);
410  }
411 } // XmGuideBankUtilImpl::GuideBankEndCapEndPoints
412 //------------------------------------------------------------------------------
417 //------------------------------------------------------------------------------
419  cs3dPtIdx& a_ptIdx,
420  VecInt& a_blTypes)
421 {
422  BreakLinesAddCenterLine(a_io, a_ptIdx, a_blTypes);
423  BreakLinesAddEndPoints(a_io, a_ptIdx, a_blTypes);
424  BreakLinesAddCrossSections(a_io, a_ptIdx, a_blTypes);
425  BreakLinesAddEndCap(a_io, a_ptIdx, a_blTypes);
426  BreakLinesAddShoulders(a_io, a_ptIdx, a_blTypes);
427 } // XmGuideBankUtilImpl::GetEndCapBreakLines
428 //------------------------------------------------------------------------------
433 //------------------------------------------------------------------------------
435  cs3dPtIdx& a_ptIdx,
436  VecInt& a_blTypes)
437 {
438  VecInt2d& b(a_io.m_outBreakLines);
439  VecInt bl;
440  bool firstIsGuideBank(a_io.m_firstEndCap.m_type == 0);
441  bool lastIsGuideBank(a_io.m_lastEndCap.m_type == 0);
442  if (firstIsGuideBank)
443  {
444  if (!a_ptIdx.m_first_end_cap.m_centerLine.empty())
445  {
446  bl.resize(0);
447  bl.push_back(a_ptIdx.m_centerLine[0]);
448  auto beg = a_ptIdx.m_first_end_cap.m_centerLine.begin();
449  auto end = a_ptIdx.m_first_end_cap.m_centerLine.end();
450  bl.insert(bl.end(), beg, end);
451  b.push_back(bl);
452  a_blTypes.push_back(XmBreaklines::BL_CENTERLINE);
453  }
454  }
455  if (lastIsGuideBank)
456  {
457  if (!a_ptIdx.m_last_end_cap.m_centerLine.empty())
458  {
459  bl.resize(0);
460  bl.push_back(a_ptIdx.m_centerLine.back());
461  auto beg = a_ptIdx.m_last_end_cap.m_centerLine.begin();
462  auto end = a_ptIdx.m_last_end_cap.m_centerLine.end();
463  bl.insert(bl.end(), beg, end);
464  b.push_back(bl);
465  a_blTypes.push_back(XmBreaklines::BL_CENTERLINE);
466  }
467  }
468 } // XmGuideBankUtilImpl::BreakLinesAddCenterLine
469 //------------------------------------------------------------------------------
474 //------------------------------------------------------------------------------
476  cs3dPtIdx& a_ptIdx,
477  VecInt& a_blTypes)
478 {
479  VecInt2d& b(a_io.m_outBreakLines);
480  bool firstIsGuideBank(a_io.m_firstEndCap.m_type == 0);
481  bool lastIsGuideBank(a_io.m_lastEndCap.m_type == 0);
482  VecInt bl, firstEndCapEndPts, lastEndCapEndPts;
483  GetEndCapEndPoints(a_ptIdx, firstEndCapEndPts, lastEndCapEndPts, a_io);
484 
485  {
486  VecInt& cl(a_ptIdx.m_first_end_cap.m_centerLine);
487  VecInt2d& vl(a_ptIdx.m_first_end_cap.m_left);
488  if (firstIsGuideBank && !cl.empty())
489  { // breaklines for the end points
490  bl.resize(0);
491  bl.push_back(a_ptIdx.m_xsPts.m_left.front().back());
492  auto beg = firstEndCapEndPts.begin();
493  auto end = beg + (a_ptIdx.m_first_end_cap.m_centerLine.size() - 1);
494  bl.insert(bl.end(), beg, end);
495  b.push_back(bl);
496  a_blTypes.push_back(XmBreaklines::BL_END);
497 
498  if (vl.size() > cl.size())
499  {
500  bl.resize(0);
501  beg = end - 1;
502  end = beg + 14;
503  bl.insert(bl.end(), beg, end);
504  b.push_back(bl);
505  a_blTypes.push_back(XmBreaklines::BL_END);
506  }
507 
508  bl.resize(0);
509  beg = end - 1;
510  end = firstEndCapEndPts.end();
511  bl.insert(bl.end(), beg, end);
512  bl.push_back(a_ptIdx.m_xsPts.m_right.front().back());
513  b.push_back(bl);
514  a_blTypes.push_back(XmBreaklines::BL_END);
515  }
516  }
517  {
518  VecInt& cl(a_ptIdx.m_last_end_cap.m_centerLine);
519  VecInt2d& vl(a_ptIdx.m_last_end_cap.m_left);
520  if (lastIsGuideBank && !cl.empty())
521  { // breaklines for the end points
522  bl.resize(0);
523  bl.push_back(a_ptIdx.m_xsPts.m_left.back().back());
524  auto beg = lastEndCapEndPts.begin();
525  auto end = beg + (a_ptIdx.m_last_end_cap.m_centerLine.size());
526  bl.insert(bl.end(), beg, end);
527  b.push_back(bl);
528  a_blTypes.push_back(XmBreaklines::BL_END);
529 
530  if (vl.size() > cl.size())
531  {
532  bl.resize(0);
533  beg = end - 1;
534  end = beg + 13;
535  bl.insert(bl.end(), beg, end);
536  b.push_back(bl);
537  a_blTypes.push_back(XmBreaklines::BL_END);
538  }
539 
540  bl.resize(0);
541  end = lastEndCapEndPts.end();
542  beg = end - (a_ptIdx.m_last_end_cap.m_centerLine.size());
543  bl.insert(bl.end(), beg, end);
544  bl.push_back(a_ptIdx.m_xsPts.m_right.back().back());
545  b.push_back(bl);
546  a_blTypes.push_back(XmBreaklines::BL_END);
547  }
548  }
549 } // XmGuideBankUtilImpl::BreakLinesAddEndPoints
550 //------------------------------------------------------------------------------
555 //------------------------------------------------------------------------------
557  cs3dPtIdx& a_ptIdx,
558  VecInt& a_blTypes)
559 {
560  VecInt2d& b(a_io.m_outBreakLines);
561  bool firstIsGuideBank(a_io.m_firstEndCap.m_type == 0);
562  bool lastIsGuideBank(a_io.m_lastEndCap.m_type == 0);
563  VecInt bl;
564  if (firstIsGuideBank)
565  { // breaklines for cross sections
566  VecInt& v(a_ptIdx.m_first_end_cap.m_centerLine);
567  for (size_t i = 0; i < v.size(); ++i)
568  {
569  bl.resize(0);
570  // reverse add the left side
571  {
572  auto beg = a_ptIdx.m_first_end_cap.m_left[i].rbegin();
573  auto end = a_ptIdx.m_first_end_cap.m_left[i].rend();
574  bl.insert(bl.end(), beg, end);
575  }
576  // add centerline
577  bl.push_back(v[i]);
578  // add right side
579  {
580  auto beg = a_ptIdx.m_first_end_cap.m_right[i].begin();
581  auto end = a_ptIdx.m_first_end_cap.m_right[i].end();
582  bl.insert(bl.end(), beg, end);
583  }
584  b.push_back(bl);
585  a_blTypes.push_back(XmBreaklines::BL_XSECT);
586  }
587  }
588  if (lastIsGuideBank)
589  { // breaklines for cross sections
590  VecInt& v(a_ptIdx.m_last_end_cap.m_centerLine);
591  for (size_t i = 0; i < v.size(); ++i)
592  {
593  bl.resize(0);
594  // reverse add the left side
595  {
596  auto beg = a_ptIdx.m_last_end_cap.m_left[i].rbegin();
597  auto end = a_ptIdx.m_last_end_cap.m_left[i].rend();
598  bl.insert(bl.end(), beg, end);
599  }
600  // add centerline
601  bl.push_back(v[i]);
602  // add right side
603  {
604  auto beg = a_ptIdx.m_last_end_cap.m_right[i].begin();
605  auto end = a_ptIdx.m_last_end_cap.m_right[i].end();
606  bl.insert(bl.end(), beg, end);
607  }
608  b.push_back(bl);
609  a_blTypes.push_back(XmBreaklines::BL_XSECT);
610  }
611  }
612 } // XmGuideBankUtilImpl::BreakLinesAddCrossSections
613 //------------------------------------------------------------------------------
618 //------------------------------------------------------------------------------
620  cs3dPtIdx& a_ptIdx,
621  VecInt& a_blTypes)
622 {
623  VecInt2d& b(a_io.m_outBreakLines);
624  bool firstIsGuideBank(a_io.m_firstEndCap.m_type == 0);
625  bool lastIsGuideBank(a_io.m_lastEndCap.m_type == 0);
626  VecInt bl;
627  if (firstIsGuideBank)
628  {
629  VecInt& v(a_ptIdx.m_first_end_cap.m_centerLine);
630  VecInt2d& v1(a_ptIdx.m_first_end_cap.m_left);
631  if (v1.size() > v.size())
632  {
633  // breaklines for the end cap
634  for (size_t i = v.size(); i < v1.size(); ++i)
635  {
636  bl.resize(0);
637  bl.push_back(v.back());
638  auto beg = v1[i].begin();
639  auto end = v1[i].end();
640  bl.insert(bl.end(), beg, end);
641  b.push_back(bl);
642  a_blTypes.push_back(XmBreaklines::BL_XSECT);
643  }
644  }
645  }
646  if (lastIsGuideBank)
647  {
648  VecInt& v(a_ptIdx.m_last_end_cap.m_centerLine);
649  VecInt2d& v1(a_ptIdx.m_last_end_cap.m_left);
650  if (v1.size() > v.size())
651  {
652  // breaklines for the end cap
653  for (size_t i = v.size(); i < v1.size(); ++i)
654  {
655  bl.resize(0);
656  bl.push_back(v.back());
657  auto beg = v1[i].begin();
658  auto end = v1[i].end();
659  bl.insert(bl.end(), beg, end);
660  b.push_back(bl);
661  a_blTypes.push_back(XmBreaklines::BL_XSECT);
662  }
663  }
664  }
665 } // XmGuideBankUtilImpl::BreakLinesAddEndCap
666 //------------------------------------------------------------------------------
671 //------------------------------------------------------------------------------
673  cs3dPtIdx& a_ptIdx,
674  VecInt& a_blTypes)
675 {
676  VecInt2d& b(a_io.m_outBreakLines);
677  bool firstIsGuideBank(a_io.m_firstEndCap.m_type == 0);
678  bool lastIsGuideBank(a_io.m_lastEndCap.m_type == 0);
679  VecInt bl;
680  if (firstIsGuideBank && !a_ptIdx.m_first_end_cap.m_centerLine.empty())
681  {
682  VecInt& v(a_ptIdx.m_first_end_cap.m_centerLine);
683  VecInt2d& v1(a_ptIdx.m_first_end_cap.m_left);
684  VecInt2d& vR(a_ptIdx.m_first_end_cap.m_right);
685 
686  // Left and right are backwards for the first guide bank
687  // breaklines for the shoulders
688  int rShoulder(a_io.m_cs.front().m_idxLeftShoulder - 1),
689  lShoulder(a_io.m_cs.front().m_idxRightShoulder - 1);
690  // left side
691  bl.resize(0);
692  bl.push_back(a_ptIdx.m_xsPts.m_right.front()[lShoulder]);
693  for (size_t i = 0; i < v.size(); ++i)
694  {
695  bl.push_back(v1[i][lShoulder]);
696  }
697  b.push_back(bl);
698  a_blTypes.push_back(XmBreaklines::BL_SHOULDER);
699  // end cap shoulder
700  if (v1.size() > v.size())
701  {
702  bl.resize(0);
703  for (size_t i = v.size() - 1; i < v1.size(); ++i)
704  {
705  bl.push_back(v1[i][lShoulder]);
706  }
707  bl.push_back(vR.back()[rShoulder]);
708  b.push_back(bl);
709  a_blTypes.push_back(XmBreaklines::BL_SHOULDER);
710  }
711  // right shoulder
712  bl.resize(0);
713  bl.push_back(a_ptIdx.m_xsPts.m_left.front()[rShoulder]);
714  for (size_t i = 0; i < vR.size(); ++i)
715  {
716  bl.push_back(vR[i][rShoulder]);
717  }
718  b.push_back(bl);
719  a_blTypes.push_back(XmBreaklines::BL_SHOULDER);
720  }
721  if (lastIsGuideBank && !a_ptIdx.m_last_end_cap.m_centerLine.empty())
722  {
723  VecInt& v(a_ptIdx.m_last_end_cap.m_centerLine);
724  VecInt2d& v1(a_ptIdx.m_last_end_cap.m_left);
725  VecInt2d& vR(a_ptIdx.m_last_end_cap.m_right);
726 
727  // breaklines for the shoulders
728  int lShoulder(a_io.m_cs.back().m_idxLeftShoulder - 1),
729  rShoulder(a_io.m_cs.back().m_idxRightShoulder - 1);
730  // left side
731  bl.resize(0);
732  bl.push_back(a_ptIdx.m_xsPts.m_left.back()[lShoulder]);
733  for (size_t i = 0; i < v.size(); ++i)
734  {
735  bl.push_back(v1[i][lShoulder]);
736  }
737  b.push_back(bl);
738  a_blTypes.push_back(XmBreaklines::BL_SHOULDER);
739  // end cap shoulder
740  if (v1.size() > v.size())
741  {
742  bl.resize(0);
743  for (size_t i = v.size() - 1; i < v1.size(); ++i)
744  {
745  bl.push_back(v1[i][lShoulder]);
746  }
747  bl.push_back(vR.back()[rShoulder]);
748  b.push_back(bl);
749  a_blTypes.push_back(XmBreaklines::BL_SHOULDER);
750  }
751  // right shoulder
752  bl.resize(0);
753  bl.push_back(a_ptIdx.m_xsPts.m_right.back()[rShoulder]);
754  for (size_t i = 0; i < vR.size(); ++i)
755  {
756  bl.push_back(vR[i][rShoulder]);
757  }
758  b.push_back(bl);
759  a_blTypes.push_back(XmBreaklines::BL_SHOULDER);
760  }
761 } // XmGuideBankUtilImpl::BreakLinesAddShoulders
762 
763 //------------------------------------------------------------------------------
765 //------------------------------------------------------------------------------
766 XmGuideBankUtil::XmGuideBankUtil()
767 {
768 } // XmGuideBankUtil::XmGuideBankUtil
769 //------------------------------------------------------------------------------
771 //------------------------------------------------------------------------------
772 XmGuideBankUtil::~XmGuideBankUtil()
773 {
774 } // XmGuideBankUtil::~XmGuideBankUtil
775 //------------------------------------------------------------------------------
778 //------------------------------------------------------------------------------
779 BSHP<XmGuideBankUtil> XmGuideBankUtil::New()
780 {
781  BSHP<XmGuideBankUtil> p(new XmGuideBankUtilImpl());
782  return p;
783 } // XmGuideBankUtil::New
784 
785 } // namespace xms
static BSHP< XmGuideBankUtil > New()
Creates a XmStampInterpCrossSection class.
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
virtual void GetEndCapBreakLines(XmStamperIo &a_io, cs3dPtIdx &a_ptIdx, VecInt &a_blTypes) override
breaklines from the end cap
std::vector< int > VecInt
static BSHP< XmStampInterpCrossSection > New()
Creates a XmStampInterpCrossSection class.
void BreakLinesAddCrossSections(XmStamperIo &a_io, cs3dPtIdx &a_ptIdx, VecInt &a_blTypes)
breaklines for cross sections
VecPt3d m_left
left side of the cross section
Definition: XmStamperIo.h:156
void GuideBankEndCap()
Makes the cross sections for the end cap of the guide bank.
VecPt3d2d m_right
3d locations of cross section points
void BreakLinesAddCenterLine(XmStamperIo &a_io, cs3dPtIdx &a_ptIdx, VecInt &a_blTypes)
breaklines from the center line
int m_idxRightShoulder
index to the shoulder point in the m_right vector
Definition: XmStamperIo.h:162
void BreakLinesAddShoulders(XmStamperIo &a_io, cs3dPtIdx &a_ptIdx, VecInt &a_blTypes)
breaklines for end cap
VecInt2d m_outBreakLines
break lines that are honored in the TIN
Definition: XmStamperIo.h:205
double m_radius2
second radius (R2) for guidebank creation
Definition: XmStamperIo.h:110
std::vector< double > VecDbl
XmStampCrossSection m_cs
cross section for the guidebank
VecInt m_centerLine
used by guidebank
Implementaion of XmGuideBankUtil.
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
VecPt3d m_centerline
centerline for the guidebank
double gmConvertAngleToBetween0And360(double a_angle, bool a_InDegrees)
void CrossSectionTo3dPts()
Creates a cross section to be used for the guide bank.
double m_leftMax
max x value for left side
Definition: XmStamperIo.h:157
void AdjustEndCapCrossSection()
Creates a cross section to be used for the guide bank.
End cap definition for feature stamp.
Definition: XmStamperIo.h:120
static void EnsureVectorAtMaxX(VecPt3d &a_pts, double a_maxX)
Makes sure the cross section goes to the maxX value.
Definition: XmUtil.cpp:94
VecPt3d m_centerLine
only used by guidebank
Converts sloped abutment to 3d points.
std::vector< VecInt > VecInt2d
XmStamperEndCap m_lastEndCap
end cap at end of polyline
Definition: XmStamperIo.h:197
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
helper struct to store point indexes
#define XM_ENSURE_TRUE(...)
int m_side
position of guidebank relative to center line, 0-left, 1-right
Definition: XmStamperIo.h:108
void GuideBankCenterLine()
Creates the centerline for the guidebank.
void BreakLinesAddEndPoints(XmStamperIo &a_io, cs3dPtIdx &a_ptIdx, VecInt &a_blTypes)
breaklines the outer edge of the stamp
void BreakLinesAddEndCap(XmStamperIo &a_io, cs3dPtIdx &a_ptIdx, VecInt &a_blTypes)
breaklines for end cap
XmGuidebank m_guidebank
guidebank definition
Definition: XmStamperIo.h:131
void gmComponentMagnitudes(double *a_x, double *a_y, double *a_mag, double *a_dir, bool a_tomagdir)
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
XmStamper3dPts * m_3dpts
class that holds the 3d points from the stamp coversion
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
virtual void DoConvertTo3d(bool a_first, XmStamperIo &a_io, XmStamper3dPts &a_3dpts) override
Converts an end cap to 3d pts defining the geometry.
Pt3d gmCreateVector(const Pt3d &a_p1, const Pt3d &a_p2)
csPtIdx m_first_end_cap
helper struct to store point indexes
int m_nPts
number of points created along the center line to create the guidebank
Definition: XmStamperIo.h:112
Cross section definition for stamping.
Definition: XmStamperIo.h:142
std::vector< XmStampCrossSection > m_cs
cross sections along the polyLine
Definition: XmStamperIo.h:193
VecPt3d2d m_left
3d locations of cross section points
double m_angle
degrees from -45 to 45
Definition: XmStamperIo.h:130
Guidebank definition for feature stamp end cap.
Definition: XmStamperIo.h:96
double m_width
width of guidebank about the center line
Definition: XmStamperIo.h:111
VecInt2d m_right
indexes of cross section points
VecInt2d m_left
indexes of cross section points
bool m_first
flag indicating if this is from the first end of the stamp
VecInt m_centerLine
indexes of cross section points
XmStamperIo * m_io
io class that has the stamping inputs
std::vector< Pt3d > VecPt3d
double m_radius1
first radius (R1) for guidebank creation
Definition: XmStamperIo.h:109
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