- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
本质上,我想使用 VTK 引擎来渲染具有预先计算的投影和模型 View 变换矩阵的场景,统称为“复合投影变换矩阵”。
出于此目的,我们有 vtkCamera.SetUseExplicitProjectionTransformMatrix
但我无法使用它使我的 View Prop 或 Actor 可见。我猜想这与 vtkRenderer 如何通过使用其边界框预选择可见 Actor 有关,但在这种情况下,近和远的剪切范围被烘焙到单个矩阵中,因此渲染器甚至无法猜测。在下面的示例代码中,我还补偿了相机的初始模型 View 变换矩阵(从单位矩阵稍微转换而来),以便相机能够按照我想要的方式计算其复合投影。
import vtk
class Renderer:
def __init__( self ):
self.layer0 = vtk.vtkRenderer()
self.layer0.SetLayer(0)
self.renWin = vtk.vtkRenderWindow()
self.renWin.AddRenderer(self.layer0)
self.iren = vtk.vtkRenderWindowInteractor()
self.iren.SetRenderWindow(self.renWin)
self.iren.Initialize()
def Render( self ):
self.iren.Render()
def AddActor( self, actor ):
self.layer0.AddActor( actor )
def Start(self):
self.iren.Start()
def CreateActor( polydata ):
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputData( polydata )
mapper.SetScalarVisibility( 0 )
actor = vtk.vtkActor()
actor.SetMapper( mapper )
return actor
def OBJReader( name ):
reader = vtk.vtkOBJReader()
reader.SetFileName( name )
reader.Update()
return reader.GetOutput()
# Suzanne by Blender.org
suzanne = OBJReader( 'D:/data/suzanne.obj' )
size = (900,600)
# Create a VTK renderwindow
r = Renderer()
r.renWin.SetSize(size[0],size[1])
r.AddActor( CreateActor(suzanne) )
# Use vtkRenderWindowInteractor to select the camera view
# Then exit the window by pressing 'x'
r.Start()
# Store the current composite projection transform matrix
# i.e., the product of the projection and the modelview matrix
# into X
c = r.layer0.GetActiveCamera()
n, f = c.GetClippingRange()
aspect = size[0]/size[1]
X = c.GetCompositeProjectionTransformMatrix( aspect, n, f )
# Create another VTK renderwindow
r2 = Renderer()
r2.renWin.SetSize(size[0],size[1])
r2.AddActor( CreateActor(suzanne) )
# but this time, construct the camera by using a precomputed
# projection matrix
c2 = vtk.vtkCamera()
if 1:
# assert that the modelview matrix will be identity matrix
M = vtk.vtkMatrix4x4()
M.DeepCopy( c2.GetModelViewTransformMatrix() )
print( M ) # its not!
M.Invert() # so invert
# and concatenate
Y = vtk.vtkMatrix4x4()
# Y*M = X*inv(M)*M = X
vtk.vtkMatrix4x4.Multiply4x4( X, M, Y )
c2.SetUseExplicitProjectionTransformMatrix(1)
c2.SetExplicitProjectionTransformMatrix( Y )
# these should be now the same (in case of explicit, aspect, n and f are ignored)
print( c2.GetCompositeProjectionTransformMatrix( 1, 0, 0 ) )
print( X )
else:
#this works clearly
c2.DeepCopy( c )
r2.layer0.SetActiveCamera( c2 )
r2.Render()
r2.Start()
最佳答案
经过测试,我得出的结论是应该使用vtkExternalOpenGLCamera
This class extends vtkOpenGLCamera by introducing API wherein the camera matrices can be set explicitly by the application.
复合投影变换矩阵X
虽然不容易使用,但它的裁剪范围必须改变。
# copy X into numpy matrix for comfort
P = np.zeros( (4,4),dtype=np.double)
for y in range(4):
for x in range(4):
P[y][x]=X.GetElement(y,x)
# P maps valid z-values to [n,f] so change that by
# z <- 2.0 * ( z - n )/(f-n) -1.0
# to fit values into the default clipping range [-1,1]
A = np.eye(4,dtype=np.double)
A[2][3]=-n
B = np.eye(4, dtype=np.double)
B[2][2]=2.0/(f-n)
C = np.eye(4, dtype=np.double)
C[2][3]=-1.0
P = np.matmul(C,np.matmul(B,np.matmul(A,P)) )
# then use vtkExternalOpenGLCamera
c2 = vtk.vtkExternalOpenGLCamera()
c2.SetViewTransformMatrix( np.reshape( np.eye(4,dtype=np.double),[-1,1]) )
c2.SetProjectionTransformMatrix( np.reshape( np.transpose(P),[-1,1]) )
r2.layer0.SetActiveCamera( c2 )
r2.Render()
值得注意的是,下面的矩阵 P
也适用于上面提到的模型 View 矩阵变换 hack:
c2 = vtk.vtkCamera()
# P is now back to vtk.vtkMatrix4x4 type
# assert that the modelview matrix will be identity matrix
Mx = vtk.vtkMatrix4x4()
Mx.DeepCopy( c2.GetModelViewTransformMatrix() )
print( Mx ) # its not!
Mx.Invert() # so invert
# Y*M = X*inv(M)*M = X
vtk.vtkMatrix4x4.Multiply4x4( P, Mx, P )
c2.SetUseExplicitProjectionTransformMatrix(1)
c2.SetExplicitProjectionTransformMatrix( P )
但是结果并不漂亮......
虽然 VTK 的默认相机光源模型不能与烘焙的复合变换一起使用,但如果将投影和模型 View 矩阵分别放入 vtkExternalOpenGLCamera
中,它就可以工作。
关于python - 使用 vtkCamera 显式投影变换矩阵和 prop3D 可见性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58877739/
我正在使用 vtkCamera 并且会尝试移动它并让它看向某个点。例如,如果我想将相机放在位置 (x,y,z) 并让它看 (0,0,0) 例如使用 gluLookAt在 openGL 中,我们会将眼睛
我想将图像的大小增加到 50%、100%、200%、400% 和 800%。为了缩放 DICOM 图像。为此,我将在查看器中使用 QComboBox,并将其索引设置为 (50,100,200,400,
我在原点有一个物体,我将相机移动到 (0,650,650) 并将焦点设置到原点,即: vtkSmartPointer cam = vtkSmartPointer::New(); renderer->S
本质上,我想使用 VTK 引擎来渲染具有预先计算的投影和模型 View 变换矩阵的场景,统称为“复合投影变换矩阵”。 出于此目的,我们有 vtkCamera.SetUseExplicitProject
我是一名优秀的程序员,十分优秀!