1 // SMESH DriverMED : driver to read and write 'med' files
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
24 // File : DriverMED_W_SMESHDS_Mesh.cxx
29 #include "DriverMED_W_SMESHDS_Mesh.h"
30 #include "DriverMED_W_SMDS_Mesh.h"
31 #include "DriverMED_Family.h"
33 #include "SMESHDS_Mesh.hxx"
34 #include "SMDS_MeshElement.hxx"
35 #include "SMDS_MeshNode.hxx"
36 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
38 #include "utilities.h"
40 #include "MED_Utilities.hxx"
42 #define _EDF_NODE_IDS_
43 //#define _ELEMENTS_BY_DIM_
49 DriverMED_W_SMESHDS_Mesh::DriverMED_W_SMESHDS_Mesh():
50 myAllSubMeshes (false),
51 myDoGroupOfNodes (false),
52 myDoGroupOfEdges (false),
53 myDoGroupOfFaces (false),
54 myDoGroupOfVolumes (false)
57 void DriverMED_W_SMESHDS_Mesh::SetFile(const std::string& theFileName,
60 myMed = CrWrapper(theFileName,theId);
61 Driver_SMESHDS_Mesh::SetFile(theFileName);
64 void DriverMED_W_SMESHDS_Mesh::SetFile(const std::string& theFileName)
66 return SetFile(theFileName,MED::eV2_2);
69 void DriverMED_W_SMESHDS_Mesh::SetMeshName(const std::string& theMeshName)
71 myMeshName = theMeshName;
74 void DriverMED_W_SMESHDS_Mesh::AddGroup(SMESHDS_GroupBase* theGroup)
76 myGroups.push_back(theGroup);
79 void DriverMED_W_SMESHDS_Mesh::AddAllSubMeshes()
81 myAllSubMeshes = true;
84 void DriverMED_W_SMESHDS_Mesh::AddSubMesh(SMESHDS_SubMesh* theSubMesh, int theID)
86 mySubMeshes[theID] = theSubMesh;
89 void DriverMED_W_SMESHDS_Mesh::AddGroupOfNodes()
91 myDoGroupOfNodes = true;
94 void DriverMED_W_SMESHDS_Mesh::AddGroupOfEdges()
96 myDoGroupOfEdges = true;
99 void DriverMED_W_SMESHDS_Mesh::AddGroupOfFaces()
101 myDoGroupOfFaces = true;
104 void DriverMED_W_SMESHDS_Mesh::AddGroupOfVolumes()
106 myDoGroupOfVolumes = true;
110 typedef double (SMDS_MeshNode::* TGetCoord)() const;
111 typedef const char* TName;
112 typedef const char* TUnit;
114 // name length in a mesh must be equal to 16 :
121 TUnit aUnit[3] = {M,M,M};
124 TGetCoord aXYZGetCoord[3] = {
129 TName aXYZName[3] = {X,Y,Z};
132 TGetCoord aXYGetCoord[2] = {
136 TName aXYName[2] = {X,Y};
138 TGetCoord aYZGetCoord[2] = {
142 TName aYZName[2] = {Y,Z};
144 TGetCoord aXZGetCoord[2] = {
148 TName aXZName[2] = {X,Z};
151 TGetCoord aXGetCoord[1] = {
154 TName aXName[1] = {X};
156 TGetCoord aYGetCoord[1] = {
159 TName aYName[1] = {Y};
161 TGetCoord aZGetCoord[1] = {
164 TName aZName[1] = {Z};
168 SMDS_NodeIteratorPtr myNodeIter;
169 const SMDS_MeshNode* myCurrentNode;
170 TGetCoord* myGetCoord;
174 TCoordHelper(const SMDS_NodeIteratorPtr& theNodeIter,
175 TGetCoord* theGetCoord,
177 TUnit* theUnit = aUnit):
178 myNodeIter(theNodeIter),
179 myGetCoord(theGetCoord),
183 virtual ~TCoordHelper(){}
185 return myNodeIter->more() &&
186 (myCurrentNode = myNodeIter->next());
188 const SMDS_MeshNode* GetNode(){
189 return myCurrentNode;
191 MED::TIntVector::value_type GetID(){
192 return myCurrentNode->GetID();
194 MED::TFloatVector::value_type GetCoord(TInt theCoodId){
195 return (myCurrentNode->*myGetCoord[theCoodId])();
197 MED::TStringVector::value_type GetName(TInt theDimId){
198 return myName[theDimId];
200 MED::TStringVector::value_type GetUnit(TInt theDimId){
201 return myUnit[theDimId];
204 typedef boost::shared_ptr<TCoordHelper> TCoordHelperPtr;
209 Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
211 Status aResult = DRS_OK;
212 if (myMesh->hasConstructionEdges() || myMesh->hasConstructionFaces()) {
213 INFOS("SMDS_MESH with hasConstructionEdges() or hasConstructionFaces() do not supports!!!");
217 MESSAGE("Perform - myFile : "<<myFile);
219 // Creating the MED mesh for corresponding SMDS structure
220 //-------------------------------------------------------
222 if (myMeshId != -1) {
223 ostringstream aMeshNameStr;
224 aMeshNameStr<<myMeshId;
225 aMeshName = aMeshNameStr.str();
227 aMeshName = myMeshName;
230 // Mesh dimension definition
232 TCoordHelperPtr aCoordHelperPtr;
234 bool anIsXDimension = false;
235 bool anIsYDimension = false;
236 bool anIsZDimension = false;
238 SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator();
240 if(aNodesIter->more()){
241 const SMDS_MeshNode* aNode = aNodesIter->next();
242 aBounds[0] = aBounds[1] = aNode->X();
243 aBounds[2] = aBounds[3] = aNode->Y();
244 aBounds[4] = aBounds[5] = aNode->Z();
246 while(aNodesIter->more()){
247 const SMDS_MeshNode* aNode = aNodesIter->next();
248 aBounds[0] = min(aBounds[0],aNode->X());
249 aBounds[1] = max(aBounds[1],aNode->X());
251 aBounds[2] = min(aBounds[2],aNode->Y());
252 aBounds[3] = max(aBounds[3],aNode->Y());
254 aBounds[4] = min(aBounds[4],aNode->Z());
255 aBounds[5] = max(aBounds[5],aNode->Z());
259 anIsXDimension = (aBounds[1] - aBounds[0]) + abs(aBounds[1]) + abs(aBounds[0]) > EPS;
260 anIsYDimension = (aBounds[3] - aBounds[2]) + abs(aBounds[3]) + abs(aBounds[2]) > EPS;
261 anIsZDimension = (aBounds[5] - aBounds[4]) + abs(aBounds[5]) + abs(aBounds[4]) > EPS;
262 aMeshDimension = anIsXDimension + anIsYDimension + anIsZDimension;
265 // PAL16857(SMESH not conform to the MED convention):
266 if ( aMeshDimension == 2 && anIsZDimension ) // 2D only if mesh is in XOY plane
270 SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator();
271 switch(aMeshDimension){
273 aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXYZGetCoord,aXYZName));
276 if(anIsXDimension && anIsYDimension)
277 aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXYGetCoord,aXYName));
278 if(anIsYDimension && anIsZDimension)
279 aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aYZGetCoord,aYZName));
280 if(anIsXDimension && anIsZDimension)
281 aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXZGetCoord,aXZName));
285 aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXGetCoord,aXName));
287 aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aYGetCoord,aYName));
289 aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aZGetCoord,aZName));
295 PMeshInfo aMeshInfo = myMed->CrMeshInfo(aMeshDimension,aMeshName);
296 MESSAGE("Add - aMeshName : "<<aMeshName<<"; "<<aMeshInfo->GetName());
297 myMed->SetMeshInfo(aMeshInfo);
299 // Storing SMDS groups and sub-meshes
300 //-----------------------------------
301 int myNodesDefaultFamilyId = 0;
302 int myEdgesDefaultFamilyId = 0;
303 int myFacesDefaultFamilyId = 0;
304 int myVolumesDefaultFamilyId = 0;
305 int nbNodes = myMesh->NbNodes();
306 int nbEdges = myMesh->NbEdges();
307 int nbFaces = myMesh->NbFaces();
308 int nbVolumes = myMesh->NbVolumes();
309 if (myDoGroupOfNodes && nbNodes)
310 myNodesDefaultFamilyId = REST_NODES_FAMILY;
311 if (myDoGroupOfEdges && nbEdges)
312 myEdgesDefaultFamilyId = REST_EDGES_FAMILY;
313 if (myDoGroupOfFaces && nbFaces)
314 myFacesDefaultFamilyId = REST_FACES_FAMILY;
315 if (myDoGroupOfVolumes && nbVolumes)
316 myVolumesDefaultFamilyId = REST_VOLUMES_FAMILY;
318 MESSAGE("Perform - aFamilyInfo");
319 map<const SMDS_MeshElement *, int> anElemFamMap;
320 list<DriverMED_FamilyPtr> aFamilies;
321 if (myAllSubMeshes) {
322 aFamilies = DriverMED_Family::MakeFamilies
323 (myMesh->SubMeshes(), myGroups,
324 myDoGroupOfNodes && nbNodes,
325 myDoGroupOfEdges && nbEdges,
326 myDoGroupOfFaces && nbFaces,
327 myDoGroupOfVolumes && nbVolumes);
329 aFamilies = DriverMED_Family::MakeFamilies
330 (mySubMeshes, myGroups,
331 myDoGroupOfNodes && nbNodes,
332 myDoGroupOfEdges && nbEdges,
333 myDoGroupOfFaces && nbFaces,
334 myDoGroupOfVolumes && nbVolumes);
336 list<DriverMED_FamilyPtr>::iterator aFamsIter = aFamilies.begin();
338 for (; aFamsIter != aFamilies.end(); aFamsIter++)
340 PFamilyInfo aFamilyInfo = (*aFamsIter)->GetFamilyInfo(myMed,aMeshInfo);
341 myMed->SetFamilyInfo(aFamilyInfo);
342 int aFamId = (*aFamsIter)->GetId();
344 const set<const SMDS_MeshElement *>& anElems = (*aFamsIter)->GetElements();
345 set<const SMDS_MeshElement *>::const_iterator anElemsIter = anElems.begin();
346 for (; anElemsIter != anElems.end(); anElemsIter++)
348 anElemFamMap[*anElemsIter] = aFamId;
352 // Storing SMDS nodes to the MED file for the MED mesh
353 //----------------------------------------------------
354 #ifdef _EDF_NODE_IDS_
355 typedef map<TInt,TInt> TNodeIdMap;
356 TNodeIdMap aNodeIdMap;
358 TInt aNbElems = myMesh->NbNodes();
359 MED::TIntVector anElemNums(aNbElems);
360 MED::TIntVector aFamilyNums(aNbElems);
361 MED::TFloatVector aCoordinates(aNbElems*aMeshDimension);
362 for(TInt iNode = 0, aStartId = 0; aCoordHelperPtr->Next(); iNode++, aStartId += aMeshDimension){
363 for(TInt iCoord = 0; iCoord < aMeshDimension; iCoord++){
364 aCoordinates[aStartId+iCoord] = aCoordHelperPtr->GetCoord(iCoord);
366 int aNodeID = aCoordHelperPtr->GetID();
367 anElemNums[iNode] = aNodeID;
368 #ifdef _EDF_NODE_IDS_
369 aNodeIdMap[aNodeID] = iNode+1;
371 const SMDS_MeshNode* aNode = aCoordHelperPtr->GetNode();
372 if (anElemFamMap.find(aNode) != anElemFamMap.end())
373 aFamilyNums[iNode] = anElemFamMap[aNode];
375 aFamilyNums[iNode] = myNodesDefaultFamilyId;
378 MED::TStringVector aCoordNames(aMeshDimension);
379 MED::TStringVector aCoordUnits(aMeshDimension);
380 for(TInt iCoord = 0; iCoord < aMeshDimension; iCoord++){
381 aCoordNames[iCoord] = aCoordHelperPtr->GetName(iCoord);
382 aCoordUnits[iCoord] = aCoordHelperPtr->GetUnit(iCoord);
385 const ERepere SMDS_COORDINATE_SYSTEM = eCART;
387 PNodeInfo aNodeInfo = myMed->CrNodeInfo(aMeshInfo,
390 SMDS_COORDINATE_SYSTEM,
395 MESSAGE("Perform - aNodeInfo->GetNbElem() = "<<aNbElems);
396 myMed->SetNodeInfo(aNodeInfo);
399 // Storing others SMDS elements to the MED file for the MED mesh
400 //--------------------------------------------------------------
401 EEntiteMaillage SMDS_MED_ENTITY = eMAILLE;
402 const EConnectivite SMDS_MED_CONNECTIVITY = eNOD;
404 // Storing SMDS Edges
405 if(TInt aNbElems = myMesh->NbEdges()){
406 #ifdef _ELEMENTS_BY_DIM_
407 SMDS_MED_ENTITY = eARETE;
409 // count edges of diff types
410 int aNbSeg3 = 0, aNbSeg2 = 0;
411 SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator();
412 while ( anIter->more() )
413 if ( anIter->next()->NbNodes() == 3 )
415 aNbSeg2 = aNbElems - aNbSeg3;
417 TInt aNbSeg2Conn = MED::GetNbNodes(eSEG2);
418 MED::TIntVector aSeg2ElemNums, aSeg2FamilyNums, aSeg2Conn;
419 aSeg2ElemNums .reserve( aNbSeg2 );
420 aSeg2FamilyNums.reserve( aNbSeg2 );
421 aSeg2Conn .reserve( aNbSeg2*aNbSeg2Conn );
423 TInt aNbSeg3Conn = MED::GetNbNodes(eSEG3);
424 MED::TIntVector aSeg3ElemNums, aSeg3FamilyNums, aSeg3Conn;
425 aSeg3ElemNums .reserve( aNbSeg3 );
426 aSeg3FamilyNums.reserve( aNbSeg3 );
427 aSeg3Conn .reserve( aNbSeg3*aNbSeg3Conn );
429 anIter = myMesh->edgesIterator();
430 while ( anIter->more() ) {
431 const SMDS_MeshEdge* anElem = anIter->next();
432 TInt aNbNodes = anElem->NbNodes();
434 TInt aNbConnectivity;
435 MED::TIntVector* anElemNums;
436 MED::TIntVector* aFamilyNums;
437 MED::TIntVector* aConnectivity;
440 aNbConnectivity = aNbSeg2Conn;
441 anElemNums = &aSeg2ElemNums;
442 aFamilyNums = &aSeg2FamilyNums;
443 aConnectivity = &aSeg2Conn;
446 aNbConnectivity = aNbSeg3Conn;
447 anElemNums = &aSeg3ElemNums;
448 aFamilyNums = &aSeg3FamilyNums;
449 aConnectivity = &aSeg3Conn;
455 for(TInt iNode = 0; iNode < aNbNodes; iNode++) {
456 const SMDS_MeshElement* aNode = anElem->GetNode( iNode );
457 #ifdef _EDF_NODE_IDS_
458 aConnectivity->push_back( aNodeIdMap[aNode->GetID()] );
460 aConnectivity->push_back( aNode->GetID() );
464 anElemNums->push_back(anElem->GetID());
466 map<const SMDS_MeshElement*,int>::iterator edge_fam = anElemFamMap.find( anElem );
467 if ( edge_fam != anElemFamMap.end() )
468 aFamilyNums->push_back( edge_fam->second );
470 aFamilyNums->push_back( myEdgesDefaultFamilyId );
474 PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
478 SMDS_MED_CONNECTIVITY,
481 myMed->SetCellInfo(aCellInfo);
484 PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
488 SMDS_MED_CONNECTIVITY,
491 myMed->SetCellInfo(aCellInfo);
495 // Storing SMDS Faces
496 if(TInt aNbElems = myMesh->NbFaces()){
497 SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
498 #ifdef _ELEMENTS_BY_DIM_
499 SMDS_MED_ENTITY = eFACE;
501 TInt aNbTriaConn = MED::GetNbNodes(eTRIA3);
502 MED::TIntVector anTriaElemNums;
503 anTriaElemNums.reserve(aNbElems);
504 MED::TIntVector aTriaFamilyNums;
505 aTriaFamilyNums.reserve(aNbElems);
506 MED::TIntVector aTriaConn;
507 aTriaConn.reserve(aNbElems*aNbTriaConn);
509 TInt aNbTria6Conn = MED::GetNbNodes(eTRIA6);
510 MED::TIntVector anTria6ElemNums;
511 anTria6ElemNums.reserve(aNbElems);
512 MED::TIntVector aTria6FamilyNums;
513 aTria6FamilyNums.reserve(aNbElems);
514 MED::TIntVector aTria6Conn;
515 aTria6Conn.reserve(aNbElems*aNbTria6Conn);
517 TInt aNbQuadConn = MED::GetNbNodes(eQUAD4);
518 MED::TIntVector aQuadElemNums;
519 aQuadElemNums.reserve(aNbElems);
520 MED::TIntVector aQuadFamilyNums;
521 aQuadFamilyNums.reserve(aNbElems);
522 MED::TIntVector aQuadConn;
523 aQuadConn.reserve(aNbElems*aNbQuadConn);
525 TInt aNbQuad8Conn = MED::GetNbNodes(eQUAD8);
526 MED::TIntVector aQuad8ElemNums;
527 aQuad8ElemNums.reserve(aNbElems);
528 MED::TIntVector aQuad8FamilyNums;
529 aQuad8FamilyNums.reserve(aNbElems);
530 MED::TIntVector aQuad8Conn;
531 aQuad8Conn.reserve(aNbElems*aNbQuad8Conn);
533 MED::TIntVector aPolygoneElemNums;
534 aPolygoneElemNums.reserve(aNbElems);
535 MED::TIntVector aPolygoneInds;
536 aPolygoneInds.reserve(aNbElems + 1);
537 aPolygoneInds.push_back(1); // reference on the first element in the connectivities
538 MED::TIntVector aPolygoneFamilyNums;
539 aPolygoneFamilyNums.reserve(aNbElems);
540 MED::TIntVector aPolygoneConn;
541 aPolygoneConn.reserve(aNbElems*aNbQuadConn);
543 for(TInt iElem = 0; iElem < aNbElems && anIter->more(); iElem++){
544 const SMDS_MeshFace* anElem = anIter->next();
545 TInt aNbNodes = anElem->NbNodes();
546 SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
547 TInt aNbConnectivity;
548 MED::TIntVector* anElemNums;
549 MED::TIntVector* aFamilyNums;
550 MED::TIntVector* aConnectivity;
551 if (anElem->IsPoly()) {
552 aNbConnectivity = aNbNodes;
553 anElemNums = &aPolygoneElemNums;
554 aFamilyNums = &aPolygoneFamilyNums;
555 aConnectivity = &aPolygoneConn;
560 aNbConnectivity = aNbTriaConn;
561 anElemNums = &anTriaElemNums;
562 aFamilyNums = &aTriaFamilyNums;
563 aConnectivity = &aTriaConn;
566 aNbConnectivity = aNbQuadConn;
567 anElemNums = &aQuadElemNums;
568 aFamilyNums = &aQuadFamilyNums;
569 aConnectivity = &aQuadConn;
572 aNbConnectivity = aNbTria6Conn;
573 anElemNums = &anTria6ElemNums;
574 aFamilyNums = &aTria6FamilyNums;
575 aConnectivity = &aTria6Conn;
578 aNbConnectivity = aNbQuad8Conn;
579 anElemNums = &aQuad8ElemNums;
580 aFamilyNums = &aQuad8FamilyNums;
581 aConnectivity = &aQuad8Conn;
587 MED::TIntVector aVector(aNbNodes);
588 for(TInt iNode = 0; aNodesIter->more(); iNode++){
589 const SMDS_MeshElement* aNode = aNodesIter->next();
590 #ifdef _EDF_NODE_IDS_
591 aVector[iNode] = aNodeIdMap[aNode->GetID()];
593 aVector[iNode] = aNode->GetID();
597 TInt aSize = aConnectivity->size();
598 aConnectivity->resize(aSize+aNbConnectivity);
599 // There is some differences between SMDS and MED in cells mapping
602 (*aConnectivity)[aSize+0] = aVector[0];
603 (*aConnectivity)[aSize+1] = aVector[1];
604 (*aConnectivity)[aSize+2] = aVector[3];
605 (*aConnectivity)[aSize+3] = aVector[2];
607 for(TInt iNode = 0; iNode < aNbNodes; iNode++)
608 (*aConnectivity)[aSize+iNode] = aVector[iNode];
611 if (anElem->IsPoly()) {
612 // fill indices for polygonal element
613 TInt aPrevPos = aPolygoneInds.back();
614 aPolygoneInds.push_back(aPrevPos + aNbNodes);
617 anElemNums->push_back(anElem->GetID());
619 if (anElemFamMap.find(anElem) != anElemFamMap.end())
620 aFamilyNums->push_back(anElemFamMap[anElem]);
622 aFamilyNums->push_back(myFacesDefaultFamilyId);
624 if(TInt aNbElems = anTriaElemNums.size()){
625 PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
629 SMDS_MED_CONNECTIVITY,
632 MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<eTRIA3<<"; aNbElems = "<<aNbElems);
633 myMed->SetCellInfo(aCellInfo);
635 if(TInt aNbElems = aQuadElemNums.size()){
636 PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
640 SMDS_MED_CONNECTIVITY,
643 MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<eQUAD4<<"; aNbElems = "<<aNbElems);
644 myMed->SetCellInfo(aCellInfo);
646 if(TInt aNbElems = anTria6ElemNums.size()){
647 PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
651 SMDS_MED_CONNECTIVITY,
654 MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<eTRIA6<<"; aNbElems = "<<aNbElems);
655 myMed->SetCellInfo(aCellInfo);
657 if(TInt aNbElems = aQuad8ElemNums.size()){
658 PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
662 SMDS_MED_CONNECTIVITY,
665 MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<eQUAD8<<"; aNbElems = "<<aNbElems);
666 myMed->SetCellInfo(aCellInfo);
668 if(TInt aNbElems = aPolygoneElemNums.size()){
669 // add one element in connectivities,
670 // referenced by the last element in indices
671 aPolygoneConn.push_back(0);
673 PPolygoneInfo aCellInfo = myMed->CrPolygoneInfo(aMeshInfo,
678 SMDS_MED_CONNECTIVITY,
681 MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<ePOLYGONE<<"; aNbElems = "<<aNbElems);
682 myMed->SetPolygoneInfo(aCellInfo);
686 // Storing SMDS Volumes
687 if(TInt aNbElems = myMesh->NbVolumes()){
688 SMDS_VolumeIteratorPtr anIter = myMesh->volumesIterator();
689 #ifdef _ELEMENTS_BY_DIM_
690 SMDS_MED_ENTITY = eMAILLE;
692 TInt aNbTetraConn = MED::GetNbNodes(eTETRA4);
693 MED::TIntVector anTetraElemNums;
694 anTetraElemNums.reserve(aNbElems);
695 MED::TIntVector aTetraFamilyNums;
696 aTetraFamilyNums.reserve(aNbElems);
697 MED::TIntVector aTetraConn;
698 aTetraConn.reserve(aNbElems*aNbTetraConn);
700 TInt aNbPyraConn = MED::GetNbNodes(ePYRA5);
701 MED::TIntVector anPyraElemNums;
702 anPyraElemNums.reserve(aNbElems);
703 MED::TIntVector aPyraFamilyNums;
704 aPyraFamilyNums.reserve(aNbElems);
705 MED::TIntVector aPyraConn;
706 aPyraConn.reserve(aNbElems*aNbPyraConn);
708 TInt aNbPentaConn = MED::GetNbNodes(ePENTA6);
709 MED::TIntVector anPentaElemNums;
710 anPentaElemNums.reserve(aNbElems);
711 MED::TIntVector aPentaFamilyNums;
712 aPentaFamilyNums.reserve(aNbElems);
713 MED::TIntVector aPentaConn;
714 aPentaConn.reserve(aNbElems*aNbPentaConn);
716 TInt aNbHexaConn = MED::GetNbNodes(eHEXA8);
717 MED::TIntVector aHexaElemNums;
718 aHexaElemNums.reserve(aNbElems);
719 MED::TIntVector aHexaFamilyNums;
720 aHexaFamilyNums.reserve(aNbElems);
721 MED::TIntVector aHexaConn;
722 aHexaConn.reserve(aNbElems*aNbHexaConn);
724 TInt aNbTetra10Conn = MED::GetNbNodes(eTETRA10);
725 MED::TIntVector anTetra10ElemNums;
726 anTetra10ElemNums.reserve(aNbElems);
727 MED::TIntVector aTetra10FamilyNums;
728 aTetra10FamilyNums.reserve(aNbElems);
729 MED::TIntVector aTetra10Conn;
730 aTetra10Conn.reserve(aNbElems*aNbTetra10Conn);
732 TInt aNbPyra13Conn = MED::GetNbNodes(ePYRA13);
733 MED::TIntVector anPyra13ElemNums;
734 anPyra13ElemNums.reserve(aNbElems);
735 MED::TIntVector aPyra13FamilyNums;
736 aPyra13FamilyNums.reserve(aNbElems);
737 MED::TIntVector aPyra13Conn;
738 aPyra13Conn.reserve(aNbElems*aNbPyra13Conn);
740 TInt aNbPenta15Conn = MED::GetNbNodes(ePENTA15);
741 MED::TIntVector anPenta15ElemNums;
742 anPenta15ElemNums.reserve(aNbElems);
743 MED::TIntVector aPenta15FamilyNums;
744 aPenta15FamilyNums.reserve(aNbElems);
745 MED::TIntVector aPenta15Conn;
746 aPenta15Conn.reserve(aNbElems*aNbPenta15Conn);
748 TInt aNbHexa20Conn = MED::GetNbNodes(eHEXA20);
749 MED::TIntVector aHexa20ElemNums;
750 aHexa20ElemNums.reserve(aNbElems);
751 MED::TIntVector aHexa20FamilyNums;
752 aHexa20FamilyNums.reserve(aNbElems);
753 MED::TIntVector aHexa20Conn;
754 aHexa20Conn.reserve(aNbElems*aNbHexa20Conn);
756 MED::TIntVector aPolyedreElemNums;
757 aPolyedreElemNums.reserve(aNbElems);
758 MED::TIntVector aPolyedreInds;
759 aPolyedreInds.reserve(aNbElems + 1);
760 aPolyedreInds.push_back(1); // reference on the first element in the faces
761 MED::TIntVector aPolyedreFaces;
762 aPolyedreFaces.reserve(aNbElems + 1);
763 aPolyedreFaces.push_back(1); // reference on the first element in the connectivities
764 MED::TIntVector aPolyedreFamilyNums;
765 aPolyedreFamilyNums.reserve(aNbElems);
766 MED::TIntVector aPolyedreConn;
767 aPolyedreConn.reserve(aNbElems*aNbHexaConn);
769 for(TInt iElem = 0; iElem < aNbElems && anIter->more(); iElem++){
770 const SMDS_MeshVolume* anElem = anIter->next();
772 MED::TIntVector* anElemNums;
773 MED::TIntVector* aFamilyNums;
775 if (anElem->IsPoly()) {
776 const SMDS_PolyhedralVolumeOfNodes* aPolyedre =
777 (const SMDS_PolyhedralVolumeOfNodes*) anElem;
779 MESSAGE("Warning: bad volumic element");
783 anElemNums = &aPolyedreElemNums;
784 aFamilyNums = &aPolyedreFamilyNums;
786 TInt aNodeId, aNbFaces = aPolyedre->NbFaces();
787 for (int iface = 1; iface <= aNbFaces; iface++) {
788 int aNbFaceNodes = aPolyedre->NbFaceNodes(iface);
789 for (int inode = 1; inode <= aNbFaceNodes; inode++) {
790 aNodeId = aPolyedre->GetFaceNode(iface, inode)->GetID();
791 #ifdef _EDF_NODE_IDS_
792 aPolyedreConn.push_back(aNodeIdMap[aNodeId]);
794 aPolyedreConn.push_back(aNodeId);
797 TInt aPrevPos = aPolyedreFaces.back();
798 aPolyedreFaces.push_back(aPrevPos + aNbFaceNodes);
800 TInt aPrevPos = aPolyedreInds.back();
801 aPolyedreInds.push_back(aPrevPos + aNbFaces);
805 TInt aNbNodes = anElem->NbNodes();
806 SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
807 TInt aNbConnectivity;
808 MED::TIntVector* aConnectivity;
811 aNbConnectivity = aNbTetraConn;
812 anElemNums = &anTetraElemNums;
813 aFamilyNums = &aTetraFamilyNums;
814 aConnectivity = &aTetraConn;
817 aNbConnectivity = aNbPyraConn;
818 anElemNums = &anPyraElemNums;
819 aFamilyNums = &aPyraFamilyNums;
820 aConnectivity = &aPyraConn;
823 aNbConnectivity = aNbPentaConn;
824 anElemNums = &anPentaElemNums;
825 aFamilyNums = &aPentaFamilyNums;
826 aConnectivity = &aPentaConn;
829 aNbConnectivity = aNbHexaConn;
830 anElemNums = &aHexaElemNums;
831 aFamilyNums = &aHexaFamilyNums;
832 aConnectivity = &aHexaConn;
835 aNbConnectivity = aNbTetra10Conn;
836 anElemNums = &anTetra10ElemNums;
837 aFamilyNums = &aTetra10FamilyNums;
838 aConnectivity = &aTetra10Conn;
841 aNbConnectivity = aNbPyra13Conn;
842 anElemNums = &anPyra13ElemNums;
843 aFamilyNums = &aPyra13FamilyNums;
844 aConnectivity = &aPyra13Conn;
847 aNbConnectivity = aNbPenta15Conn;
848 anElemNums = &anPenta15ElemNums;
849 aFamilyNums = &aPenta15FamilyNums;
850 aConnectivity = &aPenta15Conn;
853 aNbConnectivity = aNbHexa20Conn;
854 anElemNums = &aHexa20ElemNums;
855 aFamilyNums = &aHexa20FamilyNums;
856 aConnectivity = &aHexa20Conn;
859 TInt aSize = aConnectivity->size();
860 aConnectivity->resize(aSize + aNbConnectivity);
862 MED::TIntVector aVector(aNbNodes);
863 for(TInt iNode = 0; aNodesIter->more(); iNode++){
864 const SMDS_MeshElement* aNode = aNodesIter->next();
865 #ifdef _EDF_NODE_IDS_
866 aVector[iNode] = aNodeIdMap[aNode->GetID()];
868 aVector[iNode] = aNode->GetID();
871 // There is some difference between SMDS and MED in cells mapping
874 (*aConnectivity)[aSize+0] = aVector[0];
875 (*aConnectivity)[aSize+1] = aVector[3];
876 (*aConnectivity)[aSize+2] = aVector[2];
877 (*aConnectivity)[aSize+3] = aVector[1];
878 (*aConnectivity)[aSize+4] = aVector[4];
880 for(TInt iNode = 0; iNode < aNbNodes; iNode++)
881 (*aConnectivity)[aSize+iNode] = aVector[iNode];
885 anElemNums->push_back(anElem->GetID());
887 if (anElemFamMap.find(anElem) != anElemFamMap.end())
888 aFamilyNums->push_back(anElemFamMap[anElem]);
890 aFamilyNums->push_back(myVolumesDefaultFamilyId);
893 if(TInt aNbElems = anTetraElemNums.size()){
894 PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
898 SMDS_MED_CONNECTIVITY,
901 MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<eTETRA4<<"; aNbElems = "<<aNbElems);
902 myMed->SetCellInfo(aCellInfo);
904 if(TInt aNbElems = anPyraElemNums.size()){
905 PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
909 SMDS_MED_CONNECTIVITY,
912 MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<ePYRA5<<"; aNbElems = "<<aNbElems);
913 myMed->SetCellInfo(aCellInfo);
915 if(TInt aNbElems = anPentaElemNums.size()){
916 PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
920 SMDS_MED_CONNECTIVITY,
923 MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<ePENTA6<<"; aNbElems = "<<aNbElems);
924 myMed->SetCellInfo(aCellInfo);
926 if(TInt aNbElems = aHexaElemNums.size()){
927 PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
931 SMDS_MED_CONNECTIVITY,
934 MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<eHEXA8<<"; aNbElems = "<<aNbElems);
935 myMed->SetCellInfo(aCellInfo);
937 if(TInt aNbElems = anTetra10ElemNums.size()){
938 PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
942 SMDS_MED_CONNECTIVITY,
945 MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<eTETRA10<<"; aNbElems = "<<aNbElems);
946 myMed->SetCellInfo(aCellInfo);
948 if(TInt aNbElems = anPyra13ElemNums.size()){
949 PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
953 SMDS_MED_CONNECTIVITY,
956 MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<ePYRA13<<"; aNbElems = "<<aNbElems);
957 myMed->SetCellInfo(aCellInfo);
959 if(TInt aNbElems = anPenta15ElemNums.size()){
960 PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
964 SMDS_MED_CONNECTIVITY,
967 MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<ePENTA15<<"; aNbElems = "<<aNbElems);
968 myMed->SetCellInfo(aCellInfo);
970 if(TInt aNbElems = aHexa20ElemNums.size()){
971 PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
975 SMDS_MED_CONNECTIVITY,
978 MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<eHEXA20<<"; aNbElems = "<<aNbElems);
979 myMed->SetCellInfo(aCellInfo);
982 if(TInt aNbElems = aPolyedreElemNums.size()){
983 // add one element in connectivities,
984 // referenced by the last element in faces
985 aPolyedreConn.push_back(0);
987 PPolyedreInfo aCellInfo = myMed->CrPolyedreInfo(aMeshInfo,
993 SMDS_MED_CONNECTIVITY,
996 MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<ePOLYEDRE<<"; aNbElems = "<<aNbElems);
997 myMed->SetPolyedreInfo(aCellInfo);
1001 catch(const std::exception& exc) {
1002 INFOS("Follow exception was cought:\n\t"<<exc.what());
1006 INFOS("Unknown exception was cought !!!");
1012 mySubMeshes.clear();