Salome HOME
Correct bugs, connected with 0D Elements implementation (IMP 20089, BUG 21300)
[modules/smesh.git] / src / SMDS / SMDS_MeshInfo.hxx
1 //  Copyright (C) 2007-2008  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      : SMDS_MeshInfo.hxx
23 // Created   : Mon Sep 24 18:32:41 2007
24 // Author    : Edward AGAPOV (eap)
25 //
26 #ifndef SMDS_MeshInfo_HeaderFile
27 #define SMDS_MeshInfo_HeaderFile
28
29 using namespace std;
30
31 #include "SMESH_SMDS.hxx"
32
33 #include "SMDS_MeshElement.hxx"
34
35 class SMDS_EXPORT SMDS_MeshInfo
36 {
37 public:
38
39   inline SMDS_MeshInfo();
40   inline void Clear();
41
42   int NbNodes() const { return myNbNodes; }
43   inline int NbElements(SMDSAbs_ElementType type=SMDSAbs_All) const;
44
45   int Nb0DElements() const { return myNb0DElements; }
46   inline int NbEdges      (SMDSAbs_ElementOrder order = ORDER_ANY) const;
47   inline int NbFaces      (SMDSAbs_ElementOrder order = ORDER_ANY) const;
48   inline int NbTriangles  (SMDSAbs_ElementOrder order = ORDER_ANY) const;
49   inline int NbQuadrangles(SMDSAbs_ElementOrder order = ORDER_ANY) const;
50   int NbPolygons() const { return myNbPolygons; }
51
52   inline int NbVolumes (SMDSAbs_ElementOrder order = ORDER_ANY) const;
53   inline int NbTetras  (SMDSAbs_ElementOrder order = ORDER_ANY) const;
54   inline int NbHexas   (SMDSAbs_ElementOrder order = ORDER_ANY) const;
55   inline int NbPyramids(SMDSAbs_ElementOrder order = ORDER_ANY) const;
56   inline int NbPrisms  (SMDSAbs_ElementOrder order = ORDER_ANY) const;
57   int NbPolyhedrons() const { return myNbPolyhedrons; }
58
59 private:
60   friend class SMDS_Mesh;
61
62   // methods to count NOT POLY elements
63   inline void remove(const SMDS_MeshElement* el);
64   inline void add   (const SMDS_MeshElement* el);
65   inline int  index(SMDSAbs_ElementType type, int nbNodes) const;
66   // methods to remove elements of ANY kind
67   inline void RemoveEdge(const SMDS_MeshElement* el);
68   inline void RemoveFace(const SMDS_MeshElement* el);
69   inline void RemoveVolume(const SMDS_MeshElement* el);
70
71   int myNbNodes;
72
73   int myNb0DElements;
74   int myNbEdges      , myNbQuadEdges      ;
75   int myNbTriangles  , myNbQuadTriangles  ;
76   int myNbQuadrangles, myNbQuadQuadrangles;
77   int myNbPolygons;
78
79   int myNbTetras  , myNbQuadTetras  ;
80   int myNbHexas   , myNbQuadHexas   ;
81   int myNbPyramids, myNbQuadPyramids;
82   int myNbPrisms  , myNbQuadPrisms  ;
83   int myNbPolyhedrons;
84
85   std::vector<int*> myNb; // pointers to myNb... fields
86   std::vector<int>  myShift; // shift to get an index in myNb by elem->NbNodes()
87 };
88
89 inline SMDS_MeshInfo::SMDS_MeshInfo():
90   myNbNodes(0),
91   myNb0DElements(0),
92   myNbEdges      (0), myNbQuadEdges      (0),
93   myNbTriangles  (0), myNbQuadTriangles  (0),
94   myNbQuadrangles(0), myNbQuadQuadrangles(0),
95   myNbPolygons(0),
96   myNbTetras  (0), myNbQuadTetras  (0),
97   myNbHexas   (0), myNbQuadHexas   (0),
98   myNbPyramids(0), myNbQuadPyramids(0),
99   myNbPrisms  (0), myNbQuadPrisms  (0),
100   myNbPolyhedrons(0)
101 {
102   // Number of nodes in standard element types
103   // n   v  f  e  0  n
104   // o   o  a  d  d  o
105   // d   l  c  g     d
106   // e      e  e     e
107   // s
108   // -----------------
109   // 0         *
110   // 1            .  *
111   // 2         *
112   // 3      .     *
113   // 4   *  .  .
114   // 5   *
115   // 6   *  .
116   // 7
117   // 8   *  .
118   // 9
119   // 10  *
120   // 11     *
121   // 12     *
122   // 13  *
123   // 14     *
124   // 15  *
125   // 16     *
126   // 17
127   // 18
128   // 19
129   // 20  *
130   //
131   // So to have a unique index for each type basing on nb of nodes, we use a shift:
132   myShift.resize(SMDSAbs_NbElementTypes, 0);
133
134   myShift[ SMDSAbs_Face      ] = +8; // 3->11, 4->12, 6->14, 8->16
135   myShift[ SMDSAbs_Edge      ] = -2; // 2->0, 4->2
136   myShift[ SMDSAbs_0DElement ] = +2; // 1->3
137
138   myNb.resize( index( SMDSAbs_Volume,20 ) + 1, NULL);
139
140   myNb[ index( SMDSAbs_Node,1 )] = & myNbNodes;
141
142   myNb[ index( SMDSAbs_0DElement,1 )] = & myNb0DElements;
143
144   myNb[ index( SMDSAbs_Edge,2 )] = & myNbEdges;
145   myNb[ index( SMDSAbs_Edge,4 )] = & myNbQuadEdges;
146
147   myNb[ index( SMDSAbs_Face,3 )] = & myNbTriangles;
148   myNb[ index( SMDSAbs_Face,4 )] = & myNbQuadrangles;
149   myNb[ index( SMDSAbs_Face,6 )] = & myNbQuadTriangles;
150   myNb[ index( SMDSAbs_Face,8 )] = & myNbQuadQuadrangles;
151
152   myNb[ index( SMDSAbs_Volume, 4)]  = & myNbTetras;
153   myNb[ index( SMDSAbs_Volume, 5)]  = & myNbPyramids;
154   myNb[ index( SMDSAbs_Volume, 6)]  = & myNbPrisms;
155   myNb[ index( SMDSAbs_Volume, 8)]  = & myNbHexas;
156   myNb[ index( SMDSAbs_Volume, 10)] = & myNbQuadTetras;  
157   myNb[ index( SMDSAbs_Volume, 13)] = & myNbQuadPyramids;
158   myNb[ index( SMDSAbs_Volume, 15)] = & myNbQuadPrisms;  
159   myNb[ index( SMDSAbs_Volume, 20)] = & myNbQuadHexas;   
160 }
161
162 inline void // Clear
163 SMDS_MeshInfo::Clear()
164 { for ( int i=0; i<myNb.size(); ++i ) if ( myNb[i] ) (*myNb[i])=0;
165   myNbPolygons=myNbPolyhedrons=0;
166 }
167
168 inline int // index
169 SMDS_MeshInfo::index(SMDSAbs_ElementType type, int nbNodes) const
170 { return nbNodes + myShift[ type ]; }
171
172 inline void // remove
173 SMDS_MeshInfo::remove(const SMDS_MeshElement* el)
174 { --(*myNb[ index(el->GetType(), el->NbNodes()) ]); }
175
176 inline void // add
177 SMDS_MeshInfo::add(const SMDS_MeshElement* el)
178 { ++(*myNb[ index(el->GetType(), el->NbNodes()) ]); }
179
180 inline void // RemoveEdge
181 SMDS_MeshInfo::RemoveEdge(const SMDS_MeshElement* el)
182 { if ( el->IsQuadratic() ) --myNbQuadEdges; else --myNbEdges; }
183
184 inline void // RemoveFace
185 SMDS_MeshInfo::RemoveFace(const SMDS_MeshElement* el)
186 { if ( el->IsPoly() ) --myNbPolygons; else remove( el ); }
187
188 inline void // RemoveVolume
189 SMDS_MeshInfo::RemoveVolume(const SMDS_MeshElement* el)
190 { if ( el->IsPoly() ) --myNbPolyhedrons; else remove( el ); }
191
192 inline int // NbEdges
193 SMDS_MeshInfo::NbEdges      (SMDSAbs_ElementOrder order) const
194 { return order == ORDER_ANY ? myNbEdges+myNbQuadEdges : order == ORDER_LINEAR ? myNbEdges : myNbQuadEdges; }
195
196 inline int // NbFaces
197 SMDS_MeshInfo::NbFaces      (SMDSAbs_ElementOrder order) const
198 { return NbTriangles(order)+NbQuadrangles(order)+(order == ORDER_QUADRATIC ? 0 : myNbPolygons); }
199
200 inline int // NbTriangles
201 SMDS_MeshInfo::NbTriangles  (SMDSAbs_ElementOrder order) const
202 { return order == ORDER_ANY ? myNbTriangles+myNbQuadTriangles : order == ORDER_LINEAR ? myNbTriangles : myNbQuadTriangles; }
203
204 inline int // NbQuadrangles
205 SMDS_MeshInfo::NbQuadrangles(SMDSAbs_ElementOrder order) const
206 { return order == ORDER_ANY ? myNbQuadrangles+myNbQuadQuadrangles : order == ORDER_LINEAR ? myNbQuadrangles : myNbQuadQuadrangles; }
207
208 inline int // NbVolumes
209 SMDS_MeshInfo::NbVolumes (SMDSAbs_ElementOrder order) const
210 { return NbTetras(order) + NbHexas(order) + NbPyramids(order) + NbPrisms(order) + (order == ORDER_QUADRATIC ? 0 : myNbPolyhedrons); }
211
212 inline int // NbTetras
213 SMDS_MeshInfo::NbTetras  (SMDSAbs_ElementOrder order) const
214 { return order == ORDER_ANY ? myNbTetras+myNbQuadTetras : order == ORDER_LINEAR ? myNbTetras : myNbQuadTetras; }
215
216 inline int // NbHexas
217 SMDS_MeshInfo::NbHexas   (SMDSAbs_ElementOrder order) const
218 { return order == ORDER_ANY ? myNbHexas+myNbQuadHexas : order == ORDER_LINEAR ? myNbHexas : myNbQuadHexas; }
219
220 inline int // NbPyramids
221 SMDS_MeshInfo::NbPyramids(SMDSAbs_ElementOrder order) const
222 { return order == ORDER_ANY ? myNbPyramids+myNbQuadPyramids : order == ORDER_LINEAR ? myNbPyramids : myNbQuadPyramids; }
223
224 inline int // NbPrisms
225 SMDS_MeshInfo::NbPrisms  (SMDSAbs_ElementOrder order) const
226 { return order == ORDER_ANY ? myNbPrisms+myNbQuadPrisms : order == ORDER_LINEAR ? myNbPrisms : myNbQuadPrisms; }
227
228 inline int // NbElements
229 SMDS_MeshInfo::NbElements(SMDSAbs_ElementType type) const
230
231   int nb = 0;
232   switch (type) {
233   case SMDSAbs_All:
234     for ( int i=1+index( SMDSAbs_Node,1 ); i<myNb.size(); ++i ) if ( myNb[i] ) nb += *myNb[i];
235     nb += myNbPolygons + myNbPolyhedrons;
236     break;
237   case SMDSAbs_Volume:
238     nb = myNbTetras+ myNbPyramids+ myNbPrisms+ myNbHexas+
239       myNbQuadTetras+ myNbQuadPyramids+ myNbQuadPrisms+ myNbQuadHexas+myNbPolyhedrons;
240     break;
241   case SMDSAbs_Face:
242     nb = myNbTriangles+ myNbQuadrangles+ myNbQuadTriangles+ myNbQuadQuadrangles + myNbPolygons;
243     break;
244   case SMDSAbs_Edge:
245     nb = myNbEdges + myNbQuadEdges;
246     break;
247   case SMDSAbs_0DElement:
248     nb = myNb0DElements;
249     break;
250   case SMDSAbs_Node:
251     nb = myNbNodes;
252     break;
253   default:;
254   }
255   return nb;
256 }
257 #endif