0024043: Performance improvements: Modeling Algorithms
[occt.git] / src / ShapeAnalysis / ShapeAnalysis_Shell.cxx
1 // Copyright (c) 1999-2012 OPEN CASCADE SAS
2 //
3 // The content of this file is subject to the Open CASCADE Technology Public
4 // License Version 6.5 (the "License"). You may not use the content of this file
5 // except in compliance with the License. Please obtain a copy of the License
6 // at http://www.opencascade.org and read it completely before using this file.
7 //
8 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
9 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
10 //
11 // The Original Code and all software distributed under the License is
12 // distributed on an "AS IS" basis, without warranty of any kind, and the
13 // Initial Developer hereby disclaims all such warranties, including without
14 // limitation, any warranties of merchantability, fitness for a particular
15 // purpose or non-infringement. Please see the License for the specific terms
16 // and conditions governing the rights and limitations under the License.
17
18 //szv#4 S4163
19 #include <ShapeAnalysis_Shell.ixx>
20
21 #include <BRep_Builder.hxx>
22 #include <BRep_Tool.hxx>
23
24 #include <TopoDS.hxx>
25 #include <TopoDS_Edge.hxx>
26 #include <TopoDS_Iterator.hxx>
27 #include <TopExp_Explorer.hxx>
28
29 //=======================================================================
30 //function : Clear
31 //purpose  : 
32 //=======================================================================
33
34 void ShapeAnalysis_Shell::Clear() 
35 {
36   myShells.Clear();
37   myBad.Clear();
38   myFree.Clear();
39   myConex = Standard_False;
40 }
41
42 //=======================================================================
43 //function : LoadShells
44 //purpose  : 
45 //=======================================================================
46
47  void ShapeAnalysis_Shell::LoadShells(const TopoDS_Shape& shape) 
48 {
49   if (shape.IsNull()) return;
50
51   if (shape.ShapeType() == TopAbs_SHELL) myShells.Add (shape); //szv#4:S4163:12Mar99 i =
52   else {
53     for (TopExp_Explorer exs (shape,TopAbs_SHELL); exs.More(); exs.Next()) {
54       TopoDS_Shape sh = exs.Current();
55       myShells.Add (sh); //szv#4:S4163:12Mar99 i =
56     }
57   }
58 }
59
60
61 //  CheckOrientedShells : alimente BadEdges et FreeEdges
62 //  BadEdges : edges presentes plus d une fois dans une meme orientation
63 //  FreeEdges : edges presentes une seule fois
64 //  On utilise pour cela une fonction auxiliaire : CheckEdges
65 //    Qui alimente 2 maps auxiliaires : les edges directes et les inverses
66
67 static  Standard_Boolean CheckEdges(const TopoDS_Shape& shape,
68                                     TopTools_IndexedMapOfShape& bads,
69                                     TopTools_IndexedMapOfShape& dirs,
70                                     TopTools_IndexedMapOfShape& revs,
71                                     TopTools_IndexedMapOfShape& ints)
72 {
73   Standard_Boolean res = Standard_False;
74
75   if (shape.ShapeType() != TopAbs_EDGE) {
76     for (TopoDS_Iterator it(shape); it.More(); it.Next()) {
77       if (CheckEdges (it.Value(),bads,dirs,revs,ints)) res = Standard_True;
78     }
79   }
80   else {
81     TopoDS_Edge E = TopoDS::Edge(shape);
82     if (BRep_Tool::Degenerated(E)) return Standard_False;
83
84     if (shape.Orientation() == TopAbs_FORWARD) {
85       //szv#4:S4163:12Mar99 optimized
86       if (dirs.FindIndex (shape) == 0) dirs.Add (shape);
87       else { bads.Add (shape); res = Standard_True; }
88     }
89     if (shape.Orientation() == TopAbs_REVERSED) {
90       //szv#4:S4163:12Mar99 optimized
91       if (revs.FindIndex (shape) == 0) revs.Add (shape);
92       else { bads.Add (shape); res = Standard_True; }
93     }
94     if (shape.Orientation() == TopAbs_INTERNAL) {
95       if (ints.FindIndex (shape) == 0) ints.Add (shape);
96       //else { bads.Add (shape); res = Standard_True; }
97     }
98   }
99
100   return res;
101 }
102
103 //=======================================================================
104 //function : CheckOrientedShells
105 //purpose  : 
106 //=======================================================================
107
108 Standard_Boolean ShapeAnalysis_Shell::CheckOrientedShells(const TopoDS_Shape& shape,
109                                                           const Standard_Boolean alsofree,
110                                                           const Standard_Boolean checkinternaledges)
111 {
112   myConex = Standard_False;
113   if (shape.IsNull()) return Standard_False;
114   Standard_Boolean res = Standard_False;
115
116   TopTools_IndexedMapOfShape dirs, revs, ints;
117   for (TopExp_Explorer exs(shape,TopAbs_SHELL); exs.More(); exs.Next()) {
118     TopoDS_Shape sh = exs.Current();
119     //szv#4:S4163:12Mar99 optimized
120     if (CheckEdges (sh,myBad,dirs,revs,ints))
121       if (myShells.Add (sh)) res = Standard_True;
122   }
123
124   //  Resteraient a faire les FreeEdges
125   if (!alsofree) return res;
126
127   //  Free Edges . Ce sont les edges d une map pas dans l autre
128   //  et lycee de Versailles  (les maps dirs et revs)
129   Standard_Integer nb = dirs.Extent();
130   Standard_Integer i; // svv Jan11 2000 : porting on DEC
131   for (i = 1; i <= nb; i ++) {
132     TopoDS_Shape sh = dirs.FindKey (i);
133     if (!myBad.Contains(sh)) {
134       if (!revs.Contains(sh)) {
135         if(checkinternaledges) {
136           if (!ints.Contains(sh)) {
137             myFree.Add (sh);
138           }
139           else myConex = Standard_True;
140         }
141         else {
142           myFree.Add (sh);
143         }
144       }
145       else myConex = Standard_True;
146     }
147     else myConex = Standard_True;
148   }
149
150   nb = revs.Extent();
151   for (i = 1; i <= nb; i ++) {
152     TopoDS_Shape sh = revs.FindKey (i);
153     if (!myBad.Contains(sh)) {
154       if (!dirs.Contains(sh)) {
155         if(checkinternaledges) {
156           if (!ints.Contains(sh)) {
157             myFree.Add (sh);
158           }
159           else myConex = Standard_True;
160         }
161         else {
162           myFree.Add (sh);
163         }
164       }
165       else myConex = Standard_True;
166     }
167     else myConex = Standard_True;
168   }
169
170   return res;
171 }
172
173 //=======================================================================
174 //function : IsLoaded
175 //purpose  : 
176 //=======================================================================
177
178  Standard_Boolean ShapeAnalysis_Shell::IsLoaded(const TopoDS_Shape& shape) const
179 {
180   if (shape.IsNull()) return Standard_False;
181   return myShells.Contains (shape);
182 }
183
184 //=======================================================================
185 //function : NbLoaded
186 //purpose  : 
187 //=======================================================================
188
189  Standard_Integer ShapeAnalysis_Shell::NbLoaded() const
190 {
191   return myShells.Extent();
192 }
193
194 //=======================================================================
195 //function : Loaded
196 //purpose  : 
197 //=======================================================================
198
199  TopoDS_Shape ShapeAnalysis_Shell::Loaded(const Standard_Integer num) const
200 {
201   return myShells.FindKey (num);
202 }
203
204 //=======================================================================
205 //function : HasBadEdges
206 //purpose  : 
207 //=======================================================================
208
209  Standard_Boolean ShapeAnalysis_Shell::HasBadEdges() const
210 {
211   return (myBad.Extent() > 0);
212 }
213
214 //=======================================================================
215 //function : BadEdges
216 //purpose  : 
217 //=======================================================================
218
219  TopoDS_Compound ShapeAnalysis_Shell::BadEdges() const
220 {
221   TopoDS_Compound C;
222   BRep_Builder B;
223   B.MakeCompound (C);
224   Standard_Integer n = myBad.Extent();
225   for (Standard_Integer i = 1; i <= n; i ++)  B.Add (C,myBad.FindKey(i));
226   return C;
227 }
228
229 //=======================================================================
230 //function : HasFreeEdges
231 //purpose  : 
232 //=======================================================================
233
234  Standard_Boolean ShapeAnalysis_Shell::HasFreeEdges() const
235 {
236   return (myFree.Extent() > 0);
237 }
238
239 //=======================================================================
240 //function : FreeEdges
241 //purpose  : 
242 //=======================================================================
243
244  TopoDS_Compound ShapeAnalysis_Shell::FreeEdges() const
245 {
246   TopoDS_Compound C;
247   BRep_Builder B;
248   B.MakeCompound (C);
249   Standard_Integer n = myFree.Extent();
250   for (Standard_Integer i = 1; i <= n; i ++)  B.Add (C,myFree.FindKey(i));
251   return C;
252 }
253
254 //=======================================================================
255 //function : HasConnectedEdges
256 //purpose  : 
257 //=======================================================================
258
259  Standard_Boolean ShapeAnalysis_Shell::HasConnectedEdges() const
260 {
261   return myConex;
262 }