Fem: Add FemMeshShapeBaseObject and fix FemMeshShapeObject meshing

This commit is contained in:
marioalexis
2024-07-25 13:30:15 -03:00
parent 5c9d780a17
commit f089c710bd
10 changed files with 160 additions and 166 deletions

View File

@@ -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();

View File

@@ -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<StdMeshers_MaxLength>(hyp++);
static_cast<StdMeshers_MaxLength*>(len.get())->SetLength(1.0);
hypoth.push_back(len);
addHypothesis(shape, len);
SMESH_HypothesisPtr loc(new StdMeshers_LocalLength(hyp++, getGenerator()));
auto loc = createHypothesis<StdMeshers_LocalLength>(hyp++);
static_cast<StdMeshers_LocalLength*>(loc.get())->SetLength(1.0);
hypoth.push_back(loc);
addHypothesis(shape, loc);
SMESH_HypothesisPtr area(new StdMeshers_MaxElementArea(hyp++, getGenerator()));
auto area = createHypothesis<StdMeshers_MaxElementArea>(hyp++);
static_cast<StdMeshers_MaxElementArea*>(area.get())->SetMaxArea(1.0);
hypoth.push_back(area);
addHypothesis(shape, area);
SMESH_HypothesisPtr segm(new StdMeshers_NumberOfSegments(hyp++, getGenerator()));
auto segm = createHypothesis<StdMeshers_NumberOfSegments>(hyp++);
static_cast<StdMeshers_NumberOfSegments*>(segm.get())->SetNumberOfSegments(1);
hypoth.push_back(segm);
addHypothesis(shape, segm);
SMESH_HypothesisPtr defl(new StdMeshers_Deflection1D(hyp++, getGenerator()));
auto defl = createHypothesis<StdMeshers_Deflection1D>(hyp++);
static_cast<StdMeshers_Deflection1D*>(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<StdMeshers_Regular_1D>(hyp++);
addHypothesis(shape, reg);
SMESH_HypothesisPtr qdp(new StdMeshers_QuadranglePreference(hyp++, getGenerator()));
hypoth.push_back(qdp);
auto qdp = createHypothesis<StdMeshers_QuadranglePreference>(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<StdMeshers_MaxLength*>(len.get())->SetLength(1.0);
hypoth.push_back(len);
SMESH_HypothesisPtr loc(new StdMeshers_LocalLength(hyp++, 1, getGenerator()));
static_cast<StdMeshers_LocalLength*>(loc.get())->SetLength(1.0);
hypoth.push_back(loc);
SMESH_HypothesisPtr area(new StdMeshers_MaxElementArea(hyp++, 1, getGenerator()));
static_cast<StdMeshers_MaxElementArea*>(area.get())->SetMaxArea(1.0);
hypoth.push_back(area);
SMESH_HypothesisPtr segm(new StdMeshers_NumberOfSegments(hyp++, 1, getGenerator()));
static_cast<StdMeshers_NumberOfSegments*>(segm.get())->SetNumberOfSegments(1);
hypoth.push_back(segm);
SMESH_HypothesisPtr defl(new StdMeshers_Deflection1D(hyp++, 1, getGenerator()));
static_cast<StdMeshers_Deflection1D*>(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<StdMeshers_Quadrangle_2D>(hyp++);
addHypothesis(shape, q2d);
}
void FemMesh::compute()

View File

@@ -95,6 +95,9 @@ public:
static SMESH_Gen* getGenerator();
void addHypothesis(const TopoDS_Shape& aSubShape, SMESH_HypothesisPtr hyp);
void setStandardHypotheses();
template<typename T>
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<SMESH_HypothesisPtr> hypoth;
static SMESH_Gen* _mesh_gen;
};
template<typename T>
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

View File

@@ -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());

View File

