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 オブジェクトを回転するには、それとも別の方法を使用する必要がありますか? 3D を回転させる C# の例はあまりないようです。どうもありがとう。

4

2 に答える 2

2

別の角度からオブジェクトを表示するだけの場合は、カメラ ビューを変更することもオプションの 1 つです。-angle の y 軸を中心に 3D オブジェクトを回転させる例を次に示します。

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();
}

元のビューは次のとおりです。 ここに画像の説明を入力

関数が 1 回実行された後のビューを次に示します。この場合、オブジェクトは y 軸を中心に -角度 (- は時計回りにカウントすることを意味します) 回転します。 ここに画像の説明を入力

于 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 に答える