diff --git a/src/Mod/Fem/App/AppFem.cpp b/src/Mod/Fem/App/AppFem.cpp index 81cf2e84b7..d9566c54fd 100644 --- a/src/Mod/Fem/App/AppFem.cpp +++ b/src/Mod/Fem/App/AppFem.cpp @@ -161,6 +161,8 @@ PyMOD_INIT_FUNC(Fem) Fem::FemMesh ::init(); Fem::FemMeshObject ::init(); Fem::FemMeshObjectPython ::init(); + Fem::FemMeshShapeBaseObject ::init(); + Fem::FemMeshShapeBaseObjectPython ::init(); Fem::FemMeshShapeObject ::init(); Fem::FemMeshShapeNetgenObject ::init(); Fem::PropertyFemMesh ::init(); diff --git a/src/Mod/Fem/App/FemMesh.cpp b/src/Mod/Fem/App/FemMesh.cpp index 2b8788a687..f5d7128321 100644 --- a/src/Mod/Fem/App/FemMesh.cpp +++ b/src/Mod/Fem/App/FemMesh.cpp @@ -82,39 +82,35 @@ using namespace Fem; using namespace Base; using namespace boost; -#if SMESH_VERSION_MAJOR < 9 -static int StatCount = 0; -#endif - SMESH_Gen* FemMesh::_mesh_gen = nullptr; TYPESYSTEM_SOURCE(Fem::FemMesh, Base::Persistence) FemMesh::FemMesh() + : myMesh(nullptr) + , myStudyId(0) { - // Base::Console().Log("FemMesh::FemMesh():%p (id=%i)\n",this,StatCount); - // create a mesh always with new StudyId to avoid overlapping destruction #if SMESH_VERSION_MAJOR >= 9 myMesh = getGenerator()->CreateMesh(false); #else - myMesh = getGenerator()->CreateMesh(StatCount++, false); + myMesh = getGenerator()->CreateMesh(myStudyId, false); #endif } FemMesh::FemMesh(const FemMesh& mesh) + : myMesh(nullptr) + , myStudyId(0) { #if SMESH_VERSION_MAJOR >= 9 myMesh = getGenerator()->CreateMesh(false); #else - myMesh = getGenerator()->CreateMesh(StatCount++, false); + myMesh = getGenerator()->CreateMesh(myStudyId, false); #endif copyMeshData(mesh); } FemMesh::~FemMesh() { - // Base::Console().Log("FemMesh::~FemMesh():%p\n",this); - try { TopoDS_Shape aNull; myMesh->ShapeToMesh(aNull); @@ -132,7 +128,7 @@ FemMesh& FemMesh::operator=(const FemMesh& mesh) #if SMESH_VERSION_MAJOR >= 9 myMesh = getGenerator()->CreateMesh(true); #else - myMesh = getGenerator()->CreateMesh(0, true); + myMesh = getGenerator()->CreateMesh(myStudyId, true); #endif copyMeshData(mesh); } @@ -537,75 +533,41 @@ void FemMesh::addHypothesis(const TopoDS_Shape& aSubShape, SMESH_HypothesisPtr h void FemMesh::setStandardHypotheses() { - if (!hypoth.empty()) { + TopoDS_Shape shape = getSMesh()->GetShapeToMesh(); + if (shape.IsNull()) { return; } -#if SMESH_VERSION_MAJOR >= 9 + int hyp = 0; - SMESH_HypothesisPtr len(new StdMeshers_MaxLength(hyp++, getGenerator())); + + auto len = createHypothesis(hyp++); static_cast(len.get())->SetLength(1.0); - hypoth.push_back(len); + addHypothesis(shape, len); - SMESH_HypothesisPtr loc(new StdMeshers_LocalLength(hyp++, getGenerator())); + auto loc = createHypothesis(hyp++); static_cast(loc.get())->SetLength(1.0); - hypoth.push_back(loc); + addHypothesis(shape, loc); - SMESH_HypothesisPtr area(new StdMeshers_MaxElementArea(hyp++, getGenerator())); + auto area = createHypothesis(hyp++); static_cast(area.get())->SetMaxArea(1.0); - hypoth.push_back(area); + addHypothesis(shape, area); - SMESH_HypothesisPtr segm(new StdMeshers_NumberOfSegments(hyp++, getGenerator())); + auto segm = createHypothesis(hyp++); static_cast(segm.get())->SetNumberOfSegments(1); - hypoth.push_back(segm); + addHypothesis(shape, segm); - SMESH_HypothesisPtr defl(new StdMeshers_Deflection1D(hyp++, getGenerator())); + auto defl = createHypothesis(hyp++); static_cast(defl.get())->SetDeflection(0.01); - hypoth.push_back(defl); + addHypothesis(shape, defl); - SMESH_HypothesisPtr reg(new StdMeshers_Regular_1D(hyp++, getGenerator())); - hypoth.push_back(reg); + auto reg = createHypothesis(hyp++); + addHypothesis(shape, reg); - SMESH_HypothesisPtr qdp(new StdMeshers_QuadranglePreference(hyp++, getGenerator())); - hypoth.push_back(qdp); + auto qdp = createHypothesis(hyp++); + addHypothesis(shape, qdp); - SMESH_HypothesisPtr q2d(new StdMeshers_Quadrangle_2D(hyp++, getGenerator())); - hypoth.push_back(q2d); -#else - int hyp = 0; - 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, getGenerator())); - static_cast(loc.get())->SetLength(1.0); - hypoth.push_back(loc); - - 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, getGenerator())); - static_cast(segm.get())->SetNumberOfSegments(1); - hypoth.push_back(segm); - - 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, getGenerator())); - hypoth.push_back(reg); - - SMESH_HypothesisPtr qdp(new StdMeshers_QuadranglePreference(hyp++, 1, getGenerator())); - hypoth.push_back(qdp); - - SMESH_HypothesisPtr q2d(new StdMeshers_Quadrangle_2D(hyp++, 1, getGenerator())); - hypoth.push_back(q2d); -#endif - - // Apply hypothesis - for (int i = 0; i < hyp; i++) { - myMesh->AddHypothesis(myMesh->GetShapeToMesh(), i); - } + auto q2d = createHypothesis(hyp++); + addHypothesis(shape, q2d); } void FemMesh::compute() diff --git a/src/Mod/Fem/App/FemMesh.h b/src/Mod/Fem/App/FemMesh.h index 4ef1144983..5008e25252 100644 --- a/src/Mod/Fem/App/FemMesh.h +++ b/src/Mod/Fem/App/FemMesh.h @@ -95,6 +95,9 @@ public: static SMESH_Gen* getGenerator(); void addHypothesis(const TopoDS_Shape& aSubShape, SMESH_HypothesisPtr hyp); void setStandardHypotheses(); + template + SMESH_HypothesisPtr createHypothesis(int hypId); + void compute(); // from base class @@ -220,11 +223,26 @@ private: /// positioning matrix Base::Matrix4D _Mtrx; SMESH_Mesh* myMesh; + const int myStudyId; std::list hypoth; static SMESH_Gen* _mesh_gen; }; + +template +inline SMESH_HypothesisPtr FemMesh::createHypothesis(int hypId) +{ + SMESH_Gen* myGen = getGenerator(); +#if SMESH_VERSION_MAJOR >= 9 + SMESH_HypothesisPtr hypo(new T(hypId, myGen)); +#else + // use own StudyContextStruct + SMESH_HypothesisPtr hypo(new T(hypId, myStudyId, myGen)); +#endif + return hypo; +} + } // namespace Fem diff --git a/src/Mod/Fem/App/FemMeshShapeNetgenObject.cpp b/src/Mod/Fem/App/FemMeshShapeNetgenObject.cpp index 6f5e93a7f7..a296b0b10b 100644 --- a/src/Mod/Fem/App/FemMeshShapeNetgenObject.cpp +++ b/src/Mod/Fem/App/FemMeshShapeNetgenObject.cpp @@ -45,7 +45,7 @@ using namespace Fem; using namespace App; -PROPERTY_SOURCE(Fem::FemMeshShapeNetgenObject, Fem::FemMeshShapeObject) +PROPERTY_SOURCE(Fem::FemMeshShapeNetgenObject, Fem::FemMeshShapeBaseObject) const char* FinenessEnums[] = {"VeryCoarse", "Coarse", "Moderate", "Fine", "VeryFine", "UserDefined", nullptr}; @@ -93,7 +93,7 @@ App::DocumentObjectExecReturn* FemMeshShapeNetgenObject::execute() #if SMESH_VERSION_MAJOR >= 9 NETGENPlugin_Hypothesis* tet = new NETGENPlugin_Hypothesis(0, newMesh.getGenerator()); #else - NETGENPlugin_Hypothesis* tet = new NETGENPlugin_Hypothesis(0, 1, newMesh.getGenerator()); + NETGENPlugin_Hypothesis* tet = new NETGENPlugin_Hypothesis(0, 0, newMesh.getGenerator()); #endif tet->SetMaxSize(MaxSize.getValue()); tet->SetMinSize(MinSize.getValue()); diff --git a/src/Mod/Fem/App/FemMeshShapeNetgenObject.h b/src/Mod/Fem/App/FemMeshShapeNetgenObject.h index e8d952df32..b8db150610 100644 --- a/src/Mod/Fem/App/FemMeshShapeNetgenObject.h +++ b/src/Mod/Fem/App/FemMeshShapeNetgenObject.h @@ -29,7 +29,7 @@ namespace Fem { -class FemExport FemMeshShapeNetgenObject: public FemMeshShapeObject +class FemExport FemMeshShapeNetgenObject: public FemMeshShapeBaseObject { PROPERTY_HEADER_WITH_OVERRIDE(Fem::FemMeshShapeNetgenObject); diff --git a/src/Mod/Fem/App/FemMeshShapeObject.cpp b/src/Mod/Fem/App/FemMeshShapeObject.cpp index 6aad5cd41d..281c524d8c 100644 --- a/src/Mod/Fem/App/FemMeshShapeObject.cpp +++ b/src/Mod/Fem/App/FemMeshShapeObject.cpp @@ -21,32 +21,13 @@ ***************************************************************************/ #include "PreCompiled.h" -#include #ifndef _PreComp_ -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #endif -#include +#include +#include #include #include "FemMesh.h" @@ -56,10 +37,9 @@ using namespace Fem; using namespace App; -PROPERTY_SOURCE(Fem::FemMeshShapeObject, Fem::FemMeshObject) +PROPERTY_SOURCE(Fem::FemMeshShapeBaseObject, Fem::FemMeshObject) - -FemMeshShapeObject::FemMeshShapeObject() +FemMeshShapeBaseObject::FemMeshShapeBaseObject() { ADD_PROPERTY_TYPE( Shape, @@ -67,8 +47,18 @@ FemMeshShapeObject::FemMeshShapeObject() "FEM Mesh", Prop_None, "Geometry object, the mesh is made from. The geometry object has to have a Shape."); + + Shape.setScope(LinkScope::Global); } +FemMeshShapeBaseObject::~FemMeshShapeBaseObject() = default; + +// ------------------------------------------------------------------------ + +PROPERTY_SOURCE(Fem::FemMeshShapeObject, Fem::FemMeshShapeBaseObject) + +FemMeshShapeObject::FemMeshShapeObject() = default; + FemMeshShapeObject::~FemMeshShapeObject() = default; App::DocumentObjectExecReturn* FemMeshShapeObject::execute() @@ -76,83 +66,43 @@ App::DocumentObjectExecReturn* FemMeshShapeObject::execute() Fem::FemMesh newMesh; Part::Feature* feat = Shape.getValue(); - TopoDS_Shape shape = feat->Shape.getValue(); newMesh.getSMesh()->ShapeToMesh(shape); - SMESH_Gen* myGen = newMesh.getGenerator(); + newMesh.setStandardHypotheses(); - int hyp = 0; - -#if 1 // Surface quad mesh -#if SMESH_VERSION_MAJOR >= 9 - SMESH_HypothesisPtr len(new StdMeshers_MaxLength(hyp++, myGen)); - static_cast(len.get())->SetLength(1.0); - newMesh.addHypothesis(shape, len); - - SMESH_HypothesisPtr loc(new StdMeshers_LocalLength(hyp++, myGen)); - static_cast(loc.get())->SetLength(1.0); - newMesh.addHypothesis(shape, loc); - - SMESH_HypothesisPtr area(new StdMeshers_MaxElementArea(hyp++, myGen)); - static_cast(area.get())->SetMaxArea(1.0); - newMesh.addHypothesis(shape, area); - - SMESH_HypothesisPtr segm(new StdMeshers_NumberOfSegments(hyp++, myGen)); - static_cast(segm.get())->SetNumberOfSegments(1); - newMesh.addHypothesis(shape, segm); - - SMESH_HypothesisPtr defl(new StdMeshers_Deflection1D(hyp++, myGen)); - static_cast(defl.get())->SetDeflection(0.01); - newMesh.addHypothesis(shape, defl); - - SMESH_HypothesisPtr reg(new StdMeshers_Regular_1D(hyp++, myGen)); - newMesh.addHypothesis(shape, reg); - - SMESH_HypothesisPtr qdp(new StdMeshers_QuadranglePreference(hyp++, myGen)); - newMesh.addHypothesis(shape, qdp); - - SMESH_HypothesisPtr q2d(new StdMeshers_Quadrangle_2D(hyp++, myGen)); - newMesh.addHypothesis(shape, q2d); -#else - SMESH_HypothesisPtr len(new StdMeshers_MaxLength(hyp++, 1, myGen)); - static_cast(len.get())->SetLength(1.0); - newMesh.addHypothesis(shape, len); - - SMESH_HypothesisPtr loc(new StdMeshers_LocalLength(hyp++, 1, myGen)); - static_cast(loc.get())->SetLength(1.0); - newMesh.addHypothesis(shape, loc); - - SMESH_HypothesisPtr area(new StdMeshers_MaxElementArea(hyp++, 1, myGen)); - static_cast(area.get())->SetMaxArea(1.0); - newMesh.addHypothesis(shape, area); - - SMESH_HypothesisPtr segm(new StdMeshers_NumberOfSegments(hyp++, 1, myGen)); - static_cast(segm.get())->SetNumberOfSegments(1); - newMesh.addHypothesis(shape, segm); - - SMESH_HypothesisPtr defl(new StdMeshers_Deflection1D(hyp++, 1, myGen)); - static_cast(defl.get())->SetDeflection(0.01); - newMesh.addHypothesis(shape, defl); - - SMESH_HypothesisPtr reg(new StdMeshers_Regular_1D(hyp++, 1, myGen)); - newMesh.addHypothesis(shape, reg); - - SMESH_HypothesisPtr qdp(new StdMeshers_QuadranglePreference(hyp++, 1, myGen)); - newMesh.addHypothesis(shape, qdp); - - SMESH_HypothesisPtr q2d(new StdMeshers_Quadrangle_2D(hyp++, 1, myGen)); - newMesh.addHypothesis(shape, q2d); -#endif - - // create mesh newMesh.compute(); -#endif - // set the value to the object FemMesh.setValue(newMesh); - return App::DocumentObject::StdReturn; } + +// Python feature --------------------------------------------------------- + +namespace App +{ + +PROPERTY_SOURCE_TEMPLATE(Fem::FemMeshShapeBaseObjectPython, Fem::FemMeshShapeBaseObject) + +template<> +const char* Fem::FemMeshShapeBaseObjectPython::getViewProviderName() const +{ + return "FemGui::ViewProviderFemMeshShapeBasePython"; +} + +template<> +PyObject* Fem::FemMeshShapeBaseObjectPython::getPyObject() +{ + if (PythonObject.is(Py::_None())) { + // ref counter is set to 1 + PythonObject = Py::asObject(new App::FeaturePythonPyT(this)); + } + return Py::new_reference_to(PythonObject); +} + +// explicit template instantiation +template class FemExport FeaturePythonT; + +} // namespace App diff --git a/src/Mod/Fem/App/FemMeshShapeObject.h b/src/Mod/Fem/App/FemMeshShapeObject.h index 13d20af526..adf08ee618 100644 --- a/src/Mod/Fem/App/FemMeshShapeObject.h +++ b/src/Mod/Fem/App/FemMeshShapeObject.h @@ -29,7 +29,26 @@ namespace Fem { -class FemExport FemMeshShapeObject: public FemMeshObject +class FemExport FemMeshShapeBaseObject: public FemMeshObject +{ + PROPERTY_HEADER_WITH_OVERRIDE(Fem::FemMeshShapeBaseObject); + +public: + /// Constructor + FemMeshShapeBaseObject(); + ~FemMeshShapeBaseObject() override; + + App::PropertyLink Shape; + + /// returns the type name of the ViewProvider + const char* getViewProviderName() const override + { + return "FemGui::ViewProviderFemMeshShapeBase"; + } +}; + + +class FemExport FemMeshShapeObject: public FemMeshShapeBaseObject { PROPERTY_HEADER_WITH_OVERRIDE(Fem::FemMeshShapeObject); @@ -48,13 +67,13 @@ public: // virtual short mustExecute(void) const; // virtual PyObject *getPyObject(void); - App::PropertyLink Shape; - protected: /// get called by the container when a property has changed // virtual void onChanged (const App::Property* prop); }; +using FemMeshShapeBaseObjectPython = App::FeaturePythonT; + } // namespace Fem diff --git a/src/Mod/Fem/Gui/AppFemGui.cpp b/src/Mod/Fem/Gui/AppFemGui.cpp index ffe08198d4..6f9fc459b2 100644 --- a/src/Mod/Fem/Gui/AppFemGui.cpp +++ b/src/Mod/Fem/Gui/AppFemGui.cpp @@ -138,6 +138,8 @@ PyMOD_INIT_FUNC(FemGui) FemGui::ViewProviderFemMesh ::init(); FemGui::ViewProviderFemMeshPython ::init(); + FemGui::ViewProviderFemMeshShapeBase ::init(); + FemGui::ViewProviderFemMeshShapeBasePython ::init(); FemGui::ViewProviderFemMeshShape ::init(); FemGui::ViewProviderFemMeshShapeNetgen ::init(); FemGui::PropertyFemMeshItem ::init(); diff --git a/src/Mod/Fem/Gui/ViewProviderFemMeshShape.cpp b/src/Mod/Fem/Gui/ViewProviderFemMeshShape.cpp index e53b4fd76a..62e82d664c 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemMeshShape.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemMeshShape.cpp @@ -27,8 +27,30 @@ using namespace FemGui; -PROPERTY_SOURCE(FemGui::ViewProviderFemMeshShape, FemGui::ViewProviderFemMesh) +PROPERTY_SOURCE(FemGui::ViewProviderFemMeshShapeBase, FemGui::ViewProviderFemMesh) + +ViewProviderFemMeshShapeBase::ViewProviderFemMeshShapeBase() = default; + +ViewProviderFemMeshShapeBase::~ViewProviderFemMeshShapeBase() = default; + +// ------------------------------------------------------------------------ + +PROPERTY_SOURCE(FemGui::ViewProviderFemMeshShape, FemGui::ViewProviderFemMeshShapeBase) ViewProviderFemMeshShape::ViewProviderFemMeshShape() = default; ViewProviderFemMeshShape::~ViewProviderFemMeshShape() = default; + + +// Python feature --------------------------------------------------------- + +namespace Gui +{ + +PROPERTY_SOURCE_TEMPLATE(FemGui::ViewProviderFemMeshShapeBasePython, + FemGui::ViewProviderFemMeshShapeBase) + +// explicit template instantiation +template class FemGuiExport ViewProviderPythonFeatureT; + +} // namespace Gui diff --git a/src/Mod/Fem/Gui/ViewProviderFemMeshShape.h b/src/Mod/Fem/Gui/ViewProviderFemMeshShape.h index 0cfe89e1bf..5c52f1b4f7 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemMeshShape.h +++ b/src/Mod/Fem/Gui/ViewProviderFemMeshShape.h @@ -24,12 +24,28 @@ #ifndef FEM_ViewProviderFemMeshShape_H #define FEM_ViewProviderFemMeshShape_H +#include + #include "ViewProviderFemMesh.h" + namespace FemGui { -class FemGuiExport ViewProviderFemMeshShape: public ViewProviderFemMesh +class FemGuiExport ViewProviderFemMeshShapeBase: public ViewProviderFemMesh +{ + PROPERTY_HEADER_WITH_OVERRIDE(FemGui::ViewProviderFemMeshShapeBase); + +public: + /// constructor. + ViewProviderFemMeshShapeBase(); + + /// destructor. + ~ViewProviderFemMeshShapeBase() override; +}; + + +class FemGuiExport ViewProviderFemMeshShape: public ViewProviderFemMeshShapeBase { PROPERTY_HEADER_WITH_OVERRIDE(FemGui::ViewProviderFemMeshShape); @@ -41,6 +57,9 @@ public: ~ViewProviderFemMeshShape() override; }; +using ViewProviderFemMeshShapeBasePython = + Gui::ViewProviderPythonFeatureT; + } // namespace FemGui