From a306ce5686bbc255a088629534079389c9a18abb Mon Sep 17 00:00:00 2001 From: Uwe Date: Thu, 31 Mar 2022 05:14:01 +0200 Subject: [PATCH] [FEM] fix crash with result filters fixes #6683 We cannot cast the object type before checking it and in case the object is wrong, the filter cannot be processed and the user needs info about his mistake that he can fix this. - also some code style fixes by MSVC --- src/Mod/Fem/App/FemPostFilter.cpp | 197 +++++++++++++++--------------- 1 file changed, 99 insertions(+), 98 deletions(-) diff --git a/src/Mod/Fem/App/FemPostFilter.cpp b/src/Mod/Fem/App/FemPostFilter.cpp index b763724b3c..9f18b163d4 100644 --- a/src/Mod/Fem/App/FemPostFilter.cpp +++ b/src/Mod/Fem/App/FemPostFilter.cpp @@ -61,27 +61,28 @@ FemPostFilter::FilterPipeline& FemPostFilter::getFilterPipeline(std::string name void FemPostFilter::setActiveFilterPipeline(std::string name) { - if(m_activePipeline != name && isValid()) { + if (m_activePipeline != name && isValid()) { m_activePipeline = name; } } DocumentObjectExecReturn* FemPostFilter::execute(void) { - if(!m_pipelines.empty() && !m_activePipeline.empty()) { + if (!m_pipelines.empty() && !m_activePipeline.empty()) { FemPostFilter::FilterPipeline& pipe = m_pipelines[m_activePipeline]; if (m_activePipeline.length() >= 11) { - std::string LineClip = m_activePipeline.substr(0,13); - std::string PointClip = m_activePipeline.substr(0,11); + std::string LineClip = m_activePipeline.substr(0, 13); + std::string PointClip = m_activePipeline.substr(0, 11); if ((LineClip == "DataAlongLine") || (PointClip == "DataAtPoint")) { pipe.filterSource->SetSourceData(getInputData()); pipe.filterTarget->Update(); Data.setValue(pipe.filterTarget->GetOutputDataObject(0)); } - } else { + } + else { pipe.source->SetInputDataObject(getInputData()); - pipe.target->Update(); + pipe.target->Update(); Data.setValue(pipe.target->GetOutputDataObject(0)); } @@ -91,18 +92,18 @@ DocumentObjectExecReturn* FemPostFilter::execute(void) { vtkDataObject* FemPostFilter::getInputData() { - if(Input.getValue()) { - return Input.getValue()->Data.getValue(); + if (Input.getValue()) { + if (Input.getValue()->getTypeId().isDerivedFrom(Base::Type::fromName("Fem::FemPostObject")) ) + return Input.getValue()->Data.getValue(); + else + throw std::runtime_error("The filter's Input object is not a 'Fem::FemPostObject' object!"); } else { //get the pipeline and use the pipelinedata std::vector objs = getDocument()->getObjectsOfType(FemPostPipeline::getClassTypeId()); - for(std::vector::iterator it = objs.begin(); it != objs.end(); ++it) { - - if(static_cast(*it)->holdsPostObject(this)) { - + for (std::vector::iterator it = objs.begin(); it != objs.end(); ++it) { + if (static_cast(*it)->holdsPostObject(this)) return static_cast(*it)->Data.getValue(); - } } } @@ -119,15 +120,15 @@ FemPostClipFilter::FemPostClipFilter(void) : FemPostFilter() { ADD_PROPERTY_TYPE(CutCells, (false), "Clip", App::Prop_None, "Decides if cells are cuttet 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; + 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; + m_extractor = vtkSmartPointer::New(); + extr.source = m_extractor; + extr.target = m_extractor; addFilterPipeline(extr, "extract"); m_extractor->SetExtractInside(0); @@ -140,21 +141,21 @@ FemPostClipFilter::~FemPostClipFilter() { void FemPostClipFilter::onChanged(const Property* prop) { - if(prop == &Function) { + if (prop == &Function) { - if(Function.getValue() && Function.getValue()->isDerivedFrom(FemPostFunction::getClassTypeId())) { + 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) { + else if (prop == &InsideOut) { m_clipper->SetInsideOut(InsideOut.getValue()); - m_extractor->SetExtractInside( (InsideOut.getValue()) ? 1 : 0 ); + m_extractor->SetExtractInside((InsideOut.getValue()) ? 1 : 0); } - else if(prop == &CutCells) { + else if (prop == &CutCells) { - if(!CutCells.getValue()) + if (!CutCells.getValue()) setActiveFilterPipeline("extract"); else setActiveFilterPipeline("clip"); @@ -165,9 +166,9 @@ void FemPostClipFilter::onChanged(const Property* prop) { short int FemPostClipFilter::mustExecute(void) const { - if(Function.isTouched() || - InsideOut.isTouched() || - CutCells.isTouched()) { + if (Function.isTouched() || + InsideOut.isTouched() || + CutCells.isTouched()) { return 1; } @@ -176,7 +177,7 @@ short int FemPostClipFilter::mustExecute(void) const { DocumentObjectExecReturn* FemPostClipFilter::execute(void) { - if(!m_extractor->GetImplicitFunction()) + if (!m_extractor->GetImplicitFunction()) return StdReturn; return Fem::FemPostFilter::execute(); @@ -186,12 +187,12 @@ PROPERTY_SOURCE(Fem::FemPostDataAlongLineFilter, Fem::FemPostFilter) FemPostDataAlongLineFilter::FemPostDataAlongLineFilter(void) : FemPostFilter() { - ADD_PROPERTY_TYPE(Point1,(Base::Vector3d(0.0,0.0,0.0)), "DataAlongLine", App::Prop_None, "The point 1 used to define end point of line"); - ADD_PROPERTY_TYPE(Point2,(Base::Vector3d(0.0,0.0,1.0)), "DataAlongLine", App::Prop_None, "The point 2 used to define end point of line"); - ADD_PROPERTY_TYPE(Resolution,(100), "DataAlongLine", App::Prop_None, "The number of intervals between the 2 end points of line"); - ADD_PROPERTY_TYPE(XAxisData,(0), "DataAlongLine",App::Prop_None,"X axis data values used for plotting"); - ADD_PROPERTY_TYPE(YAxisData,(0), "DataAlongLine",App::Prop_None,"Y axis data values used for plotting"); - ADD_PROPERTY_TYPE(PlotData ,(""),"DataAlongLine",App::Prop_None,"Field used for plotting"); + ADD_PROPERTY_TYPE(Point1, (Base::Vector3d(0.0, 0.0, 0.0)), "DataAlongLine", App::Prop_None, "The point 1 used to define end point of line"); + ADD_PROPERTY_TYPE(Point2, (Base::Vector3d(0.0, 0.0, 1.0)), "DataAlongLine", App::Prop_None, "The point 2 used to define end point of line"); + ADD_PROPERTY_TYPE(Resolution, (100), "DataAlongLine", App::Prop_None, "The number of intervals between the 2 end points of line"); + ADD_PROPERTY_TYPE(XAxisData, (0), "DataAlongLine", App::Prop_None, "X axis data values used for plotting"); + ADD_PROPERTY_TYPE(YAxisData, (0), "DataAlongLine", App::Prop_None, "Y axis data values used for plotting"); + ADD_PROPERTY_TYPE(PlotData, (""), "DataAlongLine", App::Prop_None, "Field used for plotting"); PlotData.setStatus(App::Property::ReadOnly, true); XAxisData.setStatus(App::Property::ReadOnly, true); @@ -218,8 +219,8 @@ FemPostDataAlongLineFilter::FemPostDataAlongLineFilter(void) : FemPostFilter() { m_probe->SetTolerance(0.01); #endif - clip.filterSource = m_probe; - clip.filterTarget = m_probe; + clip.filterSource = m_probe; + clip.filterTarget = m_probe; addFilterPipeline(clip, "DataAlongLine"); setActiveFilterPipeline("DataAlongLine"); @@ -237,18 +238,18 @@ DocumentObjectExecReturn* FemPostDataAlongLineFilter::execute(void) { void FemPostDataAlongLineFilter::onChanged(const Property* prop) { - if(prop == &Point1) { + if (prop == &Point1) { const Base::Vector3d& vec1 = Point1.getValue(); m_line->SetPoint1(vec1.x, vec1.y, vec1.z); } - else if(prop == &Point2) { + else if (prop == &Point2) { const Base::Vector3d& vec2 = Point2.getValue(); m_line->SetPoint2(vec2.x, vec2.y, vec2.z); } - else if(prop == &Resolution) { + else if (prop == &Resolution) { m_line->SetResolution(Resolution.getValue()); } - else if(prop == &PlotData) { + else if (prop == &PlotData) { GetAxisData(); } Fem::FemPostFilter::onChanged(prop); @@ -256,9 +257,9 @@ void FemPostDataAlongLineFilter::onChanged(const Property* prop) { short int FemPostDataAlongLineFilter::mustExecute(void) const { - if(Point1.isTouched() || - Point2.isTouched() || - Resolution.isTouched()){ + if (Point1.isTouched() || + Point2.isTouched() || + Resolution.isTouched()) { return 1; } @@ -273,7 +274,7 @@ void FemPostDataAlongLineFilter::GetAxisData() { vtkSmartPointer data = m_probe->GetOutputDataObject(0); vtkDataSet* dset = vtkDataSet::SafeDownCast(data); vtkDataArray* pdata = dset->GetPointData()->GetArray(PlotData.getValue()); - vtkDataArray *tcoords = dset->GetPointData()->GetTCoords("Texture Coordinates"); + vtkDataArray* tcoords = dset->GetPointData()->GetTCoords("Texture Coordinates"); vtkIdType component = 0; @@ -309,11 +310,11 @@ PROPERTY_SOURCE(Fem::FemPostDataAtPointFilter, Fem::FemPostFilter) FemPostDataAtPointFilter::FemPostDataAtPointFilter(void) : FemPostFilter() { - ADD_PROPERTY_TYPE(Center,(Base::Vector3d(0.0,0.0,1.0)), "DataAtPoint", App::Prop_None, "The center used to define the center of the point"); - ADD_PROPERTY_TYPE(Radius,(0), "DataAtPoint", App::Prop_None, "The point 2 used to define end point of line"); - ADD_PROPERTY_TYPE(PointData,(0), "DataAtPoint",App::Prop_None,"Point data values used for plotting"); - ADD_PROPERTY_TYPE(FieldName,(""),"DataAtPoint",App::Prop_None,"Field used for plotting"); - ADD_PROPERTY_TYPE(Unit,(""),"DataAtPoint",App::Prop_None,"Unit used for Field"); + ADD_PROPERTY_TYPE(Center, (Base::Vector3d(0.0, 0.0, 1.0)), "DataAtPoint", App::Prop_None, "The center used to define the center of the point"); + ADD_PROPERTY_TYPE(Radius, (0), "DataAtPoint", App::Prop_None, "The point 2 used to define end point of line"); + ADD_PROPERTY_TYPE(PointData, (0), "DataAtPoint", App::Prop_None, "Point data values used for plotting"); + ADD_PROPERTY_TYPE(FieldName, (""), "DataAtPoint", App::Prop_None, "Field used for plotting"); + ADD_PROPERTY_TYPE(Unit, (""), "DataAtPoint", App::Prop_None, "Unit used for Field"); PointData.setStatus(App::Property::ReadOnly, true); FieldName.setStatus(App::Property::ReadOnly, true); @@ -337,8 +338,8 @@ FemPostDataAtPointFilter::FemPostDataAtPointFilter(void) : FemPostFilter() { m_probe->SetTolerance(0.01); #endif - clip.filterSource = m_probe; - clip.filterTarget = m_probe; + clip.filterSource = m_probe; + clip.filterTarget = m_probe; addFilterPipeline(clip, "DataAtPoint"); setActiveFilterPipeline("DataAtPoint"); @@ -356,11 +357,11 @@ DocumentObjectExecReturn* FemPostDataAtPointFilter::execute(void) { void FemPostDataAtPointFilter::onChanged(const Property* prop) { - if(prop == &Center) { + if (prop == &Center) { const Base::Vector3d& vec = Center.getValue(); m_point->SetCenter(vec.x, vec.y, vec.z); } - else if(prop == &FieldName) { + else if (prop == &FieldName) { GetPointData(); } Fem::FemPostFilter::onChanged(prop); @@ -368,7 +369,7 @@ void FemPostDataAtPointFilter::onChanged(const Property* prop) { short int FemPostDataAtPointFilter::mustExecute(void) const { - if(Center.isTouched()){ + if (Center.isTouched()) { return 1; } @@ -385,14 +386,14 @@ void FemPostDataAtPointFilter::GetPointData() { int component = 0; - for(int i=0; iGetNumberOfPoints(); ++i) { + for (int i = 0; i < dset->GetNumberOfPoints(); ++i) { double value = 0; - if(pdata->GetNumberOfComponents() == 1) + if (pdata->GetNumberOfComponents() == 1) value = pdata->GetComponent(i, component); else { - for(int j=0; jGetNumberOfComponents(); ++j) - value += std::pow(pdata->GetComponent(i, j),2); + for (int j = 0; j < pdata->GetNumberOfComponents(); ++j) + value += std::pow(pdata->GetComponent(i, j), 2); value = std::sqrt(value); } @@ -412,9 +413,9 @@ FemPostScalarClipFilter::FemPostScalarClipFilter(void) : FemPostFilter() { Value.setConstraints(&m_constraints); FilterPipeline clip; - m_clipper = vtkSmartPointer::New(); - clip.source = m_clipper; - clip.target = m_clipper; + m_clipper = vtkSmartPointer::New(); + clip.source = m_clipper; + clip.target = m_clipper; addFilterPipeline(clip, "clip"); setActiveFilterPipeline("clip"); } @@ -426,20 +427,20 @@ FemPostScalarClipFilter::~FemPostScalarClipFilter() { DocumentObjectExecReturn* FemPostScalarClipFilter::execute(void) { std::string val; - if(m_scalarFields.getEnums() && Scalars.getValue() >= 0) + if (m_scalarFields.getEnums() && Scalars.getValue() >= 0) val = Scalars.getValueAsString(); std::vector array; vtkSmartPointer data = getInputData(); - if(!data || !data->IsA("vtkDataSet")) + if (!data || !data->IsA("vtkDataSet")) return StdReturn; vtkDataSet* dset = vtkDataSet::SafeDownCast(data); vtkPointData* pd = dset->GetPointData(); - for(int i=0; iGetNumberOfArrays(); ++i) { - if(pd->GetArray(i)->GetNumberOfComponents()==1) + for (int i = 0; i < pd->GetNumberOfArrays(); ++i) { + if (pd->GetArray(i)->GetNumberOfComponents() == 1) array.push_back(pd->GetArrayName(i)); } @@ -449,7 +450,7 @@ DocumentObjectExecReturn* FemPostScalarClipFilter::execute(void) { Scalars.setValue(m_scalarFields); std::vector::iterator it = std::find(array.begin(), array.end(), val); - if(!val.empty() && it != array.end()) + if (!val.empty() && it != array.end()) Scalars.setValue(val.c_str()); //recalculate the filter @@ -459,15 +460,15 @@ DocumentObjectExecReturn* FemPostScalarClipFilter::execute(void) { void FemPostScalarClipFilter::onChanged(const Property* prop) { - if(prop == &Value) { + if (prop == &Value) { m_clipper->SetValue(Value.getValue()); } - else if(prop == &InsideOut) { + else if (prop == &InsideOut) { m_clipper->SetInsideOut(InsideOut.getValue()); } - else if(prop == &Scalars && (Scalars.getValue() >= 0)) { + else if (prop == &Scalars && (Scalars.getValue() >= 0)) { m_clipper->SetInputArrayToProcess(0, 0, 0, - vtkDataObject::FIELD_ASSOCIATION_POINTS, Scalars.getValueAsString() ); + vtkDataObject::FIELD_ASSOCIATION_POINTS, Scalars.getValueAsString()); setConstraintForField(); } @@ -476,9 +477,9 @@ void FemPostScalarClipFilter::onChanged(const Property* prop) { short int FemPostScalarClipFilter::mustExecute(void) const { - if(Value.isTouched() || - InsideOut.isTouched() || - Scalars.isTouched()) { + if (Value.isTouched() || + InsideOut.isTouched() || + Scalars.isTouched()) { return 1; } @@ -488,7 +489,7 @@ short int FemPostScalarClipFilter::mustExecute(void) const { void FemPostScalarClipFilter::setConstraintForField() { vtkSmartPointer data = getInputData(); - if(!data || !data->IsA("vtkDataSet")) + if (!data || !data->IsA("vtkDataSet")) return; vtkDataSet* dset = vtkDataSet::SafeDownCast(data); @@ -498,21 +499,21 @@ void FemPostScalarClipFilter::setConstraintForField() { pdata->GetRange(p); m_constraints.LowerBound = p[0]; m_constraints.UpperBound = p[1]; - m_constraints.StepSize = (p[1]-p[0])/100.; + m_constraints.StepSize = (p[1] - p[0]) / 100.; } PROPERTY_SOURCE(Fem::FemPostWarpVectorFilter, Fem::FemPostFilter) -FemPostWarpVectorFilter::FemPostWarpVectorFilter(void): FemPostFilter() { +FemPostWarpVectorFilter::FemPostWarpVectorFilter(void) : 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; + m_warp = vtkSmartPointer::New(); + warp.source = m_warp; + warp.target = m_warp; addFilterPipeline(warp, "warp"); setActiveFilterPipeline("warp"); } @@ -525,20 +526,20 @@ FemPostWarpVectorFilter::~FemPostWarpVectorFilter() { DocumentObjectExecReturn* FemPostWarpVectorFilter::execute(void) { std::string val; - if(m_vectorFields.getEnums() && Vector.getValue() >= 0) + if (m_vectorFields.getEnums() && Vector.getValue() >= 0) val = Vector.getValueAsString(); std::vector array; vtkSmartPointer data = getInputData(); - if(!data || !data->IsA("vtkDataSet")) + if (!data || !data->IsA("vtkDataSet")) return StdReturn; vtkDataSet* dset = vtkDataSet::SafeDownCast(data); vtkPointData* pd = dset->GetPointData(); - for(int i=0; iGetNumberOfArrays(); ++i) { - if(pd->GetArray(i)->GetNumberOfComponents()==3) + for (int i = 0; i < pd->GetNumberOfArrays(); ++i) { + if (pd->GetArray(i)->GetNumberOfComponents() == 3) array.push_back(pd->GetArrayName(i)); } @@ -548,7 +549,7 @@ DocumentObjectExecReturn* FemPostWarpVectorFilter::execute(void) { Vector.setValue(m_vectorFields); std::vector::iterator it = std::find(array.begin(), array.end(), val); - if(!val.empty() && it != array.end()) + if (!val.empty() && it != array.end()) Vector.setValue(val.c_str()); //recalculate the filter @@ -558,12 +559,12 @@ DocumentObjectExecReturn* FemPostWarpVectorFilter::execute(void) { void FemPostWarpVectorFilter::onChanged(const Property* prop) { - if(prop == &Factor) { + if (prop == &Factor) { m_warp->SetScaleFactor(Factor.getValue()); } - else if(prop == &Vector && (Vector.getValue() >= 0)) { + else if (prop == &Vector && (Vector.getValue() >= 0)) { m_warp->SetInputArrayToProcess(0, 0, 0, - vtkDataObject::FIELD_ASSOCIATION_POINTS, Vector.getValueAsString() ); + vtkDataObject::FIELD_ASSOCIATION_POINTS, Vector.getValueAsString()); } Fem::FemPostFilter::onChanged(prop); @@ -571,8 +572,8 @@ void FemPostWarpVectorFilter::onChanged(const Property* prop) { short int FemPostWarpVectorFilter::mustExecute(void) const { - if(Factor.isTouched() || - Vector.isTouched()) { + if (Factor.isTouched() || + Vector.isTouched()) { return 1; } @@ -587,9 +588,9 @@ FemPostCutFilter::FemPostCutFilter(void) : FemPostFilter() { ADD_PROPERTY_TYPE(Function, (nullptr), "Cut", App::Prop_None, "The function object which defines the clip cut function"); FilterPipeline clip; - m_cutter = vtkSmartPointer::New(); - clip.source = m_cutter; - clip.target = m_cutter; + m_cutter = vtkSmartPointer::New(); + clip.source = m_cutter; + clip.target = m_cutter; addFilterPipeline(clip, "cut"); setActiveFilterPipeline("cut"); } @@ -600,11 +601,11 @@ FemPostCutFilter::~FemPostCutFilter() { void FemPostCutFilter::onChanged(const Property* prop) { - if(prop == &Function) { + if (prop == &Function) { - if(Function.getValue() && Function.getValue()->isDerivedFrom(FemPostFunction::getClassTypeId())) { + if (Function.getValue() && Function.getValue()->isDerivedFrom(FemPostFunction::getClassTypeId())) { m_cutter->SetCutFunction(static_cast(Function.getValue())->getImplicitFunction()); - } + } } Fem::FemPostFilter::onChanged(prop); @@ -612,7 +613,7 @@ void FemPostCutFilter::onChanged(const Property* prop) { short int FemPostCutFilter::mustExecute(void) const { - if(Function.isTouched()) { + if (Function.isTouched()) { return 1; } @@ -621,7 +622,7 @@ short int FemPostCutFilter::mustExecute(void) const { DocumentObjectExecReturn* FemPostCutFilter::execute(void) { - if(!m_cutter->GetCutFunction()) + if (!m_cutter->GetCutFunction()) return StdReturn; return Fem::FemPostFilter::execute();