0023625: New functionality building reflect lines on a shape
[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 #include <BRep_TEdge.hxx>
59 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
60 #include <BRep_CurveRepresentation.hxx>
61 #include <BRepExtrema_ExtPC.hxx>
62 #include <TopTools_ListIteratorOfListOfShape.hxx>
63
64 #define INTERPOLATE 0
65 #define BRISE       0
66 #define APPROX      1
67
68
69 static Standard_Boolean IntLineRisesFromRegularity(const TopoDS_Edge& anIntLine,
70                                                    const TopoDS_Edge& anEdge,
71                                                    const TopoDS_Face& aFace,
72                                                    const TopTools_ListOfShape& aList)
73 {
74   TopoDS_Vertex Ver [2];
75   TopExp::Vertices(anIntLine, Ver[0], Ver[1]);
76
77   //find min param and max param
78   Standard_Real MinPar = RealLast(), MaxPar = RealFirst();
79   TopTools_ListIteratorOfListOfShape itl(aList);
80   for (; itl.More(); itl.Next())
81   {
82     const TopoDS_Edge& anOutLine = TopoDS::Edge(itl.Value());
83     Standard_Real aFirst, aLast;
84     BRep_Tool::Range(anOutLine, aFirst, aLast);
85     if (aFirst < MinPar)
86       MinPar = aFirst;
87     if (aLast > MaxPar)
88       MaxPar = aLast;
89   }
90   
91   Standard_Real theTol = BRep_Tool::Tolerance(anEdge);
92   Standard_Real ParamTol = Precision::Confusion();
93   
94   Standard_Integer i, j;
95   for (i = 0; i < 2; i++)
96   {
97     BRepExtrema_ExtPC anExtPC(Ver[i], anEdge);
98     if (!anExtPC.IsDone())
99       continue;
100     Standard_Integer NbExt = anExtPC.NbExt();
101     if (NbExt == 0)
102       continue;
103     Standard_Integer jmin = 1;
104     for (j = 2; j <= NbExt; j++)
105       if (anExtPC.SquareDistance(j) < anExtPC.SquareDistance(jmin))
106         jmin = j;
107     Standard_Real aDist = anExtPC.SquareDistance(jmin);
108     aDist = Sqrt(aDist);
109     if (aDist > theTol)
110       continue;
111
112     Standard_Real theParam = anExtPC.Parameter(jmin);
113     if (theParam > MinPar + ParamTol &&
114         theParam < MaxPar - ParamTol)
115       return Standard_True;
116   }
117
118   return Standard_False;
119 }
120
121
122 //=======================================================================
123 //function : Insert
124 //purpose  : explore the faces and insert them
125 //=======================================================================
126
127 void  HLRTopoBRep_DSFiller::Insert (const TopoDS_Shape& S,
128                                     Contap_Contour& FO,
129                                     HLRTopoBRep_Data& DS,
130                                     BRepTopAdaptor_MapOfShapeTool& MST,
131                                     const Standard_Integer nbIso)
132 {
133   TopTools_MapOfShape ShapeMap;
134   TopExp_Explorer ex(S,TopAbs_FACE);
135   DS.Clear();
136   Standard_Boolean withPCurve = Standard_True; // instead of nbIso != 0;
137   Standard_Integer f = 0;
138   
139   while (ex.More()) {
140     if (ShapeMap.Add(ex.Current())) {
141       f++;
142       TopoDS_Face S1 = TopoDS::Face(ex.Current());
143       S1.Orientation(TopAbs_FORWARD);
144       Handle(BRepTopAdaptor_TopolTool) Domain; 
145       Handle(Adaptor3d_HSurface)         Surface;
146       if(MST.IsBound(S1)) {  
147         BRepTopAdaptor_Tool& BRT = MST.ChangeFind(S1);
148         Domain  = BRT.GetTopolTool();
149         Surface = BRT.GetSurface();
150       }
151       else { 
152         BRepTopAdaptor_Tool BRT(S1,Precision::PConfusion());
153         MST.Bind(S1,BRT);
154         Domain  = BRT.GetTopolTool();
155         Surface = BRT.GetSurface();
156       }
157       FO.Perform(Surface, Domain);
158       if (FO.IsDone()) {
159         if (!FO.IsEmpty())
160           InsertFace(f,S1,FO,DS,withPCurve);
161       }
162       if (nbIso != 0) HLRTopoBRep_FaceIsoLiner::Perform(f,S1,DS,nbIso);
163     }
164     ex.Next();
165   }
166   ProcessEdges(DS);
167 }
168
169 //=======================================================================
170 //function : InsertFace
171 //purpose  : private, insert the outlines of a face
172 //=======================================================================
173
174 void  HLRTopoBRep_DSFiller::InsertFace (const Standard_Integer FI,
175                                         const TopoDS_Face& F,
176                                         Contap_Contour& FO,
177                                         HLRTopoBRep_Data& DS,
178                                         const Standard_Boolean withPCurve)
179 {
180   // Insert the intersections of FO in DS
181
182   const Standard_Real tol = BRep_Tool::Tolerance(F);
183   TopTools_ListOfShape& IntL = DS.AddIntL(F);
184   TopTools_ListOfShape& OutL = DS.AddOutL(F);
185
186   TopoDS_Vertex VF,VL;
187   /*
188   TopTools_MapOfShape VM;
189   TopExp_Explorer ex(F,TopAbs_EDGE);
190   while (ex.More()) {
191     const TopoDS_Edge& E = TopoDS::Edge(ex.Current());
192     if (BRep_Tool::IsClosed(E,F)) {
193       TopExp::Vertices(E,VF,VL);
194       VM.Add(VF);
195       VM.Add(VL);
196     }
197     ex.Next();
198   }
199   */
200
201   const Standard_Integer NbLines = FO.NbLines();
202   Standard_Integer CurLine;
203   for (CurLine = 1; CurLine <= NbLines; CurLine++)
204   {
205     const Contap_TheLineOfContour& Line = FO.Line(CurLine);
206     const Standard_Integer NbPoints = Line.NbVertex();
207     Standard_Integer CurPoint;
208     if (Line.TypeContour() == Contap_Restriction)
209     {
210       // OutLine on restriction
211       TopoDS_Edge E = (*(BRepAdaptor_Curve2d*)&(Line.Arc()->Curve2d())).Edge();
212       OutL.Append(E);
213       TopExp::Vertices(E,VF,VL);
214       // insert the Internal points.
215
216       for (CurPoint = 1; CurPoint <= NbPoints; CurPoint++) {
217         Contap_ThePointOfContour P = Line.Vertex(CurPoint);
218         if (P.IsInternal()) {
219           if (P.Value().IsEqual(BRep_Tool::Pnt(VF),BRep_Tool::Tolerance(VF))) {
220             if (P.Value().IsEqual(BRep_Tool::Pnt(VL),BRep_Tool::Tolerance(VL))) {
221               InsertVertex(P,tol,E,DS);
222             }
223           }
224         }
225       }
226     }
227     else
228     {
229       for (CurPoint = 1; CurPoint <= NbPoints; CurPoint++) {
230
231         const Contap_ThePointOfContour PF = Line.Vertex(CurPoint);
232         if (PF.IsInternal() && CurPoint != 1)
233           VF = VL;
234         else
235           VF = MakeVertex(PF,tol,DS);
236         const Standard_Real parF = PF.ParameterOnLine();
237
238         if (CurPoint < NbPoints) {
239           const Contap_ThePointOfContour PL = Line.Vertex(CurPoint+1);
240           VL = MakeVertex(PL,tol,DS);
241           const Standard_Real parL = PL.ParameterOnLine();
242
243           if( (parL-parF) > Precision::PConfusion() ) {
244
245             Handle(Geom_Curve) C;
246             Handle(Geom2d_Curve) C2d;
247             Standard_Real first = parF;
248             Standard_Real last  = parL;
249             Standard_Boolean InsuffisantNumberOfPoints=Standard_False;
250
251             switch (Line.TypeContour()) {
252               
253               case Contap_Lin :
254               {
255                 C = new Geom_Line(Line.Line());
256                 if (withPCurve) {
257                   Handle(Geom_Surface) S = BRep_Tool::Surface(F);
258                   Standard_Real Tol = 1e-7;
259                   C2d = GeomProjLib::Curve2d(C,first,last,S,Tol); 
260                 }
261               }
262               break;
263               
264               case Contap_Circle :
265               {
266                 C = new Geom_Circle(Line.Circle());
267                 if (withPCurve) {
268                   TopLoc_Location Loc;
269                   Handle(Geom_Surface) S = BRep_Tool::Surface(F,Loc);
270                   if (!Loc.IsIdentity()) {
271                     S = Handle(Geom_Surface)::DownCast(S->Transformed(Loc.Transformation()));
272                   }
273                   Standard_Real Tol = 1e-7;
274                   C2d = GeomProjLib::Curve2d(C,first,last,S,Tol); 
275                 }
276               }
277               break;
278               
279               case Contap_Walking :
280               {
281                 // copy the points
282                 Standard_Integer ipF = Standard_Integer(parF);
283                 Standard_Integer ipL = Standard_Integer(parL);
284                 
285                 if(ipL-ipF < 1) { 
286                   InsuffisantNumberOfPoints=Standard_True;
287                   //cout<<"\n !! Pb ds HLRTopoBRep_DSFiller.cxx (Contour App Nbp <3)"<<endl;
288                 }
289 /*
290                 else if(ipL-ipF < 6) { 
291                   // compute the tangents
292                   Contap_TheSurfFunctionOfContour& SFunc =
293                     FO.SurfaceFunction();
294                   
295                   Standard_Boolean isTg1,isTg2;
296                   gp_Vec tg1,tg2;
297                   gp_Vec2d uv1,uv2;
298                   math_Vector UV(1,2),F(1,1);
299                   
300                   Line.Point(ipF).ParametersOnS2(UV(1),UV(2));
301                   SFunc.Value(UV,F);
302                   isTg1 = SFunc.IsTangent();
303                   if (!isTg1) {
304                     tg1 = SFunc.Direction3d();
305                     if (withPCurve) uv1 = SFunc.Direction2d();
306                   }
307                   
308                   Line.Point(ipL).ParametersOnS2(UV(1),UV(2));
309                   SFunc.Value(UV,F);
310                   isTg2 = SFunc.IsTangent();
311                   if (!isTg2) {
312                     tg2 = SFunc.Direction3d();
313                     if (withPCurve) uv2 = SFunc.Direction2d();
314                   }
315                   // interpolate
316                   Standard_Integer nbp = ipL - ipF + 1;
317                   AppDef_MultiLine MLine(nbp);
318                   Standard_Integer nb2d = 0;
319                   if (withPCurve)  nb2d = 1;
320                   
321                   for (Standard_Integer i = 1; i <= nbp; i++) {
322                     AppDef_MultiPointConstraint MP(1, nb2d);
323                     MP.SetPoint(1,Line.Point(i + ipF - 1).Value());
324                     if (withPCurve) {
325                       Line.Point(i + ipF - 1).ParametersOnS2(UV(1),UV(2));
326                       MP.SetPoint2d(2,gp_Pnt2d(UV(1),UV(2)));
327                     }
328                     
329                     if (i == 1   && !isTg1) {
330                       MP.SetTang  (1,tg1);
331                       if (withPCurve) MP.SetTang2d(2,uv1);
332                     }
333                     if (i == nbp && !isTg2) {
334                       MP.SetTang  (1,tg2);
335                       if (withPCurve) MP.SetTang2d(2,uv2);
336                     }
337                     MLine.SetValue(i,MP);
338                   }
339                   AppDef_BSplineCompute interp;
340                   interp.Interpol(MLine);
341                   AppParCurves_MultiBSpCurve TheCurve = interp.Value();
342                   Standard_Integer Degree = TheCurve.Degree();
343                   TColgp_Array1OfPnt   Poles(1,TheCurve.NbPoles());
344                   TheCurve.Curve(1,Poles);
345                   C   = new Geom_BSplineCurve(Poles, 
346                                               TheCurve.Knots(),
347                                               TheCurve.Multiplicities(),
348                                               Degree);
349                   if (withPCurve) {
350                     TColgp_Array1OfPnt2d Pol2d(1,TheCurve.NbPoles());
351                     TheCurve.Curve(2,Pol2d);
352                     C2d = new Geom2d_BSplineCurve(Pol2d, 
353                                                   TheCurve.Knots(),
354                                                   TheCurve.Multiplicities(),
355                                                   Degree);
356                   }
357                   first = 0;
358                   last = 1;
359                 }
360 */
361                 else if(ipL-ipF < 5) { 
362                   const Standard_Integer nbp = ipL - ipF + 1;
363                   TColStd_Array1OfReal knots(1,nbp);
364                   TColStd_Array1OfInteger mults(1,nbp);
365                   TColgp_Array1OfPnt Points(1,nbp);
366
367                   for(Standard_Integer i=1;i<=nbp;i++) {
368                     knots.SetValue(i,(Standard_Real)i);
369                     mults.SetValue(i,1);
370                     Points.SetValue(i,Line.Point(i+ipF-1).Value());
371                   }
372                   mults(1)=mults(nbp)=2;
373                   C = new Geom_BSplineCurve(Points,knots,mults,1);
374                   
375                   if(withPCurve) { 
376                     TColgp_Array1OfPnt2d Points2d(1,nbp);
377                     for(Standard_Integer i=1;i<=nbp;i++) {
378                       Standard_Real u,v;
379                       Line.Point(i+ipF-1).ParametersOnS2(u,v);
380                       Points2d.SetValue(i,gp_Pnt2d(u,v));
381                     }
382                     C2d = new Geom2d_BSplineCurve(Points2d,knots,mults,1);
383                   }
384                   first = 1;
385                   last = nbp;
386                 }
387                 else { 
388                   const Standard_Integer nbp = ipL - ipF + 1;
389                   TColStd_Array1OfReal knots(1,nbp);
390                   TColStd_Array1OfInteger mults(1,nbp);
391                   TColgp_Array1OfPnt Points(1,nbp);
392
393                   Standard_Real Maxx,Maxy,Maxz,Maxu,Maxv;
394                   Standard_Real Minx,Miny,Minz,Minu,Minv;
395                   Maxx=Maxy=Maxz=Maxu=Maxv=-RealLast();
396                   Minx=Miny=Minz=Minu=Minv=RealLast();
397                   
398                   for(Standard_Integer i=1;i<=nbp;i++) {
399                     knots.SetValue(i,(Standard_Real)i);
400                     mults.SetValue(i,1);
401                     const gp_Pnt& P= Line.Point(i+ipF-1).Value();
402                     if(P.X()<Minx) Minx=P.X();
403                     if(P.Y()<Miny) Miny=P.Y();
404                     if(P.Z()<Minz) Minz=P.Z();
405                     if(P.X()>Maxx) Maxx=P.X();
406                     if(P.Y()>Maxy) Maxy=P.Y();
407                     if(P.Z()>Maxz) Maxz=P.Z();              
408                     Points.SetValue(i,P);
409                   }
410                   mults(1)=mults(nbp)=2;
411                   Handle(Geom_BSplineCurve)   AppC;
412                   Handle(Geom2d_BSplineCurve) AppC2d;
413                   AppC = new Geom_BSplineCurve(Points,knots,mults,1);
414
415                   if(withPCurve) {
416                     TColgp_Array1OfPnt2d Points2d(1,nbp);
417                     for(Standard_Integer i=1;i<=nbp;i++) {
418                       Standard_Real u,v;
419                       Line.Point(i+ipF-1).ParametersOnS2(u,v);
420                       if(u<Minu) Minu=u;
421                       if(v<Minv) Minv=v;
422                       if(u>Maxu) Maxu=u;
423                       if(v>Maxv) Maxv=v;
424                       Points2d.SetValue(i,gp_Pnt2d(u,v));
425                     }
426                     AppC2d = new Geom2d_BSplineCurve(Points2d,knots,mults,1);
427                   }
428                   first = 1;
429                   last = nbp;
430                   
431                   Handle(BRepApprox_ApproxLine) AppLine;
432                   Handle(Geom2d_BSplineCurve) CNull;
433                   AppLine = new BRepApprox_ApproxLine(AppC,AppC2d,CNull);
434                   
435                   Standard_Integer dmin=4,dmax=8,niter=0;
436                   Standard_Boolean tg= Standard_False;
437                   BRepApprox_Approx Approx;
438                   Standard_Real TOL3d,TOL2d,TOL=0.0001;
439
440                   Maxx-=Minx; Maxy-=Miny; Maxz-=Minz;
441                   Maxu-=Minu; Maxv-=Minv;
442                   if(Maxy>Maxx) Maxx=Maxy;
443                   if(Maxz>Maxx) Maxx=Maxy;
444                   if(Maxv>Maxu) Maxu=Maxv;
445
446                   TOL3d=TOL*Maxx; if(TOL3d<1e-12) TOL3d=1e-12; else if(TOL3d>0.1) TOL3d=0.1;
447                   TOL2d=TOL*Maxu; if(TOL2d<1e-12) TOL2d=1e-12; else if(TOL2d>0.1) TOL2d=0.1;
448                   
449                   //-- cout<<"\nHLRTopoBRep_DSFiller : nbp="<<nbp<<"  Tol3d="<<TOL3d<<"   Tol2d="<<TOL2d<<endl;
450
451                   Approx.SetParameters(TOL3d,TOL2d,dmin,dmax,niter,tg);
452                   Approx.Perform(AppLine,Standard_True,Standard_True,Standard_False,1,nbp);
453                   if (!Approx.IsDone()) {
454                     C = AppC;
455                     C2d=AppC2d; 
456                     first = 1;
457                     last = nbp;
458                   }
459                   else { 
460                     const AppParCurves_MultiBSpCurve& AppVal = Approx.Value(1); 
461                     TColgp_Array1OfPnt poles3d(1,AppVal.NbPoles());
462                     AppVal.Curve(1,poles3d);
463                     C = new Geom_BSplineCurve(poles3d,AppVal.Knots(),AppVal.Multiplicities(),AppVal.Degree());
464                     
465                     const AppParCurves_MultiBSpCurve& AppVal2 = Approx.Value(2);
466                     TColgp_Array1OfPnt2d poles2d(1,AppVal2.NbPoles());
467                     AppVal2.Curve(2,poles2d);
468                     C2d = new Geom2d_BSplineCurve(poles2d,AppVal2.Knots(),AppVal2.Multiplicities(),AppVal2.Degree());
469                     first = C2d->FirstParameter();
470                     last  = C2d->LastParameter();
471                   }
472                 }
473               }
474               break;
475               
476               case Contap_Restriction :
477               {
478                 Standard_ProgramError::Raise("HLRTopoBRep_DSFiller::InsertFace : Restriction");
479               }
480               break;
481             }
482             
483             // compute the PCurve
484             // make the edge
485             if (!InsuffisantNumberOfPoints) {
486               TopoDS_Edge E;
487               BRep_Builder B;
488               B.MakeEdge(E,C,tol);
489               VF.Orientation(TopAbs_FORWARD);
490               VL.Orientation(TopAbs_REVERSED);
491               B.Add(E,VF);
492               B.Add(E,VL);
493               B.Range(E,first,last);
494
495               if (!C2d.IsNull()) {
496                 BRep_Builder B;
497                 B.UpdateEdge(E,C2d,F,BRep_Tool::Tolerance(F));
498               }
499               
500               // add the edge in the DS
501               if (!E.IsNull())
502                 IntL.Append(E);
503             }
504           }
505         }
506       }
507     }
508   }
509
510   //jgv: correction of internal outlines: remove those that rise from middle of boundary outlines
511   TopTools_ListIteratorOfListOfShape itl(IntL);
512   while (itl.More())
513   {
514     TopoDS_Edge anIntLine = TopoDS::Edge(itl.Value());
515     Standard_Real found = Standard_False;
516     TopExp_Explorer Explo(F, TopAbs_EDGE);
517     for (; Explo.More(); Explo.Next())
518     {
519       TopoDS_Edge anEdge = TopoDS::Edge(Explo.Current());
520       if (!BRep_Tool::HasContinuity(anEdge))
521         continue;
522
523       TopLoc_Location RegLoc;
524       Standard_Real fpar, lpar;
525       Handle(Geom_Curve) RegCurve = BRep_Tool::Curve(anEdge, RegLoc, fpar, lpar);
526       TopTools_ListOfShape thelist;
527       TopTools_ListIteratorOfListOfShape itoutl(OutL);
528       for (; itoutl.More(); itoutl.Next())
529       {
530         TopoDS_Edge anOutLine = TopoDS::Edge(itoutl.Value());
531         TopLoc_Location aLoc;
532         Standard_Real aFirst, aLast;
533         Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anOutLine, aLoc, aFirst, aLast);
534         if (aCurve == RegCurve && aLoc == RegLoc)
535           thelist.Append(anOutLine);
536       }
537
538       if (thelist.IsEmpty())
539         continue;
540
541       if (IntLineRisesFromRegularity(anIntLine, anEdge, F, thelist))
542       {
543         IntL.Remove(itl);
544         found = Standard_True;
545         break;
546       }
547     }
548     
549     if (!found)
550       itl.Next();
551   }
552   ///////////////////////////////////////////////////
553 }
554
555 //=======================================================================
556 //function : MakeVertex
557 //purpose  : private, make a vertex from an intersection point
558 //=======================================================================
559
560 TopoDS_Vertex
561 HLRTopoBRep_DSFiller::MakeVertex (const Contap_ThePointOfContour& P,
562                                   const Standard_Real tol,
563                                   HLRTopoBRep_Data& DS)
564 {
565   BRep_Builder B;
566   TopoDS_Vertex V;
567   if (P.IsVertex()) {
568     V = Handle(BRepTopAdaptor_HVertex)::DownCast(P.Vertex())->Vertex();
569     DS.AddOutV(V);
570   }
571   else {
572     // if on arc, insert in the DS
573     if (P.IsOnArc()) {
574       const TopoDS_Edge& E = 
575         (*(BRepAdaptor_Curve2d*)&((P.Arc())->Curve2d())).Edge();
576       Standard_Real Par = P.ParameterOnArc();
577       const gp_Pnt& P3d = P.Value();
578
579       for (DS.InitVertex(E); DS.MoreVertex(); DS.NextVertex()) {
580         TopoDS_Vertex curV = DS.Vertex();
581         Standard_Real curP = DS.Parameter();
582         const gp_Pnt& PPP=BRep_Tool::Pnt(curV);
583         Standard_Real TTT=BRep_Tool::Tolerance(curV);
584         if (P3d.IsEqual(PPP,TTT)) { 
585           V = curV;
586           break;
587         }
588         else if (Par < curP) {
589           B.MakeVertex(V,P.Value(),tol);
590           DS.InsertBefore(V,Par);
591           break;
592         }
593       }
594       if (!DS.MoreVertex()) {
595         B.MakeVertex(V,P.Value(),tol);
596         DS.Append(V,Par);
597       } 
598       DS.AddOutV(V);
599     }
600     // if internal create a vertex and insert in the DS
601     else {
602       B.MakeVertex(V,P.Value(),tol);
603       if (P.IsInternal())
604         DS.AddIntV(V);
605       else
606         DS.AddOutV(V);
607     }
608   }
609   return V;
610 }
611
612 //=======================================================================
613 //function : InsertVertex
614 //purpose  : private, insert a vertex from an internal intersection point
615 //           on resctriction
616 //=======================================================================
617
618 void
619 HLRTopoBRep_DSFiller::InsertVertex (const Contap_ThePointOfContour& P,
620                                     const Standard_Real tol,
621                                     const TopoDS_Edge& E,
622                                     HLRTopoBRep_Data& DS)
623 {
624   BRep_Builder B;
625   TopoDS_Vertex V;
626
627   if (P.IsVertex()) {
628     V = Handle(BRepTopAdaptor_HVertex)::DownCast(P.Vertex())->Vertex();
629   }
630   else {
631     Standard_Real Par = P.ParameterOnLine();
632     
633     for (DS.InitVertex(E); DS.MoreVertex(); DS.NextVertex()) {
634       TopoDS_Vertex curV = DS.Vertex();
635       Standard_Real curP = DS.Parameter();
636       if (P.Value().IsEqual(BRep_Tool::Pnt(curV),
637                             BRep_Tool::Tolerance(curV))) {
638         V = curV;
639         break;
640       }
641       else if (Par < curP) {
642         B.MakeVertex(V,P.Value(),tol);
643         DS.InsertBefore(V,Par);
644         break;
645       }
646     }
647     if (!DS.MoreVertex()) {
648       B.MakeVertex(V,P.Value(),tol);
649       DS.Append(V,Par);
650     }   
651   }
652   DS.AddIntV(V);
653 }
654
655 //=======================================================================
656 //function : ProcessEdges
657 //purpose  : private, split edges with outline vertices
658 //=======================================================================
659
660 void  HLRTopoBRep_DSFiller::ProcessEdges (HLRTopoBRep_Data& DS)
661 {
662   BRep_Builder B;
663   TopoDS_Edge newE;
664   TopoDS_Vertex VF,VL,VI;
665   Standard_Real PF,PL,PI;
666
667   for (DS.InitEdge(); DS.MoreEdge(); DS.NextEdge()) {
668     TopoDS_Edge E = DS.Edge();
669     TopTools_ListOfShape& SplE = DS.AddSplE(E);
670     VF = TopExp::FirstVertex(E);
671     VL = TopExp::LastVertex(E);
672     BRep_Tool::Range(E,PF,PL);
673     VF.Orientation(TopAbs_FORWARD);
674     VL.Orientation(TopAbs_REVERSED);
675
676     for (DS.InitVertex(E); DS.MoreVertex(); DS.NextVertex()) {
677       VI = DS.Vertex();
678       PI = DS.Parameter();
679       VI.Orientation(TopAbs_REVERSED);
680       newE = E;
681       newE.EmptyCopy();
682       newE.Orientation(TopAbs_FORWARD);
683       B.Add(newE,VF);
684       B.UpdateVertex(VF,PF,newE,BRep_Tool::Tolerance(VF));
685       B.Add(newE,VI);
686       B.UpdateVertex(VI,PI,newE,BRep_Tool::Tolerance(VI));
687       newE.Orientation(E.Orientation());
688       SplE.Append(newE);
689       VF = VI;
690       PF = PI;
691       VF.Orientation(TopAbs_FORWARD);
692     }
693     newE = E;
694     newE.EmptyCopy();
695     newE.Orientation(TopAbs_FORWARD);
696     B.Add(newE,VF);
697     B.UpdateVertex(VF,PF,newE,BRep_Tool::Tolerance(VF));
698     B.Add(newE,VL);
699     B.UpdateVertex(VL,PL,newE,BRep_Tool::Tolerance(VL));
700     newE.Orientation(E.Orientation());
701     SplE.Append(newE);
702   }
703 }
704