LAMPCAE/src/MeshData/meshChecker.cpp

322 lines
7.6 KiB
C++
Raw Normal View History

2023-05-08 06:32:41 +00:00
#include "meshChecker.h"
#include "meshKernal.h"
#include "meshSingleton.h"
#include <vtkDataSet.h>
#include <vtkCell.h>
#include <vtkCellQuality.h>
#include <vtkCellData.h>
#include <vtkDoubleArray.h>
#include <math.h>
#include <vtkUnstructuredGrid.h>
#include <QDebug>
namespace MeshData
{
MeshChecker::MeshChecker()
{
_meshData = MeshData::getInstance();
_cellQuality = vtkSmartPointer<vtkCellQuality>::New();
_qualityArray = vtkSmartPointer<vtkDoubleArray>::New();
_cellQuality->SetUndefinedQuality(-1e66);
_cellQuality->SetUnsupportedGeometry(-1e66);
}
MeshChecker::~MeshChecker()
{
// const int n = _resultList.size();
// for (int i = 0; i < n; ++i)
// {
// vtkDataSet* d = _resultList.at(i);
// d->Delete();
// }
// _resultList.clear();
}
void MeshChecker::run()
{
_qualityArray->SetNumberOfValues(0);
_inputCount.clear();
_checkedCount.clear();
// const int nc = _resultList.size();
// for (int i = 0; i < nc; ++i)
// {
// vtkDataSet* d = _resultList.at(i);
// d->Delete();
// }
_resultList.clear();
if (_measure == NONE) return;
const int n = _meshData->getKernalCount();
for (int i = 0; i < n; ++i)
{
MeshKernal* k = _meshData->getKernalAt(i);
this->checkKernal(k);
}
_qualityArray->Modified();
countResult();
}
void MeshChecker::setQualityMeasure(QualityMeasure m)
{
_measure = m;
_cellQuality->SetQualityMeasure(m);
}
void MeshChecker::checkKernal(MeshKernal* k)
{
vtkDataSet* checkingDataset = k->getMeshData();
_cellQuality->SetInputData(checkingDataset);
_cellQuality->Update();
vtkDataSet* res = _cellQuality->GetOutput();
// vtkUnstructuredGrid* g = vtkUnstructuredGrid::New();
// g->DeepCopy(res);
_resultList.append(res);
this->collectInfo(res);
}
void MeshChecker::collectInfo(vtkDataSet* res)
{
vtkDataArray* qua = res->GetCellData()->GetScalars("CellQuality");
const int n = res->GetNumberOfCells();
for (int i = 0; i < n; ++i)
{
vtkCell* cell = res->GetCell(i);
VTKCellType type = (VTKCellType)cell->GetCellType();
++_inputCount[type];
double q = qua->GetComponent(i, 0);
if (q > -1e65)
{
_qualityArray->InsertNextValue(q);
_checkedCount[type].append(q);
}
}
}
QString MeshChecker::VTKCellTypeToString(VTKCellType type)
{
QString stype("Undefined");
switch (type)
{
case VTK_VERTEX:
stype = "Vertex"; break;
case VTK_POLY_VERTEX:
stype = "PolyVertex"; break;
case VTK_LINE:
stype = "Line"; break;
case VTK_POLY_LINE:
stype = "PolyLine"; break;
case VTK_TRIANGLE:
stype = "Tri3"; break;
case VTK_TRIANGLE_STRIP:
stype = "Tri3Strip"; break;
case VTK_POLYGON:
stype = "Polygon"; break;
case VTK_PIXEL:
stype = "Pixel"; break;
case VTK_QUAD:
stype = "Quad4"; break;
case VTK_TETRA:
stype = "Tet4"; break;
case VTK_VOXEL:
stype = "Voxel"; break;
case VTK_HEXAHEDRON:
stype = "Hex8"; break;
case VTK_WEDGE:
stype = "Wedge"; break;
case VTK_PYRAMID:
stype = "Pyramid"; break;
case VTK_PENTAGONAL_PRISM:
stype = "PentaPrism"; break;
case VTK_HEXAGONAL_PRISM:
stype = "HexaPrism"; break;
case VTK_QUADRATIC_EDGE:
stype = "QuaEdge"; break;
case VTK_QUADRATIC_TRIANGLE:
stype = "QuaTriangle"; break;
case VTK_QUADRATIC_LINEAR_QUAD:
stype = "QuaLinearQuad"; break;
case VTK_QUADRATIC_QUAD:
stype = "QuaQuad"; break;
case VTK_BIQUADRATIC_QUAD:
stype = "BiquaQuad"; break;
case VTK_QUADRATIC_TETRA:
stype = "QuaTetra"; break;
case VTK_QUADRATIC_PYRAMID:
stype = "QuaPyramid"; break;
case VTK_QUADRATIC_HEXAHEDRON:
stype = "QuaHexa"; break;
case VTK_BIQUADRATIC_QUADRATIC_HEXAHEDRON:
stype = "BiquaQuaHexa"; break;
case VTK_TRIQUADRATIC_HEXAHEDRON:
stype = "TriquaHexa"; break;
case VTK_QUADRATIC_LINEAR_WEDGE:
stype = "QuaLinearWedge"; break;
case VTK_QUADRATIC_WEDGE:
stype = "QuaWedge"; break;
case VTK_BIQUADRATIC_QUADRATIC_WEDGE:
stype = "BiquaQuaWedge"; break;
default:
break;
}
return stype;
}
QList<VTKCellType> MeshChecker::getInputCellType()
{
return _inputCount.keys();
}
int MeshChecker::getInputCellCount(VTKCellType type)
{
int count = 0;
if (_inputCount.contains(type))
count = _inputCount.value(type);
return count;
}
int MeshChecker::getInputCellCount()
{
int count = 0;
QList<VTKCellType> typelist = this->getInputCellType();
const int n = typelist.size();
for (int i = 0; i < n; ++i)
{
VTKCellType t = typelist.at(i);
count += this->getInputCellCount(t);
}
return count;
}
QList<VTKCellType> MeshChecker::getQualityCellType()
{
return _checkedCount.keys();
}
int MeshChecker::gettQualityCellCount(VTKCellType type)
{
int count = 0;
if (_checkedCount.contains(type))
count = _checkedCount.value(type).size();
return count;
}
int MeshChecker::gettQualityCellCount()
{
int count = 0;
QList<VTKCellType> typelist = this->getQualityCellType();
const int n = typelist.size();
for (int i = 0; i < n; ++i)
{
VTKCellType t = typelist.at(i);
count += this->gettQualityCellCount(t);
}
return count;
}
void MeshChecker::getQualityRange(double* range)
{
_qualityArray->GetRange(range);
// range[0] = r[0];
// range[1] = r[1];
}
double MeshChecker::getAverageQuality()
{
const int n = _qualityArray->GetNumberOfValues();
if (n == 0) return -1e66;
double sum = 0;
for (int i = 0; i < n; ++i)
{
sum += _qualityArray->GetValue(i);
}
return sum / n;
}
void MeshChecker::countResult()
{
_ticks.clear();
_cellCount.clear();
const int count = gettQualityCellCount();
if (count == 0) return;
double range[2];
this->getQualityRange(range);
if (range[1] - range[0] < 1e-8)
{
_ticks.append((range[0] + range[1]) / 2);
QList<VTKCellType> types = this->getQualityCellType();
for (int i = 0; i < types.size(); ++i)
{
VTKCellType t = types.at(i);
int n = this->gettQualityCellCount(t);
_cellCount[t].append(n);
}
return;
}
QList<VTKCellType> types = this->getQualityCellType();
for (int i = 0; i < types.size(); ++i)
{
VTKCellType t = types.at(i);
//int n = this->gettQualityCellCount(t);
_cellCount[t].resize(10);
}
double ran = range[1] - range[0];
double step = ran / 10.0;
for (int i = 0; i < 10; ++i)
_ticks.append(range[0] + step / 2 + step*i);
for (int i = 0; i < types.size(); ++i)
{
VTKCellType t = types.at(i);
QList<double> qual = _checkedCount[t];
int cellcount = qual.size();
for (int c = 0; c < cellcount; ++c)
{
double v = qual.at(c);
for (int j = 0; j < 10; ++j)
{
double ti = _ticks.at(j);
if (v >= ti - step / 2 && v < ti + step / 2)
{
++_cellCount[t][j];
continue;
}
}
}
}
}
QVector<double> MeshChecker::getTicks()
{
return _ticks;
}
QVector<double> MeshChecker::getCountList(VTKCellType t)
{
QVector<double> d;
if (_cellCount.contains(t))
d = _cellCount.value(t);
return d;
}
QList<vtkDataSet*> MeshChecker::getResultList()
{
return _resultList;
}
}