MeshKit  1.0
frontObj2D.cpp
Go to the documentation of this file.
00001 
00010 // C++
00011 #include <cstddef>
00012 #include <iostream>
00013 #include <list>
00014 
00015 // MeshKit
00016 #include "meshkit/AF2Front.hpp"
00017 #include "meshkit/AF2DfltPlaneProjMaker.hpp"
00018 #include "meshkit/Error.hpp"
00019 #include "meshkit/MKCore.hpp"
00020 #include "meshkit/ModelEnt.hpp"
00021 
00022 // MeshKit test utilities
00023 #include "TestUtil.hpp"
00024 
00025 // define the geometry file extension depending on the geometry model
00026 #if HAVE_OCC
00027 #define FILE_EXT "stp"
00028 #else
00029 #define FILE_EXT "facet"
00030 #endif
00031 
00032 // This variable is at global scope because a new MKCore instance cannot
00033 // be easily constructed after another MKCore instance is deleted
00034 // There are problems with a tag left behind in iGeom.
00035 // Thus this instance is shared across tests.
00036 MeshKit::MKCore* mk = NULL;
00037 // These variables are at global scope because (1) calling deleteAll on
00038 // the MKCore geometry instance appears to cause memory inconsistencies
00039 // with later use of the geometry instance and (2) it is more efficient
00040 // to load the geometry model only once
00041 MeshKit::MEntVector surfs;
00042 MeshKit::ModelEnt* square = NULL;
00043 
00044 AF2LocalTransformMaker* makeTransformBuilder();
00045 void initHex(AF2Front* front, AF2Point3D** & pointsAry, AF2Edge3D** & edgesAry);
00046 void deletePoints(AF2Point3D** & pointsAry, int pointsAryLength);
00047 void testSelectEmpty();
00048 void testInitAndDestruct();
00049 void testQualityDecrease();
00050 void testSelectNeighborhood();
00051 void testSelectIsolatedPoint();
00052 void testSelectHourglass();
00053 void testAdvanceMissingPoints();
00054 void testAdvanceInvalidQuality();
00055 void testAdvanceFront();
00056 void testAdvanceHangingEdge();
00057 void testCompletedAdvance();
00058 
00059 int main(int argc, char **argv)
00060 {
00061   mk = new MeshKit::MKCore();
00062 
00063   int num_fail = 0;
00064 
00065   num_fail += RUN_TEST(testSelectEmpty);
00066   num_fail += RUN_TEST(testInitAndDestruct);
00067   num_fail += RUN_TEST(testQualityDecrease);
00068   num_fail += RUN_TEST(testSelectNeighborhood);
00069   num_fail += RUN_TEST(testSelectIsolatedPoint);
00070   num_fail += RUN_TEST(testSelectHourglass);
00071   num_fail += RUN_TEST(testAdvanceMissingPoints);
00072   num_fail += RUN_TEST(testAdvanceInvalidQuality);
00073   num_fail += RUN_TEST(testAdvanceFront);
00074   num_fail += RUN_TEST(testAdvanceHangingEdge);
00075   num_fail += RUN_TEST(testCompletedAdvance);
00076 
00077   delete mk;
00078 
00079   return num_fail;
00080 }
00081 
00082 AF2LocalTransformMaker* makeTransformBuilder()
00083 {
00084   if (square == NULL)
00085   {
00086     // load a square in plane z = 0.5 with -1.0 <= x <= 0 and -0.5 <= y <= 0.5
00087     std::string file_name = TestDir + "/squaresurf." + FILE_EXT;
00088     mk->load_geometry_mesh(file_name.c_str(), file_name.c_str());
00089 
00090     mk->get_entities_by_dimension(2, surfs);
00091     square = *surfs.begin();
00092   }
00093 
00094   return new AF2DfltPlaneProjMaker(
00095       square->igeom_instance(), square->geom_handle());
00096 }
00097 
00098 void initHex(AF2Front* front, AF2Point3D** & pointsAry, AF2Edge3D** & edgesAry)
00099 {
00100   pointsAry = new AF2Point3D*[6];
00101   pointsAry[0] = new AF2Point3D(0, -0.625, -0.25, 0.5);
00102   pointsAry[1] = new AF2Point3D(1, -0.375, -0.25, 0.5);
00103   pointsAry[2] = new AF2Point3D(2, -0.25, 0.0, 0.5);
00104   pointsAry[3] = new AF2Point3D(3, -0.375, 0.25, 0.5);
00105   pointsAry[4] = new AF2Point3D(4, -0.625, 0.25, 0.5);
00106   pointsAry[5] = new AF2Point3D(5, -0.75, 0.0, 0.5);
00107 
00108   for (int pi = 0; pi < 6; ++pi)
00109   {
00110     pointsAry[pi]->limitDistanceToBoundary(0u);
00111     front->addPoint(pointsAry[pi]);
00112   }
00113 
00114   edgesAry = new AF2Edge3D*[6];
00115   edgesAry[0] = new AF2Edge3D(pointsAry[0], pointsAry[1]);
00116   edgesAry[1] = new AF2Edge3D(pointsAry[1], pointsAry[2]);
00117   edgesAry[2] = new AF2Edge3D(pointsAry[2], pointsAry[3]);
00118   edgesAry[3] = new AF2Edge3D(pointsAry[3], pointsAry[4]);
00119   edgesAry[4] = new AF2Edge3D(pointsAry[4], pointsAry[5]);
00120   edgesAry[5] = new AF2Edge3D(pointsAry[5], pointsAry[0]);
00121 
00122   std::list<AF2Edge3D*> edges;
00123   for (int ei = 0; ei < 6; ++ei)
00124   {
00125     edges.push_back(edgesAry[ei]);
00126   }
00127   front->advanceFront(edges);
00128 }
00129 
00130 void deletePoints(AF2Point3D** & pointsAry, int pointsAryLength)
00131 {
00132   for (int i = 0; i < pointsAryLength; ++i)
00133   {
00134     delete pointsAry[i];
00135   }
00136   delete[] pointsAry;
00137 }
00138 
00139 // test that attempting to select a neighborhood when there
00140 // are no edges on the advancing front throws an exception
00141 void testSelectEmpty()
00142 {
00143   AF2LocalTransformMaker* transformBuilder = makeTransformBuilder();
00144 
00145   AF2Front* emptyFront = new AF2Front();
00146   CHECK(emptyFront->isEmpty());
00147   std::cout << "Good: At initial construction, the front is empty."
00148       << std::endl;
00149 
00150   bool exceptionThrown = false;
00151   try
00152   {
00153     AF2Neighborhood* shouldFail =
00154         emptyFront->selectNeighborhood(transformBuilder);
00155     delete shouldFail;
00156   }
00157   catch (MeshKit::Error& mkError)
00158   {
00159     std::cout << "Good: Attempting to select a neighborhood caused an error."
00160         << std::endl;
00161     exceptionThrown = true;
00162     CHECK_EQUAL(MeshKit::MK_FAILURE, mkError.error_code());
00163     std::cout << "Good: The error is a failure error." << std::endl;
00164   }
00165   CHECK(exceptionThrown);
00166 
00167   AF2Point3D* aPoint = new AF2Point3D(0, -0.5, 0.0, 0.5);
00168   aPoint->limitDistanceToBoundary(0);
00169   emptyFront->addPoint(aPoint);
00170   std::cout << "Added a point to the advancing front, but no edges."
00171       << std::endl;
00172   CHECK(!emptyFront->isEmpty());
00173   std::cout << "Good: The front is no longer empty." << std::endl;
00174 
00175   exceptionThrown = false;
00176   try
00177   {
00178     AF2Neighborhood* shouldFail =
00179         emptyFront->selectNeighborhood(transformBuilder);
00180     delete shouldFail;
00181   }
00182   catch (MeshKit::Error& mkError)
00183   {
00184     std::cout << "Good: Attempting to select a neighborhood caused an error."
00185         << std::endl;
00186     exceptionThrown = true;
00187     CHECK_EQUAL(MeshKit::MK_FAILURE, mkError.error_code());
00188     std::cout << "Good: The error is a failure error." << std::endl;
00189   }
00190   CHECK(exceptionThrown);
00191 
00192   delete aPoint;
00193   delete emptyFront;
00194 
00195   delete transformBuilder;
00196 
00197   std::cout << "PASS: Attempts to select a neighborhood when the front has\n"
00198       << "  no edges failed appropriately." << std::endl;
00199 }
00200 
00201 void testInitAndDestruct()
00202 {
00203   AF2Front* hexFront = new AF2Front();
00204   AF2Point3D** pointsAry = NULL;
00205   AF2Edge3D** edgesAry = NULL;
00206   initHex(hexFront, pointsAry, edgesAry);
00207   CHECK(!hexFront->isEmpty());
00208   std::cout << "Good: The front is not empty after it has been initialized."
00209       << std::endl;
00210   CHECK_EQUAL(1u, hexFront->getMaximumQuality());
00211   std::cout << "Good: The maximum quality is 1 after the front has\n"
00212       << "  been initialized." << std::endl;
00213   delete hexFront;
00214   delete[] edgesAry;
00215   deletePoints(pointsAry, 6);
00216   std::cout << "PASS: The front is initialized and destructed correctly."
00217       << std::endl;
00218 }
00219 
00220 void testQualityDecrease()
00221 {
00222   AF2Front* hexFront = new AF2Front();
00223   AF2Point3D** pointsAry = NULL;
00224   AF2Edge3D** edgesAry = NULL;
00225   initHex(hexFront, pointsAry, edgesAry);
00226 
00227   for (int ei = 0; ei < 6; ++ei)
00228   {
00229     edgesAry[ei]->decreaseQuality();
00230     edgesAry[ei]->decreaseQuality();
00231   }
00232 
00233   CHECK_EQUAL(3u, hexFront->getMaximumQuality());
00234   std::cout << "Good: The maximum quality is 3 after each edge has\n"
00235       << "  had its quality decreased twice." << std::endl;
00236 
00237   for (int ei = 0; ei < 4; ++ei)
00238   {
00239     edgesAry[ei]->decreaseQuality();
00240     edgesAry[ei]->decreaseQuality();
00241     edgesAry[ei]->decreaseQuality();
00242   }
00243 
00244   CHECK_EQUAL(3u, hexFront->getMaximumQuality());
00245   std::cout << "Good: The maximum quality is 3 after some but not all edges\n"
00246       << "  have their quality decreased three more times." << std::endl;
00247 
00248   for (int ei = 4; ei < 6; ++ei)
00249   {
00250     edgesAry[ei]->decreaseQuality();
00251     edgesAry[ei]->decreaseQuality();
00252     edgesAry[ei]->decreaseQuality();
00253     edgesAry[ei]->decreaseQuality();
00254     edgesAry[ei]->decreaseQuality();
00255   }
00256 
00257   CHECK_EQUAL(6u, hexFront->getMaximumQuality());
00258   std::cout << "Good: The maximum quality is 6 after some edges\n"
00259       << "  have their quality decreased five times and others\n"
00260       << "  have their quality decreased seven times." << std::endl;
00261 
00262   for (int ei = 0; ei < 3; ++ei)
00263   {
00264     edgesAry[ei]->decreaseQuality();
00265     edgesAry[ei]->decreaseQuality();
00266   }
00267 
00268   CHECK_EQUAL(6u, hexFront->getMaximumQuality());
00269   std::cout << "Good: The maximum quality should be and is 6." << std::endl;
00270   edgesAry[3]->decreaseQuality();
00271   CHECK_EQUAL(7u, hexFront->getMaximumQuality());
00272   std::cout << "Good: The maximum quality should be and is 7." << std::endl;
00273   edgesAry[3]->decreaseQuality();
00274   CHECK_EQUAL(8u, hexFront->getMaximumQuality());
00275   std::cout << "Good: The maximum quality should be and is 8." << std::endl;
00276   edgesAry[3]->decreaseQuality();
00277   CHECK_EQUAL(8u, hexFront->getMaximumQuality());
00278   std::cout << "Good: The maximum quality should be and is 8." << std::endl;
00279 
00280   delete hexFront;
00281   delete[] edgesAry;
00282   deletePoints(pointsAry, 6);
00283 
00284   std::cout << "PASS: Quality decreases are being correctly reported to\n"
00285       << "  and tracked by the front." << std::endl;
00286 }
00287 
00288 void testSelectNeighborhood()
00289 {
00290   AF2Front* frontObj = new AF2Front();
00291   AF2Point3D** pointsAry = NULL;
00292   AF2Edge3D** edgesAry = NULL;
00293   initHex(frontObj, pointsAry, edgesAry);
00294 
00295   AF2LocalTransformMaker* transformBuilder = makeTransformBuilder();
00296 
00297   AF2Neighborhood* ngbhd = frontObj->selectNeighborhood(transformBuilder);
00298   std::list<const AF2Point2D*>::size_type sizeSix(6u);
00299   CHECK_EQUAL(sizeSix, ngbhd->getPoints2D()->size());
00300   std::cout << "Good: The selected neighborhood has 6 points." << std::endl;
00301   CHECK_EQUAL(sizeSix, ngbhd->getEdges2D()->size());
00302   std::cout << "Good: The selected neighborhood has 6 edges." << std::endl;
00303   delete ngbhd;
00304 
00305   for (int ei = 0; ei < 6; ++ei)
00306   {
00307     if (ei == 2)
00308     {
00309       continue;
00310     }
00311     edgesAry[ei]->decreaseQuality();
00312   }
00313   std::cout << "Decreased quality on all but one of the edges." << std::endl;
00314 
00315   ngbhd = frontObj->selectNeighborhood(transformBuilder);
00316   const AF2Edge2D* baseEdge2D = ngbhd->getBaselineEdge2D();
00317   CHECK_EQUAL(edgesAry[2]->getStart(),
00318       ngbhd->getCorrespondingPoint(baseEdge2D->getStart()));
00319   CHECK_EQUAL(edgesAry[2]->getEnd(),
00320       ngbhd->getCorrespondingPoint(baseEdge2D->getEnd()));
00321   std::cout << "Good: The baseline edge is the maximum quality edge."
00322       << std::endl;
00323   CHECK_EQUAL(sizeSix, ngbhd->getPoints2D()->size());
00324   std::cout << "Good: The selected neighborhood has 6 points." << std::endl;
00325   CHECK_EQUAL(sizeSix, ngbhd->getEdges2D()->size());
00326   std::cout << "Good: The selected neighborhood has 6 edges." << std::endl;
00327 
00328   delete ngbhd;
00329   delete frontObj;
00330   delete[] edgesAry;
00331   deletePoints(pointsAry, 6);
00332   delete transformBuilder;
00333 
00334   std::cout << "PASS: The basic case of selecting a neighborhood with a\n"
00335       << "  contiguous front of edges appears to work properly." << std::endl;
00336 }
00337 
00338 void testSelectIsolatedPoint()
00339 {
00340   AF2Front* frontObj = new AF2Front();
00341   AF2Point3D** pointsAry = NULL;
00342   AF2Edge3D** edgesAry = NULL;
00343   initHex(frontObj, pointsAry, edgesAry);
00344 
00345   // add an isolated point
00346   AF2Point3D* isoPoint = new AF2Point3D(6, -0.5, 0.0625, 0.5);
00347   frontObj->addPoint(isoPoint);
00348 
00349   // decrease quality on all but one of the edges
00350   for (int ei = 1; ei < 6; ++ei)
00351   {
00352     edgesAry[ei]->decreaseQuality();
00353   }
00354 
00355   AF2LocalTransformMaker* transformBuilder = makeTransformBuilder();
00356 
00357   AF2Neighborhood* ngbhd = frontObj->selectNeighborhood(transformBuilder);
00358   const AF2Edge2D* baseEdge2D = ngbhd->getBaselineEdge2D();
00359   CHECK_EQUAL(edgesAry[0]->getStart(),
00360       ngbhd->getCorrespondingPoint(baseEdge2D->getStart()));
00361   CHECK_EQUAL(edgesAry[0]->getEnd(),
00362       ngbhd->getCorrespondingPoint(baseEdge2D->getEnd()));
00363   std::cout << "Good: The baseline edge is the maximum quality edge."
00364       << std::endl;
00365   std::list<const AF2Point2D*>::size_type sizeSeven(7u);
00366   CHECK_EQUAL(sizeSeven, ngbhd->getPoints2D()->size());
00367   std::cout << "Good: The selected neighborhood has 7 points." << std::endl;
00368   std::list<const AF2Point2D*>::size_type sizeSix(6u);
00369   CHECK_EQUAL(sizeSix, ngbhd->getEdges2D()->size());
00370   std::cout << "Good: The selected neighborhood has 6 edges." << std::endl;
00371 
00372   delete ngbhd;
00373   delete frontObj;
00374   delete[] edgesAry;
00375   delete isoPoint;
00376   deletePoints(pointsAry, 6);
00377   delete transformBuilder;
00378 
00379   std::cout << "PASS: The case of selecting a neighborhood with an\n"
00380       << "  isolated point in addition to edges appears to work properly."
00381       << std::endl;
00382 }
00383 
00384 void testSelectHourglass()
00385 {
00386   AF2Front* frontObj = new AF2Front();
00387   AF2Point3D** pointsAry = NULL;
00388   AF2Edge3D** edgesAry = NULL;
00389 
00390   unsigned int numPoints = 54u;
00391   pointsAry = new AF2Point3D*[numPoints];
00392   pointsAry[0] = new AF2Point3D(0, -0.501, -0.0005, 0.5);
00393   pointsAry[1] = new AF2Point3D(1, -0.499, -0.0005, 0.5);
00394   pointsAry[2] = new AF2Point3D(2, -0.497, -0.0006, 0.5);
00395   pointsAry[3] = new AF2Point3D(3, -0.495, -0.0008, 0.5);
00396   pointsAry[4] = new AF2Point3D(4, -0.493, -0.0011, 0.5);
00397   pointsAry[5] = new AF2Point3D(5, -0.491, -0.0015, 0.5);
00398   pointsAry[6] = new AF2Point3D(6, -0.489, -0.0020, 0.5);
00399   pointsAry[7] = new AF2Point3D(7, -0.487, -0.0024, 0.5);
00400   pointsAry[8] = new AF2Point3D(8, -0.485, -0.0027, 0.5);
00401   pointsAry[9] = new AF2Point3D(9, -0.483, -0.0029, 0.5);
00402   pointsAry[10] = new AF2Point3D(10, -0.481, -0.0030, 0.5);
00403   pointsAry[11] = new AF2Point3D(11, -0.479, -0.0030, 0.5);
00404   pointsAry[12] = new AF2Point3D(12, -0.479, -0.0020, 0.5);
00405   pointsAry[13] = new AF2Point3D(13, -0.479, -0.0010, 0.5);
00406   pointsAry[14] = new AF2Point3D(14, -0.479, 0.0, 0.5);
00407   pointsAry[15] = new AF2Point3D(15, -0.479, 0.0010, 0.5);
00408   pointsAry[16] = new AF2Point3D(16, -0.479, 0.0020, 0.5);
00409   pointsAry[17] = new AF2Point3D(17, -0.479, 0.0030, 0.5);
00410   pointsAry[18] = new AF2Point3D(18, -0.481, 0.0030, 0.5);
00411   pointsAry[19] = new AF2Point3D(19, -0.483, 0.0029, 0.5);
00412   pointsAry[20] = new AF2Point3D(20, -0.485, 0.0027, 0.5);
00413   pointsAry[21] = new AF2Point3D(21, -0.487, 0.0024, 0.5);
00414   pointsAry[22] = new AF2Point3D(22, -0.489, 0.0020, 0.5);
00415   pointsAry[23] = new AF2Point3D(23, -0.491, 0.0015, 0.5);
00416   pointsAry[24] = new AF2Point3D(24, -0.493, 0.0011, 0.5);
00417   pointsAry[25] = new AF2Point3D(25, -0.495, 0.0008, 0.5);
00418   pointsAry[26] = new AF2Point3D(26, -0.497, 0.0006, 0.5);
00419   pointsAry[27] = new AF2Point3D(27, -0.499, 0.0005, 0.5);
00420   pointsAry[28] = new AF2Point3D(28, -0.501, 0.0005, 0.5);
00421   pointsAry[29] = new AF2Point3D(29, -0.503, 0.0006, 0.5);
00422   pointsAry[30] = new AF2Point3D(30, -0.505, 0.0008, 0.5);
00423   pointsAry[31] = new AF2Point3D(31, -0.507, 0.0011, 0.5);
00424   pointsAry[32] = new AF2Point3D(32, -0.509, 0.0015, 0.5);
00425   pointsAry[33] = new AF2Point3D(33, -0.511, 0.0020, 0.5);
00426   pointsAry[34] = new AF2Point3D(34, -0.513, 0.0024, 0.5);
00427   pointsAry[35] = new AF2Point3D(35, -0.515, 0.0027, 0.5);
00428   pointsAry[36] = new AF2Point3D(36, -0.517, 0.0029, 0.5);
00429   pointsAry[37] = new AF2Point3D(37, -0.519, 0.0030, 0.5);
00430   pointsAry[38] = new AF2Point3D(38, -0.521, 0.0030, 0.5);
00431   pointsAry[39] = new AF2Point3D(39, -0.521, 0.0020, 0.5);
00432   pointsAry[40] = new AF2Point3D(40, -0.521, 0.0010, 0.5);
00433   pointsAry[41] = new AF2Point3D(41, -0.521, 0.0, 0.5);
00434   pointsAry[42] = new AF2Point3D(42, -0.521, -0.0010, 0.5);
00435   pointsAry[43] = new AF2Point3D(43, -0.521, -0.0020, 0.5);
00436   pointsAry[44] = new AF2Point3D(44, -0.521, -0.0030, 0.5);
00437   pointsAry[45] = new AF2Point3D(45, -0.519, -0.0030, 0.5);
00438   pointsAry[46] = new AF2Point3D(46, -0.517, -0.0029, 0.5);
00439   pointsAry[47] = new AF2Point3D(47, -0.515, -0.0027, 0.5);
00440   pointsAry[48] = new AF2Point3D(48, -0.513, -0.0024, 0.5);
00441   pointsAry[49] = new AF2Point3D(49, -0.511, -0.0020, 0.5);
00442   pointsAry[50] = new AF2Point3D(50, -0.509, -0.0015, 0.5);
00443   pointsAry[51] = new AF2Point3D(51, -0.507, -0.0011, 0.5);
00444   pointsAry[52] = new AF2Point3D(52, -0.505, -0.0008, 0.5);
00445   pointsAry[53] = new AF2Point3D(53, -0.503, -0.0006, 0.5);
00446 
00447   for (unsigned int pi = 0; pi < numPoints; ++pi)
00448   {
00449     pointsAry[pi]->limitDistanceToBoundary(0u);
00450     frontObj->addPoint(pointsAry[pi]);
00451   }
00452 
00453   edgesAry = new AF2Edge3D*[numPoints];
00454   std::list<AF2Edge3D*> edges;
00455   for (unsigned int ei = 0; ei < numPoints; ++ei)
00456   {
00457     edgesAry[ei] =
00458         new AF2Edge3D(pointsAry[ei], pointsAry[(ei + 1) % numPoints]);
00459     edges.push_back(edgesAry[ei]);
00460   }
00461 
00462   frontObj->advanceFront(edges);
00463 
00464   // decrease quality on all but the first edge
00465   for (unsigned int ei = 1u; ei < numPoints; ++ei)
00466   {
00467     edgesAry[ei]->decreaseQuality();
00468   }
00469 
00470   AF2LocalTransformMaker* transformBuilder = makeTransformBuilder();
00471 
00472   AF2Neighborhood* ngbhd = frontObj->selectNeighborhood(transformBuilder);
00473   const AF2Edge2D* baseEdge2D = ngbhd->getBaselineEdge2D();
00474   CHECK_EQUAL(edgesAry[0]->getStart(),
00475       ngbhd->getCorrespondingPoint(baseEdge2D->getStart()));
00476   CHECK_EQUAL(edgesAry[0]->getEnd(),
00477       ngbhd->getCorrespondingPoint(baseEdge2D->getEnd()));
00478   std::cout << "Good: The baseline edge is the maximum quality edge."
00479       << std::endl;
00480   // The neighborhood should have two disconnected paths
00481   CHECK(ngbhd->getPoints2D()->size() == ngbhd->getEdges2D()->size() + 2);
00482   std::cout << "Good: The selected neighborhood has 2 more points than edges."
00483       << std::endl;
00484   // The neighborhood should exclude more than just the two caps
00485   CHECK(ngbhd->getEdges2D()->size() < 40u);
00486   std::cout << "Good: The selected neighborhood has fewer than 40 edges.\n"
00487       << "  (It has " << ngbhd->getEdges2D()->size() << " edges.)"
00488       << std::endl;
00489 
00490   delete ngbhd;
00491   delete frontObj;
00492   delete[] edgesAry;
00493   deletePoints(pointsAry, numPoints);
00494   delete transformBuilder;
00495 
00496   std::cout << "PASS: Neighborhood selection can select two disjoint paths."
00497       << std::endl;
00498 }
00499 
00500 void testAdvanceMissingPoints()
00501 {
00502   AF2Point3D** pointsAry = new AF2Point3D*[6];
00503   pointsAry[0] = new AF2Point3D(0, -0.625, -0.25, 0.5);
00504   pointsAry[1] = new AF2Point3D(1, -0.375, -0.25, 0.5);
00505   pointsAry[2] = new AF2Point3D(2, -0.25, 0.0, 0.5);
00506   pointsAry[3] = new AF2Point3D(3, -0.375, 0.25, 0.5);
00507   pointsAry[4] = new AF2Point3D(4, -0.625, 0.25, 0.5);
00508   pointsAry[5] = new AF2Point3D(5, -0.75, 0.0, 0.5);
00509 
00510   // do not add the points to the front before attempting to 
00511   // advance the front and add the edges
00512 
00513   AF2Edge3D** edgesAry = new AF2Edge3D*[6];
00514   edgesAry[0] = new AF2Edge3D(pointsAry[0], pointsAry[1]);
00515   edgesAry[1] = new AF2Edge3D(pointsAry[1], pointsAry[2]);
00516   edgesAry[2] = new AF2Edge3D(pointsAry[2], pointsAry[3]);
00517   edgesAry[3] = new AF2Edge3D(pointsAry[3], pointsAry[4]);
00518   edgesAry[4] = new AF2Edge3D(pointsAry[4], pointsAry[5]);
00519   edgesAry[5] = new AF2Edge3D(pointsAry[5], pointsAry[0]);
00520 
00521   std::list<AF2Edge3D*> edges;
00522   for (int ei = 0; ei < 6; ++ei)
00523   {
00524     edges.push_back(edgesAry[ei]);
00525   }
00526 
00527   AF2Front* frontObj = new AF2Front();
00528   bool exceptionThrown = false;
00529   try
00530   {
00531     frontObj->advanceFront(edges);
00532   }
00533   catch (MeshKit::Error& mkError)
00534   {
00535     std::cout << "Good: Attempting to initialize/advance the front using\n"
00536         << "  edges whose endpoints have not been added causes an error."
00537         << std::endl;
00538     exceptionThrown = true;
00539     CHECK_EQUAL(MeshKit::MK_BAD_INPUT, mkError.error_code());
00540     std::cout << "Good: The error is a bad input error." << std::endl;
00541   }
00542   CHECK(exceptionThrown);
00543 
00544   // delete the edges (due to error, none of them should be owned by the front)
00545   for (int i = 0; i < 6; ++i)
00546   {
00547     delete edgesAry[i];
00548   }
00549   delete[] edgesAry;
00550   deletePoints(pointsAry, 6);
00551   delete frontObj;
00552 
00553   std::cout << "PASS: Advancing the front fails if there are missing points."
00554       << std::endl;
00555 }
00556 
00557 void testAdvanceInvalidQuality()
00558 {
00559   AF2Front* frontObj = new AF2Front();
00560 
00561   AF2Point3D** pointsAry = new AF2Point3D*[6];
00562   pointsAry[0] = new AF2Point3D(0, -0.625, -0.25, 0.5);
00563   pointsAry[1] = new AF2Point3D(1, -0.375, -0.25, 0.5);
00564   pointsAry[2] = new AF2Point3D(2, -0.25, 0.0, 0.5);
00565   pointsAry[3] = new AF2Point3D(3, -0.375, 0.25, 0.5);
00566   pointsAry[4] = new AF2Point3D(4, -0.625, 0.25, 0.5);
00567   pointsAry[5] = new AF2Point3D(5, -0.75, 0.0, 0.5);
00568 
00569   for (int pi = 0; pi < 6; ++pi)
00570   {
00571     pointsAry[pi]->limitDistanceToBoundary(0u);
00572     frontObj->addPoint(pointsAry[pi]);
00573   }
00574 
00575   AF2Edge3D** edgesAry = new AF2Edge3D*[6];
00576   edgesAry[0] = new AF2Edge3D(pointsAry[0], pointsAry[1]);
00577   edgesAry[1] = new AF2Edge3D(pointsAry[1], pointsAry[2]);
00578   edgesAry[2] = new AF2Edge3D(pointsAry[2], pointsAry[3]);
00579   edgesAry[3] = new AF2Edge3D(pointsAry[3], pointsAry[4]);
00580   edgesAry[4] = new AF2Edge3D(pointsAry[4], pointsAry[5]);
00581   edgesAry[5] = new AF2Edge3D(pointsAry[5], pointsAry[0]);
00582 
00583   // decrease the quality of one of the edges before advancing the front
00584   edgesAry[4]->decreaseQuality();
00585 
00586   std::list<AF2Edge3D*> edges;
00587   for (int ei = 0; ei < 6; ++ei)
00588   {
00589     edges.push_back(edgesAry[ei]);
00590   }
00591 
00592   bool exceptionThrown = false;
00593   try
00594   {
00595     frontObj->advanceFront(edges);
00596   }
00597   catch (MeshKit::Error& mkError)
00598   {
00599     std::cout << "Good: Attempting to initialize/advance the front using\n"
00600         << "  edges whose quality has been decreased causes an error."
00601         << std::endl;
00602     exceptionThrown = true;
00603     CHECK_EQUAL(MeshKit::MK_BAD_INPUT, mkError.error_code());
00604     std::cout << "Good: The error is a bad input error." << std::endl;
00605   }
00606   CHECK(exceptionThrown);
00607 
00608   // delete the edges (due to error, none of them should be owned by the front)
00609   for (int i = 0; i < 6; ++i)
00610   {
00611     delete edgesAry[i];
00612   }
00613   delete[] edgesAry;
00614   deletePoints(pointsAry, 6);
00615   delete frontObj;
00616 
00617   std::cout << "PASS: Advancing the front fails if edges have decreased in\n"
00618       << "  quality before they are added to the front."
00619       << std::endl;
00620 }
00621 
00622 void testAdvanceFront()
00623 {
00624   AF2Front* frontObj = new AF2Front();
00625   AF2Point3D** pointsAry = NULL;
00626   AF2Edge3D** edgesAry = NULL;
00627   initHex(frontObj, pointsAry, edgesAry);
00628 
00629   AF2Point3D* addedPoint = new AF2Point3D(6, -0.5, 0.0625, 0.5);
00630   frontObj->addPoint(addedPoint);
00631 
00632   std::list<AF2Edge3D*> addedEdges;
00633   addedEdges.push_back(new AF2Edge3D(pointsAry[0], addedPoint));
00634   addedEdges.push_back(new AF2Edge3D(addedPoint, pointsAry[1]));
00635   addedEdges.push_back(new AF2Edge3D(pointsAry[1], pointsAry[0]));
00636   frontObj->advanceFront(addedEdges);
00637   std::cout << "Good: The front has advanced without error." << std::endl;
00638 
00639   AF2LocalTransformMaker* transformBuilder = makeTransformBuilder();
00640   AF2Neighborhood* ngbhd = frontObj->selectNeighborhood(transformBuilder);
00641   std::list<const AF2Point2D*>::size_type sizeSeven(7u);
00642   CHECK_EQUAL(sizeSeven, ngbhd->getPoints2D()->size());
00643   std::cout << "Good: After advance, the selected neighborhood has 7 points."
00644       << std::endl;
00645   CHECK_EQUAL(sizeSeven, ngbhd->getEdges2D()->size());
00646   std::cout << "Good: After advance, the selected neighborhood has 7 edges."
00647       << std::endl;
00648   CHECK_EQUAL(1u, addedPoint->getDistanceToBoundary());
00649   std::cout << "Good: After advance, the distance from the added point\n"
00650       << "  to the boundary is 1." << std::endl;
00651 
00652   delete ngbhd;
00653   delete frontObj;
00654   delete[] edgesAry;
00655   delete addedPoint;
00656   deletePoints(pointsAry, 6);
00657   delete transformBuilder;
00658   std::cout << "PASS: The front appears to have been advanced correctly."
00659       << std::endl;
00660 }
00661 
00662 void testAdvanceHangingEdge()
00663 {
00664   AF2Front* frontObj = new AF2Front();
00665 
00666   AF2Point3D** pointsAry = new AF2Point3D*[7];
00667   pointsAry[0] = new AF2Point3D(0, -0.625, -0.25, 0.5);
00668   pointsAry[1] = new AF2Point3D(1, -0.375, -0.25, 0.5);
00669   pointsAry[2] = new AF2Point3D(2, -0.25, 0.0, 0.5);
00670   pointsAry[3] = new AF2Point3D(3, -0.375, 0.25, 0.5);
00671   pointsAry[4] = new AF2Point3D(4, -0.625, 0.25, 0.5);
00672   pointsAry[5] = new AF2Point3D(5, -0.75, 0.0, 0.5);
00673   pointsAry[6] = new AF2Point3D(6, -0.5, 0.0625, 0.5);
00674 
00675   for (int pi = 0; pi < 7; ++pi)
00676   {
00677     pointsAry[pi]->limitDistanceToBoundary(0u);
00678     frontObj->addPoint(pointsAry[pi]);
00679   }
00680 
00681   AF2Edge3D** edgesAry = new AF2Edge3D*[8];
00682   // first edge
00683   edgesAry[0] = new AF2Edge3D(pointsAry[0], pointsAry[1]);
00684   // both half edges of a hanging edge
00685   edgesAry[1] = new AF2Edge3D(pointsAry[1], pointsAry[6]);
00686   edgesAry[2] = new AF2Edge3D(pointsAry[6], pointsAry[1]);
00687   // other edges
00688   edgesAry[3] = new AF2Edge3D(pointsAry[1], pointsAry[2]);
00689   edgesAry[4] = new AF2Edge3D(pointsAry[2], pointsAry[3]);
00690   edgesAry[5] = new AF2Edge3D(pointsAry[3], pointsAry[4]);
00691   edgesAry[6] = new AF2Edge3D(pointsAry[4], pointsAry[5]);
00692   edgesAry[7] = new AF2Edge3D(pointsAry[5], pointsAry[0]);
00693 
00694   std::list<AF2Edge3D*> edges;
00695   for (int ei = 0; ei < 8; ++ei)
00696   {
00697     edges.push_back(edgesAry[ei]);
00698   }
00699   frontObj->advanceFront(edges);
00700 
00701   AF2LocalTransformMaker* transformBuilder = makeTransformBuilder();
00702   AF2Neighborhood* ngbhd = frontObj->selectNeighborhood(transformBuilder);
00703   std::list<const AF2Point2D*>::size_type sizeSeven(7u);
00704   std::list<const AF2Point2D*>::size_type sizeEight(8u);
00705   CHECK_EQUAL(sizeSeven, ngbhd->getPoints2D()->size());
00706   std::cout << "Good: After init, the selected neighborhood has 7 points."
00707       << std::endl;
00708   CHECK_EQUAL(sizeEight, ngbhd->getEdges2D()->size());
00709   std::cout << "Good: After init, the selected neighborhood has 8 edges."
00710       << std::endl;
00711   delete ngbhd;
00712 
00713   std::list<AF2Edge3D*> addedEdges;
00714   addedEdges.push_back(new AF2Edge3D(pointsAry[0], pointsAry[6]));
00715   addedEdges.push_back(new AF2Edge3D(pointsAry[6], pointsAry[1]));
00716   addedEdges.push_back(new AF2Edge3D(pointsAry[1], pointsAry[0]));
00717   frontObj->advanceFront(addedEdges);
00718   std::cout << "Good: The front has advanced without error." << std::endl;
00719 
00720   ngbhd = frontObj->selectNeighborhood(transformBuilder);
00721   CHECK_EQUAL(sizeSeven, ngbhd->getPoints2D()->size());
00722   std::cout << "Good: After advance, the selected neighborhood has 7 points."
00723       << std::endl;
00724   CHECK_EQUAL(sizeSeven, ngbhd->getEdges2D()->size());
00725   std::cout << "Good: After advance, the selected neighborhood has 7 edges."
00726       << std::endl;
00727 
00728   delete ngbhd;
00729   delete frontObj;
00730   delete[] edgesAry;
00731   deletePoints(pointsAry, 7);
00732   delete transformBuilder;
00733   std::cout << "PASS: The front appears to have initialized and advanced\n"
00734       << "  correctly in the presence of a hanging edge."
00735       << std::endl;
00736 }
00737 
00738 void testCompletedAdvance()
00739 {
00740   AF2Front* frontObj = new AF2Front();
00741   AF2Point3D** pointsAry = NULL;
00742   AF2Edge3D** edgesAry = NULL;
00743   initHex(frontObj, pointsAry, edgesAry);
00744 
00745   // add a point near the center of the hexagon
00746   AF2Point3D* addedPoint = new AF2Point3D(6, -0.5, 0.0625, 0.5);
00747   frontObj->addPoint(addedPoint);
00748 
00749   // fill in triangles with the added point one at a time
00750   // until all should be filled in
00751   std::list<AF2Edge3D*> addedEdges;
00752   for (unsigned int i = 0; i < 6u; ++i)
00753   {
00754     addedEdges.clear();
00755     addedEdges.push_back(new AF2Edge3D(pointsAry[i], addedPoint));
00756     addedEdges.push_back(new AF2Edge3D(addedPoint, pointsAry[(i + 1) % 6]));
00757     addedEdges.push_back(new AF2Edge3D(pointsAry[(i + 1) % 6], pointsAry[i]));
00758     frontObj->advanceFront(addedEdges);
00759   }
00760 
00761   CHECK(frontObj->isEmpty());
00762   std::cout << "Good: The front is empty after appropriate advances."
00763       << std::endl;
00764 
00765   delete frontObj;
00766   delete[] edgesAry;
00767   delete addedPoint;
00768   deletePoints(pointsAry, 6);
00769   std::cout << "PASS: The front is empty after appropriate advances."
00770       << std::endl;
00771 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines