0023603: Boolean operation between two edges fails
[occt.git] / src / IntTools / IntTools_EdgeEdge_1.cxx
1 // Created on: 2012-11-29
2 // Created by: Peter KURNEV
3 // Copyright (c) 2012 OPEN CASCADE SAS
4 //
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
9 //
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 //
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
19
20
21 #include <IntTools_EdgeEdge.ixx>
22
23 #include <gp_Elips.hxx>
24 #include <gp_Ax1.hxx>
25 #include <gp_Dir.hxx>
26 #include <gp_XYZ.hxx>
27 #include <gp_Ax2.hxx>
28 #include <gp_Pnt.hxx>
29 //
30 #include <Geom_Curve.hxx>
31 #include <Geom_Line.hxx>
32 #include <Geom_Circle.hxx>
33 #include <Geom_Ellipse.hxx>
34 #include <Geom_Parabola.hxx>
35 #include <Geom_Hyperbola.hxx>
36 #include <Geom_BezierCurve.hxx>
37 #include <Geom_BSplineCurve.hxx>
38 #include <Geom_TrimmedCurve.hxx>
39 #include <Geom_OffsetCurve.hxx>
40 //
41 #include <BRep_Tool.hxx>
42 #include <BRepAdaptor_Curve.hxx>
43
44 //=======================================================================
45 //class    : IntTools_ComparatorCurve
46 //purpose  : 
47 //=======================================================================
48 class IntTools_ComparatorCurve {
49  public: 
50   IntTools_ComparatorCurve() {
51     myT11=0.;
52     myT12=0.;
53     myT21=0.;
54     myT22=0.;
55     myIsSame=Standard_False;
56   };
57   //
58   virtual ~IntTools_ComparatorCurve(){
59   }; 
60   //
61   void SetCurve1(const BRepAdaptor_Curve& aBC3D) {
62     myBC1=aBC3D;
63   };
64   //
65   const BRepAdaptor_Curve& Curve1()const {
66     return myBC1;
67   };
68   //
69   void SetRange1(const Standard_Real aT1,
70                  const Standard_Real aT2) {
71     myT11=aT1;
72     myT12=aT2;
73   };
74   //
75   void Range1(Standard_Real& aT1, Standard_Real& aT2)const {
76     aT1=myT11;
77     aT2=myT12;
78   };
79   //
80   void SetCurve2(const BRepAdaptor_Curve& aBC3D){
81     myBC2=aBC3D;
82   };
83   //
84   const BRepAdaptor_Curve& Curve2()const{
85     return myBC2;
86   };
87   //
88   void SetRange2(const Standard_Real aT1,
89                  const Standard_Real aT2){
90     myT21=aT1;
91     myT22=aT2;
92   };
93   //
94   void Range2(Standard_Real& aT1, 
95               Standard_Real& aT2)const {
96     aT1=myT21;
97     aT2=myT22;
98   };
99   //
100   Standard_Boolean IsSame()const {
101     return myIsSame;
102   }; 
103   //
104   void Perform();
105   //
106   //--------------------------------------
107  protected:
108   //
109   void IsSameElipse();
110   //
111   void IsSameBSplineCurve();
112   //
113   static 
114     Standard_Boolean 
115       IsSameReal(const Standard_Real aR1, 
116                  const Standard_Real aR2);
117   //
118   static
119     Standard_Boolean 
120       IsSameAx2(const gp_Ax2& aAx21, 
121                 const gp_Ax2& aAx22);
122   //
123   static
124     Standard_Boolean
125       IsSameAx1(const gp_Ax1& aAx1, 
126                 const gp_Ax1& aAx2);
127   //
128   static
129     Standard_Boolean 
130       IsSamePnt(const gp_Pnt& aP1, 
131                 const gp_Pnt& aP2);
132   static
133     Standard_Boolean 
134       IsSameDir(const gp_Dir& aDir1, 
135                 const gp_Dir& aDir2);
136   //
137   static
138     Standard_Boolean 
139       IsSameXYZ(const gp_XYZ& aXYZ1, 
140                 const gp_XYZ& aXYZ2);
141   //
142   static
143     void GetCurveBase(const Handle(Geom_Curve)& aC3D,
144                       GeomAbs_CurveType& aTypeBase,
145                       Handle(Geom_Curve)& aCurveBase);
146   //
147   static
148     Standard_Boolean 
149       IsTypeBase(const Handle(Geom_Curve)& aC,
150                  GeomAbs_CurveType& aTypeB);
151   //
152  protected:
153   BRepAdaptor_Curve myBC1;
154   Standard_Real myT11;
155   Standard_Real myT12;
156   //
157   BRepAdaptor_Curve myBC2;
158   Standard_Real myT21;
159   Standard_Real myT22;
160   //
161   Standard_Boolean myIsSame;
162 };
163 //=======================================================================
164 //function : Perform
165 //purpose  : 
166 //=======================================================================
167 void IntTools_ComparatorCurve::Perform()
168 {
169   GeomAbs_CurveType aCurveType1, aCurveType2;
170   //
171   myIsSame=Standard_False;
172   //
173   aCurveType1=myBC1.GetType();
174   aCurveType2=myBC2.GetType();
175   //
176   myIsSame=(aCurveType1==aCurveType2);
177   if (!myIsSame) {
178     return; 
179   }
180   // 
181   myIsSame=IsSameReal(myT11, myT21);
182   if (!myIsSame) {
183     return;
184   }
185   //
186   myIsSame=IsSameReal(myT12, myT22);
187   if (!myIsSame) {
188     return;
189   }
190   //
191   if (aCurveType1==GeomAbs_Ellipse) {
192     IsSameElipse();
193     return;
194   } 
195   else if (aCurveType1==GeomAbs_BSplineCurve) {
196     IsSameBSplineCurve();
197     return ;
198   }
199   else {
200     myIsSame=Standard_False;
201     return;
202   }
203 }
204 //=======================================================================
205 //function : IsSameBSplineCurve
206 //purpose  : 
207 //=======================================================================
208 void IntTools_ComparatorCurve::IsSameBSplineCurve()
209 {
210   Standard_Boolean bIsRational, bIsPreiodic;
211   Standard_Integer iNbPoles, iNbKnots, iDegree;
212   //
213   bIsRational=myBC1.IsRational();
214   myIsSame=(bIsRational==myBC2.IsRational());
215   if (!myIsSame) {
216     return;
217   }
218   //
219   iNbPoles=myBC1.NbPoles();
220   myIsSame=(iNbPoles==myBC2.NbPoles());
221   if (!myIsSame) {
222     return;
223   }
224   //
225   iNbKnots=myBC1.NbKnots();
226   myIsSame=(iNbKnots==myBC2.NbKnots());
227   if (!myIsSame) {
228     return;
229   }
230   //
231   iDegree=myBC1.Degree();
232   myIsSame=(iDegree==myBC2.Degree());
233   if (!myIsSame) {
234     return;
235   } 
236   //
237   bIsPreiodic=myBC1.IsPeriodic();
238   myIsSame=(bIsPreiodic==myBC2.IsPeriodic());
239   if (!myIsSame) {
240     return;
241   }
242  
243   //-------------------------------------------
244   Standard_Integer i, j, aM[2];
245   Standard_Real aT1, aT2, aX0[4], aX1[4];
246   GeomAbs_CurveType aTypeBase;
247   gp_Pnt aP;
248   Handle(Geom_Curve) aC;
249   Handle(Geom_BSplineCurve) aBSp[2];
250   TopoDS_Edge aE1, aE2;
251   //
252   aE1=myBC1.Edge();
253   aE2=myBC2.Edge();
254   //
255   aC=BRep_Tool::Curve (aE1, aT1, aT2);
256   GetCurveBase(aC, aTypeBase, aBSp[0]);
257   //
258   aC=BRep_Tool::Curve (aE2, aT1, aT2);
259   GetCurveBase(aC, aTypeBase, aBSp[1]);
260   //
261   // Poles / Weights
262   for(i=1; i<=iNbPoles; ++i) {
263     aP=aBSp[0]->Pole(i);
264     aP.Coord(aX0[0], aX0[1], aX0[2]);
265     aX0[3]=aBSp[0]->Weight(i);
266     //
267     aP=aBSp[1]->Pole(i);
268     aP.Coord(aX1[0], aX1[1], aX1[2]);
269     aX1[3]=aBSp[1]->Weight(i);
270     //
271     for (j=0; j<4; ++j) {
272       myIsSame=IsSameReal(aX0[j], aX1[j]);
273       if(!myIsSame) {
274         return;
275       }
276     }
277   }//for(i=1; i<iNbPoles; ++i) {
278   //
279   // Knots / Multiplicities
280   for(i=1; i<=iNbKnots; ++i) {
281     aX0[0]=aBSp[0]->Knot(i);
282     aX0[1]=aBSp[1]->Knot(i);
283     myIsSame=IsSameReal(aX0[0], aX0[1]);
284     if(!myIsSame) {
285       return;
286     }
287     //
288     aM[0]=aBSp[0]->Multiplicity(i);
289     aM[1]=aBSp[1]->Multiplicity(i);
290     myIsSame=(aM[0]==aM[1]);
291     if(!myIsSame) {
292       return;
293     }
294   }
295 }
296 //=======================================================================
297 //function : GetCurveBase
298 //purpose  : 
299 //=======================================================================
300 void IntTools_ComparatorCurve::GetCurveBase(const Handle(Geom_Curve)& aC3D,
301                                             GeomAbs_CurveType& aTypeBase,
302                                             Handle(Geom_Curve)& aCurveBase)
303 {
304   Standard_Boolean bIsTypeBase;
305   Standard_Integer  iTrimmed, iOffset;
306   Standard_Real aOffsetBase;
307   GeomAbs_CurveType aTypeB;
308   Handle(Geom_Curve) aC3DB;
309   Handle(Geom_TrimmedCurve) aCT3D;
310   Handle(Geom_OffsetCurve) aCF3D;
311   //
312   aTypeBase=GeomAbs_OtherCurve;
313   aOffsetBase=0.;
314   //
315   aC3DB=aC3D;
316   bIsTypeBase=IsTypeBase(aC3DB, aTypeB);
317   if (bIsTypeBase) {
318     aTypeBase=aTypeB;
319     aCurveBase=aC3D;
320     return;
321   }
322   //
323   while(1) {
324     iTrimmed=0;
325     iOffset=0;
326     aCT3D=Handle(Geom_TrimmedCurve)::DownCast(aC3DB);
327     if (!aCT3D.IsNull()) {
328       aC3DB=aCT3D->BasisCurve();
329       ++iTrimmed;
330     }
331     //
332     aCF3D=Handle(Geom_OffsetCurve)::DownCast(aC3DB);
333     if (!aCF3D.IsNull()) {
334       Standard_Real aOffset;
335       //
336       aOffset=aCF3D->Offset();
337       aOffsetBase=aOffsetBase+aOffset;
338       //
339       aC3DB=aCF3D->BasisCurve();
340       ++iOffset;
341     }
342     //
343     if (!(iTrimmed || iOffset)) {
344       break;
345     }
346     //
347     bIsTypeBase=IsTypeBase(aC3DB, aTypeB);
348     if (bIsTypeBase) {
349       aTypeBase=aTypeB;
350       aCurveBase=aC3DB;
351       return;
352     }
353   }
354 }
355 //=======================================================================
356 //function : IsTypeBase
357 //purpose  : 
358 //=======================================================================
359 Standard_Boolean 
360   IntTools_ComparatorCurve::IsTypeBase(const Handle(Geom_Curve)& aC,
361                                        GeomAbs_CurveType& aTypeB)
362 {
363   Standard_Boolean bRet; 
364   Handle(Standard_Type) aType;
365   //
366   bRet=Standard_True;
367   //
368   aType=aC->DynamicType();
369   if (aType==STANDARD_TYPE(Geom_Line)) {
370     aTypeB=GeomAbs_Line;
371   }
372   else if (aType==STANDARD_TYPE(Geom_Circle)) {
373     aTypeB=GeomAbs_Circle;
374   }
375   else if (aType==STANDARD_TYPE(Geom_Ellipse)) {
376     aTypeB=GeomAbs_Ellipse;
377   }
378   else if (aType==STANDARD_TYPE(Geom_Parabola)) {
379     aTypeB=GeomAbs_Parabola;
380   }
381   else if (aType==STANDARD_TYPE(Geom_Hyperbola)) {
382     aTypeB=GeomAbs_Hyperbola;
383   }
384   else if (aType==STANDARD_TYPE(Geom_BezierCurve)) {
385     aTypeB=GeomAbs_BezierCurve;
386   }
387   else if (aType==STANDARD_TYPE(Geom_BSplineCurve)) {
388     aTypeB=GeomAbs_BSplineCurve;
389   }
390   else {
391     aTypeB=GeomAbs_OtherCurve;
392     bRet=!bRet;
393   }
394   return bRet;
395 }
396 //=======================================================================
397 //function : IsSameElipse
398 //purpose  : 
399 //=======================================================================
400 void IntTools_ComparatorCurve::IsSameElipse()
401 {
402   Standard_Real aR1, aR2;
403   gp_Elips aElips1, aElips2;
404   // 
405   myIsSame=Standard_False;
406   //
407   aElips1=myBC1.Ellipse();
408   aElips2=myBC2.Ellipse();
409   //
410   aR1=aElips1.MajorRadius();
411   aR2=aElips2.MajorRadius();
412   myIsSame=IsSameReal(aR1, aR2);
413   if (!myIsSame) {
414     return;
415   }
416   //
417   aR1=aElips1.MinorRadius();
418   aR2=aElips2.MinorRadius();
419   myIsSame=IsSameReal(aR1, aR2);
420   if (!myIsSame) {
421     return;
422   }
423   //
424   const gp_Ax2& aAx21=aElips1.Position();
425   const gp_Ax2& aAx22=aElips2.Position();
426   myIsSame=IsSameAx2(aAx21, aAx22);
427 }
428 //=======================================================================
429 //function : IsSameAx2
430 //purpose  : 
431 //=======================================================================
432 Standard_Boolean 
433   IntTools_ComparatorCurve::IsSameAx2(const gp_Ax2& aAx21, 
434                                       const gp_Ax2& aAx22)
435 {
436   Standard_Boolean bRet;
437   //
438   const gp_Ax1& aAx1=aAx21.Axis();
439   const gp_Ax1& aAx2=aAx22.Axis();
440   //
441   bRet=IsSameAx1(aAx1, aAx2);
442   if (!bRet) {
443     return bRet;
444   }
445   //
446   const gp_Dir& aDirX1=aAx21.XDirection();
447   const gp_Dir& aDirX2=aAx22.XDirection();
448   //
449   bRet=IsSameDir(aDirX1, aDirX2);
450   if (!bRet) {
451     return bRet;
452   }
453   //
454   //
455   const gp_Dir& aDirY1=aAx21.YDirection();
456   const gp_Dir& aDirY2=aAx22.YDirection();
457   //
458   bRet=IsSameDir(aDirY1, aDirY2);
459   //
460   return bRet;
461 }
462 //=======================================================================
463 //function : IsSamePnt
464 //purpose  : 
465 //=======================================================================
466 Standard_Boolean 
467   IntTools_ComparatorCurve::IsSamePnt(const gp_Pnt& aP1, 
468                                       const gp_Pnt& aP2)
469 {
470   const gp_XYZ& aXYZ1=aP1.XYZ();
471   const gp_XYZ& aXYZ2=aP2.XYZ();
472   return IsSameXYZ(aXYZ1, aXYZ2);
473 }
474 //=======================================================================
475 //function : IsSameAx1
476 //purpose  : 
477 //=======================================================================
478 Standard_Boolean 
479   IntTools_ComparatorCurve::IsSameAx1(const gp_Ax1& aAx1, 
480                                       const gp_Ax1& aAx2)
481 {
482   Standard_Boolean bRet;
483   //
484   const gp_Pnt& aP1=aAx1.Location();
485   const gp_Pnt& aP2=aAx2.Location();
486   //
487   bRet=IsSamePnt(aP1, aP2);
488   if (!bRet) {
489     return bRet;
490   }
491   //
492   const gp_Dir& aDir1=aAx1.Direction();
493   const gp_Dir& aDir2=aAx2.Direction();
494   //
495   bRet=IsSameDir(aDir1, aDir2);
496   return bRet;
497 }
498 //=======================================================================
499 //function : IsSameDir
500 //purpose  : 
501 //=======================================================================
502 Standard_Boolean 
503   IntTools_ComparatorCurve::IsSameDir(const gp_Dir& aDir1, 
504                                       const gp_Dir& aDir2)
505 {
506   const gp_XYZ& aXYZ1=aDir1.XYZ();
507   const gp_XYZ& aXYZ2=aDir2.XYZ();
508   return IsSameXYZ(aXYZ1, aXYZ2);
509 }
510 //=======================================================================
511 //function : IsSameXYZ
512 //purpose  : 
513 //=======================================================================
514 Standard_Boolean 
515   IntTools_ComparatorCurve::IsSameXYZ(const gp_XYZ& aXYZ1, 
516                                       const gp_XYZ& aXYZ2)
517 {
518   Standard_Boolean bRet;
519   Standard_Integer i;
520   Standard_Real aX1[3], aX2[3];
521   
522   aXYZ1.Coord(aX1[0], aX1[1], aX1[2]);
523   aXYZ2.Coord(aX2[0], aX2[1], aX2[2]);
524   //
525   for (i=0; i<3; ++i) {
526     bRet=IsSameReal(aX1[i], aX2[i]);
527     if(!bRet) {
528       break;
529     }
530   }
531   return bRet;
532 }
533 //=======================================================================
534 //function : IsSameReal
535 //purpose  : 
536 //=======================================================================
537 Standard_Boolean 
538   IntTools_ComparatorCurve::IsSameReal(const Standard_Real aR1, 
539                                        const Standard_Real aR2)
540 {
541   Standard_Boolean bRet;
542   Standard_Real aEpsilon;
543   //
544   aEpsilon=Epsilon(aR1);
545   bRet=(fabs(aR1-aR2)<aEpsilon);
546   return bRet;
547 }
548 //=======================================================================
549 //function : IsSameCurves
550 //purpose  : 
551 //=======================================================================
552 Standard_Boolean IntTools_EdgeEdge::IsSameCurves()
553 {
554   Standard_Boolean bRet;
555   IntTools_ComparatorCurve aICC;
556   //
557   aICC.SetCurve1(myCFrom);
558   aICC.SetRange1(myTminFrom, myTmaxFrom);
559   //
560   aICC.SetCurve2(myCTo);
561   aICC.SetRange2(myTminTo, myTmaxTo);
562   //
563   aICC.Perform();
564   bRet=aICC.IsSame();
565   //
566   return bRet;
567 }