使用VTK交互器拾取网格点坐标后鼠标控制失效,该如何解决?
问题原因
你完全重写了vtk交互器样式的鼠标事件方法,没有执行父类原生的交互逻辑,导致原有的旋转、平移、缩放功能被覆盖;另外你手动调用StartPan()也会干扰原生交互状态的判断。
解决方案
- 所有需要保留原有交互能力的重写事件,在自定义逻辑执行完成后,必须调用父类的同名方法
- 移除不必要的
StartPan()调用,该方法是原生交互用来触发平移动作的内部方法,不要在点选逻辑里主动调用 - 若你需要的是控制整个场景视角(而非单独拖动某个actor),建议将父类从
vtkInteractorStyleTrackballActor改为vtkInteractorStyleTrackballCamera,更符合常规的3D场景浏览交互习惯 - vtkPointPicker无需每次点击都重新创建,可以放到类的初始化逻辑中优化性能
修改后的核心代码示例
void OnLeftButtonDown() override { this->PointPicker = vtkSmartPointer<vtkPointPicker>::New(); // 获取点击位置 int x = this->Interactor->GetEventPosition()[0]; int y = this->Interactor->GetEventPosition()[1]; this->FindPokedRenderer(x, y); this->PointPicker->Pick(this->Interactor->GetEventPosition()[0], this->Interactor->GetEventPosition()[1], 0, // 该参数固定为0 this->Interactor->GetRenderWindow() ->GetRenderers() ->GetFirstRenderer()); if (this->PointPicker->GetPointId() >= 0) { // 移除多余的StartPan()调用 this->SelectedPoint = this->PointPicker->GetPointId(); double p[3]; this->eleNodeIdsPtr->GetPoint(this->SelectedPoint, p); std::cout << "p: " << p[0] << " " << p[1] << " " << p[2] << std::endl; } // 关键:调用父类同名方法,执行原有交互逻辑 Superclass::OnLeftButtonDown(); }
可选优化
如果想要避免拖拽操作时误触发点选,可以将点选逻辑放到OnLeftButtonUp方法中,只有鼠标抬起时才判断是否选中了节点,逻辑和上面一致,最后调用Superclass::OnLeftButtonUp()即可。
内容的提问来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

