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