X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDLoader%2FMEDFileMesh.cxx;h=66355a7dc44770bba2ca97bd4d0866471f271d82;hb=68a0c40d78df28a0ecf45af75c138c6789f25bf1;hp=dd31d0a96efc5b31e474969a0f0203fe1d8f10fe;hpb=b3484c5993a2fb7f31ce22644a39742326007cdb;p=tools%2Fmedcoupling.git diff --git a/src/MEDLoader/MEDFileMesh.cxx b/src/MEDLoader/MEDFileMesh.cxx index dd31d0a96..66355a7dc 100644 --- a/src/MEDLoader/MEDFileMesh.cxx +++ b/src/MEDLoader/MEDFileMesh.cxx @@ -1,9 +1,9 @@ -// Copyright (C) 2007-2013 CEA/DEN, EDF R&D +// Copyright (C) 2007-2015 CEA/DEN, EDF R&D // // 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. +// 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 @@ -32,6 +32,8 @@ #include #include +extern med_geometry_type typmai3[34]; + using namespace ParaMEDMEM; const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO"; @@ -54,7 +56,7 @@ std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const return ret; } -std::vector MEDFileMesh::getDirectChildren() const +std::vector MEDFileMesh::getDirectChildrenWithNull() const { return std::vector(); } @@ -69,7 +71,7 @@ std::vector MEDFileMesh::getDirectChildren() const * \throw If there is no meshes in the file. * \throw If the mesh in the file is of a not supported type. */ -MEDFileMesh *MEDFileMesh::New(const char *fileName, MEDFileMeshReadSelector *mrs) +MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs) { std::vector ms=MEDLoader::GetMeshNames(fileName); if(ms.empty()) @@ -79,28 +81,28 @@ MEDFileMesh *MEDFileMesh::New(const char *fileName, MEDFileMeshReadSelector *mrs } MEDFileUtilities::CheckFileForRead(fileName); ParaMEDMEM::MEDCouplingMeshType meshType; - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); int dt,it; std::string dummy2; - MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2); + MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2); switch(meshType) - { + { case UNSTRUCTURED: { MEDCouplingAutoRefCountObjectPtr ret=MEDFileUMesh::New(); - ret->loadUMeshFromFile(fid,ms.front().c_str(),dt,it,mrs); + ret->loadUMeshFromFile(fid,ms.front(),dt,it,mrs); return (MEDFileUMesh *)ret.retn(); } case CARTESIAN: { MEDCouplingAutoRefCountObjectPtr ret=MEDFileCMesh::New(); - ret->loadCMeshFromFile(fid,ms.front().c_str(),dt,it,mrs); + ret->loadCMeshFromFile(fid,ms.front(),dt,it,mrs); return (MEDFileCMesh *)ret.retn(); } case CURVE_LINEAR: { MEDCouplingAutoRefCountObjectPtr ret=MEDFileCurveLinearMesh::New(); - ret->loadCLMeshFromFile(fid,ms.front().c_str(),dt,it,mrs); + ret->loadCLMeshFromFile(fid,ms.front(),dt,it,mrs); return (MEDFileCurveLinearMesh *)ret.retn(); } default: @@ -108,7 +110,7 @@ MEDFileMesh *MEDFileMesh::New(const char *fileName, MEDFileMeshReadSelector *mrs std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - } + } } /*! @@ -125,16 +127,16 @@ MEDFileMesh *MEDFileMesh::New(const char *fileName, MEDFileMeshReadSelector *mrs * \throw If there is no mesh with given attributes in the file. * \throw If the mesh in the file is of a not supported type. */ -MEDFileMesh *MEDFileMesh::New(const char *fileName, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) +MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) { MEDFileUtilities::CheckFileForRead(fileName); ParaMEDMEM::MEDCouplingMeshType meshType; - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); int dummy0,dummy1; std::string dummy2; MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2); switch(meshType) - { + { case UNSTRUCTURED: { MEDCouplingAutoRefCountObjectPtr ret=MEDFileUMesh::New(); @@ -158,7 +160,7 @@ MEDFileMesh *MEDFileMesh::New(const char *fileName, const char *mName, int dt, i std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - } + } } /*! @@ -187,12 +189,12 @@ void MEDFileMesh::write(med_idt fid) const * \throw If the mesh name is not set. * \throw If \a mode == 1 and the same data is present in an existing file. */ -void MEDFileMesh::write(const char *fileName, int mode) const +void MEDFileMesh::write(const std::string& fileName, int mode) const { med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,medmod); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\""; - MEDFileUtilities::CheckMEDCode(fid,fid,oss.str().c_str()); + MEDFileUtilities::CheckMEDCode(fid,fid,oss.str()); write(fid); } @@ -243,12 +245,17 @@ bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& wha return true; } +void MEDFileMesh::setName(const std::string& name) +{ + _name=name; +} + /*! * Clears redundant attributes of incorporated data arrays. */ void MEDFileMesh::clearNonDiscrAttributes() const { - + } bool MEDFileMesh::changeNames(const std::vector< std::pair >& modifTab) @@ -319,7 +326,7 @@ void MEDFileMesh::clearFamGrpMaps() * \return std::vector - a sequence of names of the families. * \throw If the name of a nonexistent group is specified. */ -std::vector MEDFileMesh::getFamiliesOnGroup(const char *name) const +std::vector MEDFileMesh::getFamiliesOnGroup(const std::string& name) const { std::string oname(name); std::map >::const_iterator it=_groups.find(oname); @@ -364,7 +371,7 @@ std::vector MEDFileMesh::getFamiliesOnGroups(const std::vector - sequence of ids of the families. * \throw If the name of a nonexistent group is specified. */ -std::vector MEDFileMesh::getFamiliesIdsOnGroup(const char *name) const +std::vector MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const { std::string oname(name); std::map >::const_iterator it=_groups.find(oname); @@ -385,7 +392,7 @@ std::vector MEDFileMesh::getFamiliesIdsOnGroup(const char *name) const * \param [in] name - the name of the group of interest. * \param [in] fams - a sequence of names of families constituting the group. */ -void MEDFileMesh::setFamiliesOnGroup(const char *name, const std::vector& fams) +void MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector& fams) { std::string oname(name); _groups[oname]=fams; @@ -405,7 +412,7 @@ void MEDFileMesh::setFamiliesOnGroup(const char *name, const std::vector& famIds) +void MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector& famIds) { std::string oname(name); std::vector fams(famIds.size()); @@ -423,7 +430,7 @@ void MEDFileMesh::setFamiliesIdsOnGroup(const char *name, const std::vector * \param [in] name - the name of the family of interest. * \return std::vector - a sequence of names of groups including the family. */ -std::vector MEDFileMesh::getGroupsOnFamily(const char *name) const +std::vector MEDFileMesh::getGroupsOnFamily(const std::string& name) const { std::vector ret; for(std::map >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++) @@ -444,7 +451,7 @@ std::vector MEDFileMesh::getGroupsOnFamily(const char *name) const * \param [in] grps - a sequence of group names to add the family in. * \throw If a family named \a famName not yet exists. */ -void MEDFileMesh::setGroupsOnFamily(const char *famName, const std::vector& grps) +void MEDFileMesh::setGroupsOnFamily(const std::string& famName, const std::vector& grps) { std::string fName(famName); const std::map::const_iterator it=_families.find(fName); @@ -504,7 +511,7 @@ void MEDFileMesh::assignFamilyNameWithGroupName() std::map newFams; for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) { - std::vector grps=getGroupsOnFamily((*it).first.c_str()); + std::vector grps=getGroupsOnFamily((*it).first); if(grps.size()==1 && groups[grps[0]].size()==1) { if(newFams.find(grps[0])!=newFams.end()) @@ -557,7 +564,7 @@ std::vector MEDFileMesh::removeEmptyGroups() * \param [in] name - the name of the group to remove. * \throw If no group with such a \a name exists. */ -void MEDFileMesh::removeGroup(const char *name) +void MEDFileMesh::removeGroup(const std::string& name) { std::string oname(name); std::map >::iterator it=_groups.find(oname); @@ -576,7 +583,7 @@ void MEDFileMesh::removeGroup(const char *name) * \param [in] name - the name of the family to remove. * \throw If no family with such a \a name exists. */ -void MEDFileMesh::removeFamily(const char *name) +void MEDFileMesh::removeFamily(const std::string& name) { std::string oname(name); std::map::iterator it=_families.find(oname); @@ -638,7 +645,7 @@ std::vector MEDFileMesh::removeOrphanFamilies() else { ret.push_back((*it).first); - std::vector grpsOnEraseFam=getGroupsOnFamily((*it).first.c_str()); + std::vector grpsOnEraseFam=getGroupsOnFamily((*it).first); for(std::vector::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++) { std::map >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy @@ -653,6 +660,81 @@ std::vector MEDFileMesh::removeOrphanFamilies() return ret; } +/*! + * This method operates only on maps in \a this. The arrays are not considered here. So this method will remove a family (except "FAMILLE_ZERO" family) if no group lies on it whatever + * this family is orphan or not. + * + * \warning this method is different from removeOrphanFamilies that scans family field array to find orphan families. + */ +void MEDFileMesh::removeFamiliesReferedByNoGroups() +{ + std::map fams; + std::set sfams; + for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) + sfams.insert((*it).first); + for(std::map >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++) + for(std::vector::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++) + sfams.erase(*it1); + for(std::set::const_iterator it=sfams.begin();it!=sfams.end();it++) + if(*it!=DFT_FAM_NAME) + _families.erase(*it); +} + +/*! + * This method has no impact on groups. This method only works on families. This method firstly removes families not refered by any groups in \a this, then all unused entities + * are put as belonging to family 0 ("FAMILLE_ZERO"). Finally, all orphanFamilies are killed. + * This method raises an exception if "FAMILLE_ZERO" is already belonging to a group. + * + * \sa MEDFileMesh::removeOrphanFamilies + */ +void MEDFileMesh::rearrangeFamilies() +{ + checkOrphanFamilyZero(); + removeFamiliesReferedByNoGroups(); + // + std::vector levels(getNonEmptyLevelsExt()); + std::set idsRefed; + for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) + idsRefed.insert((*it).second); + for(std::vector::const_iterator it=levels.begin();it!=levels.end();it++) + { + const DataArrayInt *fams(0); + try + { + fams=getFamilyFieldAtLevel(*it); + } + catch(INTERP_KERNEL::Exception& e) { } + if(!fams) + continue; + std::vector v(fams->getNumberOfTuples(),false); + for(std::set::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++) + fams->switchOnTupleEqualTo(*pt,v); + MEDCouplingAutoRefCountObjectPtr unfetchedIds(DataArrayInt::BuildListOfSwitchedOff(v)); + if(!unfetchedIds->empty()) + { + MEDCouplingAutoRefCountObjectPtr newFams(fams->deepCpy()); + newFams->setPartOfValuesSimple3(0,unfetchedIds->begin(),unfetchedIds->end(),0,1,1); + setFamilyFieldArr(*it,newFams); + } + } + removeOrphanFamilies(); +} + +/*! + * This method only checks that "FAMILLE_ZERO" is orphan (not belonging to a group). + */ +void MEDFileMesh::checkOrphanFamilyZero() const +{ + for(std::map >::const_iterator it=_groups.begin();it!=_groups.end();it++) + { + if(std::find((*it).second.begin(),(*it).second.end(),DFT_FAM_NAME)!=(*it).second.end()) + { + std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Groups \"" << (*it).first << "\" is lying on family \"" << DFT_FAM_NAME << "\" !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } +} + /*! * Renames a group in \a this mesh. * \param [in] oldName - a current name of the group to rename. @@ -660,7 +742,7 @@ std::vector MEDFileMesh::removeOrphanFamilies() * \throw If no group named \a oldName exists in \a this mesh. * \throw If a group named \a newName already exists. */ -void MEDFileMesh::changeGroupName(const char *oldName, const char *newName) +void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName) { std::string oname(oldName); std::map >::iterator it=_groups.find(oname); @@ -710,7 +792,7 @@ void MEDFileMesh::changeFamilyId(int oldId, int newId) * \throw If no family named \a oldName exists in \a this mesh. * \throw If a family named \a newName already exists. */ -void MEDFileMesh::changeFamilyName(const char *oldName, const char *newName) +void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName) { std::string oname(oldName); std::map::iterator it=_families.find(oname); @@ -808,7 +890,7 @@ bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) cons { oss << " Group \"" << (*it).first << "\" on following families :\n"; for(std::vector::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++) - oss << " \"" << *it2 << "\n"; + oss << " \"" << *it2 << "\n"; } oss << "Second group description :\n"; for(std::map >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++) @@ -827,7 +909,7 @@ bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) cons * \param [in] groupName - the group name. * \return bool - \c true the group \a groupName exists in \a this mesh. */ -bool MEDFileMesh::existsGroup(const char *groupName) const +bool MEDFileMesh::existsGroup(const std::string& groupName) const { std::string grpName(groupName); return _groups.find(grpName)!=_groups.end(); @@ -851,7 +933,7 @@ bool MEDFileMesh::existsFamily(int famId) const * \param [in] familyName - the family name. * \return bool - \c true the family \a familyName exists in \a this mesh. */ -bool MEDFileMesh::existsFamily(const char *familyName) const +bool MEDFileMesh::existsFamily(const std::string& familyName) const { std::string fname(familyName); return _families.find(fname)!=_families.end(); @@ -862,13 +944,13 @@ bool MEDFileMesh::existsFamily(const char *familyName) const * \param [in] familyName - the family name. * \param [in] id - a new id of the family. */ -void MEDFileMesh::setFamilyId(const char *familyName, int id) +void MEDFileMesh::setFamilyId(const std::string& familyName, int id) { std::string fname(familyName); _families[fname]=id; } -void MEDFileMesh::setFamilyIdUnique(const char *familyName, int id) +void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id) { std::string fname(familyName); for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) @@ -889,20 +971,20 @@ void MEDFileMesh::setFamilyIdUnique(const char *familyName, int id) * \param [in] famId - an id of the family. * \throw If a family with the same name or id already exists in \a this mesh. */ -void MEDFileMesh::addFamily(const char *familyName, int famId) +void MEDFileMesh::addFamily(const std::string& familyName, int famId) { std::string fname(familyName); std::map::const_iterator it=_families.find(fname); if(it==_families.end()) { - for(std::map::const_iterator it2=_families.begin();it2!=_families.end();it2++) - if((*it2).second==famId) - { - std::ostringstream oss; - oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - _families[fname]=famId; + for(std::map::const_iterator it2=_families.begin();it2!=_families.end();it2++) + if((*it2).second==famId) + { + std::ostringstream oss; + oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + _families[fname]=famId; } else { @@ -928,7 +1010,7 @@ void MEDFileMesh::addFamily(const char *familyName, int famId) * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh. * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh. */ -void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const char *groupName) +void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName) { std::string grpName(groupName); std::vector levs=getNonEmptyLevelsExt(); @@ -996,7 +1078,7 @@ bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector& famIds, const std std::string famName=getFamilyNameGivenId(*it2); std::ostringstream oss; oss << "Family_" << maxFamId; std::string zeName=CreateNameNotIn(oss.str(),allFams); - addFamilyOnAllGroupsHaving(famName.c_str(),zeName.c_str()); + addFamilyOnAllGroupsHaving(famName,zeName); _families[zeName]=maxFamId; (const_cast(fieldFamIds))->changeValue(*it2,maxFamId); maxFamId++; @@ -1014,7 +1096,7 @@ bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector& famIds, const std * \throw If \a grpName or \a famName is an empty string. * \throw If no family named \a famName is present in \a this mesh. */ -void MEDFileMesh::addFamilyOnGrp(const char *grpName, const char *famName) +void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName) { std::string grpn(grpName); std::string famn(famName); @@ -1046,7 +1128,7 @@ void MEDFileMesh::addFamilyOnGrp(const char *grpName, const char *famName) * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families. * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method. */ -void MEDFileMesh::addFamilyOnAllGroupsHaving(const char *famName, const char *otherFamName) +void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName) { std::string famNameCpp(famName); std::string otherCpp(otherFamName); @@ -1060,12 +1142,12 @@ void MEDFileMesh::addFamilyOnAllGroupsHaving(const char *famName, const char *ot } } -void MEDFileMesh::changeAllGroupsContainingFamily(const char *familyNameToChange, const std::vector& newFamiliesNames) +void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector& newFamiliesNames) { ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames); } -void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map >& groups, const char *familyNameToChange, const std::vector& newFamiliesNames) +void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map >& groups, const std::string& familyNameToChange, const std::vector& newFamiliesNames) { std::string fam(familyNameToChange); for(std::map >::iterator it=groups.begin();it!=groups.end();it++) @@ -1149,7 +1231,7 @@ void MEDFileMesh::setGroupInfo(const std::map::const_iterator it=_families.find(oname); @@ -1355,12 +1437,12 @@ bool MEDFileMesh::ensureDifferentFamIdsPerLevel() if(allIds->presenceOfValue(*it3)) { std::string famName=getFamilyNameGivenId(*it3); - std::vector grps=getGroupsOnFamily(famName.c_str()); + std::vector grps=getGroupsOnFamily(famName); ren[*it3]=maxId; bool dummy; std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy); for(std::vector::const_iterator it4=grps.begin();it4!=grps.end();it4++) - addFamilyOnGrp((*it4).c_str(),newFam.c_str()); + addFamilyOnGrp((*it4),newFam); } } MEDCouplingAutoRefCountObjectPtr ids=fam->getIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size()); @@ -1581,7 +1663,7 @@ std::string MEDFileMesh::simpleRepr() const * \throw If the name of a nonexistent group is specified. * \throw If the family field is missing for \a meshDimRelToMaxExt. */ -DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const char *grp, bool renum) const +DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const { std::vector tmp(1); tmp[0]=grp; @@ -1621,7 +1703,7 @@ DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vecto * is to delete this array using decrRef() as it is no more needed. * \throw If the family field is missing for \a meshDimRelToMaxExt. */ -DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const char *fam, bool renum) const +DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const { std::vector tmp(1); tmp[0]=fam; @@ -1641,7 +1723,7 @@ DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const char *fam, * \throw If the name of a nonexistent group is specified. * \throw If the family field is missing for nodes. */ -DataArrayInt *MEDFileMesh::getNodeGroupArr(const char *grp, bool renum) const +DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const { std::vector tmp(1); tmp[0]=grp; @@ -1677,7 +1759,7 @@ DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector& grps * \throw If the name of a nonexistent group is specified. * \throw If the family field is missing for nodes. */ -DataArrayInt *MEDFileMesh::getNodeFamilyArr(const char *fam, bool renum) const +DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const { std::vector tmp(1); tmp[0]=fam; @@ -1743,7 +1825,7 @@ void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vectorsetName(grps[ii]->getName().c_str()); + grps2[ii]->setName(grps[ii]->getName()); } std::vector grps3(grps2.begin(),grps2.end()); fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups); @@ -1782,6 +1864,18 @@ void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vec } } +std::vector MEDFileMesh::getAllGeoTypes() const +{ + std::vector levs(getNonEmptyLevels()); + std::vector ret; + for(std::vector::const_iterator it=levs.begin();it!=levs.end();it++) + { + std::vector elts(getGeoTypesAtLevel(*it)); + ret.insert(ret.end(),elts.begin(),elts.end()); + } + return ret; +} + std::vector MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const { MEDCouplingAutoRefCountObjectPtr mLev(getGenMeshAtLevel(meshDimRelToMax)); @@ -1900,7 +1994,7 @@ void MEDFileMesh::getFamilyRepr(std::ostream& oss) const { oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl; oss << " - Groups lying on this family : "; - std::vector grps=getGroupsOnFamily((*it).first.c_str()); + std::vector grps=getGroupsOnFamily((*it).first); std::copy(grps.begin(),grps.end(),std::ostream_iterator(oss," ")); oss << std::endl << std::endl; } @@ -1920,10 +2014,10 @@ void MEDFileMesh::getFamilyRepr(std::ostream& oss) const * \throw If there is no mesh with given attributes in the file. * \throw If the mesh in the file is not an unstructured one. */ -MEDFileUMesh *MEDFileUMesh::New(const char *fileName, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) +MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) { MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); return new MEDFileUMesh(fid,mName,dt,it,mrs); } @@ -1937,7 +2031,7 @@ MEDFileUMesh *MEDFileUMesh::New(const char *fileName, const char *mName, int dt, * \throw If there is no meshes in the file. * \throw If the mesh in the file is not an unstructured one. */ -MEDFileUMesh *MEDFileUMesh::New(const char *fileName, MEDFileMeshReadSelector *mrs) +MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs) { std::vector ms=MEDLoader::GetMeshNames(fileName); if(ms.empty()) @@ -1946,12 +2040,12 @@ MEDFileUMesh *MEDFileUMesh::New(const char *fileName, MEDFileMeshReadSelector *m throw INTERP_KERNEL::Exception(oss.str().c_str()); } MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); int dt,it; ParaMEDMEM::MEDCouplingMeshType meshType; std::string dummy2; - MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2); - return new MEDFileUMesh(fid,ms.front().c_str(),dt,it,mrs); + MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2); + return new MEDFileUMesh(fid,ms.front(),dt,it,mrs); } /*! @@ -1964,6 +2058,40 @@ MEDFileUMesh *MEDFileUMesh::New() return new MEDFileUMesh; } +/*! + * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that + * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters + * \a types and \a slicPerTyp. This method allows to load from a mesh (typically huge) in a MED file a part of cells of that mesh. + * The part of cells is specified using triplet (start,stop,step) for each geometric type. Only nodes lying on selected cells will be loaded to reduce + * at most the memory consumtion. + * + * \param [in] fileName - the name of the file. + * \param [in] mName - the name of the mesh to be read. + * \param [in] types - the list of the geo types of which some part will be taken. A geometric type in \a types must appear only once at most. + * \param [in] slicPerType - an array of size 3 times larger than \a types that specifies for each type in \a types (in the same order) resp the start, the stop and the step. + * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step. + * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step. + * \param [in] mrs - the request for what to be loaded. + * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed. + */ +MEDFileUMesh *MEDFileUMesh::LoadPartOf(const std::string& fileName, const std::string& mName, const std::vector& types, const std::vector& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY)); + return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs); +} + +/*! + * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first). + * This method is \b NOT wrapped into python. + */ +MEDFileUMesh *MEDFileUMesh::LoadPartOf(med_idt fid, const std::string& mName, const std::vector& types, const std::vector& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs) +{ + MEDCouplingAutoRefCountObjectPtr ret(MEDFileUMesh::New()); + ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs); + return ret.retn(); +} + std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const { std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren()); @@ -1971,22 +2099,17 @@ std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const return ret; } -std::vector MEDFileUMesh::getDirectChildren() const +std::vector MEDFileUMesh::getDirectChildrenWithNull() const { - std::vector ret(MEDFileMesh::getDirectChildren()); - if((const DataArrayDouble*)_coords) - ret.push_back((const DataArrayDouble*)_coords); - if((const DataArrayInt *)_fam_coords) - ret.push_back((const DataArrayInt *)_fam_coords); - if((const DataArrayInt *)_num_coords) - ret.push_back((const DataArrayInt *)_num_coords); - if((const DataArrayInt *)_rev_num_coords) - ret.push_back((const DataArrayInt *)_rev_num_coords); - if((const DataArrayAsciiChar *)_name_coords) - ret.push_back((const DataArrayAsciiChar *)_name_coords); + std::vector ret(MEDFileMesh::getDirectChildrenWithNull()); + ret.push_back((const DataArrayDouble*)_coords); + ret.push_back((const DataArrayInt *)_fam_coords); + ret.push_back((const DataArrayInt *)_num_coords); + ret.push_back((const DataArrayInt *)_rev_num_coords); + ret.push_back((const DataArrayAsciiChar *)_name_coords); + ret.push_back((const PartDefinition *)_part_coords); for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) - if((const MEDFileUMeshSplitL1*) *it) - ret.push_back((const MEDFileUMeshSplitL1*) *it); + ret.push_back((const MEDFileUMeshSplitL1*) *it); return ret; } @@ -2020,6 +2143,8 @@ MEDFileMesh *MEDFileUMesh::deepCpy() const if((const MEDFileUMeshSplitL1 *)(*it)) ret->_ms[i]=(*it)->deepCpy(ret->_coords); } + if((const PartDefinition*)_part_coords) + ret->_part_coords=_part_coords->deepCpy(); return ret.retn(); } @@ -2128,7 +2253,15 @@ bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& wh return false; } } - return true; + const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords); + if(!pd0 && !pd1) + return true; + if((!pd0 && pd1) || (pd0 && !pd1)) + { + what=std::string("node part def is defined only for one among this or other !"); + return false; + } + return pd0->isEqual(pd1,what); } /*! @@ -2157,33 +2290,74 @@ void MEDFileUMesh::clearNonDiscrAttributes() const } } +void MEDFileUMesh::setName(const std::string& name) +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_ms.begin();it!=_ms.end();it++) + if((MEDFileUMeshSplitL1 *)(*it)!=0) + (*it)->setName(name); + MEDFileMesh::setName(name); +} + MEDFileUMesh::MEDFileUMesh() { } -MEDFileUMesh::MEDFileUMesh(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) +MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) try - { +{ loadUMeshFromFile(fid,mName,dt,it,mrs); - } +} catch(INTERP_KERNEL::Exception& e) - { +{ throw e; - } +} + +/*! + * This method loads only a part of specified cells (given by range of cell ID per geometric type) + * See MEDFileUMesh::LoadPartOf for detailed description. + * + * \sa loadUMeshFromFile + */ +void MEDFileUMesh::loadPartUMeshFromFile(med_idt fid, const std::string& mName, const std::vector& types, const std::vector& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs) +{ + MEDFileUMeshL2 loaderl2; + ParaMEDMEM::MEDCouplingMeshType meshType; + int dummy0,dummy1; + std::string dummy2; + int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2)); + if(meshType!=UNSTRUCTURED) + { + std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs); + dispatchLoadedPart(fid,loaderl2,mName,mrs); +} -void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) +/*! + * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor. + * + * \sa loadPartUMeshFromFile + */ +void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) { MEDFileUMeshL2 loaderl2; ParaMEDMEM::MEDCouplingMeshType meshType; int dummy0,dummy1; std::string dummy2; - int mid=MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2); + int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2)); if(meshType!=UNSTRUCTURED) { std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } loaderl2.loadAll(fid,mid,mName,dt,it,mrs); + dispatchLoadedPart(fid,loaderl2,mName,mrs); + +} + +void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs) +{ int lev=loaderl2.getNumberOfLevels(); _ms.resize(lev); for(int i=0;iisNodeNameFieldReading()) _name_coords=loaderl2.getCoordsName(); + _part_coords=loaderl2.getPartDefOfCoo(); computeRevNum(); } @@ -2224,7 +2399,9 @@ void MEDFileUMesh::writeLL(med_idt fid) const MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str); MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str); int spaceDim=coo?coo->getNumberOfComponents():0; - int mdim=getMeshDimension(); + int mdim(0); + if(!_ms.empty()) + mdim=getMeshDimension(); INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); for(int i=0;i >::const_iterator it=_ms.begin();it!=_ms.end();it++) if((const MEDFileUMeshSplitL1 *)(*it)!=0) - (*it)->write(fid,maa,mdim); - MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa,_families,_groups,_too_long_str); + (*it)->write(fid,meshName,mdim); + MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str); } /*! @@ -2333,7 +2511,7 @@ std::vector MEDFileUMesh::getNameArrNonEmptyLevelsExt() const * \param [in] grp - the name of the group of interest. * \return std::vector - a sequence of the relative dimensions. */ -std::vector MEDFileUMesh::getGrpNonEmptyLevels(const char *grp) const +std::vector MEDFileUMesh::getGrpNonEmptyLevels(const std::string& grp) const { std::vector fams=getFamiliesOnGroup(grp); return getFamsNonEmptyLevels(fams); @@ -2344,7 +2522,7 @@ std::vector MEDFileUMesh::getGrpNonEmptyLevels(const char *grp) const * \param [in] grp - the name of the group of interest. * \return std::vector - a sequence of the relative dimensions. */ -std::vector MEDFileUMesh::getGrpNonEmptyLevelsExt(const char *grp) const +std::vector MEDFileUMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const { std::vector fams=getFamiliesOnGroup(grp); return getFamsNonEmptyLevelsExt(fams); @@ -2356,7 +2534,7 @@ std::vector MEDFileUMesh::getGrpNonEmptyLevelsExt(const char *grp) const * \param [in] fam - the name of the family of interest. * \return std::vector - a sequence of the relative dimensions. */ -std::vector MEDFileUMesh::getFamNonEmptyLevels(const char *fam) const +std::vector MEDFileUMesh::getFamNonEmptyLevels(const std::string& fam) const { std::vector fams(1,std::string(fam)); return getFamsNonEmptyLevels(fams); @@ -2367,7 +2545,7 @@ std::vector MEDFileUMesh::getFamNonEmptyLevels(const char *fam) const * \param [in] fam - the name of the family of interest. * \return std::vector - a sequence of the relative dimensions. */ -std::vector MEDFileUMesh::getFamNonEmptyLevelsExt(const char *fam) const +std::vector MEDFileUMesh::getFamNonEmptyLevelsExt(const std::string& fam) const { std::vector fams(1,std::string(fam)); return getFamsNonEmptyLevelsExt(fams); @@ -2448,7 +2626,7 @@ std::vector MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToM std::vector allGrps=getGroupsNames(); for(std::vector::const_iterator it=allGrps.begin();it!=allGrps.end();it++) { - std::vector levs=getGrpNonEmptyLevelsExt((*it).c_str()); + std::vector levs=getGrpNonEmptyLevelsExt((*it)); if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end()) ret.push_back(*it); } @@ -2666,6 +2844,21 @@ const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxE return l1->getNameField(); } +/*! + * This method returns for a specified relative level \a meshDimRelToMaxExt the part effectively read (if the instance is the result of the read of a file). + * + * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested. + * \param [in] gt - The input geometric type for which the part definition is requested. + * \return the part definition owned by \a this. So no need to deallocate the returned instance. + */ +const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const +{ + if(meshDimRelToMaxExt==1) + return _part_coords; + const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt)); + return l1->getPartDef(gt); +} + int MEDFileUMesh::getNumberOfNodes() const { const DataArrayDouble *coo=_coords; @@ -2674,6 +2867,26 @@ int MEDFileUMesh::getNumberOfNodes() const return coo->getNumberOfTuples(); } +int MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const +{ + const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); + return l1->getNumberOfCells(); +} + +bool MEDFileUMesh::hasImplicitPart() const +{ + return false; +} + +int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const +{ + throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !"); +} + +void MEDFileUMesh::releaseImplicitPartIfAny() const +{ +} + void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector& nodesFetched) const { std::size_t sz(st.getNumberOfItems()); @@ -2685,7 +2898,7 @@ void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, con m->computeNodeIdsAlg(nodesFetched); else { - const DataArrayInt *arr(globs->getProfile(st[i].getPflName().c_str())); + const DataArrayInt *arr(globs->getProfile(st[i].getPflName())); MEDCouplingAutoRefCountObjectPtr m2(dynamic_cast(m->buildPartOfMySelf(arr->begin(),arr->end(),true))); m2->computeNodeIdsAlg(nodesFetched); } @@ -2740,7 +2953,7 @@ DataArrayDouble *MEDFileUMesh::getCoords() const * \throw If the name of a nonexistent group is specified. * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. */ -MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const char *grp, bool renum) const +MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const { synchronizeTinyInfoOnLeaves(); std::vector tmp(1); @@ -2768,7 +2981,7 @@ MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vec std::vector fams2=getFamiliesOnGroups(grps); MEDCouplingAutoRefCountObjectPtr zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum); if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet)) - zeRet->setName(grps[0].c_str()); + zeRet->setName(grps[0]); return zeRet.retn(); } @@ -2786,7 +2999,7 @@ MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vec * \throw If a name of a nonexistent family is present in \a grps. * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. */ -MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const char *fam, bool renum) const +MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const { synchronizeTinyInfoOnLeaves(); std::vector tmp(1); @@ -2827,7 +3040,7 @@ MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::v else zeRet=l1->getFamilyPart(0,0,renum); if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet)) - zeRet->setName(fams[0].c_str()); + zeRet->setName(fams[0]); return zeRet.retn(); } @@ -2895,7 +3108,7 @@ MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renu MEDCouplingAutoRefCountObjectPtr cc=_coords->deepCpy(); umesh->setCoords(cc); MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh); - umesh->setName(getName().c_str()); + umesh->setName(getName()); return umesh; } } @@ -3061,6 +3274,18 @@ DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::Normalize return sp->extractNumberFieldOnGeoType(gt); } +/*! + * This method returns for specified geometric type \a gt the relative level to \a this. + * If the relative level is empty an exception will be thrown. + */ +int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const +{ + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt); + int ret((int)cm.getDimension()-getMeshDimension()); + getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level. + return ret; +} + const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const { if(meshDimRelToMaxExt==1) @@ -3069,7 +3294,7 @@ const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !"); int tracucedRk=-meshDimRelToMaxExt; if(tracucedRk>=(int)_ms.size()) - throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !"); + throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !"); if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0) throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !"); return _ms[tracucedRk]; @@ -3077,13 +3302,13 @@ const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) { - if(meshDimRelToMaxExt==1) + if(meshDimRelToMaxExt==1) throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !"); if(meshDimRelToMaxExt>1) throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !"); int tracucedRk=-meshDimRelToMaxExt; if(tracucedRk>=(int)_ms.size()) - throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !"); + throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !"); if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0) throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !"); return _ms[tracucedRk]; @@ -3185,7 +3410,7 @@ void MEDFileUMesh::optimizeFamilies() _groups.erase(*it); } -void MEDFileUMesh::duplicateNodesOnM1Group(const char *grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified) +void MEDFileUMesh::duplicateNodesOnM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified) { std::vector levs=getNonEmptyLevels(); if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end()) @@ -3229,7 +3454,7 @@ void MEDFileUMesh::duplicateNodesOnM1Group(const char *grpNameM1, DataArrayInt * MEDCouplingAutoRefCountObjectPtr szOfCellGrpOfSameType(tmp00); MEDCouplingAutoRefCountObjectPtr idInMsOfCellGrpOfSameType(tmp11); // - newm1->setName(getName().c_str()); + newm1->setName(getName()); const DataArrayInt *fam=getFamilyFieldAtLevel(-1); if(!fam) throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : internal problem !"); @@ -3258,8 +3483,8 @@ void MEDFileUMesh::duplicateNodesOnM1Group(const char *grpNameM1, DataArrayInt * setMeshAtLevel(-1,newm1); setFamilyFieldArr(-1,newFam); std::string grpName2(grpNameM1); grpName2+="_dup"; - addFamily(grpName2.c_str(),idd); - addFamilyOnGrp(grpName2.c_str(),grpName2.c_str()); + addFamily(grpName2,idd); + addFamilyOnGrp(grpName2,grpName2); // fam=_fam_coords; if(fam) @@ -3301,7 +3526,7 @@ bool MEDFileUMesh::unPolyze(std::vector& oldCode, std::vector& newCode bool hasChanged=m->unPolyze(); DataArrayInt *fake=0; MEDCouplingAutoRefCountObjectPtr o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER, - MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake); + MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake); fake->decrRef(); renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart); if(hasChanged) @@ -3365,24 +3590,35 @@ struct MEDLoaderAccVisit1 */ DataArrayInt *MEDFileUMesh::zipCoords() { - const DataArrayDouble *coo=getCoords(); + const DataArrayDouble *coo(getCoords()); if(!coo) throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !"); - int nbOfNodes=coo->getNumberOfTuples(); + int nbOfNodes(coo->getNumberOfTuples()); std::vector nodeIdsInUse(nbOfNodes,false); - std::vector neLevs=getNonEmptyLevels(); + std::vector neLevs(getNonEmptyLevels()); for(std::vector::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++) { - MEDCouplingAutoRefCountObjectPtr m=getMeshAtLevel(*lev); - m->computeNodeIdsAlg(nodeIdsInUse); + const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev)); + if(zeLev->isMeshStoredSplitByType()) + { + std::vector ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes()); + for(std::vector::const_iterator it=ms.begin();it!=ms.end();it++) + if(*it) + (*it)->computeNodeIdsAlg(nodeIdsInUse); + } + else + { + MEDCouplingAutoRefCountObjectPtr mesh(zeLev->getWholeMesh(false)); + mesh->computeNodeIdsAlg(nodeIdsInUse); + } } - int nbrOfNodesInUse=(int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true); + int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true)); if(nbrOfNodesInUse==nbOfNodes) - return 0; - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbOfNodes,1); + return 0;//no need to update _part_coords + MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(nbOfNodes,1); std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1()); - MEDCouplingAutoRefCountObjectPtr ret2=ret->invertArrayO2N2N2OBis(nbrOfNodesInUse); - MEDCouplingAutoRefCountObjectPtr newCoords=coo->selectByTupleIdSafe(ret2->begin(),ret2->end()); + MEDCouplingAutoRefCountObjectPtr ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse)); + MEDCouplingAutoRefCountObjectPtr newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end())); MEDCouplingAutoRefCountObjectPtr newFamCoords; MEDCouplingAutoRefCountObjectPtr newNameCoords; if((const DataArrayInt *)_fam_coords) @@ -3396,15 +3632,443 @@ DataArrayInt *MEDFileUMesh::zipCoords() for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_ms.begin();it!=_ms.end();it++) { if((MEDFileUMeshSplitL1*)*it) - (*it)->renumberNodesInConn(ret->begin()); + { + (*it)->renumberNodesInConn(ret->begin()); + (*it)->setCoords(_coords); + } + } + // updates _part_coords + const PartDefinition *pc(_part_coords); + if(pc) + { + MEDCouplingAutoRefCountObjectPtr tmpPD(DataArrayPartDefinition::New(ret2)); + _part_coords=tmpPD->composeWith(pc); + } + return ret.retn(); +} + +/*! + * This method performs an extrusion along a path defined by \a m1D. + * \a this is expected to be a mesh with max mesh dimension equal to 2. + * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1. + * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this. + * This method scans all levels in \a this + * and put them in the returned mesh. All groups in \a this are also put in the returned mesh. + * + * \param [in] m1D - the mesh defining the extrusion path. + * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details) + * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this. + * + * \sa MEDCouplingUMesh::buildExtrudedMesh + */ +MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const +{ + if(getMeshDimension()!=2) + throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !"); + MEDCouplingAutoRefCountObjectPtr ret(MEDFileUMesh::New()); + m1D->checkCoherency(); + if(m1D->getMeshDimension()!=1) + throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !"); + int nbRep(m1D->getNumberOfCells()); + std::vector levs(getNonEmptyLevels()); + std::vector grps(getGroupsNames()); + std::vector< MEDCouplingAutoRefCountObjectPtr > zeList; + DataArrayDouble *coords(0); + std::size_t nbOfLevsOut(levs.size()+1); + std::vector< MEDCouplingAutoRefCountObjectPtr > o2ns(nbOfLevsOut); + for(std::vector::const_iterator lev=levs.begin();lev!=levs.end();lev++) + { + MEDCouplingAutoRefCountObjectPtr item(getMeshAtLevel(*lev)); + item=item->clone(false); + item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data + MEDCouplingAutoRefCountObjectPtr tmp(static_cast(m1D->deepCpy())); + tmp->changeSpaceDimension(3+(*lev),0.); + MEDCouplingAutoRefCountObjectPtr elt(item->buildExtrudedMesh(tmp,policy)); + zeList.push_back(elt); + if(*lev==0) + coords=elt->getCoords(); + } + if(!coords) + throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !"); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=zeList.begin();it!=zeList.end();it++) + { + (*it)->setName(getName()); + (*it)->setCoords(coords); + } + for(std::size_t ii=0;ii!=zeList.size();ii++) + { + int lev(levs[ii]); + MEDCouplingAutoRefCountObjectPtr elt(zeList[ii]); + if(lev<=-1) + { + MEDCouplingAutoRefCountObjectPtr elt1(getMeshAtLevel(lev+1)); + MEDCouplingAutoRefCountObjectPtr elt2(elt1->clone(false)); + MEDCouplingAutoRefCountObjectPtr tmp(elt2->getNodalConnectivity()->deepCpy()); + elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex()); + elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes()); + elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords()); + std::vector elts(3); + elts[0]=elt; elts[1]=elt1; elts[2]=elt2; + elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts); + elt->setName(getName()); + } + // + o2ns[ii]=elt->sortCellsInMEDFileFrmt(); + ret->setMeshAtLevel(lev,elt); + } + MEDCouplingAutoRefCountObjectPtr endLev(getMeshAtLevel(levs.back())),endLev2; + endLev=endLev->clone(false); endLev->setCoords(coords); + MEDCouplingAutoRefCountObjectPtr tmp(endLev->getNodalConnectivity()->deepCpy()); + endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex()); + endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes()); + endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2); + o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt(); + endLev->setName(getName()); + ret->setMeshAtLevel(levs.back()-1,endLev); + // + for(std::size_t ii=0;ii!=zeList.size();ii++) + { + int lev(levs[ii]); + std::vector< MEDCouplingAutoRefCountObjectPtr > outGrps; + std::vector< const DataArrayInt * > outGrps2; + if(lev<=-1) + { + for(std::vector::const_iterator grp=grps.begin();grp!=grps.end();grp++) + { + MEDCouplingAutoRefCountObjectPtr grpArr(getGroupArr(lev+1,*grp)); + if(!grpArr->empty()) + { + MEDCouplingAutoRefCountObjectPtr grpArr1(grpArr->deepCpy()),grpArr2(grpArr->deepCpy()); + int offset0(zeList[ii]->getNumberOfCells()); + int offset1(offset0+getNumberOfCellsAtLevel(lev+1)); + grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1); + std::ostringstream oss; oss << grpArr2->getName() << "_top"; + grpArr2->setName(oss.str()); + grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end()); + grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end()); + outGrps.push_back(grpArr1); outGrps.push_back(grpArr2); + outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2); + } + } + } + // + for(std::vector::const_iterator grp=grps.begin();grp!=grps.end();grp++) + { + MEDCouplingAutoRefCountObjectPtr grpArr(getGroupArr(lev,*grp)); + if(!grpArr->empty()) + { + int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev)); + std::vector< MEDCouplingAutoRefCountObjectPtr > grpArrs(nbRep); + std::vector< const DataArrayInt *> grpArrs2(nbRep); + for(int iii=0;iiideepCpy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion); + grpArrs2[iii]=grpArrs[iii]; + } + MEDCouplingAutoRefCountObjectPtr grpArrExt(DataArrayInt::Aggregate(grpArrs2)); + grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end()); + std::ostringstream grpName; grpName << *grp << "_extruded"; + grpArrExt->setName(grpName.str()); + outGrps.push_back(grpArrExt); + outGrps2.push_back(grpArrExt); + } + } + ret->setGroupsAtLevel(lev,outGrps2); + } + std::vector< MEDCouplingAutoRefCountObjectPtr > outGrps; + std::vector< const DataArrayInt * > outGrps2; + for(std::vector::const_iterator grp=grps.begin();grp!=grps.end();grp++) + { + MEDCouplingAutoRefCountObjectPtr grpArr1(getGroupArr(levs.back(),*grp)); + if(grpArr1->empty()) + continue; + MEDCouplingAutoRefCountObjectPtr grpArr2(grpArr1->deepCpy()); + std::ostringstream grpName; grpName << *grp << "_top"; + grpArr2->setName(grpName.str()); + grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back())); + outGrps.push_back(grpArr1); outGrps.push_back(grpArr2); + outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2); + } + ret->setGroupsAtLevel(levs.back()-1,outGrps2); + return ret.retn(); +} + +/*! + * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy). + * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance. + * Groups on nodes and families on nodes are copied directly to the returned instance without transformation. + * + * \param [in] conversionType - conversionType specifies the type of conversion expected. Only 0 (default) and 1 are supported presently. 0 those that creates the 'most' simple + * corresponding quadratic cells. 1 is those creating the 'most' complex. + * \param [in] eps - detection threshold for coordinates. + * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance. + * + * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear + */ +MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const +{ + MEDCouplingAutoRefCountObjectPtr ret(MEDFileUMesh::New()); + int initialNbNodes(getNumberOfNodes()); + MEDCouplingAutoRefCountObjectPtr m0Tmp(getMeshAtLevel(0)); + MEDCouplingAutoRefCountObjectPtr m0(dynamic_cast(m0Tmp->deepCpy())); + { + MEDCouplingAutoRefCountObjectPtr notUsed(m0->convertLinearCellsToQuadratic(conversionType)); + } + DataArrayDouble *zeCoords(m0->getCoords()); + ret->setMeshAtLevel(0,m0); + std::vector levs(getNonEmptyLevels()); + const DataArrayInt *famField(getFamilyFieldAtLevel(0)); + if(famField) + { + MEDCouplingAutoRefCountObjectPtr famFieldCpy(famField->deepCpy()); + ret->setFamilyFieldArr(0,famFieldCpy); + } + famField=getFamilyFieldAtLevel(1); + if(famField) + { + MEDCouplingAutoRefCountObjectPtr fam(DataArrayInt::New()); fam->alloc(zeCoords->getNumberOfTuples(),1); + fam->fillWithZero(); + fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1); + ret->setFamilyFieldArr(1,fam); + } + ret->copyFamGrpMapsFrom(*this); + MEDCouplingAutoRefCountObjectPtr partZeCoords(zeCoords->selectByTupleId2(initialNbNodes,zeCoords->getNumberOfTuples(),1)); + for(std::vector::const_iterator lev=levs.begin();lev!=levs.end();lev++) + { + if(*lev==0) + continue; + MEDCouplingAutoRefCountObjectPtr m1Tmp(getMeshAtLevel(*lev)); + MEDCouplingAutoRefCountObjectPtr m1(dynamic_cast(m1Tmp->deepCpy())); + { + MEDCouplingAutoRefCountObjectPtr notUsed(m1->convertLinearCellsToQuadratic(conversionType)); + } + MEDCouplingAutoRefCountObjectPtr m1Coords(m1->getCoords()->selectByTupleId2(initialNbNodes,m1->getNumberOfNodes(),1)); + DataArrayInt *b(0); + bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b)); + MEDCouplingAutoRefCountObjectPtr bSafe(b); + if(!a) + { + std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + b->applyLin(1,initialNbNodes); + MEDCouplingAutoRefCountObjectPtr l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota(); + std::vector v(2); v[0]=l0; v[1]=b; + MEDCouplingAutoRefCountObjectPtr renum(DataArrayInt::Aggregate(v)); + m1->renumberNodesInConn(renum->begin()); + m1->setCoords(zeCoords); + ret->setMeshAtLevel(*lev,m1); + famField=getFamilyFieldAtLevel(*lev); + if(famField) + { + MEDCouplingAutoRefCountObjectPtr famFieldCpy(famField->deepCpy()); + ret->setFamilyFieldArr(*lev,famFieldCpy); + } + } + return ret.retn(); +} + +/*! + * This method converts all quadratic cells in \a this into linear cells. + * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance. + * Groups on nodes and families on nodes are copied directly to the returned instance without transformation. + * + * \param [in] eps - detection threshold for coordinates. + * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance. + * + * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic + */ +MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const +{ + MEDCouplingAutoRefCountObjectPtr ret(MEDFileUMesh::New()); + MEDCouplingAutoRefCountObjectPtr m0Tmp(getMeshAtLevel(0)); + MEDCouplingAutoRefCountObjectPtr m0(dynamic_cast(m0Tmp->deepCpy())); + m0->convertQuadraticCellsToLinear(); + m0->zipCoords(); + DataArrayDouble *zeCoords(m0->getCoords()); + ret->setMeshAtLevel(0,m0); + std::vector levs(getNonEmptyLevels()); + const DataArrayInt *famField(getFamilyFieldAtLevel(0)); + if(famField) + { + MEDCouplingAutoRefCountObjectPtr famFieldCpy(famField->deepCpy()); + ret->setFamilyFieldArr(0,famFieldCpy); + } + famField=getFamilyFieldAtLevel(1); + if(famField) + { + MEDCouplingAutoRefCountObjectPtr fam(famField->selectByTupleId2(0,zeCoords->getNumberOfTuples(),1)); + ret->setFamilyFieldArr(1,fam); + } + ret->copyFamGrpMapsFrom(*this); + for(std::vector::const_iterator lev=levs.begin();lev!=levs.end();lev++) + { + if(*lev==0) + continue; + MEDCouplingAutoRefCountObjectPtr m1Tmp(getMeshAtLevel(*lev)); + MEDCouplingAutoRefCountObjectPtr m1(dynamic_cast(m1Tmp->deepCpy())); + m1->convertQuadraticCellsToLinear(); + m1->zipCoords(); + DataArrayInt *b(0); + bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b)); + MEDCouplingAutoRefCountObjectPtr bSafe(b); + if(!a) + { + std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + m1->renumberNodesInConn(b->begin()); + m1->setCoords(zeCoords); + ret->setMeshAtLevel(*lev,m1); + famField=getFamilyFieldAtLevel(*lev); + if(famField) + { + MEDCouplingAutoRefCountObjectPtr famFieldCpy(famField->deepCpy()); + ret->setFamilyFieldArr(*lev,famFieldCpy); + } } return ret.retn(); } +void MEDFileUMesh::serialize(std::vector& tinyDouble, std::vector& tinyInt, std::vector& tinyStr, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI, MEDCouplingAutoRefCountObjectPtr& bigArrayD) +{ + clearNonDiscrAttributes(); + forceComputationOfParts(); + tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0; + std::vector layer0; + layer0.push_back(_order); //0 i + layer0.push_back(_iteration);//1 i + layer0.push_back(getSpaceDimension());//2 i + tinyDouble.push_back(_time);//0 d + tinyStr.push_back(_name);//0 s + tinyStr.push_back(_desc_name);//1 s + for(int i=0;igetInfoOnComponent(i)); + layer0.push_back((int)_families.size());//3 i <- key info aa layer#0 + for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) + { + tinyStr.push_back((*it).first); + layer0.push_back((*it).second); + } + layer0.push_back((int)_groups.size());//3+aa i <- key info bb layer#0 + for(std::map >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++) + { + layer0.push_back((int)(*it0).second.size()); + tinyStr.push_back((*it0).first); + for(std::vector::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++) + tinyStr.push_back(*it1); + } + // sizeof(layer0)==3+aa+1+bb layer#0 + bigArrayD=_coords;// 0 bd + bigArraysI.push_back(_fam_coords);// 0 bi + bigArraysI.push_back(_num_coords);// 1 bi + const PartDefinition *pd(_part_coords); + if(!pd) + layer0.push_back(-1); + else + { + std::vector tmp0; + pd->serialize(tmp0,bigArraysI); + tinyInt.push_back(tmp0.size()); + tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end()); + } + // + std::vector layer1; + std::vector levs(getNonEmptyLevels()); + layer1.push_back((int)levs.size());// 0 i <- key + layer1.insert(layer1.end(),levs.begin(),levs.end()); + for(std::vector::const_iterator it=levs.begin();it!=levs.end();it++) + { + const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it)); + lev->serialize(layer1,bigArraysI); + } + // put layers all together. + tinyInt.push_back(layer0.size()); + tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end()); + tinyInt.push_back(layer1.size()); + tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end()); +} + +void MEDFileUMesh::unserialize(std::vector& tinyDouble, std::vector& tinyInt, std::vector& tinyStr, + std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI, MEDCouplingAutoRefCountObjectPtr& bigArrayD) +{ + int sz0(tinyInt[0]); + std::vector layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0); + int sz1(tinyInt[sz0+1]); + std::vector layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1); + // + std::reverse(layer0.begin(),layer0.end()); + std::reverse(layer1.begin(),layer1.end()); + std::reverse(tinyDouble.begin(),tinyDouble.end()); + std::reverse(tinyStr.begin(),tinyStr.end()); + std::reverse(bigArraysI.begin(),bigArraysI.end()); + // + _order=layer0.back(); layer0.pop_back(); + _iteration=layer0.back(); layer0.pop_back(); + int spaceDim(layer0.back()); layer0.pop_back(); + _time=tinyDouble.back(); tinyDouble.pop_back(); + _name=tinyStr.back(); tinyStr.pop_back(); + _desc_name=tinyStr.back(); tinyStr.pop_back(); + _coords=bigArrayD; _coords->rearrange(spaceDim); + for(int i=0;isetInfoOnComponent(i,tinyStr.back()); + tinyStr.pop_back(); + } + int nbOfFams(layer0.back()); layer0.pop_back(); + _families.clear(); + for(int i=0;i fams(nbOfFamsOnGrp); + for(int j=0;j tmp0(layer0.begin(),layer0.begin()+isPd); + layer0.erase(layer0.begin(),layer0.begin()+isPd); + _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI); + } + if(!layer0.empty()) + throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !"); + // + int nbLevs(layer1.back()); layer1.pop_back(); + std::vector levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end()); + _ms.clear(); + int maxLev(-(*std::min_element(levs.begin(),levs.end()))); + _ms.resize(maxLev+1); + for(int i=0;igetName() == "". @@ -3425,8 +4089,13 @@ void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids) /*! * Adds a group of nodes/cells/faces/edges to \a this mesh. + * * \param [in] ids - a DataArrayInt providing ids and a name of the group to add. * The ids should be sorted and different each other (MED file norm). + * + * \warning this method can alter default "FAMILLE_ZERO" family. + * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session. + * * \throw If the node coordinates array is not set. * \throw If \a ids == \c NULL. * \throw If \a ids->getName() == "". @@ -3499,7 +4168,7 @@ void MEDFileUMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids if(existsFamily(*famId)) { std::string locFamName2=getFamilyNameGivenId(*famId); std::vector v(2); v[0]=locFamName2; v[1]=locFamName; - ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId).c_str(),v); + ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v); } maxVal++; } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal @@ -3512,7 +4181,7 @@ void MEDFileUMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids if(existsFamily(*famId)) { std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector v(2); v[0]=n1; v[1]=n2; - ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId).c_str(),v); + ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v); } maxVal+=2; } @@ -3653,10 +4322,10 @@ void MEDFileUMesh::setMeshes(const std::vector& ms, bo for(std::vector::const_iterator it=ms.begin();it!=ms.end();it++) { int mdim=(*it)->getMeshDimension(); - setName((*it)->getName().c_str()); + setName((*it)->getName()); setMeshAtLevel(mdim-zeDim,const_cast(*it),renum); } - setName(name.c_str()); + setName(name); } /*! @@ -3799,7 +4468,7 @@ void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famAr throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !"); int traducedRk=-meshDimRelToMaxExt; if(traducedRk>=(int)_ms.size()) - throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !"); + throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !"); if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0) throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !"); return _ms[traducedRk]->setFamilyArr(famArr); @@ -3835,7 +4504,7 @@ void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumA throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !"); int traducedRk=-meshDimRelToMaxExt; if(traducedRk>=(int)_ms.size()) - throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !"); + throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !"); if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0) throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !"); return _ms[traducedRk]->setRenumArr(renumArr); @@ -3869,7 +4538,7 @@ void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiCha throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !"); int traducedRk=-meshDimRelToMaxExt; if(traducedRk>=(int)_ms.size()) - throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !"); + throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !"); if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0) throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !"); return _ms[traducedRk]->setNameArr(nameArr); @@ -3934,21 +4603,21 @@ std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const return MEDFileMesh::getHeapMemorySizeWithoutChildren(); } -std::vector MEDFileStructuredMesh::getDirectChildren() const -{ - std::vector ret(MEDFileMesh::getDirectChildren()); - if((const DataArrayInt *)_fam_nodes) - ret.push_back((const DataArrayInt *)_fam_nodes); - if((const DataArrayInt *)_num_nodes) - ret.push_back((const DataArrayInt *)_num_nodes); - if((const DataArrayInt *)_fam_cells) - ret.push_back((const DataArrayInt *)_fam_cells); - if((const DataArrayInt *)_num_cells) - ret.push_back((const DataArrayInt *)_num_nodes); - if((const DataArrayInt *)_rev_num_nodes) - ret.push_back((const DataArrayInt *)_rev_num_nodes); - if((const DataArrayInt *)_rev_num_cells) - ret.push_back((const DataArrayInt *)_rev_num_cells); +std::vector MEDFileStructuredMesh::getDirectChildrenWithNull() const +{ + std::vector ret(MEDFileMesh::getDirectChildrenWithNull()); + ret.push_back((const DataArrayInt *)_fam_nodes); + ret.push_back((const DataArrayInt *)_num_nodes); + ret.push_back((const DataArrayAsciiChar *)_names_nodes); + ret.push_back((const DataArrayInt *)_fam_cells); + ret.push_back((const DataArrayInt *)_num_cells); + ret.push_back((const DataArrayAsciiChar *)_names_cells); + ret.push_back((const DataArrayInt *)_fam_faces); + ret.push_back((const DataArrayInt *)_num_faces); + ret.push_back((const DataArrayInt *)_rev_num_nodes); + ret.push_back((const DataArrayAsciiChar *)_names_faces); + ret.push_back((const DataArrayInt *)_rev_num_cells); + ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary); return ret; } @@ -3965,6 +4634,11 @@ int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const int val=_fam_cells->getMaxValue(tmp); ret=std::max(ret,std::abs(val)); } + if((const DataArrayInt *)_fam_faces) + { + int val=_fam_faces->getMaxValue(tmp); + ret=std::max(ret,std::abs(val)); + } return ret; } @@ -3981,6 +4655,11 @@ int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const int val=_fam_cells->getMaxValue(tmp); ret=std::max(ret,val); } + if((const DataArrayInt *)_fam_faces) + { + int val=_fam_faces->getMaxValue(tmp); + ret=std::max(ret,val); + } return ret; } @@ -3997,6 +4676,11 @@ int MEDFileStructuredMesh::getMinFamilyIdInArrays() const int val=_fam_cells->getMinValue(tmp); ret=std::min(ret,val); } + if((const DataArrayInt *)_fam_faces) + { + int val=_fam_faces->getMinValue(tmp); + ret=std::min(ret,val); + } return ret; } @@ -4042,6 +4726,22 @@ bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::s return false; } } + famc1=_fam_faces; + famc2=otherC->_fam_faces; + if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) + { + what="Mismatch of families arr on faces ! One is defined and not other !"; + return false; + } + if(famc1) + { + bool ret=famc1->isEqual(*famc2); + if(!ret) + { + what="Families arr on faces differ !"; + return false; + } + } famc1=_num_nodes; famc2=otherC->_num_nodes; if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) @@ -4074,6 +4774,22 @@ bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::s return false; } } + famc1=_num_faces; + famc2=otherC->_num_faces; + if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) + { + what="Mismatch of numbering arr on faces ! One is defined and not other !"; + return false; + } + if(famc1) + { + bool ret=famc1->isEqual(*famc2); + if(!ret) + { + what="Numbering arr on faces differ !"; + return false; + } + } const DataArrayAsciiChar *d1=_names_cells; const DataArrayAsciiChar *d2=otherC->_names_cells; if((d1==0 && d2!=0) || (d1!=0 && d2==0)) @@ -4090,6 +4806,22 @@ bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::s return false; } } + d1=_names_faces; + d2=otherC->_names_faces; + if((d1==0 && d2!=0) || (d1!=0 && d2==0)) + { + what="Mismatch of naming arr on faces ! One is defined and not other !"; + return false; + } + if(d1) + { + bool ret=d1->isEqual(*d2); + if(!ret) + { + what="Naming arr on faces differ !"; + return false; + } + } d1=_names_nodes; d2=otherC->_names_nodes; if((d1==0 && d2!=0) || (d1!=0 && d2==0)) @@ -4124,6 +4856,12 @@ void MEDFileStructuredMesh::clearNonDiscrAttributes() const tmp=_num_cells; if(tmp) (const_cast(tmp))->setName(""); + tmp=_fam_faces; + if(tmp) + (const_cast(tmp))->setName(""); + tmp=_num_faces; + if(tmp) + (const_cast(tmp))->setName(""); } /*! @@ -4140,43 +4878,67 @@ void MEDFileStructuredMesh::clearNonDiscrAttributes() const */ DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum) const { - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : Only available for levels 0 or 1 !"); - std::vector famIds=getFamiliesIds(fams); - if(meshDimRelToMaxExt==1) - { - if((const DataArrayInt *)_fam_nodes) - { - MEDCouplingAutoRefCountObjectPtr da; - if(!famIds.empty()) - da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); - else - da=_fam_nodes->getIdsEqualList(0,0); - if(renum) - return MEDFileUMeshSplitL1::Renumber(_num_nodes,da); - else - return da.retn(); - } - else - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !"); - } - else - { - if((const DataArrayInt *)_fam_cells) - { - MEDCouplingAutoRefCountObjectPtr da; - if(!famIds.empty()) - da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); - else - da=_fam_cells->getIdsEqualList(0,0); - if(renum) - return MEDFileUMeshSplitL1::Renumber(_num_cells,da); - else - return da.retn(); - } - else - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !"); - } + std::vector famIds(getFamiliesIds(fams)); + switch(meshDimRelToMaxExt) + { + case 1: + { + if((const DataArrayInt *)_fam_nodes) + { + MEDCouplingAutoRefCountObjectPtr da; + if(!famIds.empty()) + da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); + else + da=_fam_nodes->getIdsEqualList(0,0); + if(renum) + return MEDFileUMeshSplitL1::Renumber(_num_nodes,da); + else + return da.retn(); + } + else + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !"); + break; + } + case 0: + { + if((const DataArrayInt *)_fam_cells) + { + MEDCouplingAutoRefCountObjectPtr da; + if(!famIds.empty()) + da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); + else + da=_fam_cells->getIdsEqualList(0,0); + if(renum) + return MEDFileUMeshSplitL1::Renumber(_num_cells,da); + else + return da.retn(); + } + else + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !"); + break; + } + case -1: + { + if((const DataArrayInt *)_fam_faces) + { + MEDCouplingAutoRefCountObjectPtr da; + if(!famIds.empty()) + da=_fam_faces->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); + else + da=_fam_faces->getIdsEqualList(0,0); + if(renum) + return MEDFileUMeshSplitL1::Renumber(_num_faces,da); + else + return da.retn(); + } + else + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !"); + break; + } + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !"); + } + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !"); } /*! @@ -4186,27 +4948,39 @@ DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, cons * \param [in] famArr - the array of the family field. * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. * \throw If \a famArr has an invalid size. - * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1. + * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1. */ void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) { - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !"); - const MEDCouplingStructuredMesh *mesh=getStructuredMesh(); + const MEDCouplingStructuredMesh *mesh(getStructuredMesh()); if(!mesh) throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !"); - if(meshDimRelToMaxExt==0) - { - int nbCells=mesh->getNumberOfCells(); - famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !"); - _fam_cells=famArr; - } - else - { - int nbNodes=mesh->getNumberOfNodes(); - famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !"); - _fam_nodes=famArr; - } + switch(meshDimRelToMaxExt) + { + case 0: + { + int nbCells=mesh->getNumberOfCells(); + famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !"); + _fam_cells=famArr; + break; + } + case 1: + { + int nbNodes=mesh->getNumberOfNodes(); + famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !"); + _fam_nodes=famArr; + break; + } + case -1: + { + int nbCells=mesh->getNumberOfCellsOfSubLevelMesh(); + famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !"); + _fam_faces=famArr; + break; + } + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !"); + } if(famArr) famArr->incrRef(); } @@ -4221,23 +4995,35 @@ void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayI */ void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) { - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !"); const MEDCouplingStructuredMesh *mesh=getStructuredMesh(); if(!mesh) throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !"); - if(meshDimRelToMaxExt==0) - { - int nbCells=mesh->getNumberOfCells(); - renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !"); - _num_cells=renumArr; - } - else - { - int nbNodes=mesh->getNumberOfNodes(); - renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !"); - _num_nodes=renumArr; - } + switch(meshDimRelToMaxExt) + { + case 0: + { + int nbCells=mesh->getNumberOfCells(); + renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !"); + _num_cells=renumArr; + break; + } + case 1: + { + int nbNodes=mesh->getNumberOfNodes(); + renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !"); + _num_nodes=renumArr; + break; + } + case -1: + { + int nbCells=mesh->getNumberOfCellsOfSubLevelMesh(); + renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !"); + _num_faces=renumArr; + break; + } + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !"); + } if(renumArr) renumArr->incrRef(); } @@ -4251,23 +5037,34 @@ void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayIn */ void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) { - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 !"); - const MEDCouplingStructuredMesh *mesh=getStructuredMesh(); + const MEDCouplingStructuredMesh *mesh(getStructuredMesh()); if(!mesh) throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !"); - if(meshDimRelToMaxExt==0) - { - int nbCells=mesh->getNumberOfCells(); - nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !"); - _names_cells=nameArr; - } - else - { - int nbNodes=mesh->getNumberOfNodes(); - nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !"); - _names_nodes=nameArr; - } + switch(meshDimRelToMaxExt) + { + case 0: + { + int nbCells=mesh->getNumberOfCells(); + nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !"); + _names_cells=nameArr; + break; + } + case 1: + { + int nbNodes=mesh->getNumberOfNodes(); + nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !"); + _names_nodes=nameArr; + break; + } + case -1: + { + int nbCells=mesh->getNumberOfCellsOfSubLevelMesh(); + nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !"); + _names_cells=nameArr; + } + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !"); + } if(nameArr) nameArr->incrRef(); } @@ -4281,12 +5078,17 @@ void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArra */ const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const { - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 !"); - if(meshDimRelToMaxExt==0) - return _fam_cells; - else - return _fam_nodes; + switch(meshDimRelToMaxExt) + { + case 0: + return _fam_cells; + case 1: + return _fam_nodes; + case -1: + return _fam_faces; + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !"); + } } /*! @@ -4298,12 +5100,17 @@ const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelT */ const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const { - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 !"); - if(meshDimRelToMaxExt==0) - return _num_cells; - else - return _num_nodes; + switch(meshDimRelToMaxExt) + { + case 0: + return _num_cells; + case 1: + return _num_nodes; + case -1: + return _num_faces; + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !"); + } } /*! @@ -4347,12 +5154,17 @@ const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimR const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const { - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 !"); - if(meshDimRelToMaxExt==0) - return _names_cells; - else - return _names_nodes; + switch(meshDimRelToMaxExt) + { + case 0: + return _names_cells; + case 1: + return _names_nodes; + case -1: + return _names_faces; + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !"); + } } /*! @@ -4382,11 +5194,13 @@ std::vector MEDFileStructuredMesh::getNonEmptyLevelsExt() const std::vector MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const { std::vector ret; - const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells); + const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces); if(famNodes) ret.push_back(1); if(famCells) ret.push_back(0); + if(famFaces) + ret.push_back(-1); return ret; } @@ -4396,11 +5210,13 @@ std::vector MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const std::vector MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const { std::vector ret; - const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells); + const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces); if(numNodes) ret.push_back(1); if(numCells) ret.push_back(0); + if(numFaces) + ret.push_back(-1); return ret; } @@ -4410,9 +5226,13 @@ std::vector MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const std::vector MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const { std::vector ret; - const DataArrayAsciiChar *namesCells(_names_cells); + const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces); + if(namesNodes) + ret.push_back(1); if(namesCells) ret.push_back(0); + if(namesFaces) + ret.push_back(-1); return ret; } @@ -4433,6 +5253,9 @@ void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId) arr=_fam_cells; if(arr) arr->changeValue(oldId,newId); + arr=_fam_faces; + if(arr) + arr->changeValue(oldId,newId); } void MEDFileStructuredMesh::deepCpyAttributes() @@ -4441,10 +5264,20 @@ void MEDFileStructuredMesh::deepCpyAttributes() _fam_nodes=_fam_nodes->deepCpy(); if((const DataArrayInt*)_num_nodes) _num_nodes=_num_nodes->deepCpy(); + if((const DataArrayAsciiChar*)_names_nodes) + _names_nodes=_names_nodes->deepCpy(); if((const DataArrayInt*)_fam_cells) _fam_cells=_fam_cells->deepCpy(); if((const DataArrayInt*)_num_cells) _num_cells=_num_cells->deepCpy(); + if((const DataArrayAsciiChar*)_names_cells) + _names_cells=_names_cells->deepCpy(); + if((const DataArrayInt*)_fam_faces) + _fam_faces=_fam_faces->deepCpy(); + if((const DataArrayInt*)_num_faces) + _num_faces=_num_faces->deepCpy(); + if((const DataArrayAsciiChar*)_names_faces) + _names_faces=_names_faces->deepCpy(); if((const DataArrayInt*)_rev_num_nodes) _rev_num_nodes=_rev_num_nodes->deepCpy(); if((const DataArrayInt*)_rev_num_cells) @@ -4460,7 +5293,7 @@ void MEDFileStructuredMesh::deepCpyAttributes() /*! * Returns a pointer to MEDCouplingStructuredMesh held by \a this. - * \param [in] meshDimRelToMax - it must be \c 0. + * \param [in] meshDimRelToMax - it must be \c 0 or \c -1. * \param [in] renum - it must be \c false. * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to * delete using decrRef() as it is no more needed. @@ -4469,12 +5302,28 @@ MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, b { if(renum) throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !"); - if(meshDimRelToMax!=0) - throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !"); - const MEDCouplingStructuredMesh *m=getStructuredMesh(); - if(m) - m->incrRef(); - return const_cast(m); + const MEDCouplingStructuredMesh *m(getStructuredMesh()); + switch(meshDimRelToMax) + { + case 0: + { + if(m) + m->incrRef(); + return const_cast(m); + } + case -1: + { + if(!m) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGenMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !"); + buildMinusOneImplicitPartIfNeeded(); + MEDCouplingMesh *ret(_faces_if_necessary); + if(ret) + ret->incrRef(); + return ret; + } + default: + throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !"); + } } /*! @@ -4485,25 +5334,114 @@ MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, b */ int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const { - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 !"); - const MEDCouplingStructuredMesh *cmesh=getStructuredMesh(); + const MEDCouplingStructuredMesh *cmesh(getStructuredMesh()); if(!cmesh) throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !"); - if(meshDimRelToMaxExt==0) - return cmesh->getNumberOfCells(); - else - return cmesh->getNumberOfNodes(); + switch(meshDimRelToMaxExt) + { + case 0: + return cmesh->getNumberOfCells(); + case 1: + return cmesh->getNumberOfNodes(); + case -1: + return cmesh->getNumberOfCellsOfSubLevelMesh(); + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !"); + } } int MEDFileStructuredMesh::getNumberOfNodes() const { - const MEDCouplingStructuredMesh *cmesh=getStructuredMesh(); + const MEDCouplingStructuredMesh *cmesh(getStructuredMesh()); if(!cmesh) throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !"); return cmesh->getNumberOfNodes(); } +bool MEDFileStructuredMesh::hasImplicitPart() const +{ + return true; +} + +/*! + * \sa MEDFileStructuredMesh::getImplicitFaceMesh + */ +int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const +{ + static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !"; + const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary); + if(!zeFaceMesh) + { + const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))); + if(cm.getReverseExtrudedType()!=gt) + throw INTERP_KERNEL::Exception(MSG); + buildImplicitPart(); + return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh(); + } + else + { + if(gt!=zeFaceMesh->getCellModelEnum()) + throw INTERP_KERNEL::Exception(MSG); + return zeFaceMesh->getNumberOfCells(); + } +} + +void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const +{ + const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary); + if(!zeFaceMesh) + buildImplicitPart(); +} + +void MEDFileStructuredMesh::buildImplicitPart() const +{ + const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh()); + if(!mcmesh) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !"); + _faces_if_necessary=mcmesh->build1SGTSubLevelMesh(); +} + +void MEDFileStructuredMesh::releaseImplicitPartIfAny() const +{ + _faces_if_necessary=0; +} + +/*! + * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any. + * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method. + * + * \sa MEDFileStructuredMesh::buildImplicitPartIfAny + */ +MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const +{ + return _faces_if_necessary; +} + +std::vector MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const +{ + const MEDCouplingStructuredMesh *cmesh(getStructuredMesh()); + if(!cmesh) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !"); + switch(meshDimRelToMax) + { + case 0: + { + std::vector ret(1,cmesh->getTypeOfCell(0)); + return ret; + } + case -1: + { + int mdim(cmesh->getMeshDimension()); + if(mdim<1) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !"); + std::vector ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1)); + return ret; + } + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !"); + } +} + void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector& nodesFetched) const { if(st.getNumberOfItems()!=1) @@ -4517,7 +5455,7 @@ void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem std::fill(nodesFetched.begin(),nodesFetched.end(),true); return ; } - const DataArrayInt *arr(globs->getProfile(st[0].getPflName().c_str())); + const DataArrayInt *arr(globs->getProfile(st[0].getPflName())); const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before int sz(nodesFetched.size()); for(const int *work=arr->begin();work!=arr->end();work++) @@ -4534,117 +5472,119 @@ void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim) { - med_geometry_type geoTypeReq=MED_NONE; - switch(meshDim) - { - case 3: - geoTypeReq=MED_HEXA8; - break; - case 2: - geoTypeReq=MED_QUAD4; - break; - case 1: - geoTypeReq=MED_SEG2; - break; - case 0: - geoTypeReq=MED_POINT1; - break; - default: - throw INTERP_KERNEL::Exception("Invalid meshdim detected for structured mesh ! Must be in (1,2,3) !"); - } - return geoTypeReq; + INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim)); + return typmai3[ct]; } -void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) +void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs, + MEDCouplingAutoRefCountObjectPtr& famCells, MEDCouplingAutoRefCountObjectPtr& numCells, MEDCouplingAutoRefCountObjectPtr& namesCells) { - setName(strm->getName()); - setDescription(strm->getDescription()); - setUnivName(strm->getUnivName()); - setIteration(strm->getIteration()); - setOrder(strm->getOrder()); - setTimeValue(strm->getTime()); - setTimeUnit(strm->getTimeUnit()); - MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs); med_bool chgt=MED_FALSE,trsf=MED_FALSE; - int nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf); + med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim); + int nbOfElt(0); + nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf); if(nbOfElt>0) { - if(!mrs || mrs->isNodeFamilyFieldReading()) + if(!mrs || mrs->isCellFamilyFieldReading()) { - _fam_nodes=DataArrayInt::New(); - _fam_nodes->alloc(nbOfElt,1); - MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer()); + famCells=DataArrayInt::New(); + famCells->alloc(nbOfElt,1); + MEDmeshEntityFamilyNumberRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer()); } } - nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf); + nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf); if(nbOfElt>0) { - if(!mrs || mrs->isNodeNumFieldReading()) + if(!mrs || mrs->isCellNumFieldReading()) { - _num_nodes=DataArrayInt::New(); - _num_nodes->alloc(nbOfElt,1); - MEDmeshEntityNumberRd(fid,mName,dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer()); + numCells=DataArrayInt::New(); + numCells->alloc(nbOfElt,1); + MEDmeshEntityNumberRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer()); } } - int meshDim=getStructuredMesh()->getMeshDimension(); - med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim); - nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf); + nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf); if(nbOfElt>0) { - if(!mrs || mrs->isCellFamilyFieldReading()) + if(!mrs || mrs->isCellNameFieldReading()) { - _fam_cells=DataArrayInt::New(); - _fam_cells->alloc(nbOfElt,1); - MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_fam_cells->getPointer()); + namesCells=DataArrayAsciiChar::New(); + namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end + MEDmeshEntityNameRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer()); + namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end } } - nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf); +} + +void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) +{ + setName(strm->getName()); + setDescription(strm->getDescription()); + setUnivName(strm->getUnivName()); + setIteration(strm->getIteration()); + setOrder(strm->getOrder()); + setTimeValue(strm->getTime()); + setTimeUnit(strm->getTimeUnit()); + MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs); + med_bool chgt=MED_FALSE,trsf=MED_FALSE; + int nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf); if(nbOfElt>0) { - if(!mrs || mrs->isCellNumFieldReading()) + if(!mrs || mrs->isNodeFamilyFieldReading()) { - _num_cells=DataArrayInt::New(); - _num_cells->alloc(nbOfElt,1); - MEDmeshEntityNumberRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_num_cells->getPointer()); + int nbNodes(getNumberOfNodes()); + if(nbOfElt>nbNodes) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !"); + _fam_nodes=DataArrayInt::New(); + _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line. + if(nbNodes>nbOfElt)//yes it appends some times... It explains surely the mdump implementation. Bug revealed by PARAVIS EDF #2475 on structured.med file where only 12 first nodes are !=0 so nbOfElt=12 and nbOfNodes=378... + _fam_nodes->fillWithZero(); + MEDmeshEntityFamilyNumberRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer()); } } - nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf); + nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf); if(nbOfElt>0) { - if(!mrs || mrs->isCellNameFieldReading()) + if(!mrs || mrs->isNodeNumFieldReading()) { - _names_cells=DataArrayAsciiChar::New(); - _names_cells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end - MEDmeshEntityNameRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_names_cells->getPointer()); - _names_cells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end + _num_nodes=DataArrayInt::New(); + _num_nodes->alloc(nbOfElt,1); + MEDmeshEntityNumberRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer()); } } - nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf); + nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf); if(nbOfElt>0) { if(!mrs || mrs->isNodeNameFieldReading()) { _names_nodes=DataArrayAsciiChar::New(); _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end - MEDmeshEntityNameRd(fid,mName,dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer()); + MEDmeshEntityNameRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer()); _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end } } + int meshDim(getStructuredMesh()->getMeshDimension()); + LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells); + if(meshDim>=1) + LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces); } -void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const char *maa) const +void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const { - int meshDim=getStructuredMesh()->getMeshDimension(); - med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim); + int meshDim(getStructuredMesh()->getMeshDimension()); + med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1)); // if((const DataArrayInt *)_fam_cells) - MEDmeshEntityFamilyNumberWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer()); + MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer()); + if((const DataArrayInt *)_fam_faces) + MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer()); if((const DataArrayInt *)_fam_nodes) - MEDmeshEntityFamilyNumberWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer()); + MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer()); if((const DataArrayInt *)_num_cells) - MEDmeshEntityNumberWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer()); + MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer()); + if((const DataArrayInt *)_num_faces) + MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer()); if((const DataArrayInt *)_num_nodes) - MEDmeshEntityNumberWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer()); + MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer()); if((const DataArrayAsciiChar *)_names_cells) { if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE) @@ -4653,7 +5593,17 @@ void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const char *maa) cons oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - MEDmeshEntityNameWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer()); + MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer()); + } + if((const DataArrayAsciiChar *)_names_faces) + { + if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE) + { + std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE; + oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer()); } if((const DataArrayAsciiChar *)_names_nodes) { @@ -4663,10 +5613,10 @@ void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const char *maa) cons oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - MEDmeshEntityNameWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer()); + MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer()); } // - MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa,_families,_groups,_too_long_str); + MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str); } /*! @@ -4689,7 +5639,7 @@ MEDFileCMesh *MEDFileCMesh::New() * \throw If there is no meshes in the file. * \throw If the mesh in the file is not a Cartesian one. */ -MEDFileCMesh *MEDFileCMesh::New(const char *fileName, MEDFileMeshReadSelector *mrs) +MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs) { std::vector ms=MEDLoader::GetMeshNames(fileName); if(ms.empty()) @@ -4698,12 +5648,12 @@ MEDFileCMesh *MEDFileCMesh::New(const char *fileName, MEDFileMeshReadSelector *m throw INTERP_KERNEL::Exception(oss.str().c_str()); } MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); int dt,it; ParaMEDMEM::MEDCouplingMeshType meshType; std::string dummy2; - MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2); - return new MEDFileCMesh(fid,ms.front().c_str(),dt,it,mrs); + MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2); + return new MEDFileCMesh(fid,ms.front(),dt,it,mrs); } /*! @@ -4720,10 +5670,10 @@ MEDFileCMesh *MEDFileCMesh::New(const char *fileName, MEDFileMeshReadSelector *m * \throw If there is no mesh with given attributes in the file. * \throw If the mesh in the file is not a Cartesian one. */ -MEDFileCMesh *MEDFileCMesh::New(const char *fileName, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) +MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) { MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); return new MEDFileCMesh(fid,mName,dt,it,mrs); } @@ -4732,11 +5682,10 @@ std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren(); } -std::vector MEDFileCMesh::getDirectChildren() const +std::vector MEDFileCMesh::getDirectChildrenWithNull() const { - std::vector ret(MEDFileStructuredMesh::getDirectChildren()); - if((const MEDCouplingCMesh *)_cmesh) - ret.push_back((const MEDCouplingCMesh *)_cmesh); + std::vector ret(MEDFileStructuredMesh::getDirectChildrenWithNull()); + ret.push_back((const MEDCouplingCMesh *)_cmesh); return ret; } @@ -4752,6 +5701,18 @@ int MEDFileCMesh::getMeshDimension() const return _cmesh->getMeshDimension(); } +/*! + * Returns the dimension on nodes in \a this mesh. + * \return int - the space dimension. + * \throw If there are no cells in this mesh. + */ +int MEDFileCMesh::getSpaceDimension() const +{ + if(!((const MEDCouplingCMesh*)_cmesh)) + throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !"); + return _cmesh->getSpaceDimension(); +} + /*! * Returns a string describing \a this mesh. * \return std::string - the mesh information string. @@ -4841,17 +5802,17 @@ MEDFileCMesh::MEDFileCMesh() { } -MEDFileCMesh::MEDFileCMesh(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) +MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) try - { +{ loadCMeshFromFile(fid,mName,dt,it,mrs); - } +} catch(INTERP_KERNEL::Exception& e) - { +{ throw e; - } +} -void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) +void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) { ParaMEDMEM::MEDCouplingMeshType meshType; int dummy0,dummy1; @@ -4908,8 +5869,7 @@ void MEDFileCMesh::writeLL(med_idt fid) const MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str); MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str); MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str); - int spaceDim=_cmesh->getSpaceDimension(); - int meshDim=_cmesh->getMeshDimension(); + int spaceDim(_cmesh->getSpaceDimension()); INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); for(int i=0;igetNumberOfTuples(),da->getConstPointer()); } // - MEDFileStructuredMesh::writeStructuredLL(fid,maa); + std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE)); + MEDFileStructuredMesh::writeStructuredLL(fid,meshName); } void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const @@ -4937,10 +5898,10 @@ void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const const MEDCouplingCMesh *cmesh=_cmesh; if(!cmesh) return; - (const_cast(cmesh))->setName(_name.c_str()); - (const_cast(cmesh))->setDescription(_desc_name.c_str()); + (const_cast(cmesh))->setName(_name); + (const_cast(cmesh))->setDescription(_desc_name); (const_cast(cmesh))->setTime(_time,_iteration,_order); - (const_cast(cmesh))->setTimeUnit(_dt_unit.c_str()); + (const_cast(cmesh))->setTimeUnit(_dt_unit); } MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New() @@ -4948,7 +5909,7 @@ MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New() return new MEDFileCurveLinearMesh; } -MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const char *fileName, MEDFileMeshReadSelector *mrs) +MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs) { std::vector ms=MEDLoader::GetMeshNames(fileName); if(ms.empty()) @@ -4957,18 +5918,18 @@ MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const char *fileName, MEDFil throw INTERP_KERNEL::Exception(oss.str().c_str()); } MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); int dt,it; ParaMEDMEM::MEDCouplingMeshType meshType; std::string dummy2; - MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2); - return new MEDFileCurveLinearMesh(fid,ms.front().c_str(),dt,it,mrs); + MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2); + return new MEDFileCurveLinearMesh(fid,ms.front(),dt,it,mrs); } -MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const char *fileName, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) +MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) { MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs); } @@ -4977,11 +5938,10 @@ std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren(); } -std::vector MEDFileCurveLinearMesh::getDirectChildren() const +std::vector MEDFileCurveLinearMesh::getDirectChildrenWithNull() const { - std::vector ret(MEDFileStructuredMesh::getDirectChildren()); - if((const MEDCouplingCurveLinearMesh *)_clmesh) - ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh); + std::vector ret(MEDFileStructuredMesh::getDirectChildrenWithNull()); + ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh); return ret; } @@ -5064,10 +6024,10 @@ void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const const MEDCouplingCurveLinearMesh *clmesh=_clmesh; if(!clmesh) return; - (const_cast(clmesh))->setName(_name.c_str()); - (const_cast(clmesh))->setDescription(_desc_name.c_str()); + (const_cast(clmesh))->setName(_name); + (const_cast(clmesh))->setDescription(_desc_name); (const_cast(clmesh))->setTime(_time,_iteration,_order); - (const_cast(clmesh))->setTimeUnit(_dt_unit.c_str()); + (const_cast(clmesh))->setTimeUnit(_dt_unit); } const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const @@ -5094,15 +6054,15 @@ MEDFileCurveLinearMesh::MEDFileCurveLinearMesh() { } -MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) +MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) try - { +{ loadCLMeshFromFile(fid,mName,dt,it,mrs); - } +} catch(INTERP_KERNEL::Exception& e) - { +{ throw e; - } +} void MEDFileCurveLinearMesh::writeLL(med_idt fid) const { @@ -5132,13 +6092,14 @@ void MEDFileCurveLinearMesh::writeLL(med_idt fid) const MEDmeshGridTypeWr(fid,maa,MED_CURVILINEAR_GRID); std::vector nodeGridSt=_clmesh->getNodeGridStructure(); MEDmeshGridStructWr(fid,maa,_iteration,_order,_time,&nodeGridSt[0]); - + MEDmeshNodeCoordinateWr(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin()); // - MEDFileStructuredMesh::writeStructuredLL(fid,maa); + std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE)); + MEDFileStructuredMesh::writeStructuredLL(fid,meshName); } -void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) +void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) { ParaMEDMEM::MEDCouplingMeshType meshType; int dummy0,dummy1; @@ -5162,12 +6123,12 @@ MEDFileMeshMultiTS *MEDFileMeshMultiTS::New() return new MEDFileMeshMultiTS; } -MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const char *fileName) +MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName) { return new MEDFileMeshMultiTS(fileName); } -MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const char *fileName, const char *mName) +MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName) { return new MEDFileMeshMultiTS(fileName,mName); } @@ -5189,15 +6150,11 @@ std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const return _mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); } -std::vector MEDFileMeshMultiTS::getDirectChildren() const +std::vector MEDFileMeshMultiTS::getDirectChildrenWithNull() const { std::vector ret; for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++) - { - const MEDFileMesh *cur(*it); - if(cur) - ret.push_back(cur); - } + ret.push_back((const MEDFileMesh *)*it); return ret; } @@ -5208,7 +6165,7 @@ std::string MEDFileMeshMultiTS::getName() const return _mesh_one_ts[0]->getName(); } -void MEDFileMeshMultiTS::setName(const char *newMeshName) +void MEDFileMeshMultiTS::setName(const std::string& newMeshName) { std::string oldName(getName()); std::vector< std::pair > v(1); @@ -5254,16 +6211,16 @@ void MEDFileMeshMultiTS::write(med_idt fid) const } } -void MEDFileMeshMultiTS::write(const char *fileName, int mode) const +void MEDFileMeshMultiTS::write(const std::string& fileName, int mode) const { med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,medmod); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\""; - MEDFileUtilities::CheckMEDCode(fid,fid,oss.str().c_str()); + MEDFileUtilities::CheckMEDCode(fid,fid,oss.str()); write(fid); } -void MEDFileMeshMultiTS::loadFromFile(const char *fileName, const char *mName) +void MEDFileMeshMultiTS::loadFromFile(const std::string& fileName, const std::string& mName) {//for the moment to be improved _mesh_one_ts.resize(1); _mesh_one_ts[0]=MEDFileMesh::New(fileName,mName,-1,-1); @@ -5273,44 +6230,44 @@ MEDFileMeshMultiTS::MEDFileMeshMultiTS() { } -MEDFileMeshMultiTS::MEDFileMeshMultiTS(const char *fileName) +MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName) try - { +{ std::vector ms=MEDLoader::GetMeshNames(fileName); if(ms.empty()) - { - std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } + { + std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); int dt,it; ParaMEDMEM::MEDCouplingMeshType meshType; std::string dummy2; - MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2); - loadFromFile(fileName,ms.front().c_str()); - } + MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2); + loadFromFile(fileName,ms.front()); +} catch(INTERP_KERNEL::Exception& e) - { +{ throw e; - } +} -MEDFileMeshMultiTS::MEDFileMeshMultiTS(const char *fileName, const char *mName) +MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName) try - { +{ loadFromFile(fileName,mName); - } +} catch(INTERP_KERNEL::Exception& e) - { +{ throw e; - } +} MEDFileMeshes *MEDFileMeshes::New() { return new MEDFileMeshes; } -MEDFileMeshes *MEDFileMeshes::New(const char *fileName) +MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName) { return new MEDFileMeshes(fileName); } @@ -5325,12 +6282,12 @@ void MEDFileMeshes::write(med_idt fid) const } } -void MEDFileMeshes::write(const char *fileName, int mode) const +void MEDFileMeshes::write(const std::string& fileName, int mode) const { med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,medmod); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\""; - MEDFileUtilities::CheckMEDCode(fid,fid,oss.str().c_str()); + MEDFileUtilities::CheckMEDCode(fid,fid,oss.str()); checkCoherency(); write(fid); } @@ -5345,6 +6302,7 @@ MEDFileMeshesIterator *MEDFileMeshes::iterator() return new MEDFileMeshesIterator(this); } +/** Return a borrowed reference (caller is not responsible) */ MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const { if(i<0 || i>=(int)_meshes.size()) @@ -5355,7 +6313,8 @@ MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const return _meshes[i]->getOneTimeStep(); } -MEDFileMesh *MEDFileMeshes::getMeshWithName(const char *mname) const +/** Return a borrowed reference (caller is not responsible) */ +MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const { std::vector ms=getMeshesNames(); std::vector::iterator it=std::find(ms.begin(),ms.end(),mname); @@ -5435,27 +6394,27 @@ void MEDFileMeshes::destroyMeshAtPos(int i) _meshes.erase(_meshes.begin()+i); } -void MEDFileMeshes::loadFromFile(const char *fileName) +void MEDFileMeshes::loadFromFile(const std::string& fileName) { std::vector ms=MEDLoader::GetMeshNames(fileName); int i=0; _meshes.resize(ms.size()); for(std::vector::const_iterator it=ms.begin();it!=ms.end();it++,i++) - _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it).c_str()); + _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it)); } MEDFileMeshes::MEDFileMeshes() { } -MEDFileMeshes::MEDFileMeshes(const char *fileName) +MEDFileMeshes::MEDFileMeshes(const std::string& fileName) try - { +{ loadFromFile(fileName); - } +} catch(INTERP_KERNEL::Exception& /*e*/) - { - } +{ +} MEDFileMeshes *MEDFileMeshes::deepCpy() const { @@ -5474,15 +6433,11 @@ std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const return _meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr)); } -std::vector MEDFileMeshes::getDirectChildren() const +std::vector MEDFileMeshes::getDirectChildrenWithNull() const { std::vector ret; for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_meshes.begin();it!=_meshes.end();it++) - { - const MEDFileMeshMultiTS *cur(*it); - if(cur) - ret.push_back(cur); - } + ret.push_back((const MEDFileMeshMultiTS *)*it); return ret; }