Hi all,
 in the end it took a while for me to be able to put my hands on this bug.
I made a fix that allows you to just replace the python script file without waiting for a new release.
The bug was due to a change in the behavior of a method and it will have to be fixed, quite easily,
in the C++ code. In any case, the present fix is not 100% elegant but it works and it can be applied
without recompiling.

I'm attaching the new script (I also committed the change in the git repository). In your vmtk
installation, find the lib/vmtk/vmtk directory and replace the vmtkimagevoipainter with the one
attached. Let me know on what system you are working, in case you can't find it and I'll direct you 
to the right place.

Hope this solves it, sorry if it took a while. I had to go through a few deadlines, which left very little 
extra time.

Best,


Luca


#!/usr/bin/env python

## Program:   VMTK
## Module:    $RCSfile: vmtkimagevoipainter.py,v $
## Language:  Python
## Date:      $Date: 2006/05/26 12:35:13 $
## Version:   $Revision: 1.9 $

##   Copyright (c) Luca Antiga, David Steinman. All rights reserved.
##   See LICENCE file for details.

##      This software is distributed WITHOUT ANY WARRANTY; without even 
##      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
##      PURPOSE.  See the above copyright notices for more information.

import vtk
import sys
import math

import vtkvmtk
import vmtkrenderer
import pypes

vmtkimagevoipainter = 'vmtkImageVOIPainter'

