diff --git a/src/app/main.cpp b/src/app/main.cpp index 8b71a02..4dac989 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -137,6 +137,7 @@ #include "TileBasemap.hpp" #include "panels/columns/ColumnDrawer.hpp" #include "panels/columns/CategoryAnalysisTab.hpp" +#include "panels/columns/CategorySection.hpp" #include "panels/columns/Column3DDataset.hpp" #include "panels/columns/Column2DDataset.hpp" #include "panels/columns/Column3DAnalysis.hpp" @@ -450,11 +451,21 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re // splitByCategory 后注入 5 段(电阻率/视电阻率/瞬变/三维体/切片);二维(足迹)经 dim2D 仍走 col2D。 auto lastSourceRows = std::make_shared>(); auto refreshAnalysis = [drawer, scene3dRepo, lastSourceRows]() { - std::vector rows = *lastSourceRows; - for (auto& vr : scene3dRepo->volumeRows()) rows.push_back(std::move(vr)); // 客户端三维体 - for (auto& sr : scene3dRepo->sliceRows()) rows.push_back(std::move(sr)); // 已保存切片(挂父体下) - drawer->analysisTab()->setBuckets(geopro::app::splitByCategory(rows)); - drawer->col2D()->setDatasets(geopro::app::splitByDimension(rows).dim2D); + const auto vols = scene3dRepo->volumeRows(); + const auto slices = scene3dRepo->sliceRows(); + const auto anomalies = scene3dRepo->anomalyRows(); + // 电阻率/视/瞬变段=对象树反演 ds;voxel/slice 段先由 splitByCategory 按 ddCode 填体/切片。 + std::vector forCat = *lastSourceRows; + for (const auto& v : vols) forCat.push_back(v); + for (const auto& s : slices) forCat.push_back(s); + drawer->analysisTab()->setBuckets(geopro::app::splitByCategory(forCat)); + // 三维体段重置为「体→切片/异常」三级树:体(根)+切片(parentId=体)+异常(parentId=体/切片), + // populateDatasetList 按 parentId 自动建三级树(spec §8)。 + std::vector voxelTree = vols; + for (const auto& s : slices) voxelTree.push_back(s); + for (const auto& a : anomalies) voxelTree.push_back(a); + if (auto* sec = drawer->analysisTab()->section("voxel")) sec->setDatasets(voxelTree); + drawer->col2D()->setDatasets(geopro::app::splitByDimension(*lastSourceRows).dim2D); }; // 渲染勾选聚合:三维数据集栏(剖面→帘面)+ 三维分析栏(三维体/切片→体素/切片)两套勾选并集 @@ -504,8 +515,8 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re const std::string savedSliceId = interactionMgr->selectedSliceDsId(); anomalyDrawTool->start( o, normal, - [&window, sceneView, scene3dRepo, renderWindowPtr, refreshAnomalies, volId, - savedSliceId, normal, o](const std::vector& worldPts) { + [&window, sceneView, scene3dRepo, renderWindowPtr, refreshAnomalies, refreshAnalysis, + volId, savedSliceId, normal, o](const std::vector& worldPts) { // 草稿异常:先临时渲染(让用户在对话框前看到所画,且截图含异常)。 geopro::core::Anomaly a; a.markType = geopro::core::AnomalyMarkType::Polygon; @@ -539,9 +550,11 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re a.remark = dlg.remark().toStdString(); scene3dRepo->saveAnomaly( a, shot.toStdString(), - [sceneView, renderWindowPtr, refreshAnomalies, draftId](std::string) { + [sceneView, renderWindowPtr, refreshAnomalies, refreshAnalysis, + draftId](std::string) { sceneView->removeAnomaly(draftId); // 撤草稿 - refreshAnomalies(); // 重渲染 + 刷新异常列表(含新异常) + refreshAnomalies(); // 重渲染异常 actor + refreshAnalysis(); // 新异常进三维体段三级树(挂体/切片) renderWindowPtr->Render(); }, [&window](const std::string& m) { @@ -663,7 +676,9 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re checkedSliceIds->clear(); for (const QString& id : ids) { const std::string s = id.toStdString(); - if (scene3dRepo->isSliceDataset(s)) + if (scene3dRepo->isAnomalyDataset(s)) + continue; // 异常不进渲染勾选(显隐另管,避免被当帘面源 loadSection 失败) + else if (scene3dRepo->isSliceDataset(s)) checkedSliceIds->insert(s); else if (scene3dRepo->isVolumeDataset(s)) analysis << id; diff --git a/src/data/api/Api3dRepository.cpp b/src/data/api/Api3dRepository.cpp index d825cb5..5a889d8 100644 --- a/src/data/api/Api3dRepository.cpp +++ b/src/data/api/Api3dRepository.cpp @@ -321,6 +321,10 @@ bool Api3dRepository::isSliceDataset(const std::string& dsId) const { return slices_.find(dsId) != slices_.end(); } +bool Api3dRepository::isAnomalyDataset(const std::string& dsId) const { + return anomalies_.find(dsId) != anomalies_.end(); +} + bool Api3dRepository::sliceSpec(const std::string& dsId, SliceSpec& out) const { auto it = slices_.find(dsId); if (it == slices_.end()) return false; diff --git a/src/data/api/Api3dRepository.hpp b/src/data/api/Api3dRepository.hpp index 7a767b2..182b437 100644 --- a/src/data/api/Api3dRepository.hpp +++ b/src/data/api/Api3dRepository.hpp @@ -67,6 +67,8 @@ public: std::vector anomalyRows() const; // 该 dsId 是否为已保存切片(3b:分析栏勾选 dd_slice 走切片重渲染路径,不进控制器帘面/体素路径)。 bool isSliceDataset(const std::string& dsId) const; + // 该 dsId 是否为异常(dd_anomaly)——勾选异常不进帘面/体素渲染勾选,显隐另管。 + bool isAnomalyDataset(const std::string& dsId) const; // 取回已保存切片位姿(还原渲染用);不存在返回 false。 bool sliceSpec(const std::string& dsId, SliceSpec& out) const;