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