feat/vtk-3d-view #7
|
|
@ -608,10 +608,12 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
if (!ok) return;
|
if (!ok) return;
|
||||||
scene3dRepo->createSlice(
|
scene3dRepo->createSlice(
|
||||||
spec, name.isEmpty() ? std::string("切片") : name.toStdString(),
|
spec, name.isEmpty() ? std::string("切片") : name.toStdString(),
|
||||||
[interactionMgr, refreshAnalysis](std::string newId) {
|
[interactionMgr, refreshAnalysis, drawer](std::string newId) {
|
||||||
interactionMgr->tagSelectedSlice(newId); // 链接当前切片 → 新数据集(不重绘)
|
interactionMgr->tagSelectedSlice(newId); // 链接当前切片 → 新数据集(不重绘)
|
||||||
refreshAnalysis(); // 新行进列表(勾选集不变→不发多余信号)
|
refreshAnalysis(); // 新行进列表
|
||||||
// TODO:新分段 tab 暂无 setItemChecked,新切片列表默认未勾(已渲染但列表不打勾,待补)。
|
// 新切片自动勾选 → 列表打勾 + 保持渲染(refreshAnalysis 已重建列表,故在其后勾选)。
|
||||||
|
if (auto* sec = drawer->analysisTab()->section("voxel"))
|
||||||
|
sec->setChecked(QString::fromStdString(newId), true);
|
||||||
},
|
},
|
||||||
[&window](const std::string& m) {
|
[&window](const std::string& m) {
|
||||||
QMessageBox::warning(&window, QStringLiteral("保存切片"),
|
QMessageBox::warning(&window, QStringLiteral("保存切片"),
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,10 @@ CategoryAnalysisTab::CategoryAnalysisTab(geopro::data::DatasetFieldDictionary* d
|
||||||
void CategoryAnalysisTab::setBuckets(const CategoryBuckets& b) {
|
void CategoryAnalysisTab::setBuckets(const CategoryBuckets& b) {
|
||||||
const auto& cfg = categoryConfigs();
|
const auto& cfg = categoryConfigs();
|
||||||
for (std::size_t i = 0; i < cfg.size() && i < b.segments.size(); ++i) {
|
for (std::size_t i = 0; i < cfg.size() && i < b.segments.size(); ++i) {
|
||||||
|
// voxel(三维体) 段数据来自 mock voxelTree(体/切片/异常),由调用方单独 section("voxel")->setDatasets
|
||||||
|
// 注入;splitByCategory 对它永远是空桶,若在此用空桶覆盖会先清掉其勾选(随后重填但勾选已丢) →
|
||||||
|
// 表现为「创建切片/异常后体/切片选择被清空」(用户 issue 1)。故跳过 voxel,勿覆盖。
|
||||||
|
if (cfg[i].id == "voxel") continue;
|
||||||
if (auto* sec = section(cfg[i].id)) sec->setDatasets(b.segments[i]);
|
if (auto* sec = section(cfg[i].id)) sec->setDatasets(b.segments[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,15 @@ void CategorySection::setDatasets(const std::vector<DsRow>& rows) {
|
||||||
rebuildList();
|
rebuildList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CategorySection::setChecked(const QString& dsId, bool on) {
|
||||||
|
for (QTreeWidgetItemIterator it(list_); *it; ++it)
|
||||||
|
if ((*it)->data(0, kDsIdRole).toString() == dsId &&
|
||||||
|
((*it)->flags() & Qt::ItemIsUserCheckable)) {
|
||||||
|
(*it)->setCheckState(0, on ? Qt::Checked : Qt::Unchecked); // 触发 itemChanged→emitChecked→渲染
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CategorySection::refreshArrayCombo() {
|
void CategorySection::refreshArrayCombo() {
|
||||||
if (!spec_.hasArrayTypeFilter || !arrayCombo_) return;
|
if (!spec_.hasArrayTypeFilter || !arrayCombo_) return;
|
||||||
const QString prev = arrayCombo_->currentData().toString();
|
const QString prev = arrayCombo_->currentData().toString();
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ public:
|
||||||
// 对象树同源的扁平 GS/TM 节点(段体容器分层用;Task 12 接入真实结构,当前仅存储)。
|
// 对象树同源的扁平 GS/TM 节点(段体容器分层用;Task 12 接入真实结构,当前仅存储)。
|
||||||
void setStructure(const std::vector<geopro::data::StructNode>& nodes);
|
void setStructure(const std::vector<geopro::data::StructNode>& nodes);
|
||||||
void setDatasets(const std::vector<geopro::data::DsRow>& rows);
|
void setDatasets(const std::vector<geopro::data::DsRow>& rows);
|
||||||
|
void setChecked(const QString& dsId, bool on); // 按 dsId 勾选/取消(新建切片自动勾选等场景)
|
||||||
const CategorySpec& spec() const { return spec_; }
|
const CategorySpec& spec() const { return spec_; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
|
||||||
|
|
@ -416,6 +416,9 @@ void Api3dRepository::saveAnomaly(const geopro::core::Anomaly& a,
|
||||||
if (id.empty()) id = "anomaly-" + std::to_string(++anomalyCounter_); // 新建 → 生成 id
|
if (id.empty()) id = "anomaly-" + std::to_string(++anomalyCounter_); // 新建 → 生成 id
|
||||||
geopro::core::Anomaly stored = a;
|
geopro::core::Anomaly stored = a;
|
||||||
stored.id = id;
|
stored.id = id;
|
||||||
|
if (stored.createTime.empty()) // mock:构建时未设创建时刻 → 补当前时间(副标题/列表显示)
|
||||||
|
stored.createTime =
|
||||||
|
QDateTime::currentDateTime().toString(QStringLiteral("yyyy-MM-dd HH:mm")).toStdString();
|
||||||
anomalies_[id] = StoredAnomaly{std::move(stored), screenshotPngPath};
|
anomalies_[id] = StoredAnomaly{std::move(stored), screenshotPngPath};
|
||||||
onOk(id);
|
onOk(id);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue