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