bool CamalPaveDriver::prepareCGMEvaluator() { // // we will have to mesh every geo edge separately, and we have to ensure that the number of mesh edges // for a face is even. // pretty tough to do. Initially, we have to decide loops, number of edges on each face, etc // first build //int err; // get the triangles and the vertices from moab set /*iBase_EntityHandle *triangles = NULL; int triangles_alloc = 0; iBase_EntityHandle *vert_adj = NULL; int vert_adj_alloc = 0, vert_adj_size; int numTriangles; int * offsets = NULL, offsets_alloc = 0, indices_size; int * indices = NULL, indices_alloc = 0, offsets_size; iMesh_getAdjEntIndices(_meshIface, _set, iBase_FACE, iMesh_TRIANGLE, iBase_VERTEX, &triangles, &triangles_alloc, &numTriangles, &vert_adj, &vert_adj_alloc, &vert_adj_size, &indices, &indices_alloc, &indices_size, &offsets, &offsets_alloc, &offsets_size, &err); ERRORR("Couldn't get connectivity for triangles.", 1);*/ MBRange triangles; MBErrorCode rval = _mb->get_entities_by_type( 0 /* root set, as above, we know */, MBTRI, triangles); // get all the nodes MBRange vertices; rval = _mb->get_adjacencies(triangles, 0, false, vertices, MBInterface::UNION); // first, create CubitPointData list, from the coordinates in one array /* get the coordinates in one array */ /*int vert_coords_alloc = 0, vertex_coord_size; double * xyz = NULL; iMesh_getVtxArrCoords(_meshIface, vert_adj, vert_adj_size, iBase_INTERLEAVED, &xyz, &vert_coords_alloc, &vertex_coord_size, &err); ERRORR("Couldn't get coordinates for vertices.", 1);*/ // here, we use Cholla from CGM // we need to replace it with something equivalent, but simpler // the first try would be some tags in MOAB // create the cubit point data // initialize CGM AppUtil::instance()->startup(0, NULL); CGMApp::instance()->startup(0, NULL); // Initialize the GeometryTool GeometryQueryTool *gqt = GeometryQueryTool::instance(); FacetModifyEngine *fme = FacetModifyEngine::instance(); int vert_adj_size = vertices.size(); int numTriangles = triangles.size(); DLIList<CubitFacet*> f_list(numTriangles); DLIList<CubitPoint*> p_list(vert_adj_size); double * xyz = new double [3*vert_adj_size]; rval = _mb-> get_coords(vertices, xyz); //std::map<MBEntityHandle, CubitPoint *> mapPoints; //MBRange::iterator it = vertices.begin(); for (int i = 0; i < vert_adj_size; i++/*, it++*/) { double * pCoord = &xyz[3 * i]; CubitPointData * newPoint = new CubitPointData(pCoord[0], pCoord[1], pCoord[2]); p_list.append(newPoint); //mapPoints[*it] = newPoint;// or maybe we should use finding the index in MBRange?? } // yes // define all the triangles, to see what we have for (MBRange::iterator it = triangles.begin(); it!=triangles.end(); it++) { MBEntityHandle tri = *it; int nnodes; const MBEntityHandle * conn3;// _mb->get_connectivity(tri, conn3, nnodes); assert(nnodes == 3); int vtri[3];// indices for triangles int ii = 0; for (ii = 0; ii < 3; ii++) vtri[ii] = vertices.index(conn3[ii]); // vtri[ii] = indices[offsets[j] + ii]; CubitFacetData * triangle = new CubitFacetData(p_list[vtri[0]], p_list[vtri[1]], p_list[vtri[2]]); f_list.append(triangle); } DLIList<LoopSM*> my_loops; DLIList<Surface*> surf_list; CubitStatus result; //double angle = 0.01;// very small, negligible; is this radians or degrees? result = fme->build_facet_surface(NULL, f_list, p_list, _angle, 4, true, false, surf_list); if (surf_list.size() == 0 || result != CUBIT_SUCCESS) { PRINT_ERROR("Problems building mesh based surfaces.\n"); return result; } else PRINT_INFO("Constructed %d surfaces.\n", surf_list.size()); //Now build the shell. If we had it set up right this would be //in a loop. We need to store list of DLBlockSurfaceLists on each //blockvolumemesh to store the shell information. But that will //be saved for later. ShellSM *shell_ptr; result = fme->make_facet_shell(surf_list, shell_ptr); if (shell_ptr == NULL || result != CUBIT_SUCCESS) { PRINT_ERROR("Problems building mesh based shell entity.\n"); return result; } #if 1 DLIList<ShellSM*> shell_list; shell_list.append(shell_ptr); Lump *lump_ptr; result = fme->make_facet_lump(shell_list, lump_ptr); if (lump_ptr == NULL || result != CUBIT_SUCCESS) { PRINT_ERROR("Problems building mesh based lump entity.\n"); return result; } DLIList<Lump*> lump_list; lump_list.append(lump_ptr); BodySM *bodysm_ptr; Body *body_ptr; result = fme->make_facet_body(lump_list, bodysm_ptr); body_ptr = GeometryQueryTool::instance()->make_Body(bodysm_ptr); if (body_ptr == NULL || result != CUBIT_SUCCESS) { PRINT_ERROR("Problems building mesh based body entity.\n"); return result; } if (!body_ptr) { exit(1); } PRINT_INFO("Body successfully created.\n"); #endif PRINT_INFO("Number of vertices = %d\n", gqt->num_ref_vertices()); PRINT_INFO("Number of edges = %d\n", gqt->num_ref_edges()); PRINT_INFO("Number of faces = %d\n", gqt->num_ref_faces()); // print vertex positions DLIList<RefVertex*> verts; gqt->ref_vertices(verts); int i; for (i = 0; i < verts.size(); i++) { RefVertex * vert = verts[i]; CubitVector coords = vert->coordinates(); PRINT_INFO("Vertex %d: %4.2f, %4.2f, %4.2f.\n", vert->id(), coords.x(), coords.y(), coords.z()); } // print edges and faces DLIList<RefEdge*> refEdges; gqt->ref_edges(refEdges); for (i = 0; i < refEdges.size(); i++) { RefEdge * edg = refEdges[i]; PRINT_INFO("Edge %d: %d %d\n", edg->id(), edg->start_vertex()->id(), edg->end_vertex ()->id() ); } DLIList<RefFace*> refFaces; gqt->ref_faces(refFaces); for (i = 0; i < refFaces.size(); i++) { RefFace * face = refFaces[i]; DLIList< Loop * > loop_list ; face->ordered_loops (loop_list ) ; DLIList< RefEdge * > ordered_edge_list; loop_list[0]->ordered_ref_edges (ordered_edge_list); //DLIList< RefVertex* > *listV = ref_vert_loop_list[0]; PRINT_INFO("face %d: loop 0 size %d\n", face->id(), ordered_edge_list.size() ); for (int j=0; j<ordered_edge_list.size(); j++) { PRINT_INFO(" %d", ordered_edge_list[j]->id() ); } PRINT_INFO("\n"); } return true; }
int main(int argc, char **argv) { //open moab instance MBInterface *MBI(); //for unit testing purposes, we don't care about the output. Just PASS or FAIL. bool verbose=false; // ****************************************************************** // Load the h5m file and create tags. // ****************************************************************** clock_t start_time; start_time = clock(); // load file and get tolerance from the iter file MBErrorCode result; std::string filename = "iter_imprinted.h5m"; //set filename MBEntityHandle input_set; result = MBI()->create_meshset( MESHSET_SET, input_set ); //create handle to meshset if(MB_SUCCESS != result) { return result; } result = MBI()->load_file( filename.c_str(), &input_set ); //load the file into the meshset if(MB_SUCCESS != result) { // failed to load the file std::cout << "could not load file" << std::endl; return result; } /// get faceting tolerance /// double facet_tolerance; MBTag faceting_tol_tag; //get faceting tolerance handle from file result = MBI()->tag_get_handle( "FACETING_TOL", 1, MB_TYPE_DOUBLE, faceting_tol_tag , moab::MB_TAG_SPARSE|moab::MB_TAG_CREAT ); if(gen::error(MB_SUCCESS!=result, "could not get the faceting tag handle")) return result; //get the faceting tolerance of any entity MBRange file_set; result = MBI()->get_entities_by_type_and_tag( 0, MBENTITYSET, &faceting_tol_tag, NULL, 1, file_set ); //get facetint tolerance value result = MBI()->tag_get_data( faceting_tol_tag, &file_set.front(), 1, &facet_tolerance ); if(gen::error(MB_SUCCESS!=result, "could not get the faceting tolerance")) return result; // create tags on geometry MBTag geom_tag, id_tag; result = MBI()->tag_get_handle( GEOM_DIMENSION_TAG_NAME, 1, MB_TYPE_INTEGER, geom_tag, moab::MB_TAG_DENSE|moab::MB_TAG_CREAT ); if(gen::error(MB_SUCCESS != result, "could not get GEOM_DIMENSION_TAG_NAME handle")) return result; result = MBI()->tag_get_handle( GLOBAL_ID_TAG_NAME, 1, MB_TYPE_INTEGER, id_tag, moab::MB_TAG_DENSE|moab::MB_TAG_CREAT ); if(gen::error(MB_SUCCESS != result, "could not get GLOBAL_ID_TAG_NAME handle")) return result; // get surface and volume sets MBRange surf_sets, vol_sets; // MBRange of set of surfaces and volumes // surface sets int dim = 2; void* input_dim[] = {&dim}; result = MBI()->get_entities_by_type_and_tag( input_set, MBENTITYSET, &geom_tag, input_dim, 1, surf_sets); if(MB_SUCCESS != result) { return result; } // volume sets dim = 3; result = MBI()->get_entities_by_type_and_tag( input_set, MBENTITYSET, &geom_tag, input_dim, 1, vol_sets); if(MB_SUCCESS != result) { return result; } //vertex sets dim= 0; MBRange verts; result = MBI()->get_entities_by_dimension(input_set, dim, verts, false); if(gen::error(MB_SUCCESS!=result, " could not get vertices from the mesh")) return result; if(gen::error(MB_SUCCESS!=result, "could not get vertex coordinates")) return result; if(verbose) { std::cout<< "number of verticies= " << verts.size() << std::endl; std::cout<< "number of surfaces= " << surf_sets.size() << std::endl; std::cout<< "number of volumes= " << vol_sets.size() << std::endl; } //initialize booleans to pass to make_mesh_watertight bool check_topology, test, sealed; check_topology=false; test=true; // initialize boolean for each set of tests bool test_set_result=true; //seal mesh and make sure it is entirely sealed // seal the model using make_watertight result=mw_func::make_mesh_watertight (input_set, facet_tolerance, false); if(gen::error(MB_SUCCESS!=result, "could not make the mesh watertight")) return result; // Lastly Check to see if make_watertight fixed the model result=cw_func::check_mesh_for_watertightness( input_set, facet_tolerance, sealed, test); if(gen::error(MB_SUCCESS!=result, "could not check model for watertightness")) return result; if(sealed) { std::cout << "PASS" << std::endl; } else { std::cout << "FAIL" << std::endl; test_set_result=false; } exit(0); }
MBErrorCode t_joint( MBTag normal_tag, const MBEntityHandle vert0, const MBEntityHandle vert1, const MBEntityHandle vert2 ) { struct triangles { MBEntityHandle before_tri; const MBEntityHandle *before; MBCartVect before_norm; MBEntityHandle after0[3]; MBEntityHandle after1[3]; MBCartVect after0_norm; MBCartVect after1_norm; MBEntityHandle surf_set; }; // Get all of the old information before changing anything. // This is important because once the // new connectivity is set stuff becomes stale. // get the edge // get endpoints of the edge MBErrorCode result; MBEntityHandle endpts[2] = { vert0, vert2 }; MBRange tris; result = MBI()->get_adjacencies( endpts, 2, 2, true, tris ); assert(MB_SUCCESS == result); //std::cout << "t_joint: tris.size()=" << tris.size() << std::endl; //MBI()->list_entities( tris ); triangles joints[tris.size()]; for(unsigned int i=0; i<tris.size(); i++) { joints[i].before_tri = tris[i]; // Find the surface set that the tri is in. MBRange surf_sets; result = MBI()->get_adjacencies( &joints[i].before_tri, 1, 4, false, surf_sets); assert(MB_SUCCESS == result); //std::cout << "t_joint: " << surf_sets.size() << " surface sets found for triangle" // << std::endl; // Check to make sure we found a set if(1 != surf_sets.size()) { std::cout << " t_joint: " << surf_sets.size() << " surface sets found for triangle " << joints[i].before_tri << std::endl; assert(1 == surf_sets.size()); //if(1!=surf_sets.size()) return MB_FAILURE; } joints[i].surf_set = surf_sets.front(); //std::cout << "t_joint: surf id=" << gen::geom_id_by_handle( joints[i].surf_set ) // << std::endl; //gen::print_triangle( joints[i].before_tri, false ); // get old connectivity int n_verts; result = MBI()->get_connectivity( joints[i].before_tri, joints[i].before, n_verts); if(MB_SUCCESS != result) std::cout << "result=" << result << std::endl; assert(MB_SUCCESS == result); if(3 != n_verts) std::cout << "n_verts=" << n_verts << std::endl; assert(3 == n_verts); // test to make sure not degenerate //if(conn[0]==conn[1] || conn[1]==conn[2] || conn[2]==conn[0]) { if( gen::triangle_degenerate( joints[i].before_tri )) { std::cout << " t_joint: degenerate input triangle" << std::endl; gen::print_triangle( joints[i].before_tri, false); return MB_FAILURE; } // make new connectivity for(int j=0; j<3; j++) { joints[i].after0[j] = (joints[i].before[j]==endpts[0]) ? vert1 : joints[i].before[j]; joints[i].after1[j] = (joints[i].before[j]==endpts[1]) ? vert1 : joints[i].before[j]; } // test to make sure not degenerate //if(conn0[0]==conn0[1] || conn0[1]==conn0[2] || conn0[2]==conn0[0]) { if(gen::triangle_degenerate( joints[i].after0[0], joints[i].after0[1], joints[i].after0[2])) { std::cout << " t_joint: degenerate output triangle 1" << std::endl; gen::print_triangle( joints[i].before_tri, false ); // return MB_FAILURE; } // test to make sure not degenerate //if(conn1[0]==conn1[1] || conn1[1]==conn1[2] || conn1[2]==conn1[0]) { if(gen::triangle_degenerate( joints[i].after1[0], joints[i].after1[1], joints[i].after1[2])) { std::cout << " t_joint: degenerate output triangle 2" << std::endl; gen::print_triangle( joints[i].before_tri, false ); //gen::print_triangle( *i, true ); //return MB_FAILURE; } // set the new connectivity on the original triangle result = MBI()->set_connectivity( joints[i].before_tri, joints[i].after0, 3 ); assert(MB_SUCCESS == result); // set the new connectivity on the new triangle MBEntityHandle new_tri; result = MBI()->create_element( MBTRI, joints[i].after1, 3, new_tri ); assert(MB_SUCCESS == result); // copy the original normal to the new triangle MBCartVect normal; result = MBI()->tag_get_data( normal_tag, &joints[i].before_tri, 1, &normal); assert(MB_SUCCESS == result); result = MBI()->tag_set_data( normal_tag, &new_tri, 1, &normal); assert(MB_SUCCESS == result); // add the new triangle to the same surface set as the original result = MBI()->add_entities( joints[i].surf_set, &new_tri, 1); assert(MB_SUCCESS == result); // catch-all to remove degenerate tris result = zip::delete_degenerate_tris( joints[i].before_tri ); if(gen::error(MB_SUCCESS!=result,"could not delete degenerate tri")) return result; result = zip::delete_degenerate_tris( new_tri ); if(gen::error(MB_SUCCESS!=result,"could not delete degenerate tri")) return result; //gen::print_triangle( tri, false ); //gen::print_triangle( new_tri, false ); } return MB_SUCCESS; }