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