MeshKit
1.0
|
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 }