MBErrorCode delete_degenerate_tris( MBRange tris ) { MBErrorCode result; for(MBRange::iterator i=tris.begin(); i!=tris.end(); i++) { result = delete_degenerate_tris( *i ); assert(MB_SUCCESS == result); } return MB_SUCCESS; }
MBErrorCode build_obbs(moab::OrientedBoxTreeTool *obbTree, MBRange &surfs, MBRange &volumes) { MBErrorCode rval = MB_SUCCESS; for (MBRange::iterator i = surfs.begin(); i != surfs.end(); ++i) { MBEntityHandle root; MBRange tris; rval = MBI()->get_entities_by_dimension( *i, 2, tris ); if (MB_SUCCESS != rval) return rval; if (tris.empty()) std::cerr << "WARNING: Surface " << *i << " has no facets." << std::endl; rval = obbTree->build( tris, root ); if (MB_SUCCESS != rval) return rval; #pragma omp critical rval = MBI()->add_entities( root, &*i, 1 ); if (MB_SUCCESS != rval) return rval; } return MB_SUCCESS; }
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; }
// we do not merge edges, just vert. check the verts MBErrorCode test_zipping(const double FACET_TOL, const std::vector< std::vector<MBEntityHandle> > arcs ) { MBErrorCode result; // make sure each arc has the same number of edges for(unsigned int i=1; i<arcs.size(); i++) { if(arcs[0].size() != arcs[i].size()) { std::cout << "The curve has " << arcs[0].size() << " edges but arc " << i << " has " << arcs[i].size() << " edges." << std::endl; gen::print_arcs( arcs ); return MB_FAILURE; } } // loop over every edge of the curve (first arc) for(unsigned int i=0; i<arcs[0].size()-1; i++) { // check for degenerate edge if(arcs[0][i] == arcs[0][i+1]) { std::cout << "degenerate edge at pos " << i << " and " << i+1 << " with verts " << arcs[0][i] << " and " << arcs[0][i+1] << std::endl; return MB_FAILURE; } // check for edge of zero dist double d = gen::dist_between_verts( arcs[0][i], arcs[0][i+1] ); if(FACET_TOL >= d) { std::cout << "edge length=" << d << " betwee pos " << i << " and " << i+1 << " with verts " << arcs[0][i] << " and " << arcs[0][i+1] << std::endl; return MB_FAILURE; } // loop over every arc for( unsigned int j=0; j<arcs.size(); j++) { // make sure vertices match if(arcs[0][i]!=arcs[j][i] || arcs[0][i+1]!=arcs[j][i+1]) { std::cout << "arc " << j << " vertices do not match curve vertices, pos= " << i << "/" << arcs[j].size() << std::endl; return MB_FAILURE; } } // make sure triangles have area MBRange tris; result = MBI()->get_adjacencies( &(arcs[0][i]), 2, 2, false, tris ); assert(MB_SUCCESS == result); for(MBRange::iterator k=tris.begin(); k!=tris.end(); k++) { // We know that there are not degenerate edges along the curve. // Sometimes degenerate tris are created due to merging curve endpts. // here we do not remove tri from the surf meshset, but we should if( gen::triangle_degenerate(*k) ) { //result = MBI()->delete_entities( &(*k), 1); //assert(MB_SUCCESS == result); std::cout << " arc=" << 0 << " pos=" << i << " vert=" << arcs[0][i] << " degenerate triangle" << std::endl; gen::print_triangle(*k, false); //print_edge( edge ); //continue; return MB_FAILURE; } double area; result = gen::triangle_area( *k, area ); assert(MB_SUCCESS == result); // I found a valid tri on a curve with only one edge (1e-5 long) // that had an area of 1e-11. if(1e-8 > area) { std::cout << " arc=" << 0 << " pos=" << i << " vert=" << arcs[0][i] << " small triangle " << std::endl; gen::print_triangle(*k, false); //print_edge( edge ); gen::print_arcs( arcs ); //if(0.0 >= area) return MB_FAILURE; } } } return MB_SUCCESS; }