1 #include "vtkRenderer.h" 2 #include "vtkRenderWindow.h" 3 #include "vtkRenderWindowInteractor.h" 4 #include "vtkDICOMImageReader.h" 5 #include "vtkPolyDataMapper.h" 6 #include "vtkActor.h" 7 #include "vtkOutlineFilter.h" 8 #include "vtkCamera.h" 9 #include "vtkProperty.h" 10 #include "vtkPolyDataNormals.h" 11 #include "vtkContourFilter.h" 12 13 void main () 14 { 15 16 // Create the renderer, the render window, and the interactor. The renderer 17 // draws into the render window, the interactor enables mouse- and 18 // keyboard-based interaction with the data within the render window. 19 // 20 vtkRenderer *aRenderer = vtkRenderer::New(); 21 vtkRenderWindow *renWin = vtkRenderWindow::New(); 22 renWin->AddRenderer(aRenderer); 23 vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New(); 24 iren->SetRenderWindow(renWin); 25 26 // The following reader is used to read a series of 2D slices (images) 27 // that compose the volume. The slice dimensions are set, and the 28 // pixel spacing. The data Endianness must also be specified. The reader 29 // usese the FilePrefix in combination with the slice number to construct 30 // filenames using the format FilePrefix.%d. (In this case the FilePrefix 31 // is the root name of the file: quarter.) 32 vtkDICOMImageReader *v16 = vtkDICOMImageReader::New(); 33 // v16->SetDataDimensions (64,64); 34 // v16->SetImageRange (1,93); 35 v16->SetDataByteOrderToLittleEndian(); 36 v16->SetDirectoryName("E://03280848"); 37 v16->SetDataSpacing (3.2, 3.2, 1.5); 38 39 // An isosurface, or contour value of 500 is known to correspond to the 40 // skin of the patient. Once generated, a vtkPolyDataNormals filter is 41 // is used to create normals for smooth surface shading during rendering. 42 vtkContourFilter *skinExtractor = vtkContourFilter::New(); 43 skinExtractor->SetInputConnection(v16->GetOutputPort()); 44 skinExtractor->SetValue(0, 500); 45 vtkPolyDataNormals *skinNormals = vtkPolyDataNormals::New(); 46 skinNormals->SetInputConnection(skinExtractor->GetOutputPort()); 47 skinNormals->SetFeatureAngle(60.0); 48 vtkPolyDataMapper *skinMapper = vtkPolyDataMapper::New(); 49 skinMapper->SetInputConnection(skinNormals->GetOutputPort()); 50 skinMapper->ScalarVisibilityOff(); 51 vtkActor *skin = vtkActor::New(); 52 skin->SetMapper(skinMapper); 53 54 // An outline provides context around the data. 55 // 56 vtkOutlineFilter *outlineData = vtkOutlineFilter::New(); 57 outlineData->SetInputConnection(v16->GetOutputPort()); 58 vtkPolyDataMapper *mapOutline = vtkPolyDataMapper::New(); 59 mapOutline->SetInputConnection(outlineData->GetOutputPort()); 60 vtkActor *outline = vtkActor::New(); 61 outline->SetMapper(mapOutline); 62 outline->GetProperty()->SetColor(0,0,0); 63 64 // It is convenient to create an initial view of the data. The FocalPoint 65 // and Position form a vector direction. Later on (ResetCamera() method) 66 // this vector is used to position the camera to look at the data in 67 // this direction. 68 vtkCamera *aCamera = vtkCamera::New(); 69 aCamera->SetViewUp (0, 0, -1); 70 aCamera->SetPosition (0, 1, 0); 71 aCamera->SetFocalPoint (0, 0, 0); 72 aCamera->ComputeViewPlaneNormal(); 73 74 // Actors are added to the renderer. An initial camera view is created. 75 // The Dolly() method moves the camera towards the FocalPoint, 76 // thereby enlarging the image. 77 aRenderer->AddActor(outline); 78 aRenderer->AddActor(skin); 79 aRenderer->SetActiveCamera(aCamera); 80 aRenderer->ResetCamera (); 81 aCamera->Dolly(1.5); 82 83 // Set a background color for the renderer and set the size of the 84 // render window (expressed in pixels). 85 aRenderer->SetBackground(1,1,1); 86 renWin->SetSize(640, 480); 87 88 // Note that when camera movement occurs (as it does in the Dolly() 89 // method), the clipping planes often need adjusting. Clipping planes 90 // consist of two planes: near and far along the view direction. The 91 // near plane clips out objects in front of the plane; the far plane 92 // clips out objects behind the plane. This way only what is drawn 93 // between the planes is actually rendered. 94 aRenderer->ResetCameraClippingRange (); 95 96 // Initialize the event loop and then start it. 97 iren->Initialize(); 98 iren->Start(); 99 100 // It is important to delete all objects created previously to prevent 101 // memory leaks. In this case, since the program is on its way to 102 // exiting, it is not so important. But in applications it is 103 // essential. 104 v16->Delete(); 105 skinExtractor->Delete(); 106 skinNormals->Delete(); 107 skinMapper->Delete(); 108 skin->Delete(); 109 outlineData->Delete(); 110 mapOutline->Delete(); 111 outline->Delete(); 112 aCamera->Delete(); 113 iren->Delete(); 114 renWin->Delete(); 115 aRenderer->Delete(); 116 117 }