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