X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FDriverMED%2FDriverMED_W_SMESHDS_Mesh.cxx;h=1b3c26bac11ab5e2120c601832686403dc5b2792;hp=5665790ad410454e3263633d426f830389f39b22;hb=77ab84920942791849f9fdbd567da6701acfca7f;hpb=f7fbf1c62246f439c35746c731f64dab57391c1b diff --git a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx index 5665790ad..1b3c26bac 100644 --- a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx +++ b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx @@ -1,691 +1,1004 @@ -// SMESH DriverMED : driver to read and write 'med' files +// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. // +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH DriverMED : driver to read and write 'med' files // File : DriverMED_W_SMESHDS_Mesh.cxx // Module : SMESH +// -using namespace std; #include "DriverMED_W_SMESHDS_Mesh.h" -#include "DriverMED_W_SMDS_Mesh.h" + +#include "DriverMED_Family.h" +#include "MED_Factory.hxx" +#include "MED_Utilities.hxx" +#include "SMDS_IteratorOnIterators.hxx" #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" -#include -#include -#include "utilities.h" +#include "SMDS_PolyhedralVolumeOfNodes.hxx" +#include "SMDS_SetIterator.hxx" +#include "SMESHDS_Mesh.hxx" -DriverMED_W_SMESHDS_Mesh::DriverMED_W_SMESHDS_Mesh() +#include +#include +#include + +#include + + +#define _EDF_NODE_IDS_ +//#define _ELEMENTS_BY_DIM_ + +using namespace std; +using namespace MED; + + +DriverMED_W_SMESHDS_Mesh::DriverMED_W_SMESHDS_Mesh(): + myMedVersion(MED::eV2_2), + myAllSubMeshes (false), + myDoGroupOfNodes (false), + myDoGroupOfEdges (false), + myDoGroupOfFaces (false), + myDoGroupOfVolumes (false), + myDoGroupOf0DElems(false), + myDoGroupOfBalls(false), + myAutoDimension(true), + myAddODOnVertices(false) +{} + +void DriverMED_W_SMESHDS_Mesh::SetFile(const std::string& theFileName, + MED::EVersion theId) { - ; + Driver_SMESHDS_Mesh::SetFile(theFileName); + myMedVersion = theId; } -DriverMED_W_SMESHDS_Mesh::~DriverMED_W_SMESHDS_Mesh() +void DriverMED_W_SMESHDS_Mesh::SetFile(const std::string& theFileName) { - ; + Driver_SMESHDS_Mesh::SetFile(theFileName); } -void DriverMED_W_SMESHDS_Mesh::SetMesh(SMDS_Mesh * aMesh) +string DriverMED_W_SMESHDS_Mesh::GetVersionString(const MED::EVersion theVersion, int theNbDigits) { - myMesh = aMesh; + TInt majeur, mineur, release; + majeur = mineur = release = 0; +// if ( theVersion == eV2_1 ) +// MED::GetVersionRelease(majeur, mineur, release); +// else + MED::GetVersionRelease(majeur, mineur, release); + ostringstream name; + if ( theNbDigits > 0 ) + name << majeur; + if ( theNbDigits > 1 ) + name << "." << mineur; + if ( theNbDigits > 2 ) + name << "." << release; + return name.str(); } -void DriverMED_W_SMESHDS_Mesh::SetFile(string aFile) +void DriverMED_W_SMESHDS_Mesh::AddGroup(SMESHDS_GroupBase* theGroup) { - myFile = aFile; + myGroups.push_back(theGroup); } -void DriverMED_W_SMESHDS_Mesh::SetFileId(med_idt aFileId) +void DriverMED_W_SMESHDS_Mesh::AddAllSubMeshes() { - myFileId = aFileId; + myAllSubMeshes = true; } -void DriverMED_W_SMESHDS_Mesh::SetMeshId(int aMeshId) +void DriverMED_W_SMESHDS_Mesh::AddSubMesh(SMESHDS_SubMesh* theSubMesh, int theID) { - myMeshId = aMeshId; + mySubMeshes.push_back( theSubMesh ); } -void DriverMED_W_SMESHDS_Mesh::Write() +void DriverMED_W_SMESHDS_Mesh::AddGroupOfNodes() { - - string myClass = string("SMDS_Mesh"); - string myExtension = string("MED"); - - DriverMED_W_SMDS_Mesh *myWriter = new DriverMED_W_SMDS_Mesh; - - myWriter->SetMesh(myMesh); - // myWriter->SetFile(myFile); - myWriter->SetMeshId(myMeshId); - myWriter->SetFileId(myFileId); - - myWriter->Write(); - + myDoGroupOfNodes = true; } -void DriverMED_W_SMESHDS_Mesh::Add() +void DriverMED_W_SMESHDS_Mesh::AddGroupOfEdges() { - - med_err ret = 0; - int i, j, k, l; - int numero; - char message[200]; - bool ok; - /* nombre d'objets MED */ - char nom_universel[MED_TAILLE_LNOM + 1]; - med_int long_fichier_en_tete; - char *fichier_en_tete; - char version_hdf[10]; - char version_med[10]; - med_int nmaa, mdim, nnoe; - med_int nmai[MED_NBR_GEOMETRIE_MAILLE], nfac[MED_NBR_GEOMETRIE_FACE]; - med_int nare[MED_NBR_GEOMETRIE_ARETE]; - /* nom du maillage */ - char nommaa[MED_TAILLE_NOM + 1]; - /* noeuds */ - med_float *coo; - // PN : Initilialisation de nomcoo et unicoo pour lisibilite du maillage - char nomcoo[3 * MED_TAILLE_PNOM + 1] = "x y z "; - char unicoo[3 * MED_TAILLE_PNOM + 1] = "m m m "; - char *nomnoe; - med_int *numnoe; - med_int *nufano; - med_repere rep; - med_booleen inonoe, inunoe; - med_mode_switch mode_coo; - char str[MED_TAILLE_PNOM + 1]; - med_int nbNodes; - /* elements */ - med_int nsup; - med_int edim; - med_int taille; - med_int elem_id, myId; - med_int *connectivite; - char *nomele; - med_int *numele; - med_int *nufael; - med_booleen inoele, inuele; - med_connectivite typ_con; - med_geometrie_element typgeo; - med_geometrie_element typmai[MED_NBR_GEOMETRIE_MAILLE] = - { MED_POINT1, MED_SEG2, - MED_SEG3, MED_TRIA3, - MED_TRIA6, MED_QUAD4, - MED_QUAD8, MED_TETRA4, - MED_TETRA10, MED_HEXA8, - MED_HEXA20, MED_PENTA6, - MED_PENTA15, MED_PYRA5, - MED_PYRA13 - }; - med_int desmai[MED_NBR_GEOMETRIE_MAILLE] = - { 0, 2, 3, 3, 3, 4, 4, 4, 4, 6, 6, 5, 5, 5, 5 }; - med_int nmailles[MED_NBR_GEOMETRIE_MAILLE]; - char nommai[MED_NBR_GEOMETRIE_MAILLE][MED_TAILLE_NOM + 1] = { "MED_POINT1", - "MED_SEG2", - "MED_SEG3", - "MED_TRIA3", - "MED_TRIA6", - "MED_QUAD4", - "MED_QUAD8", - "MED_TETRA4", - "MED_TETRA10", - "MED_HEXA8", - "MED_HEXA20", - "MED_PENTA6", - "MED_PENTA15", - "MED_PYRA5", - "MED_PYRA13" - }; - med_geometrie_element typfac[MED_NBR_GEOMETRIE_FACE] = - { MED_TRIA3, MED_TRIA6, - MED_QUAD4, MED_QUAD8 - }; - med_int desfac[MED_NBR_GEOMETRIE_FACE] = { 3, 3, 4, 4 }; - med_int nfaces[MED_NBR_GEOMETRIE_FACE]; - char nomfac[MED_NBR_GEOMETRIE_FACE][MED_TAILLE_NOM + 1] = - { "MED_TRIA3", "MED_TRIA6", - "MED_QUAD4", "MED_QUAD8" - }; - med_geometrie_element typare[MED_NBR_GEOMETRIE_ARETE] = - { MED_SEG2, MED_SEG3 }; - med_int desare[MED_NBR_GEOMETRIE_ARETE] = { 2, 3 }; - med_int naretes[MED_NBR_GEOMETRIE_ARETE]; - char nomare[MED_NBR_GEOMETRIE_ARETE][MED_TAILLE_NOM + 1] = - { "MED_SEG2", "MED_SEG3" }; - - typ_con = MED_NOD; - mode_coo = MED_FULL_INTERLACE; - numero = myMeshId; - - //---- provisoire : switch pour ecrire les familles de mailles - int besoinfamilledemaille = 1; - //---- provisoire : switch pour ecrire les familles de mailles - - /**************************************************************************** - * OUVERTURE DU FICHIER EN ECRITURE * - ****************************************************************************/ - char *file2Read = (char *)myFile.c_str(); - - MESSAGE(" file2Read " << file2Read) - myFileId = MEDouvrir(file2Read, MED_REMP); - if (myFileId < 0) - { - fprintf(stderr, ">> ERREUR : ouverture du fichier %s \n", file2Read); - exit(EXIT_FAILURE); - } - - /**************************************************************************** - * NOMBRES D'OBJETS MED * - ****************************************************************************/ - MESSAGE("(****************************)"); - MESSAGE("(* INFORMATIONS GENERALES : *)"); - MESSAGE("(****************************)"); - - /* calcul de la dimension */ - mdim = 2; - double epsilon = 0.00001; - double nodeRefX; - double nodeRefY; - double nodeRefZ; - - bool dimX = true; - bool dimY = true; - bool dimZ = true; - - int inode = 0; - SMDS_Iterator * myItNodes=myMesh->nodesIterator(); - while(myItNodes->more()) - { - const SMDS_MeshNode * node = myItNodes->next(); - if (inode == 0) - { - nodeRefX = fabs(node->X()); - nodeRefY = fabs(node->Y()); - nodeRefZ = fabs(node->Z()); - } - SCRUTE(inode); - SCRUTE(nodeRefX); - SCRUTE(nodeRefY); - SCRUTE(nodeRefZ); - - if (inode != 0) - { - if ((fabs(fabs(node->X()) - nodeRefX) > epsilon) && dimX) - dimX = false; - if ((fabs(fabs(node->Y()) - nodeRefY) > epsilon) && dimY) - dimY = false; - if ((fabs(fabs(node->Z()) - nodeRefZ) > epsilon) && dimZ) - dimZ = false; - } - if (!dimX && !dimY && !dimZ) - { - mdim = 3; - break; - } - inode++; - } - - if (mdim != 3) - { - if (dimX && dimY && dimZ) - mdim = 0; - else if (!dimX) - { - if (dimY && dimZ) - mdim = 1; - else if ((dimY && !dimZ) || (!dimY && dimZ)) - mdim = 2; - } - else if (!dimY) - { - if (dimX && dimZ) - mdim = 1; - else if ((dimX && !dimZ) || (!dimX && dimZ)) - mdim = 2; - } - else if (!dimZ) - { - if (dimY && dimX) - mdim = 1; - else if ((dimY && !dimX) || (!dimY && dimX)) - mdim = 2; - } - } - - MESSAGE(" mdim " << mdim); - - /* creation du maillage */ - //mdim=3; - sprintf(nommaa, "Mesh %d", numero); - SCRUTE(nommaa); - ret = MEDmaaCr(myFileId, nommaa, mdim); - - ASSERT(ret == 0); - SCRUTE(ret); - - /* Combien de noeuds ? */ - nnoe = myMesh->NbNodes(); - //SCRUTE(nnoe); - /* Combien de mailles, faces ou aretes ? */ - for (i = 0; i < MED_NBR_GEOMETRIE_MAILLE; i++) - nmailles[i] = 0; - - int nb_of_nodes, nb_of_faces, nb_of_edges; - vector < int >elem_Id[MED_NBR_GEOMETRIE_MAILLE]; - - nb_of_edges = myMesh->NbEdges(); - SMDS_Iterator * itEdges=myMesh->edgesIterator(); - while(itEdges->more()) - { - const SMDS_MeshEdge * elem = itEdges->next(); - - nb_of_nodes = elem->NbNodes(); - - switch (nb_of_nodes) - { - case 2: - { - elem_Id[1].push_back(elem->GetID()); - nmailles[1]++; - break; - } - case 3: - { - elem_Id[2].push_back(elem->GetID()); - nmailles[2]++; - break; - } - } - } - - nb_of_faces = myMesh->NbFaces(); - SMDS_Iterator * itFaces=myMesh->facesIterator(); - while(itFaces->more()) - { - const SMDS_MeshElement * elem = itFaces->next(); - - nb_of_nodes = elem->NbNodes(); - - switch (nb_of_nodes) - { - case 3: - { - elem_Id[3].push_back(elem->GetID()); - nmailles[3]++; - break; - } - case 4: - { - elem_Id[5].push_back(elem->GetID()); - nmailles[5]++; - break; - } - case 6: - { - elem_Id[4].push_back(elem->GetID()); - nmailles[4]++; - break; - } - } - - } - - SMDS_Iterator * itVolumes=myMesh->volumesIterator(); - while(itVolumes->more()) - { - const SMDS_MeshElement * elem = itVolumes->next(); - - nb_of_nodes = elem->NbNodes(); - switch (nb_of_nodes) - { - case 8: - { - elem_Id[9].push_back(elem->GetID()); - nmailles[9]++; - break; - } - } - } - - /**************************************************************************** - * ECRITURE DES NOEUDS * - ****************************************************************************/ - MESSAGE("(************************)"); - MESSAGE("(* NOEUDS DU MAILLAGE : *)"); - MESSAGE("(************************)"); - - /* Allocations memoires */ - /* table des coordonnees - * profil : (dimension * nombre de noeuds ) */ - coo = (med_float *) malloc(sizeof(med_float) * nnoe * mdim); - /* table des numeros, des numeros de familles des noeuds - * profil : (nombre de noeuds) */ - numnoe = (med_int *) malloc(sizeof(med_int) * nnoe); - nufano = (med_int *) malloc(sizeof(med_int) * nnoe); - /* table des noms des noeuds - * profil : (nnoe*MED_TAILLE_PNOM+1) */ - nomnoe = ""; - - /* PN pour aster, il faut une famille 0 pour les noeuds et une autre pour les elements */ - /* PN : Creation de la famille 0 */ - char *nomfam = "FAMILLE_0"; - char *attdes = ""; - char *gro = 0; - med_int ngro = 0; - med_int natt = 1; - med_int attide = 0; - med_int attval = 0; - med_int numfam = 0; - med_int attvalabs = 1; - ret = - MEDfamCr(myFileId, nommaa, nomfam, numfam, &attide, &attval, attdes, - natt, gro, ngro); - ASSERT(ret == 0); - - /* PN : FIN Creation de la famille 0 */ - - map < int, int >mapNoeud; - typedef pair < set < int >::iterator, bool > IsFamily; - int nbFamillesNoeud; - - i = 0; - set < int >FamilySet; - nbFamillesNoeud = 0; - int verifienbnoeuds = 0; - med_int *rien = 0; - - SMDS_Iterator * itNodes=myMesh->nodesIterator(); - while(itNodes->more()) - { - const SMDS_MeshNode * node = itNodes->next(); - - if (mdim == 3) - { - coo[i * 3] = node->X(); - coo[i * 3 + 1] = node->Y(); - coo[i * 3 + 2] = node->Z(); - } - else if (mdim == 2) - { - if (dimX) - { - coo[i * 2] = node->Y(); - coo[i * 2 + 1] = node->Z(); - } - if (dimY) - { - coo[i * 2] = node->X(); - coo[i * 2 + 1] = node->Z(); - } - if (dimZ) - { - coo[i * 2] = node->X(); - coo[i * 2 + 1] = node->Y(); - } - } - else - { - if (dimX) - { - coo[i * 2] = node->Y(); - coo[i * 2 + 1] = node->Z(); - } - if (dimY) - { - coo[i * 2] = node->X(); - coo[i * 2 + 1] = node->Z(); - } - if (dimZ) - { - coo[i * 2] = node->X(); - coo[i * 2 + 1] = node->Y(); - } - } - mapNoeud[node->GetID()] = i + 1; - - // renvoie 0 pour les noeuds internes du volume - int numfamille = node->GetPosition()->GetShapeId(); - nufano[i] = numfamille; - - //SCRUTE(i); - //SCRUTE(nufano[i]); - //SCRUTE(coo[i*3]); - //SCRUTE(coo[i*3+1]); - //SCRUTE(coo[i*3+2]); - if (nufano[i] != 0) - { - IsFamily deja = FamilySet.insert(nufano[i]); // insert if new, or gives existant - if (deja.second) // actually inserted - { - char famille[MED_TAILLE_NOM + 1]; - sprintf(famille, "F%d", nufano[i]); - // CreateFamily(strdup(nommaa),strdup(famille),nufano[i],attvalabs++); - attvalabs++; - CreateFamily(strdup(nommaa), strdup(famille), nufano[i], - numfamille); - //MESSAGE("---famille-noeud--- "<(myMesh); - TopTools_IndexedMapOfShape myIndexToShape; - TopExp::MapShapes(mySMESHDSMesh->ShapeToMesh(), myIndexToShape); - - map mapFamille; - - if (besoinfamilledemaille == 1) - { - int t; - for (t = 1; t <= myIndexToShape.Extent(); t++) - { - const TopoDS_Shape S = myIndexToShape(t); - if (mySMESHDSMesh->HasMeshElements(S)) - { - //MESSAGE ("********* Traitement de la Famille "<<-t); - - SMESHDS_SubMesh * SM = mySMESHDSMesh->MeshElements(S); - SMDS_Iterator * ite=SM->GetElements(); - bool plein = false; - while(ite->more()) - { - mapFamille[ite->next()->GetID()] = -t; - plein = true; - } - if (plein) - { - nbFamillesElts++; - char famille[MED_TAILLE_NOM + 1]; - sprintf(famille, "E%d", t); - CreateFamily(strdup(nommaa), strdup(famille), -t, - attvalabs++); - } - } - } - } - - int indice = 1; - for (i = 0; i < MED_NBR_GEOMETRIE_MAILLE; i++) - { - if (nmailles[i] > 0 && ret == 0) - { - MESSAGE(" Start " << typmai[i]); - - /* dimension de la maille */ - edim = typmai[i] / 100; - nsup = 0; - if (mdim == 2 || mdim == 3) - if (edim == 1) - nsup = 1; - if (mdim == 3) - if (edim == 2) - nsup = 1; - //SCRUTE(nsup); - - taille = nsup + typmai[i] % 100; - //SCRUTE(taille); - - /* allocation memoire */ - connectivite = - (med_int *) malloc(sizeof(med_int) * taille * nmailles[i]); - nomele = - (char *)malloc(sizeof(char) * MED_TAILLE_PNOM * - nmailles[i] + 1); - numele = (med_int *) malloc(sizeof(med_int) * nmailles[i]); - nufael = (med_int *) malloc(sizeof(med_int) * nmailles[i]); - nomele = ""; - nbNodes = typmai[i] % 100; - - for (j = 0; j < nmailles[i]; j++) - { - myId = elem_Id[i][j]; - const SMDS_MeshElement * elem = - myMesh->FindElement(myId); - //*(numele+j) = myId; - *(numele + j) = indice++; - - SMDS_Iterator * itk=elem->nodesIterator(); - for (k = 0; itk->more(); k++) - { - *(connectivite + j * taille + k) = - mapNoeud[itk->next()->GetID()]; - } - delete itk; - - if (nsup) - *(connectivite + j * taille + nbNodes) = 0; - - if (besoinfamilledemaille == 1) - { - if (mapFamille.find(myId) != mapFamille.end()) - { - nufael[j] = mapFamille[myId]; - } - else - { - nufael[j] = 0; - } - } - else - { - nufael[j] = 0; - } - - //SCRUTE(myId); - //SCRUTE(j); - //SCRUTE(nufael[j]); - } - - /* ecriture des données */ - - med_int *rien = 0; - ret = - MEDelementsEcr(myFileId, nommaa, mdim, connectivite, - mode_coo, nomele, MED_FAUX, numele, MED_VRAI, nufael, - nmailles[i], MED_MAILLE, typmai[i], typ_con, MED_REMP); - ASSERT(ret == 0); - //SCRUTE(ret); - - if (ret < 0) - MESSAGE(">> ERREUR : ecriture des mailles \n"); - - /* liberation memoire */ - free(connectivite); - free(numele); - free(nomele); - free(nufael); - MESSAGE(" End " << typmai[i]); - } - }; - MESSAGE("--- Creation de " << nbFamillesElts << " familles d elements"); - - } - - /**************************************************************************** - * FERMETURE DU FICHIER * - ****************************************************************************/ - - ret = MEDfermer(myFileId); - - if (ret != 0) - fprintf(stderr, ">> ERREUR : erreur a la fermeture du fichier %s\n", - file2Read); - MESSAGE("fichier ferme"); - + myDoGroupOfEdges = true; } -void DriverMED_W_SMESHDS_Mesh::CreateFamily(char *nommaa, char *famille, int i, - med_int k) +void DriverMED_W_SMESHDS_Mesh::AddGroupOfFaces() { + myDoGroupOfFaces = true; +} - med_int ngro = 0; - med_int natt; - - natt = 1; - char attdes[MED_TAILLE_DESC + 1]; - char gro[MED_TAILLE_LNOM + 1]; - char fam2[MED_TAILLE_LNOM + 1]; +void DriverMED_W_SMESHDS_Mesh::AddGroupOfVolumes() +{ + myDoGroupOfVolumes = true; +} - strcpy(attdes, ""); - strcpy(gro, ""); - strcpy(fam2, famille); +namespace +{ + typedef double (SMDS_MeshNode::* TGetCoord)() const; + typedef const char* TName; + typedef const char* TUnit; + + // name length in a mesh must be equal to 16 : + // 1234567890123456 + TName M = "m "; + TName X = "x "; + TName Y = "y "; + TName Z = "z "; + + TUnit aUnit[3] = {M,M,M}; + + // 3 dim + TGetCoord aXYZGetCoord[3] = { + &SMDS_MeshNode::X, + &SMDS_MeshNode::Y, + &SMDS_MeshNode::Z + }; + TName aXYZName[3] = {X,Y,Z}; + + // 2 dim + TGetCoord aXYGetCoord[2] = { + &SMDS_MeshNode::X, + &SMDS_MeshNode::Y + }; + TName aXYName[2] = {X,Y}; + + TGetCoord aYZGetCoord[2] = { + &SMDS_MeshNode::Y, + &SMDS_MeshNode::Z + }; + TName aYZName[2] = {Y,Z}; + + TGetCoord aXZGetCoord[2] = { + &SMDS_MeshNode::X, + &SMDS_MeshNode::Z + }; + TName aXZName[2] = {X,Z}; + + // 1 dim + TGetCoord aXGetCoord[1] = { + &SMDS_MeshNode::X + }; + TName aXName[1] = {X}; + + TGetCoord aYGetCoord[1] = { + &SMDS_MeshNode::Y + }; + TName aYName[1] = {Y}; + + TGetCoord aZGetCoord[1] = { + &SMDS_MeshNode::Z + }; + TName aZName[1] = {Z}; + + + class TCoordHelper{ + SMDS_NodeIteratorPtr myNodeIter; + const SMDS_MeshNode* myCurrentNode; + TGetCoord* myGetCoord; + TName* myName; + TUnit* myUnit; + public: + TCoordHelper(const SMDS_NodeIteratorPtr& theNodeIter, + TGetCoord* theGetCoord, + TName* theName, + TUnit* theUnit = aUnit): + myNodeIter(theNodeIter), + myGetCoord(theGetCoord), + myName(theName), + myUnit(theUnit) + {} + virtual ~TCoordHelper(){} + bool Next(){ + return myNodeIter->more() && + (myCurrentNode = myNodeIter->next()); + } + const SMDS_MeshNode* GetNode(){ + return myCurrentNode; + } + MED::TIntVector::value_type GetID(){ + return myCurrentNode->GetID(); + } + MED::TFloatVector::value_type GetCoord(TInt theCoodId){ + return (myCurrentNode->*myGetCoord[theCoodId])(); + } + MED::TStringVector::value_type GetName(TInt theDimId){ + return myName[theDimId]; + } + MED::TStringVector::value_type GetUnit(TInt theDimId){ + return myUnit[theDimId]; + } + }; + typedef boost::shared_ptr TCoordHelperPtr; + + //------------------------------------------------------- + /*! + * \brief Structure describing element type + */ + //------------------------------------------------------- + struct TElemTypeData + { + EEntiteMaillage _entity; + EGeometrieElement _geomType; + TInt _nbElems; + SMDSAbs_ElementType _smdsType; + + TElemTypeData (EEntiteMaillage entity, EGeometrieElement geom, TInt nb, SMDSAbs_ElementType type) + : _entity(entity), _geomType(geom), _nbElems( nb ), _smdsType( type ) {} + }; + + + typedef NCollection_DataMap< Standard_Address, int > TElemFamilyMap; + + //================================================================================ + /*! + * \brief Fills element to famaly ID map for element type. + * Removes all families of anElemType + */ + //================================================================================ + + void fillElemFamilyMap( TElemFamilyMap & anElemFamMap, + list & aFamilies, + const SMDSAbs_ElementType anElemType) + { + anElemFamMap.Clear(); + list::iterator aFamsIter = aFamilies.begin(); + while ( aFamsIter != aFamilies.end() ) + { + if ((*aFamsIter)->GetType() != anElemType) { + aFamsIter++; + } + else { + int aFamId = (*aFamsIter)->GetId(); + const ElementsSet& anElems = (*aFamsIter)->GetElements(); + ElementsSet::const_iterator anElemsIter = anElems.begin(); + for (; anElemsIter != anElems.end(); anElemsIter++) + { + anElemFamMap.Bind( (Standard_Address)*anElemsIter, aFamId ); + } + // remove a family from the list + aFamilies.erase( aFamsIter++ ); + } + } + } + + //================================================================================ + /*! + * \brief For an element, return family ID found in the map or a default one + */ + //================================================================================ + + int getFamilyId( const TElemFamilyMap & anElemFamMap, + const SMDS_MeshElement* anElement, + const int aDefaultFamilyId) + { + if ( anElemFamMap.IsBound( (Standard_Address) anElement )) + return anElemFamMap( (Standard_Address) anElement ); + + return aDefaultFamilyId; + } + + //================================================================================ + /*! + * \brief Returns iterator on sub-meshes + */ + //================================================================================ + + SMESHDS_SubMeshIteratorPtr getIterator( std::vector& mySubMeshes ) + { + return SMESHDS_SubMeshIteratorPtr + ( new SMDS_SetIterator + < const SMESHDS_SubMesh*, std::vector< SMESHDS_SubMesh* >::iterator >( mySubMeshes.begin(), + mySubMeshes.end() )); + } +} - med_int *attide = new med_int[1]; - med_int *attval = new med_int[1]; - attide[0] = k; - attval[0] = k; +Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() +{ + Status aResult = DRS_OK; + if (myMesh->hasConstructionEdges() || myMesh->hasConstructionFaces()) { + INFOS("SMDS_MESH with hasConstructionEdges() or hasConstructionFaces() do not supports!!!"); + return DRS_FAIL; + } + try { + MESSAGE("Perform - myFile : "<nodesIterator(); + double aBounds[6]; + if(aNodesIter->more()){ + const SMDS_MeshNode* aNode = aNodesIter->next(); + aBounds[0] = aBounds[1] = aNode->X(); + aBounds[2] = aBounds[3] = aNode->Y(); + aBounds[4] = aBounds[5] = aNode->Z(); + } + while(aNodesIter->more()){ + const SMDS_MeshNode* aNode = aNodesIter->next(); + aBounds[0] = min(aBounds[0],aNode->X()); + aBounds[1] = max(aBounds[1],aNode->X()); + + aBounds[2] = min(aBounds[2],aNode->Y()); + aBounds[3] = max(aBounds[3],aNode->Y()); + + aBounds[4] = min(aBounds[4],aNode->Z()); + aBounds[5] = max(aBounds[5],aNode->Z()); + } + + double EPS = 1.0E-7; + TopoDS_Shape mainShape = myMesh->ShapeToMesh(); + bool hasShapeToMesh = ( myMesh->SubMeshIndices().size() > 1 ); + if ( !mainShape.IsNull() && hasShapeToMesh ) + { + // define EPS by max tolerance of the mainShape (IPAL53097) + TopExp_Explorer subShape; + for ( subShape.Init( mainShape, TopAbs_FACE ); subShape.More(); subShape.Next() ) { + EPS = Max( EPS, BRep_Tool::Tolerance( TopoDS::Face( subShape.Current() ))); + } + for ( subShape.Init( mainShape, TopAbs_EDGE ); subShape.More(); subShape.Next() ) { + EPS = Max( EPS, BRep_Tool::Tolerance( TopoDS::Edge( subShape.Current() ))); + } + for ( subShape.Init( mainShape, TopAbs_VERTEX ); subShape.More(); subShape.Next() ) { + EPS = Max( EPS, BRep_Tool::Tolerance( TopoDS::Vertex( subShape.Current() ))); + } + EPS *= 2.; + } + anIsXDimension = (aBounds[1] - aBounds[0]) + abs(aBounds[1]) + abs(aBounds[0]) > EPS; + anIsYDimension = (aBounds[3] - aBounds[2]) + abs(aBounds[3]) + abs(aBounds[2]) > EPS; + anIsZDimension = (aBounds[5] - aBounds[4]) + abs(aBounds[5]) + abs(aBounds[4]) > EPS; + aSpaceDimension = anIsXDimension + anIsYDimension + anIsZDimension; + if ( !aSpaceDimension ) + aSpaceDimension = 3; + // PAL16857(SMESH not conform to the MED convention): + if ( aSpaceDimension == 2 && anIsZDimension ) // 2D only if mesh is in XOY plane + aSpaceDimension = 3; + // PAL18941(a saved study with a mesh belong Z is opened and the mesh is belong X) + if ( aSpaceDimension == 1 && !anIsXDimension ) {// 1D only if mesh is along OX + if ( anIsYDimension ) { + aSpaceDimension = 2; + anIsXDimension = true; + } else { + aSpaceDimension = 3; + } + } + } + + SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator(/*idInceasingOrder=*/true); + switch ( aSpaceDimension ) { + case 3: + aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXYZGetCoord,aXYZName)); + break; + case 2: + if(anIsXDimension && anIsYDimension) + aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXYGetCoord,aXYName)); + if(anIsYDimension && anIsZDimension) + aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aYZGetCoord,aYZName)); + if(anIsXDimension && anIsZDimension) + aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXZGetCoord,aXZName)); + break; + case 1: + if(anIsXDimension) + aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXGetCoord,aXName)); + if(anIsYDimension) + aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aYGetCoord,aYName)); + if(anIsZDimension) + aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aZGetCoord,aZName)); + break; + } + } + TInt aMeshDimension = 0; + if ( myMesh->NbEdges() > 0 ) + aMeshDimension = 1; + if ( myMesh->NbFaces() > 0 ) + aMeshDimension = 2; + if ( myMesh->NbVolumes() > 0 ) + aMeshDimension = 3; + + MED::PWrapper myMed = CrWrapper(myFile,myMedVersion); + PMeshInfo aMeshInfo = myMed->CrMeshInfo(aMeshDimension,aSpaceDimension,aMeshName); + MESSAGE("Add - aMeshName : "<GetName()); + myMed->SetMeshInfo(aMeshInfo); + + // Storing SMDS groups and sub-meshes as med families + //---------------------------------------------------- + int myNodesDefaultFamilyId = 0; + int my0DElementsDefaultFamilyId = 0; + int myBallsDefaultFamilyId = 0; + int myEdgesDefaultFamilyId = 0; + int myFacesDefaultFamilyId = 0; + int myVolumesDefaultFamilyId = 0; + int nbNodes = myMesh->NbNodes(); + int nb0DElements = myMesh->Nb0DElements(); + int nbBalls = myMesh->NbBalls(); + int nbEdges = myMesh->NbEdges(); + int nbFaces = myMesh->NbFaces(); + int nbVolumes = myMesh->NbVolumes(); + if (myDoGroupOfNodes && nbNodes) myNodesDefaultFamilyId = REST_NODES_FAMILY; + if (myDoGroupOfEdges && nbEdges) myEdgesDefaultFamilyId = REST_EDGES_FAMILY; + if (myDoGroupOfFaces && nbFaces) myFacesDefaultFamilyId = REST_FACES_FAMILY; + if (myDoGroupOfVolumes && nbVolumes) myVolumesDefaultFamilyId = REST_VOLUMES_FAMILY; + if (myDoGroupOf0DElems && nb0DElements) my0DElementsDefaultFamilyId = REST_0DELEM_FAMILY; + if (myDoGroupOfBalls && nbBalls) myBallsDefaultFamilyId = REST_BALL_FAMILY; + + MESSAGE("Perform - aFamilyInfo"); + list aFamilies; + if (myAllSubMeshes) { + aFamilies = DriverMED_Family::MakeFamilies + (myMesh->SubMeshes(), myGroups, + myDoGroupOfNodes && nbNodes, + myDoGroupOfEdges && nbEdges, + myDoGroupOfFaces && nbFaces, + myDoGroupOfVolumes && nbVolumes, + myDoGroupOf0DElems && nb0DElements, + myDoGroupOfBalls && nbBalls); + } + else { + aFamilies = DriverMED_Family::MakeFamilies + (getIterator( mySubMeshes ), myGroups, + myDoGroupOfNodes && nbNodes, + myDoGroupOfEdges && nbEdges, + myDoGroupOfFaces && nbFaces, + myDoGroupOfVolumes && nbVolumes, + myDoGroupOf0DElems && nb0DElements, + myDoGroupOfBalls && nbBalls); + } + list::iterator aFamsIter; + for (aFamsIter = aFamilies.begin(); aFamsIter != aFamilies.end(); aFamsIter++) + { + PFamilyInfo aFamilyInfo = (*aFamsIter)->GetFamilyInfo(myMed,aMeshInfo); + myMed->SetFamilyInfo(aFamilyInfo); + } + + // Storing SMDS nodes to the MED file for the MED mesh + //---------------------------------------------------- +#ifdef _EDF_NODE_IDS_ + typedef map TNodeIdMap; + TNodeIdMap aNodeIdMap; +#endif + const EModeSwitch theMode = eFULL_INTERLACE; + const ERepere theSystem = eCART; + const EBooleen theIsElemNum = eVRAI; + const EBooleen theIsElemNames = eFAUX; + const EConnectivite theConnMode = eNOD; + + TInt aNbNodes = myMesh->NbNodes(); + PNodeInfo aNodeInfo = myMed->CrNodeInfo(aMeshInfo, aNbNodes, + theMode, theSystem, theIsElemNum, theIsElemNames); + + // find family numbers for nodes + TElemFamilyMap anElemFamMap; + fillElemFamilyMap( anElemFamMap, aFamilies, SMDSAbs_Node ); + + for (TInt iNode = 0; aCoordHelperPtr->Next(); iNode++) + { + // coordinates + TCoordSlice aTCoordSlice = aNodeInfo->GetCoordSlice( iNode ); + for(TInt iCoord = 0; iCoord < aSpaceDimension; iCoord++){ + aTCoordSlice[iCoord] = aCoordHelperPtr->GetCoord(iCoord); + } + // node number + int aNodeID = aCoordHelperPtr->GetID(); + aNodeInfo->SetElemNum( iNode, aNodeID ); +#ifdef _EDF_NODE_IDS_ + aNodeIdMap.insert( aNodeIdMap.end(), make_pair( aNodeID, iNode+1 )); +#endif + // family number + const SMDS_MeshNode* aNode = aCoordHelperPtr->GetNode(); + int famNum = getFamilyId( anElemFamMap, aNode, myNodesDefaultFamilyId ); + aNodeInfo->SetFamNum( iNode, famNum ); + } + anElemFamMap.Clear(); + + // coordinate names and units + for (TInt iCoord = 0; iCoord < aSpaceDimension; iCoord++) { + aNodeInfo->SetCoordName( iCoord, aCoordHelperPtr->GetName(iCoord)); + aNodeInfo->SetCoordUnit( iCoord, aCoordHelperPtr->GetUnit(iCoord)); + } + + //cout << " SetNodeInfo(aNodeInfo)" << endl; + MESSAGE("Perform - aNodeInfo->GetNbElem() = "<SetNodeInfo(aNodeInfo); + aNodeInfo.reset(); // free memory used for arrays + + + // Storing SMDS elements to the MED file for the MED mesh + //------------------------------------------------------- + // Write one element type at once in order to minimize memory usage (PAL19276) + + const SMDS_MeshInfo& nbElemInfo = myMesh->GetMeshInfo(); + + // poly elements are not supported by med-2.1 + bool polyTypesSupported = ( myMed->CrPolygoneInfo(aMeshInfo,eMAILLE,ePOLYGONE,0,0).get() != 0 ); + TInt nbPolygonNodes = 0, nbPolyhedronNodes = 0, nbPolyhedronFaces = 0; + + // nodes on VERTEXes where 0D elements are absent + std::vector nodesOf0D; + std::vector< SMDS_ElemIteratorPtr > iterVec; + SMDS_ElemIteratorPtr iterVecIter; + if ( myAddODOnVertices && getNodesOfMissing0DOnVert( myMesh, nodesOf0D )) + { + iterVec.resize(2); + iterVec[0] = myMesh->elementsIterator( SMDSAbs_0DElement ); + iterVec[1] = SMDS_ElemIteratorPtr + ( new SMDS_ElementVectorIterator( nodesOf0D.begin(), nodesOf0D.end() )); + + typedef SMDS_IteratorOnIterators + < const SMDS_MeshElement *, std::vector< SMDS_ElemIteratorPtr > > TItIterator; + iterVecIter = SMDS_ElemIteratorPtr( new TItIterator( iterVec )); + } + + // collect info on all geom types + + list< TElemTypeData > aTElemTypeDatas; + + EEntiteMaillage anEntity = eMAILLE; +#ifdef _ELEMENTS_BY_DIM_ + anEntity = eNOEUD_ELEMENT; +#endif + aTElemTypeDatas.push_back(TElemTypeData(anEntity, + ePOINT1, + nbElemInfo.Nb0DElements() + nodesOf0D.size(), + SMDSAbs_0DElement)); +#ifdef _ELEMENTS_BY_DIM_ + anEntity = eSTRUCT_ELEMENT; +#endif + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + eBALL, + nbElemInfo.NbBalls(), + SMDSAbs_Ball)); +#ifdef _ELEMENTS_BY_DIM_ + anEntity = eARETE; +#endif + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + eSEG2, + nbElemInfo.NbEdges( ORDER_LINEAR ), + SMDSAbs_Edge)); + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + eSEG3, + nbElemInfo.NbEdges( ORDER_QUADRATIC ), + SMDSAbs_Edge)); +#ifdef _ELEMENTS_BY_DIM_ + anEntity = eFACE; +#endif + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + eTRIA3, + nbElemInfo.NbTriangles( ORDER_LINEAR ), + SMDSAbs_Face)); + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + eTRIA6, + nbElemInfo.NbTriangles( ORDER_QUADRATIC ) - + nbElemInfo.NbBiQuadTriangles(), + SMDSAbs_Face)); + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + eTRIA7, + nbElemInfo.NbBiQuadTriangles(), + SMDSAbs_Face)); + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + eQUAD4, + nbElemInfo.NbQuadrangles( ORDER_LINEAR ), + SMDSAbs_Face)); + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + eQUAD8, + nbElemInfo.NbQuadrangles( ORDER_QUADRATIC ) - + nbElemInfo.NbBiQuadQuadrangles(), + SMDSAbs_Face)); + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + eQUAD9, + nbElemInfo.NbBiQuadQuadrangles(), + SMDSAbs_Face)); + if ( polyTypesSupported ) { + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + ePOLYGONE, + nbElemInfo.NbPolygons( ORDER_LINEAR ), + SMDSAbs_Face)); + // we need one more loop on poly elements to count nb of their nodes + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + ePOLYGONE, + nbElemInfo.NbPolygons( ORDER_LINEAR ), + SMDSAbs_Face)); + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + ePOLYGON2, + nbElemInfo.NbPolygons( ORDER_QUADRATIC ), + SMDSAbs_Face)); + // we need one more loop on QUAD poly elements to count nb of their nodes + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + ePOLYGON2, + nbElemInfo.NbPolygons( ORDER_QUADRATIC ), + SMDSAbs_Face)); + } +#ifdef _ELEMENTS_BY_DIM_ + anEntity = eMAILLE; +#endif + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + eTETRA4, + nbElemInfo.NbTetras( ORDER_LINEAR ), + SMDSAbs_Volume)); + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + eTETRA10, + nbElemInfo.NbTetras( ORDER_QUADRATIC ), + SMDSAbs_Volume)); + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + ePYRA5, + nbElemInfo.NbPyramids( ORDER_LINEAR ), + SMDSAbs_Volume)); + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + ePYRA13, + nbElemInfo.NbPyramids( ORDER_QUADRATIC ), + SMDSAbs_Volume)); + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + ePENTA6, + nbElemInfo.NbPrisms( ORDER_LINEAR ), + SMDSAbs_Volume)); + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + ePENTA15, + nbElemInfo.NbPrisms( ORDER_QUADRATIC ), + SMDSAbs_Volume)); + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + eHEXA8, + nbElemInfo.NbHexas( ORDER_LINEAR ), + SMDSAbs_Volume)); + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + eHEXA20, + nbElemInfo.NbHexas( ORDER_QUADRATIC )- + nbElemInfo.NbTriQuadHexas(), + SMDSAbs_Volume)); + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + eHEXA27, + nbElemInfo.NbTriQuadHexas(), + SMDSAbs_Volume)); + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + eOCTA12, + nbElemInfo.NbHexPrisms(), + SMDSAbs_Volume)); + if ( polyTypesSupported ) { + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + ePOLYEDRE, + nbElemInfo.NbPolyhedrons(), + SMDSAbs_Volume)); + // we need one more loop on poly elements to count nb of their nodes + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + ePOLYEDRE, + nbElemInfo.NbPolyhedrons(), + SMDSAbs_Volume)); + } + + vector< bool > isElemFamMapBuilt( SMDSAbs_NbElementTypes, false ); + + // loop on all geom types of elements + + list< TElemTypeData >::iterator aElemTypeData = aTElemTypeDatas.begin(); + for ( ; aElemTypeData != aTElemTypeDatas.end(); ++aElemTypeData ) + { + if ( aElemTypeData->_nbElems == 0 ) + continue; + + int defaultFamilyId = 0; + switch ( aElemTypeData->_smdsType ) { + case SMDSAbs_0DElement: defaultFamilyId = my0DElementsDefaultFamilyId; break; + case SMDSAbs_Ball: defaultFamilyId = myBallsDefaultFamilyId; break; + case SMDSAbs_Edge: defaultFamilyId = myEdgesDefaultFamilyId; break; + case SMDSAbs_Face: defaultFamilyId = myFacesDefaultFamilyId; break; + case SMDSAbs_Volume: defaultFamilyId = myVolumesDefaultFamilyId; break; + default: + continue; + } + + // iterator on elements of a current type + SMDS_ElemIteratorPtr elemIterator; + int iElem = 0; + + // Treat POLYGONs + // --------------- + if ( aElemTypeData->_geomType == ePOLYGONE || + aElemTypeData->_geomType == ePOLYGON2 ) + { + if ( aElemTypeData->_geomType == ePOLYGONE ) + elemIterator = myMesh->elementEntityIterator( SMDSEntity_Polygon ); + else + elemIterator = myMesh->elementEntityIterator( SMDSEntity_Quad_Polygon ); + + if ( nbPolygonNodes == 0 ) { + // Count nb of nodes + while ( elemIterator->more() ) { + const SMDS_MeshElement* anElem = elemIterator->next(); + nbPolygonNodes += anElem->NbNodes(); + if ( ++iElem == aElemTypeData->_nbElems ) + break; + } + } + else { + // Store in med file + PPolygoneInfo aPolygoneInfo = myMed->CrPolygoneInfo(aMeshInfo, + aElemTypeData->_entity, + aElemTypeData->_geomType, + aElemTypeData->_nbElems, + nbPolygonNodes, + theConnMode, theIsElemNum, + theIsElemNames); + TElemNum & index = *(aPolygoneInfo->myIndex.get()); + index[0] = 1; + + while ( elemIterator->more() ) + { + const SMDS_MeshElement* anElem = elemIterator->next(); + // index + TInt aNbNodes = anElem->NbNodes(); + index[ iElem+1 ] = index[ iElem ] + aNbNodes; + + // connectivity + TConnSlice aTConnSlice = aPolygoneInfo->GetConnSlice( iElem ); + for(TInt iNode = 0; iNode < aNbNodes; iNode++) { + const SMDS_MeshElement* aNode = anElem->GetNode( iNode ); +#ifdef _EDF_NODE_IDS_ + aTConnSlice[ iNode ] = aNodeIdMap[aNode->GetID()]; +#else + aTConnSlice[ iNode ] = aNode->GetID(); +#endif + } + // element number + aPolygoneInfo->SetElemNum( iElem, anElem->GetID() ); + + // family number + int famNum = getFamilyId( anElemFamMap, anElem, defaultFamilyId ); + aPolygoneInfo->SetFamNum( iElem, famNum ); + + if ( ++iElem == aPolygoneInfo->GetNbElem() ) + break; + } + myMed->SetPolygoneInfo(aPolygoneInfo); + + nbPolygonNodes = 0; // to treat next polygon type + } + } + + // Treat POLYEDREs + // ---------------- + else if (aElemTypeData->_geomType == ePOLYEDRE ) + { + elemIterator = myMesh->elementGeomIterator( SMDSGeom_POLYHEDRA ); + + if ( nbPolyhedronNodes == 0 ) { + // Count nb of nodes + while ( elemIterator->more() ) { + const SMDS_MeshElement* anElem = elemIterator->next(); + const SMDS_VtkVolume *aPolyedre = dynamic_cast(anElem); + if ( !aPolyedre ) continue; + nbPolyhedronNodes += aPolyedre->NbNodes(); + nbPolyhedronFaces += aPolyedre->NbFaces(); + if ( ++iElem == aElemTypeData->_nbElems ) + break; + } + } + else { + // Store in med file + PPolyedreInfo aPolyhInfo = myMed->CrPolyedreInfo(aMeshInfo, + aElemTypeData->_entity, + aElemTypeData->_geomType, + aElemTypeData->_nbElems, + nbPolyhedronFaces+1, + nbPolyhedronNodes, + theConnMode, + theIsElemNum, + theIsElemNames); + TElemNum & index = *(aPolyhInfo->myIndex.get()); + TElemNum & faces = *(aPolyhInfo->myFaces.get()); + TElemNum & conn = *(aPolyhInfo->myConn.get()); + index[0] = 1; + faces[0] = 1; + + TInt iFace = 0, iNode = 0; + while ( elemIterator->more() ) + { + const SMDS_MeshElement* anElem = elemIterator->next(); + const SMDS_VtkVolume *aPolyedre = dynamic_cast(anElem); + if ( !aPolyedre ) continue; + // index + TInt aNbFaces = aPolyedre->NbFaces(); + index[ iElem+1 ] = index[ iElem ] + aNbFaces; + + // face index + for (TInt f = 1; f <= aNbFaces; ++f, ++iFace ) { + int aNbFaceNodes = aPolyedre->NbFaceNodes( f ); + faces[ iFace+1 ] = faces[ iFace ] + aNbFaceNodes; + } + // connectivity + SMDS_ElemIteratorPtr nodeIt = anElem->nodesIterator(); + while ( nodeIt->more() ) { + const SMDS_MeshElement* aNode = nodeIt->next(); +#ifdef _EDF_NODE_IDS_ + conn[ iNode ] = aNodeIdMap[aNode->GetID()]; +#else + conn[ iNode ] = aNode->GetID(); +#endif + ++iNode; + } + // element number + aPolyhInfo->SetElemNum( iElem, anElem->GetID() ); + + // family number + int famNum = getFamilyId( anElemFamMap, anElem, defaultFamilyId ); + aPolyhInfo->SetFamNum( iElem, famNum ); + + if ( ++iElem == aPolyhInfo->GetNbElem() ) + break; + } + myMed->SetPolyedreInfo(aPolyhInfo); + } + } // if (aElemTypeData->_geomType == ePOLYEDRE ) + + // Treat BALLs + // ---------------- + else if (aElemTypeData->_geomType == eBALL ) + { + // allocate data arrays + PBallInfo aBallInfo = myMed->CrBallInfo( aMeshInfo, aElemTypeData->_nbElems ); + + // build map of family numbers for this type + if ( !isElemFamMapBuilt[ aElemTypeData->_smdsType ]) + { + fillElemFamilyMap( anElemFamMap, aFamilies, aElemTypeData->_smdsType ); + isElemFamMapBuilt[ aElemTypeData->_smdsType ] = true; + } + + elemIterator = myMesh->elementsIterator( SMDSAbs_Ball ); + while ( elemIterator->more() ) + { + const SMDS_MeshElement* anElem = elemIterator->next(); + // connectivity + const SMDS_MeshElement* aNode = anElem->GetNode( 0 ); +#ifdef _EDF_NODE_IDS_ + (*aBallInfo->myConn)[ iElem ] = aNodeIdMap[aNode->GetID()]; +#else + (*aBallInfo->myConn)[ iElem ] = aNode->GetID(); +#endif + // element number + aBallInfo->SetElemNum( iElem, anElem->GetID() ); + + // diameter + aBallInfo->myDiameters[ iElem ] = + static_cast( anElem )->GetDiameter(); + + // family number + int famNum = getFamilyId( anElemFamMap, anElem, defaultFamilyId ); + aBallInfo->SetFamNum( iElem, famNum ); + ++iElem; + } + // store data in a file + myMed->SetBallInfo(aBallInfo); + } + + else + { + // Treat standard types + // --------------------- + + // allocate data arrays + PCellInfo aCellInfo = myMed->CrCellInfo( aMeshInfo, + aElemTypeData->_entity, + aElemTypeData->_geomType, + aElemTypeData->_nbElems, + theConnMode, + theIsElemNum, + theIsElemNames); + // build map of family numbers for this type + if ( !isElemFamMapBuilt[ aElemTypeData->_smdsType ]) + { + //cout << " fillElemFamilyMap()" << endl; + fillElemFamilyMap( anElemFamMap, aFamilies, aElemTypeData->_smdsType ); + isElemFamMapBuilt[ aElemTypeData->_smdsType ] = true; + } + + TInt aNbNodes = MED::GetNbNodes(aElemTypeData->_geomType); + elemIterator = myMesh->elementsIterator( aElemTypeData->_smdsType ); + if ( aElemTypeData->_smdsType == SMDSAbs_0DElement && ! nodesOf0D.empty() ) + elemIterator = iterVecIter; + while ( elemIterator->more() ) + { + const SMDS_MeshElement* anElem = elemIterator->next(); + if ( anElem->NbNodes() != aNbNodes || anElem->IsPoly() ) + continue; // other geometry + + // connectivity + TConnSlice aTConnSlice = aCellInfo->GetConnSlice( iElem ); + for (TInt iNode = 0; iNode < aNbNodes; iNode++) { + const SMDS_MeshElement* aNode = anElem->GetNode( iNode ); +#ifdef _EDF_NODE_IDS_ + aTConnSlice[ iNode ] = aNodeIdMap[aNode->GetID()]; +#else + aTConnSlice[ iNode ] = aNode->GetID(); +#endif + } + // element number + aCellInfo->SetElemNum( iElem, anElem->GetID() ); + + // family number + int famNum = getFamilyId( anElemFamMap, anElem, defaultFamilyId ); + aCellInfo->SetFamNum( iElem, famNum ); + + if ( ++iElem == aCellInfo->GetNbElem() ) + break; + } + // store data in a file + myMed->SetCellInfo(aCellInfo); + } + + } // loop on geom types + + + } + catch(const std::exception& exc) { + INFOS("The following exception was caught:\n\t"<& nodes) +{ + nodes.clear(); + for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i ) + { + if ( meshDS->IndexToShape( i ).ShapeType() != TopAbs_VERTEX ) + continue; + if ( SMESHDS_SubMesh* sm = meshDS->MeshElements(i) ) { + SMDS_NodeIteratorPtr nIt= sm->GetNodes(); + while (nIt->more()) + { + const SMDS_MeshNode* n = nIt->next(); + if ( n->NbInverseElements( SMDSAbs_0DElement ) == 0 ) + nodes.push_back( n ); + } + } + } + return !nodes.empty(); }