#include "FITKUnstructuredMeshVTK.h" #include "FITKMeshFeatureVTK.h" #include "FITKMeshVTKMap.h" // VTK #include #include #include // For VTK 7 //@{ #include #include #include #include //@} #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 #include 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 writer = vtkSmartPointer::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; iGetPoint(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 cellID{}; const int ncellPt = cell->GetNumberOfPoints(); for (int cpt = 0 ; cpt GetPointId(cpt); cellID.append(nodeid + 1); } ele->setNodeID(cellID); } } void FITKUnstructuredMeshVTK::clearMesh() { this->removeAllNode(); this->removeAllElement(); _vtkDataSet->GetPoints()->Reset(); _vtkDataSet->Reset(); } }