ActiViz实战:基于ActiViz 9.3 实现体绘制裁剪

135 阅读1分钟

@TOC


关键代码

1、实现体绘制

FolderBrowserDialog folderDialog = new FolderBrowserDialog();
folderDialog.SelectedPath = "E:\\S100";
string foldPath = string.Empty;
if(folderDialog.ShowDialog() == DialogResult.OK)
{
    foldPath = folderDialog.SelectedPath;
    vtkDICOMImageReader dicomReader = vtkDICOMImageReader.New();
    dicomReader.SetDirectoryName(foldPath);
    dicomReader.SetDataByteOrderToLittleEndian();
    dicomReader.Update();
    imagedata = dicomReader.GetOutput();
    volumeMapper = vtkGPUVolumeRayCastMapper.New();
    volumeMapper.SetBlendModeToComposite();
    volumeMapper.SetInputConnection(dicomReader.GetOutputPort());
    volumeMapper.SetSampleDistance(volumeMapper.GetSampleDistance() / 2f);
    vtkVolumeProperty volumeProperty = vtkVolumeProperty.New();
    volumeProperty.SetInterpolationTypeToLinear();
    volumeProperty.ShadeOn();
    volumeProperty.SetAmbient(0.4);
    volumeProperty.SetDiffuse(0.6);
    volumeProperty.SetSpecular(0.2);
    vtkPiecewiseFunction compositeOpacity = vtkPiecewiseFunction.New();
    compositeOpacity.AddPoint(-3024.0,0.0,0.5,0.0);
    compositeOpacity.AddPoint(-16.0,0.0,0.49,0.61);
    compositeOpacity.AddPoint(641.0,0.72,0.5,0.0);
    compositeOpacity.AddPoint(3071.0,0.0,0.5,0.0);
    volumeProperty.SetScalarOpacity(compositeOpacity);
    vtkPiecewiseFunction volumeGradientOpacity = vtkPiecewiseFunction.New();
    volumeGradientOpacity.AddPoint(0.0,2.0);
    volumeGradientOpacity.AddPoint(500.0,2.0);
    volumeGradientOpacity.AddPoint(600.0,0.73);
    volumeGradientOpacity.AddPoint(900.0,0.9);
    volumeGradientOpacity.AddPoint(1300.0,0.1);
    volumeProperty.SetGradientOpacity(volumeGradientOpacity);
    vtkColorTransferFunction color = vtkColorTransferFunction.New();
    color.AddRGBPoint(-3024.0,0.0,0.0,0.0,0.5,0.0);
    color.AddRGBPoint(-200.0,0.73,0.25,0.3,0.49,0.61);
    color.AddRGBPoint(641.0,0.9,0.82,0.56,0.5,0.0);
    color.AddRGBPoint(3071.0,1.0,1.0,1.0,0.5,0.0);
    volumeProperty.SetColor(color);
    volume = vtkVolume.New();
    volume.SetMapper(volumeMapper);
    volume.SetProperty(volumeProperty);
    renderer.AddVolume(volume);
    renderer.ResetCamera();
    renderWindowControl1.RenderWindow.Render();
}

2、使用vtkInteractorStyle添加鼠标交互

 style = vtkInteractorStyle.New();
 IsStartClip = true;
 LeftHandler = new vtkObject.vtkObjectEventHandler(iren_LeftButtonPressEvt);
 style.LeftButtonPressEvt += LeftHandler;
 LeftReHandler = new vtkObject.vtkObjectEventHandler(iren_LeftButtonUpEvt);
 style.LeftButtonReleaseEvt += LeftReHandler;
 MouseMove = new vtkObject.vtkObjectEventHandler(iren_MouseMoveEvt);
 style.MouseMoveEvt += MouseMove;     
 renderInteractor.SetInteractorStyle(style);      
 renderWindowControl1.RenderWindow.Render();

