Skip to content

Commit 8e147f2

Browse files
committed
Fem: Export PostObject data to VTK - fixes FreeCAD#5816
1 parent bcf54d3 commit 8e147f2

9 files changed

+179
-9
lines changed

src/Mod/Fem/App/CMakeLists.txt

+4-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ endif()
5151

5252

5353
generate_from_xml(FemMeshPy)
54-
generate_from_xml(FemPostPipelinePy)
5554

5655

5756
SET(Python_SRCS
@@ -65,9 +64,13 @@ SET(Python_SRCS
6564
if(BUILD_FEM_VTK)
6665
SET(Python_SRCS
6766
${Python_SRCS}
67+
FemPostObjectPy.xml
68+
FemPostObjectPyImp.cpp
6869
FemPostPipelinePy.xml
6970
FemPostPipelinePyImp.cpp
7071
)
72+
generate_from_xml(FemPostObjectPy)
73+
generate_from_xml(FemPostPipelinePy)
7174
endif(BUILD_FEM_VTK)
7275
SOURCE_GROUP("Python" FILES ${Python_SRCS})
7376

src/Mod/Fem/App/FemPostObject.cpp

+67
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,20 @@
2424

2525
#ifndef _PreComp_
2626
#include <vtkDataSet.h>
27+
#include <vtkXMLPolyDataWriter.h>
28+
#include <vtkXMLStructuredGridWriter.h>
29+
#include <vtkXMLRectilinearGridWriter.h>
30+
#include <vtkXMLUnstructuredGridWriter.h>
31+
#include <vtkXMLImageDataWriter.h>
32+
#include <vtkPolyData.h>
33+
#include <vtkStructuredGrid.h>
34+
#include <vtkRectilinearGrid.h>
35+
#include <vtkUnstructuredGrid.h>
36+
#include <vtkUniformGrid.h>
2737
#endif
2838

2939
#include "FemPostObject.h"
40+
#include "FemPostObjectPy.h"
3041

3142

3243
using namespace Fem;
@@ -56,3 +67,59 @@ vtkBoundingBox FemPostObject::getBoundingBox()
5667

5768
return box;
5869
}
70+
71+
PyObject* FemPostObject::getPyObject()
72+
{
73+
if (PythonObject.is(Py::_None())) {
74+
// ref counter is set to 1
75+
PythonObject = Py::Object(new FemPostObjectPy(this), true);
76+
}
77+
78+
return Py::new_reference_to(PythonObject);
79+
}
80+
81+
namespace
82+
{
83+
84+
template<typename T>
85+
void vtkWriter(const char* filename, const vtkSmartPointer<vtkDataObject>& dataObject)
86+
{
87+
vtkSmartPointer<T> writer = vtkSmartPointer<T>::New();
88+
writer->SetFileName(filename);
89+
writer->SetDataModeToBinary();
90+
writer->SetInputDataObject(dataObject);
91+
writer->Write();
92+
}
93+
94+
} // namespace
95+
96+
97+
void FemPostObject::writeVTK(const char* filename)
98+
{
99+
const vtkSmartPointer<vtkDataObject>& data = Data.getValue();
100+
std::string name(filename);
101+
switch (data->GetDataObjectType()) {
102+
case VTK_POLY_DATA:
103+
vtkWriter<vtkXMLPolyDataWriter>(name.append(".vtp").c_str(),
104+
vtkPolyData::SafeDownCast(data));
105+
break;
106+
case VTK_STRUCTURED_GRID:
107+
vtkWriter<vtkXMLStructuredGridWriter>(name.append(".vts").c_str(),
108+
vtkStructuredGrid::SafeDownCast(data));
109+
break;
110+
case VTK_RECTILINEAR_GRID:
111+
vtkWriter<vtkXMLRectilinearGridWriter>(name.append(".vtr").c_str(),
112+
vtkRectilinearGrid::SafeDownCast(data));
113+
break;
114+
case VTK_UNSTRUCTURED_GRID:
115+
vtkWriter<vtkXMLUnstructuredGridWriter>(name.append(".vtu").c_str(),
116+
vtkUnstructuredGrid::SafeDownCast(data));
117+
break;
118+
case VTK_UNIFORM_GRID:
119+
vtkWriter<vtkXMLImageDataWriter>(name.append(".vti").c_str(),
120+
vtkUniformGrid::SafeDownCast(data));
121+
break;
122+
default:
123+
break;
124+
}
125+
}

src/Mod/Fem/App/FemPostObject.h

+3
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@ class FemExport FemPostObject: public App::GeoFeature
4545

4646
Fem::PropertyPostDataObject Data;
4747

48+
PyObject* getPyObject() override;
49+
4850
vtkBoundingBox getBoundingBox();
51+
void writeVTK(const char* filename);
4952
};
5053

5154
} // namespace Fem

