0026936: Drawbacks of inlining in new type system in OCCT 7.0 -- manual
[occt.git] / src / BRepTopAdaptor / BRepTopAdaptor_TopolTool.cxx
1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15
16 #include <Adaptor2d_HCurve2d.hxx>
17 #include <Adaptor3d_HSurface.hxx>
18 #include <Adaptor3d_HVertex.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRepAdaptor_HCurve2d.hxx>
21 #include <BRepAdaptor_HSurface.hxx>
22 #include <BRepClass_FaceClassifier.hxx>
23 #include <BRepClass_FaceExplorer.hxx>
24 #include <BRepTopAdaptor_FClass2d.hxx>
25 #include <BRepTopAdaptor_HVertex.hxx>
26 #include <BRepTopAdaptor_TopolTool.hxx>
27 #include <Geom_BezierSurface.hxx>
28 #include <Geom_BSplineSurface.hxx>
29 #include <gp_Pnt.hxx>
30 #include <gp_Pnt2d.hxx>
31 #include <Precision.hxx>
32 #include <Standard_ConstructionError.hxx>
33 #include <Standard_DomainError.hxx>
34 #include <Standard_NotImplemented.hxx>
35 #include <Standard_Type.hxx>
36 #include <TColgp_Array2OfPnt.hxx>
37 #include <TopoDS.hxx>
38
39 static 
40   void Analyse(const TColgp_Array2OfPnt& array2,
41                const Standard_Integer nbup,
42                const Standard_Integer nbvp,
43                Standard_Integer& myNbSamplesU,
44                Standard_Integer& myNbSamplesV); 
45 //=======================================================================
46 //function : BRepTopAdaptor_TopolTool
47 //purpose  : 
48 //=======================================================================
49   BRepTopAdaptor_TopolTool::BRepTopAdaptor_TopolTool () : myFClass2d(NULL)
50 {
51   myNbSamplesU=-1;
52 }
53
54 //=======================================================================
55 //function : BRepTopAdaptor_TopolTool
56 //purpose  : 
57 //=======================================================================
58   BRepTopAdaptor_TopolTool::BRepTopAdaptor_TopolTool(const Handle(Adaptor3d_HSurface)& S) 
59 : myFClass2d(NULL)
60 {
61   Initialize(S);
62   //myS = S;
63 }
64 //=======================================================================
65 //function : Initialize
66 //purpose  : 
67 //=======================================================================
68   void BRepTopAdaptor_TopolTool::Initialize()
69 {
70   Standard_NotImplemented::Raise("BRepTopAdaptor_TopolTool::Initialize()");
71 }
72 //=======================================================================
73 //function : Initialize
74 //purpose  : 
75 //=======================================================================
76   void BRepTopAdaptor_TopolTool::Initialize(const Handle(Adaptor3d_HSurface)& S)
77 {
78   Handle(BRepAdaptor_HSurface) brhs = 
79     Handle(BRepAdaptor_HSurface)::DownCast(S);
80   if (brhs.IsNull()) {Standard_ConstructionError::Raise();}
81   TopoDS_Shape s_wnt = ((BRepAdaptor_Surface *)&(brhs->Surface()))->Face();
82   s_wnt.Orientation(TopAbs_FORWARD);
83   myFace = TopoDS::Face(s_wnt);
84   if(myFClass2d != NULL) { 
85     delete (BRepTopAdaptor_FClass2d *)myFClass2d;
86   } 
87   myFClass2d = NULL;
88   myNbSamplesU=-1;
89   myS = S;
90   myCurves.Clear();
91   TopExp_Explorer ex(myFace,TopAbs_EDGE);
92   for (; ex.More(); ex.Next()) {
93     Handle(BRepAdaptor_HCurve2d) aCurve = new BRepAdaptor_HCurve2d
94       (BRepAdaptor_Curve2d(TopoDS::Edge(ex.Current()),myFace));
95     myCurves.Append(aCurve);
96   }
97   myCIterator = TColStd_ListIteratorOfListOfTransient();
98 }
99 //=======================================================================
100 //function : Initialize
101 //purpose  : 
102 //=======================================================================
103   void BRepTopAdaptor_TopolTool::Initialize(const Handle(Adaptor2d_HCurve2d)& C)
104 {
105   myCurve = Handle(BRepAdaptor_HCurve2d)::DownCast(C);
106   if (myCurve.IsNull()) {Standard_ConstructionError::Raise();}
107 }
108 //=======================================================================
109 //function : Init
110 //purpose  : 
111 //=======================================================================
112   void BRepTopAdaptor_TopolTool::Init ()
113 {
114   myCIterator.Initialize(myCurves);
115 }
116 //=======================================================================
117 //function : More
118 //purpose  : 
119 //=======================================================================
120   Standard_Boolean BRepTopAdaptor_TopolTool::More ()
121 {
122   return myCIterator.More();
123 }
124 //=======================================================================
125 //function : Next
126 //purpose  : 
127 //=======================================================================
128   void BRepTopAdaptor_TopolTool::Next()
129 {
130   myCIterator.Next();
131 }
132 //=======================================================================
133 //function : Value
134 //purpose  : 
135 //=======================================================================
136   Handle(Adaptor2d_HCurve2d) BRepTopAdaptor_TopolTool::Value ()
137 {
138   return Handle(Adaptor2d_HCurve2d)::DownCast(myCIterator.Value());
139 }
140 //modified by NIZNHY-PKV Tue Mar 27 14:23:40 2001 f
141 //=======================================================================
142 //function : Edge
143 //purpose  : 
144 //=======================================================================
145   Standard_Address BRepTopAdaptor_TopolTool::Edge () const
146 {
147   Handle(BRepAdaptor_HCurve2d) aHCurve =
148     Handle(BRepAdaptor_HCurve2d)::DownCast(myCIterator.Value());
149   const BRepAdaptor_Curve2d& aCurve = (const BRepAdaptor_Curve2d&)aHCurve->Curve2d();
150   return Standard_Address (& aCurve.Edge());
151 }
152
153 //modified by NIZNHY-PKV Tue Mar 27 14:23:43 2001 t
154 //=======================================================================
155 //function : InitVertexIterator
156 //purpose  : 
157 //=======================================================================
158   void BRepTopAdaptor_TopolTool::InitVertexIterator ()
159 {
160   myVIterator.Init(((BRepAdaptor_Curve2d *)&(myCurve->Curve2d()))->Edge(),TopAbs_VERTEX);
161 }
162 //=======================================================================
163 //function : NextVertex
164 //purpose  : 
165 //=======================================================================
166   Standard_Boolean BRepTopAdaptor_TopolTool::MoreVertex ()
167 {
168   return myVIterator.More();
169 }
170
171   void BRepTopAdaptor_TopolTool::NextVertex ()
172 {
173   myVIterator.Next();
174 }
175 //=======================================================================
176 //function : Vertex
177 //purpose  : 
178 //=======================================================================
179   Handle(Adaptor3d_HVertex) BRepTopAdaptor_TopolTool::Vertex ()
180 {
181   return new 
182     BRepTopAdaptor_HVertex(TopoDS::Vertex(myVIterator.Current()),myCurve);
183 }
184   
185 //=======================================================================
186 //function : Classify
187 //purpose  : 
188 //=======================================================================
189   TopAbs_State BRepTopAdaptor_TopolTool::Classify(const gp_Pnt2d& P,
190                                                   const Standard_Real Tol,
191                                                   const Standard_Boolean RecadreOnPeriodic)
192 {
193   if(myFace.IsNull())
194     return TopAbs_UNKNOWN;
195   if(myFClass2d == NULL) { 
196     myFClass2d = (void *) new BRepTopAdaptor_FClass2d(myFace,Tol);
197   } 
198   return(((BRepTopAdaptor_FClass2d *)myFClass2d)->Perform(P,RecadreOnPeriodic));
199 }
200
201 //=======================================================================
202 //function : IsThePointOn
203 //purpose  : 
204 //=======================================================================
205   Standard_Boolean BRepTopAdaptor_TopolTool::IsThePointOn(const gp_Pnt2d& P,
206                                                           const Standard_Real Tol,
207                                                           const Standard_Boolean RecadreOnPeriodic)
208 {
209   if(myFClass2d == NULL) { 
210     myFClass2d = (void *) new BRepTopAdaptor_FClass2d(myFace,Tol);
211   } 
212   return(TopAbs_ON==((BRepTopAdaptor_FClass2d *)myFClass2d)->TestOnRestriction(P,Tol,RecadreOnPeriodic));
213 }
214
215 //=======================================================================
216 //function : Destroy
217 //purpose  : 
218 //=======================================================================
219   void BRepTopAdaptor_TopolTool::Destroy() 
220
221   if(myFClass2d != NULL) { 
222     delete (BRepTopAdaptor_FClass2d *)myFClass2d;
223     myFClass2d=NULL;
224   }
225 }
226 //=======================================================================
227 //function : Orientation
228 //purpose  : 
229 //=======================================================================
230   TopAbs_Orientation BRepTopAdaptor_TopolTool::Orientation  (const Handle(Adaptor2d_HCurve2d)& C)
231 {
232   Handle(BRepAdaptor_HCurve2d) brhc =
233     Handle(BRepAdaptor_HCurve2d)::DownCast(C);
234   return ((BRepAdaptor_Curve2d *)&(brhc->Curve2d()))->Edge().Orientation(); 
235 }
236 //=======================================================================
237 //function : Orientation
238 //purpose  : 
239 //=======================================================================
240   TopAbs_Orientation BRepTopAdaptor_TopolTool::Orientation  (const Handle(Adaptor3d_HVertex)& C)
241 {
242  return Adaptor3d_TopolTool::Orientation(C); 
243 }
244 //-- ============================================================
245 //-- methods  used for samples
246 //-- ============================================================ 
247
248 //=======================================================================
249 //function : Analyse
250 //purpose  : 
251 //=======================================================================
252 void Analyse(const TColgp_Array2OfPnt& array2,
253              const Standard_Integer nbup,
254              const Standard_Integer nbvp,
255              Standard_Integer& myNbSamplesU,
256              Standard_Integer& myNbSamplesV) 
257
258   gp_Vec Vi,Vip1;
259   Standard_Integer sh,nbch,i,j;
260   
261   sh = 1;
262   nbch = 0;
263   if(nbvp>2) { 
264     for(i=2;i<nbup;i++) { 
265       const gp_Pnt& A=array2.Value(i,1);
266       const gp_Pnt& B=array2.Value(i,2);
267       const gp_Pnt& C=array2.Value(i,3);
268       Vi.SetCoord(C.X()-B.X()-B.X()+A.X(),
269                   C.Y()-B.Y()-B.Y()+A.Y(),
270                   C.Z()-B.Z()-B.Z()+A.Z());
271       Standard_Integer locnbch=0;
272       for(j=3; j<nbvp;j++) {  //-- test
273         const gp_Pnt& Ax=array2.Value(i,j-1);
274         const gp_Pnt& Bx=array2.Value(i,j);
275         const gp_Pnt& Cx=array2.Value(i,j+1);
276         Vip1.SetCoord(Cx.X()-Bx.X()-Bx.X()+Ax.X(),
277                       Cx.Y()-Bx.Y()-Bx.Y()+Ax.Y(),
278                       Cx.Z()-Bx.Z()-Bx.Z()+Ax.Z());
279         Standard_Real pd = Vi.Dot(Vip1);
280         Vi=Vip1;
281         if(pd>1.0e-7 || pd<-1.0e-7) {  
282           if(pd>0) {  if(sh==-1) {   sh=1; locnbch++;   }  }
283           else {        if(sh==1) {  sh=-1; locnbch++;  }  }
284         }
285       }
286       if(locnbch>nbch) { 
287         nbch=locnbch; 
288       }
289     }
290   }
291   myNbSamplesV = nbch+5;
292   
293
294   nbch=0;
295   if(nbup>2) { 
296     for(j=2;j<nbvp;j++) { 
297       const gp_Pnt& A=array2.Value(1,j);
298       const gp_Pnt& B=array2.Value(2,j);
299       const gp_Pnt& C=array2.Value(3,j);
300       Vi.SetCoord(C.X()-B.X()-B.X()+A.X(),
301                   C.Y()-B.Y()-B.Y()+A.Y(),
302                   C.Z()-B.Z()-B.Z()+A.Z());
303       Standard_Integer locnbch=0;
304       for(i=3; i<nbup;i++) {  //-- test
305         const gp_Pnt& Ax=array2.Value(i-1,j);
306         const gp_Pnt& Bx=array2.Value(i,j);
307         const gp_Pnt& Cx=array2.Value(i+1,j);
308         Vip1.SetCoord(Cx.X()-Bx.X()-Bx.X()+Ax.X(),
309                     Cx.Y()-Bx.Y()-Bx.Y()+Ax.Y(),
310                     Cx.Z()-Bx.Z()-Bx.Z()+Ax.Z());
311         Standard_Real pd = Vi.Dot(Vip1);
312         Vi=Vip1;
313         if(pd>1.0e-7 || pd<-1.0e-7) {  
314           if(pd>0) {  if(sh==-1) {   sh=1; locnbch++;   }  }
315           else {        if(sh==1) {  sh=-1; locnbch++;  }  }
316         }
317       }
318       if(locnbch>nbch) nbch=locnbch;
319     }  
320   }
321   myNbSamplesU = nbch+5;
322 }  
323
324
325
326
327 //=======================================================================
328 //function : ComputeSamplePoints
329 //purpose  : 
330 //=======================================================================
331   void BRepTopAdaptor_TopolTool::ComputeSamplePoints() 
332
333   Standard_Real uinf,usup,vinf,vsup;
334   uinf = myS->FirstUParameter();  usup = myS->LastUParameter();
335   vinf = myS->FirstVParameter();  vsup = myS->LastVParameter();
336   if (usup < uinf) { Standard_Real temp=uinf; uinf=usup; usup=temp; }
337   if (vsup < vinf) { Standard_Real temp=vinf; vinf=vsup; vsup=temp; }
338   if (uinf == RealFirst() && usup == RealLast()) { uinf=-1.e5; usup=1.e5; }
339   else if (uinf == RealFirst()) { uinf=usup-2.e5; }
340   else if (usup == RealLast()) {  usup=uinf+2.e5; }
341   
342   if (vinf == RealFirst() && vsup == RealLast()) { vinf=-1.e5; vsup=1.e5; }
343   else if (vinf == RealFirst()) { vinf=vsup-2.e5;  }
344   else if (vsup == RealLast()) {  vsup=vinf+2.e5;  }
345   
346   Standard_Integer nbsu,nbsv;
347   GeomAbs_SurfaceType typS = myS->GetType();
348   switch(typS) { 
349   case GeomAbs_Plane:          { nbsv=2; nbsu=2; } break;
350   case GeomAbs_BezierSurface:  { nbsv=3+myS->NbVPoles(); nbsu=3+myS->NbUPoles();  } break;
351   case GeomAbs_BSplineSurface: {
352     nbsv = myS->NbVKnots();     nbsv*= myS->VDegree();     if(nbsv < 4) nbsv=4;    
353     nbsu = myS->NbUKnots();     nbsu*= myS->UDegree();     if(nbsu < 4) nbsu=4;
354   }
355     break;
356   case GeomAbs_Cylinder:
357   case GeomAbs_Cone:
358   case GeomAbs_Sphere:
359   case GeomAbs_Torus:                 { 
360     //-- Set 15 for 2pi
361     //-- Not enough ->25 for 2pi
362     nbsu = (Standard_Integer)(8*(usup-uinf));
363     nbsv = (Standard_Integer)(7*(vsup-vinf));
364     if(nbsu<5) nbsu=5;
365     if(nbsv<5) nbsv=5;
366     if(nbsu>30) nbsu=30; //modif HRT buc60462
367     if(nbsv>15) nbsv=15;
368     //-- printf("\n nbsu=%d nbsv=%d\n",nbsu,nbsv);
369   }     break;
370   case GeomAbs_SurfaceOfRevolution:
371   case GeomAbs_SurfaceOfExtrusion:    { nbsv = 15; nbsu=25; }     break;
372   default:                            { nbsu = 10; nbsv=10; }    break;
373   }
374   
375   //-- If the number of points is too great, analyze 
376   //-- 
377   //-- 
378   
379   if(nbsu<10) nbsu=10;
380   if(nbsv<10) nbsv=10;
381   
382   myNbSamplesU = nbsu;
383   myNbSamplesV = nbsv;
384   
385   //-- printf("\n BRepTopAdaptor_TopolTool NbSu=%d NbSv=%d ",nbsu,nbsv);
386   if(nbsu>10 || nbsv>10) { 
387     if(typS == GeomAbs_BSplineSurface) { 
388       const Handle(Geom_BSplineSurface)& Bspl = myS->BSpline();
389       Standard_Integer nbup = Bspl->NbUPoles();
390       Standard_Integer nbvp = Bspl->NbVPoles();
391       TColgp_Array2OfPnt array2(1,nbup,1,nbvp);
392       Bspl->Poles(array2);
393       Analyse(array2,nbup,nbvp,myNbSamplesU,myNbSamplesV);
394       nbsu=myNbSamplesU;
395       nbsv=myNbSamplesV;
396       //-- printf("\n Apres analyse BSPline  NbSu=%d NbSv=%d ",myNbSamplesU,myNbSamplesV);
397     }
398     else if(typS == GeomAbs_BezierSurface) { 
399       const Handle(Geom_BezierSurface)& Bez = myS->Bezier();
400       Standard_Integer nbup = Bez->NbUPoles();
401       Standard_Integer nbvp = Bez->NbVPoles();
402       TColgp_Array2OfPnt array2(1,nbup,1,nbvp);
403       Bez->Poles(array2);
404       Analyse(array2,nbup,nbvp,myNbSamplesU,myNbSamplesV);
405       nbsu=myNbSamplesU;
406       nbsv=myNbSamplesV;
407       //-- printf("\n Apres analyse Bezier  NbSu=%d NbSv=%d ",myNbSamplesU,myNbSamplesV);
408     }
409   }
410  
411   if(nbsu<10) nbsu=10;
412   if(nbsv<10) nbsv=10;
413   
414   myNbSamplesU = nbsu;
415   myNbSamplesV = nbsv; 
416   
417   myU0 = uinf;
418   myV0 = vinf;
419   
420   myDU = (usup-uinf)/(myNbSamplesU+1);
421   myDV = (vsup-vinf)/(myNbSamplesV+1);
422 }
423 //=======================================================================
424 //function : NbSamplesU
425 //purpose  : 
426 //=======================================================================
427   Standard_Integer BRepTopAdaptor_TopolTool::NbSamplesU() 
428
429   if(myNbSamplesU <0) { 
430     ComputeSamplePoints();
431   }
432   return(myNbSamplesU);
433 }
434 //=======================================================================
435 //function : NbSamplesV
436 //purpose  : 
437 //=======================================================================
438   Standard_Integer BRepTopAdaptor_TopolTool::NbSamplesV() 
439
440   if(myNbSamplesU <0) { 
441     ComputeSamplePoints();    
442   }
443   return(myNbSamplesV);
444 }
445 //=======================================================================
446 //function : NbSamples
447 //purpose  : 
448 //=======================================================================
449   Standard_Integer BRepTopAdaptor_TopolTool::NbSamples()
450
451   if(myNbSamplesU <0) { 
452     ComputeSamplePoints();    
453   }
454   return(myNbSamplesU*myNbSamplesV);
455 }
456
457 //=======================================================================
458 //function : SamplePoint
459 //purpose  : 
460 //=======================================================================
461   void BRepTopAdaptor_TopolTool::SamplePoint(const Standard_Integer i,
462                                              gp_Pnt2d& P2d,
463                                              gp_Pnt& P3d)
464
465   Standard_Integer iv = 1 + i/myNbSamplesU;
466   Standard_Integer iu = 1+ i-(iv-1)*myNbSamplesU;
467   Standard_Real u=myU0+iu*myDU;
468   Standard_Real v=myV0+iv*myDV;
469   P2d.SetCoord(u,v);
470   P3d=myS->Value(u,v);
471 }
472 //=======================================================================
473 //function : DomainIsInfinite
474 //purpose  : 
475 //=======================================================================
476   Standard_Boolean BRepTopAdaptor_TopolTool::DomainIsInfinite() 
477 {
478   Standard_Real uinf,usup,vinf,vsup;
479   uinf = myS->FirstUParameter();  usup = myS->LastUParameter();
480   vinf = myS->FirstVParameter();  vsup = myS->LastVParameter();
481   if(Precision::IsNegativeInfinite(uinf)) return(Standard_True);
482   if(Precision::IsPositiveInfinite(usup)) return(Standard_True);
483   if(Precision::IsNegativeInfinite(vinf)) return(Standard_True);
484   if(Precision::IsPositiveInfinite(vsup)) return(Standard_True);
485   return(Standard_False);  
486 }
487
488 //=======================================================================
489 //function : Has3d
490 //purpose  : 
491 //=======================================================================
492
493 Standard_Boolean BRepTopAdaptor_TopolTool::Has3d() const
494 {
495   return Standard_True;
496 }
497
498 //=======================================================================
499 //function : Tol3d
500 //purpose  : 
501 //=======================================================================
502
503 Standard_Real BRepTopAdaptor_TopolTool::Tol3d(const Handle(Adaptor2d_HCurve2d)& C) const
504 {
505   Handle(BRepAdaptor_HCurve2d) brhc = Handle(BRepAdaptor_HCurve2d)::DownCast(C);
506   if (brhc.IsNull())
507     Standard_DomainError::Raise("BRepTopAdaptor_TopolTool: arc has no 3d representation");
508   const BRepAdaptor_Curve2d& brc = (const BRepAdaptor_Curve2d &)brhc->Curve2d();
509   const TopoDS_Edge& edge = brc.Edge();
510   if (edge.IsNull())
511     Standard_DomainError::Raise("BRepTopAdaptor_TopolTool: arc has no 3d representation");
512   return BRep_Tool::Tolerance(edge);
513 }
514
515 //=======================================================================
516 //function : Tol3d
517 //purpose  : 
518 //=======================================================================
519
520 Standard_Real BRepTopAdaptor_TopolTool::Tol3d(const Handle(Adaptor3d_HVertex)& V) const
521 {
522   Handle(BRepTopAdaptor_HVertex) brhv = Handle(BRepTopAdaptor_HVertex)::DownCast(V);
523   if (brhv.IsNull())
524     Standard_DomainError::Raise("BRepTopAdaptor_TopolTool: vertex has no 3d representation");
525   const TopoDS_Vertex& ver = brhv->Vertex();
526   if (ver.IsNull())
527     Standard_DomainError::Raise("BRepTopAdaptor_TopolTool: vertex has no 3d representation");
528   return BRep_Tool::Tolerance(ver);
529 }
530
531 //=======================================================================
532 //function : Pnt
533 //purpose  : 
534 //=======================================================================
535
536 gp_Pnt BRepTopAdaptor_TopolTool::Pnt(const Handle(Adaptor3d_HVertex)& V) const
537 {
538   Handle(BRepTopAdaptor_HVertex) brhv = Handle(BRepTopAdaptor_HVertex)::DownCast(V);
539   if (brhv.IsNull())
540     Standard_DomainError::Raise("BRepTopAdaptor_TopolTool: vertex has no 3d representation");
541   const TopoDS_Vertex& ver = brhv->Vertex();
542   if (ver.IsNull())
543     Standard_DomainError::Raise("BRepTopAdaptor_TopolTool: vertex has no 3d representation");
544   return BRep_Tool::Pnt(ver);
545 }