#include "meshChecker.h" #include "meshKernal.h" #include "meshSingleton.h" #include #include #include #include #include #include #include #include namespace MeshData { MeshChecker::MeshChecker() { _meshData = MeshData::getInstance(); _cellQuality = vtkSmartPointer::New(); _qualityArray = vtkSmartPointer::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 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 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 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 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 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 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 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 MeshChecker::getTicks() { return _ticks; } QVector MeshChecker::getCountList(VTKCellType t) { QVector d; if (_cellCount.contains(t)) d = _cellCount.value(t); return d; } QList MeshChecker::getResultList() { return _resultList; } }