xmsmesh  1.0
MeMultiPolyTo2dm.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 <array>
17 #include <fstream>
18 #include <sstream>
19 #include <cmath>
20 
21 // 4. External library headers
22 #include <boost/format.hpp>
23 
24 // 5. Shared code headers
26 #include <xmscore/misc/XmConst.h>
27 #include <xmscore/misc/XmError.h>
28 #include <xmscore/misc/XmLog.h>
29 #include <xmscore/points/pt.h> // Pt3d
30 #include <xmscore/stl/vector.h>
34 #include <xmscore/misc/carray.h>
35 
36 // 6. Non-shared code headers
37 
38 //----- Forward declarations ---------------------------------------------------
39 
40 //----- External globals -------------------------------------------------------
41 
42 //----- Namespace declaration --------------------------------------------------
43 
44 namespace xms
45 {
46 //----- Constants / Enumerations -----------------------------------------------
47 
48 //----- Classes / Structs ------------------------------------------------------
50 {
51 public:
53 
54  bool Generate2dm(MeMultiPolyMesherIo& a_input,
55  const std::string& a_outFileName,
56  int a_precision = 15) override;
57  bool Generate2dm(MeMultiPolyMesherIo& a_input, std::ostream& a_os, int a_precision = 15) override;
58 
59  void Write2dm(MeMultiPolyMesherIo& a_input, std::ostream& a_os, int a_precision);
60 
63  bool m_sortCellsForTesting = true;
64 };
65 
66 //----- Internal functions -----------------------------------------------------
67 
68 //------------------------------------------------------------------------------
72 //------------------------------------------------------------------------------
74 {
75  VecInt& outCells(a_io.m_cells);
76 
77  // build array of sorted cells
78  std::vector<std::array<int, 6>> sortableCells;
79  for (size_t i = 0; i < outCells.size();)
80  {
81  std::array<int, 6> cell = {-1, -1, -1, -1, -1, -1};
82  cell[4] = outCells[i];
83  int nPts = cell[5] = outCells[i + 1];
84  int minIndex(outCells[i + 2]);
85  auto minItr = cell.begin();
86  for (int j = 0; j < nPts; ++j)
87  {
88  int idx = outCells[i + 2 + j];
89  cell[j] = idx;
90  if (idx < minIndex)
91  {
92  minIndex = idx;
93  minItr = cell.begin() + j;
94  }
95  }
96  i += (size_t)nPts + 2;
97 
98  // put minimum index point first
99  std::rotate(cell.begin(), minItr, cell.begin() + nPts);
100  sortableCells.push_back(cell);
101  }
102  int cnt(0);
103  std::sort(sortableCells.begin(), sortableCells.end());
104 
105  // place cells back in output
106  for (auto& c : sortableCells)
107  {
108  outCells[cnt++] = c[4];
109  outCells[cnt++] = c[5];
110  outCells[cnt++] = c[0];
111  outCells[cnt++] = c[1];
112  outCells[cnt++] = c[2];
113  if (c[3] != -1)
114  {
115  outCells[cnt++] = c[3];
116  }
117  }
118 } // iSortCellsForTesting
119 
120 //----- Class / Function definitions -------------------------------------------
124 //------------------------------------------------------------------------------
127 //------------------------------------------------------------------------------
128 BSHP<MeMultiPolyTo2dm> MeMultiPolyTo2dm::New()
129 {
130  BSHP<MeMultiPolyTo2dm> ret(new MeMultiPolyTo2dmImpl);
131  return ret;
132 } // MeMultiPolyTo2dm::New
133 
138 //------------------------------------------------------------------------------
144 //------------------------------------------------------------------------------
146  const std::string& a_outFileName,
147  int a_precision)
148 {
149  std::fstream os(a_outFileName.c_str(), std::fstream::out);
150  if (os.bad())
151  return false;
152  return Generate2dm(a_io, os, a_precision);
153 } // MeMultiPolyTo2dmImpl::Generate2dm
154 //------------------------------------------------------------------------------
160 //------------------------------------------------------------------------------
162  std::ostream& a_os,
163  int a_precision)
164 {
165  if (a_os.bad())
166  {
167  XM_LOG(xmlog::error, "Invalid output specified. Aborting");
168  return false;
169  }
170 
171  // Mesh the polygons
172  BSHP<MeMultiPolyMesher> mp = MeMultiPolyMesher::New();
173  if (!mp->MeshIt(a_io))
174  {
175  XM_LOG(xmlog::error, "Failed to generate mesh from polygons.");
176  return false;
177  }
178 
179  // write the 2dm
180  Write2dm(a_io, a_os, a_precision);
181  return true;
182 } // MeMultiPolyTo2dmImpl::Generate2dm
183 //------------------------------------------------------------------------------
189 //------------------------------------------------------------------------------
190 void MeMultiPolyTo2dmImpl::Write2dm(MeMultiPolyMesherIo& a_io, std::ostream& a_os, int a_precision)
191 {
192  XM_ENSURE_TRUE_NO_ASSERT(a_io.m_points.size() && a_io.m_cells.size());
193 
194  a_os << "MESH2D\n";
195  std::string tempStr("E3T"), format("%5d");
196  int ival = static_cast<int>(std::log10(a_io.m_points.size())) + 1;
197  if (ival > 5)
198  {
199  std::stringstream ss;
200  ss << "%" << ival << "d";
201  format = ss.str();
202  }
203 
205  {
206  iSortCellsForTesting(a_io);
207  }
208 
209  int id(0);
210  for (size_t i = 0; i < a_io.m_cells.size();)
211  {
212  ++id;
213  VecInt& cells(a_io.m_cells);
214  int celltype = cells[i + 0];
215  tempStr = "E3T";
216  if (celltype != 5) // 5 = VTK_TRIANGLE
217  tempStr = "E4Q";
218  a_os << tempStr;
219 
220  tempStr = (boost::format(format.c_str()) % id).str();
221  a_os << " " << tempStr;
222 
223  // order the points so that the one with the lowest number is first
224  int numPoints = cells[i + 1];
225  int* points = &cells[i + 2]; // points for cell start at i + 2
226  int lowPointNumber = points[0];
227  int lowPointIndex = 0;
228  for (int j = 1; j < numPoints; ++j)
229  {
230  if (points[j] < lowPointNumber)
231  {
232  lowPointNumber = points[j];
233  lowPointIndex = j;
234  }
235  }
236  for (int j = 0; j < numPoints; ++j)
237  {
238  int pointIndex = (j + lowPointIndex) % numPoints;
239  // add 1 to change from 0 based to 1 based point numbers.
240  tempStr = (boost::format(format.c_str()) % (points[pointIndex] + 1)).str();
241  a_os << " " << tempStr;
242  }
243  tempStr = (boost::format(format.c_str()) % 1).str();
244  a_os << " " << tempStr << "\n";
245 
246  i = i + 2 + numPoints;
247  }
248 
249  id = 0;
250  for (size_t i = 0; i < a_io.m_points.size(); ++i)
251  {
252  ++id;
253  tempStr = (boost::format(format.c_str()) % id).str();
254  Pt3d& p(a_io.m_points[i]);
255 
256  int test_precision = -1;
257 #ifdef TEST_PRECISION
258  test_precision = TEST_PRECISION;
259 #endif
260  a_os << "ND " << tempStr << " " << STRstd(p.x, test_precision, a_precision, STR_FULLWIDTH)
261  << " " << STRstd(p.y, test_precision, a_precision, STR_FULLWIDTH) << " "
262  << STRstd(p.z, test_precision, a_precision, STR_FULLWIDTH) << "\n";
263  }
264 } // MeMultiPolyTo2dmImpl::Write2dm
265 
266 } // namespace xms
267 
268 #if CXX_TEST
269 // UNIT TESTS
273 
276 
277 //----- Namespace declaration --------------------------------------------------
278 using namespace xms;
279 
280 namespace
281 {
282 //------------------------------------------------------------------------------
284 //------------------------------------------------------------------------------
285 static VecPt3d iArrayToVecPt3d(double* a_array, int a_size)
286 {
287  VecPt3d v(a_size / 2);
288  for (int i = 0; i < a_size; i += 2)
289  {
290  v[i / 2].x = a_array[i];
291  v[i / 2].y = a_array[i + 1];
292  }
293  return v;
294 } // iArrayToVecPt3d
295 //------------------------------------------------------------------------------
299 //------------------------------------------------------------------------------
300 static void iReadPolysAndCreate2dm(std::string a_filename, std::ostream& a_os, int a_precision)
301 {
302  std::string inPolyFile(a_filename);
304  std::vector<std::vector<std::vector<Pt3d>>> inside;
305  std::vector<std::vector<Pt3d>> outside;
307  tutReadMeshIoFromFile(inPolyFile, io);
308  p2g.Generate2dm(io, a_os, a_precision);
309 } // iReadPolysAndCreate2dm
310 //------------------------------------------------------------------------------
313 //------------------------------------------------------------------------------
314 static void iTestFromPolyFile(std::string a_fileBase, int a_precision)
315 {
316 #ifdef XMS_TEST_PATH
317  const std::string path(std::string(XMS_TEST_PATH) + "meshing/");
318 #else
319  // not using ttGetXmsngTestPath() because the XMSNG_TEST_PATH is not defined
320  // in xmscore.
321  const std::string path("test_files/meshing/");
322 #endif
323  std::string outFile;
324  std::string baseFile;
325  ttGetTestFilePaths(path, a_fileBase, ".2dm", baseFile, outFile);
326  {
327  std::fstream os;
328  os.open(outFile.c_str(), std::fstream::out);
329  iReadPolysAndCreate2dm(path + a_fileBase + ".txt", os, a_precision);
330  }
331  TS_ASSERT_TXT_FILES_EQUAL(baseFile, outFile);
332  // ugExportVtkUGridAndCompare(ug, path, a_fileBase);
333 } // iTestFromPolyFile
334 //------------------------------------------------------------------------------
337 // Two adjacent outer polygons each with two inner polygons
338 //
339 // 60- 0-----1-----2----3|0----1-----2-----3-----4
340 // | | | |
341 // 50- 17 0-----3 4|23--22 0-----3 5
342 // | | | inA1| | | | inB1| |
343 // 40- 16 1-----2 5|20--21 1-----2 6
344 // | | | |
345 // 30- 15 outA 6|19--18 outB 7
346 // | | | | |
347 // 20- 14 0-----3 7|16--17 0-----3 8
348 // | | | inA2| | | inB2| |
349 // 10- 13 1-----2 8|15--14 1-----2 9
350 // | | | | |
351 // 0- 12----11----10----9| 13----12----11----10
352 //
353 // |-----|-----|-----|-----|-----|-----|-----|
354 // 0 10 20 30 40 50 60 70
356 //------------------------------------------------------------------------------
357 static void iBuildTestCase4Polys(std::vector<VecPt3d>& a_outside,
358  std::vector<std::vector<VecPt3d>>& a_inside,
359  std::vector<double>& a_bias)
360 {
361  a_outside.clear();
362  a_inside.clear();
363  a_bias.clear();
364 
365  // Set up polygon A
366  {
367  double outAa[] = {0, 60, 10, 60, 20, 60, 30, 60, 30, 50, 30, 40, 30, 30, 30, 20, 30, 10,
368  30, 0, 20, 0, 10, 0, 0, 0, 0, 10, 0, 20, 0, 30, 0, 40, 0, 50};
369  double inA1a[] = {10, 50, 10, 40, 20, 40, 20, 50};
370  double inA2a[] = {10, 20, 10, 10, 20, 10, 20, 20};
371  a_outside.push_back(iArrayToVecPt3d(outAa, XM_COUNTOF(outAa)));
372  std::vector<VecPt3d> insides;
373  insides.push_back(iArrayToVecPt3d(inA1a, XM_COUNTOF(inA1a)));
374  insides.push_back(iArrayToVecPt3d(inA2a, XM_COUNTOF(inA2a)));
375  a_inside.push_back(insides);
376  a_bias.push_back(1.0);
377  }
378 
379  // Set up polygon B
380  {
381  double outBa[] = {30, 60, 40, 60, 50, 60, 60, 60, 70, 60, 70, 50, 70, 40, 70, 30,
382  70, 20, 70, 10, 70, 0, 60, 0, 50, 0, 40, 0, 40, 10, 30, 10,
383  30, 20, 40, 20, 40, 30, 30, 30, 30, 40, 40, 40, 40, 50, 30, 50};
384  double inB1a[] = {50, 50, 50, 40, 60, 40, 60, 50};
385  double inB2a[] = {50, 20, 50, 10, 60, 10, 60, 20};
386  a_outside.push_back(iArrayToVecPt3d(outBa, XM_COUNTOF(outBa)));
387  std::vector<VecPt3d> insides;
388  insides.push_back(iArrayToVecPt3d(inB1a, XM_COUNTOF(inB1a)));
389  insides.push_back(iArrayToVecPt3d(inB2a, XM_COUNTOF(inB2a)));
390  a_inside.push_back(insides);
391  a_bias.push_back(1.0);
392  }
393 } // iBuildTestCase4Polys
394 
395 } // namespace
396 
401 //------------------------------------------------------------------------------
403 //------------------------------------------------------------------------------
405 {
406  BSHP<MeMultiPolyTo2dm> m = MeMultiPolyTo2dm::New();
407  TS_ASSERT(m);
408 } // MeMultiPolyToUGridIntermediateTests::testCreateClass
409 //------------------------------------------------------------------------------
411 //------------------------------------------------------------------------------
413 {
414  // Create polygons
415  std::vector<VecPt3d> outside;
416  std::vector<std::vector<VecPt3d>> inside;
417  std::vector<double> bias;
418  iBuildTestCase4Polys(outside, inside, bias);
419  MePolyInput poly;
420  poly.m_bias = bias[0];
421  poly.m_outPoly = outside[0];
422  poly.m_insidePolys = inside[0];
424  io.m_polys.push_back(poly);
425  poly.m_bias = bias[1];
426  poly.m_outPoly = outside[1];
427  poly.m_insidePolys = inside[1];
428  io.m_polys.push_back(poly);
429 
430  // Mesh the polys
431  std::stringstream ss;
433  p2g.Generate2dm(io, ss);
434 
435  // Compare
436  std::string base =
437  "MESH2D\n"
438  "E3T 1 1 18 2 1\n"
439  "E3T 2 2 18 24 1\n"
440  "E3T 3 2 24 3 1\n"
441  "E3T 4 3 23 4 1\n"
442  "E3T 5 3 24 23 1\n"
443  "E3T 6 4 23 27 1\n"
444  "E3T 7 4 27 5 1\n"
445  "E3T 8 5 20 6 1\n"
446  "E3T 9 5 27 20 1\n"
447  "E3T 10 6 19 7 1\n"
448  "E3T 11 6 20 19 1\n"
449  "E3T 12 7 19 8 1\n"
450  "E3T 13 8 19 22 1\n"
451  "E3T 14 8 22 9 1\n"
452  "E3T 15 9 11 10 1\n"
453  "E3T 16 9 22 11 1\n"
454  "E3T 17 10 11 33 1\n"
455  "E3T 18 10 33 34 1\n"
456  "E3T 19 11 22 12 1\n"
457  "E3T 20 12 13 31 1\n"
458  "E3T 21 12 21 28 1\n"
459  "E3T 22 12 22 21 1\n"
460  "E3T 23 12 28 13 1\n"
461  "E3T 24 12 31 32 1\n"
462  "E3T 25 13 26 14 1\n"
463  "E3T 26 13 28 26 1\n"
464  "E3T 27 14 15 47 1\n"
465  "E3T 28 14 26 15 1\n"
466  "E3T 29 14 47 30 1\n"
467  "E3T 30 15 25 16 1\n"
468  "E3T 31 15 26 25 1\n"
469  "E3T 32 16 25 17 1\n"
470  "E3T 33 17 24 18 1\n"
471  "E3T 34 17 25 24 1\n"
472  "E3T 35 20 27 28 1\n"
473  "E3T 36 20 28 21 1\n"
474  "E3T 37 23 26 29 1\n"
475  "E3T 38 23 29 27 1\n"
476  "E3T 39 26 28 29 1\n"
477  "E3T 40 27 29 28 1\n"
478  "E3T 41 30 47 53 1\n"
479  "E3T 42 30 52 31 1\n"
480  "E3T 43 30 53 52 1\n"
481  "E3T 44 31 52 56 1\n"
482  "E3T 45 31 56 32 1\n"
483  "E3T 46 32 49 33 1\n"
484  "E3T 47 32 56 49 1\n"
485  "E3T 48 33 48 34 1\n"
486  "E3T 49 33 49 48 1\n"
487  "E3T 50 34 48 35 1\n"
488  "E3T 51 35 48 51 1\n"
489  "E3T 52 35 51 36 1\n"
490  "E3T 53 36 38 37 1\n"
491  "E3T 54 36 51 38 1\n"
492  "E3T 55 38 51 39 1\n"
493  "E3T 56 39 50 57 1\n"
494  "E3T 57 39 51 50 1\n"
495  "E3T 58 39 57 40 1\n"
496  "E3T 59 40 55 41 1\n"
497  "E3T 60 40 57 55 1\n"
498  "E3T 61 41 55 42 1\n"
499  "E3T 62 42 54 43 1\n"
500  "E3T 63 42 55 54 1\n"
501  "E3T 64 43 54 44 1\n"
502  "E3T 65 44 53 45 1\n"
503  "E3T 66 44 54 53 1\n"
504  "E3T 67 45 47 46 1\n"
505  "E3T 68 45 53 47 1\n"
506  "E3T 69 49 56 57 1\n"
507  "E3T 70 49 57 50 1\n"
508  "E3T 71 52 55 58 1\n"
509  "E3T 72 52 58 56 1\n"
510  "E3T 73 55 57 58 1\n"
511  "E3T 74 56 58 57 1\n"
512  "ND 1 0.0 0.0 0.0\n"
513  "ND 2 0.0 10.0 0.0\n"
514  "ND 3 0.0 20.0 0.0\n"
515  "ND 4 0.0 30.0 0.0\n"
516  "ND 5 0.0 40.0 0.0\n"
517  "ND 6 0.0 50.0 0.0\n"
518  "ND 7 0.0 60.0 0.0\n"
519  "ND 8 10.0 60.0 0.0\n"
520  "ND 9 20.0 60.0 0.0\n"
521  "ND 10 30.0 60.0 0.0\n"
522  "ND 11 30.0 50.0 0.0\n"
523  "ND 12 30.0 40.0 0.0\n"
524  "ND 13 30.0 30.0 0.0\n"
525  "ND 14 30.0 20.0 0.0\n"
526  "ND 15 30.0 10.0 0.0\n"
527  "ND 16 30.0 0.0 0.0\n"
528  "ND 17 20.0 0.0 0.0\n"
529  "ND 18 10.0 0.0 0.0\n"
530  "ND 19 10.0 50.0 0.0\n"
531  "ND 20 10.0 40.0 0.0\n"
532  "ND 21 20.0 40.0 0.0\n"
533  "ND 22 20.0 50.0 0.0\n"
534  "ND 23 10.0 20.0 0.0\n"
535  "ND 24 10.0 10.0 0.0\n"
536  "ND 25 20.0 10.0 0.0\n"
537  "ND 26 20.0 20.0 0.0\n"
538  "ND 27 8.5108202542291 31.757958032906 0.0\n"
539  "ND 28 19.918901892813 32.426918311488 0.0\n"
540  "ND 29 14.906323131347 26.659241919112 0.0\n"
541  "ND 30 40.0 20.0 0.0\n"
542  "ND 31 40.0 30.0 0.0\n"
543  "ND 32 40.0 40.0 0.0\n"
544  "ND 33 40.0 50.0 0.0\n"
545  "ND 34 40.0 60.0 0.0\n"
546  "ND 35 50.0 60.0 0.0\n"
547  "ND 36 60.0 60.0 0.0\n"
548  "ND 37 70.0 60.0 0.0\n"
549  "ND 38 70.0 50.0 0.0\n"
550  "ND 39 70.0 40.0 0.0\n"
551  "ND 40 70.0 30.0 0.0\n"
552  "ND 41 70.0 20.0 0.0\n"
553  "ND 42 70.0 10.0 0.0\n"
554  "ND 43 70.0 0.0 0.0\n"
555  "ND 44 60.0 0.0 0.0\n"
556  "ND 45 50.0 0.0 0.0\n"
557  "ND 46 40.0 0.0 0.0\n"
558  "ND 47 40.0 10.0 0.0\n"
559  "ND 48 50.0 50.0 0.0\n"
560  "ND 49 50.0 40.0 0.0\n"
561  "ND 50 60.0 40.0 0.0\n"
562  "ND 51 60.0 50.0 0.0\n"
563  "ND 52 50.0 20.0 0.0\n"
564  "ND 53 50.0 10.0 0.0\n"
565  "ND 54 60.0 10.0 0.0\n"
566  "ND 55 60.0 20.0 0.0\n"
567  "ND 56 48.371140004857 31.770815509095 0.0\n"
568  "ND 57 59.828479553661 32.416248616621 0.0\n"
569  "ND 58 54.803686217591 26.664267399073 0.0\n";
570  TS_ASSERT_EQUALS(base, ss.str());
571 } // MeMultiPolyTo2dmUnitTests::testCase4
576 //------------------------------------------------------------------------------
578 //------------------------------------------------------------------------------
580 {
581  iTestFromPolyFile("case2", 10);
582 } // MeMultiPolyTo2dmIntermediateTests::testCase2
583 //------------------------------------------------------------------------------
586 //------------------------------------------------------------------------------
588 {
589  iTestFromPolyFile("case100", 7);
590 } // MeMultiPolyTo2dmIntermediateTests::testCase100
591 //------------------------------------------------------------------------------
594 //------------------------------------------------------------------------------
596 {
597  iTestFromPolyFile("case101", 7);
598 } // MeMultiPolyTo2dmIntermediateTests::testCase101
599 //------------------------------------------------------------------------------
603 //------------------------------------------------------------------------------
605 {
606  iTestFromPolyFile("case102", 7);
607 } // MeMultiPolyTo2dmIntermediateTests::testCase102
608 //------------------------------------------------------------------------------
612 //------------------------------------------------------------------------------
614 {
615  iTestFromPolyFile("case103", 7);
616 } // MeMultiPolyTo2dmIntermediateTests::testCase103
617 //------------------------------------------------------------------------------
619 //------------------------------------------------------------------------------
621 {
622  iTestFromPolyFile("CasePaveGeo", 10);
623 } // MeMultiPolyTo2dmIntermediateTests::testCasePaveGeo
624 //------------------------------------------------------------------------------
626 //------------------------------------------------------------------------------
628 {
629  iTestFromPolyFile("CasePaveSanDiego", 10);
630 } // MeMultiPolyTo2dmIntermediateTests::testCasePaveSanDiego
631 //------------------------------------------------------------------------------
633 //------------------------------------------------------------------------------
635 {
636  iTestFromPolyFile("CasePaveSanDiegoSpringRelax", 10);
637 } // MeMultiPolyTo2dmIntermediateTests::testCasePaveSanDiego_SpringRelaxation
638 //------------------------------------------------------------------------------
641 //------------------------------------------------------------------------------
643 {
644 #ifdef XMS_TEST_PATH
645  const std::string path(std::string(XMS_TEST_PATH) + "meshing/");
646 #else
647  const std::string path("test_files/meshing/");
648 #endif
649  const std::string fname(path + "CasePatch6.txt");
650  std::string fbase("CasePatch6");
651  std::vector<std::vector<std::vector<Pt3d>>> inside;
652  std::vector<std::vector<Pt3d>> outside;
653  tutReadPolygons(fname, outside, inside);
654  MeMultiPolyMesherIo input;
655  VecInt corner;
656  input.m_polys.push_back(MePolyInput(outside[0], inside[0], 1.0, nullptr, corner));
657  corner = {0, 5, 10};
658  input.m_polys.push_back(MePolyInput(outside[1], inside[1], 1.0, nullptr, corner));
659  corner = {5, 10, 15};
660  input.m_polys.push_back(MePolyInput(outside[2], inside[2], 1.0, nullptr, corner));
662 
663  {
664  std::string outFile = path + "CasePatch6_out.2dm";
665  std::fstream os(outFile.c_str(), std::fstream::out);
666  imp.Generate2dm(input, os, 10);
667  os.close();
668  std::string baseFile = path + "CasePatch6_base.2dm";
669  TS_ASSERT_TXT_FILES_EQUAL(baseFile, outFile);
670  }
671 
672  {
673  std::string outFile = path + "CasePatch6a_out.2dm";
674  std::fstream os(outFile.c_str(), std::fstream::out);
675  input.m_polys[1].m_polyCorners[0] = 5;
676  imp.Generate2dm(input, os, 10);
677  os.close();
678  std::string baseFile = path + "CasePatch6a_base.2dm";
679  TS_ASSERT_TXT_FILES_EQUAL(baseFile, outFile);
680  }
681 
682  {
683  std::string outFile = path + "CasePatch6b_out.2dm";
684  std::fstream os(outFile.c_str(), std::fstream::out);
685  input.m_polys[1].m_polyCorners[1] = 10;
686  imp.Generate2dm(input, os, 10);
687  os.close();
688  std::string baseFile = path + "CasePatch6b_base.2dm";
689  TS_ASSERT_TXT_FILES_EQUAL(baseFile, outFile);
690  }
691 } // MeMultiPolyTo2dmIntermediateTests::testCasePatch6
692 //------------------------------------------------------------------------------
694 //------------------------------------------------------------------------------
696 {
697 #ifdef XMS_TEST_PATH
698  const std::string path(std::string(XMS_TEST_PATH) + "meshing/");
699 #else
700  const std::string path("test_files/meshing/");
701 #endif
702  std::string fbase("CaseTransitionToConstSize");
703  std::string fname(path + "CaseTransitionToConstSize.txt");
704  std::string inPolyFile(fname);
705  std::vector<std::vector<std::vector<Pt3d>>> inside;
706  std::vector<std::vector<Pt3d>> outside;
708  ip.m_polys.push_back(MePolyInput());
709  MePolyInput& pp(ip.m_polys.back());
710  VecPt3d2d outPoly;
711  VecPt3d3d inPolys;
712  tutReadPolygons(inPolyFile, outPoly, inPolys);
713  TS_ASSERT_EQUALS(false, outPoly.empty());
714  if (outPoly.empty() || inPolys.empty())
715  {
716  TS_FAIL("");
717  return;
718  }
719  pp.m_outPoly = outPoly[0];
720  pp.m_insidePolys = inPolys[0];
721  pp.m_constSizeBias = 0.15;
722  pp.m_constSizeFunction = 100.0;
723 
724  BSHP<MeMultiPolyTo2dm> p2g = MeMultiPolyTo2dm::New();
725  std::string outFile, baseFile;
726  outFile = path + "CaseTransitionToConstSize_out.2dm";
727  baseFile = path + "CaseTransitionToConstSize_base.2dm";
728  p2g->Generate2dm(ip, outFile);
729  TS_ASSERT_TXT_FILES_EQUAL(baseFile, outFile);
730 } // MeMultiPolyTo2dmIntermediateTests::testCasePaveConstSizeTransition
731 //------------------------------------------------------------------------------
733 //------------------------------------------------------------------------------
735 {
736  iTestFromPolyFile("CaseTestSeedPoints", 10);
737 } // MeMultiPolyTo2dmIntermediateTests::testSeedPoints
738 //------------------------------------------------------------------------------
740 //------------------------------------------------------------------------------
742 {
743  iTestFromPolyFile("CaseTestSeedPointsPolygonWithHole", 10);
744 } // MeMultiPolyTo2dmIntermediateTests::testSeedPoints_PolygonWithHole
745 //------------------------------------------------------------------------------
747 //------------------------------------------------------------------------------
749 {
750  iTestFromPolyFile("bug11299", 10);
751 } // MeMultiPolyTo2dmIntermediateTests::testbug11299
752 //------------------------------------------------------------------------------
754 //------------------------------------------------------------------------------
756 {
757  iTestFromPolyFile("internalFeatures/case0", 10);
758 } // MeMultiPolyTo2dmIntermediateTests::testInternalFeaturesCase0
759 //------------------------------------------------------------------------------
761 //------------------------------------------------------------------------------
763 {
764  iTestFromPolyFile("internalFeatures/case1", 10);
765 } // MeMultiPolyTo2dmIntermediateTests::testInternalFeaturesCase1
766 //------------------------------------------------------------------------------
768 //------------------------------------------------------------------------------
770 {
771  iTestFromPolyFile("internalFeatures/case2", 10);
772 } // MeMultiPolyTo2dmIntermediateTests::testInternalFeaturesCase2
773 
774 #endif // CXX_TEST
void testSeedPoints_PolygonWithHole()
Test providing seed points to the mesher for a polygon with a hole.
#define XM_LOG(A, B)
std::vector< VecPt3d2d > VecPt3d3d
void testCasePaveConstSizeTransition()
Test paving to a constant size with a transition factor.
std::vector< int > VecInt
void testbug11299()
Test providing seed points to the mesher for a polygon with a hole.
std::vector< MePolyInput > m_polys
Required (but some data is optional). Inputs for each polygon.
VecPt3d2d m_insidePolys
Optional. Inner polygons (holes). Counter clockwise. 1st pt != last.
void testCase101()
tests meshing a square with a "c" shaped hole in it Also has refine points, constant size function...
std::string STRstd(double a_value, int a_n, int width, int flags)
STR_FULLWIDTH
bool Generate2dm(MeMultiPolyMesherIo &a_input, const std::string &a_outFileName, int a_precision=15) override
Creates a 2dm file from polygons.
void ttGetTestFilePaths(const std::string &a_path, const std::string &a_fileBase, const std::string &a_extension, std::string &a_baseFilePath, std::string &a_outFilePath)
void testInternalFeaturesCase1()
Test providing seed points to the mesher for a polygon with a hole.
void testInternalFeaturesCase0()
Test providing seed points to the mesher for a polygon with a hole.
#define XM_ENSURE_TRUE_NO_ASSERT(...)
void Write2dm(MeMultiPolyMesherIo &a_input, std::ostream &a_os, int a_precision)
Writes 2dm data from a point and cell stream from the MeMultiPolyMesherIo class.
void testInternalFeaturesCase2()
Test providing seed points to the mesher for a polygon with a hole.
void testCase4()
tests meshing 2 adajacent polygons with holes
bool tutReadPolygons(const std::string &a_fname, VecPt3d2d &a_outside, VecPt3d3d &a_inside)
helper function to read polygons from a text file
Definition: TutMeshing.cpp:220
void testCasePaveGeo()
Test a paving bug.
void testCase100()
tests meshing a square with a "c" shaped hole in it Also has refine points, size function, and elevation function
Creates a 2dm file of a mesh from polygons.
#define TS_ASSERT_TXT_FILES_EQUAL(a, b)
Creates a VTK Unstructured Grid from polygons.
void testCreateClass()
tests creating the class
VecPt3d m_outPoly
Required. Outer polygons. Clockwise. 1st pt != last.
static void iSortCellsForTesting(MeMultiPolyMesherIo &a_io)
sorts the cells based so that the node with the smallest number will be first and then the cells are ...
VecPt3d m_points
The points of the resulting mesh.
Provides the input to meshing multiple polygons and holds the output.
void testCasePaveSanDiego_SpringRelaxation()
Test San Diego bay with spring relaxation.
std::vector< VecPt3d > VecPt3d2d
#define XM_COUNTOF(array)
bool tutReadMeshIoFromFile(const std::string &a_fname, MeMultiPolyMesherIo &a_io)
helper function to read MeMultiPolyMesherIo
Definition: TutMeshing.cpp:64
void testCasePatch6()
Tests two patched polys next to each other, and one paved poly next to them.
static boost::shared_ptr< MeMultiPolyTo2dm > New()
Creates a class.
static boost::shared_ptr< MeMultiPolyMesher > New()
Creates a class.
void testCase102()
tests meshing a square with a "c" shaped hole in it Also has refine points, constant size function...
void testCase2()
tests meshing a square with a "c" shaped hole in it
Meshing inputs for one polygon.
void testCase103()
tests meshing a square with a "c" shaped hole in it Also has refine points, constant size function...
VecInt m_cells
The cells of the resulting mesh, as a stream.
void testCasePaveSanDiego()
Test San Diego bay.
std::vector< Pt3d > VecPt3d
void testSeedPoints()
Test providing seed points to the mesher.