0024360: Hang up trying to intersect two faces
[occt.git] / src / BOPAlgo / BOPAlgo_WireSplitter_1.cxx
CommitLineData
4e57c75e 1// Created by: Peter KURNEV
2// Copyright (c) 1999-2012 OPEN CASCADE SAS
3//
4// The content of this file is subject to the Open CASCADE Technology Public
5// License Version 6.5 (the "License"). You may not use the content of this file
6// except in compliance with the License. Please obtain a copy of the License
7// at http://www.opencascade.org and read it completely before using this file.
8//
9// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11//
12// The Original Code and all software distributed under the License is
13// distributed on an "AS IS" basis, without warranty of any kind, and the
14// Initial Developer hereby disclaims all such warranties, including without
15// limitation, any warranties of merchantability, fitness for a particular
16// purpose or non-infringement. Please see the License for the specific terms
17// and conditions governing the rights and limitations under the License.
18
19#include <BOPAlgo_WireSplitter.ixx>
20
21#include <Precision.hxx>
22
23#include <gp_Pnt2d.hxx>
24#include <gp_Vec2d.hxx>
25#include <gp_Dir2d.hxx>
26#include <Geom2d_Curve.hxx>
27#include <GeomAdaptor_Surface.hxx>
28
29#include <TopoDS_Edge.hxx>
30#include <TopoDS_Vertex.hxx>
31#include <TopoDS_Wire.hxx>
32#include <TopoDS_Iterator.hxx>
33#include <BRep_Tool.hxx>
34#include <BRepAdaptor_Surface.hxx>
35
36#include <BOPCol_ListOfShape.hxx>
37#include <BOPCol_SequenceOfShape.hxx>
38#include <BOPCol_SequenceOfPnt2d.hxx>
39#include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
40//
41#include <Geom_Surface.hxx>
42#include <Geom_Plane.hxx>
43#include <Geom_RectangularTrimmedSurface.hxx>
44#include <Geom_RectangularTrimmedSurface.hxx>
45#include <BOPTools_AlgoTools2D.hxx>
46#include <TopLoc_Location.hxx>
47#include <BRep_Builder.hxx>
48#include <BOPCol_SequenceOfReal.hxx>
49#include <TopExp.hxx>
50#include <TopExp_Explorer.hxx>
acccace3 51#include <BOPTools_AlgoTools2D.hxx>
4e57c75e 52//
53
54static
55 Standard_Real Angle (const gp_Dir2d& aDir2D);
56
57static
58 Standard_Real Angle2D (const TopoDS_Vertex& aV,
59 const TopoDS_Edge& anEdge,
60 const TopoDS_Face& myFace,
61 const GeomAdaptor_Surface& aGAS,
62 const Standard_Boolean aFlag);
63
64static
65 void GetNextVertex(const TopoDS_Vertex& aV,
66 const TopoDS_Edge& aE,
67 TopoDS_Vertex& aV1);
68
69static
70 Standard_Real AngleIn(const TopoDS_Edge& aEIn,
71 const BOPAlgo_ListOfEdgeInfo& aLEInfo);
72
73static
74 Standard_Integer NbWaysOut(const BOPAlgo_ListOfEdgeInfo& aLEInfo);
75
76static
77 gp_Pnt2d Coord2dVf (const TopoDS_Edge& aE,
78 const TopoDS_Face& aF);
79
80static
81 gp_Pnt2d Coord2d (const TopoDS_Vertex& aV1,
82 const TopoDS_Edge& aE1,
83 const TopoDS_Face& aF);
84
85
86static
87 Standard_Real ClockWiseAngle(const Standard_Real aAngleIn,
88 const Standard_Real aAngleOut);
89
90static
91 void Path (const GeomAdaptor_Surface& aGAS,
92 const TopoDS_Face& myFace,
93 const TopoDS_Vertex& aVa,
94 const TopoDS_Edge& aEOuta,
95 BOPAlgo_EdgeInfo& anEdgeInfo,
96 BOPCol_SequenceOfShape& aLS,
97 BOPCol_SequenceOfShape& aVertVa,
98 BOPCol_SequenceOfPnt2d& aCoordVa,
99 BOPTools_ConnexityBlock& aCB,
100 BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap);
101
102static
103 Standard_Real Angle2D (const TopoDS_Vertex& aV,
104 const TopoDS_Edge& anEdge,
105 const TopoDS_Face& myFace,
106 const GeomAdaptor_Surface& aGAS,
107 const Standard_Boolean aFlag);
108static
109 Standard_Real Angle (const gp_Dir2d& aDir2D);
110
111static
112 Standard_Real Tolerance2D (const TopoDS_Vertex& aV,
113 const GeomAdaptor_Surface& aGAS);
114
acccace3 115
4e57c75e 116
117static
118 Standard_Real UTolerance2D (const TopoDS_Vertex& aV,
119 const GeomAdaptor_Surface& aGAS);
120static
121 Standard_Real VTolerance2D (const TopoDS_Vertex& aV,
122 const GeomAdaptor_Surface& aGAS);
123
124static
125 Standard_Boolean RecomputeAngles(const BOPAlgo_ListOfEdgeInfo& aLEInfo,
126 const TopoDS_Face& theFace,
127 const gp_Pnt2d& thePb,
128 const TopoDS_Vertex& theVb,
129 const GeomAdaptor_Surface& theGAS,
130 const TopoDS_Edge& theEOuta,
131 const Standard_Boolean& bHasClosed,
132 const Standard_Real& theTol2D,
133 BOPCol_SequenceOfReal& theRecomputedAngles);
134
135//=======================================================================
136//function : SplitBlock
137//purpose :
138//=======================================================================
139 void BOPAlgo_WireSplitter::SplitBlock(BOPTools_ConnexityBlock& aCB)
140{
141 Standard_Boolean bNothingToDo;
142 Standard_Integer aIx, aNb, i, aCntIn, aCntOut;
143 Standard_Real aAngle;
144 TopAbs_Orientation aOr;
145 TopoDS_Iterator aItS;
146 TopoDS_Vertex aVV;
147 BOPCol_ListIteratorOfListOfShape aIt;
148 BOPAlgo_ListIteratorOfListOfEdgeInfo aItLEI;
149 //
150 BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo mySmartMap(100, myAllocator);
151 //
152 const TopoDS_Face& myFace=myWES->Face();
153 const BOPCol_ListOfShape& myEdges=aCB.Shapes();
154 //
155 // 1.Filling mySmartMap
acccace3 156 BOPTools_AlgoTools2D::BuildPCurveForEdgesOnPlane(myEdges, myFace);
157 //
4e57c75e 158 aIt.Initialize(myEdges);
159 for(; aIt.More(); aIt.Next()) {
160 const TopoDS_Edge& aE=(*(TopoDS_Edge *)&aIt.Value());
161 if (!BOPTools_AlgoTools2D::HasCurveOnSurface (aE, myFace)) {
162 continue;
163 }
164 //
165 aItS.Initialize(aE);
166 for(; aItS.More(); aItS.Next()) {
167 const TopoDS_Shape& aV=aItS.Value();
168 aIx=mySmartMap.FindIndex(aV);
169 if (!aIx) {
170 BOPAlgo_ListOfEdgeInfo aLEIx(myAllocator);
171 aIx=mySmartMap.Add(aV, aLEIx);
172 }
173 //
174 BOPAlgo_ListOfEdgeInfo& aLEI=mySmartMap(aIx);
175 //
176 BOPAlgo_EdgeInfo aEI;
177 //
178 aEI.SetEdge(aE);
179 aOr=aV.Orientation();
180 if (aOr==TopAbs_FORWARD) {
181 aEI.SetInFlag(Standard_False);
182 }
183 else if (aOr==TopAbs_REVERSED) {
184 aEI.SetInFlag(Standard_True);
185 }
186 aLEI.Append(aEI);
187 }
188 }
189 //
190 aNb=mySmartMap.Extent();
191 //
192 bNothingToDo=Standard_True;
193 for (i=1; i<=aNb; i++) {
194 aCntIn=0;
195 aCntOut=0;
196 const BOPAlgo_ListOfEdgeInfo& aLEInfo= mySmartMap(i);
197 BOPAlgo_ListIteratorOfListOfEdgeInfo anIt(aLEInfo);
198 for (; anIt.More(); anIt.Next()) {
199 const BOPAlgo_EdgeInfo& aEI=anIt.Value();
200 if (aEI.IsIn()) {
201 aCntIn++;
202 }
203 else {
204 aCntOut++;
205 }
206 }
207 if (aCntIn!=1 || aCntOut!=1) {
208 bNothingToDo=Standard_False;
209 break;
210 }
211 }
212 //
213 // Each vertex has one edge In and one - Out. Good. But it is not enought
214 // to consider that nothing to do with this. We must check edges on TShape
215 // coinsidence. If there are such edges there is something to do with.
216 if (bNothingToDo) {
217 Standard_Integer aNbE, aNbMapEE;
218 Standard_Boolean bFlag;
219 //
220 BOPCol_IndexedDataMapOfShapeListOfShape aMapEE(100, myAllocator);
221 aNbE=myEdges.Extent();
222 //
223 aIt.Initialize(myEdges);
224 for (; aIt.More(); aIt.Next()) {
225 const TopoDS_Shape& aE = aIt.Value();
226 if (!aMapEE.Contains(aE)) {
227 BOPCol_ListOfShape aLEx(myAllocator);
228 aLEx.Append(aE);
229 aMapEE.Add(aE, aLEx);
230 }
231 else {
232 BOPCol_ListOfShape& aLEx=aMapEE.ChangeFromKey(aE);
233 aLEx.Append(aE);
234 }
235 }
236 //
237 bFlag=Standard_True;
238 aNbMapEE=aMapEE.Extent();
239 for (i=1; i<=aNbMapEE; ++i) {
240 const BOPCol_ListOfShape& aLEx=aMapEE(i);
241 aNbE=aLEx.Extent();
242 if (aNbE==1) {// usual case
243 continue;
244 }
245 else if (aNbE==2){
246 const TopoDS_Shape& aE1=aLEx.First();
247 const TopoDS_Shape& aE2=aLEx.Last();
248 if (aE1.IsSame(aE2)) {
249 bFlag=Standard_False;
250 break;
251 }
252 }
253 else {
254 bFlag=Standard_False;
255 break;
256 }
257 }
258 bNothingToDo=bNothingToDo && bFlag;
259 } // if (bNothingToDo) {
260 if (bNothingToDo) {
261 TopoDS_Wire aW;
262 //
263 BOPCol_ListOfShape& aLECB=aCB.ChangeShapes();
264 BOPAlgo_WireSplitter::MakeWire(aLECB, aW);
265 BOPCol_ListOfShape& aLoops=aCB.ChangeLoops();
266 aLoops.Append(aW);
267 //
268 myErrorStatus=0;
269 return;
270 }
271 //
272 // 3. Angles in mySmartMap
273 BRepAdaptor_Surface aBAS(myFace);
274 const GeomAdaptor_Surface& aGAS=aBAS.Surface();
275 //
276 for (i=1; i<=aNb; i++) {
277 const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&mySmartMap.FindKey(i)));
278 const BOPAlgo_ListOfEdgeInfo& aLEI= mySmartMap(i);
279
280 aItLEI.Initialize(aLEI);
281 for (; aItLEI.More(); aItLEI.Next()) {
282 BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue();
283 const TopoDS_Edge& aE=aEI.Edge();
284 //
285 aVV=aV;
286 if (aEI.IsIn()) {
287 aVV.Orientation(TopAbs_REVERSED);
288 aAngle=Angle2D (aVV, aE, myFace, aGAS, Standard_True);
289 }
290 else { // OUT
291 aVV.Orientation(TopAbs_FORWARD);
292 aAngle=Angle2D (aVV, aE, myFace, aGAS, Standard_False);
293 }
294 aEI.SetAngle(aAngle);
295 }
296 }// for (i=1; i<=aNb; i++) {
297 //
298 // 4. Do
299 //
300 Standard_Boolean bIsOut, bIsNotPassed;
301 BOPCol_SequenceOfShape aLS, aVertVa;
302 BOPCol_SequenceOfPnt2d aCoordVa;
303 //
304 for (i=1; i<=aNb; ++i) {
305 const TopoDS_Vertex& aVa=(*(TopoDS_Vertex *)(&mySmartMap.FindKey(i)));
306 const BOPAlgo_ListOfEdgeInfo& aLEI=mySmartMap(i);
307 aItLEI.Initialize(aLEI);
308 for (; aItLEI.More(); aItLEI.Next()) {
309 BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue();
310 const TopoDS_Edge& aEOuta=aEI.Edge();
311 //
312 bIsOut=!aEI.IsIn();
313 bIsNotPassed=!aEI.Passed();
314 if (bIsOut && bIsNotPassed) {
315 //
316 aLS.Clear();
317 aVertVa.Clear();
318 aCoordVa.Clear();
319 //
320 Path(aGAS, myFace, aVa, aEOuta, aEI, aLS,
321 aVertVa, aCoordVa, aCB, mySmartMap);
322 }
323 }
324 }// for (i=1; i<=aNb; ++i) {
325}
326//=======================================================================
327// function: Path
328// purpose:
329//=======================================================================
330void Path (const GeomAdaptor_Surface& aGAS,
331 const TopoDS_Face& myFace,
332 const TopoDS_Vertex& aVa,
333 const TopoDS_Edge& aEOuta,
334 BOPAlgo_EdgeInfo& anEdgeInfo,
335 BOPCol_SequenceOfShape& aLS,
336 BOPCol_SequenceOfShape& aVertVa,
337 BOPCol_SequenceOfPnt2d& aCoordVa,
338 BOPTools_ConnexityBlock& aCB,
339 BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap)
340
341{
342 Standard_Integer i, j, aNb, aNbj;
343 Standard_Real aTol, anAngleIn, anAngleOut, anAngle, aMinAngle;
344 Standard_Real aTol2D, aTol2D2;
b20eeb13 345 Standard_Real aTol2, aD2, aTwoPI;
4e57c75e 346 Standard_Boolean anIsSameV2d, anIsSameV, anIsFound, anIsOut, anIsNotPassed;
347 TopoDS_Vertex aVb;
348 TopoDS_Edge aEOutb;
349 BOPAlgo_ListIteratorOfListOfEdgeInfo anIt;
350 //
b20eeb13 351 aTwoPI = M_PI + M_PI;
4e57c75e 352 aTol=1.e-7;
353 //
354 // append block
355 //
356 // Do not escape through edge from which you enter
357 aNb=aLS.Length();
358 if (aNb==1) {
359 const TopoDS_Shape& anEPrev=aLS(aNb);
360 if (anEPrev.IsSame(aEOuta)) {
361 return;
362 }
363 }
364 //
365 anEdgeInfo.SetPassed(Standard_True);
366 aLS.Append(aEOuta);
367 aVertVa.Append(aVa);
368
369 TopoDS_Vertex pVa=aVa;
370 pVa.Orientation(TopAbs_FORWARD);
371 gp_Pnt2d aPa=Coord2d(pVa, aEOuta, myFace);
372 aCoordVa.Append(aPa);
373
374 GetNextVertex (pVa, aEOuta, aVb);
375
376 gp_Pnt2d aPb=Coord2d(aVb, aEOuta, myFace);
377
378 const BOPAlgo_ListOfEdgeInfo& aLEInfoVb=mySmartMap.FindFromKey(aVb);
379 //
380 aTol=2.*Tolerance2D(aVb, aGAS);
381 aTol2=10.*aTol*aTol;
382
383 TopoDS_Vertex aV1, aV2;
384 TopExp::Vertices(aEOuta, aV1, aV2);
385 Standard_Boolean bIsClosedEdge = aV1.IsNull() || aV2.IsNull() || aV1.IsSame(aV2);
386 Standard_Boolean bIsDegenerated = BRep_Tool::Degenerated(aEOuta);
387 Standard_Boolean bIsSeam = BRep_Tool::IsClosed(aEOuta, myFace);
388
389 anIt.Initialize(aLEInfoVb);
390 for (; anIt.More(); anIt.Next()) {
391 const BOPAlgo_EdgeInfo& anEI = anIt.Value();
392 const TopoDS_Edge& aE = anEI.Edge();
393 bIsDegenerated = bIsDegenerated || BRep_Tool::Degenerated(aE);
394 bIsSeam = bIsSeam || BRep_Tool::IsClosed(aE, myFace);
395 aV1.Nullify();
396 aV2.Nullify();
397 TopExp::Vertices(aE, aV1, aV2);
398 bIsClosedEdge = bIsClosedEdge || aV1.IsNull() || aV2.IsNull() || aV1.IsSame(aV2);
399 }
400 //
401 aNb=aLS.Length();
402 if (aNb>0) {
403 //
404 BOPCol_ListOfShape aBuf;
405 //
406 for (i=aNb; i>0; --i) {
407 const TopoDS_Shape& aVPrev=aVertVa(i);
408 const gp_Pnt2d& aPaPrev=aCoordVa(i);
409 const TopoDS_Shape& aEPrev=aLS(i);
410
411 aBuf.Append(aEPrev);
412
413 anIsSameV=aVPrev.IsSame(aVb);
414 anIsSameV2d=Standard_False;
415
416 if (anIsSameV) {
417 anIsSameV2d = Standard_True;
418 //
419 aD2=aPaPrev.SquareDistance(aPb);
420 anIsSameV2d =aD2<aTol2;
421 if(anIsSameV2d &&
422 (bIsDegenerated || bIsSeam || bIsClosedEdge)) {
423 Standard_Real udist = fabs(aPaPrev.X() - aPb.X());
424 Standard_Real vdist = fabs(aPaPrev.Y() - aPb.Y());
425 Standard_Real aTolU = 2. * UTolerance2D(aVb, aGAS);
426 Standard_Real aTolV = 2. * VTolerance2D(aVb, aGAS);
427 //
428 if((udist > aTolU) ||
429 (vdist > aTolV)) {
430 anIsSameV2d = Standard_False;
431 }
432 }
433 }//if (anIsSameV) {
434 //
435 if (anIsSameV && anIsSameV2d) {
436 Standard_Integer iPriz;
437 iPriz=1;
438 if (aBuf.Extent()==2) {
439 if(aBuf.First().IsSame(aBuf.Last())) {
440 iPriz=0;
441 }
442 }
443 if (iPriz) {
444 TopoDS_Wire aW;
445 BOPAlgo_WireSplitter::MakeWire(aBuf, aW);
446 aCB.ChangeLoops().Append(aW);
447 }
448 //
449 aNbj=i-1;
450 if (aNbj<1) {
451 //
452 aLS.Clear();
453 aVertVa.Clear();
454 aCoordVa.Clear();
455 //
456 return;
457 }
458 //
459 BOPCol_SequenceOfShape aLSt, aVertVat;
460 BOPCol_SequenceOfPnt2d aCoordVat;
461 //
462 aVb=(*(TopoDS_Vertex *)(&aVertVa(i)));
463 //
464 for (j=1; j<=aNbj; ++j) {
465 aLSt.Append(aLS(j));
466 aVertVat.Append(aVertVa(j));
467 aCoordVat.Append(aCoordVa(j));
468 }
469 //
470 aLS.Clear();
471 aVertVa.Clear();
472 aCoordVa.Clear();
473
474 aLS=aLSt;
475 aVertVa=aVertVat;
476 aCoordVa=aCoordVat;
477 //
478 break;
479 }
480 }
481 }
482 //
483 aTol2D=2.*Tolerance2D(aVb, aGAS);
484 aTol2D2=1000.*aTol2D*aTol2D;//100.*aTol2D*aTol2D;
485 //
486 // anAngleIn in Vb from edge aEOuta
487 const BOPAlgo_ListOfEdgeInfo& aLEInfo=mySmartMap.FindFromKey(aVb);
488 //
489 anAngleIn=AngleIn(aEOuta, aLEInfo);
490 BOPCol_SequenceOfReal aRecomputedAngles;
491
492 Standard_Boolean bRecomputeAngle =
493 RecomputeAngles(aLEInfo, myFace, aPb, aVb, aGAS, aEOuta,
494 (bIsDegenerated || bIsSeam || bIsClosedEdge),
495 aTol2D, aRecomputedAngles);
496
497 //
498 // aEOutb
499 BOPAlgo_EdgeInfo *pEdgeInfo=NULL;
500 //
501 aMinAngle=100.;
502 anIsFound=Standard_False;
503 Standard_Integer aCurIndexE = 0;
504 anIt.Initialize(aLEInfo);
505 for (; anIt.More(); anIt.Next()) {
506 BOPAlgo_EdgeInfo& anEI=anIt.ChangeValue();
507 const TopoDS_Edge& aE=anEI.Edge();
508 anIsOut=!anEI.IsIn();
509 anIsNotPassed=!anEI.Passed();
510
511 if (anIsOut && anIsNotPassed) {
512 aCurIndexE++;
513 //
514 // Is there one way to go out of the vertex
515 // we have to use it only.
516 Standard_Integer iCnt;
517 iCnt=NbWaysOut (aLEInfo);
518 //
519 if (!iCnt) {
520 // no way to go . (Error)
521 return ;
522 }
523 //
524 if (iCnt==1) {
525 // the one and only way to go out .
526 pEdgeInfo=&anEI;
527 anIsFound=Standard_True;
528 break;
529 }
530 //
b20eeb13 531 if (aE.IsSame(aEOuta)) {
532 anAngle = aTwoPI;
533 } else {
534 // Look for minimal angle and make the choice.
535 gp_Pnt2d aP2Dx;
536 //
537 aP2Dx=Coord2dVf(aE, myFace);
538 //
539 aD2=aP2Dx.SquareDistance(aPb);
540 if (aD2 > aTol2D2){
541 continue;
4e57c75e 542 }
b20eeb13 543 //
544 //
545 anAngleOut=anEI.Angle();
546 //
547 if(bRecomputeAngle) {
548 if(aCurIndexE <= aRecomputedAngles.Length()) {
549 anAngleOut = aRecomputedAngles.Value(aCurIndexE);
550 }
551 }
552 anAngle=ClockWiseAngle(anAngleIn, anAngleOut);
4e57c75e 553 }
4e57c75e 554 if (anAngle < aMinAngle) {
555 aMinAngle=anAngle;
556 pEdgeInfo=&anEI;
557 anIsFound=Standard_True;
558 }
559 }
560 } // for (; anIt.More(); anIt.Next())
561 //
562 if (!anIsFound) {
563 // no way to go . (Error)
564 return;
565 }
566
567 aEOutb=pEdgeInfo->Edge();
568 //
569 Path (aGAS, myFace, aVb, aEOutb, *pEdgeInfo, aLS,
570 aVertVa, aCoordVa, aCB, mySmartMap);
571}
572//=======================================================================
573// function: ClockWiseAngle
574// purpose:
575//=======================================================================
576 Standard_Real ClockWiseAngle(const Standard_Real aAngleIn,
577 const Standard_Real aAngleOut)
578{
579 Standard_Real aTwoPi=M_PI+M_PI;
580 Standard_Real dA, A1, A2, AIn, AOut ;
581
582 AIn=aAngleIn;
583 AOut=aAngleOut;
584 if (AIn >= aTwoPi) {
585 AIn=AIn-aTwoPi;
586 }
587
588 if (AOut >= aTwoPi) {
589 AOut=AOut-aTwoPi;
590 }
591
592 A1=AIn+M_PI;
593
594 if (A1 >= aTwoPi) {
595 A1=A1-aTwoPi;
596 }
597
598 A2=AOut;
599
600 dA=A1-A2;
601 if (dA <= 0.) {
602 dA=aTwoPi+dA;
603 }
604 //xx
605 //else if (dA <= 1.e-15) {
606 else if (dA <= 1.e-14) {
607 dA=aTwoPi;
608 }
609 return dA;
610}
611//=======================================================================
612// function: Coord2d
613// purpose:
614//=======================================================================
615 gp_Pnt2d Coord2d (const TopoDS_Vertex& aV1,
616 const TopoDS_Edge& aE1,
617 const TopoDS_Face& aF)
618{
619 Standard_Real aT, aFirst, aLast;
620 Handle(Geom2d_Curve) aC2D;
621 gp_Pnt2d aP2D1;
622 //
623 aT=BRep_Tool::Parameter (aV1, aE1, aF);
624 aC2D=BRep_Tool::CurveOnSurface(aE1, aF, aFirst, aLast);
625 aC2D->D0 (aT, aP2D1);
626 //
627 return aP2D1;
628}
629//=======================================================================
630// function: Coord2dVf
631// purpose:
632//=======================================================================
633 gp_Pnt2d Coord2dVf (const TopoDS_Edge& aE,
634 const TopoDS_Face& aF)
635{
636 Standard_Real aCoord=99.;
637 gp_Pnt2d aP2D1(aCoord, aCoord);
638 TopoDS_Iterator aIt;
639 //
640 aIt.Initialize(aE);
641 for (; aIt.More(); aIt.Next()) {
642 const TopoDS_Shape& aVx=aIt.Value();
643 if (aVx.Orientation()==TopAbs_FORWARD) {
644
645 const TopoDS_Vertex& aVxx=(*(TopoDS_Vertex *)(&aVx));// TopoDS::Vertex(aVx);
646 aP2D1=Coord2d(aVxx, aE, aF);
647 return aP2D1;
648 }
649 }
650 return aP2D1;
651}
652
653//=======================================================================
654// function: NbWaysOut
655// purpose:
656//=======================================================================
657Standard_Integer NbWaysOut(const BOPAlgo_ListOfEdgeInfo& aLEInfo)
658{
659 Standard_Boolean bIsOut, bIsNotPassed;
660 Standard_Integer iCnt=0;
661 BOPAlgo_ListIteratorOfListOfEdgeInfo anIt;
662 //
663 anIt.Initialize(aLEInfo);
664 for (; anIt.More(); anIt.Next()) {
665 const BOPAlgo_EdgeInfo& anEI=anIt.Value();
666 //
667 bIsOut=!anEI.IsIn();
668 bIsNotPassed=!anEI.Passed();
669 if (bIsOut && bIsNotPassed) {
670 iCnt++;
671 }
672 }
673 return iCnt;
674}
675
676//=======================================================================
677// function: AngleIn
678// purpose:
679//=======================================================================
680 Standard_Real AngleIn(const TopoDS_Edge& aEIn,
681 const BOPAlgo_ListOfEdgeInfo& aLEInfo)
682{
683 Standard_Real anAngleIn;
684 Standard_Boolean anIsIn;
685 BOPAlgo_ListIteratorOfListOfEdgeInfo anIt;
686
687 anIt.Initialize(aLEInfo);
688 for (; anIt.More(); anIt.Next()) {
689 const BOPAlgo_EdgeInfo& anEdgeInfo=anIt.Value();
690 const TopoDS_Edge& aE=anEdgeInfo.Edge();
691 anIsIn=anEdgeInfo.IsIn();
692 //
693 if (anIsIn && aE==aEIn) {
694 anAngleIn=anEdgeInfo.Angle();
695 return anAngleIn;
696 }
697 }
698 anAngleIn=0.;
699 return anAngleIn;
700}
701//=======================================================================
702// function: GetNextVertex
703// purpose:
704//=======================================================================
705 void GetNextVertex(const TopoDS_Vertex& aV,
706 const TopoDS_Edge& aE,
707 TopoDS_Vertex& aV1)
708{
709 TopoDS_Iterator aIt;
710 //
711 aIt.Initialize(aE);
712 for (; aIt.More(); aIt.Next()) {
713 const TopoDS_Shape& aVx=aIt.Value();
714 if (!aVx.IsEqual(aV)) {
715 aV1=(*(TopoDS_Vertex *)(&aVx));
716 return ;
717 }
718 }
719 aV1=aV;
720}
721//=======================================================================
722// function: Angle2D
723// purpose:
724//=======================================================================
725 Standard_Real Angle2D (const TopoDS_Vertex& aV,
726 const TopoDS_Edge& anEdge,
727 const TopoDS_Face& myFace,
728 const GeomAdaptor_Surface& aGAS,
729 const Standard_Boolean aFlag)
730{
731 Standard_Real aFirst, aLast, aToler, dt, aTV, aTV1, anAngle, aTX;
732 gp_Pnt2d aPV, aPV1;
733 gp_Vec2d aV2D;
734 Handle(Geom2d_Curve) aC2D;
735 //
736 aTV=BRep_Tool::Parameter (aV, anEdge, myFace);
737 if (Precision::IsInfinite(aTV)) {
738 return 0.;
739 }
740 //
741 BOPTools_AlgoTools2D::CurveOnSurface (anEdge, myFace, aC2D,
742 aFirst, aLast, aToler);
743 dt=2.*Tolerance2D(aV, aGAS);
744 //
745 //for case chl/927/r9
746 aTX=0.05*(aLast - aFirst);//aTX=0.25*(aLast - aFirst);
747 if (aTX < 5.e-5) {
748 aTX = 5.e-5;
749 }
750 if(dt > aTX) {
751 // to save direction of the curve as much as it possible
752 // in the case of big tolerances
753 dt = aTX;
754 }
755 //
756 if (fabs (aTV-aFirst) < fabs(aTV - aLast)) {
757 aTV1=aTV + dt;
758 }
759 else {
760 aTV1=aTV - dt;
761 }
762 //
763 aC2D->D0 (aTV1, aPV1);
764 aC2D->D0 (aTV, aPV);
765 //
766 if (aFlag) {//IN
767 gp_Vec2d aV2DIn(aPV1, aPV);
768 aV2D=aV2DIn;
769 }
770 else {
771 gp_Vec2d aV2DOut(aPV, aPV1);
772 aV2D=aV2DOut;
773 }
774 //
775 gp_Dir2d aDir2D(aV2D);
776 anAngle=Angle(aDir2D);
777 //
778 return anAngle;
779}
780//=======================================================================
781// function: Angle
782// purpose:
783//=======================================================================
784Standard_Real Angle (const gp_Dir2d& aDir2D)
785{
786 gp_Dir2d aRefDir(1., 0.);
787 Standard_Real anAngle;
788
789 anAngle = aRefDir.Angle(aDir2D);
790 if (anAngle < 0.)
791 anAngle += M_PI + M_PI;
792 return anAngle;
793}
794//=======================================================================
795// function: Tolerance2D
796// purpose:
797//=======================================================================
798 Standard_Real Tolerance2D (const TopoDS_Vertex& aV,
799 const GeomAdaptor_Surface& aGAS)
800{
801 Standard_Real aTol2D, anUr, aVr, aTolV3D;
802 GeomAbs_SurfaceType aType;
803 //
804 aType=aGAS.GetType();
805 aTolV3D=BRep_Tool::Tolerance(aV);
806
807 anUr=aGAS.UResolution(aTolV3D);
808 aVr =aGAS.VResolution(aTolV3D);
809 aTol2D=(aVr>anUr) ? aVr : anUr;
810 //
811 if (aTol2D < aTolV3D) {
812 aTol2D=aTolV3D;
813 }
814 if (aType==GeomAbs_BSplineSurface) {
815 aTol2D=1.1*aTol2D;
816 }
817 //
818 return aTol2D;
819}
acccace3 820
4e57c75e 821//=======================================================================
822//function : UTolerance2D
823//purpose :
824//=======================================================================
825Standard_Real UTolerance2D (const TopoDS_Vertex& aV,
826 const GeomAdaptor_Surface& aGAS)
827{
828 const Standard_Real aTolV3D = BRep_Tool::Tolerance(aV);
829 const Standard_Real anUr = aGAS.UResolution(aTolV3D);
830 //
831 return anUr;
832}
833
834//=======================================================================
835//function : VTolerance2D
836//purpose :
837//=======================================================================
838Standard_Real VTolerance2D (const TopoDS_Vertex& aV,
839 const GeomAdaptor_Surface& aGAS)
840{
841 const Standard_Real aTolV3D = BRep_Tool::Tolerance(aV);
842 const Standard_Real anVr = aGAS.VResolution(aTolV3D);
843 //
844 return anVr;
845}
846
847//=======================================================================
848// function: RecomputeAngles
849// purpose:
850//=======================================================================
851Standard_Boolean RecomputeAngles(const BOPAlgo_ListOfEdgeInfo& aLEInfo,
852 const TopoDS_Face& theFace,
853 const gp_Pnt2d& thePb,
854 const TopoDS_Vertex& theVb,
855 const GeomAdaptor_Surface& theGAS,
856 const TopoDS_Edge& theEOuta,
857 const Standard_Boolean& bIsClosed,
858 const Standard_Real& theTol2D,
859 BOPCol_SequenceOfReal& theRecomputedAngles)
860{
861 Standard_Boolean bRecomputeAngle = Standard_False;
862 BOPAlgo_ListIteratorOfListOfEdgeInfo anIt;
863 anIt.Initialize(aLEInfo);
864
865 for (; anIt.More(); anIt.Next()) {
866 const BOPAlgo_EdgeInfo& anEI=anIt.Value();
867 const TopoDS_Edge& aE=anEI.Edge();
868 Standard_Boolean anIsOut=!anEI.IsIn();
869 Standard_Boolean anIsNotPassed=!anEI.Passed();
870
871 if (anIsOut && anIsNotPassed) {
872 theRecomputedAngles.Append(anEI.Angle());
873 Standard_Integer acurindex = theRecomputedAngles.Length();
874
875 Standard_Boolean bRecomputeAngleLocal = Standard_False;
876 TopExp_Explorer anExp1(aE, TopAbs_VERTEX);
877
878 for(; anExp1.More(); anExp1.Next()) {
879 TopExp_Explorer anExp2(theEOuta, TopAbs_VERTEX);
880 Standard_Boolean existsInEdge = Standard_False;
881
882 for(; anExp2.More(); anExp2.Next()) {
883 if(anExp1.Current().IsSame(anExp2.Current())) {
884 existsInEdge = Standard_True;
885 break;
886 }
887 }
888
889 if(!existsInEdge) {
890 bRecomputeAngleLocal = Standard_False;
891 break;
892 }
893 bRecomputeAngleLocal = Standard_True;
894 }
895 bRecomputeAngle = bRecomputeAngle || bRecomputeAngleLocal;
896
897 if(!bRecomputeAngle) {
898 BOPAlgo_ListIteratorOfListOfEdgeInfo anIt2(aLEInfo);
899
900 for(; anIt2.More(); anIt2.Next()) {
901 const BOPAlgo_EdgeInfo& anEI2=anIt2.Value();
902 const TopoDS_Edge& aE2=anEI2.Edge();
903
904 if(aE2.IsSame(aE))
905 continue;
906 Standard_Boolean anIsOut2=!anEI2.IsIn();
907 Standard_Boolean anIsNotPassed2=!anEI2.Passed();
908
909 if (anIsOut2 && anIsNotPassed2) {
910 anExp1.Init(aE, TopAbs_VERTEX);
911
912 for(; anExp1.More(); anExp1.Next()) {
913 TopExp_Explorer anExp2(aE2, TopAbs_VERTEX);
914 Standard_Boolean existsInEdge = Standard_False;
915
916 for(; anExp2.More(); anExp2.Next()) {
917 if(anExp1.Current().IsSame(anExp2.Current())) {
918 existsInEdge = Standard_True;
919 break;
920 }
921 }
922
923 if(!existsInEdge) {
924 bRecomputeAngleLocal = Standard_False;
925 break;
926 }
927 bRecomputeAngleLocal = Standard_True;
928 }
929 bRecomputeAngle = bRecomputeAngle || bRecomputeAngleLocal;
930 }
931 }
932 }
933
934 bRecomputeAngle = bRecomputeAngle || bRecomputeAngleLocal;
935
936 if(bRecomputeAngle) {
937 gp_Pnt2d aP2Dx;
938 //
939 aP2Dx=Coord2dVf(aE, theFace);
940 Standard_Real aD = aP2Dx.Distance(thePb);
941
942 TopoDS_Vertex aVf;
943 TopExp_Explorer anExp(aE, TopAbs_VERTEX);
944
945 for (; anExp.More(); anExp.Next()) {
946 const TopoDS_Vertex& aVx=*(TopoDS_Vertex*)(&anExp.Current());
947 if (aVx.Orientation()==TopAbs_FORWARD) {
948 aVf = aVx;
949 }
950 }
951 Standard_Boolean bIgnore = Standard_False;
952
953 if(bIsClosed || aVf.IsNull() || !aVf.IsSame(theVb)) {
954 bIgnore = (aD > theTol2D);
955 }
956
957 if(!bIgnore && (theTol2D > M_PI)) {
958 Standard_Real udist = fabs(aP2Dx.X() - thePb.X());
959 Standard_Real vdist = fabs(aP2Dx.Y() - thePb.Y());
960 Standard_Real aTolU = 2. * UTolerance2D(theVb, theGAS);
961 Standard_Real aTolV = 2. * VTolerance2D(theVb, theGAS);
962
963 if((udist > aTolU) ||
964 (vdist > aTolV)) {
965 bIgnore = Standard_True;
966 }
967 }
968
969 if((aD > Precision::Confusion()) && !bIgnore) {
970 Standard_Real f1, l1;
971 Handle(Geom2d_Curve) ac1 = BRep_Tool::CurveOnSurface(aE, theFace, f1, l1);
972
973 Standard_Real aTV1 = BRep_Tool::Parameter (aVf, aE, theFace);
974 Standard_Real aTV12 = 0.;
975 Standard_Real dt1 = (l1 - f1) * 0.5;
976
977 if (fabs (aTV1-f1) < fabs(aTV1 - l1)) {
978 aTV12 = aTV1 + dt1;
979 }
980 else {
981 aTV12 = aTV1 - dt1;
982 }
983
984 gp_Pnt2d aPointNew = ac1->Value(aTV12);
985 gp_Vec2d aV2DOut(thePb, aPointNew);
986
987 gp_Dir2d aDir2D(aV2DOut);
988 Standard_Real anAngleOut = Angle(aDir2D);
989 theRecomputedAngles.ChangeValue(acurindex) = anAngleOut;
990 }
991 }
992 }
993 }
994 return bRecomputeAngle;
995}