Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
HarryHeres committed Aug 31, 2023
1 parent bf51d56 commit 8ba0988
Show file tree
Hide file tree
Showing 12 changed files with 392 additions and 0 deletions.
27 changes: 27 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
cmake_minimum_required(VERSION 3.16.3...3.19.7 FATAL_ERROR)

project(SlicerBoneMorphing)

#-----------------------------------------------------------------------------
# Extension meta-information
set(EXTENSION_HOMEPAGE "https://www.slicer.org/wiki/Documentation/Nightly/Extensions/SlicerBoneMorphing")
set(EXTENSION_CATEGORY "Examples")
set(EXTENSION_CONTRIBUTORS "Jan Heres (West Bohemian University)")
set(EXTENSION_DESCRIPTION "This extensions allows the user to generate and morph bone meshes based on its CT scans")
set(EXTENSION_ICONURL "https://www.example.com/Slicer/Extensions/SlicerBoneMorphing.png")
set(EXTENSION_SCREENSHOTURLS "https://www.example.com/Slicer/Extensions/SlicerBoneMorphing/Screenshots/1.png")
set(EXTENSION_DEPENDS "NA") # Specified as a list or "NA" if no dependencies

#-----------------------------------------------------------------------------
# Extension dependencies
find_package(Slicer REQUIRED)
include(${Slicer_USE_FILE})

#-----------------------------------------------------------------------------
# Extension modules
add_subdirectory(SlicerBoneMorphing)
## NEXT_MODULE

#-----------------------------------------------------------------------------
include(${Slicer_EXTENSION_GENERATE_CONFIG})
include(${Slicer_EXTENSION_CPACK})
Binary file added SlicerBoneMorphing.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 31 additions & 0 deletions SlicerBoneMorphing/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#-----------------------------------------------------------------------------
set(MODULE_NAME SlicerBoneMorphing)

#-----------------------------------------------------------------------------
set(MODULE_PYTHON_SCRIPTS
${MODULE_NAME}.py
)

set(MODULE_PYTHON_RESOURCES
Resources/Icons/${MODULE_NAME}.png
Resources/UI/${MODULE_NAME}.ui
)

#-----------------------------------------------------------------------------
slicerMacroBuildScriptedModule(
NAME ${MODULE_NAME}
SCRIPTS ${MODULE_PYTHON_SCRIPTS}
RESOURCES ${MODULE_PYTHON_RESOURCES}
WITH_GENERIC_TESTS
)

#-----------------------------------------------------------------------------
if(BUILD_TESTING)

# Register the unittest subclass in the main script as a ctest.
# Note that the test will also be available at runtime.
slicer_add_python_unittest(SCRIPT ${MODULE_NAME}.py)

