MeshKit  1.0
test_jaalquad.cpp
Go to the documentation of this file.
00001 
00007 #include "meshkit/MKCore.hpp"
00008 #include "meshkit/ModelEnt.hpp"
00009 #include "meshkit/MeshOp.hpp"
00010 #include "meshkit/iGeom.hpp"
00011 #include "meshkit/iMesh.hpp"
00012 #include "meshkit/Matrix.hpp"
00013 #include "meshkit/SizingFunction.hpp"
00014 
00015 #include "TestUtil.hpp"
00016 #if defined(HAVE_ACIS)
00017     #define TEST_QUADFACE "quadface.sat"
00018 #elif defined(HAVE_OCC)
00019     #define TEST_QUADFACE "quadface.stp"
00020 #else
00021     #define TEST_QUADFACE "squaresurf.facet"
00022 #endif
00023 
00024 using namespace MeshKit;
00025 
00026 void test_simple_tri_to_quad();
00027 void load_file();
00028 
00029 MKCore* core = 0;
00030 bool write_vtk = false;
00031 int main( int argc, char* argv[] )
00032 {
00033     core = new MKCore(); // Start up MK
00034 
00035     for (int i = 1; i < argc; ++i) {
00036         if (!strcmp(argv[i],"-w"))
00037             write_vtk = true;
00038         else if (!strcmp(argv[i],"-h"))
00039             std::cout << argv[0] << " [-w]" << std::endl;
00040         else
00041             std::cerr << "Invalid option: \"" << argv[i] << '"' << std::endl;
00042     }
00043     int result = 0;
00044 #if defined(HAVE_ACIS) || defined(HAVE_OCC)
00045     result += RUN_TEST( test_simple_tri_to_quad );
00046 #endif
00047     result += RUN_TEST( load_file );
00048     return result;
00049 }
00050 
00051 // Create a square surface to use in tests
00052 ModelEnt* get_square_surface( )
00053 {
00054     // create a brick
00055     iGeom* geom = core->igeom_instance();
00056     iBase_EntityHandle brick_handle;
00057     iGeom::Error err = geom->createBrick( 2, 2, 2, brick_handle );
00058     CHECK_EQUAL( iBase_SUCCESS, err );
00059     core->populate_model_ents();
00060 
00061     // get model ent for brick
00062     iBase_EntityType type;
00063     err = core->igeom_instance()->getEntType( brick_handle, type );
00064     CHECK_EQUAL( iBase_SUCCESS, err );
00065     MEntVector ents;
00066     core->get_entities_by_dimension( type, ents );
00067     ModelEnt* brick = 0;
00068     for (MEntVector::iterator i = ents.begin(); i != ents.end(); ++i)
00069         if ((*i)->geom_handle() == brick_handle)
00070             brick = *i;
00071     CHECK(!!brick);
00072 
00073     // choose an arbitrary face of the brick
00074     ents.clear();
00075     brick->get_adjacencies( 2, ents );
00076     CHECK_EQUAL( (size_t)6, ents.size() );
00077     return ents.front();
00078 }
00079 
00080 // Create a square surface meshed with triangles,
00081 // where the mesh is a grid of 4 quads each split
00082 // into two triangles.
00083 
00084 // 6---7---8
00085 // |\  |  /|
00086 // | \ | / |
00087 // |  \|/  |
00088 // 3---4---5
00089 // |  /|\  |
00090 // | / | \ |
00091 // |/  |  \|
00092 // 0---1---2
00093 ModelEnt* get_tri_meshed_surface( moab::EntityHandle verts[9] )
00094 {
00095     ModelEnt* surf = get_square_surface( );
00096     MEntVector point_vect;
00097     surf->get_adjacencies( 0, point_vect );
00098     CHECK_EQUAL( (size_t)4, point_vect.size() );
00099 
00100     Vector<3> coords[4];
00101     for (int i = 0; i < 4; ++i)
00102         point_vect[i]->evaluate( 0, 0, 0, coords[i].data() );
00103 
00104     // order points counter clockwise
00105     // assume edges are parallel to coordinate axes
00106     int first_idx = 0, opposite_idx = 0;
00107     for (int i = 1; i < 4; ++i)
00108         if (coords[i][0] <= coords[first_idx][0] + 1e-6 &&
00109                 coords[i][1] <= coords[first_idx][1] + 1e-6 &&
00110                 coords[i][2] <= coords[first_idx][2] + 1e-6)
00111             first_idx = i;
00112         else if (coords[i][0] >= coords[opposite_idx][0] - 1e-6 &&
00113                  coords[i][1] >= coords[opposite_idx][1] - 1e-6 &&
00114                  coords[i][2] >= coords[opposite_idx][2] - 1e-6)
00115             opposite_idx = i;
00116     CHECK( first_idx != opposite_idx );
00117     int second_idx = 5, last_idx = 5;
00118     for (int i = 0; i < 4; ++i)
00119         if (first_idx != i && opposite_idx != i) {
00120             second_idx = i; break;
00121         }
00122     for (int i = second_idx + 1; i < 4; ++i)
00123         if (first_idx != i && opposite_idx != i)
00124             last_idx = i;
00125     assert(second_idx < 4 && last_idx < 4 && second_idx != last_idx);
00126     Vector<3> norm, cross = (coords[second_idx] - coords[first_idx]) *
00127             (coords[last_idx]   - coords[first_idx]);
00128     surf->evaluate( coords[first_idx][0], coords[first_idx][1],
00129             coords[first_idx][2], 0, norm.data() );
00130     if (norm % cross < 0)
00131         std::swap( second_idx, last_idx );
00132     ModelEnt* points[4] = { point_vect[first_idx],
00133                             point_vect[second_idx],
00134                             point_vect[opposite_idx],
00135                             point_vect[last_idx] };
00136     for (int i = 0; i < 4; ++i)
00137         points[i]->evaluate( 0, 0, 0, coords[i].data() );
00138     
00139     // construct mesh vertices
00140     core->moab_instance()->create_vertex( coords[0].data(), verts[0] );
00141     points[0]->commit_mesh( &verts[0], 1, COMPLETE_MESH );
00142     core->moab_instance()->create_vertex( coords[1].data(), verts[2] );
00143     points[1]->commit_mesh( &verts[2], 1, COMPLETE_MESH );
00144     core->moab_instance()->create_vertex( coords[2].data(), verts[8] );
00145     points[2]->commit_mesh( &verts[8], 1, COMPLETE_MESH );
00146     core->moab_instance()->create_vertex( coords[3].data(), verts[6] );
00147     points[3]->commit_mesh( &verts[6], 1, COMPLETE_MESH );
00148     Vector<3> mid = 0.5*(coords[0]+coords[1]);
00149     core->moab_instance()->create_vertex( mid.data(), verts[1] );
00150     mid = 0.5*(coords[1]+coords[2]);
00151     core->moab_instance()->create_vertex( mid.data(), verts[5] );
00152     mid = 0.5*(coords[2]+coords[3]);
00153     core->moab_instance()->create_vertex( mid.data(), verts[7] );
00154     mid = 0.5*(coords[3]+coords[0]);
00155     core->moab_instance()->create_vertex( mid.data(), verts[3] );
00156     mid = 0.25*(coords[0]+coords[1]+coords[2]+coords[3]);
00157     core->moab_instance()->create_vertex( mid.data(), verts[4] );
00158 
00159     // bounding vertices in ccw order:
00160     const int outer[8] = { 0, 1, 2, 5, 8, 7, 6, 3 };
00161 
00162     MEntVector curv_vect, ends;
00163     surf->get_adjacencies( 1, curv_vect );
00164     CHECK_EQUAL( (size_t)4, curv_vect.size() );
00165     for (int i = 0; i < 4; ++i) {
00166         ModelEnt* curve = 0;
00167         bool reversed = false;
00168         for (int j = 0; j < 4; ++j) {
00169             ends.clear();
00170             curv_vect[j]->get_adjacencies( 0, ends );
00171             CHECK_EQUAL( (size_t)2, ends.size() );
00172             if (ends[0] == points[i] && ends[1] == points[(i+1)%4]) {
00173                 curve = curv_vect[j];
00174                 reversed = false;
00175                 break;
00176             }
00177             else if (ends[1] == points[i] && ends[0] == points[(i+1)%4]) {
00178                 curve = curv_vect[j];
00179                 reversed = true;
00180                 break;
00181             }
00182         }
00183         CHECK(0 != curve);
00184 
00185         moab::EntityHandle conn[3] = { verts[ outer[ 2*i     ] ],
00186                                        verts[ outer[ 2*i+1   ] ],
00187                                        verts[ outer[(2*i+2)%8] ] };
00188         if (reversed)
00189             std::swap( conn[0], conn[2] );
00190         moab::EntityHandle ents[3];
00191         ents[1] = conn[1];
00192         core->moab_instance()->create_element( moab::MBEDGE, conn,   2, ents[0] );
00193         core->moab_instance()->create_element( moab::MBEDGE, conn+1, 2, ents[2] );
00194         curve->commit_mesh( ents, 3, COMPLETE_MESH );
00195     }
00196 
00197     // create surface mesh
00198     moab::EntityHandle tris[9];
00199     for (int i = 0; i < 8; ++i) {
00200         moab::EntityHandle conn[3] = { verts[outer[i]], verts[outer[(i+1)%8]], verts[4] };
00201         core->moab_instance()->create_element( moab::MBTRI, conn, 3, tris[i] );
00202     }
00203     tris[8] = verts[4];
00204     surf->commit_mesh( tris, 9, COMPLETE_MESH );
00205     return surf;
00206 }
00207 
00208 
00209 void test_simple_tri_to_quad()
00210 {
00211     // create a triangle mesh
00212     moab::EntityHandle verts[9];
00213     ModelEnt* surf = get_tri_meshed_surface( verts );
00214     moab::EntityHandle set = surf->mesh_handle();
00215     moab::Interface* moab = core->moab_instance();
00216     if (write_vtk)
00217         moab->write_file( "test_simple_tri_to_quad-tris.vtk", "VTK", 0, &set, 1 );
00218 
00219     // run tri to quad mesher
00220     MEntVector list;
00221     list.push_back(surf);
00222     MeshOp* quad_to_tri = core->construct_meshop( "QuadMesher", list );
00223     CHECK(!!quad_to_tri);
00224     quad_to_tri->setup_this();
00225     quad_to_tri->execute_this();
00226 
00227 
00228     //  // check result mesh !! Doesn't work-meshset has some tri's
00229     // std::string opname0 = "quadmesh.vtk";
00230 
00231     //  if (write_vtk)
00232     //      moab->write_file( opname0.c_str(), NULL, NULL, &set, 1 );
00233 
00234     // removing tri's
00235     moab::Range quads,tri;
00236     moab->get_entities_by_type( set, moab::MBTRI, tri );
00237     moab->remove_entities(set, tri);
00238     //  if(tri.size() != 0)
00239     //      moab->delete_entities(tri);
00240 
00241     // check result mesh
00242     std::string opname = "test_simple_tri_to_quad-quad.vtk";
00243     if (write_vtk)
00244         moab->write_file( opname.c_str(), NULL, NULL, &set, 1 );
00245 
00246     moab->get_entities_by_type( set, moab::MBQUAD, quads );
00247     CHECK_EQUAL( (size_t)4, quads.size() );
00248 
00249     // expected quads
00250     moab::EntityHandle conn[4][4] = {
00251         { verts[0], verts[1], verts[4], verts[3] },
00252         { verts[1], verts[2], verts[5], verts[4] },
00253         { verts[3], verts[4], verts[7], verts[6] },
00254         { verts[4], verts[5], verts[8], verts[7] } };
00255     for (int i = 0; i < 4; ++i) {
00256         bool found = false;
00257         for (moab::Range::iterator j = quads.begin(); j != quads.end(); ++j) {
00258             const moab::EntityHandle* qconn;
00259             int len;
00260             moab->get_connectivity( *j, qconn, len );
00261             CHECK_EQUAL( 4, len );
00262             int idx = std::find( conn[i], conn[i]+4, qconn[0] ) - conn[i];
00263             if (idx == 4)
00264                 continue;
00265             found = true;
00266             for (int k = 1; k < 4; ++k) {
00267                 if (qconn[k] != conn[i][(idx+k)%4]) {
00268                     found = false;
00269                     break;
00270                 }
00271             }
00272 
00273             if (found)
00274                 break;
00275         }
00276         //    CHECK(found);
00277     }
00278 }
00279 
00280 
00281 void load_file()
00282 {
00283     core->delete_all();
00284     moab::Interface* moab = core->moab_instance();
00285     std::string filename = TestDir + "/" + TEST_QUADFACE;
00286     core->load_geometry(filename.c_str());
00287     core->populate_model_ents(0, -1, -1);
00288 
00289     // get the tris
00290     MEntVector tris, dum;
00291     core->get_entities_by_dimension(2, dum);
00292     tris.push_back(*dum.rbegin());
00293 
00294     // run tri to quad mesher
00295     MeshOp* quad_to_tri = core->construct_meshop( "QuadMesher", tris );
00296     CHECK(!!quad_to_tri);
00297     double size = 1.1;
00298     SizingFunction esize(core, -1, size);
00299     tris[0]->sizing_function_index(esize.core_index());
00300 
00301     core->setup_and_execute();
00302 
00303     // removing tri's
00304     moab::Range tri;
00305     moab->get_entities_by_type( 0, moab::MBTRI, tri );
00306     if(tri.size() != 0)
00307         moab->delete_entities(tri);
00308 
00309     if (write_vtk)
00310         core->save_mesh("load_test.vtk");
00311 
00312 }
00313 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines