0029968: Modeling Algorithms - BRepAlgoAPI_Cut produces an empty result with half...
[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>
944768d2 17#include <Bnd_OBB.hxx>
7fd59977 18#include <BRep_Tool.hxx>
19#include <BRepAdaptor_Surface.hxx>
f47b8d2b 20#include <BRepBndLib.hxx>
42cf5bc1 21#include <BRepClass3d_SolidClassifier.hxx>
7fd59977 22#include <Extrema_LocateExtPC.hxx>
7fd59977 23#include <Geom2d_Curve.hxx>
42cf5bc1 24#include <Geom2d_TrimmedCurve.hxx>
25#include <Geom2dHatch_Hatcher.hxx>
26#include <Geom2dHatch_Intersector.hxx>
27#include <Geom_BoundedCurve.hxx>
28#include <Geom_Curve.hxx>
29#include <GeomAdaptor_Curve.hxx>
30#include <GeomAPI_ProjectPointOnCurve.hxx>
31#include <GeomAPI_ProjectPointOnSurf.hxx>
32#include <gp_Pnt.hxx>
33#include <gp_Pnt2d.hxx>
34#include <IntTools_Context.hxx>
35#include <IntTools_Curve.hxx>
36#include <IntTools_FClass2d.hxx>
4e57c75e 37#include <IntTools_SurfaceRangeLocalizeData.hxx>
42cf5bc1 38#include <IntTools_Tools.hxx>
42cf5bc1 39#include <Precision.hxx>
40#include <Standard_Type.hxx>
41#include <TopAbs_State.hxx>
42#include <TopExp_Explorer.hxx>
43#include <TopoDS.hxx>
44#include <TopoDS_Edge.hxx>
45#include <TopoDS_Face.hxx>
46#include <TopoDS_Shape.hxx>
47#include <TopoDS_Solid.hxx>
48#include <TopoDS_Vertex.hxx>
4e57c75e 49
51db0179 50IMPLEMENT_STANDARD_RTTIEXT(IntTools_Context,Standard_Transient)
92efcf78 51
42cf5bc1 52//
7fd59977 53//=======================================================================
54//function :
55//purpose :
56//=======================================================================
1e143abb 57IntTools_Context::IntTools_Context()
4e57c75e 58:
488e5b9d 59 myAllocator(NCollection_BaseAllocator::CommonBaseAllocator()),
4e57c75e 60 myFClass2dMap(100, myAllocator),
61 myProjPSMap(100, myAllocator),
62 myProjPCMap(100, myAllocator),
63 mySClassMap(100, myAllocator),
64 myProjPTMap(100, myAllocator),
65 myHatcherMap(100, myAllocator),
66 myProjSDataMap(100, myAllocator),
f47b8d2b 67 myBndBoxDataMap(100, myAllocator),
51db0179 68 mySurfAdaptorMap(100, myAllocator),
944768d2 69 myOBBMap(100, myAllocator),
b285c9fe 70 myCreateFlag(0),
71 myPOnSTolerance(1.e-12)
4e57c75e 72{
73}
74//=======================================================================
75//function :
76//purpose :
77//=======================================================================
1e143abb 78IntTools_Context::IntTools_Context
79 (const Handle(NCollection_BaseAllocator)& theAllocator)
4e57c75e 80:
81 myAllocator(theAllocator),
82 myFClass2dMap(100, myAllocator),
83 myProjPSMap(100, myAllocator),
84 myProjPCMap(100, myAllocator),
85 mySClassMap(100, myAllocator),
86 myProjPTMap(100, myAllocator),
87 myHatcherMap(100, myAllocator),
88 myProjSDataMap(100, myAllocator),
f47b8d2b 89 myBndBoxDataMap(100, myAllocator),
51db0179 90 mySurfAdaptorMap(100, myAllocator),
944768d2 91 myOBBMap(100, myAllocator),
b285c9fe 92 myCreateFlag(1),
93 myPOnSTolerance(1.e-12)
7fd59977 94{
95}
96//=======================================================================
97//function : ~
98//purpose :
99//=======================================================================
1e143abb 100IntTools_Context::~IntTools_Context()
7fd59977 101{
102 Standard_Address anAdr;
1155d05a 103 DataMapOfShapeAddress::Iterator aIt;
104 DataMapOfTransientAddress::Iterator aIt1;
3f524765 105 //
7fd59977 106 IntTools_FClass2d* pFClass2d;
4e57c75e 107 //
108 aIt.Initialize(myFClass2dMap);
109 for (; aIt.More(); aIt.Next()) {
110 anAdr=aIt.Value();
7fd59977 111 pFClass2d=(IntTools_FClass2d*)anAdr;
4e57c75e 112 (*pFClass2d).~IntTools_FClass2d();
113 myAllocator->Free(anAdr);
7fd59977 114 }
115 myFClass2dMap.Clear();
116 //
b285c9fe 117 clearCachedPOnSProjectors();
7fd59977 118 //
119 GeomAPI_ProjectPointOnCurve* pProjPC;
4e57c75e 120 aIt.Initialize(myProjPCMap);
121 for (; aIt.More(); aIt.Next()) {
122 anAdr=aIt.Value();
7fd59977 123 pProjPC=(GeomAPI_ProjectPointOnCurve*)anAdr;
4e57c75e 124 (*pProjPC).~GeomAPI_ProjectPointOnCurve();
125 myAllocator->Free(anAdr);
7fd59977 126 }
127 myProjPCMap.Clear();
128 //
4e57c75e 129 //
130 BRepClass3d_SolidClassifier* pSC;
131 aIt.Initialize(mySClassMap);
132 for (; aIt.More(); aIt.Next()) {
133 anAdr=aIt.Value();
134 pSC=(BRepClass3d_SolidClassifier*)anAdr;
135 (*pSC).~BRepClass3d_SolidClassifier();
136 myAllocator->Free(anAdr);
137 }
138 mySClassMap.Clear();
139 //
7fd59977 140 GeomAPI_ProjectPointOnCurve* pProjPT;
4e57c75e 141 aIt1.Initialize(myProjPTMap);
142 for (; aIt1.More(); aIt1.Next()) {
143 anAdr=aIt1.Value();
7fd59977 144 pProjPT=(GeomAPI_ProjectPointOnCurve*)anAdr;
4e57c75e 145 (*pProjPT).~GeomAPI_ProjectPointOnCurve();
146 myAllocator->Free(anAdr);
7fd59977 147 }
148 myProjPTMap.Clear();
149 //
4e57c75e 150 Geom2dHatch_Hatcher* pHatcher;
151 aIt.Initialize(myHatcherMap);
152 for (; aIt.More(); aIt.Next()) {
153 anAdr=aIt.Value();
154 pHatcher=(Geom2dHatch_Hatcher*)anAdr;
155 (*pHatcher).~Geom2dHatch_Hatcher();
156 myAllocator->Free(anAdr);
7fd59977 157 }
4e57c75e 158 myHatcherMap.Clear();
7fd59977 159 //
160 IntTools_SurfaceRangeLocalizeData* pSData = NULL;
4e57c75e 161 aIt.Initialize(myProjSDataMap);
162 for (; aIt.More(); aIt.Next()) {
163 anAdr=aIt.Value();
7fd59977 164 pSData = (IntTools_SurfaceRangeLocalizeData*)anAdr;
4e57c75e 165 (*pSData).~IntTools_SurfaceRangeLocalizeData();
166 myAllocator->Free(anAdr);
7fd59977 167 }
168 myProjSDataMap.Clear();
f47b8d2b 169 //
170 Bnd_Box* pBox;
171 aIt.Initialize(myBndBoxDataMap);
172 for (; aIt.More(); aIt.Next()) {
173 anAdr=aIt.Value();
174 pBox=(Bnd_Box*)anAdr;
175 (*pBox).~Bnd_Box();
176 myAllocator->Free(anAdr);
177 }
178 myBndBoxDataMap.Clear();
51db0179 179 //
180 BRepAdaptor_Surface* pSurfAdaptor;
181 aIt.Initialize(mySurfAdaptorMap);
182 for (; aIt.More(); aIt.Next()) {
183 anAdr=aIt.Value();
184 pSurfAdaptor=(BRepAdaptor_Surface*)anAdr;
185 (*pSurfAdaptor).~BRepAdaptor_Surface();
186 myAllocator->Free(anAdr);
187 }
188 mySurfAdaptorMap.Clear();
944768d2 189 //
190 Bnd_OBB* pOBB;
191 aIt.Initialize(myOBBMap);
192 for (; aIt.More(); aIt.Next()) {
193 anAdr=aIt.Value();
194 pOBB=(Bnd_OBB*)anAdr;
195 (*pOBB).~Bnd_OBB();
196 myAllocator->Free(anAdr);
197 }
198 myOBBMap.Clear();
f47b8d2b 199}
200//=======================================================================
201//function : BndBox
202//purpose :
203//=======================================================================
204Bnd_Box& IntTools_Context::BndBox(const TopoDS_Shape& aS)
205{
206 Standard_Address anAdr;
207 Bnd_Box* pBox;
208 //
209 if (!myBndBoxDataMap.IsBound(aS)) {
210 //
211 pBox=(Bnd_Box*)myAllocator->Allocate(sizeof(Bnd_Box));
212 new (pBox) Bnd_Box();
213 //
214 Bnd_Box &aBox=*pBox;
215 BRepBndLib::Add(aS, aBox);
216 //
217 anAdr=(Standard_Address)pBox;
218 myBndBoxDataMap.Bind(aS, anAdr);
219 }
220 else {
221 anAdr=myBndBoxDataMap.Find(aS);
222 pBox=(Bnd_Box*)anAdr;
223 }
224 return *pBox;
225}
226//=======================================================================
227//function : IsInfiniteFace
228//purpose :
229//=======================================================================
230Standard_Boolean IntTools_Context::IsInfiniteFace
231 (const TopoDS_Face& aFace)
232{
ae276302 233 const Bnd_Box& aBox = BndBox(aFace);
234 return aBox.IsOpenXmax() ||
235 aBox.IsOpenXmin() ||
236 aBox.IsOpenYmax() ||
237 aBox.IsOpenYmin() ||
238 aBox.IsOpenZmax() ||
239 aBox.IsOpenZmin();
7fd59977 240}
241//=======================================================================
242//function : FClass2d
243//purpose :
244//=======================================================================
1e143abb 245IntTools_FClass2d& IntTools_Context::FClass2d(const TopoDS_Face& aF)
7fd59977 246{
247 Standard_Address anAdr;
248 IntTools_FClass2d* pFClass2d;
cf8e963a 249 //
4e57c75e 250 if (!myFClass2dMap.IsBound(aF)) {
7fd59977 251 Standard_Real aTolF;
4e57c75e 252 TopoDS_Face aFF;
253 //
254 aFF=aF;
7fd59977 255 aFF.Orientation(TopAbs_FORWARD);
256 aTolF=BRep_Tool::Tolerance(aFF);
257 //
4e57c75e 258 pFClass2d=(IntTools_FClass2d*)myAllocator->Allocate(sizeof(IntTools_FClass2d));
259 new (pFClass2d) IntTools_FClass2d(aFF, aTolF);
7fd59977 260 //
261 anAdr=(Standard_Address)pFClass2d;
4e57c75e 262 myFClass2dMap.Bind(aFF, anAdr);
7fd59977 263 }
7fd59977 264 else {
4e57c75e 265 anAdr=myFClass2dMap.Find(aF);
266 pFClass2d=(IntTools_FClass2d*)anAdr;
7fd59977 267 }
7fd59977 268 return *pFClass2d;
269}
270//=======================================================================
271//function : ProjPS
272//purpose :
273//=======================================================================
1e143abb 274GeomAPI_ProjectPointOnSurf& IntTools_Context::ProjPS(const TopoDS_Face& aF)
7fd59977 275{
276 Standard_Address anAdr;
277 GeomAPI_ProjectPointOnSurf* pProjPS;
4e57c75e 278
279 if (!myProjPSMap.IsBound(aF)) {
b285c9fe 280 Standard_Real Umin, Usup, Vmin, Vsup;
51db0179 281 UVBounds(aF, Umin, Usup, Vmin, Vsup);
7fd59977 282 const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aF);
7fd59977 283 //
4e57c75e 284 pProjPS=(GeomAPI_ProjectPointOnSurf*)myAllocator->Allocate(sizeof(GeomAPI_ProjectPointOnSurf));
285 new (pProjPS) GeomAPI_ProjectPointOnSurf();
7868210d 286 pProjPS->Init(aS ,Umin, Usup, Vmin, Vsup, myPOnSTolerance);
287 pProjPS->SetExtremaFlag(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
944768d2 476//=======================================================================
477//function : OBB
478//purpose :
479//=======================================================================
480Bnd_OBB& IntTools_Context::OBB(const TopoDS_Shape& aS,
481 const Standard_Real theGap)
482{
483 Standard_Address anAdr;
484 Bnd_OBB* pBox;
485 //
486 if (!myOBBMap.IsBound(aS))
487 {
488 pBox = (Bnd_OBB*)myAllocator->Allocate(sizeof(Bnd_OBB));
489 new (pBox) Bnd_OBB();
490 //
491 Bnd_OBB &aBox = *pBox;
492 BRepBndLib::AddOBB(aS, aBox);
493 aBox.Enlarge(theGap);
494 //
495 anAdr = (Standard_Address)pBox;
496 myOBBMap.Bind(aS, anAdr);
497 }
498 else
499 {
500 anAdr = myOBBMap.Find(aS);
501 pBox = (Bnd_OBB*)anAdr;
502 }
503 return *pBox;
504}
505
4e57c75e 506//=======================================================================
507//function : SurfaceData
508//purpose :
509//=======================================================================
1e143abb 510IntTools_SurfaceRangeLocalizeData& IntTools_Context::SurfaceData
511 (const TopoDS_Face& aF)
4e57c75e 512{
513 Standard_Address anAdr;
514 IntTools_SurfaceRangeLocalizeData* pSData;
515 //
516 if (!myProjSDataMap.IsBound(aF)) {
f41525d3 517 pSData=(IntTools_SurfaceRangeLocalizeData*)
518 myAllocator->Allocate(sizeof(IntTools_SurfaceRangeLocalizeData));
519 new (pSData) IntTools_SurfaceRangeLocalizeData
1e143abb 520 (3,
521 3,
522 10. * Precision::PConfusion(),
523 10. * Precision::PConfusion());
4e57c75e 524 //
525 anAdr=(Standard_Address)pSData;
526 myProjSDataMap.Bind(aF, anAdr);
527 }
528
7fd59977 529 else {
4e57c75e 530 anAdr=myProjSDataMap.Find(aF);
531 pSData=(IntTools_SurfaceRangeLocalizeData*)anAdr;
7fd59977 532 }
4e57c75e 533 return *pSData;
534
7fd59977 535}
4e57c75e 536
7fd59977 537//=======================================================================
4e57c75e 538//function : ComputePE
7fd59977 539//purpose :
540//=======================================================================
1e143abb 541Standard_Integer IntTools_Context::ComputePE
542 (const gp_Pnt& aP1,
543 const Standard_Real aTolP1,
544 const TopoDS_Edge& aE2,
05cf4d98 545 Standard_Real& aT,
546 Standard_Real& aDist)
7fd59977 547{
4e57c75e 548 if (!BRep_Tool::IsGeometric(aE2)) {
549 return -2;
550 }
05cf4d98 551 Standard_Real aTolE2, aTolSum;
4e57c75e 552 Standard_Integer aNbProj;
7fd59977 553 //
4e57c75e 554 GeomAPI_ProjectPointOnCurve& aProjector=ProjPC(aE2);
555 aProjector.Perform(aP1);
556
557 aNbProj=aProjector.NbPoints();
24542bc0 558 if (aNbProj)
559 {
560 // point falls on the curve
561 aDist = aProjector.LowerDistance();
562 //
563 aTolE2 = BRep_Tool::Tolerance(aE2);
564 aTolSum = aTolP1 + aTolE2 + Precision::Confusion();
565 //
566 aT = aProjector.LowerDistanceParameter();
567 if (aDist > aTolSum) {
568 return -4;
569 }
4e57c75e 570 }
24542bc0 571 else
572 {
573 // point falls out of the curve, check distance to vertices
574 TopoDS_Edge aEFwd = TopoDS::Edge(aE2.Oriented(TopAbs_FORWARD));
575 TopoDS_Iterator itV(aEFwd);
576 aDist = RealLast();
577 for (; itV.More(); itV.Next())
578 {
579 const TopoDS_Vertex& aV = TopoDS::Vertex(itV.Value());
580 if (aV.Orientation() == TopAbs_FORWARD || aV.Orientation() == TopAbs_REVERSED)
581 {
582 gp_Pnt aPV = BRep_Tool::Pnt(aV);
583 aTolSum = aTolP1 + BRep_Tool::Tolerance(aV) + Precision::Confusion();
584 Standard_Real aDist1 = aP1.SquareDistance(aPV);
585 if (aDist1 < aDist && aDist1 < Square(aTolSum))
586 {
587 aDist = aDist1;
588 aT = BRep_Tool::Parameter(aV, aEFwd);
589 }
590 }
591 }
592 if (Precision::IsInfinite(aDist)) {
593 return -3;
594 }
4e57c75e 595 }
596 return 0;
7fd59977 597}
598//=======================================================================
599//function : ComputeVE
600//purpose :
601//=======================================================================
1e143abb 602Standard_Integer IntTools_Context::ComputeVE
0d0481c7 603 (const TopoDS_Vertex& theV,
604 const TopoDS_Edge& theE,
605 Standard_Real& theT,
606 Standard_Real& theTol,
607 const Standard_Real theFuzz)
7fd59977 608{
0d0481c7 609 if (BRep_Tool::Degenerated(theE)) {
7fd59977 610 return -1;
611 }
0d0481c7 612 if (!BRep_Tool::IsGeometric(theE)) {
4e57c75e 613 return -2;
614 }
0d0481c7 615 Standard_Real aDist, aTolV, aTolE, aTolSum;
7fd59977 616 Standard_Integer aNbProj;
617 gp_Pnt aP;
618 //
0d0481c7 619 aP=BRep_Tool::Pnt(theV);
7fd59977 620 //
0d0481c7 621 GeomAPI_ProjectPointOnCurve& aProjector=ProjPC(theE);
7fd59977 622 aProjector.Perform(aP);
4e57c75e 623
7fd59977 624 aNbProj=aProjector.NbPoints();
625 if (!aNbProj) {
626 return -3;
627 }
628 //
629 aDist=aProjector.LowerDistance();
3510db62 630 //
0d0481c7 631 aTolV=BRep_Tool::Tolerance(theV);
632 aTolE=BRep_Tool::Tolerance(theE);
633 aTolSum = aTolV + aTolE + Max(theFuzz, Precision::Confusion());
7fd59977 634 //
0d0481c7 635 theTol = aDist + aTolE;
636 theT = aProjector.LowerDistanceParameter();
7fd59977 637 if (aDist > aTolSum) {
638 return -4;
639 }
7fd59977 640 return 0;
641}
7fd59977 642//=======================================================================
3510db62 643//function : ComputeVF
7fd59977 644//purpose :
645//=======================================================================
1e143abb 646Standard_Integer IntTools_Context::ComputeVF
0d0481c7 647 (const TopoDS_Vertex& theVertex,
648 const TopoDS_Face& theFace,
649 Standard_Real& theU,
650 Standard_Real& theV,
651 Standard_Real& theTol,
652 const Standard_Real theFuzz)
7fd59977 653{
0d0481c7 654 Standard_Real aTolV, aTolF, aTolSum, aDist;
7fd59977 655 gp_Pnt aP;
656
0d0481c7 657 aP = BRep_Tool::Pnt(theVertex);
7fd59977 658 //
659 // 1. Check if the point is projectable on the surface
0d0481c7 660 GeomAPI_ProjectPointOnSurf& aProjector=ProjPS(theFace);
7fd59977 661 aProjector.Perform(aP);
662 //
4e57c75e 663 if (!aProjector.IsDone()) { // the point is not projectable on the surface
7fd59977 664 return -1;
665 }
666 //
667 // 2. Check the distance between the projection point and
668 // the original point
0d0481c7 669 aDist = aProjector.LowerDistance();
3510db62 670 //
0d0481c7 671 aTolV = BRep_Tool::Tolerance(theVertex);
672 aTolF = BRep_Tool::Tolerance(theFace);
3510db62 673 //
0d0481c7 674 aTolSum = aTolV + aTolF + Max(theFuzz, Precision::Confusion());
675 theTol = aDist + aTolF;
676 aProjector.LowerDistanceParameters(theU, theV);
3510db62 677 //
7fd59977 678 if (aDist > aTolSum) {
679 // the distance is too large
680 return -2;
681 }
7fd59977 682 //
0d0481c7 683 gp_Pnt2d aP2d(theU, theV);
684 Standard_Boolean pri = IsPointInFace (theFace, aP2d);
4e57c75e 685 if (!pri) {// the point lays on the surface but out of the face
7fd59977 686 return -3;
687 }
688 return 0;
689}
690//=======================================================================
691//function : StatePointFace
692//purpose :
693//=======================================================================
1e143abb 694TopAbs_State IntTools_Context::StatePointFace
695 (const TopoDS_Face& aF,
696 const gp_Pnt2d& aP2d)
7fd59977 697{
698 TopAbs_State aState;
699 IntTools_FClass2d& aClass2d=FClass2d(aF);
700 aState=aClass2d.Perform(aP2d);
701 return aState;
702}
703//=======================================================================
704//function : IsPointInFace
705//purpose :
706//=======================================================================
1e143abb 707Standard_Boolean IntTools_Context::IsPointInFace
708 (const TopoDS_Face& aF,
709 const gp_Pnt2d& aP2d)
7fd59977 710{
711 TopAbs_State aState=StatePointFace(aF, aP2d);
712 if (aState==TopAbs_OUT || aState==TopAbs_ON) {
713 return Standard_False;
714 }
715 return Standard_True;
716}
717//=======================================================================
bd28b2af 718//function : IsPointInFace
719//purpose :
720//=======================================================================
721Standard_Boolean IntTools_Context::IsPointInFace
722 (const gp_Pnt& aP,
723 const TopoDS_Face& aF,
724 const Standard_Real aTol)
725{
726 Standard_Boolean bIn;
727 Standard_Real aDist;
728 //
729 GeomAPI_ProjectPointOnSurf& aProjector=ProjPS(aF);
730 aProjector.Perform(aP);
731 //
732 bIn = aProjector.IsDone();
733 if (bIn) {
734 aDist = aProjector.LowerDistance();
735 if (aDist < aTol) {
736 Standard_Real U, V;
737 //
738 aProjector.LowerDistanceParameters(U, V);
739 gp_Pnt2d aP2D(U, V);
740 bIn = IsPointInFace(aF, aP2D);
741 }
742 }
743 //
744 return bIn;
745}
746//=======================================================================
7fd59977 747//function : IsPointInOnFace
748//purpose :
749//=======================================================================
1e143abb 750 Standard_Boolean IntTools_Context::IsPointInOnFace(const TopoDS_Face& aF,
4e57c75e 751 const gp_Pnt2d& aP2d)
7fd59977 752{
753 TopAbs_State aState=StatePointFace(aF, aP2d);
754 if (aState==TopAbs_OUT) {
755 return Standard_False;
756 }
757 return Standard_True;
758}
759//=======================================================================
760//function : IsValidPointForFace
761//purpose :
762//=======================================================================
1e143abb 763Standard_Boolean IntTools_Context::IsValidPointForFace
764 (const gp_Pnt& aP,
765 const TopoDS_Face& aF,
766 const Standard_Real aTol)
7fd59977 767{
768 Standard_Boolean bFlag;
96a95605 769 Standard_Real Umin, U, V;
7fd59977 770
771 GeomAPI_ProjectPointOnSurf& aProjector=ProjPS(aF);
772 aProjector.Perform(aP);
773
774 bFlag=aProjector.IsDone();
775 if (bFlag) {
776
777 Umin=aProjector.LowerDistance();
778 //if (Umin > 1.e-3) { // it was
779 if (Umin > aTol) {
780 return !bFlag;
781 }
782 //
783 aProjector.LowerDistanceParameters(U, V);
784 gp_Pnt2d aP2D(U, V);
785 bFlag=IsPointInOnFace (aF, aP2D);
786 }
787 return bFlag;
788}
789//=======================================================================
790//function : IsValidPointForFaces
791//purpose :
792//=======================================================================
1e143abb 793Standard_Boolean IntTools_Context::IsValidPointForFaces
794 (const gp_Pnt& aP,
795 const TopoDS_Face& aF1,
796 const TopoDS_Face& aF2,
797 const Standard_Real aTol)
7fd59977 798{
799 Standard_Boolean bFlag1, bFlag2;
800
801 bFlag1=IsValidPointForFace(aP, aF1, aTol);
802 if (!bFlag1) {
803 return bFlag1;
804 }
805 bFlag2=IsValidPointForFace(aP, aF2, aTol);
806 return bFlag2;
807}
808//=======================================================================
809//function : IsValidBlockForFace
810//purpose :
811//=======================================================================
1e143abb 812Standard_Boolean IntTools_Context::IsValidBlockForFace
813 (const Standard_Real aT1,
814 const Standard_Real aT2,
815 const IntTools_Curve& aC,
816 const TopoDS_Face& aF,
817 const Standard_Real aTol)
7fd59977 818{
819 Standard_Boolean bFlag;
96a95605 820 Standard_Real aTInterm;
7fd59977 821 gp_Pnt aPInterm;
822
823 aTInterm=IntTools_Tools::IntermediatePoint(aT1, aT2);
824
825 Handle(Geom_Curve) aC3D=aC.Curve();
7fd59977 826 // point 3D
827 aC3D->D0(aTInterm, aPInterm);
828 //
829 bFlag=IsValidPointForFace (aPInterm, aF, aTol);
830 return bFlag;
831}
832//=======================================================================
833//function : IsValidBlockForFaces
834//purpose :
835//=======================================================================
370101f3 836Standard_Boolean IntTools_Context::IsValidBlockForFaces(const Standard_Real theT1,
837 const Standard_Real theT2,
838 const IntTools_Curve& theC,
839 const TopoDS_Face& theF1,
840 const TopoDS_Face& theF2,
841 const Standard_Real theTol)
7fd59977 842{
370101f3 843 const Standard_Integer aNbElem = 2;
844 const Handle(Geom2d_Curve) &aPC1 = theC.FirstCurve2d();
845 const Handle(Geom2d_Curve) &aPC2 = theC.SecondCurve2d();
846 const Handle(Geom_Curve) &aC3D = theC.Curve();
847
848 const Handle(Geom2d_Curve)* anArrPC[aNbElem] = { &aPC1, &aPC2 };
849 const TopoDS_Face* anArrF[aNbElem] = { &theF1, &theF2 };
7fd59977 850
370101f3 851 const Standard_Real aMidPar = IntTools_Tools::IntermediatePoint(theT1, theT2);
852 const gp_Pnt aP(aC3D->Value(aMidPar));
7fd59977 853
370101f3 854 Standard_Boolean bFlag = Standard_True;
855 gp_Pnt2d aPnt2D;
7fd59977 856
370101f3 857 for (Standard_Integer i = 0; (i < 2) && bFlag; ++i)
858 {
859 const Handle(Geom2d_Curve) &aPC = *anArrPC[i];
860 const TopoDS_Face &aF = *anArrF[i];
7fd59977 861
370101f3 862 if (!aPC.IsNull())
863 {
864 aPC->D0(aMidPar, aPnt2D);
865 bFlag = IsPointInOnFace(aF, aPnt2D);
866 }
867 else
868 {
869 bFlag = IsValidPointForFace(aP, aF, theTol);
870 }
7fd59977 871 }
7fd59977 872
370101f3 873 return bFlag;
7fd59977 874}
875//=======================================================================
876//function : IsVertexOnLine
877//purpose :
878//=======================================================================
1e143abb 879Standard_Boolean IntTools_Context::IsVertexOnLine
880 (const TopoDS_Vertex& aV,
881 const IntTools_Curve& aC,
882 const Standard_Real aTolC,
883 Standard_Real& aT)
7fd59977 884{
885 Standard_Boolean bRet;
886 Standard_Real aTolV;
887 //
888 aTolV=BRep_Tool::Tolerance(aV);
1e143abb 889 bRet=IntTools_Context::IsVertexOnLine(aV, aTolV, aC, aTolC , aT);
7fd59977 890 //
891 return bRet;
892}
893//=======================================================================
894//function : IsVertexOnLine
895//purpose :
896//=======================================================================
1e143abb 897Standard_Boolean IntTools_Context::IsVertexOnLine
898 (const TopoDS_Vertex& aV,
899 const Standard_Real aTolV,
900 const IntTools_Curve& aC,
901 const Standard_Real aTolC,
902 Standard_Real& aT)
7fd59977 903{
904 Standard_Real aFirst, aLast, aDist, aTolSum;
905 Standard_Integer aNbProj;
906 gp_Pnt aPv;
907
908 aPv=BRep_Tool::Pnt(aV);
909
910 Handle(Geom_Curve) aC3D=aC.Curve();
911
912
913 aTolSum=aTolV+aTolC;
914 //
915 GeomAdaptor_Curve aGAC(aC3D);
916 GeomAbs_CurveType aType=aGAC.GetType();
917 if (aType==GeomAbs_BSplineCurve ||
918 aType==GeomAbs_BezierCurve) {
919 aTolSum=2.*aTolSum;
920 if (aTolSum<1.e-5) {
921 aTolSum=1.e-5;
922 }
923 }
924 else {
925 aTolSum=2.*aTolSum;//xft
926 if(aTolSum < 1.e-6)
927 aTolSum = 1.e-6;
928 }
929 //
930 aFirst=aC3D->FirstParameter();
931 aLast =aC3D->LastParameter();
932 //
416022a1 933 // Checking extermities first
934 // It is necessary to chose the closest bound to the point
935 Standard_Boolean bFirstValid = Standard_False;
936 Standard_Real aFirstDist = Precision::Infinite();
937 //
7fd59977 938 if (!Precision::IsInfinite(aFirst)) {
939 gp_Pnt aPCFirst=aC3D->Value(aFirst);
416022a1 940 aFirstDist = aPv.Distance(aPCFirst);
941 if (aFirstDist < aTolSum) {
942 bFirstValid = Standard_True;
7fd59977 943 aT=aFirst;
944 //
416022a1 945 if (aFirstDist > aTolV) {
4e57c75e 946 Extrema_LocateExtPC anExt(aPv, aGAC, aFirst, 1.e-10);
947
948 if(anExt.IsDone()) {
949 Extrema_POnCurv aPOncurve = anExt.Point();
950 aT = aPOncurve.Parameter();
951
952 if((aT > (aLast + aFirst) * 0.5) ||
953 (aPv.Distance(aPOncurve.Value()) > aTolSum) ||
954 (aPCFirst.Distance(aPOncurve.Value()) < Precision::Confusion()))
955 aT = aFirst;
956 }
4e14c88f 957 else
958 {
959 // Local search may fail. Try to use more precise algo.
c7854818 960 Extrema_ExtPC anExt2(aPv, aGAC, 1.e-10);
4e14c88f 961 Standard_Real aMinDist = RealLast();
962 Standard_Integer aMinIdx = -1;
3510db62 963 if (anExt2.IsDone()) {
964 for (Standard_Integer anIdx = 1; anIdx <= anExt2.NbExt(); anIdx++)
965 {
966 if ( anExt2.IsMin(anIdx) &&
967 anExt2.SquareDistance(anIdx) < aMinDist )
4e14c88f 968 {
c7854818 969 aMinDist = anExt2.SquareDistance(anIdx);
4e14c88f 970 aMinIdx = anIdx;
971 }
3510db62 972 }
4e14c88f 973 }
974 if (aMinIdx != -1)
975 {
c7854818 976 const Extrema_POnCurv& aPOncurve = anExt2.Point(aMinIdx);
4e14c88f 977 aT = aPOncurve.Parameter();
978
979 if((aT > (aLast + aFirst) * 0.5) ||
980 (aPv.Distance(aPOncurve.Value()) > aTolSum) ||
981 (aPCFirst.Distance(aPOncurve.Value()) < Precision::Confusion()))
982 aT = aFirst;
983 }
984 }
985
7fd59977 986 }
7fd59977 987 }
988 }
989 //
990 if (!Precision::IsInfinite(aLast)) {
991 gp_Pnt aPCLast=aC3D->Value(aLast);
992 aDist=aPv.Distance(aPCLast);
416022a1 993 if (bFirstValid && (aFirstDist < aDist)) {
994 return Standard_True;
995 }
996 //
7fd59977 997 if (aDist < aTolSum) {
998 aT=aLast;
999 //
1000 if(aDist > aTolV) {
4e57c75e 1001 Extrema_LocateExtPC anExt(aPv, aGAC, aLast, 1.e-10);
1002
1003 if(anExt.IsDone()) {
1004 Extrema_POnCurv aPOncurve = anExt.Point();
1005 aT = aPOncurve.Parameter();
1006
1007 if((aT < (aLast + aFirst) * 0.5) ||
1008 (aPv.Distance(aPOncurve.Value()) > aTolSum) ||
1009 (aPCLast.Distance(aPOncurve.Value()) < Precision::Confusion()))
1010 aT = aLast;
1011 }
4e14c88f 1012 else
1013 {
1014 // Local search may fail. Try to use more precise algo.
c7854818 1015 Extrema_ExtPC anExt2(aPv, aGAC, 1.e-10);
4e14c88f 1016 Standard_Real aMinDist = RealLast();
1017 Standard_Integer aMinIdx = -1;
3510db62 1018 if (anExt2.IsDone()) {
1019 for (Standard_Integer anIdx = 1; anIdx <= anExt2.NbExt(); anIdx++)
1020 {
1021 if ( anExt2.IsMin(anIdx) &&
1022 anExt2.SquareDistance(anIdx) < aMinDist )
4e14c88f 1023 {
c7854818 1024 aMinDist = anExt2.SquareDistance(anIdx);
4e14c88f 1025 aMinIdx = anIdx;
1026 }
3510db62 1027 }
4e14c88f 1028 }
1029 if (aMinIdx != -1)
1030 {
c7854818 1031 const Extrema_POnCurv& aPOncurve = anExt2.Point(aMinIdx);
4e14c88f 1032 aT = aPOncurve.Parameter();
1033
1034 if((aT < (aLast + aFirst) * 0.5) ||
1035 (aPv.Distance(aPOncurve.Value()) > aTolSum) ||
1036 (aPCLast.Distance(aPOncurve.Value()) < Precision::Confusion()))
1037 aT = aLast;
1038 }
1039 }
7fd59977 1040 }
1041 //
1042 return Standard_True;
1043 }
1044 }
416022a1 1045 else if (bFirstValid) {
1046 return Standard_True;
1047 }
7fd59977 1048 //
1049 GeomAPI_ProjectPointOnCurve& aProjector=ProjPT(aC3D);
1050 aProjector.Perform(aPv);
1051
1052 aNbProj=aProjector.NbPoints();
1053 if (!aNbProj) {
1054 Handle(Geom_BoundedCurve) aBC=
1055 Handle(Geom_BoundedCurve)::DownCast(aC3D);
1056 if (!aBC.IsNull()) {
1057 gp_Pnt aPStart=aBC->StartPoint();
1058 gp_Pnt aPEnd =aBC->EndPoint();
1059
1060 aDist=aPv.Distance(aPStart);
1061 if (aDist < aTolSum) {
4e57c75e 1062 aT=aFirst;
1063 return Standard_True;
7fd59977 1064 }
1065
1066 aDist=aPv.Distance(aPEnd);
1067 if (aDist < aTolSum) {
4e57c75e 1068 aT=aLast;
1069 return Standard_True;
7fd59977 1070 }
1071 }
1072
1073 return Standard_False;
1074 }
1075
1076 aDist=aProjector.LowerDistance();
1077
1078 if (aDist > aTolSum) {
1079 return Standard_False;
1080 }
1081
1082 aT=aProjector.LowerDistanceParameter();
1083
1084 return Standard_True;
1085}
1086//=======================================================================
1087//function : ProjectPointOnEdge
1088//purpose :
1089//=======================================================================
1e143abb 1090Standard_Boolean IntTools_Context::ProjectPointOnEdge
1091 (const gp_Pnt& aP,
1092 const TopoDS_Edge& anEdge,
1093 Standard_Real& aT)
7fd59977 1094{
1095 Standard_Integer aNbPoints;
1096
1097 GeomAPI_ProjectPointOnCurve& aProjector=ProjPC(anEdge);
1098 aProjector.Perform(aP);
1099
1100 aNbPoints=aProjector.NbPoints();
1101 if (aNbPoints) {
1102 aT=aProjector.LowerDistanceParameter();
1103 return Standard_True;
1104 }
1105 return Standard_False;
1106}
1107
b285c9fe 1108//=======================================================================
1109//function : SetPOnSProjectionTolerance
1110//purpose :
1111//=======================================================================
1112void IntTools_Context::SetPOnSProjectionTolerance(const Standard_Real theValue)
1113{
1114 myPOnSTolerance = theValue;
1115 clearCachedPOnSProjectors();
1116}
1117
1118//=======================================================================
1119//function : clearCachedPOnSProjectors
1120//purpose :
1121//=======================================================================
1122void IntTools_Context::clearCachedPOnSProjectors()
1123{
1124 GeomAPI_ProjectPointOnSurf* pProjPS;
1155d05a 1125 DataMapOfShapeAddress::Iterator aIt(myProjPSMap);
b285c9fe 1126 for (; aIt.More(); aIt.Next()) {
1127 Standard_Address anAdr=aIt.Value();
1128 pProjPS=(GeomAPI_ProjectPointOnSurf*)anAdr;
1129 (*pProjPS).~GeomAPI_ProjectPointOnSurf();
1130 myAllocator->Free(anAdr);
1131 }
1132 myProjPSMap.Clear();
1133}
51db0179 1134
1135//=======================================================================
1136//function : UVBounds
1137//purpose :
1138//=======================================================================
1139void IntTools_Context::UVBounds(const TopoDS_Face& theFace,
1140 Standard_Real& UMin,
1141 Standard_Real& UMax,
1142 Standard_Real& VMin,
1143 Standard_Real& VMax)
1144{
1145 const BRepAdaptor_Surface& aBAS = SurfaceAdaptor(theFace);
1146 UMin = aBAS.FirstUParameter();
1147 UMax = aBAS.LastUParameter ();
1148 VMin = aBAS.FirstVParameter();
1149 VMax = aBAS.LastVParameter ();
1150}