2 // File: VISU_CorbaMedConvertor.cxx
3 // Created: Fri Jan 10 12:04:54 2003
4 // Author: Alexey PETROV
5 // <apo@ivanox.nnov.matra-dtv.fr>
8 #include "VISU_CorbaMedConvertor.hxx"
11 #include <vtkCellType.h>
13 #define USER_INTERLACE MED_FULL_INTERLACE
16 static int MYDEBUG = 1;
18 static int MYDEBUG = 0;
20 static med_err ret = 0;
22 typedef map<VISU::TEntity,SALOME_MED::medEntityMesh> TVisu2MedEntity;
23 static TVisu2MedEntity aVisu2MedEntity;
25 aVisu2MedEntity[VISU::CELL_ENTITY] = SALOME_MED::MED_CELL,
26 aVisu2MedEntity[VISU::FACE_ENTITY] = SALOME_MED::MED_FACE,
27 aVisu2MedEntity[VISU::EDGE_ENTITY] = SALOME_MED::MED_EDGE,
28 aVisu2MedEntity[VISU::NODE_ENTITY] = SALOME_MED::MED_NODE,
31 static int CELLGEOM[MED_NBR_GEOMETRIE_MAILLE] = {
32 SALOME_MED::MED_POINT1,
35 SALOME_MED::MED_TRIA3,
36 SALOME_MED::MED_QUAD4,
37 SALOME_MED::MED_TRIA6,
38 SALOME_MED::MED_QUAD8,
39 SALOME_MED::MED_TETRA4,
40 SALOME_MED::MED_PYRA5,
41 SALOME_MED::MED_PENTA6,
42 SALOME_MED::MED_TETRA10,
43 SALOME_MED::MED_HEXA8,
44 SALOME_MED::MED_PYRA13,
45 SALOME_MED::MED_PENTA15,
46 SALOME_MED::MED_HEXA20
49 static const int VTKCELLGEOMEND = 8;
50 static int VTKCELLGEOM[VTKCELLGEOMEND] = {
51 SALOME_MED::MED_POINT1,
53 SALOME_MED::MED_TRIA3,
54 SALOME_MED::MED_QUAD4,
55 SALOME_MED::MED_TETRA4,
56 SALOME_MED::MED_PYRA5,
57 SALOME_MED::MED_PENTA6,
61 static int FACEGEOM[MED_NBR_GEOMETRIE_FACE] = {
62 SALOME_MED::MED_TRIA3,
63 SALOME_MED::MED_QUAD4,
64 SALOME_MED::MED_TRIA6,
68 static int EDGEGEOM[MED_NBR_GEOMETRIE_ARETE] = {
73 static int NODEGEOM[1] = {
74 SALOME_MED::MED_POINT1,
77 void Entity2Geom(const VISU::TEntity& theEntity, int* theVector, int* theEnd) {
79 case VISU::CELL_ENTITY: theVector = CELLGEOM; *theEnd = MED_NBR_GEOMETRIE_MAILLE; break;
80 case VISU::FACE_ENTITY: theVector = FACEGEOM; *theEnd = MED_NBR_GEOMETRIE_FACE; break;
81 case VISU::EDGE_ENTITY: theVector = EDGEGEOM; *theEnd = MED_NBR_GEOMETRIE_ARETE; break;
82 case VISU::NODE_ENTITY: theVector = NODEGEOM; *theEnd = 1; break;
86 typedef pair<int*,int> TEntity2Geom;
87 typedef map<SALOME_MED::medEntityMesh,TEntity2Geom> TEntity2GeomMap;
88 static TEntity2GeomMap anEntity2GeomMap;
90 anEntity2GeomMap[SALOME_MED::MED_CELL] = TEntity2Geom(CELLGEOM,MED_NBR_GEOMETRIE_MAILLE),
91 anEntity2GeomMap[SALOME_MED::MED_FACE] = TEntity2Geom(FACEGEOM,MED_NBR_GEOMETRIE_FACE),
92 anEntity2GeomMap[SALOME_MED::MED_EDGE] = TEntity2Geom(EDGEGEOM,MED_NBR_GEOMETRIE_ARETE),
93 anEntity2GeomMap[SALOME_MED::MED_NODE] = TEntity2Geom(NODEGEOM,1),
97 struct SalomeMed2vtk {
98 SALOME_MED::medGeometryElement medType;
106 #define CORBAMED2VTK(MEDTYPE,VTKTYPE,VTKNBNODES) \
107 {SALOME_MED::MEDTYPE,#MEDTYPE,getNbMedNodes(MEDTYPE),VTKTYPE,#VTKTYPE,VTKNBNODES}
108 static SalomeMed2vtk salome_med2vtk[SALOME_MED::MED_ALL_ELEMENTS] = {
109 {SALOME_MED::MED_NONE,"MED_NONE",0,VTK_EMPTY_CELL,"VTK_EMPTY_CELL",0},
110 CORBAMED2VTK(MED_POINT1,VTK_VERTEX,1),
111 CORBAMED2VTK(MED_SEG2,VTK_LINE,2),
112 CORBAMED2VTK(MED_SEG3,VTK_LINE,2),
113 CORBAMED2VTK(MED_TRIA3,VTK_TRIANGLE,3),
114 CORBAMED2VTK(MED_QUAD4,VTK_QUAD,4),
115 CORBAMED2VTK(MED_TRIA6,VTK_TRIANGLE,3),
116 CORBAMED2VTK(MED_QUAD8,VTK_QUAD,4),
117 CORBAMED2VTK(MED_TETRA4,VTK_TETRA,4),
118 CORBAMED2VTK(MED_PYRA5,VTK_PYRAMID,5),
119 CORBAMED2VTK(MED_PENTA6,VTK_WEDGE,6),
120 CORBAMED2VTK(MED_TETRA10,VTK_TETRA,4),
121 CORBAMED2VTK(MED_HEXA8,VTK_HEXAHEDRON,8),
122 CORBAMED2VTK(MED_PYRA13,VTK_PYRAMID,5),
123 CORBAMED2VTK(MED_PENTA15,VTK_WEDGE,6),
124 CORBAMED2VTK(MED_HEXA20,VTK_HEXAHEDRON,8)
128 int FindIdMEDType(int medType){
129 for(int i = 0; i < SALOME_MED::MED_ALL_ELEMENTS; i++)
130 if(salome_med2vtk[i].medType == medType) return i;
134 void VISU_MedMeshConvertor::SetMedMesh(SALOME_MED::MESH_ptr theMedMesh) {
135 myMedMesh = SALOME_MED::MESH::_duplicate(theMedMesh);
138 void VISU_CorbaMedConvertor::SetMedField(SALOME_MED::FIELD_ptr theMedField) {
139 myMedField = SALOME_MED::FIELD::_duplicate(theMedField);
140 if(!myMedField->_is_nil())
141 myMedMesh = myMedField->getSupport()->getMesh();
144 void VISU_CorbaMedSupportConvertor::SetSupport(SALOME_MED::SUPPORT_ptr theSupport) {
145 mySupport = SALOME_MED::SUPPORT::_duplicate(theSupport);
146 if(!mySupport->_is_nil())
147 myMedMesh = mySupport->getMesh();
150 int ImportPoints(VISU::TMesh& theMesh, SALOME_MED::MESH_ptr theMESH)
151 throw (std::runtime_error&)
154 if(MYDEBUG) MESSAGE("ImportPoints - beginning");
155 theMesh.myDim = theMESH->getMeshDimension();
156 int aNbPoints = theMESH->getNumberOfNodes();
157 VISU::TMesh::TPointsCoord& aPointsCoord = theMesh.myPointsCoord;
158 aPointsCoord.resize(theMesh.myDim*aNbPoints,0.0);
159 Engines::double_array_var coord = theMESH->getCoordinates(SALOME_MED::MED_FULL_INTERLACE);
160 for (int i = 0 ; i < aNbPoints; i++)
161 for(int j = 0, ij = theMesh.myDim*i; j < theMesh.myDim; j++)
162 aPointsCoord[ij+j] = coord[ij+j];
164 MESSAGE("ImportPoints - End : theDim = "<<theMesh.myDim<<"; aNbPoints = "<<aNbPoints);
169 int ImportCells(VISU::TMesh& theMesh, SALOME_MED::MESH_ptr theMESH,
170 const SALOME_MED::medEntityMesh& theEntity)
171 throw (std::runtime_error&)
174 if(MYDEBUG) MESSAGE("ImportCells - theEntity = "<<theEntity);
175 //TEntity2Geom anEntity2Geom = anEntity2GeomMap[theEntity];
176 //int *iVector = anEntity2Geom->first, iEnd = anEntity2Geom->second;
178 VISU::TEntity anEntity = MED2VISUEntity(theEntity);
179 Entity2Geom(anEntity,iArray,&iEnd);
180 int aNbPoints = theMesh.myPointsCoord.size();
181 for (int i = 0; i < iEnd; i++) {
182 int medId = FindIdMEDType(iArray[i]);
183 int nbMedNodes = salome_med2vtk[medId].medNbNodes;
184 int nbVtkNodes = salome_med2vtk[medId].vtkNbNodes;
185 int aVtkType = salome_med2vtk[medId].vtkType;
186 SALOME_MED::medGeometryElement aMedType = salome_med2vtk[medId].medType;
187 int jEnd = theMESH->getNumberOfElements(theEntity,aMedType);
189 VISU::TMeshOnEntity& aMeshOnEntity = theMesh.myMeshOnEntityMap[anEntity];
190 Engines::long_array_var conn =
191 theMESH->getConnectivity(SALOME_MED::MED_FULL_INTERLACE,SALOME_MED::MED_NODAL,theEntity,aMedType);
192 if(MYDEBUG) MESSAGE("ImportCells - medName = "<<salome_med2vtk[medId].medName<<"; jEnd = "<<jEnd);
193 VISU::TMeshOnEntity::TConnForCellType& aConnForCellType = aMeshOnEntity.myCellsConn[aVtkType];
194 aConnForCellType.resize(jEnd);
195 valarray<med_int> aConnect(nbMedNodes);
196 for (int j = 0; j < jEnd; j++) {
197 VISU::TMeshOnEntity::TConnect& anArray = aConnForCellType[j];
198 anArray.resize(nbVtkNodes);
199 for (int k = 0, kj = j*nbMedNodes; k < nbMedNodes; k++)
200 aConnect[k] = conn[kj+k] - 1;
202 case SALOME_MED::MED_TETRA4 :
203 case SALOME_MED::MED_TETRA10 :
204 anArray[0] = aConnect[0];
205 anArray[1] = aConnect[1];
206 anArray[2] = aConnect[3];
207 anArray[3] = aConnect[2];
209 case SALOME_MED::MED_PYRA5 :
210 case SALOME_MED::MED_PYRA13 :
211 anArray[0] = aConnect[0];
212 anArray[1] = aConnect[3];
213 anArray[2] = aConnect[2];
214 anArray[3] = aConnect[1];
215 anArray[4] = aConnect[4];
218 for (int k = 0; k < nbVtkNodes; k++)
219 anArray[k] = aConnect[k];
221 for (int k = 0; k < nbVtkNodes; k++)
222 if(anArray[k] < 0 || aNbPoints <= anArray[k])
223 throw std::runtime_error("ImportCells >> anArray[k] < 0 || aNbPoints <= anArray[k]");
226 MESSAGE("ImportCells - aMeshOnEntity.myCellsConn.size() = "<<aMeshOnEntity.myCellsConn.size());
232 VISU_Convertor* VISU_MedMeshConvertor::Build() throw (std::runtime_error&) {
234 if(myMedMesh->_is_nil())
235 throw std::runtime_error("VISU_MedMeshConvertor::Build >> myMesh->_is_nil()");
236 CORBA::String_var aName = myMedMesh->getName();
238 TMesh& aMesh = myMeshMap[myName];
239 if(MYDEBUG) MESSAGE("MedInfo - aMeshName = "<<myMeshMap.begin()->first);
240 ::ImportPoints(aMesh,myMedMesh);
241 TVisu2MedEntity::const_iterator aVisu2MedEntityIter = aVisu2MedEntity.begin();
242 for(; aVisu2MedEntityIter != aVisu2MedEntity.end(); aVisu2MedEntityIter++)
243 ::ImportCells(aMesh,myMedMesh,aVisu2MedEntityIter->second);
249 template<class TArray> int ImportField(TArray& theArray,
250 const VISU::TMeshOnEntity& theMeshOnEntity,
251 VISU::TField& theField,
252 const SALOME_MED::medEntityMesh& theEntity,
253 const VISU::TField::TTime& theTime)
256 if(MYDEBUG) MESSAGE("ImportField - IEnd = "<<theArray->length()<<"; myNbComp = "<<theField.myNbComp);
257 VISU::TEntity anEntity = MED2VISUEntity(theEntity);
258 VISU::TMeshOnEntity& aMeshOnEntity = theMesh.myMeshOnEntityMap[anEntity];
259 VISU::TField& aField = aMeshOnEntity.myFieldMap[nomcha]
260 VISU::TField::TValForTime& aValForTime = theField.myValField[theTime];
261 if(theField.myTypeConn == POINT_DATA){
262 VISU::TField::TValForCellsWithType& aValForCellsWithType = aValForTime[VTK_VERTEX];
263 int iEnd = theMesh.myPointsCoord.size()/theMesh.myDim * theField.myNbComp;
264 if(MYDEBUG) MESSAGE("ImportField - iEnd = "<<iEnd);
265 aValForCellsWithType.resize(iEnd);
266 for (int i = 0; i < iEnd; i++)
267 aValForCellsWithType[i] = theArray[i];
269 int iEnd = VTKCELLGEOMEND, *iArray = VTKCELLGEOM, kEnd = theField.myNbComp;
270 for (int i = 0, I = 0; i < iEnd; i++) {
271 int medId = FindIdMEDType(iArray[i]), aVtkType = salome_med2vtk[medId].vtkType;
272 const VISU::TMeshOnEntity::TCellsConn& aCellsConn = theMesh.myCellsConn;
273 VISU::TMeshOnEntity::TCellsConn::const_iterator aCellsConnIter = aCellsConn.find(aVtkType);
274 if(aCellsConnIter != aCellsConn.end()){
275 const VISU::TMesh::TConnForCellType& aConnForCellType = aCellsConnIter->second;
276 int jEnd = aConnForCellType.size();
277 if(MYDEBUG) MESSAGE("ImportField - medName = "<<salome_med2vtk[medId].medName<<
278 "; vtkName = "<<salome_med2vtk[medId].vtkName<<"; jEnd = "<<jEnd);
279 VISU::TField::TValForCellsWithType& aValForCellsWithType = aValForTime[aVtkType];
280 aValForCellsWithType.resize(jEnd*kEnd);
281 for (int j = 0; j < jEnd; j++)
282 for (int k = 0, kj = j*kEnd; k < kEnd; k++)
283 aValForCellsWithType[kj+k] = theArray[I++];
290 VISU_Convertor* VISU_CorbaMedConvertor::Build() throw (std::runtime_error&){
292 if(myMedField->_is_nil())
293 throw std::runtime_error("VISU_CorbaMedConvertor::Build >> myField->_is_nil()");
294 if(VISU_MedMeshConvertor::Build() == NULL) return NULL;
295 CORBA::String_var aName = myMedField->getName();
297 TMeshMap::const_iterator aMeshIter = myMeshMap.begin();
298 const TMesh& aMesh = aMeshIter->second;
299 int aNbPoints = aMesh.myPointsCoord.size()/aMesh.myDim;
300 int aNbCells = aMesh.GetCellsDims().first;
301 aName = myMedField->getName();
302 aMeshOnEntity.myEntity = theEntity;
303 aMeshOnEntity.myMeshName = theMesh.myName;
304 TField& aField = myFieldMap[aName.in()];
305 aField.myMeshName = aMeshIter->first;
306 SALOME_MED::SUPPORT_var aSupport = myMedField->getSupport();
307 SALOME_MED::medEntityMesh anEntity = aSupport->getEntity();
309 if(anEntity == SALOME_MED::MED_NODE){
311 aField.myTypeConn = POINT_DATA;
312 if(MYDEBUG) MESSAGE("VISU_CorbaMedConvertor::Build - POINT_DATA = "<<aSize);
313 }else if(anEntity == SALOME_MED::MED_CELL){
315 aField.myTypeConn = CELL_DATA;
316 if(MYDEBUG) MESSAGE("VISU_CorbaMedConvertor::Build - CELL_DATA = "<<aSize);
318 aField.myNbComp = myMedField->getNumberOfComponents();
319 if(MYDEBUG) MESSAGE("VISU_CorbaMedConvertor::Build - aField.myNbComp = "<<aField.myNbComp);
320 TField::TTime aTime(myMedField->getTime(),"");
321 SALOME_MED::FIELDDOUBLE_ptr aFieldDouble = SALOME_MED::FIELDDOUBLE::_narrow(myMedField);
322 if(!aFieldDouble->_is_nil()){
323 if(MYDEBUG) MESSAGE("VISU_CorbaMedConvertor::Build - There is FIELDDOUBLE");
324 Engines::double_array_var anArray = aFieldDouble->getValue(SALOME_MED::MED_FULL_INTERLACE);
325 ::ImportField(anArray,aMesh,aField,anEntity,aTime);
327 SALOME_MED::FIELDINT_ptr aFieldInt = SALOME_MED::FIELDINT::_narrow(myMedField);
328 if(!aFieldInt->_is_nil()){
329 if(MYDEBUG) MESSAGE("VISU_CorbaMedConvertor::Build - There is FIELDINT");
330 Engines::long_array_var anArray = aFieldInt->getValue(SALOME_MED::MED_FULL_INTERLACE);
331 ::ImportField(anArray,aMesh,aField,anEntity,aTime);
338 int ImportCellsOfSupport(VISU::TMesh& theMesh, SALOME_MED::SUPPORT_ptr theSUPPORT)
339 throw (std::runtime_error&)
342 if(MYDEBUG) MESSAGE("ImportCellsOfSupport - beginning");
343 SALOME_MED::medEntityMesh anEntity = theSUPPORT->getEntity();
344 med_int nmailles[SALOME_MED::MED_ALL_ELEMENTS];
345 if(MYDEBUG) MESSAGE("ImportCellsOfSupport - anEntity = "<<anEntity);
346 if(anEntity == SALOME_MED::MED_NODE){
347 VISU::TMesh::TConnForCellType& aConnForCellType = theMesh.myCellsConn[VTK_VERTEX];
348 if(theSUPPORT->isOnAllElements()){
349 int jEnd = theMesh.myPointsCoord.size()/theMesh.myDim;
350 if(MYDEBUG) MESSAGE("ImportCellsOfSupport - isOnAllElements - "<<jEnd);
351 aConnForCellType.resize(jEnd);
352 for (int j = 0; j < jEnd; j++)
353 aConnForCellType[j] = vector<int>(1,j);
355 SALOME_MED::medGeometryElement_array_var aGeom = theSUPPORT->getTypes();
356 Engines::long_array_var aCellNumForType = theSUPPORT->getNumber(aGeom[0]);
357 int jEnd = aCellNumForType->length();
358 aConnForCellType.resize(jEnd);
359 for (int j = 0; j < jEnd; j++)
360 aConnForCellType[j] = vector<int>(1,aCellNumForType[j]-1);
363 VISU::TMesh aBaseMesh;
364 SALOME_MED::MESH_var aMedMesh = theSUPPORT->getMesh();
365 ::ImportPoints(aBaseMesh,aMedMesh);
366 ::ImportCells(aBaseMesh,aMedMesh,anEntity);
367 if(theSUPPORT->isOnAllElements()){
368 if(MYDEBUG) MESSAGE("ImportCellsOfSupport - isOnAllElements");
370 SALOME_MED::medGeometryElement_array_var aGeom = theSUPPORT->getTypes();
371 int iEnd = aGeom->length();
372 if(MYDEBUG) MESSAGE("ImportCellsOfSupport - aGeom->length() = "<<iEnd);
373 for (int i = 0; i < iEnd; i++) {
374 Engines::long_array_var aCellNumForType = theSUPPORT->getNumber(aGeom[i]);
375 int medId = FindIdMEDType(aGeom[i]);
376 int aVtkType = salome_med2vtk[medId].vtkType;
377 med_int jEnd = aCellNumForType->length();
378 if(MYDEBUG) MESSAGE("ImportCellsOfSupport - medName = "<<salome_med2vtk[medId].medName<<"; jEnd = "<<jEnd);
379 VISU::TMesh::TConnForCellType& aConnForCellType = theMesh.myCellsConn[aVtkType];
380 aConnForCellType.resize(jEnd);
381 VISU::TMesh::TConnForCellType& aBaseConnForCellType = aBaseMesh.myCellsConn[aVtkType];
382 for (int j = 0; j < jEnd; j++) {
383 aConnForCellType[j] = aBaseConnForCellType[aCellNumForType[j]-1];
392 VISU_Convertor* VISU_CorbaMedSupportConvertor::Build() throw (std::runtime_error&) {
394 if(MYDEBUG) MESSAGE("BuildSupport - checking mySupport & mySupport->getMesh()");
395 if(mySupport->_is_nil())
396 throw std::runtime_error("VISU_CorbaMedConvertor::Build >> mySupport->_is_nil()");
397 SALOME_MED::GROUP_var aGroup = SALOME_MED::GROUP::_narrow(mySupport);
399 if(!aGroup->_is_nil()){
400 CORBA::String_var aName = aGroup->getName();
402 if(MYDEBUG) MESSAGE("BuildSupport aGroup->getName() = "<<myName);
403 SALOME_MED::Family_array_var anArray = aGroup->getFamilies();
404 med_int iEnd = anArray->length();
405 TMesh& aMesh = myMeshMap[myName];
406 if(MYDEBUG) MESSAGE("BuildSupport - aGroup->getFamilies()->length() = "<<iEnd);
407 ::ImportPoints(aMesh,myMedMesh);
408 for(med_int i = 0; i < iEnd; i++){
409 if(MYDEBUG) MESSAGE("BuildSupport - import FAMILY with number = "<<i);
410 SALOME_MED::FAMILY_var aFamily = anArray[i];
411 ::ImportCellsOfSupport(aMesh,aFamily);
413 aNbCells = aMesh.GetCellsDims().first;
415 CORBA::String_var aName = mySupport->getName();
417 if(MYDEBUG) MESSAGE("mySupport - myName = "<<myName);
418 TMesh& aMesh = myMeshMap[myName];
419 myMedMesh = mySupport->getMesh();
420 ::ImportPoints(aMesh,myMedMesh);
421 ::ImportCellsOfSupport(aMesh,mySupport);
422 aNbCells = aMesh.GetCellsDims().first;
425 throw std::runtime_error("VISU_MedMeshConvertor::Build >> aNbCells == 0");
426 if(MYDEBUG) MESSAGE("BuildSupport - aNbCells = "<<aNbCells);