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 | |
16 | #include <IntTools_EdgeFace.ixx> | |
17 | ||
18 | ||
19 | ||
20 | #include <IntTools_CArray1OfReal.hxx> | |
21 | #include <IntTools.hxx> | |
22 | #include <IntTools_CArray1OfInteger.hxx> | |
23 | #include <IntTools_Range.hxx> | |
24 | #include <IntTools_Tools.hxx> | |
25 | #include <IntTools_Array1OfRange.hxx> | |
7fd59977 | 26 | #include <IntTools_CommonPrt.hxx> |
27 | #include <IntTools_Root.hxx> | |
28 | #include <IntTools_BeanFaceIntersector.hxx> | |
1e143abb | 29 | #include <IntTools_Context.hxx> |
7fd59977 | 30 | |
31 | #include <BRep_Tool.hxx> | |
32 | ||
33 | #include <GeomAdaptor_Surface.hxx> | |
34 | #include <GeomAdaptor_Curve.hxx> | |
35 | ||
36 | #include <Geom_Surface.hxx> | |
37 | #include <Geom_Curve.hxx> | |
38 | ||
39 | #include <GeomAPI_ProjectPointOnSurf.hxx> | |
40 | ||
41 | #include <Precision.hxx> | |
42 | ||
43 | #include <Bnd_Box.hxx> | |
44 | #include <BndLib_AddSurface.hxx> | |
45 | ||
46 | #include <gp_Cylinder.hxx> | |
47 | #include <gp_Ax1.hxx> | |
48 | #include <gp_Lin.hxx> | |
49 | #include <gp_Cone.hxx> | |
50 | #include <gp_Torus.hxx> | |
51 | #include <gp_Circ.hxx> | |
52 | #include <gp_Pln.hxx> | |
53 | ||
54 | ||
55 | #include <Extrema_ExtCS.hxx> | |
56 | #include <Extrema_POnCurv.hxx> | |
57 | #include <Extrema_POnSurf.hxx> | |
58 | ||
e30616a7 | 59 | |
7fd59977 | 60 | #include <IntCurveSurface_HInter.hxx> |
61 | #include <GeomAdaptor_HCurve.hxx> | |
62 | #include <GeomAdaptor_HSurface.hxx> | |
63 | #include <IntCurveSurface_IntersectionPoint.hxx> | |
64 | ||
e35db416 | 65 | #include <algorithm> |
7fd59977 | 66 | |
67 | static | |
68 | Standard_Boolean IsCoplanar (const BRepAdaptor_Curve& , | |
bd28b2af | 69 | const BRepAdaptor_Surface& ); |
7fd59977 | 70 | static |
71 | Standard_Boolean IsRadius (const BRepAdaptor_Curve& aCurve , | |
bd28b2af | 72 | const BRepAdaptor_Surface& aSurface, |
73 | const Standard_Real aCriteria); | |
7fd59977 | 74 | static |
75 | Standard_Integer AdaptiveDiscret (const Standard_Integer iDiscret, | |
bd28b2af | 76 | const BRepAdaptor_Curve& aCurve , |
77 | const BRepAdaptor_Surface& aSurface); | |
7fd59977 | 78 | |
79 | //======================================================================= | |
80 | //function : IntTools_EdgeFace::IntTools_EdgeFace | |
81 | //purpose : | |
82 | //======================================================================= | |
83 | IntTools_EdgeFace::IntTools_EdgeFace() | |
84 | { | |
85 | myTolE=1.e-7; | |
86 | myTolF=1.e-7; | |
87 | myDiscret=30; | |
88 | myEpsT =1e-12; | |
89 | myEpsNull=1e-12; | |
90 | myDeflection=0.01; | |
91 | myIsDone=Standard_False; | |
92 | myErrorStatus=1; | |
93 | myParallel=Standard_False; | |
94 | myPar1=0.; | |
4f189102 P |
95 | } |
96 | //======================================================================= | |
97 | //function : SetContext | |
98 | //purpose : | |
99 | //======================================================================= | |
1e143abb | 100 | void IntTools_EdgeFace::SetContext(const Handle(IntTools_Context)& theContext) |
4f189102 P |
101 | { |
102 | myContext = theContext; | |
7fd59977 | 103 | } |
104 | ||
4f189102 P |
105 | //======================================================================= |
106 | //function : Context | |
107 | //purpose : | |
108 | //======================================================================= | |
1e143abb | 109 | const Handle(IntTools_Context)& IntTools_EdgeFace::Context()const |
4f189102 P |
110 | { |
111 | return myContext; | |
112 | } | |
7fd59977 | 113 | //======================================================================= |
114 | //function : SetEdge | |
115 | //purpose : | |
116 | //======================================================================= | |
e30616a7 | 117 | void IntTools_EdgeFace::SetEdge(const TopoDS_Edge& anEdge) |
7fd59977 | 118 | { |
119 | myEdge=anEdge; | |
120 | } | |
7fd59977 | 121 | //======================================================================= |
122 | //function : SetFace | |
123 | //purpose : | |
124 | //======================================================================= | |
e30616a7 | 125 | void IntTools_EdgeFace::SetFace(const TopoDS_Face& aFace) |
7fd59977 | 126 | { |
127 | myFace=aFace; | |
128 | } | |
7fd59977 | 129 | //======================================================================= |
130 | //function : SetTolE | |
131 | //purpose : | |
132 | //======================================================================= | |
e30616a7 | 133 | void IntTools_EdgeFace::SetTolE(const Standard_Real aTol) |
7fd59977 | 134 | { |
135 | myTolE=aTol; | |
136 | } | |
137 | //======================================================================= | |
138 | //function : SetTolF | |
139 | //purpose : | |
140 | //======================================================================= | |
e30616a7 | 141 | void IntTools_EdgeFace::SetTolF(const Standard_Real aTol) |
7fd59977 | 142 | { |
143 | myTolF=aTol; | |
144 | } | |
e30616a7 | 145 | //======================================================================= |
146 | //function : Edge | |
147 | //purpose : | |
148 | //======================================================================= | |
149 | const TopoDS_Edge& IntTools_EdgeFace::Edge()const | |
150 | { | |
151 | return myEdge; | |
152 | } | |
153 | //======================================================================= | |
154 | //function : Face | |
155 | //purpose : | |
156 | //======================================================================= | |
157 | const TopoDS_Face& IntTools_EdgeFace::Face()const | |
158 | { | |
159 | return myFace; | |
160 | } | |
161 | //======================================================================= | |
162 | //function : TolE | |
163 | //purpose : | |
164 | //======================================================================= | |
165 | Standard_Real IntTools_EdgeFace::TolE()const | |
166 | { | |
167 | return myTolE; | |
168 | } | |
169 | //======================================================================= | |
170 | //function : TolF | |
171 | //purpose : | |
172 | //======================================================================= | |
173 | Standard_Real IntTools_EdgeFace::TolF()const | |
174 | { | |
175 | return myTolF; | |
176 | } | |
7fd59977 | 177 | //======================================================================= |
178 | //function : SetDiscretize | |
179 | //purpose : | |
180 | //======================================================================= | |
e30616a7 | 181 | void IntTools_EdgeFace::SetDiscretize(const Standard_Integer aDiscret) |
7fd59977 | 182 | { |
183 | myDiscret=aDiscret; | |
184 | } | |
185 | //======================================================================= | |
186 | //function : SetDeflection | |
187 | //purpose : | |
188 | //======================================================================= | |
e30616a7 | 189 | void IntTools_EdgeFace::SetDeflection(const Standard_Real aDefl) |
7fd59977 | 190 | { |
191 | myDeflection=aDefl; | |
192 | } | |
193 | //======================================================================= | |
194 | //function : SetEpsilonT | |
195 | //purpose : | |
196 | //======================================================================= | |
e30616a7 | 197 | void IntTools_EdgeFace::SetEpsilonT(const Standard_Real anEpsT) |
7fd59977 | 198 | { |
199 | myEpsT=anEpsT; | |
200 | } | |
201 | //======================================================================= | |
202 | //function : SetEpsilonNull | |
203 | //purpose : | |
204 | //======================================================================= | |
e30616a7 | 205 | void IntTools_EdgeFace::SetEpsilonNull(const Standard_Real anEpsNull) |
7fd59977 | 206 | { |
207 | myEpsNull=anEpsNull; | |
208 | } | |
209 | ||
210 | //======================================================================= | |
211 | //function : SetRange | |
212 | //purpose : | |
213 | //======================================================================= | |
e30616a7 | 214 | void IntTools_EdgeFace::SetRange(const Standard_Real aFirst, |
215 | const Standard_Real aLast) | |
7fd59977 | 216 | { |
217 | myRange.SetFirst (aFirst); | |
218 | myRange.SetLast (aLast); | |
219 | } | |
220 | ||
221 | //======================================================================= | |
222 | //function : SetRange | |
223 | //purpose : | |
224 | //======================================================================= | |
e30616a7 | 225 | void IntTools_EdgeFace::SetRange(const IntTools_Range& aRange) |
7fd59977 | 226 | { |
227 | myRange.SetFirst (aRange.First()); | |
228 | myRange.SetLast (aRange.Last()); | |
229 | } | |
230 | //======================================================================= | |
231 | //function : IsDone | |
232 | //purpose : | |
233 | //======================================================================= | |
4f189102 | 234 | Standard_Boolean IntTools_EdgeFace::IsDone()const |
7fd59977 | 235 | { |
236 | return myIsDone; | |
237 | } | |
238 | //======================================================================= | |
239 | //function : ErrorStatus | |
240 | //purpose : | |
241 | //======================================================================= | |
4f189102 | 242 | Standard_Integer IntTools_EdgeFace::ErrorStatus()const |
7fd59977 | 243 | { |
244 | return myErrorStatus; | |
245 | } | |
246 | //======================================================================= | |
247 | //function : CommonParts | |
248 | //purpose : | |
249 | //======================================================================= | |
4f189102 | 250 | const IntTools_SequenceOfCommonPrts& IntTools_EdgeFace::CommonParts() const |
7fd59977 | 251 | { |
252 | return mySeqOfCommonPrts; | |
253 | } | |
254 | //======================================================================= | |
255 | //function : Range | |
256 | //purpose : | |
257 | //======================================================================= | |
4f189102 | 258 | const IntTools_Range& IntTools_EdgeFace::Range() const |
7fd59977 | 259 | { |
260 | return myRange; | |
261 | } | |
262 | ||
263 | //======================================================================= | |
264 | //function : CheckData | |
265 | //purpose : | |
266 | //======================================================================= | |
4f189102 | 267 | void IntTools_EdgeFace::CheckData() |
7fd59977 | 268 | { |
269 | if (BRep_Tool::Degenerated(myEdge)) { | |
270 | myErrorStatus=2; | |
271 | } | |
272 | if (!BRep_Tool::IsGeometric(myEdge)) { | |
273 | myErrorStatus=3; | |
274 | } | |
275 | } | |
7fd59977 | 276 | //======================================================================= |
277 | //function : Prepare | |
278 | //purpose : | |
279 | //======================================================================= | |
e30616a7 | 280 | void IntTools_EdgeFace::Prepare() |
7fd59977 | 281 | { |
282 | Standard_Integer pri; | |
283 | IntTools_CArray1OfReal aPars; | |
284 | ||
285 | // | |
286 | // 1.Prepare Curve's data and Surface's data | |
287 | myC.Initialize(myEdge); | |
288 | GeomAbs_CurveType aCurveType; | |
289 | aCurveType=myC.GetType(); | |
290 | // | |
291 | // 2.Prepare myCriteria | |
292 | if (aCurveType==GeomAbs_BSplineCurve|| | |
e30616a7 | 293 | aCurveType==GeomAbs_BezierCurve) { |
7fd59977 | 294 | myCriteria=1.5*myTolE+myTolF; |
295 | } | |
296 | else { | |
297 | myCriteria=myTolE+myTolF; | |
298 | } | |
299 | // 2.a myTmin, myTmax | |
300 | myTmin=myRange.First(); | |
301 | myTmax=myRange.Last(); | |
302 | // 2.b myFClass2d | |
303 | myS.Initialize (myFace,Standard_True); | |
304 | myFClass2d.Init(myFace, 1.e-6); | |
305 | // | |
306 | // 2.c Prepare adaptive myDiscret | |
307 | myDiscret=AdaptiveDiscret(myDiscret, myC, myS); | |
308 | // | |
309 | // | |
310 | // 3.Prepare myPars | |
e30616a7 | 311 | pri = IntTools::PrepareArgs(myC, myTmax, myTmin, |
312 | myDiscret, myDeflection, aPars); | |
7fd59977 | 313 | if (pri) { |
314 | myErrorStatus=6; | |
315 | return; | |
316 | } | |
317 | // 4. | |
318 | //ProjectableRanges | |
319 | Standard_Integer i, iProj, aNb, aNbProj, ind0, ind1; | |
320 | Standard_Real t0, t1, tRoot; | |
321 | ||
322 | // | |
323 | // Table of Projection's function values | |
324 | aNb=aPars.Length(); | |
325 | IntTools_CArray1OfInteger anArrProjectability; | |
326 | anArrProjectability.Resize(aNb); | |
327 | ||
328 | for (iProj=0, i=0; i<aNb; i++) { | |
329 | t0=aPars(i); | |
330 | aNbProj=IsProjectable (t0); | |
331 | ||
332 | anArrProjectability(i)=0; | |
333 | if (aNbProj) { | |
334 | anArrProjectability(i)=1; | |
335 | iProj++; | |
336 | } | |
337 | } | |
338 | // | |
339 | // Checking | |
340 | if (!iProj ) { | |
341 | myErrorStatus=7; | |
342 | return; | |
343 | } | |
344 | ||
345 | // | |
346 | // Projectable Ranges | |
347 | IntTools_Range aRange; | |
348 | ||
349 | ind0=anArrProjectability(0); | |
350 | if (ind0) { | |
351 | t0=aPars(0); | |
352 | aRange.SetFirst(t0); | |
353 | } | |
354 | ||
355 | for(i=1; i<aNb; i++) { | |
356 | ind1=anArrProjectability(i); | |
357 | t0=aPars(i-1); | |
358 | t1=aPars(i); | |
359 | ||
360 | if (i==(aNb-1)) { | |
361 | if (ind1 && ind0) { | |
e30616a7 | 362 | aRange.SetLast(t1); |
363 | myProjectableRanges.Append(aRange); | |
7fd59977 | 364 | } |
365 | if (ind1 && !ind0) { | |
e30616a7 | 366 | FindProjectableRoot(t0, t1, ind0, ind1, tRoot); |
367 | aRange.SetFirst(tRoot); | |
368 | aRange.SetLast(t1); | |
369 | myProjectableRanges.Append(aRange); | |
7fd59977 | 370 | } |
371 | // | |
372 | if (ind0 && !ind1) { | |
e30616a7 | 373 | FindProjectableRoot(t0, t1, ind0, ind1, tRoot); |
374 | aRange.SetLast(tRoot); | |
375 | myProjectableRanges.Append(aRange); | |
7fd59977 | 376 | } |
377 | // | |
378 | break; | |
379 | } | |
380 | ||
381 | if (ind0 != ind1) { | |
382 | FindProjectableRoot(t0, t1, ind0, ind1, tRoot); | |
383 | ||
384 | if (ind0 && !ind1) { | |
e30616a7 | 385 | aRange.SetLast(tRoot); |
386 | myProjectableRanges.Append(aRange); | |
7fd59977 | 387 | } |
388 | else { | |
e30616a7 | 389 | aRange.SetFirst(tRoot); |
7fd59977 | 390 | } |
391 | } // if (ind0 != ind1) | |
392 | ind0=ind1; | |
393 | } // for(i=1; i<aNb; i++) { | |
394 | } | |
395 | ||
396 | //======================================================================= | |
397 | //function : FindProjectableRoot | |
398 | //purpose : | |
399 | //======================================================================= | |
55468283 | 400 | void IntTools_EdgeFace::FindProjectableRoot (const Standard_Real tt1, |
401 | const Standard_Real tt2, | |
402 | const Standard_Integer ff1, | |
403 | const Standard_Integer /*ff2*/, | |
404 | Standard_Real& tRoot) | |
7fd59977 | 405 | { |
406 | Standard_Real tm, t1, t2, aEpsT; | |
55468283 | 407 | Standard_Integer anIsProj1, anIsProjm; |
408 | aEpsT = 0.5 * myEpsT; | |
409 | ||
7fd59977 | 410 | // Root is inside [tt1, tt2] |
55468283 | 411 | t1 = tt1; |
412 | t2 = tt2; | |
413 | anIsProj1 = ff1; | |
414 | ||
415 | for(;;) | |
416 | { | |
417 | if (fabs(t1 - t2) < aEpsT) | |
418 | { | |
419 | tRoot = (anIsProj1) ? t1 : t2; | |
7fd59977 | 420 | return; |
421 | } | |
55468283 | 422 | tm = 0.5 * (t1 + t2); |
423 | anIsProjm = IsProjectable(tm); | |
424 | ||
425 | if (anIsProjm != anIsProj1) | |
426 | { | |
427 | t2 = tm; | |
7fd59977 | 428 | } |
55468283 | 429 | else |
430 | { | |
431 | t1 = tm; | |
432 | anIsProj1 = anIsProjm; | |
7fd59977 | 433 | } |
55468283 | 434 | } // for(;;) |
7fd59977 | 435 | } |
436 | //======================================================================= | |
437 | //function : IsProjectable | |
438 | //purpose : | |
439 | //======================================================================= | |
e30616a7 | 440 | Standard_Boolean IntTools_EdgeFace::IsProjectable |
441 | (const Standard_Real aT) const | |
7fd59977 | 442 | { |
66993778 | 443 | Standard_Boolean bFlag; |
444 | gp_Pnt aPC; | |
7fd59977 | 445 | // |
66993778 | 446 | myC.D0(aT, aPC); |
447 | bFlag=myContext->IsValidPointForFace(aPC, myFace, myCriteria); | |
7fd59977 | 448 | // |
7fd59977 | 449 | return bFlag; |
450 | } | |
7fd59977 | 451 | //======================================================================= |
452 | //function : DistanceFunction | |
453 | //purpose : | |
454 | //======================================================================= | |
e30616a7 | 455 | Standard_Real IntTools_EdgeFace::DistanceFunction |
456 | (const Standard_Real t) | |
7fd59977 | 457 | { |
96a95605 DB |
458 | Standard_Real aD; |
459 | ||
7fd59977 | 460 | // |
461 | gp_Pnt P; | |
462 | myC.D0(t, P); | |
463 | // | |
464 | Standard_Boolean bIsEqDistance; | |
465 | ||
466 | bIsEqDistance= IntTools_EdgeFace::IsEqDistance(P, myS, 1.e-7, aD); | |
467 | if (bIsEqDistance) { | |
468 | aD=aD-myCriteria; | |
469 | return aD; | |
470 | } | |
7fd59977 | 471 | |
7fd59977 | 472 | // |
473 | Standard_Boolean bFlag = Standard_False; | |
474 | ||
4f189102 P |
475 | GeomAPI_ProjectPointOnSurf& aLocProj = myContext->ProjPS(myFace); |
476 | aLocProj.Perform(P); | |
477 | bFlag = aLocProj.IsDone(); | |
478 | ||
479 | if(bFlag) { | |
480 | aD = aLocProj.LowerDistance(); | |
7fd59977 | 481 | } |
482 | // | |
483 | ||
484 | if (!bFlag) { | |
485 | myErrorStatus=11; | |
486 | return 99.; | |
487 | } | |
488 | ||
489 | // | |
490 | // aD=aProjector.LowerDistance(); | |
491 | // | |
492 | aD=aD-myCriteria; | |
493 | return aD; | |
494 | } | |
495 | // | |
496 | //======================================================================= | |
497 | //function : IsEqDistance | |
498 | //purpose : | |
499 | //======================================================================= | |
e30616a7 | 500 | Standard_Boolean IntTools_EdgeFace::IsEqDistance |
501 | (const gp_Pnt& aP, | |
502 | const BRepAdaptor_Surface& aBAS, | |
503 | const Standard_Real aTol, | |
504 | Standard_Real& aD) | |
7fd59977 | 505 | { |
506 | Standard_Boolean bRetFlag=Standard_True; | |
507 | ||
508 | GeomAbs_SurfaceType aSurfType=aBAS.GetType(); | |
509 | ||
510 | if (aSurfType==GeomAbs_Cylinder) { | |
511 | gp_Cylinder aCyl=aBAS.Cylinder(); | |
512 | const gp_Ax1& anAx1 =aCyl.Axis(); | |
513 | gp_Lin aLinAxis(anAx1); | |
514 | Standard_Real aDC, aRadius=aCyl.Radius(); | |
515 | aDC=aLinAxis.Distance(aP); | |
516 | if (aDC < aTol) { | |
517 | aD=aRadius; | |
518 | return bRetFlag; | |
519 | } | |
520 | } | |
521 | ||
522 | if (aSurfType==GeomAbs_Cone) { | |
523 | gp_Cone aCone=aBAS.Cone(); | |
524 | const gp_Ax1& anAx1 =aCone.Axis(); | |
525 | gp_Lin aLinAxis(anAx1); | |
526 | Standard_Real aDC, aRadius, aDS, aSemiAngle; | |
527 | aDC=aLinAxis.Distance(aP); | |
528 | if (aDC < aTol) { | |
529 | gp_Pnt anApex=aCone.Apex(); | |
530 | aSemiAngle=aCone.SemiAngle(); | |
531 | aDS=aP.Distance(anApex); | |
532 | ||
533 | aRadius=aDS*tan(aSemiAngle); | |
534 | aD=aRadius; | |
535 | return bRetFlag; | |
536 | } | |
537 | } | |
538 | ||
539 | if (aSurfType==GeomAbs_Torus) { | |
540 | Standard_Real aMajorRadius, aMinorRadius, aDC; | |
541 | ||
542 | gp_Torus aTorus=aBAS.Torus(); | |
543 | gp_Pnt aPLoc=aTorus.Location(); | |
544 | aMajorRadius=aTorus.MajorRadius(); | |
545 | ||
546 | aDC=fabs(aPLoc.Distance(aP)-aMajorRadius); | |
547 | if (aDC < aTol) { | |
548 | aMinorRadius=aTorus.MinorRadius(); | |
549 | aD=aMinorRadius; | |
550 | return bRetFlag; | |
551 | } | |
552 | } | |
553 | return !bRetFlag; | |
554 | } | |
555 | // | |
556 | //======================================================================= | |
557 | //function : PrepareArgsFuncArrays | |
558 | //purpose : Obtain | |
559 | // myFuncArray and myArgsArray for the interval [ta, tb] | |
e30616a7 | 560 | //======================================================================= |
561 | void IntTools_EdgeFace::PrepareArgsFuncArrays(const Standard_Real ta, | |
562 | const Standard_Real tb) | |
7fd59977 | 563 | { |
564 | IntTools_CArray1OfReal anArgs, aFunc; | |
565 | Standard_Integer i, aNb, pri; | |
566 | Standard_Real t, f, f1; | |
567 | // | |
568 | // Prepare values of arguments for the interval [ta, tb] | |
569 | pri=IntTools::PrepareArgs (myC, tb, ta, myDiscret, myDeflection, anArgs); | |
570 | ||
571 | if (pri) { | |
572 | myErrorStatus=8; | |
573 | return; | |
574 | } | |
575 | //... | |
576 | aNb=anArgs.Length(); | |
577 | ||
578 | if (!aNb){ | |
579 | myErrorStatus=9; | |
580 | return; | |
581 | } | |
582 | // | |
583 | // Prepare values of functions for the interval [ta, tb] | |
584 | aFunc.Resize(aNb); | |
585 | for (i=0; i<aNb; i++) { | |
586 | t=anArgs(i); | |
587 | f1=DistanceFunction(t); | |
588 | f=f1+myCriteria; | |
589 | ||
590 | if (myErrorStatus==11) | |
591 | return; | |
592 | ||
593 | if (f1 < myEpsNull) { | |
594 | f=0.; | |
595 | } | |
596 | aFunc(i)=f; | |
597 | } | |
598 | // | |
599 | // Add points where the derivative = 0 | |
600 | AddDerivativePoints(anArgs, aFunc); | |
601 | ||
602 | } | |
e35db416 | 603 | |
604 | //======================================================================= | |
605 | ||
606 | namespace { | |
607 | // Auxiliary: comparator function for sorting ranges | |
608 | bool IntTools_RangeComparator (const IntTools_Range& theLeft, const IntTools_Range& theRight) | |
609 | { | |
610 | return theLeft.First() < theRight.First(); | |
611 | } | |
612 | } | |
613 | ||
7fd59977 | 614 | //======================================================================= |
615 | //function : AddDerivativePoints | |
616 | //purpose : | |
617 | //======================================================================= | |
e30616a7 | 618 | void IntTools_EdgeFace::AddDerivativePoints |
619 | (const IntTools_CArray1OfReal& t, | |
620 | const IntTools_CArray1OfReal& f) | |
7fd59977 | 621 | { |
622 | Standard_Integer i, j, n, k, nn=100; | |
623 | Standard_Real fr, tr, tr1, dEpsNull=10.*myEpsNull; | |
624 | IntTools_CArray1OfReal fd; | |
625 | TColStd_SequenceOfReal aTSeq, aFSeq; | |
626 | ||
627 | n=t.Length(); | |
628 | fd.Resize(n+1); | |
629 | // | |
630 | // Table of derivatives | |
631 | Standard_Real dfx, tx, tx1, fx, fx1, dt=1.e-6; | |
632 | // Left limit | |
633 | tx=t(0); | |
634 | tx1=tx+dt; | |
635 | fx=f(0); | |
636 | fx1=DistanceFunction(tx1); | |
637 | fx1=fx1+myCriteria; | |
638 | if (fx1 < myEpsNull) { | |
639 | fx1=0.; | |
640 | } | |
641 | dfx=(fx1-fx)/dt; | |
642 | fd(0)=dfx; | |
643 | ||
644 | if (fabs(fd(0)) < dEpsNull){ | |
645 | fd(0)=0.; | |
646 | } | |
647 | ||
648 | ||
649 | k=n-1; | |
650 | for (i=1; i<k; i++) { | |
7fd59977 | 651 | fd(i)=.5*(f(i+1)-f(i-1))/(t(i)-t(i-1)); |
652 | if (fabs(fd(i)) < dEpsNull){ | |
653 | fd(i)=0.; | |
654 | } | |
655 | } | |
656 | // Right limit | |
657 | tx=t(n-1); | |
658 | tx1=tx-dt; | |
659 | fx=f(n-1); | |
660 | fx1=DistanceFunction(tx1); | |
661 | fx1=fx1+myCriteria; | |
662 | if (fx1 < myEpsNull) { | |
663 | fx1=0.; | |
664 | } | |
665 | dfx=(fx-fx1)/dt; | |
666 | fd(n-1)=dfx; | |
667 | ||
668 | if (fabs(fd(n-1)) < dEpsNull){ | |
669 | fd(n-1)=0.; | |
670 | } | |
671 | // | |
672 | // Finding the range where the derivatives have different signs | |
673 | // for neighbouring points | |
674 | for (i=1; i<n; i++) { | |
675 | Standard_Real fd1, fd2, t1, t2; | |
676 | t1 =t(i-1); | |
677 | t2 =t(i); | |
678 | fd1=fd(i-1); | |
679 | fd2=fd(i); | |
680 | ||
681 | if (fd1*fd2 < 0.) { | |
682 | if (fabs(fd1) < myEpsNull) { | |
e30616a7 | 683 | tr=t1; |
684 | fr=DistanceFunction(tr);//fd1; | |
7fd59977 | 685 | } |
686 | else if (fabs(fd2) < myEpsNull) { | |
e30616a7 | 687 | tr=t2; |
688 | fr=DistanceFunction(tr); | |
7fd59977 | 689 | } |
690 | else { | |
e30616a7 | 691 | tr=FindSimpleRoot(2, t1, t2, fd1); |
692 | fr=DistanceFunction(tr); | |
7fd59977 | 693 | } |
694 | ||
695 | aTSeq.Append(tr); | |
696 | aFSeq.Append(fr); | |
697 | } | |
698 | } // end of for (i=1; i<n; i++) | |
699 | // | |
700 | // remove identical t, f | |
701 | nn=aTSeq.Length(); | |
702 | if (nn) { | |
703 | for (i=1; i<=aTSeq.Length(); i++) { | |
704 | tr=aTSeq(i); | |
705 | for (j=0; j<n; j++) { | |
e30616a7 | 706 | tr1=t(j); |
707 | if (fabs (tr1-tr) < myEpsT) { | |
708 | aTSeq.Remove(i); | |
709 | aFSeq.Remove(i); | |
710 | } | |
7fd59977 | 711 | } |
712 | } | |
713 | nn=aTSeq.Length(); | |
714 | } | |
715 | // | |
716 | // sorting args and funcs in increasing order | |
717 | if (nn) { | |
718 | k=nn+n; | |
719 | IntTools_Array1OfRange anArray1OfRange(1, k); | |
720 | for (i=1; i<=n; i++) { | |
721 | anArray1OfRange(i).SetFirst(t(i-1)); | |
722 | anArray1OfRange(i).SetLast (f(i-1)); | |
723 | } | |
724 | for (i=1; i<=nn; i++) { | |
725 | anArray1OfRange(n+i).SetFirst(aTSeq(i)); | |
726 | anArray1OfRange(n+i).SetLast (aFSeq(i)); | |
727 | } | |
728 | ||
e35db416 | 729 | std::sort (anArray1OfRange.begin(), anArray1OfRange.end(), IntTools_RangeComparator); |
7fd59977 | 730 | |
731 | // filling the output arrays | |
732 | myArgsArray.Resize(k); | |
733 | myFuncArray.Resize(k); | |
734 | for (i=1; i<=k; i++) { | |
735 | myArgsArray(i-1)=anArray1OfRange(i).First(); | |
736 | myFuncArray(i-1)=anArray1OfRange(i).Last (); | |
737 | } | |
738 | } | |
739 | ||
740 | else { // nn=0 | |
741 | myArgsArray.Resize(n); | |
742 | myFuncArray.Resize(n); | |
743 | for (i=0; i<n; i++) { | |
744 | myArgsArray(i)=t(i); | |
745 | myFuncArray(i)=f(i); | |
746 | } | |
747 | } | |
748 | } | |
749 | ||
750 | //======================================================================= | |
751 | //function : DerivativeFunction | |
752 | //purpose : | |
753 | //======================================================================= | |
e30616a7 | 754 | Standard_Real IntTools_EdgeFace::DerivativeFunction |
755 | (const Standard_Real t2) | |
7fd59977 | 756 | { |
757 | Standard_Real t1, t3, aD1, aD2, aD3; | |
758 | Standard_Real dt=1.e-9; | |
759 | t1=t2-dt; | |
760 | aD1=DistanceFunction(t1); | |
761 | t3=t2+dt; | |
762 | aD3=DistanceFunction(t3); | |
763 | ||
764 | aD2=.5*(aD3-aD1)/dt; | |
765 | return aD2; | |
766 | } | |
767 | ||
768 | //======================================================================= | |
769 | //function : FindSimpleRoot | |
770 | //purpose : [private] | |
771 | //======================================================================= | |
e30616a7 | 772 | Standard_Real IntTools_EdgeFace::FindSimpleRoot |
773 | (const Standard_Integer IP, | |
774 | const Standard_Real tA, | |
775 | const Standard_Real tB, | |
776 | const Standard_Real fA) | |
7fd59977 | 777 | { |
778 | Standard_Real r, a, b, y, x0, s; | |
779 | ||
780 | a=tA; b=tB; r=fA; | |
781 | ||
302f96fb | 782 | for(;;) { |
7fd59977 | 783 | x0=.5*(a+b); |
784 | ||
785 | if (IP==1) | |
786 | y=DistanceFunction(x0); | |
787 | else | |
788 | y=DerivativeFunction(x0); | |
789 | ||
790 | if (fabs(b-a) < myEpsT || y==0.) { | |
791 | return x0; | |
792 | } | |
793 | ||
794 | ||
795 | s=y*r; | |
796 | ||
797 | if (s<0.) { | |
798 | b=x0; | |
799 | continue; | |
800 | } | |
801 | ||
802 | if (s>0.) { | |
803 | a=x0; r=y; | |
804 | } | |
805 | } | |
806 | } | |
807 | //======================================================================= | |
808 | //function : FindGoldRoot | |
809 | //purpose : [private] | |
810 | //======================================================================= | |
e30616a7 | 811 | Standard_Real IntTools_EdgeFace::FindGoldRoot |
812 | (const Standard_Real tA, | |
813 | const Standard_Real tB, | |
814 | const Standard_Real coeff) | |
7fd59977 | 815 | { |
816 | Standard_Real gs=0.61803399; | |
817 | Standard_Real a, b, xp, xl, yp, yl; | |
818 | ||
819 | a=tA; b=tB; | |
820 | ||
821 | xp=a+(b-a)*gs; | |
822 | xl=b-(b-a)*gs; | |
823 | yp=coeff*DistanceFunction(xp); | |
824 | yl=coeff*DistanceFunction(xl); | |
825 | ||
826 | ||
302f96fb | 827 | for(;;) { |
7fd59977 | 828 | |
829 | if (fabs(b-a) < myEpsT) { | |
830 | return .5*(b+a); | |
831 | } | |
832 | ||
833 | if (yp < yl) { | |
834 | a=xl; | |
835 | xl=xp; | |
836 | xp=a+(b-a)*gs; | |
837 | yp=coeff*DistanceFunction(xp); | |
838 | } | |
839 | ||
840 | else { | |
841 | b=xp; | |
842 | xp=xl; | |
843 | yp=yl; | |
844 | xl=b-(b-a)*gs; | |
845 | yl=coeff*DistanceFunction(xl); | |
846 | } | |
847 | } | |
848 | } | |
849 | ||
850 | //======================================================================= | |
851 | //function : MakeType | |
852 | //purpose : | |
853 | //======================================================================= | |
e30616a7 | 854 | Standard_Integer IntTools_EdgeFace::MakeType |
855 | (IntTools_CommonPrt& aCommonPrt) | |
7fd59977 | 856 | { |
857 | Standard_Real af1, al1; | |
295cb053 | 858 | Standard_Real df1, tm; |
7fd59977 | 859 | Standard_Boolean bAllNullFlag; |
860 | // | |
861 | bAllNullFlag=aCommonPrt.AllNullFlag(); | |
862 | if (bAllNullFlag) { | |
863 | aCommonPrt.SetType(TopAbs_EDGE); | |
864 | return 0; | |
865 | } | |
866 | // | |
867 | aCommonPrt.Range1(af1, al1); | |
868 | ||
869 | { | |
870 | gp_Pnt aPF, aPL; | |
871 | myC.D0(af1, aPF); | |
872 | myC.D0(al1, aPL); | |
873 | df1=aPF.Distance(aPL); | |
874 | Standard_Boolean isWholeRange = Standard_False; | |
875 | ||
876 | if((Abs(af1 - myRange.First()) < myC.Resolution(myCriteria)) && | |
877 | (Abs(al1 - myRange.Last()) < myC.Resolution(myCriteria))) | |
878 | isWholeRange = Standard_True; | |
e30616a7 | 879 | |
7fd59977 | 880 | |
881 | if ((df1 > myCriteria * 2.) && isWholeRange) { | |
882 | aCommonPrt.SetType(TopAbs_EDGE); | |
883 | } | |
884 | else { | |
885 | if(isWholeRange) { | |
e30616a7 | 886 | tm = (af1 + al1) * 0.5; |
887 | ||
888 | if(aPF.Distance(myC.Value(tm)) > myCriteria * 2.) { | |
889 | aCommonPrt.SetType(TopAbs_EDGE); | |
890 | return 0; | |
891 | } | |
7fd59977 | 892 | } |
e30616a7 | 893 | |
7fd59977 | 894 | if(!CheckTouch(aCommonPrt, tm)) { |
e30616a7 | 895 | tm = (af1 + al1) * 0.5; |
7fd59977 | 896 | } |
897 | aCommonPrt.SetType(TopAbs_VERTEX); | |
898 | aCommonPrt.SetVertexParameter1(tm); | |
899 | aCommonPrt.SetRange1 (af1, al1); | |
900 | } | |
7fd59977 | 901 | } |
e30616a7 | 902 | return 0; |
7fd59977 | 903 | } |
904 | ||
905 | ||
906 | //======================================================================= | |
907 | //function : IsIntersection | |
908 | //purpose : | |
909 | //======================================================================= | |
e30616a7 | 910 | void IntTools_EdgeFace::IsIntersection (const Standard_Real ta, |
911 | const Standard_Real tb) | |
7fd59977 | 912 | { |
913 | IntTools_CArray1OfReal anArgs, aFunc; | |
96a95605 | 914 | Standard_Integer i, aNb, aCnt=0; |
7fd59977 | 915 | // |
916 | Standard_Integer aCntIncreasing=1, aCntDecreasing=1; | |
917 | Standard_Real t, f, f1; | |
918 | // | |
919 | // Prepare values of arguments for the interval [ta, tb] | |
96a95605 | 920 | IntTools::PrepareArgs (myC, tb, ta, myDiscret, myDeflection, anArgs); |
7fd59977 | 921 | aNb=anArgs.Length(); |
922 | ||
923 | aFunc.Resize(aNb); | |
924 | for (i=0; i<aNb; i++) { | |
925 | t=anArgs(i); | |
926 | ||
927 | f1=DistanceFunction(t); | |
928 | f=f1+myCriteria; | |
929 | ||
930 | if (fabs(f1) < myEpsNull) { | |
931 | aCnt++; | |
932 | f=0.; | |
933 | } | |
934 | aFunc(i)=f; | |
935 | // | |
936 | if (i) { | |
937 | if (aFunc(i)>aFunc(i-1)) { | |
e30616a7 | 938 | aCntIncreasing++; |
7fd59977 | 939 | } |
940 | if (aFunc(i)<aFunc(i-1)) { | |
e30616a7 | 941 | aCntDecreasing++; |
7fd59977 | 942 | } |
943 | } | |
944 | // | |
945 | } | |
946 | ||
947 | if (aCnt==aNb) { | |
948 | myParallel=Standard_True; | |
949 | return; | |
950 | } | |
951 | ||
952 | FindDerivativeRoot(anArgs, aFunc); | |
953 | ||
954 | // | |
955 | if (myParallel) { | |
956 | if (!(myC.GetType()==GeomAbs_Line | |
e30616a7 | 957 | && |
958 | myS.GetType()==GeomAbs_Cylinder)) { | |
7fd59977 | 959 | if (aCntDecreasing==aNb) { |
e30616a7 | 960 | myPar1=anArgs(aNb-1); |
961 | myParallel=Standard_False; | |
7fd59977 | 962 | } |
963 | if (aCntIncreasing==aNb) { | |
e30616a7 | 964 | myPar1=anArgs(0); |
965 | myParallel=Standard_False; | |
7fd59977 | 966 | } |
967 | } | |
968 | } | |
969 | // | |
970 | return ; | |
971 | } | |
972 | ||
973 | //======================================================================= | |
974 | //function : FindDerivativeRoot | |
975 | //purpose : | |
976 | //======================================================================= | |
e30616a7 | 977 | void IntTools_EdgeFace::FindDerivativeRoot |
978 | (const IntTools_CArray1OfReal& t, | |
979 | const IntTools_CArray1OfReal& f) | |
7fd59977 | 980 | { |
981 | Standard_Integer i, n, k; | |
96a95605 | 982 | Standard_Real tr; |
7fd59977 | 983 | IntTools_CArray1OfReal fd; |
984 | TColStd_SequenceOfReal aTSeq, aFSeq; | |
985 | ||
986 | myPar1=0.; | |
987 | myParallel=Standard_True; | |
988 | ||
989 | n=t.Length(); | |
990 | fd.Resize(n+1); | |
991 | // | |
992 | // Table of derivatives | |
993 | fd(0)=(f(1)-f(0))/(t(1)-t(0)); | |
994 | if (fabs(fd(0)) < myEpsNull) { | |
995 | fd(0)=0.; | |
996 | } | |
997 | ||
998 | k=n-1; | |
999 | for (i=1; i<k; i++) { | |
1000 | fd(i)=.5*(f(i+1)-f(i-1))/(t(i)-t(i-1)); | |
1001 | if (fabs(fd(i)) < myEpsNull) { | |
1002 | fd(i)=0.; | |
1003 | } | |
1004 | } | |
1005 | ||
1006 | fd(n-1)=(f(n-1)-f(n-2))/(t(n-1)-t(n-2)); | |
1007 | if (fabs(fd(n-1)) < myEpsNull) { | |
1008 | fd(n-1)=0.; | |
1009 | } | |
1010 | // | |
1011 | // Finding the range where the derivatives have different signs | |
1012 | // for neighbouring points | |
1013 | for (i=1; i<n; i++) { | |
1014 | Standard_Real fd1, fd2, t1, t2, fabsfd1, fabsfd2; | |
1015 | Standard_Boolean bF1, bF2; | |
1016 | t1 =t(i-1); | |
1017 | t2 =t(i); | |
1018 | fd1=fd(i-1); | |
1019 | fd2=fd(i); | |
1020 | ||
1021 | fabsfd1=fabs(fd1); | |
1022 | bF1=fabsfd1 < myEpsNull; | |
1023 | ||
1024 | fabsfd2=fabs(fd2); | |
1025 | bF2=fabsfd2 < myEpsNull; | |
1026 | // | |
1027 | if (fd1*fd2 < 0.) { | |
1028 | tr=FindSimpleRoot(2, t1, t2, fd1); | |
96a95605 | 1029 | DistanceFunction(tr); |
7fd59977 | 1030 | myPar1=tr; |
1031 | myParallel=Standard_False; | |
1032 | break; | |
1033 | } | |
1034 | ||
1035 | if (!bF1 && bF2) { | |
1036 | tr=t2; | |
7fd59977 | 1037 | myPar1=tr; |
1038 | myParallel=Standard_False; | |
1039 | break; | |
1040 | } | |
1041 | ||
1042 | if (bF1 && !bF2) { | |
1043 | tr=t1; | |
7fd59977 | 1044 | myPar1=tr; |
1045 | myParallel=Standard_False; | |
1046 | break; | |
1047 | } | |
1048 | ||
1049 | } | |
1050 | } | |
1051 | //======================================================================= | |
1052 | //function : RemoveIdenticalRoots | |
1053 | //purpose : | |
1054 | //======================================================================= | |
e30616a7 | 1055 | void IntTools_EdgeFace::RemoveIdenticalRoots() |
7fd59977 | 1056 | { |
1057 | Standard_Integer aNbRoots, j, k; | |
1058 | ||
1059 | aNbRoots=mySequenceOfRoots.Length(); | |
1060 | for (j=1; j<=aNbRoots; j++) { | |
1061 | const IntTools_Root& aRj=mySequenceOfRoots(j); | |
1062 | for (k=j+1; k<=aNbRoots; k++) { | |
1063 | const IntTools_Root& aRk=mySequenceOfRoots(k); | |
1064 | ||
1065 | Standard_Real aTj, aTk, aDistance; | |
1066 | gp_Pnt aPj, aPk; | |
1067 | ||
1068 | aTj=aRj.Root(); | |
1069 | aTk=aRk.Root(); | |
1070 | ||
1071 | myC.D0(aTj, aPj); | |
1072 | myC.D0(aTk, aPk); | |
1073 | ||
1074 | aDistance=aPj.Distance(aPk); | |
1075 | if (aDistance < myCriteria) { | |
e30616a7 | 1076 | mySequenceOfRoots.Remove(k); |
1077 | aNbRoots=mySequenceOfRoots.Length(); | |
7fd59977 | 1078 | } |
1079 | } | |
1080 | } | |
1081 | } | |
1082 | ||
1083 | //======================================================================= | |
1084 | //function : CheckTouch | |
1085 | //purpose : | |
1086 | //======================================================================= | |
e30616a7 | 1087 | Standard_Boolean IntTools_EdgeFace::CheckTouch |
1088 | (const IntTools_CommonPrt& aCP, | |
1089 | Standard_Real& aTx) | |
7fd59977 | 1090 | { |
1091 | Standard_Real aTF, aTL, Tol, U1f, U1l, V1f, V1l, af, al,aDist2, aMinDist2; | |
1092 | Standard_Boolean theflag=Standard_False; | |
1093 | Standard_Integer aNbExt, i, iLower ; | |
1094 | ||
1095 | aCP.Range1(aTF, aTL); | |
1096 | ||
1097 | // | |
1098 | Standard_Real aCR; | |
1099 | aCR=myC.Resolution(myCriteria); | |
1100 | if((Abs(aTF - myRange.First()) < aCR) && | |
1101 | (Abs(aTL - myRange.Last()) < aCR)) { | |
1102 | return theflag; // EDGE | |
1103 | } | |
1104 | // | |
1105 | ||
1106 | Tol = Precision::PConfusion(); | |
1107 | ||
1108 | const Handle(Geom_Curve)& Curve =BRep_Tool::Curve (myC.Edge(), af, al); | |
1109 | const Handle(Geom_Surface)& Surface=BRep_Tool::Surface(myS.Face()); | |
1110 | // Surface->Bounds(U1f,U1l,V1f,V1l); | |
1111 | U1f = myS.FirstUParameter(); | |
1112 | U1l = myS.LastUParameter(); | |
1113 | V1f = myS.FirstVParameter(); | |
1114 | V1l = myS.LastVParameter(); | |
1115 | ||
1116 | GeomAdaptor_Curve TheCurve (Curve,aTF, aTL); | |
1117 | GeomAdaptor_Surface TheSurface (Surface, U1f, U1l, V1f, V1l); | |
e30616a7 | 1118 | |
7fd59977 | 1119 | Extrema_ExtCS anExtrema (TheCurve, TheSurface, Tol, Tol); |
1120 | ||
1121 | aDist2 = 1.e100; | |
1122 | ||
1123 | if(anExtrema.IsDone()) { | |
1124 | aMinDist2 = aDist2; | |
1125 | ||
1126 | if(!anExtrema.IsParallel()) { | |
1127 | aNbExt=anExtrema.NbExt(); | |
1128 | ||
1129 | if(aNbExt > 0) { | |
e30616a7 | 1130 | iLower=1; |
1131 | for (i=1; i<=aNbExt; i++) { | |
1132 | aDist2=anExtrema.SquareDistance(i); | |
1133 | if (aDist2 < aMinDist2) { | |
1134 | aMinDist2=aDist2; | |
1135 | iLower=i; | |
1136 | } | |
1137 | } | |
1138 | aDist2=anExtrema.SquareDistance(iLower); | |
1139 | Extrema_POnCurv aPOnC; | |
1140 | Extrema_POnSurf aPOnS; | |
1141 | anExtrema.Points(iLower, aPOnC, aPOnS); | |
1142 | aTx=aPOnC.Parameter(); | |
7fd59977 | 1143 | } |
1144 | else { | |
e30616a7 | 1145 | // modified by NIZHNY-MKK Thu Jul 21 11:35:32 2005.BEGIN |
1146 | IntCurveSurface_HInter anExactIntersector; | |
7fd59977 | 1147 | |
e30616a7 | 1148 | Handle(GeomAdaptor_HCurve) aCurve = new GeomAdaptor_HCurve(TheCurve); |
1149 | Handle(GeomAdaptor_HSurface) aSurface = new GeomAdaptor_HSurface(TheSurface); | |
1150 | ||
1151 | anExactIntersector.Perform(aCurve, aSurface); | |
7fd59977 | 1152 | |
e30616a7 | 1153 | if(anExactIntersector.IsDone()) { |
1154 | Standard_Integer i = 0; | |
7fd59977 | 1155 | |
e30616a7 | 1156 | for(i = 1; i <= anExactIntersector.NbPoints(); i++) { |
1157 | const IntCurveSurface_IntersectionPoint& aPoint = anExactIntersector.Point(i); | |
7fd59977 | 1158 | |
e30616a7 | 1159 | if((aPoint.W() >= aTF) && (aPoint.W() <= aTL)) { |
1160 | aDist2=0.; | |
1161 | aTx = aPoint.W(); | |
1162 | } | |
1163 | } | |
1164 | } | |
1165 | // modified by NIZHNY-MKK Thu Jul 21 11:35:40 2005.END | |
7fd59977 | 1166 | } |
1167 | } | |
1168 | else { | |
1169 | return theflag; | |
1170 | } | |
1171 | } | |
1172 | ||
1173 | Standard_Real aBoundaryDist; | |
1174 | ||
1175 | aBoundaryDist = DistanceFunction(aTF) + myCriteria; | |
1176 | if(aBoundaryDist * aBoundaryDist < aDist2) { | |
1177 | aDist2 = aBoundaryDist * aBoundaryDist; | |
1178 | aTx = aTF; | |
1179 | } | |
1180 | ||
1181 | aBoundaryDist = DistanceFunction(aTL) + myCriteria; | |
1182 | if(aBoundaryDist * aBoundaryDist < aDist2) { | |
1183 | aDist2 = aBoundaryDist * aBoundaryDist; | |
1184 | aTx = aTL; | |
1185 | } | |
1186 | ||
1187 | Standard_Real aParameter = (aTF + aTL) * 0.5; | |
1188 | aBoundaryDist = DistanceFunction(aParameter) + myCriteria; | |
1189 | if(aBoundaryDist * aBoundaryDist < aDist2) { | |
1190 | aDist2 = aBoundaryDist * aBoundaryDist; | |
1191 | aTx = aParameter; | |
1192 | } | |
1193 | ||
1194 | if(aDist2 > myCriteria * myCriteria) { | |
1195 | return theflag; | |
1196 | } | |
1197 | ||
1198 | if (fabs (aTx-aTF) < myEpsT) { | |
1199 | return !theflag; | |
1200 | } | |
1201 | ||
1202 | if (fabs (aTx-aTL) < myEpsT) { | |
1203 | return !theflag; | |
1204 | } | |
1205 | ||
1206 | if (aTx>aTF && aTx<aTL) { | |
1207 | return !theflag; | |
1208 | } | |
1209 | ||
1210 | return theflag; | |
1211 | } | |
7fd59977 | 1212 | //======================================================================= |
1213 | //function : Perform | |
1214 | //purpose : | |
1215 | //======================================================================= | |
e30616a7 | 1216 | void IntTools_EdgeFace::Perform() |
7fd59977 | 1217 | { |
1218 | Standard_Integer i, aNb; | |
1219 | IntTools_CommonPrt aCommonPrt; | |
7fd59977 | 1220 | // |
4f189102 | 1221 | aCommonPrt.SetEdge1(myEdge); |
7fd59977 | 1222 | // |
1223 | myErrorStatus=0; | |
1224 | CheckData(); | |
4f189102 | 1225 | if (myErrorStatus) { |
7fd59977 | 1226 | return; |
4f189102 P |
1227 | } |
1228 | // | |
1229 | if (myContext.IsNull()) { | |
1e143abb | 1230 | myContext=new IntTools_Context; |
4f189102 P |
1231 | } |
1232 | // | |
7fd59977 | 1233 | myIsDone = Standard_False; |
1234 | myC.Initialize(myEdge); | |
1235 | GeomAbs_CurveType aCurveType; | |
1236 | aCurveType=myC.GetType(); | |
1237 | // | |
1238 | // Prepare myCriteria | |
1239 | if (aCurveType==GeomAbs_BSplineCurve|| | |
e30616a7 | 1240 | aCurveType==GeomAbs_BezierCurve) { |
7fd59977 | 1241 | //--- 5112 |
1242 | Standard_Real diff1 = (myTolE/myTolF); | |
1243 | Standard_Real diff2 = (myTolF/myTolE); | |
1244 | if( diff1 > 100 || diff2 > 100 ) { | |
1245 | myCriteria = Max(myTolE,myTolF); | |
1246 | } | |
1247 | else //--- 5112 | |
1248 | myCriteria=1.5*myTolE+myTolF; | |
1249 | } | |
1250 | else { | |
1251 | myCriteria=myTolE+myTolF; | |
1252 | } | |
e30616a7 | 1253 | |
7fd59977 | 1254 | myTmin=myRange.First(); |
1255 | myTmax=myRange.Last(); | |
e30616a7 | 1256 | |
7fd59977 | 1257 | myS.Initialize (myFace,Standard_True); |
e30616a7 | 1258 | |
4f189102 | 1259 | if(myContext.IsNull()) { |
7fd59977 | 1260 | myFClass2d.Init(myFace, 1.e-6); |
1261 | } | |
e30616a7 | 1262 | |
7fd59977 | 1263 | IntTools_BeanFaceIntersector anIntersector(myC, myS, myTolE, myTolF); |
1264 | anIntersector.SetBeanParameters(myRange.First(), myRange.Last()); | |
1265 | // | |
1266 | anIntersector.SetContext(myContext); | |
1267 | // | |
1268 | anIntersector.Perform(); | |
e30616a7 | 1269 | |
7fd59977 | 1270 | if(!anIntersector.IsDone()) { |
1271 | return; | |
1272 | } | |
e30616a7 | 1273 | |
7fd59977 | 1274 | for(Standard_Integer r = 1; r <= anIntersector.Result().Length(); r++) { |
1275 | const IntTools_Range& aRange = anIntersector.Result().Value(r); | |
1276 | ||
1277 | if(IsProjectable(IntTools_Tools::IntermediatePoint(aRange.First(), aRange.Last()))) { | |
1278 | aCommonPrt.SetRange1(aRange.First(), aRange.Last()); | |
1279 | mySeqOfCommonPrts.Append(aCommonPrt); | |
1280 | } | |
1281 | } | |
1282 | ||
1283 | aNb = mySeqOfCommonPrts.Length(); | |
1284 | ||
1285 | for (i=1; i<=aNb; i++) { | |
1286 | IntTools_CommonPrt& aCP=mySeqOfCommonPrts.ChangeValue(i); | |
1287 | // | |
1288 | Standard_Real aTx1, aTx2; | |
1289 | gp_Pnt aPx1, aPx2; | |
1290 | // | |
1291 | aCP.Range1(aTx1, aTx2); | |
1292 | myC.D0(aTx1, aPx1); | |
1293 | myC.D0(aTx2, aPx2); | |
1294 | aCP.SetBoundingPoints(aPx1, aPx2); | |
1295 | // | |
1296 | MakeType (aCP); | |
1297 | } | |
1298 | { | |
1299 | // Line\Cylinder's Common Parts treatement | |
1300 | GeomAbs_CurveType aCType; | |
1301 | GeomAbs_SurfaceType aSType; | |
1302 | TopAbs_ShapeEnum aType; | |
1303 | Standard_Boolean bIsTouch; | |
1304 | Standard_Real aTx; | |
e30616a7 | 1305 | |
7fd59977 | 1306 | aCType=myC.GetType(); |
1307 | aSType=myS.GetType(); | |
1308 | ||
1309 | if (aCType==GeomAbs_Line && aSType==GeomAbs_Cylinder) { | |
1310 | for (i=1; i<=aNb; i++) { | |
e30616a7 | 1311 | IntTools_CommonPrt& aCP=mySeqOfCommonPrts(i); |
1312 | aType=aCP.Type(); | |
1313 | if (aType==TopAbs_EDGE) { | |
1314 | bIsTouch=CheckTouch (aCP, aTx); | |
1315 | if (bIsTouch) { | |
1316 | aCP.SetType(TopAbs_VERTEX); | |
1317 | aCP.SetVertexParameter1(aTx); | |
bd28b2af | 1318 | //aCP.SetRange1 (aTx, aTx); |
e30616a7 | 1319 | } |
1320 | } | |
bd28b2af | 1321 | else if (aType==TopAbs_VERTEX) { |
e30616a7 | 1322 | bIsTouch=CheckTouchVertex (aCP, aTx); |
1323 | if (bIsTouch) { | |
1324 | aCP.SetVertexParameter1(aTx); | |
bd28b2af | 1325 | //aCP.SetRange1 (aTx, aTx); |
e30616a7 | 1326 | } |
1327 | } | |
7fd59977 | 1328 | } |
1329 | } | |
e30616a7 | 1330 | |
7fd59977 | 1331 | // Circle\Plane's Common Parts treatement |
1332 | ||
1333 | if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) { | |
1334 | Standard_Boolean bIsCoplanar, bIsRadius; | |
1335 | bIsCoplanar=IsCoplanar(myC, myS); | |
bd28b2af | 1336 | bIsRadius=IsRadius(myC, myS, myCriteria); |
7fd59977 | 1337 | if (!bIsCoplanar && !bIsRadius) { |
e30616a7 | 1338 | for (i=1; i<=aNb; i++) { |
1339 | IntTools_CommonPrt& aCP=mySeqOfCommonPrts(i); | |
1340 | aType=aCP.Type(); | |
1341 | if (aType==TopAbs_EDGE) { | |
1342 | bIsTouch=CheckTouch (aCP, aTx); | |
1343 | if (bIsTouch) { | |
1344 | aCP.SetType(TopAbs_VERTEX); | |
1345 | aCP.SetVertexParameter1(aTx); | |
bd28b2af | 1346 | //aCP.SetRange1 (aTx, aTx); |
1347 | } | |
1348 | } | |
1349 | else if (aType==TopAbs_VERTEX) { | |
1350 | bIsTouch=CheckTouchVertex (aCP, aTx); | |
1351 | if (bIsTouch) { | |
1352 | aCP.SetVertexParameter1(aTx); | |
1353 | //aCP.SetRange1 (aTx, aTx); | |
e30616a7 | 1354 | } |
1355 | } | |
1356 | } | |
7fd59977 | 1357 | } |
1358 | } | |
1359 | } | |
1360 | myIsDone=Standard_True; | |
1361 | } | |
1362 | ||
1363 | // | |
1364 | // myErrorStatus | |
1365 | // 1 - the method Perform() is not invoked | |
1366 | // 2,3,4,5 -the method CheckData() fails | |
1367 | // 6 - PrepareArgs() problems | |
1368 | // 7 - No Projectable ranges | |
1369 | // 8,9 - PrepareArgs() problems occured inside projectable Ranges | |
1370 | // 11 - can't fill array aFunc(i) in PrepareArgsFuncArrays | |
1371 | ||
1372 | ||
1373 | //======================================================================= | |
1374 | //function : CheckTouch | |
1375 | //purpose : | |
1376 | //======================================================================= | |
e30616a7 | 1377 | Standard_Boolean IntTools_EdgeFace::CheckTouchVertex |
1378 | (const IntTools_CommonPrt& aCP, | |
1379 | Standard_Real& aTx) | |
7fd59977 | 1380 | { |
cf2439de | 1381 | Standard_Real aTF, aTL, Tol, U1f,U1l,V1f,V1l; |
1382 | Standard_Real aEpsT, af, al,aDist2, aMinDist2, aTm, aDist2New; | |
7fd59977 | 1383 | Standard_Boolean theflag=Standard_False; |
1384 | Standard_Integer aNbExt, i, iLower ; | |
cf2439de | 1385 | GeomAbs_CurveType aType; |
1386 | // | |
7fd59977 | 1387 | aCP.Range1(aTF, aTL); |
cf2439de | 1388 | aType=myC.GetType(); |
1389 | // | |
ddd95bbf | 1390 | aEpsT=8.e-5; |
cf2439de | 1391 | if (aType==GeomAbs_Line) { |
1392 | aEpsT=9.e-5; | |
1393 | } | |
1394 | // | |
7fd59977 | 1395 | aTm=0.5*(aTF+aTL); |
1396 | aDist2=DistanceFunction(aTm); | |
1397 | aDist2 *= aDist2; | |
1398 | ||
1399 | Tol = Precision::PConfusion(); | |
1400 | ||
cf2439de | 1401 | const Handle(Geom_Curve)& Curve =BRep_Tool::Curve (myC.Edge(), af, al); |
7fd59977 | 1402 | const Handle(Geom_Surface)& Surface=BRep_Tool::Surface(myS.Face()); |
1403 | ||
1404 | Surface->Bounds(U1f,U1l,V1f,V1l); | |
1405 | ||
1406 | GeomAdaptor_Curve TheCurve (Curve,aTF, aTL); | |
1407 | GeomAdaptor_Surface TheSurface (Surface, U1f, U1l, V1f, V1l); | |
e30616a7 | 1408 | |
7fd59977 | 1409 | Extrema_ExtCS anExtrema (TheCurve, TheSurface, Tol, Tol); |
1410 | ||
1411 | if(!anExtrema.IsDone()) { | |
1412 | return theflag; | |
1413 | } | |
1414 | if (anExtrema.IsParallel()) { | |
1415 | return theflag; | |
1416 | } | |
1417 | ||
1418 | aNbExt=anExtrema.NbExt() ; | |
1419 | if (!aNbExt) { | |
1420 | return theflag; | |
1421 | } | |
1422 | ||
1423 | iLower=1; | |
1424 | aMinDist2=1.e100; | |
1425 | for (i=1; i<=aNbExt; ++i) { | |
1426 | aDist2=anExtrema.SquareDistance(i); | |
1427 | if (aDist2 < aMinDist2) { | |
1428 | aMinDist2=aDist2; | |
1429 | iLower=i; | |
1430 | } | |
1431 | } | |
1432 | ||
1433 | aDist2New=anExtrema.SquareDistance(iLower); | |
1434 | ||
1435 | if (aDist2New > aDist2) { | |
1436 | aTx=aTm; | |
1437 | return !theflag; | |
1438 | } | |
1439 | ||
1440 | if (aDist2New > myCriteria * myCriteria) { | |
1441 | return theflag; | |
1442 | } | |
1443 | ||
1444 | Extrema_POnCurv aPOnC; | |
1445 | Extrema_POnSurf aPOnS; | |
1446 | anExtrema.Points(iLower, aPOnC, aPOnS); | |
1447 | ||
ddd95bbf | 1448 | |
7fd59977 | 1449 | aTx=aPOnC.Parameter(); |
ddd95bbf | 1450 | /// |
1451 | if (fabs (aTx-aTF) < aEpsT) { | |
1452 | return theflag; | |
7fd59977 | 1453 | } |
1454 | ||
ddd95bbf | 1455 | if (fabs (aTx-aTL) < aEpsT) { |
1456 | return theflag; | |
7fd59977 | 1457 | } |
1458 | ||
1459 | if (aTx>aTF && aTx<aTL) { | |
1460 | return !theflag; | |
1461 | } | |
1462 | ||
1463 | return theflag; | |
1464 | } | |
1465 | ||
1466 | ||
1467 | //======================================================================= | |
1468 | //function : IsCoplanar | |
1469 | //purpose : | |
1470 | //======================================================================= | |
1471 | Standard_Boolean IsCoplanar (const BRepAdaptor_Curve& aCurve , | |
e30616a7 | 1472 | const BRepAdaptor_Surface& aSurface) |
7fd59977 | 1473 | { |
1474 | Standard_Boolean bFlag=Standard_False; | |
1475 | ||
1476 | GeomAbs_CurveType aCType; | |
1477 | GeomAbs_SurfaceType aSType; | |
1478 | ||
1479 | aCType=aCurve.GetType(); | |
1480 | aSType=aSurface.GetType(); | |
1481 | ||
1482 | if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) { | |
1483 | gp_Circ aCirc=aCurve.Circle(); | |
1484 | const gp_Ax1& anAx1=aCirc.Axis(); | |
1485 | const gp_Dir& aDirAx1=anAx1.Direction(); | |
1486 | ||
1487 | gp_Pln aPln=aSurface.Plane(); | |
1488 | const gp_Ax1& anAx=aPln.Axis(); | |
1489 | const gp_Dir& aDirPln=anAx.Direction(); | |
1490 | ||
1491 | bFlag=IntTools_Tools::IsDirsCoinside(aDirAx1, aDirPln); | |
1492 | } | |
1493 | return bFlag; | |
1494 | } | |
1495 | //======================================================================= | |
1496 | //function : IsRadius | |
1497 | //purpose : | |
1498 | //======================================================================= | |
bd28b2af | 1499 | Standard_Boolean IsRadius (const BRepAdaptor_Curve& aCurve, |
1500 | const BRepAdaptor_Surface& aSurface, | |
1501 | const Standard_Real aCriteria) | |
7fd59977 | 1502 | { |
1503 | Standard_Boolean bFlag=Standard_False; | |
1504 | ||
1505 | GeomAbs_CurveType aCType; | |
1506 | GeomAbs_SurfaceType aSType; | |
1507 | ||
1508 | aCType=aCurve.GetType(); | |
1509 | aSType=aSurface.GetType(); | |
1510 | ||
1511 | if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) { | |
1512 | gp_Circ aCirc=aCurve.Circle(); | |
1513 | const gp_Pnt aCenter=aCirc.Location(); | |
1514 | Standard_Real aR=aCirc.Radius(); | |
1515 | gp_Pln aPln=aSurface.Plane(); | |
1516 | Standard_Real aD=aPln.Distance(aCenter); | |
bd28b2af | 1517 | if (fabs (aD-aR) < aCriteria) { |
7fd59977 | 1518 | return !bFlag; |
1519 | } | |
1520 | } | |
1521 | return bFlag; | |
1522 | } | |
1523 | // | |
1524 | //======================================================================= | |
1525 | //function : AdaptiveDiscret | |
1526 | //purpose : | |
1527 | //======================================================================= | |
1528 | Standard_Integer AdaptiveDiscret (const Standard_Integer iDiscret, | |
e30616a7 | 1529 | const BRepAdaptor_Curve& aCurve , |
1530 | const BRepAdaptor_Surface& aSurface) | |
7fd59977 | 1531 | { |
1532 | Standard_Integer iDiscretNew; | |
1533 | ||
1534 | iDiscretNew=iDiscret; | |
1535 | ||
7fd59977 | 1536 | GeomAbs_SurfaceType aSType; |
1537 | ||
7fd59977 | 1538 | aSType=aSurface.GetType(); |
1539 | ||
1540 | if (aSType==GeomAbs_Cylinder) { | |
96a95605 | 1541 | Standard_Real aELength, aRadius, dLR; |
7fd59977 | 1542 | |
1543 | aELength=IntTools::Length(aCurve.Edge()); | |
7fd59977 | 1544 | |
1545 | gp_Cylinder aCylinder=aSurface.Cylinder(); | |
1546 | aRadius=aCylinder.Radius(); | |
1547 | dLR=2*aRadius; | |
1548 | ||
1549 | iDiscretNew=(Standard_Integer)(aELength/dLR); | |
1550 | ||
1551 | if (iDiscretNew<iDiscret) { | |
1552 | iDiscretNew=iDiscret; | |
1553 | } | |
1554 | ||
1555 | } | |
1556 | return iDiscretNew; | |
1557 | } | |
1558 | ||
1559 | ||
1560 | #ifdef WNT | |
1561 | #pragma warning ( default : 4101 ) | |
1562 | #endif |