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