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);
188 for (i=1; i<=aNbE; ++i) {
189 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aMEF.FindKey(i)));
190 if (BRep_Tool::Degenerated(aE)) {
194 BOPCol_ListOfShape& aLF=aMEF.ChangeFromKey(aE);
200 aOrE=aE.Orientation();
202 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
204 if (aOrE==TopAbs_INTERNAL) {
207 bFound=Standard_True;
208 myShapesToAvoid.Add(aF1);
211 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aLF.Last()));
212 if (aF2.IsSame(aF1)) {
213 if (BRep_Tool::IsClosed(aE, aF1)) {
217 if (aOrE==TopAbs_INTERNAL) {
221 bFound=Standard_True;
222 myShapesToAvoid.Add(aF1);
223 myShapesToAvoid.Add(aF2);
226 }// for (i=1; i<=aNbE; ++i) {
234 //=======================================================================
235 //function : PerformLoops
237 //=======================================================================
238 void BOPAlgo_BuilderSolid::PerformLoops()
244 Standard_Integer aNbLF, aNbOff, aNbFP, aNbFA;
246 TopAbs_Orientation anOr;
249 TopoDS_Iterator aItS;
251 BOPCol_ListIteratorOfListOfShape aItF, aIt;
252 BOPCol_MapIteratorOfMapOfOrientedShape aItM;
253 BOPTools_CoupleOfShape aCSOff;
255 BOPCol_MapOfOrientedShape AddedFacesMap;
256 BOPCol_IndexedDataMapOfShapeListOfShape aEFMap, aMEFP;
258 //=================================================
262 aItF.Initialize (myShapes);
263 for (; aItF.More(); aItF.Next()) {
264 const TopoDS_Shape& aFF = aItF.Value();
265 BOPTools::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap);
268 aItF.Initialize (myShapes);
269 for (i=1; aItF.More(); aItF.Next(), ++i) {
270 const TopoDS_Shape& aFF = aItF.Value();
271 if (myShapesToAvoid.Contains(aFF)) {
274 if (!AddedFacesMap.Add(aFF)) {
280 aBB.MakeShell(aShell);
281 aBB.Add(aShell, aFF);
284 BOPTools::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aMEFP);
286 // loop on faces added to Shell; add their neighbor faces to Shell and so on
287 TopoDS_Iterator aItAddedF (aShell);
288 for (; aItAddedF.More(); aItAddedF.Next()) {
289 const TopoDS_Face& aF = (*(TopoDS_Face*)(&aItAddedF.Value()));
291 // loop on edges of aF; find a good neighbor face of aF by aE
292 TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
293 for (; aEdgeExp.More(); aEdgeExp.Next()) {
294 const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aEdgeExp.Current()));
297 if (aMEFP.Contains(aE)) {
298 const BOPCol_ListOfShape& aLFP=aMEFP.FindFromKey(aE);
305 anOr=aE.Orientation();
306 if (anOr==TopAbs_INTERNAL) {
310 if (BRep_Tool::Degenerated(aE)) {
314 // candidate faces list
315 const BOPCol_ListOfShape& aLF=aEFMap.FindFromKey(aE);
321 // try to select one of neighbors
322 // check if a face already added to Shell shares E
323 Standard_Boolean bFound;
324 BOPCol_ListIteratorOfListOfShape aItLF;
325 BOPTools_ListOfCoupleOfShape aLCSOff;
327 aItLF.Initialize(aLF);
328 for (; aItLF.More(); aItLF.Next()) {
329 const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aItLF.Value()));
330 if (myShapesToAvoid.Contains(aFL)) {
333 if (aF.IsSame(aFL)) {
336 if (AddedFacesMap.Contains(aFL)){
340 bFound=BOPTools_AlgoTools::GetEdgeOff(aE, aFL, aEL);
345 aCSOff.SetShape1(aEL);
346 aCSOff.SetShape2(aFL);
347 aLCSOff.Append(aCSOff);
348 }//for (; aItLF.More(); aItLF.Next()) {
350 aNbOff=aLCSOff.Extent();
357 aSelF=(*(TopoDS_Face*)(&aLCSOff.First().Shape2()));
360 BOPTools_AlgoTools::GetFaceOff(aE, aF, aLCSOff, aSelF, myContext);
363 if (!aSelF.IsNull() && AddedFacesMap.Add(aSelF)) {
364 aBB.Add(aShell, aSelF);
365 BOPTools::MapShapesAndAncestors(aSelF, TopAbs_EDGE, TopAbs_FACE, aMEFP);
367 } // for (; aEdgeExp.More(); aEdgeExp.Next()) {
368 } //for (; aItAddedF.More(); aItAddedF.Next()) {
370 if (IsClosedShell(aShell)) {
371 myLoops.Append(aShell);
373 } // for (; aItF.More(); aItF.Next()) {
377 BOPCol_MapOfOrientedShape aMP;
379 // a. collect all edges that are in loops
380 aIt.Initialize (myLoops);
381 for (; aIt.More(); aIt.Next()) {
382 const TopoDS_Shape& aS=aIt.Value();
384 for (; aItS.More(); aItS.Next()) {
385 const TopoDS_Shape& aF=aItS.Value();
390 // b. collect all edges that are to avoid
391 aItM.Initialize(myShapesToAvoid);
392 for (; aItM.More(); aItM.Next()) {
393 const TopoDS_Shape& aF=aItM.Key();
397 // c. add all edges that are not processed to myShapesToAvoid
398 aIt.Initialize (myShapes);
399 for (; aIt.More(); aIt.Next()) {
400 const TopoDS_Shape& aF=aIt.Value();
401 if (!aMP.Contains(aF)) {
402 myShapesToAvoid.Add(aF);
405 //=================================================
409 myLoopsInternal.Clear();
412 AddedFacesMap.Clear();
414 aNbFA=myShapesToAvoid.Extent();
416 aItM.Initialize(myShapesToAvoid);
417 for (; aItM.More(); aItM.Next()) {
418 const TopoDS_Shape& aFF=aItM.Key();
419 BOPTools::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap);
422 aItM.Initialize(myShapesToAvoid);
423 for (; aItM.More(); aItM.Next()) {
424 const TopoDS_Shape& aFF=aItM.Key();
425 if (!AddedFacesMap.Add(aFF)) {
431 aBB.MakeShell(aShell);
432 aBB.Add(aShell, aFF);
434 TopoDS_Iterator aItAddedF (aShell);
435 for (; aItAddedF.More(); aItAddedF.Next()) {
436 const TopoDS_Face& aF = (*(TopoDS_Face*)(&aItAddedF.Value()));
438 TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
439 for (; aEdgeExp.More(); aEdgeExp.Next()) {
440 const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aEdgeExp.Current()));
441 const BOPCol_ListOfShape& aLF=aEFMap.FindFromKey(aE);
442 aItF.Initialize(aLF);
443 for (; aItF.More(); aItF.Next()) {
444 const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aItF.Value()));
445 if (AddedFacesMap.Add(aFL)){
446 aBB.Add(aShell, aFL);
451 myLoopsInternal.Append(aShell);
454 //=======================================================================
455 //function : PerformAreas
457 //=======================================================================
458 void BOPAlgo_BuilderSolid::PerformAreas()
462 Standard_Boolean bIsGrowthShell, bIsHole;
464 TopoDS_Shape anInfinitePointShape;
465 BOPCol_DataMapIteratorOfDataMapOfShapeListOfShape aItMSH;
466 BOPCol_ListIteratorOfListOfShape aShellIt, aSolidIt;
468 BOPCol_ListOfShape aNewSolids, aHoleShells;
469 BOPCol_DataMapOfShapeShape aInOutMap;
470 BOPCol_DataMapOfShapeListOfShape aMSH;
471 BOPCol_IndexedMapOfShape aMHF;
475 // Draft solids [aNewSolids]
476 aShellIt.Initialize(myLoops);
477 for ( ; aShellIt.More(); aShellIt.Next()) {
478 const TopoDS_Shape& aShell = aShellIt.Value();
480 bIsGrowthShell=IsGrowthShell(aShell, aMHF);
481 if (bIsGrowthShell) {
482 // make a growth solid from a shell
484 aBB.MakeSolid(Solid);
485 aBB.Add (Solid, aShell);
487 aNewSolids.Append (Solid);
490 // check if a shell is a hole
492 bIsHole=IsHole(aShell, myContext);
495 aHoleShells.Append(aShell);
496 BOPTools::MapShapes(aShell, TopAbs_FACE, aMHF);
499 // make a growth solid from a shell
501 aBB.MakeSolid(Solid);
502 aBB.Add (Solid, aShell);
504 aNewSolids.Append (Solid);
509 // 2. Find outer growth shell that is most close to each hole shell
510 aShellIt.Initialize(aHoleShells);
511 for (; aShellIt.More(); aShellIt.Next()) {
512 const TopoDS_Shape& aHole = aShellIt.Value();
514 aSolidIt.Initialize(aNewSolids);
515 for ( ; aSolidIt.More(); aSolidIt.Next()) {
516 const TopoDS_Shape& aSolid = aSolidIt.Value();
518 if (!IsInside(aHole, aSolid, myContext)){
522 if ( aInOutMap.IsBound (aHole)){
523 const TopoDS_Shape& aSolid2 = aInOutMap(aHole);
524 if (IsInside(aSolid, aSolid2, myContext)) {
525 aInOutMap.UnBind(aHole);
526 aInOutMap.Bind (aHole, aSolid);
530 aInOutMap.Bind (aHole, aSolid);
534 // Add aHole to a map Solid/ListOfHoles [aMSH]
535 if (aInOutMap.IsBound(aHole)){
536 const TopoDS_Shape& aSolid=aInOutMap(aHole);
537 if (aMSH.IsBound(aSolid)) {
538 BOPCol_ListOfShape& aLH=aMSH.ChangeFind(aSolid);
542 BOPCol_ListOfShape aLH;
544 aMSH.Bind(aSolid, aLH);
546 //aBB.Add (aSolid, aHole);
548 }// for (; aShellIt.More(); aShellIt.Next()) {
550 // 3. Add aHoles to Solids
551 aItMSH.Initialize(aMSH);
552 for (; aItMSH.More(); aItMSH.Next()) {
553 TopoDS_Solid aSolid=(*(TopoDS_Solid*)(&aItMSH.Key()));
555 const BOPCol_ListOfShape& aLH=aItMSH.Value();
556 aShellIt.Initialize(aLH);
557 for (; aShellIt.More(); aShellIt.Next()) {
558 const TopoDS_Shape& aHole = aShellIt.Value();
559 aBB.Add (aSolid, aHole);
563 BRepClass3d_SolidClassifier& aSC=myContext->SolidClassifier(aSolid);
568 // These aNewSolids are draft solids that
569 // do not contain any internal shapes
571 aShellIt.Initialize(aNewSolids);
572 for ( ; aShellIt.More(); aShellIt.Next()) {
573 const TopoDS_Shape& aSx = aShellIt.Value();
577 // Add holes that outside the solids to myAreas
578 aShellIt.Initialize(aHoleShells);
579 for (; aShellIt.More(); aShellIt.Next()) {
580 const TopoDS_Shape& aHole = aShellIt.Value();
581 if (!aInOutMap.IsBound(aHole)){
583 aBB.MakeSolid(aSolid);
584 aBB.Add (aSolid, aHole);
586 myAreas.Append(aSolid);
590 //=======================================================================
591 //function : PerformInternalShapes
593 //=======================================================================
594 void BOPAlgo_BuilderSolid::PerformInternalShapes()
598 Standard_Integer aNbFI=myLoopsInternal.Extent();
599 if (!aNbFI) {// nothing to do
605 BOPCol_ListIteratorOfListOfShape aShellIt, aSolidIt;
606 BOPCol_MapIteratorOfMapOfShape aItMF;
608 BOPCol_MapOfShape aMF, aMFP, aMFx;
609 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
610 BOPCol_ListOfShape aLSI;
612 // 1. All internal faces
613 aShellIt.Initialize(myLoopsInternal);
614 for (; aShellIt.More(); aShellIt.Next()) {
615 const TopoDS_Shape& aShell=aShellIt.Value();
616 aIt.Initialize(aShell);
617 for (; aIt.More(); aIt.Next()) {
618 const TopoDS_Shape& aF=aIt.Value();
625 aSolidIt.Initialize(myAreas);
626 for ( ; aSolidIt.More(); aSolidIt.Next()) {
627 TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aSolidIt.Value()));
629 TopExp_Explorer anExpSol(aSolid, TopAbs_FACE);;
630 for (; anExpSol.More(); anExpSol.Next()) {
631 const TopoDS_Shape& aF = anExpSol.Current();
634 aFF.Orientation(TopAbs_FORWARD);
636 aFF.Orientation(TopAbs_REVERSED);
640 BOPTools::MapShapesAndAncestors(aSolid, TopAbs_EDGE, TopAbs_FACE, aMEF);
642 // 2.1 Separate faces to process aMFP
644 aItMF.Initialize(aMF);
645 for (; aItMF.More(); aItMF.Next()) {
646 const TopoDS_Face& aF=(*(TopoDS_Face*)(&aItMF.Key()));
647 if (!aMFx.Contains(aF)) {
648 if (BOPTools_AlgoTools::IsInternalFace(aF, aSolid, aMEF, 1.e-14, myContext)) {
655 // 2.2 Make Internal Shells
657 MakeInternalShells(aMFP, aLSI);
659 // 2.3 Add them to aSolid
660 aShellIt.Initialize(aLSI);
661 for (; aShellIt.More(); aShellIt.Next()) {
662 const TopoDS_Shape& aSI=aShellIt.Value();
663 aBB.Add (aSolid, aSI);
666 // 2.4 Remove faces aMFP from aMF
667 aItMF.Initialize(aMFP);
668 for (; aItMF.More(); aItMF.Next()) {
669 const TopoDS_Shape& aF=aItMF.Key();
677 } //for ( ; aSolidIt.More(); aSolidIt.Next()) {
680 aBB.MakeSolid(aSolid);
682 MakeInternalShells(aMF, aLSI);
683 aShellIt.Initialize(aLSI);
684 for (; aShellIt.More(); aShellIt.Next()) {
685 const TopoDS_Shape& aSI=aShellIt.Value();
686 aBB.Add (aSolid, aSI);
688 myAreas.Append(aSolid);
692 //=======================================================================
693 //function : MakeInternalShells
695 //=======================================================================
696 void MakeInternalShells(const BOPCol_MapOfShape& theMF,
697 BOPCol_ListOfShape& theShells)
699 BOPCol_ListIteratorOfListOfShape aItF;
702 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
703 BOPCol_MapIteratorOfMapOfShape aItM;
704 BOPCol_MapOfShape aAddedFacesMap;
706 aItM.Initialize(theMF);
707 for (; aItM.More(); aItM.Next()) {
708 const TopoDS_Shape& aF=aItM.Key();
709 BOPTools::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
712 aItM.Initialize(theMF);
713 for (; aItM.More(); aItM.Next()) {
714 TopoDS_Shape aFF=aItM.Key();
715 if (!aAddedFacesMap.Add(aFF)) {
721 aBB.MakeShell(aShell);
722 aFF.Orientation(TopAbs_INTERNAL);
723 aBB.Add(aShell, aFF);
725 TopoDS_Iterator aItAddedF (aShell);
726 for (; aItAddedF.More(); aItAddedF.Next()) {
727 const TopoDS_Shape& aF =aItAddedF.Value();
729 TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
730 for (; aEdgeExp.More(); aEdgeExp.Next()) {
731 const TopoDS_Shape& aE =aEdgeExp.Current();
732 const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
733 aItF.Initialize(aLF);
734 for (; aItF.More(); aItF.Next()) {
735 TopoDS_Shape aFL=aItF.Value();
736 if (aAddedFacesMap.Add(aFL)){
737 aFL.Orientation(TopAbs_INTERNAL);
738 aBB.Add(aShell, aFL);
743 theShells.Append(aShell);
746 //=======================================================================
749 //=======================================================================
750 Standard_Boolean IsHole(const TopoDS_Shape& theS2,
751 Handle(BOPInt_Context)& theContext)
753 TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2;
754 BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2);
756 aClsf.PerformInfinitePoint(::RealSmall());
758 return (aClsf.State()==TopAbs_IN);
760 //=======================================================================
761 //function : IsInside
763 //=======================================================================
764 Standard_Boolean IsInside(const TopoDS_Shape& theS1,
765 const TopoDS_Shape& theS2,
766 Handle(BOPInt_Context)& theContext)
768 TopExp_Explorer aExp;
771 TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2;
773 aExp.Init(theS1, TopAbs_FACE);
775 BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2);
776 aClsf.PerformInfinitePoint(::RealSmall());
777 aState=aClsf.State();
780 BOPCol_IndexedMapOfShape aBounds;
781 BOPTools::MapShapes(*pS2, TopAbs_EDGE, aBounds);
782 const TopoDS_Face& aF = (*(TopoDS_Face*)(&aExp.Current()));
783 aState=BOPTools_AlgoTools::ComputeState(aF, *pS2, 1.e-14, aBounds, theContext);
785 return (aState==TopAbs_IN);
787 //=======================================================================
788 //function : IsGrowthShell
790 //=======================================================================
791 Standard_Boolean IsGrowthShell(const TopoDS_Shape& theShell,
792 const BOPCol_IndexedMapOfShape& theMHF)
794 Standard_Boolean bRet;
798 if (theMHF.Extent()) {
799 aIt.Initialize(theShell);
800 for(; aIt.More(); aIt.Next()) {
801 const TopoDS_Shape& aF=aIt.Value();
802 if (theMHF.Contains(aF)) {
809 //=======================================================================
810 //function : IsClosedShell
812 //=======================================================================
813 Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell)
815 Standard_Integer aNbE;
816 Standard_Boolean bRet;
818 TopExp_Explorer aExp;
820 BOPCol_MapOfShape aM;
823 aIt.Initialize(theShell);
824 for(; aIt.More(); aIt.Next()) {
825 const TopoDS_Face& aF=(*(TopoDS_Face*)(&aIt.Value()));
826 aExp.Init(aF, TopAbs_EDGE);
827 for (; aExp.More(); aExp.Next()) {
828 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
829 if (BRep_Tool::Degenerated(aE)) {
833 if (aE.Orientation()==TopAbs_INTERNAL) {