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 string DriverMED_W_SMESHDS_Mesh::GetVersionString(const MED::EVersion theVersion, int theNbDigits)
71 TInt majeur, mineur, release;
72 majeur = mineur = release = 0;
73 if ( theVersion == eV2_1 )
74 MED::GetVersionRelease<eV2_1>(majeur, mineur, release);
76 MED::GetVersionRelease<eV2_2>(majeur, mineur, release);
78 if ( theNbDigits > 0 )
80 if ( theNbDigits > 1 )
81 name << "." << mineur;
82 if ( theNbDigits > 2 )
83 name << "." << release;
87 void DriverMED_W_SMESHDS_Mesh::SetMeshName(const std::string& theMeshName)
89 myMeshName = theMeshName;
92 void DriverMED_W_SMESHDS_Mesh::AddGroup(SMESHDS_GroupBase* theGroup)
94 myGroups.push_back(theGroup);
97 void DriverMED_W_SMESHDS_Mesh::AddAllSubMeshes()
99 myAllSubMeshes = true;
102 void DriverMED_W_SMESHDS_Mesh::AddSubMesh(SMESHDS_SubMesh* theSubMesh, int theID)
104 mySubMeshes[theID] = theSubMesh;
107 void DriverMED_W_SMESHDS_Mesh::AddGroupOfNodes()
109 myDoGroupOfNodes = true;
112 void DriverMED_W_SMESHDS_Mesh::AddGroupOfEdges()
114 myDoGroupOfEdges = true;
117 void DriverMED_W_SMESHDS_Mesh::AddGroupOfFaces()
119 myDoGroupOfFaces = true;
122 void DriverMED_W_SMESHDS_Mesh::AddGroupOfVolumes()
124 myDoGroupOfVolumes = true;
128 typedef double (SMDS_MeshNode::* TGetCoord)() const;
129 typedef const char* TName;
130 typedef const char* TUnit;
132 // name length in a mesh must be equal to 16 :
139 TUnit aUnit[3] = {M,M,M};
142 TGetCoord aXYZGetCoord[3] = {
147 TName aXYZName[3] = {X,Y,Z};
150 TGetCoord aXYGetCoord[2] = {
154 TName aXYName[2] = {X,Y};
156 TGetCoord aYZGetCoord[2] = {
160 TName aYZName[2] = {Y,Z};
162 TGetCoord aXZGetCoord[2] = {
166 TName aXZName[2] = {X,Z};
169 TGetCoord aXGetCoord[1] = {
172 TName aXName[1] = {X};
174 TGetCoord aYGetCoord[1] = {
177 TName aYName[1] = {Y};
179 TGetCoord aZGetCoord[1] = {
182 TName aZName[1] = {Z};
186 SMDS_NodeIteratorPtr myNodeIter;
187 const SMDS_MeshNode* myCurrentNode;
188 TGetCoord* myGetCoord;
192 TCoordHelper(const SMDS_NodeIteratorPtr& theNodeIter,
193 TGetCoord* theGetCoord,
195 TUnit* theUnit = aUnit):
196 myNodeIter(theNodeIter),
197 myGetCoord(theGetCoord),
201 virtual ~TCoordHelper(){}
203 return myNodeIter->more() &&
204 (myCurrentNode = myNodeIter->next());
206 const SMDS_MeshNode* GetNode(){
207 return myCurrentNode;
209 MED::TIntVector::value_type GetID(){
210 return myCurrentNode->GetID();
212 MED::TFloatVector::value_type GetCoord(TInt theCoodId){
213 return (myCurrentNode->*myGetCoord[theCoodId])();
215 MED::TStringVector::value_type GetName(TInt theDimId){
216 return myName[theDimId];
218 MED::TStringVector::value_type GetUnit(TInt theDimId){
219 return myUnit[theDimId];
222 typedef boost::shared_ptr<TCoordHelper> TCoordHelperPtr;
227 Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
229 Status aResult = DRS_OK;
230 if (myMesh->hasConstructionEdges() || myMesh->hasConstructionFaces()) {
231 INFOS("SMDS_MESH with hasConstructionEdges() or hasConstructionFaces() do not supports!!!");
235 MESSAGE("Perform - myFile : "<<myFile);
237 // Creating the MED mesh for corresponding SMDS structure
238 //-------------------------------------------------------
240 if (myMeshId != -1) {
241 ostringstream aMeshNameStr;
242 aMeshNameStr<<myMeshId;
243 aMeshName = aMeshNameStr.str();
245 aMeshName = myMeshName;
248 // Mesh dimension definition
250 TCoordHelperPtr aCoordHelperPtr;
252 bool anIsXDimension = false;
253 bool anIsYDimension = false;
254 bool anIsZDimension = false;
256 SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator();
258 if(aNodesIter->more()){
259 const SMDS_MeshNode* aNode = aNodesIter->next();
260 aBounds[0] = aBounds[1] = aNode->X();
261 aBounds[2] = aBounds[3] = aNode->Y();
262 aBounds[4] = aBounds[5] = aNode->Z();
264 while(aNodesIter->more()){
265 const SMDS_MeshNode* aNode = aNodesIter->next();
266 aBounds[0] = min(aBounds[0],aNode->X());
267 aBounds[1] = max(aBounds[1],aNode->X());
269 aBounds[2] = min(aBounds[2],aNode->Y());
270 aBounds[3] = max(aBounds[3],aNode->Y());
272 aBounds[4] = min(aBounds[4],aNode->Z());
273 aBounds[5] = max(aBounds[5],aNode->Z());
277 anIsXDimension = (aBounds[1] - aBounds[0]) + abs(aBounds[1]) + abs(aBounds[0]) > EPS;
278 anIsYDimension = (aBounds[3] - aBounds[2]) + abs(aBounds[3]) + abs(aBounds[2]) > EPS;
279 anIsZDimension = (aBounds[5] - aBounds[4]) + abs(aBounds[5]) + abs(aBounds[4]) > EPS;
280 aMeshDimension = anIsXDimension + anIsYDimension + anIsZDimension;
283 // PAL16857(SMESH not conform to the MED convention):
284 if ( aMeshDimension == 2 && anIsZDimension ) // 2D only if mesh is in XOY plane
286 // PAL18941(a saved study with a mesh belong Z is opened and the mesh is belong X)
287 if ( aMeshDimension == 1 && !anIsXDimension ) // 1D only if mesh is along OX
288 if ( anIsYDimension ) {
290 anIsXDimension = true;
296 SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator();
297 switch(aMeshDimension){
299 aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXYZGetCoord,aXYZName));
302 if(anIsXDimension && anIsYDimension)
303 aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXYGetCoord,aXYName));
304 if(anIsYDimension && anIsZDimension)
305 aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aYZGetCoord,aYZName));
306 if(anIsXDimension && anIsZDimension)
307 aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXZGetCoord,aXZName));
311 aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXGetCoord,aXName));
313 aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aYGetCoord,aYName));
315 aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aZGetCoord,aZName));
321 PMeshInfo aMeshInfo = myMed->CrMeshInfo(aMeshDimension,aMeshName);
322 MESSAGE("Add - aMeshName : "<<aMeshName<<"; "<<aMeshInfo->GetName());
323 myMed->SetMeshInfo(aMeshInfo);
325 // Storing SMDS groups and sub-meshes
326 //-----------------------------------
327 int myNodesDefaultFamilyId = 0;
328 int myEdgesDefaultFamilyId = 0;
329 int myFacesDefaultFamilyId = 0;
330 int myVolumesDefaultFamilyId = 0;
331 int nbNodes = myMesh->NbNodes();
332 int nbEdges = myMesh->NbEdges();
333 int nbFaces = myMesh->NbFaces();
334 int nbVolumes = myMesh->NbVolumes();
335 if (myDoGroupOfNodes && nbNodes)
336 myNodesDefaultFamilyId = REST_NODES_FAMILY;
337 if (myDoGroupOfEdges && nbEdges)
338 myEdgesDefaultFamilyId = REST_EDGES_FAMILY;
339 if (myDoGroupOfFaces && nbFaces)
340 myFacesDefaultFamilyId = REST_FACES_FAMILY;
341 if (myDoGroupOfVolumes && nbVolumes)
342 myVolumesDefaultFamilyId = REST_VOLUMES_FAMILY;
344 MESSAGE("Perform - aFamilyInfo");
345 map<const SMDS_MeshElement *, int> anElemFamMap;
346 list<DriverMED_FamilyPtr> aFamilies;
347 if (myAllSubMeshes) {
348 aFamilies = DriverMED_Family::MakeFamilies
349 (myMesh->SubMeshes(), myGroups,
350 myDoGroupOfNodes && nbNodes,
351 myDoGroupOfEdges && nbEdges,
352 myDoGroupOfFaces && nbFaces,
353 myDoGroupOfVolumes && nbVolumes);
355 aFamilies = DriverMED_Family::MakeFamilies
356 (mySubMeshes, myGroups,
357 myDoGroupOfNodes && nbNodes,
358 myDoGroupOfEdges && nbEdges,
359 myDoGroupOfFaces && nbFaces,
360 myDoGroupOfVolumes && nbVolumes);
362 list<DriverMED_FamilyPtr>::iterator aFamsIter = aFamilies.begin();
364 for (; aFamsIter != aFamilies.end(); aFamsIter++)
366 PFamilyInfo aFamilyInfo = (*aFamsIter)->GetFamilyInfo(myMed,aMeshInfo);
367 myMed->SetFamilyInfo(aFamilyInfo);
368 int aFamId = (*aFamsIter)->GetId();
370 const set<const SMDS_MeshElement *>& anElems = (*aFamsIter)->GetElements();
371 set<const SMDS_MeshElement *>::const_iterator anElemsIter = anElems.begin();
372 for (; anElemsIter != anElems.end(); anElemsIter++)
374 anElemFamMap[*anElemsIter] = aFamId;
378 // Storing SMDS nodes to the MED file for the MED mesh
379 //----------------------------------------------------
380 #ifdef _EDF_NODE_IDS_
381 typedef map<TInt,TInt> TNodeIdMap;
382 TNodeIdMap aNodeIdMap;
384 TInt aNbElems = myMesh->NbNodes();
385 MED::TIntVector anElemNums(aNbElems);
386 MED::TIntVector aFamilyNums(aNbElems);
387 MED::TFloatVector aCoordinates(aNbElems*aMeshDimension);
388 for(TInt iNode = 0, aStartId = 0; aCoordHelperPtr->Next(); iNode++, aStartId += aMeshDimension){
389 for(TInt iCoord = 0; iCoord < aMeshDimension; iCoord++){
390 aCoordinates[aStartId+iCoord] = aCoordHelperPtr->GetCoord(iCoord);
392 int aNodeID = aCoordHelperPtr->GetID();
393 anElemNums[iNode] = aNodeID;
394 #ifdef _EDF_NODE_IDS_
395 aNodeIdMap[aNodeID] = iNode+1;
397 const SMDS_MeshNode* aNode = aCoordHelperPtr->GetNode();
398 if (anElemFamMap.find(aNode) != anElemFamMap.end())
399 aFamilyNums[iNode] = anElemFamMap[aNode];
401 aFamilyNums[iNode] = myNodesDefaultFamilyId;
404 MED::TStringVector aCoordNames(aMeshDimension);
405 MED::TStringVector aCoordUnits(aMeshDimension);
406 for(TInt iCoord = 0; iCoord < aMeshDimension; iCoord++){
407 aCoordNames[iCoord] = aCoordHelperPtr->GetName(iCoord);
408 aCoordUnits[iCoord] = aCoordHelperPtr->GetUnit(iCoord);
411 const ERepere SMDS_COORDINATE_SYSTEM = eCART;
413 PNodeInfo aNodeInfo = myMed->CrNodeInfo(aMeshInfo,
416 SMDS_COORDINATE_SYSTEM,
421 MESSAGE("Perform - aNodeInfo->GetNbElem() = "<<aNbElems);
422 myMed->SetNodeInfo(aNodeInfo);
425 // Storing others SMDS elements to the MED file for the MED mesh
426 //--------------------------------------------------------------
427 EEntiteMaillage SMDS_MED_ENTITY = eMAILLE;
428 const EConnectivite SMDS_MED_CONNECTIVITY = eNOD;
430 // Storing SMDS Edges
431 if(TInt aNbElems = myMesh->NbEdges()){
432 #ifdef _ELEMENTS_BY_DIM_
433 SMDS_MED_ENTITY = eARETE;
435 // count edges of diff types
436 int aNbSeg3 = 0, aNbSeg2 = 0;
437 SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator();
438 while ( anIter->more() )
439 if ( anIter->next()->NbNodes() == 3 )
441 aNbSeg2 = aNbElems - aNbSeg3;
443 TInt aNbSeg2Conn = MED::GetNbNodes(eSEG2);
444 MED::TIntVector aSeg2ElemNums, aSeg2FamilyNums, aSeg2Conn;
445 aSeg2ElemNums .reserve( aNbSeg2 );
446 aSeg2FamilyNums.reserve( aNbSeg2 );
447 aSeg2Conn .reserve( aNbSeg2*aNbSeg2Conn );
449 TInt aNbSeg3Conn = MED::GetNbNodes(eSEG3);
450 MED::TIntVector aSeg3ElemNums, aSeg3FamilyNums, aSeg3Conn;
451 aSeg3ElemNums .reserve( aNbSeg3 );
452 aSeg3FamilyNums.reserve( aNbSeg3 );
453 aSeg3Conn .reserve( aNbSeg3*aNbSeg3Conn );
455 anIter = myMesh->edgesIterator();
456 while ( anIter->more() ) {
457 const SMDS_MeshEdge* anElem = anIter->next();
458 TInt aNbNodes = anElem->NbNodes();
460 TInt aNbConnectivity;
461 MED::TIntVector* anElemNums;
462 MED::TIntVector* aFamilyNums;
463 MED::TIntVector* aConnectivity;
466 aNbConnectivity = aNbSeg2Conn;
467 anElemNums = &aSeg2ElemNums;
468 aFamilyNums = &aSeg2FamilyNums;
469 aConnectivity = &aSeg2Conn;
472 aNbConnectivity = aNbSeg3Conn;
473 anElemNums = &aSeg3ElemNums;
474 aFamilyNums = &aSeg3FamilyNums;
475 aConnectivity = &aSeg3Conn;
481 for(TInt iNode = 0; iNode < aNbNodes; iNode++) {
482 const SMDS_MeshElement* aNode = anElem->GetNode( iNode );
483 #ifdef _EDF_NODE_IDS_
484 aConnectivity->push_back( aNodeIdMap[aNode->GetID()] );
486 aConnectivity->push_back( aNode->GetID() );
490 anElemNums->push_back(anElem->GetID());
492 map<const SMDS_MeshElement*,int>::iterator edge_fam = anElemFamMap.find( anElem );
493 if ( edge_fam != anElemFamMap.end() )
494 aFamilyNums->push_back( edge_fam->second );
496 aFamilyNums->push_back( myEdgesDefaultFamilyId );
500 PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
504 SMDS_MED_CONNECTIVITY,
507 myMed->SetCellInfo(aCellInfo);
510 PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
514 SMDS_MED_CONNECTIVITY,
517 myMed->SetCellInfo(aCellInfo);
521 // Storing SMDS Faces
522 if(TInt aNbElems = myMesh->NbFaces()){
523 SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
524 #ifdef _ELEMENTS_BY_DIM_
525 SMDS_MED_ENTITY = eFACE;
527 TInt aNbTriaConn = MED::GetNbNodes(eTRIA3);
528 MED::TIntVector anTriaElemNums;
529 anTriaElemNums.reserve(aNbElems);
530 MED::TIntVector aTriaFamilyNums;
531 aTriaFamilyNums.reserve(aNbElems);
532 MED::TIntVector aTriaConn;
533 aTriaConn.reserve(aNbElems*aNbTriaConn);
535 TInt aNbTria6Conn = MED::GetNbNodes(eTRIA6);
536 MED::TIntVector anTria6ElemNums;
537 anTria6ElemNums.reserve(aNbElems);
538 MED::TIntVector aTria6FamilyNums;
539 aTria6FamilyNums.reserve(aNbElems);
540 MED::TIntVector aTria6Conn;
541 aTria6Conn.reserve(aNbElems*aNbTria6Conn);
543 TInt aNbQuadConn = MED::GetNbNodes(eQUAD4);
544 MED::TIntVector aQuadElemNums;
545 aQuadElemNums.reserve(aNbElems);
546 MED::TIntVector aQuadFamilyNums;
547 aQuadFamilyNums.reserve(aNbElems);
548 MED::TIntVector aQuadConn;
549 aQuadConn.reserve(aNbElems*aNbQuadConn);
551 TInt aNbQuad8Conn = MED::GetNbNodes(eQUAD8);
552 MED::TIntVector aQuad8ElemNums;
553 aQuad8ElemNums.reserve(aNbElems);
554 MED::TIntVector aQuad8FamilyNums;
555 aQuad8FamilyNums.reserve(aNbElems);
556 MED::TIntVector aQuad8Conn;
557 aQuad8Conn.reserve(aNbElems*aNbQuad8Conn);
559 MED::TIntVector aPolygoneElemNums;
560 aPolygoneElemNums.reserve(aNbElems);
561 MED::TIntVector aPolygoneInds;
562 aPolygoneInds.reserve(aNbElems + 1);
563 aPolygoneInds.push_back(1); // reference on the first element in the connectivities
564 MED::TIntVector aPolygoneFamilyNums;
565 aPolygoneFamilyNums.reserve(aNbElems);
566 MED::TIntVector aPolygoneConn;
567 aPolygoneConn.reserve(aNbElems*aNbQuadConn);
569 for(TInt iElem = 0; iElem < aNbElems && anIter->more(); iElem++){
570 const SMDS_MeshFace* anElem = anIter->next();
571 TInt aNbNodes = anElem->NbNodes();
572 SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
573 TInt aNbConnectivity;
574 MED::TIntVector* anElemNums;
575 MED::TIntVector* aFamilyNums;
576 MED::TIntVector* aConnectivity;
577 if (anElem->IsPoly()) {
578 aNbConnectivity = aNbNodes;
579 anElemNums = &aPolygoneElemNums;
580 aFamilyNums = &aPolygoneFamilyNums;
581 aConnectivity = &aPolygoneConn;
586 aNbConnectivity = aNbTriaConn;
587 anElemNums = &anTriaElemNums;
588 aFamilyNums = &aTriaFamilyNums;
589 aConnectivity = &aTriaConn;
592 aNbConnectivity = aNbQuadConn;
593 anElemNums = &aQuadElemNums;
594 aFamilyNums = &aQuadFamilyNums;
595 aConnectivity = &aQuadConn;
598 aNbConnectivity = aNbTria6Conn;
599 anElemNums = &anTria6ElemNums;
600 aFamilyNums = &aTria6FamilyNums;
601 aConnectivity = &aTria6Conn;
604 aNbConnectivity = aNbQuad8Conn;
605 anElemNums = &aQuad8ElemNums;
606 aFamilyNums = &aQuad8FamilyNums;
607 aConnectivity = &aQuad8Conn;
613 MED::TIntVector aVector(aNbNodes);
614 for(TInt iNode = 0; aNodesIter->more(); iNode++){
615 const SMDS_MeshElement* aNode = aNodesIter->next();
616 #ifdef _EDF_NODE_IDS_
617 aVector[iNode] = aNodeIdMap[aNode->GetID()];
619 aVector[iNode] = aNode->GetID();
623 TInt aSize = aConnectivity->size();
624 aConnectivity->resize(aSize+aNbConnectivity);
625 // There is some differences between SMDS and MED in cells mapping
628 (*aConnectivity)[aSize+0] = aVector[0];
629 (*aConnectivity)[aSize+1] = aVector[1];
630 (*aConnectivity)[aSize+2] = aVector[3];
631 (*aConnectivity)[aSize+3] = aVector[2];
633 for(TInt iNode = 0; iNode < aNbNodes; iNode++)
634 (*aConnectivity)[aSize+iNode] = aVector[iNode];
637 if (anElem->IsPoly()) {
638 // fill indices for polygonal element
639 TInt aPrevPos = aPolygoneInds.back();
640 aPolygoneInds.push_back(aPrevPos + aNbNodes);
643 anElemNums->push_back(anElem->GetID());
645 if (anElemFamMap.find(anElem) != anElemFamMap.end())
646 aFamilyNums->push_back(anElemFamMap[anElem]);
648 aFamilyNums->push_back(myFacesDefaultFamilyId);
650 if(TInt aNbElems = anTriaElemNums.size()){
651 PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
655 SMDS_MED_CONNECTIVITY,
658 MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<eTRIA3<<"; aNbElems = "<<aNbElems);
659 myMed->SetCellInfo(aCellInfo);
661 if(TInt aNbElems = aQuadElemNums.size()){
662 PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
666 SMDS_MED_CONNECTIVITY,
669 MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<eQUAD4<<"; aNbElems = "<<aNbElems);
670 myMed->SetCellInfo(aCellInfo);
672 if(TInt aNbElems = anTria6ElemNums.size()){
673 PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
677 SMDS_MED_CONNECTIVITY,
680 MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<eTRIA6<<"; aNbElems = "<<aNbElems);
681 myMed->SetCellInfo(aCellInfo);
683 if(TInt aNbElems = aQuad8ElemNums.size()){
684 PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
688 SMDS_MED_CONNECTIVITY,
691 MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<eQUAD8<<"; aNbElems = "<<aNbElems);
692 myMed->SetCellInfo(aCellInfo);
694 if(TInt aNbElems = aPolygoneElemNums.size()){
695 // add one element in connectivities,
696 // referenced by the last element in indices
697 aPolygoneConn.push_back(0);
699 PPolygoneInfo aCellInfo = myMed->CrPolygoneInfo(aMeshInfo,
704 SMDS_MED_CONNECTIVITY,
707 MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<ePOLYGONE<<"; aNbElems = "<<aNbElems);
708 myMed->SetPolygoneInfo(aCellInfo);
712 // Storing SMDS Volumes
713 if(TInt aNbElems = myMesh->NbVolumes()){
714 SMDS_VolumeIteratorPtr anIter = myMesh->volumesIterator();
715 #ifdef _ELEMENTS_BY_DIM_
716 SMDS_MED_ENTITY = eMAILLE;
718 TInt aNbTetraConn = MED::GetNbNodes(eTETRA4);
719 MED::TIntVector anTetraElemNums;
720 anTetraElemNums.reserve(aNbElems);
721 MED::TIntVector aTetraFamilyNums;
722 aTetraFamilyNums.reserve(aNbElems);
723 MED::TIntVector aTetraConn;
724 aTetraConn.reserve(aNbElems*aNbTetraConn);
726 TInt aNbPyraConn = MED::GetNbNodes(ePYRA5);
727 MED::TIntVector anPyraElemNums;
728 anPyraElemNums.reserve(aNbElems);
729 MED::TIntVector aPyraFamilyNums;
730 aPyraFamilyNums.reserve(aNbElems);
731 MED::TIntVector aPyraConn;
732 aPyraConn.reserve(aNbElems*aNbPyraConn);
734 TInt aNbPentaConn = MED::GetNbNodes(ePENTA6);
735 MED::TIntVector anPentaElemNums;
736 anPentaElemNums.reserve(aNbElems);
737 MED::TIntVector aPentaFamilyNums;
738 aPentaFamilyNums.reserve(aNbElems);
739 MED::TIntVector aPentaConn;
740 aPentaConn.reserve(aNbElems*aNbPentaConn);
742 TInt aNbHexaConn = MED::GetNbNodes(eHEXA8);
743 MED::TIntVector aHexaElemNums;
744 aHexaElemNums.reserve(aNbElems);
745 MED::TIntVector aHexaFamilyNums;
746 aHexaFamilyNums.reserve(aNbElems);
747 MED::TIntVector aHexaConn;
748 aHexaConn.reserve(aNbElems*aNbHexaConn);
750 TInt aNbTetra10Conn = MED::GetNbNodes(eTETRA10);
751 MED::TIntVector anTetra10ElemNums;
752 anTetra10ElemNums.reserve(aNbElems);
753 MED::TIntVector aTetra10FamilyNums;
754 aTetra10FamilyNums.reserve(aNbElems);
755 MED::TIntVector aTetra10Conn;
756 aTetra10Conn.reserve(aNbElems*aNbTetra10Conn);
758 TInt aNbPyra13Conn = MED::GetNbNodes(ePYRA13);
759 MED::TIntVector anPyra13ElemNums;
760 anPyra13ElemNums.reserve(aNbElems);
761 MED::TIntVector aPyra13FamilyNums;
762 aPyra13FamilyNums.reserve(aNbElems);
763 MED::TIntVector aPyra13Conn;
764 aPyra13Conn.reserve(aNbElems*aNbPyra13Conn);
766 TInt aNbPenta15Conn = MED::GetNbNodes(ePENTA15);
767 MED::TIntVector anPenta15ElemNums;
768 anPenta15ElemNums.reserve(aNbElems);
769 MED::TIntVector aPenta15FamilyNums;
770 aPenta15FamilyNums.reserve(aNbElems);
771 MED::TIntVector aPenta15Conn;
772 aPenta15Conn.reserve(aNbElems*aNbPenta15Conn);
774 TInt aNbHexa20Conn = MED::GetNbNodes(eHEXA20);
775 MED::TIntVector aHexa20ElemNums;
776 aHexa20ElemNums.reserve(aNbElems);
777 MED::TIntVector aHexa20FamilyNums;
778 aHexa20FamilyNums.reserve(aNbElems);
779 MED::TIntVector aHexa20Conn;
780 aHexa20Conn.reserve(aNbElems*aNbHexa20Conn);
782 MED::TIntVector aPolyedreElemNums;
783 aPolyedreElemNums.reserve(aNbElems);
784 MED::TIntVector aPolyedreInds;
785 aPolyedreInds.reserve(aNbElems + 1);
786 aPolyedreInds.push_back(1); // reference on the first element in the faces
787 MED::TIntVector aPolyedreFaces;
788 aPolyedreFaces.reserve(aNbElems + 1);
789 aPolyedreFaces.push_back(1); // reference on the first element in the connectivities
790 MED::TIntVector aPolyedreFamilyNums;
791 aPolyedreFamilyNums.reserve(aNbElems);
792 MED::TIntVector aPolyedreConn;
793 aPolyedreConn.reserve(aNbElems*aNbHexaConn);
795 for(TInt iElem = 0; iElem < aNbElems && anIter->more(); iElem++){
796 const SMDS_MeshVolume* anElem = anIter->next();
798 MED::TIntVector* anElemNums;
799 MED::TIntVector* aFamilyNums;
801 if (anElem->IsPoly()) {
802 const SMDS_PolyhedralVolumeOfNodes* aPolyedre =
803 (const SMDS_PolyhedralVolumeOfNodes*) anElem;
805 MESSAGE("Warning: bad volumic element");
809 anElemNums = &aPolyedreElemNums;
810 aFamilyNums = &aPolyedreFamilyNums;
812 TInt aNodeId, aNbFaces = aPolyedre->NbFaces();
813 for (int iface = 1; iface <= aNbFaces; iface++) {
814 int aNbFaceNodes = aPolyedre->NbFaceNodes(iface);
815 for (int inode = 1; inode <= aNbFaceNodes; inode++) {
816 aNodeId = aPolyedre->GetFaceNode(iface, inode)->GetID();
817 #ifdef _EDF_NODE_IDS_
818 aPolyedreConn.push_back(aNodeIdMap[aNodeId]);
820 aPolyedreConn.push_back(aNodeId);
823 TInt aPrevPos = aPolyedreFaces.back();
824 aPolyedreFaces.push_back(aPrevPos + aNbFaceNodes);
826 TInt aPrevPos = aPolyedreInds.back();
827 aPolyedreInds.push_back(aPrevPos + aNbFaces);
831 TInt aNbNodes = anElem->NbNodes();
832 SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
833 TInt aNbConnectivity;
834 MED::TIntVector* aConnectivity;
837 aNbConnectivity = aNbTetraConn;
838 anElemNums = &anTetraElemNums;
839 aFamilyNums = &aTetraFamilyNums;
840 aConnectivity = &aTetraConn;
843 aNbConnectivity = aNbPyraConn;
844 anElemNums = &anPyraElemNums;
845 aFamilyNums = &aPyraFamilyNums;
846 aConnectivity = &aPyraConn;
849 aNbConnectivity = aNbPentaConn;
850 anElemNums = &anPentaElemNums;
851 aFamilyNums = &aPentaFamilyNums;
852 aConnectivity = &aPentaConn;
855 aNbConnectivity = aNbHexaConn;
856 anElemNums = &aHexaElemNums;
857 aFamilyNums = &aHexaFamilyNums;
858 aConnectivity = &aHexaConn;
861 aNbConnectivity = aNbTetra10Conn;
862 anElemNums = &anTetra10ElemNums;
863 aFamilyNums = &aTetra10FamilyNums;
864 aConnectivity = &aTetra10Conn;
867 aNbConnectivity = aNbPyra13Conn;
868 anElemNums = &anPyra13ElemNums;
869 aFamilyNums = &aPyra13FamilyNums;
870 aConnectivity = &aPyra13Conn;
873 aNbConnectivity = aNbPenta15Conn;
874 anElemNums = &anPenta15ElemNums;
875 aFamilyNums = &aPenta15FamilyNums;
876 aConnectivity = &aPenta15Conn;
879 aNbConnectivity = aNbHexa20Conn;
880 anElemNums = &aHexa20ElemNums;
881 aFamilyNums = &aHexa20FamilyNums;
882 aConnectivity = &aHexa20Conn;
885 TInt aSize = aConnectivity->size();
886 aConnectivity->resize(aSize + aNbConnectivity);
888 MED::TIntVector aVector(aNbNodes);
889 for(TInt iNode = 0; aNodesIter->more(); iNode++){
890 const SMDS_MeshElement* aNode = aNodesIter->next();
891 #ifdef _EDF_NODE_IDS_
892 aVector[iNode] = aNodeIdMap[aNode->GetID()];
894 aVector[iNode] = aNode->GetID();
897 // There is some difference between SMDS and MED in cells mapping
900 (*aConnectivity)[aSize+0] = aVector[0];
901 (*aConnectivity)[aSize+1] = aVector[3];
902 (*aConnectivity)[aSize+2] = aVector[2];
903 (*aConnectivity)[aSize+3] = aVector[1];
904 (*aConnectivity)[aSize+4] = aVector[4];
906 for(TInt iNode = 0; iNode < aNbNodes; iNode++)
907 (*aConnectivity)[aSize+iNode] = aVector[iNode];
911 anElemNums->push_back(anElem->GetID());
913 if (anElemFamMap.find(anElem) != anElemFamMap.end())
914 aFamilyNums->push_back(anElemFamMap[anElem]);
916 aFamilyNums->push_back(myVolumesDefaultFamilyId);
919 if(TInt aNbElems = anTetraElemNums.size()){
920 PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
924 SMDS_MED_CONNECTIVITY,
927 MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<eTETRA4<<"; aNbElems = "<<aNbElems);
928 myMed->SetCellInfo(aCellInfo);
930 if(TInt aNbElems = anPyraElemNums.size()){
931 PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
935 SMDS_MED_CONNECTIVITY,
938 MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<ePYRA5<<"; aNbElems = "<<aNbElems);
939 myMed->SetCellInfo(aCellInfo);
941 if(TInt aNbElems = anPentaElemNums.size()){
942 PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
946 SMDS_MED_CONNECTIVITY,
949 MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<ePENTA6<<"; aNbElems = "<<aNbElems);
950 myMed->SetCellInfo(aCellInfo);
952 if(TInt aNbElems = aHexaElemNums.size()){
953 PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
957 SMDS_MED_CONNECTIVITY,
960 MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<eHEXA8<<"; aNbElems = "<<aNbElems);
961 myMed->SetCellInfo(aCellInfo);
963 if(TInt aNbElems = anTetra10ElemNums.size()){
964 PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
968 SMDS_MED_CONNECTIVITY,
971 MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<eTETRA10<<"; aNbElems = "<<aNbElems);
972 myMed->SetCellInfo(aCellInfo);
974 if(TInt aNbElems = anPyra13ElemNums.size()){
975 PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
979 SMDS_MED_CONNECTIVITY,
982 MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<ePYRA13<<"; aNbElems = "<<aNbElems);
983 myMed->SetCellInfo(aCellInfo);
985 if(TInt aNbElems = anPenta15ElemNums.size()){
986 PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
990 SMDS_MED_CONNECTIVITY,
993 MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<ePENTA15<<"; aNbElems = "<<aNbElems);
994 myMed->SetCellInfo(aCellInfo);
996 if(TInt aNbElems = aHexa20ElemNums.size()){
997 PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
1001 SMDS_MED_CONNECTIVITY,
1004 MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<eHEXA20<<"; aNbElems = "<<aNbElems);
1005 myMed->SetCellInfo(aCellInfo);
1008 if(TInt aNbElems = aPolyedreElemNums.size()){
1009 // add one element in connectivities,
1010 // referenced by the last element in faces
1011 aPolyedreConn.push_back(0);
1013 PPolyedreInfo aCellInfo = myMed->CrPolyedreInfo(aMeshInfo,
1019 SMDS_MED_CONNECTIVITY,
1020 aPolyedreFamilyNums,
1022 MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<ePOLYEDRE<<"; aNbElems = "<<aNbElems);
1023 myMed->SetPolyedreInfo(aCellInfo);
1027 catch(const std::exception& exc) {
1028 INFOS("Follow exception was cought:\n\t"<<exc.what());
1032 INFOS("Unknown exception was cought !!!");
1038 mySubMeshes.clear();