0026073: Changes were lost
[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(myFace.IsNull())
191     return TopAbs_UNKNOWN;
192   if(myFClass2d == NULL) { 
193     myFClass2d = (void *) new BRepTopAdaptor_FClass2d(myFace,Tol);
194   } 
195   return(((BRepTopAdaptor_FClass2d *)myFClass2d)->Perform(P,RecadreOnPeriodic));
196 }
197
198 //=======================================================================
199 //function : IsThePointOn
200 //purpose  : 
201 //=======================================================================
202   Standard_Boolean BRepTopAdaptor_TopolTool::IsThePointOn(const gp_Pnt2d& P,
203                                                           const Standard_Real Tol,
204                                                           const Standard_Boolean RecadreOnPeriodic)
205 {
206   if(myFClass2d == NULL) { 
207     myFClass2d = (void *) new BRepTopAdaptor_FClass2d(myFace,Tol);
208   } 
209   return(TopAbs_ON==((BRepTopAdaptor_FClass2d *)myFClass2d)->TestOnRestriction(P,Tol,RecadreOnPeriodic));
210 }
211
212 //=======================================================================
213 //function : Destroy
214 //purpose  : 
215 //=======================================================================
216   void BRepTopAdaptor_TopolTool::Destroy() 
217
218   if(myFClass2d != NULL) { 
219     delete (BRepTopAdaptor_FClass2d *)myFClass2d;
220     myFClass2d=NULL;
221   }
222 }
223 //=======================================================================
224 //function : Orientation
225 //purpose  : 
226 //=======================================================================
227   TopAbs_Orientation BRepTopAdaptor_TopolTool::Orientation  (const Handle(Adaptor2d_HCurve2d)& C)
228 {
229   Handle(BRepAdaptor_HCurve2d) brhc =
230     Handle(BRepAdaptor_HCurve2d)::DownCast(C);
231   return ((BRepAdaptor_Curve2d *)&(brhc->Curve2d()))->Edge().Orientation(); 
232 }
233 //=======================================================================
234 //function : Orientation
235 //purpose  : 
236 //=======================================================================
237   TopAbs_Orientation BRepTopAdaptor_TopolTool::Orientation  (const Handle(Adaptor3d_HVertex)& C)
238 {
239  return Adaptor3d_TopolTool::Orientation(C); 
240 }
241 //-- ============================================================
242 //-- methods  used for samples
243 //-- ============================================================ 
244
245 //=======================================================================
246 //function : Analyse
247 //purpose  : 
248 //=======================================================================
249 void Analyse(const TColgp_Array2OfPnt& array2,
250              const Standard_Integer nbup,
251              const Standard_Integer nbvp,
252              Standard_Integer& myNbSamplesU,
253              Standard_Integer& myNbSamplesV) 
254
255   gp_Vec Vi,Vip1;
256   Standard_Integer sh,nbch,i,j;
257   
258   sh = 1;
259   nbch = 0;
260   if(nbvp>2) { 
261     for(i=2;i<nbup;i++) { 
262       const gp_Pnt& A=array2.Value(i,1);
263       const gp_Pnt& B=array2.Value(i,2);
264       const gp_Pnt& C=array2.Value(i,3);
265       Vi.SetCoord(C.X()-B.X()-B.X()+A.X(),
266                   C.Y()-B.Y()-B.Y()+A.Y(),
267                   C.Z()-B.Z()-B.Z()+A.Z());
268       Standard_Integer locnbch=0;
269       for(j=3; j<nbvp;j++) {  //-- test
270         const gp_Pnt& Ax=array2.Value(i,j-1);
271         const gp_Pnt& Bx=array2.Value(i,j);
272         const gp_Pnt& Cx=array2.Value(i,j+1);
273         Vip1.SetCoord(Cx.X()-Bx.X()-Bx.X()+Ax.X(),
274                       Cx.Y()-Bx.Y()-Bx.Y()+Ax.Y(),
275                       Cx.Z()-Bx.Z()-Bx.Z()+Ax.Z());
276         Standard_Real pd = Vi.Dot(Vip1);
277         Vi=Vip1;
278         if(pd>1.0e-7 || pd<-1.0e-7) {  
279           if(pd>0) {  if(sh==-1) {   sh=1; locnbch++;   }  }
280           else {        if(sh==1) {  sh=-1; locnbch++;  }  }
281         }
282       }
283       if(locnbch>nbch) { 
284         nbch=locnbch; 
285       }
286     }
287   }
288   myNbSamplesV = nbch+5;
289   
290
291   nbch=0;
292   if(nbup>2) { 
293     for(j=2;j<nbvp;j++) { 
294       const gp_Pnt& A=array2.Value(1,j);
295       const gp_Pnt& B=array2.Value(2,j);
296       const gp_Pnt& C=array2.Value(3,j);
297       Vi.SetCoord(C.X()-B.X()-B.X()+A.X(),
298                   C.Y()-B.Y()-B.Y()+A.Y(),
299                   C.Z()-B.Z()-B.Z()+A.Z());
300       Standard_Integer locnbch=0;
301       for(i=3; i<nbup;i++) {  //-- test
302         const gp_Pnt& Ax=array2.Value(i-1,j);
303         const gp_Pnt& Bx=array2.Value(i,j);
304         const gp_Pnt& Cx=array2.Value(i+1,j);
305         Vip1.SetCoord(Cx.X()-Bx.X()-Bx.X()+Ax.X(),
306                     Cx.Y()-Bx.Y()-Bx.Y()+Ax.Y(),
307                     Cx.Z()-Bx.Z()-Bx.Z()+Ax.Z());
308         Standard_Real pd = Vi.Dot(Vip1);
309         Vi=Vip1;
310         if(pd>1.0e-7 || pd<-1.0e-7) {  
311           if(pd>0) {  if(sh==-1) {   sh=1; locnbch++;   }  }
312           else {        if(sh==1) {  sh=-1; locnbch++;  }  }
313         }
314       }
315       if(locnbch>nbch) nbch=locnbch;
316     }  
317   }
318   myNbSamplesU = nbch+5;
319 }  
320
321
322
323
324 //=======================================================================
325 //function : ComputeSamplePoints
326 //purpose  : 
327 //=======================================================================
328   void BRepTopAdaptor_TopolTool::ComputeSamplePoints() 
329
330   Standard_Real uinf,usup,vinf,vsup;
331   uinf = myS->FirstUParameter();  usup = myS->LastUParameter();
332   vinf = myS->FirstVParameter();  vsup = myS->LastVParameter();
333   if (usup < uinf) { Standard_Real temp=uinf; uinf=usup; usup=temp; }
334   if (vsup < vinf) { Standard_Real temp=vinf; vinf=vsup; vsup=temp; }
335   if (uinf == RealFirst() && usup == RealLast()) { uinf=-1.e5; usup=1.e5; }
336   else if (uinf == RealFirst()) { uinf=usup-2.e5; }
337   else if (usup == RealLast()) {  usup=uinf+2.e5; }
338   
339   if (vinf == RealFirst() && vsup == RealLast()) { vinf=-1.e5; vsup=1.e5; }
340   else if (vinf == RealFirst()) { vinf=vsup-2.e5;  }
341   else if (vsup == RealLast()) {  vsup=vinf+2.e5;  }
342   
343   Standard_Integer nbsu,nbsv;
344   GeomAbs_SurfaceType typS = myS->GetType();
345   switch(typS) { 
346   case GeomAbs_Plane:          { nbsv=2; nbsu=2; } break;
347   case GeomAbs_BezierSurface:  { nbsv=3+myS->NbVPoles(); nbsu=3+myS->NbUPoles();  } break;
348   case GeomAbs_BSplineSurface: {
349     nbsv = myS->NbVKnots();     nbsv*= myS->VDegree();     if(nbsv < 4) nbsv=4;    
350     nbsu = myS->NbUKnots();     nbsu*= myS->UDegree();     if(nbsu < 4) nbsu=4;
351   }
352     break;
353   case GeomAbs_Cylinder:
354   case GeomAbs_Cone:
355   case GeomAbs_Sphere:
356   case GeomAbs_Torus:                 { 
357     //-- Set 15 for 2pi
358     //-- Not enough ->25 for 2pi
359     nbsu = (Standard_Integer)(8*(usup-uinf));
360     nbsv = (Standard_Integer)(7*(vsup-vinf));
361     if(nbsu<5) nbsu=5;
362     if(nbsv<5) nbsv=5;
363     if(nbsu>30) nbsu=30; //modif HRT buc60462
364     if(nbsv>15) nbsv=15;
365     //-- printf("\n nbsu=%d nbsv=%d\n",nbsu,nbsv);
366   }     break;
367   case GeomAbs_SurfaceOfRevolution:
368   case GeomAbs_SurfaceOfExtrusion:    { nbsv = 15; nbsu=25; }     break;
369   default:                            { nbsu = 10; nbsv=10; }    break;
370   }
371   
372   //-- If the number of points is too great, analyze 
373   //-- 
374   //-- 
375   
376   if(nbsu<10) nbsu=10;
377   if(nbsv<10) nbsv=10;
378   
379   myNbSamplesU = nbsu;
380   myNbSamplesV = nbsv;
381   
382   //-- printf("\n BRepTopAdaptor_TopolTool NbSu=%d NbSv=%d ",nbsu,nbsv);
383   if(nbsu>10 || nbsv>10) { 
384     if(typS == GeomAbs_BSplineSurface) { 
385       const Handle(Geom_BSplineSurface)& Bspl = myS->BSpline();
386       Standard_Integer nbup = Bspl->NbUPoles();
387       Standard_Integer nbvp = Bspl->NbVPoles();
388       TColgp_Array2OfPnt array2(1,nbup,1,nbvp);
389       Bspl->Poles(array2);
390       Analyse(array2,nbup,nbvp,myNbSamplesU,myNbSamplesV);
391       nbsu=myNbSamplesU;
392       nbsv=myNbSamplesV;
393       //-- printf("\n Apres analyse BSPline  NbSu=%d NbSv=%d ",myNbSamplesU,myNbSamplesV);
394     }
395     else if(typS == GeomAbs_BezierSurface) { 
396       const Handle(Geom_BezierSurface)& Bez = myS->Bezier();
397       Standard_Integer nbup = Bez->NbUPoles();
398       Standard_Integer nbvp = Bez->NbVPoles();
399       TColgp_Array2OfPnt array2(1,nbup,1,nbvp);
400       Bez->Poles(array2);
401       Analyse(array2,nbup,nbvp,myNbSamplesU,myNbSamplesV);
402       nbsu=myNbSamplesU;
403       nbsv=myNbSamplesV;
404       //-- printf("\n Apres analyse Bezier  NbSu=%d NbSv=%d ",myNbSamplesU,myNbSamplesV);
405     }
406   }
407  
408   if(nbsu<10) nbsu=10;
409   if(nbsv<10) nbsv=10;
410   
411   myNbSamplesU = nbsu;
412   myNbSamplesV = nbsv; 
413   
414   myU0 = uinf;
415   myV0 = vinf;
416   
417   myDU = (usup-uinf)/(myNbSamplesU+1);
418   myDV = (vsup-vinf)/(myNbSamplesV+1);
419 }
420 //=======================================================================
421 //function : NbSamplesU
422 //purpose  : 
423 //=======================================================================
424   Standard_Integer BRepTopAdaptor_TopolTool::NbSamplesU() 
425
426   if(myNbSamplesU <0) { 
427     ComputeSamplePoints();
428   }
429   return(myNbSamplesU);
430 }
431 //=======================================================================
432 //function : NbSamplesV
433 //purpose  : 
434 //=======================================================================
435   Standard_Integer BRepTopAdaptor_TopolTool::NbSamplesV() 
436
437   if(myNbSamplesU <0) { 
438     ComputeSamplePoints();    
439   }
440   return(myNbSamplesV);
441 }
442 //=======================================================================
443 //function : NbSamples
444 //purpose  : 
445 //=======================================================================
446   Standard_Integer BRepTopAdaptor_TopolTool::NbSamples()
447
448   if(myNbSamplesU <0) { 
449     ComputeSamplePoints();    
450   }
451   return(myNbSamplesU*myNbSamplesV);
452 }
453
454 //=======================================================================
455 //function : SamplePoint
456 //purpose  : 
457 //=======================================================================
458   void BRepTopAdaptor_TopolTool::SamplePoint(const Standard_Integer i,
459                                              gp_Pnt2d& P2d,
460                                              gp_Pnt& P3d)
461
462   Standard_Integer iv = 1 + i/myNbSamplesU;
463   Standard_Integer iu = 1+ i-(iv-1)*myNbSamplesU;
464   Standard_Real u=myU0+iu*myDU;
465   Standard_Real v=myV0+iv*myDV;
466   P2d.SetCoord(u,v);
467   P3d=myS->Value(u,v);
468 }
469 //=======================================================================
470 //function : DomainIsInfinite
471 //purpose  : 
472 //=======================================================================
473   Standard_Boolean BRepTopAdaptor_TopolTool::DomainIsInfinite() 
474 {
475   Standard_Real uinf,usup,vinf,vsup;
476   uinf = myS->FirstUParameter();  usup = myS->LastUParameter();
477   vinf = myS->FirstVParameter();  vsup = myS->LastVParameter();
478   if(Precision::IsNegativeInfinite(uinf)) return(Standard_True);
479   if(Precision::IsPositiveInfinite(usup)) return(Standard_True);
480   if(Precision::IsNegativeInfinite(vinf)) return(Standard_True);
481   if(Precision::IsPositiveInfinite(vsup)) return(Standard_True);
482   return(Standard_False);  
483 }
484
485 //=======================================================================
486 //function : Has3d
487 //purpose  : 
488 //=======================================================================
489
490 Standard_Boolean BRepTopAdaptor_TopolTool::Has3d() const
491 {
492   return Standard_True;
493 }
494
495 //=======================================================================
496 //function : Tol3d
497 //purpose  : 
498 //=======================================================================
499
500 Standard_Real BRepTopAdaptor_TopolTool::Tol3d(const Handle(Adaptor2d_HCurve2d)& C) const
501 {
502   Handle(BRepAdaptor_HCurve2d) brhc = Handle(BRepAdaptor_HCurve2d)::DownCast(C);
503   if (brhc.IsNull())
504     Standard_DomainError::Raise("BRepTopAdaptor_TopolTool: arc has no 3d representation");
505   const BRepAdaptor_Curve2d& brc = (const BRepAdaptor_Curve2d &)brhc->Curve2d();
506   const TopoDS_Edge& edge = brc.Edge();
507   if (edge.IsNull())
508     Standard_DomainError::Raise("BRepTopAdaptor_TopolTool: arc has no 3d representation");
509   return BRep_Tool::Tolerance(edge);
510 }
511
512 //=======================================================================
513 //function : Tol3d
514 //purpose  : 
515 //=======================================================================
516
517 Standard_Real BRepTopAdaptor_TopolTool::Tol3d(const Handle(Adaptor3d_HVertex)& V) const
518 {
519   Handle(BRepTopAdaptor_HVertex) brhv = Handle(BRepTopAdaptor_HVertex)::DownCast(V);
520   if (brhv.IsNull())
521     Standard_DomainError::Raise("BRepTopAdaptor_TopolTool: vertex has no 3d representation");
522   const TopoDS_Vertex& ver = brhv->Vertex();
523   if (ver.IsNull())
524     Standard_DomainError::Raise("BRepTopAdaptor_TopolTool: vertex has no 3d representation");
525   return BRep_Tool::Tolerance(ver);
526 }
527
528 //=======================================================================
529 //function : Pnt
530 //purpose  : 
531 //=======================================================================
532
533 gp_Pnt BRepTopAdaptor_TopolTool::Pnt(const Handle(Adaptor3d_HVertex)& V) const
534 {
535   Handle(BRepTopAdaptor_HVertex) brhv = Handle(BRepTopAdaptor_HVertex)::DownCast(V);
536   if (brhv.IsNull())
537     Standard_DomainError::Raise("BRepTopAdaptor_TopolTool: vertex has no 3d representation");
538   const TopoDS_Vertex& ver = brhv->Vertex();
539   if (ver.IsNull())
540     Standard_DomainError::Raise("BRepTopAdaptor_TopolTool: vertex has no 3d representation");
541   return BRep_Tool::Pnt(ver);
542 }