MeshKit  1.0
zip.cpp
Go to the documentation of this file.
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   }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines