跳转至

Representation3D无法移动手柄

在升级到 VTK9 后,之前在 VTK8 中实现的一些自定义交互可能失效。例如,使用隐藏的手柄进行拖动和交互时,发现手柄无法响应鼠标事件。

1 原来的功能

在屏幕中放置一个手柄,设置其尺寸为 0 或隐藏。当鼠标移入隐藏手柄时,会改变其形状,选中并拖动后可触发其他操作,实时响应用户交互。

2 升级9后遇到的问题

  • 隐藏手柄不再有鼠标移入效果。
  • 手柄无法被拖动。

3 分析问题

经过调试发现,vtkPointHandleRepresentation3D 在 VTK9 中做了源码修改:

  • 设置隐藏或尺寸为 0 后,ComputeInteractionState 永远返回 vtkHandleRepresentation::Outside。
  • 新版本确保光标必须位于显示空间中的边界球体内才会触发交互状态,这是为了修复视角相关的 BUG。

相关 MR

4 解决办法

最简单的办法是继承 vtkPointHandleRepresentation3D 并重写 ComputeInteractionState,恢复到 VTK8 的行为:

class CBvtkPointHandleRepresentation3D : public vtkPointHandleRepresentation3D {
public:
    static CBvtkPointHandleRepresentation3D *New();
    vtkTypeMacro(CBvtkPointHandleRepresentation3D, vtkPointHandleRepresentation3D);

    CBvtkPointHandleRepresentation3D() = default;
    ~CBvtkPointHandleRepresentation3D() = default;

    int ComputeInteractionState(int X, int Y, int modify) override;
};

int CBvtkPointHandleRepresentation3D::ComputeInteractionState(int X, int Y, int ) {
    this->VisibilityOn();
    vtkAssemblyPath *path = this->GetAssemblyPath(X, Y, 0., this->CursorPicker);
    if (path != nullptr) {
        this->InteractionState = vtkHandleRepresentation::Nearby;
    } else {
        this->InteractionState = vtkHandleRepresentation::Outside;
        if (this->ActiveRepresentation) {
            this->VisibilityOff();
        }
    }
    return this->InteractionState;
}

使用说明

  • 保持手柄尺寸为 0 或隐藏仍然可用。
  • 鼠标移入隐藏手柄时,可以触发 Nearby 状态,允许拖动和交互。
  • 恢复了 VTK8 的交互逻辑,同时兼容 VTK9 的渲染管线。