@@ -29,7 +29,7 @@
namespace Fem
{
class FemExport FemMeshShapeNetgenObject: public FemMeshShapeObject
class FemExport FemMeshShapeNetgenObject: public FemMeshShapeBaseObject
{
PROPERTY_HEADER_WITH_OVERRIDE(Fem::FemMeshShapeNetgenObject);

View File

@@ -21,32 +21,13 @@
***************************************************************************/
#include "PreCompiled.h"
#include <SMESH_Version.h>
#ifndef _PreComp_
#include <BRepBuilderAPI_Copy.hxx>
#include <BRepTools.hxx>
#include <Python.h>
#include <SMESH_Gen.hxx>
#include <SMESH_Mesh.hxx>
#include <StdMeshers_Deflection1D.hxx>
#include <StdMeshers_Hexa_3D.hxx>
#include <StdMeshers_LocalLength.hxx>
#include <StdMeshers_MaxElementArea.hxx>
#include <StdMeshers_MaxLength.hxx>
#include <StdMeshers_NumberOfSegments.hxx>
#include <StdMeshers_ProjectionSource1D.hxx>
#include <StdMeshers_ProjectionSource2D.hxx>
#include <StdMeshers_ProjectionSource3D.hxx>
#include <StdMeshers_QuadranglePreference.hxx>
#include <StdMeshers_Quadrangle_2D.hxx>
#include <StdMeshers_RadialPrism_3D.hxx>
#include <StdMeshers_Regular_1D.hxx>
#include <StdMeshers_SegmentAroundVertex_0D.hxx>
#include <StdMeshers_StartEndLength.hxx>
#endif
#include <App/DocumentObjectPy.h>
#include <App/FeaturePythonPyImp.h>
#include <App/GeoFeaturePy.h>
#include <Mod/Part/App/PartFeature.h>
#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<Part::Feature*>();
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<StdMeshers_MaxLength*>(len.get())->SetLength(1.0);
newMesh.addHypothesis(shape, len);
SMESH_HypothesisPtr loc(new StdMeshers_LocalLength(hyp++, myGen));
static_cast<StdMeshers_LocalLength*>(loc.get())->SetLength(1.0);
newMesh.addHypothesis(shape, loc);
SMESH_HypothesisPtr area(new StdMeshers_MaxElementArea(hyp++, myGen));
static_cast<StdMeshers_MaxElementArea*>(area.get())->SetMaxArea(1.0);
newMesh.addHypothesis(shape, area);
SMESH_HypothesisPtr segm(new StdMeshers_NumberOfSegments(hyp++, myGen));
static_cast<StdMeshers_NumberOfSegments*>(segm.get())->SetNumberOfSegments(1);
newMesh.addHypothesis(shape, segm);
SMESH_HypothesisPtr defl(new StdMeshers_Deflection1D(hyp++, myGen));
static_cast<StdMeshers_Deflection1D*>(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<StdMeshers_MaxLength*>(len.get())->SetLength(1.0);
newMesh.addHypothesis(shape, len);
SMESH_HypothesisPtr loc(new StdMeshers_LocalLength(hyp++, 1, myGen));
static_cast<StdMeshers_LocalLength*>(loc.get())->SetLength(1.0);
newMesh.addHypothesis(shape, loc);
SMESH_HypothesisPtr area(new StdMeshers_MaxElementArea(hyp++, 1, myGen));
static_cast<StdMeshers_MaxElementArea*>(area.get())->SetMaxArea(1.0);
newMesh.addHypothesis(shape, area);
SMESH_HypothesisPtr segm(new StdMeshers_NumberOfSegments(hyp++, 1, myGen));
static_cast<StdMeshers_NumberOfSegments*>(segm.get())->SetNumberOfSegments(1);
newMesh.addHypothesis(shape, segm);
SMESH_HypothesisPtr defl(new StdMeshers_Deflection1D(hyp++, 1, myGen));
static_cast<StdMeshers_Deflection1D*>(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<App::GeoFeaturePy>(this));
}
return Py::new_reference_to(PythonObject);
}
// explicit template instantiation
template class FemExport FeaturePythonT<Fem::FemMeshShapeBaseObject>;
} // namespace App

View File

@@ -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<FemMeshShapeBaseObject>;
} // namespace Fem

View File

@@ -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();

View File

@@ -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<ViewProviderFemMeshShapeBase>;
} // namespace Gui

View File

@@ -24,12 +24,28 @@
#ifndef FEM_ViewProviderFemMeshShape_H
#define FEM_ViewProviderFemMeshShape_H
#include <Gui/ViewProviderPythonFeature.h>
#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<ViewProviderFemMeshShapeBase>;
} // namespace FemGui