我是VTK的新手。我想知道VTK抽象选择器如何对不同不透明度值的多个actor表现出来。让我们考虑两个演员,一个 在另一个里面当我将外表面的不透明度设置为0.3时,同时 保持内部的不透明度1.0。由于外部的半透明,我可以看到两个演员的重叠区域中的内部演员。当我在该区域进行拾取时,生成的坐标来自内表面本身,当我选择除重叠区域以外的某些点时,我得到外表面坐标。如何根据不透明度值执行拾取操作?这样我想一次挑选一个演员。有人请帮忙..
答案 0 :(得分:0)
vtkAbstractPicker就像一个定义拾取界面的抽象类,但仅此而已。在选择实际拣货员时,您基本上可以选择使用基于光线投射的拣选或使用图形硬件进行“颜色拣选”(请参阅实施vtk类的链接文档)。
现在对于实际问题,如果我理解你正确写的是什么,你就会遇到一个相当简单的排序问题。不透明度可以看作是一种优先级 - 即使它们在不透明度较低的其他人中,也应该挑选具有较高不透明度的角色,对吗?然后,您需要做的就是获取鼠标光标下方的所有演员,然后选择具有最高不透明度的演员,或者选择最接近它们具有相同不透明度的情况。
我认为实现这个的最简单方法是使用vtkPropPicker(vtkProp
是actor的父类,所以这是挑选actor的好选择器)。它是使用颜色选择算法的“硬件”选择器之一。基本算法是每个可选对象使用不同的颜色渲染到隐藏缓冲区(纹理)中。这种颜色(毕竟是32位数字,与其他颜色一样)用作该对象的ID:当用户点击屏幕时,您从点击的坐标上的拾取纹理中读取像素的颜色,然后您只需查看ID等于该颜色的对象的地图,即可获得该对象。显然,它不能使用任何透明度 - 单个颜色是对象的ID,混合它们会使它们无法识别。
但是,vtkPropPicker
提供了一种方法:
// Perform a pick from the user-provided list of vtkProps
// and not from the list of vtkProps that the render maintains.
// If something is picked, a 1 is returned, otherwise 0 is returned.
// Use the GetViewProp() method to get the instance of vtkProp that was picked.
int PickProp (double selectionX, double selectionY,
vtkRenderer *renderer, vtkPropCollection *pickfrom);
你可以做的就是首先调用PickProp(mouseClickX, mouseClickY, renderer of your render window, pickfrom)
只提供pickfrom
集合中最高优先级的角色,即不透明度最高的角色。在下面,这将使用颜色编码算法渲染所有提供的actor,并告诉您哪个actor位于指定坐标下方。如果它选择一些东西(返回值为1,你在它上面调用GetViewProp并且它给你指向你所选择的演员的指针),你保留它,如果没有(返回值为0),你再次调用它,这次提供具有较低不透明度的演员等等,直到你选择一些东西或者你测试所有演员。
你也可以对像vtkPicker
这样的光线投射拾取器做同样的事情 - 它会在你的鼠标下面投射一条光线,并为你提供场景中所有东西的所有交叉点。但是vtkPicker的API针对找到最近的交叉点进行了优化,获取所有这些并然后对它们进行排序可能需要一些工作,最后,我相信使用vtkPropPicker
的解决方案无论如何都会更快。
如果此解决方案很好,您可能需要查看使用相同算法的vtkHardwareSelector,但与vtkPropPicker
不同,您可以多次访问基础拾取纹理,这样您就可以每个拣货查询都需要重新渲染。根据渲染管道的设置方式,这可能是一种更有效的解决方案(=如果您在不更新场景的情况下进行大量拾取)。