I’m working on Slicer CAT where I need to display different 3D data (the data represent the geological objects) in XYZ domain where X, Y axes - has the meaning of geographic coordinates (meters) and Z - is the depth (zero is the ocean water level) or time (meters or milliseconds). Right handed coordinate system: X-to the east, Y-to the north, Z-out of the Earth.
I need to provide ability to zoom Z-axis independently from X and Y. That leads that the scales along X,Y will differ from Z-axis.
Maybe Slicer already has such opportunity? If not maybe you have some recommendations/links and especially should I implement it in Slicer core library via Slicer-github pull request or only in my Slicer CAT?
Yes, all of that should be pretty doable. You could have a look at SlicerAstro, which also adapted a lot of things to deal with different coordinate meanings so I’d think a lot of the hooks that @Davide_Punzo added will be of use to you.
I’m trying to build Slicer Astro but there are some things…
My slicer cat (named Colada) is in C:/C and the build folder C:/C/d.
Slicer Astro is in C:/A and the build folder C:/A/d.
Then I do (using IDE though the commands should be similar):
cd C:/A/d
cmake .. -DSlicer_DIR=C:/C/d/Slicer-build
cmake --build .
Then I can see that only SlicerAstroWelcome module is built. Can’t understand why…
How to add this extension to my Slicer CAT? Do I need to add all the path to Slicer Astro’s built modules (via `Edit->Application Settings->Modules->add)?
If I try to execute C:\A\d\SlicerWithSlicerAstro.exe in cmd I get:
PS C:\A\d> ./SlicerWithSlicerAstro.exe
error: File specified using --launcher-additional-settings argument does NOT exist ! [C:/A/d/AdditionalLauncherSettings.ini]
Usage
Colada [options]
Options
--launcher-help Display help
--launcher-version Show launcher version information
--launcher-verbose Verbose mode
--launch Specify the application to launch
--launcher-detach Launcher will NOT wait for the application to finish
--launcher-no-splash Hide launcher splash
--launcher-timeout Specify the time in second before the launcher kills the application. -1 means no timeout (default: -1)
--launcher-load-environment Specify the saved environment to load.
--launcher-dump-environment Launcher will print environment variables to be set, then exit
--launcher-show-set-environment-commands Launcher will print commands suitable for setting the parent environment (i.e. using 'eval' in a POSIX shell), then exit
--launcher-additional-settings Additional settings file to consider
--launcher-additional-settings-exclude-groups Comma separated list of settings groups that should NOT be overwritten by values in User and Additional settings. For example: General,Application,ExtraApplicationToLaunch
--launcher-ignore-user-additional-settings Ignore additional user settings
--launcher-generate-exec-wrapper-script Generate executable wrapper script allowing to set the environment
--launcher-generate-template Generate an example of setting file
--VisualStudioProject Open Visual Studio Slicer project with Slicer's DLL paths set up
--cmd Start cmd
--designer Start Qt designer using Slicer plugins
--VisualStudio Open Visual Studio with Slicer's DLL paths set up
PS C:\A\d>
I have installed Slicer Astro on Ubuntu, definately there are some useful features.
But I can’t find a way to make independent zooming along chosen axis…
Perhaps I postpone this task for a while and try get a little experience of writing/modifying Slcier’s widgets that are on the scene (on the picture, I think they are called qMRMLwidgets)
This question has come up before and I think setting slice field of view manually worked acceptably for that use case. However, it would be a much cleaner solution to simply apply a transform to the volume that scales it down along an axis.
I’m afraid that I need to work in XYZ coordinate system and all the data (not only volumes, but everything that is on scene) must be hard linked to axes… But thank you, I’m going to take some time to investigate the problem
You can apply linear transforms to all node types, not just volumes. Also, you can unregister default measurements in markups nodes and register your own custom measurements that take into account the changed scale when reporting length/area/volume values.
There should be examples for this in the script repository, but the idea is that you l get widgets via the layout manager and then manipulate child widgets using standard Qt API.
In SlicerAstro there isn’t s feature to zoom just one axis. However you could easily add in Python some widgets (e.g. sliders) in the slide pop up menu on which you could modify the field of view of the slice (i.e. you modify the attributes of the MRML slice object associated to the slice widget). Modifying the mouse zooming interaction is more complicated.
In general, regarding a full coordinates customization, you may have a look at the custom classes in the AstroVolumes module (the MRMLDM classes and the widgets, something like SlicerAstroController etc…) and few tweaks in Python (SlicerAstroDataProde module). The implementation is mainly in C++ and somewhat tricky if you don’t have a full picture of Slicer infrastructure.
Thank you, I have found example how to customize 3d view and slice widgets here.
@Davide_Punzo thank you for explanation. Step by step I’m getting known with Slicer philosophy. Probably a little later I will come back to this task and reread this topic. I guess that should help me
I’m trying to set transfrom on camera but it seems that this only affect on 3D view:
# Getting camera from 3D view
layoutManager = slicer.app.layoutManager()
view = layoutManager.threeDWidget(0).threeDView()
threeDViewNode = view.mrmlViewNode()
cameraNode = slicer.modules.cameras.logic().GetViewActiveCameraNode(threeDViewNode)
# Getting camera
renderWindow = view.renderWindow()
renderers = renderWindow.GetRenderers()
renderer = renderers.GetItemAsObject(0)
camera = cameraNode.GetCamera()
# Create `transform` object and set scales for it
transform = vtk.vtkTransform()
transform.Scale(2, 1, 1)
# Apply transform to the camera
camera.SetModelTransformMatrix(transform.GetMatrix())
With this I get scaled 3D view but none of the Slice view is affected by scale. It seems that there is no camera on Slice view.
I understand that I can apply transform directly on volume but in this case coordinates of my object will be broken. I need to keep the original coordinates of object untouched…
What can I do to apply independently scale axes in slice view? I don’t fully understand yet how what are slice-views represented in sense of VTK objects, but probably I could set fake camera on them?