# Additional build-time testing
add_subdirectory(Testing)
endif()
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
280 changes: 280 additions & 0 deletions SlicerBoneMorphing/Resources/UI/SlicerBoneMorphing.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,280 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>UI</class>
<widget class="qMRMLWidget" name="UI">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>279</width>
<height>286</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="ctkCollapsibleButton" name="inputsCollapsibleButton">
<property name="text">
<string>Inputs</string>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Input volume:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="qMRMLNodeComboBox" name="inputSelector">
<property name="toolTip">
<string>Pick the input to the algorithm.</string>
</property>
<property name="nodeTypes">
<stringlist notr="true">
<string>vtkMRMLScalarVolumeNode</string>
</stringlist>
</property>
<property name="showChildNodeTypes">
<bool>false</bool>
</property>
<property name="addEnabled">
<bool>false</bool>
</property>
<property name="removeEnabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Image threshold:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="ctkSliderWidget" name="imageThresholdSliderWidget">
<property name="toolTip">
<string>Set threshold value for computing the output image. Voxels that have intensities lower than this value will set to zero.</string>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="minimum">
<double>-100.000000000000000</double>
</property>
<property name="maximum">
<double>500.000000000000000</double>
</property>
<property name="value">
<double>0.500000000000000</double>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="ctkCollapsibleButton" name="outputsCollapsibleButton">
<property name="text">
<string>Outputs</string>
</property>
<layout class="QFormLayout" name="formLayout_4">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Thresholded volume:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="qMRMLNodeComboBox" name="outputSelector">
<property name="toolTip">
<string>Pick the output to the algorithm.</string>
</property>
<property name="nodeTypes">
<stringlist notr="true">
<string>vtkMRMLScalarVolumeNode</string>
</stringlist>
</property>
<property name="showChildNodeTypes">
<bool>false</bool>
</property>
<property name="noneEnabled">
<bool>true</bool>
</property>
<property name="addEnabled">
<bool>true</bool>
</property>
<property name="removeEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Inverted volume:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="qMRMLNodeComboBox" name="invertedOutputSelector">
<property name="toolTip">
<string>Result with inverted threshold will be written into this volume</string>
</property>
<property name="nodeTypes">
<stringlist notr="true">
<string>vtkMRMLScalarVolumeNode</string>
</stringlist>
</property>
<property name="showChildNodeTypes">
<bool>false</bool>
</property>
<property name="noneEnabled">
<bool>true</bool>
</property>
<property name="addEnabled">
<bool>true</bool>
</property>
<property name="removeEnabled">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="ctkCollapsibleButton" name="advancedCollapsibleButton">
<property name="text">
<string>Advanced</string>
</property>
<property name="collapsed">
<bool>true</bool>
</property>
<layout class="QFormLayout" name="formLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Invert threshold: </string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="invertOutputCheckBox">
<property name="toolTip">
<string>If checked, values above threshold are set to 0. If unchecked, values below are set to 0.</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QPushButton" name="applyButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Run the algorithm.</string>
</property>
<property name="text">
<string>Apply</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>ctkCollapsibleButton</class>
<extends>QWidget</extends>
<header>ctkCollapsibleButton.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>ctkSliderWidget</class>
<extends>QWidget</extends>
<header>ctkSliderWidget.h</header>
</customwidget>
<customwidget>
<class>qMRMLNodeComboBox</class>
<extends>QWidget</extends>
<header>qMRMLNodeComboBox.h</header>
</customwidget>
<customwidget>
<class>qMRMLWidget</class>
<extends>QWidget</extends>
<header>qMRMLWidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>UI</sender>
<signal>mrmlSceneChanged(vtkMRMLScene*)</signal>
<receiver>inputSelector</receiver>
<slot>setMRMLScene(vtkMRMLScene*)</slot>
<hints>
<hint type="sourcelabel">
<x>122</x>
<y>132</y>
</hint>
<hint type="destinationlabel">
<x>248</x>
<y>61</y>
</hint>
</hints>
</connection>
<connection>
<sender>UI</sender>
<signal>mrmlSceneChanged(vtkMRMLScene*)</signal>
<receiver>outputSelector</receiver>
<slot>setMRMLScene(vtkMRMLScene*)</slot>
<hints>
<hint type="sourcelabel">
<x>82</x>
<y>135</y>
</hint>
<hint type="destinationlabel">
<x>220</x>
<y>161</y>
</hint>
</hints>
</connection>
<connection>
<sender>UI</sender>
<signal>mrmlSceneChanged(vtkMRMLScene*)</signal>
<receiver>invertedOutputSelector</receiver>
<slot>setMRMLScene(vtkMRMLScene*)</slot>
<hints>
<hint type="sourcelabel">
<x>161</x>
<y>8</y>
</hint>
<hint type="destinationlabel">
<x>173</x>
<y>176</y>
</hint>
</hints>
</connection>
</connections>
</ui>
21 changes: 21 additions & 0 deletions SlicerBoneMorphing/SlicerBoneMorphing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from slicer.ScriptedLoadableModule import ScriptedLoadableModule

from src.main import *

class SlicerBoneMorphing(ScriptedLoadableModule):
"""Uses ScriptedLoadableModule base class, available at:
https://github.com/Slicer/Slicer/blob/master/Base/Python/slicer/ScriptedLoadableModule.py
"""

def __init__(self, parent):
ScriptedLoadableModule.__init__(self, parent)
self.parent.title = "Slicer Bone Mesh Module"
self.parent.categories = ["Examples"]
self.parent.dependencies = []
self.parent.contributors = ["Jan Heres"]
self.parent.helpText = """
This is a testing module help text.
"""
self.parent.acknowledgementText = """
Credits: Jan Heres
"""
1 change: 1 addition & 0 deletions SlicerBoneMorphing/Testing/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add_subdirectory(Python)
2 changes: 2 additions & 0 deletions SlicerBoneMorphing/Testing/Python/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

#slicer_add_python_unittest(SCRIPT ${MODULE_NAME}ModuleTest.py)
2 changes: 2 additions & 0 deletions SlicerBoneMorphing/src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
add_subdirectory(logic)
add_subdirectory(widget)
12 changes: 12 additions & 0 deletions SlicerBoneMorphing/src/logic/SlicerBoneMorphingLogic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from slicer.ScriptedLoadableModule import ScriptedLoadableModuleLogic


class SlicerBoneMorphingLogic(ScriptedLoadableModuleLogic):
"""This class should implement all the actual
computation done by your module. The interface
should be such that other python code can import
this class and make use of the functionality without
requiring an instance of the Widget.
Uses ScriptedLoadableModuleLogic base class, available at:
https://github.com/Slicer/Slicer/blob/master/Base/Python/slicer/ScriptedLoadableModule.py
"""
2 changes: 2 additions & 0 deletions SlicerBoneMorphing/src/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from .widget.SlicerBoneMorphingWidget import SlicerBoneMorphingWidget
from .logic.SlicerBoneMorphingLogic import SlicerBoneMorphingLogic
Loading

0 comments on commit 8ba0988

Please sign in to comment.