opennurbs_brep_extrude.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 static 
00020 void ON_BrepExtrudeHelper_ReserveSpace( 
00021           ON_Brep& brep, 
00022           int extruded_trim_count, 
00023           int cap_count 
00024           )
00025 {
00026   if ( extruded_trim_count >= 0 && cap_count >= 0 )
00027   {
00028     const int vertex_count0 = brep.m_V.Count();
00029     const int trim_count0 = brep.m_T.Count();
00030     const int loop_count0 = brep.m_L.Count();
00031     const int edge_count0 = brep.m_E.Count();
00032     const int face_count0 = brep.m_F.Count();
00033     const int srf_count0 = brep.m_S.Count();
00034     const int c2_count0 = brep.m_C2.Count();
00035     const int c3_count0 = brep.m_C3.Count();
00036 
00037     // the +1's are for open loops
00038 
00039     brep.m_V.Reserve( vertex_count0 + extruded_trim_count + 1 );
00040     brep.m_T.Reserve( trim_count0 + (4+cap_count)*extruded_trim_count );
00041     brep.m_F.Reserve( face_count0 + extruded_trim_count + cap_count );
00042     brep.m_E.Reserve( edge_count0 + 2*extruded_trim_count + 1 );
00043     brep.m_L.Reserve( loop_count0 + extruded_trim_count + cap_count );
00044     brep.m_S.Reserve( srf_count0 + extruded_trim_count + cap_count );
00045     brep.m_C2.Reserve( c2_count0 + (4+cap_count)*extruded_trim_count );
00046     brep.m_C3.Reserve( c3_count0 + 2*extruded_trim_count + 1 );
00047   }
00048 }
00049 
00050 static
00051 ON_SumSurface* ON_BrepExtrudeHelper_MakeSumSrf( const ON_Curve& path_curve,
00052                                                  const ON_BrepEdge& base_edge, ON_BOOL32 bRev )
00053 {
00054   ON_SumSurface* sum_srf = 0;
00055   // create side surface
00056   if ( base_edge.ProxyCurve() )
00057   {
00058     ON_Curve* srf_path_curve = path_curve.DuplicateCurve();
00059     ON_Curve* srf_base_curve = base_edge.DuplicateCurve();
00060     if ( !bRev )
00061       srf_base_curve->Reverse();
00062     ON_3dPoint sum_basepoint = -ON_3dVector(srf_path_curve->PointAtStart());
00063     sum_srf = new ON_SumSurface();
00064     sum_srf->m_curve[0] = srf_base_curve;
00065     sum_srf->m_curve[1] = srf_path_curve;
00066     sum_srf->m_basepoint = sum_basepoint;
00067     sum_srf->BoundingBox(); // fills in sum_srf->m_bbox
00068   }
00069   return sum_srf;
00070 }
00071 
00072 static
00073 ON_NurbsSurface* ON_BrepExtrudeHelper_MakeConeSrf( const ON_3dPoint& apex_point,
00074                                                  const ON_BrepEdge& edge, ON_BOOL32 bRev )
00075 {
00076   // The "s" parameter runs along the edge.
00077   // The "t" parameter is the ruling parameter;
00078   // t=0 is at the base_edge and t=max is at the apex.
00079   //   surface side    location
00080   //     south           base_edge
00081   //     east            line from bRev?START:END of edge to apex
00082   //     north           singular side at apex
00083   //     west            line from bRev?END:START of edge to apex.
00084   ON_NurbsSurface* cone_srf = new ON_NurbsSurface();
00085   if ( cone_srf->CreateConeSurface( apex_point, edge ) )
00086   {
00087     if ( bRev )
00088       cone_srf->Reverse(0);
00089     // get a decent interval for the ruling parameter
00090     double d = 0.0;
00091     ON_Interval edom = edge.Domain();
00092     ON_3dPoint pt;
00093     int i, hint=0;
00094     for ( i = 0; i <= 16; i++ )
00095     {
00096       if ( !edge.EvPoint( edom.ParameterAt(i/16.0), pt, 0, &hint ) )
00097         continue;
00098       if ( pt.DistanceTo(apex_point) > d )
00099         d = pt.DistanceTo(apex_point);
00100     }
00101     if ( d > ON_SQRT_EPSILON )
00102       cone_srf->SetDomain(1,0.0,d);
00103   }
00104   else
00105   {
00106     delete cone_srf;
00107     cone_srf = 0;
00108   }
00109   return cone_srf;
00110 }
00111 
00112 static
00113 ON_BOOL32 ON_BrepExtrudeHelper_MakeSides(
00114           ON_Brep& brep,
00115           int loop_index,
00116           const ON_Curve& path_curve,
00117           ON_BOOL32 bCap,
00118           ON_SimpleArray<int>& side_face_index
00119           )
00120 {
00121   int lti, ti, i, vid[4], eid[4], bRev3d[4];
00122 
00123   // indices of new faces appended to the side_face_index[] array 
00124   // (1 face index for each trim, -1 is used for singular trims)
00125 
00126   // count number of new objects so we can grow arrays
00127   // efficiently and use refs to dynamic array elements.
00128   const int loop_trim_count = brep.m_L[loop_index].m_ti.Count();
00129   if ( loop_trim_count == 0 )
00130     return false;
00131 
00132   // save input trim and edge counts for use below
00133   const int trim_count0 = brep.m_T.Count();
00134   const int edge_count0 = brep.m_E.Count();
00135 
00136   ON_BrepExtrudeHelper_ReserveSpace( brep, loop_trim_count, bCap?1:0 );
00137 
00138   side_face_index.Reserve( side_face_index.Count() + loop_trim_count); // index of new face above brep.m_L[loop_index].m_ti[lti]
00139   int prev_face_index = -1;
00140   int first_face_east_trim_index = -1;
00141 
00142   for ( lti = 0; lti < loop_trim_count; lti++ )
00143   {
00144     ON_SumSurface* sum_srf = 0;
00145     side_face_index.Append(-1);
00146     ti = brep.m_L[loop_index].m_ti[lti];
00147     if ( ti < 0 || ti >= trim_count0 )
00148       continue;
00149 
00150     for ( i = 0; i < 4; i++ )
00151     {
00152       vid[i] = -1;
00153       eid[i] = -1;
00154     }
00155     bRev3d[0] = false;
00156     bRev3d[1] = false;
00157     bRev3d[2] = false;
00158     bRev3d[3] = false;
00159 
00160     // get side surface for new face
00161     {
00162       ON_BrepTrim& trim = brep.m_T[ti];
00163       if ( trim.m_ei >= 0 &&  trim.m_ei < edge_count0 )
00164       {
00165         const ON_BrepEdge& base_edge = brep.m_E[trim.m_ei];
00166 
00167         // 5 September, 2003 Dale Lear
00168         //   do not extrude seams - fixes rectangle slabe bug
00169         if ( trim.m_type == ON_BrepTrim::seam )
00170         {
00171           prev_face_index = -1;
00172           continue;
00173         }
00174 
00175         // connect new face to existing topology on trim
00176         vid[0] = trim.m_vi[1];
00177         vid[1] = trim.m_vi[0];
00178         eid[0] = base_edge.m_edge_index;
00179         bRev3d[0] = (trim.m_bRev3d?false:true);
00180         sum_srf = ON_BrepExtrudeHelper_MakeSumSrf( path_curve, base_edge, trim.m_bRev3d );
00181       }
00182     }
00183     if ( !sum_srf )
00184       continue;
00185 
00186     if ( prev_face_index >= 0 )
00187     {
00188       const ON_BrepTrim& prev_west_trim = brep.m_T[ brep.m_L[ brep.m_F[prev_face_index].m_li[0]].m_ti[3] ];
00189       vid[2] = prev_west_trim.m_vi[0];
00190       eid[1] = prev_west_trim.m_ei;
00191       bRev3d[1] = (prev_west_trim.m_bRev3d?false:true);
00192     }
00193     if ( first_face_east_trim_index >= 0 && brep.m_T[first_face_east_trim_index].m_vi[0] == vid[0] )
00194     {
00195       const ON_BrepTrim& first_face_east_trim = brep.m_T[first_face_east_trim_index];
00196       vid[3] = first_face_east_trim.m_vi[1];
00197       eid[3] = first_face_east_trim.m_ei;
00198       bRev3d[3] = (first_face_east_trim.m_bRev3d?false:true);
00199     }
00200     const ON_BrepFace* side_face = brep.NewFace(sum_srf,vid,eid,bRev3d);
00201     if ( side_face )
00202     {
00203       *side_face_index.Last() = side_face->m_face_index;
00204       prev_face_index = side_face->m_face_index;
00205       if ( first_face_east_trim_index < 0 )
00206         first_face_east_trim_index = brep.m_L[ side_face->m_li[0] ].m_ti[1];
00207     }
00208   }
00209 
00210   return true;
00211 }
00212 
00213 static
00214 bool ON_BrepExtrudeHelper_CheckPathCurve( const ON_Curve& path_curve, ON_3dVector& path_vector )
00215 {
00216   ON_Line path_line;
00217   path_line.from = path_curve.PointAtStart();
00218   path_line.to = path_curve.PointAtEnd();
00219   path_vector = path_line.Direction();
00220   return ( path_vector.IsZero() ? false : true );
00221 }
00222 
00223 static 
00224 bool ON_BrepExtrudeHelper_MakeTopLoop( 
00225           ON_Brep& brep, 
00226           ON_BrepFace& top_face,
00227           int bottom_loop_index,
00228           const ON_3dVector path_vector,
00229           const int* side_face_index // array of brep.m_L[bottom_loop_index].m_ti.Count() face indices
00230           )
00231 {
00232   bool rc = true;
00233 
00234   int lti, top_trim_index, i;
00235   if ( bottom_loop_index < 0 || bottom_loop_index >= brep.m_L.Count() )
00236     return false;
00237   ON_BrepLoop::TYPE loop_type = brep.m_L[bottom_loop_index].m_type;
00238   if ( loop_type != ON_BrepLoop::inner )
00239     loop_type = ON_BrepLoop::outer;
00240   ON_BrepLoop& top_loop = brep.NewLoop( loop_type, top_face );
00241   const ON_BrepLoop& bottom_loop = brep.m_L[bottom_loop_index];
00242   const int loop_trim_count = bottom_loop.m_ti.Count();
00243   brep.m_T.Reserve( brep.m_T.Count() + loop_trim_count );
00244 
00245   // Set top_vertex_index[lti] = index of vertex above 
00246   // vertex brep.m_V[brep.m_T[bottom_loop.m_ti[lti]].m_vi[0]].
00247   // Set top_vertex_index[lti] = index of edge above 
00248   // edge of brep.m_T[bottom_loop.m_ti[lti]].
00249   // This informtion is needed for singular and seam trims.
00250   ON_SimpleArray<int> top_vertex_index(loop_trim_count);
00251   ON_SimpleArray<int> top_edge_index(loop_trim_count);
00252   ON_SimpleArray<bool> top_trim_bRev3d(loop_trim_count);
00253   for ( lti = 0; lti < loop_trim_count; lti++ )
00254   {
00255     top_vertex_index.Append(-1);
00256     top_edge_index.Append(-1);
00257     top_trim_bRev3d.Append(false);
00258   }
00259 
00260   // some (often all of) of the "top" vertices are already on
00261   // the side faces
00262   for ( lti = 0; lti < loop_trim_count; lti++ )
00263   {
00264     if ( side_face_index[lti] >= 0 )
00265     {
00266       const ON_BrepFace& side_face = brep.m_F[side_face_index[lti]];
00267       const ON_BrepLoop& side_loop = brep.m_L[side_face.m_li[0]];
00268       const ON_BrepTrim& side_north_trim = brep.m_T[side_loop.m_ti[2]];
00269       top_vertex_index[lti] = side_north_trim.m_vi[0];
00270       top_vertex_index[(lti+1)%loop_trim_count] = side_north_trim.m_vi[1];
00271       top_edge_index[lti] = side_north_trim.m_ei;
00272     }
00273     else 
00274     {
00275       // fix for RR 20423
00276       int lti_prev = (lti+loop_trim_count-1)%loop_trim_count;
00277       int lti_next = (lti+1)%loop_trim_count;
00278       if (   side_face_index[lti_prev] < 0 
00279            && side_face_index[lti_next] < 0 
00280            && top_vertex_index[lti] < 0
00281            && top_vertex_index[lti_next] < 0
00282            )
00283       {
00284         int bottom_ti_prev = bottom_loop.m_ti[lti_prev];
00285         int bottom_ti      = bottom_loop.m_ti[lti];
00286         int bottom_ti_next = bottom_loop.m_ti[lti_next];
00287         if (    bottom_ti >= 0      && bottom_ti < brep.m_T.Count() 
00288              && bottom_ti_prev >= 0 && bottom_ti_prev < brep.m_T.Count() 
00289              && bottom_ti_next >= 0 && bottom_ti_next < brep.m_T.Count() 
00290            )
00291         {
00292           const ON_BrepTrim& bottom_trim_prev = brep.m_T[bottom_ti_prev];
00293           const ON_BrepTrim& bottom_trim = brep.m_T[bottom_ti];
00294           const ON_BrepTrim& bottom_trim_next = brep.m_T[bottom_ti_next];
00295           if (    ON_BrepTrim::seam == bottom_trim_prev.m_type
00296                && ON_BrepTrim::singular == bottom_trim.m_type
00297                && ON_BrepTrim::seam == bottom_trim_next.m_type 
00298                && bottom_trim.m_vi[0] == bottom_trim.m_vi[1]
00299                )
00300           {
00301             int vi = bottom_trim.m_vi[0];
00302             if ( vi >= 0 && vi < brep.m_V.Count() )
00303             {
00304               ON_BrepVertex& top_vertex = brep.NewVertex(brep.m_V[vi].point+path_vector,0.0);
00305               top_vertex_index[lti] = top_vertex.m_vertex_index;
00306               top_vertex_index[lti_next] = top_vertex_index[lti];
00307             }
00308           }
00309         }
00310       }
00311     }
00312   }
00313 
00314   // Fill in the missing "top" vertices that
00315   // are associated with singular and trim edges by looking
00316   // at their neighbors.
00317   {
00318     bool bKeepChecking = true;
00319     while( bKeepChecking )
00320     {
00321       // set back to true if we make a change.  This handles the
00322       // (very rare) cases of multiple adjacent singular trims.
00323       bKeepChecking = false; 
00324 
00325       for ( lti = 0; lti < loop_trim_count; lti++ )
00326       {
00327         if ( top_vertex_index[lti] == -1 )
00328         {
00329           for ( i = lti+1; i < loop_trim_count; i++ )
00330           {
00331             if ( ON_BrepTrim::singular != brep.m_T[bottom_loop.m_ti[i-1]].m_type )
00332               break;
00333             if ( top_vertex_index[i] >= 0 )
00334             {
00335               top_vertex_index[lti] = top_vertex_index[i];
00336               bKeepChecking = true; 
00337               break;
00338             }
00339           }
00340         }
00341 
00342         if ( top_vertex_index[lti] == -1 )
00343         {
00344           for ( i = lti-1; i >= 0; i-- )
00345           {
00346             if ( ON_BrepTrim::singular != brep.m_T[bottom_loop.m_ti[i+1]].m_type )
00347               break;
00348             if ( top_vertex_index[i] >= 0 )
00349             {
00350               top_vertex_index[lti] = top_vertex_index[i];
00351               bKeepChecking = true; 
00352               break;
00353             }
00354           }
00355         }
00356       }
00357     }
00358   }
00359 
00360   // Fill in missing edges of "seam" trims.
00361   for ( lti = 0; lti < loop_trim_count; lti++ )
00362   {
00363     if ( -1 != top_edge_index[lti] )
00364       continue;
00365     int bottom_ti = bottom_loop.m_ti[lti];
00366     if ( bottom_ti < 0 || bottom_ti >= brep.m_T.Count() )
00367       continue;
00368     const ON_BrepTrim& bottom_trim = brep.m_T[bottom_ti];
00369     if ( ON_BrepTrim::seam != bottom_trim.m_type )
00370       continue;
00371     if ( bottom_trim.m_ei < 0 )
00372       continue;
00373     if ( bottom_trim.m_ei >= brep.m_E.Count() )
00374       continue;
00375 
00376     // duplicate bottom edge curve
00377     const ON_BrepEdge& bottom_edge = brep.m_E[bottom_trim.m_ei];
00378     ON_Curve* top_c3 = bottom_edge.DuplicateCurve();
00379     if ( 0 == top_c3 )
00380       continue;
00381     // move new edge curve to top location
00382     top_c3->Translate(path_vector);
00383     ON_3dPoint P0 = top_c3->PointAtStart();
00384     ON_3dPoint P1 = top_c3->PointAtEnd();
00385     int top_c3i = brep.AddEdgeCurve(top_c3);
00386     top_c3 = 0;
00387     // get vertices at start/end of the new edge
00388     int e_vi0 = top_vertex_index[lti];
00389     int e_vi1 = top_vertex_index[(lti+1)%loop_trim_count];
00390     if ( bottom_trim.m_bRev3d )
00391     {
00392       // put points in trim order
00393       ON_3dPoint tmp_P = P0; P0 = P1; P1 = tmp_P;
00394     }
00395     if ( e_vi0 < 0 )
00396     {
00397       e_vi0 = brep.NewVertex(P0).m_vertex_index;
00398       top_vertex_index[lti] = e_vi0;
00399     }
00400     if ( e_vi1 < 0 )
00401     {
00402       e_vi1 = brep.NewVertex(P1).m_vertex_index;
00403       top_vertex_index[(lti+1)%loop_trim_count] = e_vi1;
00404     }
00405     if ( bottom_trim.m_bRev3d )
00406     {
00407       // put edge vertex indices in edge order
00408       int tmp_i = e_vi0; e_vi0 = e_vi1; e_vi1 = tmp_i;
00409     }
00410     ON_BrepEdge& top_edge = brep.NewEdge(brep.m_V[e_vi0],brep.m_V[e_vi1],top_c3i);
00411     top_edge.m_tolerance = bottom_edge.m_tolerance;
00412     top_edge_index[lti] = top_edge.m_edge_index;
00413     top_trim_bRev3d[lti] = bottom_trim.m_bRev3d?true:false;
00414 
00415     // find seam mate and set it's 
00416     // top_edge_index[] to top_edge.m_edge_index.
00417     int mate_lti;
00418     for( mate_lti = lti+1; mate_lti < loop_trim_count; mate_lti++ )
00419     {
00420       if ( top_edge_index[mate_lti] != -1  )
00421         continue;
00422       int bottom_mate_ti = bottom_loop.m_ti[mate_lti];
00423       if ( bottom_mate_ti < 0 || bottom_mate_ti >= brep.m_T.Count() )
00424         continue;
00425       const ON_BrepTrim& bottom_mate_trim = brep.m_T[bottom_mate_ti];
00426       if ( bottom_mate_trim.m_type != ON_BrepTrim::seam )
00427         continue;
00428       if ( bottom_mate_trim.m_ei != bottom_trim.m_ei )
00429         continue;
00430       top_edge_index[mate_lti] = top_edge.m_edge_index;
00431       top_trim_bRev3d[mate_lti] = bottom_mate_trim.m_bRev3d?true:false;
00432       break;
00433     }
00434   }
00435 
00436 
00437   for ( lti = 0; lti < loop_trim_count; lti++ )
00438   {
00439     const ON_BrepTrim& bottom_trim = brep.m_T[ bottom_loop.m_ti[lti] ];
00440     ON_Curve* top_c2 = bottom_trim.DuplicateCurve();
00441     int top_c2i = (0!=top_c2) ? brep.AddTrimCurve(top_c2) : bottom_trim.m_c2i;
00442     top_trim_index = -1;
00443     if ( bottom_trim.m_type == ON_BrepTrim::singular && top_vertex_index[lti] >= 0 )
00444     {
00445       top_trim_index = brep.NewSingularTrim(brep.m_V[top_vertex_index[lti]], top_loop, bottom_trim.m_iso, top_c2i ).m_trim_index;
00446     }
00447     else if ( bottom_trim.m_type != ON_BrepTrim::singular && top_edge_index[lti] >= 0 && top_edge_index[lti] < brep.m_E.Count() )
00448     {
00449       ON_BrepEdge& top_edge = brep.m_E[top_edge_index[lti]];
00450       top_trim_index = brep.NewTrim( top_edge, top_trim_bRev3d[lti], top_loop, top_c2i ).m_trim_index;
00451     }
00452     else
00453     {
00454       ON_ERROR("ON_BrepExtrudeHelper_MakeTopLoop ran into capping trouble.");
00455       rc = false;
00456       break;
00457     }
00458     ON_BrepTrim& top_trim = brep.m_T[top_trim_index];
00459     top_trim.m_pline = bottom_trim.m_pline;
00460     top_trim.m_pbox = bottom_trim.m_pbox;
00461     top_trim.m_iso = bottom_trim.m_iso;
00462     top_trim.m_type = bottom_trim.m_type;
00463     top_trim.m_tolerance[0] = bottom_trim.m_tolerance[0];
00464     top_trim.m_tolerance[1] = bottom_trim.m_tolerance[1];
00465     top_trim.m__legacy_2d_tol = bottom_trim.m__legacy_2d_tol;
00466     top_trim.m__legacy_3d_tol = bottom_trim.m__legacy_2d_tol;
00467     top_trim.m__legacy_flags = bottom_trim.m__legacy_flags;
00468   }
00469   if (rc)
00470   {
00471     top_loop.m_pbox = bottom_loop.m_pbox;
00472   }
00473   return rc;
00474 }
00475 
00476 static          
00477 bool ON_BrepExtrudeHelper_CheckLoop( const ON_Brep& brep, int loop_index )
00478 {
00479   bool rc = false;
00480   if ( loop_index >= 0 )
00481   {
00482     ON_BrepLoop::TYPE loop_type = brep.m_L[loop_index].m_type;
00483     if ( loop_type == ON_BrepLoop::inner || loop_type == ON_BrepLoop::outer )
00484       rc = true;
00485   }
00486   return rc;
00487 }
00488 
00489 static
00490 bool ON_BrepExtrudeHelper_MakeCap(
00491           ON_Brep& brep,
00492           int bottom_loop_index,
00493           const ON_3dVector path_vector,
00494           const int* side_face_index
00495           )
00496 {
00497   bool bCap = true;
00498   // make cap
00499   if ( !ON_BrepExtrudeHelper_CheckLoop( brep, bottom_loop_index ) )
00500     return false;
00501   brep.m_F.Reserve(brep.m_F.Count() + 1);
00502   brep.m_L.Reserve(brep.m_L.Count() + 1);
00503   const ON_BrepLoop& bottom_loop = brep.m_L[bottom_loop_index];
00504   const ON_BrepFace& bottom_face = brep.m_F[bottom_loop.m_fi];
00505   const ON_Surface* bottom_surface = bottom_face.SurfaceOf();
00506   ON_Surface* top_surface = bottom_surface->Duplicate();
00507   top_surface->Translate( path_vector );
00508   int top_surface_index = brep.AddSurface( top_surface );
00509   ON_BrepFace& top_face = brep.NewFace( top_surface_index );
00510 
00511   bCap = ON_BrepExtrudeHelper_MakeTopLoop( brep, top_face, bottom_loop_index, path_vector, side_face_index );
00512   if ( bCap )
00513   {
00514     ON_BrepLoop& top_loop = brep.m_L[brep.m_L.Count()-1];
00515     if ( bottom_loop.m_type == ON_BrepLoop::inner )
00516     {
00517       // we capped an inner boundary
00518       // top_loop.m_type = ON_BrepLoop::outer; // done in ON_BrepExtrudeHelper_MakeTopLoop
00519       brep.FlipLoop(top_loop);
00520     }
00521     else if ( bottom_loop.m_type == ON_BrepLoop::outer )
00522     {
00523       // we capped an outer boundary
00524       // top_loop.m_type = ON_BrepLoop::outer; // done in ON_BrepExtrudeHelper_MakeTopLoop
00525       brep.FlipFace(top_face);
00526     }
00527   }
00528   else
00529   {
00530     // delete partially made cap face
00531     brep.DeleteFace( top_face, false );
00532     delete brep.m_S[top_surface_index];
00533     brep.m_S[top_surface_index] = 0;
00534   }
00535   return bCap;
00536 }
00537 
00538 
00539 
00540 int ON_BrepExtrudeFace( 
00541           ON_Brep& brep,
00542           int face_index,
00543           const ON_Curve& path_curve,
00544           bool bCap
00545           )
00546 {
00547   int rc = 0; // returns 1 for success with no cap, 2 for success with a cap
00548 
00549   if ( face_index < 0 || face_index >= brep.m_F.Count() )
00550     return false;
00551 
00552   const int face_loop_count = brep.m_F[face_index].m_li.Count();
00553   if ( face_loop_count < 1 )
00554     return false;
00555 
00556 
00557   if ( brep.m_F[face_index].m_li.Count() == 1 )
00558   {
00559     rc = ON_BrepExtrudeLoop( brep, brep.m_F[face_index].m_li[0], path_curve, bCap );
00560   }
00561   else
00562   {
00563     ON_3dVector path_vector;
00564     ON_SimpleArray<int> side_face_index;
00565     ON_SimpleArray<int> side_face_index_loop_mark;
00566     int li, fli;
00567 
00568     if ( !ON_BrepExtrudeHelper_CheckPathCurve( path_curve, path_vector ) )
00569       return 0;
00570 
00571     //const int trim_count0 = brep.m_T.Count();
00572     const int loop_count0 = brep.m_L.Count();
00573     const int face_count0 = brep.m_F.Count();
00574 
00575     // count number of new objects so we can grow arrays
00576     // efficiently and use refs to dynamic array elements.
00577     int new_side_trim_count = 0;
00578     for ( fli = 0; fli < face_loop_count; fli++ )
00579     {
00580       li = brep.m_F[face_index].m_li[fli];
00581       if ( li < 0 || li >= loop_count0 )
00582         return false;
00583       if ( !ON_BrepExtrudeHelper_CheckLoop( brep, li ) )
00584         continue;
00585       new_side_trim_count += brep.m_L[li].m_ti.Count();
00586     }
00587     if ( new_side_trim_count == 0 )
00588       return false;
00589     ON_BrepExtrudeHelper_ReserveSpace( brep, new_side_trim_count, bCap?1:0 );
00590 
00591     side_face_index.Reserve(new_side_trim_count);
00592     side_face_index_loop_mark.Reserve(face_loop_count);
00593 
00594     const ON_BrepFace& face = brep.m_F[face_index];
00595   
00596     rc = true;
00597     int outer_loop_index = -1;
00598     int outer_fli = -1;
00599     for ( fli = 0; fli < face_loop_count && rc; fli++ )
00600     {
00601       side_face_index_loop_mark.Append( side_face_index.Count() );
00602       li = face.m_li[fli];
00603       if ( !ON_BrepExtrudeHelper_CheckLoop( brep, li ) )
00604         continue;
00605       ON_BrepLoop& loop = brep.m_L[li];
00606       if ( bCap && loop.m_type == ON_BrepLoop::outer )
00607       {
00608         if ( outer_loop_index >= 0 )
00609           bCap = false;
00610         else 
00611         {
00612           outer_loop_index = li;
00613           outer_fli = fli;
00614         }
00615       }
00616       rc = ON_BrepExtrudeHelper_MakeSides( brep, li, path_curve, bCap, side_face_index );
00617     }
00618 
00619     if ( bCap && rc && outer_loop_index >= 0 )
00620     {
00621       const int face_count1 = brep.m_F.Count();
00622       bCap = ON_BrepExtrudeHelper_MakeCap( 
00623                   brep, 
00624                   outer_loop_index, 
00625                   path_vector, 
00626                   side_face_index.Array() + side_face_index_loop_mark[outer_fli] );
00627       if ( bCap && brep.m_F.Count() > face_count1)
00628       {
00629         // put inner bondaries on the cap
00630         rc = 2;
00631 
00632         ON_BrepFace& cap_face = brep.m_F[brep.m_F.Count()-1];
00633         for ( fli = 0; fli < face_loop_count && rc; fli++ )
00634         {
00635           li = face.m_li[fli];
00636           if ( li == outer_loop_index )
00637             continue;
00638           if ( !ON_BrepExtrudeHelper_CheckLoop( brep, li ) )
00639             continue;
00640           if ( ON_BrepExtrudeHelper_MakeTopLoop( 
00641                       brep, 
00642                       cap_face, 
00643                       li, 
00644                       path_vector,
00645                       side_face_index.Array() + side_face_index_loop_mark[fli] ) )
00646           {
00647             ON_BrepLoop& top_loop = brep.m_L[brep.m_L.Count()-1];
00648             top_loop.m_type = brep.m_L[li].m_type;
00649           }
00650         }
00651       }
00652     }
00653 
00654     if ( brep.m_F[face_index].m_bRev )
00655     {
00656       for ( int fi = face_count0; fi < brep.m_F.Count(); fi++ )
00657       {
00658         brep.FlipFace(brep.m_F[fi]);
00659       }
00660     }
00661   }
00662 
00663   return rc;
00664 }
00665 
00666 
00667 int ON_BrepExtrudeLoop( 
00668           ON_Brep& brep,
00669           int loop_index,
00670           const ON_Curve& path_curve,
00671           bool bCap
00672           )
00673 {
00674   ON_SimpleArray<int> side_face_index; // index of new face above brep.m_L[loop_index].m_ti[lti]
00675   ON_3dVector path_vector;
00676 
00677   const int face_count0 = brep.m_F.Count();
00678 
00679   if ( loop_index < 0 || loop_index >= brep.m_L.Count() )
00680     return false;
00681 
00682   if ( !ON_BrepExtrudeHelper_CheckPathCurve(path_curve,path_vector) )
00683     return false;
00684 
00685   // can only cap closed loops ( for now, just test for inner and outer loops).
00686   if ( brep.m_L[loop_index].m_type != ON_BrepLoop::outer && brep.m_L[loop_index].m_type != ON_BrepLoop::inner )
00687     bCap = false;
00688 
00689   // make sides
00690   if ( !ON_BrepExtrudeHelper_MakeSides( brep, loop_index, path_curve, bCap, side_face_index ) )
00691     return false;
00692 
00693   // make cap
00694   if ( bCap )
00695     bCap = ON_BrepExtrudeHelper_MakeCap( brep, loop_index, path_vector, side_face_index.Array() );
00696 
00697   const ON_BrepLoop& loop = brep.m_L[loop_index];
00698   if ( loop.m_fi >= 0 && loop.m_fi < brep.m_F.Count() && brep.m_F[loop.m_fi].m_bRev )
00699   {
00700     for ( int fi = face_count0; fi < brep.m_F.Count(); fi++ )
00701     {
00702       brep.FlipFace( brep.m_F[fi] );
00703     }
00704   }
00705 
00706   return (bCap?2:1);
00707 }
00708 
00709 
00710 
00711 int ON_BrepExtrudeEdge( 
00712           ON_Brep& brep,
00713           int edge_index,
00714           const ON_Curve& path_curve
00715           )
00716 {
00717   ON_3dVector path_vector;
00718 
00719   if ( edge_index < 0 && edge_index >= brep.m_E.Count() )
00720     return false;
00721 
00722   if ( !ON_BrepExtrudeHelper_CheckPathCurve(path_curve,path_vector) )
00723     return false;
00724 
00725 
00726   // make sides
00727   bool bRev = false;
00728   ON_SumSurface* sum_srf = ON_BrepExtrudeHelper_MakeSumSrf( 
00729                               path_curve, brep.m_E[edge_index], bRev );
00730 
00731   if ( !sum_srf )
00732     return false;
00733 
00734   int vid[4], eid[4], bRev3d[4];
00735 
00736   vid[0] = brep.m_E[edge_index].m_vi[bRev?0:1];
00737   vid[1] = brep.m_E[edge_index].m_vi[bRev?1:0];
00738   vid[2] = -1;
00739   vid[3] = -1;
00740 
00741   eid[0] = edge_index; // "south side edge"
00742   eid[1] = -1;
00743   eid[2] = -1;
00744   eid[3] = -1;
00745 
00746   bRev3d[0] = bRev?0:1;
00747   bRev3d[1] = 0;
00748   bRev3d[2] = 0;
00749   bRev3d[3] = 0;
00750 
00751   return brep.NewFace( sum_srf, vid, eid, bRev3d ) ? true : false;
00752 }
00753 
00754 
00755 bool ON_BrepExtrude( 
00756           ON_Brep& brep,
00757           const ON_Curve& path_curve,
00758           bool bCap
00759           )
00760 {
00761   ON_Workspace ws;
00762   const int vcount0 = brep.m_V.Count();
00763   const int tcount0 = brep.m_T.Count();
00764   const int lcount0 = brep.m_L.Count();
00765   const int ecount0 = brep.m_E.Count();
00766   const int fcount0 = brep.m_F.Count();
00767 
00768   const ON_3dPoint PathStart = path_curve.PointAtStart();
00769   ON_3dPoint P = path_curve.PointAtEnd();
00770   if ( !PathStart.IsValid() || !P.IsValid() )
00771     return false;
00772   const ON_3dVector height = P - PathStart;
00773   if ( !height.IsValid() || height.Length() <= ON_ZERO_TOLERANCE )
00774     return false;
00775 
00776   ON_Xform tr;
00777   tr.Translation(height);
00778 
00779   // count number of new sides
00780   int side_count = 0;
00781   int i, vi, ei, fi;
00782   bool* bSideEdge = (bool*)ws.GetIntMemory(ecount0*sizeof(bSideEdge[0]));
00783   for ( ei = 0; ei < ecount0; ei++ )
00784   {
00785     const ON_BrepEdge& e = brep.m_E[ei];
00786     if ( 1 == e.m_ti.Count() )
00787     {
00788       side_count++;
00789       bSideEdge[ei] = true;
00790     }
00791     else
00792     {
00793       bSideEdge[ei] = false;
00794     }
00795   }
00796 
00797   brep.m_V.Reserve( 2*vcount0 );
00798   i = 4*side_count + (bCap?tcount0:0);
00799   brep.m_T.Reserve( tcount0 + i );
00800   brep.m_C2.Reserve( brep.m_C2.Count() + i );
00801   brep.m_L.Reserve( lcount0 + side_count + (bCap?lcount0:0) );
00802   i = side_count + (bCap?ecount0:side_count);
00803   brep.m_E.Reserve( ecount0 + i );
00804   brep.m_C3.Reserve( brep.m_C3.Count() + i );
00805   i = side_count + (bCap?fcount0:0);
00806   brep.m_F.Reserve( fcount0 + i );
00807   brep.m_S.Reserve( brep.m_S.Count() + i );
00808 
00809   bool bOK = true;
00810 
00811   // build top vertices
00812   int* topvimap = ws.GetIntMemory(vcount0);
00813   memset(topvimap,0,vcount0*sizeof(topvimap[0]));
00814   if ( bCap )
00815   {
00816     for ( vi = 0; vi < vcount0; vi++ )
00817     {
00818       const ON_BrepVertex& bottomv = brep.m_V[vi];
00819       ON_BrepVertex& topv = brep.NewVertex(bottomv.point+height,bottomv.m_tolerance);
00820       topvimap[vi] = topv.m_vertex_index;
00821     }
00822   }
00823   else
00824   {
00825     for ( ei = 0; ei < ecount0; ei++ )
00826     {
00827       if ( bSideEdge[ei] )
00828       {
00829         const ON_BrepEdge& bottome = brep.m_E[ei];
00830         int bottomvi0 = bottome.m_vi[0];
00831         if ( bottomvi0 < 0 || bottomvi0 >= vcount0 )
00832         {
00833           bOK = false;
00834           break;
00835         }
00836         int bottomvi1 = bottome.m_vi[1];
00837         if ( bottomvi1 < 0 || bottomvi1 >= vcount0 )
00838         {
00839           bOK = false;
00840           break;
00841         }
00842         if ( !topvimap[bottomvi0] )
00843         {
00844           const ON_BrepVertex& bottomv = brep.m_V[bottomvi0];
00845           ON_BrepVertex& topv = brep.NewVertex(bottomv.point+height,bottomv.m_tolerance);
00846           topvimap[bottomvi0] = topv.m_vertex_index;
00847         }
00848         if ( !topvimap[bottomvi1] )
00849         {
00850           const ON_BrepVertex& bottomv = brep.m_V[bottomvi1];
00851           ON_BrepVertex& topv = brep.NewVertex(bottomv.point+height,bottomv.m_tolerance);
00852           topvimap[bottomvi1] = topv.m_vertex_index;
00853         }
00854       }
00855     }
00856   }
00857 
00858   // build top edges
00859   int* topeimap = ws.GetIntMemory(ecount0);
00860   memset(topeimap,0,ecount0*sizeof(topeimap[0]));
00861   if ( bOK ) for ( ei = 0; ei < ecount0; ei++ )
00862   {
00863     if ( bCap || bSideEdge[ei] )
00864     {
00865       const ON_BrepEdge& bottome = brep.m_E[ei];
00866       ON_BrepVertex& topv0 = brep.m_V[topvimap[bottome.m_vi[0]]];
00867       ON_BrepVertex& topv1 = brep.m_V[topvimap[bottome.m_vi[1]]];
00868       ON_Curve* c3 = bottome.DuplicateCurve();
00869       if ( !c3 )
00870       {
00871         bOK = false;
00872         break;
00873       }
00874       c3->Transform(tr);
00875       int c3i = brep.AddEdgeCurve(c3);
00876       ON_BrepEdge& tope = brep.NewEdge(topv0,topv1,c3i,0,bottome.m_tolerance);
00877       topeimap[ei] = tope.m_edge_index;
00878     }
00879   }
00880 
00881   // build side edges
00882   int* sideveimap = ws.GetIntMemory(vcount0);
00883   memset(sideveimap,0,vcount0*sizeof(sideveimap[0]));
00884   if ( bOK ) for ( vi = 0; vi < vcount0; vi++ )
00885   {
00886     ON_BrepVertex& bottomv = brep.m_V[vi];
00887     for ( int vei = 0; vei < bottomv.m_ei.Count(); vei++ )
00888     {
00889       if ( bSideEdge[bottomv.m_ei[vei]] && topvimap[vi] )
00890       {
00891         ON_BrepVertex& topv = brep.m_V[topvimap[vi]];
00892         ON_Curve* c3 = path_curve.DuplicateCurve();
00893         if ( !c3 )
00894         {
00895           bOK = false;
00896         }
00897         else
00898         {
00899           ON_3dVector D = bottomv.point - PathStart;
00900           c3->Translate(D);
00901           int c3i = brep.AddEdgeCurve(c3);
00902           const ON_BrepEdge& e = brep.NewEdge(bottomv,topv,c3i,0,0.0);
00903           sideveimap[vi] = e.m_edge_index;
00904         }
00905         break;
00906       }
00907     }
00908   }
00909 
00910   if ( bOK && bCap )
00911   {
00912     // build top faces
00913     for (fi = 0; fi < fcount0; fi++ )
00914     {
00915       const ON_BrepFace& bottomf = brep.m_F[fi];
00916       ON_Surface* srf = bottomf.DuplicateSurface();
00917       if ( !srf )
00918       {
00919         bOK = false;
00920         break;
00921       }
00922       srf->Transform(tr);
00923       int si = brep.AddSurface(srf);
00924       ON_BrepFace& topf = brep.NewFace(si);
00925       topf.m_bRev = !bottomf.m_bRev;
00926       const int loop_count = bottomf.m_li.Count();
00927       topf.m_li.Reserve(loop_count);
00928       for ( int fli = 0; fli < loop_count; fli++ )
00929       {
00930         const ON_BrepLoop& bottoml = brep.m_L[bottomf.m_li[fli]];
00931         ON_BrepLoop& topl = brep.NewLoop(bottoml.m_type,topf);
00932         const int loop_trim_count = bottoml.m_ti.Count();
00933         topl.m_ti.Reserve(loop_trim_count);
00934         for ( int lti = 0; lti < loop_trim_count; lti++ )
00935         {
00936           const ON_BrepTrim& bottomt = brep.m_T[bottoml.m_ti[lti]];
00937           ON_NurbsCurve* c2 = ON_NurbsCurve::New();
00938           if ( !bottomt.GetNurbForm(*c2) )
00939           {
00940             delete c2;
00941             bOK = false;
00942             break;
00943           }
00944           int c2i = brep.AddTrimCurve(c2);
00945           ON_BrepTrim* topt = 0;
00946           if ( bottomt.m_ei >= 0 )
00947           {
00948             ON_BrepEdge& tope = brep.m_E[topeimap[bottomt.m_ei]];
00949             topt = &brep.NewTrim(tope,bottomt.m_bRev3d,topl,c2i);
00950           }
00951           else
00952           {
00953             // singular trim
00954             ON_BrepVertex& topv = brep.m_V[topvimap[bottomt.m_vi[0]]];
00955             topt = &brep.NewSingularTrim(topv,topl,bottomt.m_iso,c2i);
00956           }
00957           topt->m_tolerance[0] = bottomt.m_tolerance[0];
00958           topt->m_tolerance[1] = bottomt.m_tolerance[1];
00959           topt->m_pbox = bottomt.m_pbox;
00960           topt->m_type = bottomt.m_type;
00961           topt->m_iso = bottomt.m_iso;
00962         }
00963         topl.m_pbox = bottoml.m_pbox;
00964       }
00965     }
00966   }
00967 
00968   // build sides
00969   int bRev3d[4] = {0,0,1,1};
00970   int vid[4], eid[4];
00971   if( bOK ) for ( ei = 0; ei < ecount0; ei++ )
00972   {
00973     if ( bSideEdge[ei] && topeimap[ei] )
00974     {
00975       ON_BrepEdge& bottome = brep.m_E[ei];
00976       ON_BrepEdge& tope = brep.m_E[topeimap[ei]];
00977       vid[0] = bottome.m_vi[0];
00978       vid[1] = bottome.m_vi[1];
00979       vid[2] = topvimap[vid[1]];
00980       vid[3] = topvimap[vid[0]];
00981       if ( sideveimap[vid[0]] && sideveimap[vid[1]] )
00982       {
00983         ON_BrepEdge& leftedge = brep.m_E[sideveimap[vid[0]]];
00984         ON_BrepEdge& rightedge = brep.m_E[sideveimap[vid[1]]];
00985         ON_Curve* cx = bottome.DuplicateCurve();
00986         if ( !cx )
00987         {
00988           bOK = false;
00989           break;
00990         }
00991         ON_Curve* cy = leftedge.DuplicateCurve();
00992         if ( !cy )
00993         {
00994           delete cx;
00995           bOK = false;
00996           break;
00997         }
00998         ON_SumSurface* srf = new ON_SumSurface();
00999         srf->m_curve[0] = cx;
01000         srf->m_curve[1] = cy;
01001         srf->m_basepoint = srf->m_curve[1]->PointAtStart();
01002         srf->m_basepoint.x = -srf->m_basepoint.x;
01003         srf->m_basepoint.y = -srf->m_basepoint.y;
01004         srf->m_basepoint.z = -srf->m_basepoint.z;
01005         eid[0] = bottome.m_edge_index;
01006         eid[1] = rightedge.m_edge_index;
01007         eid[2] = tope.m_edge_index;
01008         eid[3] = leftedge.m_edge_index;
01009         ON_BrepFace* face = brep.NewFace(srf,vid,eid,bRev3d);
01010         if ( !face )
01011         {
01012           bOK = false;
01013           break;
01014         }
01015         else if ( bottome.m_ti.Count() == 2 )
01016         {
01017           const ON_BrepTrim& trim0 = brep.m_T[bottome.m_ti[0]];
01018           const ON_BrepTrim& trim1 = brep.m_T[bottome.m_ti[1]];
01019           const ON_BrepLoop& loop0 = brep.m_L[trim0.m_li];
01020           const ON_BrepLoop& loop1 = brep.m_L[trim1.m_li];
01021           bool bBottomFaceRev = brep.m_F[(loop0.m_fi != face->m_face_index) ? loop0.m_fi : loop1.m_fi].m_bRev;
01022           bool bSideFaceRev = ( trim0.m_bRev3d != trim1.m_bRev3d ) 
01023                             ? bBottomFaceRev 
01024                             : !bBottomFaceRev;
01025           face->m_bRev = bSideFaceRev;
01026         }
01027       }
01028     }
01029   }
01030 
01031   if ( !bOK )
01032   {
01033     for ( vi = brep.m_V.Count(); vi >= vcount0; vi-- )
01034     {
01035       brep.DeleteVertex(brep.m_V[vi]);
01036     }
01037   }
01038 
01039   return bOK;
01040 }
01041 
01042 
01043 
01044 int ON_BrepExtrudeVertex( 
01045           ON_Brep& brep,
01046           int vertex_index,
01047           const ON_Curve& path_curve
01048           )
01049 {
01050   ON_3dVector path_vector;
01051   if ( vertex_index < 0 && vertex_index >= brep.m_V.Count() )
01052     return false;
01053   if ( !ON_BrepExtrudeHelper_CheckPathCurve(path_curve,path_vector) )
01054     return false;
01055   ON_Curve* c3 = path_curve.Duplicate();
01056   brep.m_V.Reserve( brep.m_V.Count() + 1 );
01057   ON_BrepVertex& v0 = brep.m_V[vertex_index];
01058   ON_BrepVertex& v1 = brep.NewVertex( v0.point + path_vector, 0.0 );
01059   c3->Translate( v0.point - c3->PointAtStart() );
01060   int c3i = brep.AddEdgeCurve( c3 );
01061   ON_BrepEdge& edge = brep.NewEdge( v0, v1, c3i );
01062   edge.m_tolerance = 0.0;
01063   return true;
01064 }
01065 
01066 
01067 int ON_BrepConeFace( 
01068           ON_Brep& brep,
01069           int face_index,
01070           ON_3dPoint apex_point
01071           )
01072 {
01073   int rc = 0; // returns 1 for success with no cap, 2 for success with a cap
01074 
01075   if ( face_index < 0 || face_index >= brep.m_F.Count() )
01076     return false;
01077 
01078   const int face_loop_count = brep.m_F[face_index].m_li.Count();
01079   if ( face_loop_count < 1 )
01080     return false;
01081 
01082   if ( brep.m_F[face_index].m_li.Count() == 1 )
01083   {
01084     rc = ON_BrepConeLoop( brep, brep.m_F[face_index].m_li[0], apex_point );
01085   }
01086   else
01087   {
01088     int li, fli;
01089 
01090     //const int trim_count0 = brep.m_T.Count();
01091     const int loop_count0 = brep.m_L.Count();
01092     //const int face_count0 = brep.m_F.Count();
01093 
01094     // count number of new objects so we can grow arrays
01095     // efficiently and use refs to dynamic array elements.
01096     int new_side_trim_count = 0;
01097     for ( fli = 0; fli < face_loop_count; fli++ )
01098     {
01099       li = brep.m_F[face_index].m_li[fli];
01100       if ( li < 0 || li >= loop_count0 )
01101         return false;
01102       if ( !ON_BrepExtrudeHelper_CheckLoop( brep, li ) )
01103         continue;
01104       new_side_trim_count += brep.m_L[li].m_ti.Count();
01105     }
01106     if ( new_side_trim_count == 0 )
01107       return false;
01108     ON_BrepExtrudeHelper_ReserveSpace( brep, new_side_trim_count, 0 );
01109 
01110     const ON_BrepFace& face = brep.m_F[face_index];
01111 
01112     //ON_BrepVertex& apex_vertex = 
01113     brep.NewVertex( apex_point, 0.0 );
01114   
01115     rc = true;
01116     for ( fli = 0; fli < face_loop_count && rc; fli++ )
01117     {
01118       li = face.m_li[fli];
01119       if ( !ON_BrepExtrudeHelper_CheckLoop( brep, li ) )
01120         continue;
01121 
01122       rc = ON_BrepConeLoop( brep, li, apex_point );
01123     }
01124   }
01125 
01126   return rc;
01127 }
01128 
01129 
01130 bool ON_BrepConeLoop( 
01131           ON_Brep& brep,
01132           int loop_index,
01133           ON_3dPoint apex_point
01134           )
01135 {
01136   if ( loop_index < 0 && loop_index >= brep.m_L.Count() )
01137     return false;
01138 
01139   int lti, ti, i, vid[4], eid[4], bRev3d[4];
01140 
01141   // indices of new faces appended to the side_face_index[] array 
01142   // (1 face index for each trim, -1 is used for singular trims)
01143 
01144   // count number of new objects so we can grow arrays
01145   // efficiently and use refs to dynamic array elements.
01146   const int loop_trim_count = brep.m_L[loop_index].m_ti.Count();
01147   if ( loop_trim_count == 0 )
01148     return false;
01149 
01150   // save input trim and edge counts for use below
01151   const int trim_count0 = brep.m_T.Count();
01152   const int edge_count0 = brep.m_E.Count();
01153 
01154   ON_BrepExtrudeHelper_ReserveSpace( brep, loop_trim_count, 0 );
01155 
01156   int prev_face_index = -1;
01157   int first_face_east_trim_index = -1;
01158 
01159   ON_BrepVertex& apex_vertex = brep.NewVertex( apex_point, 0.0 );
01160 
01161   for ( lti = 0; lti < loop_trim_count; lti++ )
01162   {
01163     ON_NurbsSurface* cone_srf = 0;
01164     ti = brep.m_L[loop_index].m_ti[lti];
01165     if ( ti < 0 || ti >= trim_count0 )
01166       continue;
01167 
01168     for ( i = 0; i < 4; i++ )
01169     {
01170       vid[i] = -1;
01171       eid[i] = -1;
01172     }
01173     bRev3d[0] = false;
01174     bRev3d[1] = false;
01175     bRev3d[2] = false;
01176     bRev3d[3] = false;
01177 
01178     // get side surface for new face
01179     // get side surface for new face
01180     {
01181       ON_BrepTrim& trim = brep.m_T[ti];
01182       if ( trim.m_ei >= 0 &&  trim.m_ei < edge_count0 )
01183       {
01184         const ON_BrepEdge& base_edge = brep.m_E[trim.m_ei];
01185 
01186         // connect new face to existing topology on trim
01187         vid[0] = trim.m_vi[1];
01188         vid[1] = trim.m_vi[0];
01189         eid[0] = base_edge.m_edge_index;
01190         bRev3d[0] = (trim.m_bRev3d?false:true);
01191         cone_srf = ON_BrepExtrudeHelper_MakeConeSrf( apex_point, base_edge, bRev3d[0] );
01192       }
01193     }
01194     if ( !cone_srf )
01195       continue;
01196     vid[2] = apex_vertex.m_vertex_index;
01197     vid[3] = apex_vertex.m_vertex_index;
01198 
01199     if ( prev_face_index >= 0 )
01200     {
01201       const ON_BrepTrim& prev_west_trim = brep.m_T[ brep.m_L[ brep.m_F[prev_face_index].m_li[0]].m_ti[3] ];
01202       vid[2] = prev_west_trim.m_vi[0];
01203       eid[1] = prev_west_trim.m_ei;
01204       bRev3d[1] = (prev_west_trim.m_bRev3d?false:true);
01205     }
01206     if ( first_face_east_trim_index >= 0 && brep.m_T[first_face_east_trim_index].m_vi[0] == vid[0] )
01207     {
01208       const ON_BrepTrim& first_face_east_trim = brep.m_T[first_face_east_trim_index];
01209       vid[3] = first_face_east_trim.m_vi[1];
01210       eid[3] = first_face_east_trim.m_ei;
01211       bRev3d[3] = (first_face_east_trim.m_bRev3d?false:true);
01212     }
01213     const ON_BrepFace* side_face = brep.NewFace(cone_srf,vid,eid,bRev3d);
01214     if ( side_face )
01215     {
01216       prev_face_index = side_face->m_face_index;
01217       if ( first_face_east_trim_index < 0 )
01218         first_face_east_trim_index = brep.m_L[ side_face->m_li[0] ].m_ti[1];
01219     }
01220   }
01221 
01222   return true;
01223 }
01224 
01225 
01226 
01227 int ON_BrepConeEdge( 
01228           ON_Brep& brep,
01229           int edge_index,
01230           ON_3dPoint apex_point
01231           )
01232 {
01233   //ON_3dVector path_vector;
01234 
01235   if ( edge_index < 0 && edge_index >= brep.m_E.Count() )
01236     return false;
01237 
01238   // make sides
01239   ON_NurbsSurface* cone_srf = ON_BrepExtrudeHelper_MakeConeSrf( 
01240                               apex_point, brep.m_E[edge_index], false );
01241 
01242   if ( !cone_srf )
01243     return false;
01244 
01245   int vid[4], eid[4], bRev3d[4];
01246 
01247   vid[0] = brep.m_E[edge_index].m_vi[0];
01248   vid[1] = brep.m_E[edge_index].m_vi[1];
01249   vid[2] = -1;
01250   vid[3] = -1;
01251 
01252   eid[0] = edge_index;
01253   eid[1] = -1;
01254   eid[2] = -1;
01255   eid[3] = -1;
01256 
01257   bRev3d[0] = 0;
01258   bRev3d[1] = 0;
01259   bRev3d[2] = 0;
01260   bRev3d[3] = 0;
01261 
01262   return brep.NewFace( cone_srf, vid, eid, bRev3d ) ? true : false;
01263 }
01264 


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