# HG changeset patch # User Sebastien Jodogne # Date 1712672982 -7200 # Node ID 5a3c238575f85643e6e112b528752f887190af6c # Parent 89bb195dfbc05c67d6bf85d85695f193becf2d3f documentation of stl diff -r 89bb195dfbc0 -r 5a3c238575f8 Sphinx/source/plugins/ohif.rst --- a/Sphinx/source/plugins/ohif.rst Sat Apr 06 18:10:09 2024 +0200 +++ b/Sphinx/source/plugins/ohif.rst Tue Apr 09 16:29:42 2024 +0200 @@ -64,7 +64,7 @@ download `__. Pre-compiled binaries for `Microsoft Windows `__ -and `macOS ` are available as well. +and `macOS `__ are available as well. Furthermore, the :ref:`Docker images ` ``jodogne/orthanc-plugins`` and ``orthancteam/orthanc`` also contain the diff -r 89bb195dfbc0 -r 5a3c238575f8 Sphinx/source/plugins/stl.rst --- a/Sphinx/source/plugins/stl.rst Sat Apr 06 18:10:09 2024 +0200 +++ b/Sphinx/source/plugins/stl.rst Tue Apr 09 16:29:42 2024 +0200 @@ -13,22 +13,254 @@ This **official** plugin by the `ICTEAM institute of UCLouvain `__ extends Orthanc with support for `Encapsulated 3D Manufacturing Model IODs -`_, -for the moment limited to `STL files +`_. +As of release 1.0 of the plugin, this support is limited to `STL files `__. The plugin allows to attach STL files to existing DICOM studies and to generate a STL mesh from structure sets (i.e., DICOM RT-STRUCT) or from `NIfTI binary volumes `__. -The description of these features is `available as a paper +A high-level description of these features is `available as a paper `__. +Importantly, any creation of a STL file requires the version of +Orthanc to be above or equal to 1.12.1. + **For researchers**: `Please cite this paper `__. -Usage ------ +Compilation +----------- + +.. highlight:: bash + +Official releases can be `downloaded from the Orthanc homepage +`__. As +an alternative, the `repository containing the source code +`__ can be accessed +using Mercurial. + +The procedure to compile this plugin is similar of that for the +:ref:`core of Orthanc `. The following commands should work +on most GNU/Linux distributions, provided Docker is installed:: + + $ mkdir Build + $ cd Build + $ ../Resources/CreateJavaScriptLibraries.sh + $ cmake .. -DSTATIC_BUILD=ON -DCMAKE_BUILD_TYPE=Release + $ make + +The compilation will produce a shared library ``libOrthancSTL.so`` +that contains the STL plugin for Orthanc. + +Pre-compiled Linux Standard Base (LSB) binaries `are available for +download `__. + +Pre-compiled binaries for `Microsoft Windows `__ +and `macOS `__ are available as well. + +Furthermore, the :ref:`Docker images ` +``jodogne/orthanc-plugins`` and ``orthancteam/orthanc`` also contain the +plugin. Debian and Ubuntu packages can be found in the +:ref:`standalone repository ` +``https://debian.orthanc-labs.com/``. + + +.. _stl_orthanc_explorer: + +Usage using Orthanc Explorer +---------------------------- + +The plugin extends the default :ref:`Orthanc Explorer +` Web interface with some new features. + + +.. _stl_attach: + +Attach STL file +^^^^^^^^^^^^^^^ + +An existing STL file can be attached to an existing DICOM study by +clicking on the "*Attach STL model*" yellow button: + +.. image:: stl/attach.png + :align: center + :width: 480 + +After selecting the STL file, entering a series description, and +clicking on the "*Import*" button, Orthanc creates a new DICOM +instance that embeds the STL file. Orthanc Explorer then automatically +opens the parent DICOM series containing the newly created DICOM STL +instance. A button entitled "*STL viewer*" can then be used to render +the STL: + +.. image:: stl/viewers.png + :align: center + :width: 480 + +Note how the STL plugin provides two viewers: + +* One `very basic custom viewer + `__ + with a small footprint that is directly built using the well-known + `Three.js library `__. + +* One slightly more advanced Web viewer that corresponds to + `Online3DViewer `__ running in `engine mode + `__. + +Here is a screenshot of a rendering using the Online3DViewer embedded +viewer: + +.. image:: stl/o3dv.png + :align: center + :width: 480 + + +.. _stl_rt_struct: + +Create STL from RT-STRUCT +^^^^^^^^^^^^^^^^^^^^^^^^^ + +The plugin can also be used to create a STL model from DICOM structure +sets (RT-STRUCT) that are routinely used in the context of +radiotherapy and nuclear medicine. To this end, open a DICOM RT-STRUCT +series using Orthanc Explorer: + +.. image:: stl/rt-struct.png + :align: center + :width: 480 + +As can be seen in this screenshot, an interface opens to choose the +structure set of interest, as well as the resolution of the +intermediate 3D bitmap that will be used to create the STL mesh. After +clicking on the "*Generate*" button, just like if :ref:`attaching an +existing STL file `, Orthanc Explorer will open the newly +created DICOM series and will propose to open a STL viewer. + +Internally, the 3D model is generated using the well-known `marching +cubes algorithm `__, as +implemented by the `VTK library `__ +by Kitware. Additional technical details can be found in the +`reference paper `__. + -WIP. +Create STL from binary NIfTI +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. highlight:: json + +Besides converting :ref:`RT-STRUCT to STL `, it is also +possible to convert a `NIfTI +`__ +3D binary bitmap into a STL mesh. As this use case is very specific, +it must be explicitly enabled in the :ref:`configuration file of +Orthanc ` as follows:: + + { + "Plugins" : [ "libOrthancSTL.so" ], + "STL" : { + "EnableNIfTI" : true + } + } + +If the ``EnableNIfTI`` option is present, a new button entitled +"*Attach NIfTI 3D model*" appears if opening an existing DICOM study: + +.. image:: stl/nifti.png + :align: center + :width: 480 + +This dialog box can be used to upload a NIfTI volume, and to generate +a 3D mesh with a specific resolution through the marching cubes +algorithm. + + +REST API +-------- + +Besides :ref:`extending the Orthanc Explorer user interface +`, the STL plugin adds dedicated routes to the +REST API of Orthanc. + + +DICOM-ization of STL files +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The creation of a DICOM instance that embeds an existing STL file can +be done using the ``/tools/create-dicom`` `route +`__ +in the built-in REST API of Orthanc (starting with version +1.12.1). This route can be used similarly to the :ref:`DICOM-ization +of PDF files `, with the `data URI scheme +`__ using ``model/stl`` +instead of ``application/pdf``. Here is a working example in Python 3: + +.. literalinclude:: stl/dicomize.py + :language: python + +Note that if the ``Parent`` field is not provided, a new DICOM study +will be created. + + +Extraction of STL from DICOM +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. highlight:: txt + +The route ``/instances/{id}/stl`` can be used to extract a STL from a +DICOM instance embedding a STL file, where ``id`` is the :ref:`Orthanc +identifier ` of the DICOM instance. For instance:: + + $ curl http://localhost:8042/instances/a88c4c3f-8f2bd6fd-02080bed-92ab6817-2cb3c26e/stl > /tmp/liver.stl + $ meshlab /tmp/liver.stl + +Evidently, an error is generated for DICOM instances that do not embed +a STL file. Note that ``meshlab`` is a well-known desktop application +to display STL file. + + +Listing structures of a DICOM RT-STRUCT +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. highlight:: txt + +The STL plugin provides the list of the names of the structures that +are part of a DICOM RT-STRUCT instance with :ref:`Orthanc identifier +` ``id`` at route ``/stl/rt-struct/{id}``. For instance:: + + $ curl http://localhost:8042/stl/rt-struct/f0dc2345-8f627774-f66083ae-a14d781e-1187b513 + [ + "Esophagus", + "Heart", + "Lung_L", + "Lung_R", + "SpinalCord" + ] + + +Generating a STL mesh from RT-STRUCT +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A DICOM RT-STRUCT instance can be converted into a DICOM STL instance +using the ``/stl/encode-rtstruct`` route provided by the STL plugin. +Here is a sample Python script: + +.. literalinclude:: stl/rt-struct.py + :language: python + +Note that contrarily to :ref:`the default user interface +`, this route can be used to encode multiple structure +sets as a single STL model. + + +Generating a STL mesh from NIfTI +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Here is a sample Python 3 script to convert a NIfTI file as a DICOM +STL instance: + +.. literalinclude:: stl/nifti.py + :language: python diff -r 89bb195dfbc0 -r 5a3c238575f8 Sphinx/source/plugins/stl/attach.png Binary file Sphinx/source/plugins/stl/attach.png has changed diff -r 89bb195dfbc0 -r 5a3c238575f8 Sphinx/source/plugins/stl/dicomize.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Sphinx/source/plugins/stl/dicomize.py Tue Apr 09 16:29:42 2024 +0200 @@ -0,0 +1,17 @@ +import base64 +import json +import requests + +with open('liver.stl', 'rb') as f: + stl = f.read() + +r = requests.post('http://localhost:8042/tools/create-dicom', json.dumps({ + 'Content' : 'data:model/stl;base64,%s' % base64.b64encode(stl).decode('ascii'), + 'Parent' : '6ed7e8a4-60deff42-5e22a424-2128629f-158d0b3a', + 'Tags' : { + 'SeriesDescription' : 'Liver' + } +})) + +r.raise_for_status() +instanceId = r.json() ['ID'] diff -r 89bb195dfbc0 -r 5a3c238575f8 Sphinx/source/plugins/stl/nifti.png Binary file Sphinx/source/plugins/stl/nifti.png has changed diff -r 89bb195dfbc0 -r 5a3c238575f8 Sphinx/source/plugins/stl/nifti.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Sphinx/source/plugins/stl/nifti.py Tue Apr 09 16:29:42 2024 +0200 @@ -0,0 +1,16 @@ +import base64 +import json +import requests + +with open('colon.nii.gz', 'rb') as f: + nifti = f.read() + +r = requests.post('http://localhost:8042/stl/encode-nifti', json.dumps({ + 'Nifti' : 'data:application/octet-stream;base64,' + base64.b64encode(nifti).decode('ascii'), + 'ParentStudy' : '6ed7e8a4-60deff42-5e22a424-2128629f-158d0b3a', + 'Smooth' : True, + 'Resolution' : 256, +})) + +r.raise_for_status() +instanceId = r.json() ['ID'] diff -r 89bb195dfbc0 -r 5a3c238575f8 Sphinx/source/plugins/stl/o3dv.png Binary file Sphinx/source/plugins/stl/o3dv.png has changed diff -r 89bb195dfbc0 -r 5a3c238575f8 Sphinx/source/plugins/stl/rt-struct.png Binary file Sphinx/source/plugins/stl/rt-struct.png has changed diff -r 89bb195dfbc0 -r 5a3c238575f8 Sphinx/source/plugins/stl/rt-struct.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Sphinx/source/plugins/stl/rt-struct.py Tue Apr 09 16:29:42 2024 +0200 @@ -0,0 +1,12 @@ +import json +import requests + +r = requests.post('http://localhost:8042/stl/encode-rtstruct', json.dumps({ + 'Instance' : 'f0dc2345-8f627774-f66083ae-a14d781e-1187b513', # ID of the RT-STRUCT DICOM instance + 'RoiNames' : [ 'Lung_L', 'Lung_R' ], + 'Smooth' : True, + 'Resolution' : 256 +})) + +r.raise_for_status() +instanceId = r.json() ['ID'] diff -r 89bb195dfbc0 -r 5a3c238575f8 Sphinx/source/plugins/stl/viewers.png Binary file Sphinx/source/plugins/stl/viewers.png has changed