0026619: Tolerances of operands are modified using bop
[occt.git] / src / IntTools / IntTools_Context.cxx
CommitLineData
b311480e 1// Created by: Peter KURNEV
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
d5f74e42 6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
7fd59977 14
7fd59977 15
42cf5bc1 16#include <Bnd_Box.hxx>
7fd59977 17#include <BRep_Tool.hxx>
18#include <BRepAdaptor_Surface.hxx>
f47b8d2b 19#include <BRepBndLib.hxx>
42cf5bc1 20#include <BRepClass3d_SolidClassifier.hxx>
7fd59977 21#include <Extrema_LocateExtPC.hxx>
7fd59977 22#include <Geom2d_Curve.hxx>
42cf5bc1 23#include <Geom2d_TrimmedCurve.hxx>
24#include <Geom2dHatch_Hatcher.hxx>
25#include <Geom2dHatch_Intersector.hxx>
26#include <Geom_BoundedCurve.hxx>
27#include <Geom_Curve.hxx>
28#include <GeomAdaptor_Curve.hxx>
29#include <GeomAPI_ProjectPointOnCurve.hxx>
30#include <GeomAPI_ProjectPointOnSurf.hxx>
31#include <gp_Pnt.hxx>
32#include <gp_Pnt2d.hxx>
33#include <IntTools_Context.hxx>
34#include <IntTools_Curve.hxx>
35#include <IntTools_FClass2d.hxx>
4e57c75e 36#include <IntTools_SurfaceRangeLocalizeData.hxx>
42cf5bc1 37#include <IntTools_Tools.hxx>
42cf5bc1 38#include <Precision.hxx>
39#include <Standard_Type.hxx>
40#include <TopAbs_State.hxx>
41#include <TopExp_Explorer.hxx>
42#include <TopoDS.hxx>
43#include <TopoDS_Edge.hxx>
44#include <TopoDS_Face.hxx>
45#include <TopoDS_Shape.hxx>
46#include <TopoDS_Solid.hxx>
47#include <TopoDS_Vertex.hxx>
4e57c75e 48
92efcf78 49IMPLEMENT_STANDARD_RTTIEXT(IntTools_Context,MMgt_TShared)
50
42cf5bc1 51//
7fd59977 52//=======================================================================
53//function :
54//purpose :
55//=======================================================================
1e143abb 56IntTools_Context::IntTools_Context()
4e57c75e 57:
488e5b9d 58 myAllocator(NCollection_BaseAllocator::CommonBaseAllocator()),
4e57c75e 59 myFClass2dMap(100, myAllocator),
60 myProjPSMap(100, myAllocator),
61 myProjPCMap(100, myAllocator),
62 mySClassMap(100, myAllocator),
63 myProjPTMap(100, myAllocator),
64 myHatcherMap(100, myAllocator),
65 myProjSDataMap(100, myAllocator),
f47b8d2b 66 myBndBoxDataMap(100, myAllocator),
b285c9fe 67 myCreateFlag(0),
68 myPOnSTolerance(1.e-12)
4e57c75e 69{
70}
71//=======================================================================
72//function :
73//purpose :
74//=======================================================================
1e143abb 75IntTools_Context::IntTools_Context
76 (const Handle(NCollection_BaseAllocator)& theAllocator)
4e57c75e 77:
78 myAllocator(theAllocator),
79 myFClass2dMap(100, myAllocator),
80 myProjPSMap(100, myAllocator),
81 myProjPCMap(100, myAllocator),
82 mySClassMap(100, myAllocator),
83 myProjPTMap(100, myAllocator),
84 myHatcherMap(100, myAllocator),
85 myProjSDataMap(100, myAllocator),
f47b8d2b 86 myBndBoxDataMap(100, myAllocator),
b285c9fe 87 myCreateFlag(1),
88 myPOnSTolerance(1.e-12)
7fd59977 89{
90}
91//=======================================================================
92//function : ~
93//purpose :
94//=======================================================================
1e143abb 95IntTools_Context::~IntTools_Context()
7fd59977 96{
97 Standard_Address anAdr;
4e57c75e 98 BOPCol_DataMapIteratorOfDataMapOfShapeAddress aIt;
99 BOPCol_DataMapIteratorOfDataMapOfTransientAddress aIt1;
3f524765 100 //
7fd59977 101 IntTools_FClass2d* pFClass2d;
4e57c75e 102 //
103 aIt.Initialize(myFClass2dMap);
104 for (; aIt.More(); aIt.Next()) {
105 anAdr=aIt.Value();
7fd59977 106 pFClass2d=(IntTools_FClass2d*)anAdr;
4e57c75e 107 (*pFClass2d).~IntTools_FClass2d();
108 myAllocator->Free(anAdr);
7fd59977 109 }
110 myFClass2dMap.Clear();
111 //
b285c9fe 112 clearCachedPOnSProjectors();
7fd59977 113 //
114 GeomAPI_ProjectPointOnCurve* pProjPC;
4e57c75e 115 aIt.Initialize(myProjPCMap);
116 for (; aIt.More(); aIt.Next()) {
117 anAdr=aIt.Value();
7fd59977 118 pProjPC=(GeomAPI_ProjectPointOnCurve*)anAdr;
4e57c75e 119 (*pProjPC).~GeomAPI_ProjectPointOnCurve();
120 myAllocator->Free(anAdr);
7fd59977 121 }
122 myProjPCMap.Clear();
123 //
4e57c75e 124 //
125 BRepClass3d_SolidClassifier* pSC;
126 aIt.Initialize(mySClassMap);
127 for (; aIt.More(); aIt.Next()) {
128 anAdr=aIt.Value();
129 pSC=(BRepClass3d_SolidClassifier*)anAdr;
130 (*pSC).~BRepClass3d_SolidClassifier();
131 myAllocator->Free(anAdr);
132 }
133 mySClassMap.Clear();
134 //
7fd59977 135 GeomAPI_ProjectPointOnCurve* pProjPT;
4e57c75e 136 aIt1.Initialize(myProjPTMap);
137 for (; aIt1.More(); aIt1.Next()) {
138 anAdr=aIt1.Value();
7fd59977 139 pProjPT=(GeomAPI_ProjectPointOnCurve*)anAdr;
4e57c75e 140 (*pProjPT).~GeomAPI_ProjectPointOnCurve();
141 myAllocator->Free(anAdr);
7fd59977 142 }
143 myProjPTMap.Clear();
144 //
4e57c75e 145 Geom2dHatch_Hatcher* pHatcher;
146 aIt.Initialize(myHatcherMap);
147 for (; aIt.More(); aIt.Next()) {
148 anAdr=aIt.Value();
149 pHatcher=(Geom2dHatch_Hatcher*)anAdr;
150 (*pHatcher).~Geom2dHatch_Hatcher();
151 myAllocator->Free(anAdr);
7fd59977 152 }
4e57c75e 153 myHatcherMap.Clear();
7fd59977 154 //
155 IntTools_SurfaceRangeLocalizeData* pSData = NULL;
4e57c75e 156 aIt.Initialize(myProjSDataMap);
157 for (; aIt.More(); aIt.Next()) {
158 anAdr=aIt.Value();
7fd59977 159 pSData = (IntTools_SurfaceRangeLocalizeData*)anAdr;
4e57c75e 160 (*pSData).~IntTools_SurfaceRangeLocalizeData();
161 myAllocator->Free(anAdr);
7fd59977 162 }
163 myProjSDataMap.Clear();
f47b8d2b 164 //
165 Bnd_Box* pBox;
166 aIt.Initialize(myBndBoxDataMap);
167 for (; aIt.More(); aIt.Next()) {
168 anAdr=aIt.Value();
169 pBox=(Bnd_Box*)anAdr;
170 (*pBox).~Bnd_Box();
171 myAllocator->Free(anAdr);
172 }
173 myBndBoxDataMap.Clear();
174}
175//=======================================================================
176//function : BndBox
177//purpose :
178//=======================================================================
179Bnd_Box& IntTools_Context::BndBox(const TopoDS_Shape& aS)
180{
181 Standard_Address anAdr;
182 Bnd_Box* pBox;
183 //
184 if (!myBndBoxDataMap.IsBound(aS)) {
185 //
186 pBox=(Bnd_Box*)myAllocator->Allocate(sizeof(Bnd_Box));
187 new (pBox) Bnd_Box();
188 //
189 Bnd_Box &aBox=*pBox;
190 BRepBndLib::Add(aS, aBox);
191 //
192 anAdr=(Standard_Address)pBox;
193 myBndBoxDataMap.Bind(aS, anAdr);
194 }
195 else {
196 anAdr=myBndBoxDataMap.Find(aS);
197 pBox=(Bnd_Box*)anAdr;
198 }
199 return *pBox;
200}
201//=======================================================================
202//function : IsInfiniteFace
203//purpose :
204//=======================================================================
205Standard_Boolean IntTools_Context::IsInfiniteFace
206 (const TopoDS_Face& aFace)
207{
208 Standard_Boolean bRet;
209 Standard_Integer i;
210 Standard_Real aX[6];
211 //
212 bRet=Standard_False;
213 //
214 if (!BRep_Tool::NaturalRestriction(aFace)) {
215 return bRet;
216 }
217 //
218 Bnd_Box& aBox=BndBox(aFace);
219 //
220 aBox.Get(aX[0], aX[1], aX[2], aX[3], aX[4], aX[5]);
221 //
222 for (i=0; (i<6) && (!bRet); ++i) {
223 bRet=Precision::IsInfinite(aX[i]);
224 }
225 //
226 return bRet;
7fd59977 227}
228//=======================================================================
229//function : FClass2d
230//purpose :
231//=======================================================================
1e143abb 232IntTools_FClass2d& IntTools_Context::FClass2d(const TopoDS_Face& aF)
7fd59977 233{
234 Standard_Address anAdr;
235 IntTools_FClass2d* pFClass2d;
cf8e963a 236 //
4e57c75e 237 if (!myFClass2dMap.IsBound(aF)) {
7fd59977 238 Standard_Real aTolF;
4e57c75e 239 TopoDS_Face aFF;
240 //
241 aFF=aF;
7fd59977 242 aFF.Orientation(TopAbs_FORWARD);
243 aTolF=BRep_Tool::Tolerance(aFF);
244 //
4e57c75e 245 pFClass2d=(IntTools_FClass2d*)myAllocator->Allocate(sizeof(IntTools_FClass2d));
246 new (pFClass2d) IntTools_FClass2d(aFF, aTolF);
7fd59977 247 //
248 anAdr=(Standard_Address)pFClass2d;
4e57c75e 249 myFClass2dMap.Bind(aFF, anAdr);
7fd59977 250 }
7fd59977 251 else {
4e57c75e 252 anAdr=myFClass2dMap.Find(aF);
253 pFClass2d=(IntTools_FClass2d*)anAdr;
7fd59977 254 }
7fd59977 255 return *pFClass2d;
256}
257//=======================================================================
258//function : ProjPS
259//purpose :
260//=======================================================================
1e143abb 261GeomAPI_ProjectPointOnSurf& IntTools_Context::ProjPS(const TopoDS_Face& aF)
7fd59977 262{
263 Standard_Address anAdr;
264 GeomAPI_ProjectPointOnSurf* pProjPS;
4e57c75e 265
266 if (!myProjPSMap.IsBound(aF)) {
b285c9fe 267 Standard_Real Umin, Usup, Vmin, Vsup;
7fd59977 268 BRepAdaptor_Surface aBAS;
269 //
270 const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aF);
271 aBAS.Initialize (aF, Standard_True);
272 //
273 Umin=aBAS.FirstUParameter();
274 Usup=aBAS.LastUParameter ();
275 Vmin=aBAS.FirstVParameter();
276 Vsup=aBAS.LastVParameter ();
277 //
4e57c75e 278 pProjPS=(GeomAPI_ProjectPointOnSurf*)myAllocator->Allocate(sizeof(GeomAPI_ProjectPointOnSurf));
279 new (pProjPS) GeomAPI_ProjectPointOnSurf();
b285c9fe 280 pProjPS->Init(aS ,Umin, Usup, Vmin, Vsup, myPOnSTolerance/*, Extrema_ExtAlgo_Tree*/);
d633fd70 281 Extrema_ExtPS& anExtAlgo = const_cast<Extrema_ExtPS&>(pProjPS->Extrema());
282 anExtAlgo.SetFlag(Extrema_ExtFlag_MIN);
7fd59977 283 //
284 anAdr=(Standard_Address)pProjPS;
4e57c75e 285 myProjPSMap.Bind(aF, anAdr);
7fd59977 286 }
287
288 else {
4e57c75e 289 anAdr=myProjPSMap.Find(aF);
290 pProjPS=(GeomAPI_ProjectPointOnSurf*)anAdr;
7fd59977 291 }
292 return *pProjPS;
293}
294//=======================================================================
295//function : ProjPC
296//purpose :
297//=======================================================================
1e143abb 298GeomAPI_ProjectPointOnCurve& IntTools_Context::ProjPC(const TopoDS_Edge& aE)
7fd59977 299{
300 Standard_Address anAdr;
301 GeomAPI_ProjectPointOnCurve* pProjPC;
4e57c75e 302
303 if (!myProjPCMap.IsBound(aE)) {
7fd59977 304 Standard_Real f, l;
305 //
306 Handle(Geom_Curve)aC3D=BRep_Tool::Curve (aE, f, l);
307 //
4e57c75e 308 pProjPC=(GeomAPI_ProjectPointOnCurve*)myAllocator->Allocate(sizeof(GeomAPI_ProjectPointOnCurve));
309 new (pProjPC) GeomAPI_ProjectPointOnCurve();
7fd59977 310 pProjPC->Init(aC3D, f, l);
311 //
312 anAdr=(Standard_Address)pProjPC;
4e57c75e 313 myProjPCMap.Bind(aE, anAdr);
7fd59977 314 }
4e57c75e 315
7fd59977 316 else {
4e57c75e 317 anAdr=myProjPCMap.Find(aE);
318 pProjPC=(GeomAPI_ProjectPointOnCurve*)anAdr;
7fd59977 319 }
320 return *pProjPC;
321}
4e57c75e 322
7fd59977 323//=======================================================================
324//function : ProjPT
325//purpose :
326//=======================================================================
1e143abb 327GeomAPI_ProjectPointOnCurve& IntTools_Context::ProjPT
328 (const Handle(Geom_Curve)& aC3D)
4e57c75e 329
7fd59977 330{
331 Standard_Address anAdr;
332 GeomAPI_ProjectPointOnCurve* pProjPT;
4e57c75e 333
334 if (!myProjPTMap.IsBound(aC3D)) {
7fd59977 335 Standard_Real f, l;
336 f=aC3D->FirstParameter();
337 l=aC3D->LastParameter();
338 //
4e57c75e 339 pProjPT=(GeomAPI_ProjectPointOnCurve*)myAllocator->Allocate(sizeof(GeomAPI_ProjectPointOnCurve));
340 new (pProjPT) GeomAPI_ProjectPointOnCurve();
7fd59977 341 pProjPT->Init(aC3D, f, l);
342 //
343 anAdr=(Standard_Address)pProjPT;
4e57c75e 344 myProjPTMap.Bind(aC3D, anAdr);
7fd59977 345 }
346
347 else {
4e57c75e 348 anAdr=myProjPTMap.Find(aC3D);
349 pProjPT=(GeomAPI_ProjectPointOnCurve*)anAdr;
7fd59977 350 }
351 return *pProjPT;
352}
353//=======================================================================
4e57c75e 354//function : SolidClassifier
7fd59977 355//purpose :
356//=======================================================================
1e143abb 357BRepClass3d_SolidClassifier& IntTools_Context::SolidClassifier
358 (const TopoDS_Solid& aSolid)
7fd59977 359{
360 Standard_Address anAdr;
4e57c75e 361 BRepClass3d_SolidClassifier* pSC;
362
363 if (!mySClassMap.IsBound(aSolid)) {
7fd59977 364 //
4e57c75e 365 pSC=(BRepClass3d_SolidClassifier*)myAllocator->Allocate(sizeof(BRepClass3d_SolidClassifier));
366 new (pSC) BRepClass3d_SolidClassifier(aSolid);
7fd59977 367 //
4e57c75e 368 anAdr=(Standard_Address)pSC;
369 mySClassMap.Bind(aSolid, anAdr);
7fd59977 370 }
371
372 else {
4e57c75e 373 anAdr=mySClassMap.Find(aSolid);
374 pSC =(BRepClass3d_SolidClassifier*)anAdr;
7fd59977 375 }
4e57c75e 376 return *pSC;
7fd59977 377}
4e57c75e 378
7fd59977 379//=======================================================================
4e57c75e 380//function : Hatcher
7fd59977 381//purpose :
382//=======================================================================
1e143abb 383Geom2dHatch_Hatcher& IntTools_Context::Hatcher(const TopoDS_Face& aF)
7fd59977 384{
385 Standard_Address anAdr;
4e57c75e 386 Geom2dHatch_Hatcher* pHatcher;
cf8e963a 387 //
4e57c75e 388 if (!myHatcherMap.IsBound(aF)) {
389 Standard_Real aTolArcIntr, aTolTangfIntr, aTolHatch2D, aTolHatch3D;
390 Standard_Real aU1, aU2, aEpsT;
391 TopAbs_Orientation aOrE;
392 Handle(Geom_Surface) aS;
393 Handle(Geom2d_Curve) aC2D;
394 Handle(Geom2d_TrimmedCurve) aCT2D;
395 TopoDS_Face aFF;
396 TopExp_Explorer aExp;
7fd59977 397 //
4e57c75e 398 aTolHatch2D=1.e-8;
399 aTolHatch3D=1.e-8;
400 aTolArcIntr=1.e-10;
401 aTolTangfIntr=1.e-10;
402 aEpsT=Precision::PConfusion();
7fd59977 403 //
4e57c75e 404 Geom2dHatch_Intersector aIntr(aTolArcIntr, aTolTangfIntr);
f41525d3 405 pHatcher=(Geom2dHatch_Hatcher*)
406 myAllocator->Allocate(sizeof(Geom2dHatch_Hatcher));
407 new (pHatcher) Geom2dHatch_Hatcher(aIntr,
408 aTolHatch2D, aTolHatch3D,
409 Standard_True, Standard_False);
4e57c75e 410 //
411 aFF=aF;
412 aFF.Orientation(TopAbs_FORWARD);
413 aS=BRep_Tool::Surface(aFF);
414
415 aExp.Init (aFF, TopAbs_EDGE);
416 for (; aExp.More() ; aExp.Next()) {
417 const TopoDS_Edge& aE=*((TopoDS_Edge*)&aExp.Current());
418 aOrE=aE.Orientation();
419 //
420 aC2D=BRep_Tool::CurveOnSurface (aE, aFF, aU1, aU2);
421 if (aC2D.IsNull() ) {
422 continue;
423 }
424 if (fabs(aU1-aU2) < aEpsT) {
425 continue;
426 }
427 //
428 aCT2D=new Geom2d_TrimmedCurve(aC2D, aU1, aU2);
543a9964 429 Geom2dAdaptor_Curve aGAC (aCT2D);
430 pHatcher->AddElement(aGAC, aOrE);
4e57c75e 431 }// for (; aExp.More() ; aExp.Next()) {
432 //
433 anAdr=(Standard_Address)pHatcher;
434 myHatcherMap.Bind(aFF, anAdr);
435 }//if (!myHatcherMap.IsBound(aF)) {
436 //
437 else {
438 anAdr=myHatcherMap.Find(aF);
439 pHatcher=(Geom2dHatch_Hatcher*)anAdr;
7fd59977 440 }
4e57c75e 441
442 return *pHatcher;
443}
444
445//=======================================================================
446//function : SurfaceData
447//purpose :
448//=======================================================================
1e143abb 449IntTools_SurfaceRangeLocalizeData& IntTools_Context::SurfaceData
450 (const TopoDS_Face& aF)
4e57c75e 451{
452 Standard_Address anAdr;
453 IntTools_SurfaceRangeLocalizeData* pSData;
454 //
455 if (!myProjSDataMap.IsBound(aF)) {
f41525d3 456 pSData=(IntTools_SurfaceRangeLocalizeData*)
457 myAllocator->Allocate(sizeof(IntTools_SurfaceRangeLocalizeData));
458 new (pSData) IntTools_SurfaceRangeLocalizeData
1e143abb 459 (3,
460 3,
461 10. * Precision::PConfusion(),
462 10. * Precision::PConfusion());
4e57c75e 463 //
464 anAdr=(Standard_Address)pSData;
465 myProjSDataMap.Bind(aF, anAdr);
466 }
467
7fd59977 468 else {
4e57c75e 469 anAdr=myProjSDataMap.Find(aF);
470 pSData=(IntTools_SurfaceRangeLocalizeData*)anAdr;
7fd59977 471 }
4e57c75e 472 return *pSData;
473
7fd59977 474}
4e57c75e 475
7fd59977 476//=======================================================================
4e57c75e 477//function : ComputePE
7fd59977 478//purpose :
479//=======================================================================
1e143abb 480Standard_Integer IntTools_Context::ComputePE
481 (const gp_Pnt& aP1,
482 const Standard_Real aTolP1,
483 const TopoDS_Edge& aE2,
484 Standard_Real& aT)
7fd59977 485{
4e57c75e 486 if (!BRep_Tool::IsGeometric(aE2)) {
487 return -2;
488 }
489 Standard_Real aDist, aTolE2, aTolSum;
490 Standard_Integer aNbProj;
7fd59977 491 //
4e57c75e 492 GeomAPI_ProjectPointOnCurve& aProjector=ProjPC(aE2);
493 aProjector.Perform(aP1);
494
495 aNbProj=aProjector.NbPoints();
496 if (!aNbProj) {
497 return -3;
498 }
7fd59977 499 //
4e57c75e 500 aDist=aProjector.LowerDistance();
501 //
502 aTolE2=BRep_Tool::Tolerance(aE2);
3510db62 503 aTolSum = aTolP1 + aTolE2 + Precision::Confusion();
4e57c75e 504 //
505 aT=aProjector.LowerDistanceParameter();
506 if (aDist > aTolSum) {
507 return -4;
508 }
509 return 0;
7fd59977 510}
511//=======================================================================
512//function : ComputeVE
513//purpose :
514//=======================================================================
1e143abb 515Standard_Integer IntTools_Context::ComputeVE
516 (const TopoDS_Vertex& aV1,
517 const TopoDS_Edge& aE2,
3510db62 518 Standard_Real& aParam,
519 Standard_Real& aTolVnew)
7fd59977 520{
7fd59977 521 if (BRep_Tool::Degenerated(aE2)) {
522 return -1;
523 }
4e57c75e 524 if (!BRep_Tool::IsGeometric(aE2)) {
525 return -2;
526 }
527 Standard_Real aDist, aTolV1, aTolE2, aTolSum;
7fd59977 528 Standard_Integer aNbProj;
529 gp_Pnt aP;
530 //
531 aP=BRep_Tool::Pnt(aV1);
532 //
533 GeomAPI_ProjectPointOnCurve& aProjector=ProjPC(aE2);
534 aProjector.Perform(aP);
4e57c75e 535
7fd59977 536 aNbProj=aProjector.NbPoints();
537 if (!aNbProj) {
538 return -3;
539 }
540 //
541 aDist=aProjector.LowerDistance();
3510db62 542 //
7fd59977 543 aTolV1=BRep_Tool::Tolerance(aV1);
544 aTolE2=BRep_Tool::Tolerance(aE2);
42ff8f5b 545 aTolSum = aTolV1 + aTolE2 + Precision::Confusion();
7fd59977 546 //
3510db62 547 aTolVnew=aDist+aTolE2;
548 //
549 aParam=aProjector.LowerDistanceParameter();
7fd59977 550 if (aDist > aTolSum) {
551 return -4;
552 }
7fd59977 553 return 0;
554}
7fd59977 555//=======================================================================
3510db62 556//function : ComputeVF
7fd59977 557//purpose :
558//=======================================================================
1e143abb 559Standard_Integer IntTools_Context::ComputeVF
560 (const TopoDS_Vertex& aV1,
561 const TopoDS_Face& aF2,
562 Standard_Real& U,
3510db62 563 Standard_Real& V,
564 Standard_Real& aTolVnew)
7fd59977 565{
566 Standard_Real aTolV1, aTolF2, aTolSum, aDist;
567 gp_Pnt aP;
568
569 aP=BRep_Tool::Pnt(aV1);
570 //
571 // 1. Check if the point is projectable on the surface
572 GeomAPI_ProjectPointOnSurf& aProjector=ProjPS(aF2);
573 aProjector.Perform(aP);
574 //
4e57c75e 575 if (!aProjector.IsDone()) { // the point is not projectable on the surface
7fd59977 576 return -1;
577 }
578 //
579 // 2. Check the distance between the projection point and
580 // the original point
581 aDist=aProjector.LowerDistance();
3510db62 582 //
7fd59977 583 aTolV1=BRep_Tool::Tolerance(aV1);
584 aTolF2=BRep_Tool::Tolerance(aF2);
3510db62 585 //
586 aTolSum = aTolV1 + aTolF2 + Precision::Confusion();
587 aTolVnew = aDist + aTolF2;
588 //
7fd59977 589 if (aDist > aTolSum) {
590 // the distance is too large
591 return -2;
592 }
593 aProjector.LowerDistanceParameters(U, V);
594 //
595 gp_Pnt2d aP2d(U, V);
596 Standard_Boolean pri=IsPointInFace (aF2, aP2d);
4e57c75e 597 if (!pri) {// the point lays on the surface but out of the face
7fd59977 598 return -3;
599 }
600 return 0;
601}
602//=======================================================================
603//function : StatePointFace
604//purpose :
605//=======================================================================
1e143abb 606TopAbs_State IntTools_Context::StatePointFace
607 (const TopoDS_Face& aF,
608 const gp_Pnt2d& aP2d)
7fd59977 609{
610 TopAbs_State aState;
611 IntTools_FClass2d& aClass2d=FClass2d(aF);
612 aState=aClass2d.Perform(aP2d);
613 return aState;
614}
615//=======================================================================
616//function : IsPointInFace
617//purpose :
618//=======================================================================
1e143abb 619Standard_Boolean IntTools_Context::IsPointInFace
620 (const TopoDS_Face& aF,
621 const gp_Pnt2d& aP2d)
7fd59977 622{
623 TopAbs_State aState=StatePointFace(aF, aP2d);
624 if (aState==TopAbs_OUT || aState==TopAbs_ON) {
625 return Standard_False;
626 }
627 return Standard_True;
628}
629//=======================================================================
bd28b2af 630//function : IsPointInFace
631//purpose :
632//=======================================================================
633Standard_Boolean IntTools_Context::IsPointInFace
634 (const gp_Pnt& aP,
635 const TopoDS_Face& aF,
636 const Standard_Real aTol)
637{
638 Standard_Boolean bIn;
639 Standard_Real aDist;
640 //
641 GeomAPI_ProjectPointOnSurf& aProjector=ProjPS(aF);
642 aProjector.Perform(aP);
643 //
644 bIn = aProjector.IsDone();
645 if (bIn) {
646 aDist = aProjector.LowerDistance();
647 if (aDist < aTol) {
648 Standard_Real U, V;
649 //
650 aProjector.LowerDistanceParameters(U, V);
651 gp_Pnt2d aP2D(U, V);
652 bIn = IsPointInFace(aF, aP2D);
653 }
654 }
655 //
656 return bIn;
657}
658//=======================================================================
7fd59977 659//function : IsPointInOnFace
660//purpose :
661//=======================================================================
1e143abb 662 Standard_Boolean IntTools_Context::IsPointInOnFace(const TopoDS_Face& aF,
4e57c75e 663 const gp_Pnt2d& aP2d)
7fd59977 664{
665 TopAbs_State aState=StatePointFace(aF, aP2d);
666 if (aState==TopAbs_OUT) {
667 return Standard_False;
668 }
669 return Standard_True;
670}
671//=======================================================================
672//function : IsValidPointForFace
673//purpose :
674//=======================================================================
1e143abb 675Standard_Boolean IntTools_Context::IsValidPointForFace
676 (const gp_Pnt& aP,
677 const TopoDS_Face& aF,
678 const Standard_Real aTol)
7fd59977 679{
680 Standard_Boolean bFlag;
96a95605 681 Standard_Real Umin, U, V;
7fd59977 682
683 GeomAPI_ProjectPointOnSurf& aProjector=ProjPS(aF);
684 aProjector.Perform(aP);
685
686 bFlag=aProjector.IsDone();
687 if (bFlag) {
688
689 Umin=aProjector.LowerDistance();
690 //if (Umin > 1.e-3) { // it was
691 if (Umin > aTol) {
692 return !bFlag;
693 }
694 //
695 aProjector.LowerDistanceParameters(U, V);
696 gp_Pnt2d aP2D(U, V);
697 bFlag=IsPointInOnFace (aF, aP2D);
698 }
699 return bFlag;
700}
701//=======================================================================
702//function : IsValidPointForFaces
703//purpose :
704//=======================================================================
1e143abb 705Standard_Boolean IntTools_Context::IsValidPointForFaces
706 (const gp_Pnt& aP,
707 const TopoDS_Face& aF1,
708 const TopoDS_Face& aF2,
709 const Standard_Real aTol)
7fd59977 710{
711 Standard_Boolean bFlag1, bFlag2;
712
713 bFlag1=IsValidPointForFace(aP, aF1, aTol);
714 if (!bFlag1) {
715 return bFlag1;
716 }
717 bFlag2=IsValidPointForFace(aP, aF2, aTol);
718 return bFlag2;
719}
720//=======================================================================
721//function : IsValidBlockForFace
722//purpose :
723//=======================================================================
1e143abb 724Standard_Boolean IntTools_Context::IsValidBlockForFace
725 (const Standard_Real aT1,
726 const Standard_Real aT2,
727 const IntTools_Curve& aC,
728 const TopoDS_Face& aF,
729 const Standard_Real aTol)
7fd59977 730{
731 Standard_Boolean bFlag;
96a95605 732 Standard_Real aTInterm;
7fd59977 733 gp_Pnt aPInterm;
734
735 aTInterm=IntTools_Tools::IntermediatePoint(aT1, aT2);
736
737 Handle(Geom_Curve) aC3D=aC.Curve();
7fd59977 738 // point 3D
739 aC3D->D0(aTInterm, aPInterm);
740 //
741 bFlag=IsValidPointForFace (aPInterm, aF, aTol);
742 return bFlag;
743}
744//=======================================================================
745//function : IsValidBlockForFaces
746//purpose :
747//=======================================================================
1e143abb 748Standard_Boolean IntTools_Context::IsValidBlockForFaces
749 (const Standard_Real aT1,
750 const Standard_Real aT2,
751 const IntTools_Curve& aC,
752 const TopoDS_Face& aF1,
753 const TopoDS_Face& aF2,
754 const Standard_Real aTol)
7fd59977 755{
756 Standard_Boolean bFlag1, bFlag2;
757 //
758 Handle(Geom2d_Curve) aPC1 = aC.FirstCurve2d();
759 Handle(Geom2d_Curve) aPC2 = aC.SecondCurve2d();
760 if( !aPC1.IsNull() && !aPC2.IsNull() ) {
761 Standard_Real aMidPar = IntTools_Tools::IntermediatePoint(aT1, aT2);
762 gp_Pnt2d aPnt2D;
763
764
765 aPC1->D0(aMidPar, aPnt2D);
766 bFlag1 = IsPointInOnFace(aF1, aPnt2D);
767
768 if( !bFlag1 )
769 return bFlag1;
770
771 aPC2->D0(aMidPar, aPnt2D);
772 bFlag2 = IsPointInOnFace(aF2, aPnt2D);
773 return bFlag2;
774 }
775 //
776
777 bFlag1=IsValidBlockForFace (aT1, aT2, aC, aF1, aTol);
778 if (!bFlag1) {
779 return bFlag1;
780 }
781 bFlag2=IsValidBlockForFace (aT1, aT2, aC, aF2, aTol);
782 return bFlag2;
783}
784//=======================================================================
785//function : IsVertexOnLine
786//purpose :
787//=======================================================================
1e143abb 788Standard_Boolean IntTools_Context::IsVertexOnLine
789 (const TopoDS_Vertex& aV,
790 const IntTools_Curve& aC,
791 const Standard_Real aTolC,
792 Standard_Real& aT)
7fd59977 793{
794 Standard_Boolean bRet;
795 Standard_Real aTolV;
796 //
797 aTolV=BRep_Tool::Tolerance(aV);
1e143abb 798 bRet=IntTools_Context::IsVertexOnLine(aV, aTolV, aC, aTolC , aT);
7fd59977 799 //
800 return bRet;
801}
802//=======================================================================
803//function : IsVertexOnLine
804//purpose :
805//=======================================================================
1e143abb 806Standard_Boolean IntTools_Context::IsVertexOnLine
807 (const TopoDS_Vertex& aV,
808 const Standard_Real aTolV,
809 const IntTools_Curve& aC,
810 const Standard_Real aTolC,
811 Standard_Real& aT)
7fd59977 812{
813 Standard_Real aFirst, aLast, aDist, aTolSum;
814 Standard_Integer aNbProj;
815 gp_Pnt aPv;
816
817 aPv=BRep_Tool::Pnt(aV);
818
819 Handle(Geom_Curve) aC3D=aC.Curve();
820
821
822 aTolSum=aTolV+aTolC;
823 //
824 GeomAdaptor_Curve aGAC(aC3D);
825 GeomAbs_CurveType aType=aGAC.GetType();
826 if (aType==GeomAbs_BSplineCurve ||
827 aType==GeomAbs_BezierCurve) {
828 aTolSum=2.*aTolSum;
829 if (aTolSum<1.e-5) {
830 aTolSum=1.e-5;
831 }
832 }
833 else {
834 aTolSum=2.*aTolSum;//xft
835 if(aTolSum < 1.e-6)
836 aTolSum = 1.e-6;
837 }
838 //
839 aFirst=aC3D->FirstParameter();
840 aLast =aC3D->LastParameter();
841 //
842 //Checking extermities first
843 if (!Precision::IsInfinite(aFirst)) {
844 gp_Pnt aPCFirst=aC3D->Value(aFirst);
845 aDist=aPv.Distance(aPCFirst);
846 if (aDist < aTolSum) {
847 aT=aFirst;
848 //
849 if(aDist > aTolV) {
4e57c75e 850 Extrema_LocateExtPC anExt(aPv, aGAC, aFirst, 1.e-10);
851
852 if(anExt.IsDone()) {
853 Extrema_POnCurv aPOncurve = anExt.Point();
854 aT = aPOncurve.Parameter();
855
856 if((aT > (aLast + aFirst) * 0.5) ||
857 (aPv.Distance(aPOncurve.Value()) > aTolSum) ||
858 (aPCFirst.Distance(aPOncurve.Value()) < Precision::Confusion()))
859 aT = aFirst;
860 }
4e14c88f 861 else
862 {
863 // Local search may fail. Try to use more precise algo.
c7854818 864 Extrema_ExtPC anExt2(aPv, aGAC, 1.e-10);
4e14c88f 865 Standard_Real aMinDist = RealLast();
866 Standard_Integer aMinIdx = -1;
3510db62 867 if (anExt2.IsDone()) {
868 for (Standard_Integer anIdx = 1; anIdx <= anExt2.NbExt(); anIdx++)
869 {
870 if ( anExt2.IsMin(anIdx) &&
871 anExt2.SquareDistance(anIdx) < aMinDist )
4e14c88f 872 {
c7854818 873 aMinDist = anExt2.SquareDistance(anIdx);
4e14c88f 874 aMinIdx = anIdx;
875 }
3510db62 876 }
4e14c88f 877 }
878 if (aMinIdx != -1)
879 {
c7854818 880 const Extrema_POnCurv& aPOncurve = anExt2.Point(aMinIdx);
4e14c88f 881 aT = aPOncurve.Parameter();
882
883 if((aT > (aLast + aFirst) * 0.5) ||
884 (aPv.Distance(aPOncurve.Value()) > aTolSum) ||
885 (aPCFirst.Distance(aPOncurve.Value()) < Precision::Confusion()))
886 aT = aFirst;
887 }
888 }
889
7fd59977 890 }
891 //
892 return Standard_True;
893 }
894 }
895 //
4e57c75e 896 //if (!Precision::IsInfinite(aFirst)) {
7fd59977 897 if (!Precision::IsInfinite(aLast)) {
898 gp_Pnt aPCLast=aC3D->Value(aLast);
899 aDist=aPv.Distance(aPCLast);
900 if (aDist < aTolSum) {
901 aT=aLast;
902 //
903 if(aDist > aTolV) {
4e57c75e 904 Extrema_LocateExtPC anExt(aPv, aGAC, aLast, 1.e-10);
905
906 if(anExt.IsDone()) {
907 Extrema_POnCurv aPOncurve = anExt.Point();
908 aT = aPOncurve.Parameter();
909
910 if((aT < (aLast + aFirst) * 0.5) ||
911 (aPv.Distance(aPOncurve.Value()) > aTolSum) ||
912 (aPCLast.Distance(aPOncurve.Value()) < Precision::Confusion()))
913 aT = aLast;
914 }
4e14c88f 915 else
916 {
917 // Local search may fail. Try to use more precise algo.
c7854818 918 Extrema_ExtPC anExt2(aPv, aGAC, 1.e-10);
4e14c88f 919 Standard_Real aMinDist = RealLast();
920 Standard_Integer aMinIdx = -1;
3510db62 921 if (anExt2.IsDone()) {
922 for (Standard_Integer anIdx = 1; anIdx <= anExt2.NbExt(); anIdx++)
923 {
924 if ( anExt2.IsMin(anIdx) &&
925 anExt2.SquareDistance(anIdx) < aMinDist )
4e14c88f 926 {
c7854818 927 aMinDist = anExt2.SquareDistance(anIdx);
4e14c88f 928 aMinIdx = anIdx;
929 }
3510db62 930 }
4e14c88f 931 }
932 if (aMinIdx != -1)
933 {
c7854818 934 const Extrema_POnCurv& aPOncurve = anExt2.Point(aMinIdx);
4e14c88f 935 aT = aPOncurve.Parameter();
936
937 if((aT < (aLast + aFirst) * 0.5) ||
938 (aPv.Distance(aPOncurve.Value()) > aTolSum) ||
939 (aPCLast.Distance(aPOncurve.Value()) < Precision::Confusion()))
940 aT = aLast;
941 }
942 }
7fd59977 943 }
944 //
945 return Standard_True;
946 }
947 }
948 //
949 GeomAPI_ProjectPointOnCurve& aProjector=ProjPT(aC3D);
950 aProjector.Perform(aPv);
951
952 aNbProj=aProjector.NbPoints();
953 if (!aNbProj) {
954 Handle(Geom_BoundedCurve) aBC=
955 Handle(Geom_BoundedCurve)::DownCast(aC3D);
956 if (!aBC.IsNull()) {
957 gp_Pnt aPStart=aBC->StartPoint();
958 gp_Pnt aPEnd =aBC->EndPoint();
959
960 aDist=aPv.Distance(aPStart);
961 if (aDist < aTolSum) {
4e57c75e 962 aT=aFirst;
963 return Standard_True;
7fd59977 964 }
965
966 aDist=aPv.Distance(aPEnd);
967 if (aDist < aTolSum) {
4e57c75e 968 aT=aLast;
969 return Standard_True;
7fd59977 970 }
971 }
972
973 return Standard_False;
974 }
975
976 aDist=aProjector.LowerDistance();
977
978 if (aDist > aTolSum) {
979 return Standard_False;
980 }
981
982 aT=aProjector.LowerDistanceParameter();
983
984 return Standard_True;
985}
986//=======================================================================
987//function : ProjectPointOnEdge
988//purpose :
989//=======================================================================
1e143abb 990Standard_Boolean IntTools_Context::ProjectPointOnEdge
991 (const gp_Pnt& aP,
992 const TopoDS_Edge& anEdge,
993 Standard_Real& aT)
7fd59977 994{
995 Standard_Integer aNbPoints;
996
997 GeomAPI_ProjectPointOnCurve& aProjector=ProjPC(anEdge);
998 aProjector.Perform(aP);
999
1000 aNbPoints=aProjector.NbPoints();
1001 if (aNbPoints) {
1002 aT=aProjector.LowerDistanceParameter();
1003 return Standard_True;
1004 }
1005 return Standard_False;
1006}
1007
b285c9fe 1008//=======================================================================
1009//function : SetPOnSProjectionTolerance
1010//purpose :
1011//=======================================================================
1012void IntTools_Context::SetPOnSProjectionTolerance(const Standard_Real theValue)
1013{
1014 myPOnSTolerance = theValue;
1015 clearCachedPOnSProjectors();
1016}
1017
1018//=======================================================================
1019//function : clearCachedPOnSProjectors
1020//purpose :
1021//=======================================================================
1022void IntTools_Context::clearCachedPOnSProjectors()
1023{
1024 GeomAPI_ProjectPointOnSurf* pProjPS;
1025 BOPCol_DataMapIteratorOfDataMapOfShapeAddress aIt(myProjPSMap);
1026 for (; aIt.More(); aIt.Next()) {
1027 Standard_Address anAdr=aIt.Value();
1028 pProjPS=(GeomAPI_ProjectPointOnSurf*)anAdr;
1029 (*pProjPS).~GeomAPI_ProjectPointOnSurf();
1030 myAllocator->Free(anAdr);
1031 }
1032 myProjPSMap.Clear();
1033}