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