3、添加鼠标事件

 private void iren_LeftButtonPressEvt(vtkObject sender,vtkObjectEventArgs e)
 {
     IsMousePressed = true;
     pointPicker = vtkWorldPointPicker.New();
     renderInteractor.SetPicker(pointPicker);
 }

按下鼠标开始拾取点,接下来移动鼠标画线:

if (IsStartClip && IsMousePressed)
{
    int[] evtPosition = renderInteractor.GetEventPosition();
    pointPicker.Pick(evtPosition[0], evtPosition[1], 0.0, renderer);
    double[] pickCoords = pointPicker.GetPickPosition();
    position.Add(pickCoords);
    point.InsertNextPoint(evtPosition[0], evtPosition[1], 0.0);
    vtkPolyLine polyLine = vtkPolyLine.New();
    
    polyLine.GetPointIds().SetNumberOfIds(position.Count);
    for (int i = 0; i < position.Count; i++)
    {
        polyLine.GetPointIds().SetId(i, i);
    }
    
    vtkCellArray cells = vtkCellArray.New();
    cells.InsertNextCell(polyLine);
    vtkPolyData polyData = vtkPolyData.New();
    polyData.SetPoints(point);
    polyData.SetLines(cells);              
    vtkPolyDataMapper2D mapper2d = vtkPolyDataMapper2D.New();
    mapper2d.SetInputData(polyData);
    
    if (polyactor != null)
    {
        renderer.RemoveActor2D(polyactor);
        polyactor.Dispose();
        polyactor = null;
    }

    polyactor = vtkActor2D.New();
    polyactor.GetProperty().SetColor(1, 0, 0);
    polyactor.SetMapper(mapper2d);
    renderer.AddActor2D(polyactor);            
    renderWindowControl1.RenderWindow.Render();
}     

4、执行裁剪

vtkLinearExtrusionFilter extruder = vtkLinearExtrusionFilter.New();
extruder.SetInputData(polyData);
extruder.SetScaleFactor(1.0);
extruder.SetExtrusionTypeToNormalExtrusion();
extruder.SetVector(normal2[0] - normal[0], normal2[1] - normal[1], normal2[2] - normal[2]);
extruder.Update();
vtkLinearExtrusionFilter extruder2 = vtkLinearExtrusionFilter.New();
extruder2.SetInputData(polyData);
extruder2.SetScaleFactor(1.0);
extruder2.SetExtrusionTypeToNormalExtrusion();
extruder2.SetVector(normal[0] - normal2[0], normal[1] - normal2[1], normal[2] - normal2[2]);
extruder2.Update();
vtkAppendPolyData append = vtkAppendPolyData.New();
append.AddInputData(extruder.GetOutput());
append.AddInputData(extruder2.GetOutput());
append.Update();
vtkPolyDataToImageStencil pol2stenc = vtkPolyDataToImageStencil.New();
pol2stenc.SetInputData(append.GetOutput());
pol2stenc.SetOutputOrigin(0.0, 0.0, 0.0);
pol2stenc.SetOutputSpacing(imagedata.GetSpacing()[0], imagedata.GetSpacing()[1], imagedata.GetSpacing()[2]);
pol2stenc.SetOutputWholeExtent(imagedata.GetExtent()[0], imagedata.GetExtent()[1], imagedata.GetExtent()[2], imagedata.GetExtent()[3], imagedata.GetExtent()[4], imagedata.GetExtent()[5]);
pol2stenc.Update();
vtkImageStencil imgstenc = vtkImageStencil.New();
imgstenc.SetInputData(imagedata);
imgstenc.SetStencilData(pol2stenc.GetOutput());
imgstenc.ReverseStencilOn();
imgstenc.SetBackgroundValue(imagedata.GetScalarRange()[0]);
imgstenc.Update();
imagedata = imgstenc.GetOutput();
volumeMapper.SetInputData(imgstenc.GetOutput());
volume.Update();
position.Clear();
point.Reset();
renderer.RemoveActor2D(polyactor);
renderWindowControl1.RenderWindow.Render();

源码地址

踩坑创作不易,白嫖党勿扰:源码