Commit | Line | Data |
---|---|---|
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 | 56 | static |
57 | Standard_Boolean IsCoplanar (const BRepAdaptor_Curve& , | |
bd28b2af | 58 | const BRepAdaptor_Surface& ); |
7fd59977 | 59 | static |
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 | //======================================================================= | |
79 | Standard_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 | 161 | void 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 | 175 | Standard_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 | 190 | Standard_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 | 235 | Standard_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 | 295 | Standard_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 | 351 | Standard_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 | 479 | void 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 | 636 | Standard_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 | //======================================================================= | |
730 | Standard_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 | 758 | Standard_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 | //======================================================================= | |
787 | Standard_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 | } |