Fem: Add smoothing filter extension to contours filter (#18088)

* Fem: Add smoothing filter extension to contours filter
This commit is contained in:
marioalexis84
2024-12-16 13:40:02 -03:00
committed by GitHub
parent 0d4e7ac27f
commit 072ecb2a4f
6 changed files with 221 additions and 17 deletions

View File

@@ -181,6 +181,8 @@ PyMOD_INIT_FUNC(Fem)
Fem::FemSolverObjectPython ::init();
#ifdef FC_USE_VTK
Fem::FemPostSmoothFilterExtension ::init();
Fem::FemPostObject ::init();
Fem::FemPostPipeline ::init();
Fem::FemPostFilter ::init();

View File

@@ -515,6 +515,104 @@ DocumentObjectExecReturn* FemPostClipFilter::execute()
return Fem::FemPostFilter::execute();
}
// ***************************************************************************
// smoothing filter extension
const App::PropertyQuantityConstraint::Constraints FemPostSmoothFilterExtension::angleRange = {
0.0,
180.0,
1.0};
const App::PropertyIntegerConstraint::Constraints FemPostSmoothFilterExtension::iterationRange = {
0,
VTK_INT_MAX,
1};
const App::PropertyFloatConstraint::Constraints FemPostSmoothFilterExtension::relaxationRange = {
0,
1.0,
0.01};
EXTENSION_PROPERTY_SOURCE(Fem::FemPostSmoothFilterExtension, App::DocumentObjectExtension)
FemPostSmoothFilterExtension::FemPostSmoothFilterExtension()
{
EXTENSION_ADD_PROPERTY_TYPE(BoundarySmoothing,
(true),
"Smoothing",
App::Prop_None,
"Smooth vertices on the boundary");
EXTENSION_ADD_PROPERTY_TYPE(EdgeAngle,
(15),
"Smoothing",
App::Prop_None,
"Angle to control smoothing along edges");
EXTENSION_ADD_PROPERTY_TYPE(EnableSmoothing,
(false),
"Smoothing",
App::Prop_None,
"Enable Laplacian smoothing");
EXTENSION_ADD_PROPERTY_TYPE(FeatureAngle,
(45),
"Smoothing",
App::Prop_None,
"Angle for sharp edge identification");
EXTENSION_ADD_PROPERTY_TYPE(EdgeSmoothing,
(false),
"Smoothing",
App::Prop_None,
"Smooth align sharp interior edges");
EXTENSION_ADD_PROPERTY_TYPE(RelaxationFactor,
(0.05),
"Smoothing",
App::Prop_None,
"Factor to control vertex displacement");
EXTENSION_ADD_PROPERTY_TYPE(Iterations,
(20),
"Smoothing",
App::Prop_None,
"Number of smoothing iterations");
EdgeAngle.setConstraints(&angleRange);
FeatureAngle.setConstraints(&angleRange);
Iterations.setConstraints(&iterationRange);
RelaxationFactor.setConstraints(&relaxationRange);
m_smooth = vtkSmartPointer<vtkSmoothPolyDataFilter>::New();
// override default VTK values
m_smooth->SetNumberOfIterations(EnableSmoothing.getValue() ? Iterations.getValue() : 0);
m_smooth->SetBoundarySmoothing(BoundarySmoothing.getValue());
m_smooth->SetEdgeAngle(EdgeAngle.getValue());
m_smooth->SetFeatureAngle(FeatureAngle.getValue());
m_smooth->SetFeatureEdgeSmoothing(EdgeSmoothing.getValue());
m_smooth->SetRelaxationFactor(RelaxationFactor.getValue());
initExtensionType(FemPostSmoothFilterExtension::getExtensionClassTypeId());
}
void FemPostSmoothFilterExtension::extensionOnChanged(const App::Property* prop)
{
if (prop == &EnableSmoothing || prop == &Iterations) {
// if disabled, set iterations to zero to do nothing
m_smooth->SetNumberOfIterations(EnableSmoothing.getValue() ? Iterations.getValue() : 0);
}
else if (prop == &BoundarySmoothing) {
m_smooth->SetBoundarySmoothing(static_cast<const App::PropertyBool*>(prop)->getValue());
}
else if (prop == &EdgeAngle) {
m_smooth->SetEdgeAngle(static_cast<const App::PropertyAngle*>(prop)->getValue());
}
else if (prop == &FeatureAngle) {
m_smooth->SetFeatureAngle(static_cast<const App::PropertyAngle*>(prop)->getValue());
}
else if (prop == &EdgeSmoothing) {
m_smooth->SetFeatureEdgeSmoothing(static_cast<const App::PropertyBool*>(prop)->getValue());
}
else if (prop == &RelaxationFactor) {
m_smooth->SetRelaxationFactor(static_cast<const App::PropertyFloat*>(prop)->getValue());
}
else {
DocumentObjectExtension::extensionOnChanged(prop);
}
}
// ***************************************************************************
// contours filter
PROPERTY_SOURCE(Fem::FemPostContoursFilter, Fem::FemPostFilter)
@@ -543,10 +641,13 @@ FemPostContoursFilter::FemPostContoursFilter()
FilterPipeline contours;
m_contours = vtkSmartPointer<vtkContourFilter>::New();
m_contours->ComputeScalarsOn();
smoothExtension.getFilter()->SetInputConnection(m_contours->GetOutputPort());
contours.source = m_contours;
contours.target = m_contours;
contours.target = smoothExtension.getFilter();
addFilterPipeline(contours, "contours");
setActiveFilterPipeline("contours");
smoothExtension.initExtension(this);
}
FemPostContoursFilter::~FemPostContoursFilter() = default;

