1 // Created by: Peter KURNEV
2 // Copyright (c) 2010-2012 OPEN CASCADE SAS
3 // Copyright (c) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
4 // Copyright (c) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT,
5 // EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
7 // The content of this file is subject to the Open CASCADE Technology Public
8 // License Version 6.5 (the "License"). You may not use the content of this file
9 // except in compliance with the License. Please obtain a copy of the License
10 // at http://www.opencascade.org and read it completely before using this file.
12 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
13 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
15 // The Original Code and all software distributed under the License is
16 // distributed on an "AS IS" basis, without warranty of any kind, and the
17 // Initial Developer hereby disclaims all such warranties, including without
18 // limitation, any warranties of merchantability, fitness for a particular
19 // purpose or non-infringement. Please see the License for the specific terms
20 // and conditions governing the rights and limitations under the License.
23 #include <BOPAlgo_BuilderSolid.ixx>
25 #include <gp_Pnt2d.hxx>
31 #include <Geom_Curve.hxx>
32 #include <Geom_Surface.hxx>
33 #include <Geom2d_Curve.hxx>
37 #include <TopoDS_Iterator.hxx>
38 #include <TopoDS_Face.hxx>
39 #include <TopoDS_Shape.hxx>
40 #include <TopoDS_Shell.hxx>
41 #include <TopoDS_Edge.hxx>
42 #include <TopoDS_Solid.hxx>
43 #include <TopoDS_Vertex.hxx>
44 #include <TopoDS_Compound.hxx>
46 #include <BRep_Builder.hxx>
47 #include <BRep_Tool.hxx>
48 #include <BRepTools.hxx>
49 #include <BRepClass3d_SolidClassifier.hxx>
52 #include <TopExp_Explorer.hxx>
54 #include <BOPTools_AlgoTools.hxx>
55 #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
56 #include <BOPTools.hxx>
57 #include <BOPCol_ListOfShape.hxx>
58 #include <BOPCol_MapOfOrientedShape.hxx>
60 #include <NCollection_List.hxx>
62 #include <BOPCol_DataMapOfShapeShape.hxx>
63 #include <BOPCol_DataMapOfShapeListOfShape.hxx>
64 #include <BOPInt_Context.hxx>
65 #include <BOPTools_CoupleOfShape.hxx>
66 #include <BOPCol_MapOfShape.hxx>
69 Standard_Boolean IsGrowthShell(const TopoDS_Shape& ,
70 const BOPCol_IndexedMapOfShape& );
72 Standard_Boolean IsHole(const TopoDS_Shape& ,
73 Handle(BOPInt_Context)& );
75 Standard_Boolean IsInside(const TopoDS_Shape& ,
77 Handle(BOPInt_Context)& );
79 void MakeInternalShells(const BOPCol_MapOfShape& ,
80 BOPCol_ListOfShape& );
83 Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell);
85 //=======================================================================
88 //=======================================================================
89 BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid()
94 //=======================================================================
97 //=======================================================================
98 BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid(const Handle(NCollection_BaseAllocator)& theAllocator)
100 BOPAlgo_BuilderArea(theAllocator)
103 //=======================================================================
106 //=======================================================================
107 BOPAlgo_BuilderSolid::~BOPAlgo_BuilderSolid()
110 //=======================================================================
113 //=======================================================================
114 void BOPAlgo_BuilderSolid::Perform()
118 if (myContext.IsNull()) {
119 //myErrorStatus=11;// Null Context
121 myContext=new BOPInt_Context;
126 BOPCol_ListIteratorOfListOfShape aIt;
128 aBB.MakeCompound(aC);
129 aIt.Initialize(myShapes);
130 for(; aIt.More(); aIt.Next()) {
131 const TopoDS_Shape& aF=aIt.Value();
136 PerformShapesToAvoid();
149 PerformInternalShapes();
154 //=======================================================================
155 //function :PerformShapesToAvoid
157 //=======================================================================
158 void BOPAlgo_BuilderSolid::PerformShapesToAvoid()
160 Standard_Boolean bFound;
161 Standard_Integer i, iCnt, aNbE, aNbF;
162 TopAbs_Orientation aOrE;
163 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
164 BOPCol_ListIteratorOfListOfShape aIt;
166 myShapesToAvoid.Clear();
171 bFound=Standard_False;
175 aIt.Initialize (myShapes);
176 for (; aIt.More(); aIt.Next()) {
177 const TopoDS_Shape& aF=aIt.Value();
178 if (!myShapesToAvoid.Contains(aF)) {
179 BOPTools::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
185 for (i=1; i<=aNbE; ++i) {
186 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aMEF.FindKey(i)));
187 if (BRep_Tool::Degenerated(aE)) {
191 BOPCol_ListOfShape& aLF=aMEF.ChangeFromKey(aE);
197 aOrE=aE.Orientation();
199 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
201 if (aOrE==TopAbs_INTERNAL) {
204 bFound=Standard_True;
205 myShapesToAvoid.Add(aF1);
208 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aLF.Last()));
209 if (aF2.IsSame(aF1)) {
210 if (BRep_Tool::IsClosed(aE, aF1)) {
214 if (aOrE==TopAbs_INTERNAL) {
218 bFound=Standard_True;
219 myShapesToAvoid.Add(aF1);
220 myShapesToAvoid.Add(aF2);
223 }// for (i=1; i<=aNbE; ++i) {
231 //=======================================================================
232 //function : PerformLoops
234 //=======================================================================
235 void BOPAlgo_BuilderSolid::PerformLoops()
241 Standard_Integer aNbLF, aNbOff, aNbFP, aNbFA;
243 TopAbs_Orientation anOr;
246 TopoDS_Iterator aItS;
248 BOPCol_ListIteratorOfListOfShape aItF, aIt;
249 BOPCol_MapIteratorOfMapOfOrientedShape aItM;
250 BOPTools_CoupleOfShape aCSOff;
252 BOPCol_MapOfOrientedShape AddedFacesMap;
253 BOPCol_IndexedDataMapOfShapeListOfShape aEFMap, aMEFP;
255 //=================================================
259 aItF.Initialize (myShapes);
260 for (; aItF.More(); aItF.Next()) {
261 const TopoDS_Shape& aFF = aItF.Value();
262 BOPTools::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap);
265 aItF.Initialize (myShapes);
266 for (i=1; aItF.More(); aItF.Next(), ++i) {
267 const TopoDS_Shape& aFF = aItF.Value();
268 if (myShapesToAvoid.Contains(aFF)) {
271 if (!AddedFacesMap.Add(aFF)) {
277 aBB.MakeShell(aShell);
278 aBB.Add(aShell, aFF);
281 BOPTools::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aMEFP);
283 // loop on faces added to Shell; add their neighbor faces to Shell and so on
284 TopoDS_Iterator aItAddedF (aShell);
285 for (; aItAddedF.More(); aItAddedF.Next()) {
286 const TopoDS_Face& aF = (*(TopoDS_Face*)(&aItAddedF.Value()));
288 // loop on edges of aF; find a good neighbor face of aF by aE
289 TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
290 for (; aEdgeExp.More(); aEdgeExp.Next()) {
291 const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aEdgeExp.Current()));
294 if (aMEFP.Contains(aE)) {
295 const BOPCol_ListOfShape& aLFP=aMEFP.FindFromKey(aE);
302 anOr=aE.Orientation();
303 if (anOr==TopAbs_INTERNAL) {
307 if (BRep_Tool::Degenerated(aE)) {
311 // candidate faces list
312 const BOPCol_ListOfShape& aLF=aEFMap.FindFromKey(aE);
318 // try to select one of neighbors
319 // check if a face already added to Shell shares E
320 Standard_Boolean bFound;
321 BOPCol_ListIteratorOfListOfShape aItLF;
322 BOPTools_ListOfCoupleOfShape aLCSOff;
324 aItLF.Initialize(aLF);
325 for (; aItLF.More(); aItLF.Next()) {
326 const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aItLF.Value()));
327 if (myShapesToAvoid.Contains(aFL)) {
330 if (aF.IsSame(aFL)) {
333 if (AddedFacesMap.Contains(aFL)){
337 bFound=BOPTools_AlgoTools::GetEdgeOff(aE, aFL, aEL);
342 aCSOff.SetShape1(aEL);
343 aCSOff.SetShape2(aFL);
344 aLCSOff.Append(aCSOff);
345 }//for (; aItLF.More(); aItLF.Next()) {
347 aNbOff=aLCSOff.Extent();
354 aSelF=(*(TopoDS_Face*)(&aLCSOff.First().Shape2()));
357 BOPTools_AlgoTools::GetFaceOff(aE, aF, aLCSOff, aSelF, myContext);
360 if (!aSelF.IsNull() && AddedFacesMap.Add(aSelF)) {
361 aBB.Add(aShell, aSelF);
362 BOPTools::MapShapesAndAncestors(aSelF, TopAbs_EDGE, TopAbs_FACE, aMEFP);
364 } // for (; aEdgeExp.More(); aEdgeExp.Next()) {
365 } //for (; aItAddedF.More(); aItAddedF.Next()) {
367 if (IsClosedShell(aShell)) {
368 myLoops.Append(aShell);
370 } // for (; aItF.More(); aItF.Next()) {
374 BOPCol_MapOfOrientedShape aMP;
376 // a. collect all edges that are in loops
377 aIt.Initialize (myLoops);
378 for (; aIt.More(); aIt.Next()) {
379 const TopoDS_Shape& aS=aIt.Value();
381 for (; aItS.More(); aItS.Next()) {
382 const TopoDS_Shape& aF=aItS.Value();
387 // b. collect all edges that are to avoid
388 aItM.Initialize(myShapesToAvoid);
389 for (; aItM.More(); aItM.Next()) {
390 const TopoDS_Shape& aF=aItM.Key();
394 // c. add all edges that are not processed to myShapesToAvoid
395 aIt.Initialize (myShapes);
396 for (; aIt.More(); aIt.Next()) {
397 const TopoDS_Shape& aF=aIt.Value();
398 if (!aMP.Contains(aF)) {
399 myShapesToAvoid.Add(aF);
402 //=================================================
406 myLoopsInternal.Clear();
409 AddedFacesMap.Clear();
411 aNbFA=myShapesToAvoid.Extent();
413 aItM.Initialize(myShapesToAvoid);
414 for (; aItM.More(); aItM.Next()) {
415 const TopoDS_Shape& aFF=aItM.Key();
416 BOPTools::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap);
419 aItM.Initialize(myShapesToAvoid);
420 for (; aItM.More(); aItM.Next()) {
421 const TopoDS_Shape& aFF=aItM.Key();
422 if (!AddedFacesMap.Add(aFF)) {
428 aBB.MakeShell(aShell);
429 aBB.Add(aShell, aFF);
431 TopoDS_Iterator aItAddedF (aShell);
432 for (; aItAddedF.More(); aItAddedF.Next()) {
433 const TopoDS_Face& aF = (*(TopoDS_Face*)(&aItAddedF.Value()));
435 TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
436 for (; aEdgeExp.More(); aEdgeExp.Next()) {
437 const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aEdgeExp.Current()));
438 const BOPCol_ListOfShape& aLF=aEFMap.FindFromKey(aE);
439 aItF.Initialize(aLF);
440 for (; aItF.More(); aItF.Next()) {
441 const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aItF.Value()));
442 if (AddedFacesMap.Add(aFL)){
443 aBB.Add(aShell, aFL);
448 myLoopsInternal.Append(aShell);
451 //=======================================================================
452 //function : PerformAreas
454 //=======================================================================
455 void BOPAlgo_BuilderSolid::PerformAreas()
459 Standard_Boolean bIsGrowthShell, bIsHole;
461 TopoDS_Shape anInfinitePointShape;
462 BOPCol_DataMapIteratorOfDataMapOfShapeListOfShape aItMSH;
463 BOPCol_ListIteratorOfListOfShape aShellIt, aSolidIt;
465 BOPCol_ListOfShape aNewSolids, aHoleShells;
466 BOPCol_DataMapOfShapeShape aInOutMap;
467 BOPCol_DataMapOfShapeListOfShape aMSH;
468 BOPCol_IndexedMapOfShape aMHF;
472 // Draft solids [aNewSolids]
473 aShellIt.Initialize(myLoops);
474 for ( ; aShellIt.More(); aShellIt.Next()) {
475 const TopoDS_Shape& aShell = aShellIt.Value();
477 bIsGrowthShell=IsGrowthShell(aShell, aMHF);
478 if (bIsGrowthShell) {
479 // make a growth solid from a shell
481 aBB.MakeSolid(Solid);
482 aBB.Add (Solid, aShell);
484 aNewSolids.Append (Solid);
487 // check if a shell is a hole
489 bIsHole=IsHole(aShell, myContext);
492 aHoleShells.Append(aShell);
493 BOPTools::MapShapes(aShell, TopAbs_FACE, aMHF);
496 // make a growth solid from a shell
498 aBB.MakeSolid(Solid);
499 aBB.Add (Solid, aShell);
501 aNewSolids.Append (Solid);
506 // 2. Find outer growth shell that is most close to each hole shell
507 aShellIt.Initialize(aHoleShells);
508 for (; aShellIt.More(); aShellIt.Next()) {
509 const TopoDS_Shape& aHole = aShellIt.Value();
511 aSolidIt.Initialize(aNewSolids);
512 for ( ; aSolidIt.More(); aSolidIt.Next()) {
513 const TopoDS_Shape& aSolid = aSolidIt.Value();
515 if (!IsInside(aHole, aSolid, myContext)){
519 if ( aInOutMap.IsBound (aHole)){
520 const TopoDS_Shape& aSolid2 = aInOutMap(aHole);
521 if (IsInside(aSolid, aSolid2, myContext)) {
522 aInOutMap.UnBind(aHole);
523 aInOutMap.Bind (aHole, aSolid);
527 aInOutMap.Bind (aHole, aSolid);
531 // Add aHole to a map Solid/ListOfHoles [aMSH]
532 if (aInOutMap.IsBound(aHole)){
533 const TopoDS_Shape& aSolid=aInOutMap(aHole);
534 if (aMSH.IsBound(aSolid)) {
535 BOPCol_ListOfShape& aLH=aMSH.ChangeFind(aSolid);
539 BOPCol_ListOfShape aLH;
541 aMSH.Bind(aSolid, aLH);
543 //aBB.Add (aSolid, aHole);
545 }// for (; aShellIt.More(); aShellIt.Next()) {
547 // 3. Add aHoles to Solids
548 aItMSH.Initialize(aMSH);
549 for (; aItMSH.More(); aItMSH.Next()) {
550 TopoDS_Solid aSolid=(*(TopoDS_Solid*)(&aItMSH.Key()));
552 const BOPCol_ListOfShape& aLH=aItMSH.Value();
553 aShellIt.Initialize(aLH);
554 for (; aShellIt.More(); aShellIt.Next()) {
555 const TopoDS_Shape& aHole = aShellIt.Value();
556 aBB.Add (aSolid, aHole);
560 BRepClass3d_SolidClassifier& aSC=myContext->SolidClassifier(aSolid);
565 // These aNewSolids are draft solids that
566 // do not contain any internal shapes
568 aShellIt.Initialize(aNewSolids);
569 for ( ; aShellIt.More(); aShellIt.Next()) {
570 const TopoDS_Shape& aSx = aShellIt.Value();
574 // Add holes that outside the solids to myAreas
575 aShellIt.Initialize(aHoleShells);
576 for (; aShellIt.More(); aShellIt.Next()) {
577 const TopoDS_Shape& aHole = aShellIt.Value();
578 if (!aInOutMap.IsBound(aHole)){
580 aBB.MakeSolid(aSolid);
581 aBB.Add (aSolid, aHole);
583 myAreas.Append(aSolid);
587 //=======================================================================
588 //function : PerformInternalShapes
590 //=======================================================================
591 void BOPAlgo_BuilderSolid::PerformInternalShapes()
595 Standard_Integer aNbFI=myLoopsInternal.Extent();
596 if (!aNbFI) {// nothing to do
602 BOPCol_ListIteratorOfListOfShape aShellIt, aSolidIt;
603 BOPCol_MapIteratorOfMapOfShape aItMF;
605 BOPCol_MapOfShape aMF, aMFP, aMFx;
606 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
607 BOPCol_ListOfShape aLSI;
609 // 1. All internal faces
610 aShellIt.Initialize(myLoopsInternal);
611 for (; aShellIt.More(); aShellIt.Next()) {
612 const TopoDS_Shape& aShell=aShellIt.Value();
613 aIt.Initialize(aShell);
614 for (; aIt.More(); aIt.Next()) {
615 const TopoDS_Shape& aF=aIt.Value();
622 aSolidIt.Initialize(myAreas);
623 for ( ; aSolidIt.More(); aSolidIt.Next()) {
624 TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aSolidIt.Value()));
626 TopExp_Explorer anExpSol(aSolid, TopAbs_FACE);;
627 for (; anExpSol.More(); anExpSol.Next()) {
628 const TopoDS_Shape& aF = anExpSol.Current();
631 aFF.Orientation(TopAbs_FORWARD);
633 aFF.Orientation(TopAbs_REVERSED);
637 BOPTools::MapShapesAndAncestors(aSolid, TopAbs_EDGE, TopAbs_FACE, aMEF);
639 // 2.1 Separate faces to process aMFP
641 aItMF.Initialize(aMF);
642 for (; aItMF.More(); aItMF.Next()) {
643 const TopoDS_Face& aF=(*(TopoDS_Face*)(&aItMF.Key()));
644 if (!aMFx.Contains(aF)) {
645 if (BOPTools_AlgoTools::IsInternalFace(aF, aSolid, aMEF, 1.e-14, myContext)) {
652 // 2.2 Make Internal Shells
654 MakeInternalShells(aMFP, aLSI);
656 // 2.3 Add them to aSolid
657 aShellIt.Initialize(aLSI);
658 for (; aShellIt.More(); aShellIt.Next()) {
659 const TopoDS_Shape& aSI=aShellIt.Value();
660 aBB.Add (aSolid, aSI);
663 // 2.4 Remove faces aMFP from aMF
664 aItMF.Initialize(aMFP);
665 for (; aItMF.More(); aItMF.Next()) {
666 const TopoDS_Shape& aF=aItMF.Key();
674 } //for ( ; aSolidIt.More(); aSolidIt.Next()) {
677 aBB.MakeSolid(aSolid);
679 MakeInternalShells(aMF, aLSI);
680 aShellIt.Initialize(aLSI);
681 for (; aShellIt.More(); aShellIt.Next()) {
682 const TopoDS_Shape& aSI=aShellIt.Value();
683 aBB.Add (aSolid, aSI);
685 myAreas.Append(aSolid);
689 //=======================================================================
690 //function : MakeInternalShells
692 //=======================================================================
693 void MakeInternalShells(const BOPCol_MapOfShape& theMF,
694 BOPCol_ListOfShape& theShells)
696 BOPCol_ListIteratorOfListOfShape aItF;
699 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
700 BOPCol_MapIteratorOfMapOfShape aItM;
701 BOPCol_MapOfShape aAddedFacesMap;
703 aItM.Initialize(theMF);
704 for (; aItM.More(); aItM.Next()) {
705 const TopoDS_Shape& aF=aItM.Key();
706 BOPTools::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
709 aItM.Initialize(theMF);
710 for (; aItM.More(); aItM.Next()) {
711 TopoDS_Shape aFF=aItM.Key();
712 if (!aAddedFacesMap.Add(aFF)) {
718 aBB.MakeShell(aShell);
719 aFF.Orientation(TopAbs_INTERNAL);
720 aBB.Add(aShell, aFF);
722 TopoDS_Iterator aItAddedF (aShell);
723 for (; aItAddedF.More(); aItAddedF.Next()) {
724 const TopoDS_Shape& aF =aItAddedF.Value();
726 TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
727 for (; aEdgeExp.More(); aEdgeExp.Next()) {
728 const TopoDS_Shape& aE =aEdgeExp.Current();
729 const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
730 aItF.Initialize(aLF);
731 for (; aItF.More(); aItF.Next()) {
732 TopoDS_Shape aFL=aItF.Value();
733 if (aAddedFacesMap.Add(aFL)){
734 aFL.Orientation(TopAbs_INTERNAL);
735 aBB.Add(aShell, aFL);
740 theShells.Append(aShell);
743 //=======================================================================
746 //=======================================================================
747 Standard_Boolean IsHole(const TopoDS_Shape& theS2,
748 Handle(BOPInt_Context)& theContext)
750 TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2;
751 BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2);
753 aClsf.PerformInfinitePoint(::RealSmall());
755 return (aClsf.State()==TopAbs_IN);
757 //=======================================================================
758 //function : IsInside
760 //=======================================================================
761 Standard_Boolean IsInside(const TopoDS_Shape& theS1,
762 const TopoDS_Shape& theS2,
763 Handle(BOPInt_Context)& theContext)
765 TopExp_Explorer aExp;
768 TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2;
770 aExp.Init(theS1, TopAbs_FACE);
772 BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2);
773 aClsf.PerformInfinitePoint(::RealSmall());
774 aState=aClsf.State();
777 BOPCol_IndexedMapOfShape aBounds;
778 BOPTools::MapShapes(*pS2, TopAbs_EDGE, aBounds);
779 const TopoDS_Face& aF = (*(TopoDS_Face*)(&aExp.Current()));
780 aState=BOPTools_AlgoTools::ComputeState(aF, *pS2, 1.e-14, aBounds, theContext);
782 return (aState==TopAbs_IN);
784 //=======================================================================
785 //function : IsGrowthShell
787 //=======================================================================
788 Standard_Boolean IsGrowthShell(const TopoDS_Shape& theShell,
789 const BOPCol_IndexedMapOfShape& theMHF)
791 Standard_Boolean bRet;
795 if (theMHF.Extent()) {
796 aIt.Initialize(theShell);
797 for(; aIt.More(); aIt.Next()) {
798 const TopoDS_Shape& aF=aIt.Value();
799 if (theMHF.Contains(aF)) {
806 //=======================================================================
807 //function : IsClosedShell
809 //=======================================================================
810 Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell)
812 Standard_Integer aNbE;
813 Standard_Boolean bRet;
815 TopExp_Explorer aExp;
817 BOPCol_MapOfShape aM;
820 aIt.Initialize(theShell);
821 for(; aIt.More(); aIt.Next()) {
822 const TopoDS_Face& aF=(*(TopoDS_Face*)(&aIt.Value()));
823 aExp.Init(aF, TopAbs_EDGE);
824 for (; aExp.More(); aExp.Next()) {
825 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
826 if (BRep_Tool::Degenerated(aE)) {
830 if (aE.Orientation()==TopAbs_INTERNAL) {