Mercurial > hg > orthanc-stone
changeset 1704:902d13889ae4
LoadMultipartInstanceInViewport() in C++
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 27 Nov 2020 17:15:09 +0100 |
parents | 76c590a62755 |
children | 3d62634d442f |
files | Applications/StoneWebViewer/WebApplication/app.js Applications/StoneWebViewer/WebApplication/index.html Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp |
diffstat | 3 files changed, 125 insertions(+), 60 deletions(-) [+] |
line wrap: on
line diff
--- a/Applications/StoneWebViewer/WebApplication/app.js Fri Nov 27 16:36:43 2020 +0100 +++ b/Applications/StoneWebViewer/WebApplication/app.js Fri Nov 27 17:15:09 2020 +0100 @@ -102,7 +102,7 @@ Vue.component('viewport', { - props: [ 'left', 'top', 'width', 'height', 'canvasId', 'active', 'series', 'viewportIndex', + props: [ 'left', 'top', 'width', 'height', 'canvasId', 'active', 'content', 'viewportIndex', 'showInfo' ], template: '#viewport-template', data: function () { @@ -128,7 +128,7 @@ **/ this.cineLoadingFrame = false; }, - series: function(newVal, oldVal) { + content: function(newVal, oldVal) { this.status = 'loading'; this.cineControls = false; this.cineMode = ''; @@ -202,9 +202,9 @@ var pdfPointer = args.detail.pdfPointer; var pdfSize = args.detail.pdfSize; - if ('tags' in that.series && - that.series.tags[STUDY_INSTANCE_UID] == studyInstanceUid && - that.series.tags[SERIES_INSTANCE_UID] == seriesInstanceUid) { + if ('tags' in that.content && + that.content.tags[STUDY_INSTANCE_UID] == studyInstanceUid && + that.content.tags[SERIES_INSTANCE_UID] == seriesInstanceUid) { that.status = 'pdf'; var pdf = new Uint8Array(HEAPU8.subarray(pdfPointer, pdfPointer + pdfSize)); @@ -228,7 +228,10 @@ event.preventDefault(); // The "parseInt()" is because of Microsoft Edge Legacy (*) - this.$emit('updated-series', parseInt(event.dataTransfer.getData('seriesIndex'), 10)); + this.$emit('updated-series', { + seriesIndex: parseInt(event.dataTransfer.getData('seriesIndex'), 10), + sopInstanceUid: event.dataTransfer.getData('sopInstanceUid') + }); }, MakeActive: function() { this.$emit('selected-viewport'); @@ -336,28 +339,28 @@ viewport1Left: '0%', viewport1Top: '0%', viewport1Visible: true, - viewport1Series: {}, + viewport1Content: {}, viewport2Width: '100%', viewport2Height: '100%', viewport2Left: '0%', viewport2Top: '0%', viewport2Visible: false, - viewport2Series: {}, + viewport2Content: {}, viewport3Width: '100%', viewport3Height: '100%', viewport3Left: '0%', viewport3Top: '0%', viewport3Visible: false, - viewport3Series: {}, + viewport3Content: {}, viewport4Width: '100%', viewport4Height: '100%', viewport4Left: '0%', viewport4Top: '0%', viewport4Visible: false, - viewport4Series: {}, + viewport4Content: {}, showWindowing: false, windowingPresets: [], @@ -420,17 +423,17 @@ GetActiveSeries: function() { var s = []; - if ('tags' in this.viewport1Series) - s.push(this.viewport1Series.tags[SERIES_INSTANCE_UID]); + if ('tags' in this.viewport1Content) + s.push(this.viewport1Content.tags[SERIES_INSTANCE_UID]); - if ('tags' in this.viewport2Series) - s.push(this.viewport2Series.tags[SERIES_INSTANCE_UID]); + if ('tags' in this.viewport2Content) + s.push(this.viewport2Content.tags[SERIES_INSTANCE_UID]); - if ('tags' in this.viewport3Series) - s.push(this.viewport3Series.tags[SERIES_INSTANCE_UID]); + if ('tags' in this.viewport3Content) + s.push(this.viewport3Content.tags[SERIES_INSTANCE_UID]); - if ('tags' in this.viewport4Series) - s.push(this.viewport4Series.tags[SERIES_INSTANCE_UID]); + if ('tags' in this.viewport4Content) + s.push(this.viewport4Content.tags[SERIES_INSTANCE_UID]); return s; }, @@ -518,31 +521,40 @@ event.dataTransfer.setData('seriesIndex', seriesIndex.toString()); }, + MultiframeInstanceDragStart: function(event, seriesIndex, sopInstanceUid) { + event.dataTransfer.setData('seriesIndex', seriesIndex.toString()); + event.dataTransfer.setData('sopInstanceUid', sopInstanceUid.toString()); + }, + SetViewportSeriesInstanceUid: function(viewportIndex, seriesInstanceUid) { if (seriesInstanceUid in this.seriesIndex) { - this.SetViewportSeries(viewportIndex, this.seriesIndex[seriesInstanceUid]); + this.SetViewportSeries(viewportIndex, { + seriesIndex: this.seriesIndex[seriesInstanceUid] + }); } }, - SetViewportSeries: function(viewportIndex, seriesIndex) { - var series = this.series[seriesIndex]; + SetViewportSeries: function(viewportIndex, info) { + var series = this.series[info.seriesIndex]; if (viewportIndex == 1) { - this.viewport1Series = series; + this.viewport1Content = series; } else if (viewportIndex == 2) { - this.viewport2Series = series; + this.viewport2Content = series; } else if (viewportIndex == 3) { - this.viewport3Series = series; + this.viewport3Content = series; } else if (viewportIndex == 4) { - this.viewport4Series = series; + this.viewport4Content = series; } }, ClickSeries: function(seriesIndex) { - this.SetViewportSeries(this.activeViewport, seriesIndex); + this.SetViewportSeries(this.activeViewport, { + seriesIndex: seriesIndex + }); }, HideViewport: function(index) { @@ -673,24 +685,24 @@ // https://fr.vuejs.org/2016/02/06/common-gotchas/#Why-isn%E2%80%99t-the-DOM-updating this.$set(this.series, index, series); - if ('tags' in this.viewport1Series && - this.viewport1Series.tags[SERIES_INSTANCE_UID] == seriesInstanceUid) { - this.$set(this.viewport1Series, series); + if ('tags' in this.viewport1Content && + this.viewport1Content.tags[SERIES_INSTANCE_UID] == seriesInstanceUid) { + this.$set(this.viewport1Content, series); } - if ('tags' in this.viewport2Series && - this.viewport2Series.tags[SERIES_INSTANCE_UID] == seriesInstanceUid) { - this.$set(this.viewport2Series, series); + if ('tags' in this.viewport2Content && + this.viewport2Content.tags[SERIES_INSTANCE_UID] == seriesInstanceUid) { + this.$set(this.viewport2Content, series); } - if ('tags' in this.viewport3Series && - this.viewport3Series.tags[SERIES_INSTANCE_UID] == seriesInstanceUid) { - this.$set(this.viewport3Series, series); + if ('tags' in this.viewport3Content && + this.viewport3Content.tags[SERIES_INSTANCE_UID] == seriesInstanceUid) { + this.$set(this.viewport3Content, series); } - if ('tags' in this.viewport4Series && - this.viewport4Series.tags[SERIES_INSTANCE_UID] == seriesInstanceUid) { - this.$set(this.viewport4Series, series); + if ('tags' in this.viewport4Content && + this.viewport4Content.tags[SERIES_INSTANCE_UID] == seriesInstanceUid) { + this.$set(this.viewport4Content, series); } } },
--- a/Applications/StoneWebViewer/WebApplication/index.html Fri Nov 27 16:36:43 2020 +0100 +++ b/Applications/StoneWebViewer/WebApplication/index.html Fri Nov 27 17:15:09 2020 +0100 @@ -245,9 +245,9 @@ <!-- Series with multiple multiframe instances (CINE) --> <li class="wvSerieslist__seriesItem" v-bind:class="{ highlighted : GetActiveSeries().includes(series[seriesIndex].tags['0020,000e']), 'wvSerieslist__seriesItem--list' : leftMode != 'grid', 'wvSerieslist__seriesItem--grid' : leftMode == 'grid' }" - v-on:dragstart="SeriesDragStart($event, seriesIndex)" - v-on:click="ClickSeries(seriesIndex)" - v-for="(numberOfFrames, sopInstanceUid) in series[seriesIndex].multiframeInstances"> + v-for="(numberOfFrames, sopInstanceUid) in series[seriesIndex].multiframeInstances" + v-on:dragstart="MultiframeInstanceDragStart($event, seriesIndex, sopInstanceUid)" + v-on:click="ClickMultiframeInstance(seriesIndex, sopInstanceUid)"> <div class="wvSerieslist__picture" style="z-index:0" draggable="true"> <img v-if="series[seriesIndex].type == stone.ThumbnailType.IMAGE" @@ -264,8 +264,8 @@ <div v-if="leftMode == 'full'" class="wvSerieslist__information" draggable="true" - v-on:dragstart="SeriesDragStart($event, seriesIndex)" - v-on:click="ClickSeries(seriesIndex)"> + v-on:dragstart="MultiframeInstanceDragStart($event, seriesIndex, sopInstanceUid)" + v-on:click="MultiframeInstanceDragStart($event, seriesIndex, sopInstanceUid)"> <p class="wvSerieslist__label"> [{{ series[seriesIndex].tags['0008,0060'] }}] {{ series[seriesIndex].tags['0008,103e'] }} @@ -523,7 +523,7 @@ v-on:selected-viewport="activeViewport=1" v-show="viewport1Visible" canvas-id="canvas1" - v-bind:series="viewport1Series" + v-bind:content="viewport1Content" v-bind:left="viewport1Left" v-bind:top="viewport1Top" v-bind:width="viewport1Width" @@ -534,7 +534,7 @@ v-on:selected-viewport="activeViewport=2" v-show="viewport2Visible" canvas-id="canvas2" - v-bind:series="viewport2Series" + v-bind:content="viewport2Content" v-bind:left="viewport2Left" v-bind:top="viewport2Top" v-bind:width="viewport2Width" @@ -545,7 +545,7 @@ v-on:selected-viewport="activeViewport=3" v-show="viewport3Visible" canvas-id="canvas3" - v-bind:series="viewport3Series" + v-bind:content="viewport3Content" v-bind:left="viewport3Left" v-bind:top="viewport3Top" v-bind:width="viewport3Width" @@ -556,7 +556,7 @@ v-on:selected-viewport="activeViewport=4" v-show="viewport4Visible" canvas-id="canvas4" - v-bind:series="viewport4Series" + v-bind:content="viewport4Content" v-bind:left="viewport4Left" v-bind:top="viewport4Top" v-bind:width="viewport4Width" @@ -579,12 +579,12 @@ width: width, height: height }"> <div v-bind:class="{ 'wvSplitpane__cellBorder--selected' : active, - 'wvSplitpane__cellBorder' : series.color == '', - 'wvSplitpane__cellBorder--blue' : series.color == 'blue', - 'wvSplitpane__cellBorder--red' : series.color == 'red', - 'wvSplitpane__cellBorder--green' : series.color == 'green', - 'wvSplitpane__cellBorder--yellow' : series.color == 'yellow', - 'wvSplitpane__cellBorder--violet' : series.color == 'violet' + 'wvSplitpane__cellBorder' : content.color == '', + 'wvSplitpane__cellBorder--blue' : content.color == 'blue', + 'wvSplitpane__cellBorder--red' : content.color == 'red', + 'wvSplitpane__cellBorder--green' : content.color == 'green', + 'wvSplitpane__cellBorder--yellow' : content.color == 'yellow', + 'wvSplitpane__cellBorder--violet' : content.color == 'violet' }" ondragover="event.preventDefault()" v-on:drop="DragDrop($event)" @@ -600,14 +600,14 @@ <div v-show="showInfo"> <div class="wv-overlay"> - <div v-if="'tags' in series" class="wv-overlay-topleft"> - {{ series.tags['0010,0010'] }}<br/> - {{ series.tags['0010,0020'] }} + <div v-if="'tags' in content" class="wv-overlay-topleft"> + {{ content.tags['0010,0010'] }}<br/> + {{ content.tags['0010,0020'] }} </div> - <div v-if="'tags' in series" class="wv-overlay-topright"> - {{ series.tags['0008,1030'] }}<br/> - {{ app.FormatDate(series.tags['0008,0020']) }}<br/> - {{ series.tags['0020,0011'] }} | {{ series.tags['0008,103e'] }} + <div v-if="'tags' in content" class="wv-overlay-topright"> + {{ content.tags['0008,1030'] }}<br/> + {{ app.FormatDate(content.tags['0008,0020']) }}<br/> + {{ content.tags['0020,0011'] }} | {{ content.tags['0008,103e'] }} </div> <div class="wv-overlay-timeline-wrapper wvPrintExclude"> <div style="text-align:left; padding:5px" v-show="numberOfFrames != 0">
--- a/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Fri Nov 27 16:36:43 2020 +0100 +++ b/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Fri Nov 27 17:15:09 2020 +0100 @@ -575,6 +575,35 @@ } } + bool SortMultipartInstanceFrames(OrthancStone::SortedFrames& target, + const std::string& seriesInstanceUid, + const std::string& sopInstanceUid) const + { + OrthancStone::SeriesMetadataLoader::Accessor accessor(*metadataLoader_, seriesInstanceUid); + + if (accessor.IsComplete()) + { + for (size_t i = 0; i < accessor.GetInstancesCount(); i++) + { + std::string s; + if (accessor.GetInstance(i).LookupStringValue(s, Orthanc::DICOM_TAG_SOP_INSTANCE_UID, false) && + s == sopInstanceUid) + { + target.Clear(); + target.AddInstance(accessor.GetInstance(i)); + target.Sort(); + return true; + } + } + + return true; + } + else + { + return false; + } + } + size_t GetSeriesNumberOfFrames(const std::string& seriesInstanceUid) const { OrthancStone::SeriesMetadataLoader::Accessor accessor(*metadataLoader_, seriesInstanceUid); @@ -3078,6 +3107,30 @@ EMSCRIPTEN_KEEPALIVE + int LoadMultipartInstanceInViewport(const char* canvas, + const char* seriesInstanceUid, + const char* sopInstanceUid) + { + try + { + std::unique_ptr<OrthancStone::SortedFrames> frames(new OrthancStone::SortedFrames); + + if (GetResourcesLoader().SortMultipartInstanceFrames(*frames, seriesInstanceUid, sopInstanceUid)) + { + GetViewport(canvas)->SetFrames(frames.release()); + return 1; + } + else + { + return 0; + } + } + EXTERN_CATCH_EXCEPTIONS; + return 0; + } + + + EMSCRIPTEN_KEEPALIVE void AllViewportsUpdateSize(int fitContent) { try