<HTML><BODY style="word-wrap: break-word; -khtml-nbsp-mode: space; -khtml-line-break: after-white-space; "><DIV><SPAN class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><SPAN class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><SPAN class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; ">Hi David,</SPAN></SPAN></SPAN></DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>Tracker:</DIV><DIV><SPAN class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><SPAN class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><SPAN class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; ">I just went trough your "tracker interface changes" page: It looks very good, I will send our comments after speaking to the rest of the trondheim developers. </SPAN></SPAN></SPAN></DIV><DIV><SPAN class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><SPAN class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><SPAN class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; ">But I was hoping that it would be possible to incorporate the "coordinate system changes" that we basically agrees on (both in terms of the necessity for doing so as well as how it should be done) at the same time:</SPAN></SPAN></SPAN></DIV><A href="http://public.kitware.com/IGSTKWIKI/index.php/DesignChallenges#Coordinate_systems_.2F_Transforms_.2F_Registration">http://public.kitware.com/IGSTKWIKI/index.php/DesignChallenges#Coordinate_systems_.2F_Transforms_.2F_Registration</A><DIV>http://public.kitware.com/IGSTKWIKI/index.php/Talk:DesignChallenges#Coordinate_systems_.2F_Transforms_.2F_Registration</DIV><DIV>http://public.kitware.com/IGSTKWIKI/index.php/Minutes_052407#DesignChallenges</DIV><DIV>I.e. <BR><DIV>- The Tracker comp. supplies the (Image)SpatialObj with tool (tip) positions and orientations (i.e. calibration included) in tracker (reference frame) coordinates. </DIV><DIV>- Each ImageSpatialObject is associated with A) a <FONT class="Apple-style-span" size="3"><SPAN class="Apple-style-span" style="font-size: 12.7px;">accumulated </SPAN></FONT>Image/VolumeTransform that tells where the volume is relative to the tracker ref. frame and B) a list of all the UpdateTransforms that a volume has gone trough (for a pre.op. volume the list of updateTransf. could be 1)DICOM transf. 2) MR-MR or CT-CT or CT-MR transf. 3) Patient reg. transf. (Tracker-Image transf.) 4) MR to US-01 update, 5) US-01 to US-02 update, etc.). </DIV><DIV><SPAN class="Apple-style-span">- Using the position of the tool tip in tracker coords. and <FONT class="Apple-style-span" size="3"><SPAN class="Apple-style-span" style="font-size: 12.7px;">accumulated</SPAN></FONT><FONT class="Apple-style-span" size="3"><SPAN class="Apple-style-span" style="font-size: 12.7px;"> </SPAN></FONT>Image/VolumeTransform the ImageSpatialObj can supply the ImageSliceRep. with the information needed to extract the right slices from the volume.</SPAN></DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>Slicer:</DIV><DIV>As pointed out by Patrick, it's time to start the practical work with the new Slicer comp.</DIV><DIV>much have been said already:</DIV><DIV>http://public.kitware.com/IGSTKWIKI/index.php/ImageSliceRepresentation</DIV><DIV>http://public.kitware.com/IGSTKWIKI/index.php/Talk:ImageSliceRepresentation</DIV><DIV>http://public.kitware.com/IGSTKWIKI/index.php/DesignChallenges#Slicing</DIV><DIV>http://public.kitware.com/IGSTKWIKI/index.php/Talk:DesignChallenges#Slicing</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>As you know, a slice can be displayed in both a "2D window" and (on a 2D plane) in a "3D scene".</DIV><DIV>IGSTK needs both. You have previously told me that you will submit a C++ OrthoPlaneWidget class (based on the "atamai python classes") to VTK:</DIV><BLOCKQUOTE type="cite"><BLOCKQUOTE type="cite"><BLOCKQUOTE type="cite"><BLOCKQUOTE type="cite"><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">Yes, we have an OrthoPlaneWidget C++ class that can be used for displaying</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">three (or just two or one) slices in a 3D scene. This class will be committed</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">to VTK cvs, probably around the middle of June.</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><BR class="khtml-block-placeholder"></DIV></BLOCKQUOTE></BLOCKQUOTE></BLOCKQUOTE></BLOCKQUOTE>Do you think that it would be possible/wise to make IGSTK Slicer comp. based on such a Ortho/ObliquePlane/SliceWidget?<BR></DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>--------------</DIV><DIV>Just to illustrate it's intended use of the slicer comp. I have included the miniasp.py atamai example below</DIV><DIV>Of course, writing an application in C++ usually requires more lines of code than the equivalent application in python,</DIV><DIV>but this is actually a "full blown viewer app." (easily extendable to a navigation/tracker app.), and it shows how "easy" it could</DIV><DIV>be to put together an application with the right functionality using high-level components. I loved it during my PhD work several years ago,</DIV><DIV>and I love it today... Wouldn't it be nice if it was just as easy to use IGSTK some time in the future, at the same time as it was safe. I believe this</DIV><DIV>is possible if we focus functionality, anybody else???</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>miniasp.py:</DIV><DIV>----</DIV><DIV>#!/usr/local/bin/python</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># Basic image viewer example that doesn't rely on any GUI toolkits</DIV><DIV># outside of VTK</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># here are a few variables to change the behaviour:</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># initial size of the window</DIV><DIV>windowWidth = 852</DIV><DIV>windowHeight = 640</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># interpolation of images</DIV><DIV>interpolation = 1</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># width of border around the frames</DIV><DIV>borderwidth = 1</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># arrange the panes in a 1 + 3 griding</DIV><DIV>viewports = [(0.00, 0.00, 0.67, 1.00),</DIV><DIV> (0.67, 0.67, 1.00, 1.00),</DIV><DIV> (0.67, 0.33, 1.00, 0.67),</DIV><DIV> (0.67, 0.00, 1.00, 0.33)]</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># or arrange the planes in 2 * 2 gridding</DIV><DIV>#viewports = [(0.00, 0.00, 0.50, 0.50),</DIV><DIV># (0.00, 0.50, 0.50, 1.00),</DIV><DIV># (0.50, 0.00, 1.00, 0.50),</DIV><DIV># (0.50, 0.50, 1.00, 1.00)]</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># check for correct usage</DIV><DIV>import os, sys</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>if not sys.argv[1:]:</DIV><DIV> filename = "phantom.mnc"</DIV><DIV>else:</DIV><DIV> filename = sys.argv[1]</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># first, load a script that sets the paths for the modules we load</DIV><DIV>import paths</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># then load all of the classes we use</DIV><DIV>from PaneFrame import *</DIV><DIV>from RenderPane import *</DIV><DIV>from RenderPane2D import *</DIV><DIV>from WindowLevelInteractionMode import *</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>from OrthoPlanesFactory import *</DIV><DIV>from AnatomicalLabelsFactory import *</DIV><DIV>from OutlineFactory import *</DIV><DIV>from CrossCursorFactory import *</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>from ModePalette import *</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># load the 'vtk widget set'</DIV><DIV>import Widgets</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># load the file reader</DIV><DIV>from vtkMINCReader import *</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># put everything together</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># create the ortho-planes, to display 3 slices through data set</DIV><DIV>planes = OrthoPlanesFactory()</DIV><DIV>planes.SetSliceInterpolate(interpolation)</DIV><DIV>planes.SetTextureInterpolate(interpolation)</DIV><DIV>planes.ActivatePlaneGuides()</DIV><DIV># this reader can be replaced by a reader for other file types</DIV><DIV>reader = vtkMINCReader()</DIV><DIV>reader.SetFileName(filename)</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># get the data range for the lookup table,</DIV><DIV># also get the shift/scale to convert the data into intensity</DIV><DIV># values: intensity = data*scale + shift</DIV><DIV>(minval,maxval) = reader.GetDataRange()</DIV><DIV>intensityShift = reader.GetShift()</DIV><DIV>intensityScale = reader.GetScale()</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># for convenience</DIV><DIV>imageData = reader.GetOutput()</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># create a greyscale lookup table to use</DIV><DIV>table = vtkLookupTable()</DIV><DIV>table.SetTableRange(minval,maxval)</DIV><DIV>table.SetSaturationRange(0,0)</DIV><DIV>table.SetHueRange(0,0)</DIV><DIV>table.SetValueRange(0,1)</DIV><DIV>table.Build()</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># add these to the orthoplanes</DIV><DIV>planes.SetInput(imageData)</DIV><DIV>planes.SetLookupTable(table)</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># generate a frame around the volume</DIV><DIV>frame = OutlineFactory()</DIV><DIV>frame.SetInput(imageData)</DIV><DIV>frame.SetColor(1.0000, 0.8431, 0.0000)</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># generate axes labels</DIV><DIV>labels = AnatomicalLabelsFactory()</DIV><DIV>labels.SetInput(imageData)</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># make a cursor to display in all the frames</DIV><DIV>cursor = CrossCursorFactory()</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># create window/level interaction for the rendering pane, attach</DIV><DIV># the lookup table here too</DIV><DIV>windowlevel = WindowLevelInteractionMode()</DIV><DIV>windowlevel.SetLookupTable(table)</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># create the rendering panes, add the actors</DIV><DIV>paneframe = PaneFrame(width=windowWidth, height=windowHeight)</DIV><DIV>paneframe.SetTitle("Atamai MiniAsp ["+filename+"]")</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># the height of the control panel at the bottom,</DIV><DIV># and the width of the borders around the panes</DIV><DIV>panelheight = 27</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># figure out what the offsets on the viewports will have to</DIV><DIV># be to make room for the control panel</DIV><DIV>viewportOffsets = []</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>for viewport in viewports:</DIV><DIV> viewportOffsets.append(</DIV><DIV> (0, int(panelheight*(1.0-viewport[1])),</DIV><DIV> 0, int(panelheight*(1.0-viewport[3]))))</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># create the primary rendering pane with a nice border around it</DIV><DIV>pane = RenderPane(paneframe)</DIV><DIV>pane.SetViewport(viewports[0])</DIV><DIV>pane.SetViewportOffsets(viewportOffsets[0])</DIV><DIV>pane.SetBackground(1,1,1)</DIV><DIV>pane.SetBorderWidth(borderwidth)</DIV><DIV>pane.ConnectActorFactory(planes)</DIV><DIV>pane.ConnectActorFactory(frame)</DIV><DIV>pane.ConnectActorFactory(labels)</DIV><DIV>pane.ConnectCursor(cursor)</DIV><DIV>pane.BindModeToButton(windowlevel,3,"Shift")</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># set up another pane for the single image</DIV><DIV>pane2 = RenderPane2D(paneframe)</DIV><DIV>pane2.SetViewport(viewports[1])</DIV><DIV>pane2.SetViewportOffsets(viewportOffsets[1])</DIV><DIV>pane2.SetBackground(0.5,0.5,0.5)</DIV><DIV>pane2.SetBorderWidth(borderwidth)</DIV><DIV>pane2.ConnectPlane(planes.GetAxialPlane())</DIV><DIV>pane2.ConnectCursor(cursor)</DIV><DIV>pane2.BindModeToButton(windowlevel,3,"Shift")</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># set up another pane for the single image</DIV><DIV>pane3 = RenderPane2D(paneframe)</DIV><DIV>pane3.SetViewport(viewports[2])</DIV><DIV>pane3.SetViewportOffsets(viewportOffsets[2])</DIV><DIV>pane3.SetBackground(0.5,0.5,0.5)</DIV><DIV>pane3.SetBorderWidth(borderwidth)</DIV><DIV>pane3.ConnectPlane(planes.GetCoronalPlane())</DIV><DIV>pane3.ConnectCursor(cursor)</DIV><DIV>pane3.BindModeToButton(windowlevel,3,"Shift")</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># set up another pane for the single image</DIV><DIV>pane4 = RenderPane2D(paneframe)</DIV><DIV>pane4.SetViewport(viewports[3])</DIV><DIV>pane4.SetViewportOffsets(viewportOffsets[3])</DIV><DIV>pane4.SetBackground(0.5,0.5,0.5)</DIV><DIV>pane4.SetBorderWidth(borderwidth)</DIV><DIV>pane4.ConnectPlane(planes.GetSagittalPlane())</DIV><DIV>pane4.ConnectCursor(cursor)</DIV><DIV>pane4.BindModeToButton(windowlevel,3,"Shift")</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># set up a final pane just for the control panel</DIV><DIV>pane5 = RenderPane2D(paneframe)</DIV><DIV>pane5.SetViewport(0.0,0.0,1.0,0.0)</DIV><DIV>pane5.SetViewportOffsets(0,0,0,panelheight)</DIV><DIV>pane5.SetBackground(0.75,0.75,0.75)</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># create a label for cursor coordinate readout, set the text to black</DIV><DIV>coordlabel = Widgets.CoordinateLabel(pane5,x=-280,y=0,</DIV><DIV> foreground=(0.0,0.0,0.0))</DIV><DIV>coordlabel.SetCursor(cursor)</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># create a label for intensity readout, set the text to red</DIV><DIV>intensitylabel = Widgets.IntensityLabel(pane5,x=-380,y=0,</DIV><DIV> foreground=(1.0,0.0,0.0))</DIV><DIV>intensitylabel.SetInput(imageData)</DIV><DIV>intensitylabel.SetCursor(cursor)</DIV><DIV>intensitylabel.SetShift(intensityShift)</DIV><DIV>intensitylabel.SetScale(intensityScale)</DIV><DIV>intensitylabel.SetInterpolate(interpolation)</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># create a logo bitmap</DIV><DIV>bitmapReader = vtkImageReader()</DIV><DIV>bitmapReader.SetFileName(os.path.join(paths.prefix,"classes/Atamai.rgba"))</DIV><DIV>bitmapReader.SetDataScalarTypeToUnsignedChar()</DIV><DIV>bitmapReader.SetNumberOfScalarComponents(4)</DIV><DIV>bitmapReader.SetDataExtent(0,199,0,57,0,0)</DIV><DIV>logolabel = Widgets.Label(pane5,x=0,y=0,width=100,height=27,</DIV><DIV> bitmap=bitmapReader.GetOutput())</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># create a palette of mouse mode interaction choices</DIV><DIV>modePalette = ModePalette(pane5,x=105,y=0)</DIV><DIV>modePalette.AddPane(pane)</DIV><DIV>modePalette.AddPane(pane2)</DIV><DIV>modePalette.AddPane(pane3)</DIV><DIV>modePalette.AddPane(pane4)</DIV><DIV>modePalette.SetLookupTable(table)</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>paneframe.Render()</DIV><DIV>pane.GetRenderer().GetActiveCamera().SetEyeAngle(5.0)</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV># start 'er up</DIV><DIV>paneframe.Start()</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV><BR class="khtml-block-placeholder"></DIV></BODY></HTML>