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