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
8 // This file is part of Open CASCADE Technology software library.
10 // This library is free software; you can redistribute it and/or modify it under
11 // the terms of the GNU Lesser General Public License version 2.1 as published
12 // by the Free Software Foundation, with special exception defined in the file
13 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
14 // distribution for complete text of the license and disclaimer of any warranty.
16 // Alternatively, this file may be used under the terms of Open CASCADE
17 // commercial license or contractual agreement.
20 #include <Bnd_Box.hxx>
21 #include <BOPAlgo_BuilderFace.hxx>
22 #include <BOPAlgo_WireEdgeSet.hxx>
23 #include <BOPAlgo_WireSplitter.hxx>
24 #include <BOPCol_Box2DBndTree.hxx>
25 #include <BOPCol_DataMapOfShapeListOfShape.hxx>
26 #include <BOPCol_DataMapOfShapeShape.hxx>
27 #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
28 #include <BOPCol_ListOfShape.hxx>
29 #include <BOPCol_MapOfShape.hxx>
30 #include <BOPTools.hxx>
31 #include <BOPTools_AlgoTools.hxx>
32 #include <BOPTools_AlgoTools2D.hxx>
33 #include <BRep_Builder.hxx>
34 #include <BRep_Tool.hxx>
35 #include <BRepBndLib.hxx>
36 #include <BRepTools.hxx>
37 #include <Geom_Surface.hxx>
41 #include <gp_Pnt2d.hxx>
43 #include <IntTools_Context.hxx>
44 #include <IntTools_FClass2d.hxx>
45 #include <NCollection_DataMap.hxx>
46 #include <NCollection_UBTreeFiller.hxx>
47 #include <TColStd_MapIntegerHasher.hxx>
50 #include <TopExp_Explorer.hxx>
51 #include <TopLoc_Location.hxx>
52 #include <TopoDS_Edge.hxx>
53 #include <TopoDS_Face.hxx>
54 #include <TopoDS_Iterator.hxx>
55 #include <TopoDS_Shape.hxx>
56 #include <TopoDS_Vertex.hxx>
57 #include <TopoDS_Wire.hxx>
74 Standard_Boolean IsGrowthWire(const TopoDS_Shape& ,
75 const BOPCol_IndexedMapOfShape& );
78 Standard_Boolean IsInside(const TopoDS_Shape& ,
80 Handle(IntTools_Context)& );
82 void MakeInternalWires(const BOPCol_MapOfShape& ,
83 BOPCol_ListOfShape& );
85 void GetWire(const TopoDS_Shape& ,
90 //=======================================================================
91 //class : BOPAlgo_ShapeBox2D
92 //purpose : Auxiliary class
93 //=======================================================================
94 class BOPAlgo_ShapeBox2D {
96 BOPAlgo_ShapeBox2D() {
97 myIsHole=Standard_False;
100 ~BOPAlgo_ShapeBox2D() {
103 void SetShape(const TopoDS_Shape& aS) {
107 const TopoDS_Shape& Shape()const {
111 void SetBox2D(const Bnd_Box2d& aBox2D) {
115 const Bnd_Box2d& Box2D()const {
119 void SetIsHole(const Standard_Boolean bFlag) {
123 Standard_Boolean IsHole()const {
128 Standard_Boolean myIsHole;
129 TopoDS_Shape myShape;
133 typedef NCollection_IndexedDataMap
136 TColStd_MapIntegerHasher> BOPAlgo_IndexedDataMapOfIntegerShapeBox2D;
138 typedef NCollection_IndexedDataMap
141 TopTools_ShapeMapHasher> BOPCol_IndexedDataMapOfShapeShape;
143 //=======================================================================
146 //=======================================================================
147 BOPAlgo_BuilderFace::BOPAlgo_BuilderFace()
149 BOPAlgo_BuilderArea()
151 myOrientation=TopAbs_EXTERNAL;
153 //=======================================================================
156 //=======================================================================
157 BOPAlgo_BuilderFace::BOPAlgo_BuilderFace
158 (const Handle(NCollection_BaseAllocator)& theAllocator)
160 BOPAlgo_BuilderArea(theAllocator)
162 myOrientation=TopAbs_EXTERNAL;
164 //=======================================================================
167 //=======================================================================
168 BOPAlgo_BuilderFace::~BOPAlgo_BuilderFace()
171 //=======================================================================
174 //=======================================================================
175 void BOPAlgo_BuilderFace::SetFace(const TopoDS_Face& theFace)
177 myOrientation=theFace.Orientation();
179 myFace.Orientation(TopAbs_FORWARD);
181 //=======================================================================
182 //function : Orientation
184 //=======================================================================
185 TopAbs_Orientation BOPAlgo_BuilderFace::Orientation()const
187 return myOrientation;
189 //=======================================================================
192 //=======================================================================
193 const TopoDS_Face& BOPAlgo_BuilderFace::Face()const
197 //=======================================================================
198 //function : CheckData
200 //=======================================================================
201 void BOPAlgo_BuilderFace::CheckData()
205 if (myFace.IsNull()) {
206 myErrorStatus=12;// Null face generix
209 if (myContext.IsNull()) {
210 myContext = new IntTools_Context;
213 //=======================================================================
216 //=======================================================================
217 void BOPAlgo_BuilderFace::Perform()
228 PerformShapesToAvoid();
249 PerformInternalShapes();
254 //=======================================================================
255 //function :PerformShapesToAvoid
257 //=======================================================================
258 void BOPAlgo_BuilderFace::PerformShapesToAvoid()
260 Standard_Boolean bFound;
261 Standard_Integer i, iCnt, aNbV, aNbE;
262 BOPCol_IndexedDataMapOfShapeListOfShape aMVE;
263 BOPCol_ListIteratorOfListOfShape aIt;
265 myShapesToAvoid.Clear();
270 bFound=Standard_False;
274 aIt.Initialize (myShapes);
275 for (; aIt.More(); aIt.Next()) {
276 const TopoDS_Shape& aE=aIt.Value();
277 if (!myShapesToAvoid.Contains(aE)) {
278 BOPTools::MapShapesAndAncestors(aE, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
284 for (i=1; i<=aNbV; ++i) {
285 const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&aMVE.FindKey(i)));
287 BOPCol_ListOfShape& aLE=aMVE.ChangeFromKey(aV);
293 const TopoDS_Edge& aE1=(*(TopoDS_Edge *)(&aLE.First()));
295 if (BRep_Tool::Degenerated(aE1)) {
298 if (aV.Orientation()==TopAbs_INTERNAL) {
301 bFound=Standard_True;
302 myShapesToAvoid.Add(aE1);
305 const TopoDS_Edge& aE2=(*(TopoDS_Edge *)(&aLE.Last()));
306 if (aE2.IsSame(aE1)) {
307 TopoDS_Vertex aV1x, aV2x;
309 TopExp::Vertices(aE1, aV1x, aV2x);
310 if (aV1x.IsSame(aV2x)) {
313 bFound=Standard_True;
314 myShapesToAvoid.Add(aE1);
315 myShapesToAvoid.Add(aE2);
318 }// for (i=1; i<=aNbE; ++i) {
325 //printf(" EdgesToAvoid=%d, iCnt=%d\n", EdgesToAvoid.Extent(), iCnt);
327 //=======================================================================
328 //function : PerformLoops
330 //=======================================================================
331 void BOPAlgo_BuilderFace::PerformLoops()
335 Standard_Boolean bFlag;
336 Standard_Integer iErr, aNbEA;
337 BOPCol_ListIteratorOfListOfShape aIt;
338 BOPCol_MapIteratorOfMapOfOrientedShape aItM;
339 BOPCol_IndexedDataMapOfShapeListOfShape aVEMap;
340 BOPCol_MapOfOrientedShape aMAdded;
341 TopoDS_Iterator aItW;
343 BOPAlgo_WireEdgeSet aWES(myAllocator);
344 BOPAlgo_WireSplitter aWSp(myAllocator);
348 aWES.SetFace(myFace);
350 aIt.Initialize(myShapes);
351 for (; aIt.More(); aIt.Next()) {
352 const TopoDS_Shape& aE=aIt.Value();
353 if (!myShapesToAvoid.Contains(aE)) {
354 aWES.AddStartElement(aE);
359 aWSp.SetRunParallel(myRunParallel);
361 iErr=aWSp.ErrorStatus();
366 const BOPCol_ListOfShape& aLW=aWES.Shapes();
367 aIt.Initialize (aLW);
368 for (; aIt.More(); aIt.Next()) {
369 const TopoDS_Shape& aW=aIt.Value();
373 BOPCol_MapOfOrientedShape aMEP;
375 // a. collect all edges that are in loops
376 aIt.Initialize (myLoops);
377 for (; aIt.More(); aIt.Next()) {
378 const TopoDS_Shape& aW=aIt.Value();
380 for (; aItW.More(); aItW.Next()) {
381 const TopoDS_Shape& aE=aItW.Value();
386 // b. collect all edges that are to avoid
387 aItM.Initialize(myShapesToAvoid);
388 for (; aItM.More(); aItM.Next()) {
389 const TopoDS_Shape& aE=aItM.Key();
393 // c. add all edges that are not processed to myShapesToAvoid
394 aIt.Initialize (myShapes);
395 for (; aIt.More(); aIt.Next()) {
396 const TopoDS_Shape& aE=aIt.Value();
397 if (!aMEP.Contains(aE)) {
398 myShapesToAvoid.Add(aE);
403 myLoopsInternal.Clear();
405 aNbEA=myShapesToAvoid.Extent();
406 aItM.Initialize(myShapesToAvoid);
407 for (; aItM.More(); aItM.Next()) {
408 const TopoDS_Shape& aEE=aItM.Key();
409 BOPTools::MapShapesAndAncestors(aEE,
416 aItM.Initialize(myShapesToAvoid);
417 for (; aItM.More()&&bFlag; aItM.Next()) {
418 const TopoDS_Shape& aEE=aItM.Key();
419 if (!aMAdded.Add(aEE)) {
429 for (; aItW.More()&&bFlag; aItW.Next()) {
430 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aItW.Value()));
432 TopoDS_Iterator aItE(aE);
433 for (; aItE.More()&&bFlag; aItE.Next()) {
434 const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&aItE.Value()));
435 const BOPCol_ListOfShape& aLE=aVEMap.FindFromKey(aV);
437 for (; aIt.More()&&bFlag; aIt.Next()) {
438 const TopoDS_Shape& aEx=aIt.Value();
439 if (aMAdded.Add(aEx)) {
441 if(aMAdded.Extent()==aNbEA) {
445 }//for (; aIt.More(); aIt.Next()) {
446 }//for (; aItE.More(); aItE.Next()) {
447 }//for (; aItW.More(); aItW.Next()) {
448 myLoopsInternal.Append(aW);
449 }//for (; aItM.More(); aItM.Next()) {
451 //=======================================================================
452 //function : PerformAreas
454 //=======================================================================
455 void BOPAlgo_BuilderFace::PerformAreas()
457 Standard_Boolean bIsGrowth, bIsHole;
458 Standard_Integer k, aNbS, aNbHoles, aNbDMISB, m, aNbMSH, aNbInOutMap;
460 TopLoc_Location aLoc;
461 Handle(Geom_Surface) aS;
464 BOPCol_ListIteratorOfListOfInteger aItLI;
465 BOPCol_IndexedMapOfShape aMHE;
466 BOPCol_ListIteratorOfListOfShape aIt1;
467 BOPCol_IndexedDataMapOfShapeListOfShape aMSH;
468 BOPCol_IndexedDataMapOfShapeShape aInOutMap;
469 BOPAlgo_IndexedDataMapOfIntegerShapeBox2D aDMISB(100);
471 BOPCol_Box2DBndTreeSelector aSelector;
472 BOPCol_Box2DBndTree aBBTree;
473 NCollection_UBTreeFiller <Standard_Integer, Bnd_Box2d> aTreeFiller(aBBTree);
478 aTol=BRep_Tool::Tolerance(myFace);
479 aS=BRep_Tool::Surface(myFace, aLoc);
483 if (myLoops.IsEmpty()) {
484 if (myContext->IsInfiniteFace(myFace)) {
485 aBB.MakeFace(aFace, aS, aLoc, aTol);
486 if (BRep_Tool::NaturalRestriction(myFace)) {
487 aBB.NaturalRestriction(aFace, Standard_True);
489 myAreas.Append(aFace);
494 // 1. Growthes and Holes -> aDMISB: [Index/ShapeBox2D]
495 aIt1.Initialize(myLoops);
496 for (k=0 ; aIt1.More(); aIt1.Next(), ++k) {
499 const TopoDS_Shape& aWire=aIt1.Value();
501 aBB.MakeFace(aFace, aS, aLoc, aTol);
502 aBB.Add (aFace, aWire);
503 BRepTools::AddUVBounds(aFace, aBox2D);
505 bIsGrowth=IsGrowthWire(aWire, aMHE);
507 bIsHole=Standard_False;
510 // check if a wire is a hole
511 IntTools_FClass2d& aClsf=myContext->FClass2d(aFace);
512 aClsf.Init(aFace, aTol);
514 bIsHole=aClsf.IsHole();
516 BOPTools::MapShapes(aWire, TopAbs_EDGE, aMHE);
518 bIsHole=Standard_True;
521 bIsHole=Standard_False;
525 BOPAlgo_ShapeBox2D aSB2D;
527 aSB2D.SetShape(aFace);
528 aSB2D.SetBox2D(aBox2D);
529 aSB2D.SetIsHole(bIsHole);
531 aDMISB.Add(k, aSB2D);
532 }// for (k=0 ; aIt1.More(); aIt1.Next(), ++k) {
534 // 2. Prepare TreeFiller
535 aNbDMISB=aDMISB.Extent();
536 for (m=1; m<=aNbDMISB; ++m) {
538 const BOPAlgo_ShapeBox2D& aSB2D=aDMISB.FindFromIndex(m);
540 bIsHole=aSB2D.IsHole();
542 const Bnd_Box2d& aBox2D=aSB2D.Box2D();
543 aTreeFiller.Add(k, aBox2D);
548 // 3. Shake TreeFiller
551 // 4. Find outer growth shell that is most close
552 // to each hole shell
553 for (m=1; m<=aNbDMISB; ++m) {
554 const BOPAlgo_ShapeBox2D& aSB2D=aDMISB.FindFromIndex(m);
555 bIsHole=aSB2D.IsHole();
560 const Bnd_Box2d& aBox2DF=aSB2D.Box2D();
561 const TopoDS_Shape aF=aSB2D.Shape();
564 aSelector.SetBox(aBox2DF);
566 aNbS = aBBTree.Select(aSelector);
571 const BOPCol_ListOfInteger& aLI=aSelector.Indices();
573 aItLI.Initialize(aLI);
574 for (; aItLI.More(); aItLI.Next()) {
576 const BOPAlgo_ShapeBox2D& aSB2Dk=aDMISB.FindFromKey(k);
577 const TopoDS_Shape& aHole=aSB2Dk.Shape();
579 if (!IsInside(aHole, aF, myContext)){
583 if (aInOutMap.Contains(aHole)){
584 TopoDS_Shape& aF2=aInOutMap.ChangeFromKey(aHole);
585 if (IsInside(aF, aF2, myContext)) {
590 aInOutMap.Add(aHole, aF);
593 }// for (m=1; m<=aNbDMISB; ++m)
595 // 5.1 Map [Face/Holes] -> aMSH
596 aNbInOutMap=aInOutMap.Extent();
597 for (m=1; m<=aNbInOutMap; ++m) {
598 const TopoDS_Shape& aHole=aInOutMap.FindKey(m);
599 const TopoDS_Shape& aF=aInOutMap.FindFromIndex(m);
601 if (aMSH.Contains(aF)) {
602 BOPCol_ListOfShape& aLH=aMSH.ChangeFromKey(aF);
606 BOPCol_ListOfShape aLH;
612 // 5.2. Add unused holes to the original face
613 if (aNbHoles != aNbInOutMap) {
615 BRepBndLib::Add(myFace, aBoxF);
616 if (aBoxF.IsOpenXmin() || aBoxF.IsOpenXmax() ||
617 aBoxF.IsOpenYmin() || aBoxF.IsOpenYmax() ||
618 aBoxF.IsOpenZmin() || aBoxF.IsOpenZmax()) {
620 BOPCol_ListOfShape anUnUsedHoles;
621 for (m = 1; m <= aNbDMISB; ++m) {
622 const BOPAlgo_ShapeBox2D& aSB2D=aDMISB.FindFromIndex(m);
623 if (aSB2D.IsHole()) {
624 const TopoDS_Shape& aHole = aSB2D.Shape();
625 if (!aInOutMap.Contains(aHole)) {
626 anUnUsedHoles.Append(aHole);
631 if (anUnUsedHoles.Extent()) {
633 aBB.MakeFace(aFace, aS, aLoc, aTol);
634 aMSH.Add(aFace, anUnUsedHoles);
636 BOPAlgo_ShapeBox2D aSB2D;
638 aSB2D.SetShape(aFace);
639 aSB2D.SetIsHole(Standard_False);
641 aDMISB.Add(aNbDMISB, aSB2D);
647 // 6. Add aHoles to Faces
648 aNbMSH=aMSH.Extent();
649 for (m=1; m<=aNbMSH; ++m) {
650 TopoDS_Face aF=(*(TopoDS_Face *)(&aMSH.FindKey(m)));
651 const BOPCol_ListOfShape& aLH=aMSH.FindFromIndex(m);
653 aIt1.Initialize(aLH);
654 for (; aIt1.More(); aIt1.Next()) {
657 const TopoDS_Shape& aFHole=aIt1.Value();
658 GetWire(aFHole, aWHole);
659 aBB.Add (aF, aWHole);
663 aTol=BRep_Tool::Tolerance(aF);
664 IntTools_FClass2d& aClsf=myContext->FClass2d(aF);
665 aClsf.Init(aF, aTol);
669 // NB:These aNewFaces are draft faces that
670 // do not contain any internal shapes
671 for (m=1; m<=aNbDMISB; ++m) {
672 const BOPAlgo_ShapeBox2D& aSB2D=aDMISB.FindFromIndex(m);
673 bIsHole=aSB2D.IsHole();
675 const TopoDS_Shape aF=aSB2D.Shape();
680 //=======================================================================
683 //=======================================================================
684 void GetWire(const TopoDS_Shape& aF, TopoDS_Shape& aW)
690 for (; aIt.More(); aIt.Next()) {
694 //=======================================================================
695 //function : PerformInternalShapes
697 //=======================================================================
698 void BOPAlgo_BuilderFace::PerformInternalShapes()
702 Standard_Integer aNbWI=myLoopsInternal.Extent();
703 if (!aNbWI) {// nothing to do
707 //Standard_Real aTol;
709 BOPCol_ListIteratorOfListOfShape aIt1, aIt2;
711 BOPCol_MapOfShape aME, aMEP;
712 BOPCol_MapIteratorOfMapOfShape aItME;
713 BOPCol_IndexedDataMapOfShapeListOfShape aMVE;
714 BOPCol_ListOfShape aLSI;
716 // 1. All internal edges
717 aIt1.Initialize(myLoopsInternal);
718 for (; aIt1.More(); aIt1.Next()) {
719 const TopoDS_Shape& aWire=aIt1.Value();
720 aIt.Initialize(aWire);
721 for (; aIt.More(); aIt.Next()) {
722 const TopoDS_Shape& aE=aIt.Value();
729 aIt2.Initialize(myAreas);
730 for ( ; aIt2.More(); aIt2.Next()) {
731 TopoDS_Face& aF=(*(TopoDS_Face *)(&aIt2.Value()));
734 BOPTools::MapShapesAndAncestors(aF, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
736 // 2.1 Separate faces to process aMEP
738 aItME.Initialize(aME);
739 for (; aItME.More(); aItME.Next()) {
740 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aItME.Key()));
741 if (IsInside(aE, aF, myContext)) {
746 // 2.2 Make Internal Wires
748 MakeInternalWires(aMEP, aLSI);
750 // 2.3 Add them to aF
751 aIt1.Initialize(aLSI);
752 for (; aIt1.More(); aIt1.Next()) {
753 const TopoDS_Shape& aSI=aIt1.Value();
757 // 2.4 Remove faces aMFP from aMF
758 aItME.Initialize(aMEP);
759 for (; aItME.More(); aItME.Next()) {
760 const TopoDS_Shape& aE=aItME.Key();
768 } //for ( ; aIt2.More(); aIt2.Next()) {
770 //=======================================================================
771 //function : MakeInternalWires
773 //=======================================================================
774 void MakeInternalWires(const BOPCol_MapOfShape& theME,
775 BOPCol_ListOfShape& theWires)
777 BOPCol_MapIteratorOfMapOfShape aItM;
778 BOPCol_MapOfShape aAddedMap;
779 BOPCol_ListIteratorOfListOfShape aItE;
780 BOPCol_IndexedDataMapOfShapeListOfShape aMVE;
783 aItM.Initialize(theME);
784 for (; aItM.More(); aItM.Next()) {
785 const TopoDS_Shape& aE=aItM.Key();
786 BOPTools::MapShapesAndAncestors(aE, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
789 aItM.Initialize(theME);
790 for (; aItM.More(); aItM.Next()) {
791 TopoDS_Shape aEE=aItM.Key();
792 if (!aAddedMap.Add(aEE)) {
799 aEE.Orientation(TopAbs_INTERNAL);
802 TopoDS_Iterator aItAdded (aW);
803 for (; aItAdded.More(); aItAdded.Next()) {
804 const TopoDS_Shape& aE =aItAdded.Value();
806 TopExp_Explorer aExp(aE, TopAbs_VERTEX);
807 for (; aExp.More(); aExp.Next()) {
808 const TopoDS_Shape& aV =aExp.Current();
809 const BOPCol_ListOfShape& aLE=aMVE.FindFromKey(aV);
810 aItE.Initialize(aLE);
811 for (; aItE.More(); aItE.Next()) {
812 TopoDS_Shape aEL=aItE.Value();
813 if (aAddedMap.Add(aEL)){
814 aEL.Orientation(TopAbs_INTERNAL);
823 //=======================================================================
824 //function : IsInside
826 //=======================================================================
827 Standard_Boolean IsInside(const TopoDS_Shape& theHole,
828 const TopoDS_Shape& theF2,
829 Handle(IntTools_Context)& theContext)
831 Standard_Boolean bRet;
832 Standard_Real aT, aU, aV;
835 TopExp_Explorer aExp;
836 BOPCol_IndexedMapOfShape aME2;
840 aState=TopAbs_UNKNOWN;
841 const TopoDS_Face& aF2=(*(TopoDS_Face *)(&theF2));
843 BOPTools::MapShapes(aF2, TopAbs_EDGE, aME2);//AA
845 aExp.Init(theHole, TopAbs_EDGE);
847 const TopoDS_Edge& aE =(*(TopoDS_Edge *)(&aExp.Current()));
848 if (aME2.Contains(aE)) {
851 if (!BRep_Tool::Degenerated(aE)) {
853 aT=BOPTools_AlgoTools2D::IntermediatePoint(aE);
854 BOPTools_AlgoTools2D::PointOnSurface(aE, aF2, aT, aU, aV);
855 aP2D.SetCoord(aU, aV);
857 IntTools_FClass2d& aClsf=theContext->FClass2d(aF2);
858 aState=aClsf.Perform(aP2D);
859 bRet=(aState==TopAbs_IN);
866 //=======================================================================
867 //function : IsGrowthWire
869 //=======================================================================
870 Standard_Boolean IsGrowthWire(const TopoDS_Shape& theWire,
871 const BOPCol_IndexedMapOfShape& theMHE)
873 Standard_Boolean bRet;
877 if (theMHE.Extent()) {
878 aIt.Initialize(theWire);
879 for(; aIt.More(); aIt.Next()) {
880 const TopoDS_Shape& aE=aIt.Value();
881 if (theMHE.Contains(aE)) {
889 //BRepTools::Write(aFF, "ff");
893 // 12 - Null face generix