Mercurial > hg > orthanc-stl
changeset 36:13698d34e059
preparing to include O3DV
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 05 Apr 2024 07:42:06 +0200 |
parents | ee3bc8f7df5b |
children | 2cc9950018ab |
files | .hgignore CMakeLists.txt Sources/OrthancExplorer.js Sources/Plugin.cpp Sources/viewer.html Sources/viewer.js WebApplications/o3dv.html WebApplications/o3dv.js WebApplications/three.html WebApplications/three.js |
diffstat | 10 files changed, 264 insertions(+), 162 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgignore Thu Apr 04 20:37:08 2024 +0200 +++ b/.hgignore Fri Apr 05 07:42:06 2024 +0200 @@ -7,4 +7,5 @@ Three/three.js-*.tar.gz Three/dist i/ +s/ *.orig
--- a/CMakeLists.txt Thu Apr 04 20:37:08 2024 +0200 +++ b/CMakeLists.txt Fri Apr 05 07:42:06 2024 +0200 @@ -169,8 +169,10 @@ ##################################################################### EmbedResources( - VIEWER_HTML ${CMAKE_SOURCE_DIR}/Sources/viewer.html - VIEWER_JS ${CMAKE_SOURCE_DIR}/Sources/viewer.js + THREE_HTML ${CMAKE_SOURCE_DIR}/WebApplications/three.html + THREE_JS ${CMAKE_SOURCE_DIR}/WebApplications/three.js + O3DV_HTML ${CMAKE_SOURCE_DIR}/WebApplications/o3dv.html + O3DV_JS ${CMAKE_SOURCE_DIR}/WebApplications/o3dv.js ORTHANC_EXPLORER ${CMAKE_SOURCE_DIR}/Sources/OrthancExplorer.js )
--- a/Sources/OrthancExplorer.js Thu Apr 04 20:37:08 2024 +0200 +++ b/Sources/OrthancExplorer.js Fri Apr 05 07:42:06 2024 +0200 @@ -38,7 +38,7 @@ b.insertAfter($('#' + parent)); b.click(function() { if ($.mobile.pageData) { - window.open('../stl/app/viewer.html?instance=' + instanceId); + window.open('../stl/app/three.html?instance=' + instanceId); } }); }
--- a/Sources/Plugin.cpp Thu Apr 04 20:37:08 2024 +0200 +++ b/Sources/Plugin.cpp Fri Apr 05 07:42:06 2024 +0200 @@ -46,6 +46,7 @@ #include <vtkNew.h> +#include <boost/algorithm/string.hpp> #include <boost/thread/shared_mutex.hpp> #define ORTHANC_PLUGIN_NAME "stl" @@ -132,21 +133,21 @@ std::string file = request->groups[0]; - if (file == "viewer.html") + if (file == "three.html") { std::string s; - Orthanc::EmbeddedResources::GetFileResource(s, Orthanc::EmbeddedResources::VIEWER_HTML); + Orthanc::EmbeddedResources::GetFileResource(s, Orthanc::EmbeddedResources::THREE_HTML); OrthancPluginAnswerBuffer(OrthancPlugins::GetGlobalContext(), output, s.c_str(), s.size(), Orthanc::EnumerationToString(Orthanc::MimeType_Html)); } - else if (file == "viewer.js") + else if (file == "three.js") { std::string s; - Orthanc::EmbeddedResources::GetFileResource(s, Orthanc::EmbeddedResources::VIEWER_JS); + Orthanc::EmbeddedResources::GetFileResource(s, Orthanc::EmbeddedResources::THREE_JS); OrthancPluginAnswerBuffer(OrthancPlugins::GetGlobalContext(), output, s.c_str(), s.size(), Orthanc::EnumerationToString(Orthanc::MimeType_JavaScript)); } - else + else if (boost::starts_with(file, "libs/")) { - cache_.Answer(output, file); + cache_.Answer(output, file.substr(5)); } }
--- a/Sources/viewer.html Thu Apr 04 20:37:08 2024 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,23 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> - <head> - <meta charset="utf-8"> - <title>Orthanc STL viewer</title> - <style> - body { margin: 0; } - </style> - </head> - <body> - <script async src="es-module-shims.js"></script> - - <script type="importmap"> - { - "imports": { - "three": "./three.module.min.js" - } - } - </script> - - <script type="module" src="./viewer.js"></script> - </body> -</html>
--- a/Sources/viewer.js Thu Apr 04 20:37:08 2024 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,130 +0,0 @@ -/** - * 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/>. - **/ - - -import * as THREE from 'three'; - -import { OrbitControls } from './OrbitControls.js'; -import { STLLoader } from './STLLoader.js'; - - -// 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'); - - -const scene = new THREE.Scene(); - -const renderer = new THREE.WebGLRenderer(); -renderer.setSize(window.innerWidth, window.innerHeight); -document.body.appendChild(renderer.domElement); - -const material = new THREE.MeshPhongMaterial(); - -const light = new THREE.AmbientLight(0x555555); -scene.add(light); - -const light2 = new THREE.PointLight(0xaaaaaa, 2); -light2.position.set(10, 10, 10); -scene.add(light2); - -const loader = new STLLoader() -loader.load( - //'../../instances/' + instanceId + '/content/0042-0011', - '../../instances/' + instanceId + '/stl', - function (geometry) { - const frustumSize = 200; - - geometry.computeBoundingBox(); - geometry.translate(-(geometry.boundingBox.min.x + geometry.boundingBox.max.x) / 2.0, - -(geometry.boundingBox.min.y + geometry.boundingBox.max.y) / 2.0, - -(geometry.boundingBox.min.z + geometry.boundingBox.max.z) / 2.0); - - var maxSize = Math.max(geometry.boundingBox.max.x - geometry.boundingBox.min.x, - geometry.boundingBox.max.y - geometry.boundingBox.min.y, - geometry.boundingBox.max.z - geometry.boundingBox.min.z); - - geometry.scale((frustumSize / 2.0) / maxSize, - (frustumSize / 2.0) / maxSize, - (frustumSize / 2.0) / maxSize); - - const mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - const aspect = window.innerWidth / window.innerHeight; - const camera = new THREE.OrthographicCamera( - frustumSize * aspect / - 2, frustumSize * aspect / 2, - frustumSize / 2, frustumSize / - 2, 1, frustumSize); - - camera.position.z = 100; - - const controls = new OrbitControls(camera, renderer.domElement); - - //controls.update() must be called after any manual changes to the camera's transform - controls.update(); - - function animate() { - requestAnimationFrame(animate); - - // required if controls.enableDamping or controls.autoRotate are set to true - controls.update(); - light2.position.copy(camera.position); - - renderer.render(scene, camera); - } - - animate(); - - function onWindowResize() { - const aspect = window.innerWidth / window.innerHeight; - camera.left = - frustumSize * aspect / 2; - camera.right = frustumSize * aspect / 2; - camera.top = frustumSize / 2; - camera.bottom = - frustumSize / 2; - camera.updateProjectionMatrix(); - renderer.setSize(window.innerWidth, window.innerHeight); - } - - window.addEventListener('resize', onWindowResize ); - }, - function (xhr) { - }, - function (error) { - console.log(error); - } -);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WebApplications/o3dv.html Fri Apr 05 07:42:06 2024 +0200 @@ -0,0 +1,37 @@ +<!DOCTYPE html> +<html> + + <head> + <meta http-equiv="content-type" content="text/html;charset=utf-8"> + <meta name="viewport" content="width=device-width, user-scalable=no"> + + <title>Orthanc STL viewer (O3DV)</title> + + <style> + html, body { + width: 100%; + height: 100%; + margin: 0px; + border: 0; + overflow: hidden; + display: block; + } + + div.online_3d_viewer { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + } + </style> + </head> + + <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.js"></script> + </body> + +</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WebApplications/o3dv.js Fri Apr 05 07:42:06 2024 +0200 @@ -0,0 +1,61 @@ +/** + * 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/>. + **/ + + +// 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'); + + +window.addEventListener ('load', () => { + let parentDiv = document.getElementById ('viewer'); + + let viewer = new OV.EmbeddedViewer (parentDiv, { + /*backgroundColor : new OV.RGBAColor (255, 255, 255, 255), + defaultColor : new OV.RGBColor (200, 200, 200), + edgeSettings : new OV.EdgeSettings (false, new OV.RGBColor (0, 0, 0), 1)*/ + + backgroundColor : new OV.RGBAColor (0, 0, 0, 255), + defaultColor : new OV.RGBColor (200, 200, 200), + edgeSettings : new OV.EdgeSettings (false, new OV.RGBColor (255, 255, 255), 1) + }); + + viewer.LoadModelFromInputFiles ([ + new OV.InputFile('model.stl', OV.FileSource.Url, '../../instances/' + instance + '/stl'), + ]); +});
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WebApplications/three.html Fri Apr 05 07:42:06 2024 +0200 @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <title>Orthanc STL viewer (Three)</title> + <style> + body { margin: 0; } + </style> + </head> + <body> + <script async src="libs/es-module-shims.js"></script> + + <script type="importmap"> + { + "imports": { + "three": "./libs/three.module.min.js" + } + } + </script> + + <script type="module" src="./three.js"></script> + </body> +</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WebApplications/three.js Fri Apr 05 07:42:06 2024 +0200 @@ -0,0 +1,130 @@ +/** + * 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/>. + **/ + + +import * as THREE from 'three'; + +import { OrbitControls } from './libs/OrbitControls.js'; +import { STLLoader } from './libs/STLLoader.js'; + + +// 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'); + + +const scene = new THREE.Scene(); + +const renderer = new THREE.WebGLRenderer(); +renderer.setSize(window.innerWidth, window.innerHeight); +document.body.appendChild(renderer.domElement); + +const material = new THREE.MeshPhongMaterial(); + +const light = new THREE.AmbientLight(0x555555); +scene.add(light); + +const light2 = new THREE.PointLight(0xaaaaaa, 2); +light2.position.set(10, 10, 10); +scene.add(light2); + +const loader = new STLLoader() +loader.load( + //'../../instances/' + instanceId + '/content/0042-0011', + '../../instances/' + instanceId + '/stl', + function (geometry) { + const frustumSize = 200; + + geometry.computeBoundingBox(); + geometry.translate(-(geometry.boundingBox.min.x + geometry.boundingBox.max.x) / 2.0, + -(geometry.boundingBox.min.y + geometry.boundingBox.max.y) / 2.0, + -(geometry.boundingBox.min.z + geometry.boundingBox.max.z) / 2.0); + + var maxSize = Math.max(geometry.boundingBox.max.x - geometry.boundingBox.min.x, + geometry.boundingBox.max.y - geometry.boundingBox.min.y, + geometry.boundingBox.max.z - geometry.boundingBox.min.z); + + geometry.scale((frustumSize / 2.0) / maxSize, + (frustumSize / 2.0) / maxSize, + (frustumSize / 2.0) / maxSize); + + const mesh = new THREE.Mesh(geometry, material); + scene.add(mesh); + + const aspect = window.innerWidth / window.innerHeight; + const camera = new THREE.OrthographicCamera( + frustumSize * aspect / - 2, frustumSize * aspect / 2, + frustumSize / 2, frustumSize / - 2, 1, frustumSize); + + camera.position.z = 100; + + const controls = new OrbitControls(camera, renderer.domElement); + + //controls.update() must be called after any manual changes to the camera's transform + controls.update(); + + function animate() { + requestAnimationFrame(animate); + + // required if controls.enableDamping or controls.autoRotate are set to true + controls.update(); + light2.position.copy(camera.position); + + renderer.render(scene, camera); + } + + animate(); + + function onWindowResize() { + const aspect = window.innerWidth / window.innerHeight; + camera.left = - frustumSize * aspect / 2; + camera.right = frustumSize * aspect / 2; + camera.top = frustumSize / 2; + camera.bottom = - frustumSize / 2; + camera.updateProjectionMatrix(); + renderer.setSize(window.innerWidth, window.innerHeight); + } + + window.addEventListener('resize', onWindowResize ); + }, + function (xhr) { + }, + function (error) { + console.log(error); + } +);