return ret;
}
+/*!
+ * Aggregate the given MEDFileUMesh objects into a single mesh. When groups are present, those are
+ * merged in such a way that the final mesh contain all of them.
+ * \return a new object.
+ */
MCAuto<MEDFileUMesh> MEDFileUMesh::Aggregate(const std::vector<const MEDFileUMesh *>& meshes)
{
if(meshes.empty())
std::map<std::string,int> famNumMap;
std::map<int, std::string> famNumMap_rev;
std::map<std::string, std::vector<std::string> > grpFamMap;
+ std::set< MCAuto<DataArrayInt> > mem_cleanup; // Memory clean-up. At set deletion (end of method), arrays will be deallocated.
// Identify min family number used:
int min_fam_num(0);
// Family field - substitute new family number if needed:
if(fam_conflict)
{
- DataArrayInt *dai(msh->getFamilyFieldAtLevel(level)->deepCopy()); // Need a copy
+ DataArrayInt* dai(msh->getFamilyFieldAtLevel(level)->deepCopy()); // Need a copy
+ mem_cleanup.insert(MCAuto<DataArrayInt>(dai)); // Make sure array will decrRef() at end of method
for (const auto& subN : substituteN)
dai->changeValue(subN.first, subN.second);
m_fam[level].push_back(dai);
const std::map<std::string, std::vector<std::string> >& locMap2(msh->getGroupInfo());
for(const auto& grpItem : locMap2)
{
- const auto& famLst = grpItem.second;
+ const std::string& grpName = grpItem.first;
+ std::vector<std::string> famLst;
// Substitute family name in group description if needed:
if (fam_conflict)
{
- std::vector<std::string> newLst(famLst); // Copy needed.
+ famLst = grpItem.second;
for (const auto& sub : substitute)
- std::replace(newLst.begin(), newLst.end(), sub.first, sub.second);
- grpFamMap[grpItem.first]=newLst;
+ std::replace(famLst.begin(), famLst.end(), sub.first, sub.second);
+ }
+ else
+ famLst = grpItem.second;
+
+ // Potentially merge groups (if same name):
+ const auto& it = grpFamMap.find(grpName);
+ if (it != grpFamMap.end())
+ {
+ // Group already exists, merge should be done. Normally we whould never
+ // have twice the same family name in famLstCur and famLst since we dealt with family number
+ // conflict just above ...
+ std::vector<std::string>& famLstCur = (*it).second;
+ famLstCur.insert(famLstCur.end(), famLst.begin(), famLst.end());
}
else
- grpFamMap[grpItem.first]=famLst;
+ grpFamMap[grpName] = famLst;
}
}
// Easy part : nodes
mu.setMeshAtLevel(0, m)
g = DataArrayInt([0])
g.setName(grp_name)
- mu.setGroupsAtLevel(0, [g])
+ g2 = DataArrayInt([1])
+ g2.setName("common") # make a common group for all meshes being merged
+ mu.setGroupsAtLevel(0, [g, g2])
return mu
m1 = generate("A", 0.)
m2 = generate("B", 2.)
mm = MEDFileUMesh.Aggregate([m1,m2])
- self.assertEqual(mm.getFamilyFieldAtLevel(0).getValues(), [-2, -1, -1, -1, -3, -1, -1, -1])
+ self.assertEqual(mm.getFamilyFieldAtLevel(0).getValues(), [-2, -3, -1, -1, -4, -5, -1, -1])
self.assertEqual(mm.getNumberFieldAtLevel(0), None)
- refFamIds=[('Family_-1',-1),('Family_-2',-2),('Family_-3',-3)]
+ refFamIds=[('Family_-1',-1),('Family_-2',-2),('Family_-3',-3), ('Family_-4',-4), ('Family_-5',-5)]
self.assertEqual(set(mm.getFamiliesNames()),set([elt[0] for elt in refFamIds]))
self.assertEqual(set([mm.getFamilyId(elt) for elt in mm.getFamiliesNames()]),set([elt[1] for elt in refFamIds]))
- self.assertEqual(mm.getGroupsNames(),('A','B'))
+ self.assertEqual(mm.getGroupsNames(),('A','B', 'common'))
self.assertEqual(mm.getGroupArr(0, 'A').getValues(), [0])
self.assertEqual(mm.getGroupArr(0, 'B').getValues(), [4])
+ self.assertEqual(mm.getGroupArr(0, 'common').getValues(), [1,5])
pass