use openigtlink_rust::error::Result;
use openigtlink_rust::io::IgtlClient;
use openigtlink_rust::protocol::message::IgtlMessage;
use openigtlink_rust::protocol::types::{PointElement, PointMessage};
fn main() {
if let Err(e) = run() {
eprintln!("[ERROR] {}", e);
std::process::exit(1);
}
}
fn run() -> Result<()> {
let mut client = IgtlClient::connect("127.0.0.1:18944")?;
println!("[INFO] Connected to OpenIGTLink server\n");
println!("=== Surgical Navigation: Fiducial Point Registration ===");
println!("System: Image-Guided Surgery Navigation");
println!("Image Modality: CT scan (pre-operative)");
println!("Coordinate System: LPS (Left-Posterior-Superior)\n");
register_fiducials(&mut client)?;
println!("\n[INFO] Fiducial registration completed successfully");
Ok(())
}
fn register_fiducials(client: &mut IgtlClient) -> Result<()> {
println!("[STEP 1] Defining anatomical fiducial points from CT image...\n");
let fiducials = vec![
create_fiducial(
"Nasion",
"Fiducials",
[0.0, 85.0, -40.0],
[255, 0, 0, 255], 5.0,
"CTImage",
),
create_fiducial(
"LeftEar",
"Fiducials",
[-70.0, 0.0, -60.0],
[0, 255, 0, 255], 5.0,
"CTImage",
),
create_fiducial(
"RightEar",
"Fiducials",
[70.0, 0.0, -60.0],
[0, 0, 255, 255], 5.0,
"CTImage",
),
create_fiducial(
"TargetLesion",
"Targets",
[15.0, 30.0, 45.0],
[255, 255, 0, 255], 8.0,
"CTImage",
),
create_fiducial(
"EntryPoint",
"Targets",
[10.0, 25.0, 30.0],
[255, 0, 255, 255], 4.0,
"CTImage",
),
];
println!(" Registering {} fiducial points:", fiducials.len());
println!(" ┌─────────────────┬──────────────────────────────────┐");
println!(" │ Name │ Position (LPS, mm) │");
println!(" ├─────────────────┼──────────────────────────────────┤");
for fid in &fiducials {
println!(
" │ {:<15} │ ({:7.1}, {:7.1}, {:7.1}) │",
fid.name, fid.position[0], fid.position[1], fid.position[2]
);
}
println!(" └─────────────────┴──────────────────────────────────┘\n");
println!("[STEP 2] Sending fiducial data to navigation system...\n");
let point_msg = PointMessage::new(fiducials);
let msg = IgtlMessage::new(point_msg.clone(), "NavigationSystem")?;
client.send(&msg)?;
println!(" ✓ {} points transmitted successfully", point_msg.len());
println!(" ✓ Total data size: {} bytes", point_msg.len() * 136);
println!("\n[STEP 3] Registration workflow:\n");
println!(" 1. Identify corresponding points on physical patient");
println!(" 2. Use pointer/probe to digitize points in physical space");
println!(" 3. Compute transformation matrix (image → physical space)");
println!(" 4. Calculate registration error (RMS of fiducial distances)");
println!(" 5. Verify registration accuracy < 2mm for neuro procedures");
Ok(())
}
fn create_fiducial(
name: &str,
group: &str,
position: [f32; 3],
rgba: [u8; 4],
diameter: f32,
owner: &str,
) -> PointElement {
PointElement::with_details(name, group, rgba, position, diameter, owner)
}
#[cfg(test)]
mod tests {
use super::*;
use openigtlink_rust::protocol::message::Message;
#[test]
fn test_create_fiducial() {
let fid = create_fiducial(
"TestPoint",
"TestGroup",
[10.0, 20.0, 30.0],
[255, 0, 0, 255],
5.0,
"TestImage",
);
assert_eq!(fid.name, "TestPoint");
assert_eq!(fid.group, "TestGroup");
assert_eq!(fid.position, [10.0, 20.0, 30.0]);
assert_eq!(fid.rgba, [255, 0, 0, 255]);
assert_eq!(fid.diameter, 5.0);
assert_eq!(fid.owner, "TestImage");
}
#[test]
fn test_fiducial_count() {
let fiducials = vec![
create_fiducial("P1", "G", [0.0, 0.0, 0.0], [255, 0, 0, 255], 5.0, "I"),
create_fiducial("P2", "G", [1.0, 1.0, 1.0], [0, 255, 0, 255], 5.0, "I"),
create_fiducial("P3", "G", [2.0, 2.0, 2.0], [0, 0, 255, 255], 5.0, "I"),
];
let msg = PointMessage::new(fiducials);
assert_eq!(msg.len(), 3);
}
#[test]
fn test_point_message_encoding() {
let fid = create_fiducial(
"Nasion",
"Fiducials",
[0.0, 85.0, -40.0],
[255, 0, 0, 255],
5.0,
"CTImage",
);
let msg = PointMessage::new(vec![fid]);
let encoded = msg.encode_content().unwrap();
assert_eq!(encoded.len(), 136);
}
#[test]
fn test_fiducial_colors() {
let colors = vec![
[255, 0, 0, 255], [0, 255, 0, 255], [0, 0, 255, 255], [255, 255, 0, 255], [255, 0, 255, 255], ];
for (i, color) in colors.iter().enumerate() {
let fid = create_fiducial(
&format!("Point{}", i + 1),
"Test",
[0.0, 0.0, 0.0],
*color,
5.0,
"Test",
);
assert_eq!(fid.rgba, *color);
}
}
#[test]
fn test_lps_coordinates() {
let left_ear = create_fiducial(
"LeftEar",
"Fiducials",
[-70.0, 0.0, -60.0],
[0, 255, 0, 255],
5.0,
"CT",
);
assert!(left_ear.position[0] < 0.0);
let right_ear = create_fiducial(
"RightEar",
"Fiducials",
[70.0, 0.0, -60.0],
[0, 0, 255, 255],
5.0,
"CT",
);
assert!(right_ear.position[0] > 0.0);
let nasion = create_fiducial(
"Nasion",
"Fiducials",
[0.0, 85.0, -40.0],
[255, 0, 0, 255],
5.0,
"CT",
);
assert!(nasion.position[1] > 0.0); }
}