Mercurial > hg > orthanc-stone
comparison Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp @ 2097:a9e23ef9ee09 dicom-sr
preparing to extract dicom-sr annotations
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 08 Nov 2023 16:31:49 +0100 |
parents | 79e984a89a38 |
children | 4288d635d77e |
comparison
equal
deleted
inserted
replaced
2096:79e984a89a38 | 2097:a9e23ef9ee09 |
---|---|
224 | 224 |
225 virtual bool FindClosestFrame(size_t& frameIndex, | 225 virtual bool FindClosestFrame(size_t& frameIndex, |
226 const OrthancStone::Vector& point, | 226 const OrthancStone::Vector& point, |
227 double maximumDistance) const = 0; | 227 double maximumDistance) const = 0; |
228 | 228 |
229 virtual OrthancStone::ISceneLayer* ExtractAnnotations(const std::string& sopInstanceUid, | |
230 unsigned int frameNumber, | |
231 double originX, | |
232 double originY, | |
233 double pixelSpacingX, | |
234 double pixelSpacingY) const = 0; | |
235 | |
229 static OrthancStone::CoordinateSystem3D GetFrameGeometry(const IFramesCollection& frames, | 236 static OrthancStone::CoordinateSystem3D GetFrameGeometry(const IFramesCollection& frames, |
230 size_t frameIndex) | 237 size_t frameIndex) |
231 { | 238 { |
232 return frames.GetInstanceOfFrame(frameIndex).GetFrameGeometry(frames.GetFrameNumberInInstance(frameIndex)); | 239 return frames.GetInstanceOfFrame(frameIndex).GetFrameGeometry(frames.GetFrameNumberInInstance(frameIndex)); |
233 } | 240 } |
277 virtual bool FindClosestFrame(size_t& frameIndex, | 284 virtual bool FindClosestFrame(size_t& frameIndex, |
278 const OrthancStone::Vector& point, | 285 const OrthancStone::Vector& point, |
279 double maximumDistance) const ORTHANC_OVERRIDE | 286 double maximumDistance) const ORTHANC_OVERRIDE |
280 { | 287 { |
281 return frames_->FindClosestFrame(frameIndex, point, maximumDistance); | 288 return frames_->FindClosestFrame(frameIndex, point, maximumDistance); |
282 }; | 289 } |
290 | |
291 virtual OrthancStone::ISceneLayer* ExtractAnnotations(const std::string& sopInstanceUid, | |
292 unsigned int frameNumber, | |
293 double originX, | |
294 double originY, | |
295 double pixelSpacingX, | |
296 double pixelSpacingY) const ORTHANC_OVERRIDE | |
297 { | |
298 return NULL; | |
299 } | |
283 }; | 300 }; |
284 | 301 |
285 | 302 |
286 class DicomStructuredReportFrames : public IFramesCollection | 303 class DicomStructuredReportFrames : public IFramesCollection |
287 { | 304 { |
319 const OrthancStone::DicomInstanceParameters& GetParameters() const | 336 const OrthancStone::DicomInstanceParameters& GetParameters() const |
320 { | 337 { |
321 return *parameters_; | 338 return *parameters_; |
322 } | 339 } |
323 }; | 340 }; |
324 | 341 |
325 std::string studyInstanceUid_; | 342 std::unique_ptr<OrthancStone::DicomStructuredReport> sr_; |
326 std::string seriesInstanceUid_; | 343 std::vector<Frame*> frames_; |
327 std::vector<Frame*> frames_; | |
328 | 344 |
329 void Finalize() | 345 void Finalize() |
330 { | 346 { |
331 for (size_t i = 0; i < frames_.size(); i++) | 347 for (size_t i = 0; i < frames_.size(); i++) |
332 { | 348 { |
351 return *frames_[index]; | 367 return *frames_[index]; |
352 } | 368 } |
353 } | 369 } |
354 | 370 |
355 public: | 371 public: |
356 DicomStructuredReportFrames(OrthancStone::DicomStructuredReport& sr, | 372 DicomStructuredReportFrames(const OrthancStone::DicomStructuredReport& sr, |
357 const OrthancStone::LoadedDicomResources& instances) : | 373 const OrthancStone::LoadedDicomResources& instances) : |
358 studyInstanceUid_(sr.GetStudyInstanceUid()), | 374 sr_(new OrthancStone::DicomStructuredReport(sr)) |
359 seriesInstanceUid_(sr.GetSeriesInstanceUid()) | |
360 { | 375 { |
361 std::list<OrthancStone::DicomStructuredReport::ReferencedFrame> tmp; | 376 std::list<OrthancStone::DicomStructuredReport::ReferencedFrame> tmp; |
362 sr.ExportReferencedFrames(tmp); | 377 sr_->ExportReferencedFrames(tmp); |
363 | 378 |
364 frames_.reserve(tmp.size()); | 379 frames_.reserve(tmp.size()); |
365 for (std::list<OrthancStone::DicomStructuredReport::ReferencedFrame>::const_iterator | 380 for (std::list<OrthancStone::DicomStructuredReport::ReferencedFrame>::const_iterator |
366 it = tmp.begin(); it != tmp.end(); ++it) | 381 it = tmp.begin(); it != tmp.end(); ++it) |
367 { | 382 { |
431 frameIndex = i; | 446 frameIndex = i; |
432 } | 447 } |
433 } | 448 } |
434 | 449 |
435 return found; | 450 return found; |
451 } | |
452 | |
453 virtual OrthancStone::ISceneLayer* ExtractAnnotations(const std::string& sopInstanceUid, | |
454 unsigned int frameNumber, | |
455 double originX, | |
456 double originY, | |
457 double pixelSpacingX, | |
458 double pixelSpacingY) const ORTHANC_OVERRIDE | |
459 { | |
460 size_t frameIndex; | |
461 if (!LookupFrame(frameIndex, sopInstanceUid, frameNumber)) | |
462 { | |
463 return NULL; | |
464 } | |
465 | |
466 const OrthancStone::DicomInstanceParameters& parameters = GetInstanceOfFrame(frameIndex); | |
467 | |
468 const double x = originX - pixelSpacingX / 2.0; | |
469 const double y = originY - pixelSpacingY / 2.0; | |
470 const double w = parameters.GetWidth() * pixelSpacingX; | |
471 const double h = parameters.GetHeight() * pixelSpacingY; | |
472 | |
473 std::unique_ptr<OrthancStone::MacroSceneLayer> layer(new OrthancStone::MacroSceneLayer); | |
474 | |
475 { | |
476 std::unique_ptr<OrthancStone::PolylineSceneLayer> polyline(new OrthancStone::PolylineSceneLayer); | |
477 { | |
478 OrthancStone::PolylineSceneLayer::Chain chain; | |
479 chain.push_back(OrthancStone::ScenePoint2D(x, y)); | |
480 chain.push_back(OrthancStone::ScenePoint2D(x + pixelSpacingX, y)); | |
481 chain.push_back(OrthancStone::ScenePoint2D(x + pixelSpacingX, y + pixelSpacingY)); | |
482 chain.push_back(OrthancStone::ScenePoint2D(x, y + pixelSpacingY)); | |
483 | |
484 polyline->AddChain(chain, true, 255, 0, 0); | |
485 } | |
486 | |
487 layer->AddLayer(polyline.release()); | |
488 } | |
489 | |
490 { | |
491 std::unique_ptr<OrthancStone::PolylineSceneLayer> polyline(new OrthancStone::PolylineSceneLayer); | |
492 { | |
493 OrthancStone::PolylineSceneLayer::Chain chain; | |
494 chain.push_back(OrthancStone::ScenePoint2D(x, y)); | |
495 chain.push_back(OrthancStone::ScenePoint2D(x + w, y)); | |
496 chain.push_back(OrthancStone::ScenePoint2D(x + w, y + h)); | |
497 chain.push_back(OrthancStone::ScenePoint2D(x, y + h)); | |
498 | |
499 polyline->AddChain(chain, true, 255, 0, 0); | |
500 } | |
501 | |
502 layer->AddLayer(polyline.release()); | |
503 } | |
504 | |
505 return layer.release(); | |
436 } | 506 } |
437 }; | 507 }; |
438 | 508 |
439 | 509 |
440 class VirtualSeries : public boost::noncopyable | 510 class VirtualSeries : public boost::noncopyable |
1964 static const int LAYER_OVERLAY = 1; | 2034 static const int LAYER_OVERLAY = 1; |
1965 static const int LAYER_ORIENTATION_MARKERS = 2; | 2035 static const int LAYER_ORIENTATION_MARKERS = 2; |
1966 static const int LAYER_REFERENCE_LINES = 3; | 2036 static const int LAYER_REFERENCE_LINES = 3; |
1967 static const int LAYER_ANNOTATIONS_OSIRIX = 4; | 2037 static const int LAYER_ANNOTATIONS_OSIRIX = 4; |
1968 static const int LAYER_ANNOTATIONS_STONE = 5; | 2038 static const int LAYER_ANNOTATIONS_STONE = 5; |
2039 static const int LAYER_STRUCTURED_REPORT = 6; | |
1969 | 2040 |
1970 | 2041 |
1971 class ICommand : public Orthanc::IDynamicObject | 2042 class ICommand : public Orthanc::IDynamicObject |
1972 { | 2043 { |
1973 private: | 2044 private: |
2648 text->SetAnchor(OrthancStone::BitmapAnchor_CenterRight); | 2719 text->SetAnchor(OrthancStone::BitmapAnchor_CenterRight); |
2649 orientationMarkers->AddLayer(text.release()); | 2720 orientationMarkers->AddLayer(text.release()); |
2650 } | 2721 } |
2651 | 2722 |
2652 | 2723 |
2724 std::unique_ptr<OrthancStone::ISceneLayer> structuredReportAnnotations; | |
2725 | |
2726 if (frames_.get() != NULL) | |
2727 { | |
2728 structuredReportAnnotations.reset(frames_->ExtractAnnotations(instance.GetSopInstanceUid(), frameIndex, | |
2729 layer->GetOriginX(), layer->GetOriginY(), | |
2730 layer->GetPixelSpacingX(), layer->GetPixelSpacingY())); | |
2731 } | |
2732 | |
2733 | |
2653 { | 2734 { |
2654 std::unique_ptr<OrthancStone::IViewport::ILock> lock(viewport_->Lock()); | 2735 std::unique_ptr<OrthancStone::IViewport::ILock> lock(viewport_->Lock()); |
2655 | 2736 |
2656 OrthancStone::Scene2D& scene = lock->GetController().GetScene(); | 2737 OrthancStone::Scene2D& scene = lock->GetController().GetScene(); |
2657 | 2738 |
2680 scene.SetLayer(LAYER_ORIENTATION_MARKERS, orientationMarkers.release()); | 2761 scene.SetLayer(LAYER_ORIENTATION_MARKERS, orientationMarkers.release()); |
2681 } | 2762 } |
2682 else | 2763 else |
2683 { | 2764 { |
2684 scene.DeleteLayer(LAYER_ORIENTATION_MARKERS); | 2765 scene.DeleteLayer(LAYER_ORIENTATION_MARKERS); |
2766 } | |
2767 | |
2768 if (orientationMarkers.get() != NULL) | |
2769 { | |
2770 scene.SetLayer(LAYER_ORIENTATION_MARKERS, orientationMarkers.release()); | |
2771 } | |
2772 else | |
2773 { | |
2774 scene.DeleteLayer(LAYER_ORIENTATION_MARKERS); | |
2775 } | |
2776 | |
2777 if (structuredReportAnnotations.get() != NULL) | |
2778 { | |
2779 scene.SetLayer(LAYER_STRUCTURED_REPORT, structuredReportAnnotations.release()); | |
2780 } | |
2781 else | |
2782 { | |
2783 scene.DeleteLayer(LAYER_STRUCTURED_REPORT); | |
2685 } | 2784 } |
2686 | 2785 |
2687 stoneAnnotations_->Render(scene); // Necessary for "FitContent()" to work | 2786 stoneAnnotations_->Render(scene); // Necessary for "FitContent()" to work |
2688 | 2787 |
2689 if (fitNextContent_) | 2788 if (fitNextContent_) |