Creating a custom 3D Slicer

Hi.
I wish to create a custom Slicer. Something like http://salt.slicer.org/
I have build Slicer v4.11.20210226 on my machine (ubuntu 20.04) before.
Now, I wish to customize the application. Change the name, logo, looks, modules, etc.
I have been able to change logos quiet easily. Just change the logos and build Slicer, I got it to work. But, I’m still unclear on how to make other changes.

I found a custom app template SlicerCustomAppTemplate/{{cookiecutter.project_name}} at master · KitwareMedical/SlicerCustomAppTemplate · GitHub
I tried to use this and ended up with many errors. This page hadn’t been updated in a couple of years.

Please guide me to other resources/instructions to create a customized 3D Slicer v4.11.20210226 with changes in style, logo, name, etc.

Thanks

The custom app template you linked works well. It is actually live and maintained; it was updated last month. GitHub - KitwareMedical/SlicerCustomAppTemplate: Template to be used as a starting point for creating a custom 3D Slicer application

Hi. So, I’ve tried using the SlicerCustomAppTemplate again. I was getting some errors but maybe its because I’m doing something wrong.

First, I used ‘cookiecutter gh:KitwareMedical/SlicerCustomAppTemplate’ to create the template.
Then, I followed the steps given in https://www.kitware.com/slicercat-creating-custom-applications-based-on-3d-slicer/ to change any settings if necessary.

Finally, I build it using instructions from Build Instructions — 3D Slicer documentation.

It runs for a couple of hours and build fails. These are the errors that I am getting

In order to make sure that my logos are not the cause of the problem, I have not changed anything. Just let the default logos be. In fact, the only change I made is the Slicer tag to v4.11.20210226 in the CMakeLists.txt file and started the build process.

I don’t understand what caused this error. Please help me decode this. It will be very helpful for my build.

I have checked qMRMLWidget class and found the following.
qMRMLWidget Class in 4.13 has a Static Public Member Function called pixmapFromIcon as seen here Slicer: qMRMLWidget Class Reference.

But, I want to build Slicer 4.11.20210226. It doesn’t seem to have pixmapFromIcon as seen here Slicer: qMRMLWidget Class Reference

Is my analysis correct?
What steps can I take to get this working?

After running the following:

pip install cookiecutter jinja2-github
cookiecutter gh:KitwareMedical/SlicerCustomAppTemplate

the Slicer SHA injected in the top-level CMakeLists.txt will correspond to the latest one and you should keep it as such.

The template is maintained up-to-date so that it builds against the latest version of Slicer.

The Step 2: Customize Slicer using CMake options of the blog provides some general information and is not intended to prescribe a specific SHA.

Could you indicate the value used in the top level of you your CMakeLists.txt ?

Creating a custom app is a pretty advanced topic, meaning that you do it when you need total control of the build process, dependency libraries, and app behavior. With this much control it means there are a million options to consider and these need to be kept up to date with changes at various levels, so only the latest code versions are maintained and most likely to work so you should always start there before trying to customize.

I want to build Slicer 4.11.20210226

Considering we will soon release Slicer 5.0 (see milestone here), I suggest you build your application using the latest version (basically the one injected by default in the CMakeLists.txt)

Is there a specific reason for using the “older” version ?

Ultimately, if you would like to create a custom app based on an older version of Slicer, you would have to revert changes added to the template that were introduced to support the latest one.

1 Like

So, I have tried to build it again. This time, I didn’t want to change anything. Hence, I used the default git tag in the top level CMakeLists.txt which was the latest commit in Slicer git repository. I have made no other changes to the file. In fact, I just did ‘cookiecutter gh:KitwareMedical/SlicerCustomAppTemplate’ with the name as SSLIP. Then, I created another directory named SSLIP-rel. I performed cmake. Then, make.

However, even without making any changes to the SlicerCustomAppTemplate, I am still unable to complete the build.
This is the latest error that I got.

