You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
AppFlow/FITK_Interface/FITKInterfaceMesh/FITKUnstructuredMeshVTK.cpp

259 lines
7.2 KiB
C++

#include "FITKUnstructuredMeshVTK.h"
#include "FITKMeshFeatureVTK.h"
#include "FITKMeshVTKMap.h"
// VTK
#include <vtkUnstructuredGrid.h>
#include <vtkUnstructuredGridWriter.h>
#include <vtkPoints.h>
// For VTK 7
//@{
#include <vtkSmartPointer.h>
#include <vtkIdList.h>
#include <vtkCell.h>
#include <vtkCellType.h>
//@}
#include "FITKInterfaceModel/FITKAbstractElement.h"
#include "FITKInterfaceModel/FITKElementFactory.h"
#include "FITKInterfaceModel/FITKElementHex.h"
#include "FITKInterfaceModel/FITKElementQuad.h"
#include "FITKInterfaceModel/FITKElementTet.h"
#include "FITKInterfaceModel/FITKElementTri.h"
#include <QHash>
#include <QColor>
namespace Interface
{
FITKUnstructuredMeshVTK::FITKUnstructuredMeshVTK()
{
//创建VTK的网格对象
_vtkDataSet = vtkUnstructuredGrid::New();
vtkPoints* points = vtkPoints::New();
_vtkDataSet->SetPoints(points);
_feature = new FITKMeshFeatureVTK(_vtkDataSet);
}
FITKUnstructuredMeshVTK::~FITKUnstructuredMeshVTK()
{
// 移除特征数据。
//@{
if (_feature)
{
delete _feature;
_feature = nullptr;
}
//@}
//内存回收
if (_vtkDataSet != nullptr)
_vtkDataSet->Delete();
}
FITKModelEnum::AbsModelType FITKUnstructuredMeshVTK::getAbsModelType()
{
return FITKModelEnum::AbsModelType::AMTunstructuredMeshvtk;
}
void FITKUnstructuredMeshVTK::update()
{
if (!_modified) return;
_vtkDataSet->Modified();
if(_feature)
_feature->update();
_modified = false;
}
int FITKUnstructuredMeshVTK::addNode(const double x, const double y, const double z)
{
//追加节点vtk中的节点顺序与节点列表一致
int id = FITKNodeList::addNode(x, y, z);
vtkPoints* points = _vtkDataSet->GetPoints();
if (points == nullptr) return -1;
points->InsertNextPoint(x, y, z);
_modified = true;
return id;
}
void FITKUnstructuredMeshVTK::addNode(const int id, const double x, const double y, const double z)
{
//追加节点vtk中的节点顺序与节点列表一致
FITKNodeList::addNode(id, x, y, z);
vtkPoints* points = _vtkDataSet->GetPoints();
if (points == nullptr) return;
points->InsertNextPoint(x, y, z);
_modified = true;
}
void FITKUnstructuredMeshVTK::appendElement(FITKAbstractElement* element)
{
if (element == nullptr) return;
Interface::FITKModelEnum::FITKEleType type = element->getEleType();
if (!eleTypeHash.contains(type)) return;
//追加到单元中
FITKElementList::appendElement(element);
int count = element->getNodeCount();
vtkIdList* idList = vtkIdList::New();
for (int i = 0; i < count; ++i)
{
//查找节点索引
const int nodeID = element->getNodeID(i);
const int index = this->getNodeIndexByID(nodeID);
idList->InsertNextId(index);
}
_vtkDataSet->InsertNextCell(eleTypeHash[type], idList);
_modified = true;
}
bool FITKUnstructuredMeshVTK::writeToFile(const QString & file)
{
//写出文件
vtkSmartPointer<vtkUnstructuredGridWriter> writer = vtkSmartPointer<vtkUnstructuredGridWriter>::New();
writer->SetFileName(file.toStdString().c_str());
writer->SetFileTypeToASCII();
// writer->SetFileTypeToBinary();
writer->SetInputData(_vtkDataSet);
writer->Write();
return true;
}
void FITKUnstructuredMeshVTK::reverseEleByID(const int id)
{
const int index = getEleIndexByID(id);
this->reverseEleByIndex(index);
}
void FITKUnstructuredMeshVTK::reverseEleByIndex(const int index)
{
FITKUnstructuredMesh::reverseEleByIndex(index);
auto cell = _vtkDataSet->GetCell(index);
if (cell == nullptr) return;
auto points = cell->GetPointIds();
if (points == nullptr) return;
//交换首尾节点编号
const int np = points->GetNumberOfIds();
vtkIdType* pts = new vtkIdType[np];
for (int i = 0; i < np / 2; ++i)
{
int p1 = points->GetId(i);
int p2 = points->GetId(np - 1 - i);
pts[i] = p2;
pts[np - 1 - i] = p1;
}
// 替换单元。
_vtkDataSet->ReplaceCell(index, np, pts);
// 已经过测试可删除。
delete pts;
_modified = true;
}
FITKMeshFeatureVTK* FITKUnstructuredMeshVTK::getMeshFeature()
{
return _feature;
}
vtkUnstructuredGrid* FITKUnstructuredMeshVTK::getGrid()
{
return _vtkDataSet;
}
int FITKUnstructuredMeshVTK::getNumberOfCells()
{
if (!_vtkDataSet)
return 0;
return _vtkDataSet->GetNumberOfCells();
}
void FITKUnstructuredMeshVTK::reConstructure()
{
// 重置网格数据,重新构建。
_vtkDataSet->Reset();
vtkPoints* points = vtkPoints::New();
_vtkDataSet->SetPoints(points);
for (FITKAbstractElement* element : _elementList)
{
int count = element->getNodeCount();
vtkIdList* idList = vtkIdList::New();
for (int i = 0; i < count; ++i)
{
//查找节点索引
const int nodeID = element->getNodeID(i);
const int index = this->getNodeIndexByID(nodeID);
idList->InsertNextId(index);
}
Interface::FITKModelEnum::FITKEleType type = element->getEleType();
_vtkDataSet->InsertNextCell(eleTypeHash[type], idList);
}
}
void FITKUnstructuredMeshVTK::transformVTKMesh(vtkUnstructuredGrid* grid)
{
if (grid == nullptr) return;
this->removeAllNode();
this->removeAllElement();
_vtkDataSet->DeepCopy(grid);
//复制节点
const int npt = _vtkDataSet->GetNumberOfPoints();
for (int i =0; i<npt; ++i)
{
double coor[3] = { 0,0,0 };
_vtkDataSet->GetPoint(i, coor);
FITKNodeList::addNode(coor[0],coor[1],coor[2]);
}
//复制单元
const int ncell = _vtkDataSet->GetNumberOfCells();
for (int i = 0; i < ncell; ++i)
{
vtkCell* cell = _vtkDataSet->GetCell(i);
if(cell == nullptr) continue;
int cT = cell->GetCellType();
//查询单元类型
Interface::FITKModelEnum::FITKEleType t = eleTypeHash.key(cT);
FITKAbstractElement* ele = FITKElementFactory::createElement(t);
if(ele == nullptr) continue;
//单元节点
QList<int> cellID{};
const int ncellPt = cell->GetNumberOfPoints();
for (int cpt = 0 ; cpt <ncellPt; ++cpt)
{
int nodeid = cell->GetPointId(cpt);
cellID.append(nodeid + 1);
}
ele->setNodeID(cellID);
}
}
void FITKUnstructuredMeshVTK::clearMesh()
{
this->removeAllNode();
this->removeAllElement();
_vtkDataSet->GetPoints()->Reset();
_vtkDataSet->Reset();
}
}