From a84d6d19e60b0784c021fcb0f24bf9918a5056a2 Mon Sep 17 00:00:00 2001 From: Uwe Date: Tue, 14 Feb 2023 01:05:39 +0100 Subject: [PATCH] [FEM] improve visualization of pvtu files - To speed up analyses one calculates on several CPU cores. The result is a partial VTU file. Unfortunately when applying a transparency the boundaries of the volumes computed by each CPU core are always visible. This makes it often unusable for visualizations. The solution is to filter the results the same way a clip filter does. --- src/Mod/Fem/Gui/ViewProviderFemPostObject.cpp | 71 +++++++++++++++++-- src/Mod/Fem/Gui/ViewProviderFemPostObject.h | 2 + 2 files changed, 68 insertions(+), 5 deletions(-) diff --git a/src/Mod/Fem/Gui/ViewProviderFemPostObject.cpp b/src/Mod/Fem/Gui/ViewProviderFemPostObject.cpp index 9e9a164974..ed4c204ef5 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemPostObject.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemPostObject.cpp @@ -38,6 +38,7 @@ # include # include # include +# include # include # include @@ -55,6 +56,8 @@ #include #include #include +#include +#include #include #include "ViewProviderFemPostObject.h" @@ -265,8 +268,8 @@ void ViewProviderFemPostObject::attach(App::DocumentObject* pcObj) (void)setupPipeline(); } -SoSeparator* ViewProviderFemPostObject::getFrontRoot() const { - +SoSeparator* ViewProviderFemPostObject::getFrontRoot() const +{ return m_colorRoot; } @@ -623,10 +626,65 @@ void ViewProviderFemPostObject::updateData(const App::Property* p) { } } -bool ViewProviderFemPostObject::setupPipeline() +void ViewProviderFemPostObject::filterArtifacts(vtkDataObject* data) +{ + // The problem is that in the surface view the boundary reagions of the volumess + // calculated by the different CPU cores is always visible, independent of the + // transparency setting. Elmer is not to blame, this is just a property of the + // partial VTK file reader. So this can happen with various input + // since FreeCAD can also be used to view VTK files without the need to perform + // an analysis. Therefore it is impossible to know in advance when to filter + // or not. + // Only for pure CCX analyses we know that no filtering is necessary. + // However, the effort to catch this case is not worth it since the filtering + // is only as time-consuming as enabling the surface filter. In fact, it is like + // performing the surface flter twice. + + // We need to set the filter clipping plane below the z minimum of the data. + // We can either do this by checkting the VTK data or by getting the info from + // the 3D view. We use here the latter because this much faster. + + // since we will set the filter according to the visible bounding box + // assure the object is visible + bool visibility = this->Visibility.getValue(); + this->Visibility.setValue(false); + + Gui::Document* doc = this->getDocument(); + Gui::View3DInventor* view = + qobject_cast(doc->getViewOfViewProvider(this)); + if (view) { + Gui::View3DInventorViewer* viewer = view->getViewer(); + SbBox3f boundingBox; + boundingBox = viewer->getBoundingBox(); + if (boundingBox.hasVolume()) { + // setup + vtkSmartPointer m_implicit; + auto m_plane = vtkSmartPointer::New(); + m_implicit = m_plane; + m_plane->SetNormal(0., 0., 1.); + auto extractor = vtkSmartPointer::New(); + float dx, dy, dz; + boundingBox.getSize(dx, dy, dz); + // set plane slightly below the minimum to assure there are + // no boundary cells (touching the function + m_plane->SetOrigin(0., 0., -1 * dz - 1); + extractor->SetClipFunction(m_implicit); + extractor->SetInputData(data); + extractor->Update(); + m_surface->SetInputData(extractor->GetOutputDataObject(0)); + } + else { + // for e.g. DataAtPoint filter + m_surface->SetInputData(data); + } + } + // restore initial vsibility + this->Visibility.setValue(visibility); +} + + bool ViewProviderFemPostObject::setupPipeline() { vtkDataObject* data = static_cast(getObject())->Data.getValue(); - if (!data) return false; @@ -644,10 +702,13 @@ bool ViewProviderFemPostObject::setupPipeline() } m_outline->SetInputData(data); - m_surface->SetInputData(data); m_wireframe->SetInputData(data); m_points->SetInputData(data); + // filter artifacts + // only necessary for the surface filter + filterArtifacts(data); + return true; } diff --git a/src/Mod/Fem/Gui/ViewProviderFemPostObject.h b/src/Mod/Fem/Gui/ViewProviderFemPostObject.h index fce127a5c5..8a5d7f0bc9 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemPostObject.h +++ b/src/Mod/Fem/Gui/ViewProviderFemPostObject.h @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -150,6 +151,7 @@ protected: vtkSmartPointer m_points, m_pointsSurface; private: + void filterArtifacts(vtkDataObject* data); void updateProperties(); void update3D(); void WritePointData(vtkPoints *points, vtkDataArray *normals,