MeshKit
1.0
|
00001 00011 // C++ 00012 #include <cstddef> 00013 #include <iostream> 00014 #include <string> 00015 00016 // MeshKit 00017 #include "meshkit/MKCore.hpp" 00018 #include "meshkit/AF2DfltTriangleMeshOp.hpp" 00019 #include "meshkit/SizingFunction.hpp" 00020 #include "meshkit/SizingFunctionVar.hpp" 00021 #include "meshkit/ModelEnt.hpp" 00022 00023 // MeshKit testing 00024 #include "TestUtil.hpp" 00025 00026 // define the geometry file extension depending on the geometry model 00027 00028 #if HAVE_OCC 00029 std::string geomExt = ".stp"; 00030 #else 00031 std::string geomExt = ".facet"; 00032 #define HAVE_FACET 00033 #endif 00034 00035 using namespace MeshKit; 00036 00037 MEntVector constructMeshOp(std::string geomFile); 00038 void testMesh(std::string geomFile, 00039 std::string meshFile, SizingFunction* sfPtr); 00040 00041 void testSquare(); 00042 void testHoleySurf(); 00043 void testSingleHoleSurf(); 00044 void testSingleHoleSurfImprinted(); 00045 void testSquareVarSize(); 00046 void testPieceOfTorus(); 00047 void testSphere(); 00048 void testBrick(); 00049 00050 00051 // This variable is at global scope because calling deleteAll on 00052 // the MKCore geometry instance appears to cause memory inconsistencies 00053 // with later use of the geometry instance 00054 MKCore* mk = NULL; 00055 00056 // These variables are at global scope because they affect all of 00057 // the tests. There is no way provided to save only some of the 00058 // meshes 00059 bool saveMesh = false; 00060 std::string meshExt = ""; 00061 00062 int main(int argc, char **argv) 00063 { 00064 // This variable is defined and used in main because a new MKCore 00065 // instance cannot be easily constructed after another MKCore 00066 // instance is deleted; there are problems with a tag left behind in 00067 // iGeom. 00068 mk = new MeshKit::MKCore(); 00069 00070 int num_fail = 0; 00071 00072 if (argc == 2) 00073 { 00074 meshExt = argv[1]; 00075 if (meshExt.size() > 0 && meshExt.at(0) != '.') 00076 { 00077 meshExt.insert(0, "."); 00078 } 00079 saveMesh = true; 00080 std::cout << "Requested meshes saved with file extension " 00081 << meshExt << std::endl; 00082 } 00083 num_fail += RUN_TEST(testSquare); 00084 num_fail += RUN_TEST(testSquareVarSize); 00085 num_fail += RUN_TEST(testPieceOfTorus); 00086 #ifdef HAVE_FACET 00087 num_fail += RUN_TEST(testBrick); 00088 #else 00089 num_fail += RUN_TEST(testHoleySurf); 00090 num_fail += RUN_TEST(testSingleHoleSurf); 00091 num_fail += RUN_TEST(testSingleHoleSurfImprinted); 00092 num_fail += RUN_TEST(testSphere); 00093 #endif 00094 delete mk; 00095 00096 return num_fail; 00097 } 00098 00107 MEntVector constructMeshOp(std::string geomFile) 00108 { 00109 // count the number of surfaces that existing before 00110 MEntVector temp; 00111 mk->get_entities_by_dimension(2, temp); 00112 unsigned int countExisting = temp.size(); 00113 temp.clear(); 00114 00115 // load the geometry 00116 std::string file_name = TestDir + "/" + geomFile + geomExt; 00117 mk->load_geometry(file_name.c_str()); 00118 00119 // extract the new surfaces into an MEntVector 00120 MEntVector newSurfs; 00121 mk->get_entities_by_dimension(2, temp); 00122 unsigned int countAll = temp.size(); 00123 unsigned int count = 0u; 00124 MEntVector::reverse_iterator surfItr = temp.rbegin(); 00125 while (count < (countAll - countExisting)) 00126 { 00127 newSurfs.push_back(*surfItr); 00128 ++count; 00129 ++surfItr; 00130 } 00131 00132 // Construct the AF2DfltTriangleMeshOp on the surfaces 00133 mk->construct_meshop("AF2DfltTriangleMeshOp", newSurfs); 00134 00135 return newSurfs; 00136 } 00137 00149 void testMesh(std::string geomFile, 00150 std::string meshFile, SizingFunction* sfPtr) 00151 { 00152 MEntVector surfs = constructMeshOp(geomFile); 00153 00154 // Set the size on the surfaces and their children edges 00155 // if a size was provided 00156 if (sfPtr != NULL) 00157 { 00158 for (unsigned int si = 0u; si < surfs.size(); ++si) 00159 { 00160 surfs[si]->sizing_function_index(sfPtr->core_index()); 00161 } 00162 } 00163 00164 // setup and execute the MeshOp to mesh the surface 00165 mk->setup_and_execute(); 00166 00167 // report the number of triangles 00168 moab::Range tris; 00169 moab::ErrorCode rval = 00170 mk->moab_instance()->get_entities_by_dimension(0, 2, tris); 00171 CHECK_EQUAL(moab::MB_SUCCESS, rval); 00172 std::cout << tris.size() << " tris generated." << std::endl; 00173 00174 // save the mesh if directed to do so 00175 if (saveMesh) { 00176 std::string outfile = meshFile + meshExt; 00177 moab::EntityHandle* outputSets = new moab::EntityHandle[surfs.size()]; 00178 for (unsigned int si = 0u; si < surfs.size(); ++si) 00179 { 00180 outputSets[si] = surfs[si]->mesh_handle(); 00181 } 00182 rval = mk->moab_instance()->write_file(outfile.c_str(), NULL, NULL, 00183 outputSets, surfs.size()); 00184 MBERRCHK(rval, mk->moab_instance()); 00185 delete[] outputSets; 00186 } 00187 00188 // remove the MeshOp and the rest of the graph 00189 mk->clear_graph(); 00190 00191 // delete the triangles from the mesh 00192 mk->moab_instance()->delete_entities(tris); 00193 } 00194 00195 void testSquare() 00196 { 00197 // Provide a sizing function that will become the index 0 sizing function 00198 // and will be used on the edges. Without this, there will be a failure 00199 // in the edge mesher. 00200 SizingFunction* sfPtr = new SizingFunction(mk, 5, -1); 00201 // Do not pass a sizing function to the surface, though. It is not required. 00202 testMesh("squaresurf", "squaresurf", NULL); 00203 delete sfPtr; 00204 } 00205 00206 void testHoleySurf() 00207 { 00208 SizingFunction esize(mk, -1, 0.25); 00209 testMesh("holysurf", "holysurf", &esize); 00210 } 00211 00212 void testSingleHoleSurf() 00213 { 00214 SizingFunction esize(mk, -1, 0.25); 00215 testMesh("singleholesurf", "singleholesurf", &esize); 00216 } 00217 00218 void testSingleHoleSurfImprinted() 00219 { 00220 SizingFunction esize(mk, -1, 0.25); 00221 testMesh("singleholesurfimprinted", "singleholesurfimprinted", &esize); 00222 } 00223 00224 00225 void testSquareVarSize() 00226 { 00227 // make a sizing function and set it on the surface 00228 SizingFunctionVar svar(mk, -1, 0.1); 00229 00230 // these could be read from a file, or something 00231 double point0[3] = {0, 0, 0}; 00232 double coeffs[4] = {0.05, 0.05, 0.05, 0.1}; 00233 svar.set_linear_coeff(point0, coeffs); 00234 00235 // run the test 00236 testMesh("squaresurf", "squaresurf_var", &svar); 00237 } 00238 00239 void testPieceOfTorus() 00240 { 00241 SizingFunction esize(mk, -1, 0.25); 00242 testMesh("pieceOfTorus01", "pieceOfTorus01", &esize); 00243 } 00244 00245 void testSphere() 00246 { 00247 MEntVector surfs = constructMeshOp("sphere"); 00248 00249 // Set the size to 1.0 on all surfaces of the sphere, 00250 // but don't pass the sizing down to the child edges to test 00251 // whether the setup method will do that 00252 SizingFunction esize(mk, -1, 1.0); 00253 for (unsigned int si = 0u; si < surfs.size(); ++si) 00254 { 00255 surfs[si]->sizing_function_index(esize.core_index(), false); 00256 } 00257 00258 // setup and execute the MeshOp to mesh the surface 00259 mk->setup_and_execute(); 00260 00261 // report the number of triangles 00262 moab::Range tris; 00263 moab::ErrorCode rval = 00264 mk->moab_instance()->get_entities_by_dimension(0, 2, tris); 00265 CHECK_EQUAL(moab::MB_SUCCESS, rval); 00266 std::cout << tris.size() << " tris generated." << std::endl; 00267 00268 // save the mesh if directed to do so 00269 if (saveMesh) { 00270 std::string outfile = std::string("sphere") + meshExt; 00271 moab::EntityHandle* outputSets = new moab::EntityHandle[surfs.size()]; 00272 for (unsigned int si = 0u; si < surfs.size(); ++si) 00273 { 00274 outputSets[si] = surfs[si]->mesh_handle(); 00275 } 00276 rval = mk->moab_instance()->write_file(outfile.c_str(), NULL, NULL, 00277 outputSets, surfs.size()); 00278 MBERRCHK(rval, mk->moab_instance()); 00279 delete[] outputSets; 00280 } 00281 00282 // remove the MeshOp and the rest of the graph 00283 mk->clear_graph(); 00284 00285 // delete the triangles from the mesh 00286 mk->moab_instance()->delete_entities(tris); 00287 } 00288 00289 void testBrick() 00290 { 00291 MEntVector surfs = constructMeshOp("brick"); 00292 00293 // Set the size to 1.0 on all surfaces of the sphere, 00294 // but don't pass the sizing down to the child edges to test 00295 // whether the setup method will do that 00296 SizingFunction esize(mk, -1, 0.2); 00297 for (unsigned int si = 0u; si < surfs.size(); ++si) 00298 { 00299 surfs[si]->sizing_function_index(esize.core_index(), false); 00300 } 00301 00302 // setup and execute the MeshOp to mesh the surface 00303 mk->setup_and_execute(); 00304 00305 // report the number of triangles 00306 moab::Range tris; 00307 moab::ErrorCode rval = 00308 mk->moab_instance()->get_entities_by_dimension(0, 2, tris); 00309 CHECK_EQUAL(moab::MB_SUCCESS, rval); 00310 std::cout << tris.size() << " tris generated." << std::endl; 00311 00312 // save the mesh if directed to do so 00313 if (saveMesh) { 00314 std::string outfile = std::string("brick") + meshExt; 00315 moab::EntityHandle* outputSets = new moab::EntityHandle[surfs.size()]; 00316 for (unsigned int si = 0u; si < surfs.size(); ++si) 00317 { 00318 outputSets[si] = surfs[si]->mesh_handle(); 00319 } 00320 rval = mk->moab_instance()->write_file(outfile.c_str(), NULL, NULL, 00321 outputSets, surfs.size()); 00322 MBERRCHK(rval, mk->moab_instance()); 00323 delete[] outputSets; 00324 } 00325 00326 // remove the MeshOp and the rest of the graph 00327 mk->clear_graph(); 00328 00329 // delete the triangles from the mesh 00330 mk->moab_instance()->delete_entities(tris); 00331 }