修复因前后处理工具栏的显示边框按钮对象同名导致的后处理无法点击显示边框的问题,添加OpenFOAM网格支持
parent
2a2499ecf9
commit
c517575922
|
@ -3,7 +3,7 @@
|
||||||
Version:2.5.x
|
Version:2.5.x
|
||||||
|
|
||||||
---
|
---
|
||||||
更新时间:2020-05-08
|
更新时间:2020-07-04
|
||||||
|
|
||||||
**新增功能**
|
**新增功能**
|
||||||
- 后处理增加tecplot文件(szplt)的读取。
|
- 后处理增加tecplot文件(szplt)的读取。
|
||||||
|
@ -11,6 +11,7 @@ Version:2.5.x
|
||||||
- 新增自动打包功能,Windows需要NSIS 3.03+、Linux需要dpkg-deb或者rpmbuild(需要python3)。
|
- 新增自动打包功能,Windows需要NSIS 3.03+、Linux需要dpkg-deb或者rpmbuild(需要python3)。
|
||||||
- 新增文档自动生成功能,需要安装Doxygen和Graphviz。
|
- 新增文档自动生成功能,需要安装Doxygen和Graphviz。
|
||||||
- 增加vtu、pvtu格式的后处理文件支持
|
- 增加vtu、pvtu格式的后处理文件支持
|
||||||
|
- 增加OpenFOAM的网格文件支持,目前仅支持ascii格式,且不支持并行划分的网格
|
||||||
|
|
||||||
**功能优化**
|
**功能优化**
|
||||||
- 代码全部采用cmake进行管理,可任意选择vscode、Visual Studio、Clion、Qtcreator等支持cmake系统的IDE。
|
- 代码全部采用cmake进行管理,可任意选择vscode、Visual Studio、Clion、Qtcreator等支持cmake系统的IDE。
|
||||||
|
@ -26,6 +27,8 @@ Version:2.5.x
|
||||||
- 修复linux环境卸载插件时崩溃的问题
|
- 修复linux环境卸载插件时崩溃的问题
|
||||||
- 修复单个窗口下视图控制不正常的问题
|
- 修复单个窗口下视图控制不正常的问题
|
||||||
- 修复几何绘制线段失败的问题
|
- 修复几何绘制线段失败的问题
|
||||||
|
- 修复后处理动画崩溃问题
|
||||||
|
- 修复因前后处理工具栏的显示边框按钮对象同名导致的后处理无法点击显示边框的问题
|
||||||
|
|
||||||
**其他**
|
**其他**
|
||||||
- OpenCASCADE的版本变更(7.5.0->7.6.0)。
|
- OpenCASCADE的版本变更(7.5.0->7.6.0)。
|
||||||
|
|
|
@ -348,7 +348,7 @@ namespace GUI {
|
||||||
_ui->menuSelect->setEnabled(on);
|
_ui->menuSelect->setEnabled(on);
|
||||||
}
|
}
|
||||||
_ui->actionDisplayNode->setVisible(on);
|
_ui->actionDisplayNode->setVisible(on);
|
||||||
_ui->actionDisplayWireFrame->setVisible(on);
|
_ui->actionPreDisplayWireFrame->setVisible(on);
|
||||||
_ui->actionDisplaySurface->setVisible(on);
|
_ui->actionDisplaySurface->setVisible(on);
|
||||||
// _ui->actionDisplaySurfaceEdge->setVisible(on);
|
// _ui->actionDisplaySurfaceEdge->setVisible(on);
|
||||||
|
|
||||||
|
|
|
@ -280,7 +280,7 @@ namespace GUI {
|
||||||
// 网格显示模式
|
// 网格显示模式
|
||||||
// _displayModeSignalMapper = new QSignalMapper(this);
|
// _displayModeSignalMapper = new QSignalMapper(this);
|
||||||
connect(_ui->actionDisplayNode, SIGNAL(triggered()), this, SLOT(setMeshDisplay()));
|
connect(_ui->actionDisplayNode, SIGNAL(triggered()), this, SLOT(setMeshDisplay()));
|
||||||
connect(_ui->actionDisplayWireFrame, SIGNAL(triggered()), this, SLOT(setMeshDisplay()));
|
connect(_ui->actionPreDisplayWireFrame, SIGNAL(triggered()), this, SLOT(setMeshDisplay()));
|
||||||
connect(_ui->actionDisplaySurface, SIGNAL(triggered()), this, SLOT(setMeshDisplay()));
|
connect(_ui->actionDisplaySurface, SIGNAL(triggered()), this, SLOT(setMeshDisplay()));
|
||||||
// 几何显示模式(点、线、面)
|
// 几何显示模式(点、线、面)
|
||||||
connect(_ui->actionDisplayPoint, SIGNAL(triggered()), this, SLOT(setGeometryDisplay()));
|
connect(_ui->actionDisplayPoint, SIGNAL(triggered()), this, SLOT(setGeometryDisplay()));
|
||||||
|
@ -884,7 +884,7 @@ namespace GUI {
|
||||||
void MainWindow::setMeshDisplay()
|
void MainWindow::setMeshDisplay()
|
||||||
{
|
{
|
||||||
bool showNode = _ui->actionDisplayNode->isChecked();
|
bool showNode = _ui->actionDisplayNode->isChecked();
|
||||||
bool showEdge = _ui->actionDisplayWireFrame->isChecked();
|
bool showEdge = _ui->actionPreDisplayWireFrame->isChecked();
|
||||||
bool showFace = _ui->actionDisplaySurface->isChecked();
|
bool showFace = _ui->actionDisplaySurface->isChecked();
|
||||||
|
|
||||||
auto gp = Setting::BusAPI::instance()->getGraphOption();
|
auto gp = Setting::BusAPI::instance()->getGraphOption();
|
||||||
|
|
|
@ -127,7 +127,7 @@
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</attribute>
|
</attribute>
|
||||||
<addaction name="actionDisplayNode"/>
|
<addaction name="actionDisplayNode"/>
|
||||||
<addaction name="actionDisplayWireFrame"/>
|
<addaction name="actionPreDisplayWireFrame"/>
|
||||||
<addaction name="actionDisplaySurface"/>
|
<addaction name="actionDisplaySurface"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="actionDisplayPoint"/>
|
<addaction name="actionDisplayPoint"/>
|
||||||
|
@ -362,7 +362,7 @@
|
||||||
<string>View</string>
|
<string>View</string>
|
||||||
</property>
|
</property>
|
||||||
<addaction name="actionDisplayNode"/>
|
<addaction name="actionDisplayNode"/>
|
||||||
<addaction name="actionDisplayWireFrame"/>
|
<addaction name="actionPreDisplayWireFrame"/>
|
||||||
<addaction name="actionDisplaySurface"/>
|
<addaction name="actionDisplaySurface"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenu" name="menuSelect">
|
<widget class="QMenu" name="menuSelect">
|
||||||
|
@ -557,7 +557,7 @@
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</attribute>
|
</attribute>
|
||||||
<addaction name="actionDisplayPoints"/>
|
<addaction name="actionDisplayPoints"/>
|
||||||
<addaction name="actionDisplayWireframe"/>
|
<addaction name="actionPostDisplayWireframe"/>
|
||||||
<addaction name="actionDisplaySurfaceWithoutEdge"/>
|
<addaction name="actionDisplaySurfaceWithoutEdge"/>
|
||||||
<addaction name="actionDisplaySurfaceWithEdge"/>
|
<addaction name="actionDisplaySurfaceWithEdge"/>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -970,7 +970,7 @@
|
||||||
<string>DisplayNode</string>
|
<string>DisplayNode</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionDisplayWireFrame">
|
<action name="actionPreDisplayWireFrame">
|
||||||
<property name="checkable">
|
<property name="checkable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
|
@ -1718,7 +1718,7 @@
|
||||||
<string>DisplayPoints</string>
|
<string>DisplayPoints</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionDisplayWireframe">
|
<action name="actionPostDisplayWireframe">
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../qrc/qianfan.qrc">
|
<iconset resource="../qrc/qianfan.qrc">
|
||||||
<normaloff>:/QUI/post/rep_wireFrame.png</normaloff>:/QUI/post/rep_wireFrame.png</iconset>
|
<normaloff>:/QUI/post/rep_wireFrame.png</normaloff>:/QUI/post/rep_wireFrame.png</iconset>
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -218,7 +218,7 @@ namespace GUI {
|
||||||
SLOT(openPostFile()));
|
SLOT(openPostFile()));
|
||||||
connect(mainwindow->getUi()->actionDisplayPoints, &QAction::triggered,
|
connect(mainwindow->getUi()->actionDisplayPoints, &QAction::triggered,
|
||||||
[=] { this->setPostDisplayMode(0); });
|
[=] { this->setPostDisplayMode(0); });
|
||||||
connect(mainwindow->getUi()->actionDisplayWireframe, &QAction::triggered,
|
connect(mainwindow->getUi()->actionPostDisplayWireframe, &QAction::triggered,
|
||||||
[=] { this->setPostDisplayMode(1); });
|
[=] { this->setPostDisplayMode(1); });
|
||||||
connect(mainwindow->getUi()->actionDisplaySurfaceWithoutEdge, &QAction::triggered,
|
connect(mainwindow->getUi()->actionDisplaySurfaceWithoutEdge, &QAction::triggered,
|
||||||
[=] { this->setPostDisplayMode(2); });
|
[=] { this->setPostDisplayMode(2); });
|
||||||
|
@ -568,7 +568,7 @@ namespace GUI {
|
||||||
ui->actionDisplayNode->setEnabled(false);
|
ui->actionDisplayNode->setEnabled(false);
|
||||||
ui->actionDisplaySurface->setEnabled(false);
|
ui->actionDisplaySurface->setEnabled(false);
|
||||||
// ui->actionDisplaySurfaceEdge->setEnabled(false);
|
// ui->actionDisplaySurfaceEdge->setEnabled(false);
|
||||||
ui->actionDisplayWireFrame->setEnabled(false);
|
ui->actionPreDisplayWireFrame->setEnabled(false);
|
||||||
ui->actionCreate_Set->setEnabled(false);
|
ui->actionCreate_Set->setEnabled(false);
|
||||||
ui->actionChecking->setEnabled(false);
|
ui->actionChecking->setEnabled(false);
|
||||||
ui->actionFilterMesh->setEnabled(false);
|
ui->actionFilterMesh->setEnabled(false);
|
||||||
|
@ -586,7 +586,7 @@ namespace GUI {
|
||||||
ui->actionSaveImage->setEnabled(false);
|
ui->actionSaveImage->setEnabled(false);
|
||||||
ui->actionSaveVideo->setEnabled(false);
|
ui->actionSaveVideo->setEnabled(false);
|
||||||
ui->actionDisplayPoints->setEnabled(false);
|
ui->actionDisplayPoints->setEnabled(false);
|
||||||
ui->actionDisplayWireframe->setEnabled(false);
|
ui->actionPostDisplayWireframe->setEnabled(false);
|
||||||
ui->actionDisplaySurfaceWithEdge->setEnabled(false);
|
ui->actionDisplaySurfaceWithEdge->setEnabled(false);
|
||||||
ui->actionDisplaySurfaceWithoutEdge->setEnabled(false);
|
ui->actionDisplaySurfaceWithoutEdge->setEnabled(false);
|
||||||
ui->actionCreateClip->setEnabled(false);
|
ui->actionCreateClip->setEnabled(false);
|
||||||
|
@ -649,13 +649,13 @@ namespace GUI {
|
||||||
ui->actionDisplayNode->setEnabled(true);
|
ui->actionDisplayNode->setEnabled(true);
|
||||||
ui->actionDisplaySurface->setEnabled(true);
|
ui->actionDisplaySurface->setEnabled(true);
|
||||||
// ui->actionDisplaySurfaceEdge->setEnabled(true);
|
// ui->actionDisplaySurfaceEdge->setEnabled(true);
|
||||||
ui->actionDisplayWireFrame->setEnabled(true);
|
ui->actionPreDisplayWireFrame->setEnabled(true);
|
||||||
ui->actionVTKTranslation->setEnabled(true);
|
ui->actionVTKTranslation->setEnabled(true);
|
||||||
|
|
||||||
auto gp = Setting::BusAPI::instance()->getGraphOption();
|
auto gp = Setting::BusAPI::instance()->getGraphOption();
|
||||||
ui->actionDisplayNode->setChecked(gp->isShowMeshNode());
|
ui->actionDisplayNode->setChecked(gp->isShowMeshNode());
|
||||||
ui->actionDisplaySurface->setChecked(gp->isShowMeshFace());
|
ui->actionDisplaySurface->setChecked(gp->isShowMeshFace());
|
||||||
ui->actionDisplayWireFrame->setChecked(gp->isShowMeshEdge());
|
ui->actionPreDisplayWireFrame->setChecked(gp->isShowMeshEdge());
|
||||||
}
|
}
|
||||||
if(subwins->isPostWindowOpened()) {
|
if(subwins->isPostWindowOpened()) {
|
||||||
ui->actionViewXPlus->setEnabled(true);
|
ui->actionViewXPlus->setEnabled(true);
|
||||||
|
@ -671,7 +671,7 @@ namespace GUI {
|
||||||
ui->actionSaveImage->setEnabled(true);
|
ui->actionSaveImage->setEnabled(true);
|
||||||
ui->actionSaveVideo->setEnabled(true);
|
ui->actionSaveVideo->setEnabled(true);
|
||||||
ui->actionDisplayPoints->setEnabled(true);
|
ui->actionDisplayPoints->setEnabled(true);
|
||||||
ui->actionDisplayWireframe->setEnabled(true);
|
ui->actionPostDisplayWireframe->setEnabled(true);
|
||||||
ui->actionDisplaySurfaceWithEdge->setEnabled(true);
|
ui->actionDisplaySurfaceWithEdge->setEnabled(true);
|
||||||
ui->actionDisplaySurfaceWithoutEdge->setEnabled(true);
|
ui->actionDisplaySurfaceWithoutEdge->setEnabled(true);
|
||||||
ui->actionCreateClip->setEnabled(true);
|
ui->actionCreateClip->setEnabled(true);
|
||||||
|
|
|
@ -360,4 +360,20 @@ QString MeshSet::setTypeToString(SetType type)
|
||||||
}
|
}
|
||||||
return qtype;
|
return qtype;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BoundMeshSet::BoundMeshSet(): MeshSet()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void BoundMeshSet::setCellFaces(const QMap<int, QVector<int>> cellFaces)
|
||||||
|
{
|
||||||
|
m_CellFaces = cellFaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMap<int, QVector<int>> BoundMeshSet::getCellFaces()
|
||||||
|
{
|
||||||
|
return m_CellFaces;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QMultiHash>
|
#include <QMultiHash>
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
|
#include <QMap>
|
||||||
|
|
||||||
class vtkDataSet;
|
class vtkDataSet;
|
||||||
class vtkUnstructuredGrid;
|
class vtkUnstructuredGrid;
|
||||||
|
@ -102,7 +103,19 @@ namespace MeshData
|
||||||
// static int maxID;
|
// static int maxID;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//用于流体网格边界信息存储。边界由多个单元的一个或多个面组成。
|
||||||
|
class MESHDATAAPI BoundMeshSet : public MeshSet
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BoundMeshSet();
|
||||||
|
~BoundMeshSet() = default;
|
||||||
|
void setCellFaces(const QMap<int, QVector<int>> cellFaces);
|
||||||
|
QMap<int, QVector<int>> getCellFaces();
|
||||||
|
protected:
|
||||||
|
//key为单元索引,value为该单元的面索引
|
||||||
|
QMap<int, QVector<int>> m_CellFaces{};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ namespace FastCAEDesigner{
|
||||||
{
|
{
|
||||||
ui->chk_cgns->setChecked(true);
|
ui->chk_cgns->setChecked(true);
|
||||||
ui->chk_flunet->setChecked(true);
|
ui->chk_flunet->setChecked(true);
|
||||||
|
ui->chk_openfoam->setChecked(true);
|
||||||
ui->chk_gambit->setChecked(true);
|
ui->chk_gambit->setChecked(true);
|
||||||
ui->chk_stl->setChecked(true);
|
ui->chk_stl->setChecked(true);
|
||||||
ui->chk_tecplot->setChecked(true);
|
ui->chk_tecplot->setChecked(true);
|
||||||
|
@ -55,6 +56,7 @@ namespace FastCAEDesigner{
|
||||||
{
|
{
|
||||||
ui->chk_cgns->setChecked(false);
|
ui->chk_cgns->setChecked(false);
|
||||||
ui->chk_flunet->setChecked(false);
|
ui->chk_flunet->setChecked(false);
|
||||||
|
ui->chk_openfoam->setChecked(false);
|
||||||
ui->chk_gambit->setChecked(false);
|
ui->chk_gambit->setChecked(false);
|
||||||
ui->chk_stl->setChecked(false);
|
ui->chk_stl->setChecked(false);
|
||||||
ui->chk_tecplot->setChecked(false);
|
ui->chk_tecplot->setChecked(false);
|
||||||
|
@ -79,6 +81,10 @@ namespace FastCAEDesigner{
|
||||||
{
|
{
|
||||||
sl.append("msh");
|
sl.append("msh");
|
||||||
}
|
}
|
||||||
|
if (ui->chk_openfoam->isChecked())
|
||||||
|
{
|
||||||
|
sl.append("foam");
|
||||||
|
}
|
||||||
if (ui->chk_gambit->isChecked())
|
if (ui->chk_gambit->isChecked())
|
||||||
{
|
{
|
||||||
sl.append("neu");
|
sl.append("neu");
|
||||||
|
@ -147,6 +153,11 @@ namespace FastCAEDesigner{
|
||||||
ui->chk_flunet->setChecked(true);
|
ui->chk_flunet->setChecked(true);
|
||||||
a = a + 1;
|
a = a + 1;
|
||||||
}
|
}
|
||||||
|
if (sl.at(i) == "foam")
|
||||||
|
{
|
||||||
|
ui->chk_openfoam->setChecked(true);
|
||||||
|
a = a + 1;
|
||||||
|
}
|
||||||
if (sl.at(i) == "neu")
|
if (sl.at(i) == "neu")
|
||||||
{
|
{
|
||||||
ui->chk_gambit->setChecked(true);
|
ui->chk_gambit->setChecked(true);
|
||||||
|
@ -208,6 +219,7 @@ namespace FastCAEDesigner{
|
||||||
void ParaImportMeshSetup::CancelCheckAll()
|
void ParaImportMeshSetup::CancelCheckAll()
|
||||||
{
|
{
|
||||||
if ((ui->chk_cgns->isChecked()) && (ui->chk_flunet->isChecked()) && (ui->chk_gambit->isChecked()) &&
|
if ((ui->chk_cgns->isChecked()) && (ui->chk_flunet->isChecked()) && (ui->chk_gambit->isChecked()) &&
|
||||||
|
(ui->chk_openfoam->isChecked()) &&
|
||||||
(ui->chk_stl->isChecked()) && (ui->chk_tecplot->isChecked()) && (ui->chk_vtk->isChecked())
|
(ui->chk_stl->isChecked()) && (ui->chk_tecplot->isChecked()) && (ui->chk_vtk->isChecked())
|
||||||
&& (ui->chk_inp->isChecked()) && (ui->chk_cntm->isChecked()) && (ui->chk_su2->isChecked())
|
&& (ui->chk_inp->isChecked()) && (ui->chk_cntm->isChecked()) && (ui->chk_su2->isChecked())
|
||||||
&& (ui->chk_key->isChecked()) && (ui->chk_pdb->isChecked()) && (ui->chk_bdf->isChecked()))
|
&& (ui->chk_key->isChecked()) && (ui->chk_pdb->isChecked()) && (ui->chk_bdf->isChecked()))
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Import mesh setup</string>
|
<string>Import mesh setup</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_3">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item row="0" column="0">
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="chk_selectall">
|
<widget class="QCheckBox" name="chk_selectall">
|
||||||
|
@ -45,7 +45,7 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer">
|
<spacer name="horizontalSpacer">
|
||||||
|
@ -64,7 +64,7 @@
|
||||||
<widget class="QCheckBox" name="chk_cgns">
|
<widget class="QCheckBox" name="chk_cgns">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>110</width>
|
<width>120</width>
|
||||||
<height>0</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
@ -88,7 +88,7 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_13">
|
<layout class="QHBoxLayout" name="horizontalLayout_13">
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer_22">
|
<spacer name="horizontalSpacer_22">
|
||||||
|
@ -107,7 +107,7 @@
|
||||||
<widget class="QCheckBox" name="chk_flunet">
|
<widget class="QCheckBox" name="chk_flunet">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>110</width>
|
<width>120</width>
|
||||||
<height>0</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
@ -131,7 +131,50 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_15">
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_27">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="chk_openfoam">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>120</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>OpenFOAM(*.foam)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_28">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_11">
|
<layout class="QHBoxLayout" name="horizontalLayout_11">
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer_18">
|
<spacer name="horizontalSpacer_18">
|
||||||
|
@ -150,7 +193,7 @@
|
||||||
<widget class="QCheckBox" name="chk_gambit">
|
<widget class="QCheckBox" name="chk_gambit">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>110</width>
|
<width>120</width>
|
||||||
<height>0</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
@ -174,7 +217,7 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="0">
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_12">
|
<layout class="QHBoxLayout" name="horizontalLayout_12">
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer_20">
|
<spacer name="horizontalSpacer_20">
|
||||||
|
@ -193,7 +236,7 @@
|
||||||
<widget class="QCheckBox" name="chk_stl">
|
<widget class="QCheckBox" name="chk_stl">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>110</width>
|
<width>120</width>
|
||||||
<height>0</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
@ -217,7 +260,7 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="0">
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_10">
|
<layout class="QHBoxLayout" name="horizontalLayout_10">
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer_16">
|
<spacer name="horizontalSpacer_16">
|
||||||
|
@ -236,7 +279,7 @@
|
||||||
<widget class="QCheckBox" name="chk_tecplot">
|
<widget class="QCheckBox" name="chk_tecplot">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>110</width>
|
<width>120</width>
|
||||||
<height>0</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
@ -260,7 +303,7 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="0">
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer_14">
|
<spacer name="horizontalSpacer_14">
|
||||||
|
@ -279,7 +322,7 @@
|
||||||
<widget class="QCheckBox" name="chk_vtk">
|
<widget class="QCheckBox" name="chk_vtk">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>110</width>
|
<width>120</width>
|
||||||
<height>0</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
@ -303,7 +346,7 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="7" column="0">
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer_3">
|
<spacer name="horizontalSpacer_3">
|
||||||
|
@ -322,7 +365,7 @@
|
||||||
<widget class="QCheckBox" name="chk_inp">
|
<widget class="QCheckBox" name="chk_inp">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>110</width>
|
<width>120</width>
|
||||||
<height>0</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
@ -346,7 +389,7 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="8" column="0">
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer_5">
|
<spacer name="horizontalSpacer_5">
|
||||||
|
@ -365,7 +408,7 @@
|
||||||
<widget class="QCheckBox" name="chk_cntm">
|
<widget class="QCheckBox" name="chk_cntm">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>110</width>
|
<width>120</width>
|
||||||
<height>0</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
@ -389,13 +432,13 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="9" column="0">
|
<item>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QCheckBox" name="chk_su2">
|
<widget class="QCheckBox" name="chk_su2">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>110</width>
|
<width>120</width>
|
||||||
<height>0</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
@ -432,13 +475,13 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="10" column="0">
|
<item>
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QCheckBox" name="chk_key">
|
<widget class="QCheckBox" name="chk_key">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>110</width>
|
<width>120</width>
|
||||||
<height>0</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
@ -475,7 +518,7 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="11" column="0">
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer_7">
|
<spacer name="horizontalSpacer_7">
|
||||||
|
@ -494,7 +537,7 @@
|
||||||
<widget class="QCheckBox" name="chk_pdb">
|
<widget class="QCheckBox" name="chk_pdb">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>110</width>
|
<width>120</width>
|
||||||
<height>0</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
@ -518,7 +561,7 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="12" column="0">
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer_25">
|
<spacer name="horizontalSpacer_25">
|
||||||
|
@ -537,7 +580,7 @@
|
||||||
<widget class="QCheckBox" name="chk_bdf">
|
<widget class="QCheckBox" name="chk_bdf">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>110</width>
|
<width>120</width>
|
||||||
<height>0</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
@ -561,7 +604,7 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="13" column="0">
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_14">
|
<layout class="QHBoxLayout" name="horizontalLayout_14">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="btnOk">
|
<widget class="QPushButton" name="btnOk">
|
||||||
|
|
|
@ -0,0 +1,528 @@
|
||||||
|
#include "FoamDataExchange.h"
|
||||||
|
#include "MeshData/meshSingleton.h"
|
||||||
|
#include "MeshData/meshKernal.h"
|
||||||
|
#include "MeshData/meshSet.h"
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QTextStream>
|
||||||
|
#include <vtkUnstructuredGrid.h>
|
||||||
|
#include <vtkSmartPointer.h>
|
||||||
|
#include <vtkDataSet.h>
|
||||||
|
#include <vtkPoints.h>
|
||||||
|
#include <vtkCellArray.h>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <set>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
namespace MeshData {
|
||||||
|
FoamDataExchange::FoamDataExchange(const QString& fileName, MeshOperation operation,
|
||||||
|
GUI::MainWindow* mw, int modelId)
|
||||||
|
: // _fileName(fileName),
|
||||||
|
_operation(operation)
|
||||||
|
, _meshData(MeshData::getInstance())
|
||||||
|
, MeshThreadBase(fileName, operation, mw)
|
||||||
|
, _modelId(modelId)
|
||||||
|
{
|
||||||
|
_fileName = fileName;
|
||||||
|
_file = new QFile(_fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
FoamDataExchange::~FoamDataExchange()
|
||||||
|
{
|
||||||
|
if(_stream != nullptr)
|
||||||
|
delete _stream;
|
||||||
|
if(_file != nullptr)
|
||||||
|
delete _file;
|
||||||
|
_file = nullptr;
|
||||||
|
_stream = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FoamDataExchange::readHeader()
|
||||||
|
{
|
||||||
|
QFileInfo tempinfo(_fileName);
|
||||||
|
if(!tempinfo.exists())
|
||||||
|
return false;
|
||||||
|
QString name = tempinfo.fileName();
|
||||||
|
QString path = tempinfo.filePath();
|
||||||
|
QFile tempfile(_fileName);
|
||||||
|
if(!tempfile.open(QIODevice::ReadOnly))
|
||||||
|
return false;
|
||||||
|
// QTextStream* tempStream=new QTextStream(&tempfile);
|
||||||
|
QTextStream tempStream(&tempfile);
|
||||||
|
while(!tempStream.atEnd()) {
|
||||||
|
if(!_threadRuning)
|
||||||
|
return false;
|
||||||
|
QString line = tempStream.readLine().simplified();
|
||||||
|
}
|
||||||
|
// delete tempStream;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FoamDataExchange::write()
|
||||||
|
{
|
||||||
|
return _modelId >= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FoamDataExchange::run()
|
||||||
|
{
|
||||||
|
ModuleBase::ThreadTask::run();
|
||||||
|
bool result = false;
|
||||||
|
switch(_operation) {
|
||||||
|
case MESH_READ:
|
||||||
|
emit showInformation(tr("Import MSH Mesh File From \"%1\"").arg(_fileName));
|
||||||
|
result = read();
|
||||||
|
setReadResult(result);
|
||||||
|
break;
|
||||||
|
case MESH_WRITE:
|
||||||
|
emit showInformation(tr("Export MSH Mesh File From \"%1\"").arg(_fileName));
|
||||||
|
// result = write();
|
||||||
|
// setWriteResult(result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
defaultMeshFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FoamDataExchange::read()
|
||||||
|
{
|
||||||
|
_file = new QFile();
|
||||||
|
QFileInfo info(_fileName);
|
||||||
|
if(!info.exists())
|
||||||
|
return false;
|
||||||
|
_baseFileName = info.fileName();
|
||||||
|
_filePath = info.filePath();
|
||||||
|
_file->setFileName(_fileName);
|
||||||
|
if(!_file->open(QIODevice::ReadOnly))
|
||||||
|
return false;
|
||||||
|
_stream = new QTextStream(_file);
|
||||||
|
OpenFoamMeshReader* reader = new OpenFoamMeshReader;
|
||||||
|
CFDOpenfoamMeshParser* parser = new CFDOpenfoamMeshParser;
|
||||||
|
reader->setMeshFileParser(parser);
|
||||||
|
bool ok = reader->readFile(_fileName.toStdString());
|
||||||
|
if(!ok)
|
||||||
|
return ok;
|
||||||
|
vtkSmartPointer<vtkUnstructuredGrid> dataset = reader->getGrid();
|
||||||
|
MeshKernal* k = new MeshKernal;
|
||||||
|
k->setName(_baseFileName);
|
||||||
|
k->setPath(_filePath);
|
||||||
|
k->setMeshData((vtkDataSet*)dataset);
|
||||||
|
_meshData->appendMeshKernal(k);
|
||||||
|
int kid = k->getID();
|
||||||
|
std::unordered_map<int, std::string> zones = parser->getZones();
|
||||||
|
QMap<int, std::string> zoneNames{};
|
||||||
|
for(auto zone : zones) {
|
||||||
|
zoneNames.insert(zone.first, zone.second);
|
||||||
|
}
|
||||||
|
std::unordered_map<int, std::pair<int, int>> zoneIndexes = parser->getCellZones();
|
||||||
|
for(auto it : zoneIndexes) {
|
||||||
|
int setid = it.first;
|
||||||
|
MeshSet* set = new MeshSet;
|
||||||
|
set->setType(SetType::Element);
|
||||||
|
if(zoneNames.contains(setid))
|
||||||
|
set->setName(QString::fromStdString(zoneNames[setid]));
|
||||||
|
else
|
||||||
|
set->setName("ElementSet" + QString::number(it.first));
|
||||||
|
MeshSet* s = _idsetList.value(setid);
|
||||||
|
if(s != nullptr) {
|
||||||
|
delete s;
|
||||||
|
_idsetList.remove(setid);
|
||||||
|
}
|
||||||
|
_idsetList[setid] = set;
|
||||||
|
int firstIndex = it.second.first;
|
||||||
|
int lastIndex = it.second.second;
|
||||||
|
for(int i = firstIndex; i <= lastIndex; ++i)
|
||||||
|
set->appendTempMem(i - 1);
|
||||||
|
}
|
||||||
|
std::unordered_map<int, std::pair<int, int>> faceZones = parser->getPointZones();
|
||||||
|
for(auto it : faceZones) {
|
||||||
|
int setid = it.first;
|
||||||
|
MeshSet* set = new MeshSet;
|
||||||
|
set->setType(SetType::Node);
|
||||||
|
if(zoneNames.contains(setid))
|
||||||
|
set->setName(QString::fromStdString(zoneNames[setid]));
|
||||||
|
else
|
||||||
|
set->setName("PointSet" + QString::number(it.first));
|
||||||
|
MeshSet* s = _idsetList.value(setid);
|
||||||
|
if(s != nullptr) {
|
||||||
|
delete s;
|
||||||
|
_idsetList.remove(setid);
|
||||||
|
}
|
||||||
|
_idsetList[setid] = set;
|
||||||
|
int firstIndex = it.second.first;
|
||||||
|
int lastIndex = it.second.second;
|
||||||
|
for(int i = firstIndex; i <= lastIndex; ++i)
|
||||||
|
set->appendTempMem(i - 1);
|
||||||
|
}
|
||||||
|
std::unordered_map<int, std::pair<int, int>> face2CellIndex =
|
||||||
|
parser->getFaceIDtoCellIndex();
|
||||||
|
for(auto faceZone : parser->getFaceZones()) {
|
||||||
|
int zoneId = faceZone.first;
|
||||||
|
if(zoneNames.contains(zoneId)) {
|
||||||
|
BoundMeshSet* set = new BoundMeshSet;
|
||||||
|
set->setName(QString::fromStdString(zoneNames[zoneId]));
|
||||||
|
QMap<int, QVector<int>> cellFaces{};
|
||||||
|
int firstIndex = faceZone.second.first;
|
||||||
|
int lastIndex = faceZone.second.second;
|
||||||
|
for(int i = firstIndex; i <= lastIndex; ++i) {
|
||||||
|
int cellIndex = face2CellIndex[i].first;
|
||||||
|
int index = face2CellIndex[i].second;
|
||||||
|
cellFaces[cellIndex - 1].push_back(index - 1);
|
||||||
|
}
|
||||||
|
MeshSet* s = _idsetList.value(zoneId);
|
||||||
|
if(s != nullptr) {
|
||||||
|
delete s;
|
||||||
|
_idsetList.remove(zoneId);
|
||||||
|
}
|
||||||
|
_idsetList[zoneId] = set;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QList<MeshSet*> setList = _idsetList.values();
|
||||||
|
for(int i = 0; i < _idsetList.size(); ++i) {
|
||||||
|
MeshSet* set = setList.at(i);
|
||||||
|
set->setKeneralID(kid);
|
||||||
|
_meshData->appendMeshSet(set);
|
||||||
|
}
|
||||||
|
delete parser;
|
||||||
|
delete reader;
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFDOpenfoamMeshParser::stringSplit(const std::string str, const const char split,
|
||||||
|
std::vector<std::string>& vec)
|
||||||
|
{
|
||||||
|
std::istringstream iss(str);
|
||||||
|
std::string token;
|
||||||
|
while(getline(iss, token, split)) {
|
||||||
|
if(token.size() != 0)
|
||||||
|
vec.push_back(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFDOpenfoamMeshParser::stringTrimmed(std::string& str)
|
||||||
|
{
|
||||||
|
int first = str.find_first_not_of(" ");
|
||||||
|
str.erase(0, first);
|
||||||
|
int last = str.find_last_not_of(" ");
|
||||||
|
if(last + 1 < str.size())
|
||||||
|
str.erase(last + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CFDOpenfoamMeshParser::setFile(const std::string& file)
|
||||||
|
{
|
||||||
|
m_File = file;
|
||||||
|
return this->read();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<double> CFDOpenfoamMeshParser::getPoints()
|
||||||
|
{
|
||||||
|
return m_Points;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_map<int, std::vector<int>> CFDOpenfoamMeshParser::getFaces()
|
||||||
|
{
|
||||||
|
return m_Faces;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_map<int, std::vector<int>> CFDOpenfoamMeshParser::getCells()
|
||||||
|
{
|
||||||
|
return m_Cells;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_map<int, int> CFDOpenfoamMeshParser::getCellsType()
|
||||||
|
{
|
||||||
|
return m_CellsType;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_map<int, std::pair<int, int>> CFDOpenfoamMeshParser::getPointZones()
|
||||||
|
{
|
||||||
|
return m_PointZones;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_map<int, std::pair<int, int>> CFDOpenfoamMeshParser::getFaceZones()
|
||||||
|
{
|
||||||
|
return m_FaceZones;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_map<int, std::pair<int, int>> CFDOpenfoamMeshParser::getCellZones()
|
||||||
|
{
|
||||||
|
return m_CellZones;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_map<int, std::pair<int, int>> CFDOpenfoamMeshParser::getFaceIDtoCellIndex()
|
||||||
|
{
|
||||||
|
return m_FaceIdToCellFaceIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_map<int, std::string> CFDOpenfoamMeshParser::getZones()
|
||||||
|
{
|
||||||
|
return m_Zones;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CFDOpenfoamMeshParser::read()
|
||||||
|
{
|
||||||
|
QFileInfo f{ QString::fromStdString(m_File) };
|
||||||
|
QString path = f.absoluteDir().absolutePath() + "/constant/polyMesh/";
|
||||||
|
std::string pointsFile = path.toStdString() + "/points";
|
||||||
|
std::string facesFile = path.toStdString() + "/faces";
|
||||||
|
std::string ownerFile = path.toStdString() + "/owner";
|
||||||
|
std::string neighbourFile = path.toStdString() + "/neighbour";
|
||||||
|
std::string boundaryFile = path.toStdString() + "/boundary";
|
||||||
|
|
||||||
|
std::ifstream inPoints{};
|
||||||
|
inPoints.open(pointsFile, std::ios_base::in);
|
||||||
|
if(!inPoints.is_open())
|
||||||
|
return false;
|
||||||
|
std::stringstream buffer;
|
||||||
|
buffer << inPoints.rdbuf();
|
||||||
|
m_PointsString = std::string(buffer.str());
|
||||||
|
inPoints.close();
|
||||||
|
bool p = this->readPoints();
|
||||||
|
if(!p)
|
||||||
|
return p;
|
||||||
|
|
||||||
|
std::ifstream inFaces{};
|
||||||
|
inFaces.open(facesFile, std::ios_base::in);
|
||||||
|
if(!inFaces.is_open())
|
||||||
|
return false;
|
||||||
|
std::stringstream buffer1;
|
||||||
|
buffer1 << inFaces.rdbuf();
|
||||||
|
m_FacesString = std::string(buffer1.str());
|
||||||
|
inFaces.close();
|
||||||
|
bool fa = this->readFaces();
|
||||||
|
if(!fa)
|
||||||
|
return fa;
|
||||||
|
|
||||||
|
std::ifstream inOwner{};
|
||||||
|
inOwner.open(ownerFile, std::ios_base::in);
|
||||||
|
if(!inOwner.is_open())
|
||||||
|
return false;
|
||||||
|
std::stringstream buffer2;
|
||||||
|
buffer2 << inOwner.rdbuf();
|
||||||
|
m_OwnerString = std::string(buffer2.str());
|
||||||
|
inOwner.close();
|
||||||
|
bool c = this->readOwner();
|
||||||
|
if(!c)
|
||||||
|
return c;
|
||||||
|
|
||||||
|
std::ifstream inNeigh{};
|
||||||
|
inNeigh.open(neighbourFile, std::ios_base::in);
|
||||||
|
if(!inNeigh.is_open())
|
||||||
|
return false;
|
||||||
|
std::stringstream buffer3;
|
||||||
|
buffer3 << inNeigh.rdbuf();
|
||||||
|
m_NeighbourString = std::string(buffer3.str());
|
||||||
|
inNeigh.close();
|
||||||
|
bool n = this->readNeighbour();
|
||||||
|
if(!n)
|
||||||
|
return n;
|
||||||
|
|
||||||
|
std::ifstream inBoundary{};
|
||||||
|
inBoundary.open(boundaryFile, std::ios_base::in);
|
||||||
|
if(!inBoundary.is_open())
|
||||||
|
return false;
|
||||||
|
std::stringstream buffer4;
|
||||||
|
buffer4 << inBoundary.rdbuf();
|
||||||
|
m_NeighbourString = std::string(buffer4.str());
|
||||||
|
inBoundary.close();
|
||||||
|
bool b = this->readBoundary();
|
||||||
|
if(!b)
|
||||||
|
return b;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CFDOpenfoamMeshParser::readPoints()
|
||||||
|
{
|
||||||
|
int index = m_PointsString.find(m_FoamLabel);
|
||||||
|
if(index == -1)
|
||||||
|
return false;
|
||||||
|
int end = m_PointsString.find("}", index);
|
||||||
|
if(end == -1)
|
||||||
|
return false;
|
||||||
|
int start = m_PointsString.find("(", end);
|
||||||
|
int finish = m_PointsString.find_last_of(")", start);
|
||||||
|
std::string ps = m_PointsString.substr(start + 1, end - start - 1);
|
||||||
|
// std::vector<std::string> strList{};
|
||||||
|
// CFDMeshFileParserBase::stringSplit(m_PointsString.substr(end + 1), '\n', strList);
|
||||||
|
QStringList strList =
|
||||||
|
QString::fromStdString(ps).split(QRegExp("[()]+"), QString::SkipEmptyParts);
|
||||||
|
for(auto str : strList) {
|
||||||
|
str = str.trimmed();
|
||||||
|
if(str.size() == 0)
|
||||||
|
continue;
|
||||||
|
QStringList coords = str.split(" ", Qt::SkipEmptyParts);
|
||||||
|
if(coords.size() == 3) {
|
||||||
|
for(auto& coord : coords) {
|
||||||
|
double x = coord.toDouble();
|
||||||
|
m_Points.push_back(x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CFDOpenfoamMeshParser::readFaces()
|
||||||
|
{
|
||||||
|
int index = m_FacesString.find(m_FoamLabel);
|
||||||
|
if(index == -1)
|
||||||
|
return false;
|
||||||
|
int end = m_FacesString.find("}", index);
|
||||||
|
if(end == -1)
|
||||||
|
return false;
|
||||||
|
std::vector<std::string> strList{};
|
||||||
|
this->stringSplit(m_FacesString.substr(end + 1), '\n', strList);
|
||||||
|
int faceID{ 1 };
|
||||||
|
for(auto& str : strList) {
|
||||||
|
this->stringTrimmed(str);
|
||||||
|
if(str.size() == 0)
|
||||||
|
continue;
|
||||||
|
if(isdigit(str[0])) {
|
||||||
|
int start = str.find_first_of('(');
|
||||||
|
if(start == -1)
|
||||||
|
continue;
|
||||||
|
int end = str.find_last_of(')');
|
||||||
|
if(end == -1)
|
||||||
|
continue;
|
||||||
|
std::string numStr = str.substr(0, start);
|
||||||
|
int num{};
|
||||||
|
sscanf(numStr.c_str(), "%d", &num);
|
||||||
|
std::string coordsStr = str.substr(start + 1, end - start - 1);
|
||||||
|
std::vector<std::string> coords{};
|
||||||
|
this->stringSplit(coordsStr, ' ', coords);
|
||||||
|
std::vector<int> pointIdS{};
|
||||||
|
if(coords.size() >= 3) {
|
||||||
|
for(auto& coord : coords) {
|
||||||
|
int id{ 0 };
|
||||||
|
sscanf(coord.c_str(), "%d", &id);
|
||||||
|
pointIdS.push_back(id + 1);
|
||||||
|
}
|
||||||
|
m_Faces[faceID++] = pointIdS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CFDOpenfoamMeshParser::readOwner()
|
||||||
|
{
|
||||||
|
int index = m_OwnerString.find(m_FoamLabel);
|
||||||
|
if(index == -1)
|
||||||
|
return false;
|
||||||
|
int end = m_OwnerString.find("}", index);
|
||||||
|
if(end == -1)
|
||||||
|
return false;
|
||||||
|
int start = m_OwnerString.find("(", end);
|
||||||
|
if(start == -1)
|
||||||
|
return false;
|
||||||
|
end = m_OwnerString.find(")", start);
|
||||||
|
if(end == -1)
|
||||||
|
return false;
|
||||||
|
QString owners = QString::fromStdString(m_OwnerString.substr(start + 1, end - start - 1));
|
||||||
|
QStringList strList = owners.split(QRegExp("\\s+"), Qt::SkipEmptyParts);
|
||||||
|
int faceID{ 1 };
|
||||||
|
for(auto& str : strList) {
|
||||||
|
int cellID = str.toInt();
|
||||||
|
m_Cells[cellID].push_back(faceID);
|
||||||
|
m_FaceIdToCellFaceIndex[faceID] = std::make_pair(cellID, m_Cells[cellID].size());
|
||||||
|
++faceID;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CFDOpenfoamMeshParser::readNeighbour()
|
||||||
|
{
|
||||||
|
int index = m_NeighbourString.find(m_FoamLabel);
|
||||||
|
if(index == -1)
|
||||||
|
return false;
|
||||||
|
int end = m_NeighbourString.find("}", index);
|
||||||
|
if(end == -1)
|
||||||
|
return false;
|
||||||
|
int start = m_NeighbourString.find("(", end);
|
||||||
|
if(start == -1)
|
||||||
|
return false;
|
||||||
|
end = m_NeighbourString.find(")", start);
|
||||||
|
if(end == -1)
|
||||||
|
return false;
|
||||||
|
QString neighbours =
|
||||||
|
QString::fromStdString(m_NeighbourString.substr(start + 1, end - start - 1));
|
||||||
|
QStringList strList = neighbours.split(QRegExp("\\s+"), Qt::SkipEmptyParts);
|
||||||
|
int faceID{ 1 };
|
||||||
|
for(auto& str : strList) {
|
||||||
|
int cellID = str.toInt();
|
||||||
|
if(cellID == -1)
|
||||||
|
continue;
|
||||||
|
m_Cells[cellID].push_back(faceID);
|
||||||
|
m_FaceIdToCellFaceIndex[faceID] = std::make_pair(cellID, m_Cells[cellID].size());
|
||||||
|
++faceID;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CFDOpenfoamMeshParser::readBoundary()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenFoamMeshReader::setMeshFileParser(CFDOpenfoamMeshParser* parser)
|
||||||
|
{
|
||||||
|
m_Parser = parser;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OpenFoamMeshReader::readFile(const std::string& file)
|
||||||
|
{
|
||||||
|
if(m_Parser == nullptr)
|
||||||
|
return false;
|
||||||
|
bool ok = m_Parser->setFile(file);
|
||||||
|
if(!ok)
|
||||||
|
return ok;
|
||||||
|
m_ugrid = vtkSmartPointer<vtkUnstructuredGrid>::New();
|
||||||
|
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
|
||||||
|
const std::vector<double> ps = m_Parser->getPoints();
|
||||||
|
const std::unordered_map<int, std::vector<int>> cells = m_Parser->getCells();
|
||||||
|
const std::unordered_map<int, std::vector<int>> faces = m_Parser->getFaces();
|
||||||
|
const std::unordered_map<int, int> cellTyps = m_Parser->getCellsType();
|
||||||
|
std::set<int> usedFaces{};
|
||||||
|
int num = ps.size() / 3;
|
||||||
|
for(int i = 0; i < num; ++i) {
|
||||||
|
double coord[3]{ ps[i * 3], ps[i * 3 + 1], ps[i * 3 + 2] };
|
||||||
|
points->InsertNextPoint(coord);
|
||||||
|
}
|
||||||
|
m_ugrid->SetPoints(points);
|
||||||
|
std::unordered_map<int, std::vector<int>>::const_iterator it = cells.cbegin();
|
||||||
|
while(it != cells.cend()) {
|
||||||
|
std::vector<vtkIdType> pointIds{};
|
||||||
|
vtkSmartPointer<vtkIdList> facesIDS = vtkSmartPointer<vtkIdList>::New();
|
||||||
|
std::vector<int> faceids = it->second;
|
||||||
|
int index = it->first;
|
||||||
|
for(int id : faceids) {
|
||||||
|
auto it = faces.find(id);
|
||||||
|
if(it == faces.cend())
|
||||||
|
continue;
|
||||||
|
const std::vector<int> pids = it->second;
|
||||||
|
usedFaces.insert(it->first);
|
||||||
|
facesIDS->InsertNextId(pids.size());
|
||||||
|
for(int pid : pids) {
|
||||||
|
pointIds.push_back(pid - 1);
|
||||||
|
facesIDS->InsertNextId(pid - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(pointIds.begin(), pointIds.end());
|
||||||
|
auto ii = std::unique(pointIds.begin(), pointIds.end());
|
||||||
|
pointIds.erase(ii, pointIds.end());
|
||||||
|
m_ugrid->InsertNextCell(VTK_POLYHEDRON, pointIds.size(), pointIds.data(),
|
||||||
|
faceids.size(), facesIDS->GetPointer(0));
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
vtkSmartPointer<vtkUnstructuredGrid> OpenFoamMeshReader::getGrid()
|
||||||
|
{
|
||||||
|
return m_ugrid;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace MeshData
|
|
@ -0,0 +1,106 @@
|
||||||
|
#pragma once
|
||||||
|
#include "MeshThreadBase.h"
|
||||||
|
#include "meshDataExchangePlugin.h"
|
||||||
|
#include <QHash>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vtkSmartPointer.h>
|
||||||
|
|
||||||
|
class QTextStream;
|
||||||
|
class vtkUnstructuredGrid;
|
||||||
|
class QFile;
|
||||||
|
|
||||||
|
namespace MeshData
|
||||||
|
{
|
||||||
|
class MeshData;
|
||||||
|
class MeshSet;
|
||||||
|
|
||||||
|
class MESHDATAEXCHANGEPLUGINAPI FoamDataExchange : public MeshThreadBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FoamDataExchange(const QString& fileName, MeshOperation operation, GUI::MainWindow *mw, int modelId = -1);
|
||||||
|
~FoamDataExchange();
|
||||||
|
|
||||||
|
bool read();
|
||||||
|
bool readHeader();
|
||||||
|
bool write();
|
||||||
|
void run();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QFile *_file;
|
||||||
|
QString _baseFileName{};
|
||||||
|
QString _filePath{};
|
||||||
|
QString _fileName{};
|
||||||
|
MeshData* _meshData{};
|
||||||
|
QTextStream* _stream{};
|
||||||
|
QHash<int, MeshSet*> _idsetList{};
|
||||||
|
|
||||||
|
QString _describe{};
|
||||||
|
int _ND{ 3 };
|
||||||
|
int _staticid{ 0 };
|
||||||
|
int _modelId;
|
||||||
|
MeshOperation _operation;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* @brief OpenFOAM Mesh文件解析类。解析后所得信息中索引均以1开始,使用vtk渲染时注意索引的转换。
|
||||||
|
*/
|
||||||
|
class CFDOpenfoamMeshParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void stringSplit(const std::string str, const char split, std::vector<std::string> &vec);
|
||||||
|
static void stringTrimmed(std::string& str);
|
||||||
|
public:
|
||||||
|
CFDOpenfoamMeshParser() = default;
|
||||||
|
~CFDOpenfoamMeshParser() = default;
|
||||||
|
bool setFile(const std::string& file);
|
||||||
|
std::vector<double> getPoints();
|
||||||
|
std::unordered_map<int, std::vector<int>> getFaces();
|
||||||
|
std::unordered_map<int, std::vector<int>> getCells();
|
||||||
|
std::unordered_map<int, int> getCellsType();
|
||||||
|
std::unordered_map<int, std::pair<int, int>> getPointZones();
|
||||||
|
std::unordered_map<int, std::pair<int, int>> getFaceZones();
|
||||||
|
std::unordered_map<int, std::pair<int, int>> getCellZones();
|
||||||
|
std::unordered_map<int, std::pair<int, int>> getFaceIDtoCellIndex();
|
||||||
|
std::unordered_map<int, std::string> getZones();
|
||||||
|
protected:
|
||||||
|
bool read();
|
||||||
|
private:
|
||||||
|
bool readPoints();
|
||||||
|
bool readFaces();
|
||||||
|
bool readOwner();
|
||||||
|
bool readNeighbour();
|
||||||
|
bool readBoundary();
|
||||||
|
private:
|
||||||
|
std::string m_File{};
|
||||||
|
std::string m_PointsString{};
|
||||||
|
std::string m_FacesString{};
|
||||||
|
std::string m_OwnerString{};
|
||||||
|
std::string m_NeighbourString{};
|
||||||
|
std::string m_BoundaryString{};
|
||||||
|
std::vector<double> m_Points{};
|
||||||
|
std::unordered_map<int, std::vector<int>> m_Faces{};
|
||||||
|
std::unordered_map<int, std::vector<int>> m_Cells{};
|
||||||
|
std::unordered_map<int, int> m_CellsType{};
|
||||||
|
std::unordered_map<int, std::pair<int, int>> m_PointZones{};
|
||||||
|
std::unordered_map<int, std::pair<int, int>> m_FaceZones{};
|
||||||
|
std::unordered_map<int, std::pair<int, int>> m_CellZones{};
|
||||||
|
std::unordered_map<int, std::pair<int, int>> m_FaceIdToCellFaceIndex{};
|
||||||
|
std::unordered_map < int, std::string > m_Zones{};
|
||||||
|
const std::string m_FoamLabel{ "FoamFile" };
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class OpenFoamMeshReader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OpenFoamMeshReader() = default;
|
||||||
|
~OpenFoamMeshReader() = default;
|
||||||
|
void setMeshFileParser(CFDOpenfoamMeshParser* parser);
|
||||||
|
bool readFile(const std::string& file);
|
||||||
|
vtkSmartPointer<vtkUnstructuredGrid> getGrid();
|
||||||
|
|
||||||
|
private:
|
||||||
|
CFDOpenfoamMeshParser* m_Parser{ nullptr };
|
||||||
|
vtkSmartPointer<vtkUnstructuredGrid> m_ugrid{ nullptr };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,12 @@
|
||||||
#include <vtkCellArray.h>
|
#include <vtkCellArray.h>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
namespace MeshData
|
namespace MeshData
|
||||||
{
|
{
|
||||||
|
@ -114,37 +120,134 @@ namespace MeshData
|
||||||
|
|
||||||
bool MSHdataExchange::read()
|
bool MSHdataExchange::read()
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!readHeader())
|
if (!readHeader())
|
||||||
{
|
{
|
||||||
// QMessageBox::warning(nullptr, tr("Prompt"), tr("The file format could not parse the amount!"), QMessageBox::Ok);
|
// QMessageBox::warning(nullptr, tr("Prompt"), tr("The file format could not parse the amount!"), QMessageBox::Ok);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//_file = new QFile();
|
_file = new QFile();
|
||||||
QFileInfo info(_fileName);
|
QFileInfo info(_fileName);
|
||||||
if (!info.exists())
|
if (!info.exists())
|
||||||
return false;
|
return false;
|
||||||
_baseFileName = info.fileName();
|
_baseFileName = info.fileName();
|
||||||
_filePath = info.filePath();
|
_filePath = info.filePath();
|
||||||
//_file->setFileName(_fileName);
|
_file->setFileName(_fileName);
|
||||||
if (!_file->open(QIODevice::ReadOnly))
|
if (!_file->open(QIODevice::ReadOnly))
|
||||||
return false;
|
return false;
|
||||||
_stream = new QTextStream(_file);
|
_stream = new QTextStream(_file);
|
||||||
vtkSmartPointer<vtkUnstructuredGrid> dataset = vtkSmartPointer<vtkUnstructuredGrid>::New();
|
CFDMeshReader* reader = new CFDMeshReader;
|
||||||
if (mMeshType == typeGambit)
|
CFDMshFileParser* parser = new CFDMshFileParser;
|
||||||
|
reader->setMeshFileParser(parser);
|
||||||
|
bool ok = reader->readFile(_fileName.toStdString());
|
||||||
|
if (!ok)
|
||||||
|
return ok;
|
||||||
|
vtkSmartPointer<vtkUnstructuredGrid> dataset = reader->getGrid();
|
||||||
|
MeshKernal *k = new MeshKernal;
|
||||||
|
k->setName(_baseFileName);
|
||||||
|
k->setPath(_filePath);
|
||||||
|
k->setMeshData((vtkDataSet *)dataset);
|
||||||
|
_meshData->appendMeshKernal(k);
|
||||||
|
int kid = k->getID();
|
||||||
|
std::unordered_map<int, std::string> zones = parser->getZones();
|
||||||
|
QMap<int, std::string> zoneNames{};
|
||||||
|
for (auto zone : zones)
|
||||||
{
|
{
|
||||||
if (!readGambitFile(dataset))
|
zoneNames.insert(zone.first, zone.second);
|
||||||
return false;
|
}
|
||||||
|
std::unordered_map<int, std::pair<int, int>> zoneIndexes = parser->getCellZones();
|
||||||
|
for (auto it : zoneIndexes)
|
||||||
|
{
|
||||||
|
int setid = it.first;
|
||||||
|
MeshSet* set = new MeshSet;
|
||||||
|
set->setType(SetType::Element);
|
||||||
|
if (zoneNames.contains(setid))
|
||||||
|
set->setName(QString::fromStdString(zoneNames[setid]));
|
||||||
else
|
else
|
||||||
return true;
|
set->setName("ElementSet" + QString::number(it.first));
|
||||||
}
|
MeshSet *s = _idsetList.value(setid);
|
||||||
else if (mMeshType == typeFluent)
|
if (s != nullptr)
|
||||||
{
|
{
|
||||||
if (!readFluentFile(dataset))
|
delete s;
|
||||||
return false;
|
_idsetList.remove(setid);
|
||||||
}
|
}
|
||||||
return true;
|
_idsetList[setid] = set;
|
||||||
|
int firstIndex = it.second.first;
|
||||||
|
int lastIndex = it.second.second;
|
||||||
|
for (int i = firstIndex; i <= lastIndex; ++i)
|
||||||
|
set->appendTempMem(i - 1);
|
||||||
|
}
|
||||||
|
std::unordered_map<int, std::pair<int, int>> faceZones = parser->getPointZones();
|
||||||
|
for (auto it : faceZones)
|
||||||
|
{
|
||||||
|
int setid = it.first;
|
||||||
|
MeshSet* set = new MeshSet;
|
||||||
|
set->setType(SetType::Node);
|
||||||
|
if (zoneNames.contains(setid))
|
||||||
|
set->setName(QString::fromStdString(zoneNames[setid]));
|
||||||
|
else
|
||||||
|
set->setName("PointSet" + QString::number(it.first));
|
||||||
|
MeshSet* s = _idsetList.value(setid);
|
||||||
|
if (s != nullptr)
|
||||||
|
{
|
||||||
|
delete s;
|
||||||
|
_idsetList.remove(setid);
|
||||||
|
}
|
||||||
|
_idsetList[setid] = set;
|
||||||
|
int firstIndex = it.second.first;
|
||||||
|
int lastIndex = it.second.second;
|
||||||
|
for (int i = firstIndex; i <= lastIndex; ++i)
|
||||||
|
set->appendTempMem(i - 1);
|
||||||
|
}
|
||||||
|
std::unordered_map<int, std::pair<int, int>> face2CellIndex = parser->getFaceIDtoCellIndex();
|
||||||
|
for (auto faceZone : parser->getFaceZones())
|
||||||
|
{
|
||||||
|
int zoneId = faceZone.first;
|
||||||
|
if (zoneNames.contains(zoneId))
|
||||||
|
{
|
||||||
|
BoundMeshSet* set = new BoundMeshSet;
|
||||||
|
set->setName(QString::fromStdString(zoneNames[zoneId]));
|
||||||
|
QMap<int, QVector<int>> cellFaces{};
|
||||||
|
int firstIndex = faceZone.second.first;
|
||||||
|
int lastIndex = faceZone.second.second;
|
||||||
|
for (int i = firstIndex; i <= lastIndex; ++i)
|
||||||
|
{
|
||||||
|
int cellIndex = face2CellIndex[i].first;
|
||||||
|
int index = face2CellIndex[i].second;
|
||||||
|
cellFaces[cellIndex - 1].push_back(index - 1);
|
||||||
|
}
|
||||||
|
MeshSet* s = _idsetList.value(zoneId);
|
||||||
|
if (s != nullptr)
|
||||||
|
{
|
||||||
|
delete s;
|
||||||
|
_idsetList.remove(zoneId);
|
||||||
|
}
|
||||||
|
_idsetList[zoneId] = set;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QList<MeshSet *> setList = _idsetList.values();
|
||||||
|
for (int i = 0; i < _idsetList.size(); ++i)
|
||||||
|
{
|
||||||
|
MeshSet *set = setList.at(i);
|
||||||
|
set->setKeneralID(kid);
|
||||||
|
_meshData->appendMeshSet(set);
|
||||||
|
}
|
||||||
|
delete parser;
|
||||||
|
delete reader;
|
||||||
|
return ok;
|
||||||
|
//if (mMeshType == typeGambit)
|
||||||
|
//{
|
||||||
|
// if (!readGambitFile(dataset))
|
||||||
|
// return false;
|
||||||
|
// else
|
||||||
|
// return true;
|
||||||
|
//}
|
||||||
|
//else if (mMeshType == typeFluent)
|
||||||
|
//{
|
||||||
|
// if (!readFluentFile(dataset))
|
||||||
|
// return false;
|
||||||
|
//}
|
||||||
|
//return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MSHdataExchange::readPoints10(vtkUnstructuredGrid *dataset, QString info)
|
void MSHdataExchange::readPoints10(vtkUnstructuredGrid *dataset, QString info)
|
||||||
|
@ -683,4 +786,487 @@ namespace MeshData
|
||||||
_idsetList.clear();
|
_idsetList.clear();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool CFDMshFileParser::setFile(const std::string& file)
|
||||||
|
{
|
||||||
|
m_File = file;
|
||||||
|
return this->read();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<double> CFDMshFileParser::getPoints()
|
||||||
|
{
|
||||||
|
return m_Points;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_map<int, std::vector<int>> CFDMshFileParser::getFaces()
|
||||||
|
{
|
||||||
|
return m_Faces;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_map<int, std::vector<int>> CFDMshFileParser::getCells()
|
||||||
|
{
|
||||||
|
return m_Cells;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_map<int, int> CFDMshFileParser::getCellsType()
|
||||||
|
{
|
||||||
|
return m_CellsType;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_map<int, std::pair<int, int>> CFDMshFileParser::getPointZones()
|
||||||
|
{
|
||||||
|
return m_PointZones;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_map<int, std::pair<int, int>> CFDMshFileParser::getFaceZones()
|
||||||
|
{
|
||||||
|
return m_FaceZones;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_map<int, std::pair<int, int>> CFDMshFileParser::getCellZones()
|
||||||
|
{
|
||||||
|
return m_CellZones;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_map<int, std::pair<int, int>> CFDMshFileParser::getFaceIDtoCellIndex()
|
||||||
|
{
|
||||||
|
return m_FaceIdToCellFaceIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_map<int, std::string> CFDMshFileParser::getZones()
|
||||||
|
{
|
||||||
|
return m_Zones;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CFDMshFileParser::read()
|
||||||
|
{
|
||||||
|
std::ifstream in{};
|
||||||
|
in.open(m_File, std::ios_base::in);
|
||||||
|
if (!in.is_open())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::stringstream buffer;
|
||||||
|
buffer << in.rdbuf();
|
||||||
|
m_ByteArray = std::string(buffer.str());
|
||||||
|
in.close();
|
||||||
|
bool p = this->readPoints();
|
||||||
|
if (!p)
|
||||||
|
return p;
|
||||||
|
bool f = this->readFaces();
|
||||||
|
if (!f)
|
||||||
|
return f;
|
||||||
|
bool c = this->readCellsType();
|
||||||
|
if (!c)
|
||||||
|
return c;
|
||||||
|
this->readZones();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CFDMshFileParser::readPoints()
|
||||||
|
{
|
||||||
|
//读取点
|
||||||
|
const std::string nodeLabel{"\n(10"};
|
||||||
|
int nlSize = nodeLabel.size();
|
||||||
|
int first = m_ByteArray.find(nodeLabel);
|
||||||
|
if (first == -1)
|
||||||
|
return false;
|
||||||
|
while (first != -1)
|
||||||
|
{
|
||||||
|
int end = m_ByteArray.find("\n", first+nlSize);
|
||||||
|
if (end == -1)
|
||||||
|
return false;
|
||||||
|
std::string element{m_ByteArray.substr(first+1, end-first)};
|
||||||
|
stringTrimmed(element);
|
||||||
|
std::vector<std::string> list{};
|
||||||
|
this->stringSplit(element, ' ', list);
|
||||||
|
if (list.size() < 5)
|
||||||
|
return false;
|
||||||
|
bool ok;
|
||||||
|
std::string zoneIdStr = list.at(1).substr(1);
|
||||||
|
int zoneID{-1};
|
||||||
|
sscanf(zoneIdStr.c_str(), "%X", &zoneID);
|
||||||
|
std::string firstIndex = list.at(2);
|
||||||
|
std::string lastIndex = list.at(3);
|
||||||
|
int fIndex{ 0 }, lIndex{ 0 };
|
||||||
|
sscanf(firstIndex.c_str(), "%X", &fIndex);
|
||||||
|
sscanf(lastIndex.c_str(), "%X", &lIndex);
|
||||||
|
if (zoneID == 0)
|
||||||
|
{
|
||||||
|
std::string pnStr = list.at(3);
|
||||||
|
m_PointNumber = strtol(pnStr.c_str(), 0, 16);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_PointZones[zoneID] = std::make_pair(fIndex, lIndex);
|
||||||
|
int first = m_ByteArray.find(")", end + 1);
|
||||||
|
if (first == -1)
|
||||||
|
break;
|
||||||
|
std::string nodes = m_ByteArray.substr(end+1, first-end);
|
||||||
|
std::vector<std::string> arrays{};
|
||||||
|
stringSplit(nodes, '\n', arrays);
|
||||||
|
for (auto& array : arrays)
|
||||||
|
{
|
||||||
|
std::string coords {array};
|
||||||
|
stringTrimmed(coords);
|
||||||
|
std::vector<std::string> cs{};
|
||||||
|
stringSplit(coords, ' ', cs);
|
||||||
|
if (cs.size() == 3)
|
||||||
|
{
|
||||||
|
m_Points.push_back(atof(cs.at(0).c_str()));
|
||||||
|
m_Points.push_back(atof(cs.at(1).c_str()));
|
||||||
|
m_Points.push_back(atof(cs.at(2).c_str()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end = first;
|
||||||
|
}
|
||||||
|
first = m_ByteArray.find(nodeLabel, end);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CFDMshFileParser::readZones()
|
||||||
|
{
|
||||||
|
std::string zoneLable{ "\n(39" };
|
||||||
|
int first = m_ByteArray.find(zoneLable);
|
||||||
|
if (first == -1)
|
||||||
|
{
|
||||||
|
zoneLable = "\n(45";
|
||||||
|
first = m_ByteArray.find(zoneLable);
|
||||||
|
}
|
||||||
|
if (first == -1)
|
||||||
|
return false;
|
||||||
|
int clSize = zoneLable.size();
|
||||||
|
while (first != -1)
|
||||||
|
{
|
||||||
|
int end = m_ByteArray.find("\n", first + clSize);
|
||||||
|
std::string line = m_ByteArray.substr(first + clSize, end - first - clSize);
|
||||||
|
int i = line.find("(");
|
||||||
|
if (i == -1)
|
||||||
|
return false;
|
||||||
|
int j = line.find(")");
|
||||||
|
if (j == -1)
|
||||||
|
return false;
|
||||||
|
std::string element = line.substr(i + 1, j - i - 1);
|
||||||
|
stringTrimmed(element);
|
||||||
|
std::vector<std::string> segs{};
|
||||||
|
stringSplit(element, ' ', segs);
|
||||||
|
if (segs.size() >= 3)
|
||||||
|
{
|
||||||
|
std::string name = segs.at(2);
|
||||||
|
int zoneID = strtol(segs.at(0).c_str(), 0, 10);
|
||||||
|
m_Zones[zoneID] = name;
|
||||||
|
}
|
||||||
|
first = m_ByteArray.find(zoneLable, end);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CFDMshFileParser::readFaces()
|
||||||
|
{
|
||||||
|
//读取面及单元
|
||||||
|
const std::string faceLable{"\n(13"};
|
||||||
|
int flSize = faceLable.size();
|
||||||
|
int first = m_ByteArray.find(faceLable);
|
||||||
|
if (first == -1)
|
||||||
|
return false;
|
||||||
|
while (first != -1)
|
||||||
|
{
|
||||||
|
int end = m_ByteArray.find("\n", first+flSize);
|
||||||
|
if (end == -1)
|
||||||
|
return false;
|
||||||
|
//以(13开头的整行
|
||||||
|
std::string element{m_ByteArray.substr(first+1, end-first)};
|
||||||
|
int a = element.find("(", 3);
|
||||||
|
int b = element.find_last_of(")");
|
||||||
|
element = element.substr(a+1, b-a-1);
|
||||||
|
stringTrimmed(element);
|
||||||
|
std::vector<std::string> list{};
|
||||||
|
stringSplit(element, ' ', list);
|
||||||
|
if (list.size() < 4)
|
||||||
|
return false;
|
||||||
|
std::string zoneStr = list.at(0);
|
||||||
|
int zoneId{ -1 };
|
||||||
|
sscanf(zoneStr.c_str(), "%x", &zoneId);
|
||||||
|
int startFaceIndex = strtol(list.at(1).c_str(), 0 ,16);
|
||||||
|
int endFaceIndex = strtol(list.at(2).c_str(), 0, 16);
|
||||||
|
if (zoneId == 0)
|
||||||
|
{
|
||||||
|
m_FaceNumber = strtol(list.at(2).c_str(), 0 , 16);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_FaceZones[zoneId] = std::make_pair(startFaceIndex, endFaceIndex);
|
||||||
|
int bcType;
|
||||||
|
sscanf(list.at(3).c_str(), "%d", &bcType);
|
||||||
|
int faceType;
|
||||||
|
sscanf(list.at(4).c_str(), "%d", &faceType);
|
||||||
|
int first = m_ByteArray.find(")",end+1);
|
||||||
|
if (first == -1)
|
||||||
|
break;
|
||||||
|
std::string faces = m_ByteArray.substr(end+1, first-end);
|
||||||
|
std::vector<std::string> arrays{};
|
||||||
|
stringSplit(faces, '\n', arrays);
|
||||||
|
for (auto& array : arrays)
|
||||||
|
{
|
||||||
|
std::string coords {array};
|
||||||
|
stringTrimmed(coords);
|
||||||
|
std::vector<std::string> cs{};
|
||||||
|
stringSplit(coords, ' ', cs);
|
||||||
|
this->parseFaceAndCells(startFaceIndex, cs, faceType);
|
||||||
|
++startFaceIndex;
|
||||||
|
}
|
||||||
|
end = first;
|
||||||
|
}
|
||||||
|
first = m_ByteArray.find(faceLable, end);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CFDMshFileParser::readCellsType()
|
||||||
|
{
|
||||||
|
//读取单元类型
|
||||||
|
const std::string cellLable{ "\n(12" };
|
||||||
|
int clSize = cellLable.size();
|
||||||
|
int first = m_ByteArray.find(cellLable);
|
||||||
|
if (first == -1)
|
||||||
|
return false;
|
||||||
|
while (first != -1)
|
||||||
|
{
|
||||||
|
int end = m_ByteArray.find("\n", first + clSize);
|
||||||
|
if (end == -1)
|
||||||
|
return false;
|
||||||
|
std::string element{ m_ByteArray.substr(first + cellLable.size(), end - first-cellLable.size()) };
|
||||||
|
stringTrimmed(element);
|
||||||
|
std::vector<std::string> list{};
|
||||||
|
stringSplit(element, ' ', list);
|
||||||
|
if (list.size() < 4)
|
||||||
|
return false;
|
||||||
|
bool ok;
|
||||||
|
int zoneId = strtol(list.at(0).substr(1).c_str(), 0, 16);
|
||||||
|
int startIndex = strtol(list.at(1).c_str(),0, 16);
|
||||||
|
int endIndex = strtol(list.at(2).c_str(), 0, 16);
|
||||||
|
int type = strtol(list.at(3).c_str(), 0 , 16);
|
||||||
|
if (zoneId == 0)
|
||||||
|
;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_CellZones[zoneId] = std::make_pair(startIndex, endIndex);
|
||||||
|
std::string str = list.at(4);
|
||||||
|
int elementType{ -1 };
|
||||||
|
std::string etStr = str.substr(0, str.find_first_of(")"));
|
||||||
|
sscanf(etStr.c_str(), "%x", &elementType);
|
||||||
|
if (elementType == 0)
|
||||||
|
{
|
||||||
|
int bodyEnd = m_ByteArray.find(")", end + 1);
|
||||||
|
if (bodyEnd != -1)
|
||||||
|
{
|
||||||
|
std::string body{ m_ByteArray.substr(end + 1, bodyEnd - end - 1) };
|
||||||
|
stringTrimmed(body);
|
||||||
|
if (body.at(0) == '(')
|
||||||
|
body = body.substr(1);
|
||||||
|
std::vector<std::string> types{};
|
||||||
|
stringSplit(body, ' ', types);
|
||||||
|
for (const std::string& ty : types)
|
||||||
|
{
|
||||||
|
int type{};
|
||||||
|
sscanf(ty.c_str(), "%d", &type);
|
||||||
|
m_CellsType[startIndex] = type;
|
||||||
|
++startIndex;
|
||||||
|
}
|
||||||
|
end = bodyEnd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = startIndex; i <= endIndex; ++i)
|
||||||
|
m_CellsType[i] = elementType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
first = m_ByteArray.find(cellLable, end);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFDMshFileParser::parseFaceAndCells(int faceIndex, const std::vector<std::string>& faceLineSegs, int faceType)
|
||||||
|
{
|
||||||
|
bool ok;
|
||||||
|
switch (faceType)
|
||||||
|
{
|
||||||
|
case 0: case 5:
|
||||||
|
{
|
||||||
|
if (faceLineSegs.size() >= 5)
|
||||||
|
{
|
||||||
|
std::string pnStr = faceLineSegs.front();
|
||||||
|
int pointNum{ 0 };
|
||||||
|
sscanf(pnStr.c_str(), "%d", &pointNum);
|
||||||
|
std::vector<int> pointIDs{};
|
||||||
|
int i = 1;
|
||||||
|
for (; i <= pointNum; ++i)
|
||||||
|
{
|
||||||
|
std::string idStr = faceLineSegs.at(i);
|
||||||
|
int id = strtol(idStr.c_str(), 0, 16);
|
||||||
|
pointIDs.push_back(id);
|
||||||
|
}
|
||||||
|
m_Faces.insert(make_pair(faceIndex, pointIDs));
|
||||||
|
std::string ownerStr = faceLineSegs.at(i);
|
||||||
|
int owner = strtol(ownerStr.c_str(), 0, 16);
|
||||||
|
++i;
|
||||||
|
std::string nbStr = faceLineSegs.at(i);
|
||||||
|
int neigbur = strtol(nbStr.c_str(), 0, 16);
|
||||||
|
if (owner != 0)
|
||||||
|
{
|
||||||
|
m_Cells[owner].push_back(faceIndex);
|
||||||
|
m_FaceIdToCellFaceIndex[faceIndex] = std::make_pair(owner, m_Cells[owner].size());
|
||||||
|
}
|
||||||
|
if (neigbur != 0)
|
||||||
|
{
|
||||||
|
m_Cells[neigbur].push_back(faceIndex);
|
||||||
|
m_FaceIdToCellFaceIndex[faceIndex] = std::make_pair(neigbur, m_Cells[neigbur].size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
if (faceLineSegs.size() != 5)
|
||||||
|
return;
|
||||||
|
std::vector<int> pointIds{ };
|
||||||
|
for (int i = 0; i< 3; ++i)
|
||||||
|
{
|
||||||
|
int id = strtol(faceLineSegs.at(i).c_str(), 0, 16);
|
||||||
|
pointIds.push_back(id);
|
||||||
|
}
|
||||||
|
m_Faces.insert(make_pair(faceIndex, pointIds));
|
||||||
|
std::string ownerStr{ faceLineSegs.at(3) };
|
||||||
|
int owner = strtol(ownerStr.c_str(), 0, 16);
|
||||||
|
std::string nbStr{ faceLineSegs.at(4) };
|
||||||
|
int neighber = strtol(nbStr.c_str(), 0 , 16);
|
||||||
|
if (owner != 0)
|
||||||
|
{
|
||||||
|
m_Cells[owner].push_back(faceIndex);
|
||||||
|
m_FaceIdToCellFaceIndex[faceIndex] = std::make_pair(owner, m_Cells[owner].size());
|
||||||
|
}
|
||||||
|
if (neighber != 0)
|
||||||
|
{
|
||||||
|
m_Cells[neighber].push_back(faceIndex);
|
||||||
|
m_FaceIdToCellFaceIndex[faceIndex] = std::make_pair(neighber, m_Cells[neighber].size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
{
|
||||||
|
if (faceLineSegs.size() != 6)
|
||||||
|
return;
|
||||||
|
std::vector<int> pointIds{ };
|
||||||
|
for (int i = 0; i < 4; ++i)
|
||||||
|
{
|
||||||
|
int id = strtol(faceLineSegs.at(i).c_str(), 0, 16);
|
||||||
|
pointIds.push_back(id);
|
||||||
|
}
|
||||||
|
m_Faces.insert(make_pair(faceIndex, pointIds));
|
||||||
|
std::string ownerStr{ faceLineSegs.at(4) };
|
||||||
|
int owner = strtol(ownerStr.c_str(), 0, 16);
|
||||||
|
std::string nbStr{ faceLineSegs.at(5) };
|
||||||
|
int neighber = strtol(nbStr.c_str(), 0, 16);
|
||||||
|
if (owner != 0)
|
||||||
|
{
|
||||||
|
m_Cells[owner].push_back(faceIndex);
|
||||||
|
m_FaceIdToCellFaceIndex[faceIndex] = std::make_pair(owner, m_Cells[owner].size());
|
||||||
|
}
|
||||||
|
if (neighber != 0)
|
||||||
|
{
|
||||||
|
m_Cells[neighber].push_back(faceIndex);
|
||||||
|
m_FaceIdToCellFaceIndex[faceIndex] = std::make_pair(neighber, m_Cells[neighber].size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFDMshFileParser::stringSplit(const std::string str, const const char split, std::vector<std::string> &vec)
|
||||||
|
{
|
||||||
|
std::istringstream iss(str);
|
||||||
|
std::string token;
|
||||||
|
while (getline(iss, token, split))
|
||||||
|
{
|
||||||
|
if (token.size() != 0)
|
||||||
|
vec.push_back(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFDMshFileParser::stringTrimmed(std::string& str)
|
||||||
|
{
|
||||||
|
int first = str.find_first_not_of(" ");
|
||||||
|
str.erase(0, first);
|
||||||
|
int last = str.find_last_not_of(" ");
|
||||||
|
if (last+1 < str.size())
|
||||||
|
str.erase(last + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFDMeshReader::setMeshFileParser(CFDMshFileParser* parser)
|
||||||
|
{
|
||||||
|
m_Parser = parser;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CFDMeshReader::readFile(const std::string& file)
|
||||||
|
{
|
||||||
|
if (m_Parser == nullptr)
|
||||||
|
return false;
|
||||||
|
bool ok = m_Parser->setFile(file);
|
||||||
|
if (!ok)
|
||||||
|
return ok;
|
||||||
|
m_ugrid = vtkSmartPointer<vtkUnstructuredGrid>::New();
|
||||||
|
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
|
||||||
|
const std::vector<double> ps = m_Parser->getPoints();
|
||||||
|
const std::unordered_map<int, std::vector<int>> cells = m_Parser->getCells();
|
||||||
|
const std::unordered_map<int, std::vector<int>> faces = m_Parser->getFaces();
|
||||||
|
const std::unordered_map<int, int> cellTyps = m_Parser->getCellsType();
|
||||||
|
std::set<int> usedFaces{};
|
||||||
|
int num = ps.size() / 3;
|
||||||
|
for (int i = 0; i < num; ++i)
|
||||||
|
{
|
||||||
|
double coord[3]{ ps[i * 3], ps[i * 3 + 1], ps[i * 3 + 2] };
|
||||||
|
points->InsertNextPoint(coord);
|
||||||
|
}
|
||||||
|
m_ugrid->SetPoints(points);
|
||||||
|
std::unordered_map<int, std::vector<int>>::const_iterator it = cells.cbegin();
|
||||||
|
while (it != cells.cend())
|
||||||
|
{
|
||||||
|
std::vector<vtkIdType> pointIds{};
|
||||||
|
vtkSmartPointer<vtkIdList> facesIDS = vtkSmartPointer<vtkIdList>::New();
|
||||||
|
std::vector<int> faceids = it->second;
|
||||||
|
int index = it->first;
|
||||||
|
for (int id : faceids)
|
||||||
|
{
|
||||||
|
auto it = faces.find(id);
|
||||||
|
if (it == faces.cend())
|
||||||
|
continue;
|
||||||
|
const std::vector<int> pids =it->second;
|
||||||
|
usedFaces.insert(it->first);
|
||||||
|
facesIDS->InsertNextId(pids.size());
|
||||||
|
for (int pid : pids)
|
||||||
|
{
|
||||||
|
pointIds.push_back(pid - 1);
|
||||||
|
facesIDS->InsertNextId(pid - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(pointIds.begin(), pointIds.end());
|
||||||
|
auto ii = std::unique(pointIds.begin(), pointIds.end());
|
||||||
|
pointIds.erase(ii, pointIds.end());
|
||||||
|
m_ugrid->InsertNextCell(VTK_POLYHEDRON, pointIds.size(), pointIds.data(), faceids.size(), facesIDS->GetPointer(0));
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
vtkSmartPointer<vtkUnstructuredGrid> CFDMeshReader::getGrid()
|
||||||
|
{
|
||||||
|
return m_ugrid;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -4,6 +4,8 @@
|
||||||
#include "MeshThreadBase.h"
|
#include "MeshThreadBase.h"
|
||||||
#include "meshDataExchangePlugin.h"
|
#include "meshDataExchangePlugin.h"
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vtkSmartPointer.h>
|
||||||
|
|
||||||
class QTextStream;
|
class QTextStream;
|
||||||
class vtkUnstructuredGrid;
|
class vtkUnstructuredGrid;
|
||||||
|
@ -90,5 +92,111 @@ namespace MeshData
|
||||||
int _modelId;
|
int _modelId;
|
||||||
MeshOperation _operation;
|
MeshOperation _operation;
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* @brief msh文件解析类。解析后所得信息中索引均以1开始,使用vtk渲染时注意索引的转换。
|
||||||
|
*/
|
||||||
|
class CFDMshFileParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CFDMshFileParser() = default;
|
||||||
|
~CFDMshFileParser() = default;
|
||||||
|
/**
|
||||||
|
* 指定要解析的文件并执行解析。
|
||||||
|
* @param file
|
||||||
|
* @return 成功则返回true,否则返回false。
|
||||||
|
*/
|
||||||
|
bool setFile(const std::string& file);
|
||||||
|
/**
|
||||||
|
* 获取点坐标信息。
|
||||||
|
* @return 以[x1,y1,z1,x2,y2,z2,...]形式存储的所有点的坐标信息。
|
||||||
|
*/
|
||||||
|
std::vector<double> getPoints() ;
|
||||||
|
/**
|
||||||
|
* 获取面拓扑信息。
|
||||||
|
* @return key为面ID,value为点ID数组。ID均以1开始。
|
||||||
|
*/
|
||||||
|
std::unordered_map<int, std::vector<int>> getFaces() ;
|
||||||
|
/**
|
||||||
|
* 获取单元拓扑信息。
|
||||||
|
* @return key为单元ID,value为面ID数组。ID均以1开始。
|
||||||
|
*/
|
||||||
|
std::unordered_map<int, std::vector<int>> getCells() ;
|
||||||
|
/**
|
||||||
|
* 获取单元类型信息。
|
||||||
|
* @return key为面ID,value为整型类型,表示的单元类型如下:
|
||||||
|
* 1:三节点三角形;2:四节点四面体;3:四节点四边形;4:八节点六面体;5:五节点金字塔形;6:六节点五面体;7:多面体。
|
||||||
|
*/
|
||||||
|
std::unordered_map<int, int> getCellsType() ;
|
||||||
|
/**
|
||||||
|
* 获取点域。
|
||||||
|
* @return key为域ID,value为由点起始索引和结束索引组成的pair。
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
std::unordered_map<int, std::pair<int, int>> getPointZones();
|
||||||
|
/**
|
||||||
|
* 获取面域。
|
||||||
|
* @return key为域ID,value为由面起始索引和结束索引组成的pair。
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
std::unordered_map<int, std::pair<int, int>> getFaceZones();
|
||||||
|
/**
|
||||||
|
* 获取单元域。
|
||||||
|
* @return key为域ID,value为由单元起始索引和结束索引组成的pair。
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
std::unordered_map<int, std::pair<int, int>> getCellZones();
|
||||||
|
/**
|
||||||
|
* 获取面ID与单元面索引的映射。
|
||||||
|
* @return key为面ID,value为由单元索引及其面索引组成的pair。索引均以1开始。
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
std::unordered_map<int, std::pair<int, int>> getFaceIDtoCellIndex();
|
||||||
|
/**
|
||||||
|
* 获取域名称。
|
||||||
|
* @return key为域ID,value为域名称。
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
std::unordered_map<int, std::string> getZones();
|
||||||
|
protected:
|
||||||
|
bool read();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_File{};
|
||||||
|
bool readPoints();
|
||||||
|
bool readFaces();
|
||||||
|
bool readCellsType();
|
||||||
|
bool readZones();
|
||||||
|
void parseFaceAndCells(int, const std::vector<std::string>&, int);
|
||||||
|
void stringSplit(const std::string str, const char split, std::vector<std::string> &vec);
|
||||||
|
void stringTrimmed(std::string& str);
|
||||||
|
private:
|
||||||
|
std::string m_ByteArray{};
|
||||||
|
double m_Progress;
|
||||||
|
int m_PointNumber{0};
|
||||||
|
int m_FaceNumber{0};
|
||||||
|
std::vector<double> m_Points{};
|
||||||
|
std::unordered_map<int, std::vector<int>> m_Faces{};
|
||||||
|
std::unordered_map<int, std::vector<int>> m_Cells{};
|
||||||
|
std::unordered_map<int, int> m_CellsType{};
|
||||||
|
std::unordered_map<int, std::pair<int, int>> m_PointZones{};
|
||||||
|
std::unordered_map<int, std::pair<int, int>> m_FaceZones{};
|
||||||
|
std::unordered_map<int, std::pair<int, int>> m_CellZones{};
|
||||||
|
std::unordered_map<int, std::pair<int, int>> m_FaceIdToCellFaceIndex{};
|
||||||
|
std::unordered_map<int, std::string> m_Zones{};
|
||||||
|
};
|
||||||
|
|
||||||
|
class CFDMeshReader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CFDMeshReader() = default;
|
||||||
|
~CFDMeshReader() = default;
|
||||||
|
void setMeshFileParser(CFDMshFileParser* parser);
|
||||||
|
bool readFile(const std::string& file);
|
||||||
|
vtkSmartPointer<vtkUnstructuredGrid> getGrid();
|
||||||
|
|
||||||
|
private:
|
||||||
|
CFDMshFileParser* m_Parser{ nullptr };
|
||||||
|
vtkSmartPointer<vtkUnstructuredGrid> m_ugrid{ nullptr };
|
||||||
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
|
@ -14,6 +14,7 @@
|
||||||
#include "PDBdataExchange.h"
|
#include "PDBdataExchange.h"
|
||||||
#include "SU2dataExchange.h"
|
#include "SU2dataExchange.h"
|
||||||
#include "VTKdataExchange.h"
|
#include "VTKdataExchange.h"
|
||||||
|
#include "FoamDataExchange.h"
|
||||||
|
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
|
|
||||||
|
@ -29,6 +30,7 @@ namespace MeshData {
|
||||||
{
|
{
|
||||||
IO::IOConfigure::RegisterMeshImporter("CGNS(*.cgns)", CGNSimportMesh);
|
IO::IOConfigure::RegisterMeshImporter("CGNS(*.cgns)", CGNSimportMesh);
|
||||||
IO::IOConfigure::RegisterMeshImporter("Fluent(*.msh)", MSHimportMesh);
|
IO::IOConfigure::RegisterMeshImporter("Fluent(*.msh)", MSHimportMesh);
|
||||||
|
IO::IOConfigure::RegisterMeshImporter("OpenFOAM(*.foam)", FOAMimportMesh);
|
||||||
IO::IOConfigure::RegisterMeshImporter("Gambit(*.neu)", NEUimportMesh);
|
IO::IOConfigure::RegisterMeshImporter("Gambit(*.neu)", NEUimportMesh);
|
||||||
IO::IOConfigure::RegisterMeshImporter("STL(*.stl)", VTK_DAT_STL_importMesh);
|
IO::IOConfigure::RegisterMeshImporter("STL(*.stl)", VTK_DAT_STL_importMesh);
|
||||||
IO::IOConfigure::RegisterMeshImporter("Tecplot(*.dat)", VTK_DAT_STL_importMesh);
|
IO::IOConfigure::RegisterMeshImporter("Tecplot(*.dat)", VTK_DAT_STL_importMesh);
|
||||||
|
@ -42,6 +44,7 @@ namespace MeshData {
|
||||||
|
|
||||||
IO::IOConfigure::RegisterMeshExporter("CGNS(*.cgns)", CGNSexportMesh);
|
IO::IOConfigure::RegisterMeshExporter("CGNS(*.cgns)", CGNSexportMesh);
|
||||||
IO::IOConfigure::RegisterMeshExporter("Fluent(*.msh)", MSHexportMesh);
|
IO::IOConfigure::RegisterMeshExporter("Fluent(*.msh)", MSHexportMesh);
|
||||||
|
IO::IOConfigure::RegisterMeshExporter("OpenFOAM(*.foam)", FOAMexportMesh);
|
||||||
IO::IOConfigure::RegisterMeshExporter("Gambit(*.neu)", NEUexportMesh);
|
IO::IOConfigure::RegisterMeshExporter("Gambit(*.neu)", NEUexportMesh);
|
||||||
IO::IOConfigure::RegisterMeshExporter("STL(*.stl)", VTK_DAT_STL_exportMesh);
|
IO::IOConfigure::RegisterMeshExporter("STL(*.stl)", VTK_DAT_STL_exportMesh);
|
||||||
IO::IOConfigure::RegisterMeshExporter("Tecplot(*.dat)", VTK_DAT_STL_exportMesh);
|
IO::IOConfigure::RegisterMeshExporter("Tecplot(*.dat)", VTK_DAT_STL_exportMesh);
|
||||||
|
@ -302,3 +305,21 @@ bool MESHDATAEXCHANGEPLUGINAPI PDBexportMesh(QString AbFileName, int modelId)
|
||||||
// emit PDBWriter->start();
|
// emit PDBWriter->start();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MESHDATAEXCHANGEPLUGINAPI FOAMimportMesh(QString AbFileName, int modelId)
|
||||||
|
{
|
||||||
|
auto foamReader = new MeshData::FoamDataExchange(AbFileName, MeshData::MESH_READ,
|
||||||
|
MeshData::MeshDataExchangePlugin::getMWpt());
|
||||||
|
ModuleBase::ThreadControl* tc = new ModuleBase::ThreadControl(foamReader);
|
||||||
|
emit tc->threadStart(); // emit MSHreader->start();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MESHDATAEXCHANGEPLUGINAPI FOAMexportMesh(QString AbFileName, int id)
|
||||||
|
{
|
||||||
|
auto FoamWriter = new MeshData::FoamDataExchange(
|
||||||
|
AbFileName, MeshData::MESH_WRITE, MeshData::MeshDataExchangePlugin::getMWpt(), id);
|
||||||
|
ModuleBase::ThreadControl* tc = new ModuleBase::ThreadControl(FoamWriter);
|
||||||
|
emit tc->threadStart(); // emit MSHwriter->start();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ extern "C"
|
||||||
//函数返回值是无效的,不要通过返回值判断
|
//函数返回值是无效的,不要通过返回值判断
|
||||||
bool MESHDATAEXCHANGEPLUGINAPI CGNSimportMesh(QString AbFileName, int modelId);
|
bool MESHDATAEXCHANGEPLUGINAPI CGNSimportMesh(QString AbFileName, int modelId);
|
||||||
bool MESHDATAEXCHANGEPLUGINAPI MSHimportMesh(QString AbFileName, int modelId);
|
bool MESHDATAEXCHANGEPLUGINAPI MSHimportMesh(QString AbFileName, int modelId);
|
||||||
|
bool MESHDATAEXCHANGEPLUGINAPI FOAMimportMesh(QString AbFileName, int modelId);
|
||||||
bool MESHDATAEXCHANGEPLUGINAPI NEUimportMesh(QString AbFileName, int modelId);
|
bool MESHDATAEXCHANGEPLUGINAPI NEUimportMesh(QString AbFileName, int modelId);
|
||||||
bool MESHDATAEXCHANGEPLUGINAPI VTK_DAT_STL_importMesh(QString AbFileName, int modelId);
|
bool MESHDATAEXCHANGEPLUGINAPI VTK_DAT_STL_importMesh(QString AbFileName, int modelId);
|
||||||
bool MESHDATAEXCHANGEPLUGINAPI INPimportMesh(QString AbFileName, int modelId);
|
bool MESHDATAEXCHANGEPLUGINAPI INPimportMesh(QString AbFileName, int modelId);
|
||||||
|
@ -47,6 +48,7 @@ extern "C"
|
||||||
|
|
||||||
bool MESHDATAEXCHANGEPLUGINAPI CGNSexportMesh(QString AbFileName, int id);
|
bool MESHDATAEXCHANGEPLUGINAPI CGNSexportMesh(QString AbFileName, int id);
|
||||||
bool MESHDATAEXCHANGEPLUGINAPI MSHexportMesh(QString AbFileName, int id);
|
bool MESHDATAEXCHANGEPLUGINAPI MSHexportMesh(QString AbFileName, int id);
|
||||||
|
bool MESHDATAEXCHANGEPLUGINAPI FOAMexportMesh(QString AbFileName, int id);
|
||||||
bool MESHDATAEXCHANGEPLUGINAPI NEUexportMesh(QString AbFileName, int id);
|
bool MESHDATAEXCHANGEPLUGINAPI NEUexportMesh(QString AbFileName, int id);
|
||||||
bool MESHDATAEXCHANGEPLUGINAPI VTK_DAT_STL_exportMesh(QString AbFileName, int id);
|
bool MESHDATAEXCHANGEPLUGINAPI VTK_DAT_STL_exportMesh(QString AbFileName, int id);
|
||||||
bool MESHDATAEXCHANGEPLUGINAPI INPexportMesh(QString AbFileName, int id);
|
bool MESHDATAEXCHANGEPLUGINAPI INPexportMesh(QString AbFileName, int id);
|
||||||
|
|
Loading…
Reference in New Issue