Fem: Fix mesh export to vtk formats
This commit is contained in:
committed by
Chris Hennes
parent
dd1419cd5f
commit
f6e33eb5f4
@@ -196,9 +196,12 @@ private:
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
std::string EncodedName = std::string(Name);
|
||||
Base::FileInfo file(Name);
|
||||
PyMem_Free(Name);
|
||||
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
|
||||
"User parameter:BaseApp/Preferences/Mod/Fem");
|
||||
|
||||
Py::Sequence list(object);
|
||||
Base::Type meshId = Base::Type::fromName("Fem::FemMeshObject");
|
||||
for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
|
||||
@@ -207,7 +210,25 @@ private:
|
||||
App::DocumentObject* obj =
|
||||
static_cast<App::DocumentObjectPy*>(item)->getDocumentObjectPtr();
|
||||
if (obj->getTypeId().isDerivedFrom(meshId)) {
|
||||
static_cast<FemMeshObject*>(obj)->FemMesh.getValue().write(EncodedName.c_str());
|
||||
auto femMesh = static_cast<FemMeshObject*>(obj)->FemMesh.getValue();
|
||||
if (file.hasExtension({"vtk", "vtu"})) {
|
||||
// get VTK prefs
|
||||
ParameterGrp::handle g = hGrp->GetGroup("InOutVtk");
|
||||
std::string level = g->GetASCII("MeshExportLevel", "Highest");
|
||||
femMesh.writeVTK(file.filePath().c_str(),
|
||||
level == "Highest" ? true : false);
|
||||
}
|
||||
else if (file.hasExtension("inp")) {
|
||||
// get Abaqus inp prefs
|
||||
ParameterGrp::handle g = hGrp->GetGroup("Abaqus");
|
||||
int elemParam = g->GetInt("AbaqusElementChoice", 1);
|
||||
bool groupParam = g->GetBool("AbaqusWriteGroups", false);
|
||||
// write ABAQUS Output
|
||||
femMesh.writeABAQUS(file.filePath(), elemParam, groupParam);
|
||||
}
|
||||
else {
|
||||
femMesh.write(file.filePath().c_str());
|
||||
}
|
||||
return Py::None();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1647,6 +1647,11 @@ void FemMesh::read(const char* FileName)
|
||||
}
|
||||
}
|
||||
|
||||
void FemMesh::writeVTK(const std::string& fileName, bool highest) const
|
||||
{
|
||||
FemVTKTools::writeVTKMesh(fileName.c_str(), this, highest);
|
||||
}
|
||||
|
||||
void FemMesh::writeABAQUS(const std::string& Filename,
|
||||
int elemParam,
|
||||
bool groupParam,
|
||||
@@ -2272,19 +2277,14 @@ void FemMesh::write(const char* FileName) const
|
||||
}
|
||||
else if (File.hasExtension("inp")) {
|
||||
Base::Console().Log("FEM mesh object will be exported to inp format.\n");
|
||||
// get Abaqus inp prefs
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
|
||||
"User parameter:BaseApp/Preferences/Mod/Fem/Abaqus");
|
||||
int elemParam = hGrp->GetInt("AbaqusElementChoice", 1);
|
||||
bool groupParam = hGrp->GetBool("AbaqusWriteGroups", false);
|
||||
// write ABAQUS Output
|
||||
writeABAQUS(File.filePath(), elemParam, groupParam);
|
||||
writeABAQUS(File.filePath(), 1, false);
|
||||
}
|
||||
#ifdef FC_USE_VTK
|
||||
else if (File.hasExtension({"vtk", "vtu"})) {
|
||||
Base::Console().Log("FEM mesh object will be exported to either vtk or vtu format.\n");
|
||||
// write unstructure mesh to VTK format *.vtk and *.vtu
|
||||
FemVTKTools::writeVTKMesh(File.filePath().c_str(), this);
|
||||
writeVTK(File.filePath().c_str());
|
||||
}
|
||||
#endif
|
||||
else if (File.hasExtension("z88")) {
|
||||
|
||||
@@ -210,6 +210,7 @@ public:
|
||||
ABAQUS_VolumeVariant volVariant = ABAQUS_VolumeVariant::Standard,
|
||||
ABAQUS_FaceVariant faceVariant = ABAQUS_FaceVariant::Shell,
|
||||
ABAQUS_EdgeVariant edgeVariant = ABAQUS_EdgeVariant::Beam) const;
|
||||
void writeVTK(const std::string& FileName, bool highest = true) const;
|
||||
void writeZ88(const std::string& FileName) const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -339,14 +339,12 @@ FemMesh* FemVTKTools::readVTKMesh(const char* filename, FemMesh* mesh)
|
||||
return mesh;
|
||||
}
|
||||
|
||||
void exportFemMeshEdges(vtkSmartPointer<vtkUnstructuredGrid> grid,
|
||||
void exportFemMeshEdges(vtkSmartPointer<vtkCellArray>& elemArray,
|
||||
std::vector<int>& types,
|
||||
const SMDS_EdgeIteratorPtr& aEdgeIter)
|
||||
{
|
||||
Base::Console().Log(" Start: VTK mesh builder edges.\n");
|
||||
|
||||
vtkSmartPointer<vtkCellArray> elemArray = vtkSmartPointer<vtkCellArray>::New();
|
||||
std::vector<int> types;
|
||||
|
||||
while (aEdgeIter->more()) {
|
||||
const SMDS_MeshEdge* aEdge = aEdgeIter->next();
|
||||
// edge
|
||||
@@ -362,21 +360,15 @@ void exportFemMeshEdges(vtkSmartPointer<vtkUnstructuredGrid> grid,
|
||||
}
|
||||
}
|
||||
|
||||
if (elemArray->GetNumberOfCells() > 0) {
|
||||
grid->SetCells(types.data(), elemArray);
|
||||
}
|
||||
|
||||
Base::Console().Log(" End: VTK mesh builder edges.\n");
|
||||
}
|
||||
|
||||
void exportFemMeshFaces(vtkSmartPointer<vtkUnstructuredGrid> grid,
|
||||
void exportFemMeshFaces(vtkSmartPointer<vtkCellArray>& elemArray,
|
||||
std::vector<int>& types,
|
||||
const SMDS_FaceIteratorPtr& aFaceIter)
|
||||
{
|
||||
Base::Console().Log(" Start: VTK mesh builder faces.\n");
|
||||
|
||||
vtkSmartPointer<vtkCellArray> elemArray = vtkSmartPointer<vtkCellArray>::New();
|
||||
std::vector<int> types;
|
||||
|
||||
while (aFaceIter->more()) {
|
||||
const SMDS_MeshFace* aFace = aFaceIter->next();
|
||||
// triangle
|
||||
@@ -400,21 +392,15 @@ void exportFemMeshFaces(vtkSmartPointer<vtkUnstructuredGrid> grid,
|
||||
}
|
||||
}
|
||||
|
||||
if (elemArray->GetNumberOfCells() > 0) {
|
||||
grid->SetCells(types.data(), elemArray);
|
||||
}
|
||||
|
||||
Base::Console().Log(" End: VTK mesh builder faces.\n");
|
||||
}
|
||||
|
||||
void exportFemMeshCells(vtkSmartPointer<vtkUnstructuredGrid> grid,
|
||||
void exportFemMeshCells(vtkSmartPointer<vtkCellArray>& elemArray,
|
||||
std::vector<int>& types,
|
||||
const SMDS_VolumeIteratorPtr& aVolIter)
|
||||
{
|
||||
Base::Console().Log(" Start: VTK mesh builder volumes.\n");
|
||||
|
||||
vtkSmartPointer<vtkCellArray> elemArray = vtkSmartPointer<vtkCellArray>::New();
|
||||
std::vector<int> types;
|
||||
|
||||
while (aVolIter->more()) {
|
||||
const SMDS_MeshVolume* aVol = aVolIter->next();
|
||||
|
||||
@@ -447,15 +433,12 @@ void exportFemMeshCells(vtkSmartPointer<vtkUnstructuredGrid> grid,
|
||||
}
|
||||
}
|
||||
|
||||
if (elemArray->GetNumberOfCells() > 0) {
|
||||
grid->SetCells(types.data(), elemArray);
|
||||
}
|
||||
|
||||
Base::Console().Log(" End: VTK mesh builder volumes.\n");
|
||||
}
|
||||
|
||||
void FemVTKTools::exportVTKMesh(const FemMesh* mesh,
|
||||
vtkSmartPointer<vtkUnstructuredGrid> grid,
|
||||
bool highest,
|
||||
float scale)
|
||||
{
|
||||
|
||||
@@ -489,22 +472,45 @@ void FemVTKTools::exportVTKMesh(const FemMesh* mesh,
|
||||
Base::Console().Log(" Size of nodes in VTK grid: %i.\n", nNodes);
|
||||
Base::Console().Log(" End: VTK mesh builder nodes.\n");
|
||||
|
||||
// edges
|
||||
SMDS_EdgeIteratorPtr aEdgeIter = meshDS->edgesIterator();
|
||||
exportFemMeshEdges(grid, aEdgeIter);
|
||||
vtkSmartPointer<vtkCellArray> elemArray = vtkSmartPointer<vtkCellArray>::New();
|
||||
std::vector<int> types;
|
||||
|
||||
// faces
|
||||
SMDS_FaceIteratorPtr aFaceIter = meshDS->facesIterator();
|
||||
exportFemMeshFaces(grid, aFaceIter);
|
||||
if (highest) {
|
||||
// try volumes
|
||||
SMDS_VolumeIteratorPtr aVolIter = meshDS->volumesIterator();
|
||||
exportFemMeshCells(elemArray, types, aVolIter);
|
||||
// try faces
|
||||
if (elemArray->GetNumberOfCells() == 0) {
|
||||
SMDS_FaceIteratorPtr aFaceIter = meshDS->facesIterator();
|
||||
exportFemMeshFaces(elemArray, types, aFaceIter);
|
||||
}
|
||||
// try edges
|
||||
if (elemArray->GetNumberOfCells() == 0) {
|
||||
SMDS_EdgeIteratorPtr aEdgeIter = meshDS->edgesIterator();
|
||||
exportFemMeshEdges(elemArray, types, aEdgeIter);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// export all elements
|
||||
// edges
|
||||
SMDS_EdgeIteratorPtr aEdgeIter = meshDS->edgesIterator();
|
||||
exportFemMeshEdges(elemArray, types, aEdgeIter);
|
||||
// faces
|
||||
SMDS_FaceIteratorPtr aFaceIter = meshDS->facesIterator();
|
||||
exportFemMeshFaces(elemArray, types, aFaceIter);
|
||||
// volumes
|
||||
SMDS_VolumeIteratorPtr aVolIter = meshDS->volumesIterator();
|
||||
exportFemMeshCells(elemArray, types, aVolIter);
|
||||
}
|
||||
|
||||
// volumes
|
||||
SMDS_VolumeIteratorPtr aVolIter = meshDS->volumesIterator();
|
||||
exportFemMeshCells(grid, aVolIter);
|
||||
if (elemArray->GetNumberOfCells() > 0) {
|
||||
grid->SetCells(types.data(), elemArray);
|
||||
}
|
||||
|
||||
Base::Console().Log("End: VTK mesh builder ======================\n");
|
||||
}
|
||||
|
||||
void FemVTKTools::writeVTKMesh(const char* filename, const FemMesh* mesh)
|
||||
void FemVTKTools::writeVTKMesh(const char* filename, const FemMesh* mesh, bool highest)
|
||||
{
|
||||
|
||||
Base::TimeElapsed Start;
|
||||
@@ -512,7 +518,7 @@ void FemVTKTools::writeVTKMesh(const char* filename, const FemMesh* mesh)
|
||||
Base::FileInfo f(filename);
|
||||
|
||||
vtkSmartPointer<vtkUnstructuredGrid> grid = vtkSmartPointer<vtkUnstructuredGrid>::New();
|
||||
exportVTKMesh(mesh, grid);
|
||||
exportVTKMesh(mesh, grid, highest);
|
||||
Base::Console().Log("Start: writing mesh data ======================\n");
|
||||
if (f.hasExtension("vtu")) {
|
||||
writeVTKFile<vtkXMLUnstructuredGridWriter>(filename, grid);
|
||||
|
||||
@@ -42,9 +42,11 @@ public:
|
||||
// data
|
||||
static void importVTKMesh(vtkSmartPointer<vtkDataSet> grid, FemMesh* mesh, float scale = 1.0);
|
||||
|
||||
// extract data from FreCAD FEM mesh and fill a vtkUnstructuredGrid instance with that data
|
||||
// extract data from FreCAD FEM mesh and fill a vtkUnstructuredGrid instance with that data. Set
|
||||
// `highest` to false to export all elements levels.
|
||||
static void exportVTKMesh(const FemMesh* mesh,
|
||||
vtkSmartPointer<vtkUnstructuredGrid> grid,
|
||||
bool highest = true,
|
||||
float scale = 1.0);
|
||||
|
||||
// extract data from vtkUnstructuredGrid object and fill a FreeCAD FEM result object with that
|
||||
@@ -61,7 +63,7 @@ public:
|
||||
static FemMesh* readVTKMesh(const char* filename, FemMesh* mesh);
|
||||
|
||||
// FemMesh write to vtkUnstructuredGrid data file
|
||||
static void writeVTKMesh(const char* Filename, const FemMesh* mesh);
|
||||
static void writeVTKMesh(const char* Filename, const FemMesh* mesh, bool highest = true);
|
||||
|
||||
// FemResult (activeObject or created if res= NULL) read from vtkUnstructuredGrid dataset file
|
||||
static App::DocumentObject* readResult(const char* Filename,
|
||||
|
||||
@@ -84,6 +84,41 @@ exported from FreeCAD.</string>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QGroupBox" name="gb_export">
|
||||
<property name="title">
|
||||
<string>Export</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gl_export">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lbl_export_level">
|
||||
<property name="text">
|
||||
<string>Mesh elements to export</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="Gui::PrefComboBox" name="cb_export_level">
|
||||
<property name="toolTip">
|
||||
<string>Mesh element level to export</string>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QComboBox::AdjustToContents</enum>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>MeshExportLevel</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>Mod/Fem/InOutVtk</cstring>
|
||||
</property>
|
||||
<property name="prefType" stdset="0">
|
||||
<string></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
|
||||
@@ -51,6 +51,7 @@ void DlgSettingsFemInOutVtkImp::saveSettings()
|
||||
hGrp->SetInt("ImportObject", ui->comboBoxVtkImportObject->currentIndex());
|
||||
|
||||
ui->comboBoxVtkImportObject->onSave();
|
||||
ui->cb_export_level->onSave();
|
||||
}
|
||||
|
||||
void DlgSettingsFemInOutVtkImp::loadSettings()
|
||||
@@ -64,6 +65,9 @@ void DlgSettingsFemInOutVtkImp::loadSettings()
|
||||
if (index > -1) {
|
||||
ui->comboBoxVtkImportObject->setCurrentIndex(index);
|
||||
}
|
||||
|
||||
populateExportLevel();
|
||||
ui->cb_export_level->onRestore();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,4 +85,19 @@ void DlgSettingsFemInOutVtkImp::changeEvent(QEvent* e)
|
||||
}
|
||||
}
|
||||
|
||||
void DlgSettingsFemInOutVtkImp::populateExportLevel() const
|
||||
{
|
||||
std::list<std::string> values = {"All", "Highest"};
|
||||
|
||||
for (const auto& val : values) {
|
||||
ui->cb_export_level->addItem(QString::fromStdString(val));
|
||||
}
|
||||
|
||||
auto hGrp = App::GetApplication().GetParameterGroupByPath(
|
||||
"User parameter:BaseApp/Preferences/Mod/Fem/InOutVtk");
|
||||
std::string current = hGrp->GetASCII("MeshExportLevel", "Highest");
|
||||
int index = ui->cb_export_level->findText(QString::fromStdString(current));
|
||||
ui->cb_export_level->setCurrentIndex(index);
|
||||
}
|
||||
|
||||
#include "moc_DlgSettingsFemInOutVtkImp.cpp"
|
||||
|
||||
@@ -48,6 +48,7 @@ protected:
|
||||
void changeEvent(QEvent* e) override;
|
||||
|
||||
private:
|
||||
void populateExportLevel() const;
|
||||
std::unique_ptr<Ui_DlgSettingsFemInOutVtk> ui;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user