opennurbs_brep_isvalid.cpp
Go to the documentation of this file.
00001 /* $NoKeywords: $ */
00002 /*
00003 //
00004 // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved.
00005 // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
00006 // McNeel & Associates.
00007 //
00008 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
00009 // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
00010 // MERCHANTABILITY ARE HEREBY DISCLAIMED.
00011 //                              
00012 // For complete openNURBS copyright information see <http://www.opennurbs.org>.
00013 //
00015 */
00016 
00017 #include "pcl/surface/3rdparty/opennurbs/opennurbs.h"
00018 
00019 bool
00020 ON_Brep::IsValidVertexTopology( int vertex_index, ON_TextLog* text_log ) const
00021 {
00022   if ( vertex_index < 0 || vertex_index >= m_V.Count() )
00023   {
00024     if ( text_log )
00025       text_log->Print("brep vertex_index = %d (should be >=0 and <%d=brep.m_V.Count() ).\n",
00026                       vertex_index, m_V.Count());
00027     return false;
00028   }
00029   const ON_BrepVertex& vertex = m_V[vertex_index];
00030   if ( vertex.m_vertex_index != vertex_index )
00031   {
00032     if ( text_log )
00033     {
00034       text_log->Print("brep.m_V[%d] vertex is not valid.\n",vertex_index);
00035       text_log->PushIndent();
00036       text_log->Print("vertex.m_vertex_index = %d (should be %d).\n",
00037                        vertex.m_vertex_index, vertex_index );
00038       text_log->PopIndent();
00039     }
00040     return false;
00041   }
00042 
00043   const int vertex_edge_count = vertex.m_ei.Count();
00044   int i, j, vei, ei;
00045   for ( vei = 0; vei < vertex_edge_count; vei++ ) 
00046   {
00047     ei = vertex.m_ei[vei];
00048 
00049     if ( ei < 0 || ei >= m_E.Count() )
00050     {
00051       if ( text_log )
00052       {
00053         text_log->Print("brep.m_V[%d] vertex is not valid.\n",vertex_index);
00054         text_log->PushIndent();
00055         text_log->Print("vertex.m_ei[%d] = %d (should be >=0 and <%d).\n", vei, ei, m_E.Count());
00056         text_log->PopIndent();
00057       }
00058       return false;
00059     }
00060 
00061     const ON_BrepEdge& edge = m_E[ei];
00062 
00063     if ( ei != edge.m_edge_index )
00064     {
00065       if ( text_log )
00066       {
00067         text_log->Print("brep.m_V[%d] vertex is not valid.\n",vertex_index);
00068         text_log->PushIndent();
00069         text_log->Print("vertex.m_ei[%d] = %d is a deleted edge.\n", vei, ei);
00070         text_log->PopIndent();
00071       }
00072       return false;
00073     }
00074 
00075     if ( edge.m_vi[0] != vertex_index && edge.m_vi[1] != vertex_index )
00076     {
00077       if ( text_log )
00078       {
00079         text_log->Print("brep.m_V[%d] vertex or brep.m_E[%d] edge is not valid.\n",vertex_index,ei);
00080         text_log->PushIndent();
00081         text_log->Print("vertex.m_ei[%d] = %d but brep.m_E[%d].m_vi[] = [%d,%d]. "
00082                         "At least one edge m_vi[] value should be %d.\n",
00083                         vei,ei,ei,edge.m_vi[0],edge.m_vi[1],vertex_index);
00084         text_log->PopIndent();
00085       }
00086       return false;
00087     }
00088 
00089     for ( i = 0; i < vei; i++ ) 
00090     {
00091       if ( vertex.m_ei[i] == ei ) 
00092       {
00093         // edge should be closed
00094         if ( edge.m_vi[0] != vertex_index || edge.m_vi[1] != vertex_index )
00095         {
00096           if ( text_log )
00097           {
00098             text_log->Print("brep.m_V[%d] vertex is not valid.\n",vertex_index);
00099             text_log->PushIndent();
00100             text_log->Print("vertex.m_ei[%d] and vertex.m_ei[%d] = %d but brep.m_E[%d].m_vi[0] = %d",
00101                              i,vei,ei,ei,edge.m_vi[0]);
00102             text_log->Print("and ON_Brep.m_E[%d].m_vi[1] = %d (both m_vi[] values should be %d).\n",
00103                             ei,edge.m_vi[1],vertex_index);
00104             text_log->PopIndent();
00105           }
00106           return false;
00107         }
00108         for (j = i+1; j < vei; j++ ) 
00109         {
00110           if ( vertex.m_ei[j] == ei )
00111           {
00112             if ( text_log )
00113             {
00114               text_log->Print("brep.m_V[%d] vertex is not valid.\n",vertex_index);
00115               text_log->PushIndent();
00116               text_log->Print("vertex.m_ei[%d,%d,%d] = %d. An open edge index should appear once\n",i,vei,j,ei);
00117               text_log->Print("in vertex.m_ei[] and a closed edge index should appear twice.\n");
00118               text_log->PopIndent();
00119             }
00120             return false;
00121           }
00122         }
00123         break;
00124       }
00125     }
00126 
00127   }
00128 
00129   return true;
00130 }
00131 
00132 bool
00133 ON_Brep::IsValidFaceTopology( int face_index, ON_TextLog* text_log  ) const
00134 {
00135   if ( face_index < 0 || face_index >= m_F.Count() )
00136   {
00137     if ( text_log )
00138     {
00139       text_log->Print("brep face_index = %d (should be >=0 and <%d=brep.m_F.Count()).\n",
00140                       face_index, m_F.Count());
00141     }
00142     return false;
00143   }
00144   const ON_BrepFace& face = m_F[face_index];
00145   if ( face.m_face_index != face_index )
00146   {
00147     if ( text_log )
00148     {
00149       text_log->Print("brep.m_F[%d] face is not valid.\n",face_index);
00150       text_log->PushIndent();
00151       text_log->Print("face.m_face_index = %d (should be %d).\n",
00152                        face.m_face_index, face_index );
00153       text_log->PopIndent();
00154     }
00155     return false;
00156   }
00157   if ( face.m_brep != this )
00158   {
00159     if ( text_log )
00160     {
00161       text_log->Print("brep.m_F[%d] face is not valid.\n",face_index);
00162       text_log->PushIndent();
00163       text_log->Print("face.m_brep does not point to parent brep.\n");
00164       text_log->PopIndent();
00165     }
00166     return false;
00167   }
00168 
00169   const int face_loop_count = face.m_li.Count();
00170   if ( face_loop_count <= 0 )
00171   {
00172     if ( text_log )
00173     {
00174       text_log->Print("brep.m_F[%d] face is not valid.\n",face_index);
00175       text_log->PushIndent();
00176       text_log->Print("face.m_li.Count() <= 0 (should be >= 1)\n");
00177       text_log->PopIndent();
00178     }
00179     return false;
00180   }
00181 
00182   int i, fli, li;
00183   for ( fli = 0; fli < face_loop_count; fli++ ) 
00184   {
00185     li = face.m_li[fli];
00186     for ( i = 0; i < fli; i++ ) 
00187     {
00188       if ( face.m_li[i] == li )
00189       {
00190         if ( text_log )
00191         {
00192           text_log->Print("brep.m_F[%d] face is not valid.\n",face_index);
00193           text_log->PushIndent();
00194           text_log->Print("face.m_li[%d]=face.m_li[%d]=%d (a loop index should appear once in face.m_li[])\n",
00195                           fli,i,li);
00196           text_log->PopIndent();
00197         }
00198         return false;
00199       }
00200     }
00201     if ( !IsValidLoop( li, text_log ) )
00202     {
00203       if ( text_log )
00204       {
00205         text_log->Print("brep.m_F[%d] face is not valid.\n",face_index);
00206         text_log->PushIndent();
00207         text_log->Print("brep.m_L[face.m_li[%d]=%d] is not valid.\n",fli,li);
00208         text_log->PopIndent();
00209       }
00210       return false;
00211     }
00212     const ON_BrepLoop& loop = m_L[li];
00213     if ( loop.m_loop_index != li )
00214     {
00215       if ( text_log )
00216       {
00217         text_log->Print("brep.m_F[%d] face is not valid.\n",face_index);
00218         text_log->PushIndent();
00219         text_log->Print("face.m_li[%d]=%d is a deleted loop\n",
00220                         fli,li);
00221         text_log->PopIndent();
00222       }
00223       return false;
00224     }
00225     if ( loop.m_fi != face_index )
00226     {
00227       if ( text_log )
00228       {
00229         text_log->Print("brep.m_F[%d] face is not valid.\n",face_index);
00230         text_log->PushIndent();
00231         text_log->Print("face.m_li[%d]=%d but brep.m_L[%d].m_fi=%d (m_fi should be %d)\n",
00232                         fli,li,li,loop.m_fi,face_index);
00233         text_log->PopIndent();
00234       }
00235       return false;
00236     }
00237     if ( fli == 0 ) {
00238       if ( loop.m_type != ON_BrepLoop::outer )
00239       {
00240         if ( text_log )
00241         {
00242           text_log->Print("brep.m_F[%d] face is not valid.\n",face_index);
00243           text_log->PushIndent();
00244           text_log->Print("brep.m_L[face.m_li[0]=%d].m_type is not outer.\n",li);
00245           text_log->PopIndent();
00246         }
00247         return false;
00248       }
00249     }
00250     else {
00251       if ( loop.m_type != ON_BrepLoop::inner )
00252       {
00253         if ( text_log )
00254         {
00255           text_log->Print("brep.m_F[%d] face is not valid.\n",face_index);
00256           text_log->PushIndent();
00257           text_log->Print("brep.m_L[face.m_li[%d]=%d].m_type is not inner.\n",fli,li);
00258           text_log->PopIndent();
00259         }
00260         return false;
00261       }
00262     }
00263   }
00264 
00265   const int si = face.m_si;
00266   if ( si < 0 || si >= m_S.Count() )
00267   {
00268     if ( text_log )
00269     {
00270       text_log->Print("brep.m_F[%d] face is not valid.\n",face_index);
00271       text_log->PushIndent();
00272       text_log->Print("face.m_si=%d (should be >=0 and <%d=m_S.Count())\n",
00273                       face.m_si,m_S.Count());                      
00274       text_log->PopIndent();
00275     }
00276     return false;
00277   }
00278 
00279   if ( 0 == m_S[si] )
00280   {
00281     if ( text_log )
00282     {
00283       text_log->Print("brep.m_F[%d] face is not valid.\n",face_index);
00284       text_log->PushIndent();
00285       text_log->Print("brep.m_S[face.m_si=%d] is NULL\n",face.m_si);
00286       text_log->PopIndent();
00287     }
00288     return false;
00289   }
00290 
00291   if ( 0 == face.ProxySurface() )
00292   {
00293     if ( text_log )
00294     {
00295       text_log->Print("brep.m_F[%d] face is not valid.\n",face_index);
00296       text_log->PushIndent();
00297       text_log->Print("face.ProxySurface() is NULL\n");
00298       text_log->PopIndent();
00299     }
00300     return false;
00301   }
00302 
00303   if ( m_S[si] != face.ProxySurface() )
00304   {
00305     if ( text_log )
00306     {
00307       text_log->Print("brep.m_F[%d] face is not valid.\n",face_index);
00308       text_log->PushIndent();
00309       text_log->Print("brep.m_S[face.m_si=%d] != face.ProxySurface().\n",si);
00310       text_log->PopIndent();
00311     }
00312     return false;
00313   }
00314 
00315   if ( face.ProxySurfaceIsTransposed() )
00316   {
00317     if ( text_log )
00318     {
00319       text_log->Print("brep.m_F[%d] face is not valid.\n",face_index);
00320       text_log->PushIndent();
00321       text_log->Print("face.ProxySurfaceIsTransposed() is true.\n");
00322       text_log->PopIndent();
00323     }
00324     return false;
00325   }
00326 
00327   return true; 
00328 }
00329 
00330 bool
00331 ON_Brep::IsValidEdgeTopology( int edge_index, ON_TextLog* text_log ) const
00332 {
00333   if ( edge_index < 0 || edge_index >= m_E.Count() )
00334   {
00335     if ( text_log )
00336       text_log->Print("brep edge_index = %d (should be >=0 and <%d=brep.m_E.Count() ).\n",
00337                       edge_index, m_E.Count());
00338     return false;
00339   }
00340   const ON_BrepEdge& edge = m_E[edge_index];
00341   if ( edge.m_edge_index != edge_index )
00342   {
00343     if ( text_log )
00344     {
00345       text_log->Print("brep.m_E[%d] edge is not valid.\n",edge_index);
00346       text_log->PushIndent();
00347       text_log->Print("edge.m_edge_index = %d (should be %d).\n",
00348                        edge.m_edge_index, edge_index );
00349       text_log->PopIndent();
00350     }
00351     return false;
00352   }
00353   if ( edge.m_brep != this )
00354   {
00355     if ( text_log )
00356     {
00357       text_log->Print("brep.m_E[%d] edge is not valid.\n",edge_index);
00358       text_log->PushIndent();
00359       text_log->Print("edge.m_brep does not point to parent brep\n");
00360       text_log->PopIndent();
00361     }
00362     return false;
00363   }
00364 
00365   if ( !edge.IsValid(text_log) )
00366   {
00367     if ( text_log )
00368     {
00369       text_log->Print("brep.m_E[%d] edge is not valid.\n",edge_index);
00370       text_log->PushIndent();
00371       text_log->Print("edge is not a valid.\n");
00372       text_log->PopIndent();
00373     }
00374     return false;
00375   }
00376 
00377   // This checks to make sure that m_C3[] and the edge's proxy information is valid.
00378   // This isn't exactly "topology", but if this stuff isn't set right, then the
00379   // "geometry" checks might crash.
00380 
00381   const int c3i = edge.m_c3i;
00382   if ( c3i < 0 || c3i >= m_C3.Count() )
00383   {
00384     if ( text_log )
00385     {
00386       text_log->Print("brep.m_E[%d] edge is not valid.\n",edge_index);
00387       text_log->PushIndent();
00388       text_log->Print("edge.m_c3i = %d (should be >=0 and <%d=m_C3.Count()\n",
00389                       edge.m_c3i,m_C3.Count() );
00390       text_log->PopIndent();
00391     }
00392     return false;
00393   }
00394   
00395   if ( 0 == m_C3[c3i] )
00396   {
00397     if ( text_log )
00398       text_log->Print("ON_Brep.m_E[%d].m_c3i = %d, but m_C3[%d] is NULL.\n",edge_index,c3i,c3i);
00399     return false;
00400   }
00401 
00402   if ( 0 == edge.ProxyCurve() )
00403   {
00404     if ( text_log )
00405       text_log->Print("brep.m_E[%d].m_c3i = %d, but edge.ProxyCurve() is NULL.\n",edge_index,c3i);
00406     return false;
00407   }
00408 
00409   if ( m_C3[c3i] != edge.ProxyCurve() )
00410   {
00411     if ( text_log )
00412     {
00413       text_log->Print("brep.m_E[%d] edge is not valid.\n",edge_index);
00414       text_log->PushIndent();
00415       text_log->Print("m_E[%d].m_c3i=%d, m_C3[%d] != m_E[%d].ProxyCurve()\n",edge_index,c3i,c3i,edge_index);
00416       text_log->PopIndent();
00417     }
00418     return false;
00419   }
00420 
00421   ON_Interval proxy_sub_dom = edge.ProxyCurveDomain();
00422   if ( !proxy_sub_dom.IsIncreasing() )
00423   {
00424     if ( text_log )
00425     {
00426       text_log->Print("brep.m_E[%d] edge is not valid.\n",edge_index);
00427       text_log->PushIndent();
00428       text_log->Print("m_E[%d].ProxyCurveDomain() = (%g,%g) is not increasing\n",edge_index,proxy_sub_dom[0],proxy_sub_dom[1]);
00429       text_log->PopIndent();
00430     }
00431     return false;
00432   }
00433 
00434   ON_Interval c3_dom = m_C3[c3i]->Domain();
00435   if ( !c3_dom.Includes(proxy_sub_dom) )
00436   {
00437     if ( text_log )
00438     {
00439       text_log->Print("brep.m_E[%d] edge is not valid.\n",edge_index);
00440       text_log->PushIndent();
00441       text_log->Print("m_C3[%d].Domain() = (%g,%g) does not inlclude m_E[%d].ProxyCurveDomain() = (%g,%g) is not increasing\n",
00442                       c3i,c3_dom[0],c3_dom[1],edge_index,proxy_sub_dom[0],proxy_sub_dom[1]);
00443       text_log->PopIndent();
00444     }
00445     return false;
00446   }
00447 
00448   ON_Interval edge_dom = edge.Domain();
00449   if ( !edge_dom.IsIncreasing() )
00450   {
00451     if ( text_log )
00452     {
00453       text_log->Print("brep.m_E[%d] trim is not valid.\n",edge_index);
00454       text_log->PushIndent();
00455       text_log->Print("m_E[%d].Domain() = (%g,%g) is not increasing\n",edge_index,edge_dom[0],edge_dom[1]);
00456       text_log->PopIndent();
00457     }
00458     return false;
00459   }
00460 
00461 
00462 
00463   const int vi0 = edge.m_vi[0];
00464   const int vi1 = edge.m_vi[1];
00465   if ( vi0 < 0 || vi0 >= m_V.Count() )
00466   {
00467     if ( text_log )
00468     {
00469       text_log->Print("brep.m_E[%d] edge is not valid.\n",edge_index);
00470       text_log->PushIndent();
00471       text_log->Print("edge.m_vi[0]=%d (should be >=0 and <%d=m_V.Count()\n",
00472                        vi0, m_V.Count() );
00473       text_log->PopIndent();
00474     }
00475     return false;
00476   }
00477   if ( vi1 < 0 || vi1 >= m_V.Count() )
00478   {
00479     if ( text_log )
00480     {
00481       text_log->Print("brep.m_E[%d] edge is not valid.\n",edge_index);
00482       text_log->PushIndent();
00483       text_log->Print("edge.m_vi[1]=%d (should be >=0 and <%d=m_V.Count()\n",
00484                        vi1, m_V.Count() );
00485       text_log->PopIndent();
00486     }
00487     return false;
00488   }
00489   int evi;
00490   for ( evi = 0; evi < 2; evi++ ) 
00491   {
00492     const ON_BrepVertex& vertex = m_V[edge.m_vi[evi]];
00493 
00494     if ( edge.m_vi[evi] != vertex.m_vertex_index )
00495     {
00496       if ( text_log )
00497       {
00498         text_log->Print("brep.m_E[%d] edge is not valid.\n",edge_index);
00499         text_log->PushIndent();
00500         text_log->Print("edge.m_vi[%d]=%d is a deleted vertex\n",
00501                          evi,edge.m_vi[evi] );
00502         text_log->PopIndent();
00503       }
00504       return false;
00505     }
00506 
00507 
00508     const int vertex_edge_count = vertex.m_ei.Count();
00509     ON_BOOL32 bFoundIt = false;
00510     int vei;
00511     for ( vei = 0; vei < vertex_edge_count && !bFoundIt; vei++ ) 
00512     {
00513       bFoundIt = (vertex.m_ei[vei] == edge_index);
00514     }
00515     if ( !bFoundIt )
00516     {
00517       if ( text_log )
00518       {
00519         text_log->Print("brep.m_E[%d] edge is not valid.\n",edge_index);
00520         text_log->PushIndent();
00521         text_log->Print("edge.m_vi[%d]=%d but edge is not referenced in m_V[%d].m_ei[]\n",
00522                          evi,edge.m_vi[evi],edge.m_vi[evi] );
00523         text_log->PopIndent();
00524       }
00525       return false;
00526     }
00527   }
00528 
00529   const int edge_trim_count = edge.m_ti.Count();
00530   if ( edge_trim_count < 0 )
00531   {
00532     if ( text_log )
00533     {
00534       text_log->Print("brep.m_E[%d] edge is not valid.\n",edge_index);
00535       text_log->PushIndent();
00536       text_log->Print("edge.m_ti.Count() < 0\n");
00537       text_log->PopIndent();
00538     }
00539     return false;
00540   }
00541   int i, eti, ti;
00542   for (eti = 0; eti < edge_trim_count; eti++ )
00543   {
00544     ti = edge.m_ti[eti];
00545     if ( ti < 0 || ti >= m_T.Count() )
00546     {
00547       if ( text_log )
00548       {
00549         text_log->Print("brep.m_E[%d] edge is not valid.\n",edge_index);
00550         text_log->PushIndent();
00551         text_log->Print("edge.m_ti[%d]=%d (should be >=0 and <%d=m_T.Count())\n",eti,ti);
00552         text_log->PopIndent();
00553       }
00554       return false;
00555     }
00556     if ( m_T[ti].m_trim_index != ti )
00557     {
00558       if ( text_log )
00559       {
00560         text_log->Print("brep.m_E[%d] edge is not valid.\n",edge_index);
00561         text_log->PushIndent();
00562         text_log->Print("edge.m_ti[%d]=%d is a deleted trim\n",eti,ti);
00563         text_log->PopIndent();
00564       }
00565       return false;
00566     }
00567     for ( i = 0; i < eti; i++ ) 
00568     {
00569       if ( edge.m_ti[i] == ti )
00570       {
00571         if ( text_log )
00572         {
00573           text_log->Print("brep.m_E[%d] edge is not valid.\n",edge_index);
00574           text_log->PushIndent();
00575           text_log->Print("edge.m_ti[%d]=edge.m_ti[%d]=%d (a trim should be referenced once).\n",i,eti,ti);
00576           text_log->PopIndent();
00577         }
00578         return false;
00579       }
00580     }
00581     const ON_BrepTrim& trim = m_T[ti];
00582     if ( trim.m_ei != edge_index )
00583     {
00584       if ( text_log )
00585       {
00586         text_log->Print("brep.m_E[%d] edge is not valid.\n",edge_index);
00587         text_log->PushIndent();
00588         text_log->Print("edge.m_ti[%d]=%d but brep.m_T[%d].m_ei=%d\n",eti,ti,ti,trim.m_ei);
00589         text_log->PopIndent();
00590       }
00591       return false;
00592     }
00593   }
00594 
00595   return true;
00596 }
00597 
00598 bool
00599 ON_Brep::IsValidLoopTopology( int loop_index, ON_TextLog* text_log ) const
00600 {
00601   int lti, ti;
00602 
00603   if ( loop_index < 0 || loop_index >= m_L.Count() )
00604   {
00605     if ( text_log )
00606       text_log->Print("brep loop_index = %d (should be >=0 and <%d=brep.m_L.Count() ).\n",
00607                       loop_index, m_L.Count());
00608     return false;
00609   }
00610   const ON_BrepLoop& loop = m_L[loop_index];
00611   if ( loop.m_loop_index != loop_index )
00612   {
00613     if ( text_log )
00614     {
00615       text_log->Print("brep.m_L[%d] loop is not valid.\n",loop_index);
00616       text_log->PushIndent();
00617       text_log->Print("loop.m_loop_index = %d (should be %d).\n",
00618                        loop.m_loop_index, loop_index );
00619       text_log->PopIndent();
00620     }
00621     return false;
00622   }
00623   if ( loop.m_brep != this )
00624   {
00625     if ( text_log )
00626     {
00627       text_log->Print("brep.m_L[%d] loop is not valid.\n",loop_index);
00628       text_log->PushIndent();
00629       text_log->Print("loop.m_brep does not point to parent brep\n");
00630       text_log->PopIndent();
00631     }
00632     return false;
00633   }
00634 
00635   if ( loop.m_fi < 0 || loop.m_fi >= m_F.Count() )
00636   {
00637     if ( text_log )
00638       text_log->Print("ON_Brep.m_L[%d].m_fi = %d is not invalid.\n",loop_index,loop.m_fi);
00639     return false;
00640   }
00641   if ( m_F[loop.m_fi].m_face_index != loop.m_fi )
00642   {
00643     if ( text_log )
00644       text_log->Print("ON_Brep.m_L[%d].m_fi = %d is a deleted face.\n",loop_index,loop.m_fi);
00645     return false;
00646   }
00647   if ( loop.m_ti.Count() < 1 )
00648   {
00649       if ( text_log )
00650         text_log->Print("ON_Brep.m_L[%d].m_ti.Count() = %d  (should be > 0 )\n",loop_index,loop.m_ti.Count());
00651       return false;
00652   }
00653 
00654   for ( lti = 0; lti < loop.m_ti.Count(); lti++ )
00655   {
00656     ti = loop.m_ti[lti];
00657     if ( ti < 0 || ti >= m_T.Count() )
00658     {
00659       if ( text_log )
00660         text_log->Print("ON_Brep.m_L[%d].m_ti[%d] = %d is not invalid.\n",loop_index,lti,ti);
00661       return false;
00662     }
00663     const ON_BrepTrim& trim = m_T[ti];
00664     if ( trim.m_trim_index != ti )
00665     {
00666       if ( text_log )
00667         text_log->Print("ON_Brep.m_L[%d].m_ti[%d] = %d is a deleted trim.\n",loop_index,lti,ti);
00668       return false;
00669     }
00670     if ( trim.m_li != loop_index )
00671     {
00672       if ( text_log )
00673       {
00674         text_log->Print("brep loop m_L[%d] or trim m_T[%d] is not valid.\n",loop_index,ti);
00675         text_log->PushIndent();
00676         text_log->Print("loop.m_ti[%d] = %d != %d =trim.m_li\n",lti,ti,trim.m_li);
00677         text_log->PopIndent();
00678       }
00679       return false;
00680     }
00681   }
00682 
00683 
00684   int first_trim_ti = -4;
00685   int first_trim_vi0 = -3;
00686   int prev_trim_vi1 = -2;
00687   int prev_trim_ti=-9;
00688   for ( lti = 0; lti < loop.m_ti.Count(); lti++ )
00689   {
00690     const ON_BrepTrim& trim = m_T[loop.m_ti[lti]];
00691     if ( 0 == lti )
00692     {
00693       first_trim_ti = loop.m_ti[lti];
00694       first_trim_vi0 = trim.m_vi[0];
00695     }
00696     else if ( prev_trim_vi1 != trim.m_vi[0] )
00697     {
00698       // 23 May 2003 Dale Lear
00699       //     Added this test to make sure adjacent trims
00700       //     in a loop shared vertices.
00701       if ( text_log )
00702       {
00703          text_log->Print("brep loop m_L[%d] is not valid.\n",loop_index);
00704          text_log->PushIndent();
00705          text_log->Print("m_T[loop.m_ti[%d]=%d].m_vi[1] = %d != m_T[loop.m_ti[%d]=%d].m_vi[0]=%d.\n",
00706                           lti-1,prev_trim_ti,prev_trim_vi1,lti,loop.m_ti[lti],trim.m_vi[0]);
00707          text_log->PopIndent();
00708       }
00709       return false;
00710     }
00711     prev_trim_ti = loop.m_ti[lti];
00712     prev_trim_vi1 = trim.m_vi[1];
00713   }
00714 
00715   if ( first_trim_ti >= 0 && first_trim_vi0 != prev_trim_vi1 )
00716   {
00717     // 23 May 2003 Dale Lear
00718     //     Added this test to make sure adjacent trims
00719     //     in a loop shared vertices.
00720     if ( text_log )
00721     {
00722        text_log->Print("brep loop m_L[%d] is not valid.\n",loop_index);
00723        text_log->PushIndent();
00724        text_log->Print("m_T[loop.m_ti[%d]=%d].m_vi[1] = %d != m_T[loop.m_ti[0]=%d].m_vi[0]=%d.\n",
00725                         loop.m_ti.Count()-1,prev_trim_ti,prev_trim_vi1,first_trim_ti,first_trim_vi0);
00726        text_log->PopIndent();
00727     }
00728     return false;
00729   }
00730 
00731 
00732   return true;
00733 }
00734 
00735 bool
00736 ON_Brep::IsValidTrimTopology( int trim_index, ON_TextLog* text_log ) const
00737 {
00738   if ( trim_index < 0 || trim_index >= m_T.Count() )
00739   {
00740     if ( text_log )
00741       text_log->Print("brep trim_index = %d (should be >=0 and <%d=brep.m_T.Count() ).\n",
00742                       trim_index, m_T.Count());
00743     return false;
00744   }
00745   const ON_BrepTrim& trim = m_T[trim_index];
00746   if ( trim.m_trim_index != trim_index )
00747   {
00748     if ( text_log )
00749     {
00750       text_log->Print("brep.m_T[%d] trim is not valid.\n",trim_index);
00751       text_log->PushIndent();
00752       text_log->Print("trim.m_trim_index = %d (should be %d).\n",
00753                        trim.m_trim_index, trim_index );
00754       text_log->PopIndent();
00755     }
00756     return false;
00757   }
00758   if ( trim.m_brep != this )
00759   {
00760     if ( text_log )
00761     {
00762       text_log->Print("brep.m_T[%d] trim is not valid.\n",trim_index);
00763       text_log->PushIndent();
00764       text_log->Print("trim.m_brep does not point to parent brep\n");
00765       text_log->PopIndent();
00766     }
00767     return false;
00768   }
00769 
00770   if ( trim.m_vi[0] < 0 || trim.m_vi[0] >= m_V.Count() )
00771   {
00772     if ( text_log )
00773       text_log->Print("ON_Brep.m_T[%d].m_vi[0] = %d is not invalid.\n",trim_index,trim.m_vi[0]);
00774     return false;
00775   }
00776   if ( trim.m_vi[1] < 0 || trim.m_vi[1] >= m_V.Count() )
00777   {
00778     if ( text_log )
00779       text_log->Print("ON_Brep.m_T[%d].m_vi[1] = %d is not invalid.\n",trim_index,trim.m_vi[1]);
00780     return false;
00781   }
00782 
00783   if ( m_V[trim.m_vi[0]].m_vertex_index != trim.m_vi[0] )
00784   {
00785     if ( text_log )
00786       text_log->Print("ON_Brep.m_T[%d].m_vi[0] is deleted.\n",trim_index);
00787     return false;
00788   }
00789   if ( m_V[trim.m_vi[1]].m_vertex_index != trim.m_vi[1] )
00790   {
00791     if ( text_log )
00792       text_log->Print("ON_Brep.m_T[%d].m_vi[1] is deleted.\n",trim_index);
00793     return false;
00794   }
00795 
00796   if ( trim.m_c2i < 0 || trim.m_c2i >= m_C2.Count() )
00797   {
00798     if ( text_log )
00799       text_log->Print("ON_Brep.m_T[%d].m_c2i = %d is not valid.\n",trim_index,trim.m_c2i);
00800     return false;
00801   }
00802 
00803   if ( 0 == m_C2[trim.m_c2i] )
00804   {
00805     if ( text_log )
00806       text_log->Print("ON_Brep.m_T[%d].m_c2i = %d, but m_C2[%d] is NULL.\n",trim_index,trim.m_c2i,trim.m_c2i);
00807     return false;
00808   }
00809 
00810   if ( 0 == trim.ProxyCurve() )
00811   {
00812     if ( text_log )
00813       text_log->Print("brep.m_T[%d].m_c2i = %d, but trim.ProxyCurve() is NULL.\n",trim_index,trim.m_c2i);
00814     return false;
00815   }
00816 
00817   if ( m_C2[trim.m_c2i] != trim.ProxyCurve() )
00818   {
00819     if ( text_log )
00820     {
00821       text_log->Print("brep.m_T[%d] trim is not valid.\n",trim_index);
00822       text_log->PushIndent();
00823       text_log->Print("m_T[%d].m_c2i=%d, m_C2[%d] != m_T[%d].ProxyCurve()\n",
00824                       trim_index, trim.m_c2i, trim.m_c2i, trim_index);
00825       text_log->PopIndent();
00826     }
00827     return false;
00828   }
00829 
00830   ON_Interval proxy_sub_dom = trim.ProxyCurveDomain();
00831   if ( !proxy_sub_dom.IsIncreasing() )
00832   {
00833     if ( text_log )
00834     {
00835       text_log->Print("brep.m_T[%d] trim is not valid.\n",trim_index);
00836       text_log->PushIndent();
00837       text_log->Print("m_T[%d].ProxyCurveDomain() = (%g,%g) is not increasing\n",trim_index,proxy_sub_dom[0],proxy_sub_dom[1]);
00838       text_log->PopIndent();
00839     }
00840     return false;
00841   }
00842 
00843   ON_Interval c2_dom = m_C2[trim.m_c2i]->Domain();
00844   if ( !c2_dom.Includes(proxy_sub_dom) )
00845   {
00846     if ( text_log )
00847     {
00848       text_log->Print("brep.m_T[%d] trim is not valid.\n",trim_index);
00849       text_log->PushIndent();
00850       text_log->Print("m_C2[%d].Domain() = (%g,%g) does not include m_T[%d].ProxyCurveDomain() = (%g,%g) is not increasing\n",
00851                       trim.m_c2i,c2_dom[0],c2_dom[1],
00852                       trim_index,proxy_sub_dom[0],proxy_sub_dom[1]);
00853       text_log->PopIndent();
00854     }
00855     return false;
00856   }
00857 
00858   ON_Interval trim_dom = trim.Domain();
00859   if ( !trim_dom.IsIncreasing() )
00860   {
00861     if ( text_log )
00862     {
00863       text_log->Print("brep.m_T[%d] trim is not valid.\n",trim_index);
00864       text_log->PushIndent();
00865       text_log->Print("m_T[%d].Domain() = (%g,%g) is not increasing\n",trim_index,trim_dom[0],trim_dom[1]);
00866       text_log->PopIndent();
00867     }
00868     return false;
00869   }
00870 
00871   if ( trim.m_li < 0 || trim.m_li >= m_L.Count() )
00872   {
00873     if ( text_log )
00874       text_log->Print("ON_Brep.m_T[%d].m_li = %d is not valid.\n",trim_index,trim.m_li);
00875     return false;
00876   }
00877 
00878   const ON_BrepLoop& loop = m_L[trim.m_li];
00879 
00880   if ( loop.m_loop_index != trim.m_li )
00881   {
00882     if ( text_log )
00883       text_log->Print("ON_Brep.m_T[%d].m_li = %d is a deleted loop.\n",trim_index,trim.m_li);
00884     return false;
00885   }
00886 
00887   bool bFoundTrim = false;
00888   int lti, loop_trim_count = loop.m_ti.Count();
00889   for ( lti = 0; lti < loop_trim_count && !bFoundTrim; lti++ )
00890   {
00891     if ( loop.m_ti[lti] == trim_index )
00892     {
00893       bFoundTrim = true;
00894       break;
00895     }
00896   }
00897   if ( !bFoundTrim )
00898   {
00899     if ( text_log )
00900     {
00901       text_log->Print("brep.m_T[%d] trim or brep.m_L[%d] loop is not valid.\n",trim_index,trim.m_li);
00902       text_log->PushIndent();
00903       text_log->Print("trim.m_li = %d but loop.m_ti[] does not contain %d (should appear once in).\n",
00904                       trim.m_li,trim_index);
00905       text_log->PopIndent();
00906     }
00907     return false;
00908   }
00909 
00910   if ( trim.m_type == ON_BrepTrim::singular )
00911   {
00912     // trim has no 3d edge
00913     if ( trim.m_ei != -1 )
00914     {
00915       if ( text_log )
00916         text_log->Print("ON_Brep.m_T[%d].m_type = singular, but m_ei = %d (should be -1).\n",trim_index,trim.m_ei);
00917       return false;
00918     }
00919     if ( trim.m_bRev3d )
00920     {
00921       if ( text_log )
00922         text_log->Print("ON_Brep.m_T[%d].m_type = singular, but m_bRev3d = %d (should be 0).\n",trim_index,trim.m_bRev3d);
00923       return false;
00924     }
00925     if ( trim.m_vi[0] != trim.m_vi[1] )
00926     {
00927       if ( text_log )
00928         text_log->Print("ON_Brep.m_T[%d].m_type = singular, but m_vi = (%d,%d) (should be same vertex index).\n",
00929                         trim_index,trim.m_vi[0],trim.m_vi[1]);
00930       return false;
00931     }
00932   }
00933   else
00934   {
00935     // trim should be connected to a 3d edge
00936     if ( trim.m_ei < 0 || trim.m_ei >= m_E.Count() )
00937     {
00938       if ( text_log )
00939         text_log->Print("ON_Brep.m_T[%d].m_ei = %d is not invalid.\n",trim_index,trim.m_ei);
00940       return false;
00941     }
00942   
00943     const ON_BrepEdge& edge = m_E[trim.m_ei];
00944     if ( edge.m_edge_index != trim.m_ei )
00945     {
00946       if ( text_log )
00947         text_log->Print("ON_Brep.m_T[%d].m_ei is deleted.\n",trim_index);
00948       return false;
00949     }
00950 
00951     const int evi0 = trim.m_bRev3d ? 1 : 0;
00952     const int evi1 = trim.m_bRev3d ? 0 : 1;
00953     if ( trim.m_vi[0] != edge.m_vi[evi0] )
00954     {
00955       if ( text_log )
00956         text_log->Print("ON_Brep.m_T[%d].m_bRev3d = %d, but m_vi[0] != m_E[m_ei].m_vi[%d].\n",trim_index,trim.m_bRev3d,evi0);
00957       return false;
00958     }
00959     if ( trim.m_vi[1] != edge.m_vi[evi1] )
00960     {
00961       if ( text_log )
00962         text_log->Print("ON_Brep.m_T[%d].m_bRev3d = %d, but m_vi[0] != m_E[m_ei].m_vi[%d].\n",trim_index,trim.m_bRev3d,evi1);
00963       return false;
00964     }
00965   }
00966 
00967   return true;
00968 }
00969 
00970 bool
00971 ON_Brep::IsValidTopology( ON_TextLog* text_log ) const
00972 {
00973   const int curve2d_count = m_C2.Count();
00974   const int curve3d_count = m_C3.Count();
00975   const int surface_count = m_S.Count();
00976   const int vertex_count  = m_V.Count();
00977   const int edge_count    = m_E.Count();
00978   const int trim_count    = m_T.Count();
00979   const int loop_count    = m_L.Count();
00980   const int face_count    = m_F.Count();
00981 
00982   int vi, ei, fi, ti, li;
00983 
00984   if ( 0 == face_count && 0 == edge_count && 0 == vertex_count )
00985   {
00986     if ( text_log )
00987       text_log->Print( "ON_Brep has no faces, edges, or vertices\n");
00988     return false;
00989   }
00990 
00991   if ( 0 != face_count )
00992   {
00993     if ( 0 == edge_count )
00994     {
00995       if ( text_log )
00996         text_log->Print( "ON_Brep has no edges.\n");
00997       return false;
00998     }
00999     if ( 0 == loop_count )
01000     {
01001       if ( text_log )
01002         text_log->Print( "ON_Brep has no loops.\n");
01003       return false;
01004     }
01005     if ( 0 == surface_count )
01006     {
01007       if ( text_log )
01008         text_log->Print( "ON_Brep has no surfaces.\n");
01009       return false;
01010     }
01011     if ( 0 == trim_count )
01012     {
01013       if ( text_log )
01014         text_log->Print( "ON_Brep has no trims.\n");
01015       return false;
01016     }
01017     if ( 0 == curve2d_count )
01018     {
01019       if ( text_log )
01020         text_log->Print( "ON_Brep has no 2d curves.\n");
01021       return false;
01022     }
01023   }
01024 
01025   if ( 0 != edge_count )
01026   {
01027     if ( 0 == curve3d_count )
01028     {
01029       if ( text_log )
01030         text_log->Print( "ON_Brep has no 3d curves.\n");
01031       return false;
01032     }
01033     if ( 0 == vertex_count )
01034     {
01035       if ( text_log )
01036         text_log->Print( "ON_Brep has no vertices.\n");
01037       return false;
01038     }
01039   }
01040 
01041   // check element indices match array positions
01042   for ( vi = 0; vi < vertex_count; vi++ ) 
01043   {
01044     if ( m_V[vi].m_vertex_index == -1 )
01045     {
01046       const ON_BrepVertex& vertex = m_V[vi];
01047       if ( vertex.m_ei.Count() > 0 )
01048       {
01049         if ( text_log )
01050           text_log->Print( "ON_Brep.m_V[%d] is deleted (m_vertex_index = -1) but vertex.m_ei.Count() = %d.\n",
01051                            vi, vertex.m_ei.Count() );
01052         return false;
01053       }
01054     }
01055     else if ( m_V[vi].m_vertex_index != vi )
01056     {
01057       if ( text_log )
01058         text_log->Print( "ON_Brep.m_V[%d].m_vertex_index = %d (should be %d)\n",
01059                          vi, m_V[vi].m_vertex_index, vi );
01060       return false;
01061     }
01062   }
01063 
01064   for ( ei = 0; ei < edge_count; ei++ ) 
01065   {
01066     if ( m_E[ei].m_edge_index == -1 )
01067     {
01068       const ON_BrepEdge& edge = m_E[ei];
01069       if ( edge.m_ti.Count() > 0 )
01070       {
01071         if ( text_log )
01072           text_log->Print( "ON_Brep.m_E[%d] is deleted (m_edge_index = -1) but edge.m_ei.Count() = %d.\n",
01073                            ei, edge.m_ti.Count() );
01074         return false;
01075       }
01076       if ( edge.m_c3i != -1 )
01077       {
01078         if ( text_log )
01079           text_log->Print( "ON_Brep.m_E[%d] is deleted (m_edge_index = -1) but edge.m_c3i=%d (should be -1).\n",
01080                            ei, edge.m_c3i );
01081         return false;
01082       }
01083       if ( edge.ProxyCurve() )
01084       {
01085         if ( text_log )
01086           text_log->Print( "ON_Brep.m_E[%d] is deleted (m_edge_index = -1) but edge.m_curve is not NULL.\n",
01087                            ei );
01088         return false;
01089       }
01090       if ( edge.m_vi[0] != -1 )
01091       {
01092         if ( text_log )
01093           text_log->Print( "ON_Brep.m_E[%d] is deleted (m_edge_index = -1) but edge.m_vi[0]=%d (should be -1).\n",
01094                            ei, edge.m_vi[0] );
01095         return false;
01096       }
01097       if ( edge.m_vi[1] != -1 )
01098       {
01099         if ( text_log )
01100           text_log->Print( "ON_Brep.m_E[%d] is deleted (m_edge_index = -1) but edge.m_vi[1]=%d (should be -1).\n",
01101                            ei, edge.m_vi[1] );
01102         return false;
01103       }
01104     }
01105     else if ( m_E[ei].m_edge_index != ei )
01106     {
01107       if ( text_log )
01108         text_log->Print( "ON_Brep.m_E[%d].m_edge_index = %d (should be %d)\n",
01109                          ei, m_E[ei].m_edge_index, ei );
01110       return false;
01111     }
01112   }
01113 
01114   for ( ti = 0; ti < trim_count; ti++ ) 
01115   {
01116     if ( m_T[ti].m_trim_index == -1 )
01117     {
01118       const ON_BrepTrim& trim = m_T[ti];
01119       if ( trim.m_ei != -1 )
01120       {
01121         if ( text_log )
01122           text_log->Print( "ON_Brep.m_T[%d] is deleted (m_trim_index = -1) but trim.m_ei=%d (should be -1).\n",
01123                            ti, trim.m_ei );
01124         return false;
01125       }
01126       if ( trim.m_li != -1 )
01127       {
01128         if ( text_log )
01129           text_log->Print( "ON_Brep.m_T[%d] is deleted (m_trim_index = -1) but trim.m_li=%d (should be -1).\n",
01130                            ti, trim.m_li );
01131         return false;
01132       }
01133       if ( trim.m_c2i != -1 )
01134       {
01135         if ( text_log )
01136           text_log->Print( "ON_Brep.m_T[%d] is deleted (m_trim_index = -1) but trim.m_c2i=%d (should be -1).\n",
01137                            ti, trim.m_c2i );
01138         return false;
01139       }
01140       if ( trim.m_vi[0] != -1 )
01141       {
01142         if ( text_log )
01143           text_log->Print( "ON_Brep.m_T[%d] is deleted (m_trim_index = -1) but trim.m_vi[0]=%d (should be -1).\n",
01144                            ti, trim.m_vi[0] );
01145         return false;
01146       }
01147       if ( trim.m_vi[1] != -1 )
01148       {
01149         if ( text_log )
01150           text_log->Print( "ON_Brep.m_T[%d] is deleted (m_trim_index = -1) but trim.m_vi[1]=%d (should be -1).\n",
01151                            ti, trim.m_vi[1] );
01152         return false;
01153       }
01154     }
01155     else if ( m_T[ti].m_trim_index != ti  )
01156     {
01157       if ( text_log )
01158         text_log->Print( "ON_Brep.m_T[%d].m_trim_index = %d (should be %d)\n",
01159                          ti, m_T[ti].m_trim_index, ti );
01160       return false;
01161     }
01162     else if ( !m_T[ti].IsValid( text_log ) )
01163     {
01164       if ( text_log )
01165         text_log->Print( "ON_Brep.m_T[%d] is not valid\n",ti );
01166       return false;
01167     }
01168   }
01169 
01170   for ( li = 0; li < loop_count; li++ ) 
01171   {
01172     if ( m_L[li].m_loop_index == -1 )
01173     {
01174       const ON_BrepLoop& loop = m_L[li];
01175       if ( loop.m_fi != -1 )
01176       {
01177         if ( text_log )
01178           text_log->Print( "ON_Brep.m_L[%d] is deleted (m_loop_index = -1) but loop.m_fi=%d (should be -1).\n",
01179                            li, loop.m_fi );
01180         return false;
01181       }
01182       if ( loop.m_ti.Count() > 0 )
01183       {
01184         if ( text_log )
01185           text_log->Print( "ON_Brep.m_L[%d] is deleted (m_loop_index = -1) but loop.m_ti.Count()=%d.\n",
01186                            li, loop.m_ti.Count() );
01187         return false;
01188       }
01189     }
01190     else if ( m_L[li].m_loop_index != li )
01191     {
01192       if ( text_log )
01193         text_log->Print( "ON_Brep.m_L[%d].m_loop_index = %d (should be %d)\n",
01194                          li, m_L[li].m_loop_index, li );
01195       return false;
01196     }
01197   }
01198 
01199   for ( fi = 0; fi < face_count; fi++ ) 
01200   {
01201     if ( m_F[fi].m_face_index == -1 )
01202     {
01203       const ON_BrepFace& face = m_F[fi];
01204       if ( face.m_si != -1 )
01205       {
01206         if ( text_log )
01207           text_log->Print( "ON_Brep.m_F[%d] is deleted (m_face_index = -1) but face.m_si=%d (should be -1).\n",
01208                            fi, face.m_si );
01209         return false;
01210       }
01211       if ( face.ProxySurface() )
01212       {
01213         if ( text_log )
01214           text_log->Print( "ON_Brep.m_F[%d] is deleted (m_face_index = -1) but face.ProxySurface() is not NULL.\n",
01215                            fi );
01216         return false;
01217       }
01218       if ( face.m_li.Count() > 0 )
01219       {
01220         if ( text_log )
01221           text_log->Print( "ON_Brep.m_F[%d] is deleted (m_face_index = -1) but face.m_li.Count()=%d.\n",
01222                            fi, face.m_li.Count() );
01223         return false;
01224       }
01225     }
01226     else if ( m_F[fi].m_face_index != fi )
01227     {
01228       if ( text_log )
01229         text_log->Print( "ON_Brep.m_F[%d].m_face_index = %d (should be %d)\n",
01230                          fi, m_F[fi].m_face_index, fi );
01231       return false;
01232     }
01233   }
01234 
01235   // check vertices
01236   for ( vi = 0; vi < vertex_count; vi++ ) {
01237     if ( m_V[vi].m_vertex_index == -1 )
01238       continue;
01239     if ( !IsValidVertexTopology( vi, text_log ) ) {
01240       if ( text_log )
01241         text_log->Print("ON_Brep.m_V[%d] is invalid.\n",vi);
01242       return false;
01243     }
01244   }
01245 
01246   // check edges
01247   for ( ei = 0; ei < edge_count; ei++ ) 
01248   {
01249     if ( m_E[ei].m_edge_index == -1 )
01250       continue;
01251     if ( !IsValidEdgeTopology( ei, text_log ) ) {
01252       if ( text_log )
01253         text_log->Print("ON_Brep.m_E[%d] is invalid.\n",ei);
01254       return false;
01255     }
01256   }
01257 
01258   // check faces
01259   for ( fi = 0; fi < face_count; fi++ ) 
01260   {
01261     if ( m_F[fi].m_face_index == -1 )
01262       continue;
01263     if ( !IsValidFaceTopology( fi, text_log ) ) {
01264       if ( text_log )
01265         text_log->Print("ON_Brep.m_F[%d] is invalid.\n",fi);
01266       return false;
01267     }
01268   }
01269 
01270   // check trims
01271   for ( ti = 0; ti < trim_count; ti++ )
01272   {
01273     const ON_BrepTrim& trim = m_T[ti];
01274     if ( trim.m_trim_index == -1 )
01275       continue;
01276     if ( !IsValidTrimTopology( ti, text_log ) ) {
01277       if ( text_log )
01278         text_log->Print("ON_Brep.m_T[%d] is invalid.\n",ti);
01279       return false;
01280     }
01281   }
01282 
01283   // check loops
01284   for ( li = 0; li < loop_count; li++ )
01285   {
01286     const ON_BrepLoop& loop = m_L[li];
01287     if ( loop.m_loop_index == -1 )
01288       continue;
01289     if ( !IsValidLoopTopology( li, text_log ) ) {
01290       if ( text_log )
01291         text_log->Print("ON_Brep.m_L[%d] is invalid.\n",li);
01292       return false;
01293     }
01294   }
01295 
01296   return true;
01297 }
01298 
01299 
01303 
01304 bool
01305 ON_Brep::IsValidVertexGeometry( int vertex_index, ON_TextLog* text_log ) const
01306 {
01307   if ( vertex_index < 0 || vertex_index >= m_V.Count() )
01308   {
01309     if ( text_log )
01310       text_log->Print("brep vertex_index = %d (should be >=0 and <%d=brep.m_V.Count() ).\n",
01311                       vertex_index, m_V.Count());
01312     return false;
01313   }
01314   const ON_BrepVertex& vertex = m_V[vertex_index];
01315   if ( vertex.m_vertex_index != vertex_index )
01316   {
01317     if ( text_log )
01318     {
01319       text_log->Print("brep.m_V[%d] vertex is not valid.\n",vertex_index);
01320       text_log->PushIndent();
01321       text_log->Print("vertex.m_vertex_index = %d (should be %d).\n",
01322                        vertex.m_vertex_index, vertex_index );
01323       text_log->PopIndent();
01324     }
01325     return false;
01326   }
01327 
01328   if ( !vertex.point.IsValid() )
01329   {
01330     if ( text_log )
01331     {
01332       text_log->Print("brep.m_V[%d] vertex geometry is not valid.\n",vertex_index);
01333       text_log->PushIndent();
01334       text_log->Print("vertex.point = (%g,%g,%g) is not valid.\n",vertex.point.x,vertex.point.y,vertex.point.z );
01335       text_log->PopIndent();
01336     }
01337     return false;
01338   }
01339   return true;
01340 }
01341 
01342 bool
01343 ON_Brep::IsValidEdgeGeometry( int edge_index, ON_TextLog* text_log ) const
01344 {
01345   if ( edge_index < 0 || edge_index >= m_E.Count() )
01346   {
01347     if ( text_log )
01348       text_log->Print("brep edge_index = %d (should be >=0 and <%d=brep.m_E.Count() ).\n",
01349                       edge_index, m_E.Count());
01350     return false;
01351   }
01352   const ON_BrepEdge& edge = m_E[edge_index];
01353   if ( edge.m_edge_index != edge_index )
01354   {
01355     if ( text_log )
01356     {
01357       text_log->Print("brep.m_E[%d] edge is not valid.\n",edge_index);
01358       text_log->PushIndent();
01359       text_log->Print("edge.m_edge_index = %d (should be %d).\n",
01360                        edge.m_edge_index, edge_index );
01361       text_log->PopIndent();
01362     }
01363     return false;
01364   }
01365 
01366   int vi0 = edge.m_vi[0];
01367   int vi1 = edge.m_vi[1];
01368   if ( edge.IsClosed() ) 
01369   {
01370     if ( vi0 != vi1 )
01371     {
01372       if ( text_log )
01373       {
01374         text_log->Print("brep.m_E[%d] edge is not valid.\n",edge_index);
01375         text_log->PushIndent();
01376         text_log->Print("edge.m_vi[]=(%d,%d) but edge.IsClosed() is true\n",
01377                          vi0,vi1);
01378         text_log->PopIndent();
01379       }
01380       return false;
01381     }
01382   }
01383   else {
01384     if ( vi0 == vi1 )
01385     {
01386       if ( text_log )
01387       {
01388         text_log->Print("brep.m_E[%d] edge is not valid.\n",edge_index);
01389         text_log->PushIndent();
01390         text_log->Print("edge.m_vi[0]=edge.m_vi[1]=%d but edge.IsClosed() is false.\n",
01391                          vi0);
01392         text_log->PopIndent();
01393       }
01394       return false;
01395     }
01396   }
01397 
01398   return true;
01399 }
01400 
01401 bool
01402 ON_Brep::IsValidFaceGeometry( int face_index, ON_TextLog* text_log ) const
01403 {
01404   if ( face_index < 0 || face_index >= m_F.Count() )
01405   {
01406     if ( text_log )
01407       text_log->Print("brep face_index = %d (should be >=0 and <%d=brep.m_F.Count() ).\n",
01408                       face_index, m_F.Count());
01409     return false;
01410   }
01411   const ON_BrepFace& face = m_F[face_index];
01412   if ( face.m_face_index != face_index )
01413   {
01414     if ( text_log )
01415     {
01416       text_log->Print("brep.m_F[%d] face is not valid.\n",face_index);
01417       text_log->PushIndent();
01418       text_log->Print("face.m_face_index = %d (should be %d).\n",
01419                        face.m_face_index, face_index );
01420       text_log->PopIndent();
01421     }
01422     return false;
01423   }
01424   return true;
01425 }
01426 
01427 bool
01428 ON_Brep::IsValidLoopGeometry( int loop_index, ON_TextLog* text_log ) const
01429 {
01430   if ( loop_index < 0 || loop_index >= m_L.Count() )
01431   {
01432     if ( text_log )
01433       text_log->Print("brep loop_index = %d (should be >=0 and <%d=brep.m_L.Count() ).\n",
01434                       loop_index, m_L.Count());
01435     return false;
01436   }
01437   const ON_BrepLoop& loop = m_L[loop_index];
01438   if ( loop.m_loop_index != loop_index )
01439   {
01440     if ( text_log )
01441     {
01442       text_log->Print("brep.m_L[%d] loop is not valid.\n",loop_index);
01443       text_log->PushIndent();
01444       text_log->Print("loop.m_loop_index = %d (should be %d).\n",
01445                        loop.m_loop_index, loop_index );
01446       text_log->PopIndent();
01447     }
01448     return false;
01449   }
01450   return true;
01451 }
01452 
01453 bool
01454 ON_Brep::IsValidTrimGeometry( int trim_index, ON_TextLog* text_log ) const
01455 {
01456   if ( trim_index < 0 || trim_index >= m_T.Count() )
01457   {
01458     if ( text_log )
01459       text_log->Print("brep trim_index = %d (should be >=0 and <%d=brep.m_T.Count() ).\n",
01460                       trim_index, m_T.Count());
01461     return false;
01462   }
01463   const ON_BrepTrim& trim = m_T[trim_index];
01464   if ( trim.m_trim_index != trim_index )
01465   {
01466     if ( text_log )
01467     {
01468       text_log->Print("brep.m_T[%d] trim is not valid.\n",trim_index);
01469       text_log->PushIndent();
01470       text_log->Print("trim.m_trim_index = %d (should be %d).\n",
01471                        trim.m_trim_index, trim_index );
01472       text_log->PopIndent();
01473     }
01474     return false;
01475   }
01476   return true;
01477 }
01478 
01479 bool
01480 ON_Brep::IsValidGeometry( ON_TextLog* text_log ) const
01481 {
01482   const int curve2d_count = m_C2.Count();
01483   const int curve3d_count = m_C3.Count();
01484   const int surface_count = m_S.Count();
01485   const int vertex_count  = m_V.Count();
01486   const int edge_count    = m_E.Count();
01487   const int trim_count    = m_T.Count();
01488   const int loop_count    = m_L.Count();
01489   const int face_count    = m_F.Count();
01490 
01491   int c2i, c3i, si, vi, ei, fi, ti, li;
01492 
01493   // check 2d curve geometry
01494   for ( c2i = 0; c2i < curve2d_count; c2i++ ) {
01495     if ( !m_C2[c2i] )
01496     {
01497       continue;
01498       // NULL 2d curves are ok if they are not referenced
01499     }
01500     if ( !m_C2[c2i]->IsValid(text_log) )
01501     {
01502       if ( text_log )
01503         text_log->Print("ON_Brep.m_C2[%d] is invalid.\n",c2i);
01504       return false;
01505     }
01506     int c2_dim = m_C2[c2i]->Dimension();
01507     if ( c2_dim != 2 )
01508     {
01509       if ( text_log )
01510         text_log->Print("ON_Brep.m_C2[%d]->Dimension() = %d (should be 2).\n", c2i, c2_dim );
01511       return false;
01512     }
01513   }
01514 
01515   // check 3d curve geometry
01516   for ( c3i = 0; c3i < curve3d_count; c3i++ ) {
01517     if ( !m_C3[c3i] )
01518     {
01519       continue;
01520       // NULL 3d curves are ok if they are not referenced
01521     }
01522     if ( !m_C3[c3i]->IsValid(text_log) )
01523     {
01524       if ( text_log )
01525         text_log->Print("ON_Brep.m_C3[%d] is invalid.\n",c3i);
01526       return false;
01527     }
01528     int c3_dim = m_C3[c3i]->Dimension();
01529     if ( c3_dim != 3 )
01530     {
01531       if ( text_log )
01532         text_log->Print("ON_Brep.m_C3[%d]->Dimension() = %d (should be 3).\n", c3i, c3_dim );
01533       return false;
01534     }
01535   }
01536 
01537   // check 3d surface geometry
01538   for ( si = 0; si < surface_count; si++ ) {
01539     if ( !m_S[si] )
01540     {
01541       continue;
01542       // NULL 3d surfaces are ok if they are not referenced
01543     }
01544     if ( !m_S[si]->IsValid(text_log) )
01545     {
01546       if ( text_log )
01547         text_log->Print("ON_Brep.m_S[%d] is invalid.\n",si);
01548       return false;
01549     }
01550     int dim = m_S[si]->Dimension();
01551     if ( dim != 3 )
01552     {
01553       if ( text_log )
01554         text_log->Print("ON_Brep.m_S[%d]->Dimension() = %d (should be 3).\n", si, dim );
01555       return false;
01556     }
01557   }
01558 
01559   // check vertices
01560   for ( vi = 0; vi < vertex_count; vi++ ) {
01561     if ( m_V[vi].m_vertex_index == -1 )
01562       continue;
01563     if ( !IsValidVertexGeometry( vi, text_log ) ) {
01564       if ( text_log )
01565         text_log->Print("ON_Brep.m_V[%d] is invalid.\n",vi);
01566       return false;
01567     }
01568   }
01569 
01570   // check edges
01571   for ( ei = 0; ei < edge_count; ei++ ) 
01572   {
01573     if ( m_E[ei].m_edge_index == -1 )
01574       continue;
01575     if ( !IsValidEdgeGeometry( ei, text_log ) ) {
01576       if ( text_log )
01577         text_log->Print("ON_Brep.m_E[%d] is invalid.\n",ei);
01578       return false;
01579     }
01580   }
01581 
01582   // check faces
01583   for ( fi = 0; fi < face_count; fi++ ) 
01584   {
01585     if ( m_F[fi].m_face_index == -1 )
01586       continue;
01587     if ( !IsValidFaceGeometry( fi, text_log ) ) {
01588       if ( text_log )
01589         text_log->Print("ON_Brep.m_F[%d] is invalid.\n",fi);
01590       return false;
01591     }
01592   }
01593 
01594   // check trims
01595   for ( ti = 0; ti < trim_count; ti++ )
01596   {
01597     if ( m_T[ti].m_trim_index == -1 )
01598       continue;
01599     if ( !IsValidTrimGeometry( ti, text_log ) ) {
01600       if ( text_log )
01601         text_log->Print("ON_Brep.m_T[%d] is invalid.\n",ti);
01602       return false;
01603     }
01604   }
01605 
01606   // check loops
01607   for ( li = 0; li < loop_count; li++ )
01608   {
01609     if ( m_L[li].m_loop_index == -1 )
01610       continue;
01611     if ( !IsValidLoopGeometry( li, text_log ) ) {
01612       if ( text_log )
01613         text_log->Print("ON_Brep.m_L[%d] is invalid.\n",li);
01614       return false;
01615     }
01616   }
01617 
01618   return true;
01619 }
01620 
01624 
01625 bool
01626 ON_Brep::IsValidVertexTolerancesAndFlags( int vertex_index, ON_TextLog* text_log ) const
01627 {
01628   if ( vertex_index < 0 || vertex_index >= m_V.Count() )
01629   {
01630     if ( text_log )
01631       text_log->Print("brep vertex_index = %d (should be >=0 and <%d=brep.m_V.Count() ).\n",
01632                       vertex_index, m_V.Count());
01633     return false;
01634   }
01635   const ON_BrepVertex& vertex = m_V[vertex_index];
01636   if ( vertex.m_vertex_index != vertex_index )
01637   {
01638     if ( text_log )
01639     {
01640       text_log->Print("brep.m_V[%d] vertex is not valid.\n",vertex_index);
01641       text_log->PushIndent();
01642       text_log->Print("vertex.m_vertex_index = %d (should be %d).\n",
01643                        vertex.m_vertex_index, vertex_index );
01644       text_log->PopIndent();
01645     }
01646     return false;
01647   }
01648 
01649   if ( vertex.m_tolerance < 0.0 )
01650   {
01651     if ( text_log )
01652     {
01653       text_log->Print("brep.m_V[%d] vertex is not valid.\n",vertex_index);
01654       text_log->PushIndent();
01655       text_log->Print("vertex.m_tolerace = %g (should be >= 0.0)\n",vertex.m_tolerance);
01656       text_log->PopIndent();
01657     }
01658     return false;
01659   }
01660 
01661   return true;
01662 }
01663 
01664 bool
01665 ON_Brep::IsValidEdgeTolerancesAndFlags( int edge_index, ON_TextLog* text_log ) const
01666 {
01667   if ( edge_index < 0 || edge_index >= m_E.Count() )
01668   {
01669     if ( text_log )
01670       text_log->Print("brep edge_index = %d (should be >=0 and <%d=brep.m_E.Count() ).\n",
01671                       edge_index, m_E.Count());
01672     return false;
01673   }
01674   const ON_BrepEdge& edge = m_E[edge_index];
01675   if ( edge.m_edge_index != edge_index )
01676   {
01677     if ( text_log )
01678     {
01679       text_log->Print("brep.m_E[%d] edge is not valid.\n",edge_index);
01680       text_log->PushIndent();
01681       text_log->Print("edge.m_edge_index = %d (should be %d).\n",
01682                        edge.m_edge_index, edge_index );
01683       text_log->PopIndent();
01684     }
01685     return false;
01686   }
01687 
01688   if ( edge.m_tolerance < 0.0 )
01689   {
01690     if ( text_log )
01691     {
01692       text_log->Print("brep.m_E[%d] edge is not valid.\n",edge_index);
01693       text_log->PushIndent();
01694       text_log->Print("edge.m_tolerance=%g (should be >= 0.0)\n",edge.m_tolerance);
01695       text_log->PopIndent();
01696     }
01697     return false;
01698   }
01699 
01700   return true;
01701 }
01702 
01703 bool
01704 ON_Brep::IsValidFaceTolerancesAndFlags( int face_index, ON_TextLog* text_log ) const
01705 {
01706   if ( face_index < 0 || face_index >= m_F.Count() )
01707   {
01708     if ( text_log )
01709       text_log->Print("brep face_index = %d (should be >=0 and <%d=brep.m_F.Count() ).\n",
01710                       face_index, m_F.Count());
01711     return false;
01712   }
01713   const ON_BrepFace& face = m_F[face_index];
01714   if ( face.m_face_index != face_index )
01715   {
01716     if ( text_log )
01717     {
01718       text_log->Print("brep.m_F[%d] face is not valid.\n",face_index);
01719       text_log->PushIndent();
01720       text_log->Print("face.m_face_index = %d (should be %d).\n",
01721                        face.m_face_index, face_index );
01722       text_log->PopIndent();
01723     }
01724     return false;
01725   }
01726   return true;
01727 }
01728 
01729 bool
01730 ON_Brep::IsValidLoopTolerancesAndFlags( int loop_index, ON_TextLog* text_log ) const
01731 {
01732   if ( loop_index < 0 || loop_index >= m_L.Count() )
01733   {
01734     if ( text_log )
01735       text_log->Print("brep loop_index = %d (should be >=0 and <%d=brep.m_L.Count() ).\n",
01736                       loop_index, m_L.Count());
01737     return false;
01738   }
01739   const ON_BrepLoop& loop = m_L[loop_index];
01740   if ( loop.m_loop_index != loop_index )
01741   {
01742     if ( text_log )
01743     {
01744       text_log->Print("brep.m_L[%d] loop is not valid.\n",loop_index);
01745       text_log->PushIndent();
01746       text_log->Print("loop.m_loop_index = %d (should be %d).\n",
01747                        loop.m_loop_index, loop_index );
01748       text_log->PopIndent();
01749     }
01750     return false;
01751   }
01752   return true;
01753 }
01754 
01755 bool
01756 ON_Brep::IsValidTrimTolerancesAndFlags( int trim_index, ON_TextLog* text_log ) const
01757 {
01758   if ( trim_index < 0 || trim_index >= m_T.Count() )
01759   {
01760     if ( text_log )
01761       text_log->Print("brep trim_index = %d (should be >=0 and <%d=brep.m_T.Count() ).\n",
01762                       trim_index, m_T.Count());
01763     return false;
01764   }
01765   const ON_BrepTrim& trim = m_T[trim_index];
01766   if ( trim.m_trim_index != trim_index )
01767   {
01768     if ( text_log )
01769     {
01770       text_log->Print("brep.m_T[%d] trim is not valid.\n",trim_index);
01771       text_log->PushIndent();
01772       text_log->Print("trim.m_trim_index = %d (should be %d).\n",
01773                        trim.m_trim_index, trim_index );
01774       text_log->PopIndent();
01775     }
01776     return false;
01777   }
01778   return true;
01779 }
01780 
01781 bool
01782 ON_Brep::IsValidTolerancesAndFlags( ON_TextLog* text_log ) const
01783 {
01784   const int vertex_count  = m_V.Count();
01785   const int edge_count    = m_E.Count();
01786   const int trim_count    = m_T.Count();
01787   const int loop_count    = m_L.Count();
01788   const int face_count    = m_F.Count();
01789 
01790   int vi, ei, fi, ti, li;
01791 
01792   // check vertices
01793   for ( vi = 0; vi < vertex_count; vi++ ) {
01794     if ( m_V[vi].m_vertex_index == -1 )
01795       continue;
01796     if ( !IsValidVertexTolerancesAndFlags( vi, text_log ) ) {
01797       if ( text_log )
01798         text_log->Print("ON_Brep.m_V[%d] is invalid.\n",vi);
01799       return false;
01800     }
01801   }
01802 
01803   // check edges
01804   for ( ei = 0; ei < edge_count; ei++ ) 
01805   {
01806     if ( m_E[ei].m_edge_index == -1 )
01807       continue;
01808     if ( !IsValidEdgeTolerancesAndFlags( ei, text_log ) ) {
01809       if ( text_log )
01810         text_log->Print("ON_Brep.m_E[%d] is invalid.\n",ei);
01811       return false;
01812     }
01813   }
01814 
01815   // check faces
01816   for ( fi = 0; fi < face_count; fi++ ) 
01817   {
01818     if ( m_F[fi].m_face_index == -1 )
01819       continue;
01820     if ( !IsValidFaceTolerancesAndFlags( fi, text_log ) ) {
01821       if ( text_log )
01822         text_log->Print("ON_Brep.m_F[%d] is invalid.\n",fi);
01823       return false;
01824     }
01825   }
01826 
01827   // check trims
01828   for ( ti = 0; ti < trim_count; ti++ )
01829   {
01830     if ( m_T[ti].m_trim_index == -1 )
01831       continue;
01832     if ( !IsValidTrimTolerancesAndFlags( ti, text_log ) ) {
01833       if ( text_log )
01834         text_log->Print("ON_Brep.m_T[%d] is invalid.\n",ti);
01835       return false;
01836     }
01837   }
01838 
01839   // check loops
01840   for ( li = 0; li < loop_count; li++ )
01841   {
01842     if ( m_L[li].m_loop_index == -1 )
01843       continue;
01844     if ( !IsValidLoopTolerancesAndFlags( li, text_log ) ) {
01845       if ( text_log )
01846         text_log->Print("ON_Brep.m_L[%d] is invalid.\n",li);
01847       return false;
01848     }
01849   }
01850 
01851   return true;
01852 }
01853 


pcl
Author(s): Open Perception
autogenerated on Wed Aug 26 2015 15:27:00