comparison Applications/Samples/SingleFrameEditorApplication.h @ 342:4297d6c5eef9 am-2

moving bitmap
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 22 Oct 2018 09:44:52 +0200
parents 7bebbfa56bde
children 712acc87fa2e
comparison
equal deleted inserted replaced
341:7bebbfa56bde 342:4297d6c5eef9
62 unsigned int cropX_; 62 unsigned int cropX_;
63 unsigned int cropY_; 63 unsigned int cropY_;
64 unsigned int cropWidth_; 64 unsigned int cropWidth_;
65 unsigned int cropHeight_; 65 unsigned int cropHeight_;
66 Matrix transform_; 66 Matrix transform_;
67 67 double pixelSpacingX_;
68 double pixelSpacingY_;
69 double panX_;
70 double panY_;
71
72
73 void UpdateTransform()
74 {
75 transform_ = LinearAlgebra::IdentityMatrix(3);
76
77 transform_(0, 0) = pixelSpacingX_;
78 transform_(1, 1) = pixelSpacingY_;
79 transform_(0, 2) = panX_;
80 transform_(1, 2) = panY_;
81
82
83 #if 0
84 double a = 10.0 / 180.0 * boost::math::constants::pi<double>();
85 Matrix m;
86 const double v[] = { cos(a), -sin(a), 0,
87 sin(a), cos(a), 0,
88 0, 0, 1 };
89 LinearAlgebra::FillMatrix(m, 3, 3, v);
90 transform_ = LinearAlgebra::Product(m, transform_);
91 #endif
92 }
93
94
68 void ApplyConverter() 95 void ApplyConverter()
69 { 96 {
70 if (source_.get() != NULL && 97 if (source_.get() != NULL &&
71 converter_.get() != NULL) 98 converter_.get() != NULL)
72 { 99 {
105 Bitmap() : 132 Bitmap() :
106 visible_(true), 133 visible_(true),
107 width_(0), 134 width_(0),
108 height_(0), 135 height_(0),
109 hasCrop_(false), 136 hasCrop_(false),
110 transform_(LinearAlgebra::IdentityMatrix(3)) 137 pixelSpacingX_(1),
111 { 138 pixelSpacingY_(1),
139 panX_(0),
140 panY_(0)
141 {
142 UpdateTransform();
112 } 143 }
113 144
114 void ResetCrop() 145 void ResetCrop()
115 { 146 {
116 hasCrop_ = false; 147 hasCrop_ = false;
178 209
179 if (dataset.GetStringValue(tmp, ConvertTag(Orthanc::DICOM_TAG_PIXEL_SPACING)) && 210 if (dataset.GetStringValue(tmp, ConvertTag(Orthanc::DICOM_TAG_PIXEL_SPACING)) &&
180 LinearAlgebra::ParseVector(pixelSpacing, tmp) && 211 LinearAlgebra::ParseVector(pixelSpacing, tmp) &&
181 pixelSpacing.size() == 2) 212 pixelSpacing.size() == 2)
182 { 213 {
183 transform_(0, 0) = pixelSpacing[0]; 214 pixelSpacingX_ = pixelSpacing[0];
184 transform_(1, 1) = pixelSpacing[1]; 215 pixelSpacingY_ = pixelSpacing[1];
185 } 216 }
186 217
187
188 #if 0
189 double a = 10.0 / 180.0 * boost::math::constants::pi<double>();
190 Matrix m;
191 const double v[] = { cos(a), -sin(a), 0,
192 sin(a), cos(a), 0,
193 0, 0, 1 };
194 LinearAlgebra::FillMatrix(m, 3, 3, v);
195 transform_ = LinearAlgebra::Product(m, transform_);
196
197 #else
198 static unsigned int c = 0; 218 static unsigned int c = 0;
199 if (c == 0) 219 if (c == 0)
200 { 220 {
201 transform_(0, 2) = 400; 221 panX_ = 400;
202 c ++; 222 c ++;
203 } 223 }
204 #endif
205 224
206 OrthancPlugins::DicomDatasetReader reader(dataset); 225 OrthancPlugins::DicomDatasetReader reader(dataset);
207 226
208 if (!reader.GetUnsignedIntegerValue(width_, ConvertTag(Orthanc::DICOM_TAG_COLUMNS)) || 227 if (!reader.GetUnsignedIntegerValue(width_, ConvertTag(Orthanc::DICOM_TAG_COLUMNS)) ||
209 !reader.GetUnsignedIntegerValue(height_, ConvertTag(Orthanc::DICOM_TAG_ROWS))) 228 !reader.GetUnsignedIntegerValue(height_, ConvertTag(Orthanc::DICOM_TAG_ROWS)))
210 { 229 {
211 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); 230 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
212 } 231 }
232
233 UpdateTransform();
213 } 234 }
214 235
215 236
216 void SetSourceImage(Orthanc::ImageAccessor* image) // Takes ownership 237 void SetSourceImage(Orthanc::ImageAccessor* image) // Takes ownership
217 { 238 {
246 267
247 double dx = static_cast<double>(x) - 0.5; 268 double dx = static_cast<double>(x) - 0.5;
248 double dy = static_cast<double>(y) - 0.5; 269 double dy = static_cast<double>(y) - 0.5;
249 double dwidth = static_cast<double>(width); 270 double dwidth = static_cast<double>(width);
250 double dheight = static_cast<double>(height); 271 double dheight = static_cast<double>(height);
272
273 LinearAlgebra::Print(transform_);
251 274
252 AddToExtent(extent, dx, dy); 275 AddToExtent(extent, dx, dy);
253 AddToExtent(extent, dx + dwidth, dy); 276 AddToExtent(extent, dx + dwidth, dy);
254 AddToExtent(extent, dx, dy + dheight); 277 AddToExtent(extent, dx, dy + dheight);
255 AddToExtent(extent, dx + dwidth, dy + dheight); 278 AddToExtent(extent, dx + dwidth, dy + dheight);
262 const ViewportGeometry& view) const 285 const ViewportGeometry& view) const
263 { 286 {
264 if (converted_.get() != NULL) 287 if (converted_.get() != NULL)
265 { 288 {
266 Matrix m = LinearAlgebra::Product(view.GetMatrix(), transform_); 289 Matrix m = LinearAlgebra::Product(view.GetMatrix(), transform_);
267 ApplyProjectiveTransform(buffer, *converted_, m, ImageInterpolation_Bilinear, false); 290 //ApplyProjectiveTransform(buffer, *converted_, m, ImageInterpolation_Bilinear, false);
291 ApplyProjectiveTransform(buffer, *converted_, m, ImageInterpolation_Nearest, false);
268 } 292 }
269 } 293 }
270 294
271 295
272 bool Contains(double x, 296 bool Contains(double x,
284 { 308 {
285 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); 309 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
286 } 310 }
287 else 311 else
288 { 312 {
313 printf("at: (%.02f, %.02f)\n", q[0], q[1]);
289 return (q[0] >= 0 && 314 return (q[0] >= 0 &&
290 q[1] >= 0 && 315 q[1] >= 0 &&
291 q[0] <= static_cast<double>(width_) && 316 q[0] <= static_cast<double>(width_) &&
292 q[1] <= static_cast<double>(height_)); 317 q[1] <= static_cast<double>(height_));
293 } 318 }
319 }
320
321
322 void SetPan(double x,
323 double y)
324 {
325 panX_ = x;
326 panY_ = y;
327 UpdateTransform();
328 }
329
330
331 double GetPanX() const
332 {
333 return panX_;
334 }
335
336
337 double GetPanY() const
338 {
339 return panY_;
294 } 340 }
295 }; 341 };
296 342
297 343
298 typedef std::map<size_t, Bitmap*> Bitmaps; 344 typedef std::map<size_t, Bitmap*> Bitmaps;
452 return extent; 498 return extent;
453 } 499 }
454 500
455 501
456 void Render(Orthanc::ImageAccessor& buffer, 502 void Render(Orthanc::ImageAccessor& buffer,
457 const ViewportGeometry& view) 503 const ViewportGeometry& view) const
458 { 504 {
459 Orthanc::ImageProcessing::Set(buffer, 0); 505 Orthanc::ImageProcessing::Set(buffer, 0);
460 506
461 for (Bitmaps::const_iterator it = bitmaps_.begin(); 507 for (Bitmaps::const_iterator it = bitmaps_.begin();
462 it != bitmaps_.end(); ++it) 508 it != bitmaps_.end(); ++it)
463 { 509 {
464 assert(it->second != NULL); 510 assert(it->second != NULL);
465 it->second->Render(buffer, view); 511 it->second->Render(buffer, view);
466 } 512 }
467 } 513 }
514
515
516 bool LookupBitmap(size_t& index /* out */,
517 double x,
518 double y) const
519 {
520 for (Bitmaps::const_iterator it = bitmaps_.begin();
521 it != bitmaps_.end(); ++it)
522 {
523 assert(it->second != NULL);
524 if (it->second->Contains(x, y))
525 {
526 index = it->first;
527 return true;
528 }
529 }
530
531 return false;
532 }
533
534
535 void SetPan(size_t index,
536 double panX,
537 double panY)
538 {
539 Bitmaps::iterator bitmap = bitmaps_.find(index);
540 if (bitmap != bitmaps_.end())
541 {
542 assert(bitmap->second != NULL);
543 bitmap->second->SetPan(panX, panY);
544 }
545 }
546
547
548 void GetPan(double& panX,
549 double& panY,
550 size_t index) const
551 {
552 Bitmaps::const_iterator bitmap = bitmaps_.find(index);
553 if (bitmap != bitmaps_.end())
554 {
555 assert(bitmap->second != NULL);
556 panX = bitmap->second->GetPanX();
557 panY = bitmap->second->GetPanY();
558 }
559 else
560 {
561 panX = 0;
562 panY = 0;
563 }
564 }
468 }; 565 };
469 566
470 567
471 class BitmapStackInteractor : public IWorldSceneInteractor 568 class BitmapStackInteractor : public IWorldSceneInteractor
472 { 569 {
570 private:
571 BitmapStack& stack_;
572
573
574 class MoveBitmapTracker : public IWorldSceneMouseTracker
575 {
576 private:
577 WorldSceneWidget& widget_;
578 BitmapStack& stack_;
579 size_t bitmap_;
580 double clickX_;
581 double clickY_;
582
583 public:
584 MoveBitmapTracker(WorldSceneWidget& widget,
585 BitmapStack& stack,
586 size_t bitmap,
587 double x,
588 double y) :
589 widget_(widget),
590 stack_(stack),
591 bitmap_(bitmap),
592 clickX_(x),
593 clickY_(y)
594 {
595 double panX, panY;
596 stack.GetPan(panX, panY, bitmap_);
597 clickX_ -= panX;
598 clickY_ -= panY;
599 }
600
601 virtual bool HasRender() const
602 {
603 return false;
604 }
605
606 virtual void Render(CairoContext& context,
607 double zoom)
608 {
609 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
610 }
611
612 virtual void MouseUp()
613 {
614 }
615
616 virtual void MouseMove(int displayX,
617 int displayY,
618 double sceneX,
619 double sceneY)
620 {
621 stack_.SetPan(bitmap_, sceneX - clickX_, sceneY - clickY_);
622 }
623 };
624
625
473 public: 626 public:
627 BitmapStackInteractor(BitmapStack& stack) :
628 stack_(stack)
629 {
630 }
631
474 virtual IWorldSceneMouseTracker* CreateMouseTracker(WorldSceneWidget& widget, 632 virtual IWorldSceneMouseTracker* CreateMouseTracker(WorldSceneWidget& widget,
475 const ViewportGeometry& view, 633 const ViewportGeometry& view,
476 MouseButton button, 634 MouseButton button,
477 KeyboardModifiers modifiers, 635 KeyboardModifiers modifiers,
478 double x, 636 double x,
479 double y, 637 double y,
480 IStatusBar* statusBar) 638 IStatusBar* statusBar)
481 { 639 {
482 printf("CLICK\n"); 640 if (button == MouseButton_Left)
483 return NULL; 641 {
642 size_t bitmap;
643 if (stack_.LookupBitmap(bitmap, x, y))
644 {
645 printf("CLICK on bitmap %d\n", bitmap);
646 return new MoveBitmapTracker(widget, stack_, bitmap, x, y);
647 }
648 else
649 {
650 printf("CLICK outside\n");
651 return NULL;
652 }
653 }
654 else
655 {
656 return NULL;
657 }
484 } 658 }
485 659
486 virtual void MouseOver(CairoContext& context, 660 virtual void MouseOver(CairoContext& context,
487 WorldSceneWidget& widget, 661 WorldSceneWidget& widget,
488 const ViewportGeometry& view, 662 const ViewportGeometry& view,
503 KeyboardKeys key, 677 KeyboardKeys key,
504 char keyChar, 678 char keyChar,
505 KeyboardModifiers modifiers, 679 KeyboardModifiers modifiers,
506 IStatusBar* statusBar) 680 IStatusBar* statusBar)
507 { 681 {
682 if (keyChar == 's')
683 widget.FitContent();
508 } 684 }
509 }; 685 };
510 686
511 687
512 688
538 BitmapStack& stack, 714 BitmapStack& stack,
539 const std::string& name) : 715 const std::string& name) :
540 WorldSceneWidget(name), 716 WorldSceneWidget(name),
541 IObservable(broker), 717 IObservable(broker),
542 IObserver(broker), 718 IObserver(broker),
543 stack_(stack) 719 stack_(stack),
720 myInteractor_(stack_)
544 { 721 {
545 stack.RegisterObserverCallback(new Callable<BitmapStackWidget, BitmapStack::GeometryChangedMessage>(*this, &BitmapStackWidget::OnGeometryChanged)); 722 stack.RegisterObserverCallback(new Callable<BitmapStackWidget, BitmapStack::GeometryChangedMessage>(*this, &BitmapStackWidget::OnGeometryChanged));
546 stack.RegisterObserverCallback(new Callable<BitmapStackWidget, BitmapStack::ContentChangedMessage>(*this, &BitmapStackWidget::OnContentChanged)); 723 stack.RegisterObserverCallback(new Callable<BitmapStackWidget, BitmapStack::ContentChangedMessage>(*this, &BitmapStackWidget::OnContentChanged));
547 724
548 SetInteractor(myInteractor_); 725 SetInteractor(myInteractor_);