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