comparison Framework/Layers/FrameRenderer.cpp @ 97:d18dcc963930 wasm

separation of the renderers vs. viewport slice
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 30 May 2017 14:09:11 +0200
parents 7b14c12a3be5
children 53025eecbc95
comparison
equal deleted inserted replaced
96:f8bce1bebe01 97:d18dcc963930
26 26
27 #include "../../Resources/Orthanc/Core/OrthancException.h" 27 #include "../../Resources/Orthanc/Core/OrthancException.h"
28 28
29 namespace OrthancStone 29 namespace OrthancStone
30 { 30 {
31 static bool ComputePixelTransform(cairo_matrix_t& target,
32 const SliceGeometry& viewportSlice,
33 const SliceGeometry& frameSlice,
34 double pixelSpacingX,
35 double pixelSpacingY)
36 {
37 bool isOpposite;
38 if (!GeometryToolbox::IsParallelOrOpposite(isOpposite,
39 viewportSlice.GetNormal(),
40 frameSlice.GetNormal()))
41 {
42 return false;
43 }
44 else
45 {
46 double x0, y0, x1, y1, x2, y2;
47 viewportSlice.ProjectPoint(x0, y0, frameSlice.GetOrigin()
48 - 0.5 * pixelSpacingX * frameSlice.GetAxisX()
49 - 0.5 * pixelSpacingY * frameSlice.GetAxisY());
50 viewportSlice.ProjectPoint(x1, y1, frameSlice.GetOrigin()
51 + 0.5 * pixelSpacingX * frameSlice.GetAxisX()
52 - 0.5 * pixelSpacingY * frameSlice.GetAxisY());
53 viewportSlice.ProjectPoint(x2, y2, frameSlice.GetOrigin()
54 - 0.5 * pixelSpacingX * frameSlice.GetAxisX()
55 + 0.5 * pixelSpacingY * frameSlice.GetAxisY());
56
57 /**
58 * Now we solve the system of linear equations Ax + b = x', given:
59 * A [0 ; 0] + b = [x0 ; y0]
60 * A [1 ; 0] + b = [x1 ; y1]
61 * A [0 ; 1] + b = [x2 ; y2]
62 * <=>
63 * b = [x0 ; y0]
64 * A [1 ; 0] = [x1 ; y1] - b = [x1 - x0 ; y1 - y0]
65 * A [0 ; 1] = [x2 ; y2] - b = [x2 - x0 ; y2 - y0]
66 * <=>
67 * b = [x0 ; y0]
68 * [a11 ; a21] = [x1 - x0 ; y1 - y0]
69 * [a12 ; a22] = [x2 - x0 ; y2 - y0]
70 **/
71
72 cairo_matrix_init(&target, x1 - x0, y1 - y0, x2 - x0, y2 - y0, x0, y0);
73
74 return true;
75 }
76 }
77
78
79 FrameRenderer::FrameRenderer(const SliceGeometry& frameSlice, 31 FrameRenderer::FrameRenderer(const SliceGeometry& frameSlice,
80 double pixelSpacingX, 32 double pixelSpacingX,
81 double pixelSpacingY, 33 double pixelSpacingY,
82 bool isFullQuality) : 34 bool isFullQuality) :
83 frameSlice_(frameSlice), 35 frameSlice_(frameSlice),
86 isFullQuality_(isFullQuality) 38 isFullQuality_(isFullQuality)
87 { 39 {
88 } 40 }
89 41
90 42
91 bool FrameRenderer::ComputeFrameExtent(double& x1,
92 double& y1,
93 double& x2,
94 double& y2,
95 const SliceGeometry& viewportSlice,
96 const SliceGeometry& frameSlice,
97 unsigned int frameWidth,
98 unsigned int frameHeight,
99 double pixelSpacingX,
100 double pixelSpacingY)
101 {
102 bool isOpposite;
103 if (!GeometryToolbox::IsParallelOrOpposite(isOpposite, viewportSlice.GetNormal(), frameSlice.GetNormal()))
104 {
105 return false;
106 }
107 else
108 {
109 cairo_matrix_t transform;
110 if (!ComputePixelTransform(transform, viewportSlice, frameSlice, pixelSpacingX, pixelSpacingY))
111 {
112 return true;
113 }
114
115 x1 = 0;
116 y1 = 0;
117 cairo_matrix_transform_point(&transform, &x1, &y1);
118
119 x2 = frameWidth;
120 y2 = frameHeight;
121 cairo_matrix_transform_point(&transform, &x2, &y2);
122
123 if (x1 > x2)
124 {
125 std::swap(x1, x2);
126 }
127
128 if (y1 > y2)
129 {
130 std::swap(y1, y2);
131 }
132
133 return true;
134 }
135 }
136
137
138 bool FrameRenderer::RenderLayer(CairoContext& context, 43 bool FrameRenderer::RenderLayer(CairoContext& context,
139 const ViewportGeometry& view, 44 const ViewportGeometry& view)
140 const SliceGeometry& viewportSlice)
141 { 45 {
142 if (!style_.visible_) 46 if (!style_.visible_)
143 { 47 {
144 return true; 48 return true;
145 } 49 }
146 50
147 if (display_.get() == NULL) 51 if (display_.get() == NULL)
148 { 52 {
149 if (!ComputePixelTransform(transform_, viewportSlice, frameSlice_,
150 pixelSpacingX_, pixelSpacingY_))
151 {
152 return true;
153 }
154
155 display_.reset(GenerateDisplay(style_)); 53 display_.reset(GenerateDisplay(style_));
156 } 54 }
157 55
158 assert(display_.get() != NULL); 56 assert(display_.get() != NULL);
159 57
160 cairo_t *cr = context.GetObject(); 58 cairo_t *cr = context.GetObject();
161 59
162 cairo_save(cr); 60 cairo_save(cr);
163 61
164 cairo_transform(cr, &transform_); 62 cairo_matrix_t transform;
63 cairo_matrix_init_identity(&transform);
64 cairo_matrix_scale(&transform, pixelSpacingX_, pixelSpacingY_);
65 cairo_matrix_translate(&transform, -0.5, -0.5);
66 cairo_transform(cr, &transform);
67
165 //cairo_set_operator(cr, CAIRO_OPERATOR_OVER); 68 //cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
166 cairo_set_source_surface(cr, display_->GetObject(), 0, 0); 69 cairo_set_source_surface(cr, display_->GetObject(), 0, 0);
167 70
168 switch (style_.interpolation_) 71 switch (style_.interpolation_)
169 { 72 {
213 display_.reset(NULL); 116 display_.reset(NULL);
214 } 117 }
215 118
216 119
217 ILayerRenderer* FrameRenderer::CreateRenderer(Orthanc::ImageAccessor* frame, 120 ILayerRenderer* FrameRenderer::CreateRenderer(Orthanc::ImageAccessor* frame,
218 const SliceGeometry& frameSlice,
219 const OrthancPlugins::IDicomDataset& dicom,
220 double pixelSpacingX,
221 double pixelSpacingY,
222 bool isFullQuality)
223 {
224 std::auto_ptr<Orthanc::ImageAccessor> protect(frame);
225
226 if (frame->GetFormat() == Orthanc::PixelFormat_RGB24)
227 {
228 return new ColorFrameRenderer(protect.release(), frameSlice,
229 pixelSpacingX, pixelSpacingY, isFullQuality);
230 }
231 else
232 {
233 DicomFrameConverter converter;
234 converter.ReadParameters(dicom);
235 return new GrayscaleFrameRenderer(protect.release(), converter, frameSlice,
236 pixelSpacingX, pixelSpacingY, isFullQuality);
237 }
238 }
239
240
241 ILayerRenderer* FrameRenderer::CreateRenderer(Orthanc::ImageAccessor* frame,
242 const Slice& frameSlice, 121 const Slice& frameSlice,
243 bool isFullQuality) 122 bool isFullQuality)
244 { 123 {
245 std::auto_ptr<Orthanc::ImageAccessor> protect(frame); 124 std::auto_ptr<Orthanc::ImageAccessor> protect(frame);
246 125
247 if (frame->GetFormat() == Orthanc::PixelFormat_RGB24) 126 if (frame->GetFormat() == Orthanc::PixelFormat_RGB24)
248 { 127 {
249 return new ColorFrameRenderer(protect.release(), frameSlice.GetGeometry(), 128 return new ColorFrameRenderer(protect.release(),
250 frameSlice.GetPixelSpacingX(), frameSlice.GetPixelSpacingY(), isFullQuality); 129 frameSlice.GetGeometry(),
130 frameSlice.GetPixelSpacingX(),
131 frameSlice.GetPixelSpacingY(), isFullQuality);
251 } 132 }
252 else 133 else
253 { 134 {
254 return new GrayscaleFrameRenderer(protect.release(), frameSlice.GetConverter(), frameSlice.GetGeometry(), 135 return new GrayscaleFrameRenderer(protect.release(),
255 frameSlice.GetPixelSpacingX(), frameSlice.GetPixelSpacingY(), isFullQuality); 136 frameSlice.GetConverter(),
137 frameSlice.GetGeometry(),
138 frameSlice.GetPixelSpacingX(),
139 frameSlice.GetPixelSpacingY(), isFullQuality);
256 } 140 }
257 } 141 }
258 } 142 }