class vmtkImageVOIPainter(pypes.pypeScript):

    def __init__(self):

        pypes.pypeScript.__init__(self)

        self.CubeSource = vtk.vtkCubeSource()
        self.CubeActor = vtk.vtkActor()
        
        self.BoxActive = 0
        self.BoxBounds = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
        self.PaintValue = 0.0

        self.PaintedImage = vtk.vtkImageData()

        self.vmtkRenderer = None
        self.OwnRenderer = 0

        self.PlaneWidgetX = None
        self.PlaneWidgetY = None
        self.PlaneWidgetZ = None
        self.BoxWidget = None

        self.Image = None

        self.Interactive = 1

        self.SetScriptName('vmtkimagevoipainter')
        self.SetScriptDoc('fill a cubical region of an image with a given gray level')
        self.SetInputMembers([
            ['Image','i','vtkImageData',1,'','the input image','vmtkimagereader'],
            ['Interactive','interactive','bool',1,'','toggle interactivity'],
            ['BoxBounds','boxbounds','float',6,'','bounds of the cubical region for non-interactive mode'],
            ['PaintValue','paintvalue','float',1,'','graylevel to fill the region with'],
            ['vmtkRenderer','renderer','vmtkRenderer',1,'','external renderer']
            ])
        self.SetOutputMembers([
            ['Image','o','vtkImageData',1,'','the output image','vmtkimagewriter']
            ])

    def InteractCallback(self):
        if self.BoxWidget.GetEnabled() == 1:
            self.BoxWidget.SetEnabled(0)
        else:
            self.BoxWidget.SetEnabled(1)

    def HideCube(self,object, event):
        self.CubeActor.VisibilityOff()

    def UpdateCube(self,object, event):
        polyData = vtk.vtkPolyData()
        object.GetPolyData(polyData)
        polyData.ComputeBounds()
        self.CubeSource.SetBounds(polyData.GetBounds())
        self.CubeSource.Modified()
        self.CubeActor.VisibilityOn()

    def Display(self):

        wholeExtent = self.Image.GetWholeExtent()

        picker = vtk.vtkCellPicker()
        picker.SetTolerance(0.005)

        self.PlaneWidgetX.SetInput(self.Image)
        self.PlaneWidgetX.SetPlaneOrientationToXAxes()
        self.PlaneWidgetX.SetSliceIndex(wholeExtent[0])
        self.PlaneWidgetX.DisplayTextOn()
        self.PlaneWidgetX.SetPicker(picker)
        self.PlaneWidgetX.KeyPressActivationOff()
        self.PlaneWidgetX.On()

        self.PlaneWidgetY.SetInput(self.Image)
        self.PlaneWidgetY.SetPlaneOrientationToYAxes()
        self.PlaneWidgetY.SetSliceIndex(wholeExtent[2])
        self.PlaneWidgetY.DisplayTextOn()
        self.PlaneWidgetY.SetPicker(picker)
        self.PlaneWidgetY.KeyPressActivationOff()
        self.PlaneWidgetY.SetLookupTable(self.PlaneWidgetX.GetLookupTable())
        self.PlaneWidgetY.On()

        self.PlaneWidgetZ.SetInput(self.Image)
        self.PlaneWidgetZ.SetPlaneOrientationToZAxes()
        self.PlaneWidgetZ.SetSliceIndex(wholeExtent[4])
        self.PlaneWidgetZ.DisplayTextOn()
        self.PlaneWidgetZ.SetPicker(picker)
        self.PlaneWidgetZ.KeyPressActivationOff()
        self.PlaneWidgetZ.SetLookupTable(self.PlaneWidgetX.GetLookupTable())
        self.PlaneWidgetZ.On()

        self.BoxWidget.SetPriority(1.0)
        self.BoxWidget.SetHandleSize(5E-3)
        self.BoxWidget.SetInput(self.Image)
        self.BoxWidget.PlaceWidget()
        self.BoxWidget.RotationEnabledOff()
        self.BoxWidget.AddObserver("StartInteractionEvent", self.HideCube)
        self.BoxWidget.AddObserver("EndInteractionEvent", self.UpdateCube)
        self.BoxWidget.AddObserver("EnableEvent", self.UpdateCube)
        self.BoxWidget.AddObserver("DisableEvent", self.HideCube)

        polyData = vtk.vtkPolyData()
        self.BoxWidget.GetPolyData(polyData)
        polyData.ComputeBounds()
        self.CubeSource.SetBounds(polyData.GetBounds())
        cubeMapper = vtk.vtkPolyDataMapper()
        cubeMapper.SetInput(self.CubeSource.GetOutput())
        self.CubeActor.SetMapper(cubeMapper)
        self.CubeActor.GetProperty().SetColor(0.6,0.6,0.2)
        self.CubeActor.GetProperty().SetOpacity(0.25)
        self.CubeActor.VisibilityOff()
        self.vmtkRenderer.Renderer.AddActor(self.CubeActor)

        self.vmtkRenderer.Render()

        self.vmtkRenderer.Renderer.RemoveActor(self.CubeActor)

        self.BoxActive = 0
        if self.BoxWidget.GetEnabled() == 1:
            polyData = vtk.vtkPolyData()
            self.BoxWidget.GetPolyData(polyData)
            polyData.ComputeBounds()
            bounds = polyData.GetBounds()
            self.BoxBounds[0] = bounds[0]
            self.BoxBounds[1] = bounds[1]
            self.BoxBounds[2] = bounds[2]
            self.BoxBounds[3] = bounds[3]
            self.BoxBounds[4] = bounds[4]
            self.BoxBounds[5] = bounds[5]
            self.BoxActive = 1

        self.BoxWidget.Off()

    def PaintVOI(self):

        wholeExtent = self.Image.GetWholeExtent()[:]
        origin = self.Image.GetOrigin()
        spacing = self.Image.GetSpacing()

        paintedVOI = [0,0,0,0,0,0]
        paintedVOI[0] = max(wholeExtent[0],int(math.ceil((self.BoxBounds[0]-origin[0])/spacing[0])))
        paintedVOI[1] = min(wholeExtent[1],int(math.floor((self.BoxBounds[1]-origin[0])/spacing[0])))
        paintedVOI[2] = max(wholeExtent[2],int(math.ceil((self.BoxBounds[2]-origin[1])/spacing[1])))
        paintedVOI[3] = min(wholeExtent[3],int(math.floor((self.BoxBounds[3]-origin[1])/spacing[1])))
        paintedVOI[4] = max(wholeExtent[4],int(math.ceil((self.BoxBounds[4]-origin[2])/spacing[2])))
        paintedVOI[5] = min(wholeExtent[5],int(math.floor((self.BoxBounds[5]-origin[2])/spacing[2])))

        # extent trick. TODO: fix vtkvmtkImageBoxPainter
        paintedVOI[0] -= wholeExtent[0]
        paintedVOI[1] -= wholeExtent[0]
        paintedVOI[2] -= wholeExtent[2]
        paintedVOI[3] -= wholeExtent[2]
        paintedVOI[4] -= wholeExtent[4]
        paintedVOI[5] -= wholeExtent[4]

        newExtent = [0,0,0,0,0,0]
        newExtent[0] = 0
        newExtent[1] = wholeExtent[1] - wholeExtent[0]
        newExtent[2] = 0
        newExtent[3] = wholeExtent[3] - wholeExtent[2]
        newExtent[4] = 0
        newExtent[5] = wholeExtent[5] - wholeExtent[4]

        self.Image.SetWholeExtent(newExtent)
 
        imageBoxPainter = vtkvmtk.vtkvmtkImageBoxPainter()
        imageBoxPainter.SetInput(self.Image)
        imageBoxPainter.SetBoxExtent(paintedVOI)
        imageBoxPainter.SetBoxDefinitionToUseExtent()
        imageBoxPainter.SetPaintValue(self.PaintValue)
        imageBoxPainter.Update()

        self.PaintedImage.ShallowCopy(imageBoxPainter.GetOutput())
        self.PaintedImage.Update()

        if self.PaintedImage.GetSource():
            self.PaintedImage.GetSource().UnregisterAllOutputs()

    def Execute(self):

        if self.Image == None:
            self.PrintError('Error: no Image.')

        wholeExtent = self.Image.GetWholeExtent()
        if self.Interactive == 1:
            
            if not self.vmtkRenderer:
                self.vmtkRenderer = vmtkrenderer.vmtkRenderer()
                self.vmtkRenderer.Initialize()
                self.OwnRenderer = 1

            self.vmtkRenderer.RegisterScript(self)                 

            self.PlaneWidgetX = vtk.vtkImagePlaneWidget()
            self.PlaneWidgetX.SetInteractor(self.vmtkRenderer.RenderWindowInteractor)
            self.PlaneWidgetY = vtk.vtkImagePlaneWidget()
            self.PlaneWidgetY.SetInteractor(self.vmtkRenderer.RenderWindowInteractor)
            self.PlaneWidgetZ = vtk.vtkImagePlaneWidget()
            self.PlaneWidgetZ.SetInteractor(self.vmtkRenderer.RenderWindowInteractor)
            self.BoxWidget = vtk.vtkBoxWidget()
            self.BoxWidget.SetInteractor(self.vmtkRenderer.RenderWindowInteractor)
            self.vmtkRenderer.AddKeyBinding('i','Interact.', self.InteractCallback)

            self.Display()
            while (self.BoxActive == 1):
                self.PaintVOI()
                self.Image.DeepCopy(self.PaintedImage)
                self.Image.SetWholeExtent(wholeExtent)
                self.Image.SetUpdateExtent(wholeExtent)
                self.Image.SetExtent(wholeExtent)
                self.Display()
        else:
            self.PaintVOI()

        if self.OwnRenderer:
            self.vmtkRenderer.Deallocate()

        self.Image = self.PaintedImage


