0029069: Samples - handle UNICODE filenames within C++/CLI CSharp sample
[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   Standard_Integer aNbSeg=23;
226   if (myC.GetType() == GeomAbs_Line &&
227       myS.GetType() == GeomAbs_Plane)
228     aNbSeg = 2; // Check only three points for Line/Plane intersection
229
230   const Standard_Real aTresh=0.5;
231   const Standard_Integer aTreshIdxF = RealToInt((aNbSeg+1)*0.25),
232                          aTreshIdxL = RealToInt((aNbSeg+1)*0.75);
233   const Handle(Geom_Surface) aSurf = BRep_Tool::Surface(myFace);
234
235   aT1=myRange.First();
236   aT2=myRange.Last();
237   dT=(aT2-aT1)/aNbSeg;
238   //
239   Standard_Boolean isClassified = Standard_False;
240   iCnt=0;
241   for(i=0; i <= aNbSeg; ++i) {
242     aT = aT1+i*dT;
243     aP=myC.Value(aT);
244     //
245     aProjector.Perform(aP);
246     if (!aProjector.IsDone()) {
247       continue;
248     }
249     //
250     
251     aD=aProjector.LowerDistance();
252     if (aD>myCriteria) {
253       continue;
254     }
255     //
256
257     ++iCnt; 
258
259     //We classify only three points: in the begin, in the 
260     //end and in the middle of the edge.
261     //However, exact middle point (when i == (aNbSeg + 1)/2)
262     //can be unprojectable. Therefore, it will not be able to
263     //be classified. Therefore, points with indexes in 
264     //[aTreshIdxF, aTreshIdxL] range are made available 
265     //for classification.
266     //isClassified == TRUE if MIDDLE point has been choosen and
267     //classified correctly.
268
269     if(((0 < i) && (i < aTreshIdxF)) || ((aTreshIdxL < i ) && (i < aNbSeg)))
270       continue;
271
272     if(isClassified && (i != aNbSeg))
273       continue;
274
275     aProjector.LowerDistanceParameters(aU, aV);
276     aP2d.SetX(aU);
277     aP2d.SetY(aV);
278
279     IntTools_FClass2d& aClass2d=myContext->FClass2d(myFace);
280     aState = aClass2d.Perform(aP2d);
281     
282     if(aState == TopAbs_OUT)
283       return Standard_False;
284
285     if(i != 0)
286       isClassified = Standard_True;
287   }
288   //
289   const Standard_Real aCoeff=(Standard_Real)iCnt/((Standard_Real)aNbSeg+1);
290   return (aCoeff > aTresh);
291 }
292 //=======================================================================
293 //function : CheckData
294 //purpose  : 
295 //=======================================================================
296 void IntTools_EdgeFace::CheckData()
297 {
298   if (BRep_Tool::Degenerated(myEdge)) {
299     myErrorStatus=2;
300   }
301   if (!BRep_Tool::IsGeometric(myEdge)) { 
302      myErrorStatus=3;
303   }
304 }
305
306 //=======================================================================
307 //function : IsProjectable
308 //purpose  : 
309 //=======================================================================
310 Standard_Boolean IntTools_EdgeFace::IsProjectable
311   (const Standard_Real aT) const
312 {
313   Standard_Boolean bFlag; 
314   gp_Pnt aPC;
315   //
316   myC.D0(aT, aPC);
317   bFlag=myContext->IsValidPointForFace(aPC, myFace, myCriteria);
318   //
319   return bFlag;
320 }
321 //=======================================================================
322 //function : DistanceFunction
323 //purpose  : 
324 //=======================================================================
325 Standard_Real IntTools_EdgeFace::DistanceFunction
326   (const Standard_Real t)
327 {
328   Standard_Real aD;
329
330   //
331   gp_Pnt P;
332   myC.D0(t, P);
333   //
334   Standard_Boolean bIsEqDistance;
335
336   bIsEqDistance= IntTools_EdgeFace::IsEqDistance(P, myS, 1.e-7, aD); 
337   if (bIsEqDistance) {
338     aD=aD-myCriteria;
339     return aD; 
340   }
341   
342   //
343   Standard_Boolean bFlag = Standard_False;
344
345   GeomAPI_ProjectPointOnSurf& aLocProj = myContext->ProjPS(myFace);
346   aLocProj.Perform(P);
347   bFlag = aLocProj.IsDone();
348   
349   if(bFlag) {
350     aD = aLocProj.LowerDistance();
351   }
352   //
353   
354   if (!bFlag) {
355     myErrorStatus=11;
356     return 99.;
357   }
358   
359   // 
360   //   aD=aProjector.LowerDistance();
361   // 
362   aD=aD-myCriteria;
363   return aD; 
364 }
365 //
366 //=======================================================================
367 //function : IsEqDistance
368 //purpose  : 
369 //=======================================================================
370 Standard_Boolean IntTools_EdgeFace::IsEqDistance
371   (const gp_Pnt& aP,
372    const BRepAdaptor_Surface& aBAS,
373    const Standard_Real aTol,
374    Standard_Real& aD)
375 {
376   Standard_Boolean bRetFlag=Standard_True;
377
378   GeomAbs_SurfaceType aSurfType=aBAS.GetType();
379
380   if (aSurfType==GeomAbs_Cylinder) {
381     gp_Cylinder aCyl=aBAS.Cylinder();
382     const gp_Ax1& anAx1  =aCyl.Axis();
383     gp_Lin aLinAxis(anAx1);
384     Standard_Real aDC, aRadius=aCyl.Radius();
385     aDC=aLinAxis.Distance(aP);
386     if (aDC < aTol) {
387       aD=aRadius;
388       return bRetFlag; 
389     }
390   }
391
392   if (aSurfType==GeomAbs_Cone) {
393     gp_Cone aCone=aBAS.Cone();
394     const gp_Ax1& anAx1  =aCone.Axis();
395     gp_Lin aLinAxis(anAx1);
396     Standard_Real aDC, aRadius, aDS, aSemiAngle;
397     aDC=aLinAxis.Distance(aP);
398     if (aDC < aTol) {
399       gp_Pnt anApex=aCone.Apex();
400       aSemiAngle=aCone.SemiAngle();
401       aDS=aP.Distance(anApex);
402       
403       aRadius=aDS*tan(aSemiAngle);
404       aD=aRadius;
405       return bRetFlag; 
406     }
407   }
408
409   if (aSurfType==GeomAbs_Torus) {
410     Standard_Real aMajorRadius, aMinorRadius, aDC;
411
412     gp_Torus aTorus=aBAS.Torus();
413     gp_Pnt aPLoc=aTorus.Location();
414     aMajorRadius=aTorus.MajorRadius();
415     
416     aDC=fabs(aPLoc.Distance(aP)-aMajorRadius);
417     if (aDC < aTol) {
418       aMinorRadius=aTorus.MinorRadius();
419       aD=aMinorRadius;
420       return bRetFlag; 
421     }
422   }
423   return !bRetFlag; 
424 }
425 //
426 //=======================================================================
427 //function : MakeType
428 //purpose  : 
429 //=======================================================================
430 Standard_Integer IntTools_EdgeFace::MakeType
431   (IntTools_CommonPrt&  aCommonPrt)
432 {
433   Standard_Real  af1, al1;
434   Standard_Real  df1, tm;
435   Standard_Boolean bAllNullFlag;
436   //
437   bAllNullFlag=aCommonPrt.AllNullFlag();
438   if (bAllNullFlag) {
439     aCommonPrt.SetType(TopAbs_EDGE);
440     return 0;
441   }
442   //
443   aCommonPrt.Range1(af1, al1);
444
445   {
446     gp_Pnt aPF, aPL;
447     myC.D0(af1, aPF);
448     myC.D0(al1, aPL);
449     df1=aPF.Distance(aPL);
450     Standard_Boolean isWholeRange = Standard_False;
451     
452     if((Abs(af1 - myRange.First()) < myC.Resolution(myCriteria)) &&
453        (Abs(al1 - myRange.Last()) < myC.Resolution(myCriteria)))
454       isWholeRange = Standard_True;
455     
456     
457     if ((df1 > myCriteria * 2.) && isWholeRange) {
458       aCommonPrt.SetType(TopAbs_EDGE);
459     }
460     else {
461       if(isWholeRange) {
462         tm = (af1 + al1) * 0.5;
463         
464         if(aPF.Distance(myC.Value(tm)) > myCriteria * 2.) {
465           aCommonPrt.SetType(TopAbs_EDGE);
466           return 0;
467         }
468       }
469       
470       if(!CheckTouch(aCommonPrt, tm)) {
471         tm = (af1 + al1) * 0.5;
472       }
473       aCommonPrt.SetType(TopAbs_VERTEX);
474       aCommonPrt.SetVertexParameter1(tm);
475       aCommonPrt.SetRange1 (af1, al1);
476     }
477   }
478  return 0;
479 }
480
481
482 //=======================================================================
483 //function : CheckTouch 
484 //purpose  : 
485 //=======================================================================
486 Standard_Boolean IntTools_EdgeFace::CheckTouch
487   (const IntTools_CommonPrt& aCP,
488    Standard_Real&            aTx) 
489 {
490   if (myC.GetType() == GeomAbs_Line &&
491       myS.GetType() == GeomAbs_Plane) {
492     return Standard_False;
493   }
494   //
495   Standard_Real aTF, aTL, Tol, U1f, U1l, V1f, V1l, af, al,aDist2, aMinDist2;
496   Standard_Boolean theflag=Standard_False;
497   Standard_Integer aNbExt, iLower;
498
499   aCP.Range1(aTF, aTL);
500
501   //
502   Standard_Real aCR;
503   aCR=myC.Resolution(myCriteria);
504   if((Abs(aTF - myRange.First()) < aCR) &&
505      (Abs(aTL - myRange.Last())  < aCR)) {
506     return theflag; // EDGE 
507   }
508   //
509
510   Tol = Precision::PConfusion();
511
512   const Handle(Geom_Curve)&  Curve   =BRep_Tool::Curve  (myC.Edge(), af, al);
513   const Handle(Geom_Surface)& Surface=BRep_Tool::Surface(myS.Face());
514   //   Surface->Bounds(U1f,U1l,V1f,V1l);
515   U1f = myS.FirstUParameter();
516   U1l = myS.LastUParameter();
517   V1f = myS.FirstVParameter();
518   V1l = myS.LastVParameter();
519   
520   GeomAdaptor_Curve   TheCurve   (Curve,aTF, aTL);
521   GeomAdaptor_Surface TheSurface (Surface, U1f, U1l, V1f, V1l); 
522      
523   Extrema_ExtCS anExtrema (TheCurve, TheSurface, Tol, Tol);
524
525   aDist2 = 1.e100;
526
527   if(anExtrema.IsDone()) {
528     aMinDist2 = aDist2;
529
530     if(!anExtrema.IsParallel()) {
531       aNbExt=anExtrema.NbExt();
532       
533       if(aNbExt > 0) {
534  iLower=1;
535  for (Standard_Integer i=1; i<=aNbExt; i++) {
536    aDist2=anExtrema.SquareDistance(i);
537    if (aDist2 < aMinDist2) {
538      aMinDist2=aDist2;
539      iLower=i;
540    }
541  }
542  aDist2=anExtrema.SquareDistance(iLower);
543  Extrema_POnCurv aPOnC;
544  Extrema_POnSurf aPOnS;
545  anExtrema.Points(iLower, aPOnC, aPOnS);
546  aTx=aPOnC.Parameter();
547       }
548       else {
549  // modified by NIZHNY-MKK  Thu Jul 21 11:35:32 2005.BEGIN
550  IntCurveSurface_HInter anExactIntersector;
551   
552  Handle(GeomAdaptor_HCurve) aCurve     = new GeomAdaptor_HCurve(TheCurve);
553  Handle(GeomAdaptor_HSurface) aSurface = new GeomAdaptor_HSurface(TheSurface);
554  
555  anExactIntersector.Perform(aCurve, aSurface);
556
557  if(anExactIntersector.IsDone()) {
558    for(Standard_Integer i = 1; i <= anExactIntersector.NbPoints(); i++) {
559      const IntCurveSurface_IntersectionPoint& aPoint = anExactIntersector.Point(i);
560       
561      if((aPoint.W() >= aTF) && (aPoint.W() <= aTL)) {
562        aDist2=0.;
563        aTx = aPoint.W();
564      }
565    }
566  }
567  // modified by NIZHNY-MKK  Thu Jul 21 11:35:40 2005.END
568       }
569     }
570     else {
571       return theflag;
572     }
573   }
574
575   Standard_Real aBoundaryDist;
576
577   aBoundaryDist = DistanceFunction(aTF) + myCriteria;
578   if(aBoundaryDist * aBoundaryDist < aDist2) {
579     aDist2 = aBoundaryDist * aBoundaryDist;
580     aTx = aTF;
581   }
582   
583   aBoundaryDist = DistanceFunction(aTL) + myCriteria;
584   if(aBoundaryDist * aBoundaryDist < aDist2) {
585     aDist2 = aBoundaryDist * aBoundaryDist;
586     aTx = aTL;
587   }
588
589   Standard_Real aParameter = (aTF + aTL) * 0.5;
590   aBoundaryDist = DistanceFunction(aParameter) + myCriteria;
591   if(aBoundaryDist * aBoundaryDist < aDist2) {
592     aDist2 = aBoundaryDist * aBoundaryDist;
593     aTx = aParameter;
594   }
595
596   if(aDist2 > myCriteria * myCriteria) {
597     return theflag;
598   }
599   
600   if (fabs (aTx-aTF) < myEpsT) {
601     return !theflag;
602   }
603
604   if (fabs (aTx-aTL) < myEpsT) {
605     return !theflag;
606   }
607
608   if (aTx>aTF && aTx<aTL) {
609     return !theflag;
610   }
611
612   return theflag;
613 }
614
615 //=======================================================================
616 //function : Perform
617 //purpose  : 
618 //=======================================================================
619 void IntTools_EdgeFace::Perform() 
620 {
621   Standard_Integer i, aNb;
622   IntTools_CommonPrt aCommonPrt;
623   //
624   aCommonPrt.SetEdge1(myEdge);
625   //
626   myErrorStatus=0;
627   CheckData();
628   if (myErrorStatus) {
629     return;
630   }
631   //
632   if (myContext.IsNull()) {
633     myContext=new IntTools_Context;
634   }
635   //
636   myIsDone = Standard_False;
637   myC.Initialize(myEdge);
638   GeomAbs_CurveType aCurveType;
639   aCurveType=myC.GetType();
640   //
641   // Prepare myCriteria
642   Standard_Real aFuzz = myFuzzyValue / 2.;
643   Standard_Real aTolF = BRep_Tool::Tolerance(myFace) + aFuzz;
644   Standard_Real aTolE = BRep_Tool::Tolerance(myEdge) + aFuzz;
645   if (aCurveType == GeomAbs_BSplineCurve ||
646       aCurveType==GeomAbs_BezierCurve) {
647     //--- 5112
648     Standard_Real diff1 = (aTolE/aTolF);
649     Standard_Real diff2 = (aTolF/aTolE);
650     if( diff1 > 100 || diff2 > 100 ) {
651       myCriteria = Max(aTolE,aTolF);
652     }
653     else //--- 5112
654       myCriteria = 1.5*aTolE + aTolF;
655   }
656   else {
657     myCriteria = aTolE + aTolF;
658   }
659   
660   myS = myContext->SurfaceAdaptor(myFace);
661   
662   if (myQuickCoincidenceCheck) {
663     if (IsCoincident()) {
664       aCommonPrt.SetType(TopAbs_EDGE);
665       aCommonPrt.SetRange1(myRange.First(), myRange.Last());
666       mySeqOfCommonPrts.Append(aCommonPrt);
667       myIsDone=Standard_True;
668       return;
669     }
670   }
671   //
672   IntTools_BeanFaceIntersector anIntersector(myC, myS, aTolE, aTolF);
673   anIntersector.SetBeanParameters(myRange.First(), myRange.Last());
674   //
675   anIntersector.SetContext(myContext);
676   //
677   anIntersector.Perform();
678   
679   if(!anIntersector.IsDone()) {
680     return;
681   }
682   
683   for(Standard_Integer r = 1; r <= anIntersector.Result().Length(); r++) {
684     const IntTools_Range& aRange = anIntersector.Result().Value(r);
685     
686     if(IsProjectable(IntTools_Tools::IntermediatePoint(aRange.First(), aRange.Last()))) {
687       aCommonPrt.SetRange1(aRange.First(), aRange.Last());
688       mySeqOfCommonPrts.Append(aCommonPrt);
689     }
690   }
691
692   aNb = mySeqOfCommonPrts.Length();
693
694   for (i=1; i<=aNb; i++) {
695     IntTools_CommonPrt& aCP=mySeqOfCommonPrts.ChangeValue(i);
696     //
697     Standard_Real aTx1, aTx2;
698     gp_Pnt aPx1, aPx2;
699     //
700     aCP.Range1(aTx1, aTx2);
701     myC.D0(aTx1, aPx1);
702     myC.D0(aTx2, aPx2);
703     aCP.SetBoundingPoints(aPx1, aPx2);
704     //
705     MakeType (aCP); 
706   }
707   {
708     // Line\Cylinder's Common Parts treatement
709     GeomAbs_CurveType   aCType;
710     GeomAbs_SurfaceType aSType;
711     TopAbs_ShapeEnum aType;
712     Standard_Boolean bIsTouch;
713     Standard_Real aTx;
714     
715     aCType=myC.GetType();
716     aSType=myS.GetType();
717     
718     if (aCType==GeomAbs_Line && aSType==GeomAbs_Cylinder) {
719       for (i=1; i<=aNb; i++) {
720         IntTools_CommonPrt& aCP=mySeqOfCommonPrts(i);
721         aType=aCP.Type();
722         if (aType==TopAbs_EDGE) {
723           bIsTouch=CheckTouch (aCP, aTx);
724           if (bIsTouch) {
725             aCP.SetType(TopAbs_VERTEX);
726             aCP.SetVertexParameter1(aTx);
727             //aCP.SetRange1 (aTx, aTx);
728           }
729         }
730         else if (aType==TopAbs_VERTEX) {
731           bIsTouch=CheckTouchVertex (aCP, aTx);
732           if (bIsTouch) {
733             aCP.SetVertexParameter1(aTx);
734             //aCP.SetRange1 (aTx, aTx);
735           }
736         }
737       }
738     }
739     
740     // Circle\Plane's Common Parts treatement
741     
742     if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
743       Standard_Boolean bIsCoplanar, bIsRadius;
744       bIsCoplanar=IsCoplanar(myC, myS);
745       bIsRadius=IsRadius(myC, myS, myCriteria);
746       if (!bIsCoplanar && !bIsRadius) {
747         for (i=1; i<=aNb; i++) {
748           IntTools_CommonPrt& aCP=mySeqOfCommonPrts(i);
749           aType=aCP.Type();
750           if (aType==TopAbs_EDGE) {
751             bIsTouch=CheckTouch (aCP, aTx);
752             if (bIsTouch) {
753               aCP.SetType(TopAbs_VERTEX);
754               aCP.SetVertexParameter1(aTx);
755               //aCP.SetRange1 (aTx, aTx);
756             }
757           }
758           else if (aType==TopAbs_VERTEX) {
759             bIsTouch=CheckTouchVertex (aCP, aTx);
760             if (bIsTouch) {
761               aCP.SetVertexParameter1(aTx);
762               //aCP.SetRange1 (aTx, aTx);
763             }
764           }
765         }
766       }
767     }
768   }
769   myIsDone=Standard_True;
770 }
771
772 //
773 // myErrorStatus
774 // 1 - the method Perform() is not invoked  
775 // 2,3,4,5 -the method CheckData() fails
776 // 6 - PrepareArgs() problems
777 // 7 - No Projectable ranges
778 // 8,9 - PrepareArgs() problems occured inside  projectable Ranges
779 // 11 - can't fill array  aFunc(i) in PrepareArgsFuncArrays 
780
781
782 //=======================================================================
783 //function : CheckTouch 
784 //purpose  : 
785 //=======================================================================
786 Standard_Boolean IntTools_EdgeFace::CheckTouchVertex 
787   (const IntTools_CommonPrt& aCP,
788    Standard_Real& aTx) 
789 {
790   Standard_Real aTF, aTL, Tol, U1f,U1l,V1f,V1l;
791   Standard_Real aEpsT, af, al,aDist2, aMinDist2, aTm, aDist2New;
792   Standard_Boolean theflag=Standard_False;
793   Standard_Integer aNbExt, i, iLower ;
794   GeomAbs_CurveType aType;
795   //
796   aCP.Range1(aTF, aTL);
797   aType=myC.GetType();
798   //
799   aEpsT=8.e-5;
800   if (aType==GeomAbs_Line) {
801     aEpsT=9.e-5;
802   }
803   //
804   aTm=0.5*(aTF+aTL);
805   aDist2=DistanceFunction(aTm);
806   aDist2 *= aDist2;
807
808   Tol = Precision::PConfusion();
809
810   const Handle(Geom_Curve)&  Curve =BRep_Tool::Curve  (myC.Edge(), af, al);
811   const Handle(Geom_Surface)& Surface=BRep_Tool::Surface(myS.Face());
812
813   Surface->Bounds(U1f,U1l,V1f,V1l);
814   
815   GeomAdaptor_Curve   TheCurve   (Curve,aTF, aTL);
816   GeomAdaptor_Surface TheSurface (Surface, U1f, U1l, V1f, V1l); 
817      
818   Extrema_ExtCS anExtrema (TheCurve, TheSurface, Tol, Tol);
819    
820   if(!anExtrema.IsDone()) {
821     return theflag;
822   }
823   if (anExtrema.IsParallel()) {
824     return theflag;
825   }
826   
827   aNbExt=anExtrema.NbExt() ;
828   if (!aNbExt) {
829      return theflag;
830   }
831
832   iLower=1;
833   aMinDist2=1.e100;
834   for (i=1; i<=aNbExt; ++i) {
835     aDist2=anExtrema.SquareDistance(i);
836     if (aDist2 < aMinDist2) {
837       aMinDist2=aDist2;
838       iLower=i;
839     }
840   }
841
842   aDist2New=anExtrema.SquareDistance(iLower);
843   
844   if (aDist2New > aDist2) {
845     aTx=aTm;
846     return !theflag;
847   }
848   
849   if (aDist2New > myCriteria * myCriteria) {
850     return theflag;
851   }
852
853   Extrema_POnCurv aPOnC;
854   Extrema_POnSurf aPOnS;
855   anExtrema.Points(iLower, aPOnC, aPOnS);
856
857  
858   aTx=aPOnC.Parameter();
859   ///
860   if (fabs (aTx-aTF) < aEpsT) {
861     return theflag;
862   }
863
864   if (fabs (aTx-aTL) < aEpsT) {
865     return theflag;
866   }
867
868   if (aTx>aTF && aTx<aTL) {
869     return !theflag;
870   }
871
872   return theflag;
873 }
874
875
876 //=======================================================================
877 //function :  IsCoplanar
878 //purpose  : 
879 //=======================================================================
880 Standard_Boolean IsCoplanar (const BRepAdaptor_Curve& aCurve ,
881                              const BRepAdaptor_Surface& aSurface)
882 {
883   Standard_Boolean bFlag=Standard_False;
884
885   GeomAbs_CurveType   aCType;
886   GeomAbs_SurfaceType aSType;
887
888   aCType=aCurve.GetType();
889   aSType=aSurface.GetType();
890     
891   if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
892     gp_Circ aCirc=aCurve.Circle();
893     const gp_Ax1& anAx1=aCirc.Axis();
894     const gp_Dir& aDirAx1=anAx1.Direction();
895     
896     gp_Pln aPln=aSurface.Plane();
897     const gp_Ax1& anAx=aPln.Axis();
898     const gp_Dir& aDirPln=anAx.Direction();
899
900     bFlag=IntTools_Tools::IsDirsCoinside(aDirAx1, aDirPln);
901   }
902   return bFlag;
903 }
904 //=======================================================================
905 //function :  IsRadius
906 //purpose  : 
907 //=======================================================================
908 Standard_Boolean IsRadius (const BRepAdaptor_Curve& aCurve,
909                            const BRepAdaptor_Surface& aSurface,
910                            const Standard_Real aCriteria)
911 {
912   Standard_Boolean bFlag=Standard_False;
913
914   GeomAbs_CurveType   aCType;
915   GeomAbs_SurfaceType aSType;
916
917   aCType=aCurve.GetType();
918   aSType=aSurface.GetType();
919     
920   if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
921     gp_Circ aCirc=aCurve.Circle();
922     const gp_Pnt aCenter=aCirc.Location();
923     Standard_Real aR=aCirc.Radius();
924     gp_Pln aPln=aSurface.Plane();
925     Standard_Real aD=aPln.Distance(aCenter);
926     if (fabs (aD-aR) < aCriteria) {
927       return !bFlag;
928     }
929   }
930   return bFlag;
931 }
932 //
933 //=======================================================================
934 //function :  AdaptiveDiscret
935 //purpose  : 
936 //=======================================================================
937 Standard_Integer AdaptiveDiscret (const Standard_Integer iDiscret,
938                                   const BRepAdaptor_Curve& aCurve ,
939                                   const BRepAdaptor_Surface& aSurface)
940 {
941   Standard_Integer iDiscretNew;
942
943   iDiscretNew=iDiscret;
944
945   GeomAbs_SurfaceType aSType;
946
947   aSType=aSurface.GetType();
948     
949   if (aSType==GeomAbs_Cylinder) {
950    Standard_Real aELength, aRadius, dLR;
951
952    aELength=IntTools::Length(aCurve.Edge());
953    
954    gp_Cylinder aCylinder=aSurface.Cylinder();
955    aRadius=aCylinder.Radius();
956    dLR=2*aRadius;
957
958    iDiscretNew=(Standard_Integer)(aELength/dLR);
959    
960    if (iDiscretNew<iDiscret) {
961      iDiscretNew=iDiscret;
962    }
963      
964   }
965   return iDiscretNew;
966 }