Missing prebuilds for IGT extensions for Preview Release 5.9

ruffsl
Wed, 20 Aug 2025 07:08:36 +0000
Development

Hello, I’m developing slicelet for image guided therapy, particularly a scripted slicelet for simpler R&D. Ideally we’d like to use the Preview Release of Slicer 5.9 that ships with a more recent version of Python 3.12, however, it seems like a number of core IGT extensions are missing as of revision 33856 built 2025-08-19:

https://extensions.slicer.org/catalog/IGT/33856/linux

Inspecting the Extensions-Nightly build status for IGT extensions of interest:

SlicerIGSIO

SlicerPreview - Build Summary

GitHub - IGSIO/SlicerIGSIO at 1a89776c9f1c8bbbad62000561aa892afe1e7077

SlicerIGT

SlicerPreview - Build Summary

GitHub - SlicerIGT/SlicerIGT at cc9678a9b6f91aa9ffde3ff0176cad357335616f

SlicerOpenIGTLink

SlicerPreview - Build Summary

GitHub - openigtlink/SlicerOpenIGTLink at f806007ccc4b5c7cb6ea14979670a468b39c5a45

The build errors for both SlicerIGSIO and SlicerOpenIGTLink are quite nondescript, while cmake error for SlicerIGT from the missing SlicerIGSIO simple enough.

[  2%] Creating directories for 'YASM'
[  5%] Performing download step (git clone) for 'YASM'
Cloning into 'YASM'...
Already on 'master'
Your branch is up to date with 'origin/master'.
gmake[5]: *** read jobs pipe: Bad file descriptor.  Stop.
gmake[5]: *** Waiting for unfinished jobs....
[  8%] Generate version-YASM.txt and license-YASM.txt

Any idea what may be blocking the build server here? Only one test is failing atm:
IGT Extension Test Results: (click for more details)

Following the docs, I’ve gone ahead and compiled 3D Slicer from source using Ubuntu 24.04, including the IGT extensions from the HEADs of their respective default branches, as linked above. All seems to build and run fine as show (unsure if SlicerIGSIO is tested here):

drive.google.com

simplescreenrecorder-2025-08-19_19.39.42.webm

Google Drive file.

Example scene attached, sans the CTChest.nrrd from downloaded sample data:

drive.google.com

4up_Tracking_RIO.zip

Google Drive file.

And synthetic transform publisher for animating the example demo:

"""
============================
Position sending server
============================

Simple application that starts a server that provides a stream of random positions.

from slicer.util import pip_install
pip_install("pyigtl")

Adapted from:
https://github.com/lassoan/pyigtl/blob/d28132d8e9e1cef4ac531d795f5284c8aa739408/examples/example_position_server.py
https://github.com/lassoan/pyigtl/blob/d28132d8e9e1cef4ac531d795f5284c8aa739408/pyigtl/tests/test_basic_comm.py#L87-L93
"""

import pyigtl  # pylint: disable=import-error

from time import sleep
import numpy as np
from scipy.spatial.transform import Rotation as R

server = pyigtl.OpenIGTLinkServer(port=18944)

transverse180 = np.array([
    [-1.0,  0.0,  0.0,  0.0],
    [ 0.0,  1.0,  0.0,  0.0],
    [ 0.0,  0.0, -1.0,  0.0],
    [ 0.0,  0.0,  0.0,  1.0]
])

timestep = 0
while True:
    if not server.is_connected():
        # Wait for client to connect
        sleep(0.1)
        continue

    # Generate periodic trajectory: Lissajous curve on sphere
    timestep += 1
    radius = 50.0
    center = np.array([0.0, 0.0, -100.0])
    # Use two periodic angles for smooth looping
    phi = (timestep * 0.001) % (2 * np.pi)  # azimuthal
    theta = (timestep * 0.002) % (2 * np.pi) # polar
    x = center[0] + radius * np.sin(theta) * np.cos(phi)
    y = center[1] + radius * np.sin(theta) * np.sin(phi)
    z = center[2] + radius * np.cos(theta)
    position = np.array([x, y, z])

    # Orientation: always point toward center
    forward = center - position
    forward = forward / np.linalg.norm(forward)
    up = np.array([0.0, 1.0, 0.0])
    if np.abs(np.dot(forward, up)) > 0.99:
        up = np.array([1.0, 0.0, 0.0])
    rot_obj, _ = R.align_vectors([forward, up], [[0, 0, 1], [0, 1, 0]])
    rot_matrix = rot_obj.as_matrix()
    # Build 4x4 transform
    transform = np.eye(4)
    transform[:3, :3] = rot_matrix
    transform[:3, 3] = position

    transform_message = pyigtl.TransformMessage(transform, device_name='ToolToRAS')
    server.send_message(transform_message, wait=True)
    transform_message = pyigtl.TransformMessage(transverse180, device_name='TipToTool')
    server.send_message(transform_message, wait=True)
    # Since we wait until the message is actually sent, the message queue will not be flooded

14 posts - 4 participants