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