0029237: Improve performance of Boolean Operations
[occt.git] / src / BOPTools / BOPTools_AlgoTools_1.cxx
CommitLineData
4e57c75e 1// Created by: Peter KURNEV
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
4e57c75e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
4e57c75e 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.
4e57c75e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
4e57c75e 14
42cf5bc1 15
c26b5a34 16#include <Adaptor3d_CurveOnSurface.hxx>
42cf5bc1 17#include <Adaptor3d_HCurve.hxx>
c26b5a34 18#include <Adaptor3d_HCurveOnSurface.hxx>
42cf5bc1 19#include <BOPCol_NCVector.hxx>
20#include <BOPCol_Parallel.hxx>
21#include <BOPTools_AlgoTools.hxx>
22#include <BRep_Builder.hxx>
23#include <BRep_CurveRepresentation.hxx>
24#include <BRep_GCurve.hxx>
25#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
26#include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
27#include <BRep_PointRepresentation.hxx>
28#include <BRep_TEdge.hxx>
29#include <BRep_TFace.hxx>
30#include <BRep_Tool.hxx>
31#include <BRep_TVertex.hxx>
32#include <BRepAdaptor_Surface.hxx>
24542bc0 33#include <BRepAdaptor_Curve.hxx>
42cf5bc1 34#include <BRepLib_CheckCurveOnSurface.hxx>
35#include <BRepTools_WireExplorer.hxx>
36#include <Extrema_LocateExtPC.hxx>
37#include <Geom2d_Curve.hxx>
38#include <Geom2dAdaptor.hxx>
39#include <Geom2dAdaptor_Curve.hxx>
40#include <Geom2dAdaptor_HCurve.hxx>
41#include <Geom2dInt_GInter.hxx>
4e57c75e 42#include <Geom_Curve.hxx>
4e57c75e 43#include <Geom_Plane.hxx>
c26b5a34 44#include <Geom_RectangularTrimmedSurface.hxx>
42cf5bc1 45#include <Geom_Surface.hxx>
46#include <Geom_TrimmedCurve.hxx>
4e57c75e 47#include <GeomAdaptor_Curve.hxx>
48#include <GeomAdaptor_HCurve.hxx>
49#include <GeomAdaptor_HSurface.hxx>
42cf5bc1 50#include <GeomAdaptor_Surface.hxx>
4e57c75e 51#include <GeomProjLib.hxx>
24542bc0 52#include <GCPnts_AbscissaPoint.hxx>
42cf5bc1 53#include <gp_Pnt.hxx>
54#include <gp_Pnt2d.hxx>
c26b5a34 55#include <IntRes2d_Domain.hxx>
56#include <IntRes2d_IntersectionPoint.hxx>
0d0481c7 57#include <IntRes2d_IntersectionSegment.hxx>
42cf5bc1 58#include <IntTools_Context.hxx>
59#include <IntTools_Curve.hxx>
60#include <IntTools_Range.hxx>
61#include <IntTools_Tools.hxx>
62#include <ProjLib_ProjectedCurve.hxx>
63#include <TopExp.hxx>
64#include <TopExp_Explorer.hxx>
c26b5a34 65#include <TopLoc_Location.hxx>
c26b5a34 66#include <TopoDS.hxx>
67#include <TopoDS_Edge.hxx>
c26b5a34 68#include <TopoDS_Face.hxx>
4e57c75e 69#include <TopoDS_Iterator.hxx>
42cf5bc1 70#include <TopoDS_Shape.hxx>
71#include <TopoDS_Shell.hxx>
72#include <TopoDS_Solid.hxx>
73#include <TopoDS_Vertex.hxx>
4e57c75e 74#include <TopoDS_Wire.hxx>
42cf5bc1 75#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
76#include <TopTools_IndexedMapOfShape.hxx>
77#include <TopTools_ListIteratorOfListOfShape.hxx>
78#include <TopTools_ListOfShape.hxx>
79
0d0481c7 80
4e57c75e 81static
82 void CheckEdge (const TopoDS_Edge& E,
3510db62 83 const Standard_Real aMaxTol,
84 const BOPCol_IndexedMapOfShape& aMapToAvoid);
4e57c75e 85static
86 void CorrectEdgeTolerance (const TopoDS_Edge& myShape,
87 const TopoDS_Face& S,
3510db62 88 const Standard_Real aMaxTol,
89 const BOPCol_IndexedMapOfShape& aMapToAvoid);
4e57c75e 90static
91 Standard_Boolean Validate(const Adaptor3d_Curve& CRef,
92 const Adaptor3d_Curve& Other,
93 const Standard_Real Tol,
94 const Standard_Boolean SameParameter,
95 Standard_Real& aNewTolerance);
96
97static
3510db62 98 void CorrectVertexTolerance(const TopoDS_Edge& aE,
99 const BOPCol_IndexedMapOfShape& aMapToAvoid);
4e57c75e 100
101static
3510db62 102 void CorrectWires(const TopoDS_Face& aF,
103 const BOPCol_IndexedMapOfShape& aMapToAvoid);
4e57c75e 104
c26b5a34 105
106
107static
3510db62 108 void UpdateEdges(const TopoDS_Face& aF,
109 const BOPCol_IndexedMapOfShape& aMapToAvoid);
110
111static
112 void UpdateShape(const TopoDS_Shape& aS,
113 const Standard_Real aTol,
114 const BOPCol_IndexedMapOfShape& aMapToAvoid);
c26b5a34 115
c26b5a34 116//=======================================================================
117//class : BOPTools_CPC
118//purpose :
119//=======================================================================
120class BOPTools_CPC {
121 public:
122 BOPTools_CPC()
3510db62 123 : myMaxTol(1.e-7), mypMapToAvoid(0L) {
c26b5a34 124 }
125 //
126 ~BOPTools_CPC() {
127 }
128 //
129 void SetEdge(const TopoDS_Edge& aE) {
130 myEdge=aE;
131 }
132 //
133 const TopoDS_Edge& Edge()const {
134 return myEdge;
135 }
136 //
137 void SetMaxTol(const Standard_Real aMaxTol) {
138 myMaxTol=aMaxTol;
139 }
140 //
141 Standard_Real MaxTol()const {
142 return myMaxTol;
143 }
144 //
3510db62 145 void SetMapToAvoid(const BOPCol_IndexedMapOfShape& aMapToAvoid) {
146 mypMapToAvoid = &aMapToAvoid;
147 }
148 //
c26b5a34 149 void Perform() {
3510db62 150 Standard_ProgramError_Raise_if(!mypMapToAvoid, "mypMapToAvoid is null");
151 CheckEdge(myEdge, myMaxTol, *mypMapToAvoid);
c26b5a34 152 }
153
154 protected:
155 Standard_Real myMaxTol;
156 TopoDS_Edge myEdge;
3510db62 157 const BOPCol_IndexedMapOfShape* mypMapToAvoid;
c26b5a34 158};
159//
160//=======================================================================
161typedef BOPCol_NCVector<BOPTools_CPC> BOPTools_VectorOfCPC;
162//
c7b59798 163typedef BOPCol_Functor
c26b5a34 164 <BOPTools_CPC,
165 BOPTools_VectorOfCPC> BOPTools_CPCFunctor;
166//
c7b59798 167typedef BOPCol_Cnt
c26b5a34 168 <BOPTools_CPCFunctor,
169 BOPTools_VectorOfCPC> BOPTools_CPCCnt;
170//
171//=======================================================================
172//class : BOPTools_CWT
173//purpose :
174//=======================================================================
175class BOPTools_CWT {
176 public:
3510db62 177 BOPTools_CWT() : mypMapToAvoid(0L) {
c26b5a34 178 }
179 //
180 ~BOPTools_CWT() {
181 }
182 //
183 void SetFace(const TopoDS_Face& aF) {
184 myFace=aF;
185 }
186 //
3510db62 187 void SetMapToAvoid(const BOPCol_IndexedMapOfShape& aMapToAvoid) {
188 mypMapToAvoid = &aMapToAvoid;
189 }
190 //
c26b5a34 191 void Perform() {
3510db62 192 Standard_ProgramError_Raise_if(!mypMapToAvoid, "mypMapToAvoid is null");
193 CorrectWires(myFace, *mypMapToAvoid);
c26b5a34 194 }
195 //
196 protected:
197 TopoDS_Face myFace;
3510db62 198 const BOPCol_IndexedMapOfShape* mypMapToAvoid;
c26b5a34 199};
200//=======================================================================
201typedef BOPCol_NCVector<BOPTools_CWT> BOPTools_VectorOfCWT;
202//
c7b59798 203typedef BOPCol_Functor
c26b5a34 204 <BOPTools_CWT,
205 BOPTools_VectorOfCWT> BOPTools_CWTFunctor;
206//
c7b59798 207typedef BOPCol_Cnt
c26b5a34 208 <BOPTools_CWTFunctor,
209 BOPTools_VectorOfCWT> BOPTools_CWTCnt;
210//
211//=======================================================================
212//class : BOPTools_CDT
213//purpose :
214//=======================================================================
215class BOPTools_CDT {
216 public:
217 BOPTools_CDT()
3510db62 218 : myMaxTol(1.e-7), mypMapToAvoid(0L) {
c26b5a34 219 }
220 //
221 ~BOPTools_CDT() {
222 }
223 //
224 void SetEdge(const TopoDS_Edge& aE) {
225 myEdge=aE;
226 }
227 //
228 void SetFace(const TopoDS_Face& aF) {
229 myFace=aF;
230 }
231 //
232 void SetMaxTol(const Standard_Real aMaxTol) {
233 myMaxTol=aMaxTol;
234 }
235 //
3510db62 236 void SetMapToAvoid(const BOPCol_IndexedMapOfShape& aMapToAvoid) {
237 mypMapToAvoid = &aMapToAvoid;
238 }
239 //
c26b5a34 240 void Perform() {
3510db62 241 Standard_ProgramError_Raise_if(!mypMapToAvoid, "mypMapToAvoid is null");
242 CorrectEdgeTolerance (myEdge, myFace, myMaxTol, *mypMapToAvoid);
c26b5a34 243 }
244 //
245 protected:
246 Standard_Real myMaxTol;
247 TopoDS_Edge myEdge;
248 TopoDS_Face myFace;
3510db62 249 const BOPCol_IndexedMapOfShape* mypMapToAvoid;
c26b5a34 250};
251//=======================================================================
252typedef BOPCol_NCVector<BOPTools_CDT> BOPTools_VectorOfCDT;
253//
c7b59798 254typedef BOPCol_Functor
c26b5a34 255 <BOPTools_CDT,
256 BOPTools_VectorOfCDT> BOPTools_CDTFunctor;
257//
c7b59798 258typedef BOPCol_Cnt
c26b5a34 259 <BOPTools_CDTFunctor,
260 BOPTools_VectorOfCDT> BOPTools_CDTCnt;
261//
262//=======================================================================
263//class : BOPTools_CVT
264//purpose :
265//=======================================================================
266class BOPTools_CVT {
267 public:
3510db62 268 BOPTools_CVT() : mypMapToAvoid(0L) {
c26b5a34 269 }
270 //
271 ~BOPTools_CVT() {
272 }
273 //
274 void SetEdge(const TopoDS_Edge& aE) {
275 myEdge=aE;
276 }
277 //
3510db62 278 void SetMapToAvoid(const BOPCol_IndexedMapOfShape& aMapToAvoid) {
279 mypMapToAvoid = &aMapToAvoid;
280 }
281 //
c26b5a34 282 void Perform() {
3510db62 283 Standard_ProgramError_Raise_if(!mypMapToAvoid, "mypMapToAvoid is null");
284 CorrectVertexTolerance(myEdge, *mypMapToAvoid);
c26b5a34 285 }
286 //
287 protected:
288 TopoDS_Edge myEdge;
3510db62 289 const BOPCol_IndexedMapOfShape* mypMapToAvoid;
c26b5a34 290};
291//
292//=======================================================================
293typedef BOPCol_NCVector<BOPTools_CVT> BOPTools_VectorOfCVT;
294//
c7b59798 295typedef BOPCol_Functor
c26b5a34 296 <BOPTools_CVT,
297 BOPTools_VectorOfCVT> BOPTools_CVTFunctor;
298//
c7b59798 299typedef BOPCol_Cnt
c26b5a34 300 <BOPTools_CVTFunctor,
301 BOPTools_VectorOfCVT> BOPTools_CVTCnt;
302//
303//=======================================================================
304//class : BOPTools_CET
305//purpose :
306//=======================================================================
307class BOPTools_CET {
308 public:
3510db62 309 BOPTools_CET() : mypMapToAvoid(0L) {
c26b5a34 310 }
311 //
312 ~BOPTools_CET() {
313 }
314 //
315 void SetFace(const TopoDS_Face& aF) {
316 myFace=aF;
317 }
318 //
3510db62 319 void SetMapToAvoid(const BOPCol_IndexedMapOfShape& aMapToAvoid) {
320 mypMapToAvoid = &aMapToAvoid;
321 }
322 //
c26b5a34 323 void Perform() {
3510db62 324 Standard_ProgramError_Raise_if(!mypMapToAvoid, "mypMapToAvoid is null");
325 UpdateEdges(myFace, *mypMapToAvoid);
c26b5a34 326 }
327 //
328 protected:
329 TopoDS_Face myFace;
3510db62 330 const BOPCol_IndexedMapOfShape* mypMapToAvoid;
c26b5a34 331};
332//=======================================================================
333typedef BOPCol_NCVector<BOPTools_CET> BOPTools_VectorOfCET;
334//
c7b59798 335typedef BOPCol_Functor
c26b5a34 336 <BOPTools_CET,
337 BOPTools_VectorOfCET> BOPTools_CETFunctor;
338//
c7b59798 339typedef BOPCol_Cnt
c26b5a34 340 <BOPTools_CETFunctor,
341 BOPTools_VectorOfCET> BOPTools_CETCnt;
342//
e98e3990 343//
344//=======================================================================
c7b59798 345 //
4e57c75e 346//=======================================================================
347// Function : CorrectTolerances
348// purpose :
349//=======================================================================
c26b5a34 350void BOPTools_AlgoTools::CorrectTolerances
351 (const TopoDS_Shape& aShape,
3510db62 352 const BOPCol_IndexedMapOfShape& aMapToAvoid,
c26b5a34 353 const Standard_Real aMaxTol,
354 const Standard_Boolean bRunParallel)
4e57c75e 355{
3510db62 356 BOPTools_AlgoTools::CorrectPointOnCurve(aShape, aMapToAvoid, aMaxTol, bRunParallel);
357 BOPTools_AlgoTools::CorrectCurveOnSurface(aShape, aMapToAvoid, aMaxTol, bRunParallel);
4e57c75e 358}
c26b5a34 359//
4e57c75e 360//=======================================================================
361// Function : CorrectPointOnCurve
362// purpose :
363//=======================================================================
c26b5a34 364void BOPTools_AlgoTools::CorrectPointOnCurve
365 (const TopoDS_Shape& aS,
3510db62 366 const BOPCol_IndexedMapOfShape& aMapToAvoid,
c26b5a34 367 const Standard_Real aMaxTol,
368 const Standard_Boolean bRunParallel)
4e57c75e 369{
c26b5a34 370 TopExp_Explorer aExp;
371 BOPTools_VectorOfCPC aVCPC;
372 //
373 aExp.Init(aS, TopAbs_EDGE);
374 for(; aExp.More(); aExp.Next()) {
375 const TopoDS_Edge& aE=*((TopoDS_Edge*)&aExp.Current());
376 BOPTools_CPC& aCPC=aVCPC.Append1();
377 aCPC.SetEdge(aE);
378 aCPC.SetMaxTol(aMaxTol);
3510db62 379 aCPC.SetMapToAvoid(aMapToAvoid);
c26b5a34 380 }
381 //
382 //======================================================
383 BOPTools_CPCCnt::Perform(bRunParallel, aVCPC);
384 //======================================================
4e57c75e 385}
4e57c75e 386//=======================================================================
387// Function : CorrectCurveOnSurface
388// purpose :
389//=======================================================================
c26b5a34 390void BOPTools_AlgoTools::CorrectCurveOnSurface
391 (const TopoDS_Shape& aS,
3510db62 392 const BOPCol_IndexedMapOfShape& aMapToAvoid,
c26b5a34 393 const Standard_Real aMaxTol,
394 const Standard_Boolean bRunParallel)
4e57c75e 395{
c26b5a34 396 TopExp_Explorer aExpF, aExpE;
397 BOPTools_VectorOfCWT aVCWT;
398 BOPTools_VectorOfCDT aVCDT;
399 //
400 aExpF.Init(aS, TopAbs_FACE);
401 for (; aExpF.More(); aExpF.Next()) {
402 const TopoDS_Face& aF=*((TopoDS_Face*)&aExpF.Current());
4e57c75e 403 //
c26b5a34 404 BOPTools_CWT& aCWT=aVCWT.Append1();
405 aCWT.SetFace(aF);
3510db62 406 aCWT.SetMapToAvoid(aMapToAvoid);
4e57c75e 407 //
c26b5a34 408 aExpE.Init(aF, TopAbs_EDGE);
409 for (; aExpE.More(); aExpE.Next()) {
410 const TopoDS_Edge& aE=*((TopoDS_Edge*)&aExpE.Current());
411 //
412 BOPTools_CDT& aCDT=aVCDT.Append1();
413 aCDT.SetEdge(aE);
414 aCDT.SetFace(aF);
415 aCDT.SetMaxTol(aMaxTol);
3510db62 416 aCDT.SetMapToAvoid(aMapToAvoid);
4e57c75e 417 }
418 }
c26b5a34 419 //
420 //======================================================
421 BOPTools_CWTCnt::Perform(bRunParallel, aVCWT);
422 //======================================================
423 BOPTools_CDTCnt::Perform(bRunParallel, aVCDT);
424 //======================================================
425}
426//=======================================================================
427// Function : CorrectShapeTolerances
428// purpose :
429//=======================================================================
430void BOPTools_AlgoTools::CorrectShapeTolerances
431 (const TopoDS_Shape& aShape,
3510db62 432 const BOPCol_IndexedMapOfShape& aMapToAvoid,
c26b5a34 433 const Standard_Boolean bRunParallel)
434{
435 TopExp_Explorer aExp;
436 BOPTools_VectorOfCVT aVCVT;
437 BOPTools_VectorOfCET aVCET;
438 //
439 aExp.Init(aShape, TopAbs_EDGE);
440 for (; aExp.More(); aExp.Next()) {
441 const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current();
442 BOPTools_CVT& aCVT=aVCVT.Append1();
443 aCVT.SetEdge(aE);
3510db62 444 aCVT.SetMapToAvoid(aMapToAvoid);
c26b5a34 445 }
446 //
447 //======================================================
448 BOPTools_CVTCnt::Perform(bRunParallel, aVCVT);
449 //======================================================
450 //
451 aExp.Init(aShape, TopAbs_FACE);
452 for (; aExp.More(); aExp.Next()) {
453 const TopoDS_Face& aF = *(TopoDS_Face*)&aExp.Current();
454 BOPTools_CET& aCET=aVCET.Append1();
455 aCET.SetFace(aF);
3510db62 456 aCET.SetMapToAvoid(aMapToAvoid);
c26b5a34 457 }
458 //
459 //======================================================
460 BOPTools_CETCnt::Perform(bRunParallel, aVCET);
461 //======================================================
462}
463//
464//=======================================================================
465// Function : CheckEdge
466// purpose : Correct tolerances for Vertices on Edge
467//=======================================================================
468void CheckEdge (const TopoDS_Edge& Ed,
3510db62 469 const Standard_Real aMaxTol,
470 const BOPCol_IndexedMapOfShape& aMapToAvoid)
c26b5a34 471{
98b37659 472 TopoDS_Edge aE = Ed;
c26b5a34 473 aE.Orientation(TopAbs_FORWARD);
98b37659 474 Standard_Real aTolE = BRep_Tool::Tolerance(aE);
c26b5a34 475 //
476 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&aE.TShape());
477 //
98b37659 478 const TopLoc_Location& Eloc = aE.Location();
479
480 TopoDS_Iterator aItS(aE);
c26b5a34 481 for (; aItS.More(); aItS.Next()) {
98b37659 482 const TopoDS_Vertex& aV= TopoDS::Vertex(aItS.Value());
c26b5a34 483 //
484 Handle(BRep_TVertex)& TV=*((Handle(BRep_TVertex)*)&aV.TShape());
485 const gp_Pnt& aPV = TV->Pnt();
486 //
98b37659 487 Standard_Real aTol=BRep_Tool::Tolerance(aV);
c26b5a34 488 aTol=Max(aTol, aTolE);
98b37659 489 Standard_Real dd=0.1*aTol;
c26b5a34 490 aTol*=aTol;
491 //
98b37659 492 BRep_ListIteratorOfListOfCurveRepresentation aItCR(TE->Curves());
c26b5a34 493 while (aItCR.More()) {
494 const Handle(BRep_CurveRepresentation)& aCR = aItCR.Value();
c26b5a34 495 //
496 if (aCR->IsCurve3D()) {
497 const Handle(Geom_Curve)& aC = aCR->Curve3D();
498 if (!aC.IsNull()) {
98b37659 499 TopLoc_Location L = (Eloc * aCR->Location()).Predivided(aV.Location());
500 BRep_ListIteratorOfListOfPointRepresentation aItPR(TV->Points());
c26b5a34 501 while (aItPR.More()) {
502 const Handle(BRep_PointRepresentation)& aPR=aItPR.Value();
503 if (aPR->IsPointOnCurve(aC, L)) {
98b37659 504 gp_Pnt aPC = aC->Value(aPR->Parameter());
c26b5a34 505 aPC.Transform(L.Transformation());
98b37659 506 Standard_Real aD2=aPV.SquareDistance(aPC);
c26b5a34 507 if (aD2 > aTol) {
98b37659 508 Standard_Real aNewTolerance=sqrt(aD2)+dd;
c26b5a34 509 if (aNewTolerance<aMaxTol)
3510db62 510 UpdateShape(aV, aNewTolerance, aMapToAvoid);
c26b5a34 511 }
512 }
513 aItPR.Next();
514 }
515 //
98b37659 516 TopAbs_Orientation aOrV=aV.Orientation();
c26b5a34 517 if (aOrV==TopAbs_FORWARD || aOrV==TopAbs_REVERSED) {
c5f3a425 518 Handle(BRep_GCurve) aGC (Handle(BRep_GCurve)::DownCast (aCR));
98b37659 519 gp_Pnt aPC;
c26b5a34 520 if (aOrV==TopAbs_FORWARD) {
521 aPC=aC->Value(aGC->First());
522 }
523 else {
524 aPC=aC->Value(aGC->Last());
525 }
526 aPC.Transform(L.Transformation());
527 //
98b37659 528 Standard_Real aD2=aPV.SquareDistance(aPC);
c26b5a34 529 if (aD2 > aTol) {
98b37659 530 Standard_Real aNewTolerance=sqrt(aD2)+dd;
c26b5a34 531 if (aNewTolerance<aMaxTol)
3510db62 532 UpdateShape(aV, aNewTolerance, aMapToAvoid);
c26b5a34 533 }
534 }
535 }
536 }
537 aItCR.Next();
538 }// while (itcr.More()) {
539 } // for (; aVExp.More(); aVExp.Next()) {
4e57c75e 540}
0d0481c7 541
24542bc0 542//=======================================================================
543// Function : MapEdgeLength
544// purpose : Compute edge length and cache it in the map
545//=======================================================================
546static Standard_Real MapEdgeLength(const TopoDS_Edge& theEdge,
547 NCollection_DataMap<TopoDS_Shape, Standard_Real>& theMapEdgeLen)
548{
549 const Standard_Real* pLen = theMapEdgeLen.Seek(theEdge);
550 if (!pLen)
551 {
552 Standard_Real aLen = 0.;
553 if (!BRep_Tool::Degenerated(theEdge))
554 {
555 BRepAdaptor_Curve aCurve(theEdge);
556 aLen = GCPnts_AbscissaPoint::Length(aCurve);
557 }
558 pLen = theMapEdgeLen.Bound(theEdge, aLen);
559 }
560 return *pLen;
561}
98b37659 562
563//=======================================================================
564// Function : EdgeData
565// purpose : Structure to store edge data
566//=======================================================================
567namespace {
568 struct EdgeData {
569 const TopoDS_Edge* Edge; // Edge
570 Standard_Real VParameter; // Parameter of the vertex on the edge
571 Geom2dAdaptor_Curve GAdaptor; // 2D adaptor for PCurve of the edge on the face
572 Standard_Real First; // First parameter in the range
573 Standard_Real Last; // Last parameter in the rage
574 };
575}
b4109929 576//=======================================================================
577// Function : IntersectCurves2d
578// purpose : Intersect 2d curves of edges
579//=======================================================================
98b37659 580static
581 Standard_Real IntersectCurves2d(const TopoDS_Vertex& theV,
582 const Handle(Geom_Surface)& theS,
583 const EdgeData& theEData1,
584 const EdgeData& theEData2,
585 NCollection_DataMap<TopoDS_Shape, Standard_Real>& theMapEdgeLen)
b4109929 586{
0d0481c7 587 Geom2dInt_GInter anInter;
98b37659 588 // Range of the first edge
589 Standard_Real aT11 = theEData1.First;
590 Standard_Real aT12 = theEData1.Last;
591 // Range of the second edge
592 Standard_Real aT21 = theEData2.First;
593 Standard_Real aT22 = theEData2.Last;
594
595 Standard_Real aMaxDist = 0.;
596 Standard_Real aTol2d = 1.e-10;
b4109929 597 //
98b37659 598 IntRes2d_Domain aDom1(theEData1.GAdaptor.Value(aT11), aT11, aTol2d,
599 theEData1.GAdaptor.Value(aT12), aT12, aTol2d);
600 IntRes2d_Domain aDom2(theEData2.GAdaptor.Value(aT21), aT21, aTol2d,
601 theEData2.GAdaptor.Value(aT22), aT22, aTol2d);
b4109929 602 //
98b37659 603 anInter.Perform(theEData1.GAdaptor, aDom1, theEData2.GAdaptor, aDom2, aTol2d, aTol2d);
24542bc0 604 if (!anInter.IsDone() || (!anInter.NbSegments() && !anInter.NbPoints())) {
0d0481c7 605 return aMaxDist;
606 }
607 //
608 Standard_Real aT1, aT2, aTint1, aTint2, aHalfR1, aHalfR2, aDist;
609 Standard_Integer i, aNb;
610 gp_Pnt aP, aPV;
611 gp_Pnt2d aP2d;
612 NCollection_List<IntRes2d_IntersectionPoint> aLP;
613 NCollection_List<IntRes2d_IntersectionPoint>::Iterator aItLP;
614 //
615 aPV = BRep_Tool::Pnt(theV);
98b37659 616 aT1 = theEData1.VParameter;
617 aT2 = theEData2.VParameter;
0d0481c7 618 //
619 aHalfR1 = (aT12 - aT11) / 2.;
620 aHalfR2 = (aT22 - aT21) / 2.;
621 //
622 aDist = 0.;
623 //
624 aNb = anInter.NbSegments();
625 for (i = 1; i <= aNb; ++i) {
626 const IntRes2d_IntersectionSegment& aSeg = anInter.Segment(i);
627 aLP.Append(aSeg.FirstPoint());
628 aLP.Append(aSeg.LastPoint());
629 }
630 //
631 aNb = anInter.NbPoints();
632 for (i = 1; i <= aNb; ++i) {
633 const IntRes2d_IntersectionPoint& aPnt = anInter.Point(i);
634 aLP.Append(aPnt);
635 }
636 //
24542bc0 637 // evaluate the length of the smallest edge, so that not to return too large distance
98b37659 638 Standard_Real aLen1 = MapEdgeLength(*theEData1.Edge, theMapEdgeLen);
639 Standard_Real aLen2 = MapEdgeLength(*theEData1.Edge, theMapEdgeLen);
24542bc0 640 const Standard_Real MaxEdgePartCoveredByVertex = 0.3;
641 Standard_Real aMaxThresDist = Min(aLen1, aLen2) * MaxEdgePartCoveredByVertex;
642 aMaxThresDist *= aMaxThresDist;
0d0481c7 643 aItLP.Initialize(aLP);
644 for (; aItLP.More(); aItLP.Next()) {
645 const IntRes2d_IntersectionPoint& aPnt = aItLP.Value();
646 //
647 aTint1 = aPnt.ParamOnFirst();
648 aTint2 = aPnt.ParamOnSecond();
649 //
650 if ((aTint1 < aT11 || aTint1 > aT12) ||
651 (aTint2 < aT21 || aTint2 > aT22)) {
652 // out of range;
653 continue;
b4109929 654 }
0d0481c7 655 //
656 if (Abs(aTint1 - aT1) > aHalfR1 ||
657 Abs(aTint2 - aT2) > aHalfR2) {
658 // intersection on the other end of the closed edge
659 continue;
660 }
661 //
662 aP2d = aPnt.Value();
663 theS->D0(aP2d.X(), aP2d.Y(), aP);
664 aDist = aPV.SquareDistance(aP);
24542bc0 665 if (aDist > aMaxDist && aDist < aMaxThresDist) {
0d0481c7 666 aMaxDist = aDist;
b4109929 667 }
668 }
0d0481c7 669 //
670 return aMaxDist;
b4109929 671}
98b37659 672//=======================================================================
673// Function : CorrectWires
674// purpose :
675//=======================================================================
676void CorrectWires(const TopoDS_Face& aFx,
677 const BOPCol_IndexedMapOfShape& aMapToAvoid)
678{
679 Standard_Integer i, aNbV;
680 Standard_Real aTol, aTol2, aD2, aD2max, aT1, aT2, aT;
681 gp_Pnt aP, aPV;
682 gp_Pnt2d aP2D;
683 TopoDS_Face aF;
684 TopTools_IndexedDataMapOfShapeListOfShape aMVE;
685 TopTools_ListIteratorOfListOfShape aIt;
686 //
687 aF=aFx;
688 aF.Orientation(TopAbs_FORWARD);
689 const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aFx);
690 //
691 TopExp::MapShapesAndAncestors(aF,
692 TopAbs_VERTEX,
693 TopAbs_EDGE,
694 aMVE);
695 NCollection_DataMap<TopoDS_Shape, Standard_Real> aMapEdgeLen;
696 aNbV=aMVE.Extent();
697 for (i=1; i<=aNbV; ++i) {
698 const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aMVE.FindKey(i));
699 aPV=BRep_Tool::Pnt(aV);
700 aTol=BRep_Tool::Tolerance(aV);
701 aTol2=aTol*aTol;
702 //
703 aD2max=-1.;
704 // Save edge's data to avoid its recalculation during intersection of 2d curves
705 NCollection_List<EdgeData> aLEPars;
706 const TopTools_ListOfShape& aLE=aMVE.FindFromIndex(i);
707 aIt.Initialize(aLE);
708 for (; aIt.More(); aIt.Next()) {
709 const TopoDS_Edge& aE=*(TopoDS_Edge*)(&aIt.Value());
710 const Handle(Geom2d_Curve)& aC2D=
711 BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
712 aT=BRep_Tool::Parameter(aV, aE);
713 //
714 aC2D->D0(aT, aP2D);
715 aS->D0(aP2D.X(), aP2D.Y(), aP);
716 aD2=aPV.SquareDistance(aP);
717 if (aD2>aD2max) {
718 aD2max=aD2;
719 }
720 EdgeData anEData = {&aE, aT, Geom2dAdaptor_Curve(aC2D), aT1, aT2};
721 aLEPars.Append(anEData);
722 }
723 //
724 //check wires on self interference by intersecting 2d curves of the edges
725 NCollection_List<EdgeData>::Iterator aItE1(aLEPars);
726 for (; aItE1.More(); aItE1.Next()) {
727 const EdgeData& aEData1 = aItE1.Value();
728 const TopoDS_Shape& aE1 = *aEData1.Edge;
729
730 NCollection_List<EdgeData>::Iterator aItE2 = aItE1;
731 for (aItE2.Next(); aItE2.More(); aItE2.Next()) {
732 const EdgeData& aEData2 = aItE2.Value();
733 const TopoDS_Shape& aE2 = *aEData2.Edge;
734
735 if (aE1.IsSame(aE2))
736 continue;
737
738 aD2 = IntersectCurves2d(aV, aS, aEData1, aEData2, aMapEdgeLen);
739 if (aD2 > aD2max) {
740 aD2max = aD2;
741 }
742 }
743 }
744 //
745 if (aD2max>aTol2) {
746 aTol = 1.01 * sqrt(aD2max);
747 UpdateShape(aV, aTol, aMapToAvoid);
748 }
749 }// for (i=1; i<=aNbV; ++i) {
750}
751
4e57c75e 752//=======================================================================
753// Function : CorrectEdgeTolerance
754// purpose : Correct tolerances for Edge
755//=======================================================================
756void CorrectEdgeTolerance (const TopoDS_Edge& myShape,
757 const TopoDS_Face& S,
3510db62 758 const Standard_Real aMaxTol,
759 const BOPCol_IndexedMapOfShape& aMapToAvoid)
4e57c75e 760{
761 //
762 // 1. Minimum of conditions to Perform
763 Handle (BRep_CurveRepresentation) myCref;
764 Handle (Adaptor3d_HCurve) myHCurve;
765
766 myCref.Nullify();
767
768 Handle(BRep_TEdge)& TEx = *((Handle(BRep_TEdge)*)&myShape.TShape());
769 BRep_ListIteratorOfListOfCurveRepresentation itcrx(TEx->Curves());
770 Standard_Boolean Degenerated, SameParameterx, SameRangex;
771
772 Standard_Integer unique = 0;
773
774 Degenerated = TEx->Degenerated();
775 SameParameterx = TEx->SameParameter();
776 SameRangex = TEx->SameRange();
777
778 if (!SameRangex && SameParameterx) {
779 return;
780 }
781
782 Handle(Geom_Curve) C3d;
783 while (itcrx.More()) {
784 const Handle(BRep_CurveRepresentation)& cr = itcrx.Value();
785 if (cr->IsCurve3D()) {
786 unique++;
787 if (myCref.IsNull() && !cr->Curve3D().IsNull()) {
788 myCref = cr;
789 }
790 }
791 itcrx.Next();
792 }
793
794 if (unique==0) {
795 return;//...No3DCurve
796 }
797 if (unique>1) {
798 return;//...Multiple3DCurve;
799 }
800
801 if (myCref.IsNull() && !Degenerated) {
802 itcrx.Initialize(TEx->Curves());
803 while (itcrx.More()) {
804 const Handle(BRep_CurveRepresentation)& cr = itcrx.Value();
805 if (cr->IsCurveOnSurface()) {
806 myCref = cr;
807 break;
808 }
809 itcrx.Next();
810 }
811 }
812
813 else if (!myCref.IsNull() && Degenerated){
814 return ;//...InvalidDegeneratedFlag;
815 }
816
817 if (!myCref.IsNull()) {
c5f3a425 818 Handle(BRep_GCurve) GCref (Handle(BRep_GCurve)::DownCast (myCref));
4e57c75e 819 Standard_Real First,Last;
820 GCref->Range(First,Last);
821 if (Last<=First) {
822 myCref.Nullify();
823 return ;//InvalidRange;
824 }
825
826 else {
827 if (myCref->IsCurve3D()) {
828 Handle(Geom_Curve) C3dx = Handle(Geom_Curve)::DownCast
c26b5a34 829 (myCref->Curve3D()->Transformed
830 (myCref->Location().Transformation()));
4e57c75e 831 GeomAdaptor_Curve GAC3d(C3dx, First, Last);
832 myHCurve = new GeomAdaptor_HCurve(GAC3d);
833 }
834 else { // curve on surface
835 Handle(Geom_Surface) Sref = myCref->Surface();
c26b5a34 836 Sref = Handle(Geom_Surface)::
837 DownCast(Sref->Transformed(myCref->Location().Transformation()));
4e57c75e 838 const Handle(Geom2d_Curve)& PCref = myCref->PCurve();
c26b5a34 839 Handle(GeomAdaptor_HSurface) GAHSref =
840 new GeomAdaptor_HSurface(Sref);
841 Handle(Geom2dAdaptor_HCurve) GHPCref =
842 new Geom2dAdaptor_HCurve(PCref, First, Last);
4e57c75e 843 Adaptor3d_CurveOnSurface ACSref(GHPCref,GAHSref);
844 myHCurve = new Adaptor3d_HCurveOnSurface(ACSref);
845 }
846 }
847 }
848
849 //===============================================
850 // 2. Tolerances in InContext
851 {
852 if (myCref.IsNull())
853 return;
854 Standard_Boolean ok=Standard_True;;
855
856 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&myShape.TShape());
857 Standard_Real Tol = BRep_Tool::Tolerance(TopoDS::Edge(myShape));
858 Standard_Real aNewTol=Tol;
859
860 Standard_Boolean SameParameter = TE->SameParameter();
861 Standard_Boolean SameRange = TE->SameRange();
862 Standard_Real First = myHCurve->FirstParameter();
863 Standard_Real Last = myHCurve->LastParameter();
4e57c75e 864 Standard_Real Delta =1.e-12;
865
866 Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &S.TShape());
867 const TopLoc_Location& Floc = S.Location();
868 const TopLoc_Location& TFloc = TF->Location();
869 const Handle(Geom_Surface)& Su = TF->Surface();
870 TopLoc_Location L = (Floc * TFloc).Predivided(myShape.Location());
4e57c75e 871 Standard_Boolean pcurvefound = Standard_False;
872
873 BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
874 while (itcr.More()) {
875 const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
876 if (cr != myCref && cr->IsCurveOnSurface(Su,L)) {
877 pcurvefound = Standard_True;
c5f3a425 878 Handle(BRep_GCurve) GC (Handle(BRep_GCurve)::DownCast (cr));
4e57c75e 879 Standard_Real f,l;
880 GC->Range(f,l);
881 if (SameRange && (f != First || l != Last)) {
d3f26155 882 return ;//BRepCheck_InvalidSameRangeFlag;
4e57c75e 883 }
c26b5a34 884
4e57c75e 885 Handle(Geom_Surface) Sb = cr->Surface();
c26b5a34 886 Sb = Handle(Geom_Surface)::
887 DownCast (Su->Transformed(L.Transformation()));
4e57c75e 888 Handle(Geom2d_Curve) PC = cr->PCurve();
c26b5a34 889 Handle(GeomAdaptor_HSurface) GAHS =
890 new GeomAdaptor_HSurface(Sb);
891 Handle(Geom2dAdaptor_HCurve) GHPC =
892 new Geom2dAdaptor_HCurve(PC,f,l);
4e57c75e 893 Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
c26b5a34 894 ok = Validate(myHCurve->Curve(), ACS,
895 Tol, SameParameter, aNewTol);
4e57c75e 896 if (ok) {
4e57c75e 897 if (aNewTol<aMaxTol) {
3510db62 898 UpdateShape(myShape, aNewTol+Delta, aMapToAvoid);
899 CorrectVertexTolerance(myShape, aMapToAvoid);
4e57c75e 900 }
901 }
902
903 if (cr->IsCurveOnClosedSurface()) {
904 //checkclosed = Standard_True;
905 GHPC->ChangeCurve2d().Load(cr->PCurve2(),f,l); // same bounds
543a9964 906 ACS.Load(GHPC, GAHS); // sans doute inutile
4e57c75e 907 ok = Validate(myHCurve->Curve(),ACS,Tol,SameParameter, aNewTol);
908 if (ok) {
4e57c75e 909 if (aNewTol<aMaxTol) {
3510db62 910 UpdateShape(myShape, aNewTol+Delta, aMapToAvoid);
911 CorrectVertexTolerance(myShape, aMapToAvoid);
4e57c75e 912 }
913 }
914 }
915 }
916 itcr.Next();
917 }
918
919 if (!pcurvefound) {
920 Handle(Geom_Plane) P;
921 Handle(Standard_Type) styp = Su->DynamicType();
922 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
c26b5a34 923 P = Handle(Geom_Plane)::
924 DownCast(Handle(Geom_RectangularTrimmedSurface)::
925 DownCast(Su)->BasisSurface());
4e57c75e 926 }
927 else {
928 P = Handle(Geom_Plane)::DownCast(Su);
929 }
930 if (P.IsNull()) { // not a plane
c26b5a34 931 return;
4e57c75e 932 }
933
934 else {// on fait la projection a la volee, comme BRep_Tool
c26b5a34 935 P = Handle(Geom_Plane)::
936 DownCast(P->Transformed(L.Transformation()));
4e57c75e 937 //on projette Cref sur ce plan
938 Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(P);
939
940 // Dub - Normalement myHCurve est une GeomAdaptor_HCurve
c26b5a34 941 GeomAdaptor_Curve& Gac =
942 Handle(GeomAdaptor_HCurve)::DownCast(myHCurve)->ChangeCurve();
4e57c75e 943 Handle(Geom_Curve) C3dx = Gac.Curve();
c26b5a34 944 Handle(Geom_Curve) ProjOnPlane =
945 GeomProjLib::ProjectOnPlane(new Geom_TrimmedCurve(C3dx,First,Last),
946 P,
947 P->Position().Direction(),
948 Standard_True);
4e57c75e 949
c26b5a34 950 Handle(GeomAdaptor_HCurve) aHCurve =
951 new GeomAdaptor_HCurve(ProjOnPlane);
4e57c75e 952
953 ProjLib_ProjectedCurve proj(GAHS,aHCurve);
954 Handle(Geom2d_Curve) PC = Geom2dAdaptor::MakeCurve(proj);
955 Handle(Geom2dAdaptor_HCurve) GHPC =
c26b5a34 956 new Geom2dAdaptor_HCurve(PC,
957 myHCurve->FirstParameter(),
958 myHCurve->LastParameter());
4e57c75e 959
960 Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
961
962 Standard_Boolean okx = Validate(myHCurve->Curve(),ACS,
c26b5a34 963 Tol,Standard_True, aNewTol);
4e57c75e 964 if (okx) {
4e57c75e 965 if (aNewTol<aMaxTol) {
3510db62 966 UpdateShape(myShape, aNewTol+Delta, aMapToAvoid);
967 CorrectVertexTolerance(myShape, aMapToAvoid);
4e57c75e 968 }
969 }
970 }
4e57c75e 971 }//end of if (!pcurvefound) {
972 } // end of 2. Tolerances in InContext
4e57c75e 973}
4e57c75e 974//=======================================================================
975//function : CorrectVertexTolerance
976//purpose :
977//=======================================================================
3510db62 978void CorrectVertexTolerance(const TopoDS_Edge& aE,
979 const BOPCol_IndexedMapOfShape& aMapToAvoid)
4e57c75e 980{
4e57c75e 981 Standard_Real aTolE, aTolV;
c26b5a34 982 TopoDS_Iterator aIt;
983 //
4e57c75e 984 aTolE=BRep_Tool::Tolerance(aE);
c26b5a34 985 aIt.Initialize(aE);
986 for(; aIt.More(); aIt.Next()) {
987 const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aIt.Value());
4e57c75e 988 aTolV=BRep_Tool::Tolerance(aV);
989 if (aTolV<aTolE) {
3510db62 990 UpdateShape(aV, aTolE, aMapToAvoid);
4e57c75e 991 }
992 }
993}
4e57c75e 994//=======================================================================
995//function : Validate
996//purpose :
997//=======================================================================
998Standard_Boolean Validate(const Adaptor3d_Curve& CRef,
999 const Adaptor3d_Curve& Other,
1000 const Standard_Real Tol,
1001 const Standard_Boolean SameParameter,
1002 Standard_Real& aNewTolerance)
1003{
1004 Standard_Real First, Last, MaxDistance, aD, Tol2;
1005
1006 First = CRef.FirstParameter();
1007 Last = CRef.LastParameter();
1008 MaxDistance = 0.;
1009 Tol2 = Tol*Tol;
c26b5a34 1010 //
1011 Standard_Integer NCONTROL=23;
4e57c75e 1012 Standard_Integer i, aNC1=NCONTROL-1;
1013
1014 Standard_Boolean aFlag=Standard_False;
1015 Standard_Boolean proj = (!SameParameter ||
1016 First != Other.FirstParameter() ||
1017 Last != Other.LastParameter());
1018 //
1019 // 1.
1020 if (!proj) {
1021 for (i = 0; i < NCONTROL; i++) {
1022 Standard_Real prm = ((aNC1-i)*First + i*Last)/aNC1;
1023 gp_Pnt pref = CRef.Value(prm);
1024 gp_Pnt pother = Other.Value(prm);
1025
1026 aD=pref.SquareDistance(pother);
1027
1028 if (aD > Tol2) {
1029 if (aD>MaxDistance) {
1030 MaxDistance=aD;
1031 }
1032 aFlag=Standard_True;
1033 }
1034 }
1035
1036 if (aFlag) {
1037 aNewTolerance=sqrt(MaxDistance);
1038 }
1039 return aFlag;
1040 }
1041
1042 //
1043 // 2.
1044 else {
1045 Extrema_LocateExtPC refd,otherd;
1046 Standard_Real OFirst, OLast;
1047 OFirst = Other.FirstParameter();
1048 OLast = Other.LastParameter();
1049
1050 gp_Pnt pd = CRef.Value(First);
1051 gp_Pnt pdo = Other.Value(OFirst);
1052
1053 aD = pd.SquareDistance(pdo);
1054 if (aD > Tol2) {
1055 if (aD>MaxDistance) {
1056 MaxDistance=aD;
1057 }
1058 aFlag=Standard_True;
1059 }
1060
1061 pd = CRef.Value(Last);
1062 pdo = Other.Value(OLast);
1063 aD = pd.SquareDistance(pdo);
1064 if (aD > Tol2 && aD > MaxDistance) {
1065 MaxDistance=aD;
1066 aFlag=Standard_True;
1067 }
1068
1069 refd.Initialize(CRef, First, Last, CRef.Resolution(Tol));
1070 otherd.Initialize(Other, OFirst, OLast, Other.Resolution(Tol));
1071
1072 for (i = 2; i< aNC1; i++) {
1073 Standard_Real rprm = ((aNC1-i)*First + i*Last)/aNC1;
1074 gp_Pnt pref = CRef.Value(rprm);
1075
1076 Standard_Real oprm = ((aNC1-i)*OFirst + i*OLast)/aNC1;
1077 gp_Pnt pother = Other.Value(oprm);
1078
1079 refd.Perform(pother,rprm);
1080 if (!refd.IsDone() || refd.SquareDistance() > Tol2) {
1081 if (refd.IsDone()) {
1082 aD=refd.SquareDistance();
1083 if (aD > Tol2 && aD>MaxDistance) {
1084 aFlag=Standard_True;
1085 MaxDistance=aD;
1086 }
1087 }
1088 }
1089
1090 otherd.Perform(pref,oprm);
1091 if (!otherd.IsDone() || otherd.SquareDistance() > Tol2) {
1092
1093 if (otherd.IsDone()) {
1094 aD=otherd.SquareDistance();
1095 if (aD > Tol2 && aD>MaxDistance) {
1096 aFlag=Standard_True;
1097 MaxDistance=aD;
1098 }
1099 }
1100 }
1101 }
1102 }
1103
1104 aD=sqrt (MaxDistance);
1105 aNewTolerance=aD;
4e57c75e 1106 return aFlag;
4e57c75e 1107}
1108//=======================================================================
1109// Function : UpdateEdges
1110// purpose :
1111//=======================================================================
3510db62 1112void UpdateEdges(const TopoDS_Face& aF,
1113 const BOPCol_IndexedMapOfShape& aMapToAvoid)
4e57c75e 1114{
1115 Standard_Real aTolF, aTolE, aTolV;
1116 TopoDS_Iterator aItF, aItW, aItE;
4e57c75e 1117 //
c26b5a34 1118 aTolE=aTolF= BRep_Tool::Tolerance(aF);
4e57c75e 1119 aItF.Initialize(aF);
1120 for (; aItF.More(); aItF.Next()) {
1121 const TopoDS_Shape& aS = aItF.Value();
1122 if (aS.ShapeType()==TopAbs_WIRE) {
1123 aItW.Initialize(aS);
1124 for (; aItW.More(); aItW.Next()) {
c26b5a34 1125 const TopoDS_Edge& aE=*((TopoDS_Edge*)&aItW.Value());
4e57c75e 1126 aTolE = BRep_Tool::Tolerance(aE);
1127 if (aTolE < aTolF) {
3510db62 1128 UpdateShape(aE, aTolF, aMapToAvoid);
4e57c75e 1129 aTolE = aTolF;
1130 }
4e57c75e 1131 }
1132 }
1133 else {
c26b5a34 1134 const TopoDS_Vertex& aV=*(TopoDS_Vertex*)&aItF.Value();
4e57c75e 1135 aTolV = BRep_Tool::Tolerance(aV);
1136 if (aTolV < aTolE) {
3510db62 1137 UpdateShape(aV, aTolF, aMapToAvoid);
4e57c75e 1138 }
1139 }
1140 }
1141}
e98e3990 1142//=======================================================================
3510db62 1143//function : UpdateShape
1144//purpose :
1145//=======================================================================
1146void UpdateShape(const TopoDS_Shape& aS,
1147 const Standard_Real aTol,
1148 const BOPCol_IndexedMapOfShape& aMapToAvoid)
1149{
1150 if (aMapToAvoid.Contains(aS)) {
1151 return;
1152 }
1153 //
1154 TopAbs_ShapeEnum aType;
1155 BRep_Builder aBB;
1156 //
1157 aType=aS.ShapeType();
1158 if (aType==TopAbs_EDGE) {
1159 const TopoDS_Edge& aE = *((TopoDS_Edge*)&aS);
1160 aBB.UpdateEdge(aE, aTol);
1161 }
1162 else if (aType==TopAbs_VERTEX) {
1163 const TopoDS_Vertex& aV = *((TopoDS_Vertex*)&aS);
1164 aBB.UpdateVertex(aV, aTol);
1165 }
1166}
1167//=======================================================================
e98e3990 1168// Function : ComputeTolerance
1169// purpose :
1170//=======================================================================
1171Standard_Boolean BOPTools_AlgoTools::ComputeTolerance
1172 (const TopoDS_Face& theFace,
1173 const TopoDS_Edge& theEdge,
1174 Standard_Real& theMaxDist,
1b7ae951 1175 Standard_Real& theMaxPar)
e98e3990 1176{
1b7ae951 1177 BRepLib_CheckCurveOnSurface aCS;
e98e3990 1178 //
1b7ae951 1179 aCS.Init(theEdge, theFace);
1180 aCS.Perform();
1181 if (!aCS.IsDone()) {
1182 return Standard_False;
e98e3990 1183 }
1184 //
1b7ae951 1185 theMaxDist = aCS.MaxDistance();
1186 theMaxPar = aCS.MaxParameter();
c7b59798 1187 //
1b7ae951 1188 return Standard_True;
e98e3990 1189}