if __name__=='__main__':
    main = pypes.pypeMain()
    main.Arguments = sys.argv
    main.Execute()

On Jun 11, 2012, at 7:10 PM, Luca Antiga wrote:

Dear Anna,
 thanks for letting me know. I'm looking into it, I'll get back to you asap.

Luca


On 11/giu/2012, at 18:38, "Hoppe, Anna L" <anna-ho...@uiowa.edu> wrote:

Hi Luca,

Ben Dickerhoff and I tried changing the extents to "dim -1" in the header file of our image .vti and then running vmtkimagevoipainter. However the output painted region was still in a different spatial location than originally specified. We were just wondering if you had looked into this problem any further and if you had any new insights...

Thanks for all your help. It is greatly appreciated!
Anna

From: Luca Antiga [luca.ant...@gmail.com]
Sent: Wednesday, June 06, 2012 2:25 PM
To: Dickerhoff, Benjamin R
Cc: vmtk-users@lists.sourceforge.net
Subject: Re: [vmtk-users] Problem with vmtkimagevoipainter update

Hi Ben,
 yes, you can do that directly and save the file back. 
Just change both extents from 0 to dim-1 in each direction. Note that the physical location of the image will change (unless you move the origin to originalExtent[0] * spacing[0], originalExtent[2] * spacing[1], originalExtent[4] * spacing[2]).
Best,

