From 50763df45b14a172b9a0bede1d45e5478c3cfedf Mon Sep 17 00:00:00 2001 From: Uwe Date: Mon, 13 Feb 2023 18:00:03 +0100 Subject: [PATCH] [FEM] sort code of result filters - sort the functions alphabetically to know where to scroll to - eases the reading at least a bit - some automatic reformatting according to our current clang file - split too long lines --- src/Mod/Fem/App/FemPostFilter.cpp | 717 +++++---- src/Mod/Fem/App/FemPostFilter.h | 229 +-- src/Mod/Fem/Gui/TaskPostBoxes.cpp | 1368 +++++++++-------- src/Mod/Fem/Gui/TaskPostBoxes.h | 309 ++-- src/Mod/Fem/Gui/ViewProviderFemPostFilter.cpp | 241 +-- src/Mod/Fem/Gui/ViewProviderFemPostFilter.h | 115 +- 6 files changed, 1547 insertions(+), 1432 deletions(-) diff --git a/src/Mod/Fem/App/FemPostFilter.cpp b/src/Mod/Fem/App/FemPostFilter.cpp index 1127295797..2096a2c2a3 100644 --- a/src/Mod/Fem/App/FemPostFilter.cpp +++ b/src/Mod/Fem/App/FemPostFilter.cpp @@ -46,27 +46,27 @@ FemPostFilter::FemPostFilter() } FemPostFilter::~FemPostFilter() +{} + +void FemPostFilter::addFilterPipeline(const FemPostFilter::FilterPipeline& p, std::string name) { - -} - -void FemPostFilter::addFilterPipeline(const FemPostFilter::FilterPipeline& p, std::string name) { m_pipelines[name] = p; } -FemPostFilter::FilterPipeline& FemPostFilter::getFilterPipeline(std::string name) { +FemPostFilter::FilterPipeline& FemPostFilter::getFilterPipeline(std::string name) +{ return m_pipelines[name]; } -void FemPostFilter::setActiveFilterPipeline(std::string name) { - +void FemPostFilter::setActiveFilterPipeline(std::string name) +{ if (m_activePipeline != name && isValid()) { m_activePipeline = name; } } -DocumentObjectExecReturn* FemPostFilter::execute() { - +DocumentObjectExecReturn* FemPostFilter::execute() +{ if (!m_pipelines.empty() && !m_activePipeline.empty()) { FemPostFilter::FilterPipeline& pipe = m_pipelines[m_activePipeline]; vtkSmartPointer data = getInputData(); @@ -88,8 +88,8 @@ DocumentObjectExecReturn* FemPostFilter::execute() { return StdReturn; } -vtkDataObject* FemPostFilter::getInputData() { - +vtkDataObject* FemPostFilter::getInputData() +{ if (Input.getValue()) { if (Input.getValue()->getTypeId().isDerivedFrom(Base::Type::fromName("Fem::FemPostObject"))) return Input.getValue()->Data.getValue(); @@ -111,101 +111,18 @@ vtkDataObject* FemPostFilter::getInputData() { return nullptr; } - // *************************************************************************** -// clip filter -PROPERTY_SOURCE(Fem::FemPostClipFilter, Fem::FemPostFilter) - -FemPostClipFilter::FemPostClipFilter() : FemPostFilter() { - - ADD_PROPERTY_TYPE(Function, - (nullptr), - "Clip", - App::Prop_None, - "The function object which defines the clip regions"); - ADD_PROPERTY_TYPE(InsideOut, (false), "Clip", App::Prop_None, "Invert the clip direction"); - ADD_PROPERTY_TYPE( - CutCells, - (false), - "Clip", - App::Prop_None, - "Decides if cells are cut and interpolated or if the cells are kept as a whole"); - - FilterPipeline clip; - m_clipper = vtkSmartPointer::New(); - clip.source = m_clipper; - clip.target = m_clipper; - addFilterPipeline(clip, "clip"); - - FilterPipeline extr; - m_extractor = vtkSmartPointer::New(); - extr.source = m_extractor; - extr.target = m_extractor; - addFilterPipeline(extr, "extract"); - - m_extractor->SetExtractInside(0); - setActiveFilterPipeline("extract"); -} - -FemPostClipFilter::~FemPostClipFilter() { - -} - -void FemPostClipFilter::onChanged(const Property* prop) { - - if (prop == &Function) { - - if (Function.getValue() - && Function.getValue()->isDerivedFrom(FemPostFunction::getClassTypeId())) { - m_clipper->SetClipFunction( - static_cast(Function.getValue())->getImplicitFunction()); - m_extractor->SetImplicitFunction( - static_cast(Function.getValue())->getImplicitFunction()); - } - } - else if (prop == &InsideOut) { - - m_clipper->SetInsideOut(InsideOut.getValue()); - m_extractor->SetExtractInside((InsideOut.getValue()) ? 1 : 0); - } - else if (prop == &CutCells) { - - if (!CutCells.getValue()) - setActiveFilterPipeline("extract"); - else - setActiveFilterPipeline("clip"); - }; - - Fem::FemPostFilter::onChanged(prop); -} - -short int FemPostClipFilter::mustExecute() const { - - if (Function.isTouched() || - InsideOut.isTouched() || - CutCells.isTouched()) { - - return 1; - } - else - return App::DocumentObject::mustExecute(); -} - -DocumentObjectExecReturn* FemPostClipFilter::execute() { - - if (!m_extractor->GetImplicitFunction()) - return StdReturn; - - return Fem::FemPostFilter::execute(); -} +// in the following, the different filters sorted alphabetically +// *************************************************************************** // *************************************************************************** -// data along a line +// data along line filter PROPERTY_SOURCE(Fem::FemPostDataAlongLineFilter, Fem::FemPostFilter) -FemPostDataAlongLineFilter::FemPostDataAlongLineFilter() : FemPostFilter() { - +FemPostDataAlongLineFilter::FemPostDataAlongLineFilter() + : FemPostFilter() +{ ADD_PROPERTY_TYPE(Point1, (Base::Vector3d(0.0, 0.0, 0.0)), "DataAlongLine", @@ -259,12 +176,11 @@ FemPostDataAlongLineFilter::FemPostDataAlongLineFilter() : FemPostFilter() { setActiveFilterPipeline("DataAlongLine"); } -FemPostDataAlongLineFilter::~FemPostDataAlongLineFilter() { - -} - -DocumentObjectExecReturn* FemPostDataAlongLineFilter::execute() { +FemPostDataAlongLineFilter::~FemPostDataAlongLineFilter() +{} +DocumentObjectExecReturn* FemPostDataAlongLineFilter::execute() +{ //recalculate the filter return Fem::FemPostFilter::execute(); } @@ -289,7 +205,8 @@ void FemPostDataAlongLineFilter::handleChangedPropertyType(Base::XMLReader& read } } -void FemPostDataAlongLineFilter::onChanged(const Property* prop) { +void FemPostDataAlongLineFilter::onChanged(const Property* prop) +{ if (prop == &Point1) { const Base::Vector3d& vec1 = Point1.getValue(); m_line->SetPoint1(vec1.x, vec1.y, vec1.z); @@ -307,19 +224,16 @@ void FemPostDataAlongLineFilter::onChanged(const Property* prop) { Fem::FemPostFilter::onChanged(prop); } -short int FemPostDataAlongLineFilter::mustExecute() const { - - if (Point1.isTouched() || - Point2.isTouched() || - Resolution.isTouched()) { - +short int FemPostDataAlongLineFilter::mustExecute() const +{ + if (Point1.isTouched() || Point2.isTouched() || Resolution.isTouched()) return 1; - } - else return App::DocumentObject::mustExecute(); + else + return App::DocumentObject::mustExecute(); } -void FemPostDataAlongLineFilter::GetAxisData() { - +void FemPostDataAlongLineFilter::GetAxisData() +{ std::vector coords; std::vector values; @@ -364,11 +278,12 @@ void FemPostDataAlongLineFilter::GetAxisData() { // *************************************************************************** -// data point filter +// data at point filter PROPERTY_SOURCE(Fem::FemPostDataAtPointFilter, Fem::FemPostFilter) -FemPostDataAtPointFilter::FemPostDataAtPointFilter() : FemPostFilter() { - +FemPostDataAtPointFilter::FemPostDataAtPointFilter() + : FemPostFilter() +{ ADD_PROPERTY_TYPE(Center, (Base::Vector3d(0.0, 0.0, 0.0)), "DataAtPoint", @@ -409,17 +324,17 @@ FemPostDataAtPointFilter::FemPostDataAtPointFilter() : FemPostFilter() { setActiveFilterPipeline("DataAtPoint"); } -FemPostDataAtPointFilter::~FemPostDataAtPointFilter() { - -} - -DocumentObjectExecReturn* FemPostDataAtPointFilter::execute() { +FemPostDataAtPointFilter::~FemPostDataAtPointFilter() +{} +DocumentObjectExecReturn* FemPostDataAtPointFilter::execute() +{ //recalculate the filter return Fem::FemPostFilter::execute(); } -void FemPostDataAtPointFilter::onChanged(const Property* prop) { +void FemPostDataAtPointFilter::onChanged(const Property* prop) +{ if (prop == &Center) { const Base::Vector3d& vec = Center.getValue(); m_point->SetCenter(vec.x, vec.y, vec.z); @@ -428,16 +343,16 @@ void FemPostDataAtPointFilter::onChanged(const Property* prop) { Fem::FemPostFilter::onChanged(prop); } -short int FemPostDataAtPointFilter::mustExecute() const { - +short int FemPostDataAtPointFilter::mustExecute() const +{ if (Center.isTouched()) return 1; else return App::DocumentObject::mustExecute(); } -void FemPostDataAtPointFilter::GetPointData() { - +void FemPostDataAtPointFilter::GetPointData() +{ std::vector values; vtkSmartPointer data = m_probe->GetOutputDataObject(0); @@ -468,246 +383,84 @@ void FemPostDataAtPointFilter::GetPointData() { // *************************************************************************** -// scalar clip filter -PROPERTY_SOURCE(Fem::FemPostScalarClipFilter, Fem::FemPostFilter) +// clip filter +PROPERTY_SOURCE(Fem::FemPostClipFilter, Fem::FemPostFilter) -FemPostScalarClipFilter::FemPostScalarClipFilter() : FemPostFilter() { - - ADD_PROPERTY_TYPE( - Value, (0), "Clip", App::Prop_None, "The scalar value used to clip the selected field"); - ADD_PROPERTY_TYPE(Scalars, (long(0)), "Clip", App::Prop_None, "The field used to clip"); - ADD_PROPERTY_TYPE(InsideOut, (false), "Clip", App::Prop_None, "Invert the clip direction"); - - Value.setConstraints(&m_constraints); - - FilterPipeline clip; - m_clipper = vtkSmartPointer::New(); - clip.source = m_clipper; - clip.target = m_clipper; - addFilterPipeline(clip, "clip"); - setActiveFilterPipeline("clip"); -} - -FemPostScalarClipFilter::~FemPostScalarClipFilter() { - -} - -DocumentObjectExecReturn* FemPostScalarClipFilter::execute() { - - std::string val; - if (Scalars.getValue() >= 0) - val = Scalars.getValueAsString(); - - std::vector ScalarsArray; - - vtkSmartPointer data = getInputData(); - if (!data || !data->IsA("vtkDataSet")) - return StdReturn; - - vtkDataSet* dset = vtkDataSet::SafeDownCast(data); - vtkPointData* pd = dset->GetPointData(); - - // get all scalar fields - for (int i = 0; i < pd->GetNumberOfArrays(); ++i) { - if (pd->GetArray(i)->GetNumberOfComponents() == 1) - ScalarsArray.emplace_back(pd->GetArrayName(i)); - } - - App::Enumeration empty; - Scalars.setValue(empty); - m_scalarFields.setEnums(ScalarsArray); - Scalars.setValue(m_scalarFields); - - // search if the current field is in the available ones and set it - std::vector::iterator it = - std::find(ScalarsArray.begin(), ScalarsArray.end(), val); - if (!val.empty() && it != ScalarsArray.end()) - Scalars.setValue(val.c_str()); - - //recalculate the filter - return Fem::FemPostFilter::execute(); -} - -void FemPostScalarClipFilter::onChanged(const Property* prop) { - - if (prop == &Value) { - m_clipper->SetValue(Value.getValue()); - } - else if (prop == &InsideOut) { - m_clipper->SetInsideOut(InsideOut.getValue()); - } - else if (prop == &Scalars && (Scalars.getValue() >= 0)) { - m_clipper->SetInputArrayToProcess(0, 0, 0, - vtkDataObject::FIELD_ASSOCIATION_POINTS, Scalars.getValueAsString()); - setConstraintForField(); - } - - Fem::FemPostFilter::onChanged(prop); -} - -short int FemPostScalarClipFilter::mustExecute() const { - - if (Value.isTouched() || - InsideOut.isTouched() || - Scalars.isTouched()) - return 1; - else - return App::DocumentObject::mustExecute(); -} - -void FemPostScalarClipFilter::setConstraintForField() { - - vtkSmartPointer data = getInputData(); - if (!data || !data->IsA("vtkDataSet")) - return; - - vtkDataSet* dset = vtkDataSet::SafeDownCast(data); - - vtkDataArray* pdata = dset->GetPointData()->GetArray(Scalars.getValueAsString()); - // VTK cannot deliver data when the filer relies e.g. on a cut clip filter - // whose value is set so that all data are cut - if (!pdata) - return; - double p[2]; - pdata->GetRange(p); - m_constraints.LowerBound = p[0]; - m_constraints.UpperBound = p[1]; - m_constraints.StepSize = (p[1] - p[0]) / 100.; -} - - -// *************************************************************************** -// warp vector filter -PROPERTY_SOURCE(Fem::FemPostWarpVectorFilter, Fem::FemPostFilter) - -FemPostWarpVectorFilter::FemPostWarpVectorFilter() : FemPostFilter() { - - ADD_PROPERTY_TYPE(Factor, - (0), - "Warp", - App::Prop_None, - "The factor by which the vector is added to the node positions"); - ADD_PROPERTY_TYPE( - Vector, (long(0)), "Warp", App::Prop_None, "The field added to the node position"); - - FilterPipeline warp; - m_warp = vtkSmartPointer::New(); - warp.source = m_warp; - warp.target = m_warp; - addFilterPipeline(warp, "warp"); - setActiveFilterPipeline("warp"); -} - -FemPostWarpVectorFilter::~FemPostWarpVectorFilter() { - -} - -DocumentObjectExecReturn* FemPostWarpVectorFilter::execute() { - - std::string val; - if (Vector.getValue() >= 0) - val = Vector.getValueAsString(); - - std::vector VectorArray; - - vtkSmartPointer data = getInputData(); - if (!data || !data->IsA("vtkDataSet")) - return StdReturn; - - vtkDataSet* dset = vtkDataSet::SafeDownCast(data); - vtkPointData* pd = dset->GetPointData(); - - // get all vector fields - for (int i = 0; i < pd->GetNumberOfArrays(); ++i) { - if (pd->GetArray(i)->GetNumberOfComponents() == 3) - VectorArray.emplace_back(pd->GetArrayName(i)); - } - - App::Enumeration empty; - Vector.setValue(empty); - m_vectorFields.setEnums(VectorArray); - Vector.setValue(m_vectorFields); - - // search if the current field is in the available ones and set it - std::vector::iterator it = - std::find(VectorArray.begin(), VectorArray.end(), val); - if (!val.empty() && it != VectorArray.end()) - Vector.setValue(val.c_str()); - - //recalculate the filter - return Fem::FemPostFilter::execute(); -} - -void FemPostWarpVectorFilter::onChanged(const Property* prop) { - - if (prop == &Factor) - // since our mesh is in mm, we must scale the factor - m_warp->SetScaleFactor(1000 * Factor.getValue()); - else if (prop == &Vector && (Vector.getValue() >= 0)) - m_warp->SetInputArrayToProcess(0, 0, 0, - vtkDataObject::FIELD_ASSOCIATION_POINTS, Vector.getValueAsString()); - - Fem::FemPostFilter::onChanged(prop); -} - -short int FemPostWarpVectorFilter::mustExecute() const { - - if (Factor.isTouched() || - Vector.isTouched()) - return 1; - else - return App::DocumentObject::mustExecute(); -} - - -// *************************************************************************** -// cut filter -PROPERTY_SOURCE(Fem::FemPostCutFilter, Fem::FemPostFilter) - -FemPostCutFilter::FemPostCutFilter() +FemPostClipFilter::FemPostClipFilter() : FemPostFilter() { ADD_PROPERTY_TYPE(Function, (nullptr), - "Cut", + "Clip", App::Prop_None, - "The function object which defines the cut function"); + "The function object which defines the clip regions"); + ADD_PROPERTY_TYPE(InsideOut, (false), "Clip", App::Prop_None, "Invert the clip direction"); + ADD_PROPERTY_TYPE( + CutCells, + (false), + "Clip", + App::Prop_None, + "Decides if cells are cut and interpolated or if the cells are kept as a whole"); - FilterPipeline cut; - m_cutter = vtkSmartPointer::New(); - cut.source = m_cutter; - cut.target = m_cutter; - addFilterPipeline(cut, "cut"); - setActiveFilterPipeline("cut"); + FilterPipeline clip; + m_clipper = vtkSmartPointer::New(); + clip.source = m_clipper; + clip.target = m_clipper; + addFilterPipeline(clip, "clip"); + + FilterPipeline extr; + m_extractor = vtkSmartPointer::New(); + extr.source = m_extractor; + extr.target = m_extractor; + addFilterPipeline(extr, "extract"); + + m_extractor->SetExtractInside(0); + setActiveFilterPipeline("extract"); } -FemPostCutFilter::~FemPostCutFilter() +FemPostClipFilter::~FemPostClipFilter() {} -void FemPostCutFilter::onChanged(const Property* prop) +void FemPostClipFilter::onChanged(const Property* prop) { if (prop == &Function) { + if (Function.getValue() && Function.getValue()->isDerivedFrom(FemPostFunction::getClassTypeId())) { - m_cutter->SetCutFunction( + m_clipper->SetClipFunction( + static_cast(Function.getValue())->getImplicitFunction()); + m_extractor->SetImplicitFunction( static_cast(Function.getValue())->getImplicitFunction()); } } + else if (prop == &InsideOut) { + + m_clipper->SetInsideOut(InsideOut.getValue()); + m_extractor->SetExtractInside((InsideOut.getValue()) ? 1 : 0); + } + else if (prop == &CutCells) { + + if (!CutCells.getValue()) + setActiveFilterPipeline("extract"); + else + setActiveFilterPipeline("clip"); + }; Fem::FemPostFilter::onChanged(prop); } -short int FemPostCutFilter::mustExecute() const +short int FemPostClipFilter::mustExecute() const { - if (Function.isTouched()) + if (Function.isTouched() || InsideOut.isTouched() || CutCells.isTouched()) + return 1; else return App::DocumentObject::mustExecute(); } -DocumentObjectExecReturn* FemPostCutFilter::execute() +DocumentObjectExecReturn* FemPostClipFilter::execute() { - if (!m_cutter->GetCutFunction()) + if (!m_extractor->GetImplicitFunction()) return StdReturn; return Fem::FemPostFilter::execute(); @@ -720,14 +473,11 @@ PROPERTY_SOURCE(Fem::FemPostContoursFilter, Fem::FemPostFilter) FemPostContoursFilter::FemPostContoursFilter() : FemPostFilter() { - ADD_PROPERTY_TYPE(NumberOfContours, (10), "Contours", - App::Prop_None, "The number of contours"); - ADD_PROPERTY_TYPE(Field, (long(0)), "Clip", - App::Prop_None, "The field used to clip"); - ADD_PROPERTY_TYPE(VectorMode, ((long)0), "Contours", - App::Prop_None, "Select what vector field"); - ADD_PROPERTY_TYPE(NoColor, (false), "Contours", - App::Prop_None, "Don't color the contours"); + ADD_PROPERTY_TYPE(NumberOfContours, (10), "Contours", App::Prop_None, "The number of contours"); + ADD_PROPERTY_TYPE(Field, (long(0)), "Clip", App::Prop_None, "The field used to clip"); + ADD_PROPERTY_TYPE( + VectorMode, ((long)0), "Contours", App::Prop_None, "Select what vector field"); + ADD_PROPERTY_TYPE(NoColor, (false), "Contours", App::Prop_None, "Don't color the contours"); m_contourConstraints.LowerBound = 1; m_contourConstraints.UpperBound = 1000; @@ -744,8 +494,7 @@ FemPostContoursFilter::FemPostContoursFilter() } FemPostContoursFilter::~FemPostContoursFilter() -{ -} +{} DocumentObjectExecReturn* FemPostContoursFilter::execute() { @@ -827,24 +576,23 @@ void FemPostContoursFilter::onChanged(const Property* prop) } else { for (vtkIdType tupleIdx = 0; tupleIdx < numTuples; ++tupleIdx) { - componentArray->SetComponent(tupleIdx, 0, - std::sqrt(pdata->GetComponent(tupleIdx, 0) * - pdata->GetComponent(tupleIdx, 0) + - pdata->GetComponent(tupleIdx, 1) * - pdata->GetComponent(tupleIdx, 1) + - pdata->GetComponent(tupleIdx, 2) * - pdata->GetComponent(tupleIdx, 2) ) ); + componentArray->SetComponent( + tupleIdx, + 0, + std::sqrt( + pdata->GetComponent(tupleIdx, 0) * pdata->GetComponent(tupleIdx, 0) + + pdata->GetComponent(tupleIdx, 1) * pdata->GetComponent(tupleIdx, 1) + + pdata->GetComponent(tupleIdx, 2) * pdata->GetComponent(tupleIdx, 2))); } } // name the array - contourFieldName = - std::string(Field.getValueAsString()) + "_contour"; + contourFieldName = std::string(Field.getValueAsString()) + "_contour"; componentArray->SetName(contourFieldName.c_str()); // add the array as new field and use it for the contour filter dset->GetPointData()->AddArray(componentArray); - m_contours->SetInputArrayToProcess(0, 0, 0, - vtkDataObject::FIELD_ASSOCIATION_POINTS, contourFieldName.c_str()); + m_contours->SetInputArrayToProcess( + 0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_POINTS, contourFieldName.c_str()); componentArray->GetRange(p); recalculateContours(p[0], p[1]); if (prop == &Data) { @@ -966,6 +714,251 @@ void FemPostContoursFilter::refreshVectors() auto it = std::find(vectorArray.begin(), vectorArray.end(), vectorName); if (!vectorName.empty() && it != vectorArray.end()) VectorMode.setValue(vectorName.c_str()); - + m_blockPropertyChanges = false; } + + +// *************************************************************************** +// cut filter +PROPERTY_SOURCE(Fem::FemPostCutFilter, Fem::FemPostFilter) + +FemPostCutFilter::FemPostCutFilter() + : FemPostFilter() +{ + ADD_PROPERTY_TYPE(Function, + (nullptr), + "Cut", + App::Prop_None, + "The function object which defines the cut function"); + + FilterPipeline cut; + m_cutter = vtkSmartPointer::New(); + cut.source = m_cutter; + cut.target = m_cutter; + addFilterPipeline(cut, "cut"); + setActiveFilterPipeline("cut"); +} + +FemPostCutFilter::~FemPostCutFilter() +{} + +void FemPostCutFilter::onChanged(const Property* prop) +{ + if (prop == &Function) { + if (Function.getValue() + && Function.getValue()->isDerivedFrom(FemPostFunction::getClassTypeId())) { + m_cutter->SetCutFunction( + static_cast(Function.getValue())->getImplicitFunction()); + } + } + + Fem::FemPostFilter::onChanged(prop); +} + +short int FemPostCutFilter::mustExecute() const +{ + if (Function.isTouched()) + return 1; + else + return App::DocumentObject::mustExecute(); +} + +DocumentObjectExecReturn* FemPostCutFilter::execute() +{ + if (!m_cutter->GetCutFunction()) + return StdReturn; + + return Fem::FemPostFilter::execute(); +} + + +// *************************************************************************** +// scalar clip filter +PROPERTY_SOURCE(Fem::FemPostScalarClipFilter, Fem::FemPostFilter) + +FemPostScalarClipFilter::FemPostScalarClipFilter() : FemPostFilter() { + + ADD_PROPERTY_TYPE( + Value, (0), "Clip", App::Prop_None, "The scalar value used to clip the selected field"); + ADD_PROPERTY_TYPE(Scalars, (long(0)), "Clip", App::Prop_None, "The field used to clip"); + ADD_PROPERTY_TYPE(InsideOut, (false), "Clip", App::Prop_None, "Invert the clip direction"); + + Value.setConstraints(&m_constraints); + + FilterPipeline clip; + m_clipper = vtkSmartPointer::New(); + clip.source = m_clipper; + clip.target = m_clipper; + addFilterPipeline(clip, "clip"); + setActiveFilterPipeline("clip"); +} + +FemPostScalarClipFilter::~FemPostScalarClipFilter() { + +} + +DocumentObjectExecReturn* FemPostScalarClipFilter::execute() +{ + std::string val; + if (Scalars.getValue() >= 0) + val = Scalars.getValueAsString(); + + std::vector ScalarsArray; + + vtkSmartPointer data = getInputData(); + if (!data || !data->IsA("vtkDataSet")) + return StdReturn; + + vtkDataSet* dset = vtkDataSet::SafeDownCast(data); + vtkPointData* pd = dset->GetPointData(); + + // get all scalar fields + for (int i = 0; i < pd->GetNumberOfArrays(); ++i) { + if (pd->GetArray(i)->GetNumberOfComponents() == 1) + ScalarsArray.emplace_back(pd->GetArrayName(i)); + } + + App::Enumeration empty; + Scalars.setValue(empty); + m_scalarFields.setEnums(ScalarsArray); + Scalars.setValue(m_scalarFields); + + // search if the current field is in the available ones and set it + std::vector::iterator it = + std::find(ScalarsArray.begin(), ScalarsArray.end(), val); + if (!val.empty() && it != ScalarsArray.end()) + Scalars.setValue(val.c_str()); + + //recalculate the filter + return Fem::FemPostFilter::execute(); +} + +void FemPostScalarClipFilter::onChanged(const Property* prop) +{ + if (prop == &Value) { + m_clipper->SetValue(Value.getValue()); + } + else if (prop == &InsideOut) { + m_clipper->SetInsideOut(InsideOut.getValue()); + } + else if (prop == &Scalars && (Scalars.getValue() >= 0)) { + m_clipper->SetInputArrayToProcess(0, 0, 0, + vtkDataObject::FIELD_ASSOCIATION_POINTS, Scalars.getValueAsString()); + setConstraintForField(); + } + + Fem::FemPostFilter::onChanged(prop); +} + +short int FemPostScalarClipFilter::mustExecute() const +{ + if (Value.isTouched() || + InsideOut.isTouched() || + Scalars.isTouched()) + return 1; + else + return App::DocumentObject::mustExecute(); +} + +void FemPostScalarClipFilter::setConstraintForField() +{ + vtkSmartPointer data = getInputData(); + if (!data || !data->IsA("vtkDataSet")) + return; + + vtkDataSet* dset = vtkDataSet::SafeDownCast(data); + + vtkDataArray* pdata = dset->GetPointData()->GetArray(Scalars.getValueAsString()); + // VTK cannot deliver data when the filer relies e.g. on a cut clip filter + // whose value is set so that all data are cut + if (!pdata) + return; + double p[2]; + pdata->GetRange(p); + m_constraints.LowerBound = p[0]; + m_constraints.UpperBound = p[1]; + m_constraints.StepSize = (p[1] - p[0]) / 100.; +} + + +// *************************************************************************** +// warp vector filter +PROPERTY_SOURCE(Fem::FemPostWarpVectorFilter, Fem::FemPostFilter) + +FemPostWarpVectorFilter::FemPostWarpVectorFilter() : FemPostFilter() +{ + ADD_PROPERTY_TYPE(Factor, + (0), + "Warp", + App::Prop_None, + "The factor by which the vector is added to the node positions"); + ADD_PROPERTY_TYPE( + Vector, (long(0)), "Warp", App::Prop_None, "The field added to the node position"); + + FilterPipeline warp; + m_warp = vtkSmartPointer::New(); + warp.source = m_warp; + warp.target = m_warp; + addFilterPipeline(warp, "warp"); + setActiveFilterPipeline("warp"); +} + +FemPostWarpVectorFilter::~FemPostWarpVectorFilter() +{} + +DocumentObjectExecReturn* FemPostWarpVectorFilter::execute() +{ + std::string val; + if (Vector.getValue() >= 0) + val = Vector.getValueAsString(); + + std::vector VectorArray; + + vtkSmartPointer data = getInputData(); + if (!data || !data->IsA("vtkDataSet")) + return StdReturn; + + vtkDataSet* dset = vtkDataSet::SafeDownCast(data); + vtkPointData* pd = dset->GetPointData(); + + // get all vector fields + for (int i = 0; i < pd->GetNumberOfArrays(); ++i) { + if (pd->GetArray(i)->GetNumberOfComponents() == 3) + VectorArray.emplace_back(pd->GetArrayName(i)); + } + + App::Enumeration empty; + Vector.setValue(empty); + m_vectorFields.setEnums(VectorArray); + Vector.setValue(m_vectorFields); + + // search if the current field is in the available ones and set it + std::vector::iterator it = + std::find(VectorArray.begin(), VectorArray.end(), val); + if (!val.empty() && it != VectorArray.end()) + Vector.setValue(val.c_str()); + + //recalculate the filter + return Fem::FemPostFilter::execute(); +} + +void FemPostWarpVectorFilter::onChanged(const Property* prop) +{ + if (prop == &Factor) + // since our mesh is in mm, we must scale the factor + m_warp->SetScaleFactor(1000 * Factor.getValue()); + else if (prop == &Vector && (Vector.getValue() >= 0)) + m_warp->SetInputArrayToProcess(0, 0, 0, + vtkDataObject::FIELD_ASSOCIATION_POINTS, Vector.getValueAsString()); + + Fem::FemPostFilter::onChanged(prop); +} + +short int FemPostWarpVectorFilter::mustExecute() const +{ + if (Factor.isTouched() || Vector.isTouched()) + return 1; + else + return App::DocumentObject::mustExecute(); +} diff --git a/src/Mod/Fem/App/FemPostFilter.h b/src/Mod/Fem/App/FemPostFilter.h index 2ea6bdc38f..a00edb7d9b 100644 --- a/src/Mod/Fem/App/FemPostFilter.h +++ b/src/Mod/Fem/App/FemPostFilter.h @@ -75,33 +75,15 @@ private: std::string m_activePipeline; }; -class FemExport FemPostClipFilter : public FemPostFilter { +// *************************************************************************** +// in the following, the different filters sorted alphabetically +// *************************************************************************** - PROPERTY_HEADER_WITH_OVERRIDE(Fem::FemPostClipFilter); -public: - FemPostClipFilter(); - ~FemPostClipFilter() override; - - App::PropertyLink Function; - App::PropertyBool InsideOut; - App::PropertyBool CutCells; - - const char* getViewProviderName() const override { - return "FemGui::ViewProviderFemPostClip"; - } - short int mustExecute() const override; - App::DocumentObjectExecReturn* execute() override; - -protected: - void onChanged(const App::Property* prop) override; - -private: - vtkSmartPointer m_clipper; - vtkSmartPointer m_extractor; -}; - -class FemExport FemPostDataAlongLineFilter : public FemPostFilter { +// *************************************************************************** +// data along line filter +class FemExport FemPostDataAlongLineFilter: public FemPostFilter +{ PROPERTY_HEADER_WITH_OVERRIDE(Fem::FemPostDataAlongLineFilter); @@ -116,8 +98,9 @@ public: App::PropertyFloatList YAxisData; App::PropertyString PlotData; - const char* getViewProviderName() const override { - return "FemGui::ViewProviderFemPostDataAlongLine"; + const char* getViewProviderName() const override + { + return "FemGui::ViewProviderFemPostDataAlongLine"; } short int mustExecute() const override; void GetAxisData(); @@ -129,13 +112,15 @@ protected: App::Property* prop) override; private: - - vtkSmartPointer m_line; - vtkSmartPointer m_probe; - + vtkSmartPointer m_line; + vtkSmartPointer m_probe; }; -class FemExport FemPostDataAtPointFilter : public FemPostFilter { + +// *************************************************************************** +// data at point filter +class FemExport FemPostDataAtPointFilter: public FemPostFilter +{ PROPERTY_HEADER_WITH_OVERRIDE(Fem::FemPostDataAtPointFilter); @@ -149,8 +134,9 @@ public: App::PropertyFloatList PointData; App::PropertyString Unit; - const char* getViewProviderName() const override { - return "FemGui::ViewProviderFemPostDataAtPoint"; + const char* getViewProviderName() const override + { + return "FemGui::ViewProviderFemPostDataAtPoint"; } short int mustExecute() const override; @@ -160,77 +146,29 @@ protected: void GetPointData(); private: - - vtkSmartPointer m_point; - vtkSmartPointer m_probe; - + vtkSmartPointer m_point; + vtkSmartPointer m_probe; }; -class FemExport FemPostScalarClipFilter : public FemPostFilter { - PROPERTY_HEADER_WITH_OVERRIDE(Fem::FemPostScalarClipFilter); +// *************************************************************************** +// clip filter +class FemExport FemPostClipFilter: public FemPostFilter +{ + + PROPERTY_HEADER_WITH_OVERRIDE(Fem::FemPostClipFilter); public: - FemPostScalarClipFilter(); - ~FemPostScalarClipFilter() override; + FemPostClipFilter(); + ~FemPostClipFilter() override; - App::PropertyBool InsideOut; - App::PropertyFloatConstraint Value; - App::PropertyEnumeration Scalars; + App::PropertyLink Function; + App::PropertyBool InsideOut; + App::PropertyBool CutCells; - const char* getViewProviderName() const override { - return "FemGui::ViewProviderFemPostScalarClip"; - } - short int mustExecute() const override; - -protected: - App::DocumentObjectExecReturn* execute() override; - void onChanged(const App::Property* prop) override; - void setConstraintForField(); - -private: - vtkSmartPointer m_clipper; - App::Enumeration m_scalarFields; - App::PropertyFloatConstraint::Constraints m_constraints; -}; - -class FemExport FemPostWarpVectorFilter : public FemPostFilter { - - PROPERTY_HEADER_WITH_OVERRIDE(Fem::FemPostWarpVectorFilter); - -public: - FemPostWarpVectorFilter(); - ~FemPostWarpVectorFilter() override; - - App::PropertyFloat Factor; - App::PropertyEnumeration Vector; - - const char* getViewProviderName() const override { - return "FemGui::ViewProviderFemPostWarpVector"; - } - short int mustExecute() const override; - -protected: - App::DocumentObjectExecReturn* execute() override; - void onChanged(const App::Property* prop) override; - -private: - vtkSmartPointer m_warp; - App::Enumeration m_vectorFields; -}; - -class FemExport FemPostCutFilter : public FemPostFilter { - - PROPERTY_HEADER_WITH_OVERRIDE(Fem::FemPostCutFilter); - -public: - FemPostCutFilter(); - ~FemPostCutFilter() override; - - App::PropertyLink Function; - - const char* getViewProviderName() const override { - return "FemGui::ViewProviderFemPostCut"; + const char* getViewProviderName() const override + { + return "FemGui::ViewProviderFemPostClip"; } short int mustExecute() const override; App::DocumentObjectExecReturn* execute() override; @@ -239,9 +177,13 @@ protected: void onChanged(const App::Property* prop) override; private: - vtkSmartPointer m_cutter; + vtkSmartPointer m_clipper; + vtkSmartPointer m_extractor; }; + +// *************************************************************************** +// contours filter class FemExport FemPostContoursFilter: public FemPostFilter { @@ -280,6 +222,95 @@ private: App::PropertyIntegerConstraint::Constraints m_contourConstraints; }; + +// *************************************************************************** +// cut filter +class FemExport FemPostCutFilter: public FemPostFilter +{ + + PROPERTY_HEADER_WITH_OVERRIDE(Fem::FemPostCutFilter); + +public: + FemPostCutFilter(); + ~FemPostCutFilter() override; + + App::PropertyLink Function; + + const char* getViewProviderName() const override + { + return "FemGui::ViewProviderFemPostCut"; + } + short int mustExecute() const override; + App::DocumentObjectExecReturn* execute() override; + +protected: + void onChanged(const App::Property* prop) override; + +private: + vtkSmartPointer m_cutter; +}; + + +// *************************************************************************** +// scalar clip filter +class FemExport FemPostScalarClipFilter: public FemPostFilter +{ + + PROPERTY_HEADER_WITH_OVERRIDE(Fem::FemPostScalarClipFilter); + +public: + FemPostScalarClipFilter(); + ~FemPostScalarClipFilter() override; + + App::PropertyBool InsideOut; + App::PropertyFloatConstraint Value; + App::PropertyEnumeration Scalars; + + const char* getViewProviderName() const override + { + return "FemGui::ViewProviderFemPostScalarClip"; + } + short int mustExecute() const override; + +protected: + App::DocumentObjectExecReturn* execute() override; + void onChanged(const App::Property* prop) override; + void setConstraintForField(); + +private: + vtkSmartPointer m_clipper; + App::Enumeration m_scalarFields; + App::PropertyFloatConstraint::Constraints m_constraints; +}; + + +// *************************************************************************** +// warp vector filter +class FemExport FemPostWarpVectorFilter : public FemPostFilter { + + PROPERTY_HEADER_WITH_OVERRIDE(Fem::FemPostWarpVectorFilter); + +public: + FemPostWarpVectorFilter(); + ~FemPostWarpVectorFilter() override; + + App::PropertyFloat Factor; + App::PropertyEnumeration Vector; + + const char* getViewProviderName() const override { + return "FemGui::ViewProviderFemPostWarpVector"; + } + short int mustExecute() const override; + +protected: + App::DocumentObjectExecReturn* execute() override; + void onChanged(const App::Property* prop) override; + +private: + vtkSmartPointer m_warp; + App::Enumeration m_vectorFields; +}; + } //namespace Fem diff --git a/src/Mod/Fem/Gui/TaskPostBoxes.cpp b/src/Mod/Fem/Gui/TaskPostBoxes.cpp index 90ab069f66..0b9ac4d2c3 100644 --- a/src/Mod/Fem/Gui/TaskPostBoxes.cpp +++ b/src/Mod/Fem/Gui/TaskPostBoxes.cpp @@ -70,7 +70,7 @@ using namespace FemGui; using namespace Gui; // *************************************************************************** - +// point marker PointMarker::PointMarker(Gui::View3DInventorViewer* iv, std::string ObjName) : view(iv), vp(new ViewProviderPointMarker) { @@ -118,7 +118,8 @@ void PointMarker::customEvent(QEvent*) Gui::Command::doCommand(Gui::Command::Doc, ObjectInvisible().c_str()); } -std::string PointMarker::ObjectInvisible() { +std::string PointMarker::ObjectInvisible() +{ return "for amesh in App.activeDocument().Objects:\n\ if \"Mesh\" in amesh.TypeId:\n\ aparttoshow = amesh.Name.replace(\"_Mesh\",\"\")\n\ @@ -146,8 +147,9 @@ ViewProviderPointMarker::~ViewProviderPointMarker() pCoords->unref(); } -// *************************************************************************** +// *************************************************************************** +// data marker DataMarker::DataMarker(Gui::View3DInventorViewer* iv, std::string ObjName) : view(iv), vp(new ViewProviderDataMarker) { @@ -190,7 +192,8 @@ void DataMarker::customEvent(QEvent*) Gui::Command::doCommand(Gui::Command::Doc, ObjectInvisible().c_str()); } -std::string DataMarker::ObjectInvisible() { +std::string DataMarker::ObjectInvisible() +{ return "for amesh in App.activeDocument().Objects:\n\ if \"Mesh\" in amesh.TypeId:\n\ aparttoshow = amesh.Name.replace(\"_Mesh\",\"\")\n\ @@ -228,25 +231,72 @@ ViewProviderDataMarker::~ViewProviderDataMarker() pMarker->unref(); } -// *************************************************************************** -// *************************************************************************** -// TaskDialog -// *************************************************************************** +// *************************************************************************** +// main task dialog +TaskPostBox::TaskPostBox(Gui::ViewProviderDocumentObject* view, const QPixmap& icon, + const QString& title, QWidget* parent) + : TaskBox(icon, title, true, parent), + m_object(view->getObject()), + m_view(view) +{} + +TaskPostBox::~TaskPostBox() +{} + +bool TaskPostBox::autoApply() +{ + return FemSettings().getPostAutoRecompute(); +} + +App::Document* TaskPostBox::getDocument() const +{ + App::DocumentObject* obj = getObject(); + return (obj ? obj->getDocument() : nullptr); +} + +void TaskPostBox::recompute() +{ + if (autoApply()) { + App::Document* doc = getDocument(); + if (doc) + doc->recompute(); + } +} + +void TaskPostBox::updateEnumerationList(App::PropertyEnumeration& prop, QComboBox* box) +{ + QStringList list; + std::vector vec = prop.getEnumVector(); + for (std::vector::iterator it = vec.begin(); it != vec.end(); ++it) { + list.push_back(QString::fromStdString(*it)); + } + + int index = prop.getValue(); + // be aware the QComboxBox might be connected to the Property, + // thus clearing the box will set back the property enumeration index too. + // https://forum.freecadweb.org/viewtopic.php?f=10&t=30944 + box->clear(); + box->insertItems(0, list); + box->setCurrentIndex(index); +} + + +// *************************************************************************** +// simulation dialog for the TaskView TaskDlgPost::TaskDlgPost(Gui::ViewProviderDocumentObject* view) - : TaskDialog() - , m_view(view) + : TaskDialog(), + m_view(view) { assert(view); } TaskDlgPost::~TaskDlgPost() +{} + +QDialogButtonBox::StandardButtons TaskDlgPost::getStandardButtons() const { -} - -QDialogButtonBox::StandardButtons TaskDlgPost::getStandardButtons() const { - //check if we only have gui task boxes bool guionly = true; for (std::vector::const_iterator it = m_boxes.begin(); it != m_boxes.end(); ++it) @@ -284,8 +334,8 @@ void TaskDlgPost::connectSlots() } } -void TaskDlgPost::appendBox(TaskPostBox* box) { - +void TaskDlgPost::appendBox(TaskPostBox* box) +{ m_boxes.push_back(box); Content.push_back(box); } @@ -342,63 +392,13 @@ void TaskDlgPost::modifyStandardButtons(QDialogButtonBox* box) { box->button(QDialogButtonBox::Apply)->setDefault(true); } -// *************************************************************************** -// some task box methods -TaskPostBox::TaskPostBox(Gui::ViewProviderDocumentObject* view, const QPixmap& icon, - const QString& title, QWidget* parent) - : TaskBox(icon, title, true, parent) - , m_object(view->getObject()) - , m_view(view) -{ -} - -TaskPostBox::~TaskPostBox() { - -} - -bool TaskPostBox::autoApply() { - - return FemSettings().getPostAutoRecompute(); -} - -App::Document* TaskPostBox::getDocument() const { - App::DocumentObject* obj = getObject(); - return (obj ? obj->getDocument() : nullptr); -} - -void TaskPostBox::recompute() { - - if (autoApply()) { - App::Document* doc = getDocument(); - if (doc) - doc->recompute(); - } -} - -void TaskPostBox::updateEnumerationList(App::PropertyEnumeration& prop, QComboBox* box) { - - QStringList list; - std::vector vec = prop.getEnumVector(); - for (std::vector::iterator it = vec.begin(); it != vec.end(); ++it) { - list.push_back(QString::fromStdString(*it)); - } - - int index = prop.getValue(); - // be aware the QComboxBox might be connected to the Property, - // thus clearing the box will set back the property enumeration index too. - // https://forum.freecadweb.org/viewtopic.php?f=10&t=30944 - box->clear(); - box->insertItems(0, list); - box->setCurrentIndex(index); -} - // *************************************************************************** -// post pipeline results +// box to set the coloring TaskPostDisplay::TaskPostDisplay(Gui::ViewProviderDocumentObject* view, QWidget* parent) : TaskPostBox(view, Gui::BitmapFactory().pixmap("FEM_ResultShow"), tr("Result display options"), - parent) - , ui(new Ui_TaskPostDisplay) + parent), + ui(new Ui_TaskPostDisplay) { // we need a separate container widget to add all controls to proxy = new QWidget(this); @@ -408,7 +408,8 @@ TaskPostDisplay::TaskPostDisplay(Gui::ViewProviderDocumentObject* view, QWidget* this->groupLayout()->addWidget(proxy); // update all fields - updateEnumerationList(getTypedView()->DisplayMode, ui->Representation); + updateEnumerationList(getTypedView()->DisplayMode, + ui->Representation); updateEnumerationList(getTypedView()->Field, ui->Field); updateEnumerationList(getTypedView()->VectorMode, ui->VectorMode); @@ -421,29 +422,28 @@ TaskPostDisplay::TaskPostDisplay(Gui::ViewProviderDocumentObject* view, QWidget* } TaskPostDisplay::~TaskPostDisplay() -{ -} +{} void TaskPostDisplay::slotAddedFunction() { updateEnumerationList(getTypedView()->Field, ui->Field); } -void TaskPostDisplay::on_Representation_activated(int i) { - +void TaskPostDisplay::on_Representation_activated(int i) +{ getTypedView()->DisplayMode.setValue(i); updateEnumerationList(getTypedView()->Field, ui->Field); updateEnumerationList(getTypedView()->VectorMode, ui->VectorMode); } -void TaskPostDisplay::on_Field_activated(int i) { - +void TaskPostDisplay::on_Field_activated(int i) +{ getTypedView()->Field.setValue(i); updateEnumerationList(getTypedView()->VectorMode, ui->VectorMode); } -void TaskPostDisplay::on_VectorMode_activated(int i) { - +void TaskPostDisplay::on_VectorMode_activated(int i) +{ getTypedView()->VectorMode.setValue(i); } @@ -455,19 +455,16 @@ void TaskPostDisplay::on_Transparency_valueChanged(int i) { QToolTip::showText(QCursor::pos(), QString::number(i) + QString::fromLatin1(" %"), nullptr); } -void TaskPostDisplay::applyPythonCode() { +void TaskPostDisplay::applyPythonCode() +{} -} // *************************************************************************** -// ? -// the icon fem-post-geo-plane might be wrong but I do not know any better since the plane is one -// of the implicit functions +// functions TaskPostFunction::TaskPostFunction(ViewProviderDocumentObject* view, QWidget* parent) : TaskPostBox(view, Gui::BitmapFactory().pixmap("fem-post-geo-plane"), tr("Implicit function"), parent) { - assert(view->isDerivedFrom(ViewProviderFemPostFunction::getClassTypeId())); //we load the views widget @@ -477,173 +474,27 @@ TaskPostFunction::TaskPostFunction(ViewProviderDocumentObject* view, QWidget* pa this->groupLayout()->addWidget(w); } -TaskPostFunction::~TaskPostFunction() { - -} - -void TaskPostFunction::applyPythonCode() { +TaskPostFunction::~TaskPostFunction() +{} +void TaskPostFunction::applyPythonCode() +{ //we apply the views widgets python code } // *************************************************************************** -// region clip filter -TaskPostClip::TaskPostClip(ViewProviderDocumentObject* view, App::PropertyLink* function, - QWidget* parent) - : TaskPostBox(view, Gui::BitmapFactory().pixmap("FEM_PostFilterClipRegion"), - tr("Clip region, choose implicit function"), parent), - ui(new Ui_TaskPostClip) -{ - - assert(view->isDerivedFrom(ViewProviderFemPostClip::getClassTypeId())); - assert(function); - Q_UNUSED(function); - - fwidget = nullptr; - - //we load the views widget - proxy = new QWidget(this); - ui->setupUi(proxy); - QMetaObject::connectSlotsByName(this); - this->groupLayout()->addWidget(proxy); - - //the layout for the container widget - QVBoxLayout* layout = new QVBoxLayout(); - ui->Container->setLayout(layout); - - //fill up the combo box with possible functions - collectImplicitFunctions(); - - //add the function creation command - Gui::CommandManager& rcCmdMgr = Gui::Application::Instance->commandManager(); - Gui::Command* cmd = rcCmdMgr.getCommandByName("FEM_PostCreateFunctions"); - if (cmd && cmd->getAction()) - cmd->getAction()->addTo(ui->CreateButton); - ui->CreateButton->setPopupMode(QToolButton::InstantPopup); - - //load the default values - ui->CutCells->setChecked( - static_cast(getObject())->CutCells.getValue()); - ui->InsideOut->setChecked( - static_cast(getObject())->InsideOut.getValue()); -} - -TaskPostClip::~TaskPostClip() { - -} - -void TaskPostClip::applyPythonCode() { - -} - -void TaskPostClip::collectImplicitFunctions() { - - std::vector pipelines; - pipelines = getDocument()->getObjectsOfType(); - if (!pipelines.empty()) { - Fem::FemPostPipeline* pipeline = pipelines.front(); - if (pipeline->Functions.getValue() && pipeline->Functions.getValue()->getTypeId() - == Fem::FemPostFunctionProvider::getClassTypeId()) { - - ui->FunctionBox->clear(); - QStringList items; - std::size_t currentItem = 0; - App::DocumentObject* currentFunction = - static_cast(getObject())->Function.getValue(); - const std::vector& funcs = - static_cast(pipeline->Functions.getValue()) - ->Functions.getValues(); - for (std::size_t i = 0; i < funcs.size(); ++i) { - items.push_back(QString::fromLatin1(funcs[i]->getNameInDocument())); - if (currentFunction == funcs[i]) - currentItem = i; - } - ui->FunctionBox->addItems(items); - ui->FunctionBox->setCurrentIndex(currentItem); - } - } -} - -void TaskPostClip::on_CreateButton_triggered(QAction*) { - - int numFuncs = ui->FunctionBox->count(); - int currentItem = ui->FunctionBox->currentIndex(); - collectImplicitFunctions(); - - // if a new function was successfully added use it - int indexCount = ui->FunctionBox->count(); - if (indexCount > currentItem + 1) - ui->FunctionBox->setCurrentIndex(indexCount - 1); - - // When the first function ever was added, a signal must be emitted - if (numFuncs == 0) { - Q_EMIT emitAddedFunction(); - } - - recompute(); -} - -void TaskPostClip::on_FunctionBox_currentIndexChanged(int idx) { - - //set the correct property - std::vector pipelines; - pipelines = getDocument()->getObjectsOfType(); - if (!pipelines.empty()) { - Fem::FemPostPipeline* pipeline = pipelines.front(); - if (pipeline->Functions.getValue() && pipeline->Functions.getValue()->getTypeId() - == Fem::FemPostFunctionProvider::getClassTypeId()) { - - const std::vector& funcs = - static_cast(pipeline->Functions.getValue()) - ->Functions.getValues(); - if (idx >= 0) - static_cast(getObject())->Function.setValue(funcs[idx]); - else - static_cast(getObject())->Function.setValue(nullptr); - } - } - - //load the correct view - Fem::FemPostFunction* fobj = static_cast( - static_cast(getObject())->Function.getValue()); - Gui::ViewProvider* view = nullptr; - if (fobj) - view = Gui::Application::Instance->getViewProvider(fobj); - - if (fwidget) - fwidget->deleteLater(); - - if (view) { - fwidget = static_cast(view)->createControlWidget(); - fwidget->setParent(ui->Container); - fwidget->setViewProvider(static_cast(view)); - ui->Container->layout()->addWidget(fwidget); - } - recompute(); -} - -void TaskPostClip::on_CutCells_toggled(bool val) { - - static_cast(getObject())->CutCells.setValue(val); - recompute(); -} - -void TaskPostClip::on_InsideOut_toggled(bool val) { - - static_cast(getObject())->InsideOut.setValue(val); - recompute(); -} +// in the following, the different filters sorted alphabetically +// *************************************************************************** // *************************************************************************** -// data along a line +// data along line filter TaskPostDataAlongLine::TaskPostDataAlongLine(ViewProviderDocumentObject* view, QWidget* parent) : TaskPostBox(view, Gui::BitmapFactory().pixmap("FEM_PostFilterDataAlongLine"), tr("Data along a line options"), parent), ui(new Ui_TaskPostDataAlongLine) { - assert(view->isDerivedFrom(ViewProviderFemPostDataAlongLine::getClassTypeId())); //we load the views widget @@ -695,20 +546,34 @@ TaskPostDataAlongLine::TaskPostDataAlongLine(ViewProviderDocumentObject* view, Q int res = static_cast(getObject())->Resolution.getValue(); ui->resolution->setValue(res); - connect(ui->point1X, qOverload(&Gui::QuantitySpinBox::valueChanged), - this, &TaskPostDataAlongLine::point1Changed); - connect(ui->point1Y, qOverload(&Gui::QuantitySpinBox::valueChanged), - this, &TaskPostDataAlongLine::point1Changed); - connect(ui->point1Z, qOverload(&Gui::QuantitySpinBox::valueChanged), - this, &TaskPostDataAlongLine::point1Changed); - connect(ui->point2X, qOverload(&Gui::QuantitySpinBox::valueChanged), - this, &TaskPostDataAlongLine::point2Changed); - connect(ui->point2Y, qOverload(&Gui::QuantitySpinBox::valueChanged), - this, &TaskPostDataAlongLine::point2Changed); - connect(ui->point2Z, qOverload(&Gui::QuantitySpinBox::valueChanged), - this, &TaskPostDataAlongLine::point2Changed); - connect(ui->resolution, qOverload(&QSpinBox::valueChanged), - this, &TaskPostDataAlongLine::resolutionChanged); + connect(ui->point1X, + qOverload(&Gui::QuantitySpinBox::valueChanged), + this, + &TaskPostDataAlongLine::point1Changed); + connect(ui->point1Y, + qOverload(&Gui::QuantitySpinBox::valueChanged), + this, + &TaskPostDataAlongLine::point1Changed); + connect(ui->point1Z, + qOverload(&Gui::QuantitySpinBox::valueChanged), + this, + &TaskPostDataAlongLine::point1Changed); + connect(ui->point2X, + qOverload(&Gui::QuantitySpinBox::valueChanged), + this, + &TaskPostDataAlongLine::point2Changed); + connect(ui->point2Y, + qOverload(&Gui::QuantitySpinBox::valueChanged), + this, + &TaskPostDataAlongLine::point2Changed); + connect(ui->point2Z, + qOverload(&Gui::QuantitySpinBox::valueChanged), + this, + &TaskPostDataAlongLine::point2Changed); + connect(ui->resolution, + qOverload(&QSpinBox::valueChanged), + this, + &TaskPostDataAlongLine::resolutionChanged); //update all fields updateEnumerationList(getTypedView()->DisplayMode, @@ -717,39 +582,36 @@ TaskPostDataAlongLine::TaskPostDataAlongLine(ViewProviderDocumentObject* view, Q updateEnumerationList(getTypedView()->VectorMode, ui->VectorMode); } -TaskPostDataAlongLine::~TaskPostDataAlongLine() { +TaskPostDataAlongLine::~TaskPostDataAlongLine() +{} -} +void TaskPostDataAlongLine::applyPythonCode() +{} -void TaskPostDataAlongLine::applyPythonCode() { - -} - -static const char* cursor_triangle[] = { -"32 32 3 1", -" c None", -". c #FFFFFF", -"+ c #FF0000", -" . ", -" . ", -" . ", -" . ", -" . ", -" ", -"..... ..... ", -" ", -" . ", -" . ", -" . ++ ", -" . + + ", -" . + ++ + ", -" + ++++ + ", -" + ++ ++ + ", -" + ++++++++ + ", -" ++ ++ ++ ++ " }; - -void TaskPostDataAlongLine::on_SelectPoints_clicked() { +static const char* cursor_triangle[] = {"32 32 3 1", + " c None", + ". c #FFFFFF", + "+ c #FF0000", + " . ", + " . ", + " . ", + " . ", + " . ", + " ", + "..... ..... ", + " ", + " . ", + " . ", + " . ++ ", + " . + + ", + " . + ++ + ", + " + ++++ + ", + " + ++ ++ + ", + " + ++++++++ + ", + " ++ ++ ++ ++ "}; +void TaskPostDataAlongLine::on_SelectPoints_clicked() +{ Gui::Command::doCommand(Gui::Command::Doc, ObjectVisible().c_str()); Gui::Document* doc = Gui::Application::Instance->getDocument(getDocument()); Gui::View3DInventor* view = static_cast(doc->getActiveView()); @@ -764,13 +626,14 @@ void TaskPostDataAlongLine::on_SelectPoints_clicked() { FemGui::PointMarker* marker = new FemGui::PointMarker(viewer, ObjName); viewer->addEventCallback(SoMouseButtonEvent::getClassTypeId(), - FemGui::TaskPostDataAlongLine::pointCallback, marker); - connect(marker, &PointMarker::PointsChanged, - this, &TaskPostDataAlongLine::onChange); + FemGui::TaskPostDataAlongLine::pointCallback, + marker); + connect(marker, &PointMarker::PointsChanged, this, &TaskPostDataAlongLine::onChange); } } -std::string TaskPostDataAlongLine::ObjectVisible() { +std::string TaskPostDataAlongLine::ObjectVisible() +{ return "for amesh in App.activeDocument().Objects:\n\ if \"Mesh\" in amesh.TypeId:\n\ aparttoshow = amesh.Name.replace(\"_Mesh\",\"\")\n\ @@ -779,8 +642,8 @@ std::string TaskPostDataAlongLine::ObjectVisible() { apart.ViewObject.Visibility = True\n"; } -void TaskPostDataAlongLine::on_CreatePlot_clicked() { - +void TaskPostDataAlongLine::on_CreatePlot_clicked() +{ App::DocumentObjectT objT(getObject()); std::string ObjName = objT.getObjectPython(); Gui::doCommandT(Gui::Command::Doc, "x = %s.XAxisData", ObjName); @@ -793,7 +656,6 @@ void TaskPostDataAlongLine::on_CreatePlot_clicked() { void TaskPostDataAlongLine::onChange(double x1, double y1, double z1, double x2, double y2, double z2) { - // call point1Changed only once ui->point1X->blockSignals(true); ui->point1Y->blockSignals(true); @@ -819,11 +681,13 @@ void TaskPostDataAlongLine::onChange(double x1, double y1, double z1, double x2, point2Changed(0.0); } -void TaskPostDataAlongLine::point1Changed(double) { - +void TaskPostDataAlongLine::point1Changed(double) +{ try { std::string ObjName = getObject()->getNameInDocument(); - Gui::cmdAppDocumentArgs(getDocument(), "%s.Point1 = App.Vector(%f, %f, %f)", ObjName, + Gui::cmdAppDocumentArgs(getDocument(), + "%s.Point1 = App.Vector(%f, %f, %f)", + ObjName, ui->point1X->value().getValue(), ui->point1Y->value().getValue(), ui->point1Z->value().getValue()); @@ -841,11 +705,13 @@ void TaskPostDataAlongLine::point1Changed(double) { } } -void TaskPostDataAlongLine::point2Changed(double) { - +void TaskPostDataAlongLine::point2Changed(double) +{ try { std::string ObjName = getObject()->getNameInDocument(); - Gui::cmdAppDocumentArgs(getDocument(), "%s.Point2 = App.Vector(%f, %f, %f)", ObjName, + Gui::cmdAppDocumentArgs(getDocument(), + "%s.Point2 = App.Vector(%f, %f, %f)", + ObjName, ui->point2X->value().getValue(), ui->point2Y->value().getValue(), ui->point2Z->value().getValue()); @@ -863,8 +729,8 @@ void TaskPostDataAlongLine::point2Changed(double) { } } -void TaskPostDataAlongLine::resolutionChanged(int val) { - +void TaskPostDataAlongLine::resolutionChanged(int val) +{ static_cast(getObject())->Resolution.setValue(val); // recompute the feature getObject()->recomputeFeature(); @@ -910,27 +776,28 @@ void TaskPostDataAlongLine::pointCallback(void* ud, SoEventCallback* n) } } -void TaskPostDataAlongLine::on_Representation_activated(int i) { - +void TaskPostDataAlongLine::on_Representation_activated(int i) +{ getTypedView()->DisplayMode.setValue(i); updateEnumerationList(getTypedView()->Field, ui->Field); updateEnumerationList(getTypedView()->VectorMode, ui->VectorMode); } -void TaskPostDataAlongLine::on_Field_activated(int i) { - +void TaskPostDataAlongLine::on_Field_activated(int i) +{ getTypedView()->Field.setValue(i); std::string FieldName = ui->Field->currentText().toStdString(); static_cast(getObject())->PlotData.setValue(FieldName); updateEnumerationList(getTypedView()->VectorMode, ui->VectorMode); } -void TaskPostDataAlongLine::on_VectorMode_activated(int i) { - +void TaskPostDataAlongLine::on_VectorMode_activated(int i) +{ getTypedView()->VectorMode.setValue(i); } -std::string TaskPostDataAlongLine::Plot() { +std::string TaskPostDataAlongLine::Plot() +{ auto xlabel = tr("Length", "X-Axis plot label"); std::ostringstream oss; oss << "import FreeCAD\n\ @@ -940,7 +807,8 @@ from matplotlib import pyplot as plt\n\ plt.ioff()\n\ plt.figure(title)\n\ plt.plot(x, y)\n\ -plt.xlabel(\"" << xlabel.toStdString() << "\")\n\ +plt.xlabel(\"" + << xlabel.toStdString() << "\")\n\ plt.ylabel(title)\n\ plt.title(title)\n\ plt.grid()\n\ @@ -953,13 +821,12 @@ plt.show()\n"; // *************************************************************************** -// data at point +// data at point filter TaskPostDataAtPoint::TaskPostDataAtPoint(ViewProviderDocumentObject* view, QWidget* parent) : TaskPostBox(view, Gui::BitmapFactory().pixmap("FEM_PostFilterDataAtPoint"), tr("Data at point options"), parent), ui(new Ui_TaskPostDataAtPoint) { - assert(view->isDerivedFrom(ViewProviderFemPostDataAtPoint::getClassTypeId())); //we load the views widget @@ -996,57 +863,62 @@ TaskPostDataAtPoint::TaskPostDataAtPoint(ViewProviderDocumentObject* view, QWidg updateEnumerationList(getTypedView()->Field, ui->Field); // read in point value - auto pointValue = static_cast(getObject())->PointData[0]; + auto pointValue = static_cast(getObject())->PointData[0]; showValue(pointValue, static_cast(getObject())->Unit.getValue()); - connect(ui->centerX, qOverload(&Gui::QuantitySpinBox::valueChanged), - this, &TaskPostDataAtPoint::centerChanged); - connect(ui->centerY, qOverload(&Gui::QuantitySpinBox::valueChanged), - this, &TaskPostDataAtPoint::centerChanged); - connect(ui->centerZ, qOverload(&Gui::QuantitySpinBox::valueChanged), - this, &TaskPostDataAtPoint::centerChanged); + connect(ui->centerX, + qOverload(&Gui::QuantitySpinBox::valueChanged), + this, + &TaskPostDataAtPoint::centerChanged); + connect(ui->centerY, + qOverload(&Gui::QuantitySpinBox::valueChanged), + this, + &TaskPostDataAtPoint::centerChanged); + connect(ui->centerZ, + qOverload(&Gui::QuantitySpinBox::valueChanged), + this, + &TaskPostDataAtPoint::centerChanged); // the point filter object needs to be recomputed // to fill all fields with data at the current point getObject()->recomputeFeature(); } -TaskPostDataAtPoint::~TaskPostDataAtPoint() { +TaskPostDataAtPoint::~TaskPostDataAtPoint() +{ App::Document* doc = getDocument(); if (doc) doc->recompute(); } -void TaskPostDataAtPoint::applyPythonCode() { +void TaskPostDataAtPoint::applyPythonCode() +{} -} - -static const char* cursor_star[] = { -"32 17 3 1", -" c None", -". c #FFFFFF", -"+ c #FF0000", -" . ", -" . ", -" . ", -" . ", -" . ", -" ", -"..... ..... ", -" ", -" . ", -" . ", -" . ++ ", -" . + + ", -" . + ++ + ", -" + ++++ + ", -" + ++ ++ + ", -" + ++++++++ + ", -" ++ ++ ++ ++ " }; - -void TaskPostDataAtPoint::on_SelectPoint_clicked() { +static const char* cursor_star[] = {"32 17 3 1", + " c None", + ". c #FFFFFF", + "+ c #FF0000", + " . ", + " . ", + " . ", + " . ", + " . ", + " ", + "..... ..... ", + " ", + " . ", + " . ", + " . ++ ", + " . + + ", + " . + ++ + ", + " + ++++ + ", + " + ++ ++ + ", + " + ++++++++ + ", + " ++ ++ ++ ++ "}; +void TaskPostDataAtPoint::on_SelectPoint_clicked() +{ Gui::Command::doCommand(Gui::Command::Doc, ObjectVisible().c_str()); Gui::Document* doc = Gui::Application::Instance->getDocument(getDocument()); Gui::View3DInventor* view = static_cast(doc->getActiveView()); @@ -1061,14 +933,16 @@ void TaskPostDataAtPoint::on_SelectPoint_clicked() { FemGui::DataMarker* marker = new FemGui::DataMarker(viewer, ObjName); viewer->addEventCallback(SoMouseButtonEvent::getClassTypeId(), - FemGui::TaskPostDataAtPoint::pointCallback, marker); + FemGui::TaskPostDataAtPoint::pointCallback, + marker); connect(marker, &DataMarker::PointsChanged, this, &TaskPostDataAtPoint::onChange); } getTypedView()->DisplayMode.setValue(1); updateEnumerationList(getTypedView()->Field, ui->Field); } -std::string TaskPostDataAtPoint::ObjectVisible() { +std::string TaskPostDataAtPoint::ObjectVisible() +{ return "for amesh in App.activeDocument().Objects:\n\ if \"Mesh\" in amesh.TypeId:\n\ aparttoshow = amesh.Name.replace(\"_Mesh\",\"\")\n\ @@ -1077,7 +951,8 @@ std::string TaskPostDataAtPoint::ObjectVisible() { apart.ViewObject.Visibility = True\n"; } -void TaskPostDataAtPoint::onChange(double x, double y, double z) { +void TaskPostDataAtPoint::onChange(double x, double y, double z) +{ // call centerChanged only once ui->centerX->blockSignals(true); @@ -1092,11 +967,13 @@ void TaskPostDataAtPoint::onChange(double x, double y, double z) { centerChanged(0.0); } -void TaskPostDataAtPoint::centerChanged(double) { - +void TaskPostDataAtPoint::centerChanged(double) +{ try { std::string ObjName = getObject()->getNameInDocument(); - Gui::cmdAppDocumentArgs(getDocument(), "%s.Center = App.Vector(%f, %f, %f)", ObjName, + Gui::cmdAppDocumentArgs(getDocument(), + "%s.Center = App.Vector(%f, %f, %f)", + ObjName, ui->centerX->value().getValue(), ui->centerY->value().getValue(), ui->centerZ->value().getValue()); @@ -1148,8 +1025,8 @@ void TaskPostDataAtPoint::pointCallback(void* ud, SoEventCallback* n) } } -void TaskPostDataAtPoint::on_Field_activated(int i) { - +void TaskPostDataAtPoint::on_Field_activated(int i) +{ getTypedView()->Field.setValue(i); std::string FieldName = ui->Field->currentText().toStdString(); // there is no "None" for the FieldName property, thus return here @@ -1163,23 +1040,22 @@ void TaskPostDataAtPoint::on_Field_activated(int i) { // Set the unit for the different known result types. // CCX names - if ( (FieldName == "von Mises Stress") || (FieldName == "Tresca Stress") - || (FieldName == "Major Principal Stress") - || (FieldName == "Intermediate Principal Stress") - || (FieldName == "Minor Principal Stress") - || (FieldName == "Major Principal Stress Vector") + if ((FieldName == "von Mises Stress") || (FieldName == "Tresca Stress") + || (FieldName == "Major Principal Stress") || (FieldName == "Intermediate Principal Stress") + || (FieldName == "Minor Principal Stress") || (FieldName == "Major Principal Stress Vector") || (FieldName == "Intermediate Principal Stress Vector") - || (FieldName == "Minor Principal Stress Vector") - || (FieldName == "Stress xx component") || (FieldName == "Stress xy component") - || (FieldName == "Stress xz component") || (FieldName == "Stress yy component") - || (FieldName == "Stress yz component") || (FieldName == "Stress zz component") ) { + || (FieldName == "Minor Principal Stress Vector") || (FieldName == "Stress xx component") + || (FieldName == "Stress xy component") || (FieldName == "Stress xz component") + || (FieldName == "Stress yy component") || (FieldName == "Stress yz component") + || (FieldName == "Stress zz component")) { static_cast(getObject())->Unit.setValue("Pa"); } // The Elmer names are different. If there are EigenModes, the names are unique for // every mode. Therefore we only check for the beginning of the name. - else if ( (FieldName.find("tresca", 0) == 0) || (FieldName.find("vonmises", 0) == 0) - || (FieldName.find("stress_", 0) == 0) || (FieldName.find("principal stress", 0) == 0) ) { - static_cast(getObject())->Unit.setValue("Pa"); + else if ((FieldName.find("tresca", 0) == 0) || (FieldName.find("vonmises", 0) == 0) + || (FieldName.find("stress_", 0) == 0) + || (FieldName.find("principal stress", 0) == 0)) { + static_cast(getObject())->Unit.setValue("Pa"); } else if ((FieldName == "current density") || (FieldName == "current density re") || (FieldName == "current density im") || (FieldName == "current density abs")) { @@ -1197,7 +1073,7 @@ void TaskPostDataAtPoint::on_Field_activated(int i) { static_cast(getObject())->Unit.setValue("V/m"); } else if (FieldName == "electric flux") { - static_cast(getObject())->Unit.setValue("A*s/m^2"); + static_cast(getObject())->Unit.setValue("A*s/m^2"); } else if (FieldName == "electric force density") { static_cast(getObject())->Unit.setValue("N/m^2"); @@ -1239,7 +1115,7 @@ void TaskPostDataAtPoint::on_Field_activated(int i) { static_cast(getObject())->Unit.setValue("V"); } else if (FieldName == "potential flux") { - static_cast(getObject())->Unit.setValue("W/m^2"); + static_cast(getObject())->Unit.setValue("W/m^2"); } // potential loads are in Coulomb: https://www.elmerfem.org/forum/viewtopic.php?t=7780 else if (FieldName == "potential loads") { @@ -1253,7 +1129,7 @@ void TaskPostDataAtPoint::on_Field_activated(int i) { static_cast(getObject())->Unit.setValue("K"); } else if (FieldName == "temperature flux") { - static_cast(getObject())->Unit.setValue("W/m^2"); + static_cast(getObject())->Unit.setValue("W/m^2"); } else { static_cast(getObject())->Unit.setValue(""); @@ -1296,294 +1172,20 @@ std::string TaskPostDataAtPoint::toString(double val) const return valueStream.str(); } -// *************************************************************************** -// scalar clip filter -TaskPostScalarClip::TaskPostScalarClip(ViewProviderDocumentObject* view, QWidget* parent) - : TaskPostBox(view, Gui::BitmapFactory().pixmap("FEM_PostFilterClipScalar"), - tr("Scalar clip options"), parent), - ui(new Ui_TaskPostScalarClip) -{ - - assert(view->isDerivedFrom(ViewProviderFemPostScalarClip::getClassTypeId())); - - //we load the views widget - proxy = new QWidget(this); - ui->setupUi(proxy); - QMetaObject::connectSlotsByName(this); - this->groupLayout()->addWidget(proxy); - - //load the default values - updateEnumerationList(getTypedObject()->Scalars, ui->Scalar); - ui->InsideOut->setChecked( - static_cast(getObject())->InsideOut.getValue()); - App::PropertyFloatConstraint& scalar_prop = - static_cast(getObject())->Value; - double scalar_factor = scalar_prop.getValue(); - - // set spinbox scalar_factor, don't forget to sync the slider - ui->Value->blockSignals(true); - ui->Value->setValue(scalar_factor); - ui->Value->blockSignals(false); - - // sync the slider - // slider min = 0%, slider max = 100% - // - // scalar_factor - // slider_value = --------------- x 100 - // max - // - double max = scalar_prop.getConstraints()->UpperBound; - int slider_value = (scalar_factor / max) * 100.; - ui->Slider->blockSignals(true); - ui->Slider->setValue(slider_value); - ui->Slider->blockSignals(false); - Base::Console().Log( - "init: scalar_factor, slider_value: %f, %i: \n", scalar_factor, slider_value); -} - -TaskPostScalarClip::~TaskPostScalarClip() { - -} - -void TaskPostScalarClip::applyPythonCode() { - -} - -void TaskPostScalarClip::on_Scalar_currentIndexChanged(int idx) { - - static_cast(getObject())->Scalars.setValue(idx); - recompute(); - - // update constraints and values - App::PropertyFloatConstraint& scalar_prop = - static_cast(getObject())->Value; - double scalar_factor = scalar_prop.getValue(); - double min = scalar_prop.getConstraints()->LowerBound; - double max = scalar_prop.getConstraints()->UpperBound; - - ui->Maximum->setText(QString::number(min)); - ui->Minimum->setText(QString::number(max)); - - // set scalar_factor, don't forget to sync the slider - ui->Value->blockSignals(true); - ui->Value->setValue(scalar_factor); - ui->Value->blockSignals(false); - - // sync the slider - ui->Slider->blockSignals(true); - int slider_value = (scalar_factor / max) * 100.; - ui->Slider->setValue(slider_value); - ui->Slider->blockSignals(false); -} - -void TaskPostScalarClip::on_Slider_valueChanged(int v) { - - App::PropertyFloatConstraint& value = - static_cast(getObject())->Value; - double val = value.getConstraints()->LowerBound * (1 - double(v) / 100.) - + double(v) / 100. * value.getConstraints()->UpperBound; - - value.setValue(val); - recompute(); - - //don't forget to sync the spinbox - ui->Value->blockSignals(true); - ui->Value->setValue(val); - ui->Value->blockSignals(false); -} - -void TaskPostScalarClip::on_Value_valueChanged(double v) { - - App::PropertyFloatConstraint& value = - static_cast(getObject())->Value; - value.setValue(v); - recompute(); - - //don't forget to sync the slider - ui->Slider->blockSignals(true); - ui->Slider->setValue( - int(((v - value.getConstraints()->LowerBound) - / (value.getConstraints()->UpperBound - value.getConstraints()->LowerBound)) - * 100.)); - ui->Slider->blockSignals(false); -} - -void TaskPostScalarClip::on_InsideOut_toggled(bool val) { - - static_cast(getObject())->InsideOut.setValue(val); - recompute(); -} - // *************************************************************************** -// warp filter -// spinbox min, slider, spinbox max -// spinbox warp factor -TaskPostWarpVector::TaskPostWarpVector(ViewProviderDocumentObject* view, QWidget* parent) - : TaskPostBox(view, Gui::BitmapFactory().pixmap("FEM_PostFilterWarp"), tr("Warp options"), - parent), - ui(new Ui_TaskPostWarpVector) +// clip filter +TaskPostClip::TaskPostClip(ViewProviderDocumentObject* view, App::PropertyLink* function, + QWidget* parent) + : TaskPostBox(view, Gui::BitmapFactory().pixmap("FEM_PostFilterClipRegion"), + tr("Clip region, choose implicit function"), parent), + ui(new Ui_TaskPostClip) { - - assert(view->isDerivedFrom(ViewProviderFemPostWarpVector::getClassTypeId())); - - // we load the views widget - proxy = new QWidget(this); - ui->setupUi(proxy); - QMetaObject::connectSlotsByName(this); - this->groupLayout()->addWidget(proxy); - - // load the default values for warp display - updateEnumerationList(getTypedObject()->Vector, ui->Vector); - double warp_factor = static_cast(getObject()) - ->Factor.getValue();// get the standard warp factor - - // set spinbox warp_factor, don't forget to sync the slider - ui->Value->blockSignals(true); - ui->Value->setValue(warp_factor); - ui->Value->blockSignals(false); - - // set min and max, don't forget to sync the slider - // TODO if warp is set to standard 1.0, find a smarter way for standard min, max and warp_factor - // may be depend on grid boundbox and min max vector values - ui->Max->blockSignals(true); - ui->Max->setValue(warp_factor == 0 ? 1 : warp_factor * 10.); - ui->Max->blockSignals(false); - ui->Min->blockSignals(true); - ui->Min->setValue(warp_factor == 0 ? 0 : warp_factor / 10.); - ui->Min->blockSignals(false); - - // sync slider - ui->Slider->blockSignals(true); - // slider min = 0%, slider max = 100% - // - // ( warp_factor - min ) - // slider_value = ----------------------- x 100 - // ( max - min ) - // - int slider_value = - (warp_factor - ui->Min->value()) / (ui->Max->value() - ui->Min->value()) * 100.; - ui->Slider->setValue(slider_value); - ui->Slider->blockSignals(false); - Base::Console().Log("init: warp_factor, slider_value: %f, %i: \n", warp_factor, slider_value); -} - -TaskPostWarpVector::~TaskPostWarpVector() { - -} - -void TaskPostWarpVector::applyPythonCode() { - -} - -void TaskPostWarpVector::on_Vector_currentIndexChanged(int idx) { - // combobox to choose the result to warp - - static_cast(getObject())->Vector.setValue(idx); - recompute(); -} - -void TaskPostWarpVector::on_Slider_valueChanged(int slider_value) { - // slider changed, change warp factor and sync spinbox - - // - // ( max - min ) - // warp_factor = min + ( slider_value x --------------- ) - // 100 - // - double warp_factor = - ui->Min->value() + ((ui->Max->value() - ui->Min->value()) / 100.) * slider_value; - static_cast(getObject())->Factor.setValue(warp_factor); - recompute(); - - // sync the spinbox - ui->Value->blockSignals(true); - ui->Value->setValue(warp_factor); - ui->Value->blockSignals(false); - Base::Console().Log("Change: warp_factor, slider_value: %f, %i: \n", warp_factor, slider_value); -} - -void TaskPostWarpVector::on_Value_valueChanged(double warp_factor) { - // spinbox changed, change warp factor and sync slider - - // TODO warp factor should not be smaller than min and greater than max, - // but problems on automate change of warp_factor, see on_Max_valueChanged - - static_cast(getObject())->Factor.setValue(warp_factor); - recompute(); - - // sync the slider, see above for formula - ui->Slider->blockSignals(true); - int slider_value = - (warp_factor - ui->Min->value()) / (ui->Max->value() - ui->Min->value()) * 100.; - ui->Slider->setValue(slider_value); - ui->Slider->blockSignals(false); - Base::Console().Log("Change: warp_factor, slider_value: %f, %i: \n", warp_factor, slider_value); -} - -void TaskPostWarpVector::on_Max_valueChanged(double) { - - // TODO max should be greater than min, see a few lines later on problem on input characters - ui->Slider->blockSignals(true); - ui->Slider->setValue((ui->Value->value() - ui->Min->value()) - / (ui->Max->value() - ui->Min->value()) * 100.); - ui->Slider->blockSignals(false); - - /* - * problem, if warp_factor is 2000 one would like to input 4000 as max, one starts to input 4 - * immediately the warp_factor is changed to 4 because 4 < 2000, but one has just input - * one character of their 4000. * I do not know how to solve this, but the code to set slider - * and spinbox is fine thus I leave it ... - * - * mhh it works if "apply changes to pipeline directly" button is deactivated, - * still it really confuses if the button is active. More investigation is needed. - * - // set warp factor to max, if warp factor > max - if (ui->Value->value() > ui->Max->value()) { - double warp_factor = ui->Max->value(); - static_cast(getObject())->Factor.setValue(warp_factor); - recompute(); - - // sync the slider, see above for formula - ui->Slider->blockSignals(true); - int slider_value = (warp_factor - ui->Min->value()) - / (ui->Max->value() - ui->Min->value()) * 100.; - ui->Slider->setValue(slider_value); - ui->Slider->blockSignals(false); - // sync the spinbox, see above for formula - ui->Value->blockSignals(true); - ui->Value->setValue(warp_factor); - ui->Value->blockSignals(false); - Base::Console().Log("Change: warp_factor, slider_value: %f, %i: \n", warp_factor, slider_value); - } - */ -} - -void TaskPostWarpVector::on_Min_valueChanged(double) { - - // TODO min should be smaller than max - // TODO if warp factor is smaller than min, warp factor should be min, don't forget to sync - ui->Slider->blockSignals(true); - ui->Slider->setValue((ui->Value->value() - ui->Min->value()) - / (ui->Max->value() - ui->Min->value()) * 100.); - ui->Slider->blockSignals(false); -} - - -// *************************************************************************** -// function clip filter -TaskPostCut::TaskPostCut(ViewProviderDocumentObject* view, App::PropertyLink* function, - QWidget* parent) - : TaskPostBox(view, Gui::BitmapFactory().pixmap("FEM_PostFilterCutFunction"), - tr("Function cut, choose implicit function"), parent), - ui(new Ui_TaskPostCut) -{ - - assert(view->isDerivedFrom(ViewProviderFemPostCut::getClassTypeId())); + assert(view->isDerivedFrom(ViewProviderFemPostClip::getClassTypeId())); assert(function); - Q_UNUSED(function) + Q_UNUSED(function); - fwidget = nullptr; + fwidget = nullptr; //we load the views widget proxy = new QWidget(this); @@ -1604,24 +1206,27 @@ TaskPostCut::TaskPostCut(ViewProviderDocumentObject* view, App::PropertyLink* fu if (cmd && cmd->getAction()) cmd->getAction()->addTo(ui->CreateButton); ui->CreateButton->setPopupMode(QToolButton::InstantPopup); + + //load the default values + ui->CutCells->setChecked( + static_cast(getObject())->CutCells.getValue()); + ui->InsideOut->setChecked( + static_cast(getObject())->InsideOut.getValue()); } -TaskPostCut::~TaskPostCut() { +TaskPostClip::~TaskPostClip() +{} -} - -void TaskPostCut::applyPythonCode() { - -} - -void TaskPostCut::collectImplicitFunctions() { +void TaskPostClip::applyPythonCode() +{} +void TaskPostClip::collectImplicitFunctions() +{ std::vector pipelines; pipelines = getDocument()->getObjectsOfType(); if (!pipelines.empty()) { Fem::FemPostPipeline* pipeline = pipelines.front(); - if (pipeline->Functions.getValue() - && pipeline->Functions.getValue()->getTypeId() + if (pipeline->Functions.getValue() && pipeline->Functions.getValue()->getTypeId() == Fem::FemPostFunctionProvider::getClassTypeId()) { ui->FunctionBox->clear(); @@ -1643,8 +1248,8 @@ void TaskPostCut::collectImplicitFunctions() { } } -void TaskPostCut::on_CreateButton_triggered(QAction*) { - +void TaskPostClip::on_CreateButton_triggered(QAction*) +{ int numFuncs = ui->FunctionBox->count(); int currentItem = ui->FunctionBox->currentIndex(); collectImplicitFunctions(); @@ -1662,30 +1267,29 @@ void TaskPostCut::on_CreateButton_triggered(QAction*) { recompute(); } -void TaskPostCut::on_FunctionBox_currentIndexChanged(int idx) { - +void TaskPostClip::on_FunctionBox_currentIndexChanged(int idx) +{ //set the correct property std::vector pipelines; pipelines = getDocument()->getObjectsOfType(); if (!pipelines.empty()) { Fem::FemPostPipeline* pipeline = pipelines.front(); - if (pipeline->Functions.getValue() - && pipeline->Functions.getValue()->getTypeId() + if (pipeline->Functions.getValue() && pipeline->Functions.getValue()->getTypeId() == Fem::FemPostFunctionProvider::getClassTypeId()) { const std::vector& funcs = static_cast(pipeline->Functions.getValue()) ->Functions.getValues(); if (idx >= 0) - static_cast(getObject())->Function.setValue(funcs[idx]); + static_cast(getObject())->Function.setValue(funcs[idx]); else - static_cast(getObject())->Function.setValue(nullptr); + static_cast(getObject())->Function.setValue(nullptr); } } //load the correct view Fem::FemPostFunction* fobj = static_cast( - static_cast(getObject())->Function.getValue()); + static_cast(getObject())->Function.getValue()); Gui::ViewProvider* view = nullptr; if (fobj) view = Gui::Application::Instance->getViewProvider(fobj); @@ -1702,6 +1306,18 @@ void TaskPostCut::on_FunctionBox_currentIndexChanged(int idx) { recompute(); } +void TaskPostClip::on_CutCells_toggled(bool val) +{ + static_cast(getObject())->CutCells.setValue(val); + recompute(); +} + +void TaskPostClip::on_InsideOut_toggled(bool val) +{ + static_cast(getObject())->InsideOut.setValue(val); + recompute(); +} + // *************************************************************************** // contours filter @@ -1732,14 +1348,19 @@ TaskPostContours::TaskPostContours(ViewProviderDocumentObject* view, QWidget* pa ui->noColorCB->setChecked(colorState); // connect - connect(ui->fieldsCB, qOverload(&QComboBox::currentIndexChanged), - this, &TaskPostContours::onFieldsChanged); - connect(ui->vectorsCB, qOverload(&QComboBox::currentIndexChanged), - this, &TaskPostContours::onVectorModeChanged); - connect(ui->numberContoursSB, qOverload(&QSpinBox::valueChanged), - this, &TaskPostContours::onNumberOfContoursChanged); - connect(ui->noColorCB, &QCheckBox::toggled, - this, &TaskPostContours::onNoColorChanged); + connect(ui->fieldsCB, + qOverload(&QComboBox::currentIndexChanged), + this, + &TaskPostContours::onFieldsChanged); + connect(ui->vectorsCB, + qOverload(&QComboBox::currentIndexChanged), + this, + &TaskPostContours::onVectorModeChanged); + connect(ui->numberContoursSB, + qOverload(&QSpinBox::valueChanged), + this, + &TaskPostContours::onNumberOfContoursChanged); + connect(ui->noColorCB, &QCheckBox::toggled, this, &TaskPostContours::onNoColorChanged); } TaskPostContours::~TaskPostContours() @@ -1835,4 +1456,403 @@ void TaskPostContours::onNoColorChanged(bool state) } +// *************************************************************************** +// cut filter +TaskPostCut::TaskPostCut(ViewProviderDocumentObject* view, App::PropertyLink* function, + QWidget* parent) + : TaskPostBox(view, Gui::BitmapFactory().pixmap("FEM_PostFilterCutFunction"), + tr("Function cut, choose implicit function"), parent), + ui(new Ui_TaskPostCut) +{ + assert(view->isDerivedFrom(ViewProviderFemPostCut::getClassTypeId())); + assert(function); + Q_UNUSED(function) + + fwidget = nullptr; + + //we load the views widget + proxy = new QWidget(this); + ui->setupUi(proxy); + QMetaObject::connectSlotsByName(this); + this->groupLayout()->addWidget(proxy); + + //the layout for the container widget + QVBoxLayout* layout = new QVBoxLayout(); + ui->Container->setLayout(layout); + + //fill up the combo box with possible functions + collectImplicitFunctions(); + + //add the function creation command + Gui::CommandManager& rcCmdMgr = Gui::Application::Instance->commandManager(); + Gui::Command* cmd = rcCmdMgr.getCommandByName("FEM_PostCreateFunctions"); + if (cmd && cmd->getAction()) + cmd->getAction()->addTo(ui->CreateButton); + ui->CreateButton->setPopupMode(QToolButton::InstantPopup); +} + +TaskPostCut::~TaskPostCut() +{} + +void TaskPostCut::applyPythonCode() +{} + +void TaskPostCut::collectImplicitFunctions() +{ + std::vector pipelines; + pipelines = getDocument()->getObjectsOfType(); + if (!pipelines.empty()) { + Fem::FemPostPipeline* pipeline = pipelines.front(); + if (pipeline->Functions.getValue() + && pipeline->Functions.getValue()->getTypeId() + == Fem::FemPostFunctionProvider::getClassTypeId()) { + + ui->FunctionBox->clear(); + QStringList items; + std::size_t currentItem = 0; + App::DocumentObject* currentFunction = + static_cast(getObject())->Function.getValue(); + const std::vector& funcs = + static_cast(pipeline->Functions.getValue()) + ->Functions.getValues(); + for (std::size_t i = 0; i < funcs.size(); ++i) { + items.push_back(QString::fromLatin1(funcs[i]->getNameInDocument())); + if (currentFunction == funcs[i]) + currentItem = i; + } + ui->FunctionBox->addItems(items); + ui->FunctionBox->setCurrentIndex(currentItem); + } + } +} + +void TaskPostCut::on_CreateButton_triggered(QAction*) +{ + int numFuncs = ui->FunctionBox->count(); + int currentItem = ui->FunctionBox->currentIndex(); + collectImplicitFunctions(); + + // if a new function was successfully added use it + int indexCount = ui->FunctionBox->count(); + if (indexCount > currentItem + 1) + ui->FunctionBox->setCurrentIndex(indexCount - 1); + + // When the first function ever was added, a signal must be emitted + if (numFuncs == 0) { + Q_EMIT emitAddedFunction(); + } + + recompute(); +} + +void TaskPostCut::on_FunctionBox_currentIndexChanged(int idx) +{ + //set the correct property + std::vector pipelines; + pipelines = getDocument()->getObjectsOfType(); + if (!pipelines.empty()) { + Fem::FemPostPipeline* pipeline = pipelines.front(); + if (pipeline->Functions.getValue() + && pipeline->Functions.getValue()->getTypeId() + == Fem::FemPostFunctionProvider::getClassTypeId()) { + + const std::vector& funcs = + static_cast(pipeline->Functions.getValue()) + ->Functions.getValues(); + if (idx >= 0) + static_cast(getObject())->Function.setValue(funcs[idx]); + else + static_cast(getObject())->Function.setValue(nullptr); + } + } + + //load the correct view + Fem::FemPostFunction* fobj = static_cast( + static_cast(getObject())->Function.getValue()); + Gui::ViewProvider* view = nullptr; + if (fobj) + view = Gui::Application::Instance->getViewProvider(fobj); + + if (fwidget) + fwidget->deleteLater(); + + if (view) { + fwidget = static_cast(view)->createControlWidget(); + fwidget->setParent(ui->Container); + fwidget->setViewProvider(static_cast(view)); + ui->Container->layout()->addWidget(fwidget); + } + recompute(); +} + + +// *************************************************************************** +// scalar clip filter +TaskPostScalarClip::TaskPostScalarClip(ViewProviderDocumentObject* view, QWidget* parent) + : TaskPostBox(view, Gui::BitmapFactory().pixmap("FEM_PostFilterClipScalar"), + tr("Scalar clip options"), parent), + ui(new Ui_TaskPostScalarClip) +{ + assert(view->isDerivedFrom(ViewProviderFemPostScalarClip::getClassTypeId())); + + //we load the views widget + proxy = new QWidget(this); + ui->setupUi(proxy); + QMetaObject::connectSlotsByName(this); + this->groupLayout()->addWidget(proxy); + + //load the default values + updateEnumerationList(getTypedObject()->Scalars, ui->Scalar); + ui->InsideOut->setChecked( + static_cast(getObject())->InsideOut.getValue()); + App::PropertyFloatConstraint& scalar_prop = + static_cast(getObject())->Value; + double scalar_factor = scalar_prop.getValue(); + + // set spinbox scalar_factor, don't forget to sync the slider + ui->Value->blockSignals(true); + ui->Value->setValue(scalar_factor); + ui->Value->blockSignals(false); + + // sync the slider + // slider min = 0%, slider max = 100% + // + // scalar_factor + // slider_value = --------------- x 100 + // max + // + double max = scalar_prop.getConstraints()->UpperBound; + int slider_value = (scalar_factor / max) * 100.; + ui->Slider->blockSignals(true); + ui->Slider->setValue(slider_value); + ui->Slider->blockSignals(false); + Base::Console().Log( + "init: scalar_factor, slider_value: %f, %i: \n", scalar_factor, slider_value); +} + +TaskPostScalarClip::~TaskPostScalarClip() +{} + +void TaskPostScalarClip::applyPythonCode() +{} + +void TaskPostScalarClip::on_Scalar_currentIndexChanged(int idx) +{ + static_cast(getObject())->Scalars.setValue(idx); + recompute(); + + // update constraints and values + App::PropertyFloatConstraint& scalar_prop = + static_cast(getObject())->Value; + double scalar_factor = scalar_prop.getValue(); + double min = scalar_prop.getConstraints()->LowerBound; + double max = scalar_prop.getConstraints()->UpperBound; + + ui->Maximum->setText(QString::number(min)); + ui->Minimum->setText(QString::number(max)); + + // set scalar_factor, don't forget to sync the slider + ui->Value->blockSignals(true); + ui->Value->setValue(scalar_factor); + ui->Value->blockSignals(false); + + // sync the slider + ui->Slider->blockSignals(true); + int slider_value = (scalar_factor / max) * 100.; + ui->Slider->setValue(slider_value); + ui->Slider->blockSignals(false); +} + +void TaskPostScalarClip::on_Slider_valueChanged(int v) +{ + App::PropertyFloatConstraint& value = + static_cast(getObject())->Value; + double val = value.getConstraints()->LowerBound * (1 - double(v) / 100.) + + double(v) / 100. * value.getConstraints()->UpperBound; + + value.setValue(val); + recompute(); + + //don't forget to sync the spinbox + ui->Value->blockSignals(true); + ui->Value->setValue(val); + ui->Value->blockSignals(false); +} + +void TaskPostScalarClip::on_Value_valueChanged(double v) +{ + App::PropertyFloatConstraint& value = + static_cast(getObject())->Value; + value.setValue(v); + recompute(); + + //don't forget to sync the slider + ui->Slider->blockSignals(true); + ui->Slider->setValue( + int(((v - value.getConstraints()->LowerBound) + / (value.getConstraints()->UpperBound - value.getConstraints()->LowerBound)) + * 100.)); + ui->Slider->blockSignals(false); +} + +void TaskPostScalarClip::on_InsideOut_toggled(bool val) +{ + static_cast(getObject())->InsideOut.setValue(val); + recompute(); +} + + +// *************************************************************************** +// warp vector filter +TaskPostWarpVector::TaskPostWarpVector(ViewProviderDocumentObject* view, QWidget* parent) + : TaskPostBox(view, Gui::BitmapFactory().pixmap("FEM_PostFilterWarp"), tr("Warp options"), + parent), + ui(new Ui_TaskPostWarpVector) +{ + assert(view->isDerivedFrom(ViewProviderFemPostWarpVector::getClassTypeId())); + + // we load the views widget + proxy = new QWidget(this); + ui->setupUi(proxy); + QMetaObject::connectSlotsByName(this); + this->groupLayout()->addWidget(proxy); + + // load the default values for warp display + updateEnumerationList(getTypedObject()->Vector, ui->Vector); + double warp_factor = static_cast(getObject()) + ->Factor.getValue();// get the standard warp factor + + // set spinbox warp_factor, don't forget to sync the slider + ui->Value->blockSignals(true); + ui->Value->setValue(warp_factor); + ui->Value->blockSignals(false); + + // set min and max, don't forget to sync the slider + // TODO if warp is set to standard 1.0, find a smarter way for standard min, max + // and warp_factor may be depend on grid boundbox and min max vector values + ui->Max->blockSignals(true); + ui->Max->setValue(warp_factor == 0 ? 1 : warp_factor * 10.); + ui->Max->blockSignals(false); + ui->Min->blockSignals(true); + ui->Min->setValue(warp_factor == 0 ? 0 : warp_factor / 10.); + ui->Min->blockSignals(false); + + // sync slider + ui->Slider->blockSignals(true); + // slider min = 0%, slider max = 100% + // + // ( warp_factor - min ) + // slider_value = ----------------------- x 100 + // ( max - min ) + // + int slider_value = + (warp_factor - ui->Min->value()) / (ui->Max->value() - ui->Min->value()) * 100.; + ui->Slider->setValue(slider_value); + ui->Slider->blockSignals(false); + Base::Console().Log("init: warp_factor, slider_value: %f, %i: \n", warp_factor, slider_value); +} + +TaskPostWarpVector::~TaskPostWarpVector() +{} + +void TaskPostWarpVector::applyPythonCode() +{} + +void TaskPostWarpVector::on_Vector_currentIndexChanged(int idx) +{ + // combobox to choose the result to warp + + static_cast(getObject())->Vector.setValue(idx); + recompute(); +} + +void TaskPostWarpVector::on_Slider_valueChanged(int slider_value) +{ + // slider changed, change warp factor and sync spinbox + + // + // ( max - min ) + // warp_factor = min + ( slider_value x --------------- ) + // 100 + // + double warp_factor = + ui->Min->value() + ((ui->Max->value() - ui->Min->value()) / 100.) * slider_value; + static_cast(getObject())->Factor.setValue(warp_factor); + recompute(); + + // sync the spinbox + ui->Value->blockSignals(true); + ui->Value->setValue(warp_factor); + ui->Value->blockSignals(false); + Base::Console().Log("Change: warp_factor, slider_value: %f, %i: \n", warp_factor, slider_value); +} + +void TaskPostWarpVector::on_Value_valueChanged(double warp_factor) +{ + // spinbox changed, change warp factor and sync slider + + // TODO warp factor should not be smaller than min and greater than max, + // but problems on automate change of warp_factor, see on_Max_valueChanged + + static_cast(getObject())->Factor.setValue(warp_factor); + recompute(); + + // sync the slider, see above for formula + ui->Slider->blockSignals(true); + int slider_value = + (warp_factor - ui->Min->value()) / (ui->Max->value() - ui->Min->value()) * 100.; + ui->Slider->setValue(slider_value); + ui->Slider->blockSignals(false); + Base::Console().Log("Change: warp_factor, slider_value: %f, %i: \n", warp_factor, slider_value); +} + +void TaskPostWarpVector::on_Max_valueChanged(double) +{ + // TODO max should be greater than min, see a few lines later on problem on input characters + ui->Slider->blockSignals(true); + ui->Slider->setValue((ui->Value->value() - ui->Min->value()) + / (ui->Max->value() - ui->Min->value()) * 100.); + ui->Slider->blockSignals(false); + + /* + * problem, if warp_factor is 2000 one would like to input 4000 as max, one starts to input 4 + * immediately the warp_factor is changed to 4 because 4 < 2000, but one has just input + * one character of their 4000. * I do not know how to solve this, but the code to set slider + * and spinbox is fine thus I leave it ... + * + * mhh it works if "apply changes to pipeline directly" button is deactivated, + * still it really confuses if the button is active. More investigation is needed. + * + // set warp factor to max, if warp factor > max + if (ui->Value->value() > ui->Max->value()) { + double warp_factor = ui->Max->value(); + static_cast(getObject())->Factor.setValue(warp_factor); + recompute(); + + // sync the slider, see above for formula + ui->Slider->blockSignals(true); + int slider_value = (warp_factor - ui->Min->value()) + / (ui->Max->value() - ui->Min->value()) * 100.; + ui->Slider->setValue(slider_value); + ui->Slider->blockSignals(false); + // sync the spinbox, see above for formula + ui->Value->blockSignals(true); + ui->Value->setValue(warp_factor); + ui->Value->blockSignals(false); + Base::Console().Log("Change: warp_factor, slider_value: %f, %i: \n", warp_factor, slider_value); + } + */ +} + +void TaskPostWarpVector::on_Min_valueChanged(double) +{ + // TODO min should be smaller than max + // TODO if warp factor is smaller than min, warp factor should be min, don't forget to sync + ui->Slider->blockSignals(true); + ui->Slider->setValue((ui->Value->value() - ui->Min->value()) + / (ui->Max->value() - ui->Min->value()) * 100.); + ui->Slider->blockSignals(false); +} + + #include "moc_TaskPostBoxes.cpp" diff --git a/src/Mod/Fem/Gui/TaskPostBoxes.h b/src/Mod/Fem/Gui/TaskPostBoxes.h index a67977fe6c..0a6e5e7803 100644 --- a/src/Mod/Fem/Gui/TaskPostBoxes.h +++ b/src/Mod/Fem/Gui/TaskPostBoxes.h @@ -51,8 +51,11 @@ class SoEventCallback; class SoMarkerSet; -namespace FemGui { +namespace FemGui +{ +// *************************************************************************** +// point marker class ViewProviderPointMarker; class PointMarker : public QObject { @@ -78,7 +81,6 @@ private: std::string ObjectInvisible(); }; - class FemGuiExport ViewProviderPointMarker : public Gui::ViewProviderDocumentObject { PROPERTY_HEADER_WITH_OVERRIDE(FemGui::ViewProviderPointMarker); @@ -93,6 +95,8 @@ protected: }; +// *************************************************************************** +// data marker class ViewProviderDataMarker; class DataMarker : public QObject { @@ -133,8 +137,11 @@ protected: friend class DataMarker; }; -class TaskPostBox : public Gui::TaskView::TaskBox { +// *************************************************************************** +// main task dialog +class TaskPostBox : public Gui::TaskView::TaskBox +{ Q_OBJECT public: @@ -176,7 +183,8 @@ private: }; -/// simulation dialog for the TaskView +// *************************************************************************** +// simulation dialog for the TaskView class TaskDlgPost : public Gui::TaskView::TaskDialog { Q_OBJECT @@ -217,6 +225,8 @@ protected: }; +// *************************************************************************** +// box to set the coloring class TaskPostDisplay : public TaskPostBox { Q_OBJECT @@ -241,8 +251,10 @@ private: }; -class TaskPostFunction : public TaskPostBox { - +// *************************************************************************** +// functions +class TaskPostFunction : public TaskPostBox +{ Q_OBJECT public: @@ -253,8 +265,76 @@ public: }; -class TaskPostClip : public TaskPostBox { +// *************************************************************************** +// in the following, the different filters sorted alphabetically +// *************************************************************************** + +// *************************************************************************** +// data along line filter +class TaskPostDataAlongLine: public TaskPostBox +{ + Q_OBJECT + +public: + explicit TaskPostDataAlongLine(Gui::ViewProviderDocumentObject* view, + QWidget* parent = nullptr); + ~TaskPostDataAlongLine() override; + + void applyPythonCode() override; + static void pointCallback(void* ud, SoEventCallback* n); + +private Q_SLOTS: + void on_SelectPoints_clicked(); + void on_CreatePlot_clicked(); + void on_Representation_activated(int i); + void on_Field_activated(int i); + void on_VectorMode_activated(int i); + void point2Changed(double); + void point1Changed(double); + void resolutionChanged(int val); + void onChange(double x1, double y1, double z1, double x2, double y2, double z2); + +private: + std::string Plot(); + std::string ObjectVisible(); + QWidget* proxy; + std::unique_ptr ui; +}; + + +// *************************************************************************** +// data at point filter +class TaskPostDataAtPoint: public TaskPostBox +{ + Q_OBJECT + +public: + explicit TaskPostDataAtPoint(Gui::ViewProviderDocumentObject* view, QWidget* parent = nullptr); + ~TaskPostDataAtPoint() override; + + void applyPythonCode() override; + static void pointCallback(void* ud, SoEventCallback* n); + +private Q_SLOTS: + void on_SelectPoint_clicked(); + void on_Field_activated(int i); + void centerChanged(double); + void onChange(double x, double y, double z); + +private: + std::string toString(double val) const; + void showValue(double value, const char* unit); + std::string ObjectVisible(); + QWidget* proxy; + std::unique_ptr ui; +}; + + +// *************************************************************************** +// clip filter +class TaskPostClip : public TaskPostBox +{ Q_OBJECT public: @@ -283,140 +363,8 @@ private: }; -class TaskPostDataAlongLine: public TaskPostBox { - - Q_OBJECT - -public: - explicit TaskPostDataAlongLine(Gui::ViewProviderDocumentObject* view, - QWidget* parent = nullptr); - ~TaskPostDataAlongLine() override; - - void applyPythonCode() override; - static void pointCallback(void * ud, SoEventCallback * n); - -private Q_SLOTS: - void on_SelectPoints_clicked(); - void on_CreatePlot_clicked(); - void on_Representation_activated(int i); - void on_Field_activated(int i); - void on_VectorMode_activated(int i); - void point2Changed(double); - void point1Changed(double); - void resolutionChanged(int val); - void onChange(double x1, double y1, double z1, double x2, double y2, double z2); - - -private: - std::string Plot(); - std::string ObjectVisible(); - QWidget* proxy; - std::unique_ptr ui; -}; - - -class TaskPostDataAtPoint: public TaskPostBox { - - Q_OBJECT - -public: - explicit TaskPostDataAtPoint(Gui::ViewProviderDocumentObject* view, QWidget* parent = nullptr); - ~TaskPostDataAtPoint() override; - - void applyPythonCode() override; - static void pointCallback(void * ud, SoEventCallback * n); - -private Q_SLOTS: - void on_SelectPoint_clicked(); - void on_Field_activated(int i); - void centerChanged(double); - void onChange(double x, double y, double z); - -private: - std::string toString(double val) const; - void showValue(double value, const char* unit); - - -private: - std::string ObjectVisible(); - QWidget* proxy; - std::unique_ptr ui; -}; - - -class TaskPostScalarClip : public TaskPostBox { - - Q_OBJECT - -public: - explicit TaskPostScalarClip(Gui::ViewProviderDocumentObject* view, QWidget* parent = nullptr); - ~TaskPostScalarClip() override; - - void applyPythonCode() override; - -private Q_SLOTS: - void on_Slider_valueChanged(int v); - void on_Value_valueChanged(double v); - void on_Scalar_currentIndexChanged(int idx); - void on_InsideOut_toggled(bool val); - -private: - QWidget* proxy; - std::unique_ptr ui; -}; - - -class TaskPostWarpVector : public TaskPostBox { - - Q_OBJECT - -public: - explicit TaskPostWarpVector(Gui::ViewProviderDocumentObject* view, QWidget* parent = nullptr); - ~TaskPostWarpVector() override; - - void applyPythonCode() override; - -private Q_SLOTS: - void on_Slider_valueChanged(int v); - void on_Value_valueChanged(double v); - void on_Max_valueChanged(double); - void on_Min_valueChanged(double); - void on_Vector_currentIndexChanged(int idx); - -private: - QWidget* proxy; - std::unique_ptr ui; -}; - - -class TaskPostCut : public TaskPostBox { - - Q_OBJECT - -public: - TaskPostCut(Gui::ViewProviderDocumentObject* view, App::PropertyLink* function, - QWidget* parent = nullptr); - ~TaskPostCut() override; - - void applyPythonCode() override; - -private Q_SLOTS: - void on_CreateButton_triggered(QAction*); - void on_FunctionBox_currentIndexChanged(int idx); - -Q_SIGNALS: - void emitAddedFunction(); - -private: - void collectImplicitFunctions(); - - //App::PropertyLink* m_functionProperty; - QWidget* proxy; - std::unique_ptr ui; - FunctionWidget* fwidget; -}; - - +// *************************************************************************** +// contours filter class TaskPostContours: public TaskPostBox { Q_OBJECT @@ -440,6 +388,85 @@ private: void updateFields(int idx); }; + +// *************************************************************************** +// cut filter +class TaskPostCut: public TaskPostBox +{ + Q_OBJECT + +public: + TaskPostCut(Gui::ViewProviderDocumentObject* view, App::PropertyLink* function, + QWidget* parent = nullptr); + ~TaskPostCut() override; + + void applyPythonCode() override; + +private Q_SLOTS: + void on_CreateButton_triggered(QAction*); + void on_FunctionBox_currentIndexChanged(int idx); + +Q_SIGNALS: + void emitAddedFunction(); + +private: + void collectImplicitFunctions(); + + //App::PropertyLink* m_functionProperty; + QWidget* proxy; + std::unique_ptr ui; + FunctionWidget* fwidget; +}; + + +// *************************************************************************** +// scalar clip filter +class TaskPostScalarClip : public TaskPostBox +{ + Q_OBJECT + +public: + explicit TaskPostScalarClip(Gui::ViewProviderDocumentObject* view, QWidget* parent = nullptr); + ~TaskPostScalarClip() override; + + void applyPythonCode() override; + +private Q_SLOTS: + void on_Slider_valueChanged(int v); + void on_Value_valueChanged(double v); + void on_Scalar_currentIndexChanged(int idx); + void on_InsideOut_toggled(bool val); + +private: + QWidget* proxy; + std::unique_ptr ui; +}; + + +// *************************************************************************** +// warp vector filter +class TaskPostWarpVector : public TaskPostBox +{ + Q_OBJECT + +public: + explicit TaskPostWarpVector(Gui::ViewProviderDocumentObject* view, QWidget* parent = nullptr); + ~TaskPostWarpVector() override; + + void applyPythonCode() override; + +private Q_SLOTS: + void on_Slider_valueChanged(int v); + void on_Value_valueChanged(double v); + void on_Max_valueChanged(double); + void on_Min_valueChanged(double); + void on_Vector_currentIndexChanged(int idx); + +private: + QWidget* proxy; + std::unique_ptr ui; +}; + } //namespace FemGui #endif // GUI_TASKVIEW_TaskPostDisplay_H diff --git a/src/Mod/Fem/Gui/ViewProviderFemPostFilter.cpp b/src/Mod/Fem/Gui/ViewProviderFemPostFilter.cpp index 9c954dd222..c991c80253 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemPostFilter.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemPostFilter.cpp @@ -30,6 +30,63 @@ using namespace FemGui; +// *************************************************************************** +// in the following, the different filters sorted alphabetically +// *************************************************************************** + + +// *************************************************************************** +// data along line filter +PROPERTY_SOURCE(FemGui::ViewProviderFemPostDataAlongLine, FemGui::ViewProviderFemPostObject) + +ViewProviderFemPostDataAlongLine::ViewProviderFemPostDataAlongLine() +{ + sPixmap = "FEM_PostFilterDataAlongLine"; +} + +ViewProviderFemPostDataAlongLine::~ViewProviderFemPostDataAlongLine() +{} + +void ViewProviderFemPostDataAlongLine::setupTaskDialog(TaskDlgPost* dlg) +{ + //add the function box + dlg->appendBox(new TaskPostDataAlongLine(dlg->getView())); +} + + +// *************************************************************************** +// data at point filter +PROPERTY_SOURCE(FemGui::ViewProviderFemPostDataAtPoint, FemGui::ViewProviderFemPostObject) + +ViewProviderFemPostDataAtPoint::ViewProviderFemPostDataAtPoint() +{ + sPixmap = "FEM_PostFilterDataAtPoint"; +} + +void ViewProviderFemPostDataAtPoint::show() +{ + Gui::ViewProviderDocumentObject::show(); +} + +void ViewProviderFemPostDataAtPoint::onSelectionChanged(const Gui::SelectionChanges&) +{ + // do not do anything here + // For DataAtPoint the color bar must not be refreshed when it is selected + // because a single point does not make sense with a color range. +} + +ViewProviderFemPostDataAtPoint::~ViewProviderFemPostDataAtPoint() +{} + +void ViewProviderFemPostDataAtPoint::setupTaskDialog(TaskDlgPost* dlg) +{ + //add the function box + dlg->appendBox(new TaskPostDataAtPoint(dlg->getView())); +} + + +// *************************************************************************** +// clip filter PROPERTY_SOURCE(FemGui::ViewProviderFemPostClip, FemGui::ViewProviderFemPostObject) ViewProviderFemPostClip::ViewProviderFemPostClip() { @@ -37,9 +94,8 @@ ViewProviderFemPostClip::ViewProviderFemPostClip() { sPixmap = "FEM_PostFilterClipRegion"; } -ViewProviderFemPostClip::~ViewProviderFemPostClip() { - -} +ViewProviderFemPostClip::~ViewProviderFemPostClip() +{} void ViewProviderFemPostClip::setupTaskDialog(TaskDlgPost* dlg) { @@ -51,115 +107,9 @@ void ViewProviderFemPostClip::setupTaskDialog(TaskDlgPost* dlg) { FemGui::ViewProviderFemPostObject::setupTaskDialog(dlg); } -PROPERTY_SOURCE(FemGui::ViewProviderFemPostDataAlongLine, FemGui::ViewProviderFemPostObject) - -ViewProviderFemPostDataAlongLine::ViewProviderFemPostDataAlongLine() { - - sPixmap = "FEM_PostFilterDataAlongLine"; -} - -ViewProviderFemPostDataAlongLine::~ViewProviderFemPostDataAlongLine() { - -} - -void ViewProviderFemPostDataAlongLine::setupTaskDialog(TaskDlgPost* dlg) { - - //add the function box - dlg->appendBox(new TaskPostDataAlongLine(dlg->getView())); - -} - -PROPERTY_SOURCE(FemGui::ViewProviderFemPostDataAtPoint, FemGui::ViewProviderFemPostObject) - -ViewProviderFemPostDataAtPoint::ViewProviderFemPostDataAtPoint() { - - sPixmap = "FEM_PostFilterDataAtPoint"; -} - -void ViewProviderFemPostDataAtPoint::show() -{ - Gui::ViewProviderDocumentObject::show(); -} - -void ViewProviderFemPostDataAtPoint::onSelectionChanged(const Gui::SelectionChanges &) -{ - // do not do anything here - // For DataAtPoint the color bar must not be refreshed when it is selected - // because a single point does not make sense with a color range. -} - -ViewProviderFemPostDataAtPoint::~ViewProviderFemPostDataAtPoint() { - -} - -void ViewProviderFemPostDataAtPoint::setupTaskDialog(TaskDlgPost* dlg) { - - //add the function box - dlg->appendBox(new TaskPostDataAtPoint(dlg->getView())); - -} - -PROPERTY_SOURCE(FemGui::ViewProviderFemPostScalarClip, FemGui::ViewProviderFemPostObject) - -ViewProviderFemPostScalarClip::ViewProviderFemPostScalarClip() { - - sPixmap = "FEM_PostFilterClipScalar"; -} - -ViewProviderFemPostScalarClip::~ViewProviderFemPostScalarClip() { - -} - -void ViewProviderFemPostScalarClip::setupTaskDialog(TaskDlgPost* dlg) { - - //add the function box - dlg->appendBox(new TaskPostScalarClip(dlg->getView())); - - //add the display options - FemGui::ViewProviderFemPostObject::setupTaskDialog(dlg); -} - -PROPERTY_SOURCE(FemGui::ViewProviderFemPostWarpVector, FemGui::ViewProviderFemPostObject) - -ViewProviderFemPostWarpVector::ViewProviderFemPostWarpVector() { - - sPixmap = "FEM_PostFilterWarp"; -} - -ViewProviderFemPostWarpVector::~ViewProviderFemPostWarpVector() { - -} - -void ViewProviderFemPostWarpVector::setupTaskDialog(TaskDlgPost* dlg) { - - //add the function box - dlg->appendBox(new TaskPostWarpVector(dlg->getView())); - - //add the display options - FemGui::ViewProviderFemPostObject::setupTaskDialog(dlg); -} - -PROPERTY_SOURCE(FemGui::ViewProviderFemPostCut, FemGui::ViewProviderFemPostObject) - -ViewProviderFemPostCut::ViewProviderFemPostCut() { - - sPixmap = "FEM_PostFilterCutFunction"; -} - -ViewProviderFemPostCut::~ViewProviderFemPostCut() { - -} - -void ViewProviderFemPostCut::setupTaskDialog(TaskDlgPost* dlg) { - - //add the function box - dlg->appendBox(new TaskPostCut(dlg->getView(), - &static_cast(dlg->getView()->getObject())->Function)); - - //add the display options - FemGui::ViewProviderFemPostObject::setupTaskDialog(dlg); -} +// *************************************************************************** +// contours filter PROPERTY_SOURCE(FemGui::ViewProviderFemPostContours, FemGui::ViewProviderFemPostObject) ViewProviderFemPostContours::ViewProviderFemPostContours() @@ -175,3 +125,72 @@ void ViewProviderFemPostContours::setupTaskDialog(TaskDlgPost* dlg) // the filter-specific task panel dlg->appendBox(new TaskPostContours(dlg->getView())); } + + +// *************************************************************************** +// cut filter +PROPERTY_SOURCE(FemGui::ViewProviderFemPostCut, FemGui::ViewProviderFemPostObject) + +ViewProviderFemPostCut::ViewProviderFemPostCut() +{ + sPixmap = "FEM_PostFilterCutFunction"; +} + +ViewProviderFemPostCut::~ViewProviderFemPostCut() +{} + +void ViewProviderFemPostCut::setupTaskDialog(TaskDlgPost* dlg) +{ + //add the function box + dlg->appendBox(new TaskPostCut( + dlg->getView(), + &static_cast(dlg->getView()->getObject())->Function)); + + //add the display options + FemGui::ViewProviderFemPostObject::setupTaskDialog(dlg); +} + + +// *************************************************************************** +// scalar clip filter +PROPERTY_SOURCE(FemGui::ViewProviderFemPostScalarClip, FemGui::ViewProviderFemPostObject) + +ViewProviderFemPostScalarClip::ViewProviderFemPostScalarClip() +{ + sPixmap = "FEM_PostFilterClipScalar"; +} + +ViewProviderFemPostScalarClip::~ViewProviderFemPostScalarClip() { + +} + +void ViewProviderFemPostScalarClip::setupTaskDialog(TaskDlgPost* dlg) +{ + //add the function box + dlg->appendBox(new TaskPostScalarClip(dlg->getView())); + + //add the display options + FemGui::ViewProviderFemPostObject::setupTaskDialog(dlg); +} + + +// *************************************************************************** +// warp vector filter +PROPERTY_SOURCE(FemGui::ViewProviderFemPostWarpVector, FemGui::ViewProviderFemPostObject) + +ViewProviderFemPostWarpVector::ViewProviderFemPostWarpVector() +{ + sPixmap = "FEM_PostFilterWarp"; +} + +ViewProviderFemPostWarpVector::~ViewProviderFemPostWarpVector() +{} + +void ViewProviderFemPostWarpVector::setupTaskDialog(TaskDlgPost* dlg) +{ + //add the function box + dlg->appendBox(new TaskPostWarpVector(dlg->getView())); + + //add the display options + FemGui::ViewProviderFemPostObject::setupTaskDialog(dlg); +} diff --git a/src/Mod/Fem/Gui/ViewProviderFemPostFilter.h b/src/Mod/Fem/Gui/ViewProviderFemPostFilter.h index bb3b77c17d..33f326a965 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemPostFilter.h +++ b/src/Mod/Fem/Gui/ViewProviderFemPostFilter.h @@ -20,30 +20,24 @@ * * ***************************************************************************/ - #ifndef FEM_VIEWPROVIDERFEMPOSTFILTER_H #define FEM_VIEWPROVIDERFEMPOSTFILTER_H #include "ViewProviderFemPostObject.h" + namespace FemGui { -class FemGuiExport ViewProviderFemPostClip : public ViewProviderFemPostObject { +// *************************************************************************** +// in the following, the different filters sorted alphabetically +// *************************************************************************** - PROPERTY_HEADER_WITH_OVERRIDE(FemGui::ViewProviderFemPostClip); - -public: - /// constructor. - ViewProviderFemPostClip(); - ~ViewProviderFemPostClip() override; - -protected: - void setupTaskDialog(TaskDlgPost* dlg) override; -}; - -class FemGuiExport ViewProviderFemPostDataAlongLine : public ViewProviderFemPostObject { +// *************************************************************************** +// data along line filter +class FemGuiExport ViewProviderFemPostDataAlongLine : public ViewProviderFemPostObject +{ PROPERTY_HEADER_WITH_OVERRIDE(FemGui::ViewProviderFemPostDataAlongLine); public: @@ -55,8 +49,11 @@ protected: void setupTaskDialog(TaskDlgPost* dlg) override; }; -class FemGuiExport ViewProviderFemPostDataAtPoint: public ViewProviderFemPostObject { +// *************************************************************************** +// data at point filter +class FemGuiExport ViewProviderFemPostDataAtPoint: public ViewProviderFemPostObject +{ PROPERTY_HEADER_WITH_OVERRIDE(FemGui::ViewProviderFemPostDataAtPoint); public: @@ -69,48 +66,28 @@ public: protected: void setupTaskDialog(TaskDlgPost* dlg) override; }; -class FemGuiExport ViewProviderFemPostScalarClip : public ViewProviderFemPostObject { - PROPERTY_HEADER_WITH_OVERRIDE(FemGui::ViewProviderFemPostScalarClip); + +// *************************************************************************** +// clip filter +class FemGuiExport ViewProviderFemPostClip: public ViewProviderFemPostObject +{ + PROPERTY_HEADER_WITH_OVERRIDE(FemGui::ViewProviderFemPostClip); public: /// constructor. - ViewProviderFemPostScalarClip(); - ~ViewProviderFemPostScalarClip() override; + ViewProviderFemPostClip(); + ~ViewProviderFemPostClip() override; protected: void setupTaskDialog(TaskDlgPost* dlg) override; }; -class FemGuiExport ViewProviderFemPostWarpVector : public ViewProviderFemPostObject { - - PROPERTY_HEADER_WITH_OVERRIDE(FemGui::ViewProviderFemPostWarpVector); - -public: - /// constructor. - ViewProviderFemPostWarpVector(); - ~ViewProviderFemPostWarpVector() override; - -protected: - void setupTaskDialog(TaskDlgPost* dlg) override; -}; - -class FemGuiExport ViewProviderFemPostCut : public ViewProviderFemPostObject { - - PROPERTY_HEADER_WITH_OVERRIDE(FemGui::ViewProviderFemPostCut); - -public: - /// constructor. - ViewProviderFemPostCut(); - ~ViewProviderFemPostCut() override; - -protected: - void setupTaskDialog(TaskDlgPost* dlg) override; -}; +// *************************************************************************** +// contours filter class FemGuiExport ViewProviderFemPostContours: public ViewProviderFemPostObject { - PROPERTY_HEADER_WITH_OVERRIDE(FemGui::ViewProviderFemPostContours); public: @@ -122,6 +99,54 @@ protected: void setupTaskDialog(TaskDlgPost* dlg) override; }; + +// *************************************************************************** +// cut filter +class FemGuiExport ViewProviderFemPostCut: public ViewProviderFemPostObject +{ + PROPERTY_HEADER_WITH_OVERRIDE(FemGui::ViewProviderFemPostCut); + +public: + /// constructor. + ViewProviderFemPostCut(); + ~ViewProviderFemPostCut() override; + +protected: + void setupTaskDialog(TaskDlgPost* dlg) override; +}; + + +// *************************************************************************** +// scalar clip filter +class FemGuiExport ViewProviderFemPostScalarClip: public ViewProviderFemPostObject +{ + PROPERTY_HEADER_WITH_OVERRIDE(FemGui::ViewProviderFemPostScalarClip); + +public: + /// constructor. + ViewProviderFemPostScalarClip(); + ~ViewProviderFemPostScalarClip() override; + +protected: + void setupTaskDialog(TaskDlgPost* dlg) override; +}; + + +// *************************************************************************** +// warp vector filter +class FemGuiExport ViewProviderFemPostWarpVector : public ViewProviderFemPostObject +{ + PROPERTY_HEADER_WITH_OVERRIDE(FemGui::ViewProviderFemPostWarpVector); + +public: + /// constructor. + ViewProviderFemPostWarpVector(); + ~ViewProviderFemPostWarpVector() override; + +protected: + void setupTaskDialog(TaskDlgPost* dlg) override; +}; + } //namespace FemGui