0022653: Bad performance of Open CASCADE libraries that are used by Partition Algorit...
[occt.git] / src / IntTools / IntTools_Tools.cxx
1 // File:        IntTools_Tools.cxx
2 // Created:     Thu Nov 16 11:42:23 2000
3 // Author:      Peter KURNEV
4 //              <pkv@irinox>
5 //
6
7 #include <IntTools_Tools.ixx>
8
9 #include <Precision.hxx>
10
11 #include <TopExp_Explorer.hxx>
12 #include <TopTools_IndexedDataMapOfShapeShape.hxx>
13
14 #include <TopoDS.hxx>
15 #include <TopoDS_Shape.hxx>
16 #include <TopoDS_Vertex.hxx>
17 #include <TopoDS_Edge.hxx>
18 #include <TopoDS_Face.hxx>
19 #include <TopoDS_Wire.hxx>
20 #include <TopLoc_Location.hxx>
21
22 #include <BRep_Builder.hxx>
23 #include <BRep_Tool.hxx>
24 #include <BRepAdaptor_Surface.hxx>
25 #include <BRepAdaptor_Curve.hxx>
26 #include <BRepAdaptor_Surface.hxx>
27
28 #include <gp_Pnt.hxx>
29 #include <gp_Pnt2d.hxx>
30 #include <gp.hxx>
31 #include <gp_Lin.hxx>
32 #include <gp_Dir.hxx>
33 #include <gp_Ax1.hxx>
34
35 #include <Geom_Curve.hxx>
36 #include <GeomAdaptor_Surface.hxx>
37 #include <Geom_Surface.hxx>
38 #include <GeomAPI_ProjectPointOnSurf.hxx>
39 #include <GeomAPI_ProjectPointOnCurve.hxx>
40 #include <GeomAdaptor_Curve.hxx>
41 #include <GeomAbs_CurveType.hxx>
42 #include <Geom_Line.hxx>
43 #include <Geom2d_Curve.hxx>
44 #include <Geom_BoundedCurve.hxx>
45 #include <Geom_Geometry.hxx>
46 #include <Geom_TrimmedCurve.hxx>
47 #include <Geom2d_TrimmedCurve.hxx>
48
49 #include <IntTools_FClass2d.hxx>
50 #include <IntTools_Curve.hxx>
51 #include <IntTools_SequenceOfCurves.hxx>
52
53 static
54   void ParabolaTolerance(const Handle(Geom_Curve)& ,
55                          const Standard_Real ,
56                          const Standard_Real ,
57                          const Standard_Real ,
58                          Standard_Real& ,
59                          Standard_Real& );
60
61 //=======================================================================
62 //function : HasInternalEdge
63 //purpose  : 
64 //=======================================================================
65   Standard_Boolean IntTools_Tools::HasInternalEdge(const TopoDS_Wire& aW)
66 {
67   Standard_Boolean bFlag=Standard_True;
68
69   TopExp_Explorer anExp(aW, TopAbs_EDGE);
70   for (; anExp.More(); anExp.Next()) {
71     const TopoDS_Edge& aE=TopoDS::Edge(anExp.Current());
72     TopAbs_Orientation anOr=aE.Orientation();
73     if (anOr==TopAbs_INTERNAL) {
74       return bFlag;
75     }
76   }
77   return !bFlag;
78 }
79
80 //=======================================================================
81 //function : IsClosed
82 //purpose  : 
83 //=======================================================================
84   Standard_Boolean IntTools_Tools::IsClosed (const Handle(Geom_Curve)& aC3D)
85 {
86   Standard_Boolean bRet;
87   Standard_Real aF, aL, aDist, aPC;
88   gp_Pnt aP1, aP2;
89   
90   Handle (Geom_BoundedCurve) aGBC=
91       Handle (Geom_BoundedCurve)::DownCast(aC3D);
92   if (aGBC.IsNull()) {
93     return Standard_False;
94   }
95   
96   aF=aC3D->FirstParameter();
97   aL=aC3D-> LastParameter();
98   
99   aC3D->D0(aF, aP1);
100   aC3D->D0(aL, aP2);
101
102   
103   //
104   //modified by NIZNHY-PKV Mon Jul 04 11:58:23 2011f
105   aPC=Precision::Confusion();
106   aPC=aPC*aPC;
107   aDist=aP1.SquareDistance(aP2);
108   bRet=aDist<aPC;
109   return bRet;
110   //
111   //aDist=aP1.Distance(aP2);
112   //return (aDist < Precision::Confusion()); 
113   //modified by NIZNHY-PKV Mon Jul 04 11:59:50 2011t
114 }
115
116 //=======================================================================
117 //function : RejectLines
118 //purpose  : 
119 //=======================================================================
120    void IntTools_Tools::RejectLines(const IntTools_SequenceOfCurves& aSIn,
121                                     IntTools_SequenceOfCurves& aSOut)
122 {
123   Standard_Integer i, j, aNb;
124   Standard_Boolean bFlag;
125   Handle (Geom_Curve) aC3D;
126
127   gp_Dir aD1, aD2;
128
129   aSOut.Clear();
130
131   aNb=aSIn.Length();
132   for (i=1; i<=aNb; i++) {
133     const IntTools_Curve& IC=aSIn(i);
134     aC3D=IC.Curve();
135     //
136     Handle (Geom_TrimmedCurve) aGTC=
137       Handle (Geom_TrimmedCurve)::DownCast(aC3D);
138     
139     if (!aGTC.IsNull()) {
140       aC3D=aGTC->BasisCurve();
141       IntTools_Curve* pIC=(IntTools_Curve*) &IC;
142       pIC->SetCurve(aC3D);
143     }
144     //
145     Handle (Geom_Line) aGLine=
146       Handle (Geom_Line)::DownCast(aC3D);
147     
148     if (aGLine.IsNull()) {
149       aSOut.Clear();
150       for (j=1; j<=aNb; j++) {
151         aSOut.Append(aSIn(j));
152       }
153       return;
154     }
155     //
156     gp_Lin aLin=aGLine->Lin();
157     aD2=aLin.Direction();
158     if (i==1) {
159       aSOut.Append(IC);
160       aD1=aD2;
161       continue;
162     }
163     
164     bFlag=IntTools_Tools::IsDirsCoinside(aD1, aD2);
165     if (!bFlag) {
166       aSOut.Append(IC);
167       return;
168     }
169   }
170 }
171
172 //=======================================================================
173 //function : IsDirsCoinside
174 //purpose  : 
175 //=======================================================================
176   Standard_Boolean IntTools_Tools::IsDirsCoinside  (const gp_Dir& D1, const gp_Dir& D2)
177 {
178   Standard_Boolean bFlag;
179   gp_Pnt P1(D1.X(), D1.Y(), D1.Z());  
180   gp_Pnt P2(D2.X(), D2.Y(), D2.Z());
181   Standard_Real dLim=0.0002, d;
182   d=P1.Distance (P2); 
183   bFlag= (d<dLim || fabs (2.-d)<dLim); 
184   return bFlag;
185 }
186   
187 //=======================================================================
188 //function : IsDirsCoinside
189 //purpose  : 
190 //=======================================================================
191   Standard_Boolean IntTools_Tools::IsDirsCoinside  (const gp_Dir& D1, 
192                                                     const gp_Dir& D2,
193                                                     const Standard_Real dLim)
194 {
195   Standard_Boolean bFlag;
196   Standard_Real d;
197   //
198   gp_Pnt P1(D1.X(), D1.Y(), D1.Z());  
199   gp_Pnt P2(D2.X(), D2.Y(), D2.Z());
200   d=P1.Distance (P2); 
201   bFlag= (d<dLim || fabs (2.-d)<dLim); 
202   return bFlag;
203 }
204 //=======================================================================
205 //function : SplitCurve
206 //purpose  : 
207 //=======================================================================
208   Standard_Integer IntTools_Tools::SplitCurve(const IntTools_Curve& IC,
209                                               IntTools_SequenceOfCurves& aCvs)
210 {
211   Handle (Geom_Curve) aC3D =IC.Curve();
212   if(aC3D.IsNull())
213     return 0;
214   //
215   Handle (Geom2d_Curve) aC2D1=IC.FirstCurve2d();
216   Handle (Geom2d_Curve) aC2D2=IC.SecondCurve2d();
217   Standard_Boolean bIsClosed;
218
219   bIsClosed=IntTools_Tools::IsClosed(aC3D);
220   if (!bIsClosed) {
221     return 0;
222   }
223
224   Standard_Real aF, aL, aMid;
225   
226   //
227   aF=aC3D->FirstParameter();
228   aL=aC3D->LastParameter();
229   aMid=0.5*(aF+aL);
230   GeomAdaptor_Curve aGAC(aC3D);
231   GeomAbs_CurveType aCT=aGAC.GetType();
232   if (aCT==GeomAbs_BSplineCurve ||
233       aCT==GeomAbs_BezierCurve) {
234     //aMid=0.5*aMid;
235     aMid=IntTools_Tools::IntermediatePoint(aF, aL);
236   }
237   //
238   Handle(Geom_Curve) aC3DNewF, aC3DNewL;
239   aC3DNewF =new Geom_TrimmedCurve  (aC3D, aF, aMid);
240   aC3DNewL =new Geom_TrimmedCurve  (aC3D, aMid, aL);
241
242   //
243   Handle (Geom2d_Curve) aC2D1F, aC2D1L, aC2D2F, aC2D2L;
244   //
245   if(!aC2D1.IsNull()) {
246     aC2D1F=new Geom2d_TrimmedCurve (aC2D1, aF, aMid);
247     aC2D1L=new Geom2d_TrimmedCurve (aC2D1, aMid, aL);
248   }
249
250   if(!aC2D2.IsNull()) {
251     aC2D2F=new Geom2d_TrimmedCurve (aC2D2, aF, aMid);
252     aC2D2L=new Geom2d_TrimmedCurve (aC2D2, aMid, aL);
253   }
254   // 
255   
256   IntTools_Curve aIC1(aC3DNewF, aC2D1F, aC2D2F);
257   IntTools_Curve aIC2(aC3DNewL, aC2D1L, aC2D2L);
258   //
259   aCvs.Append(aIC1);
260   //
261   aCvs.Append(aIC2);
262   //
263   return 2;
264 }
265
266 //=======================================================================
267 //function : IntermediatePoint
268 //purpose  : 
269 //=======================================================================
270   Standard_Real IntTools_Tools::IntermediatePoint (const Standard_Real aFirst,
271                                                    const Standard_Real aLast)
272 {
273   //define parameter division number as 10*e^(-PI) = 0.43213918
274   const Standard_Real PAR_T = 0.43213918;
275   Standard_Real aParm;
276   aParm=(1.-PAR_T)*aFirst + PAR_T*aLast;
277   return aParm;
278 }
279
280 //=======================================================================
281 //function : IsVertex
282 //purpose  : 
283 //=======================================================================
284   Standard_Boolean IntTools_Tools::IsVertex (const gp_Pnt& aP,
285                                              const Standard_Real aTolPV,
286                                              const TopoDS_Vertex& aV)
287 {
288   Standard_Boolean bRet;
289   Standard_Real aTolV, aD, dTol;
290   gp_Pnt aPv; 
291   
292   aTolV=BRep_Tool::Tolerance(aV);
293   //
294   dTol=Precision::Confusion();
295   aTolV=aTolV+aTolPV+dTol;
296   //
297   aPv=BRep_Tool::Pnt(aV);
298   //
299   //modified by NIZNHY-PKV Mon Jul 04 12:00:37 2011f
300   aD=aPv.SquareDistance(aP);
301   aTolV=aTolV*aTolV;
302   bRet=(aD<=aTolV);
303   return bRet;
304   //
305   //aD=aPv.Distance(aP);
306   //return (aD<=aTolV);
307   //modified by NIZNHY-PKV Mon Jul 04 12:00:40 2011t
308 }
309
310
311 //=======================================================================
312 //function : IsVertex
313 //purpose  : 
314 //=======================================================================
315   Standard_Boolean IntTools_Tools::IsVertex (const IntTools_CommonPrt& aCmnPrt)
316 {
317   Standard_Boolean anIsVertex;
318   Standard_Real aParam;
319
320   const TopoDS_Edge&    aE1=aCmnPrt.Edge1();
321   const IntTools_Range& aR1=aCmnPrt.Range1();
322   aParam=0.5*(aR1.First()+aR1.Last());
323   anIsVertex=IntTools_Tools::IsVertex (aE1, aParam);
324   
325   if (anIsVertex) {
326     return Standard_True;
327   }
328
329   const TopoDS_Edge&    aE2=aCmnPrt.Edge2();
330   const IntTools_SequenceOfRanges& aRs2=aCmnPrt.Ranges2();
331   const IntTools_Range& aR2=aRs2(1);
332   aParam=0.5*(aR2.First()+aR2.Last());
333   anIsVertex=IntTools_Tools::IsVertex (aE2, aParam);
334   if (anIsVertex) {
335     return Standard_True;
336   }
337   return Standard_False;
338 }
339
340 //=======================================================================
341 //function : IsVertex
342 //purpose  : 
343 //=======================================================================
344   Standard_Boolean IntTools_Tools::IsVertex (const TopoDS_Edge& aE,
345                                              const TopoDS_Vertex& aV,
346                                              const Standard_Real t)
347 {
348   Standard_Real aTolV, aTolV2, d2;
349   gp_Pnt aPv, aPt; 
350   
351   BRepAdaptor_Curve aBAC(aE);
352   aBAC.D0(t, aPt);
353
354   aTolV=BRep_Tool::Tolerance(aV);
355   aTolV2=aTolV*aTolV;
356   aPv=BRep_Tool::Pnt(aV);
357   d2=aPv.SquareDistance (aPt);
358   if (d2 < aTolV2) {
359     return Standard_True;
360   }
361   return Standard_False;
362 }
363 //=======================================================================
364 //function : IsVertex
365 //purpose  : 
366 //=======================================================================
367   Standard_Boolean IntTools_Tools::IsVertex (const TopoDS_Edge& aE,
368                                              const Standard_Real t)
369 {
370   Standard_Real aTolV, aTolV2, d2;
371   TopoDS_Vertex aV;
372   gp_Pnt aPv, aPt; 
373   
374   BRepAdaptor_Curve aBAC(aE);
375   aBAC.D0(t, aPt);
376
377   TopExp_Explorer anExp(aE, TopAbs_VERTEX);
378   for (; anExp.More(); anExp.Next()) {
379     aV=TopoDS::Vertex (anExp.Current());
380     aTolV=BRep_Tool::Tolerance(aV);
381     aTolV2=aTolV*aTolV;
382     aTolV2=1.e-12;
383      aPv=BRep_Tool::Pnt(aV);
384      d2=aPv.SquareDistance (aPt);
385      if (d2 < aTolV2) {
386        return Standard_True;
387      }
388   }
389   return Standard_False;
390 }
391
392
393 //=======================================================================
394 //function : ComputeVV
395 //purpose  : 
396 //=======================================================================
397   Standard_Integer IntTools_Tools::ComputeVV(const TopoDS_Vertex& aV1, 
398                                              const TopoDS_Vertex& aV2)
399 {
400   Standard_Real aTolV1, aTolV2, aTolSum, d;
401   gp_Pnt aP1, aP2;
402
403   aTolV1=BRep_Tool::Tolerance(aV1);
404   aTolV2=BRep_Tool::Tolerance(aV2);
405   aTolSum=aTolV1+aTolV2;
406   
407   aP1=BRep_Tool::Pnt(aV1);
408   aP2=BRep_Tool::Pnt(aV2);
409   //modified by NIZNHY-PKV Mon Jul 04 11:55:52 2011f
410   aTolSum=aTolSum*aTolSum;
411   d=aP1.SquareDistance(aP2);
412   //d=aP1.Distance(aP2);
413   //modified by NIZNHY-PKV Mon Jul 04 11:55:53 2011t
414   if (d<aTolSum) {
415     return 0;
416   }
417   return -1;
418 }
419
420 //=======================================================================
421 //function : MakeFaceFromWireAndFace
422 //purpose  : 
423 //=======================================================================
424   void IntTools_Tools::MakeFaceFromWireAndFace(const TopoDS_Wire& aW,
425                                                const TopoDS_Face& aF,
426                                                TopoDS_Face& aFNew)
427 {
428   TopoDS_Face aFF;
429   aFF=aF;
430   aFF.Orientation(TopAbs_FORWARD);
431   aFNew=TopoDS::Face (aFF.EmptyCopied());
432   BRep_Builder BB;
433   BB.Add(aFNew, aW);
434 }
435
436 //=======================================================================
437 //function : ClassifyPointByFace
438 //purpose  : 
439 //=======================================================================
440   TopAbs_State IntTools_Tools::ClassifyPointByFace(const TopoDS_Face& aF,
441                                                    const gp_Pnt2d& aP2d)
442 {
443   Standard_Real aFaceTolerance;
444   TopAbs_State aState;
445   
446   aFaceTolerance=BRep_Tool::Tolerance(aF);
447   IntTools_FClass2d aClass2d(aF, aFaceTolerance);
448   aState=aClass2d.Perform(aP2d);
449   
450   return aState;
451 }
452
453 //=======================================================================
454 //function : IsMiddlePointsEqual
455 //purpose  : 
456 //=======================================================================
457   Standard_Boolean IntTools_Tools::IsMiddlePointsEqual(const TopoDS_Edge& aE1,
458                                                        const TopoDS_Edge& aE2)
459                                                        
460 {
461   Standard_Boolean bRet;
462   Standard_Real f1, l1, m1, f2, l2, m2, aTol1, aTol2, aSumTol, aD2;
463   gp_Pnt aP1, aP2;
464
465   aTol1=BRep_Tool::Tolerance(aE1);
466   Handle(Geom_Curve) C1=BRep_Tool::Curve(aE1, f1, l1);
467   m1=0.5*(f1+l1);
468   C1->D0(m1, aP1);
469
470   aTol2=BRep_Tool::Tolerance(aE2);
471   Handle(Geom_Curve) C2=BRep_Tool::Curve(aE2, f2, l2);
472   m2=0.5*(f2+l2);
473   C2->D0(m2, aP2);
474
475   aSumTol=aTol1+aTol2;
476   //modified by NIZNHY-PKV Mon Jul 04 12:02:20 2011f
477   aSumTol=aSumTol*aSumTol;
478   aD2=aP1.SquareDistance(aP2);
479   bRet=aD2<aSumTol;
480   return bRet;
481   //
482   //if (aP1.Distance(aP2) < aSumTol) {
483   //  return Standard_True;
484   //}
485   //return Standard_False;
486   //modified by NIZNHY-PKV Mon Jul 04 12:02:24 2011t
487 }
488
489 //=======================================================================
490 //function : CurveTolerance
491 //purpose  : 
492 //=======================================================================
493   Standard_Real IntTools_Tools::CurveTolerance(const Handle(Geom_Curve)& aC3D,
494                                                const Standard_Real aTolBase)
495 {
496   Standard_Real aTolReached, aTf, aTl, aTolMin, aTolMax;
497
498   aTolReached=aTolBase;
499   //
500   if (aC3D.IsNull()) {
501     return aTolReached;
502   }
503   //
504   Handle(Geom_TrimmedCurve) aCT3D=Handle(Geom_TrimmedCurve)::DownCast(aC3D);
505   if (aCT3D.IsNull()) {
506     return aTolReached;
507   }
508   //
509   aTolMin=aTolBase;
510   aTolMax=aTolBase;
511   //
512   aTf=aCT3D->FirstParameter();
513   aTl=aCT3D->LastParameter();
514   //
515   GeomAdaptor_Curve aGAC(aCT3D);
516   GeomAbs_CurveType aCType=aGAC.GetType();
517   //
518   if (aCType==GeomAbs_Parabola) {
519     Handle(Geom_Curve) aC3DBase=aCT3D->BasisCurve();
520     ParabolaTolerance(aC3DBase, aTf, aTl, aTolBase, aTolMin, aTolMax);
521     aTolReached=aTolMax;
522   }
523   //
524   return aTolReached;
525 }
526
527 #include <Geom_Parabola.hxx>
528 #include <gp_Parab.hxx>
529 //=======================================================================
530 //function : ParabolaTolerance
531 //purpose  : 
532 //=======================================================================
533 void ParabolaTolerance(const Handle(Geom_Curve)& aC3D,
534                        const Standard_Real aTf,
535                        const Standard_Real aTl,
536                        const Standard_Real aTol,
537                        Standard_Real& aTolMin,
538                        Standard_Real& aTolMax)
539 {
540   
541   aTolMin=aTol;
542   aTolMax=aTol;
543
544   Handle(Geom_Parabola) aGP=Handle(Geom_Parabola)::DownCast(aC3D);
545   if (aGP.IsNull()){
546     return;
547   }
548
549   Standard_Integer aNbPoints;
550   Standard_Real aFocal, aX1, aX2, aTol1, aTol2;
551   gp_Pnt aPf, aPl;
552   gp_Parab aParab=aGP->Parab();
553   gp_Ax1 aXAxis=aParab.XAxis();
554   Handle(Geom_Line) aGAxis=new Geom_Line(aXAxis);
555
556   aFocal=aGP->Focal();
557   if (aFocal==0.) {
558     return;
559   }
560   //
561   // aTol1
562   aTol1=aTol;
563   aX1=0.;
564   aGP->D0(aTf, aPf);
565   GeomAPI_ProjectPointOnCurve aProj1(aPf, aGAxis);
566   aNbPoints=aProj1.NbPoints();
567   if (aNbPoints) {
568     aX1=aProj1.LowerDistanceParameter();
569   }
570   if (aX1>=0.) {
571     aTol1=aTol*sqrt(0.5*aX1/aFocal);
572   }
573   if (aTol1==0.) {
574     aTol1=aTol;
575   }
576   //
577   // aTol2
578   aTol2=aTol;
579   aX2=0.;
580   aGP->D0(aTl, aPl);
581   GeomAPI_ProjectPointOnCurve aProj2(aPl, aGAxis);
582   aNbPoints=aProj2.NbPoints();
583   if (aNbPoints) {
584     aX2=aProj2.LowerDistanceParameter();
585   }
586   
587   if (aX2>=0.) {
588     aTol2=aTol*sqrt(0.5*aX2/aFocal);
589   }
590   if (aTol2==0.) {
591     aTol2=aTol;
592   }
593   //
594   aTolMax=(aTol1>aTol2) ? aTol1 : aTol2;
595   aTolMin=(aTol1<aTol2) ? aTol1 : aTol2;
596 }
597