0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[occt.git] / src / BOPAlgo / BOPAlgo_WireSplitter_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#include <BOPAlgo_WireEdgeSet.hxx>
16#include <BOPAlgo_WireSplitter.hxx>
17#include <BOPTools_AlgoTools2D.hxx>
18#include <BRep_Tool.hxx>
19#include <BRepAdaptor_Surface.hxx>
20#include <Geom2d_Curve.hxx>
21#include <Geom2d_Line.hxx>
22#include <Geom2dAdaptor_Curve.hxx>
23#include <Geom2dInt_GInter.hxx>
24#include <GeomAdaptor_Surface.hxx>
25#include <gp_Dir2d.hxx>
26#include <gp_Pnt2d.hxx>
27#include <gp_Vec2d.hxx>
28#include <IntRes2d_Domain.hxx>
29#include <IntRes2d_IntersectionPoint.hxx>
30#include <Precision.hxx>
31#include <TopExp.hxx>
32#include <TopExp_Explorer.hxx>
33#include <TopoDS.hxx>
34#include <TopoDS_Edge.hxx>
35#include <TopoDS_Face.hxx>
36#include <TopoDS_Iterator.hxx>
37#include <TopoDS_Vertex.hxx>
38#include <TopoDS_Wire.hxx>
39#include <TopTools_ShapeMapHasher.hxx>
40#include <Geom2dLProp_CLProps2d.hxx>
41#include <TColgp_SequenceOfPnt2d.hxx>
42#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
43#include <TopTools_ListOfShape.hxx>
44#include <TopTools_MapOfShape.hxx>
45#include <TopTools_SequenceOfShape.hxx>
46
47typedef NCollection_DataMap \
48 <TopoDS_Shape, Standard_Boolean, TopTools_ShapeMapHasher> \
49 MyDataMapOfShapeBoolean;
50//
51
52static
53 Standard_Real Angle (const gp_Dir2d& aDir2D);
54
55static
56 Standard_Real Angle2D (const TopoDS_Vertex& aV,
57 const TopoDS_Edge& anEdge,
58 const TopoDS_Face& myFace,
59 const GeomAdaptor_Surface& aGAS,
60 const Standard_Boolean aFlag,
61 const Handle(IntTools_Context)& theContext);
62
63static
64 void GetNextVertex(const TopoDS_Vertex& aV,
65 const TopoDS_Edge& aE,
66 TopoDS_Vertex& aV1);
67
68static
69 Standard_Real AngleIn(const TopoDS_Edge& aEIn,
70 const BOPAlgo_ListOfEdgeInfo& aLEInfo);
71
72static
73 Standard_Integer NbWaysOut(const BOPAlgo_ListOfEdgeInfo& aLEInfo);
74
75static
76 gp_Pnt2d Coord2dVf (const TopoDS_Edge& aE,
77 const TopoDS_Face& aF);
78
79static
80 gp_Pnt2d Coord2d (const TopoDS_Vertex& aV1,
81 const TopoDS_Edge& aE1,
82 const TopoDS_Face& aF);
83
84static
85 Standard_Real ClockWiseAngle(const Standard_Real aAngleIn,
86 const Standard_Real aAngleOut);
87
88static
89 void Path (const GeomAdaptor_Surface& aGAS,
90 const TopoDS_Face& myFace,
91 const MyDataMapOfShapeBoolean& aVertMap,
92 const TopoDS_Vertex& aVa,
93 const TopoDS_Edge& aEOuta,
94 BOPAlgo_EdgeInfo& anEdgeInfo,
95 TopTools_SequenceOfShape& aLS,
96 TopTools_SequenceOfShape& aVertVa,
97 TColgp_SequenceOfPnt2d& aCoordVa,
98 BOPTools_ConnexityBlock& aCB,
99 BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap);
100
101static
102 Standard_Real Angle (const gp_Dir2d& aDir2D);
103
104static
105 Standard_Real Tolerance2D (const TopoDS_Vertex& aV,
106 const GeomAdaptor_Surface& aGAS);
107
108
109
110static
111 Standard_Real UTolerance2D (const TopoDS_Vertex& aV,
112 const GeomAdaptor_Surface& aGAS);
113static
114 Standard_Real VTolerance2D (const TopoDS_Vertex& aV,
115 const GeomAdaptor_Surface& aGAS);
116
117static
118 void RefineAngles(const TopoDS_Face& myFace,
119 BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo&,
120 const Handle(IntTools_Context)&);
121
122
123static
124 void RefineAngles(const TopoDS_Vertex& ,
125 const TopoDS_Face& ,
126 BOPAlgo_ListOfEdgeInfo&,
127 const Handle(IntTools_Context)&);
128
129static
130 Standard_Boolean RefineAngle2D(const TopoDS_Vertex& ,
131 const TopoDS_Edge& ,
132 const TopoDS_Face& ,
133 const Standard_Real ,
134 const Standard_Real ,
135 const Standard_Real,
136 Standard_Real& ,
137 const Handle(IntTools_Context)& );
138
139//=======================================================================
140//function : SplitBlock
141//purpose :
142//=======================================================================
143void BOPAlgo_WireSplitter::SplitBlock(const TopoDS_Face& myFace,
144 BOPTools_ConnexityBlock& aCB,
145 const Handle(IntTools_Context)& theContext)
146{
147 Standard_Boolean bNothingToDo, bIsClosed, bIsIN;
148 Standard_Integer aIx, aNb, i, aCntIn, aCntOut;
149 Standard_Real aAngle;
150 TopAbs_Orientation aOr;
151 TopoDS_Iterator aItS;
152 TopoDS_Vertex aVV;
153 TopoDS_Shape aV1;
154 TopTools_ListIteratorOfListOfShape aIt;
155 BOPAlgo_ListIteratorOfListOfEdgeInfo aItLEI;
156 //
157 BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo mySmartMap(100);
158 MyDataMapOfShapeBoolean aVertMap;
159 //
160 const TopTools_ListOfShape& myEdges=aCB.Shapes();
161
162 TopTools_MapOfShape aMS;
163 //
164 // 1.Filling mySmartMap
165 aIt.Initialize(myEdges);
166 for(; aIt.More(); aIt.Next()) {
167 const TopoDS_Edge& aE=(*(TopoDS_Edge *)&aIt.Value());
168 if (!BOPTools_AlgoTools2D::HasCurveOnSurface (aE, myFace)) {
169 continue;
170 }
171 //
172 bIsClosed = BRep_Tool::Degenerated(aE) ||
173 BRep_Tool::IsClosed(aE, myFace);
174
175 if (!aMS.Add (aE) && !bIsClosed)
176 aMS.Remove (aE);
177
178 //
179 aItS.Initialize(aE);
180 for(i = 0; aItS.More(); aItS.Next(), ++i) {
181 const TopoDS_Shape& aV = aItS.Value();
182 aIx = mySmartMap.FindIndex(aV);
183 if (!aIx) {
184 BOPAlgo_ListOfEdgeInfo aLEIx;
185 aIx = mySmartMap.Add(aV, aLEIx);
186 }
187 //
188 BOPAlgo_ListOfEdgeInfo& aLEI = mySmartMap(aIx);
189 BOPAlgo_EdgeInfo aEI;
190 //
191 aEI.SetEdge(aE);
192 aOr = aV.Orientation();
193 bIsIN = (aOr == TopAbs_REVERSED);
194 aEI.SetInFlag(bIsIN);
195 aLEI.Append(aEI);
196 //
197 if (!i) {
198 aV1 = aV;
199 } else {
200 bIsClosed = bIsClosed || aV1.IsSame(aV);
201 }
202 //
203 if (aVertMap.IsBound(aV)) {
204 if (bIsClosed) {
205 aVertMap.ChangeFind(aV) = bIsClosed;
206 }
207 } else {
208 aVertMap.Bind(aV, bIsClosed);
209 }
210 }
211 }
212 //
213 aNb=mySmartMap.Extent();
214 //
215 bNothingToDo=Standard_True;
216 for (i=1; i<=aNb; i++) {
217 aCntIn=0;
218 aCntOut=0;
219 const BOPAlgo_ListOfEdgeInfo& aLEInfo = mySmartMap(i);
220 BOPAlgo_ListIteratorOfListOfEdgeInfo anIt(aLEInfo);
221 for (; anIt.More(); anIt.Next()) {
222 const BOPAlgo_EdgeInfo& aEI=anIt.Value();
223 if (aEI.IsIn()) {
224 aCntIn++;
225 }
226 else {
227 aCntOut++;
228 }
229 }
230 if (aCntIn!=1 || aCntOut!=1) {
231 bNothingToDo=Standard_False;
232 break;
233 }
234 }
235 //
236 // Each vertex has one edge In and one - Out. Good.
237 // But it is not enough to consider that nothing to do with this.
238 // We must check edges on TShape coincidence.
239 // If there are such edges there is something to do with.
240 if (bNothingToDo) {
241 Standard_Integer aNbE, aNbMapEE;
242 Standard_Boolean bFlag;
243 //
244 TopTools_IndexedDataMapOfShapeListOfShape aMapEE(100);
245 aNbE=myEdges.Extent();
246 //
247 aIt.Initialize(myEdges);
248 for (; aIt.More(); aIt.Next()) {
249 const TopoDS_Shape& aE = aIt.Value();
250 if (!aMapEE.Contains(aE)) {
251 TopTools_ListOfShape aLEx;
252 aLEx.Append(aE);
253 aMapEE.Add(aE, aLEx);
254 }
255 else {
256 TopTools_ListOfShape& aLEx=aMapEE.ChangeFromKey(aE);
257 aLEx.Append(aE);
258 }
259 }
260 //
261 bFlag=Standard_True;
262 aNbMapEE=aMapEE.Extent();
263 for (i=1; i<=aNbMapEE; ++i) {
264 const TopTools_ListOfShape& aLEx=aMapEE(i);
265 aNbE=aLEx.Extent();
266 if (aNbE==1) {// usual case
267 continue;
268 }
269 else if (aNbE==2){
270 const TopoDS_Shape& aE1=aLEx.First();
271 const TopoDS_Shape& aE2=aLEx.Last();
272 if (aE1.IsSame(aE2)) {
273 bFlag=Standard_False;
274 break;
275 }
276 }
277 else {
278 bFlag=Standard_False;
279 break;
280 }
281 }
282 bNothingToDo=bNothingToDo && bFlag;
283 } // if (bNothingToDo) {
284 if (bNothingToDo) {
285 TopoDS_Wire aW;
286 //
287 TopTools_ListOfShape& aLECB=aCB.ChangeShapes();
288 BOPAlgo_WireSplitter::MakeWire(aLECB, aW);
289 TopTools_ListOfShape& aLoops=aCB.ChangeLoops();
290 aLoops.Append(aW);
291 //
292 return;
293 }
294 //
295 // 3. Angles in mySmartMap
296 const BRepAdaptor_Surface& aBAS = theContext->SurfaceAdaptor(myFace);
297 const GeomAdaptor_Surface& aGAS=aBAS.Surface();
298 //
299 for (i=1; i<=aNb; i++) {
300 const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&mySmartMap.FindKey(i)));
301 const BOPAlgo_ListOfEdgeInfo& aLEI= mySmartMap(i);
302 aItLEI.Initialize(aLEI);
303 for (; aItLEI.More(); aItLEI.Next()) {
304 BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue();
305 const TopoDS_Edge& aE=aEI.Edge();
306 aEI.SetIsInside (!aMS.Contains (aE));
307 //
308 aVV = aV;
309 bIsIN = aEI.IsIn();
310 aOr = bIsIN ? TopAbs_REVERSED : TopAbs_FORWARD;
311 aVV.Orientation(aOr);
312 aAngle = Angle2D(aVV, aE, myFace, aGAS, bIsIN, theContext);
313 aEI.SetAngle(aAngle);
314 }
315 }// for (i=1; i<=aNb; i++) {
316 //
317 //Theme: The treatment p-curves convergent in node.
318 //The refining the angles of p-curves taking into account
319 //bounding curves if exist.
320 RefineAngles(myFace, mySmartMap, theContext);
321 //
322 // 4. Do
323 //
324 Standard_Boolean bIsOut, bIsNotPassed;
325 TopTools_SequenceOfShape aLS, aVertVa;
326 TColgp_SequenceOfPnt2d aCoordVa;
327 //
328 for (i=1; i<=aNb; ++i) {
329 const TopoDS_Vertex& aVa=(*(TopoDS_Vertex *)(&mySmartMap.FindKey(i)));
330 const BOPAlgo_ListOfEdgeInfo& aLEI=mySmartMap(i);
331 aItLEI.Initialize(aLEI);
332 for (; aItLEI.More(); aItLEI.Next()) {
333 BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue();
334 const TopoDS_Edge& aEOuta=aEI.Edge();
335 //
336 bIsOut=!aEI.IsIn();
337 bIsNotPassed=!aEI.Passed();
338 if (bIsOut && bIsNotPassed) {
339 //
340 aLS.Clear();
341 aVertVa.Clear();
342 aCoordVa.Clear();
343 //
344 Path(aGAS, myFace, aVertMap, aVa, aEOuta, aEI, aLS,
345 aVertVa, aCoordVa, aCB, mySmartMap);
346 }
347 }
348 }// for (i=1; i<=aNb; ++i) {
349}
350//=======================================================================
351// function: Path
352// purpose:
353//=======================================================================
354void Path (const GeomAdaptor_Surface& aGAS,
355 const TopoDS_Face& myFace,
356 const MyDataMapOfShapeBoolean& aVertMap,
357 const TopoDS_Vertex& aVFirst,
358 const TopoDS_Edge& aEFirst,
359 BOPAlgo_EdgeInfo& aEIFirst,
360 TopTools_SequenceOfShape& aLS,
361 TopTools_SequenceOfShape& aVertVa,
362 TColgp_SequenceOfPnt2d& aCoordVa,
363 BOPTools_ConnexityBlock& aCB,
364 BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap)
365{
366 Standard_Integer i, j, aNb, aNbj;
367 Standard_Real anAngleIn, anAngleOut, anAngle, aMinAngle;
368 Standard_Real aTol2D, aTol2D2, aD2, aTwoPI;
369 Standard_Boolean anIsSameV2d, anIsSameV, anIsOut, anIsNotPassed;
370 Standard_Boolean bIsClosed;
371 TopoDS_Vertex aVa, aVb;
372 TopoDS_Edge aEOuta;
373 BOPAlgo_ListIteratorOfListOfEdgeInfo anIt;
374 Standard_Real eps = Epsilon(1.);
375 //
376 aVa = aVFirst;
377 aEOuta = aEFirst;
378 BOPAlgo_EdgeInfo* anEdgeInfo = &aEIFirst;
379 //
380 aTwoPI = M_PI + M_PI;
381
382 NCollection_Sequence <BOPAlgo_EdgeInfo*> anInfoSeq;
383 //
384 // append block
385 //
386 for (;;) {
387 // Do not escape through edge from which you enter
388 aNb=aLS.Length();
389 if (aNb==1) {
390 const TopoDS_Shape& anEPrev=aLS(aNb);
391 if (anEPrev.IsSame(aEOuta)) {
392 return;
393 }
394 }
395 //
396 anEdgeInfo->SetPassed(Standard_True);
397 aLS.Append(aEOuta);
398 aVertVa.Append(aVa);
399 anInfoSeq.Append (anEdgeInfo);
400
401 TopoDS_Vertex pVa=aVa;
402 pVa.Orientation(TopAbs_FORWARD);
403 gp_Pnt2d aPa=Coord2d(pVa, aEOuta, myFace);
404 aCoordVa.Append(aPa);
405
406 GetNextVertex (pVa, aEOuta, aVb);
407
408 gp_Pnt2d aPb=Coord2d(aVb, aEOuta, myFace);
409
410 const BOPAlgo_ListOfEdgeInfo& aLEInfo=mySmartMap.FindFromKey(aVb);
411 //
412 aTol2D = 2.*Tolerance2D(aVb, aGAS);
413 aTol2D2 = aTol2D * aTol2D;
414 //
415 bIsClosed = aVertMap.Find(aVb);
416 {
417 TopTools_ListOfShape aBuf;
418 Standard_Boolean bHasEdge = Standard_False;
419 //
420 aNb = aLS.Length();
421 for (i = aNb; i>0; --i) {
422 const TopoDS_Shape& aVPrev=aVertVa(i);
423 const gp_Pnt2d& aPaPrev=aCoordVa(i);
424 const TopoDS_Edge& aEPrev = TopoDS::Edge(aLS(i));
425 //
426 aBuf.Append(aEPrev);
427 if (!bHasEdge) {
428 bHasEdge = !BRep_Tool::Degenerated(aEPrev);
429 // do not create wire from degenerated edges only
430 if (!bHasEdge) {
431 continue;
432 }
433 }
434 //
435 anIsSameV = aVPrev.IsSame(aVb);
436 anIsSameV2d = anIsSameV;
437 if (anIsSameV) {
438 if(bIsClosed) {
439 aD2 = aPaPrev.SquareDistance(aPb);
440 anIsSameV2d = aD2 < aTol2D2;
441 if (anIsSameV2d) {
442 Standard_Real udist = fabs(aPaPrev.X() - aPb.X());
443 Standard_Real vdist = fabs(aPaPrev.Y() - aPb.Y());
444 Standard_Real aTolU = 2.*UTolerance2D(aVb, aGAS);
445 Standard_Real aTolV = 2.*VTolerance2D(aVb, aGAS);
446 //
447 if((udist > aTolU) || (vdist > aTolV)) {
448 anIsSameV2d = Standard_False;
449 }
450 }
451 }
452 }//if (anIsSameV) {
453 //
454 if (anIsSameV && anIsSameV2d) {
455 Standard_Integer iPriz;
456 iPriz=1;
457 if (aBuf.Extent()==2) {
458 if(aBuf.First().IsSame(aBuf.Last())) {
459 iPriz=0;
460 }
461 }
462 if (iPriz) {
463 TopoDS_Wire aW;
464 BOPAlgo_WireSplitter::MakeWire(aBuf, aW);
465 aCB.ChangeLoops().Append(aW);
466 }
467 //
468 aNbj=i-1;
469 if (aNbj<1) {
470 //
471 aLS.Clear();
472 aVertVa.Clear();
473 aCoordVa.Clear();
474 //
475 return;
476 }
477 //
478 TopTools_SequenceOfShape aLSt, aVertVat;
479 TColgp_SequenceOfPnt2d aCoordVat;
480 NCollection_Sequence <BOPAlgo_EdgeInfo*> anInfoSeqTmp;
481 //
482 aVb=(*(TopoDS_Vertex *)(&aVertVa(i)));
483 //
484 for (j=1; j<=aNbj; ++j) {
485 aLSt.Append(aLS(j));
486 aVertVat.Append(aVertVa(j));
487 aCoordVat.Append(aCoordVa(j));
488 anInfoSeqTmp.Append (anInfoSeq (j));
489 }
490 //
491 aLS=aLSt;
492 aVertVa=aVertVat;
493 aCoordVa=aCoordVat;
494 anInfoSeq = anInfoSeqTmp;
495
496 aEOuta = TopoDS::Edge (aLS.Last());
497 anEdgeInfo = anInfoSeq.Last();
498 //
499 break;
500 }
501 }
502 }
503 //
504 // aEOutb
505 BOPAlgo_EdgeInfo *pEdgeInfo=NULL;
506 //
507 anAngleIn = AngleIn(aEOuta, aLEInfo);
508 aMinAngle = 100.;
509 Standard_Integer iCnt = NbWaysOut(aLEInfo);
510
511 Standard_Boolean isBoundary = !anEdgeInfo->IsInside();
512 Standard_Integer aNbWaysInside = 0;
513 BOPAlgo_EdgeInfo *pOnlyWayIn = NULL;
514
515 anIt.Initialize(aLEInfo);
516 for (; anIt.More(); anIt.Next()) {
517 BOPAlgo_EdgeInfo& anEI=anIt.ChangeValue();
518 const TopoDS_Edge& aE=anEI.Edge();
519 anIsOut=!anEI.IsIn();
520 anIsNotPassed=!anEI.Passed();
521 //
522 if (anIsOut && anIsNotPassed) {
523 //
524 // Is there one way to go out of the vertex
525 // we have to use it only.
526 //
527 if (!iCnt) {
528 // no way to go . (Error)
529 return;
530 }
531 //
532 if (iCnt==1) {
533 // the one and only way to go out .
534 pEdgeInfo=&anEI;
535 break;
536 }
537 //
538 if (aE.IsSame(aEOuta)) {
539 anAngle = aTwoPI;
540 } else {
541 //check 2d distance
542 if (bIsClosed) {
543 gp_Pnt2d aP2Dx;
544 //
545 aP2Dx = Coord2dVf(aE, myFace);
546 //
547 aD2 = aP2Dx.SquareDistance(aPb);
548 if (aD2 > aTol2D2){
549 continue;
550 }
551 }
552 //
553 // Look for minimal angle and make the choice.
554 anAngleOut=anEI.Angle();
555 anAngle=ClockWiseAngle(anAngleIn, anAngleOut);
556 }
557
558 if (isBoundary && anEI.IsInside())
559 {
560 ++aNbWaysInside;
561 pOnlyWayIn = &anEI;
562 }
563
564 if (anAngle < aMinAngle - eps) {
565 aMinAngle=anAngle;
566 pEdgeInfo=&anEI;
567 }
568 }
569 } // for (; anIt.More(); anIt.Next())
570 if (aNbWaysInside == 1)
571 {
572 pEdgeInfo = pOnlyWayIn;
573 }
574 //
575 if (!pEdgeInfo) {
576 // no way to go . (Error)
577 return;
578 }
579 //
580 aVa = aVb;
581 aEOuta = pEdgeInfo->Edge();
582 anEdgeInfo = pEdgeInfo;
583 }
584}
585//=======================================================================
586// function: ClockWiseAngle
587// purpose:
588//=======================================================================
589 Standard_Real ClockWiseAngle(const Standard_Real aAngleIn,
590 const Standard_Real aAngleOut)
591{
592 Standard_Real aTwoPi=M_PI+M_PI;
593 Standard_Real dA, A1, A2, AIn, AOut ;
594
595 AIn=aAngleIn;
596 AOut=aAngleOut;
597 if (AIn >= aTwoPi) {
598 AIn=AIn-aTwoPi;
599 }
600
601 if (AOut >= aTwoPi) {
602 AOut=AOut-aTwoPi;
603 }
604
605 A1=AIn+M_PI;
606
607 if (A1 >= aTwoPi) {
608 A1=A1-aTwoPi;
609 }
610
611 A2=AOut;
612
613 dA=A1-A2;
614 if (dA <= 0.) {
615 dA=aTwoPi+dA;
616 }
617 //xx
618 //else if (dA <= 1.e-15) {
619 else if (dA <= 1.e-14) {
620 dA=aTwoPi;
621 }
622 return dA;
623}
624//=======================================================================
625// function: Coord2d
626// purpose:
627//=======================================================================
628 gp_Pnt2d Coord2d (const TopoDS_Vertex& aV1,
629 const TopoDS_Edge& aE1,
630 const TopoDS_Face& aF)
631{
632 Standard_Real aT, aFirst, aLast;
633 Handle(Geom2d_Curve) aC2D;
634 gp_Pnt2d aP2D1;
635 //
636 aT=BRep_Tool::Parameter (aV1, aE1, aF);
637 aC2D=BRep_Tool::CurveOnSurface(aE1, aF, aFirst, aLast);
638 aC2D->D0 (aT, aP2D1);
639 //
640 return aP2D1;
641}
642//=======================================================================
643// function: Coord2dVf
644// purpose:
645//=======================================================================
646 gp_Pnt2d Coord2dVf (const TopoDS_Edge& aE,
647 const TopoDS_Face& aF)
648{
649 Standard_Real aCoord=99.;
650 gp_Pnt2d aP2D1(aCoord, aCoord);
651 TopoDS_Iterator aIt;
652 //
653 aIt.Initialize(aE);
654 for (; aIt.More(); aIt.Next()) {
655 const TopoDS_Shape& aVx=aIt.Value();
656 if (aVx.Orientation()==TopAbs_FORWARD) {
657
658 const TopoDS_Vertex& aVxx=(*(TopoDS_Vertex *)(&aVx));// TopoDS::Vertex(aVx);
659 aP2D1=Coord2d(aVxx, aE, aF);
660 return aP2D1;
661 }
662 }
663 return aP2D1;
664}
665
666//=======================================================================
667// function: NbWaysOut
668// purpose:
669//=======================================================================
670Standard_Integer NbWaysOut(const BOPAlgo_ListOfEdgeInfo& aLEInfo)
671{
672 Standard_Boolean bIsOut, bIsNotPassed;
673 Standard_Integer iCnt=0;
674 BOPAlgo_ListIteratorOfListOfEdgeInfo anIt;
675 //
676 anIt.Initialize(aLEInfo);
677 for (; anIt.More(); anIt.Next()) {
678 const BOPAlgo_EdgeInfo& anEI=anIt.Value();
679 //
680 bIsOut=!anEI.IsIn();
681 bIsNotPassed=!anEI.Passed();
682 if (bIsOut && bIsNotPassed) {
683 iCnt++;
684 }
685 }
686 return iCnt;
687}
688
689//=======================================================================
690// function: AngleIn
691// purpose:
692//=======================================================================
693 Standard_Real AngleIn(const TopoDS_Edge& aEIn,
694 const BOPAlgo_ListOfEdgeInfo& aLEInfo)
695{
696 Standard_Real anAngleIn;
697 Standard_Boolean anIsIn;
698 BOPAlgo_ListIteratorOfListOfEdgeInfo anIt;
699
700 anIt.Initialize(aLEInfo);
701 for (; anIt.More(); anIt.Next()) {
702 const BOPAlgo_EdgeInfo& anEdgeInfo=anIt.Value();
703 const TopoDS_Edge& aE=anEdgeInfo.Edge();
704 anIsIn=anEdgeInfo.IsIn();
705 //
706 if (anIsIn && aE==aEIn) {
707 anAngleIn=anEdgeInfo.Angle();
708 return anAngleIn;
709 }
710 }
711 anAngleIn=0.;
712 return anAngleIn;
713}
714//=======================================================================
715// function: GetNextVertex
716// purpose:
717//=======================================================================
718 void GetNextVertex(const TopoDS_Vertex& aV,
719 const TopoDS_Edge& aE,
720 TopoDS_Vertex& aV1)
721{
722 TopoDS_Iterator aIt;
723 //
724 aIt.Initialize(aE);
725 for (; aIt.More(); aIt.Next()) {
726 const TopoDS_Shape& aVx=aIt.Value();
727 if (!aVx.IsEqual(aV)) {
728 aV1=(*(TopoDS_Vertex *)(&aVx));
729 return ;
730 }
731 }
732 aV1=aV;
733}
734//=======================================================================
735// function: Angle2D
736// purpose:
737//=======================================================================
738 Standard_Real Angle2D (const TopoDS_Vertex& aV,
739 const TopoDS_Edge& anEdge,
740 const TopoDS_Face& myFace,
741 const GeomAdaptor_Surface& aGAS,
742 const Standard_Boolean bIsIN,
743 const Handle(IntTools_Context)& theContext)
744{
745 Standard_Real aFirst, aLast, aToler, dt, aTV, aTV1, anAngle, aTX;
746 gp_Pnt2d aPV, aPV1;
747 gp_Vec2d aV2D;
748 Handle(Geom2d_Curve) aC2D;
749 //
750 aTV=BRep_Tool::Parameter (aV, anEdge, myFace);
751 if (Precision::IsInfinite(aTV)) {
752 return 0.;
753 }
754 //
755 BOPTools_AlgoTools2D::CurveOnSurface (anEdge, myFace, aC2D,
756 aFirst, aLast, aToler, theContext);
757 Standard_Real tol2d =2.*Tolerance2D(aV, aGAS);
758 //
759 GeomAbs_CurveType aType;
760 Geom2dAdaptor_Curve aGAC2D(aC2D);
761 //
762 dt = Max(aGAC2D.Resolution(tol2d), Precision::PConfusion());
763 //
764 aType=aGAC2D.GetType();
765 if (aType != GeomAbs_Line )
766 {
767 Geom2dLProp_CLProps2d LProp(aC2D, aTV, 2, Precision::PConfusion());
768 if(LProp.IsTangentDefined())
769 {
770 Standard_Real R = LProp.Curvature();
771 if(R > Precision::PConfusion())
772 {
773 R = 1./R;
774 Standard_Real cosphi = R / (R + tol2d);
775 dt = Max(dt, ACos(cosphi)); //to avoid small dt for big R.
776 }
777 }
778 }
779 //for case chl/927/r9
780 aTX=0.05*(aLast - aFirst);//aTX=0.25*(aLast - aFirst);
781 if (aTX < 5.e-5) {
782 aTX = Min (5.e-5, (aLast - aFirst) / 2.);
783 }
784 if(dt > aTX) {
785 // to save direction of the curve as much as it possible
786 // in the case of big tolerances
787 dt = aTX;
788 }
789
790 if (fabs (aTV-aFirst) < fabs(aTV - aLast)) {
791 aTV1=aTV + dt;
792 }
793 else {
794 aTV1=aTV - dt;
795 }
796 //
797 aGAC2D.D0 (aTV1, aPV1);
798 aGAC2D.D0 (aTV, aPV);
799 //
800 aV2D = bIsIN ? gp_Vec2d(aPV1, aPV) : gp_Vec2d(aPV, aPV1);
801 //
802 gp_Dir2d aDir2D(aV2D);
803 anAngle=Angle(aDir2D);
804 //
805 return anAngle;
806}
807//=======================================================================
808// function: Angle
809// purpose:
810//=======================================================================
811Standard_Real Angle (const gp_Dir2d& aDir2D)
812{
813 gp_Dir2d aRefDir(1., 0.);
814 Standard_Real anAngle;
815
816 anAngle = aRefDir.Angle(aDir2D);
817 if (anAngle < 0.)
818 anAngle += M_PI + M_PI;
819 return anAngle;
820}
821//=======================================================================
822// function: Tolerance2D
823// purpose:
824//=======================================================================
825 Standard_Real Tolerance2D (const TopoDS_Vertex& aV,
826 const GeomAdaptor_Surface& aGAS)
827{
828 Standard_Real aTol2D, anUr, aVr, aTolV3D;
829 GeomAbs_SurfaceType aType;
830 //
831 aType=aGAS.GetType();
832 aTolV3D=BRep_Tool::Tolerance(aV);
833
834 anUr=aGAS.UResolution(aTolV3D);
835 aVr =aGAS.VResolution(aTolV3D);
836 aTol2D=(aVr>anUr) ? aVr : anUr;
837 //
838 if (aTol2D < aTolV3D) {
839 aTol2D=aTolV3D;
840 }
841 if (aType==GeomAbs_BSplineSurface) {
842 aTol2D=1.1*aTol2D;
843 }
844 //
845 return aTol2D;
846}
847
848//=======================================================================
849//function : UTolerance2D
850//purpose :
851//=======================================================================
852Standard_Real UTolerance2D (const TopoDS_Vertex& aV,
853 const GeomAdaptor_Surface& aGAS)
854{
855 const Standard_Real aTolV3D = BRep_Tool::Tolerance(aV);
856 const Standard_Real anUr = aGAS.UResolution(aTolV3D);
857 //
858 return anUr;
859}
860
861//=======================================================================
862//function : VTolerance2D
863//purpose :
864//=======================================================================
865Standard_Real VTolerance2D (const TopoDS_Vertex& aV,
866 const GeomAdaptor_Surface& aGAS)
867{
868 const Standard_Real aTolV3D = BRep_Tool::Tolerance(aV);
869 const Standard_Real anVr = aGAS.VResolution(aTolV3D);
870 //
871 return anVr;
872}
873
874//=======================================================================
875//function : RefineAngles
876//purpose :
877//=======================================================================
878void RefineAngles(const TopoDS_Face& myFace,
879 BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap,
880 const Handle(IntTools_Context)& theContext)
881{
882 const Standard_Integer aNb = mySmartMap.Extent();
883 for (Standard_Integer i = 1; i <= aNb; ++i)
884 {
885 const TopoDS_Vertex& aV = *((TopoDS_Vertex*)&mySmartMap.FindKey (i));
886 BOPAlgo_ListOfEdgeInfo& aLEI = mySmartMap (i);
887 RefineAngles(aV, myFace, aLEI, theContext);
888 }
889}
890//=======================================================================
891typedef NCollection_DataMap \
892 <TopoDS_Shape, Standard_Real, TopTools_ShapeMapHasher> \
893 TopTools_DataMapOfShapeReal;
894typedef TopTools_DataMapOfShapeReal::Iterator \
895 TopTools_DataMapIteratorOfDataMapOfShapeReal;
896//
897//=======================================================================
898//function : RefineAngles
899//purpose :
900//=======================================================================
901void RefineAngles(const TopoDS_Vertex& aV,
902 const TopoDS_Face& myFace,
903 BOPAlgo_ListOfEdgeInfo& aLEI,
904 const Handle(IntTools_Context)& theContext)
905{
906 Standard_Boolean bIsIn, bIsBoundary, bRefined;
907 Standard_Integer iCntBnd, iCntInt;
908 Standard_Real aA, aA1, aA2;
909 TopTools_DataMapOfShapeReal aDMSR;
910 BOPAlgo_ListIteratorOfListOfEdgeInfo aItLEI;
911 //
912 aA1=0.; // angle of outgoing edge
913 aA2=0.; // angle of incoming edge
914 iCntBnd=0;
915 iCntInt=0;
916 aItLEI.Initialize(aLEI);
917 for (; aItLEI.More(); aItLEI.Next()) {
918 BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue();
919 bIsIn=aEI.IsIn();
920 aA=aEI.Angle();
921 //
922 if (!aEI.IsInside()) {
923 ++iCntBnd;
924 if (!bIsIn) {
925 aA1=aA;
926 }
927 else {
928 aA2=aA;
929 }
930 }
931 else {
932 ++iCntInt;
933 }
934 }
935 //
936 if (iCntBnd!=2) {
937 return;
938 }
939 //
940 Standard_Real aDelta = ClockWiseAngle(aA2, aA1);
941 aItLEI.Initialize(aLEI);
942 for (; aItLEI.More(); aItLEI.Next()) {
943 BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue();
944 const TopoDS_Edge& aE=aEI.Edge();
945 //
946 bIsBoundary=!aEI.IsInside();
947 bIsIn=aEI.IsIn();
948 if (bIsBoundary || bIsIn) {
949 continue;
950 }
951 //
952 aA=aEI.Angle();
953 Standard_Real aDA = ClockWiseAngle(aA2, aA);
954 if (aDA < aDelta) {
955 continue; // already inside
956 }
957 //
958 bRefined=RefineAngle2D(aV, aE, myFace, aA1, aA2, aDelta, aA, theContext);
959 if (bRefined) {
960 aDMSR.Bind(aE, aA);
961 }
962 else if (iCntInt == 2) {
963 aA = (aA <= aA1) ? (aA1 + Precision::Angular()) :
964 (aA2 - Precision::Angular());
965 aDMSR.Bind(aE, aA);
966 }
967 }
968
969 if (aDMSR.IsEmpty()) {
970 return;
971 }
972 //
973 // update Angles
974 aItLEI.Initialize(aLEI);
975 for (; aItLEI.More(); aItLEI.Next()) {
976 BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue();
977 const TopoDS_Edge& aE=aEI.Edge();
978 //
979 bIsIn=aEI.IsIn();
980 if (!aDMSR.IsBound(aE)) {
981 continue;
982 }
983 //
984 aA=aDMSR.Find(aE);
985 if (bIsIn) {
986 aA=aA+M_PI;
987 }
988 //
989 aEI.SetAngle(aA);
990 }
991}
992//=======================================================================
993//function : RefineAngle2D
994//purpose :
995//=======================================================================
996Standard_Boolean RefineAngle2D(const TopoDS_Vertex& aV,
997 const TopoDS_Edge& aE,
998 const TopoDS_Face& myFace,
999 const Standard_Real aA1,
1000 const Standard_Real aA2,
1001 const Standard_Real aDelta,
1002 Standard_Real& aA,
1003 const Handle(IntTools_Context)& theContext)
1004{
1005 Standard_Boolean bRet;
1006 Standard_Integer i, j, aNbP;
1007 Standard_Real aTV, aTol, aT1, aT2, dT, aAngle, aT, aTOp;
1008 Standard_Real aTolInt, aAi, aXi, aYi, aT1j, aT2j, aT1max, aT2max, aCf;
1009 gp_Pnt2d aPV, aP, aP1, aP2;
1010 Handle(Geom2d_Curve) aC2D;
1011 Handle(Geom2d_Line) aLi;
1012 Geom2dAdaptor_Curve aGAC1, aGAC2;
1013 Geom2dInt_GInter aGInter;
1014 IntRes2d_Domain aDomain1, aDomain2;
1015 //
1016 bRet=Standard_True;
1017 aCf=0.01;
1018 aTolInt=1.e-10;
1019 //
1020 BOPTools_AlgoTools2D::CurveOnSurface(aE, myFace, aC2D, aT1, aT2, aTol, theContext);
1021 aGAC1.Load(aC2D, aT1, aT2);
1022 //
1023 aTV=BRep_Tool::Parameter (aV, aE, myFace);
1024 aGAC1.D0(aTV, aPV);
1025 //
1026 aTOp = (fabs(aTV-aT1) < fabs(aTV-aT2)) ? aT2 : aT1;
1027 //
1028 const Standard_Real MaxDT = 0.3 * (aT2 - aT1);
1029 aGAC1.D0(aT1, aP1);
1030 aGAC1.D0(aT2, aP2);
1031 aDomain1.SetValues(aP1, aT1, aTolInt, aP2, aT2, aTolInt);
1032 //
1033 for (i=0; i<2; ++i) {
1034 aAi=(!i) ? aA1 : (aA2 + M_PI);
1035 aXi=cos(aAi);
1036 aYi=sin(aAi);
1037 gp_Dir2d aDiri(aXi, aYi);
1038 aLi=new Geom2d_Line(aPV, aDiri);
1039 //
1040 aGAC2.Load(aLi);
1041 //
1042 aGInter.Perform(aGAC1, aDomain1, aGAC2, aDomain2, aTolInt, aTolInt);
1043 if (!aGInter.IsDone()) {
1044 continue;
1045 }
1046 //
1047 aNbP = aGInter.NbPoints();
1048 aT1max = aTV;
1049 aT2max = -1.;
1050 for (j = 1; j <= aNbP; ++j) {
1051 const IntRes2d_IntersectionPoint& aIPj = aGInter.Point(j);
1052 aT1j = aIPj.ParamOnFirst();
1053 aT2j = aIPj.ParamOnSecond();
1054 //
1055 if (aT2j > aT2max && Abs(aT1j - aTV) < MaxDT) {
1056 aT2max = aT2j;
1057 aT1max = aT1j;
1058 }
1059 }
1060 //
1061 if (aT2max > 0) {
1062 dT = aTOp - aT1max;
1063 if (Abs(dT) < aTolInt) {
1064 continue;
1065 }
1066 //
1067 aT = aT1max + aCf*dT;
1068 aGAC1.D0(aT, aP);
1069 gp_Vec2d aV2D(aPV, aP);
1070 gp_Dir2d aDir2D(aV2D);
1071 //
1072 aAngle = Angle(aDir2D);
1073 Standard_Real aDA = ClockWiseAngle(aA2, aAngle);
1074 if (aDA < aDelta) {
1075 aA = aAngle;
1076 return bRet;
1077 }
1078 }
1079 }// for (i=0; i<2; ++i) {
1080 return !bRet;
1081}