Mercurial > hg > orthanc-stl
changeset 62:b798387b085c
added 3DHOP viewer version 4.3
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Sat, 15 Jun 2024 16:08:52 +0200 |
parents | 5dc3f3dcc092 |
children | 1fd6d0f8fdc9 |
files | .hgignore .reuse/dep5 CMakeLists.txt NEWS Resources/CMake/3DHOP.cmake Resources/CMake/3dhop-4.3.patch Resources/CreateJavaScriptLibraries.sh Resources/EmbedStaticAssets.py Resources/Nexus.txt Resources/Nexus/threejs.html Sources/OrthancExplorer.js Sources/Plugin.cpp WebApplications/o3dv.html WebApplications/three.html WebApplications/three.js |
diffstat | 15 files changed, 300 insertions(+), 97 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgignore Wed May 22 15:35:07 2024 +0200 +++ b/.hgignore Sat Jun 15 16:08:52 2024 +0200 @@ -6,7 +6,8 @@ ThirdPartyDownloads/ JavaScriptLibraries/Online3DViewer-*.tar.gz JavaScriptLibraries/three.js-*.tar.gz -JavaScriptLibraries/dist +JavaScriptLibraries/dist-o3dv/ +JavaScriptLibraries/dist-three/ i/ s/ *.orig
--- a/.reuse/dep5 Wed May 22 15:35:07 2024 +0200 +++ b/.reuse/dep5 Sat Jun 15 16:08:52 2024 +0200 @@ -3,7 +3,7 @@ Upstream-Contact: Sebastien Jodogne <s.jodogne@gmail.com> Source: https://orthanc.uclouvain.be/ -Files: NEWS README WebApplications/o3dv.html WebApplications/three.html Resources/CreateThreeDist.txt Resources/Nexus.txt +Files: NEWS README WebApplications/o3dv.html WebApplications/three.html Resources/CreateThreeDist.txt Resources/Nexus.txt Resources/CMake/3dhop-4.3.patch Copyright: 2023-2024 Sebastien Jodogne, UCLouvain, Belgium License: GPL-3.0-or-later
--- a/CMakeLists.txt Wed May 22 15:35:07 2024 +0200 +++ b/CMakeLists.txt Sat Jun 15 16:08:52 2024 +0200 @@ -61,6 +61,9 @@ # New in release 1.1 set(ENABLE_NEXUS ON CACHE BOOL "Include support for Nexus 3D models") +# New in release 1.2 +set(ENABLE_3DHOP ON CACHE BOOL "Include support for 3DHOP viewer") + # Advanced parameters to fine-tune linking against system libraries SET(USE_SYSTEM_ORTHANC_SDK ON CACHE BOOL "Use the system version of the Orthanc plugin SDK") @@ -171,17 +174,28 @@ ## Create the autogenerated files ##################################################################### +if (ENABLE_3DHOP AND NOT + ENABLE_NEXUS) + message(FATAL_ERROR "3DHOP necessitates Nexus support") +endif() + set(EMBEDDED_RESOURCES + ORTHANC_EXPLORER ${CMAKE_SOURCE_DIR}/Sources/OrthancExplorer.js + + # These resources correspond to the "Basic viewer built using Three.js" THREE_HTML ${CMAKE_SOURCE_DIR}/WebApplications/three.html THREE_JS ${CMAKE_SOURCE_DIR}/WebApplications/three.js + + # These resources correspond to Online3DViewer O3DV_HTML ${CMAKE_SOURCE_DIR}/WebApplications/o3dv.html O3DV_JS ${CMAKE_SOURCE_DIR}/WebApplications/o3dv.js - ORTHANC_EXPLORER ${CMAKE_SOURCE_DIR}/Sources/OrthancExplorer.js ) -set(STATIC_ASSETS - ${CMAKE_SOURCE_DIR}/JavaScriptLibraries/dist - ) +set(STATIC_ASSETS_PREFIXES "o3dv") +set(STATIC_ASSETS_CONTENT "${CMAKE_SOURCE_DIR}/JavaScriptLibraries/dist-o3dv") + +list(APPEND STATIC_ASSETS_PREFIXES "basic-viewer") +list(APPEND STATIC_ASSETS_CONTENT "${CMAKE_SOURCE_DIR}/JavaScriptLibraries/dist-three") if (ENABLE_NEXUS) set(NEXUS_ASSETS_DIR ${AUTOGENERATED_DIR}/nexus) @@ -192,6 +206,11 @@ "https://orthanc.uclouvain.be/downloads/third-party-downloads/STL/three-84.js.gz" "${NEXUS_ASSETS_DIR}/three-84.js") + list(APPEND STATIC_ASSETS_PREFIXES "nexus") + list(APPEND STATIC_ASSETS_CONTENT + ${NEXUS_ASSETS_DIR} # This adds "three-84.js" that is needed by the Nexus viewer + ) + list(APPEND EMBEDDED_RESOURCES NEXUS_HTML ${CMAKE_SOURCE_DIR}/Resources/Nexus/threejs.html NEXUS_JS ${CMAKE_SOURCE_DIR}/Resources/Nexus/js/nexus.js @@ -200,13 +219,19 @@ NEXUS_TRACKBALL_JS ${CMAKE_SOURCE_DIR}/Resources/Nexus/js/TrackballControls.js ) - list(APPEND STATIC_ASSETS - ${NEXUS_ASSETS_DIR} - ) + add_definitions(-DORTHANC_ENABLE_NEXUS=1) - add_definitions(-DORTHANC_ENABLE_NEXUS=1) + if (ENABLE_3DHOP) + include(${CMAKE_SOURCE_DIR}/Resources/CMake/3DHOP.cmake) + add_definitions(-DORTHANC_ENABLE_3DHOP=1) + else() + add_definitions(-DORTHANC_ENABLE_3DHOP=0) + endif() else() - add_definitions(-DORTHANC_ENABLE_NEXUS=0) + add_definitions( + -DORTHANC_ENABLE_NEXUS=0 + -DORTHANC_ENABLE_3DHOP=0 + ) endif() EmbedResources(${EMBEDDED_RESOURCES}) @@ -218,10 +243,11 @@ ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/Resources/EmbedStaticAssets.py ${AUTOGENERATED_DIR}/StaticAssets.cpp - ${STATIC_ASSETS} + ${STATIC_ASSETS_PREFIXES} + ${STATIC_ASSETS_CONTENT} DEPENDS ${CMAKE_SOURCE_DIR}/Resources/EmbedStaticAssets.py - ${STATIC_ASSETS} + ${STATIC_ASSETS_CONTENT} ) list(APPEND AUTOGENERATED_SOURCES
--- a/NEWS Wed May 22 15:35:07 2024 +0200 +++ b/NEWS Sat Jun 15 16:08:52 2024 +0200 @@ -1,6 +1,8 @@ Pending changes in the mainline =============================== +* Added 3DHOP viewer (version 4.3) for Nexus models + Version 1.1 (2024-05-22) ======================== @@ -8,7 +10,7 @@ => Minimum SDK version: 1.2.0 <= * Support for DICOM-ization of adaptive 3D models in the Nexus format: - https://vcg.isti.cnr.it/nexus/ + https://vcg.isti.cnr.it/nexus/ (version 4.2 - Nexus 2018) Version 1.0 (2024-04-06)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/CMake/3DHOP.cmake Sat Jun 15 16:08:52 2024 +0200 @@ -0,0 +1,47 @@ +# SPDX-FileCopyrightText: 2023-2024 Sebastien Jodogne, UCLouvain, Belgium +# SPDX-License-Identifier: GPL-3.0-or-later + + +# STL plugin for Orthanc +# Copyright (C) 2023-2024 Sebastien Jodogne, UCLouvain, Belgium +# +# This program is free software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + + +DownloadPackage( + "9e0dee1e12668d5667aa9be0ae5937e0" + "https://orthanc.uclouvain.be/downloads/third-party-downloads/STL/3DHOP_4.3.zip" + "${CMAKE_BINARY_DIR}/3DHOP_4.3") + +set(3DHOP_DIR ${CMAKE_CURRENT_BINARY_DIR}/3dhop) +file(MAKE_DIRECTORY ${3DHOP_DIR}) + +file(COPY + ${CMAKE_BINARY_DIR}/3DHOP_4.3/minimal/3DHOP_all_tools.html + ${CMAKE_BINARY_DIR}/3DHOP_4.3/minimal/js + ${CMAKE_BINARY_DIR}/3DHOP_4.3/minimal/skins + ${CMAKE_BINARY_DIR}/3DHOP_4.3/minimal/stylesheet + DESTINATION + ${3DHOP_DIR} + ) + +execute_process( + COMMAND ${PATCH_EXECUTABLE} -p0 -N -i + ${CMAKE_CURRENT_LIST_DIR}/3dhop-4.3.patch + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + RESULT_VARIABLE Failure + ) + +list(APPEND STATIC_ASSETS_PREFIXES "3dhop") +list(APPEND STATIC_ASSETS_CONTENT ${3DHOP_DIR})
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/CMake/3dhop-4.3.patch Sat Jun 15 16:08:52 2024 +0200 @@ -0,0 +1,38 @@ +diff -urEb 3dhop.orig/3DHOP_all_tools.html 3dhop/3DHOP_all_tools.html +--- 3dhop.orig/3DHOP_all_tools.html 2024-06-15 15:43:28.329045772 +0200 ++++ 3dhop/3DHOP_all_tools.html 2024-06-15 15:50:04.629862005 +0200 +@@ -106,6 +106,25 @@ + </body> + + <script type="text/javascript"> ++// http://stackoverflow.com/a/21903119/881731 ++function GetUrlParameter(sParam) ++{ ++ var sPageURL = decodeURIComponent(window.location.search.substring(1)); ++ var sURLVariables = sPageURL.split('&'); ++ ++ for (var i = 0; i < sURLVariables.length; i++) { ++ var sParameterName = sURLVariables[i].split('='); ++ ++ if (sParameterName[0] === sParam) { ++ return sParameterName[1] === undefined ? '' : sParameterName[1]; ++ } ++ } ++ ++ return ''; ++}; ++ ++var instanceId = GetUrlParameter('instance'); ++ + var presenter = null; + + function setup3dhop() { +@@ -113,7 +132,7 @@ + + presenter.setScene({ + meshes: { +- "mesh_1" : { url: "models/gargo.nxz" } ++ "mesh_1" : { url: "../3dhop-instances/" + instanceId + ".nxz" } + }, + modelInstances : { + "model_1" : {
--- a/Resources/CreateJavaScriptLibraries.sh Wed May 22 15:35:07 2024 +0200 +++ b/Resources/CreateJavaScriptLibraries.sh Sat Jun 15 16:08:52 2024 +0200 @@ -22,8 +22,8 @@ # This command-line script uses the "npm" tool to populate the -# "JavaScriptLibraries/dist" folder. It uses Docker to this end, in -# order to be usable on our CIS. +# "JavaScriptLibraries/dist-o3dv" and "JavaScriptLibraries/dist-three" +# folders. It uses Docker to this end, in order to be usable on our CIS. set -ex @@ -40,12 +40,18 @@ ROOT_DIR=`dirname $(readlink -f $0)`/.. IMAGE=orthanc-stl-node -if [ -e "${ROOT_DIR}/JavaScriptLibraries/dist/" ]; then +if [ -e "${ROOT_DIR}/JavaScriptLibraries/dist-o3dv/" ]; then echo "Target folder is already existing, aborting" exit -1 fi -mkdir -p ${ROOT_DIR}/JavaScriptLibraries/dist/ +if [ -e "${ROOT_DIR}/JavaScriptLibraries/dist-three/" ]; then + echo "Target folder is already existing, aborting" + exit -1 +fi + +mkdir -p ${ROOT_DIR}/JavaScriptLibraries/dist-o3dv/ +mkdir -p ${ROOT_DIR}/JavaScriptLibraries/dist-three/ ( cd ${ROOT_DIR}/Resources/CreateJavaScriptLibraries && \ docker build --no-cache -t ${IMAGE} . ) @@ -70,7 +76,7 @@ --user $(id -u):$(id -g) \ -v ${ROOT_DIR}/Resources/CreateJavaScriptLibraries/build-o3dv.sh:/source/build-o3dv.sh:ro \ -v ${ROOT_DIR}/JavaScriptLibraries/${O3DV}.tar.gz:/source/${O3DV}.tar.gz:ro \ - -v ${ROOT_DIR}/JavaScriptLibraries/dist/:/target:rw \ + -v ${ROOT_DIR}/JavaScriptLibraries/dist-o3dv/:/target:rw \ ${IMAGE} \ bash /source/build-o3dv.sh ${O3DV} @@ -93,6 +99,6 @@ --user $(id -u):$(id -g) \ -v ${ROOT_DIR}/Resources/CreateJavaScriptLibraries/build-three.sh:/source/build-three.sh:ro \ -v ${ROOT_DIR}/JavaScriptLibraries/${THREE}.tar.gz:/source/${THREE}.tar.gz:ro \ - -v ${ROOT_DIR}/JavaScriptLibraries/dist/:/target:rw \ + -v ${ROOT_DIR}/JavaScriptLibraries/dist-three/:/target:rw \ ${IMAGE} \ bash /source/build-three.sh ${THREE}
--- a/Resources/EmbedStaticAssets.py Wed May 22 15:35:07 2024 +0200 +++ b/Resources/EmbedStaticAssets.py Sat Jun 15 16:08:52 2024 +0200 @@ -27,14 +27,37 @@ import sys if len(sys.argv) <= 2: - raise Exception('Usage: %s [target C++] [source folders]' % sys.argv[0]) + raise Exception('Usage: %s [target C++] [folder prefixes] [source folders]' % sys.argv[0]) SOURCES = sys.argv[2:] TARGET = sys.argv[1] -for source in SOURCES: - if not os.path.isdir(source): - raise Exception('Nonexistent source folder: %s' % source) +if len(SOURCES) % 2 != 0: + raise Exception('There must be an even number of sources') + +FILES = [] + +for i in range(len(SOURCES) // 2): + prefix = SOURCES[i] + if '/' in prefix: + raise Exception('Prefix cannot contain a slash, but found: %s' % prefix) + + folder = SOURCES[i + len(SOURCES) // 2] + + if not os.path.isdir(folder): + raise Exception('Nonexistent source folder: %s' % folder) + + for root, dirs, files in os.walk(folder): + files.sort() + dirs.sort() + + for f in files: + FILES.append({ + 'path' : os.path.join(root, f), + 'key' : prefix + '/' + os.path.relpath(os.path.join(root, f), folder), + }) + +FILES = sorted(FILES, key = lambda x: x['key']) def EncodeFileAsCString(f, variable, content): @@ -95,43 +118,35 @@ index = {} count = 0 - for source in SOURCES: - for root, dirs, files in os.walk(source): - files.sort() - dirs.sort() + for file in FILES: + variable = 'data_%06d' % count + count += 1 - for f in files: - fullPath = os.path.join(root, f) - relativePath = os.path.relpath(os.path.join(root, f), source) - variable = 'data_%06d' % count - - with open(fullPath, 'rb') as f: - content = f.read() + with open(file['path'], 'rb') as f: + content = f.read() - if sys.version_info < (3, 0): - # Python 2.7 - fileobj = io.BytesIO() - gzip.GzipFile(fileobj=fileobj, mode='w', mtime=0).write(content) - compressed = fileobj.getvalue() - else: - # Python 3.x - compressed = gzip.compress(content, mtime=0) + if sys.version_info < (3, 0): + # Python 2.7 + fileobj = io.BytesIO() + gzip.GzipFile(fileobj=fileobj, mode='w', mtime=0).write(content) + compressed = fileobj.getvalue() + else: + # Python 3.x + compressed = gzip.compress(content, mtime=0) - EncodeFileAsCString(g, variable, compressed) - WriteChecksum(g, variable + '_md5', content) + EncodeFileAsCString(g, variable, compressed) + WriteChecksum(g, variable + '_md5', content) - index[relativePath] = variable - - count += 1 + file['variable'] = variable g.write('void ReadStaticAsset(std::string& target, const std::string& path)\n') g.write('{\n') - for (path, variable) in sorted(index.items()): - g.write(' if (path == "%s")\n' % path) + for file in FILES: + g.write(' if (path == "%s")\n' % file['key']) g.write(' {\n') - g.write(' Uncompress(target, %s, sizeof(%s) - 1, %s_md5);\n' % (variable, variable, variable)) + g.write(' Uncompress(target, %s, sizeof(%s) - 1, %s_md5);\n' % (file['variable'], file['variable'], file['variable'])) g.write(' return;\n') g.write(' }\n\n') - g.write(' throw Orthanc::OrthancException(Orthanc::ErrorCode_InexistentItem, "Unknown Three.js resource: " + path);\n') + g.write(' throw Orthanc::OrthancException(Orthanc::ErrorCode_InexistentItem, "Unknown static asset: " + path);\n') g.write('}\n')
--- a/Resources/Nexus.txt Wed May 22 15:35:07 2024 +0200 +++ b/Resources/Nexus.txt Sat Jun 15 16:08:52 2024 +0200 @@ -10,7 +10,7 @@ is replaced by the line: -<script src="../app/libs/three-84.js"></script> +<script src="three-84.js"></script> WARNING: Releases 4.2.1, 4.2.2, and 4.3 do not seem to work anymore.
--- a/Resources/Nexus/threejs.html Wed May 22 15:35:07 2024 +0200 +++ b/Resources/Nexus/threejs.html Sat Jun 15 16:08:52 2024 +0200 @@ -5,7 +5,7 @@ <meta charset="utf-8"> <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> <style>body { margin: 0px; overflow: hidden; }</style> -<script src="../app/libs/three-84.js"></script> +<script src="three-84.js"></script> <script src="js/TrackballControls.js"></script> <script src="js/nexus.js"></script> <script src="js/nexus_three.js"></script>
--- a/Sources/OrthancExplorer.js Wed May 22 15:35:07 2024 +0200 +++ b/Sources/OrthancExplorer.js Sat Jun 15 16:08:52 2024 +0200 @@ -27,7 +27,7 @@ const STL_PLUGIN_SOP_CLASS_UID_RAW = '1.2.840.10008.5.1.4.1.1.66'; -function AddStlViewer(target, name, callback) { +function AddViewer(target, name, callback) { var li = $('<li>', { name: name, }).click(callback); @@ -59,11 +59,11 @@ .attr('data-divider-theme', 'd') .attr('data-role', 'listview'); - AddStlViewer(viewers, 'Basic viewer built using Three.js', function() { + AddViewer(viewers, 'Basic viewer built using Three.js', function() { window.open('../stl/app/three.html?instance=' + instanceId); }); - AddStlViewer(viewers, 'Online3DViewer', function() { + AddViewer(viewers, 'Online3DViewer', function() { window.open('../stl/app/o3dv.html?instance=' + instanceId); }); @@ -510,7 +510,32 @@ b.insertAfter($('#' + parent)); b.click(function() { - window.open('../stl/nexus/threejs.html?model=../../instances/' + instanceId + '/nexus'); + if (${IS_3DHOP_ENABLED}) { + var viewers = $('<ul>') + .attr('data-divider-theme', 'd') + .attr('data-role', 'listview'); + + AddViewer(viewers, 'Basic Nexus viewer', function() { + window.open('../stl/nexus/threejs.html?model=../../instances/' + instanceId + '/nexus'); + }); + + AddViewer(viewers, '3DHOP', function() { + window.open('../stl/3dhop/3DHOP_all_tools.html?instance=' + instanceId); + }); + + // Launch the dialog + $('#dialog').simpledialog2({ + mode: 'blank', + animate: false, + headerText: 'Choose Nexus viewer', + headerClose: true, + forceInput: false, + width: '100%', + blankContent: viewers + }); + } else { + window.open('../stl/nexus/threejs.html?model=../../instances/' + instanceId + '/nexus'); + } }); } }
--- a/Sources/Plugin.cpp Wed May 22 15:35:07 2024 +0200 +++ b/Sources/Plugin.cpp Sat Jun 15 16:08:52 2024 +0200 @@ -26,6 +26,10 @@ # error Macro ORTHANC_ENABLE_NEXUS must be defined #endif +#if !defined(ORTHANC_ENABLE_3DHOP) +# error Macro ORTHANC_ENABLE_3DHOP must be defined +#endif + #include "StructureSetGeometry.h" #include "STLToolbox.h" #include "VTKToolbox.h" @@ -177,9 +181,10 @@ const std::string file = request->groups[0]; - if (boost::starts_with(file, "libs/")) + if (boost::starts_with(file, "basic-viewer/") || + boost::starts_with(file, "o3dv/")) { - cache_.Answer(output, file.substr(5)); + cache_.Answer(output, file); } else { @@ -767,43 +772,50 @@ const std::string file = request->groups[0]; - Orthanc::EmbeddedResources::FileResourceId resourceId; - Orthanc::MimeType mimeType; - - if (file == "threejs.html") - { - resourceId = Orthanc::EmbeddedResources::NEXUS_HTML; - mimeType = Orthanc::MimeType_Html; - } - else if (file == "js/meco.js") + if (file == "three-84.js") { - resourceId = Orthanc::EmbeddedResources::NEXUS_MECO_JS; - mimeType = Orthanc::MimeType_JavaScript; - } - else if (file == "js/nexus.js") - { - resourceId = Orthanc::EmbeddedResources::NEXUS_JS; - mimeType = Orthanc::MimeType_JavaScript; - } - else if (file == "js/nexus_three.js") - { - resourceId = Orthanc::EmbeddedResources::NEXUS_THREE_JS; - mimeType = Orthanc::MimeType_JavaScript; - } - else if (file == "js/TrackballControls.js") - { - resourceId = Orthanc::EmbeddedResources::NEXUS_TRACKBALL_JS; - mimeType = Orthanc::MimeType_JavaScript; + cache_.Answer(output, "nexus/three-84.js"); } else { - OrthancPluginSendHttpStatusCode(OrthancPlugins::GetGlobalContext(), output, 404); - return; - } + Orthanc::EmbeddedResources::FileResourceId resourceId; + Orthanc::MimeType mimeType; - std::string s; - Orthanc::EmbeddedResources::GetFileResource(s, resourceId); - OrthancPluginAnswerBuffer(OrthancPlugins::GetGlobalContext(), output, s.c_str(), s.size(), Orthanc::EnumerationToString(mimeType)); + if (file == "threejs.html") + { + resourceId = Orthanc::EmbeddedResources::NEXUS_HTML; + mimeType = Orthanc::MimeType_Html; + } + else if (file == "js/meco.js") + { + resourceId = Orthanc::EmbeddedResources::NEXUS_MECO_JS; + mimeType = Orthanc::MimeType_JavaScript; + } + else if (file == "js/nexus.js") + { + resourceId = Orthanc::EmbeddedResources::NEXUS_JS; + mimeType = Orthanc::MimeType_JavaScript; + } + else if (file == "js/nexus_three.js") + { + resourceId = Orthanc::EmbeddedResources::NEXUS_THREE_JS; + mimeType = Orthanc::MimeType_JavaScript; + } + else if (file == "js/TrackballControls.js") + { + resourceId = Orthanc::EmbeddedResources::NEXUS_TRACKBALL_JS; + mimeType = Orthanc::MimeType_JavaScript; + } + else + { + OrthancPluginSendHttpStatusCode(OrthancPlugins::GetGlobalContext(), output, 404); + return; + } + + std::string s; + Orthanc::EmbeddedResources::GetFileResource(s, resourceId); + OrthancPluginAnswerBuffer(OrthancPlugins::GetGlobalContext(), output, s.c_str(), s.size(), Orthanc::EnumerationToString(mimeType)); + } } @@ -1005,6 +1017,25 @@ #endif +#if ORTHANC_ENABLE_3DHOP == 1 + +void Serve3DHOPAssets(OrthancPluginRestOutput* output, + const char* url, + const OrthancPluginHttpRequest* request) +{ + if (request->method != OrthancPluginHttpMethod_Get) + { + OrthancPluginSendMethodNotAllowed(OrthancPlugins::GetGlobalContext(), output, "GET"); + return; + } + + const std::string file = request->groups[0]; + cache_.Answer(output, "3dhop/" + file); +} + +#endif + + extern "C" { ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* context) @@ -1068,6 +1099,17 @@ OrthancPlugins::RegisterRestCallback<ExtractNexusModel>("/instances/([0-9a-f-]+)/nexus", true); OrthancPlugins::RegisterRestCallback<ServeNexusAssets>("/stl/nexus/(.*)", true); +#if ORTHANC_ENABLE_3DHOP == 1 + OrthancPlugins::RegisterRestCallback<Serve3DHOPAssets>("/stl/3dhop/(.*)", true); + + /** + * The 3DHOP viewer only supports ".nxs", ".nxz", and ".ply" extensions, + * as can be seen in the "minimal/js/presenter.js" file. Furthermore, it + * requires the extension to be part of the URL. + **/ + OrthancPlugins::RegisterRestCallback<ExtractNexusModel>("/stl/3dhop-instances/([0-9a-f-]+).nxz", true); +#endif + const bool hasCreateNexus_ = OrthancPlugins::CheckMinimalOrthancVersion(1, 9, 4); if (hasCreateNexus_) @@ -1108,6 +1150,7 @@ dictionary["HAS_CREATE_DICOM_STL"] = (hasCreateDicomStl ? "true" : "false"); dictionary["SHOW_NIFTI_BUTTON"] = (configuration.GetBooleanValue("EnableNIfTI", false) ? "true" : "false"); dictionary["IS_NEXUS_ENABLED"] = (enableNexus ? "true" : "false"); + dictionary["IS_3DHOP_ENABLED"] = ((ORTHANC_ENABLE_3DHOP == 1) ? "true" : "false"); FillOrthancExplorerCreatorVersionUid(dictionary); explorer = Orthanc::Toolbox::SubstituteVariables(explorer, dictionary);
--- a/WebApplications/o3dv.html Wed May 22 15:35:07 2024 +0200 +++ b/WebApplications/o3dv.html Sat Jun 15 16:08:52 2024 +0200 @@ -30,7 +30,7 @@ <body> <div class="online_3d_viewer" id="viewer"></div> - <script type="text/javascript" src="libs/o3dv.min.js"></script> + <script type="text/javascript" src="o3dv/o3dv.min.js"></script> <script type="text/javascript" src="o3dv.js"></script> </body>
--- a/WebApplications/three.html Wed May 22 15:35:07 2024 +0200 +++ b/WebApplications/three.html Sat Jun 15 16:08:52 2024 +0200 @@ -8,12 +8,12 @@ </style> </head> <body> - <script async src="libs/es-module-shims.js"></script> + <script async src="basic-viewer/es-module-shims.js"></script> <script type="importmap"> { "imports": { - "three": "./libs/three.module.min.js" + "three": "./basic-viewer/three.module.min.js" } } </script>
--- a/WebApplications/three.js Wed May 22 15:35:07 2024 +0200 +++ b/WebApplications/three.js Sat Jun 15 16:08:52 2024 +0200 @@ -24,8 +24,8 @@ import * as THREE from 'three'; -import { OrbitControls } from './libs/OrbitControls.js'; -import { STLLoader } from './libs/STLLoader.js'; +import { OrbitControls } from './basic-viewer/OrbitControls.js'; +import { STLLoader } from './basic-viewer/STLLoader.js'; // http://stackoverflow.com/a/21903119/881731