0028486: Fuse of several solids fails due to presence of common zones between faces
[occt.git] / src / IntTools / IntTools_EdgeFace.cxx
1 // Created on: 2001-02-26
2 // Created by: Peter KURNEV
3 // Copyright (c) 2001-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16
17 #include <Bnd_Box.hxx>
18 #include <BndLib_AddSurface.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRepAdaptor_Surface.hxx>
21 #include <Extrema_ExtCS.hxx>
22 #include <Extrema_POnCurv.hxx>
23 #include <Extrema_POnSurf.hxx>
24 #include <Geom_Curve.hxx>
25 #include <Geom_Surface.hxx>
26 #include <GeomAdaptor_Curve.hxx>
27 #include <GeomAdaptor_HCurve.hxx>
28 #include <GeomAdaptor_HSurface.hxx>
29 #include <GeomAdaptor_Surface.hxx>
30 #include <GeomAPI_ProjectPointOnSurf.hxx>
31 #include <gp_Ax1.hxx>
32 #include <gp_Circ.hxx>
33 #include <gp_Cone.hxx>
34 #include <gp_Cylinder.hxx>
35 #include <gp_Lin.hxx>
36 #include <gp_Pln.hxx>
37 #include <gp_Pnt.hxx>
38 #include <gp_Torus.hxx>
39 #include <IntCurveSurface_HInter.hxx>
40 #include <IntCurveSurface_IntersectionPoint.hxx>
41 #include <IntTools.hxx>
42 #include <IntTools_BeanFaceIntersector.hxx>
43 #include <IntTools_CArray1OfInteger.hxx>
44 #include <IntTools_CommonPrt.hxx>
45 #include <IntTools_Context.hxx>
46 #include <IntTools_EdgeFace.hxx>
47 #include <IntTools_FClass2d.hxx>
48 #include <IntTools_Range.hxx>
49 #include <IntTools_Root.hxx>
50 #include <IntTools_Tools.hxx>
51 #include <Precision.hxx>
52 #include <TopoDS_Edge.hxx>
53 #include <TopoDS_Face.hxx>
54
55 #include <algorithm>
56 static
57   Standard_Boolean IsCoplanar (const BRepAdaptor_Curve&  ,
58                                const BRepAdaptor_Surface& );
59 static
60   Standard_Boolean IsRadius (const BRepAdaptor_Curve& aCurve ,
61                              const BRepAdaptor_Surface& aSurface,
62                              const Standard_Real aCriteria);
63
64 //=======================================================================
65 //function : IntTools_EdgeFace::IntTools_EdgeFace
66 //purpose  : 
67 //=======================================================================
68   IntTools_EdgeFace::IntTools_EdgeFace()
69 {
70   myFuzzyValue = Precision::Confusion();
71   myDiscret = 30;
72   myEpsT   =1e-12;
73   myDeflection=0.01;
74   myIsDone=Standard_False;
75   myErrorStatus=1;
76   myQuickCoincidenceCheck=Standard_False;
77 }
78 //=======================================================================
79 //function : SetContext
80 //purpose  : 
81 //=======================================================================
82 void IntTools_EdgeFace::SetContext(const Handle(IntTools_Context)& theContext) 
83 {
84   myContext = theContext;
85 }
86
87 //=======================================================================
88 //function : Context
89 //purpose  : 
90 //=======================================================================
91 const Handle(IntTools_Context)& IntTools_EdgeFace::Context()const 
92 {
93   return myContext;
94 }
95 //=======================================================================
96 //function : SetEdge
97 //purpose  : 
98 //=======================================================================
99 void IntTools_EdgeFace::SetEdge(const TopoDS_Edge& anEdge)
100 {
101   myEdge=anEdge;
102 }
103 //=======================================================================
104 //function : SetFace
105 //purpose  : 
106 //=======================================================================
107 void IntTools_EdgeFace::SetFace(const TopoDS_Face& aFace)
108 {
109   myFace=aFace;
110 }
111 //=======================================================================
112 //function : Edge
113 //purpose  : 
114 //=======================================================================
115 const TopoDS_Edge& IntTools_EdgeFace::Edge()const 
116 {
117   return myEdge;
118 }
119 //=======================================================================
120 //function : Face
121 //purpose  : 
122 //=======================================================================
123 const TopoDS_Face& IntTools_EdgeFace::Face()const 
124 {
125   return myFace;
126 }
127 //=======================================================================
128 //function : SetFuzzyValue
129 //purpose  : 
130 //=======================================================================
131 void IntTools_EdgeFace::SetFuzzyValue(const Standard_Real theFuzz)
132 {
133   myFuzzyValue = Max(theFuzz, Precision::Confusion());
134 }
135 //=======================================================================
136 //function : SetDiscretize
137 //purpose  : 
138 //=======================================================================
139 void IntTools_EdgeFace::SetDiscretize(const Standard_Integer aDiscret)
140 {
141   myDiscret=aDiscret;
142 }
143 //=======================================================================
144 //function : SetDeflection
145 //purpose  : 
146 //=======================================================================
147 void IntTools_EdgeFace::SetDeflection(const Standard_Real aDefl) 
148 {
149   myDeflection=aDefl;
150
151 //=======================================================================
152 //function : SetEpsilonT
153 //purpose  : 
154 //=======================================================================
155 void IntTools_EdgeFace::SetEpsilonT(const Standard_Real anEpsT) 
156 {
157   myEpsT=anEpsT;
158
159 //=======================================================================
160 //function : SetRange
161 //purpose  : 
162 //=======================================================================
163 void IntTools_EdgeFace::SetRange(const Standard_Real aFirst,
164                                  const Standard_Real aLast) 
165 {
166   myRange.SetFirst (aFirst);
167   myRange.SetLast  (aLast);
168
169
170 //=======================================================================
171 //function : SetRange
172 //purpose  : 
173 //=======================================================================
174 void IntTools_EdgeFace::SetRange(const IntTools_Range& aRange) 
175 {
176   SetRange(aRange.First(), aRange.Last());
177
178 //=======================================================================
179 //function : IsDone
180 //purpose  : 
181 //=======================================================================
182 Standard_Boolean IntTools_EdgeFace::IsDone()const 
183 {
184   return myIsDone;
185
186 //=======================================================================
187 //function : ErrorStatus
188 //purpose  : 
189 //=======================================================================
190 Standard_Integer IntTools_EdgeFace::ErrorStatus()const 
191 {
192   return myErrorStatus;
193 }
194 //=======================================================================
195 //function : CommonParts
196 //purpose  : 
197 //=======================================================================
198 const IntTools_SequenceOfCommonPrts& IntTools_EdgeFace::CommonParts() const 
199 {
200   return mySeqOfCommonPrts;
201 }
202 //=======================================================================
203 //function : Range
204 //purpose  : 
205 //=======================================================================
206 const IntTools_Range&  IntTools_EdgeFace::Range() const
207 {
208   return myRange;
209
210 //=======================================================================
211 //function :  IsCoincident
212 //purpose  : 
213 //=======================================================================
214 Standard_Boolean IntTools_EdgeFace::IsCoincident() 
215 {
216   Standard_Integer i, iCnt;
217   Standard_Real dT, aT, aD, aT1, aT2, aU, aV;
218
219   gp_Pnt aP;
220   TopAbs_State aState;
221   gp_Pnt2d aP2d;
222   //
223   GeomAPI_ProjectPointOnSurf& aProjector=myContext->ProjPS(myFace);
224
225   const Standard_Integer aNbSeg=23;
226   const Standard_Real aTresh=0.5;
227   const Standard_Integer aTreshIdxF = RealToInt((aNbSeg+1)*0.25),
228                          aTreshIdxL = RealToInt((aNbSeg+1)*0.75);
229   const Handle(Geom_Surface) aSurf = BRep_Tool::Surface(myFace);
230
231   aT1=myRange.First();
232   aT2=myRange.Last();
233   dT=(aT2-aT1)/aNbSeg;
234   //
235   Standard_Boolean isClassified = Standard_False;
236   iCnt=0;
237   for(i=0; i <= aNbSeg; ++i) {
238     aT = aT1+i*dT;
239     aP=myC.Value(aT);
240     //
241     aProjector.Perform(aP);
242     if (!aProjector.IsDone()) {
243       continue;
244     }
245     //
246     
247     aD=aProjector.LowerDistance();
248     if (aD>myCriteria) {
249       continue;
250     }
251     //
252
253     ++iCnt; 
254
255     //We classify only three points: in the begin, in the 
256     //end and in the middle of the edge.
257     //However, exact middle point (when i == (aNbSeg + 1)/2)
258     //can be unprojectable. Therefore, it will not be able to
259     //be classified. Therefore, points with indexes in 
260     //[aTreshIdxF, aTreshIdxL] range are made available 
261     //for classification.
262     //isClassified == TRUE if MIDDLE point has been choosen and
263     //classified correctly.
264
265     if(((0 < i) && (i < aTreshIdxF)) || ((aTreshIdxL < i ) && (i < aNbSeg)))
266       continue;
267
268     if(isClassified && (i != aNbSeg))
269       continue;
270
271     aProjector.LowerDistanceParameters(aU, aV);
272     aP2d.SetX(aU);
273     aP2d.SetY(aV);
274
275     IntTools_FClass2d& aClass2d=myContext->FClass2d(myFace);
276     aState = aClass2d.Perform(aP2d);
277     
278     if(aState == TopAbs_OUT)
279       return Standard_False;
280
281     if(i != 0)
282       isClassified = Standard_True;
283   }
284   //
285   const Standard_Real aCoeff=(Standard_Real)iCnt/((Standard_Real)aNbSeg+1);
286   return (aCoeff > aTresh);
287 }
288 //=======================================================================
289 //function : CheckData
290 //purpose  : 
291 //=======================================================================
292 void IntTools_EdgeFace::CheckData()
293 {
294   if (BRep_Tool::Degenerated(myEdge)) {
295     myErrorStatus=2;
296   }
297   if (!BRep_Tool::IsGeometric(myEdge)) { 
298      myErrorStatus=3;
299   }
300 }
301
302 //=======================================================================
303 //function : IsProjectable
304 //purpose  : 
305 //=======================================================================
306 Standard_Boolean IntTools_EdgeFace::IsProjectable
307   (const Standard_Real aT) const
308 {
309   Standard_Boolean bFlag; 
310   gp_Pnt aPC;
311   //
312   myC.D0(aT, aPC);
313   bFlag=myContext->IsValidPointForFace(aPC, myFace, myCriteria);
314   //
315   return bFlag;
316 }
317 //=======================================================================
318 //function : DistanceFunction
319 //purpose  : 
320 //=======================================================================
321 Standard_Real IntTools_EdgeFace::DistanceFunction
322   (const Standard_Real t)
323 {
324   Standard_Real aD;
325
326   //
327   gp_Pnt P;
328   myC.D0(t, P);
329   //
330   Standard_Boolean bIsEqDistance;
331
332   bIsEqDistance= IntTools_EdgeFace::IsEqDistance(P, myS, 1.e-7, aD); 
333   if (bIsEqDistance) {
334     aD=aD-myCriteria;
335     return aD; 
336   }
337   
338   //
339   Standard_Boolean bFlag = Standard_False;
340
341   GeomAPI_ProjectPointOnSurf& aLocProj = myContext->ProjPS(myFace);
342   aLocProj.Perform(P);
343   bFlag = aLocProj.IsDone();
344   
345   if(bFlag) {
346     aD = aLocProj.LowerDistance();
347   }
348   //
349   
350   if (!bFlag) {
351     myErrorStatus=11;
352     return 99.;
353   }
354   
355   // 
356   //   aD=aProjector.LowerDistance();
357   // 
358   aD=aD-myCriteria;
359   return aD; 
360 }
361 //
362 //=======================================================================
363 //function : IsEqDistance
364 //purpose  : 
365 //=======================================================================
366 Standard_Boolean IntTools_EdgeFace::IsEqDistance
367   (const gp_Pnt& aP,
368    const BRepAdaptor_Surface& aBAS,
369    const Standard_Real aTol,
370    Standard_Real& aD)
371 {
372   Standard_Boolean bRetFlag=Standard_True;
373
374   GeomAbs_SurfaceType aSurfType=aBAS.GetType();
375
376   if (aSurfType==GeomAbs_Cylinder) {
377     gp_Cylinder aCyl=aBAS.Cylinder();
378     const gp_Ax1& anAx1  =aCyl.Axis();
379     gp_Lin aLinAxis(anAx1);
380     Standard_Real aDC, aRadius=aCyl.Radius();
381     aDC=aLinAxis.Distance(aP);
382     if (aDC < aTol) {
383       aD=aRadius;
384       return bRetFlag; 
385     }
386   }
387
388   if (aSurfType==GeomAbs_Cone) {
389     gp_Cone aCone=aBAS.Cone();
390     const gp_Ax1& anAx1  =aCone.Axis();
391     gp_Lin aLinAxis(anAx1);
392     Standard_Real aDC, aRadius, aDS, aSemiAngle;
393     aDC=aLinAxis.Distance(aP);
394     if (aDC < aTol) {
395       gp_Pnt anApex=aCone.Apex();
396       aSemiAngle=aCone.SemiAngle();
397       aDS=aP.Distance(anApex);
398       
399       aRadius=aDS*tan(aSemiAngle);
400       aD=aRadius;
401       return bRetFlag; 
402     }
403   }
404
405   if (aSurfType==GeomAbs_Torus) {
406     Standard_Real aMajorRadius, aMinorRadius, aDC;
407
408     gp_Torus aTorus=aBAS.Torus();
409     gp_Pnt aPLoc=aTorus.Location();
410     aMajorRadius=aTorus.MajorRadius();
411     
412     aDC=fabs(aPLoc.Distance(aP)-aMajorRadius);
413     if (aDC < aTol) {
414       aMinorRadius=aTorus.MinorRadius();
415       aD=aMinorRadius;
416       return bRetFlag; 
417     }
418   }
419   return !bRetFlag; 
420 }
421 //
422 //=======================================================================
423 //function : MakeType
424 //purpose  : 
425 //=======================================================================
426 Standard_Integer IntTools_EdgeFace::MakeType
427   (IntTools_CommonPrt&  aCommonPrt)
428 {
429   Standard_Real  af1, al1;
430   Standard_Real  df1, tm;
431   Standard_Boolean bAllNullFlag;
432   //
433   bAllNullFlag=aCommonPrt.AllNullFlag();
434   if (bAllNullFlag) {
435     aCommonPrt.SetType(TopAbs_EDGE);
436     return 0;
437   }
438   //
439   aCommonPrt.Range1(af1, al1);
440
441   {
442     gp_Pnt aPF, aPL;
443     myC.D0(af1, aPF);
444     myC.D0(al1, aPL);
445     df1=aPF.Distance(aPL);
446     Standard_Boolean isWholeRange = Standard_False;
447     
448     if((Abs(af1 - myRange.First()) < myC.Resolution(myCriteria)) &&
449        (Abs(al1 - myRange.Last()) < myC.Resolution(myCriteria)))
450       isWholeRange = Standard_True;
451     
452     
453     if ((df1 > myCriteria * 2.) && isWholeRange) {
454       aCommonPrt.SetType(TopAbs_EDGE);
455     }
456     else {
457       if(isWholeRange) {
458         tm = (af1 + al1) * 0.5;
459         
460         if(aPF.Distance(myC.Value(tm)) > myCriteria * 2.) {
461           aCommonPrt.SetType(TopAbs_EDGE);
462           return 0;
463         }
464       }
465       
466       if(!CheckTouch(aCommonPrt, tm)) {
467         tm = (af1 + al1) * 0.5;
468       }
469       aCommonPrt.SetType(TopAbs_VERTEX);
470       aCommonPrt.SetVertexParameter1(tm);
471       aCommonPrt.SetRange1 (af1, al1);
472     }
473   }
474  return 0;
475 }
476
477
478 //=======================================================================
479 //function : CheckTouch 
480 //purpose  : 
481 //=======================================================================
482 Standard_Boolean IntTools_EdgeFace::CheckTouch
483   (const IntTools_CommonPrt& aCP,
484    Standard_Real&            aTx) 
485 {
486   if (myC.GetType() == GeomAbs_Line &&
487       myS.GetType() == GeomAbs_Plane) {
488     return Standard_False;
489   }
490   //
491   Standard_Real aTF, aTL, Tol, U1f, U1l, V1f, V1l, af, al,aDist2, aMinDist2;
492   Standard_Boolean theflag=Standard_False;
493   Standard_Integer aNbExt, iLower;
494
495   aCP.Range1(aTF, aTL);
496
497   //
498   Standard_Real aCR;
499   aCR=myC.Resolution(myCriteria);
500   if((Abs(aTF - myRange.First()) < aCR) &&
501      (Abs(aTL - myRange.Last())  < aCR)) {
502     return theflag; // EDGE 
503   }
504   //
505
506   Tol = Precision::PConfusion();
507
508   const Handle(Geom_Curve)&  Curve   =BRep_Tool::Curve  (myC.Edge(), af, al);
509   const Handle(Geom_Surface)& Surface=BRep_Tool::Surface(myS.Face());
510   //   Surface->Bounds(U1f,U1l,V1f,V1l);
511   U1f = myS.FirstUParameter();
512   U1l = myS.LastUParameter();
513   V1f = myS.FirstVParameter();
514   V1l = myS.LastVParameter();
515   
516   GeomAdaptor_Curve   TheCurve   (Curve,aTF, aTL);
517   GeomAdaptor_Surface TheSurface (Surface, U1f, U1l, V1f, V1l); 
518      
519   Extrema_ExtCS anExtrema (TheCurve, TheSurface, Tol, Tol);
520
521   aDist2 = 1.e100;
522
523   if(anExtrema.IsDone()) {
524     aMinDist2 = aDist2;
525
526     if(!anExtrema.IsParallel()) {
527       aNbExt=anExtrema.NbExt();
528       
529       if(aNbExt > 0) {
530  iLower=1;
531  for (Standard_Integer i=1; i<=aNbExt; i++) {
532    aDist2=anExtrema.SquareDistance(i);
533    if (aDist2 < aMinDist2) {
534      aMinDist2=aDist2;
535      iLower=i;
536    }
537  }
538  aDist2=anExtrema.SquareDistance(iLower);
539  Extrema_POnCurv aPOnC;
540  Extrema_POnSurf aPOnS;
541  anExtrema.Points(iLower, aPOnC, aPOnS);
542  aTx=aPOnC.Parameter();
543       }
544       else {
545  // modified by NIZHNY-MKK  Thu Jul 21 11:35:32 2005.BEGIN
546  IntCurveSurface_HInter anExactIntersector;
547   
548  Handle(GeomAdaptor_HCurve) aCurve     = new GeomAdaptor_HCurve(TheCurve);
549  Handle(GeomAdaptor_HSurface) aSurface = new GeomAdaptor_HSurface(TheSurface);
550  
551  anExactIntersector.Perform(aCurve, aSurface);
552
553  if(anExactIntersector.IsDone()) {
554    for(Standard_Integer i = 1; i <= anExactIntersector.NbPoints(); i++) {
555      const IntCurveSurface_IntersectionPoint& aPoint = anExactIntersector.Point(i);
556       
557      if((aPoint.W() >= aTF) && (aPoint.W() <= aTL)) {
558        aDist2=0.;
559        aTx = aPoint.W();
560      }
561    }
562  }
563  // modified by NIZHNY-MKK  Thu Jul 21 11:35:40 2005.END
564       }
565     }
566     else {
567       return theflag;
568     }
569   }
570
571   Standard_Real aBoundaryDist;
572
573   aBoundaryDist = DistanceFunction(aTF) + myCriteria;
574   if(aBoundaryDist * aBoundaryDist < aDist2) {
575     aDist2 = aBoundaryDist * aBoundaryDist;
576     aTx = aTF;
577   }
578   
579   aBoundaryDist = DistanceFunction(aTL) + myCriteria;
580   if(aBoundaryDist * aBoundaryDist < aDist2) {
581     aDist2 = aBoundaryDist * aBoundaryDist;
582     aTx = aTL;
583   }
584
585   Standard_Real aParameter = (aTF + aTL) * 0.5;
586   aBoundaryDist = DistanceFunction(aParameter) + myCriteria;
587   if(aBoundaryDist * aBoundaryDist < aDist2) {
588     aDist2 = aBoundaryDist * aBoundaryDist;
589     aTx = aParameter;
590   }
591
592   if(aDist2 > myCriteria * myCriteria) {
593     return theflag;
594   }
595   
596   if (fabs (aTx-aTF) < myEpsT) {
597     return !theflag;
598   }
599
600   if (fabs (aTx-aTL) < myEpsT) {
601     return !theflag;
602   }
603
604   if (aTx>aTF && aTx<aTL) {
605     return !theflag;
606   }
607
608   return theflag;
609 }
610
611 //=======================================================================
612 //function : Perform
613 //purpose  : 
614 //=======================================================================
615 void IntTools_EdgeFace::Perform() 
616 {
617   Standard_Integer i, aNb;
618   IntTools_CommonPrt aCommonPrt;
619   //
620   aCommonPrt.SetEdge1(myEdge);
621   //
622   myErrorStatus=0;
623   CheckData();
624   if (myErrorStatus) {
625     return;
626   }
627   //
628   if (myContext.IsNull()) {
629     myContext=new IntTools_Context;
630   }
631   //
632   myIsDone = Standard_False;
633   myC.Initialize(myEdge);
634   GeomAbs_CurveType aCurveType;
635   aCurveType=myC.GetType();
636   //
637   // Prepare myCriteria
638   Standard_Real aFuzz = myFuzzyValue / 2.;
639   Standard_Real aTolF = BRep_Tool::Tolerance(myFace) + aFuzz;
640   Standard_Real aTolE = BRep_Tool::Tolerance(myEdge) + aFuzz;
641   if (aCurveType == GeomAbs_BSplineCurve ||
642       aCurveType==GeomAbs_BezierCurve) {
643     //--- 5112
644     Standard_Real diff1 = (aTolE/aTolF);
645     Standard_Real diff2 = (aTolF/aTolE);
646     if( diff1 > 100 || diff2 > 100 ) {
647       myCriteria = Max(aTolE,aTolF);
648     }
649     else //--- 5112
650       myCriteria = 1.5*aTolE + aTolF;
651   }
652   else {
653     myCriteria = aTolE + aTolF;
654   }
655   
656   myS = myContext->SurfaceAdaptor(myFace);
657   
658   if (myQuickCoincidenceCheck) {
659     if (IsCoincident()) {
660       aCommonPrt.SetType(TopAbs_EDGE);
661       aCommonPrt.SetRange1(myRange.First(), myRange.Last());
662       mySeqOfCommonPrts.Append(aCommonPrt);
663       myIsDone=Standard_True;
664       return;
665     }
666   }
667   //
668   IntTools_BeanFaceIntersector anIntersector(myC, myS, aTolE, aTolF);
669   anIntersector.SetBeanParameters(myRange.First(), myRange.Last());
670   //
671   anIntersector.SetContext(myContext);
672   //
673   anIntersector.Perform();
674   
675   if(!anIntersector.IsDone()) {
676     return;
677   }
678   
679   for(Standard_Integer r = 1; r <= anIntersector.Result().Length(); r++) {
680     const IntTools_Range& aRange = anIntersector.Result().Value(r);
681     
682     if(IsProjectable(IntTools_Tools::IntermediatePoint(aRange.First(), aRange.Last()))) {
683       aCommonPrt.SetRange1(aRange.First(), aRange.Last());
684       mySeqOfCommonPrts.Append(aCommonPrt);
685     }
686   }
687
688   aNb = mySeqOfCommonPrts.Length();
689
690   for (i=1; i<=aNb; i++) {
691     IntTools_CommonPrt& aCP=mySeqOfCommonPrts.ChangeValue(i);
692     //
693     Standard_Real aTx1, aTx2;
694     gp_Pnt aPx1, aPx2;
695     //
696     aCP.Range1(aTx1, aTx2);
697     myC.D0(aTx1, aPx1);
698     myC.D0(aTx2, aPx2);
699     aCP.SetBoundingPoints(aPx1, aPx2);
700     //
701     MakeType (aCP); 
702   }
703   {
704     // Line\Cylinder's Common Parts treatement
705     GeomAbs_CurveType   aCType;
706     GeomAbs_SurfaceType aSType;
707     TopAbs_ShapeEnum aType;
708     Standard_Boolean bIsTouch;
709     Standard_Real aTx;
710     
711     aCType=myC.GetType();
712     aSType=myS.GetType();
713     
714     if (aCType==GeomAbs_Line && aSType==GeomAbs_Cylinder) {
715       for (i=1; i<=aNb; i++) {
716         IntTools_CommonPrt& aCP=mySeqOfCommonPrts(i);
717         aType=aCP.Type();
718         if (aType==TopAbs_EDGE) {
719           bIsTouch=CheckTouch (aCP, aTx);
720           if (bIsTouch) {
721             aCP.SetType(TopAbs_VERTEX);
722             aCP.SetVertexParameter1(aTx);
723             //aCP.SetRange1 (aTx, aTx);
724           }
725         }
726         else if (aType==TopAbs_VERTEX) {
727           bIsTouch=CheckTouchVertex (aCP, aTx);
728           if (bIsTouch) {
729             aCP.SetVertexParameter1(aTx);
730             //aCP.SetRange1 (aTx, aTx);
731           }
732         }
733       }
734     }
735     
736     // Circle\Plane's Common Parts treatement
737     
738     if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
739       Standard_Boolean bIsCoplanar, bIsRadius;
740       bIsCoplanar=IsCoplanar(myC, myS);
741       bIsRadius=IsRadius(myC, myS, myCriteria);
742       if (!bIsCoplanar && !bIsRadius) {
743         for (i=1; i<=aNb; i++) {
744           IntTools_CommonPrt& aCP=mySeqOfCommonPrts(i);
745           aType=aCP.Type();
746           if (aType==TopAbs_EDGE) {
747             bIsTouch=CheckTouch (aCP, aTx);
748             if (bIsTouch) {
749               aCP.SetType(TopAbs_VERTEX);
750               aCP.SetVertexParameter1(aTx);
751               //aCP.SetRange1 (aTx, aTx);
752             }
753           }
754           else if (aType==TopAbs_VERTEX) {
755             bIsTouch=CheckTouchVertex (aCP, aTx);
756             if (bIsTouch) {
757               aCP.SetVertexParameter1(aTx);
758               //aCP.SetRange1 (aTx, aTx);
759             }
760           }
761         }
762       }
763     }
764   }
765   myIsDone=Standard_True;
766 }
767
768 //
769 // myErrorStatus
770 // 1 - the method Perform() is not invoked  
771 // 2,3,4,5 -the method CheckData() fails
772 // 6 - PrepareArgs() problems
773 // 7 - No Projectable ranges
774 // 8,9 - PrepareArgs() problems occured inside  projectable Ranges
775 // 11 - can't fill array  aFunc(i) in PrepareArgsFuncArrays 
776
777
778 //=======================================================================
779 //function : CheckTouch 
780 //purpose  : 
781 //=======================================================================
782 Standard_Boolean IntTools_EdgeFace::CheckTouchVertex 
783   (const IntTools_CommonPrt& aCP,
784    Standard_Real& aTx) 
785 {
786   Standard_Real aTF, aTL, Tol, U1f,U1l,V1f,V1l;
787   Standard_Real aEpsT, af, al,aDist2, aMinDist2, aTm, aDist2New;
788   Standard_Boolean theflag=Standard_False;
789   Standard_Integer aNbExt, i, iLower ;
790   GeomAbs_CurveType aType;
791   //
792   aCP.Range1(aTF, aTL);
793   aType=myC.GetType();
794   //
795   aEpsT=8.e-5;
796   if (aType==GeomAbs_Line) {
797     aEpsT=9.e-5;
798   }
799   //
800   aTm=0.5*(aTF+aTL);
801   aDist2=DistanceFunction(aTm);
802   aDist2 *= aDist2;
803
804   Tol = Precision::PConfusion();
805
806   const Handle(Geom_Curve)&  Curve =BRep_Tool::Curve  (myC.Edge(), af, al);
807   const Handle(Geom_Surface)& Surface=BRep_Tool::Surface(myS.Face());
808
809   Surface->Bounds(U1f,U1l,V1f,V1l);
810   
811   GeomAdaptor_Curve   TheCurve   (Curve,aTF, aTL);
812   GeomAdaptor_Surface TheSurface (Surface, U1f, U1l, V1f, V1l); 
813      
814   Extrema_ExtCS anExtrema (TheCurve, TheSurface, Tol, Tol);
815    
816   if(!anExtrema.IsDone()) {
817     return theflag;
818   }
819   if (anExtrema.IsParallel()) {
820     return theflag;
821   }
822   
823   aNbExt=anExtrema.NbExt() ;
824   if (!aNbExt) {
825      return theflag;
826   }
827
828   iLower=1;
829   aMinDist2=1.e100;
830   for (i=1; i<=aNbExt; ++i) {
831     aDist2=anExtrema.SquareDistance(i);
832     if (aDist2 < aMinDist2) {
833       aMinDist2=aDist2;
834       iLower=i;
835     }
836   }
837
838   aDist2New=anExtrema.SquareDistance(iLower);
839   
840   if (aDist2New > aDist2) {
841     aTx=aTm;
842     return !theflag;
843   }
844   
845   if (aDist2New > myCriteria * myCriteria) {
846     return theflag;
847   }
848
849   Extrema_POnCurv aPOnC;
850   Extrema_POnSurf aPOnS;
851   anExtrema.Points(iLower, aPOnC, aPOnS);
852
853  
854   aTx=aPOnC.Parameter();
855   ///
856   if (fabs (aTx-aTF) < aEpsT) {
857     return theflag;
858   }
859
860   if (fabs (aTx-aTL) < aEpsT) {
861     return theflag;
862   }
863
864   if (aTx>aTF && aTx<aTL) {
865     return !theflag;
866   }
867
868   return theflag;
869 }
870
871
872 //=======================================================================
873 //function :  IsCoplanar
874 //purpose  : 
875 //=======================================================================
876 Standard_Boolean IsCoplanar (const BRepAdaptor_Curve& aCurve ,
877                              const BRepAdaptor_Surface& aSurface)
878 {
879   Standard_Boolean bFlag=Standard_False;
880
881   GeomAbs_CurveType   aCType;
882   GeomAbs_SurfaceType aSType;
883
884   aCType=aCurve.GetType();
885   aSType=aSurface.GetType();
886     
887   if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
888     gp_Circ aCirc=aCurve.Circle();
889     const gp_Ax1& anAx1=aCirc.Axis();
890     const gp_Dir& aDirAx1=anAx1.Direction();
891     
892     gp_Pln aPln=aSurface.Plane();
893     const gp_Ax1& anAx=aPln.Axis();
894     const gp_Dir& aDirPln=anAx.Direction();
895
896     bFlag=IntTools_Tools::IsDirsCoinside(aDirAx1, aDirPln);
897   }
898   return bFlag;
899 }
900 //=======================================================================
901 //function :  IsRadius
902 //purpose  : 
903 //=======================================================================
904 Standard_Boolean IsRadius (const BRepAdaptor_Curve& aCurve,
905                            const BRepAdaptor_Surface& aSurface,
906                            const Standard_Real aCriteria)
907 {
908   Standard_Boolean bFlag=Standard_False;
909
910   GeomAbs_CurveType   aCType;
911   GeomAbs_SurfaceType aSType;
912
913   aCType=aCurve.GetType();
914   aSType=aSurface.GetType();
915     
916   if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
917     gp_Circ aCirc=aCurve.Circle();
918     const gp_Pnt aCenter=aCirc.Location();
919     Standard_Real aR=aCirc.Radius();
920     gp_Pln aPln=aSurface.Plane();
921     Standard_Real aD=aPln.Distance(aCenter);
922     if (fabs (aD-aR) < aCriteria) {
923       return !bFlag;
924     }
925   }
926   return bFlag;
927 }
928 //
929 //=======================================================================
930 //function :  AdaptiveDiscret
931 //purpose  : 
932 //=======================================================================
933 Standard_Integer AdaptiveDiscret (const Standard_Integer iDiscret,
934                                   const BRepAdaptor_Curve& aCurve ,
935                                   const BRepAdaptor_Surface& aSurface)
936 {
937   Standard_Integer iDiscretNew;
938
939   iDiscretNew=iDiscret;
940
941   GeomAbs_SurfaceType aSType;
942
943   aSType=aSurface.GetType();
944     
945   if (aSType==GeomAbs_Cylinder) {
946    Standard_Real aELength, aRadius, dLR;
947
948    aELength=IntTools::Length(aCurve.Edge());
949    
950    gp_Cylinder aCylinder=aSurface.Cylinder();
951    aRadius=aCylinder.Radius();
952    dLR=2*aRadius;
953
954    iDiscretNew=(Standard_Integer)(aELength/dLR);
955    
956    if (iDiscretNew<iDiscret) {
957      iDiscretNew=iDiscret;
958    }
959      
960   }
961   return iDiscretNew;
962 }
963
964 #ifdef _MSC_VER
965 #pragma warning ( default : 4101 )
966 #endif