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