Merge pull request #15624 from marioalexis84/fem-mesh_shape_object
Fem: Improve FemMeshShape objects
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
namespace Fem
|
||||
{
|
||||
|
||||
class FemExport FemMeshShapeNetgenObject: public FemMeshShapeObject
|
||||
class FemExport FemMeshShapeNetgenObject: public FemMeshShapeBaseObject
|
||||
{
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(Fem::FemMeshShapeNetgenObject);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -490,7 +490,7 @@ def makeMeshBoundaryLayer(doc, base_mesh, name="MeshBoundaryLayer"):
|
||||
def makeMeshGmsh(doc, name="MeshGmsh"):
|
||||
"""makeMeshGmsh(document, [name]):
|
||||
makes a Gmsh FEM mesh object"""
|
||||
obj = doc.addObject("Fem::FemMeshObjectPython", name)
|
||||
obj = doc.addObject("Fem::FemMeshShapeBaseObjectPython", name)
|
||||
from femobjects import mesh_gmsh
|
||||
|
||||
mesh_gmsh.MeshGmsh(obj)
|
||||
|
||||
@@ -762,10 +762,18 @@ class _MeshGmshFromShape(CommandManager):
|
||||
"ObjectsFem.makeMeshGmsh(FreeCAD.ActiveDocument, '" + mesh_obj_name + "')"
|
||||
)
|
||||
FreeCADGui.doCommand(
|
||||
"FreeCAD.ActiveDocument.ActiveObject.Part = FreeCAD.ActiveDocument.{}".format(
|
||||
"FreeCAD.ActiveDocument.ActiveObject.Shape = FreeCAD.ActiveDocument.{}".format(
|
||||
self.selobj.Name
|
||||
)
|
||||
)
|
||||
FreeCADGui.doCommand("FreeCAD.ActiveDocument.ActiveObject.ElementOrder = '2nd'")
|
||||
# SecondOrderLinear gives much better meshes in the regard of
|
||||
# nonpositive jacobians but on curved faces the constraint nodes
|
||||
# will no longer found thus standard will be False
|
||||
# https://forum.freecad.org/viewtopic.php?t=41738
|
||||
# https://forum.freecad.org/viewtopic.php?f=18&t=45260&start=20#p389494
|
||||
FreeCADGui.doCommand("FreeCAD.ActiveDocument.ActiveObject.SecondOrderLinear = False")
|
||||
|
||||
# Gmsh mesh object could be added without an active analysis
|
||||
# but if there is an active analysis move it in there
|
||||
import FemGui
|
||||
|
||||
@@ -73,9 +73,10 @@ def setup_boxanalysisbase(doc=None, solvertype="ccxtools"):
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
femmesh_obj.CharacteristicLengthMin = "8.0 mm"
|
||||
femmesh_obj.ElementOrder = "2nd"
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
|
||||
@@ -186,7 +186,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
femmesh_obj.CharacteristicLengthMax = "50.0 mm"
|
||||
femmesh_obj.ElementDimension = "2D"
|
||||
|
||||
@@ -159,7 +159,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
femmesh_obj.CharacteristicLengthMax = "300.0 mm"
|
||||
femmesh_obj.ElementDimension = "2D"
|
||||
|
||||
@@ -139,7 +139,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
|
||||
@@ -130,7 +130,7 @@ def setup_cantilever_base_edge(doc=None, solvertype="ccxtools"):
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
femmesh_obj.ElementDimension = "1D"
|
||||
femmesh_obj.CharacteristicLengthMax = "1750.0 mm"
|
||||
|
||||
@@ -115,7 +115,7 @@ def setup_cantilever_base_face(doc=None, solvertype="ccxtools"):
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
femmesh_obj.ElementDimension = "2D"
|
||||
femmesh_obj.CharacteristicLengthMax = "500.0 mm"
|
||||
|
||||
@@ -102,7 +102,7 @@ def setup_cantilever_base_solid(doc=None, solvertype="ccxtools"):
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
|
||||
doc.recompute()
|
||||
|
||||
@@ -92,7 +92,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
femmesh_obj.FemMesh = new_fem_mesh
|
||||
|
||||
# set mesh obj parameter
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
femmesh_obj.ElementDimension = "2D"
|
||||
femmesh_obj.ElementOrder = "1st"
|
||||
|
||||
@@ -92,7 +92,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
femmesh_obj.FemMesh = new_fem_mesh
|
||||
|
||||
# set mesh obj parameter
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
femmesh_obj.ElementDimension = "2D"
|
||||
femmesh_obj.ElementOrder = "1st"
|
||||
|
||||
@@ -92,7 +92,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
femmesh_obj.FemMesh = new_fem_mesh
|
||||
|
||||
# set mesh obj parameter
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
femmesh_obj.ElementDimension = "1D"
|
||||
femmesh_obj.ElementOrder = "1st"
|
||||
|
||||
@@ -82,7 +82,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
|
||||
# clear mesh and set meshing parameter
|
||||
femmesh_obj.FemMesh = Fem.FemMesh()
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
femmesh_obj.ElementDimension = "3D"
|
||||
femmesh_obj.ElementOrder = "1st"
|
||||
|
||||
@@ -92,7 +92,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
femmesh_obj.FemMesh = new_fem_mesh
|
||||
|
||||
# set mesh obj parameter
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
femmesh_obj.ElementDimension = "2D"
|
||||
femmesh_obj.ElementOrder = "1st"
|
||||
|
||||
@@ -191,7 +191,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
femmesh_obj.CharacteristicLengthMax = "5.0 mm"
|
||||
|
||||
|
||||
@@ -210,7 +210,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
|
||||
doc.recompute()
|
||||
|
||||
@@ -197,7 +197,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
|
||||
doc.recompute()
|
||||
|
||||
@@ -272,7 +272,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
|
||||
doc.recompute()
|
||||
|
||||
@@ -140,7 +140,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
|
||||
doc.recompute()
|
||||
|
||||
@@ -169,7 +169,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
|
||||
doc.recompute()
|
||||
|
||||
@@ -184,7 +184,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
femmesh_obj.CharacteristicLengthMax = "7 mm"
|
||||
|
||||
|
||||
@@ -173,7 +173,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
|
||||
doc.recompute()
|
||||
|
||||
@@ -137,7 +137,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
femmesh_obj.CharacteristicLengthMax = "40.80 mm"
|
||||
|
||||
|
||||
@@ -192,7 +192,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
|
||||
# mesh
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.Part = body
|
||||
femmesh_obj.Shape = body
|
||||
femmesh_obj.CharacteristicLengthMax = "1.25 mm"
|
||||
femmesh_obj.ElementOrder = "1st"
|
||||
femmesh_obj.ViewObject.Visibility = False
|
||||
|
||||
@@ -165,7 +165,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
|
||||
# mesh
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
femmesh_obj.CharacteristicLengthMax = "600 mm"
|
||||
femmesh_obj.ViewObject.Visibility = False
|
||||
|
||||
@@ -228,7 +228,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
|
||||
# mesh
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
femmesh_obj.CharacteristicLengthMax = "500 mm"
|
||||
femmesh_obj.ViewObject.Visibility = False
|
||||
|
||||
@@ -252,7 +252,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
|
||||
# mesh
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.Part = BooleanFragments
|
||||
femmesh_obj.Shape = BooleanFragments
|
||||
femmesh_obj.ElementOrder = "1st"
|
||||
femmesh_obj.CharacteristicLengthMax = "4 mm"
|
||||
femmesh_obj.ViewObject.Visibility = False
|
||||
|
||||
@@ -260,7 +260,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
|
||||
# mesh
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.Part = BooleanFragments
|
||||
femmesh_obj.Shape = BooleanFragments
|
||||
femmesh_obj.ElementOrder = "1st"
|
||||
femmesh_obj.CharacteristicLengthMax = "4 mm"
|
||||
femmesh_obj.ViewObject.Visibility = False
|
||||
|
||||
@@ -258,7 +258,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
|
||||
# mesh
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.Part = BooleanFragments
|
||||
femmesh_obj.Shape = BooleanFragments
|
||||
femmesh_obj.ElementOrder = "1st"
|
||||
femmesh_obj.CharacteristicLengthMax = "4 mm"
|
||||
femmesh_obj.ViewObject.Visibility = False
|
||||
|
||||
@@ -153,7 +153,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
|
||||
# mesh
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.Part = cube
|
||||
femmesh_obj.Shape = cube
|
||||
femmesh_obj.CharacteristicLengthMax = "1 mm"
|
||||
femmesh_obj.ViewObject.Visibility = False
|
||||
|
||||
|
||||
@@ -258,7 +258,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
|
||||
# mesh
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.Part = BooleanFragments
|
||||
femmesh_obj.Shape = BooleanFragments
|
||||
femmesh_obj.CharacteristicLengthMax = "3 mm"
|
||||
femmesh_obj.ViewObject.Visibility = False
|
||||
|
||||
|
||||
@@ -201,7 +201,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
|
||||
# mesh
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.Part = BooleanFragments
|
||||
femmesh_obj.Shape = BooleanFragments
|
||||
femmesh_obj.ElementOrder = "1st"
|
||||
femmesh_obj.CharacteristicLengthMax = "0.5 mm"
|
||||
femmesh_obj.ViewObject.Visibility = False
|
||||
|
||||
@@ -260,7 +260,7 @@ def setup(doc=None, solvertype="elmer"):
|
||||
|
||||
# mesh
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.Part = BooleanFragments
|
||||
femmesh_obj.Shape = BooleanFragments
|
||||
femmesh_obj.CharacteristicLengthMax = "100.0 mm"
|
||||
femmesh_obj.ViewObject.Visibility = False
|
||||
|
||||
|
||||
@@ -150,7 +150,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
femmesh_obj.CharacteristicLengthMax = "25.0 mm"
|
||||
|
||||
|
||||
@@ -201,7 +201,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
|
||||
doc.recompute()
|
||||
|
||||
@@ -194,7 +194,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
|
||||
doc.recompute()
|
||||
|
||||
@@ -170,7 +170,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
|
||||
doc.recompute()
|
||||
|
||||
@@ -178,7 +178,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
|
||||
doc.recompute()
|
||||
|
||||
@@ -188,7 +188,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
femmesh_obj.CharacteristicLengthMax = "1.0 mm"
|
||||
femmesh_obj.ElementDimension = "2D"
|
||||
|
||||
@@ -176,7 +176,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
|
||||
doc.recompute()
|
||||
|
||||
@@ -178,7 +178,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
|
||||
doc.recompute()
|
||||
|
||||
@@ -448,7 +448,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
|
||||
doc.recompute()
|
||||
|
||||
@@ -215,7 +215,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
|
||||
doc.recompute()
|
||||
|
||||
@@ -461,7 +461,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.Shape = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
femmesh_obj.ElementDimension = "1D"
|
||||
# four elements for each bar
|
||||
|
||||
@@ -57,7 +57,7 @@ class GmshTools:
|
||||
self.analysis = None
|
||||
|
||||
# part to mesh
|
||||
self.part_obj = self.mesh_obj.Part
|
||||
self.part_obj = self.mesh_obj.Shape
|
||||
|
||||
# clmax, CharacteristicLengthMax: float, 0.0 = 1e+22
|
||||
self.clmax = Units.Quantity(self.mesh_obj.CharacteristicLengthMax).Value
|
||||
@@ -101,6 +101,8 @@ class GmshTools:
|
||||
self.algorithm2D = "8"
|
||||
elif algo2D == "Packing Parallelograms":
|
||||
self.algorithm2D = "9"
|
||||
elif algo2D == "Quasi-structured Quad":
|
||||
self.algorithm2D = "11"
|
||||
else:
|
||||
self.algorithm2D = "2"
|
||||
|
||||
@@ -839,7 +841,7 @@ class GmshTools:
|
||||
)
|
||||
geo.write(
|
||||
"// 2D mesh algorithm (1=MeshAdapt, 2=Automatic, "
|
||||
"5=Delaunay, 6=Frontal, 7=BAMG, 8=DelQuad, 9=Packing Parallelograms)\n"
|
||||
"5=Delaunay, 6=Frontal, 7=BAMG, 8=DelQuad, 9=Packing Parallelograms, 11=Quasi-structured Quad)\n"
|
||||
)
|
||||
if len(self.bl_setting_list) and self.dimension == 3:
|
||||
geo.write("Mesh.Algorithm = " + "DelQuad" + ";\n") # Frontal/DelQuad are tested
|
||||
@@ -982,7 +984,7 @@ doc.recompute()
|
||||
box_obj.ViewObject.Visibility = False
|
||||
|
||||
femmesh_obj = ObjectsFem.makeMeshGmsh(doc, box_obj.Name + "_Mesh")
|
||||
femmesh_obj.Part = box_obj
|
||||
femmesh_obj.Shape = box_obj
|
||||
doc.recompute()
|
||||
|
||||
from femmesh.gmshtools import GmshTools as gt
|
||||
@@ -1009,7 +1011,7 @@ for len in max_mesh_sizes:
|
||||
quantity_len = "{}".format(len)
|
||||
print("\n\n Start length = {}".format(quantity_len))
|
||||
femmesh_obj = ObjectsFem.makeMeshGmsh(doc, box_obj.Name + "_Mesh")
|
||||
femmesh_obj.Part = box_obj
|
||||
femmesh_obj.Shape = box_obj
|
||||
femmesh_obj.CharacteristicLengthMax = "{}".format(quantity_len)
|
||||
femmesh_obj.CharacteristicLengthMin = "{}".format(quantity_len)
|
||||
doc.recompute()
|
||||
|
||||
@@ -64,8 +64,6 @@ class MeshSetsGetter:
|
||||
if self.mesh_object:
|
||||
if hasattr(self.mesh_object, "Shape"):
|
||||
self.theshape = self.mesh_object.Shape
|
||||
elif hasattr(self.mesh_object, "Part"):
|
||||
self.theshape = self.mesh_object.Part
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
"A finite mesh without a link to a Shape was given. "
|
||||
|
||||
@@ -31,6 +31,8 @@ __url__ = "https://www.freecad.org"
|
||||
|
||||
from . import base_fempythonobject
|
||||
|
||||
_PropHelper = base_fempythonobject._PropHelper
|
||||
|
||||
|
||||
class MeshGmsh(base_fempythonobject.BaseFemPythonObject):
|
||||
"""
|
||||
@@ -40,295 +42,271 @@ class MeshGmsh(base_fempythonobject.BaseFemPythonObject):
|
||||
Type = "Fem::FemMeshGmsh"
|
||||
|
||||
# they will be used from the task panel too, thus they need to be outside of the __init__
|
||||
known_element_dimensions = ["From Shape", "1D", "2D", "3D"]
|
||||
known_element_orders = ["1st", "2nd"]
|
||||
known_mesh_algorithm_2D = [
|
||||
"Automatic",
|
||||
"MeshAdapt",
|
||||
"Delaunay",
|
||||
"Frontal",
|
||||
"BAMG",
|
||||
"DelQuad",
|
||||
"Packing Parallelograms",
|
||||
]
|
||||
known_mesh_algorithm_3D = [
|
||||
"Automatic",
|
||||
"Delaunay",
|
||||
"New Delaunay",
|
||||
"Frontal",
|
||||
"MMG3D",
|
||||
"R-tree",
|
||||
"HXT",
|
||||
]
|
||||
known_mesh_RecombinationAlgorithms = [
|
||||
"Simple",
|
||||
"Blossom",
|
||||
"Simple full-quad",
|
||||
"Blossom full-quad",
|
||||
]
|
||||
known_mesh_HighOrderOptimizers = [
|
||||
"None",
|
||||
"Optimization",
|
||||
"Elastic+Optimization",
|
||||
"Elastic",
|
||||
"Fast curving",
|
||||
]
|
||||
known_mesh_SubdivisionAlgorithms = ["None", "All Quadrangles", "All Hexahedra", "Barycentric"]
|
||||
|
||||
def __init__(self, obj):
|
||||
super().__init__(obj)
|
||||
self.add_properties(obj)
|
||||
|
||||
for prop in self._get_properties():
|
||||
prop.add_to_object(obj)
|
||||
|
||||
def _get_properties(self):
|
||||
prop = []
|
||||
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyLinkList",
|
||||
name="MeshBoundaryLayerList",
|
||||
group="Base",
|
||||
doc="Mesh boundaries need inflation layers",
|
||||
value=[],
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyLinkList",
|
||||
name="MeshRegionList",
|
||||
group="Base",
|
||||
doc="Mesh refinments of the mesh",
|
||||
value=[],
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyLinkList",
|
||||
name="MeshGroupList",
|
||||
group="Base",
|
||||
doc="Mesh groups of the mesh",
|
||||
value=[],
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyLength",
|
||||
name="CharacteristicLengthMax",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Max mesh element size (0.0 means infinity)",
|
||||
value=0.0, # will be 1e+22
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyLength",
|
||||
name="CharacteristicLengthMin",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Min mesh element size",
|
||||
value=0.0,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyEnumeration",
|
||||
name="ElementDimension",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Dimension of mesh elements ('From Shape': according ShapeType of part to mesh)",
|
||||
value=["From Shape", "1D", "2D", "3D"],
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyEnumeration",
|
||||
name="ElementOrder",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Order of mesh elements",
|
||||
value=["1st", "2nd"],
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyBool",
|
||||
name="OptimizeStd",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Optimize tetrahedral elements",
|
||||
value=True,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyBool",
|
||||
name="OptimizeNetgen",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Optimize tetra elements by use of Netgen",
|
||||
value=False,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyEnumeration",
|
||||
name="HighOrderOptimize",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Optimization of high order meshes",
|
||||
value=[
|
||||
"None",
|
||||
"Optimization",
|
||||
"Elastic+Optimization",
|
||||
"Elastic",
|
||||
"Fast curving",
|
||||
],
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyBool",
|
||||
name="RecombineAll",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Apply recombination algorithm to all surfaces",
|
||||
value=False,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyBool",
|
||||
name="Recombine3DAll",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Apply recombination algorithm to all volumes",
|
||||
value=False,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyEnumeration",
|
||||
name="RecombinationAlgorithm",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Recombination algorithm",
|
||||
value=[
|
||||
"Simple",
|
||||
"Blossom",
|
||||
"Simple full-quad",
|
||||
"Blossom full-quad",
|
||||
],
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyBool",
|
||||
name="CoherenceMesh",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Removes all duplicate mesh vertices",
|
||||
value=True,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyFloat",
|
||||
name="GeometryTolerance",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Geometrical Tolerance (0.0 means GMSH std = 1e-08)",
|
||||
value=1e-06,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyBool",
|
||||
name="SecondOrderLinear",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Second order nodes are created by linear interpolation",
|
||||
value=False,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyIntegerConstraint",
|
||||
name="MeshSizeFromCurvature",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Number of elements per 2*pi radians, 0 to deactivate",
|
||||
value=(12, 0, 10000, 1),
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyEnumeration",
|
||||
name="Algorithm2D",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Mesh algorithm 2D",
|
||||
value=[
|
||||
"Automatic",
|
||||
"MeshAdapt",
|
||||
"Delaunay",
|
||||
"Frontal",
|
||||
"BAMG",
|
||||
"DelQuad",
|
||||
"Packing Parallelograms",
|
||||
"Quasi-structured Quad",
|
||||
],
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyEnumeration",
|
||||
name="Algorithm3D",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Mesh algorithm 3D",
|
||||
value=[
|
||||
"Automatic",
|
||||
"Delaunay",
|
||||
"New Delaunay",
|
||||
"Frontal",
|
||||
"MMG3D",
|
||||
"R-tree",
|
||||
"HXT",
|
||||
],
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyBool",
|
||||
name="GroupsOfNodes",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="For each group create not only the elements but the nodes too",
|
||||
value=False,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyEnumeration",
|
||||
name="SubdivisionAlgorithm",
|
||||
group="FEM Gmsh Mesh Params",
|
||||
doc="Mesh subdivision algorithm",
|
||||
value=["None", "All Quadrangles", "All Hexahedra", "Barycentric"],
|
||||
)
|
||||
)
|
||||
|
||||
return prop
|
||||
|
||||
def onDocumentRestored(self, obj):
|
||||
# update old project with new properties
|
||||
for prop in self._get_properties():
|
||||
try:
|
||||
obj.getPropertyByName(prop.name)
|
||||
if prop.name == "Algorithm2D":
|
||||
# refresh the list of known 2D algorithms
|
||||
obj.Algorithm2D = prop.value
|
||||
elif prop.name == "Algorithm3D":
|
||||
# refresh the list of known 3D algorithms
|
||||
obj.Algorithm3D = prop.value
|
||||
elif prop.name == "HighOrderOptimize":
|
||||
# HighOrderOptimize was once App::PropertyBool, so check this
|
||||
if type(obj.HighOrderOptimize) is bool:
|
||||
value = obj.HighOrderOptimize
|
||||
obj.setPropertyStatus("HighOrderOptimize", "-LockDynamic")
|
||||
obj.removeProperty("HighOrderOptimize")
|
||||
prop.add_to_object(obj)
|
||||
obj.HighOrderOptimize = "Optimization" if value else "None"
|
||||
except:
|
||||
prop.add_to_object(obj)
|
||||
|
||||
# HighOrderOptimize
|
||||
# was once App::PropertyBool, so check this
|
||||
high_order_optimizer = ""
|
||||
if obj.HighOrderOptimize is True:
|
||||
high_order_optimizer = "Optimization"
|
||||
elif obj.HighOrderOptimize is False:
|
||||
high_order_optimizer = "None"
|
||||
obj.removeProperty("HighOrderOptimize")
|
||||
# add new HighOrderOptimize property
|
||||
self.add_properties(obj)
|
||||
# write the stored high_order_optimizer
|
||||
if high_order_optimizer:
|
||||
obj.HighOrderOptimize = high_order_optimizer
|
||||
|
||||
# Algorithm3D
|
||||
# refresh the list of known 3D algorithms for existing meshes
|
||||
# since some algos are meanwhile deprecated and new algos are available
|
||||
obj.Algorithm3D = MeshGmsh.known_mesh_algorithm_3D
|
||||
|
||||
def add_properties(self, obj):
|
||||
|
||||
# this method is called from onDocumentRestored
|
||||
# thus only add and or set a attribute
|
||||
# if the attribute does not exist
|
||||
|
||||
if not hasattr(obj, "MeshBoundaryLayerList"):
|
||||
obj.addProperty(
|
||||
"App::PropertyLinkList",
|
||||
"MeshBoundaryLayerList",
|
||||
"Base",
|
||||
"Mesh boundaries need inflation layers",
|
||||
# migrate old Part property to Shape property
|
||||
try:
|
||||
value_part = obj.getPropertyByName("Part")
|
||||
obj.setPropertyStatus("Part", "-LockDynamic")
|
||||
obj.removeProperty("Part")
|
||||
# old object is Fem::FemMeshObjectPython (does not have Shape property with global scope)
|
||||
prop = _PropHelper(
|
||||
type="App::PropertyLinkGlobal",
|
||||
name="Shape",
|
||||
group="FEM Mesh",
|
||||
doc="Geometry object, the mesh is made from. The geometry object has to have a Shape",
|
||||
value=value_part,
|
||||
)
|
||||
obj.setPropertyStatus("MeshBoundaryLayerList", "LockDynamic")
|
||||
obj.MeshBoundaryLayerList = []
|
||||
|
||||
if not hasattr(obj, "MeshRegionList"):
|
||||
obj.addProperty(
|
||||
"App::PropertyLinkList", "MeshRegionList", "Base", "Mesh refinments of the mesh"
|
||||
)
|
||||
obj.setPropertyStatus("MeshRegionList", "LockDynamic")
|
||||
obj.MeshRegionList = []
|
||||
|
||||
if not hasattr(obj, "MeshGroupList"):
|
||||
obj.addProperty(
|
||||
"App::PropertyLinkList", "MeshGroupList", "Base", "Mesh groups of the mesh"
|
||||
)
|
||||
obj.setPropertyStatus("MeshGroupList", "LockDynamic")
|
||||
obj.MeshGroupList = []
|
||||
|
||||
if not hasattr(obj, "Part"):
|
||||
obj.addProperty(
|
||||
"App::PropertyLink",
|
||||
"Part",
|
||||
"FEM Mesh",
|
||||
"Geometry object, the mesh is made from. The geometry object has to have a Shape.",
|
||||
)
|
||||
obj.setPropertyStatus("Part", "LockDynamic")
|
||||
obj.Part = None
|
||||
|
||||
if not hasattr(obj, "CharacteristicLengthMax"):
|
||||
obj.addProperty(
|
||||
"App::PropertyLength",
|
||||
"CharacteristicLengthMax",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"Max mesh element size (0.0 = infinity)",
|
||||
)
|
||||
obj.setPropertyStatus("CharacteristicLengthMax", "LockDynamic")
|
||||
obj.CharacteristicLengthMax = 0.0 # will be 1e+22
|
||||
|
||||
if not hasattr(obj, "CharacteristicLengthMin"):
|
||||
obj.addProperty(
|
||||
"App::PropertyLength",
|
||||
"CharacteristicLengthMin",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"Min mesh element size",
|
||||
)
|
||||
obj.setPropertyStatus("CharacteristicLengthMin", "LockDynamic")
|
||||
obj.CharacteristicLengthMin = 0.0
|
||||
|
||||
if not hasattr(obj, "ElementDimension"):
|
||||
obj.addProperty(
|
||||
"App::PropertyEnumeration",
|
||||
"ElementDimension",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"Dimension of mesh elements (Auto = according ShapeType of part to mesh)",
|
||||
)
|
||||
obj.setPropertyStatus("ElementDimension", "LockDynamic")
|
||||
obj.ElementDimension = MeshGmsh.known_element_dimensions
|
||||
obj.ElementDimension = "From Shape" # according ShapeType of Part to mesh
|
||||
|
||||
if not hasattr(obj, "ElementOrder"):
|
||||
obj.addProperty(
|
||||
"App::PropertyEnumeration",
|
||||
"ElementOrder",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"Order of mesh elements",
|
||||
)
|
||||
obj.setPropertyStatus("ElementOrder", "LockDynamic")
|
||||
obj.ElementOrder = MeshGmsh.known_element_orders
|
||||
obj.ElementOrder = "2nd"
|
||||
|
||||
if not hasattr(obj, "OptimizeStd"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"OptimizeStd",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"Optimize tetrahedral elements",
|
||||
)
|
||||
obj.setPropertyStatus("OptimizeStd", "LockDynamic")
|
||||
obj.OptimizeStd = True
|
||||
|
||||
if not hasattr(obj, "OptimizeNetgen"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"OptimizeNetgen",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"Optimize tetra elements by use of Netgen",
|
||||
)
|
||||
obj.setPropertyStatus("OptimizeNetgen", "LockDynamic")
|
||||
obj.OptimizeNetgen = False
|
||||
|
||||
if not hasattr(obj, "HighOrderOptimize"):
|
||||
obj.addProperty(
|
||||
"App::PropertyEnumeration",
|
||||
"HighOrderOptimize",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"Optimization of high order meshes",
|
||||
)
|
||||
obj.setPropertyStatus("HighOrderOptimize", "LockDynamic")
|
||||
obj.HighOrderOptimize = MeshGmsh.known_mesh_HighOrderOptimizers
|
||||
obj.HighOrderOptimize = "None"
|
||||
|
||||
if not hasattr(obj, "RecombineAll"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"RecombineAll",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"Apply recombination algorithm to all surfaces",
|
||||
)
|
||||
obj.setPropertyStatus("RecombineAll", "LockDynamic")
|
||||
obj.RecombineAll = False
|
||||
|
||||
if not hasattr(obj, "Recombine3DAll"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"Recombine3DAll",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"Apply recombination algorithm to all volumes",
|
||||
)
|
||||
obj.setPropertyStatus("Recombine3DAll", "LockDynamic")
|
||||
obj.Recombine3DAll = False
|
||||
|
||||
if not hasattr(obj, "RecombinationAlgorithm"):
|
||||
obj.addProperty(
|
||||
"App::PropertyEnumeration",
|
||||
"RecombinationAlgorithm",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"Recombination algorithm",
|
||||
)
|
||||
obj.setPropertyStatus("RecombinationAlgorithm", "LockDynamic")
|
||||
obj.RecombinationAlgorithm = MeshGmsh.known_mesh_RecombinationAlgorithms
|
||||
obj.RecombinationAlgorithm = "Simple"
|
||||
|
||||
if not hasattr(obj, "CoherenceMesh"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"CoherenceMesh",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"Removes all duplicate mesh vertices",
|
||||
)
|
||||
obj.setPropertyStatus("CoherenceMesh", "LockDynamic")
|
||||
obj.CoherenceMesh = True
|
||||
|
||||
if not hasattr(obj, "GeometryTolerance"):
|
||||
obj.addProperty(
|
||||
"App::PropertyFloat",
|
||||
"GeometryTolerance",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"Geometrical Tolerance (0.0 = GMSH std = 1e-08)",
|
||||
)
|
||||
obj.setPropertyStatus("GeometryTolerance", "LockDynamic")
|
||||
obj.GeometryTolerance = 1e-06
|
||||
|
||||
if not hasattr(obj, "SecondOrderLinear"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"SecondOrderLinear",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"Second order nodes are created by linear interpolation",
|
||||
)
|
||||
obj.setPropertyStatus("SecondOrderLinear", "LockDynamic")
|
||||
obj.SecondOrderLinear = False
|
||||
# gives much better meshes in the regard of nonpositive jacobians
|
||||
# but
|
||||
# on curved faces the constraint nodes will no longer found
|
||||
# thus standard will be False
|
||||
# https://forum.freecad.org/viewtopic.php?t=41738
|
||||
# https://forum.freecad.org/viewtopic.php?f=18&t=45260&start=20#p389494
|
||||
|
||||
if not hasattr(obj, "MeshSizeFromCurvature"):
|
||||
obj.addProperty(
|
||||
"App::PropertyIntegerConstraint",
|
||||
"MeshSizeFromCurvature",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"number of elements per 2*pi radians, 0 to deactivate",
|
||||
)
|
||||
obj.setPropertyStatus("MeshSizeFromCurvature", "LockDynamic")
|
||||
obj.MeshSizeFromCurvature = (12, 0, 10000, 1)
|
||||
|
||||
if not hasattr(obj, "Algorithm2D"):
|
||||
obj.addProperty(
|
||||
"App::PropertyEnumeration",
|
||||
"Algorithm2D",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"mesh algorithm 2D",
|
||||
)
|
||||
obj.setPropertyStatus("Algorithm2D", "LockDynamic")
|
||||
obj.Algorithm2D = MeshGmsh.known_mesh_algorithm_2D
|
||||
obj.Algorithm2D = "Automatic"
|
||||
|
||||
if not hasattr(obj, "Algorithm3D"):
|
||||
obj.addProperty(
|
||||
"App::PropertyEnumeration",
|
||||
"Algorithm3D",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"mesh algorithm 3D",
|
||||
)
|
||||
obj.setPropertyStatus("Algorithm3D", "LockDynamic")
|
||||
obj.Algorithm3D = MeshGmsh.known_mesh_algorithm_3D
|
||||
obj.Algorithm3D = "Automatic"
|
||||
|
||||
if not hasattr(obj, "GroupsOfNodes"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"GroupsOfNodes",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"For each group create not only the elements but the nodes too.",
|
||||
)
|
||||
obj.setPropertyStatus("GroupsOfNodes", "LockDynamic")
|
||||
obj.GroupsOfNodes = False
|
||||
|
||||
if not hasattr(obj, "SubdivisionAlgorithm"):
|
||||
obj.addProperty(
|
||||
"App::PropertyEnumeration",
|
||||
"SubdivisionAlgorithm",
|
||||
"FEM Gmsh Mesh Params",
|
||||
"Mesh subdivision algorithm",
|
||||
)
|
||||
obj.setPropertyStatus("SubdivisionAlgorithm", "LockDynamic")
|
||||
obj.SubdivisionAlgorithm = MeshGmsh.known_mesh_SubdivisionAlgorithms
|
||||
obj.SubdivisionAlgorithm = "None"
|
||||
prop.add_to_object(obj)
|
||||
except:
|
||||
pass
|
||||
|
||||
@@ -85,7 +85,7 @@ class _TaskPanel:
|
||||
self.form = [self.refWidget, propWidget]
|
||||
analysis = obj.getParentGroup()
|
||||
self._mesh = membertools.get_single_member(analysis, "Fem::FemMeshObject")
|
||||
self._part = self._mesh.Part if self._mesh is not None else None
|
||||
self._part = self._mesh.Shape if self._mesh is not None else None
|
||||
self._partVisible = None
|
||||
self._meshVisible = None
|
||||
|
||||
|
||||
@@ -758,24 +758,24 @@ class Writer:
|
||||
obj = self.getSingleMember("Fem::FemMeshObject")
|
||||
bodyCount = 0
|
||||
prefix = ""
|
||||
if obj.Part.Shape.Solids:
|
||||
if obj.Shape.Shape.Solids:
|
||||
prefix = "Solid"
|
||||
bodyCount = len(obj.Part.Shape.Solids)
|
||||
elif obj.Part.Shape.Faces:
|
||||
bodyCount = len(obj.Shape.Shape.Solids)
|
||||
elif obj.Shape.Shape.Faces:
|
||||
prefix = "Face"
|
||||
bodyCount = len(obj.Part.Shape.Faces)
|
||||
elif obj.Part.Shape.Edges:
|
||||
bodyCount = len(obj.Shape.Shape.Faces)
|
||||
elif obj.Shape.Shape.Edges:
|
||||
prefix = "Edge"
|
||||
bodyCount = len(obj.Part.Shape.Edges)
|
||||
bodyCount = len(obj.Shape.Shape.Edges)
|
||||
return [prefix + str(i + 1) for i in range(bodyCount)]
|
||||
|
||||
def getMeshDimension(self):
|
||||
obj = self.getSingleMember("Fem::FemMeshObject")
|
||||
if obj.Part.Shape.Solids:
|
||||
if obj.Shape.Shape.Solids:
|
||||
return 3
|
||||
if obj.Part.Shape.Faces:
|
||||
if obj.Shape.Shape.Faces:
|
||||
return 2
|
||||
if obj.Part.Shape.Edges:
|
||||
if obj.Shape.Shape.Edges:
|
||||
return 1
|
||||
return None
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@ import FreeCADGui
|
||||
|
||||
from femguiutils import selection_widgets
|
||||
|
||||
from femtools import femutils
|
||||
from femtools import membertools
|
||||
|
||||
|
||||
@@ -84,7 +83,7 @@ class _TaskPanel:
|
||||
if analysis is not None:
|
||||
self._mesh = membertools.get_single_member(analysis, "Fem::FemMeshObject")
|
||||
if self._mesh is not None:
|
||||
self._part = femutils.get_part_to_mesh(self._mesh)
|
||||
self._part = self._mesh.Shape
|
||||
self._partVisible = None
|
||||
self._meshVisible = None
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@ import FreeCADGui
|
||||
|
||||
from femguiutils import selection_widgets
|
||||
|
||||
from femtools import femutils
|
||||
from femtools import membertools
|
||||
|
||||
|
||||
@@ -63,7 +62,7 @@ class _TaskPanel:
|
||||
if analysis is not None:
|
||||
self._mesh = membertools.get_single_member(analysis, "Fem::FemMeshObject")
|
||||
if self._mesh is not None:
|
||||
self._part = femutils.get_part_to_mesh(self._mesh)
|
||||
self._part = self._mesh.Shape
|
||||
self._partVisible = None
|
||||
self._meshVisible = None
|
||||
|
||||
|
||||
@@ -37,7 +37,6 @@ import FreeCAD
|
||||
import FreeCADGui
|
||||
from femguiutils import selection_widgets
|
||||
|
||||
from femtools import femutils
|
||||
from femtools import membertools
|
||||
|
||||
|
||||
@@ -66,7 +65,7 @@ class _TaskPanel:
|
||||
if analysis is not None:
|
||||
self._mesh = membertools.get_single_member(analysis, "Fem::FemMeshObject")
|
||||
if self._mesh is not None:
|
||||
self._part = femutils.get_part_to_mesh(self._mesh)
|
||||
self._part = self._mesh.Shape
|
||||
self._partVisible = None
|
||||
self._meshVisible = None
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@ import FreeCAD
|
||||
import FreeCADGui
|
||||
|
||||
from femguiutils import selection_widgets
|
||||
from femtools import femutils
|
||||
from femtools import membertools
|
||||
|
||||
|
||||
@@ -64,7 +63,7 @@ class _TaskPanel:
|
||||
if analysis is not None:
|
||||
self._mesh = membertools.get_single_member(analysis, "Fem::FemMeshObject")
|
||||
if self._mesh is not None:
|
||||
self._part = femutils.get_part_to_mesh(self._mesh)
|
||||
self._part = self._mesh.Shape
|
||||
self._partVisible = None
|
||||
self._meshVisible = None
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@ import FreeCAD
|
||||
import FreeCADGui
|
||||
|
||||
from femguiutils import selection_widgets
|
||||
from femtools import femutils
|
||||
from femtools import membertools
|
||||
|
||||
|
||||
@@ -64,7 +63,7 @@ class _TaskPanel:
|
||||
if analysis is not None:
|
||||
self._mesh = membertools.get_single_member(analysis, "Fem::FemMeshObject")
|
||||
if self._mesh is not None:
|
||||
self._part = femutils.get_part_to_mesh(self._mesh)
|
||||
self._part = self._mesh.Shape
|
||||
self._partVisible = None
|
||||
self._meshVisible = None
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@ import FreeCAD
|
||||
import FreeCADGui
|
||||
from femguiutils import selection_widgets
|
||||
|
||||
from femtools import femutils
|
||||
from femtools import membertools
|
||||
|
||||
|
||||
@@ -62,7 +61,7 @@ class _TaskPanel:
|
||||
if analysis is not None:
|
||||
self._mesh = membertools.get_single_member(analysis, "Fem::FemMeshObject")
|
||||
if self._mesh is not None:
|
||||
self._part = femutils.get_part_to_mesh(self._mesh)
|
||||
self._part = self._mesh.Shape
|
||||
self._partVisible = None
|
||||
self._meshVisible = None
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@ import FreeCADGui
|
||||
|
||||
from femguiutils import selection_widgets
|
||||
|
||||
from femtools import femutils
|
||||
from femtools import membertools
|
||||
|
||||
|
||||
@@ -63,7 +62,7 @@ class _TaskPanel:
|
||||
if analysis is not None:
|
||||
self._mesh = membertools.get_single_member(analysis, "Fem::FemMeshObject")
|
||||
if self._mesh is not None:
|
||||
self._part = femutils.get_part_to_mesh(self._mesh)
|
||||
self._part = self._mesh.Shape
|
||||
self._partVisible = None
|
||||
self._meshVisible = None
|
||||
|
||||
|
||||
@@ -41,7 +41,6 @@ import FreeCAD
|
||||
import FreeCADGui
|
||||
|
||||
import FemGui
|
||||
from femobjects import mesh_gmsh
|
||||
from femtools.femutils import is_of_type
|
||||
from femtools.femutils import getOutputWinColor
|
||||
|
||||
@@ -80,9 +79,9 @@ class _TaskPanel:
|
||||
self.form.pb_get_gmsh_version, QtCore.SIGNAL("clicked()"), self.get_gmsh_version
|
||||
)
|
||||
|
||||
self.form.cb_dimension.addItems(mesh_gmsh.MeshGmsh.known_element_dimensions)
|
||||
self.form.cb_dimension.addItems(self.mesh_obj.getEnumerationsOfProperty("ElementDimension"))
|
||||
|
||||
self.form.cb_order.addItems(mesh_gmsh.MeshGmsh.known_element_orders)
|
||||
self.form.cb_order.addItems(self.mesh_obj.getEnumerationsOfProperty("ElementOrder"))
|
||||
|
||||
self.get_mesh_params()
|
||||
self.get_active_analysis()
|
||||
@@ -195,7 +194,7 @@ class _TaskPanel:
|
||||
|
||||
gmsh_mesh = gmshtools.GmshTools(self.mesh_obj, self.analysis)
|
||||
QApplication.setOverrideCursor(Qt.WaitCursor)
|
||||
part = self.mesh_obj.Part
|
||||
part = self.mesh_obj.Shape
|
||||
if (
|
||||
self.mesh_obj.MeshRegionList
|
||||
and part.Shape.ShapeType == "Compound"
|
||||
|
||||
@@ -125,6 +125,7 @@ class TestObjectExistance(unittest.TestCase):
|
||||
"Fem::FemAnalysisPython",
|
||||
"Fem::FemMeshObject",
|
||||
"Fem::FemMeshObjectPython",
|
||||
"Fem::FemMeshShapeBaseObjectPython",
|
||||
"Fem::FemMeshShapeNetgenObject",
|
||||
"Fem::FemMeshShapeObject",
|
||||
"Fem::FemResultObject",
|
||||
|
||||
@@ -721,7 +721,7 @@ class TestObjectType(unittest.TestCase):
|
||||
# FemMeshGmsh
|
||||
mesh_gmsh = ObjectsFem.makeMeshGmsh(doc)
|
||||
self.assertTrue(is_derived_from(mesh_gmsh, "App::DocumentObject"))
|
||||
self.assertTrue(is_derived_from(mesh_gmsh, "Fem::FemMeshObjectPython"))
|
||||
self.assertTrue(is_derived_from(mesh_gmsh, "Fem::FemMeshShapeBaseObjectPython"))
|
||||
self.assertTrue(is_derived_from(mesh_gmsh, "Fem::FemMeshGmsh"))
|
||||
|
||||
# MeshBoundaryLayer
|
||||
@@ -965,7 +965,7 @@ class TestObjectType(unittest.TestCase):
|
||||
ObjectsFem.makeMaterialReinforced(doc).isDerivedFrom("App::MaterialObjectPython")
|
||||
)
|
||||
mesh = ObjectsFem.makeMeshGmsh(doc)
|
||||
self.assertTrue(mesh.isDerivedFrom("Fem::FemMeshObjectPython"))
|
||||
self.assertTrue(mesh.isDerivedFrom("Fem::FemMeshShapeBaseObjectPython"))
|
||||
self.assertTrue(
|
||||
ObjectsFem.makeMeshBoundaryLayer(doc, mesh).isDerivedFrom("Fem::FeaturePython")
|
||||
)
|
||||
|
||||
@@ -244,23 +244,6 @@ def make_dir(specific_path):
|
||||
|
||||
# ************************************************************************************************
|
||||
# other
|
||||
def get_part_to_mesh(mesh_obj):
|
||||
"""
|
||||
gmsh mesh object: the Attribute is Part
|
||||
netgen mesh object: the Attribute is Shape
|
||||
other mesh objects: do not have a Attribute which holds the part to mesh
|
||||
"""
|
||||
if is_derived_from(mesh_obj, "Fem::FemMeshGmsh"):
|
||||
return mesh_obj.Part
|
||||
elif is_derived_from(mesh_obj, "Fem::FemMeshShapeNetgenObject"):
|
||||
return mesh_obj.Shape
|
||||
else:
|
||||
return None
|
||||
# TODO: the Attributes should be named with the same name
|
||||
# should it be Shape or Part?
|
||||
# IMHO Part since the Attributes references the document object and not a Shape
|
||||
|
||||
|
||||
def getBoundBoxOfAllDocumentShapes(doc):
|
||||
"""Calculate bounding box containing all objects inside *doc*.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user