1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/
20 #ifndef CONNECTIVITY_HXX
21 #define CONNECTIVITY_HXX
25 #include "MEDMEM_Utilities.hxx"
26 #include "MEDMEM_Exception.hxx"
27 #include "MEDMEM_define.hxx"
28 #include "MEDMEM_PolyhedronArray.hxx"
31 class MEDSKYLINEARRAY;
37 This class deals with all type of connectivity .\n
41 /* ------------------------------------------- */
43 /* ------------------------------------------- */
45 /* ---------------------- */
47 /* ---------------------- */
50 /*! contains MED_CELL MED_FACE or MED_EDGE */
51 MED_EN::medEntityMesh _entity;
52 /*! contains MED_NODAL or MED_DESCEND */
53 MED_EN::medConnectivity _typeConnectivity;
54 /*! count of differents cells types
57 /*! array of all med_geometric_type used by MESH. */
58 MED_EN::medGeometryElement* _geometricTypes;
60 /*! map indexed by med_geometric_type
61 which contains the different
62 'CellModel' used by MESH. */
64 /*! contains the dimension of the entity */
67 /*! needed by calculateReverseNodalConnectivity */
70 /*! array of size _numberOfTypes+1 which
71 gives for each cell type the first
72 cell number in _nodal or _descending
73 array (depends on _typeConnectivity)
74 To get cells count for one type, we
75 must minus _count[i+1] and _count[i]
76 ( 0 <= i < _numberOfTypes ).
77 Note that _count[_numberOfTypes] returns
78 total cells count + 1 */
81 /*! pointer to an array which stores the nodal connectivity */
82 MEDSKYLINEARRAY* _nodal;
83 /*! pointer to an array which stores the nodal connectivity only for polygons */
84 MEDSKYLINEARRAY* _polygonsNodal;
85 /*! pointer to an array which stores the nodal connectivity only for polyhedron */
86 POLYHEDRONARRAY* _polyhedronNodal;
87 /*! pointer to an array which stores
88 the descending connectivity */
89 MEDSKYLINEARRAY* _descending;
90 /*! pointer to an array which stores the descending connectivity only for polygons */
91 MEDSKYLINEARRAY* _polygonsDescending;
92 /*! pointer to an array which stores the descending connectivity only for polyhedron */
93 MEDSKYLINEARRAY* _polyhedronDescending;
94 /*! pointer to an array which stores
95 the reverse nodal connectivity */
96 MEDSKYLINEARRAY* _reverseNodalConnectivity;
97 /*! pointer to an array which stores
98 the reverse descending connectivity */
99 MEDSKYLINEARRAY* _reverseDescendingConnectivity;
100 /*! if face or edge, list of 2 cells or
101 2 faces it belongs to.
102 If 2nd number equals 0, we have a
103 boundary entity. We could use
104 MEDSKYLINEARRAY, but we suppose we have
105 always only 2 (or 1) entities. */
106 MEDSKYLINEARRAY* _neighbourhood;
107 /*! connectivity of sub cell if
108 descendant connectivity is calculated */
109 CONNECTIVITY * _constituent;
111 /* -------------------- */
113 /* -------------------- */
116 /*! private method :\n
117 does nothing if already exists, else
118 evaluates _nodal from _descending */
119 void calculateNodalConnectivity();
120 /*! private method :\n
121 does nothing if already exists, else
122 evaluates from _nodal */
123 void calculateReverseNodalConnectivity();
124 /*! private method :\n
125 does nothing if already exists, else
126 evaluates _descending from _nodal */
127 void calculateDescendingConnectivity();
128 /*! private method :\n
129 does nothing if already exists, else
130 evaluates from _descending */
131 // void calculateReverseDescendingConnectivity(CONNECTIVITY *myConnectivity);
133 const int* getReverseNodalConnectivity ();
134 const int* getReverseNodalConnectivityIndex ();
135 const int* getReverseDescendingConnectivity ();
136 const int* getReverseDescendingConnectivityIndex ();
138 /*! private method :\n
139 does nothing if already exists, else
140 evaluates _neighbourhood from _descending */
141 void calculateNeighbourhood(CONNECTIVITY &myConnectivity);
143 int getIndexOfEndClassicElementInReverseNodal(const int *reverseNodalValue, const int *reverseNodalIndex, int rk) const;
147 friend class IMED_MESH_RDONLY_DRIVER;
148 friend class MED_MESH_RDONLY_DRIVER21;
149 friend class IMED_MESH_WRONLY_DRIVER;
150 friend class MED_MESH_WRONLY_DRIVER21;
151 friend class MED_MESH_RDONLY_DRIVER22;
152 friend class MED_MESH_WRONLY_DRIVER22;
155 friend ostream & operator<<(ostream &os, CONNECTIVITY &connectivity);
157 // in order to fill CONNECTIVITY of MESH
160 CONNECTIVITY (MED_EN::medEntityMesh Entity=MED_EN::MED_CELL);
161 CONNECTIVITY (int numberOfTypes, MED_EN::medEntityMesh Entity=MED_EN::MED_CELL);
162 CONNECTIVITY (const CONNECTIVITY & m);
163 virtual ~CONNECTIVITY ();
165 void setConstituent (CONNECTIVITY * Constituent)
166 throw (MEDEXCEPTION);
168 void setGeometricTypes (const MED_EN::medGeometryElement * Types,
169 const MED_EN::medEntityMesh Entity)
170 throw (MEDEXCEPTION);
172 void setCount (const int * Count, const MED_EN::medEntityMesh Entity)
173 throw (MEDEXCEPTION);
175 void setNodal (const int * Connectivity,
176 const MED_EN::medEntityMesh Entity,
177 const MED_EN::medGeometryElement Type)
178 throw (MEDEXCEPTION);
180 inline void setNumberOfNodes(int NumberOfNodes);
182 inline int getEntityDimension() const;
184 inline void setEntityDimension(int EntityDimension);
186 void setPolygonsConnectivity(MED_EN::medConnectivity ConnectivityType,
187 MED_EN::medEntityMesh Entity,
188 const int* PolygonsConnectivity,
189 const int* PolygonsConnectivityIndex,
190 int ConnectivitySize, int NumberOfPolygons);
192 void setPolyhedronConnectivity(MED_EN::medConnectivity ConnectivityType,
193 const int* PolyhedronConnectivity,
194 const int* PolyhedronIndex, int ConnectivitySize,
195 int NumberOfPolyhedron,
196 const int* PolyhedronFacesIndex= (int*) NULL,
197 int NumberOfFaces=0);
199 inline bool existConnectivity (MED_EN::medConnectivity connectivityType, MED_EN::medEntityMesh Entity) const;
201 virtual bool existPolygonsConnectivity(MED_EN::medConnectivity connectivityType,
202 MED_EN::medEntityMesh Entity) const;
204 virtual bool existPolyhedronConnectivity(MED_EN::medConnectivity connectivityType,
205 MED_EN::medEntityMesh Entity) const;
207 virtual void calculateConnectivity (MED_EN::medConnectivity connectivityType, MED_EN::medEntityMesh Entity);
209 virtual void updateFamily (const vector<FAMILY*>& myFamilies);
211 inline MED_EN::medEntityMesh getEntity () const;
212 inline int getNumberOfTypes (MED_EN::medEntityMesh Entity) const;
213 int getNumberOfTypesWithPoly(MED_EN::medEntityMesh Entity) const;
214 const int * getConnectivityOfAnElementWithPoly(MED_EN::medConnectivity ConnectivityType,
215 MED_EN::medEntityMesh Entity,
216 int Number, int &lgth);
217 int getNumberOfPolyType() const;
218 int getNumberOfElementsWithPoly(MED_EN::medEntityMesh Entity, MED_EN::medGeometryElement Type) const;
219 int getNumberOfElementOfPolyType(MED_EN::medEntityMesh Entity) const;
220 inline const MED_EN::medGeometryElement * getGeometricTypes (MED_EN::medEntityMesh Entity) const
221 throw (MEDEXCEPTION);
222 MED_EN::medGeometryElement * getGeometricTypesWithPoly (MED_EN::medEntityMesh Entity) const
223 throw (MEDEXCEPTION);
224 MED_EN::medGeometryElement getElementType (MED_EN::medEntityMesh Entity,
226 MED_EN::medGeometryElement getElementTypeWithPoly (MED_EN::medEntityMesh Entity,
228 inline MED_EN::medGeometryElement getPolyTypeRelativeTo() const;
229 virtual inline const int * getGlobalNumberingIndex (MED_EN::medEntityMesh Entity) const
230 throw (MEDEXCEPTION);
232 virtual const int * getConnectivity (MED_EN::medConnectivity ConnectivityType,
233 MED_EN::medEntityMesh Entity,
234 MED_EN::medGeometryElement Type);
235 virtual int getConnectivityLength (MED_EN::medConnectivity ConnectivityType,
236 MED_EN::medEntityMesh Entity,
237 MED_EN::medGeometryElement Type);
239 virtual const int * getConnectivityIndex (MED_EN::medConnectivity ConnectivityType,
240 MED_EN::medEntityMesh Entity);
242 virtual const int* getPolygonsConnectivity(MED_EN::medConnectivity ConnectivityType,
243 MED_EN::medEntityMesh Entity);
244 virtual const int* getPolygonsConnectivityIndex(MED_EN::medConnectivity ConnectivityType,
245 MED_EN::medEntityMesh Entity);
246 virtual int getNumberOfPolygons() const;
247 virtual const int* getPolyhedronConnectivity(MED_EN::medConnectivity ConnectivityType) const;
248 virtual const int* getPolyhedronFacesIndex() const;
249 virtual const int* getPolyhedronIndex(MED_EN::medConnectivity ConnectivityType) const;
250 virtual int getNumberOfPolyhedronFaces() const;
251 virtual int getNumberOfPolyhedron() const;
252 int *getNodesOfPolyhedron(int polyhedronId, int& lgthOfTab) const;
253 int **getNodesPerFaceOfPolyhedron(int polyhedronId, int& nbOfFaces, int* & nbOfNodesPerFaces) const;
254 const CELLMODEL & getType (MED_EN::medGeometryElement Type) const;
255 const CELLMODEL * getCellsTypes (MED_EN::medEntityMesh Entity) const
256 throw (MEDEXCEPTION);
258 int getNumberOfNodesInType (MED_EN::medGeometryElement Type) const;
259 int getNumberOfSubCellInType (MED_EN::medGeometryElement Type) const;
260 virtual int getNumberOf (MED_EN::medEntityMesh Entity,
261 MED_EN::medGeometryElement Type) const;
262 virtual const int* getValue (MED_EN::medConnectivity TypeConnectivity,
263 MED_EN::medGeometryElement Type);
264 virtual const int* getValueIndex (MED_EN::medConnectivity TypeConnectivity);
266 virtual inline const int* getReverseConnectivity (MED_EN::medConnectivity ConnectivityType,
267 MED_EN::medEntityMesh Entity=MED_EN::MED_CELL)
268 throw (MEDEXCEPTION);
269 virtual inline const int* getReverseConnectivityIndex (MED_EN::medConnectivity ConnectivityType,
270 MED_EN::medEntityMesh Entity=MED_EN::MED_CELL)
271 throw (MEDEXCEPTION);
273 const int* getNeighbourhood() const;
274 void invertConnectivityForAFace(int faceId, const int *nodalConnForFace, bool polygonFace=false);
275 bool deepCompare(const CONNECTIVITY& other) const;
277 /*----------------------*/
278 /* Methodes Inline */
279 /*----------------------*/
281 /*! Returns the medEntityMesh */
282 //--------------------------------------------------//
283 inline MED_EN::medEntityMesh CONNECTIVITY::getEntity() const
284 //--------------------------------------------------//
289 /*! Returns the number of different %medGeometryElement types
290 existing in the specified entity. \n
291 Note : Not implemented for MED_ALL_ENTITIES. */
292 //-----------------------------------------------------------------------//
293 inline int CONNECTIVITY::getNumberOfTypes(MED_EN::medEntityMesh Entity) const
294 //-----------------------------------------------------------------------//
296 MESSAGE("CONNECTIVITY::getNumberOfTypes : Entity = "<<Entity<<", _entity = "<<_entity);
298 return _numberOfTypes;
299 else if (_constituent!=NULL)
300 return _constituent->getNumberOfTypes(Entity);
301 else if (_constituent == NULL)
303 MESSAGE("CONNECTIVITY::getNumberOfTypes : _constituent == NULL");
306 (const_cast <CONNECTIVITY *> (this))->calculateDescendingConnectivity();
308 catch (MEDEXCEPTION & ex)
313 SCRUTE(_entityDimension);
315 if (_entityDimension != 2 && _entityDimension != 3) return 0;
319 _constituent->calculateConnectivity(MED_EN::MED_NODAL,Entity);
321 catch (MEDEXCEPTION & ex)
326 return _constituent->getNumberOfTypes(Entity);
329 return 0; // because it is the right information (no exception needed)!
332 /*! Returns an array of all %medGeometryElement types existing in the mesh
333 for the given %medEntityMesh.
334 Note : Not implemented for MED_ALL_ENTITIES.
335 Throws an exception if Entity is unknown */
336 //------------------------------------------------------------------------------------------//
337 inline const MED_EN::medGeometryElement* CONNECTIVITY::getGeometricTypes(MED_EN::medEntityMesh Entity) const
339 //------------------------------------------------------------------------------------------//
342 return _geometricTypes;
343 else if (_constituent!=NULL)
344 return _constituent->getGeometricTypes(Entity);
346 throw MEDEXCEPTION("CONNECTIVITY::getGeometricTypes : Entity not defined !");
349 /*! Returns an array containing the accumulated number of entities sorted by the geometric type.\n
353 In case of a CONNECTIVITY containing 3*MED_TRIA3 et 2*MED_QUAD4 : \n
354 int * count = getGlobalNumberingIndex(MED_CELL)\n
355 count[0] is always set to 1\n
356 count[1] is set to 1+3=4\n
357 count[2] is set to 4+2=6 = total number of cells + 1\n
359 Note : Not implemented for MED_ALL_ENTITIES. \n
360 Note : The geometric type order is given by the typedef enum medGeometryElement.
363 //----------------------------------------------------------------------------------//
364 inline const int * CONNECTIVITY::getGlobalNumberingIndex(MED_EN::medEntityMesh Entity) const
366 //----------------------------------------------------------------------------------//
370 else if (_constituent!=NULL)
371 return _constituent->getGlobalNumberingIndex(Entity);
373 throw MEDEXCEPTION("CONNECTIVITY::getGlobalNumberingIndex : Entity not defined !");
376 /*! Returns true if a connectivity exists on elements of type "Entity" */
377 //-----------------------------------------------------------------------------//
378 inline bool CONNECTIVITY::existConnectivity( MED_EN::medConnectivity ConnectivityType,
379 MED_EN::medEntityMesh Entity) const
380 //-----------------------------------------------------------------------------//
382 if (_entity==Entity) {
383 if ((ConnectivityType==MED_EN::MED_NODAL)&(_nodal!=(MEDSKYLINEARRAY*)NULL))
385 if ((ConnectivityType==MED_EN::MED_DESCENDING)&(_descending!=(MEDSKYLINEARRAY*)NULL))
387 } else if (_constituent!=NULL)
388 return _constituent->existConnectivity(ConnectivityType,Entity);
392 /*! Returns true if a polygons connectivity exists on elements of type "Entity" */
393 //-----------------------------------------------------------------------------//
394 inline bool CONNECTIVITY::existPolygonsConnectivity(MED_EN::medConnectivity ConnectivityType,
395 MED_EN::medEntityMesh Entity) const
396 //-----------------------------------------------------------------------------//
398 if (_entity == Entity)
400 MESSAGE("existPolygonsConnectivity : _entity == Entity = "<<Entity);
401 if (ConnectivityType == MED_EN::MED_NODAL && _polygonsNodal != (MEDSKYLINEARRAY*) NULL)
403 if (ConnectivityType == MED_EN::MED_DESCENDING && _polygonsDescending != (MEDSKYLINEARRAY*) NULL)
406 else if (_constituent != (CONNECTIVITY*) NULL)
407 return _constituent->existPolygonsConnectivity(ConnectivityType,Entity);
411 /*! Returns true if a polyhedron connectivity exists on elements of type "Entity" */
412 //-----------------------------------------------------------------------------//
413 inline bool CONNECTIVITY::existPolyhedronConnectivity(MED_EN::medConnectivity ConnectivityType,
414 MED_EN::medEntityMesh Entity) const
415 //-----------------------------------------------------------------------------//
417 if (_entity == Entity)
419 MESSAGE("existPolyhedronConnectivity : _entity == Entity = "<<Entity);
420 if (ConnectivityType == MED_EN::MED_NODAL && _polyhedronNodal != (POLYHEDRONARRAY*) NULL)
422 if (ConnectivityType == MED_EN::MED_DESCENDING && _polyhedronDescending != (MEDSKYLINEARRAY*) NULL)
425 else if (_constituent != (CONNECTIVITY*) NULL)
426 return _constituent->existPolyhedronConnectivity(ConnectivityType,Entity);
431 Returns an array containing CELLMODEL foreach element type present
432 in connectivity for given medEntityMesh (similar as getGeometricTypes).\n
433 Throw an execption if the given entity is not defined or if the array is not defined.
435 //-----------------------------------------------------------------------------//
436 inline const CELLMODEL * CONNECTIVITY::getCellsTypes(MED_EN::medEntityMesh Entity) const
438 //-----------------------------------------------------------------------------//
440 if (Entity == _entity)
444 throw MEDEXCEPTION("CONNECTIVITY::getCellsTypes(medEntityMesh) :"
445 " CELLMODEL array is not defined !");
447 if (_constituent != NULL)
448 return _constituent->getCellsTypes(Entity);
450 throw MEDEXCEPTION("CONNECTIVITY::getCellsTypes(medEntityMesh) : Not found Entity !");
454 //------------------------------------------------------------------------------------------//
455 inline const int* CONNECTIVITY::getReverseConnectivity( MED_EN::medConnectivity ConnectivityType,
456 MED_EN::medEntityMesh Entity)
458 //------------------------------------------------------------------------------------------//
461 if (ConnectivityType==MED_EN::MED_NODAL)
462 return getReverseNodalConnectivity();
463 else if (ConnectivityType==MED_EN::MED_DESCENDING)
464 return getReverseDescendingConnectivity();
466 throw MEDEXCEPTION("MESH::getReverseConnectivity : connectivity mode not supported !");
469 if (NULL==_constituent)
470 calculateDescendingConnectivity();
471 return _constituent->getReverseConnectivity(ConnectivityType,Entity);
475 //-----------------------------------------------------------------------------------------------//
476 inline const int* CONNECTIVITY::getReverseConnectivityIndex(MED_EN::medConnectivity ConnectivityType,
477 MED_EN::medEntityMesh Entity)
479 //-----------------------------------------------------------------------------------------------//
482 if (ConnectivityType==MED_EN::MED_NODAL)
483 return getReverseNodalConnectivityIndex();
484 else if (ConnectivityType==MED_EN::MED_DESCENDING)
485 return getReverseDescendingConnectivityIndex();
487 throw MEDEXCEPTION("MESH::getReverseConnectivityIndex : connectivity mode not supported !");
490 if (NULL==_constituent)
491 calculateDescendingConnectivity();
492 return _constituent->getReverseConnectivityIndex(ConnectivityType,Entity);
496 inline void CONNECTIVITY::setNumberOfNodes(int NumberOfNodes)
498 _numberOfNodes=NumberOfNodes;
501 inline void CONNECTIVITY::setEntityDimension(int EntityDimension)
503 _entityDimension=EntityDimension;
506 int CONNECTIVITY::getEntityDimension() const
508 return _entityDimension;
511 MED_EN::medGeometryElement CONNECTIVITY::getPolyTypeRelativeTo() const
513 if(_entity==MED_EN::MED_CELL && _entityDimension==3)
514 return MED_EN::MED_POLYHEDRA;
515 else if((_entity==MED_EN::MED_CELL && _entityDimension==2) || (_entity==MED_EN::MED_FACE && _entityDimension==2))
516 return MED_EN::MED_POLYGON;
518 throw MEDEXCEPTION("getPolyTypeRelativeTo : ");
521 }//End namespace MEDMEM
523 #endif /* CONNECTIVITY_HXX */