From 7713271557d8e0fc0ac7a0bc97e16d536ca66a2d Mon Sep 17 00:00:00 2001 From: gaozheng Date: Sun, 7 Jun 2026 22:53:29 +0800 Subject: [PATCH] =?UTF-8?q?refactor(app):=20=E4=B8=AD=E5=A4=AE=E5=9C=B0?= =?UTF-8?q?=E5=9B=BE/3D=E5=8D=95=E5=9C=BA=E6=99=AF(=E7=AB=96=E7=9B=B4?= =?UTF-8?q?=E5=B8=98=E9=9D=A2)+=E4=B8=8B=E6=96=B9=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E8=AF=A6=E6=83=85(#18=E5=B9=B3=E9=9D=A2=E5=89=96=E9=9D=A2),=20?= =?UTF-8?q?=E5=8E=BB=E9=99=A4=E4=BD=93=E7=B4=A0=E8=8A=82=E7=82=B9=E4=B8=8E?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E6=B7=B7=E4=B9=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/main.cpp | 265 +++++++++--------------- src/data/repo/LocalSampleRepository.cpp | 10 +- 2 files changed, 98 insertions(+), 177 deletions(-) diff --git a/src/app/main.cpp b/src/app/main.cpp index 8803be9..3701170 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -1,7 +1,11 @@ -// M1 工作台(Phase 2 / Task 4):对象树 → 选中数据集 → 中央 QVTK 渲染剖面 + 右侧属性。 -// 端到端:data(LocalSampleRepository 读真实中文路径样本) + core(Grid/ColorScale) + -// render(VTK banded contour) + view(Qt/ADS 三栏停靠)。 -// 数据:docs/剖面网格数据的色阶数据2等文件/(真实样本,UTF-8 中文路径,经 QFile 读取)。 +// M1 工作台(视图重构 Task B):正确产品模型。 +// - 左 对象树:GS→TM→DS(复选框)。勾选 dd_section → 中央场景显示该测线竖直帘面(立体断面墙),可多条共存。 +// - 中央「二维/三维视图」:单一 VTK 3D 场景,内容是测线竖直帘面。工具条仅「二维/三维」相机开关 +// (作用整场景):二维=俯视正交(看测线俯视布局)、三维=透视(看立体墙)。因内容立体,2D/3D 有真实区别。 +// - 下方「数据详情」:独立 QVTK 小视图。单击某 DS → 显示该数据集平面反演剖面(#18 banded 等值面+等值线, +// 平躺俯视正交)+ 属性。 +// - 右 属性:选中数据集属性文本。 +// 世界系:启动 loadGrid("grid1") 取一次,用其 lat/lon 中位/均值作 GeoLocalFrame(全项目共享,保证多帘面配准)。 #include #include @@ -13,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -36,24 +39,19 @@ #include "CameraPreset.hpp" #include "Scene.hpp" +#include "actors/CurtainActor.hpp" #include "actors/GridContourActor.hpp" -#include "actors/VoxelActor.hpp" -#include "algo/IInterpolator.hpp" -#include "algo/IdwInterpolator.hpp" +#include "geo/GeoLocalFrame.hpp" #include -#include -#include +#include #include #include -#include #include -#include #include #include -#include namespace { @@ -62,8 +60,8 @@ constexpr int kRoleDsId = Qt::UserRole; constexpr int kRoleDdType = Qt::UserRole + 1; // 从对象结构树构建 QTreeWidget:GS → TM → DS 三层。 -// DS 项可勾选(复选框):勾选驱动该数据集在场景中的显示;UserRole 存 dsId、UserRole+1 存 ddType。 -// 网格剖面(dd_section)默认勾选,启动即显示。 +// DS 项可勾选(复选框):勾选驱动该测线竖直帘面在中央场景显示;UserRole 存 dsId、UserRole+1 存 ddType。 +// 网格剖面(dd_section)默认勾选,启动即显示帘面。 void populateTree(QTreeWidget* tree, const std::vector& gss) { for (const auto& gs : gss) { @@ -77,9 +75,8 @@ void populateTree(QTreeWidget* tree, const std::vector& gs dsItem->setText(0, QString::fromStdString(ds.name)); dsItem->setData(0, kRoleDsId, QString::fromStdString(ds.id)); dsItem->setData(0, kRoleDdType, QString::fromStdString(ds.ddType)); - // DS 项可勾选:勾选 = 在场景中显示该数据集。 dsItem->setFlags(dsItem->flags() | Qt::ItemIsUserCheckable); - // 网格剖面默认显示;其余默认不勾。 + // 网格剖面默认勾选 → 启动即显帘面;其余默认不勾。 dsItem->setCheckState( 0, ds.ddType == "dd_section" ? Qt::Checked : Qt::Unchecked); } @@ -98,114 +95,42 @@ std::string readPem(const std::string& path) return ss.str(); } -// dd_voxel 构建结果:体绘制 volume + 其底层 vtkImageData(供切片 widget)+ 网格信息。 -struct VoxelBuildResult { - vtkSmartPointer volume; - vtkSmartPointer image; - int nx = 0, ny = 0, nz = 0; - double vmin = 0.0, vmax = 0.0; -}; - -// dd_voxel:合并两条交叉剖面散点 → 局部化 → IDW 体素 → GPU 体绘制。 -// 与 tools/validate_voxel.py 同逻辑(power=2, maxDist≈4, dxy=1m, dz=0.5m)。 -VoxelBuildResult buildVoxelFromScatters( - const std::vector& scatters, - const geopro::core::ColorScale& cs) +// 取 vector 中位数(用于由测线 lat/lon 推世界系原点)。空则返回 0。 +double median(std::vector v) { - using geopro::core::GridSpec; - using geopro::core::IdwInterpolator; - using geopro::core::PointSet; - - constexpr double kDxy = 2.0; // 水平步长(米);粗化体素网格保证实时(~1.4万格) - constexpr double kDz = 1.0; // 垂向步长(米) - constexpr double kPower = 2.0; // IDW 幂(=2 走 1/d² 快速路径) - constexpr double kMaxDist = 4.0; // 超距留空(NaN) - - // 合并两剖面点为一组 (X=projX, Y=projY, Z=z)。 - std::vector X, Y, Z, V; - for (const auto& s : scatters) { - const size_t n = s.v.size(); - for (size_t p = 0; p < n; ++p) { - // projX/projY 为 GIS 平面坐标;z 为高程;v 为值。容错缺失字段。 - if (p < s.projX.size() && p < s.projY.size() && p < s.z.size()) { - X.push_back(s.projX[p]); - Y.push_back(s.projY[p]); - Z.push_back(s.z[p]); - V.push_back(s.v[p]); - } - } - } - if (V.empty()) return VoxelBuildResult{}; - - // 局部化:三轴各减最小值(规避大坐标;ox=oy=oz=0)。 - const double minX = *std::min_element(X.begin(), X.end()); - const double minY = *std::min_element(Y.begin(), Y.end()); - const double minZ = *std::min_element(Z.begin(), Z.end()); - PointSet pts; - double extX = 0.0, extY = 0.0, extZ = 0.0; - for (size_t p = 0; p < V.size(); ++p) { - const double lx = X[p] - minX, ly = Y[p] - minY, lz = Z[p] - minZ; - pts.x.push_back(lx); - pts.y.push_back(ly); - pts.z.push_back(lz); - pts.v.push_back(V[p]); - extX = std::max(extX, lx); - extY = std::max(extY, ly); - extZ = std::max(extZ, lz); - } - - GridSpec spec; - spec.ox = spec.oy = spec.oz = 0.0; - spec.dx = spec.dy = kDxy; - spec.dz = kDz; - spec.nx = static_cast(extX / kDxy) + 1; - spec.ny = static_cast(extY / kDxy) + 1; - spec.nz = static_cast(extZ / kDz) + 1; - spec.power = kPower; - spec.maxDist = kMaxDist; - - const auto vol = IdwInterpolator().interpolate(pts, spec); - - // 算 vmin/vmax(忽略 NaN)。 - double vmin = std::numeric_limits::max(); - double vmax = std::numeric_limits::lowest(); - for (double v : vol.data()) { - if (std::isnan(v)) continue; - vmin = std::min(vmin, v); - vmax = std::max(vmax, v); - } - if (vmin > vmax) { vmin = 0.0; vmax = 1.0; } // 全 NaN 兜底 - - VoxelBuildResult r; - r.image = vtkSmartPointer::New(); - r.volume = geopro::render::buildVoxel( - vol, cs, spec.ox, spec.oy, spec.oz, spec.dx, spec.dy, spec.dz, vmin, vmax, r.image); - r.nx = spec.nx; r.ny = spec.ny; r.nz = spec.nz; - r.vmin = vmin; r.vmax = vmax; - return r; + if (v.empty()) return 0.0; + std::sort(v.begin(), v.end()); + const size_t n = v.size(); + return n % 2 ? v[n / 2] : 0.5 * (v[n / 2 - 1] + v[n / 2]); } -// 在给定 QMainWindow 上构建 M1 工作台:ADS 三栏 + 对象树 → 渲染联动 + 属性面板。 -// repo 生命周期须覆盖到事件循环结束(由调用方保证)。 -// 相机模式:默认二维俯视。 +// 当前相机模式(默认二维俯视)。 enum class CameraMode { Top2D, Free3D }; +// 在给定 QMainWindow 上构建 M1 工作台。 +// repo 生命周期须覆盖到事件循环结束(由调用方保证)。 void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& repo) { - // 中央 QVTK 视图(指针供联动回调使用)。renderer 由 render::Scene 持有。 - // Scene 需在 lambda 回调期间存活 ⇒ 堆分配,挂到 window 父链随窗口销毁。 + // ── 世界系:启动取一次 grid1 的 lat/lon,用中位数作 GeoLocalFrame 原点 ── + // 全项目共享(shared_ptr 持有):所有帘面用同一 frame 投影,保证多条测线空间配准。 + const auto baseGrid = repo.loadGrid("grid1"); + const double lat0 = median(baseGrid.lat); + const double lon0 = median(baseGrid.lon); + auto frame = std::make_shared(lat0, lon0); + + // ── 中央 QVTK + Scene(竖直帘面场景)───────────────────────────────── + // Scene 非 QObject:堆分配,用 widget 销毁信号清理(widget 随 window 销毁)。 auto* scene = new geopro::render::Scene(); auto* vtkWidget = new QVTKOpenGLStereoWidget(); - // Scene 非 QObject:用 widget 销毁信号清理,避免泄漏(widget 随 window 销毁)。 QObject::connect(vtkWidget, &QObject::destroyed, [scene]() { delete scene; }); vtkNew renderWindow; vtkWidget->setRenderWindow(renderWindow); renderWindow->AddRenderer(scene->renderer()); - // 当前相机模式(默认二维)。用 shared_ptr 让多个 lambda 共享同一状态。 - auto cameraMode = std::make_shared(CameraMode::Top2D); vtkRenderer* rendererPtr = scene->renderer(); vtkGenericOpenGLRenderWindow* renderWindowPtr = renderWindow.Get(); + + auto cameraMode = std::make_shared(CameraMode::Top2D); auto applyCurrentCamera = [rendererPtr, cameraMode]() { if (*cameraMode == CameraMode::Top2D) geopro::render::applyTop2D(rendererPtr); @@ -216,13 +141,13 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re auto* dockManager = new ads::CDockManager(&window); window.setCentralWidget(dockManager); - // 中央剖面容器:顶部 2D/3D 工具条 + 下方 QVTK 视图。 + // 中央容器:顶部 2D/3D 工具条 + 下方帘面 QVTK 视图。 auto* centerWidget = new QWidget(); auto* centerLayout = new QVBoxLayout(centerWidget); centerLayout->setContentsMargins(0, 0, 0, 0); centerLayout->setSpacing(0); - // 工具条:仅「二维/三维」相机开关,作用于整个场景(不绑定内容)。互斥二选一,默认二维。 + // 工具条:仅「二维/三维」相机开关,作用整场景(不改内容)。互斥二选一,默认二维。 auto* viewToolBar = new QToolBar(); auto* cameraGroup = new QActionGroup(viewToolBar); cameraGroup->setExclusive(true); @@ -238,7 +163,23 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re auto* vtkDock = new ads::CDockWidget(QStringLiteral("二维/三维视图")); vtkDock->setWidget(centerWidget); - dockManager->addDockWidget(ads::CenterDockWidgetArea, vtkDock); + auto* centerDockArea = dockManager->addDockWidget(ads::CenterDockWidgetArea, vtkDock); + + // ── 下方「数据详情」dock:独立 QVTK 小视图(独立 renderer/renderWindow)── + // 单击 DS → 显示该数据集平面反演剖面(#18 banded,平躺俯视正交)。 + auto* detailWidget = new QVTKOpenGLStereoWidget(); + vtkNew detailRenderWindow; + vtkNew detailRenderer; + detailRenderer->SetBackground(1.0, 1.0, 1.0); // 白底 + detailWidget->setRenderWindow(detailRenderWindow); + detailRenderWindow->AddRenderer(detailRenderer); + vtkRenderer* detailRendererPtr = detailRenderer.Get(); + vtkGenericOpenGLRenderWindow* detailRenderWindowPtr = detailRenderWindow.Get(); + + auto* detailDock = new ads::CDockWidget(QStringLiteral("数据详情")); + detailDock->setWidget(detailWidget); + // 放在中央视图下方。 + dockManager->addDockWidget(ads::BottomDockWidgetArea, detailDock, centerDockArea); // 左 dock:对象树。 auto* tree = new QTreeWidget(); @@ -249,7 +190,7 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re dockManager->addDockWidget(ads::LeftDockWidgetArea, leftDock); // 右 dock:属性。 - auto* propLabel = new QLabel(QStringLiteral("(选择左侧数据集查看属性)")); + auto* propLabel = new QLabel(QStringLiteral("(单击左侧数据集查看属性与平面剖面)")); propLabel->setWordWrap(true); propLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft); propLabel->setMargin(8); @@ -257,17 +198,15 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re rightDock->setWidget(propLabel); dockManager->addDockWidget(ads::RightDockWidgetArea, rightDock); - // ── 勾选驱动显示(核心)────────────────────────────────────────────── - // 已显示数据集 → 其 VTK props 的映射。一个数据集可对应多个 prop(如剖面 bands+edges)。 - // 用 shared_ptr 让多个 lambda 共享同一映射;props 由 renderer 引用计数保活。 + // ── 勾选驱动帘面显示(核心)───────────────────────────────────────── + // 已显示数据集 → 其 VTK props 映射(帘面=单个 actor)。多数据集叠加共存,不 clear 场景。 using PropList = std::vector>; auto dsProps = std::make_shared>(); - // 初始化守卫:populateTree 会程序化 setCheckState,触发 itemChanged; - // 也用于「点击 DS 自动勾选」等程序化改动期间,避免回调递归/重入。 + // 初始化守卫:populateTree 程序化 setCheckState 触发 itemChanged,需避免重入。 auto building = std::make_shared(false); - // 是否已有任意可见对象(用于决定首个对象时套用当前相机预设)。 + // 是否已有任意可见对象(用于首个对象时套用当前相机预设)。 auto hasVisible = [dsProps]() { for (const auto& kv : *dsProps) { if (!kv.second.empty()) return true; @@ -275,42 +214,28 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re return false; }; - // 按 ddType 构建某数据集的 props 并加入 renderer。返回构建出的 props(可能为空)。 - // dd_section:loadGrid + loadColorScale → banded contour(bands + edges)。 - // dd_voxel:两条交叉剖面散点 → IDW 体素 → GPU 体绘制(WaitCursor 包裹耗时构建)。 - auto buildProps = [&repo, propLabel](const QString& dsId, - const QString& ddType) -> PropList { + // 构建某测线竖直帘面(dd_section)并返回其 props。其它类型暂不入中央场景。 + auto buildCurtainProps = [&repo, frame](const QString& dsId, + const QString& ddType) -> PropList { PropList props; if (ddType == "dd_section") { const std::string id = dsId.toStdString(); const auto g = repo.loadGrid(id); const auto cs = repo.loadColorScale(id); - const auto actors = geopro::render::buildGridContour(g, cs); - if (actors.bands) props.push_back(actors.bands); - if (actors.edges) props.push_back(actors.edges); - } else if (ddType == "dd_voxel") { - QApplication::setOverrideCursor(Qt::WaitCursor); - const auto scatters = repo.loadVoxelScatters(); - const auto cs = repo.loadColorScale("grid1"); // 体素复用 grid1 色阶 - auto result = buildVoxelFromScatters(scatters, cs); - QApplication::restoreOverrideCursor(); - if (result.volume) props.push_back(result.volume); - else propLabel->setText(QStringLiteral("dd_voxel: 无可用散点数据")); + auto curtain = geopro::render::buildCurtain(g, cs, *frame); + if (curtain) props.push_back(curtain); } return props; }; - // 勾选态变化:勾选 → 构建/显示该数据集 props;取消 → 移除其 props。 - // 多个数据集可同时勾选并叠加共存(不 clear 场景,按数据集增删 props)。 - // 已知限制:剖面用「距离-深度」局部坐标,体素用 GIS 局部坐标,二者坐标基不同, - // 叠加时不会真正空间对齐(后续 curtain/坐标统一工作,见 STATUS §5)。 + // 勾选态变化:勾选 → 构建/显示帘面;取消 → 移除其 props。多数据集叠加共存。 QObject::connect( tree, &QTreeWidget::itemChanged, tree, - [dsProps, building, buildProps, hasVisible, applyCurrentCamera, rendererPtr, + [dsProps, building, buildCurtainProps, hasVisible, applyCurrentCamera, rendererPtr, renderWindowPtr](QTreeWidgetItem* item, int) { if (*building) return; // 程序化改动期间不处理,避免初始化递归 const QString dsId = item->data(0, kRoleDsId).toString(); - if (dsId.isEmpty()) return; // GS/TM 节点(无 dsId)忽略 + if (dsId.isEmpty()) return; // GS/TM 节点忽略 const QString ddType = item->data(0, kRoleDdType).toString(); const bool checked = item->checkState(0) == Qt::Checked; @@ -318,18 +243,15 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re const bool wasEmpty = !hasVisible(); auto it = dsProps->find(dsId); if (it == dsProps->end() || it->second.empty()) { - // 首次显示:构建并加入 renderer。 - PropList props = buildProps(dsId, ddType); + PropList props = buildCurtainProps(dsId, ddType); for (const auto& p : props) rendererPtr->AddViewProp(p); (*dsProps)[dsId] = std::move(props); } else { - // 之前隐藏过(保留了 props):仅恢复可见。 for (const auto& p : it->second) p->SetVisibility(1); } - if (wasEmpty) applyCurrentCamera(); // 首个可见对象 → 套用当前相机预设 - rendererPtr->ResetCamera(); // 框住所有可见对象 + if (wasEmpty) applyCurrentCamera(); // 首个可见对象 → 套用当前相机 + rendererPtr->ResetCamera(); } else { - // 取消勾选:从场景移除该数据集 props。 auto it = dsProps->find(dsId); if (it != dsProps->end()) { for (const auto& p : it->second) rendererPtr->RemoveViewProp(p); @@ -339,29 +261,37 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re renderWindowPtr->Render(); }); - // ── 单击 DS → 更新右侧属性(与勾选区分;不改变可见性)──────────────── + // ── 单击 DS → 下方数据详情显示平面反演剖面 + 右侧属性(与勾选区分;不改帘面可见性)── QObject::connect( tree, &QTreeWidget::itemClicked, tree, - [&repo, propLabel](QTreeWidgetItem* item, int) { + [&repo, propLabel, detailRendererPtr, detailRenderWindowPtr](QTreeWidgetItem* item, int) { const QString dsId = item->data(0, kRoleDsId).toString(); - if (dsId.isEmpty()) return; // GS/TM 节点无属性 + if (dsId.isEmpty()) return; // GS/TM 节点无详情 const QString ddType = item->data(0, kRoleDdType).toString(); const QString name = item->text(0); - if (ddType == "dd_section") { - const auto g = repo.loadGrid(dsId.toStdString()); - propLabel->setText( - QStringLiteral("数据集: %1\n类型: 剖面网格 (dd_section)\n网格: %2 x %3\n" - "vmin / vmax: %4 / %5") - .arg(name).arg(g.nx()).arg(g.ny()).arg(g.vmin).arg(g.vmax)); - } else if (ddType == "dd_voxel") { - propLabel->setText( - QStringLiteral("数据集: %1\n类型: 三维体素 (dd_voxel)\n" - "说明: 两交叉剖面 IDW 体素") - .arg(name)); - } + if (ddType != "dd_section") return; + + const std::string id = dsId.toStdString(); + const auto g = repo.loadGrid(id); + const auto cs = repo.loadColorScale(id); + + // 下方数据详情:平面反演剖面(#18 banded 等值面 + 等值线),平躺俯视正交。 + const auto actors = geopro::render::buildGridContour(g, cs); + detailRendererPtr->RemoveAllViewProps(); + if (actors.bands) detailRendererPtr->AddViewProp(actors.bands); + if (actors.edges) detailRendererPtr->AddViewProp(actors.edges); + geopro::render::applyTop2D(detailRendererPtr); + detailRendererPtr->ResetCamera(); + detailRenderWindowPtr->Render(); + + // 右侧属性。 + propLabel->setText( + QStringLiteral("数据集: %1\n类型: 剖面网格 (dd_section)\n网格: %2 x %3\n" + "vmin / vmax: %4 / %5") + .arg(name).arg(g.nx()).arg(g.ny()).arg(g.vmin).arg(g.vmax)); }); - // ── 工具条「二维/三维」:仅切换整场景相机预设,不改变内容可见性 ────────── + // ── 工具条「二维/三维」:仅切换整场景相机预设,不改内容可见性 ──────────── QObject::connect(act2D, &QAction::triggered, vtkWidget, [cameraMode, applyCurrentCamera, rendererPtr, renderWindowPtr]() { *cameraMode = CameraMode::Top2D; @@ -377,8 +307,8 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re renderWindowPtr->Render(); }); - // ── 启动默认:网格剖面 DS 已在 populateTree 中设为 Checked,但 itemChanged - // 在 connect 之前触发故未渲染。这里在 connect 之后,对已勾选的 DS 主动触发一次显示。 + // ── 启动默认:dd_section 已设为 Checked,但 itemChanged 在 connect 之前触发故未渲染。 + // 这里 connect 之后对已勾选 DS 主动触发一次帘面显示。 { QList stack; for (int i = 0; i < tree->topLevelItemCount(); ++i) stack.append(tree->topLevelItem(i)); @@ -387,7 +317,7 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re const QString dsId = cur->data(0, kRoleDsId).toString(); if (!dsId.isEmpty() && cur->checkState(0) == Qt::Checked) { const QString ddType = cur->data(0, kRoleDdType).toString(); - PropList props = buildProps(dsId, ddType); + PropList props = buildCurtainProps(dsId, ddType); const bool wasEmpty = !hasVisible(); for (const auto& p : props) rendererPtr->AddViewProp(p); (*dsProps)[dsId] = std::move(props); @@ -404,7 +334,7 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re int main(int argc, char* argv[]) { - // QVTK 默认 surface format 必须在 QApplication 之前设置。 + // QVTK 默认 surface format 必须在 QApplication 之前设置(全局一次,两个 QVTK widget 共用)。 QSurfaceFormat::setDefaultFormat(QVTKOpenGLStereoWidget::defaultFormat()); QApplication app(argc, argv); @@ -420,7 +350,6 @@ int main(int argc, char* argv[]) api.setToken(login.token()); // 注入 token 供后续 API 使用 // 登录成功 → 构建并显示工作台。 - // 本地样本仓储(中文路径,末尾带 '/')。生命周期覆盖事件循环。 geopro::data::LocalSampleRepository repo( "D:/Git/lanbingtech/geopro/docs/剖面网格数据的色阶数据2等文件/"); diff --git a/src/data/repo/LocalSampleRepository.cpp b/src/data/repo/LocalSampleRepository.cpp index bcc379b..30971d5 100644 --- a/src/data/repo/LocalSampleRepository.cpp +++ b/src/data/repo/LocalSampleRepository.cpp @@ -51,25 +51,17 @@ std::string LocalSampleRepository::readFile(const std::string& fileNameUtf8) con } std::vector LocalSampleRepository::loadStructure() { - // 剖面网格数据集(dd_section):在对象树勾选后渲染 banded contour 帘面。 + // 剖面网格数据集(dd_section):勾选后在中央场景显示竖直帘面;单击显示平面反演剖面。 DsNode dsSection; dsSection.id = kDsId; dsSection.name = u8"剖面网格数据1"; dsSection.ddType = "dd_section"; - // 三维体素数据集(dd_voxel):勾选后由两条交叉剖面散点 IDW 出体素并叠加显示。 - // 注意:体素与剖面坐标基不同(见 main.cpp 渲染处注释 + STATUS §5),暂不空间配准。 - DsNode dsVoxel; - dsVoxel.id = "voxel1"; - dsVoxel.name = u8"三维体素"; - dsVoxel.ddType = "dd_voxel"; - TmNode tm; tm.id = "tm-ert1"; tm.name = "ERT1"; tm.confCode = "ERT"; tm.dss.push_back(std::move(dsSection)); - tm.dss.push_back(std::move(dsVoxel)); GsNode gs; gs.id = "gs-1";