Mercurial > hg > orthanc-stl
changeset 31:ab231760799d
added button to import STL
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 04 Apr 2024 18:05:13 +0200 (13 months ago) |
parents | 3570c23764d4 |
children | 976da5476810 |
files | Sources/OrthancExplorer.js Sources/Plugin.cpp |
diffstat | 2 files changed, 217 insertions(+), 107 deletions(-) [+] |
line wrap: on
line diff
--- a/Sources/OrthancExplorer.js Thu Apr 04 17:28:03 2024 +0200 +++ b/Sources/OrthancExplorer.js Thu Apr 04 18:05:13 2024 +0200 @@ -147,6 +147,215 @@ } +function AddGenerateFromNIfTIButton(studyId) { + if (${HAS_CREATE_DICOM_STL} && + ${SHOW_NIFTI_BUTTON}) { + $('#stl-attach-nifti').remove(); + + var nifti = $('<a>') + .attr('id', 'stl-attach-nifti') + .attr('data-role', 'button') + .attr('href', '#') + .attr('data-icon', 'search') + .attr('data-theme', 'e') + .text('Attach NIfTI 3D model') + .button(); + + nifti.insertAfter($('#study-info')); + nifti.click(function() { + + var options = $('<ul>') + .attr('data-divider-theme', 'd') + .attr('data-role', 'listview'); + + var upload = $('<input>') + .attr('type', 'file') + .attr('id', 'stl-attach-nifti-upload') + .attr('data-theme', 'a'); + + options.append($('<li>').text('Choose the NIfTI file:')); + options.append($('<li>').append(upload)); + options.append($('<li>').text('Resolution:')); + options.append($('<li>').append($('<select>') + .attr('id', 'stl-attach-nifti-resolution') + .attr('data-theme', 'a') + .append($('<option>').attr('value', '256').text('256')) + .append($('<option>').attr('value', '128').text('128')) + .append($('<option>').attr('value', '512').text('512')))); + options.append($('<li>') + .append($('<input>') + .attr('id', 'stl-attach-nifti-smooth') + .attr('type', 'checkbox') + .attr('data-theme', 'a') + .attr('checked', '')) + .append($('<label>') + .attr('for', 'stl-attach-nifti-smooth') + .text('Smooth volume'))); + + options.append($('<li>').append( + $('<a>') + .attr('href', '#') + .attr('rel', 'close').attr('data-theme', 'b') + .text('Generate') + .click(function(e) { + e.preventDefault(); + + var fileInput = document.getElementById('stl-attach-nifti-upload'); + var resolution = $('#stl-attach-nifti-resolution').val(); + var smooth = $('#stl-attach-nifti-smooth').is(':checked'); + + if (fileInput.files.length == 0) { + alert('No NIfTI file was selected'); + return; + } + + reader = new FileReader(); + reader.onload = function() { + + // https://github.com/axios/axios/issues/513 + var nifti = reader.result; + var niftiBase64 = btoa(new Uint8Array(nifti).reduce((data, byte) => data + String.fromCharCode(byte), '')); + + $.ajax({ + url: '../stl/encode-nifti', + type: 'POST', + data: JSON.stringify({ + 'Nifti' : 'data:application/octet-stream;base64,' + niftiBase64, + 'ParentStudy' : studyId, + 'Smooth' : smooth, + 'Resolution' : parseInt(resolution, 10) + }), + dataType: 'json', + success: function(s) { + $.mobile.changePage('#series?uuid=' + s.ParentSeries, { + allowSamePageTransition: true + }); + }, + error: function() { + alert('Error while generating the 3D model'); + } + }); + + }; + + reader.readAsArrayBuffer(fileInput.files[0]); + }))); + + // Launch the dialog + $('#dialog').simpledialog2({ + mode: 'blank', + animate: false, + headerText: 'Generate 3D model', + headerClose: true, + forceInput: false, + width: '100%', + blankContent: options + }); + }); + } +} + + +function AddImportSTLButton(studyId) { + if (${HAS_CREATE_DICOM_STL}) { + $('#stl-attach-instance').remove(); + + var instance = $('<a>') + .attr('id', 'stl-attach-instance') + .attr('data-role', 'button') + .attr('href', '#') + .attr('data-icon', 'search') + .attr('data-theme', 'e') + .text('Attach STL model') + .button(); + + instance.insertAfter($('#study-info')); + instance.click(function() { + + var options = $('<ul>') + .attr('data-divider-theme', 'd') + .attr('data-role', 'listview'); + + var upload = $('<input>') + .attr('type', 'file') + .attr('id', 'stl-attach-instance-upload') + .attr('data-theme', 'a'); + + options.append($('<li>').text('Choose the STL file:')); + options.append($('<li>').append(upload)); + + options.append($('<li>').text('Series description:')); + options.append($('<li>').append($('<input>') + .attr('type', 'text') + .attr('id', 'stl-attach-instance-description') + .attr('data-theme', 'b') + .val('Imported STL'))); + + options.append($('<li>').append( + $('<a>') + .attr('href', '#') + .attr('rel', 'close').attr('data-theme', 'b') + .text('Import') + .click(function(e) { + e.preventDefault(); + + var fileInput = document.getElementById('stl-attach-instance-upload'); + var description = $('#stl-attach-instance-description').val(); + + if (fileInput.files.length == 0) { + alert('No Instance file was selected'); + return; + } + + reader = new FileReader(); + reader.onload = function() { + + // https://github.com/axios/axios/issues/513 + var stl = reader.result; + var stlBase64 = btoa(new Uint8Array(stl).reduce((data, byte) => data + String.fromCharCode(byte), '')); + + $.ajax({ + url: '../tools/create-dicom', + type: 'POST', + data: JSON.stringify({ + 'Content' : 'data:model/stl;base64,' + stlBase64, + 'Parent' : studyId, + 'Tags' : { + 'SeriesDescription' : description + } + }), + dataType: 'json', + success: function(s) { + $.mobile.changePage('#series?uuid=' + s.ParentSeries, { + allowSamePageTransition: true + }); + }, + error: function() { + alert('Error while generating the 3D model'); + } + }); + + }; + + reader.readAsArrayBuffer(fileInput.files[0]); + }))); + + // Launch the dialog + $('#dialog').simpledialog2({ + mode: 'blank', + animate: false, + headerText: 'Attach STL', + headerClose: true, + forceInput: false, + width: '100%', + blankContent: options + }); + }); + } +} + + + $('#series').live('pagebeforeshow', function() { var seriesId = $.mobile.pageData.uuid; @@ -200,111 +409,7 @@ $('#study').live('pagebeforeshow', function() { - if (${HAS_CREATE_DICOM_STL}) { - var studyId = $.mobile.pageData.uuid; - - $('#stl-attach-nifti-study').remove(); - - var b = $('<a>') - .attr('id', 'stl-attach-nifti-study') - .attr('data-role', 'button') - .attr('href', '#') - .attr('data-icon', 'search') - .attr('data-theme', 'e') - .text('Attach NIfTI 3D model') - .button(); - - b.insertAfter($('#study-info')); - b.click(function() { - - var options = $('<ul>') - .attr('data-divider-theme', 'd') - .attr('data-role', 'listview'); - - var upload = $('<input>') - .attr('type', 'file') - .attr('id', 'stl-attach-nifti-study-upload') - .attr('data-theme', 'a'); - - options.append($('<li>').text('Choose the NIfTI file:')); - options.append($('<li>').append(upload)); - options.append($('<li>').text('Resolution:')); - options.append($('<li>').append($('<select>') - .attr('id', 'stl-attach-nifti-study-resolution') - .attr('data-theme', 'a') - .append($('<option>').attr('value', '256').text('256')) - .append($('<option>').attr('value', '128').text('128')) - .append($('<option>').attr('value', '512').text('512')))); - options.append($('<li>') - .append($('<input>') - .attr('id', 'stl-attach-nifti-study-smooth') - .attr('type', 'checkbox') - .attr('data-theme', 'a') - .attr('checked', '')) - .append($('<label>') - .attr('for', 'stl-attach-nifti-study-smooth') - .text('Smooth volume'))); - - options.append($('<li>').append( - $('<a>') - .attr('href', '#') - .attr('rel', 'close').attr('data-theme', 'b') - .text('Generate') - .click(function(e) { - e.preventDefault(); - - var fileInput = document.getElementById('stl-attach-nifti-study-upload'); - var resolution = $('#stl-attach-nifti-study-resolution').val(); - var smooth = $('#stl-attach-nifti-study-smooth').is(':checked'); - - if (fileInput.files.length == 0) { - alert('No NIfTI file was selected'); - return; - } - - reader = new FileReader(); - reader.onload = function() { - - // https://github.com/axios/axios/issues/513 - var nifti = reader.result; - var niftiBase64 = btoa(new Uint8Array(nifti).reduce((data, byte) => data + String.fromCharCode(byte), '')); - - $.ajax({ - url: '../stl/encode-nifti', - type: 'POST', - data: JSON.stringify({ - 'Nifti' : 'data:application/octet-stream;base64,' + niftiBase64, - 'ParentStudy' : studyId, - 'Smooth' : smooth, - 'Resolution' : parseInt(resolution, 10) - }), - dataType: 'json', - success: function(s) { - $.mobile.changePage('#series?uuid=' + s.ParentSeries, { - allowSamePageTransition: true - }); - }, - error: function() { - alert('Error while generating the 3D model'); - } - }); - - }; - - reader.readAsArrayBuffer(fileInput.files[0]); - }))); - - // Launch the dialog - $('#dialog').simpledialog2({ - mode: 'blank', - animate: false, - headerText: 'Generate 3D model', - headerClose: true, - forceInput: false, - width: '100%', - blankContent: options - }); - - }); - } + var studyId = $.mobile.pageData.uuid; + AddImportSTLButton(studyId); + AddGenerateFromNIfTIButton(studyId); });
--- a/Sources/Plugin.cpp Thu Apr 04 17:28:03 2024 +0200 +++ b/Sources/Plugin.cpp Thu Apr 04 18:05:13 2024 +0200 @@ -1887,6 +1887,10 @@ OrthancPlugins::RegisterRestCallback<EncodeNifti>("/stl/encode-nifti", true); } + OrthancPlugins::OrthancConfiguration globalConfiguration; + OrthancPlugins::OrthancConfiguration configuration; + globalConfiguration.GetSection(configuration, "STL"); + // Extend the default Orthanc Explorer with custom JavaScript for STL std::string explorer; @@ -1895,6 +1899,7 @@ std::map<std::string, std::string> dictionary; dictionary["HAS_CREATE_DICOM_STL"] = (hasCreateDicomStl_ ? "true" : "false"); + dictionary["SHOW_NIFTI_BUTTON"] = (configuration.GetBooleanValue("NIfTI", false) ? "true" : "false"); explorer = Orthanc::Toolbox::SubstituteVariables(explorer, dictionary); OrthancPlugins::ExtendOrthancExplorer(ORTHANC_PLUGIN_NAME, explorer);