4.3. How to apply an affine transform to a StructuredGrid

In this example we will apply an affine transform to different StructuredGrid. StructuredGrid is an abstract class who has 3 concrete subclasses: Channel, ROI and MultiROI.

Let’s start by creating an instance of each of the StructuredGrid subclasses:

from ORSModel import Channel
from ORSModel import ROI, MultiROI, orsVect, orsColor
channel = Channel()
channel.setTitle('demo channel')
#set it sizes, since we use the default voxel size, the channel is for now 100 meter cube
channel.setXYZTSize(100,100,100,1)
channel.setXSpacing(0.01)
channel.setYSpacing(0.01)
channel.setZSpacing(0.01)
#now the channel is 1 meter cube
#initilize it for float32 data
channel.initializeDataForFLOAT()
channelBox = channel.getBox()
channelBox.grow(orsVect(-channelBox.getDirection0Size()*0.5, -channelBox.getDirection1Size()*0.5, -channelBox.getDirection2Size()*0.5))
channel.paintBox(channelBox,  1, 0)
channel.setDataDirty()
#publish it so that it is visible in the Object properties list
channel.publish()

roiA = ROI()
roiA.setTitle('roiA')
roiA.copyShapeFromStructuredGrid(channel)
roiA.setInitialColor(orsColor(1,0,0,1))
roiA.paintSphere(roiA.getBox().getOrigin(), roiA.getBox().getDirection0Size(), 1, 0)
roiA.publish()

multiROIa= MultiROI()
multiROIa.setTitle('multiROIa')
multiROIa.copyShapeFromStructuredGrid(roiA)
multiROIBox = multiROIa.getBox()
multiROIa.setLabelCount(3)
multiROIBox.grow(orsVect(-multiROIBox.getDirection0Size()*0.5, -multiROIBox.getDirection1Size()*0.5, -multiROIBox.getDirection2Size()*0.5))
multiROIBox.setOrigin(multiROIa.getOrigin())
multiROIa.paintBox(multiROIBox,  1, 0)

multiROIBox.setOrigin(multiROIa.getBox().getCenter())
multiROIa.paintBox(multiROIBox,  2, 0)

multiROIBox.setOrigin((multiROIa.getBox().getOriginOpposite() - multiROIa.getBox().getOrigin())*0.25)
multiROIa.paintBox(multiROIBox,  3, 0)
multiROIa.publish()

Every StructuredGrid instance possesses a member variable of class Box. Box define a rectangular prism in space. To apply an affine transform, you transform the Box of the StructuredGrid. To define the affine transform, you use a Matrix4x4 object.

Let’s define an affine transform:

translation = Matrix4x4()
translation.setTranslation(channel.getBox().getDirectionSizeVector()*0.25)
rotationAxis = orsVect(0, 1, 0)
rotation = Matrix4x4()
rotation.setAsRotation(rotationAxis, 3.1416/8)
scale = Matrix4x4()
scale.setScale(orsVect(0.5,1,2))
#now let's concatenate these transformation, in an arbritrary order
fullTransform = scale*rotation*translation

Let’s apply the affine transformation:

channelT = channel.copy()
channelT.setTitle('transformed channel')
channelT.publish()
box = channelT.getBox()
box.transform(fullTransform)
channelT.setBox(box)
channelT.setGeometryDirty()

#here we transform the original ROI and MultiROI
roiA.setBox(box)
multiROIa.setBox(box)
roiA.setGeometryDirty()
multiROIa.setGeometryDirty()