Salome HOME
Copyright update: 2016
[modules/smesh.git] / src / SMDS / SMDS_MeshInfo.hxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 // File      : SMDS_MeshInfo.hxx
21 // Created   : Mon Sep 24 18:32:41 2007
22 // Author    : Edward AGAPOV (eap)
23 //
24 #ifndef SMDS_MeshInfo_HeaderFile
25 #define SMDS_MeshInfo_HeaderFile
26
27 #include <vector>
28
29 #include "SMESH_SMDS.hxx"
30
31 #include "SMDS_MeshElement.hxx"
32
33 class SMDS_EXPORT SMDS_MeshInfo
34 {
35 public:
36
37   inline SMDS_MeshInfo();
38   inline SMDS_MeshInfo& operator=(const SMDS_MeshInfo& other);
39   inline void Clear();
40
41   inline int NbElements(SMDSAbs_ElementType  type=SMDSAbs_All) const;
42   inline int NbElements(SMDSAbs_EntityType   type) const { return NbEntities(type); }
43   inline int NbElements(SMDSAbs_GeometryType type) const { return NbElementsOfGeom(type); }
44
45   inline int NbEntities(SMDSAbs_EntityType  type) const;
46   inline int NbElementsOfGeom(SMDSAbs_GeometryType geom) const;
47
48   int NbNodes()      const { return myNbNodes; }
49   int Nb0DElements() const { return myNb0DElements; }
50   int NbBalls()      const { return myNbBalls; }
51   inline int NbEdges      (SMDSAbs_ElementOrder order = ORDER_ANY) const;
52
53   inline int NbFaces      (SMDSAbs_ElementOrder order = ORDER_ANY) const;
54   inline int NbTriangles  (SMDSAbs_ElementOrder order = ORDER_ANY) const;
55   inline int NbQuadrangles(SMDSAbs_ElementOrder order = ORDER_ANY) const;
56   int NbBiQuadTriangles() const { return myNbBiQuadTriangles; }
57   int NbBiQuadQuadrangles() const { return myNbBiQuadQuadrangles; }
58   inline int NbPolygons(SMDSAbs_ElementOrder order = ORDER_ANY) const;
59
60   inline int NbVolumes (SMDSAbs_ElementOrder order = ORDER_ANY) const;
61   inline int NbTetras  (SMDSAbs_ElementOrder order = ORDER_ANY) const;
62   inline int NbHexas   (SMDSAbs_ElementOrder order = ORDER_ANY) const;
63   inline int NbPyramids(SMDSAbs_ElementOrder order = ORDER_ANY) const;
64   inline int NbPrisms  (SMDSAbs_ElementOrder order = ORDER_ANY) const;
65   inline int NbHexPrisms(SMDSAbs_ElementOrder order = ORDER_ANY) const;
66   int NbTriQuadHexas() const { return myNbTriQuadHexas; }
67   int NbPolyhedrons() const { return myNbPolyhedrons; }
68
69 protected:
70   inline void addWithPoly(const SMDS_MeshElement* el);
71   inline void setNb(const SMDSAbs_EntityType geomType, const int nb);
72
73 private:
74   friend class SMDS_Mesh;
75
76   // methods to count NOT POLY elements
77   inline void remove(const SMDS_MeshElement* el);
78   inline void add   (const SMDS_MeshElement* el);
79   inline int  index(SMDSAbs_ElementType type, int nbNodes) const;
80   // methods to remove elements of ANY kind
81   inline void RemoveEdge(const SMDS_MeshElement* el);
82   inline void RemoveFace(const SMDS_MeshElement* el);
83   inline void RemoveVolume(const SMDS_MeshElement* el);
84
85   int myNbNodes;
86
87   int myNb0DElements;
88   int myNbBalls;
89   int myNbEdges      , myNbQuadEdges      ;
90   int myNbTriangles  , myNbQuadTriangles,   myNbBiQuadTriangles  ;
91   int myNbQuadrangles, myNbQuadQuadrangles, myNbBiQuadQuadrangles;
92   int myNbPolygons   , myNbQuadPolygons;
93
94   int myNbTetras  , myNbQuadTetras  ;
95   int myNbHexas   , myNbQuadHexas,    myNbTriQuadHexas;
96   int myNbPyramids, myNbQuadPyramids;
97   int myNbPrisms  , myNbQuadPrisms  ;
98   int myNbHexPrism;
99   int myNbPolyhedrons;
100
101   std::vector<int*> myNb; // pointers to myNb... fields
102   std::vector<int>  myShift; // shift to get an index in myNb by elem->NbNodes()
103 };
104
105 inline SMDS_MeshInfo::SMDS_MeshInfo():
106   myNbNodes      (0),
107   myNb0DElements (0),
108   myNbBalls      (0),
109   myNbEdges      (0), myNbQuadEdges      (0),
110   myNbTriangles  (0), myNbQuadTriangles  (0), myNbBiQuadTriangles(0),
111   myNbQuadrangles(0), myNbQuadQuadrangles(0), myNbBiQuadQuadrangles(0),
112   myNbPolygons   (0), myNbQuadPolygons   (0),
113   myNbTetras     (0), myNbQuadTetras  (0),
114   myNbHexas      (0), myNbQuadHexas   (0), myNbTriQuadHexas(0),
115   myNbPyramids   (0), myNbQuadPyramids(0),
116   myNbPrisms     (0), myNbQuadPrisms  (0),
117   myNbHexPrism   (0),
118   myNbPolyhedrons(0)
119 {
120   // Number of nodes in standard element types (. - actual nb, * - after the shift)
121   // n   v  f  e  0  n b
122   // o   o  a  d  d  o a
123   // d   l  c  g     d l
124   // e      e  e     e l
125   // s
126   // ====================
127   // 0 ------------------  - DON't USE 0!!!
128   // 1            .  * .
129   // 2         .       *
130   // 3      .  .  *
131   // 4   *  .
132   // 5   *
133   // 6   *  .
134   // 7      .
135   // 8   *  .
136   // 9      .
137   // 10  *
138   // 11
139   // 12  *
140   // 13  *
141   // 14
142   // 15  *
143   // 16        *
144   // 17        *
145   // 18     *
146   // 19     *
147   // 20  *   
148   // 21     *
149   // 22     *
150   // 23     *
151   // 24     *
152   // 25
153   // 26
154   // 27  *
155   //
156   // So to have a unique index for each type basing on nb of nodes, we use a shift:
157   myShift.resize(SMDSAbs_NbElementTypes, 0);
158
159   myShift[ SMDSAbs_Face      ] = +15;// 3->18, 4->19, etc.
160   myShift[ SMDSAbs_Edge      ] = +14;// 2->16, 3->17
161   myShift[ SMDSAbs_0DElement ] = +2; // 1->3
162   myShift[ SMDSAbs_Ball      ] = +1; // 1->2
163
164   myNb.resize( index( SMDSAbs_Volume,27 ) + 1, NULL);
165
166   myNb[ index( SMDSAbs_Node,1 )] = & myNbNodes;
167   myNb[ index( SMDSAbs_0DElement,1 )] = & myNb0DElements;
168   myNb[ index( SMDSAbs_Ball,1 )] = & myNbBalls;
169
170   myNb[ index( SMDSAbs_Edge,2 )] = & myNbEdges;
171   myNb[ index( SMDSAbs_Edge,3 )] = & myNbQuadEdges;
172
173   myNb[ index( SMDSAbs_Face,3 )] = & myNbTriangles;
174   myNb[ index( SMDSAbs_Face,4 )] = & myNbQuadrangles;
175   myNb[ index( SMDSAbs_Face,6 )] = & myNbQuadTriangles;
176   myNb[ index( SMDSAbs_Face,7 )] = & myNbBiQuadTriangles;
177   myNb[ index( SMDSAbs_Face,8 )] = & myNbQuadQuadrangles;
178   myNb[ index( SMDSAbs_Face,9 )] = & myNbBiQuadQuadrangles;
179
180   myNb[ index( SMDSAbs_Volume, 4)]  = & myNbTetras;
181   myNb[ index( SMDSAbs_Volume, 5)]  = & myNbPyramids;
182   myNb[ index( SMDSAbs_Volume, 6)]  = & myNbPrisms;
183   myNb[ index( SMDSAbs_Volume, 8)]  = & myNbHexas;
184   myNb[ index( SMDSAbs_Volume, 10)] = & myNbQuadTetras;  
185   myNb[ index( SMDSAbs_Volume, 12)] = & myNbHexPrism;
186   myNb[ index( SMDSAbs_Volume, 13)] = & myNbQuadPyramids;
187   myNb[ index( SMDSAbs_Volume, 15)] = & myNbQuadPrisms;  
188   myNb[ index( SMDSAbs_Volume, 20)] = & myNbQuadHexas;   
189   myNb[ index( SMDSAbs_Volume, 27)] = & myNbTriQuadHexas;   
190 }
191
192 inline SMDS_MeshInfo& // operator=
193 SMDS_MeshInfo::operator=(const SMDS_MeshInfo& other)
194 { for ( size_t i=0; i<myNb.size(); ++i ) if ( myNb[i] ) (*myNb[i])=(*other.myNb[i]);
195   myNbPolygons     = other.myNbPolygons;
196   myNbQuadPolygons = other.myNbQuadPolygons;
197   myNbPolyhedrons  = other.myNbPolyhedrons;
198   return *this;
199 }
200
201 inline void // Clear
202 SMDS_MeshInfo::Clear()
203 { for ( size_t i=0; i<myNb.size(); ++i ) if ( myNb[i] ) (*myNb[i])=0;
204   myNbPolygons=myNbQuadPolygons=myNbPolyhedrons=0;
205 }
206
207 inline int // index
208 SMDS_MeshInfo::index(SMDSAbs_ElementType type, int nbNodes) const
209 { return nbNodes + myShift[ type ]; }
210
211 inline void // remove
212 SMDS_MeshInfo::remove(const SMDS_MeshElement* el)
213 { --(*myNb[ index(el->GetType(), el->NbNodes()) ]); }
214
215 inline void // add
216 SMDS_MeshInfo::add(const SMDS_MeshElement* el)
217 { ++(*myNb[ index(el->GetType(), el->NbNodes()) ]); }
218
219 inline void // addWithPoly
220 SMDS_MeshInfo::addWithPoly(const SMDS_MeshElement* el) {
221   switch ( el->GetEntityType() ) {
222   case SMDSEntity_Polygon:      ++myNbPolygons; break;
223   case SMDSEntity_Quad_Polygon: ++myNbQuadPolygons; break;
224   case SMDSEntity_Polyhedra:    ++myNbPolyhedrons; break;
225   default:                      add(el);
226   }
227 }
228 inline void // RemoveEdge
229 SMDS_MeshInfo::RemoveEdge(const SMDS_MeshElement* el)
230 { if ( el->IsQuadratic() ) --myNbQuadEdges; else --myNbEdges; }
231
232 inline void // RemoveFace
233 SMDS_MeshInfo::RemoveFace(const SMDS_MeshElement* el) {
234   switch ( el->GetEntityType() ) {
235   case SMDSEntity_Polygon:      --myNbPolygons; break;
236   case SMDSEntity_Quad_Polygon: --myNbQuadPolygons; break;
237   default:                      remove(el);
238   }
239 }
240
241 inline void // RemoveVolume
242 SMDS_MeshInfo::RemoveVolume(const SMDS_MeshElement* el)
243 { if ( el->IsPoly() ) --myNbPolyhedrons; else remove( el ); }
244
245 inline int  // NbEdges
246 SMDS_MeshInfo::NbEdges      (SMDSAbs_ElementOrder order) const
247 { return order == ORDER_ANY ? myNbEdges+myNbQuadEdges : order == ORDER_LINEAR ? myNbEdges : myNbQuadEdges; }
248
249 inline int  // NbFaces
250 SMDS_MeshInfo::NbFaces      (SMDSAbs_ElementOrder order) const
251 { return NbTriangles(order)+NbQuadrangles(order)+(order == ORDER_ANY ? myNbPolygons+myNbQuadPolygons : order == ORDER_LINEAR ? myNbPolygons : myNbQuadPolygons ); }
252
253 inline int  // NbTriangles
254 SMDS_MeshInfo::NbTriangles  (SMDSAbs_ElementOrder order) const
255 { return order == ORDER_ANY ? myNbTriangles+myNbQuadTriangles+myNbBiQuadTriangles : order == ORDER_LINEAR ? myNbTriangles : myNbQuadTriangles+myNbBiQuadTriangles; }
256
257 inline int  // NbQuadrangles
258 SMDS_MeshInfo::NbQuadrangles(SMDSAbs_ElementOrder order) const
259 { return order == ORDER_ANY ? myNbQuadrangles+myNbQuadQuadrangles+myNbBiQuadQuadrangles : order == ORDER_LINEAR ? myNbQuadrangles : myNbQuadQuadrangles+myNbBiQuadQuadrangles; }
260
261 inline int  // NbPolygons
262 SMDS_MeshInfo::NbPolygons(SMDSAbs_ElementOrder order) const
263 { return order == ORDER_ANY ? myNbPolygons+myNbQuadPolygons : order == ORDER_LINEAR ? myNbPolygons : myNbQuadPolygons; }
264
265 inline int  // NbVolumes
266 SMDS_MeshInfo::NbVolumes (SMDSAbs_ElementOrder order) const
267 { return NbTetras(order) + NbHexas(order) + NbPyramids(order) + NbPrisms(order) + NbHexPrisms(order) + (order == ORDER_QUADRATIC ? 0 : myNbPolyhedrons); }
268
269 inline int  // NbTetras
270 SMDS_MeshInfo::NbTetras  (SMDSAbs_ElementOrder order) const
271 { return order == ORDER_ANY ? myNbTetras+myNbQuadTetras : order == ORDER_LINEAR ? myNbTetras : myNbQuadTetras; }
272
273 inline int  // NbHexas
274 SMDS_MeshInfo::NbHexas   (SMDSAbs_ElementOrder order) const
275 { return order == ORDER_ANY ? myNbHexas+myNbQuadHexas+myNbTriQuadHexas : order == ORDER_LINEAR ? myNbHexas : myNbQuadHexas+myNbTriQuadHexas; }
276
277 inline int  // NbPyramids
278 SMDS_MeshInfo::NbPyramids(SMDSAbs_ElementOrder order) const
279 { return order == ORDER_ANY ? myNbPyramids+myNbQuadPyramids : order == ORDER_LINEAR ? myNbPyramids : myNbQuadPyramids; }
280
281 inline int  // NbPrisms
282 SMDS_MeshInfo::NbPrisms  (SMDSAbs_ElementOrder order) const
283 { return order == ORDER_ANY ? myNbPrisms+myNbQuadPrisms : order == ORDER_LINEAR ? myNbPrisms : myNbQuadPrisms; }
284
285 inline int  // NbHexPrisms
286 SMDS_MeshInfo::NbHexPrisms  (SMDSAbs_ElementOrder order) const
287 { return order == ORDER_ANY ? myNbHexPrism : order == ORDER_LINEAR ? myNbHexPrism : 0; }
288
289 inline int  // NbElements
290 SMDS_MeshInfo::NbElements(SMDSAbs_ElementType type) const
291
292   int nb = 0;
293   switch (type) {
294   case SMDSAbs_All:
295     for ( size_t i=1+index( SMDSAbs_Node,1 ); i<myNb.size(); ++i ) if ( myNb[i] ) nb += *myNb[i];
296     nb += myNbPolygons + myNbQuadPolygons + myNbPolyhedrons;
297     break;
298   case SMDSAbs_Volume:
299     nb = ( myNbTetras+     myNbPyramids+     myNbPrisms+     myNbHexas+     myNbHexPrism+
300            myNbQuadTetras+ myNbQuadPyramids+ myNbQuadPrisms+ myNbQuadHexas+ myNbTriQuadHexas+
301            myNbPolyhedrons );
302     break;
303   case SMDSAbs_Face:
304     nb = ( myNbTriangles+       myNbQuadrangles+
305            myNbQuadTriangles+   myNbBiQuadTriangles+
306            myNbQuadQuadrangles+ myNbBiQuadQuadrangles+ myNbPolygons+ myNbQuadPolygons );
307     break;
308   case SMDSAbs_Edge:
309     nb = myNbEdges + myNbQuadEdges;
310     break;
311   case SMDSAbs_Node:
312     nb = myNbNodes;
313     break;
314   case SMDSAbs_0DElement:
315     nb = myNb0DElements;
316     break;
317   case SMDSAbs_Ball:
318     nb = myNbBalls;
319     break;
320   default:;
321   }
322   return nb;
323 }
324
325 inline int  // NbEntities
326 SMDS_MeshInfo::NbEntities(SMDSAbs_EntityType type) const
327 {
328   switch (type) {
329   case SMDSEntity_Node:             return myNbNodes;
330   case SMDSEntity_Edge:             return myNbEdges;
331   case SMDSEntity_Quad_Edge:        return myNbQuadEdges;
332   case SMDSEntity_Triangle:         return myNbTriangles;
333   case SMDSEntity_Quad_Triangle:    return myNbQuadTriangles;
334   case SMDSEntity_BiQuad_Triangle:  return myNbBiQuadTriangles;
335   case SMDSEntity_Quadrangle:       return myNbQuadrangles;
336   case SMDSEntity_Quad_Quadrangle:  return myNbQuadQuadrangles;
337   case SMDSEntity_BiQuad_Quadrangle:return myNbBiQuadQuadrangles;
338   case SMDSEntity_Polygon:          return myNbPolygons;
339   case SMDSEntity_Tetra:            return myNbTetras;
340   case SMDSEntity_Quad_Tetra:       return myNbQuadTetras;
341   case SMDSEntity_Pyramid:          return myNbPyramids;
342   case SMDSEntity_Quad_Pyramid:     return myNbQuadPyramids;
343   case SMDSEntity_Hexa:             return myNbHexas;
344   case SMDSEntity_Quad_Hexa:        return myNbQuadHexas;
345   case SMDSEntity_TriQuad_Hexa:     return myNbTriQuadHexas;
346   case SMDSEntity_Penta:            return myNbPrisms;
347   case SMDSEntity_Quad_Penta:       return myNbQuadPrisms;
348   case SMDSEntity_Hexagonal_Prism:  return myNbHexPrism;
349   case SMDSEntity_Polyhedra:        return myNbPolyhedrons;
350   case SMDSEntity_0D:               return myNb0DElements;
351   case SMDSEntity_Ball:             return myNbBalls;
352   case SMDSEntity_Quad_Polygon:     return myNbQuadPolygons;
353   case SMDSEntity_Quad_Polyhedra:
354   case SMDSEntity_Last:
355     break;
356   }
357   return 0;
358 }
359
360 inline int  // NbElementsOfGeom
361 SMDS_MeshInfo::NbElementsOfGeom(SMDSAbs_GeometryType geom) const
362 {
363   switch ( geom ) {
364     // 0D:
365   case SMDSGeom_POINT:           return myNb0DElements;
366     // 1D:
367   case SMDSGeom_EDGE:            return (myNbEdges +
368                                          myNbQuadEdges);
369     // 2D:
370   case SMDSGeom_TRIANGLE:        return (myNbTriangles +
371                                          myNbQuadTriangles +
372                                          myNbBiQuadTriangles );
373   case SMDSGeom_QUADRANGLE:      return (myNbQuadrangles +
374                                          myNbQuadQuadrangles +
375                                          myNbBiQuadQuadrangles );
376   case SMDSGeom_POLYGON:         return (myNbPolygons + myNbQuadPolygons );
377     // 3D:
378   case SMDSGeom_TETRA:           return (myNbTetras +
379                                          myNbQuadTetras);
380   case SMDSGeom_PYRAMID:         return (myNbPyramids +
381                                          myNbQuadPyramids);
382   case SMDSGeom_HEXA:            return (myNbHexas +
383                                          myNbQuadHexas +
384                                          myNbTriQuadHexas);
385   case SMDSGeom_PENTA:           return (myNbPrisms +
386                                          myNbQuadPrisms);
387   case SMDSGeom_HEXAGONAL_PRISM: return myNbHexPrism;
388   case SMDSGeom_POLYHEDRA:       return myNbPolyhedrons;
389     // Discrete:
390   case SMDSGeom_BALL:            return myNbBalls;
391     //
392   case SMDSGeom_NONE:
393   default:;
394   }
395   return 0;
396 }
397
398 inline void // setNb
399 SMDS_MeshInfo::setNb(const SMDSAbs_EntityType geomType, const int nb)
400 {
401   switch (geomType) {
402   case SMDSEntity_Node:             myNbNodes             = nb; break;
403   case SMDSEntity_0D:               myNb0DElements        = nb; break;
404   case SMDSEntity_Ball:             myNbBalls             = nb; break;
405   case SMDSEntity_BiQuad_Quadrangle:myNbBiQuadQuadrangles = nb; break;
406   case SMDSEntity_BiQuad_Triangle:  myNbBiQuadTriangles   = nb; break;
407   case SMDSEntity_Edge:             myNbEdges             = nb; break;
408   case SMDSEntity_Hexa:             myNbHexas             = nb; break;
409   case SMDSEntity_Hexagonal_Prism:  myNbHexPrism          = nb; break;
410   case SMDSEntity_Penta:            myNbPrisms            = nb; break;
411   case SMDSEntity_Polygon:          myNbPolygons          = nb; break;
412   case SMDSEntity_Polyhedra:        myNbPolyhedrons       = nb; break;
413   case SMDSEntity_Pyramid:          myNbPyramids          = nb; break;
414   case SMDSEntity_Quad_Edge:        myNbQuadEdges         = nb; break;
415   case SMDSEntity_Quad_Hexa:        myNbQuadHexas         = nb; break;
416   case SMDSEntity_Quad_Penta:       myNbQuadPrisms        = nb; break;
417   case SMDSEntity_Quad_Pyramid:     myNbQuadPyramids      = nb; break;
418   case SMDSEntity_Quad_Quadrangle:  myNbQuadQuadrangles   = nb; break;
419   case SMDSEntity_Quad_Tetra:       myNbQuadTetras        = nb; break;
420   case SMDSEntity_Quad_Triangle:    myNbQuadTriangles     = nb; break;
421   case SMDSEntity_Quadrangle:       myNbQuadrangles       = nb; break;
422   case SMDSEntity_Tetra:            myNbTetras            = nb; break;
423   case SMDSEntity_TriQuad_Hexa:     myNbTriQuadHexas      = nb; break;
424   case SMDSEntity_Triangle:         myNbTriangles         = nb; break;
425   case SMDSEntity_Quad_Polygon:     myNbQuadPolygons      = nb; break;
426   case SMDSEntity_Quad_Polyhedra:
427   case SMDSEntity_Last:
428     break;
429   }
430 }
431
432 #endif