Luca


On 06/giu/2012, at 21:13, "Dickerhoff, Benjamin R" <benjamin-dickerh...@uiowa.edu> wrote:

Luca-

    Thanks for the response. When you say to set the origin of the image to 0 0 0 and the extent from 0 to dim-1 in all directions, do you mean to physically change the header in the .vti? Below is the header from one of the image files. The origin of the image appears already to be set to "0 0 0".

<VTKFile type="ImageData" version="0.1" byte_order="LittleEndian" compressor="vtkZLibDataCompressor">
  <ImageData WholeExtent="203 364 141 396 75 254" Origin="0 0 0" Spacing="0.21838390827 0.21838390827 0.21838378906">
    <Piece Extent="203 364 141 396 75 254">
      <PointData Scalars="Scalars_">
        <DataArray type="Float32" Name="Scalars_" format="appended" RangeMin="-0.87353515625"       RangeMax="0.87353515625"        offset="0"                   />
      </PointData>
      <CellData>
      </CellData>
    </Piece>
  </ImageData

Thanks,
Ben

From: Luca Antiga [luca.ant...@gmail.com]
Sent: Wednesday, June 06, 2012 11:55 AM
To: Dickerhoff, Benjamin R
Cc: vmtk-users@lists.sourceforge.net
Subject: Re: [vmtk-users] Problem with vmtkimagevoipainter update

Dear all,
 I've been off-list for a few days. I'll look into this asap, in the meantime, as a test, try setting the origin of the image to 0 0 0 and the extent from 0 to dim-1 in all directions. Then save the image and execute the vmtk script. I suspect it's an extent related issue.
Keep in touch

Luca


On 06/giu/2012, at 16:51, "Dickerhoff, Benjamin R" <benjamin-dickerh...@uiowa.edu> wrote:

VMTK Users,

    With regards to the problem that I posted about trouble I was having with vmtkimagevoipainter, I have not figured out how to resolve this yet. I have figured out that the bounding box in the output has the same dimensions as the bounding box chosen as an input, however, its output location in the image set is offset towards the corner of the entire input VOI. Additionally, the output paint value does correspond to the input value specified using the option "-paintvalue".

   Ben Berkowitz helped me simplify the vmtkimagevoipainter script by writing the python script at the end of this email. It is intended to take in a vtk image file and the bounding coordinates (min and max for x, y, and z) for the region we wish to "paint". This script gives the same output as the vmtkimagevoipainter script. It seems that the vtkvmtk.vtkvmtkImageBoxPainter() script is reading in the input just fine, but can't process where to place the region to be painted in the output image. I'm not exactly sure where to go from here to help correct this. If anybody has any suggestions, I'd greatly appreciate your input.

Thanks for your time,
Ben Dickerhoff

import vtk
import sys
import math
from vmtk import vtkvmtk
from vmtk import vmtkscripts

file = sys.argv[1]

reader = vmtkscripts.vmtkImageReader()
reader.InputFileName = file
reader.Execute()

xmin = float(sys.argv[2])
xmax = float(sys.argv[3])
ymin = float(sys.argv[4])
ymax = float(sys.argv[5])
zmin = float(sys.argv[6])
zmax = float(sys.argv[7])

extents = [xmin, xmax, ymin, ymax, zmin, zmax]

imageBoxPainter = vtkvmtk.vtkvmtkImageBoxPainter()
imageBoxPainter.SetInput(reader.Image)
imageBoxPainter.SetBoxExtent(extents)
imageBoxPainter.SetBoxDefinitionToUseExtent()
imageBoxPainter.SetPaintValue(10)
imageBoxPainter.Update()

writer = vmtkscripts.vmtkImageWriter()
writer.Image = imageBoxPainter.GetOutput()
writer.OutputFileName = file[:-4]+'_painted.vti'
writer.Execute()

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
vmtk-users mailing list
vmtk-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/vmtk-users
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/_______________________________________________
vmtk-users mailing list
vmtk-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/vmtk-users

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
vmtk-users mailing list
vmtk-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/vmtk-users

Reply via email to