Mercurial > hg > orthanc-stone
comparison Applications/Samples/SingleFrameEditorApplication.h @ 341:7bebbfa56bde am-2
cont
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Sun, 21 Oct 2018 17:35:26 +0200 |
parents | f5d5814a41a0 |
children | 4297d6c5eef9 |
comparison
equal
deleted
inserted
replaced
340:f5d5814a41a0 | 341:7bebbfa56bde |
---|---|
29 | 29 |
30 #include <Core/DicomFormat/DicomArray.h> | 30 #include <Core/DicomFormat/DicomArray.h> |
31 #include <Core/Images/ImageProcessing.h> | 31 #include <Core/Images/ImageProcessing.h> |
32 #include <Core/Images/PamReader.h> | 32 #include <Core/Images/PamReader.h> |
33 #include <Core/Logging.h> | 33 #include <Core/Logging.h> |
34 #include <Core/Toolbox.h> | |
35 #include <Plugins/Samples/Common/FullOrthancDataset.h> | 34 #include <Plugins/Samples/Common/FullOrthancDataset.h> |
36 #include <Plugins/Samples/Common/DicomDatasetReader.h> | 35 #include <Plugins/Samples/Common/DicomDatasetReader.h> |
37 | 36 |
38 | 37 |
39 #include <boost/math/constants/constants.hpp> | 38 #include <boost/math/constants/constants.hpp> |
50 | 49 |
51 private: | 50 private: |
52 class Bitmap : public boost::noncopyable | 51 class Bitmap : public boost::noncopyable |
53 { | 52 { |
54 private: | 53 private: |
55 std::string uuid_; // TODO is this necessary? | |
56 bool visible_; | 54 bool visible_; |
57 std::auto_ptr<Orthanc::ImageAccessor> source_; | 55 std::auto_ptr<Orthanc::ImageAccessor> source_; |
58 std::auto_ptr<Orthanc::ImageAccessor> converted_; // Float32 or RGB24 | 56 std::auto_ptr<Orthanc::ImageAccessor> converted_; // Float32 or RGB24 |
59 std::auto_ptr<Orthanc::Image> alpha_; // Grayscale8 (if any) | 57 std::auto_ptr<Orthanc::Image> alpha_; // Grayscale8 (if any) |
60 std::auto_ptr<DicomFrameConverter> converter_; | 58 std::auto_ptr<DicomFrameConverter> converter_; |
102 } | 100 } |
103 } | 101 } |
104 | 102 |
105 | 103 |
106 public: | 104 public: |
107 Bitmap(const std::string& uuid) : | 105 Bitmap() : |
108 uuid_(uuid), | |
109 visible_(true), | 106 visible_(true), |
110 width_(0), | 107 width_(0), |
111 height_(0), | 108 height_(0), |
112 hasCrop_(false), | 109 hasCrop_(false), |
113 transform_(LinearAlgebra::IdentityMatrix(3)) | 110 transform_(LinearAlgebra::IdentityMatrix(3)) |
268 { | 265 { |
269 Matrix m = LinearAlgebra::Product(view.GetMatrix(), transform_); | 266 Matrix m = LinearAlgebra::Product(view.GetMatrix(), transform_); |
270 ApplyProjectiveTransform(buffer, *converted_, m, ImageInterpolation_Bilinear, false); | 267 ApplyProjectiveTransform(buffer, *converted_, m, ImageInterpolation_Bilinear, false); |
271 } | 268 } |
272 } | 269 } |
270 | |
271 | |
272 bool Contains(double x, | |
273 double y) const | |
274 { | |
275 Matrix inv; | |
276 LinearAlgebra::InvertMatrix(inv, transform_); | |
277 | |
278 Vector p; | |
279 LinearAlgebra::AssignVector(p, x, y, 1); | |
280 | |
281 Vector q = LinearAlgebra::Product(inv, p); | |
282 | |
283 if (!LinearAlgebra::IsNear(q[2], 1.0)) | |
284 { | |
285 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
286 } | |
287 else | |
288 { | |
289 return (q[0] >= 0 && | |
290 q[1] >= 0 && | |
291 q[0] <= static_cast<double>(width_) && | |
292 q[1] <= static_cast<double>(height_)); | |
293 } | |
294 } | |
273 }; | 295 }; |
274 | 296 |
275 | 297 |
276 typedef std::map<std::string, Bitmap*> Bitmaps; | 298 typedef std::map<size_t, Bitmap*> Bitmaps; |
277 | 299 |
278 OrthancApiClient& orthanc_; | 300 OrthancApiClient& orthanc_; |
279 bool hasWindowing_; | 301 size_t countBitmaps_; |
280 float windowingCenter_; | 302 bool hasWindowing_; |
281 float windowingWidth_; | 303 float windowingCenter_; |
282 Bitmaps bitmaps_; | 304 float windowingWidth_; |
305 Bitmaps bitmaps_; | |
283 | 306 |
284 public: | 307 public: |
285 BitmapStack(MessageBroker& broker, | 308 BitmapStack(MessageBroker& broker, |
286 OrthancApiClient& orthanc) : | 309 OrthancApiClient& orthanc) : |
287 IObserver(broker), | 310 IObserver(broker), |
288 IObservable(broker), | 311 IObservable(broker), |
289 orthanc_(orthanc), | 312 orthanc_(orthanc), |
313 countBitmaps_(0), | |
290 hasWindowing_(false), | 314 hasWindowing_(false), |
291 windowingCenter_(0), // Dummy initialization | 315 windowingCenter_(0), // Dummy initialization |
292 windowingWidth_(0) // Dummy initialization | 316 windowingWidth_(0) // Dummy initialization |
293 { | 317 { |
294 } | 318 } |
318 width = 256; | 342 width = 256; |
319 } | 343 } |
320 } | 344 } |
321 | 345 |
322 | 346 |
323 std::string LoadFrame(const std::string& instance, | 347 size_t LoadFrame(const std::string& instance, |
324 unsigned int frame, | 348 unsigned int frame, |
325 bool httpCompression) | 349 bool httpCompression) |
326 { | 350 { |
327 std::string uuid; | 351 size_t bitmap = countBitmaps_++; |
328 | 352 |
329 for (;;) | 353 bitmaps_[bitmap] = new Bitmap; |
330 { | |
331 uuid = Orthanc::Toolbox::GenerateUuid(); | |
332 if (bitmaps_.find(uuid) == bitmaps_.end()) | |
333 { | |
334 break; | |
335 } | |
336 } | |
337 | |
338 bitmaps_[uuid] = new Bitmap(uuid); | |
339 | 354 |
340 | 355 |
341 { | 356 { |
342 IWebService::Headers headers; | 357 IWebService::Headers headers; |
343 std::string uri = "/instances/" + instance + "/tags"; | 358 std::string uri = "/instances/" + instance + "/tags"; |
344 orthanc_.GetBinaryAsync(uri, headers, | 359 orthanc_.GetBinaryAsync(uri, headers, |
345 new Callable<BitmapStack, OrthancApiClient::BinaryResponseReadyMessage> | 360 new Callable<BitmapStack, OrthancApiClient::BinaryResponseReadyMessage> |
346 (*this, &BitmapStack::OnTagsReceived), NULL, | 361 (*this, &BitmapStack::OnTagsReceived), NULL, |
347 new Orthanc::SingleValueObject<std::string>(uuid)); | 362 new Orthanc::SingleValueObject<size_t>(bitmap)); |
348 } | 363 } |
349 | 364 |
350 { | 365 { |
351 IWebService::Headers headers; | 366 IWebService::Headers headers; |
352 headers["Accept"] = "image/x-portable-arbitrarymap"; | 367 headers["Accept"] = "image/x-portable-arbitrarymap"; |
358 | 373 |
359 std::string uri = "/instances/" + instance + "/frames/" + boost::lexical_cast<std::string>(frame) + "/image-uint16"; | 374 std::string uri = "/instances/" + instance + "/frames/" + boost::lexical_cast<std::string>(frame) + "/image-uint16"; |
360 orthanc_.GetBinaryAsync(uri, headers, | 375 orthanc_.GetBinaryAsync(uri, headers, |
361 new Callable<BitmapStack, OrthancApiClient::BinaryResponseReadyMessage> | 376 new Callable<BitmapStack, OrthancApiClient::BinaryResponseReadyMessage> |
362 (*this, &BitmapStack::OnFrameReceived), NULL, | 377 (*this, &BitmapStack::OnFrameReceived), NULL, |
363 new Orthanc::SingleValueObject<std::string>(uuid)); | 378 new Orthanc::SingleValueObject<size_t>(bitmap)); |
364 } | 379 } |
365 | 380 |
366 return uuid; | 381 return bitmap; |
367 } | 382 } |
368 | 383 |
369 | 384 |
370 void OnTagsReceived(const OrthancApiClient::BinaryResponseReadyMessage& message) | 385 void OnTagsReceived(const OrthancApiClient::BinaryResponseReadyMessage& message) |
371 { | 386 { |
372 const std::string& uuid = dynamic_cast<Orthanc::SingleValueObject<std::string>*>(message.Payload)->GetValue(); | 387 size_t index = dynamic_cast<Orthanc::SingleValueObject<size_t>*>(message.Payload)->GetValue(); |
373 | 388 |
374 printf("JSON received: [%s] (%d bytes) for bitmap %s\n", | 389 printf("JSON received: [%s] (%ld bytes) for bitmap %ld\n", |
375 message.Uri.c_str(), message.AnswerSize, uuid.c_str()); | 390 message.Uri.c_str(), message.AnswerSize, index); |
376 | 391 |
377 Bitmaps::iterator bitmap = bitmaps_.find(uuid); | 392 Bitmaps::iterator bitmap = bitmaps_.find(index); |
378 if (bitmap != bitmaps_.end()) | 393 if (bitmap != bitmaps_.end()) |
379 { | 394 { |
380 assert(bitmap->second != NULL); | 395 assert(bitmap->second != NULL); |
381 | 396 |
382 OrthancPlugins::FullOrthancDataset dicom(message.Answer, message.AnswerSize); | 397 OrthancPlugins::FullOrthancDataset dicom(message.Answer, message.AnswerSize); |
396 } | 411 } |
397 | 412 |
398 | 413 |
399 void OnFrameReceived(const OrthancApiClient::BinaryResponseReadyMessage& message) | 414 void OnFrameReceived(const OrthancApiClient::BinaryResponseReadyMessage& message) |
400 { | 415 { |
401 const std::string& uuid = dynamic_cast<Orthanc::SingleValueObject<std::string>*>(message.Payload)->GetValue(); | 416 size_t index = dynamic_cast<Orthanc::SingleValueObject<size_t>*>(message.Payload)->GetValue(); |
402 | 417 |
403 printf("Frame received: [%s] (%d bytes) for bitmap %s\n", message.Uri.c_str(), message.AnswerSize, uuid.c_str()); | 418 printf("Frame received: [%s] (%ld bytes) for bitmap %ld\n", |
404 | 419 message.Uri.c_str(), message.AnswerSize, index); |
405 Bitmaps::iterator bitmap = bitmaps_.find(uuid); | 420 |
421 Bitmaps::iterator bitmap = bitmaps_.find(index); | |
406 if (bitmap != bitmaps_.end()) | 422 if (bitmap != bitmaps_.end()) |
407 { | 423 { |
408 assert(bitmap->second != NULL); | 424 assert(bitmap->second != NULL); |
409 | 425 |
410 std::string content; | 426 std::string content; |
449 it->second->Render(buffer, view); | 465 it->second->Render(buffer, view); |
450 } | 466 } |
451 } | 467 } |
452 }; | 468 }; |
453 | 469 |
470 | |
471 class BitmapStackInteractor : public IWorldSceneInteractor | |
472 { | |
473 public: | |
474 virtual IWorldSceneMouseTracker* CreateMouseTracker(WorldSceneWidget& widget, | |
475 const ViewportGeometry& view, | |
476 MouseButton button, | |
477 KeyboardModifiers modifiers, | |
478 double x, | |
479 double y, | |
480 IStatusBar* statusBar) | |
481 { | |
482 printf("CLICK\n"); | |
483 return NULL; | |
484 } | |
485 | |
486 virtual void MouseOver(CairoContext& context, | |
487 WorldSceneWidget& widget, | |
488 const ViewportGeometry& view, | |
489 double x, | |
490 double y, | |
491 IStatusBar* statusBar) | |
492 { | |
493 } | |
494 | |
495 virtual void MouseWheel(WorldSceneWidget& widget, | |
496 MouseWheelDirection direction, | |
497 KeyboardModifiers modifiers, | |
498 IStatusBar* statusBar) | |
499 { | |
500 } | |
501 | |
502 virtual void KeyPressed(WorldSceneWidget& widget, | |
503 KeyboardKeys key, | |
504 char keyChar, | |
505 KeyboardModifiers modifiers, | |
506 IStatusBar* statusBar) | |
507 { | |
508 } | |
509 }; | |
510 | |
511 | |
454 | 512 |
455 class BitmapStackWidget : | 513 class BitmapStackWidget : |
456 public WorldSceneWidget, | 514 public WorldSceneWidget, |
457 public IObservable, | 515 public IObservable, |
458 public IObserver | 516 public IObserver |
459 { | 517 { |
460 private: | 518 private: |
461 BitmapStack& stack_; | 519 BitmapStack& stack_; |
520 BitmapStackInteractor myInteractor_; | |
462 | 521 |
463 protected: | 522 protected: |
464 virtual Extent2D GetSceneExtent() | 523 virtual Extent2D GetSceneExtent() |
465 { | 524 { |
466 printf("Get extent\n"); | 525 printf("Get extent\n"); |
483 IObserver(broker), | 542 IObserver(broker), |
484 stack_(stack) | 543 stack_(stack) |
485 { | 544 { |
486 stack.RegisterObserverCallback(new Callable<BitmapStackWidget, BitmapStack::GeometryChangedMessage>(*this, &BitmapStackWidget::OnGeometryChanged)); | 545 stack.RegisterObserverCallback(new Callable<BitmapStackWidget, BitmapStack::GeometryChangedMessage>(*this, &BitmapStackWidget::OnGeometryChanged)); |
487 stack.RegisterObserverCallback(new Callable<BitmapStackWidget, BitmapStack::ContentChangedMessage>(*this, &BitmapStackWidget::OnContentChanged)); | 546 stack.RegisterObserverCallback(new Callable<BitmapStackWidget, BitmapStack::ContentChangedMessage>(*this, &BitmapStackWidget::OnContentChanged)); |
547 | |
548 SetInteractor(myInteractor_); | |
488 } | 549 } |
489 | 550 |
490 void OnGeometryChanged(const BitmapStack::GeometryChangedMessage& message) | 551 void OnGeometryChanged(const BitmapStack::GeometryChangedMessage& message) |
491 { | 552 { |
492 printf("Geometry has changed\n"); | 553 printf("Geometry has changed\n"); |
733 | 794 |
734 mainWidget_ = new BitmapStackWidget(IObserver::broker_, *stack_, "main-widget"); | 795 mainWidget_ = new BitmapStackWidget(IObserver::broker_, *stack_, "main-widget"); |
735 mainWidget_->SetTransmitMouseOver(true); | 796 mainWidget_->SetTransmitMouseOver(true); |
736 | 797 |
737 mainWidgetInteractor_.reset(new Interactor(*this)); | 798 mainWidgetInteractor_.reset(new Interactor(*this)); |
738 mainWidget_->SetInteractor(*mainWidgetInteractor_); | 799 //mainWidget_->SetInteractor(*mainWidgetInteractor_); |
739 } | 800 } |
740 | 801 |
741 | 802 |
742 void Invert() | 803 void Invert() |
743 { | 804 { |