It says that Slicer_MAIN_PROJECT_WC_REVISION is mandatory. What am I doing wrong?

I wanted to build custom Slicer based on v4.11.20210226 because it is currently the stable version. v4.13 is in preview release. It is not essential that I build using this version only.
After reading your comments, I have tried to build the latest one, but still got some build errors. I posted a photo of those in this forum.

I am writing in detail the steps that I followed to build custom Slicer. Please correct me if I am wrong.
Step1: cookiecutter gh:KitwareMedical/SlicerCustomAppTemplate. Then I get prompt in terminal to fill in application name, project name etc. which I have filled in accordingly. The name of the directory that is created is called SSLIP.
At this step I would normally make changes to CMakeLists.txt, logos, etc. But to make sure that I am not changing anything important, I have not touched any file and proceeded to the next step.

Step2: created another directory at the same level of SSLIP called SSLIP-rel.

Step3: Inside SSLIP-rel, I opened a terminal and entered the following command.
cmake -DCMAKE_BUILD_TYPE:STRING=Release …/SSLIP

Step4: Then I did make.
The exact command I used is make 2>&1 >attempt11_output.log. This is to redirect the output to the log file.

The build runs for a couple of hours and then crashes with errors.

Can you please share errors.

Mostly we get error because of long file path.
If you got error because of long file path then try to have only one character named folder.

I shared the error above in this forum. I took a screenshot and the image is called attempt11_error.

It shows CMake Error: Slicer_MAIN_PROJECT_WC_REVISION is mandatory

It turns out the root cause is outlined earlier in the error message:

image

Nitpick: In the future, make sure to copy/paste the text of the error. It makes copy/pasting possible and speedup the process of trying to understand the problem.

Solution

Consider running git init in the SSLIP source tree and adding at least one commit.

Background

Error is report by the module SlicerConfigureVersionHeaderTarget expecting a revision to be set.

Original issue and possible discussion have been summarized here:

Thank you for the advice. I ran git init and added a commit. I was successfully able to build Slicer.

However, I came into some problems.
Problem1: I turned Slicer_BUILD_EXTENSIONMANAGER_SUPPORT ON in the top level CMakeLists.txt in the SlicerCustomAppTemplate as I wanted to download some extensions.
The built Slicer has the Extension Manager. But no matter which extension I try to install, it doesn’t work.

For example, I have tried to install the SlicerVMTK extension. I even get a pop-up at the top right of the screen saying ‘Installed Extension SlicerVMTK’. But, the restart button at the bottom right corner of the screen doesn’t get activated. When I close and reopen Slicer, I cannot find the extension anywhere.

This is what I see in terminal when I try to install the SlicerVMTK extension.

libpng warning: iCCP: known incorrect sRGB profile
Retrieving extension metadata [ extensionId: 61cc101f342a877cb3f28a6a]
Retrieving extension files [ extensionId: 61cc101f342a877cb3f28a6a ]
Downloading extension [ item_id: 61cc101f342a877cb3f28a6a, file_id: 61ceb486342a877cb3f3dc34]
Installed extension SlicerVMTK (61cc101f342a877cb3f28a6a) revision 8e3fdf6
QPixmap::scaled: Pixmap is a null pixmap
“” 1 “JQuery not loaded - Failed to trigger webkitvisibilitychange”

But, the files are downloaded to the extensions folder. The same thing is happening with all the extensions.

Problem2: I have written some Effects in Segment Editor which also don’t seem to be working in the customized Slicer, but were working for me before. Note: I have written and used the effects in Slicer v4.11.20210226 but the custom built Slicer is the latest commit (v4.13). Could this be the reason?

Problem3: In my laptop (where the custom Slicer was built), I am able to launch the application successfully. It leads to the Slicer application home screen.

Then, I packaged the application (using make package). I am still able to launch the application. However, when I share the custom built Slicer application with someone else, they are unable to launch the application.
Errors related to ‘libqt5’ are showing up.

libqt5_error1

