Python 更改不透明对象渲染顺序(Z顺序)VTK

Python 更改不透明对象渲染顺序(Z顺序)VTK,python,vtk,Python,Vtk,我正在寻找一种方法来控制多个对象(X射线/Image3D)共享同一Z平面时不透明对象的渲染顺序。我一直在考虑是否可能在定制的不透明通道中重新排列PropArray,但我很好奇其他人是否对此有更干净的程序。不幸的是,尽管使用了SetDisplayLocationToForeground/BackGround()方法,但使用Image2D并不是一个选项 与使用自定义不透明通道注入我们自己的渲染代码相比,他们的方法更干净吗?软件用户将能够通过bringToFront/Back控件更改X射线的渲染顺序

我正在寻找一种方法来控制多个对象(X射线/Image3D)共享同一Z平面时不透明对象的渲染顺序。我一直在考虑是否可能在定制的不透明通道中重新排列PropArray,但我很好奇其他人是否对此有更干净的程序。不幸的是,尽管使用了
SetDisplayLocationToForeground/BackGround()
方法,但使用Image2D并不是一个选项

与使用自定义不透明通道注入我们自己的渲染代码相比,他们的方法更干净吗?软件用户将能够通过bringToFront/Back控件更改X射线的渲染顺序

我已经能够在WebGL和Three.js中成功地测试这种行为,它公开了对渲染顺序的控制。 例:


注意:我正在使用Python(2.7.5)和Python Vtk:5.10.1,经过一个月的开发和故障排除,我已经解决了它

下面是我如何在VTK中解决渲染深度问题的

注意:这将只解决位于相同z深度的对象的渲染深度问题。前面或后面的对象将正常绘制,尽管具有渲染深度

逻辑

我们将在VTK渲染器的viewProps对象中编辑绘制顺序。渲染深度为null的所有VTK对象将首先绘制,然后按渲染深度的降序进行绘制

示例:
未排序的渲染深度
viewProps=[NULL,3,NULL,1,2,4,NULL]

已排序的渲染深度
viewProps=[NULL,NULL,NULL,4,3,2,1]

实施

使用Get/Set方法向vtkObject添加名为“renderDepth”的属性。在vtkObject创建上,set
renderDepth=NULL

在vtkrender中创建一个方法(我将调用我的renderedpthsort)

递归调用viewProp对象树,然后使用简单的气泡排序来交换具有渲染深度的任何项。
vtkrender::renderedpthsort(vtkPropCollection*propArray){
propArray->InitTraversal();
对于(int i=0;iGetNumberOfItems();i++){
vtkProp*prop=propArray->GetNextProp();
如果(道具->IsA(“VTK装配”)){
vtkAssembly*ptr=静态铸件(道具);
如果(ptr->GetParts()->GetNumberOfItems()>0)
这->RenderDepthSort(ptr->GetParts());
}
}
bool isUnsorted=true;
while(未排序){
isUnsorted=false;
propArray->InitTraversal();
对于(int i=0;iGetNumberOfItems()-1;i++){
vtkProp*propA=propArray->GetNextProp();
vtkProp*propB=static_cast(propArray->GetItemAsObject(i+1));

if(propA->getrenderepth()==NULL || propB->getrenderepth()==NULL){
如果(propA->getrenderepth()!=NULL&&propB->getrenderepth()==NULL){
propArray->ReplaceItem(i,propB);
propArray->ReplaceItem(i+1,propA);
isUnsorted=true;
}
}否则如果(propA->GetRenderDepth()GetRenderDepth()){
propArray->ReplaceItem(i,propB);
propArray->ReplaceItem(i+1,propA);
isUnsorted=true;
}
}//循环结束
}//结束时
}//EndRenderDepthSort方法

如果您像我们一样抽象出了vtk实现,但无法完全控制vtkViewProps,那么可以实现另一种方法来解决渲染深度问题,并将其传播到树上

void vtkrender::InitSolveRenderDepths(vtkPropCollection*propArray){
int-depth=NULL;
int numDepths=0;
propArray->InitTraversal();
对于(int i=0;iGetNumberOfItems();i++){
vtkProp*prop=propArray->GetNextProp();
如果(道具->IsA(“VTK装配”)){
此->SolveRenderDepth(道具);
int temp=prop->getrenderepth();
如果(温度!=NULL){
如果(温度

最后
再创建一个名为UpdateDrawOrder()的方法
void vtkrender::UpdateDrawOrder(){
vtkPropCollection*props=this->GetViewProps();
此->初始化SolveRenderDepth(道具);
此->渲染渲染渲染排序(道具);
}

将此设置为在vTkrender::Render()中或在vTkrender对象上调用UpdateDrawOrder

结束

  if(propA->GetRenderDepth() == NULL || propB->GetRenderDepth() == NULL){
    if(propA->GetRenderDepth() != NULL && propB->GetRenderDepth() == NULL){
      propArray->ReplaceItem(i, propB);
      propArray->ReplaceItem(i+1, propA);
      isUnsorted = true;
    }
  }else if(propA->GetRenderDepth() < propB->GetRenderDepth()){
    propArray->ReplaceItem(i, propB);
    propArray->ReplaceItem(i+1, propA);
    isUnsorted = true;
  }
} //end for loop