fix(nmCalculation): 兼容退化单元避免多段压裂井建网失败

- 放宽PEBI输出单元数量一致性校验
- 规范化连续重复点并跳过退化单元
- 保留OriginalCellId映射及非法数据校验
feature/nmNum-postprocessing-view-20260910
lh 2 weeks ago
parent 9255bfefdf
commit 3ddb5b77c6

@ -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)) {

Loading…
Cancel
Save