Reputation: 2912
I am trying to rotation a 3D object with VTK as I rotate a knob control. Here is how I implemented it (in C#). However, when I rotate the control knobs, the 3D object in the screen was gone. I am not sure what happened, but since before vtkImageReslice was added, everything was fine, I suppose it was the culprit.
Some of the code I think relevant:
private vtkAxesActor axes;
private vtkCamera camera;
private List<vtkImageChangeInformation> changeFilters;
//private vtkTIFFReader reader;
private vtkImageAppendComponents componentAdaptor;
private List<vtkStringArray> fileNameArrays;
private List<vtkImageFlip> flippers;
private vtkRenderWindowInteractor iren;
// these two arrays specify the color range for the components specified by the array indexes
private int[] lowerThreshold = { 0, 0, 0, 0 };
private List<vtkTIFFReader> readers;
private vtkRenderer renderer;
private vtkRenderWindow renderWindow;
private RenderWindowControl renWindowControl;
private int[] upperThreshold = { MaxGrayScaleLevel, MaxGrayScaleLevel, MaxGrayScaleLevel, MaxGrayScaleLevel};
private vtkVolumeProperty volProperty;
private vtkVolume volume;
private vtkFixedPointVolumeRayCastMapper volumeMapper;
private vtkOrientationMarkerWidget widget;
public void setDefaultColorMapping()
{
if (volume == null)
{
MessageBox.Show("No volume exist");
return;
}
// vtkVolumeProperty volProperty = volume.GetProperty();
vtkColorTransferFunction colorFunctionA = vtkColorTransferFunction.New();
colorFunctionA.AddRGBSegment(0, 0, 0, 0, MaxGrayScaleLevel, 1, 0, 0);
volProperty.SetColor(0, colorFunctionA);
vtkColorTransferFunction colorFunctionB = vtkColorTransferFunction.New();
colorFunctionB.AddRGBSegment(0, 0, 0, 0, MaxGrayScaleLevel, 0, 1, 0);
volProperty.SetColor(1, colorFunctionB);
vtkColorTransferFunction colorFunctionC = vtkColorTransferFunction.New();
colorFunctionC.AddRGBSegment(0, 0, 0, 0, MaxGrayScaleLevel, 0, 0, 1);
volProperty.SetColor(2, colorFunctionC);
vtkColorTransferFunction colorFunctionD = vtkColorTransferFunction.New();
colorFunctionD.AddRGBSegment(0, 0, 0, 0, MaxGrayScaleLevel, 0.5, 0.5, 0);
volProperty.SetColor(3, colorFunctionD);
//volProperty.SetInterpolationTypeToNearest();
//renWindowControl.RenderWindow.Render();
}
public void setToDefault()
{
if (null == renWindowControl.RenderWindow)
return;
volumeMapper.SetBlendModeToMaximumIntensity();
volumeMapper.SetCropping(1);
volumeMapper.SetCroppingRegionFlagsToSubVolume();
//setDefaultColorMapping();
//setDefaultOpacityfunction();
widget.SetOutlineColor(0.93, 0.57, 0.13);
widget.SetOrientationMarker(axes);
widget.SetInteractor(renWindowControl.RenderWindow.GetInteractor());
widget.SetEnabled(1);
double[] rotX = { 1.0, 0.0, 0.0 };
double[] rotY = { 0.0, 1.0, 0.0 };
double[] rotZ = { 0.0, 0.0, 1.0 };
double[] center = { 0.0, 0.0, 0.0 };
_reslicer.SetResliceAxesDirectionCosines(DoubleArrayToIntPtr(rotX), DoubleArrayToIntPtr(rotY), DoubleArrayToIntPtr(rotZ));
_reslicer.SetResliceAxesOrigin(DoubleArrayToIntPtr(center));
_reslicer.SetInterpolationModeToLinear();
_reslicer.SetOutputDimensionality(3);
iren = renWindowControl.RenderWindow.GetInteractor();
}
private void SetupScene()
{
renderer = renWindowControl.RenderWindow.GetRenderers().GetFirstRenderer();
renderer.RemoveAllViewProps();
if (_isZStackDataExist == true)
{
// volumeMapper.SetInputConnection(componentAdaptor.GetOutputPort());
_reslicer.SetInputConnection(componentAdaptor.GetOutputPort());
volumeMapper.SetInputConnection(_reslicer.GetOutputPort());
//volumeMapper.Update();
volume.SetMapper(volumeMapper);
//volume.SetOrigin(DataExtentX / 2, DataExtentY / 2, DataExtentZ / 2);
renderer.AddVolume(volume);
renderer.ResetCamera();
camera = renderer.GetActiveCamera();
}
renderer.SetBackground(0, 0, 0);
//renderer.GetActiveCamera().Zoom(3);
//deleteAllVTKObjects();
}
//---------------------------------------------------------------------------------------------------------------
public void updateXRotation()
{
if (false == IsVolumeRendererReady)
return;
if (null != _reslicer)
{
double[] rotX = { 1.0, 0.0, 0.0};
double[] rotY = { 0.0, Math.Cos(DataXRotationDegrees), -Math.Sin(DataXRotationDegrees)};
double[] rotZ = { 0.0, Math.Sin(DataXRotationDegrees), Math.Cos(DataXRotationDegrees)};
double[] center = { 0.0, 0.0, 0.0 };
_reslicer.SetResliceAxesDirectionCosines(DoubleArrayToIntPtr(rotX), DoubleArrayToIntPtr(rotY), DoubleArrayToIntPtr(rotZ));
_reslicer.SetResliceAxesOrigin(DoubleArrayToIntPtr(center));
_reslicer.SetInterpolationModeToLinear();
_reslicer.Update();
}
}
static IntPtr DoubleArrayToIntPtr(double[] rotDoubleArr)
{
// Initialize unmanaged memory to hold the array.
int size = Marshal.SizeOf(rotDoubleArr[0]) * rotDoubleArr.Length;
IntPtr rotIntPtr = Marshal.AllocHGlobal(size);
try
{
// Copy the array to unmanaged memory.
Marshal.Copy(rotDoubleArr, 0, rotIntPtr, rotDoubleArr.Length);
}
catch
{
}
return rotIntPtr;
//finally
//{
// // Free the unmanaged memory.
// Marshal.FreeHGlobal(rotIntPtr);
//}
}
Any one has any idea how I can make this work? To rotate a 3D object with vtkImageReslice, or should I go for something else? It seems there are not many C# example how to rotate a 3D. Thanks a lot.
Upvotes: 1
Views: 1600
Reputation: 117
Easier and more intuitive maybe is to use the methods RotateX, RotateY and RotateZ of the class vtkTransform.
A code example in java:
private void rotate(double angle, int axis) {
vtkTransform t = new vtkTransform();
bw.GetTransform(t);
switch(axis) {
case X:
t.RotateX(-angle);
break;
case Y:
t.RotateY(-angle);
break;
case Z:
t.RotateZ(-angle);
break;
}
ren.GetActiveCamera().ApplyTransform(t);
}
Upvotes: 0
Reputation: 2912
If you only want to view object from different angle, then change the camera view is one of the options. Here is an example of rotating a 3D object around its y axis for -angle:
public void RotateToRight()
{
double cos = Math.Cos(angle);
double sin = Math.Sin(angle);
double[] rot = { cos, 0, -sin, 0,
0, 1, 0, 0,
sin, 0, cos, 0,
0, 0, 0, 1};
transform.SetMatrix(DoubleArrayToIntPtr(rot));
camera.ApplyTransform(transform);
renderer.ResetCamera();
renderer.GetActiveCamera();
ForceWindowToRender();
}
Here is the original view:
Here is the view after the function is executed once, in which case the object rotated around its y axis for -angle (- means count clockwise)
Upvotes: 2