From 546656867bf3a1f1c9d39aec28afa2d06bf30705 Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 12 Dec 2016 12:43:05 +0100 Subject: [PATCH] fix FemMesh::copyMeshData --- src/Mod/Fem/App/FemMesh.cpp | 118 ++++++++++++++++++++++++++++++++++-- src/Mod/Fem/TestFem.py | 6 +- 2 files changed, 116 insertions(+), 8 deletions(-) diff --git a/src/Mod/Fem/App/FemMesh.cpp b/src/Mod/Fem/App/FemMesh.cpp index f17e5378a..7364efb69 100644 --- a/src/Mod/Fem/App/FemMesh.cpp +++ b/src/Mod/Fem/App/FemMesh.cpp @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -126,12 +127,119 @@ void FemMesh::copyMeshData(const FemMesh& mesh) { _Mtrx = mesh._Mtrx; + // See file SMESH_I/SMESH_Gen_i.cxx in the git repo of smesh at https://git.salome-platform.org #if 1 - // create a temporary file - Base::FileInfo fi(App::Application::getTempFileName().c_str()); - mesh.myMesh->ExportUNV(fi.filePath().c_str()); - this->myMesh->UNVToMesh(fi.filePath().c_str()); - fi.deleteFile(); + // 1. Get source mesh + SMESHDS_Mesh* srcMeshDS = mesh.myMesh->GetMeshDS(); + + // 2. Get target mesh + SMESHDS_Mesh* newMeshDS = this->myMesh->GetMeshDS(); + SMESH_MeshEditor editor(this->myMesh); + + // 3. Get elements to copy + SMDS_ElemIteratorPtr srcElemIt; SMDS_NodeIteratorPtr srcNodeIt; + srcElemIt = srcMeshDS->elementsIterator(); + srcNodeIt = srcMeshDS->nodesIterator(); + + // 4. Copy elements + int iN; + const SMDS_MeshNode *nSrc, *nTgt; + std::vector< const SMDS_MeshNode* > nodes; + while (srcElemIt->more()) { + const SMDS_MeshElement * elem = srcElemIt->next(); + // find / add nodes + nodes.resize(elem->NbNodes()); + SMDS_ElemIteratorPtr nIt = elem->nodesIterator(); + for (iN = 0; nIt->more(); ++iN) { + nSrc = static_cast( nIt->next() ); + nTgt = newMeshDS->FindNode( nSrc->GetID()); + if (!nTgt) + nTgt = newMeshDS->AddNodeWithID( nSrc->X(), nSrc->Y(), nSrc->Z(), nSrc->GetID()); + nodes[iN] = nTgt; + } + + // add elements + if (elem->GetType() != SMDSAbs_Node) { + int ID = elem->GetID(); + const SMDS_MeshElement * newElem; + switch (elem->GetEntityType()) { + case SMDSEntity_Polyhedra: + newElem = editor.GetMeshDS()-> + AddPolyhedralVolumeWithID(nodes, + static_cast(elem)->GetQuantities(), + ID); + break; + case SMDSEntity_Ball: + { + SMESH_MeshEditor::ElemFeatures elemFeat; + elemFeat.Init(static_cast(elem)->GetDiameter()); + elemFeat.SetID(ID); + newElem = editor.AddElement(nodes, elemFeat); + break; + } + default: + { + SMESH_MeshEditor::ElemFeatures elemFeat(elem->GetType(), elem->IsPoly()); + elemFeat.SetID(ID); + newElem = editor.AddElement(nodes, elemFeat); + break; + } + } + } + } + + // 4(b). Copy free nodes + if (srcNodeIt && srcMeshDS->NbNodes() != newMeshDS->NbNodes()) { + while (srcNodeIt->more()) { + nSrc = srcNodeIt->next(); + if (nSrc->NbInverseElements() == 0) { + nTgt = newMeshDS->AddNodeWithID(nSrc->X(), nSrc->Y(), nSrc->Z(), nSrc->GetID()); + } + } + } + + // 5. Copy groups + SMESH_Mesh::GroupIteratorPtr gIt = mesh.myMesh->GetGroups(); + while (gIt->more()) { + SMESH_Group* group = gIt->next(); + const SMESHDS_GroupBase* groupDS = group->GetGroupDS(); + + // Check group type. We copy nodal groups containing nodes of copied element + SMDSAbs_ElementType groupType = groupDS->GetType(); + if (groupType != SMDSAbs_Node && newMeshDS->GetMeshInfo().NbElements( groupType ) == 0) + continue; // group type differs from types of meshPart + + // Find copied elements in the group + std::vector< const SMDS_MeshElement* > groupElems; + SMDS_ElemIteratorPtr eIt = groupDS->GetElements(); + const SMDS_MeshElement* foundElem; + if (groupType == SMDSAbs_Node) { + while (eIt->more()) { + if ((foundElem = newMeshDS->FindNode( eIt->next()->GetID()))) + groupElems.push_back(foundElem); + } + } + else { + while (eIt->more()) + if ((foundElem = newMeshDS->FindElement(eIt->next()->GetID()))) + groupElems.push_back(foundElem); + } + + // Make a new group + if (!groupElems.empty()) { + int aId; + SMESH_Group* newGroupObj = this->myMesh->AddGroup(groupType, group->GetName(), aId); + SMESHDS_Group* newGroupDS = dynamic_cast(newGroupObj->GetGroupDS()); + if (newGroupDS) { + SMDS_MeshGroup& smdsGroup = ((SMESHDS_Group*)newGroupDS)->SMDSGroup(); + for (unsigned i = 0; i < groupElems.size(); ++i) + smdsGroup.Add(groupElems[i]); + } + } + } + + newMeshDS->Modified(); + #else SMESHDS_Mesh* meshds = this->myMesh->GetMeshDS(); diff --git a/src/Mod/Fem/TestFem.py b/src/Mod/Fem/TestFem.py index ecb10d262..4a0f4a6ca 100644 --- a/src/Mod/Fem/TestFem.py +++ b/src/Mod/Fem/TestFem.py @@ -238,7 +238,7 @@ class FemTest(unittest.TestCase): fcc_print('Comparing {} to {}/{}.inp'.format(static_analysis_inp_file, static_analysis_dir, mesh_name)) ret = self.compare_inp_files(static_analysis_inp_file, static_analysis_dir + "/" + mesh_name + '.inp') - #self.assertFalse(ret, "FemToolsCcx write_inp_file test failed.\n{}".format(ret)) + self.assertFalse(ret, "FemToolsCcx write_inp_file test failed.\n{}".format(ret)) fcc_print('Setting up working directory to {} in order to read simulated calculations'.format(test_file_dir)) fea.setup_working_dir(test_file_dir) @@ -282,7 +282,7 @@ class FemTest(unittest.TestCase): fcc_print('Comparing {} to {}/{}.inp'.format(frequency_analysis_inp_file, frequency_analysis_dir, mesh_name)) ret = self.compare_inp_files(frequency_analysis_inp_file, frequency_analysis_dir + "/" + mesh_name + '.inp') - #self.assertFalse(ret, "FemToolsCcx write_inp_file test failed.\n{}".format(ret)) + self.assertFalse(ret, "FemToolsCcx write_inp_file test failed.\n{}".format(ret)) fcc_print('Setting up working directory to {} in order to read simulated calculations'.format(test_file_dir)) fea.setup_working_dir(test_file_dir) @@ -501,7 +501,7 @@ class TherMechFemTest(unittest.TestCase): fcc_print('Comparing {} to {}/{}.inp'.format(thermomech_analysis_inp_file, thermomech_analysis_dir, mesh_name)) ret = self.compare_inp_files(thermomech_analysis_inp_file, thermomech_analysis_dir + "/" + mesh_name + '.inp') - #self.assertFalse(ret, "FemToolsCcx write_inp_file test failed.\n{}".format(ret)) + self.assertFalse(ret, "FemToolsCcx write_inp_file test failed.\n{}".format(ret)) fcc_print('Setting up working directory to {} in order to read simulated calculations'.format(test_file_dir)) fea.setup_working_dir(test_file_dir)