|
|
|
|
@ -913,15 +913,21 @@ vtkSmartPointer<vtkUnstructuredGrid> nmCalculationPebiGrid::createPebiUnstructur
|
|
|
|
|
if(nPointCount == 0 || nPointCount > static_cast<size_t>(INT_MAX) ||
|
|
|
|
|
nOriginalCellCount == 0 ||
|
|
|
|
|
nOriginalCellCount > static_cast<size_t>(INT_MAX) ||
|
|
|
|
|
nCellDefinitionCount > static_cast<size_t>(INT_MAX) ||
|
|
|
|
|
nCellDefinitionCount != nOriginalCellCount) {
|
|
|
|
|
nCellDefinitionCount > static_cast<size_t>(INT_MAX)) {
|
|
|
|
|
qWarning() << "PEBI grid output dimensions are invalid.";
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
if(nCellDefinitionCount != nOriginalCellCount) {
|
|
|
|
|
qWarning() << "PEBI grid output cell counts differ;"
|
|
|
|
|
<< "unmatched cells will be ignored:"
|
|
|
|
|
<< nCellDefinitionCount << nOriginalCellCount;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 第一遍只验证 DLL 输出并收集点,不向 VTK 对象提交半成品几何。
|
|
|
|
|
// 第一遍验证 DLL 输出、规范化单元并收集点,不向 VTK 对象提交半成品几何。
|
|
|
|
|
QSet<int> setUniquePointIndices;
|
|
|
|
|
int nVisibleCellCount = 0;
|
|
|
|
|
QVector<int> vecVisibleOriginalCellIds;
|
|
|
|
|
QMap<int, QVector<int> > mapCellPointIds;
|
|
|
|
|
int nSkippedCellCount = 0;
|
|
|
|
|
for(size_t i = 0; i < P1.PEBI_cell.pindex.size(); ++i) {
|
|
|
|
|
if((i % 256) == 0 && isCancellationRequested(pCancelRequested)) {
|
|
|
|
|
return nullptr;
|
|
|
|
|
@ -931,26 +937,18 @@ vtkSmartPointer<vtkUnstructuredGrid> nmCalculationPebiGrid::createPebiUnstructur
|
|
|
|
|
qWarning() << "PEBI cell point count exceeds VTK capacity:" << i;
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
if(P1.PEBI_cell.isplot[i] != 1) {
|
|
|
|
|
if(i >= nOriginalCellCount || P1.PEBI_cell.isplot[i] != 1) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(vecIndices.empty()) {
|
|
|
|
|
qWarning() << "PEBI cell has an invalid point count:" << i;
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
int nPointsInCell = static_cast<int>(vecIndices.size());
|
|
|
|
|
if(nPointsInCell > 1 && vecIndices[0] == vecIndices[nPointsInCell - 1]) {
|
|
|
|
|
nPointsInCell--;
|
|
|
|
|
}
|
|
|
|
|
// 保留既有 VTK_LINE 规则,因此去除闭合尾点后至少需要两个不同点。
|
|
|
|
|
if(nPointsInCell < 2) {
|
|
|
|
|
qWarning() << "PEBI cell has fewer than two usable points:" << i;
|
|
|
|
|
return nullptr;
|
|
|
|
|
++nSkippedCellCount;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QSet<int> setCellPointIndices;
|
|
|
|
|
for(int j = 0; j < nPointsInCell; ++j) {
|
|
|
|
|
QVector<int> vecNormalizedPointIds;
|
|
|
|
|
vecNormalizedPointIds.reserve(static_cast<int>(vecIndices.size()));
|
|
|
|
|
for(int j = 0; j < static_cast<int>(vecIndices.size()); ++j) {
|
|
|
|
|
const int nOriginalPointId = vecIndices[j];
|
|
|
|
|
if(nOriginalPointId < 0 ||
|
|
|
|
|
static_cast<size_t>(nOriginalPointId) >= nPointCount) {
|
|
|
|
|
@ -958,26 +956,58 @@ vtkSmartPointer<vtkUnstructuredGrid> nmCalculationPebiGrid::createPebiUnstructur
|
|
|
|
|
<< i << nOriginalPointId;
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
if(setCellPointIndices.contains(nOriginalPointId)) {
|
|
|
|
|
qWarning() << "PEBI cell contains a repeated interior point:"
|
|
|
|
|
<< i << nOriginalPointId;
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
const double dX = P1.PEBI_cell.p[nOriginalPointId].x;
|
|
|
|
|
const double dY = P1.PEBI_cell.p[nOriginalPointId].y;
|
|
|
|
|
if(!vtkMath::IsFinite(dX) || !vtkMath::IsFinite(dY)) {
|
|
|
|
|
qWarning() << "PEBI cell references a non-finite point:" << i;
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(vecNormalizedPointIds.isEmpty() ||
|
|
|
|
|
vecNormalizedPointIds.last() != nOriginalPointId) {
|
|
|
|
|
vecNormalizedPointIds.append(nOriginalPointId);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(vecNormalizedPointIds.size() > 1 &&
|
|
|
|
|
vecNormalizedPointIds.first() == vecNormalizedPointIds.last()) {
|
|
|
|
|
vecNormalizedPointIds.resize(
|
|
|
|
|
vecNormalizedPointIds.size() - 1);
|
|
|
|
|
}
|
|
|
|
|
if(vecNormalizedPointIds.size() < 2) {
|
|
|
|
|
++nSkippedCellCount;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QSet<int> setCellPointIndices;
|
|
|
|
|
bool bHasRepeatedInteriorPoint = false;
|
|
|
|
|
for(int j = 0; j < vecNormalizedPointIds.size(); ++j) {
|
|
|
|
|
const int nOriginalPointId = vecNormalizedPointIds[j];
|
|
|
|
|
if(setCellPointIndices.contains(nOriginalPointId)) {
|
|
|
|
|
bHasRepeatedInteriorPoint = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
setCellPointIndices.insert(nOriginalPointId);
|
|
|
|
|
}
|
|
|
|
|
if(bHasRepeatedInteriorPoint) {
|
|
|
|
|
++nSkippedCellCount;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach(int nOriginalPointId, setCellPointIndices) {
|
|
|
|
|
setUniquePointIndices.insert(nOriginalPointId);
|
|
|
|
|
}
|
|
|
|
|
++nVisibleCellCount;
|
|
|
|
|
const int nOriginalCellId = static_cast<int>(i);
|
|
|
|
|
vecVisibleOriginalCellIds.append(nOriginalCellId);
|
|
|
|
|
mapCellPointIds.insert(nOriginalCellId, vecNormalizedPointIds);
|
|
|
|
|
}
|
|
|
|
|
const int nVisibleCellCount = vecVisibleOriginalCellIds.size();
|
|
|
|
|
if(nVisibleCellCount <= 0 || setUniquePointIndices.isEmpty()) {
|
|
|
|
|
qWarning() << "PEBI grid output contains no visible cells.";
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
if(nSkippedCellCount > 0) {
|
|
|
|
|
qWarning() << "Skipped degenerate PEBI cells:" << nSkippedCellCount;
|
|
|
|
|
}
|
|
|
|
|
if(isCancellationRequested(pCancelRequested)) {
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
@ -1013,19 +1043,17 @@ vtkSmartPointer<vtkUnstructuredGrid> nmCalculationPebiGrid::createPebiUnstructur
|
|
|
|
|
// 第二遍只提交已经验证过的可见单元,并同步构造 VTK -> 原始单元映射。
|
|
|
|
|
QVector<vtkIdType> vecVtkToOriginal;
|
|
|
|
|
vecVtkToOriginal.reserve(nVisibleCellCount);
|
|
|
|
|
for(size_t i = 0; i < P1.PEBI_cell.pindex.size(); ++i) {
|
|
|
|
|
if((i % 256) == 0 && isCancellationRequested(pCancelRequested)) {
|
|
|
|
|
for(int nCellIndex = 0;
|
|
|
|
|
nCellIndex < vecVisibleOriginalCellIds.size(); ++nCellIndex) {
|
|
|
|
|
if((nCellIndex % 256) == 0 &&
|
|
|
|
|
isCancellationRequested(pCancelRequested)) {
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
if(P1.PEBI_cell.isplot[i] != 1) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const std::vector<int>& vecIndices = P1.PEBI_cell.pindex[i];
|
|
|
|
|
int nPointsInCell = static_cast<int>(vecIndices.size());
|
|
|
|
|
if(nPointsInCell > 1 && vecIndices[0] == vecIndices[nPointsInCell - 1]) {
|
|
|
|
|
nPointsInCell--;
|
|
|
|
|
}
|
|
|
|
|
const int nOriginalCellId =
|
|
|
|
|
vecVisibleOriginalCellIds[nCellIndex];
|
|
|
|
|
const QVector<int>& vecPointIds =
|
|
|
|
|
mapCellPointIds[nOriginalCellId];
|
|
|
|
|
const int nPointsInCell = vecPointIds.size();
|
|
|
|
|
int vtkCellType = 0;
|
|
|
|
|
if(nPointsInCell == 2) {
|
|
|
|
|
vtkCellType = VTK_LINE;
|
|
|
|
|
@ -1040,10 +1068,10 @@ vtkSmartPointer<vtkUnstructuredGrid> nmCalculationPebiGrid::createPebiUnstructur
|
|
|
|
|
QVector<vtkIdType> vecVtkPointIds(nPointsInCell);
|
|
|
|
|
for(int j = 0; j < nPointsInCell; ++j) {
|
|
|
|
|
QMap<int, vtkIdType>::const_iterator oPointIt =
|
|
|
|
|
mapOriginalToVtkPointId.constFind(vecIndices[j]);
|
|
|
|
|
mapOriginalToVtkPointId.constFind(vecPointIds[j]);
|
|
|
|
|
if(oPointIt == mapOriginalToVtkPointId.constEnd()) {
|
|
|
|
|
qWarning() << "Validated PEBI point is missing from the map:"
|
|
|
|
|
<< i << vecIndices[j];
|
|
|
|
|
<< nOriginalCellId << vecPointIds[j];
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
vecVtkPointIds[j] = oPointIt.value();
|
|
|
|
|
@ -1060,7 +1088,8 @@ vtkSmartPointer<vtkUnstructuredGrid> nmCalculationPebiGrid::createPebiUnstructur
|
|
|
|
|
qWarning() << "PEBI VTK cell insertion order is invalid.";
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
vecVtkToOriginal.append(static_cast<vtkIdType>(i));
|
|
|
|
|
vecVtkToOriginal.append(
|
|
|
|
|
static_cast<vtkIdType>(nOriginalCellId));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(isCancellationRequested(pCancelRequested)) {
|
|
|
|
|
|