506
|
1 /**
|
|
2 * Orthanc - A Lightweight, RESTful DICOM Store
|
|
3 * Copyright (C) 2012-2013 Medical Physics Department, CHU of Liege,
|
|
4 * Belgium
|
|
5 *
|
|
6 * Permission is hereby granted, free of charge, to any person
|
|
7 * obtaining a copy of this software and associated documentation
|
|
8 * files (the "Software"), to deal in the Software without
|
|
9 * restriction, including without limitation the rights to use, copy,
|
|
10 * modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
11 * of the Software, and to permit persons to whom the Software is
|
|
12 * furnished to do so, subject to the following conditions:
|
|
13 *
|
|
14 * The above copyright notice and this permission notice shall be
|
|
15 * included in all copies or substantial portions of the Software.
|
|
16 *
|
|
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
21 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
22 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
24 * SOFTWARE.
|
|
25 **/
|
|
26
|
|
27
|
|
28 #include <iostream>
|
|
29
|
|
30 #include <vtkRenderWindow.h>
|
|
31 #include <vtkImageData.h>
|
|
32 #include <vtkPiecewiseFunction.h>
|
|
33 #include <vtkFixedPointVolumeRayCastMapper.h>
|
|
34 #include <vtkColorTransferFunction.h>
|
|
35 #include <vtkVolumeProperty.h>
|
|
36 #include <vtkRenderWindowInteractor.h>
|
|
37 #include <vtkRenderer.h>
|
|
38 #include <vtkSmartPointer.h>
|
|
39 #include <vtkOpenGLRenderer.h>
|
|
40 #include <vtkInteractorStyleTrackballCamera.h>
|
|
41
|
510
|
42 #include "../../Build/OrthancClient.h"
|
506
|
43
|
|
44
|
|
45 void Display(OrthancClient::Series& series)
|
|
46 {
|
|
47 /**
|
|
48 * Load the 3D image from Orthanc into VTK.
|
|
49 **/
|
|
50
|
|
51 vtkSmartPointer<vtkImageData> image = vtkSmartPointer<vtkImageData>::New();
|
|
52 image->SetDimensions(series.GetWidth(), series.GetHeight(), series.GetInstanceCount());
|
|
53 image->SetScalarType(VTK_SHORT);
|
|
54 image->AllocateScalars();
|
|
55
|
|
56 if (series.GetWidth() != 0 &&
|
|
57 series.GetHeight() != 0 &&
|
|
58 series.GetInstanceCount() != 0)
|
|
59 {
|
|
60 series.Load3DImage(image->GetScalarPointer(0, 0, 0), Orthanc::PixelFormat_SignedGrayscale16,
|
|
61 2 * series.GetWidth(), 2 * series.GetHeight() * series.GetWidth());
|
|
62 }
|
|
63
|
|
64 image->SetSpacing(series.GetVoxelSizeX(),
|
|
65 series.GetVoxelSizeY(),
|
|
66 series.GetVoxelSizeZ());
|
|
67
|
|
68
|
|
69 /**
|
|
70 * The following code is based on the VTK sample for MIP
|
|
71 * http://www.vtk.org/Wiki/VTK/Examples/Cxx/VolumeRendering/MinIntensityRendering
|
|
72 **/
|
|
73
|
|
74 // Create a transfer function mapping scalar value to opacity
|
|
75 double range[2];
|
|
76 image->GetScalarRange(range);
|
|
77
|
|
78 vtkSmartPointer<vtkPiecewiseFunction> opacityTransfer =
|
|
79 vtkSmartPointer<vtkPiecewiseFunction>::New();
|
|
80 opacityTransfer->AddSegment(range[0], 0.0, range[1], 1.0);
|
|
81
|
|
82 vtkSmartPointer<vtkColorTransferFunction> colorTransfer =
|
|
83 vtkSmartPointer<vtkColorTransferFunction>::New();
|
|
84 colorTransfer->AddRGBPoint(0, 1.0, 1.0, 1.0);
|
|
85 colorTransfer->AddRGBPoint(range[1], 1.0, 1.0, 1.0);
|
|
86
|
|
87 vtkSmartPointer<vtkVolumeProperty> property =
|
|
88 vtkSmartPointer<vtkVolumeProperty>::New();
|
|
89 property->SetScalarOpacity(opacityTransfer);
|
|
90 property->SetColor(colorTransfer);
|
|
91 property->SetInterpolationTypeToLinear();
|
|
92
|
|
93 // Create a Maximum Intensity Projection rendering
|
|
94 vtkSmartPointer<vtkFixedPointVolumeRayCastMapper> mapper =
|
|
95 vtkSmartPointer<vtkFixedPointVolumeRayCastMapper>::New();
|
|
96 mapper->SetBlendModeToMaximumIntensity();
|
|
97 mapper->SetInput(image);
|
|
98
|
|
99 vtkSmartPointer<vtkVolume> volume = vtkSmartPointer<vtkVolume>::New();
|
|
100 volume->SetMapper(mapper);
|
|
101 volume->SetProperty(property);
|
|
102
|
|
103 vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkOpenGLRenderer>::New();
|
|
104 renderer->AddViewProp(volume);
|
|
105 renderer->SetBackground(0.1, 0.2, 0.3); // Background color dark blue
|
|
106
|
|
107 vtkSmartPointer<vtkInteractorStyleTrackballCamera> style =
|
|
108 vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
|
|
109
|
|
110 vtkSmartPointer<vtkRenderWindow> window = vtkSmartPointer<vtkRenderWindow>::New();
|
|
111 window->AddRenderer(renderer);
|
|
112
|
|
113 vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
|
|
114 interactor->SetRenderWindow(window);
|
|
115 interactor->SetInteractorStyle(style);
|
|
116 interactor->Start();
|
|
117 }
|
|
118
|
|
119
|
|
120 int main()
|
|
121 {
|
|
122 try
|
|
123 {
|
|
124 OrthancClient::Initialize("libOrthancCppClient.so");
|
|
125
|
|
126 // Use the commented code below if you know the identifier of a
|
|
127 // series that corresponds to a 3D image.
|
|
128
|
|
129 /*
|
|
130 {
|
|
131 OrthancClient::OrthancConnection orthanc("http://localhost:8042");
|
|
132 OrthancClient::Series series(orthanc, "c1c4cb95-05e3bd11-8da9f5bb-87278f71-0b2b43f5");
|
|
133 Display(series);
|
|
134 return 0;
|
|
135 }
|
|
136 */
|
|
137
|
|
138
|
|
139 // Try and find a 3D image inside the local store
|
|
140 OrthancClient::OrthancConnection orthanc("http://localhost:8042");
|
|
141
|
|
142 for (unsigned int i = 0; i < orthanc.GetPatientCount(); i++)
|
|
143 {
|
|
144 OrthancClient::Patient patient = orthanc.GetPatient(i);
|
|
145 std::cout << "Patient: " << patient.GetId() << std::endl;
|
|
146
|
|
147 for (unsigned int j = 0; j < patient.GetStudyCount(); j++)
|
|
148 {
|
|
149 OrthancClient::Study study = patient.GetStudy(j);
|
|
150 std::cout << " Study: " << study.GetId() << std::endl;
|
|
151
|
|
152 for (unsigned int k = 0; k < study.GetSeriesCount(); k++)
|
|
153 {
|
|
154 OrthancClient::Series series = study.GetSeries(k);
|
|
155 std::cout << " Series: " << series.GetId() << std::endl;
|
|
156
|
|
157 if (series.Is3DImage())
|
|
158 {
|
|
159 Display(series);
|
|
160 return 0;
|
|
161 }
|
|
162 else
|
|
163 {
|
|
164 std::cout << " => Not a 3D image..." << std::endl;
|
|
165 }
|
|
166 }
|
|
167 }
|
|
168 }
|
|
169
|
|
170 std::cout << "Unable to find a 3D image in the local Orthanc store" << std::endl;
|
|
171
|
|
172 return 0;
|
|
173 }
|
|
174 catch (OrthancClient::OrthancClientException e)
|
|
175 {
|
|
176 std::cerr << "EXCEPTION: [" << e.What() << "]" << std::endl;
|
|
177 return -1;
|
|
178 }
|
|
179 }
|