From 2f5740600705b0d5426938485f63e865c3248564 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Tr=C3=B6ger?= Date: Sun, 15 May 2016 21:13:59 +0200 Subject: [PATCH] FEM: Use single smesh mesh generator throughout FreeCAD Creating a mesh generator resets a critical data structure and makes all existing meshes invalid. Hence the SMESH_gen is made a singleton and all FreeCAD code is changed accordingly. --- src/3rdParty/salomesmesh/inc/SMESH_Gen.hxx | 7 +++- .../salomesmesh/src/SMESH/SMESH_Gen.cpp | 10 +++++ src/Mod/Fem/App/FemMesh.cpp | 40 ++++++++----------- src/Mod/Fem/App/FemMesh.h | 10 ++--- src/Mod/Fem/App/FemMeshShapeNetgenObject.cpp | 16 ++++---- src/Mod/MeshPart/App/Mesher.cpp | 2 +- 6 files changed, 44 insertions(+), 41 deletions(-) diff --git a/src/3rdParty/salomesmesh/inc/SMESH_Gen.hxx b/src/3rdParty/salomesmesh/inc/SMESH_Gen.hxx index eb09db52b4..744b03b7d0 100644 --- a/src/3rdParty/salomesmesh/inc/SMESH_Gen.hxx +++ b/src/3rdParty/salomesmesh/inc/SMESH_Gen.hxx @@ -60,8 +60,9 @@ typedef std::set TSetOfInt; class SMESH_EXPORT SMESH_Gen { public: - SMESH_Gen(); ~SMESH_Gen(); + + static SMESH_Gen* get(); SMESH_Mesh* CreateMesh(int theStudyId, bool theIsEmbeddedMode) throw(SALOME_Exception); @@ -159,6 +160,10 @@ public: // std::map < int, SMESH_2D_Algo * >_map2D_Algo; // std::map < int, SMESH_3D_Algo * >_map3D_Algo; +protected: + SMESH_Gen(); + static SMESH_Gen* generator; + private: int _localId; // unique Id of created objects, within SMESH_Gen entity diff --git a/src/3rdParty/salomesmesh/src/SMESH/SMESH_Gen.cpp b/src/3rdParty/salomesmesh/src/SMESH/SMESH_Gen.cpp index 4c264d50ae..5780f95f1d 100644 --- a/src/3rdParty/salomesmesh/src/SMESH/SMESH_Gen.cpp +++ b/src/3rdParty/salomesmesh/src/SMESH/SMESH_Gen.cpp @@ -55,6 +55,7 @@ using namespace std; //#include +SMESH_Gen* SMESH_Gen::generator = nullptr; //============================================================================= /*! @@ -74,6 +75,15 @@ SMESH_Gen::SMESH_Gen() //vtkDebugLeaks::SetExitError(0); } +SMESH_Gen* SMESH_Gen::get() { + + if(!generator) + generator = new SMESH_Gen(); + + return generator; +} + + //============================================================================= /*! * Destructor diff --git a/src/Mod/Fem/App/FemMesh.cpp b/src/Mod/Fem/App/FemMesh.cpp index c60dcc3ec0..f7341b54eb 100644 --- a/src/Mod/Fem/App/FemMesh.cpp +++ b/src/Mod/Fem/App/FemMesh.cpp @@ -86,17 +86,13 @@ TYPESYSTEM_SOURCE(Fem::FemMesh , Base::Persistence); FemMesh::FemMesh() { //Base::Console().Log("FemMesh::FemMesh():%p (id=%i)\n",this,StatCount); - myGen = new SMESH_Gen(); // create a mesh allways with new StudyId to avoid overlapping destruction - myMesh = myGen->CreateMesh(StatCount++,false); - + myMesh = getGenerator()->CreateMesh(StatCount++,false); } FemMesh::FemMesh(const FemMesh& mesh) -{ - //Base::Console().Log("FemMesh::FemMesh(mesh):%p (id=%i)\n",this,StatCount); - myGen = new SMESH_Gen(); - myMesh = myGen->CreateMesh(StatCount++,false); +{ + myMesh = getGenerator()->CreateMesh(StatCount++,false); copyMeshData(mesh); } @@ -109,16 +105,12 @@ FemMesh::~FemMesh() myMesh->Clear(); //myMesh->ClearLog(); delete myMesh; -#if defined(__GNUC__) - delete myGen; // crashes with MSVC -#endif } FemMesh &FemMesh::operator=(const FemMesh& mesh) { if (this != &mesh) { - myGen = new SMESH_Gen(); - myMesh = myGen->CreateMesh(0,true); + myMesh = getGenerator()->CreateMesh(0,true); copyMeshData(mesh); } return *this; @@ -134,7 +126,9 @@ void FemMesh::copyMeshData(const FemMesh& mesh) SMDS_NodeIteratorPtr aNodeIter = mesh.myMesh->GetMeshDS()->nodesIterator(); for (;aNodeIter->more();) { const SMDS_MeshNode* aNode = aNodeIter->next(); + int id = aNode->GetID(); double temp[3]; + Base::Console().Message("CopyData Mesh ID: %i\n", aNode->getMeshId()); aNode->GetXYZ(temp); meshds->AddNodeWithID(temp[0],temp[1],temp[2], aNode->GetID()); } @@ -331,7 +325,7 @@ SMESH_Mesh* FemMesh::getSMesh() SMESH_Gen * FemMesh::getGenerator() { - return myGen; + return SMESH_Gen::get(); } void FemMesh::addHypothesis(const TopoDS_Shape & aSubShape, SMESH_HypothesisPtr hyp) @@ -346,37 +340,37 @@ void FemMesh::setStanardHypotheses() if (!hypoth.empty()) return; int hyp=0; - SMESH_HypothesisPtr len(new StdMeshers_MaxLength(hyp++, 1, myGen)); + SMESH_HypothesisPtr len(new StdMeshers_MaxLength(hyp++, 1, getGenerator())); static_cast(len.get())->SetLength(1.0); hypoth.push_back(len); - SMESH_HypothesisPtr loc(new StdMeshers_LocalLength(hyp++, 1, myGen)); + SMESH_HypothesisPtr loc(new StdMeshers_LocalLength(hyp++, 1, getGenerator())); static_cast(loc.get())->SetLength(1.0); hypoth.push_back(loc); - SMESH_HypothesisPtr area(new StdMeshers_MaxElementArea(hyp++, 1, myGen)); + SMESH_HypothesisPtr area(new StdMeshers_MaxElementArea(hyp++, 1, getGenerator())); static_cast(area.get())->SetMaxArea(1.0); hypoth.push_back(area); - SMESH_HypothesisPtr segm(new StdMeshers_NumberOfSegments(hyp++, 1, myGen)); + SMESH_HypothesisPtr segm(new StdMeshers_NumberOfSegments(hyp++, 1, getGenerator())); static_cast(segm.get())->SetNumberOfSegments(1); hypoth.push_back(segm); - SMESH_HypothesisPtr defl(new StdMeshers_Deflection1D(hyp++, 1, myGen)); + SMESH_HypothesisPtr defl(new StdMeshers_Deflection1D(hyp++, 1, getGenerator())); static_cast(defl.get())->SetDeflection(0.01); hypoth.push_back(defl); - SMESH_HypothesisPtr reg(new StdMeshers_Regular_1D(hyp++, 1, myGen)); + SMESH_HypothesisPtr reg(new StdMeshers_Regular_1D(hyp++, 1, getGenerator())); hypoth.push_back(reg); - //SMESH_HypothesisPtr sel(new StdMeshers_StartEndLength(hyp++, 1, myGen)); + //SMESH_HypothesisPtr sel(new StdMeshers_StartEndLength(hyp++, 1, getGenerator())); //static_cast(sel.get())->SetLength(1.0, true); //hypoth.push_back(sel); - SMESH_HypothesisPtr qdp(new StdMeshers_QuadranglePreference(hyp++,1,myGen)); + SMESH_HypothesisPtr qdp(new StdMeshers_QuadranglePreference(hyp++,1,getGenerator())); hypoth.push_back(qdp); - SMESH_HypothesisPtr q2d(new StdMeshers_Quadrangle_2D(hyp++,1,myGen)); + SMESH_HypothesisPtr q2d(new StdMeshers_Quadrangle_2D(hyp++,1,getGenerator())); hypoth.push_back(q2d); // Apply hypothesis @@ -386,7 +380,7 @@ void FemMesh::setStanardHypotheses() void FemMesh::compute() { - myGen->Compute(*myMesh, myMesh->GetShapeToMesh()); + getGenerator()->Compute(*myMesh, myMesh->GetShapeToMesh()); } std::set FemMesh::getSurfaceNodes(long ElemId, short FaceId, float Angle) const diff --git a/src/Mod/Fem/App/FemMesh.h b/src/Mod/Fem/App/FemMesh.h index b7fb4fcd89..3f66b7aa70 100644 --- a/src/Mod/Fem/App/FemMesh.h +++ b/src/Mod/Fem/App/FemMesh.h @@ -60,7 +60,7 @@ public: FemMesh &operator=(const FemMesh&); const SMESH_Mesh* getSMesh() const; SMESH_Mesh* getSMesh(); - SMESH_Gen * getGenerator(); + static SMESH_Gen * getGenerator(); void addHypothesis(const TopoDS_Shape & aSubShape, SMESH_HypothesisPtr hyp); void setStanardHypotheses(); void compute(); @@ -143,9 +143,6 @@ public: void read(const char *FileName); void write(const char *FileName) const; void writeABAQUS(const std::string &Filename) const; - Base::Matrix4D _Mtrx; - SMESH_Gen *myGen; - SMESH_Mesh *myMesh; private: void copyMeshData(const FemMesh&); @@ -153,9 +150,8 @@ private: private: /// positioning matrix -// Base::Matrix4D _Mtrx; -// SMESH_Gen *myGen; -// SMESH_Mesh *myMesh; + Base::Matrix4D _Mtrx; + SMESH_Mesh *myMesh; std::list hypoth; }; diff --git a/src/Mod/Fem/App/FemMeshShapeNetgenObject.cpp b/src/Mod/Fem/App/FemMeshShapeNetgenObject.cpp index e2ed7f4294..6ad9ffdec3 100644 --- a/src/Mod/Fem/App/FemMeshShapeNetgenObject.cpp +++ b/src/Mod/Fem/App/FemMeshShapeNetgenObject.cpp @@ -76,13 +76,12 @@ App::DocumentObjectExecReturn *FemMeshShapeNetgenObject::execute(void) { #ifdef FCWithNetgen - Fem::FemMesh newMesh; - // SMESH_Gen *myGen = newMesh.getGenerator(); -// vejmarie NEEDED TO MAKE IT WORK - newMesh.myMesh = newMesh.myGen->CreateMesh(0, true); + Fem::FemMesh newMesh, mesh2; + + Base::Console().Message("newMesh ID: %i\n", newMesh.getSMesh()->GetMeshDS()->getMeshId()); + Base::Console().Message("second mesh ID: %i\n", mesh2.getSMesh()->GetMeshDS()->getMeshId()); + Part::Feature *feat = Shape.getValue(); - - TopoDS_Shape shape = feat->Shape.getValue(); @@ -107,7 +106,7 @@ App::DocumentObjectExecReturn *FemMeshShapeNetgenObject::execute(void) myNetGenMesher.SetParameters( tet); */ - NETGENPlugin_Hypothesis* tet= new NETGENPlugin_Hypothesis(hyp++,1,newMesh.myGen); + NETGENPlugin_Hypothesis* tet= new NETGENPlugin_Hypothesis(hyp++,1,newMesh.getGenerator()); tet->SetMaxSize(MaxSize.getValue()); tet->SetSecondOrder(SecondOrder.getValue()); tet->SetOptimize(Optimize.getValue()); @@ -119,7 +118,7 @@ App::DocumentObjectExecReturn *FemMeshShapeNetgenObject::execute(void) tet->SetNbSegPerRadius(NbSegsPerRadius.getValue()); } myNetGenMesher.SetParameters( tet); - newMesh.myMesh->ShapeToMesh(shape); + newMesh.getSMesh()->ShapeToMesh(shape); myNetGenMesher.Compute(); @@ -141,7 +140,6 @@ App::DocumentObjectExecReturn *FemMeshShapeNetgenObject::execute(void) Base::Console().Log("NetgenMesh: %i Nodes, %i Volumes, %i Faces\n",numNode,numVolu,numFaces); - // set the value to the object FemMesh.setValue(newMesh); return App::DocumentObject::StdReturn; #else diff --git a/src/Mod/MeshPart/App/Mesher.cpp b/src/Mod/MeshPart/App/Mesher.cpp index dc80ec4f68..72ef17f97d 100644 --- a/src/Mod/MeshPart/App/Mesher.cpp +++ b/src/Mod/MeshPart/App/Mesher.cpp @@ -121,7 +121,7 @@ Mesh::MeshObject* Mesher::createMesh() const #else std::list hypoth; - SMESH_Gen* meshgen = new SMESH_Gen(); + SMESH_Gen* meshgen = SMESH_Gen::get(); SMESH_Mesh* mesh = meshgen->CreateMesh(0, true); int hyp=0;