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

时间:2014-03-19 21:56:52

标签: python vtk

当多个对象(Xrays / Image3D)共享同一个Z平面时,我正在寻找一种控制不透明对象渲染顺序的方法。我一直在考虑在自定义的OpaquePass中重新排序PropArray,但我很好奇其他人是否有更清洁的程序。不幸的是,尽管使用SetDisplayLocationToForeground/BackGround()方法,但使用Image2D并不是一种选择。

除了使用自定义OpaquePass注入我们自己的渲染代码之外,他们更清洁吗?该软件的用户将能够通过bringToFront / Back控件更改xrays的渲染顺序。

我已经能够在WebGL和Three.js中成功测试这种行为,它暴露了对渲染顺序的控制。 例如:enter image description here

注意:我使用Python(2.7.5)和Python Vtk:5.10.1

1 个答案:

答案 0 :(得分:1)

经过一个月的开发和故障排除后,我已经解决了!

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

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

逻辑

我们将在vtkRenderer的viewProps对象中编辑绘制顺序。渲染深度为null的所有vtkObject将首先绘制,然后是渲染深度的降序。

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

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

实施

向vtkObject添加一个名为" renderDepth"使用Get / Set方法。在vtkObject创建集renderDepth = NULL;

在vtkRenderer中创建一个方法(我将调用我的RenderDepthSort)。

递归调用viewProp对象树,然后简单冒泡排序,以交换任何具有渲染深度的项目。 vtkRenderer::RenderDepthSort(vtkPropCollection * propArray){ propArray->InitTraversal(); for(int i=0; i < propArray->GetNumberOfItems(); i++){ vtkProp * prop = propArray->GetNextProp(); if(prop->IsA("vtkAssembly")){ vtkAssembly * ptr = static_cast<vtkAssembly *>(prop); if(ptr->GetParts()->GetNumberOfItems() > 0) this->RenderDepthSort(ptr->GetParts()); } } bool isUnsorted = true; while(isUnsorted){ isUnsorted = false; propArray->InitTraversal(); for(int i=0; i < propArray->GetNumberOfItems()-1; i++){ vtkProp * propA = propArray->GetNextProp(); vtkProp * propB = static_cast<vtkProp *>(propArray->GetItemAsObject(i+1));

  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

} // end while }//end renderDepthSort Method

如果你像我们一样抽象出你的vtk实现,并且你没有完全控制你的vtkViewProps,那么就实现另一种方法来解决渲染深度并将它们传播到树上。

void vtkRenderer::InitSolveRenderDepths(vtkPropCollection * propArray){ int depth = NULL; int numDepths = 0; propArray->InitTraversal(); for(int i=0; i < propArray->GetNumberOfItems(); i++){ vtkProp * prop = propArray->GetNextProp(); if(prop->IsA("vtkAssembly")){ this->SolveRenderDepths(prop); int temp = prop->GetRenderDepth(); if(temp != NULL){ if(temp < depth || depth == NULL){ depth = temp; } numDepths++; } } } }

<强>最后
再创建一个名为UpdateDrawOrder()的方法 void vtkRenderer::UpdateDrawOrder(){ vtkPropCollection * props = this->GetViewProps(); this->InitSolveRenderDepths(props); this->RenderDepthSort(props); }

将其设置为在vtkRenderer :: Render()或vtkRenderer对象中调用UpdateDrawOrder。

Z End!