0031642: Visualization - crash in Graphic3d_Structure::SetVisual() on redisplaying...
[occt.git] / src / ShapeAnalysis / ShapeAnalysis_Shell.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 //szv#4 S4163
15
16 #include <BRep_Builder.hxx>
17 #include <BRep_Tool.hxx>
18 #include <ShapeAnalysis_Shell.hxx>
19 #include <TopExp_Explorer.hxx>
20 #include <TopoDS.hxx>
21 #include <TopoDS_Compound.hxx>
22 #include <TopoDS_Edge.hxx>
23 #include <TopoDS_Iterator.hxx>
24 #include <TopoDS_Shape.hxx>
25
26 //=======================================================================
27 //function : Clear
28 //purpose  : 
29 //=======================================================================
30 void ShapeAnalysis_Shell::Clear() 
31 {
32   myShells.Clear();
33   myBad.Clear();
34   myFree.Clear();
35   myConex = Standard_False;
36 }
37
38 //=======================================================================
39 //function : LoadShells
40 //purpose  : 
41 //=======================================================================
42
43  void ShapeAnalysis_Shell::LoadShells(const TopoDS_Shape& shape) 
44 {
45   if (shape.IsNull()) return;
46
47   if (shape.ShapeType() == TopAbs_SHELL) myShells.Add (shape); //szv#4:S4163:12Mar99 i =
48   else {
49     for (TopExp_Explorer exs (shape,TopAbs_SHELL); exs.More(); exs.Next()) {
50       TopoDS_Shape sh = exs.Current();
51       myShells.Add (sh); //szv#4:S4163:12Mar99 i =
52     }
53   }
54 }
55
56
57 //  CheckOrientedShells : alimente BadEdges et FreeEdges
58 //  BadEdges : edges presentes plus d une fois dans une meme orientation
59 //  FreeEdges : edges presentes une seule fois
60 //  On utilise pour cela une fonction auxiliaire : CheckEdges
61 //    Qui alimente 2 maps auxiliaires : les edges directes et les inverses
62
63 static  Standard_Boolean CheckEdges(const TopoDS_Shape& shape,
64                                     TopTools_IndexedMapOfShape& bads,
65                                     TopTools_IndexedMapOfShape& dirs,
66                                     TopTools_IndexedMapOfShape& revs,
67                                     TopTools_IndexedMapOfShape& ints)
68 {
69   Standard_Boolean res = Standard_False;
70
71   if (shape.ShapeType() != TopAbs_EDGE) {
72     for (TopoDS_Iterator it(shape); it.More(); it.Next()) {
73       if (CheckEdges (it.Value(),bads,dirs,revs,ints)) res = Standard_True;
74     }
75   }
76   else {
77     TopoDS_Edge E = TopoDS::Edge(shape);
78     if (BRep_Tool::Degenerated(E)) return Standard_False;
79
80     if (shape.Orientation() == TopAbs_FORWARD) {
81       //szv#4:S4163:12Mar99 optimized
82       if (dirs.FindIndex (shape) == 0) dirs.Add (shape);
83       else { bads.Add (shape); res = Standard_True; }
84     }
85     if (shape.Orientation() == TopAbs_REVERSED) {
86       //szv#4:S4163:12Mar99 optimized
87       if (revs.FindIndex (shape) == 0) revs.Add (shape);
88       else { bads.Add (shape); res = Standard_True; }
89     }
90     if (shape.Orientation() == TopAbs_INTERNAL) {
91       if (ints.FindIndex (shape) == 0) ints.Add (shape);
92       //else { bads.Add (shape); res = Standard_True; }
93     }
94   }
95
96   return res;
97 }
98
99 //=======================================================================
100 //function : CheckOrientedShells
101 //purpose  : 
102 //=======================================================================
103
104 Standard_Boolean ShapeAnalysis_Shell::CheckOrientedShells(const TopoDS_Shape& shape,
105                                                           const Standard_Boolean alsofree,
106                                                           const Standard_Boolean checkinternaledges)
107 {
108   myConex = Standard_False;
109   if (shape.IsNull()) return Standard_False;
110   Standard_Boolean res = Standard_False;
111
112   TopTools_IndexedMapOfShape dirs, revs, ints;
113   for (TopExp_Explorer exs(shape,TopAbs_SHELL); exs.More(); exs.Next()) {
114     TopoDS_Shape sh = exs.Current();
115     //szv#4:S4163:12Mar99 optimized
116     if (CheckEdges (sh,myBad,dirs,revs,ints))
117       if (myShells.Add (sh)) res = Standard_True;
118   }
119
120   //  Resteraient a faire les FreeEdges
121   if (!alsofree) return res;
122
123   //  Free Edges . Ce sont les edges d une map pas dans l autre
124   //  et lycee de Versailles  (les maps dirs et revs)
125   Standard_Integer nb = dirs.Extent();
126   Standard_Integer i; // svv Jan11 2000 : porting on DEC
127   for (i = 1; i <= nb; i ++) {
128     TopoDS_Shape sh = dirs.FindKey (i);
129     if (!myBad.Contains(sh)) {
130       if (!revs.Contains(sh)) {
131         if(checkinternaledges) {
132           if (!ints.Contains(sh)) {
133             myFree.Add (sh);
134           }
135           else myConex = Standard_True;
136         }
137         else {
138           myFree.Add (sh);
139         }
140       }
141       else myConex = Standard_True;
142     }
143     else myConex = Standard_True;
144   }
145
146   nb = revs.Extent();
147   for (i = 1; i <= nb; i ++) {
148     TopoDS_Shape sh = revs.FindKey (i);
149     if (!myBad.Contains(sh)) {
150       if (!dirs.Contains(sh)) {
151         if(checkinternaledges) {
152           if (!ints.Contains(sh)) {
153             myFree.Add (sh);
154           }
155           else myConex = Standard_True;
156         }
157         else {
158           myFree.Add (sh);
159         }
160       }
161       else myConex = Standard_True;
162     }
163     else myConex = Standard_True;
164   }
165
166   return res;
167 }
168
169 //=======================================================================
170 //function : IsLoaded
171 //purpose  : 
172 //=======================================================================
173
174  Standard_Boolean ShapeAnalysis_Shell::IsLoaded(const TopoDS_Shape& shape) const
175 {
176   if (shape.IsNull()) return Standard_False;
177   return myShells.Contains (shape);
178 }
179
180 //=======================================================================
181 //function : NbLoaded
182 //purpose  : 
183 //=======================================================================
184
185  Standard_Integer ShapeAnalysis_Shell::NbLoaded() const
186 {
187   return myShells.Extent();
188 }
189
190 //=======================================================================
191 //function : Loaded
192 //purpose  : 
193 //=======================================================================
194
195  TopoDS_Shape ShapeAnalysis_Shell::Loaded(const Standard_Integer num) const
196 {
197   return myShells.FindKey (num);
198 }
199
200 //=======================================================================
201 //function : HasBadEdges
202 //purpose  : 
203 //=======================================================================
204
205  Standard_Boolean ShapeAnalysis_Shell::HasBadEdges() const
206 {
207   return (myBad.Extent() > 0);
208 }
209
210 //=======================================================================
211 //function : BadEdges
212 //purpose  : 
213 //=======================================================================
214
215  TopoDS_Compound ShapeAnalysis_Shell::BadEdges() const
216 {
217   TopoDS_Compound C;
218   BRep_Builder B;
219   B.MakeCompound (C);
220   Standard_Integer n = myBad.Extent();
221   for (Standard_Integer i = 1; i <= n; i ++)  B.Add (C,myBad.FindKey(i));
222   return C;
223 }
224
225 //=======================================================================
226 //function : HasFreeEdges
227 //purpose  : 
228 //=======================================================================
229
230  Standard_Boolean ShapeAnalysis_Shell::HasFreeEdges() const
231 {
232   return (myFree.Extent() > 0);
233 }
234
235 //=======================================================================
236 //function : FreeEdges
237 //purpose  : 
238 //=======================================================================
239
240  TopoDS_Compound ShapeAnalysis_Shell::FreeEdges() const
241 {
242   TopoDS_Compound C;
243   BRep_Builder B;
244   B.MakeCompound (C);
245   Standard_Integer n = myFree.Extent();
246   for (Standard_Integer i = 1; i <= n; i ++)  B.Add (C,myFree.FindKey(i));
247   return C;
248 }
249
250 //=======================================================================
251 //function : HasConnectedEdges
252 //purpose  : 
253 //=======================================================================
254
255  Standard_Boolean ShapeAnalysis_Shell::HasConnectedEdges() const
256 {
257   return myConex;
258 }