static bool ON_BrepExtrudeHelper_MakeCap( ON_Brep& brep, int bottom_loop_index, const ON_3dVector path_vector, const int* side_face_index ) { bool bCap = true; // make cap if ( !ON_BrepExtrudeHelper_CheckLoop( brep, bottom_loop_index ) ) return false; brep.m_F.Reserve(brep.m_F.Count() + 1); brep.m_L.Reserve(brep.m_L.Count() + 1); const ON_BrepLoop& bottom_loop = brep.m_L[bottom_loop_index]; const ON_BrepFace& bottom_face = brep.m_F[bottom_loop.m_fi]; const ON_Surface* bottom_surface = bottom_face.SurfaceOf(); ON_Surface* top_surface = bottom_surface->Duplicate(); top_surface->Translate( path_vector ); int top_surface_index = brep.AddSurface( top_surface ); ON_BrepFace& top_face = brep.NewFace( top_surface_index ); bCap = ON_BrepExtrudeHelper_MakeTopLoop( brep, top_face, bottom_loop_index, path_vector, side_face_index ); if ( bCap ) { ON_BrepLoop& top_loop = brep.m_L[brep.m_L.Count()-1]; if ( bottom_loop.m_type == ON_BrepLoop::inner ) { // we capped an inner boundary // top_loop.m_type = ON_BrepLoop::outer; // done in ON_BrepExtrudeHelper_MakeTopLoop brep.FlipLoop(top_loop); } else if ( bottom_loop.m_type == ON_BrepLoop::outer ) { // we capped an outer boundary // top_loop.m_type = ON_BrepLoop::outer; // done in ON_BrepExtrudeHelper_MakeTopLoop brep.FlipFace(top_face); } } else { // delete partially made cap face brep.DeleteFace( top_face, false ); delete brep.m_S[top_surface_index]; brep.m_S[top_surface_index] = 0; } return bCap; }
int ON_BrepExtrudeLoop( ON_Brep& brep, int loop_index, const ON_Curve& path_curve, bool bCap ) { ON_SimpleArray<int> side_face_index; // index of new face above brep.m_L[loop_index].m_ti[lti] ON_3dVector path_vector; const int face_count0 = brep.m_F.Count(); if ( loop_index < 0 || loop_index >= brep.m_L.Count() ) return false; if ( !ON_BrepExtrudeHelper_CheckPathCurve(path_curve,path_vector) ) return false; // can only cap closed loops ( for now, just test for inner and outer loops). if ( brep.m_L[loop_index].m_type != ON_BrepLoop::outer && brep.m_L[loop_index].m_type != ON_BrepLoop::inner ) bCap = false; // make sides if ( !ON_BrepExtrudeHelper_MakeSides( brep, loop_index, path_curve, bCap, side_face_index ) ) return false; // make cap if ( bCap ) bCap = ON_BrepExtrudeHelper_MakeCap( brep, loop_index, path_vector, side_face_index.Array() ); const ON_BrepLoop& loop = brep.m_L[loop_index]; if ( loop.m_fi >= 0 && loop.m_fi < brep.m_F.Count() && brep.m_F[loop.m_fi].m_bRev ) { for ( int fi = face_count0; fi < brep.m_F.Count(); fi++ ) { brep.FlipFace( brep.m_F[fi] ); } } return (bCap?2:1); }
int ON_BrepExtrudeFace( ON_Brep& brep, int face_index, const ON_Curve& path_curve, bool bCap ) { int rc = 0; // returns 1 for success with no cap, 2 for success with a cap if ( face_index < 0 || face_index >= brep.m_F.Count() ) return false; const int face_loop_count = brep.m_F[face_index].m_li.Count(); if ( face_loop_count < 1 ) return false; if ( brep.m_F[face_index].m_li.Count() == 1 ) { rc = ON_BrepExtrudeLoop( brep, brep.m_F[face_index].m_li[0], path_curve, bCap ); } else { ON_3dVector path_vector; ON_SimpleArray<int> side_face_index; ON_SimpleArray<int> side_face_index_loop_mark; int li, fli; if ( !ON_BrepExtrudeHelper_CheckPathCurve( path_curve, path_vector ) ) return 0; //const int trim_count0 = brep.m_T.Count(); const int loop_count0 = brep.m_L.Count(); const int face_count0 = brep.m_F.Count(); // count number of new objects so we can grow arrays // efficiently and use refs to dynamic array elements. int new_side_trim_count = 0; for ( fli = 0; fli < face_loop_count; fli++ ) { li = brep.m_F[face_index].m_li[fli]; if ( li < 0 || li >= loop_count0 ) return false; if ( !ON_BrepExtrudeHelper_CheckLoop( brep, li ) ) continue; new_side_trim_count += brep.m_L[li].m_ti.Count(); } if ( new_side_trim_count == 0 ) return false; ON_BrepExtrudeHelper_ReserveSpace( brep, new_side_trim_count, bCap?1:0 ); side_face_index.Reserve(new_side_trim_count); side_face_index_loop_mark.Reserve(face_loop_count); const ON_BrepFace& face = brep.m_F[face_index]; rc = true; int outer_loop_index = -1; int outer_fli = -1; for ( fli = 0; fli < face_loop_count && rc; fli++ ) { side_face_index_loop_mark.Append( side_face_index.Count() ); li = face.m_li[fli]; if ( !ON_BrepExtrudeHelper_CheckLoop( brep, li ) ) continue; ON_BrepLoop& loop = brep.m_L[li]; if ( bCap && loop.m_type == ON_BrepLoop::outer ) { if ( outer_loop_index >= 0 ) bCap = false; else { outer_loop_index = li; outer_fli = fli; } } rc = ON_BrepExtrudeHelper_MakeSides( brep, li, path_curve, bCap, side_face_index ); } if ( bCap && rc && outer_loop_index >= 0 ) { const int face_count1 = brep.m_F.Count(); bCap = ON_BrepExtrudeHelper_MakeCap( brep, outer_loop_index, path_vector, side_face_index.Array() + side_face_index_loop_mark[outer_fli] ); if ( bCap && brep.m_F.Count() > face_count1) { // put inner bondaries on the cap rc = 2; ON_BrepFace& cap_face = brep.m_F[brep.m_F.Count()-1]; for ( fli = 0; fli < face_loop_count && rc; fli++ ) { li = face.m_li[fli]; if ( li == outer_loop_index ) continue; if ( !ON_BrepExtrudeHelper_CheckLoop( brep, li ) ) continue; if ( ON_BrepExtrudeHelper_MakeTopLoop( brep, cap_face, li, path_vector, side_face_index.Array() + side_face_index_loop_mark[fli] ) ) { ON_BrepLoop& top_loop = brep.m_L[brep.m_L.Count()-1]; top_loop.m_type = brep.m_L[li].m_type; } } } } if ( brep.m_F[face_index].m_bRev ) { for ( int fi = face_count0; fi < brep.m_F.Count(); fi++ ) { brep.FlipFace(brep.m_F[fi]); } } } return rc; }