我正在尝试在旋转旋钮控件时使用 VTK 旋转 3D 对象。这是我实现它的方式(在 C# 中)。但是,当我旋转控制旋钮时,屏幕中的 3D 对象消失了。我不确定发生了什么,但是由于在添加 vtkImageReslice 之前,一切都很好,我想这是罪魁祸首。
我认为相关的一些代码:
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);
//}
}
任何人都知道我怎样才能使这项工作?用 vtkImageReslice 旋转 3D 对象,还是我应该去别的地方?似乎没有多少 C# 示例如何旋转 3D。非常感谢。