From 3ddb5b77c6395c7b26df9688b8704c27b4620de2 Mon Sep 17 00:00:00 2001 From: lh <2334563547@qq.com> Date: Tue, 22 Sep 2026 12:11:12 +0800 Subject: [PATCH] =?UTF-8?q?fix(nmCalculation):=20=E5=85=BC=E5=AE=B9?= =?UTF-8?q?=E9=80=80=E5=8C=96=E5=8D=95=E5=85=83=E9=81=BF=E5=85=8D=E5=A4=9A?= =?UTF-8?q?=E6=AE=B5=E5=8E=8B=E8=A3=82=E4=BA=95=E5=BB=BA=E7=BD=91=E5=A4=B1?= =?UTF-8?q?=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 放宽PEBI输出单元数量一致性校验 - 规范化连续重复点并跳过退化单元 - 保留OriginalCellId映射及非法数据校验 --- .../nmCalculation/nmCalculationPebiGrid.cpp | 105 +++++++++++------- 1 file changed, 67 insertions(+), 38 deletions(-) diff --git a/Src/nmNum/nmCalculation/nmCalculationPebiGrid.cpp b/Src/nmNum/nmCalculation/nmCalculationPebiGrid.cpp index f06c67a9..22013982 100644 --- a/Src/nmNum/nmCalculation/nmCalculationPebiGrid.cpp +++ b/Src/nmNum/nmCalculation/nmCalculationPebiGrid.cpp @@ -913,15 +913,21 @@ vtkSmartPointer nmCalculationPebiGrid::createPebiUnstructur if(nPointCount == 0 || nPointCount > static_cast(INT_MAX) || nOriginalCellCount == 0 || nOriginalCellCount > static_cast(INT_MAX) || - nCellDefinitionCount > static_cast(INT_MAX) || - nCellDefinitionCount != nOriginalCellCount) { + nCellDefinitionCount > static_cast(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 setUniquePointIndices; - int nVisibleCellCount = 0; + QVector vecVisibleOriginalCellIds; + QMap > 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 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(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 setCellPointIndices; - for(int j = 0; j < nPointsInCell; ++j) { + QVector vecNormalizedPointIds; + vecNormalizedPointIds.reserve(static_cast(vecIndices.size())); + for(int j = 0; j < static_cast(vecIndices.size()); ++j) { const int nOriginalPointId = vecIndices[j]; if(nOriginalPointId < 0 || static_cast(nOriginalPointId) >= nPointCount) { @@ -958,26 +956,58 @@ vtkSmartPointer 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 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(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 nmCalculationPebiGrid::createPebiUnstructur // 第二遍只提交已经验证过的可见单元,并同步构造 VTK -> 原始单元映射。 QVector 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& vecIndices = P1.PEBI_cell.pindex[i]; - int nPointsInCell = static_cast(vecIndices.size()); - if(nPointsInCell > 1 && vecIndices[0] == vecIndices[nPointsInCell - 1]) { - nPointsInCell--; - } + const int nOriginalCellId = + vecVisibleOriginalCellIds[nCellIndex]; + const QVector& vecPointIds = + mapCellPointIds[nOriginalCellId]; + const int nPointsInCell = vecPointIds.size(); int vtkCellType = 0; if(nPointsInCell == 2) { vtkCellType = VTK_LINE; @@ -1040,10 +1068,10 @@ vtkSmartPointer nmCalculationPebiGrid::createPebiUnstructur QVector vecVtkPointIds(nPointsInCell); for(int j = 0; j < nPointsInCell; ++j) { QMap::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 nmCalculationPebiGrid::createPebiUnstructur qWarning() << "PEBI VTK cell insertion order is invalid."; return nullptr; } - vecVtkToOriginal.append(static_cast(i)); + vecVtkToOriginal.append( + static_cast(nOriginalCellId)); } if(isCancellationRequested(pCancelRequested)) {