src/Mod/Fem/App/FemPostObjectPy.xml

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
3+
<PythonExport
4+
Father="GeoFeaturePy"
5+
Name="FemPostObjectPy"
6+
Twin="FemPostObject"
7+
TwinPointer="FemPostObject"
8+
Include="Mod/Fem/App/FemPostObject.h"
9+
Namespace="Fem"
10+
FatherInclude="App/GeoFeaturePy.h"
11+
FatherNamespace="App">
12+
<Documentation>
13+
<Author Licence="LGPL" Name="Mario Passaglia" EMail="[email protected]" />
14+
<UserDocu>The FemPostObject class.</UserDocu>
15+
</Documentation>
16+
<Methode Name="writeVTK">
17+
<Documentation>
18+
<UserDocu>writeVTK(filename) -> None
19+
20+
Write data object to VTK file.
21+
22+
filename: str
23+
File extension is automatically detected from data type.</UserDocu>
24+
</Documentation>
25+
</Methode>
26+
27+
</PythonExport>
28+
</GenerateModel>
+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// SPDX-License-Identifier: LGPL-2.1-or-later
2+
3+
/***************************************************************************
4+
* Copyright (c) 2024 Mario Passaglia <mpassaglia[at]cbc.uba.ar> *
5+
* *
6+
* This file is part of FreeCAD. *
7+
* *
8+
* FreeCAD is free software: you can redistribute it and/or modify it *
9+
* under the terms of the GNU Lesser General Public License as *
10+
* published by the Free Software Foundation, either version 2.1 of the *
11+
* License, or (at your option) any later version. *
12+
* *
13+
* FreeCAD is distributed in the hope that it will be useful, but *
14+
* WITHOUT ANY WARRANTY; without even the implied warranty of *
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
16+
* Lesser General Public License for more details. *
17+
* *
18+
* You should have received a copy of the GNU Lesser General Public *
19+
* License along with FreeCAD. If not, see *
20+
* <https://www.gnu.org/licenses/>. *
21+
* *
22+
**************************************************************************/
23+
24+
#include "PreCompiled.h"
25+
#ifndef _PreComp_
26+
#include <Python.h>
27+
#endif
28+
29+
#include "FemPostObjectPy.h"
30+
#include "FemPostObjectPy.cpp"
31+
32+
33+
using namespace Fem;
34+
35+
// returns a string which represent the object e.g. when printed in python
36+
std::string FemPostObjectPy::representation() const
37+
{
38+
std::stringstream str;
39+
str << "<FemPostObject object at " << getFemPostObjectPtr() << ">";
40+
41+
return str.str();
42+
}
43+
44+
PyObject* FemPostObjectPy::writeVTK(PyObject* args)
45+
{
46+
char* filename;
47+
if (!PyArg_ParseTuple(args, "et", "utf-8", &filename)) {
48+
return nullptr;
49+
}
50+
51+
std::string utf8Name(filename);
52+
PyMem_Free(filename);
53+
54+
getFemPostObjectPtr()->writeVTK(utf8Name.c_str());
55+
56+
Py_Return;
57+
}
58+
59+
PyObject* FemPostObjectPy::getCustomAttributes(const char* /*attr*/) const
60+
{
61+
return nullptr;
62+
}
63+
64+
int FemPostObjectPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
65+
{
66+
return 0;
67+
}

src/Mod/Fem/App/FemPostPipelinePy.xml

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
33
<PythonExport
4-
Father="GeoFeaturePy"
4+
Father="FemPostObjectPy"
55
Name="FemPostPipelinePy"
66
Twin="FemPostPipeline"
77
TwinPointer="FemPostPipeline"
88
Include="Mod/Fem/App/FemPostPipeline.h"
99
Namespace="Fem"
10-
FatherInclude="App/GeoFeaturePy.h"
11-
FatherNamespace="App">
10+
FatherInclude="Mod/Fem/App/FemPostObjectPy.h"
11+
FatherNamespace="Fem">
1212
<Documentation>
1313
<Author Licence="LGPL" Name="Werner Mayer" EMail="[email protected]" />
1414
<UserDocu>The FemPostPipeline class.</UserDocu>

src/Mod/Fem/App/PreCompiled.h

+4
Original file line numberDiff line numberDiff line change
@@ -182,10 +182,14 @@
182182
#include <vtkWedge.h>
183183
#include <vtkXMLDataSetWriter.h>
184184
#include <vtkXMLImageDataReader.h>
185+
#include <vtkXMLImageDataWriter.h>
185186
#include <vtkXMLPUnstructuredGridReader.h>
186187
#include <vtkXMLPolyDataReader.h>
188+
#include <vtkXMLPolyDataWriter.h>
187189
#include <vtkXMLRectilinearGridReader.h>
190+
#include <vtkXMLRectilinearGridWriter-h>
188191
#include <vtkXMLStructuredGridReader.h>
192+
#include <vtkXMLStructuredGridWriter.h>
189193
#include <vtkXMLUnstructuredGridReader.h>
190194
#include <vtkXMLUnstructuredGridWriter.h>
191195

src/Mod/Fem/Gui/ViewProviderFemConstraintPy.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
FatherInclude="Gui/ViewProviderDocumentObjectPy.h"
1111
FatherNamespace="Gui">
1212
<Documentation>
13-
<Author Licence="LGPL" Name="Mario Passaglia" EMail="mpassaglia@cbc.ub.ar" />
13+
<Author Licence="LGPL" Name="Mario Passaglia" EMail="mpassaglia@cbc.uba.ar" />
1414
<UserDocu>This is the ViewProviderFemConstraint class</UserDocu>
1515
</Documentation>
1616
<Attribute Name="SymbolNode" ReadOnly="true">

src/Mod/Fem/feminout/importVTKResults.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,8 @@ def export(
7575
return
7676

7777
obj = objectslist[0]
78-
if obj.isDerivedFrom("Fem::FemPostPipeline"):
79-
Console.PrintError(
80-
"Export of a VTK post object to vtk is not yet implemented!\n"
81-
)
78+
if obj.isDerivedFrom("Fem::FemPostObject"):
79+
obj.writeVTK(filename)
8280
return
8381
elif obj.isDerivedFrom("Fem::FemMeshObject"):
8482
Console.PrintError(

0 commit comments

Comments
 (0)