Salome HOME
Avoid linking to the native omniORB
[modules/geom.git] / src / GEOMAlgo / BlockFix_CheckTool.cxx
1 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 // 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either 
7 // version 2.1 of the License.
8 // 
9 // This library is distributed in the hope that it will be useful 
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
12 // Lesser General Public License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public  
15 // License along with this library; if not, write to the Free Software 
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 //
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 //
20 // File:      BlockFix_CheckTool.cxx
21 // Created:   17.12.04 11:15:25
22 // Author:    Sergey KUUL
23 // Copyright: Open CASCADE SA 2004
24
25 #include <BlockFix_CheckTool.ixx>
26
27 #include <BRep_Tool.hxx>
28 #include <BlockFix_UnionEdges.hxx>
29 #include <BlockFix_UnionFaces.hxx>
30 #include <TopExp.hxx>
31 #include <TopExp_Explorer.hxx>
32 #include <TopoDS.hxx>
33 #include <TopoDS_Edge.hxx>
34 #include <TopoDS_Face.hxx>
35 #include <TopoDS_Solid.hxx>
36 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
37 #include <TopTools_MapOfShape.hxx>
38 #include <TopTools_ListOfShape.hxx>
39 #include <TopTools_ListIteratorOfListOfShape.hxx>
40
41
42 //=======================================================================
43 //function : BlockFix_CheckTool()
44 //purpose  : Constructor
45 //=======================================================================
46
47 BlockFix_CheckTool::BlockFix_CheckTool( )
48 {
49   myHasCheck = Standard_False;
50   myPossibleBlocks.Clear();
51 }
52
53
54 //=======================================================================
55 //function : SetShape
56 //purpose  : 
57 //=======================================================================
58
59 void BlockFix_CheckTool::SetShape(const TopoDS_Shape& aShape)
60 {
61   myHasCheck = Standard_False;
62   myShape = aShape;
63   myPossibleBlocks.Clear();
64 }
65
66
67 //=======================================================================
68 //function : Perform
69 //purpose  : 
70 //=======================================================================
71
72 void BlockFix_CheckTool::Perform() 
73 {
74   myNbSolids=0;
75   myNbBlocks=0;
76   myNbDegen=0;
77   myNbUF=0;
78   myNbUE=0;
79   myNbUFUE=0;
80   TopExp_Explorer exps;
81   for(exps.Init(myShape, TopAbs_SOLID); exps.More(); exps.Next()) {
82     TopoDS_Solid aSolid = TopoDS::Solid(exps.Current());
83     myNbSolids++;
84     Standard_Boolean IsBlock=Standard_True;
85     Standard_Boolean MayBeUF=Standard_False;
86     Standard_Boolean MayBeUE=Standard_False;
87     Standard_Integer nf=0;
88     TopExp_Explorer expf;
89     for(expf.Init(aSolid, TopAbs_FACE); expf.More(); expf.Next()) nf++;
90
91     if(nf<6) {
92       IsBlock=Standard_False;
93     }
94     else if(nf>6) {
95       IsBlock=Standard_False;
96       // check faces unification
97       TopTools_SequenceOfShape faces;
98       for( expf.Init(aSolid, TopAbs_FACE); expf.More(); expf.Next()) {
99         TopoDS_Face aFace = TopoDS::Face(expf.Current());
100         faces.Append(aFace);
101       }
102       Standard_Boolean HasFacesForUnification = Standard_False;
103       for(Standard_Integer i=1; i<faces.Length() && !HasFacesForUnification; i++) {
104         TopoDS_Face F1 = TopoDS::Face(faces.Value(i));
105         TopTools_MapOfShape Edges;
106         for(TopExp_Explorer expe(F1,TopAbs_EDGE); expe.More(); expe.Next())
107           Edges.Add(expe.Current().Oriented(TopAbs_FORWARD));
108         TopLoc_Location L1;
109         Handle(Geom_Surface) S1 = BRep_Tool::Surface(F1,L1);
110         for(Standard_Integer j=i+1; j<=faces.Length() && !HasFacesForUnification; j++) {
111           TopoDS_Face F2 = TopoDS::Face(faces.Value(j));
112           TopLoc_Location L2;
113           Handle(Geom_Surface) S2 = BRep_Tool::Surface(F2,L2);
114           if( S1==S2 && L1==L2 ) {
115             // faces have equal based surface
116             // now check common edge
117             for(TopExp_Explorer expe2(F2,TopAbs_EDGE); expe2.More(); expe2.Next()) {
118               if(Edges.Contains(expe2.Current().Oriented(TopAbs_FORWARD))) {
119                 HasFacesForUnification = Standard_True;
120                 break;
121               }
122             }
123           }
124         }
125       }
126       if(HasFacesForUnification) {
127         MayBeUF=Standard_True;
128       }
129     }
130
131     Standard_Integer nbe=0;
132     TopTools_MapOfShape DegenEdges;
133     TopExp_Explorer expe;
134     for(expe.Init(aSolid, TopAbs_EDGE); expe.More(); expe.Next()) {
135       TopoDS_Edge E = TopoDS::Edge(expe.Current());
136       if(BRep_Tool::Degenerated(E)) {
137         if(!DegenEdges.Contains(E)) {
138           DegenEdges.Add(E);
139         }
140       }
141       else {
142         nbe++;
143       }
144     }
145     if( nbe==24 && DegenEdges.Extent()>0 ) {
146       IsBlock=Standard_False;
147       myNbDegen++;
148       myPossibleBlocks.Append(aSolid);
149       continue;
150     }
151     if(nbe<24)
152       IsBlock=Standard_False;
153     if(nbe>24) {
154       IsBlock=Standard_False;
155       // check edges unification
156       // creating map of edge faces
157       TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces;
158       TopExp::MapShapesAndAncestors(aSolid, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces);
159       for(expf.Init(aSolid, TopAbs_FACE); expf.More(); expf.Next()) {
160         TopoDS_Face aFace = TopoDS::Face(expf.Current());
161         TopTools_IndexedDataMapOfShapeListOfShape aMapFacesEdges;
162         for(expe.Init(aFace,TopAbs_EDGE); expe.More(); expe.Next()) {
163           TopoDS_Edge edge = TopoDS::Edge(expe.Current());
164           if(!aMapEdgeFaces.Contains(edge)) continue;
165           const TopTools_ListOfShape& aList = aMapEdgeFaces.FindFromKey(edge);
166           TopTools_ListIteratorOfListOfShape anIter(aList);
167           for( ; anIter.More(); anIter.Next()) {
168             TopoDS_Face face = TopoDS::Face(anIter.Value());
169             if(face.IsSame(aFace)) continue;
170             if(aMapFacesEdges.Contains(face)) {
171               aMapFacesEdges.ChangeFromKey(face).Append(edge);
172             }
173             else {
174               TopTools_ListOfShape ListEdges;
175               ListEdges.Append(edge);
176               aMapFacesEdges.Add(face,ListEdges);
177             }
178           }
179         }
180         Standard_Integer i=1;
181         for(; i<=aMapFacesEdges.Extent(); i++) {
182           const TopTools_ListOfShape& ListEdges = aMapFacesEdges.FindFromIndex(i);
183           if(ListEdges.Extent()>1) break;
184         }
185         if(i<=aMapFacesEdges.Extent()) {
186           MayBeUE=Standard_True;
187           break;
188         }
189       }
190     }
191
192     if(IsBlock) 
193       myNbBlocks++;
194     else {
195       if(MayBeUF) {
196         myPossibleBlocks.Append(aSolid);
197         if(MayBeUE)
198           myNbUFUE++;
199         else
200           myNbUF++;
201       }
202       else if(MayBeUE) {
203         myNbUE++;
204         myPossibleBlocks.Append(aSolid);
205       }
206     }
207
208   }
209
210   myHasCheck = Standard_True;
211 }
212
213
214 //=======================================================================
215 //function : NbPossibleBlocks
216 //purpose  : 
217 //=======================================================================
218
219 Standard_Integer BlockFix_CheckTool::NbPossibleBlocks() const
220 {
221   return myPossibleBlocks.Length();
222 }
223
224
225 //=======================================================================
226 //function : PossibleBlock
227 //purpose  : 
228 //=======================================================================
229
230 TopoDS_Shape BlockFix_CheckTool::PossibleBlock(const Standard_Integer num) const
231 {
232   TopoDS_Shape res;
233   if( num>0 && num<=myPossibleBlocks.Length() ) 
234     res = myPossibleBlocks.Value(num);
235   return res;
236 }
237
238
239 //=======================================================================
240 //function : DumpCheckResult
241 //purpose  : 
242 //=======================================================================
243
244 void BlockFix_CheckTool::DumpCheckResult(Standard_OStream& S) const
245 {
246   if(!myHasCheck)
247     S<<"Check not performed!"<<endl;
248   else {
249     S<<"dump results of check:"<<endl;
250     S<<"  total number of solids = "<<myNbSolids<<endl;
251     S<<"  including: number of good blocks = "<<myNbBlocks<<endl;
252     S<<"             number of possible blocks = "<<NbPossibleBlocks()<<endl;
253     S<<"             including: need remove degenerative = "<<myNbDegen<<endl;
254     S<<"                        need unionfaces = "<<myNbUF<<endl;
255     S<<"                        need unionedges = "<<myNbUE<<endl;
256     S<<"                        need both unionfaces and unionedges = "<<myNbUFUE<<endl;
257     Standard_Integer nbtmp = myNbSolids - myNbBlocks - NbPossibleBlocks();
258     S<<"             number of impossible blocks = "<<nbtmp<<endl;
259   }
260 }