feat/vtk-3d-view #7

Merged
gaozheng merged 301 commits from feat/vtk-3d-view into main 2026-06-27 18:43:52 +08:00
1 changed files with 10 additions and 3 deletions
Showing only changes of commit 07309da1b3 - Show all commits

View File

@ -2230,6 +2230,8 @@ struct ViewState {
// 整卷粗层 image 缓存(按 level 缓存,避免每帧重组整卷)。 // 整卷粗层 image 缓存(按 level 缓存,避免每帧重组整卷)。
int cachedWholeLevel = -1; int cachedWholeLevel = -1;
vtkSmartPointer<vtkImageData> cachedWholeImg; vtkSmartPointer<vtkImageData> cachedWholeImg;
// 回调防重入:回调内部会 Render(),若 Render 又触发观察者回调会无限递归。
bool inCb = false;
}; };
// 某 level 整卷各轴是否都 ≤16384可成单张 3D 纹理 → 整卷单 mapper 渲染)。 // 某 level 整卷各轴是否都 ≤16384可成单张 3D 纹理 → 整卷单 mapper 渲染)。
@ -2296,6 +2298,10 @@ std::size_t viewRefreshBlocks(ViewState* st) {
// interactor 回调:每次交互(旋转/缩放)结束后重选 LOD + 刷新 fps 文本。 // interactor 回调:每次交互(旋转/缩放)结束后重选 LOD + 刷新 fps 文本。
void viewOnInteract(vtkObject*, unsigned long, void* clientData, void*) { void viewOnInteract(vtkObject*, unsigned long, void* clientData, void*) {
auto* st = static_cast<ViewState*>(clientData); auto* st = static_cast<ViewState*>(clientData);
// 防重入:本回调内部会 st->rw->Render(),若该 Render 再触发观察者进本回调
// 将无限递归。已在回调中则直接返回(双保险)。
if (st->inCb) return;
st->inCb = true;
const double frameMs = st->frameTimer.elapsedMs(); const double frameMs = st->frameTimer.elapsedMs();
const std::size_t blocks = viewRefreshBlocks(st); const std::size_t blocks = viewRefreshBlocks(st);
const int lvl = st->src->lastLevel(); const int lvl = st->src->lastLevel();
@ -2309,6 +2315,7 @@ void viewOnInteract(vtkObject*, unsigned long, void* clientData, void*) {
st->lastLevel = lvl; st->lastLevel = lvl;
st->rw->Render(); st->rw->Render();
st->frameTimer.reset(); st->frameTimer.reset();
st->inCb = false;
} }
int cmdView(int argc, char** argv) { int cmdView(int argc, char** argv) {
@ -2459,10 +2466,10 @@ int cmdView(int argc, char** argv) {
vtkNew<vtkCallbackCommand> cb; vtkNew<vtkCallbackCommand> cb;
cb->SetCallback(viewOnInteract); cb->SetCallback(viewOnInteract);
cb->SetClientData(&st); cb->SetClientData(&st);
// EndInteraction旋转/缩放松手后重选 LOD保证 LOD 真切换 + fps 刷新)。 // EndInteraction旋转/缩放松手后重选 LOD + 刷 fps仅松手触发一次不自激
// 注意:绝不可在 rw 的 EndEvent 上注册——回调内部 Render() 会再触发 EndEvent
// 形成无限递归重渲窗口卡死、fps≈0。fps 文本在松手时刷新即可。
iren->AddObserver(vtkCommand::EndInteractionEvent, cb); iren->AddObserver(vtkCommand::EndInteractionEvent, cb);
// 每帧 Render 后也更新一次 fps 文本(连续拖动时实时反馈)。
rw->AddObserver(vtkCommand::EndEvent, cb);
std::cout << "[view] 打开真窗口。左键旋转 / 滚轮缩放(切 LOD) / q 退出。\n"; std::cout << "[view] 打开真窗口。左键旋转 / 滚轮缩放(切 LOD) / q 退出。\n";
st.frameTimer.reset(); st.frameTimer.reset();