Thinking that there might have been some problem with the build, I tried building Slicer again. This time I got the following error.
libqt5_error2

In the directory where I have built Slicer, I searched for these shared object libraries, but I could not find them. However, the application still launches on my computer.
Is there anything wrong with my build process?
What changes do I need to make to solve this problem?

I figured out that the new laptop on which Slicer is expected to run on also needs to have the support libraries installed as it does not come as part of superbuild as explained in GNU/Linux systems — 3D Slicer documentation.

Once I installed these using the following commands, Slicer successfully launched.

sudo apt update && sudo apt install git subversion build-essential cmake cmake-curses-gui cmake-qt-gui \
  qt5-default qtmultimedia5-dev qttools5-dev libqt5xmlpatterns5-dev libqt5svg5-dev qtwebengine5-dev qtscript5-dev \
  qtbase5-private-dev libqt5x11extras5-dev libxt-dev

However, is it possible to get rid of these requirements and get them with the superbuild itself? When I download Slicer from the website, I don’t need these support libraries to run the application. Everything comes neatly packaged. Is it possible for me to do the same for custom Slicer build?

Solution: I now understand that if I build Slicer, then I have to build the extensions myself. I cannot install them through the extension manager due to ABI compatibility issues. Using the instructions from Extensions — 3D Slicer documentation, I was able to successfully build a custom Slicer application with vmtk extension as shown in the figure below.

This creates an executable named ‘SlicerWithSlicerVMTK’ which I am able to run.
However, I now want to package this just like I would package Slicer using make package. This is what I want to achieve.

To achieve this, I would normally to go the superbuild directory and run the command make package.

But, how do I package this now that I have an executable with SlicerVMTK?

Also, why has the name of the executable changed to ‘SlicerWithSlicerVMTK’. I want the name to be SSLIP. This is what I used in the customApplicationTemplate to build custom SLicer.

Thanks

You could do the following:

  1. Create a custom application leveraging KitwareMedical/SlicerCustomAppTemplate
  2. Bundle the extension looking at the example in the top-level CMakeLists.txt of the custom application.

when I share the custom built Slicer application with someone else, they are unable to launch the application.

Consider using the latest docker image described at GitHub - Slicer/SlicerBuildEnvironment: A repository of scripts to set up a Slicer build environment.

I have tried to do the same. I just uncommented the lines for bundling the extension in the top-level CMakeLists.txt of the custom application and I got the following error.

CMake Error: list sub-command insert requires at least three arguments.

This is what I have in the top-level CMakeLists.txt file.

# Enable/Disable Slicer custom modules: To create a new module, use the SlicerExtensionWizard.
set(Slicer_EXTENSION_SOURCE_DIRS
  #${CTFFR_SOURCE_DIR}/Modules/CLI/MyCLIModule
  #${CTFFR_SOURCE_DIR}/Modules/Loadable/MyLoadableModule
  ${CTFFR_SOURCE_DIR}/Modules/Scripted/Home
  )

# Add remote extension source directories

# SlicerOpenIGTLink
set(extension_name "SlicerOpenIGTLink")
set(${extension_name}_SOURCE_DIR "${CMAKE_BINARY_DIR}/${extension_name}")
FetchContent_Populate(${extension_name}
  SOURCE_DIR     ${${extension_name}_SOURCE_DIR}
  GIT_REPOSITORY ${EP_GIT_PROTOCOL}://github.com/openigtlink/SlicerOpenIGTLink.git
  GIT_TAG        2b92f7b1ffe02403109b671f28424e8770e902a0
  GIT_PROGRESS   1
  QUIET
  )
list(APPEND Slicer_EXTENSION_SOURCE_DIRS ${${extension_name}_SOURCE_DIR})

# Add Slicer sources
add_subdirectory(${slicersources_SOURCE_DIR} ${slicersources_BINARY_DIR})

I haven’t changed any other part of the file.
Please suggest what changes I need to make to get this working.