Salome HOME
BugID IPAL9186: Added a call to method initGeomGen
[modules/geom.git] / src / GEOMAlgo / BlockFix_CheckTool.cxx
1 // File:      BlockFix_CheckTool.cxx
2 // Created:   17.12.04 11:15:25
3 // Author:    Sergey KUUL
4 // Copyright: Open CASCADE SA 2004
5
6 #include <BlockFix_CheckTool.ixx>
7
8 #include <BRep_Tool.hxx>
9 #include <BlockFix_UnionEdges.hxx>
10 #include <BlockFix_UnionFaces.hxx>
11 #include <TopExp.hxx>
12 #include <TopExp_Explorer.hxx>
13 #include <TopoDS.hxx>
14 #include <TopoDS_Edge.hxx>
15 #include <TopoDS_Face.hxx>
16 #include <TopoDS_Solid.hxx>
17 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
18 #include <TopTools_MapOfShape.hxx>
19 #include <TopTools_ListOfShape.hxx>
20 #include <TopTools_ListIteratorOfListOfShape.hxx>
21
22
23 //=======================================================================
24 //function : BlockFix_CheckTool()
25 //purpose  : Constructor
26 //=======================================================================
27
28 BlockFix_CheckTool::BlockFix_CheckTool( )
29 {
30   myHasCheck = Standard_False;
31   myPossibleBlocks.Clear();
32 }
33
34
35 //=======================================================================
36 //function : SetShape
37 //purpose  : 
38 //=======================================================================
39
40 void BlockFix_CheckTool::SetShape(const TopoDS_Shape& aShape)
41 {
42   myHasCheck = Standard_False;
43   myShape = aShape;
44   myPossibleBlocks.Clear();
45 }
46
47
48 //=======================================================================
49 //function : Perform
50 //purpose  : 
51 //=======================================================================
52
53 void BlockFix_CheckTool::Perform() 
54 {
55   myNbSolids=0;
56   myNbBlocks=0;
57   myNbDegen=0;
58   myNbUF=0;
59   myNbUE=0;
60   myNbUFUE=0;
61   TopExp_Explorer exps;
62   for(exps.Init(myShape, TopAbs_SOLID); exps.More(); exps.Next()) {
63     TopoDS_Solid aSolid = TopoDS::Solid(exps.Current());
64     myNbSolids++;
65     Standard_Boolean IsBlock=Standard_True;
66     Standard_Boolean MayBeUF=Standard_False;
67     Standard_Boolean MayBeUE=Standard_False;
68     Standard_Integer nf=0;
69     TopExp_Explorer expf;
70     for(expf.Init(aSolid, TopAbs_FACE); expf.More(); expf.Next()) nf++;
71
72     if(nf<6) {
73       IsBlock=Standard_False;
74     }
75     else if(nf>6) {
76       IsBlock=Standard_False;
77       // check faces unification
78       TopTools_SequenceOfShape faces;
79       for( expf.Init(aSolid, TopAbs_FACE); expf.More(); expf.Next()) {
80         TopoDS_Face aFace = TopoDS::Face(expf.Current());
81         faces.Append(aFace);
82       }
83       Standard_Boolean HasFacesForUnification = Standard_False;
84       for(Standard_Integer i=1; i<faces.Length() && !HasFacesForUnification; i++) {
85         TopoDS_Face F1 = TopoDS::Face(faces.Value(i));
86         TopTools_MapOfShape Edges;
87         for(TopExp_Explorer expe(F1,TopAbs_EDGE); expe.More(); expe.Next())
88           Edges.Add(expe.Current().Oriented(TopAbs_FORWARD));
89         TopLoc_Location L1;
90         Handle(Geom_Surface) S1 = BRep_Tool::Surface(F1,L1);
91         for(Standard_Integer j=i+1; j<=faces.Length() && !HasFacesForUnification; j++) {
92           TopoDS_Face F2 = TopoDS::Face(faces.Value(j));
93           TopLoc_Location L2;
94           Handle(Geom_Surface) S2 = BRep_Tool::Surface(F2,L2);
95           if( S1==S2 && L1==L2 ) {
96             // faces have equal based surface
97             // now check common edge
98             for(TopExp_Explorer expe2(F2,TopAbs_EDGE); expe2.More(); expe2.Next()) {
99               if(Edges.Contains(expe2.Current().Oriented(TopAbs_FORWARD))) {
100                 HasFacesForUnification = Standard_True;
101                 break;
102               }
103             }
104           }
105         }
106       }
107       if(HasFacesForUnification) {
108         MayBeUF=Standard_True;
109       }
110     }
111
112     Standard_Integer nbe=0;
113     TopTools_MapOfShape DegenEdges;
114     TopExp_Explorer expe;
115     for(expe.Init(aSolid, TopAbs_EDGE); expe.More(); expe.Next()) {
116       TopoDS_Edge E = TopoDS::Edge(expe.Current());
117       if(BRep_Tool::Degenerated(E)) {
118         if(!DegenEdges.Contains(E)) {
119           DegenEdges.Add(E);
120         }
121       }
122       else {
123         nbe++;
124       }
125     }
126     if( nbe==24 && DegenEdges.Extent()>0 ) {
127       IsBlock=Standard_False;
128       myNbDegen++;
129       myPossibleBlocks.Append(aSolid);
130       continue;
131     }
132     if(nbe<24)
133       IsBlock=Standard_False;
134     if(nbe>24) {
135       IsBlock=Standard_False;
136       // check edges unification
137       // creating map of edge faces
138       TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces;
139       TopExp::MapShapesAndAncestors(aSolid, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces);
140       for(expf.Init(aSolid, TopAbs_FACE); expf.More(); expf.Next()) {
141         TopoDS_Face aFace = TopoDS::Face(expf.Current());
142         TopTools_IndexedDataMapOfShapeListOfShape aMapFacesEdges;
143         for(expe.Init(aFace,TopAbs_EDGE); expe.More(); expe.Next()) {
144           TopoDS_Edge edge = TopoDS::Edge(expe.Current());
145           if(!aMapEdgeFaces.Contains(edge)) continue;
146           const TopTools_ListOfShape& aList = aMapEdgeFaces.FindFromKey(edge);
147           TopTools_ListIteratorOfListOfShape anIter(aList);
148           for( ; anIter.More(); anIter.Next()) {
149             TopoDS_Face face = TopoDS::Face(anIter.Value());
150             if(face.IsSame(aFace)) continue;
151             if(aMapFacesEdges.Contains(face)) {
152               aMapFacesEdges.ChangeFromKey(face).Append(edge);
153             }
154             else {
155               TopTools_ListOfShape ListEdges;
156               ListEdges.Append(edge);
157               aMapFacesEdges.Add(face,ListEdges);
158             }
159           }
160         }
161         Standard_Integer i=1;
162         for(; i<=aMapFacesEdges.Extent(); i++) {
163           const TopTools_ListOfShape& ListEdges = aMapFacesEdges.FindFromIndex(i);
164           if(ListEdges.Extent()>1) break;
165         }
166         if(i<=aMapFacesEdges.Extent()) {
167           MayBeUE=Standard_True;
168           break;
169         }
170       }
171     }
172
173     if(IsBlock) 
174       myNbBlocks++;
175     else {
176       if(MayBeUF) {
177         myPossibleBlocks.Append(aSolid);
178         if(MayBeUE)
179           myNbUFUE++;
180         else
181           myNbUF++;
182       }
183       else if(MayBeUE) {
184         myNbUE++;
185         myPossibleBlocks.Append(aSolid);
186       }
187     }
188
189   }
190
191   myHasCheck = Standard_True;
192 }
193
194
195 //=======================================================================
196 //function : NbPossibleBlocks
197 //purpose  : 
198 //=======================================================================
199
200 Standard_Integer BlockFix_CheckTool::NbPossibleBlocks() const
201 {
202   return myPossibleBlocks.Length();
203 }
204
205
206 //=======================================================================
207 //function : PossibleBlock
208 //purpose  : 
209 //=======================================================================
210
211 TopoDS_Shape BlockFix_CheckTool::PossibleBlock(const Standard_Integer num) const
212 {
213   TopoDS_Shape res;
214   if( num>0 && num<=myPossibleBlocks.Length() ) 
215     res = myPossibleBlocks.Value(num);
216   return res;
217 }
218
219
220 //=======================================================================
221 //function : DumpCheckResult
222 //purpose  : 
223 //=======================================================================
224
225 void BlockFix_CheckTool::DumpCheckResult(Standard_OStream& S) const
226 {
227   if(!myHasCheck)
228     S<<"Check not performed!"<<endl;
229   else {
230     S<<"dump results of check:"<<endl;
231     S<<"  total number of solids = "<<myNbSolids<<endl;
232     S<<"  including: number of good blocks = "<<myNbBlocks<<endl;
233     S<<"             number of possible blocks = "<<NbPossibleBlocks()<<endl;
234     S<<"             including: need remove degenerative = "<<myNbDegen<<endl;
235     S<<"                        need unionfaces = "<<myNbUF<<endl;
236     S<<"                        need unionedges = "<<myNbUE<<endl;
237     S<<"                        need both unionfaces and unionedges = "<<myNbUFUE<<endl;
238     Standard_Integer nbtmp = myNbSolids - myNbBlocks - NbPossibleBlocks();
239     S<<"             number of impossible blocks = "<<nbtmp<<endl;
240   }
241 }