添加多个卷时VTK中的Zorder错误(vtk.vtkrender公司().添加卷)

2024-09-30 03:22:14 发布

您现在位置:Python中文网/ 问答频道 /正文

一些背景:我需要可视化2000图像每个2560x1440和8位颜色。图像以适当的3d打印格式存储。我有代码提取每个图像作为一个numpy数组。问题是读取numpy中的所有图像会导致内存问题。所以我想一个接一个地读,然后转换成vtk.vtk卷()并将其添加到vtk.vtkrender公司().AddVolume()。你知道吗

我的问题是:我做了一个测试,添加了多个卷,每个卷由一个3d立方体组成。旋转时,一个立方体始终渲染在另一个立方体的后面,如果它在前面也是如此。你知道吗

知道我做错了什么导致了这个奇怪的z顺序吗?你知道吗

图像:

image

在下图中,黄色立方体旋转到前面,但是它显示为在绿色立方体后面。你知道吗

image

我的测试代码:

# An example from scipy cookbook demonstrating the use of numpy arrays in vtk

import numpy as np
import vtk
from tempfile import mkdtemp
import os.path as path
import psutil

installpath=''
def init():
    import sys,os
    global installpath
    if getattr(sys, 'frozen', False):# frozen
        installpath = os.path.dirname(sys.executable)
    else: # unfrozen
        installpath = os.path.dirname(os.path.realpath(__file__))
    print ("Installed at: ",installpath)

def addCube(offset,colorIndex):

    dw,dh,dd=offset
    w,h,d=75,75,75
    data_matrix=np.zeros((d,h,w),dtype='uint8')
    data_matrix[0+dd:35+dd,0+dh:35+dh,0+dw:35+dw] = colorIndex

    # For VTK to be able to use the data, it must be stored as a VTK-image.
    #  This can be done by the vtkImageImport-class which
    # imports raw data and stores it.
    dataImporter = vtk.vtkImageImport()
    # The previously created array is converted to a string of chars and imported.

    data_string = data_matrix.tostring()
    del (data_matrix)
    dataImporter.CopyImportVoidPointer(data_string, len(data_string))
    del (data_string)

    # The type of the newly imported data is set to unsigned char (uint8)
    dataImporter.SetDataScalarTypeToUnsignedChar()
    # Because the data that is imported only contains an intensity value
    #  (it isnt RGB-coded or someting similar), the importer must be told this is the case.
    dataImporter.SetNumberOfScalarComponents(1)
    # The following two functions describe how the data is stored and the dimensions of the array it is stored in.
    #  For this simple case, all axes are of length 75 and begins with the first element.
    #  For other data, this is probably not the case.
    # I have to admit however, that I honestly dont know the difference between SetDataExtent()
    #  and SetWholeExtent() although VTK complains if not both are used.
    dataImporter.SetDataExtent(0, w-1, 0, h-1, 0, d-1)
    dataImporter.SetWholeExtent(0, w-1, 0, h-1, 0, d-1)

    # The following class is used to store transparency-values for later retrival.
    #  In our case, we want the value 0 to be
    # completely opaque whereas the three different cubes are given different transparency-values to show how it works.
    alphaChannelFunc = vtk.vtkPiecewiseFunction()
    alphaChannelFunc.AddPoint(0, 0.0)
    alphaChannelFunc.AddPoint(colorIndex, 1.0)#0.05)

    # This class stores color data and can create color tables from a few color points.
    #  For this demo, we want the three cubes to be of the colors red green and blue.
    colorFunc = vtk.vtkColorTransferFunction()
    #colorFunc.AddRGBPoint(0, 0.0, 0.0, 0.0)
    colorFunc.AddRGBPoint(1, 1.0, 0.0, 0.0)
    colorFunc.AddRGBPoint(2, 0.0, 1.0, 0.0)
    colorFunc.AddRGBPoint(3, 0.0, 0.0, 1.0)
    colorFunc.AddRGBPoint(4, 1.0, 1.0, 0.0)
    colorFunc.AddRGBPoint(5, 1.0, 0.0, 1.0)
    colorFunc.AddRGBPoint(6, 0.0, 1.0, 1.0)
    colorFunc.AddRGBPoint(7, 1.0, 1.0, 1.0)

    # The previous two classes stored properties.
    #  Because we want to apply these properties to the volume we want to render,
    # we have to store them in a class that stores volume properties.
    volumeProperty = vtk.vtkVolumeProperty()
    volumeProperty.SetColor(colorFunc)
    volumeProperty.SetScalarOpacity(alphaChannelFunc)
    volumeProperty.ShadeOn()

    volumeMapper = vtk.vtkFixedPointVolumeRayCastMapper()
    volumeMapper.SetInputConnection(dataImporter.GetOutputPort())

    # The class vtkVolume is used to pair the previously declared volume as well as the properties
    #  to be used when rendering that volume.
    volume = vtk.vtkVolume()
    volume.SetMapper(volumeMapper)
    volume.SetProperty(volumeProperty)

    return volume

def main():
    global installpath

    colors = vtk.vtkNamedColors()

    # We begin by creating the data we want to render.
    volume1=addCube((0,0,0),4)
    volume2=addCube((25,25,25),2)

    # With almost everything else ready, its time to initialize the renderer and window, as well as
    #  creating a method for exiting the application
    renderer = vtk.vtkRenderer()
    renderWin = vtk.vtkRenderWindow()
    renderWin.AddRenderer(renderer)
    renderInteractor = vtk.vtkRenderWindowInteractor()
    renderInteractor.SetRenderWindow(renderWin)

    # We add the volume to the renderer ...
    renderer.AddVolume(volume1)
    renderer.AddVolume(volume2)
    renderer.SetBackground(colors.GetColor3d("MistyRose"))

    # ... and set window size.
    renderWin.SetSize(400, 400)

    # A simple function to be called when the user decides to quit the application.
    def exitCheck(obj, event):
        if obj.GetEventPending() != 0:
            obj.SetAbortRender(1)

    # Tell the application to use the function as an exit check.
    renderWin.AddObserver("AbortCheckEvent", exitCheck)

    renderInteractor.Initialize()
    # Because nothing will be rendered without any input, we order the first render manually
    #  before control is handed over to the main-loop.
    renderWin.Render()
    renderInteractor.Start()


if __name__ == '__main__':
    init()
    main()


Tags: andofthetodataisasbe

热门问题