From e6029c252ae30e1f502c8380794ac4e6d79d4f9f Mon Sep 17 00:00:00 2001 From: Anthony Geay Date: Tue, 20 Feb 2018 09:45:49 +0100 Subject: [PATCH] New : insert multi level group into MEDFileMeshes and remove a part of group at sepecified level --- src/MEDLoader/MEDFileMesh.cxx | 67 +++++++++++++++++++++++----- src/MEDLoader/MEDFileMesh.hxx | 2 + src/MEDLoader/Swig/MEDLoaderCommon.i | 1 + src/MEDLoader/Swig/MEDLoaderTest3.py | 47 +++++++++++++++++++ 4 files changed, 105 insertions(+), 12 deletions(-) diff --git a/src/MEDLoader/MEDFileMesh.cxx b/src/MEDLoader/MEDFileMesh.cxx index 4cb27ed73..04fa341d5 100644 --- a/src/MEDLoader/MEDFileMesh.cxx +++ b/src/MEDLoader/MEDFileMesh.cxx @@ -673,6 +673,35 @@ std::vector MEDFileMesh::removeEmptyGroups() return ret; } +void MEDFileMesh::removeGroupAtLevel(int meshDimRelToMaxExt, const std::string& name) +{ + std::map >::iterator it(_groups.find(name)); + std::vector grps(getGroupsNames()); + if(it==_groups.end()) + { + std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :"; + std::copy(grps.begin(),grps.end(),std::ostream_iterator(oss," ")); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const std::vector &famsOnGrp((*it).second); + std::vector famIds(getFamiliesIdsOnGroup(name)); + const DataArrayInt *famArr(getFamilyFieldAtLevel(meshDimRelToMaxExt)); + if(!famArr) + return ; + MCAuto vals(famArr->getDifferentValues()); + MCAuto famIds2(DataArrayInt::NewFromStdVector(famIds)); + MCAuto idsToKill(famIds2->buildIntersection(vals)); + if(idsToKill->empty()) + return ; + std::vector newFamsOnGrp; + for(std::vector::const_iterator it=famsOnGrp.begin();it!=famsOnGrp.end();it++) + { + if(!idsToKill->presenceOfValue(getFamilyId(*it))) + newFamsOnGrp.push_back(*it); + } + (*it).second=newFamsOnGrp; +} + /*! * Removes a group from \a this mesh. * \param [in] name - the name of the group to remove. @@ -680,9 +709,8 @@ std::vector MEDFileMesh::removeEmptyGroups() */ void MEDFileMesh::removeGroup(const std::string& name) { - std::string oname(name); - std::map >::iterator it=_groups.find(oname); - std::vector grps=getGroupsNames(); + std::map >::iterator it=_groups.find(name); + std::vector grps(getGroupsNames()); if(it==_groups.end()) { std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :"; @@ -1256,6 +1284,19 @@ void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const s } } +void MEDFileMesh::checkNoGroupClash(const DataArrayInt *famArr, const std::string& grpName) const +{ + std::vector grpsNames(getGroupsNames()); + if(std::find(grpsNames.begin(),grpsNames.end(),grpName)==grpsNames.end()) + return ; + std::vector famIds(getFamiliesIdsOnGroup(grpName)); + if(famArr->presenceOfValue(famIds)) + { + std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists at specified level ! Destroy it before calling this method !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + /*! * \param [in] ids ids and group name of the new group to add. The ids should be sorted and different each other (MED file norm). * \parma [in,out] famArr family array on level of interest to be renumbered. The input pointer should be not \c NULL (no check of that will be performed) @@ -1268,13 +1309,8 @@ void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, if(grpName.empty()) throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !"); ids->checkStrictlyMonotonic(true); - famArr->incrRef(); MCAuto famArrTmp(famArr); - std::vector grpsNames=getGroupsNames(); - if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end()) - { - std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } + checkNoGroupClash(famArr,grpName); + MCAuto famArrTmp; famArrTmp.takeRef(famArr); std::list< MCAuto > allFamIds(getAllNonNullFamilyIds()); allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp)); MCAuto famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end()); @@ -1331,8 +1367,15 @@ void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1); } _families=families; + std::map >::iterator itt(groups.find(grpName)); + if(itt!=groups.end()) + { + std::vector& famsOnGrp((*itt).second); + famsOnGrp.insert(famsOnGrp.end(),fams.begin(),fams.end()); + } + else + groups[grpName]=fams; _groups=groups; - _groups[grpName]=fams; } void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector& newFamiliesNames) @@ -4874,7 +4917,7 @@ void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids) if(!coords) throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !"); int nbOfNodes(coords->getNumberOfTuples()); - if(!((DataArrayInt *)_fam_coords)) + if(_fam_coords.isNull()) { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); } // addGroupUnderground(true,ids,_fam_coords); diff --git a/src/MEDLoader/MEDFileMesh.hxx b/src/MEDLoader/MEDFileMesh.hxx index cc3ac738b..9b1efb29d 100644 --- a/src/MEDLoader/MEDFileMesh.hxx +++ b/src/MEDLoader/MEDFileMesh.hxx @@ -136,6 +136,7 @@ namespace MEDCoupling MEDLOADER_EXPORT static std::string GetMagicFamilyStr(); MEDLOADER_EXPORT void assignFamilyNameWithGroupName(); MEDLOADER_EXPORT std::vector removeEmptyGroups(); + MEDLOADER_EXPORT void removeGroupAtLevel(int meshDimRelToMaxExt, const std::string& name); MEDLOADER_EXPORT void removeGroup(const std::string& name); MEDLOADER_EXPORT void removeFamily(const std::string& name); MEDLOADER_EXPORT std::vector removeOrphanGroups(); @@ -227,6 +228,7 @@ namespace MEDCoupling bool areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const; void getEquivalencesRepr(std::ostream& oss) const; void checkCartesian() const; + void checkNoGroupClash(const DataArrayInt *famArr, const std::string& grpName) const; private: virtual void writeMeshLL(med_idt fid) const = 0; protected: diff --git a/src/MEDLoader/Swig/MEDLoaderCommon.i b/src/MEDLoader/Swig/MEDLoaderCommon.i index 78821d92b..c6630e179 100644 --- a/src/MEDLoader/Swig/MEDLoaderCommon.i +++ b/src/MEDLoader/Swig/MEDLoaderCommon.i @@ -1111,6 +1111,7 @@ namespace MEDCoupling static std::string GetMagicFamilyStr(); void assignFamilyNameWithGroupName() throw(INTERP_KERNEL::Exception); std::vector removeEmptyGroups() throw(INTERP_KERNEL::Exception); + void removeGroupAtLevel(int meshDimRelToMaxExt, const std::string& name) throw(INTERP_KERNEL::Exception); void removeGroup(const std::string& name) throw(INTERP_KERNEL::Exception); void removeFamily(const std::string& name) throw(INTERP_KERNEL::Exception); std::vector removeOrphanGroups() throw(INTERP_KERNEL::Exception); diff --git a/src/MEDLoader/Swig/MEDLoaderTest3.py b/src/MEDLoader/Swig/MEDLoaderTest3.py index 934d384a3..aa0600393 100644 --- a/src/MEDLoader/Swig/MEDLoaderTest3.py +++ b/src/MEDLoader/Swig/MEDLoaderTest3.py @@ -6400,6 +6400,53 @@ class MEDLoaderTest3(unittest.TestCase): self.assertTrue(f1ts.getProfile("pfl_NORM_TRI3").isIota(162)) self.assertTrue(f1ts.getProfile("pfl_NORM_QUAD4").isIota(81)) pass + + def testRmGroupAtSpeLevelAndMultiLevGrpCreation(self): + """ Here multi level groups are created""" + arr=DataArrayDouble(11) ; arr.iota() + m=MEDCouplingCMesh() ; m.setCoords(arr,arr) + m=m.buildUnstructured() + m.setName("mesh") + m1=m.buildDescendingConnectivity()[0] + mm=MEDFileUMesh() + mm[0]=m ; mm[-1]=m1 + ################ + grpName="grp0" + grp0_0=DataArrayInt([0,1,2,6]) ; grp0_0.setName(grpName) + grp0_1=DataArrayInt([0,1,2,7]) ; grp0_1.setName(grpName) + grp1=DataArrayInt([1,2,3,5,6]) ; grp1.setName("grp1") + grp2=DataArrayInt([2,3,5,8]) ; grp2.setName("grp2") + ################ ajouter un groupe sur plusieurs niveau + mm.addGroup(0,grp1) + mm.addGroup(-1,grp2) + mm.addGroup(0,grp0_0) + mm.addGroup(-1,grp0_1) + self.assertEqual(mm.getGrpNonEmptyLevels(grpName),(0,-1)) + self.assertTrue(mm.getGroupArr(0,grpName).isEqual(grp0_0)) + self.assertTrue(mm.getGroupArr(-1,grpName).isEqual(grp0_1)) + self.assertTrue(mm.getGroupArr(0,"grp1").isEqual(grp1)) + self.assertTrue(mm.getGroupArr(-1,"grp2").isEqual(grp2)) + self.assertRaises(InterpKernelException,mm.addGroup,-1,grp0_1) # raise + self.assertTrue(mm.getGroupArr(0,grpName).isEqual(grp0_0)) + self.assertTrue(mm.getGroupArr(-1,grpName).isEqual(grp0_1)) + self.assertTrue(mm.getGroupArr(0,"grp1").isEqual(grp1)) + self.assertTrue(mm.getGroupArr(-1,"grp2").isEqual(grp2)) + mm.removeGroupAtLevel(0,grpName) + self.assertEqual(mm.getGrpNonEmptyLevels(grpName),(-1,)) + self.assertTrue(mm.getGroupArr(-1,grpName).isEqual(grp0_1)) + self.assertTrue(mm.getGroupArr(0,"grp1").isEqual(grp1)) + self.assertTrue(mm.getGroupArr(-1,"grp2").isEqual(grp2)) + mm.removeGroupAtLevel(-1,grpName) + self.assertEqual(mm.getGrpNonEmptyLevels(grpName),()) + self.assertRaises(InterpKernelException,mm.removeGroupAtLevel,-2,grpName) + mm.addGroup(-1,grp0_1) + mm.addGroup(0,grp0_0) + self.assertEqual(mm.getGrpNonEmptyLevels(grpName),(0,-1)) + self.assertTrue(mm.getGroupArr(0,grpName).isEqual(grp0_0)) + self.assertTrue(mm.getGroupArr(-1,grpName).isEqual(grp0_1)) + self.assertTrue(mm.getGroupArr(0,"grp1").isEqual(grp1)) + self.assertTrue(mm.getGroupArr(-1,"grp2").isEqual(grp2)) + pass pass -- 2.39.2