View File

@@ -24,6 +24,7 @@
#define Fem_FemPostFilter_H
#include <vtkContourFilter.h>
#include <vtkSmoothPolyDataFilter.h>
#include <vtkCutter.h>
#include <vtkExtractGeometry.h>
#include <vtkExtractVectorComponents.h>
@@ -36,6 +37,7 @@
#include <vtkWarpVector.h>
#include <App/PropertyUnits.h>
#include <App/DocumentObjectExtension.h>
#include "FemPostObject.h"
@@ -77,6 +79,37 @@ private:
std::string m_activePipeline;
};
class FemExport FemPostSmoothFilterExtension: public App::DocumentObjectExtension
{
EXTENSION_PROPERTY_HEADER_WITH_OVERRIDE(Fem::FemPostSmoothFilterExtension);
public:
FemPostSmoothFilterExtension();
~FemPostSmoothFilterExtension() override = default;
App::PropertyBool BoundarySmoothing;
App::PropertyAngle EdgeAngle;
App::PropertyBool EdgeSmoothing;
App::PropertyBool EnableSmoothing;
App::PropertyAngle FeatureAngle;
App::PropertyIntegerConstraint Iterations;
App::PropertyFloatConstraint RelaxationFactor;
vtkSmartPointer<vtkSmoothPolyDataFilter> getFilter() const
{
return m_smooth;
}
protected:
void extensionOnChanged(const App::Property* prop) override;
private:
vtkSmartPointer<vtkSmoothPolyDataFilter> m_smooth;
static const App::PropertyQuantityConstraint::Constraints angleRange;
static const App::PropertyIntegerConstraint::Constraints iterationRange;
static const App::PropertyFloatConstraint::Constraints relaxationRange;
};
// ***************************************************************************
// in the following, the different filters sorted alphabetically
// ***************************************************************************
@@ -210,11 +243,14 @@ public:
protected:
App::DocumentObjectExecReturn* execute() override;
void onChanged(const App::Property* prop) override;
void recalculateContours(double min, double max);
void refreshFields();
void refreshVectors();
bool m_blockPropertyChanges = false;
std::string contourFieldName;
FemPostSmoothFilterExtension smoothExtension;
private:
vtkSmartPointer<vtkContourFilter> m_contours;