1

我正在尝试在旋转旋钮控件时使用 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。非常感谢。

4

2 回答 2

2

如果您只想从不同的角度查看对象,那么更改相机视图是选项之一。这是一个围绕 y 轴旋转 3D 对象以获得 -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();
}

这是原始视图: 在此处输入图像描述

这是函数执行一次后的视图,在这种情况下,对象围绕其 y 轴旋转 -angle(- 表示顺时针计数) 在此处输入图像描述

于 2013-12-10T20:00:25.770 回答
0

更简单、更直观的方法可能是使用 vtkTransform 类的 RotateX、RotateY 和 RotateZ 方法。

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);
}
于 2016-01-04T15:12:11.013 回答