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