0023024: Update headers of OCCT files
[occt.git] / src / HLRTopoBRep / HLRTopoBRep_DSFiller.cxx
1 // Created on: 1993-08-10
2 // Created by: Christophe MARION
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21
22 #include <HLRTopoBRep_DSFiller.ixx>
23
24 #include <TopoDS.hxx>
25 #include <TopExp.hxx>
26 #include <TopExp_Explorer.hxx>
27 #include <math_Vector.hxx>
28 #include <TColgp_Array1OfPnt.hxx>
29 #include <TColgp_Array1OfPnt2d.hxx>
30 #include <TColStd_Array1OfReal.hxx>
31 #include <TColStd_Array1OfInteger.hxx>
32 #include <Geom_Line.hxx>
33 #include <Geom_Circle.hxx>
34 #include <Geom_Surface.hxx>
35 #include <Geom_BSplineCurve.hxx>
36 #include <GeomProjLib.hxx>
37 #include <Geom2d_Curve.hxx>
38 #include <Geom2d_BSplineCurve.hxx>
39 #include <AppDef_BSplineCompute.hxx>
40 #include <AppDef_MultiLine.hxx>
41 #include <AppDef_MultiPointConstraint.hxx>
42 #include <AppParCurves_MultiBSpCurve.hxx>
43 #include <HLRTopoBRep_FaceIsoLiner.hxx>
44 #include <BRep_Tool.hxx>
45 #include <BRep_Builder.hxx>
46 #include <BRepAdaptor_Curve.hxx>
47 #include <BRepAdaptor_Curve2d.hxx>
48 #include <BRepAdaptor_HCurve2d.hxx>
49 #include <BRepTopAdaptor_HVertex.hxx>
50 #include <BRepTopAdaptor_TopolTool.hxx>
51 #include <BRepTopAdaptor_Tool.hxx>
52 #include <Contap_TheLineOfContour.hxx>
53 #include <Extrema_LocateExtPC.hxx>
54 #include <Standard_ProgramError.hxx>
55 #include <Precision.hxx>
56 #include <BRepApprox_ApproxLine.hxx>
57 #include <BRepApprox_Approx.hxx>
58
59 #define INTERPOLATE 0
60 #define BRISE       0
61 #define APPROX      1
62
63 //=======================================================================
64 //function : Insert
65 //purpose  : explore the faces and insert them
66 //=======================================================================
67
68 void  HLRTopoBRep_DSFiller::Insert (const TopoDS_Shape& S,
69                                     Contap_Contour& FO,
70                                     HLRTopoBRep_Data& DS,
71                                     BRepTopAdaptor_MapOfShapeTool& MST,
72                                     const Standard_Integer nbIso)
73 {
74   TopTools_MapOfShape ShapeMap;
75   TopExp_Explorer ex(S,TopAbs_FACE);
76   DS.Clear();
77   Standard_Boolean withPCurve = Standard_True; // instead of nbIso != 0;
78   Standard_Integer f = 0;
79   
80   while (ex.More()) {
81     if (ShapeMap.Add(ex.Current())) {
82       f++;
83       TopoDS_Face S1 = TopoDS::Face(ex.Current());
84       S1.Orientation(TopAbs_FORWARD);
85       Handle(BRepTopAdaptor_TopolTool) Domain; 
86       Handle(Adaptor3d_HSurface)         Surface;
87       if(MST.IsBound(S1)) {  
88         BRepTopAdaptor_Tool& BRT = MST.ChangeFind(S1);
89         Domain  = BRT.GetTopolTool();
90         Surface = BRT.GetSurface();
91       }
92       else { 
93         BRepTopAdaptor_Tool BRT(S1,Precision::PConfusion());
94         MST.Bind(S1,BRT);
95         Domain  = BRT.GetTopolTool();
96         Surface = BRT.GetSurface();
97       }
98       FO.Perform(Surface,Domain);
99       if (FO.IsDone()) {
100         if (!FO.IsEmpty())
101           InsertFace(f,S1,FO,DS,withPCurve);
102       }
103       if (nbIso != 0) HLRTopoBRep_FaceIsoLiner::Perform(f,S1,DS,nbIso);
104     }
105     ex.Next();
106   }
107   ProcessEdges(DS);
108 }
109
110 //=======================================================================
111 //function : InsertFace
112 //purpose  : private, insert the outlines of a face
113 //=======================================================================
114
115 void  HLRTopoBRep_DSFiller::InsertFace (const Standard_Integer FI,
116                                         const TopoDS_Face& F,
117                                         Contap_Contour& FO,
118                                         HLRTopoBRep_Data& DS,
119                                         const Standard_Boolean withPCurve)
120 {
121   // Insert the intersections of FO in DS
122
123   const Standard_Real tol = BRep_Tool::Tolerance(F);
124   TopTools_ListOfShape& IntL = DS.AddIntL(F);
125   TopTools_ListOfShape& OutL = DS.AddOutL(F);
126
127   TopoDS_Vertex VF,VL;
128   /*
129   TopTools_MapOfShape VM;
130   TopExp_Explorer ex(F,TopAbs_EDGE);
131   while (ex.More()) {
132     const TopoDS_Edge& E = TopoDS::Edge(ex.Current());
133     if (BRep_Tool::IsClosed(E,F)) {
134       TopExp::Vertices(E,VF,VL);
135       VM.Add(VF);
136       VM.Add(VL);
137     }
138     ex.Next();
139   }
140   */
141
142   const Standard_Integer NbLines = FO.NbLines();
143   Standard_Integer CurLine = 1;
144   for (; CurLine <= NbLines; CurLine++)
145   {
146     const Contap_TheLineOfContour& Line = FO.Line(CurLine);
147     const Standard_Integer NbPoints = Line.NbVertex();
148     Standard_Integer CurPoint;
149     if (Line.TypeContour() == Contap_Restriction)
150     {
151       // OutLine on restriction
152       TopoDS_Edge E = (*(BRepAdaptor_Curve2d*)&(Line.Arc()->Curve2d())).Edge();
153       OutL.Append(E);
154       TopExp::Vertices(E,VF,VL);
155       // insert the Internal points.
156
157       for (CurPoint = 1; CurPoint <= NbPoints; CurPoint++) {
158         Contap_ThePointOfContour P = Line.Vertex(CurPoint);
159         if (P.IsInternal()) {
160           if (P.Value().IsEqual(BRep_Tool::Pnt(VF),BRep_Tool::Tolerance(VF))) {
161             if (P.Value().IsEqual(BRep_Tool::Pnt(VL),BRep_Tool::Tolerance(VL))) {
162               InsertVertex(P,tol,E,DS);
163             }
164           }
165         }
166       }
167     }
168     else
169     {
170       for (CurPoint = 1; CurPoint <= NbPoints; CurPoint++) {
171
172         const Contap_ThePointOfContour PF = Line.Vertex(CurPoint);
173         if (PF.IsInternal() && CurPoint != 1)
174           VF = VL;
175         else
176           VF = MakeVertex(PF,tol,DS);
177         const Standard_Real parF = PF.ParameterOnLine();
178
179         if (CurPoint < NbPoints) {
180           const Contap_ThePointOfContour PL = Line.Vertex(CurPoint+1);
181           VL = MakeVertex(PL,tol,DS);
182           const Standard_Real parL = PL.ParameterOnLine();
183
184           if( (parL-parF) > Precision::PConfusion() ) {
185
186             Handle(Geom_Curve) C;
187             Handle(Geom2d_Curve) C2d;
188             Standard_Real first = parF;
189             Standard_Real last  = parL;
190             Standard_Boolean InsuffisantNumberOfPoints=Standard_False;
191
192             switch (Line.TypeContour()) {
193               
194               case Contap_Lin :
195               {
196                 C = new Geom_Line(Line.Line());
197                 if (withPCurve) {
198                   Handle(Geom_Surface) S = BRep_Tool::Surface(F);
199                   Standard_Real Tol = 1e-7;
200                   C2d = GeomProjLib::Curve2d(C,first,last,S,Tol); 
201                 }
202               }
203               break;
204               
205               case Contap_Circle :
206               {
207                 C = new Geom_Circle(Line.Circle());
208                 if (withPCurve) {
209                   TopLoc_Location Loc;
210                   Handle(Geom_Surface) S = BRep_Tool::Surface(F,Loc);
211                   if (!Loc.IsIdentity()) {
212                     S = Handle(Geom_Surface)::DownCast(S->Transformed(Loc.Transformation()));
213                   }
214                   Standard_Real Tol = 1e-7;
215                   C2d = GeomProjLib::Curve2d(C,first,last,S,Tol); 
216                 }
217               }
218               break;
219               
220               case Contap_Walking :
221               {
222                 // copy the points
223                 Standard_Integer ipF = Standard_Integer(parF);
224                 Standard_Integer ipL = Standard_Integer(parL);
225                 
226                 if(ipL-ipF < 1) { 
227                   InsuffisantNumberOfPoints=Standard_True;
228                   //cout<<"\n !! Pb ds HLRTopoBRep_DSFiller.cxx (Contour App Nbp <3)"<<endl;
229                 }
230 /*
231                 else if(ipL-ipF < 6) { 
232                   // compute the tangents
233                   Contap_TheSurfFunctionOfContour& SFunc =
234                     FO.SurfaceFunction();
235                   
236                   Standard_Boolean isTg1,isTg2;
237                   gp_Vec tg1,tg2;
238                   gp_Vec2d uv1,uv2;
239                   math_Vector UV(1,2),F(1,1);
240                   
241                   Line.Point(ipF).ParametersOnS2(UV(1),UV(2));
242                   SFunc.Value(UV,F);
243                   isTg1 = SFunc.IsTangent();
244                   if (!isTg1) {
245                     tg1 = SFunc.Direction3d();
246                     if (withPCurve) uv1 = SFunc.Direction2d();
247                   }
248                   
249                   Line.Point(ipL).ParametersOnS2(UV(1),UV(2));
250                   SFunc.Value(UV,F);
251                   isTg2 = SFunc.IsTangent();
252                   if (!isTg2) {
253                     tg2 = SFunc.Direction3d();
254                     if (withPCurve) uv2 = SFunc.Direction2d();
255                   }
256                   // interpolate
257                   Standard_Integer nbp = ipL - ipF + 1;
258                   AppDef_MultiLine MLine(nbp);
259                   Standard_Integer nb2d = 0;
260                   if (withPCurve)  nb2d = 1;
261                   
262                   for (Standard_Integer i = 1; i <= nbp; i++) {
263                     AppDef_MultiPointConstraint MP(1, nb2d);
264                     MP.SetPoint(1,Line.Point(i + ipF - 1).Value());
265                     if (withPCurve) {
266                       Line.Point(i + ipF - 1).ParametersOnS2(UV(1),UV(2));
267                       MP.SetPoint2d(2,gp_Pnt2d(UV(1),UV(2)));
268                     }
269                     
270                     if (i == 1   && !isTg1) {
271                       MP.SetTang  (1,tg1);
272                       if (withPCurve) MP.SetTang2d(2,uv1);
273                     }
274                     if (i == nbp && !isTg2) {
275                       MP.SetTang  (1,tg2);
276                       if (withPCurve) MP.SetTang2d(2,uv2);
277                     }
278                     MLine.SetValue(i,MP);
279                   }
280                   AppDef_BSplineCompute interp;
281                   interp.Interpol(MLine);
282                   AppParCurves_MultiBSpCurve TheCurve = interp.Value();
283                   Standard_Integer Degree = TheCurve.Degree();
284                   TColgp_Array1OfPnt   Poles(1,TheCurve.NbPoles());
285                   TheCurve.Curve(1,Poles);
286                   C   = new Geom_BSplineCurve(Poles, 
287                                               TheCurve.Knots(),
288                                               TheCurve.Multiplicities(),
289                                               Degree);
290                   if (withPCurve) {
291                     TColgp_Array1OfPnt2d Pol2d(1,TheCurve.NbPoles());
292                     TheCurve.Curve(2,Pol2d);
293                     C2d = new Geom2d_BSplineCurve(Pol2d, 
294                                                   TheCurve.Knots(),
295                                                   TheCurve.Multiplicities(),
296                                                   Degree);
297                   }
298                   first = 0;
299                   last = 1;
300                 }
301 */
302                 else if(ipL-ipF < 5) { 
303                   const Standard_Integer nbp = ipL - ipF + 1;
304                   TColStd_Array1OfReal knots(1,nbp);
305                   TColStd_Array1OfInteger mults(1,nbp);
306                   TColgp_Array1OfPnt Points(1,nbp);
307
308                   for(Standard_Integer i=1;i<=nbp;i++) {
309                     knots.SetValue(i,(Standard_Real)i);
310                     mults.SetValue(i,1);
311                     Points.SetValue(i,Line.Point(i+ipF-1).Value());
312                   }
313                   mults(1)=mults(nbp)=2;
314                   C = new Geom_BSplineCurve(Points,knots,mults,1);
315                   
316                   if(withPCurve) { 
317                     TColgp_Array1OfPnt2d Points2d(1,nbp);
318                     for(Standard_Integer i=1;i<=nbp;i++) {
319                       Standard_Real u,v;
320                       Line.Point(i+ipF-1).ParametersOnS2(u,v);
321                       Points2d.SetValue(i,gp_Pnt2d(u,v));
322                     }
323                     C2d = new Geom2d_BSplineCurve(Points2d,knots,mults,1);
324                   }
325                   first = 1;
326                   last = nbp;
327                 }
328                 else { 
329                   const Standard_Integer nbp = ipL - ipF + 1;
330                   TColStd_Array1OfReal knots(1,nbp);
331                   TColStd_Array1OfInteger mults(1,nbp);
332                   TColgp_Array1OfPnt Points(1,nbp);
333
334                   Standard_Real Maxx,Maxy,Maxz,Maxu,Maxv;
335                   Standard_Real Minx,Miny,Minz,Minu,Minv;
336                   Maxx=Maxy=Maxz=Maxu=Maxv=-RealLast();
337                   Minx=Miny=Minz=Minu=Minv=RealLast();
338                   
339                   for(Standard_Integer i=1;i<=nbp;i++) {
340                     knots.SetValue(i,(Standard_Real)i);
341                     mults.SetValue(i,1);
342                     const gp_Pnt& P= Line.Point(i+ipF-1).Value();
343                     if(P.X()<Minx) Minx=P.X();
344                     if(P.Y()<Miny) Miny=P.Y();
345                     if(P.Z()<Minz) Minz=P.Z();
346                     if(P.X()>Maxx) Maxx=P.X();
347                     if(P.Y()>Maxy) Maxy=P.Y();
348                     if(P.Z()>Maxz) Maxz=P.Z();              
349                     Points.SetValue(i,P);
350                   }
351                   mults(1)=mults(nbp)=2;
352                   Handle(Geom_BSplineCurve)   AppC;
353                   Handle(Geom2d_BSplineCurve) AppC2d;
354                   AppC = new Geom_BSplineCurve(Points,knots,mults,1);
355
356                   if(withPCurve) {
357                     TColgp_Array1OfPnt2d Points2d(1,nbp);
358                     for(Standard_Integer i=1;i<=nbp;i++) {
359                       Standard_Real u,v;
360                       Line.Point(i+ipF-1).ParametersOnS2(u,v);
361                       if(u<Minu) Minu=u;
362                       if(v<Minv) Minv=v;
363                       if(u>Maxu) Maxu=u;
364                       if(v>Maxv) Maxv=v;
365                       Points2d.SetValue(i,gp_Pnt2d(u,v));
366                     }
367                     AppC2d = new Geom2d_BSplineCurve(Points2d,knots,mults,1);
368                   }
369                   first = 1;
370                   last = nbp;
371                   
372                   Handle(BRepApprox_ApproxLine) AppLine;
373                   Handle(Geom2d_BSplineCurve) CNull;
374                   AppLine = new BRepApprox_ApproxLine(AppC,AppC2d,CNull);
375                   
376                   Standard_Integer dmin=4,dmax=8,niter=0;
377                   Standard_Boolean tg= Standard_False;
378                   BRepApprox_Approx Approx;
379                   Standard_Real TOL3d,TOL2d,TOL=0.0001;
380
381                   Maxx-=Minx; Maxy-=Miny; Maxz-=Minz;
382                   Maxu-=Minu; Maxv-=Minv;
383                   if(Maxy>Maxx) Maxx=Maxy;
384                   if(Maxz>Maxx) Maxx=Maxy;
385                   if(Maxv>Maxu) Maxu=Maxv;
386
387                   TOL3d=TOL*Maxx; if(TOL3d<1e-12) TOL3d=1e-12; else if(TOL3d>0.1) TOL3d=0.1;
388                   TOL2d=TOL*Maxu; if(TOL2d<1e-12) TOL2d=1e-12; else if(TOL2d>0.1) TOL2d=0.1;
389                   
390                   //-- cout<<"\nHLRTopoBRep_DSFiller : nbp="<<nbp<<"  Tol3d="<<TOL3d<<"   Tol2d="<<TOL2d<<endl;
391
392                   Approx.SetParameters(TOL3d,TOL2d,dmin,dmax,niter,tg);
393                   Approx.Perform(AppLine,Standard_True,Standard_True,Standard_False,1,nbp);
394                   if (!Approx.IsDone()) {
395                     C = AppC;
396                     C2d=AppC2d; 
397                     first = 1;
398                     last = nbp;
399                   }
400                   else { 
401                     const AppParCurves_MultiBSpCurve& AppVal = Approx.Value(1); 
402                     TColgp_Array1OfPnt poles3d(1,AppVal.NbPoles());
403                     AppVal.Curve(1,poles3d);
404                     C = new Geom_BSplineCurve(poles3d,AppVal.Knots(),AppVal.Multiplicities(),AppVal.Degree());
405                     
406                     const AppParCurves_MultiBSpCurve& AppVal2 = Approx.Value(2);
407                     TColgp_Array1OfPnt2d poles2d(1,AppVal2.NbPoles());
408                     AppVal2.Curve(2,poles2d);
409                     C2d = new Geom2d_BSplineCurve(poles2d,AppVal2.Knots(),AppVal2.Multiplicities(),AppVal2.Degree());
410                     first = C2d->FirstParameter();
411                     last  = C2d->LastParameter();
412                   }
413                 }
414               }
415               break;
416               
417               case Contap_Restriction :
418               {
419                 Standard_ProgramError::Raise("HLRTopoBRep_DSFiller::InsertFace : Restriction");
420               }
421               break;
422             }
423             
424             // compute the PCurve
425             // make the edge
426             if (!InsuffisantNumberOfPoints) {
427               TopoDS_Edge E;
428               BRep_Builder B;
429               B.MakeEdge(E,C,tol);
430               VF.Orientation(TopAbs_FORWARD);
431               VL.Orientation(TopAbs_REVERSED);
432               B.Add(E,VF);
433               B.Add(E,VL);
434               B.Range(E,first,last);
435
436               if (!C2d.IsNull()) {
437                 BRep_Builder B;
438                 B.UpdateEdge(E,C2d,F,BRep_Tool::Tolerance(F));
439               }
440               
441               // add the edge in the DS
442               if (!E.IsNull())
443                 IntL.Append(E);
444             }
445           }
446         }
447       }
448     }
449   }
450 }
451
452 //=======================================================================
453 //function : MakeVertex
454 //purpose  : private, make a vertex from an intersection point
455 //=======================================================================
456
457 TopoDS_Vertex
458 HLRTopoBRep_DSFiller::MakeVertex (const Contap_ThePointOfContour& P,
459                                   const Standard_Real tol,
460                                   HLRTopoBRep_Data& DS)
461 {
462   BRep_Builder B;
463   TopoDS_Vertex V;
464   if (P.IsVertex()) {
465     V = Handle(BRepTopAdaptor_HVertex)::DownCast(P.Vertex())->Vertex();
466     DS.AddOutV(V);
467   }
468   else {
469     // if on arc, insert in the DS
470     if (P.IsOnArc()) {
471       const TopoDS_Edge& E = 
472         (*(BRepAdaptor_Curve2d*)&((P.Arc())->Curve2d())).Edge();
473       Standard_Real Par = P.ParameterOnArc();
474       const gp_Pnt& P3d = P.Value();
475
476       for (DS.InitVertex(E); DS.MoreVertex(); DS.NextVertex()) {
477         TopoDS_Vertex curV = DS.Vertex();
478         Standard_Real curP = DS.Parameter();
479         const gp_Pnt& PPP=BRep_Tool::Pnt(curV);
480         Standard_Real TTT=BRep_Tool::Tolerance(curV);
481         if (P3d.IsEqual(PPP,TTT)) { 
482           V = curV;
483           break;
484         }
485         else if (Par < curP) {
486           B.MakeVertex(V,P.Value(),tol);
487           DS.InsertBefore(V,Par);
488           break;
489         }
490       }
491       if (!DS.MoreVertex()) {
492         B.MakeVertex(V,P.Value(),tol);
493         DS.Append(V,Par);
494       } 
495       DS.AddOutV(V);
496     }
497     // if internal create a vertex and insert in the DS
498     else {
499       B.MakeVertex(V,P.Value(),tol);
500       if (P.IsInternal())
501         DS.AddIntV(V);
502       else
503         DS.AddOutV(V);
504     }
505   }
506   return V;
507 }
508
509 //=======================================================================
510 //function : InsertVertex
511 //purpose  : private, insert a vertex from an internal intersection point
512 //           on resctriction
513 //=======================================================================
514
515 void
516 HLRTopoBRep_DSFiller::InsertVertex (const Contap_ThePointOfContour& P,
517                                     const Standard_Real tol,
518                                     const TopoDS_Edge& E,
519                                     HLRTopoBRep_Data& DS)
520 {
521   BRep_Builder B;
522   TopoDS_Vertex V;
523
524   if (P.IsVertex()) {
525     V = Handle(BRepTopAdaptor_HVertex)::DownCast(P.Vertex())->Vertex();
526   }
527   else {
528     Standard_Real Par = P.ParameterOnLine();
529     
530     for (DS.InitVertex(E); DS.MoreVertex(); DS.NextVertex()) {
531       TopoDS_Vertex curV = DS.Vertex();
532       Standard_Real curP = DS.Parameter();
533       if (P.Value().IsEqual(BRep_Tool::Pnt(curV),
534                             BRep_Tool::Tolerance(curV))) {
535         V = curV;
536         break;
537       }
538       else if (Par < curP) {
539         B.MakeVertex(V,P.Value(),tol);
540         DS.InsertBefore(V,Par);
541         break;
542       }
543     }
544     if (!DS.MoreVertex()) {
545       B.MakeVertex(V,P.Value(),tol);
546       DS.Append(V,Par);
547     }   
548   }
549   DS.AddIntV(V);
550 }
551
552 //=======================================================================
553 //function : ProcessEdges
554 //purpose  : private, split edges with outline vertices
555 //=======================================================================
556
557 void  HLRTopoBRep_DSFiller::ProcessEdges (HLRTopoBRep_Data& DS)
558 {
559   BRep_Builder B;
560   TopoDS_Edge newE;
561   TopoDS_Vertex VF,VL,VI;
562   Standard_Real PF,PL,PI;
563
564   for (DS.InitEdge(); DS.MoreEdge(); DS.NextEdge()) {
565     TopoDS_Edge E = DS.Edge();
566     TopTools_ListOfShape& SplE = DS.AddSplE(E);
567     VF = TopExp::FirstVertex(E);
568     VL = TopExp::LastVertex(E);
569     BRep_Tool::Range(E,PF,PL);
570     VF.Orientation(TopAbs_FORWARD);
571     VL.Orientation(TopAbs_REVERSED);
572
573     for (DS.InitVertex(E); DS.MoreVertex(); DS.NextVertex()) {
574       VI = DS.Vertex();
575       PI = DS.Parameter();
576       VI.Orientation(TopAbs_REVERSED);
577       newE = E;
578       newE.EmptyCopy();
579       newE.Orientation(TopAbs_FORWARD);
580       B.Add(newE,VF);
581       B.UpdateVertex(VF,PF,newE,BRep_Tool::Tolerance(VF));
582       B.Add(newE,VI);
583       B.UpdateVertex(VI,PI,newE,BRep_Tool::Tolerance(VI));
584       newE.Orientation(E.Orientation());
585       SplE.Append(newE);
586       VF = VI;
587       PF = PI;
588       VF.Orientation(TopAbs_FORWARD);
589     }
590     newE = E;
591     newE.EmptyCopy();
592     newE.Orientation(TopAbs_FORWARD);
593     B.Add(newE,VF);
594     B.UpdateVertex(VF,PF,newE,BRep_Tool::Tolerance(VF));
595     B.Add(newE,VL);
596     B.UpdateVertex(VL,PL,newE,BRep_Tool::Tolerance(VL));
597     newE.Orientation(E.Orientation());
598     SplE.Append(newE);
599   }
600 }
601