Create a cube with the certain vertices

Hi Dears 3DSlicer developers

I want to create a cube with the certain vertices. For example, I have 8 points (vertices) with the following spatial coordinates in RAS.

Vertex R A S
superiorUpRight -731.523242270663 -74.7326192431123 -1012.2
superiorUpLeft -531.523242270663 -421.142780756888 -1012.2
superiorDownRight -818.125782649107 -124.732619243112 -1012.2
superiorDownLeft -618.125782649107 -471.142780756888 -1012.2
inferiorUpRight -731.523242270663 -74.7326192431123 -1412.2
inferiorUpLeft -531.523242270663 -421.142780756888 -1412.2
inferiorDownRight -818.125782649107 -124.732619243112 -1412.2
inferiorDownLeft -618.125782649107 -471.142780756888 -1412.2
Min -818.125782649107 -471.142780756888 -1412.2
Max -531.523242270663 -74.7326192431123 -1012.2

How can I define one cube with these points?
I do not find the fuction about setting up vertices in vtk.vtkCubeSource(), then I used the function of vtk.vtkCubeSource().SetBounds (double xMin, double xMax, double yMin, double yMax, double zMin, double zMax) as following lines:

EPID = vtk.vtkCubeSource()
EPID.SetBounds(-818.125782649107, -531.523242270663, -471.142780756888, -74.7326192431123, -1412.2, -1012.2)
modelsLogicEPID = slicer.modules.models.logic()
modelEPID = modelsLogicEPID.AddModel(EPID.GetOutput())
modelEPID.GetDisplayNode().SetSliceIntersectionVisibility(True)
modelEPID.GetDisplayNode().SetColor(0,1,0)
modelEPID.GetDisplayNode().SetSliceIntersectionThickness(3)
EPID.Update()

As seen in the following figure, the red cube is not correct. The vertices are specified with colored spheres.

Screenshot
Please guide me.
Shahrokh

vtkCubeSource creates cube with non-rotated axes. I would recommend to create a cube with the right size, centered around the origin. Then position and orient the node by specifying a parent transform.

Hi Dear Andras

Thanks a lot for your gudance. I create a cube model as mentioned you in the center of coordinate system with the following commands:

EPIDmodel = vtk.vtkCubeSource()
EPIDmodel.SetXLength(400)
EPIDmodel.SetYLength(50)
EPIDmodel.SetZLength(400)
modelsLogic = slicer.modules.models.logic()
modelEPID = modelsLogic.AddModel(EPIDmodel.GetOutput())
modelEPID.SetName(‘EPIDmodel’)
modelEPID.GetDisplayNode().SetSliceIntersectionVisibility(True)
modelEPID.GetDisplayNode().SetSliceIntersectionThickness(3)
modelEPID.GetDisplayNode().SetColor(0,1,0)
EPIDmodel.Update()

I really want to apologize. Unfortunately I did not find a simple example in moving a model (vtkMRMLModelNode) including as Translation + Rotation.
In the link you mentioned, Unfortunately, I did not see about the transformation of model node.
Using the file of procrustesAlignment.py in VTK, I enter the following commands:

transform1 = vtk.vtkTransform()
transform1.Translate(200, 100, 400)
transform1.RotateX(45)

transformer1 = vtk.vtkTransformPolyDataFilter()
transformer1.SetInputConnection(EPIDmodel.GetOutputPort())
transformer1.SetTransform(transform1)
EPIDmodel.Update()

I do not see any changes in the 3D window. Why?
I must mention that after creating the model, I can transfer it to any direction using Transforms module, but I would like to learn this from Python Interactor. Please guide me to do it from command line of Python.

Please guide me.
Shahrokh

No need to apply transform polydata filter manually. Instead, you can set a parent transform node for the model node and then call SetMatrixTransformToParent to set a transformation matrix.

Thank you very much for guidance. I do as you mentioned. Unfortunately, the cube model is not transfered with the following commands.

transform = slicer.vtkMRMLTransformNode()
transform.SetName(‘Transformation’)
slicer.mrmlScene.AddNode(transform)
matrix = vtk.vtkMatrix4x4()
matrix.SetElement(0, 0, 1)
matrix.SetElement(0, 1, 0)
matrix.SetElement(0, 2, 0)
matrix.SetElement(0, 3, 0)
matrix.SetElement(1, 0, 0)
matrix.SetElement(1, 1, 1)
matrix.SetElement(1, 2, 0)
matrix.SetElement(1, 3, 0)
matrix.SetElement(2, 0, 0)
matrix.SetElement(2, 1, 0)
matrix.SetElement(2, 2, -1212.200)
matrix.SetElement(2, 3, 0)
matrix.SetElement(3, 0, 0)
matrix.SetElement(3, 1, 0)
matrix.SetElement(3, 2, 0)
matrix.SetElement(3, 3, 0)
transform.SetMatrixTransformToParent(matrix)
modelNode = slicer.util.getNode(‘EPIDmodel’)

modelNode.SetAndObserveTransformNodeID(transform.GetName())
modelNode.SetAndObserveTransformNodeID(transform.GetID())

Where else are I wrong?
Please guide me.
Thanks a lot.

Shahrokh.

You must leave the row 3 of the matrix as is: (0,0,0,1). Calling matrix.SetElement(3, 3, 0) makes the transform invalid.

vtkMatrix4x4 is already initialized to identity, so there is no need to set the orientation (top-left 3x3 matrix) to identity again, just leave it as is.

Translation part of the transform is in column 3, not column 2, so this is incorrect: matrix.SetElement(2, 2, -1212.200) (it would ruin your model by scaling it by a factor of 1000 and turning it inside out). Use matrix.SetElement(..., 3, ...) instead.

Delete this line. SetAndObserveTransformNodeID method requires a node ID, not a node name and you set the node ID correctly in the line below.

Dear Andras

At now, I can define transform matrix, including as Translation and Rotation, with the following commands.


#Define transformation matrix (Translation and Rotation)
transform = slicer.vtkMRMLTransformNode()
transform.SetName(‘Transformation’)
#Add node Transormation to “Data” module
slicer.mrmlScene.AddNode(transform)
matrix = vtk.vtkMatrix4x4()
#Translation
#Shifting along the axis LR
matrix.SetElement(0, 3, translateLR)
#Shifting along the axis PA
matrix.SetElement(1, 3, translatePA)
#Shifting along the axis IS
matrix.SetElement(2, 3, translateIS)
#Rotation
#Rotation around IS (-60 degree)
matrix.SetElement(0, 0, math.cos(math.radians(300-360)))
matrix.SetElement(0, 1, -math.sin(math.radians(300-360)))
matrix.SetElement(1, 0, math.sin(math.radians(300-360)))
matrix.SetElement(1, 1, math.cos(math.radians(300-360)))

#Set IS parameter in “Transforms” module
transform.SetMatrixTransformToParent(matrix)

#Move “EPIDmodel” from “Transformable” to “Transormed” table in “Transforms” module and then apply to it.
modelNode = slicer.util.getNode(‘EPIDmodel’)
modelNode.SetAndObserveTransformNodeID(transform.GetID())

Thanks a lot for your guidance.
Shahrokh.

It is great to hear this. Note that you can compute transformation matrix by using translate and rotate methods of vtkTransform and retrieve the matrix by calling GetMatrix().