diff --git a/src/render/actors/CurtainActor.cpp b/src/render/actors/CurtainActor.cpp index 1feb8e2..5571186 100644 --- a/src/render/actors/CurtainActor.cpp +++ b/src/render/actors/CurtainActor.cpp @@ -9,6 +9,8 @@ #include #include +#include +#include #include #include @@ -47,6 +49,10 @@ vtkSmartPointer buildCurtain(const geopro::core::Grid& g, sc->SetName("v"); sc->SetNumberOfTuples(static_cast(nx) * ny); + // 无数据格(v 为 null → Grid 存 NaN,反演不规则区大量如此)记录待消隐:NaN 标量喂给 + // vtkBandedPolyDataContourFilter 的裁剪运算会崩(0xc0000005)。消隐后这些格不入表面/色带, + // 既不崩、又把空洞正确显示为透明。标量同时填 0(有限值)以防任何读取路径再触 NaN。 + std::vector blanks; for (int j = 0; j < ny; ++j) { for (int i = 0; i < nx; ++i) { double px, py; @@ -62,15 +68,35 @@ vtkSmartPointer buildCurtain(const geopro::core::Grid& g, const vtkIdType id = static_cast(j) * nx + i; // g.y 是深度(越大越深);VTK Z 向上 → 取负,使深部在下、浅部在上(剖面不倒置)。 points->SetPoint(id, px, py, -g.y[j]); - sc->SetValue(id, g.valueAt(i, j)); + const double val = g.valueAt(i, j); + if (std::isfinite(val)) { + sc->SetValue(id, val); + } else { + sc->SetValue(id, 0.0); + blanks.push_back(id); + } } } sgrid->SetPoints(points); sgrid->GetPointData()->SetScalars(sc); + // 消隐无数据点:vtkStructuredGrid 消隐(ghost)→ 含该点的 cell 不被 vtkDataSetSurfaceFilter 输出, + // 故 NaN 永不进入 banded contour。282/1900 有效的不规则反演区→渲染出正确的梯形帘面。 + for (vtkIdType id : blanks) sgrid->BlankPoint(id); // 用 colorBar 真实分段值做色带(与数据详情#18一致的清晰色带,而非连续插值的糊色)。 - const std::vector stops = cs.stopValues(); + // 清洗等值线值:vtkBandedPolyDataContourFilter 要求值严格升序且有限——真实色阶可能含重复值 + // (addStop 排序不去重)或非有限值,未清洗会在 Update() 时崩(0xc0000005)。去非有限 + 去重保序。 + std::vector stops; + { + std::vector raw = cs.stopValues(); + raw.erase(std::remove_if(raw.begin(), raw.end(), + [](double v) { return !std::isfinite(v); }), + raw.end()); + std::sort(raw.begin(), raw.end()); + raw.erase(std::unique(raw.begin(), raw.end()), raw.end()); + stops = std::move(raw); + } double vmin, vmax; if (stops.size() >= 2) { vmin = stops.front(); vmax = stops.back(); } else { @@ -85,7 +111,7 @@ vtkSmartPointer buildCurtain(const geopro::core::Grid& g, auto lut = buildLut(cs, vmin, vmax, kLutLevels); - // structuredGrid → 表面 polydata → banded contour(分段色带) + // structuredGrid → 表面 polydata(消隐格已剔除) → banded contour(分段色带,色带#18)。 vtkNew surf; surf->SetInputData(sgrid); vtkNew banded;