MeshKit
1.0
|
00001 #include <iostream> 00002 #include <vector> 00003 #include "meshkit/zip.hpp" 00004 #include "moab/OrientedBoxTreeTool.hpp" 00005 using namespace moab; 00006 namespace zip { 00007 struct triangles { 00008 EntityHandle before_tri; 00009 const EntityHandle *before; 00010 CartVect before_norm; 00011 EntityHandle after0[3]; 00012 EntityHandle after1[3]; 00013 CartVect after0_norm; 00014 CartVect after1_norm; 00015 EntityHandle surf_set; 00016 }; 00017 00018 ErrorCode t_joint( Tag normal_tag, 00019 const EntityHandle vert0, 00020 const EntityHandle vert1, 00021 const EntityHandle vert2, 00022 bool debug ) { 00023 // Get all of the old information before changing anything. 00024 // This is important because once the 00025 // new connectivity is set stuff becomes stale. 00026 // get the edge 00027 00028 // get endpoints of the edge 00029 ErrorCode result; 00030 EntityHandle endpts[2] = { vert0, vert2 }; 00031 Range tris; 00032 result = MBI()->get_adjacencies( endpts, 2, 2, true, tris ); 00033 assert(MB_SUCCESS == result); 00034 //std::cout << "t_joint: tris.size()=" << tris.size() << std::endl; 00035 //MBI()->list_entities( tris ); 00036 00037 std::vector<triangles> joints(tris.size()); 00038 for(unsigned int i=0; i<tris.size(); i++) { 00039 joints[i].before_tri = tris[i]; 00040 00041 // Find the surface set that the tri is in. 00042 Range surf_sets; 00043 result = MBI()->get_adjacencies( &joints[i].before_tri, 1, 4, false, surf_sets); 00044 assert(MB_SUCCESS == result); 00045 //std::cout << "t_joint: " << surf_sets.size() << " surface sets found for triangle" 00046 // << std::endl; 00047 00048 // Check to make sure we found a set 00049 if(1 != surf_sets.size()) { 00050 if(debug) std::cout << " t_joint: " << surf_sets.size() << " surface sets found for triangle " 00051 << joints[i].before_tri << std::endl; 00052 assert(1 == surf_sets.size()); 00053 //if(1!=surf_sets.size()) return MB_FAILURE; 00054 } 00055 joints[i].surf_set = surf_sets.front(); 00056 //std::cout << "t_joint: surf id=" << gen::geom_id_by_handle( joints[i].surf_set ) 00057 // << std::endl; 00058 //gen::print_triangle( joints[i].before_tri, false ); 00059 00060 // get old connectivity 00061 int n_verts; 00062 result = MBI()->get_connectivity( joints[i].before_tri, joints[i].before, n_verts); 00063 if(MB_SUCCESS != result) std::cout << "result=" << result << std::endl; 00064 assert(MB_SUCCESS == result); 00065 if(3 != n_verts) std::cout << "n_verts=" << n_verts << std::endl; 00066 assert(3 == n_verts); 00067 00068 // test to make sure not degenerate 00069 //if(conn[0]==conn[1] || conn[1]==conn[2] || conn[2]==conn[0]) { 00070 if( gen::triangle_degenerate( joints[i].before_tri ) && debug ) { 00071 std::cout << " t_joint: degenerate input triangle" << std::endl; 00072 gen::print_triangle( joints[i].before_tri, false); 00073 return MB_FAILURE; 00074 } 00075 00076 // make new connectivity 00077 for(int j=0; j<3; j++) { 00078 joints[i].after0[j] = (joints[i].before[j]==endpts[0]) ? vert1 : joints[i].before[j]; 00079 joints[i].after1[j] = (joints[i].before[j]==endpts[1]) ? vert1 : joints[i].before[j]; 00080 } 00081 00082 // test to make sure not degenerate 00083 //if(conn0[0]==conn0[1] || conn0[1]==conn0[2] || conn0[2]==conn0[0]) { 00084 if(gen::triangle_degenerate( joints[i].after0[0], joints[i].after0[1], 00085 joints[i].after0[2]) && debug ) { 00086 std::cout << " t_joint: degenerate output triangle 1" << std::endl; 00087 gen::print_triangle( joints[i].before_tri, false ); 00088 // return MB_FAILURE; 00089 } 00090 // test to make sure not degenerate 00091 //if(conn1[0]==conn1[1] || conn1[1]==conn1[2] || conn1[2]==conn1[0]) { 00092 if(gen::triangle_degenerate( joints[i].after1[0], joints[i].after1[1], 00093 joints[i].after1[2]) && debug) { 00094 std::cout << " t_joint: degenerate output triangle 2" << std::endl; 00095 gen::print_triangle( joints[i].before_tri, false ); 00096 //gen::print_triangle( *i, true ); 00097 //return MB_FAILURE; 00098 } 00099 00100 // set the new connectivity on the original triangle 00101 result = MBI()->set_connectivity( joints[i].before_tri, joints[i].after0, 3 ); 00102 assert(MB_SUCCESS == result); 00103 // set the new connectivity on the new triangle 00104 EntityHandle new_tri; 00105 result = MBI()->create_element( MBTRI, joints[i].after1, 3, new_tri ); 00106 assert(MB_SUCCESS == result); 00107 00108 // copy the original normal to the new triangle 00109 CartVect normal; 00110 result = MBI()->tag_get_data( normal_tag, &joints[i].before_tri, 1, &normal); 00111 assert(MB_SUCCESS == result); 00112 result = MBI()->tag_set_data( normal_tag, &new_tri, 1, &normal); 00113 assert(MB_SUCCESS == result); 00114 00115 // add the new triangle to the same surface set as the original 00116 result = MBI()->add_entities( joints[i].surf_set, &new_tri, 1); 00117 assert(MB_SUCCESS == result); 00118 00119 // catch-all to remove degenerate tris 00120 result = zip::delete_degenerate_tris( joints[i].before_tri ); 00121 if(gen::error(MB_SUCCESS!=result,"could not delete degenerate tri")) return result; 00122 result = zip::delete_degenerate_tris( new_tri ); 00123 if(gen::error(MB_SUCCESS!=result,"could not delete degenerate tri")) return result; 00124 00125 //gen::print_triangle( tri, false ); 00126 //gen::print_triangle( new_tri, false ); 00127 } 00128 return MB_SUCCESS; 00129 } 00130 00131 // Delete degenerate triangles in the range. 00132 ErrorCode delete_degenerate_tris( EntityHandle tri ) { 00133 ErrorCode result; 00134 const EntityHandle *con; 00135 int n_verts; 00136 result = MBI()->get_connectivity( tri, con, n_verts); 00137 assert(MB_SUCCESS == result); 00138 assert(3 == n_verts); 00139 if(con[0]==con[1] || con[1]==con[2] || con[2]==con[0]) { 00140 //std::cout << "delete_degenerate_tris: degenerate triangle=" << tri << " deleted" << std::endl; 00141 result = MBI()->delete_entities( &tri, 1 ); 00142 assert(MB_SUCCESS == result); 00143 } 00144 return result; 00145 } 00146 ErrorCode delete_degenerate_tris( Range tris ) { 00147 ErrorCode result = MB_SUCCESS; 00148 for(Range::iterator i=tris.begin(); i!=tris.end(); i++) { 00149 result = delete_degenerate_tris( *i ); 00150 assert(MB_SUCCESS == result); 00151 } 00152 return result; 00153 } 00154 00155 ErrorCode delete_adj_degenerate_tris( const EntityHandle adj_vert ) { 00156 // get the adjacent triangles 00157 ErrorCode result; 00158 Range tris; 00159 result = MBI()->get_adjacencies( &adj_vert, 1, 2, false, tris ); 00160 assert(MB_SUCCESS == result); 00161 result = delete_degenerate_tris( tris ); 00162 assert(MB_SUCCESS == result); 00163 return result; 00164 } 00165 00166 // Problem: MOAB can check for degenerate tris and delete them. 00167 // MOAB check the curves and arcs passed in to update the merged vertex, but 00168 // still ends up with degenerate edges. The curves that are in MOAB as sets 00169 // are updated but also contain degenerate edges due to merging. 00170 ErrorCode merge_verts( const EntityHandle keep_vert, 00171 const EntityHandle delete_vert, 00172 std::vector<EntityHandle> &arc0, 00173 std::vector<EntityHandle> &arc1 ) { 00174 00175 ErrorCode rval; 00176 // first update the arcs with the keep_vert 00177 for(std::vector<EntityHandle>::iterator i=arc0.begin(); i!=arc0.end(); ++i) { 00178 if(delete_vert == *i) *i = keep_vert; 00179 } 00180 for(std::vector<EntityHandle>::iterator i=arc1.begin(); i!=arc1.end(); ++i) { 00181 if(delete_vert == *i) *i = keep_vert; 00182 } 00183 00184 // UPDATE: This is slower than using the O(n) linear search above. 00185 // Let moab update adjacencies. Unless moab stores data is must be 00186 // merge-updated manually to prevent stale handles. 00187 /* EntityHandle arc0_set, arc1_set; 00188 rval = MBI()->create_meshset( MESHSET_TRACK_OWNER|MESHSET_ORDERED, arc0_set ); 00189 if(gen::error(MB_SUCCESS!=rval,"creating arc0_set failed")) return rval; 00190 rval = MBI()->create_meshset( MESHSET_TRACK_OWNER|MESHSET_ORDERED, arc1_set ); 00191 if(gen::error(MB_SUCCESS!=rval,"creating arc1_set failed")) return rval; 00192 rval = arc::set_meshset( arc0_set, arc0 ); 00193 if(gen::error(MB_SUCCESS!=rval,"setting arc0_set failed")) return rval; 00194 rval = arc::set_meshset( arc1_set, arc1 ); 00195 if(gen::error(MB_SUCCESS!=rval,"setting arc1_set failed")) return rval; 00196 */ 00197 00198 // get adjacent tris 00199 Range tris; 00200 EntityHandle verts[2]={keep_vert, delete_vert}; 00201 rval = MBI()->get_adjacencies( verts, 2, 2, false, tris, Interface::UNION ); 00202 if(gen::error(MB_SUCCESS!=rval,"getting adjacent tris failed")) return rval; 00203 //if(0 == tris.size()) { 00204 // std::cout << "merge_verts: cannot find any triangles adjacent to vertices" << std::endl; 00205 // return MB_ENTITY_NOT_FOUND; 00206 //} 00207 //gen::print_triangles( tris ); 00208 00209 // actually do the merge 00210 rval = MBI()->merge_entities( keep_vert, delete_vert, false, true ); 00211 if(gen::error(MB_SUCCESS!=rval,"merge entities failed")) return rval; 00212 //std::cout << " tris.size()=" << tris.size() << std::endl; 00213 00214 // delete degenerate tris 00215 rval = delete_degenerate_tris( tris ); 00216 if(gen::error(MB_SUCCESS!=rval,"deleting degenerate tris failed")) return rval; 00217 00218 // Get the merge-updated arcs back. 00219 /* rval = arc::get_meshset( arc0_set, arc0 ); 00220 if(gen::error(MB_SUCCESS!=rval,"getting arc0 set failed")) return rval; 00221 rval = arc::get_meshset( arc1_set, arc1 ); 00222 if(gen::error(MB_SUCCESS!=rval,"getting arc1 set failed")) return rval; 00223 rval = MBI()->delete_entities( &arc0_set, 1 ); 00224 if(gen::error(MB_SUCCESS!=rval,"deleting arc0_set failed")) return rval; 00225 rval = MBI()->delete_entities( &arc1_set, 1 ); 00226 if(gen::error(MB_SUCCESS!=rval,"deleting arc1_set failed")) return rval; 00227 */ 00228 00229 return MB_SUCCESS; 00230 } 00231 00232 // Test to make sure the triangle normal vectors have not been inverted. 00233 ErrorCode test_normals( const std::vector<CartVect> norms0, 00234 const std::vector<CartVect> norms1, 00235 std::vector<int> &inverted_tri_indices ) { 00236 assert(norms0.size() == norms1.size()); 00237 for(unsigned int i=0; i<norms0.size(); i++) { 00238 ErrorCode result = test_normals( norms0[i], norms1[i]); 00239 if(MB_SUCCESS != result) { 00240 //std::cout << "test_normals: failed on i=" << i << std::endl; 00241 inverted_tri_indices.push_back(i); 00242 } 00243 } 00244 return MB_SUCCESS; 00245 } 00246 ErrorCode test_normals( const CartVect norm0, const CartVect norm1 ) { 00247 if(0 > norm0 % norm1) { 00248 //std::cout << "test_normals: tri is inverted, dot product=" 00249 // << norm0 % norm1 << std::endl; 00250 return MB_FAILURE; 00251 } else { 00252 return MB_SUCCESS; 00253 } 00254 } 00255 00256 /* Accepts a range of inverted tris. Refacets affected surface so that no tris 00257 are inverted. */ 00258 ErrorCode remove_inverted_tris(Tag normal_tag, Range tris, const bool debug ) { 00259 00260 ErrorCode result; 00261 bool failures_occur = false; 00262 while(!tris.empty()) { 00263 00264 /* Get a group of triangles to re-facet. They must be adjacent to each other 00265 and in the same surface. */ 00266 Range tris_to_refacet; 00267 tris_to_refacet.insert( tris.front() ); 00268 Range surf_set; 00269 result = MBI()->get_adjacencies( tris_to_refacet, 4, false, surf_set ); 00270 assert(MB_SUCCESS == result); 00271 if(1 != surf_set.size()) { 00272 std::cout << "remove_inverted_tris: tri is in " << surf_set.size() 00273 << " surfaces" << std::endl; 00274 return MB_FAILURE; 00275 } 00276 00277 // get all tris in the surface 00278 Range surf_tris; 00279 result = MBI()->get_entities_by_type( surf_set.front(), MBTRI, surf_tris ); 00280 assert(MB_SUCCESS == result); 00281 00282 /* Find all of the adjacent inverted triangles of the same surface. Keep 00283 searching until a search returns no new triangles. */ 00284 bool search_again = true; 00285 while(search_again) { 00286 00287 // Here edges are being created. Remember to delete them. Outside of this 00288 // function. Skinning gets bogged down if unused MBEdges (from other 00289 // surfaces) accumulate. 00290 Range tri_edges; 00291 result = MBI()->get_adjacencies( tris_to_refacet, 1, true, tri_edges, 00292 Interface::UNION ); 00293 assert(MB_SUCCESS == result); 00294 Range connected_tris; 00295 result = MBI()->get_adjacencies( tri_edges, 2, false, connected_tris, 00296 Interface::UNION ); 00297 assert(MB_SUCCESS == result); 00298 result = MBI()->delete_entities( tri_edges ); 00299 assert(MB_SUCCESS == result); 00300 Range tris_to_refacet2 = intersect( tris_to_refacet, connected_tris ); 00301 tris_to_refacet2 = intersect( tris_to_refacet, surf_tris ); 00302 00303 if(tris_to_refacet.size() == tris_to_refacet2.size()) search_again = false; 00304 tris_to_refacet.swap( tris_to_refacet2 ); 00305 } 00306 00307 // Remove the inverted tris that will be refaceted. 00308 tris = subtract( tris, tris_to_refacet ); 00309 00310 // do edges already exist? 00311 Range temp; 00312 result = MBI()->get_entities_by_type(0, MBEDGE, temp ); 00313 assert(MB_SUCCESS == result); 00314 if(!temp.empty()) MBI()->list_entities( temp ); 00315 assert(temp.empty()); 00316 00317 00318 // keep enlarging patch until we have tried to refacet the entire surface 00319 int counter=0; 00320 while(true) { 00321 // do edges already exist? 00322 temp.clear(); 00323 result = MBI()->get_entities_by_type(0, MBEDGE, temp ); 00324 assert(MB_SUCCESS == result); 00325 if(!temp.empty()) MBI()->list_entities( temp ); 00326 assert(temp.empty()); 00327 00328 00329 counter++; 00330 // Only try enlarging each patch a few times 00331 if(48 == counter) { 00332 failures_occur = true; 00333 if(debug) std::cout << "remove_inverted_tris: ear clipping failed, counter=" 00334 << counter << std::endl; 00335 break; 00336 } 00337 // THIS PROVIDES A BAD EXIT. MUST FIX 00338 00339 // get the edges of the patch of inverted tris 00340 Range tri_edges; 00341 result = MBI()->get_adjacencies( tris_to_refacet, 1, true, tri_edges, 00342 Interface::UNION ); 00343 assert(MB_SUCCESS == result); 00344 00345 // get all adjacent tris to the patch of inverted tris in the surface 00346 Range adj_tris; 00347 result = MBI()->get_adjacencies( tri_edges, 2, false, adj_tris, 00348 Interface::UNION ); 00349 assert(MB_SUCCESS == result); 00350 result = MBI()->delete_entities( tri_edges ); 00351 assert(MB_SUCCESS == result); 00352 tris_to_refacet = intersect( surf_tris, adj_tris ); 00353 if(tris_to_refacet.empty()) continue; 00354 //gen::print_triangles( tris_to_refacet ); 00355 00356 // get an area-weighted normal of the adj_tris 00357 CartVect plane_normal(0,0,0); 00358 //for(unsigned int i=0; i<tris_to_refacet.size(); i++) { 00359 for(Range::iterator i=tris_to_refacet.begin(); i!=tris_to_refacet.end(); i++) { 00360 CartVect norm; 00361 result = MBI()->tag_get_data( normal_tag, &(*i), 1, &norm); 00362 assert(MB_SUCCESS == result); 00363 double area; 00364 result = gen::triangle_area( *i, area ); 00365 assert(MB_SUCCESS == result); 00366 if(debug) std::cout << "norm=" << norm << " area=" << area << std::endl; 00367 //plane_normal += norm*area; 00368 plane_normal += norm; 00369 } 00370 plane_normal.normalize(); 00371 00372 // do edges already exist? 00373 temp.clear(); 00374 result = MBI()->get_entities_by_type(0, MBEDGE, temp ); 00375 assert(MB_SUCCESS == result); 00376 if(!temp.empty()) MBI()->list_entities( temp ); 00377 assert(temp.empty()); 00378 00379 // skin the tris 00380 Range unordered_edges; 00381 //Skinner tool(MBI()); 00382 //result = tool.find_skin( tris_to_refacet, 1, unordered_edges, false ); 00383 result = gen::find_skin( tris_to_refacet, 1, unordered_edges, false ); 00384 assert(MB_SUCCESS == result); 00385 if(unordered_edges.empty()) { 00386 // do edges already exist? 00387 Range temp; 00388 result = MBI()->get_entities_by_type(0, MBEDGE, temp ); 00389 assert(MB_SUCCESS == result); 00390 if(!temp.empty()) MBI()->list_entities( temp ); 00391 assert(temp.empty()); 00392 continue; 00393 } 00394 00395 //std::cout << "remove_inverted_tris: surf_id=" 00396 // << gen::geom_id_by_handle(surf_set.front()) << std::endl; 00397 //result = MBI()->list_entities( tris_to_refacet ); 00398 //assert(MB_SUCCESS == result); 00399 00400 // assemble into a polygon 00401 std::vector<EntityHandle> polygon_of_verts; 00402 result = arc::order_verts_by_edge( unordered_edges, polygon_of_verts ); 00403 if(debug) gen::print_loop( polygon_of_verts ); 00404 //assert(MB_SUCCESS == result); 00405 if(MB_SUCCESS != result) { 00406 if(debug) std::cout << "remove_inverted_tris: couldn't order polygon by edge" << std::endl; 00407 return MB_FAILURE; 00408 } 00409 00410 // remember to remove edges 00411 result = MBI()->delete_entities( unordered_edges ); 00412 assert(MB_SUCCESS == result); 00413 00414 // remove the duplicate endpt 00415 polygon_of_verts.pop_back(); 00416 00417 // the polygon should have at least 3 verts 00418 if(3 > polygon_of_verts.size()) { 00419 if(debug) std::cout << "remove_inverted_tris: polygon has too few points" << std::endl; 00420 return MB_FAILURE; 00421 } 00422 00423 // orient the polygon with the triangles (could be backwards) 00424 // get the first adjacent tri 00425 EntityHandle edge[2] = { polygon_of_verts[0], polygon_of_verts[1] }; 00426 Range one_tri; 00427 result = MBI()->get_adjacencies( edge, 2, 2, false, one_tri ); 00428 assert(MB_SUCCESS == result); 00429 one_tri = intersect( tris_to_refacet, one_tri ); 00430 assert(1 == one_tri.size()); 00431 const EntityHandle *conn; 00432 int n_conn; 00433 result = MBI()->get_connectivity( one_tri.front(), conn, n_conn ); 00434 assert(MB_SUCCESS == result); 00435 assert(3 == n_conn); 00436 if( (edge[0]==conn[1] && edge[1]==conn[0]) || 00437 (edge[0]==conn[2] && edge[1]==conn[1]) || 00438 (edge[0]==conn[0] && edge[1]==conn[2]) ) { 00439 reverse( polygon_of_verts.begin(), polygon_of_verts.end() ); 00440 if(debug) std::cout << "remove_inverted_tris: polygon reversed" << std::endl; 00441 } 00442 00443 /* facet the polygon. Returns MB_FAILURE if it fails to facet the polygon. */ 00444 Range new_tris; 00445 result = gen::ear_clip_polygon( polygon_of_verts, plane_normal, new_tris ); 00446 00447 // break if the refaceting is successful 00448 if(MB_SUCCESS == result) { 00449 // summarize tri area 00450 for(Range::iterator i=new_tris.begin(); i!=new_tris.end(); i++) { 00451 double area; 00452 result = gen::triangle_area( *i, area ); 00453 assert(MB_SUCCESS == result); 00454 if(debug) std::cout << " new tri area=" << area << std::endl; 00455 } 00456 00457 // check the new normals 00458 std::vector<CartVect> new_normals; 00459 result = gen::triangle_normals( new_tris, new_normals ); 00460 if(MB_SUCCESS != result) return result; 00461 00462 // test the new triangles 00463 std::vector<int> inverted_tri_indices; 00464 std::vector<CartVect> normals ( new_normals.size(), plane_normal ); 00465 result = zip::test_normals( normals, new_normals, inverted_tri_indices ); 00466 assert(MB_SUCCESS == result); 00467 if(inverted_tri_indices.empty()) { 00468 // remove the tris that were re-faceted 00469 tris = subtract( tris, tris_to_refacet ); 00470 result = MBI()->remove_entities( surf_set.front(), tris_to_refacet ); 00471 assert(MB_SUCCESS == result); 00472 result = MBI()->delete_entities( tris_to_refacet ); 00473 assert(MB_SUCCESS == result); 00474 00475 // add the new tris to the surf set 00476 result = MBI()->add_entities( surf_set.front(), new_tris ); 00477 assert(MB_SUCCESS == result); 00478 00479 // put the new normals on the new tris 00480 result = gen::save_normals( new_tris, normal_tag ); 00481 assert(MB_SUCCESS == result); 00482 if(debug) std::cout << "remove_inverted_tris: success fixing a patch" << std::endl; 00483 break; 00484 } 00485 } 00486 00487 // remember to delete the tris that were created from the failed ear clipping 00488 else { 00489 result = MBI()->delete_entities( new_tris ); 00490 assert(MB_SUCCESS == result); 00491 } 00492 00493 // If the entire surface could not be ear clipped, give up 00494 if (tris_to_refacet.size() == surf_tris.size()) { 00495 if(debug) std::cout << "remove_inverted_tris: ear clipping entire surface failed" 00496 << std::endl; 00497 return MB_FAILURE; 00498 } 00499 00500 } // loop until the entire surface has attempted to be refaceted 00501 } // loop over each patch of inverted tris 00502 00503 if(failures_occur) { 00504 if(debug) std::cout << "remove_inverted_facets: at least one failure occured" << std::endl; 00505 return MB_FAILURE; 00506 } else { 00507 return MB_SUCCESS; 00508 } 00509 } 00510 00511 00512 // we do not merge edges, just vert. check the verts 00513 ErrorCode test_zipping(const double FACET_TOL, 00514 const std::vector< std::vector<EntityHandle> > arcs ) { 00515 ErrorCode result = MB_SUCCESS; 00516 00517 // make sure each arc has the same number of edges 00518 for(unsigned int i=1; i<arcs.size(); i++) { 00519 if(arcs[0].size() != arcs[i].size()) { 00520 std::cout << "The curve has " << arcs[0].size() << " edges but arc " 00521 << i << " has " << arcs[i].size() << " edges." << std::endl; 00522 gen::print_arcs( arcs ); 00523 return MB_FAILURE; 00524 } 00525 } 00526 00527 // loop over every edge of the curve (first arc) 00528 for(unsigned int i=0; i<arcs[0].size()-1; i++) { 00529 // check for degenerate edge 00530 if(arcs[0][i] == arcs[0][i+1]) { 00531 std::cout << "degenerate edge at pos " << i << " and " << i+1 << " with verts " 00532 << arcs[0][i] << " and " << arcs[0][i+1] << std::endl; 00533 return MB_FAILURE; 00534 } 00535 00536 // check for edge of zero dist 00537 double d = gen::dist_between_verts( arcs[0][i], arcs[0][i+1] ); 00538 if(FACET_TOL >= d) { 00539 std::cout << "edge length=" << d << " betwee pos " << i << " and " << i+1 00540 << " with verts " << arcs[0][i] << " and " << arcs[0][i+1] << std::endl; 00541 return MB_FAILURE; 00542 } 00543 00544 // loop over every arc 00545 for( unsigned int j=0; j<arcs.size(); j++) { 00546 // make sure vertices match 00547 if(arcs[0][i]!=arcs[j][i] || arcs[0][i+1]!=arcs[j][i+1]) { 00548 std::cout << "arc " << j << " vertices do not match curve vertices, pos= " 00549 << i << "/" << arcs[j].size() << std::endl; 00550 return MB_FAILURE; 00551 } 00552 } 00553 00554 // make sure triangles have area 00555 Range tris; 00556 result = MBI()->get_adjacencies( &(arcs[0][i]), 2, 2, false, tris ); 00557 assert(MB_SUCCESS == result); 00558 for(Range::iterator k=tris.begin(); k!=tris.end(); k++) { 00559 // We know that there are not degenerate edges along the curve. 00560 // Sometimes degenerate tris are created due to merging curve endpts. 00561 // here we do not remove tri from the surf meshset, but we should 00562 if( gen::triangle_degenerate(*k) ) { 00563 //result = MBI()->delete_entities( &(*k), 1); 00564 //assert(MB_SUCCESS == result); 00565 std::cout << " arc=" << 0 << " pos=" << i << " vert=" << arcs[0][i] 00566 << " degenerate triangle" << std::endl; 00567 gen::print_triangle(*k, false); 00568 //print_edge( edge ); 00569 //continue; 00570 return MB_FAILURE; 00571 } 00572 00573 double area; 00574 result = gen::triangle_area( *k, area ); 00575 assert(MB_SUCCESS == result); 00576 // I found a valid tri on a curve with only one edge (1e-5 long) 00577 // that had an area of 1e-11. 00578 if(1e-8 > area) { 00579 std::cout << " arc=" << 0 << " pos=" << i << " vert=" << arcs[0][i] 00580 << " small triangle " << std::endl; 00581 gen::print_triangle(*k, false); 00582 //print_edge( edge ); 00583 gen::print_arcs( arcs ); 00584 //if(0.0 >= area) return MB_FAILURE; 00585 } 00586 } 00587 } 00588 return result; 00589 } 00590 00591 00592 }