feat(app): 三维体段「体→切片/异常」三级树注入 + 异常排除渲染勾选 + 创建异常即时进树(Task11 Step4a)

This commit is contained in:
gaozheng 2026-06-24 20:59:21 +08:00
parent a32822f7d6
commit 2f07e605c8
3 changed files with 31 additions and 10 deletions

View File

@ -137,6 +137,7 @@
#include "TileBasemap.hpp" #include "TileBasemap.hpp"
#include "panels/columns/ColumnDrawer.hpp" #include "panels/columns/ColumnDrawer.hpp"
#include "panels/columns/CategoryAnalysisTab.hpp" #include "panels/columns/CategoryAnalysisTab.hpp"
#include "panels/columns/CategorySection.hpp"
#include "panels/columns/Column3DDataset.hpp" #include "panels/columns/Column3DDataset.hpp"
#include "panels/columns/Column2DDataset.hpp" #include "panels/columns/Column2DDataset.hpp"
#include "panels/columns/Column3DAnalysis.hpp" #include "panels/columns/Column3DAnalysis.hpp"
@ -450,11 +451,21 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
// splitByCategory 后注入 5 段(电阻率/视电阻率/瞬变/三维体/切片);二维(足迹)经 dim2D 仍走 col2D。 // splitByCategory 后注入 5 段(电阻率/视电阻率/瞬变/三维体/切片);二维(足迹)经 dim2D 仍走 col2D。
auto lastSourceRows = std::make_shared<std::vector<geopro::data::DsRow>>(); auto lastSourceRows = std::make_shared<std::vector<geopro::data::DsRow>>();
auto refreshAnalysis = [drawer, scene3dRepo, lastSourceRows]() { auto refreshAnalysis = [drawer, scene3dRepo, lastSourceRows]() {
std::vector<geopro::data::DsRow> rows = *lastSourceRows; const auto vols = scene3dRepo->volumeRows();
for (auto& vr : scene3dRepo->volumeRows()) rows.push_back(std::move(vr)); // 客户端三维体 const auto slices = scene3dRepo->sliceRows();
for (auto& sr : scene3dRepo->sliceRows()) rows.push_back(std::move(sr)); // 已保存切片(挂父体下) const auto anomalies = scene3dRepo->anomalyRows();
drawer->analysisTab()->setBuckets(geopro::app::splitByCategory(rows)); // 电阻率/视/瞬变段=对象树反演 dsvoxel/slice 段先由 splitByCategory 按 ddCode 填体/切片。
drawer->col2D()->setDatasets(geopro::app::splitByDimension(rows).dim2D); std::vector<geopro::data::DsRow> 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<geopro::data::DsRow> 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(); const std::string savedSliceId = interactionMgr->selectedSliceDsId();
anomalyDrawTool->start( anomalyDrawTool->start(
o, normal, o, normal,
[&window, sceneView, scene3dRepo, renderWindowPtr, refreshAnomalies, volId, [&window, sceneView, scene3dRepo, renderWindowPtr, refreshAnomalies, refreshAnalysis,
savedSliceId, normal, o](const std::vector<ri::Vec3>& worldPts) { volId, savedSliceId, normal, o](const std::vector<ri::Vec3>& worldPts) {
// 草稿异常:先临时渲染(让用户在对话框前看到所画,且截图含异常)。 // 草稿异常:先临时渲染(让用户在对话框前看到所画,且截图含异常)。
geopro::core::Anomaly a; geopro::core::Anomaly a;
a.markType = geopro::core::AnomalyMarkType::Polygon; a.markType = geopro::core::AnomalyMarkType::Polygon;
@ -539,9 +550,11 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
a.remark = dlg.remark().toStdString(); a.remark = dlg.remark().toStdString();
scene3dRepo->saveAnomaly( scene3dRepo->saveAnomaly(
a, shot.toStdString(), a, shot.toStdString(),
[sceneView, renderWindowPtr, refreshAnomalies, draftId](std::string) { [sceneView, renderWindowPtr, refreshAnomalies, refreshAnalysis,
draftId](std::string) {
sceneView->removeAnomaly(draftId); // 撤草稿 sceneView->removeAnomaly(draftId); // 撤草稿
refreshAnomalies(); // 重渲染 + 刷新异常列表(含新异常) refreshAnomalies(); // 重渲染异常 actor
refreshAnalysis(); // 新异常进三维体段三级树(挂体/切片)
renderWindowPtr->Render(); renderWindowPtr->Render();
}, },
[&window](const std::string& m) { [&window](const std::string& m) {
@ -663,7 +676,9 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
checkedSliceIds->clear(); checkedSliceIds->clear();
for (const QString& id : ids) { for (const QString& id : ids) {
const std::string s = id.toStdString(); const std::string s = id.toStdString();
if (scene3dRepo->isSliceDataset(s)) if (scene3dRepo->isAnomalyDataset(s))
continue; // 异常不进渲染勾选(显隐另管,避免被当帘面源 loadSection 失败)
else if (scene3dRepo->isSliceDataset(s))
checkedSliceIds->insert(s); checkedSliceIds->insert(s);
else if (scene3dRepo->isVolumeDataset(s)) else if (scene3dRepo->isVolumeDataset(s))
analysis << id; analysis << id;

View File

@ -321,6 +321,10 @@ bool Api3dRepository::isSliceDataset(const std::string& dsId) const {
return slices_.find(dsId) != slices_.end(); 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 { bool Api3dRepository::sliceSpec(const std::string& dsId, SliceSpec& out) const {
auto it = slices_.find(dsId); auto it = slices_.find(dsId);
if (it == slices_.end()) return false; if (it == slices_.end()) return false;

View File

@ -67,6 +67,8 @@ public:
std::vector<DsRow> anomalyRows() const; std::vector<DsRow> anomalyRows() const;
// 该 dsId 是否为已保存切片3b分析栏勾选 dd_slice 走切片重渲染路径,不进控制器帘面/体素路径)。 // 该 dsId 是否为已保存切片3b分析栏勾选 dd_slice 走切片重渲染路径,不进控制器帘面/体素路径)。
bool isSliceDataset(const std::string& dsId) const; bool isSliceDataset(const std::string& dsId) const;
// 该 dsId 是否为异常dd_anomaly——勾选异常不进帘面/体素渲染勾选,显隐另管。
bool isAnomalyDataset(const std::string& dsId) const;
// 取回已保存切片位姿(还原渲染用);不存在返回 false。 // 取回已保存切片位姿(还原渲染用);不存在返回 false。
bool sliceSpec(const std::string& dsId, SliceSpec& out) const; bool sliceSpec(const std::string& dsId, SliceSpec& out) const;