FEM: Draft architecture of post data extraction with histogram example

This commit is contained in:
Stefan Tröger
2025-03-31 20:11:09 +02:00
parent ce54149637
commit ac02a222ff
51 changed files with 4228 additions and 14 deletions

View File

@@ -49,6 +49,13 @@ Note: Can lead to a full recompute of the whole pipeline, hence best to call thi
<UserDocu>
Returns the names of all scalar fields available on this filter's input.
Note: Can lead to a full recompute of the whole pipeline, hence best to call this only in "execute", where the user expects long calculation cycles.
</UserDocu>
</Documentation>
</Methode>
<Methode Name="getOutputAlgorithm">
<Documentation>
<UserDocu>
Returns the filters vtk algorithm currently used as output (the one generating the Data field). Note that the output algorithm may change depending on filter settings.
</UserDocu>
</Documentation>
</Methode>"

View File

@@ -38,6 +38,7 @@
#ifdef FC_USE_VTK_PYTHON
#include <vtkUnstructuredGrid.h>
#include <vtkPythonUtil.h>
#include <vtkPolyData.h>
#endif // BUILD_FEM_VTK
using namespace Fem;
@@ -129,6 +130,9 @@ PyObject* FemPostFilterPy::getInputData(PyObject* args)
case VTK_UNSTRUCTURED_GRID:
copy = vtkUnstructuredGrid::New();
break;
case VTK_POLY_DATA:
copy = vtkPolyData::New();
break;
default:
PyErr_SetString(PyExc_TypeError,
"cannot return datatype object; not unstructured grid");
@@ -183,6 +187,25 @@ PyObject* FemPostFilterPy::getInputScalarFields(PyObject* args)
return Py::new_reference_to(list);
}
PyObject* FemPostFilterPy::getOutputAlgorithm(PyObject* args)
{
#ifdef BUILD_FEM_VTK_WRAPPER
// we take no arguments
if (!PyArg_ParseTuple(args, "")) {
return nullptr;
}
// return python object for the algorithm
auto algorithm = getFemPostFilterPtr()->getFilterOutput();
PyObject* py_algorithm = vtkPythonUtil::GetObjectFromPointer(algorithm);
return Py::new_reference_to(py_algorithm);
#else
PyErr_SetString(PyExc_NotImplementedError, "VTK python wrapper not available");
Py_Return;
#endif
}
PyObject* FemPostFilterPy::getCustomAttributes(const char* /*attr*/) const
{
return nullptr;

View File

@@ -23,6 +23,13 @@ filename: str
File extension is automatically detected from data type.</UserDocu>
</Documentation>
</Methode>
<Methode Name="getDataSet">
<Documentation>
<UserDocu>getDataset() -> vtkDataSet
Returns the current output dataset. For normal filters this is equal to the objects Data property output. However, a pipelines Data property could store multiple frames, and hence Data can be of type vtkCompositeData, which is not a vtkDataset. To simplify implementations this function always returns a vtkDataSet, and for a pipeline it will be the dataset of the currently selected frame. Note that the returned value could be None, if no data is set at all.</UserDocu>
</Documentation>
</Methode>
</PythonExport>
</GenerateModel>

View File

@@ -29,6 +29,10 @@
#include "FemPostObjectPy.h"
#include "FemPostObjectPy.cpp"
#ifdef BUILD_FEM_VTK_WRAPPER
#include <vtkDataSet.h>
#include <vtkPythonUtil.h>
#endif //BUILD_FEM_VTK
using namespace Fem;
@@ -55,6 +59,27 @@ PyObject* FemPostObjectPy::writeVTK(PyObject* args)
Py_Return;
}
PyObject* FemPostObjectPy::getDataSet(PyObject* args)
{
#ifdef BUILD_FEM_VTK_WRAPPER
// we take no arguments
if (!PyArg_ParseTuple(args, "")) {
return nullptr;
}
// return python object for the dataset
auto dataset = getFemPostObjectPtr()->getDataSet();
if (dataset) {
PyObject* py_algorithm = vtkPythonUtil::GetObjectFromPointer(dataset);
return Py::new_reference_to(py_algorithm);
}
return Py_None;
#else
PyErr_SetString(PyExc_NotImplementedError, "VTK python wrapper not available");
Py_Return;
#endif
}
PyObject* FemPostObjectPy::getCustomAttributes(const char* /*attr*/) const
{
return nullptr;

View File

@@ -118,6 +118,12 @@ public:
unsigned int getFrameNumber();
std::vector<double> getFrameValues();
// output algorithm handling
vtkSmartPointer<vtkAlgorithm> getOutputAlgorithm()
{
return m_source_algorithm;
}
protected:
void onChanged(const App::Property* prop) override;
bool allowObject(App::DocumentObject* obj) override;

View File

@@ -71,5 +71,12 @@ Load a single result object or create a multiframe result by loading multiple re
<UserDocu>Change name of data arrays</UserDocu>
</Documentation>
</Methode>
<Methode Name="getOutputAlgorithm">
<Documentation>
<UserDocu>
Returns the pipeline vtk algorithm, which generates the data passed to the pipelines filters. Note that the output algorithm may change depending on pipeline settings.
</UserDocu>
</Documentation>
</Methode>"
</PythonExport>
</GenerateModel>

View File

@@ -34,6 +34,10 @@
#include "FemPostPipelinePy.cpp"
// clang-format on
#ifdef BUILD_FEM_VTK_WRAPPER
#include <vtkPythonUtil.h>
#endif //BUILD_FEM_VTK
using namespace Fem;
@@ -313,6 +317,25 @@ PyObject* FemPostPipelinePy::renameArrays(PyObject* args)
Py_Return;
}
PyObject* FemPostPipelinePy::getOutputAlgorithm(PyObject* args)
{
#ifdef BUILD_FEM_VTK_WRAPPER
// we take no arguments
if (!PyArg_ParseTuple(args, "")) {
return nullptr;
}
// return python object for the algorithm
auto algorithm = getFemPostPipelinePtr()->getOutputAlgorithm();
PyObject* py_algorithm = vtkPythonUtil::GetObjectFromPointer(algorithm);
return Py::new_reference_to(py_algorithm);
#else
PyErr_SetString(PyExc_NotImplementedError, "VTK python wrapper not available");
Py_Return;
#endif
}
PyObject* FemPostPipelinePy::getCustomAttributes(const char* /*attr*/) const
{
return nullptr;

View File

@@ -32,8 +32,11 @@
#include <vtkStructuredGrid.h>
#include <vtkUniformGrid.h>
#include <vtkUnstructuredGrid.h>
#include <vtkTable.h>
#include <vtkXMLTableWriter.h>
#include <vtkXMLDataSetWriter.h>
#include <vtkXMLMultiBlockDataWriter.h>
#include <vtkXMLTableReader.h>
#include <vtkXMLMultiBlockDataReader.h>
#include <vtkXMLImageDataReader.h>
#include <vtkXMLPolyDataReader.h>
@@ -243,6 +246,9 @@ void PropertyPostDataObject::createDataObjectByExternalType(vtkSmartPointer<vtkD
case VTK_MULTIPIECE_DATA_SET:
m_dataObject = vtkSmartPointer<vtkMultiPieceDataSet>::New();
break;
case VTK_TABLE:
m_dataObject = vtkSmartPointer<vtkTable>::New();
break;
default:
throw Base::TypeError("Unsupported VTK data type");
};
@@ -313,6 +319,9 @@ void PropertyPostDataObject::Save(Base::Writer& writer) const
case VTK_MULTIBLOCK_DATA_SET:
extension = "zip";
break;
case VTK_TABLE:
extension = ".vtt";
break;
default:
break;
};
@@ -382,13 +391,16 @@ void PropertyPostDataObject::SaveDocFile(Base::Writer& writer) const
xmlWriter = vtkSmartPointer<vtkXMLMultiBlockDataWriter>::New();
xmlWriter->SetInputDataObject(m_dataObject);
xmlWriter->SetFileName(datafile.filePath().c_str());
xmlWriter->SetDataModeToBinary();
}
else if (m_dataObject->IsA("vtkTable")) {
xmlWriter = vtkSmartPointer<vtkXMLTableWriter>::New();
xmlWriter->SetInputDataObject(m_dataObject);
xmlWriter->SetFileName(fi.filePath().c_str());
}
else {
xmlWriter = vtkSmartPointer<vtkXMLDataSetWriter>::New();
xmlWriter->SetInputDataObject(m_dataObject);
xmlWriter->SetFileName(fi.filePath().c_str());
xmlWriter->SetDataModeToBinary();
#ifdef VTK_CELL_ARRAY_V2
// Looks like an invalid data object that causes a crash with vtk9
@@ -399,6 +411,7 @@ void PropertyPostDataObject::SaveDocFile(Base::Writer& writer) const
}
#endif
}
xmlWriter->SetDataModeToBinary();
if (xmlWriter->Write() != 1) {
// Note: Do NOT throw an exception here because if the tmp. file could
@@ -481,6 +494,9 @@ void PropertyPostDataObject::RestoreDocFile(Base::Reader& reader)
else if (extension == "vti") {
xmlReader = vtkSmartPointer<vtkXMLImageDataReader>::New();
}
else if (extension == "vtt") {
xmlReader = vtkSmartPointer<vtkXMLTableReader>::New();
}
else if (extension == "zip") {
// first unzip the file into a datafolder