[vtkusers] Strange segfault (wxPython + wxVTKRenderWindowInteractor + widget)

Paul Melis paul at science.uva.nl
Wed Mar 7 07:21:00 EST 2007


Hmmm,

The code didn't get through correctly in the post, so I've put a copy at 
http://www.pecm.nl/wxapp_with_widget.py

Paul

Paul Melis wrote:

> Hello,
>
> I'm trying to use one of the 3D VTK widgets in a wxPython application. 
> I originally stumbled upon the segfault described below while trying 
> to use a vtkImagePlaneWidget, but found that vtkBoxWidget and 
> vtkSphereWidget also show the same problem. I include here a stripped 
> version of my original app for easy demonstration. This is all with a 
> recent CVS version of VTK, wxPython 2.6.3 and Python 2.4.3 on Fedora 
> Core 4.
>
> The code below derives a custom frame from wx.Frame, places a button 
> and a wxVTKRenderWindowInteractor on that frame. The standard 
> headsq/quarter VTK dataset is loaded when the button is pressed and a 
> volume rendering is set up using the dataset. A wx.App is created that 
> creates the frame and then runs the application main loop. This all 
> works as expected, the volume is rendered and can be rotated, zoomed, 
> etc.
>
> Problems start when adding a vtkImagePlaneWidget to the pipeline, so 
> as to show image slices of the data set. The addition of the widget in 
> the code below is guarded with an "if False:", but changing to True 
> will add the widget and set its interactor to the 
> wxVTKRenderWindowInteractor of the frame. The widget is then placed 
> with PlaceWidget() and enabled with On(). When the app is run with the 
> widget enabled then any mouse interaction after the dataset is loaded 
> will cause a segfault. The relevant (top) part of the stack trace is:
>
> #0  0x00000000 in ?? ()
> #1  0x04543d87 in vtkImagePlaneWidget::ProcessEvents () from 
> /home/paul/vtk/bin/libvtkWidgets.so.5.1
> #2  0x055989c1 in vtkCallbackCommand::Execute () from 
> /home/paul/vtk/bin/libvtkCommon.so.5.1
> #3  0x0561289a in vtkSubjectHelper::InvokeEvent () from 
> /home/paul/vtk/bin/libvtkCommon.so.5.1
> #4  0x05612904 in vtkObject::InvokeEvent () from 
> /home/paul/vtk/bin/libvtkCommon.so.5.1
> #5  0x023af093 in 
> vtkGenericRenderWindowInteractor::LeftButtonPressEvent () from 
> /home/paul/vtk/bin/libvtkRendering.so.5.1
> #6  0x03026dd4 in 
> PyvtkGenericRenderWindowInteractor_LeftButtonPressEvent () from 
> /home/paul/vtk/bin/libvtkRenderingPythonD.so.5.1
> #7  0x003106c3 in PyCFunction_Call () from /usr/lib/libpython2.4.so.1.0
> #8  0x0034931c in PyEval_EvalFrame () from /usr/lib/libpython2.4.so.1.0
> #9  0x0034aa1c in PyEval_EvalCodeEx () from /usr/lib/libpython2.4.so.1.0
> #10 0x002ff0b1 in PyFunction_SetClosure () from 
> /usr/lib/libpython2.4.so.1.0
> #11 0x002ea7c6 in PyObject_Call () from /usr/lib/libpython2.4.so.1.0
> #12 0x002f20ee in PyMethod_Fini () from /usr/lib/libpython2.4.so.1.0
> #13 0x002ea7c6 in PyObject_Call () from /usr/lib/libpython2.4.so.1.0
> #14 0x00343b1c in PyEval_CallObjectWithKeywords () from 
> /usr/lib/libpython2.4.so.1.0
> #15 0x004be8de in wxPyCallback::EventThunker () from 
> /usr/lib/python2.4/site-packages/wx-2.6-gtk2-unicode/wx/_core_.so
> #16 0x009fed3d in wxAppConsole::HandleEvent () from 
> /usr/lib/libwx_baseu-2.6.so.0
> #17 0x00a87c7f in wxEvtHandler::ProcessEventIfMatches () from 
> /usr/lib/libwx_baseu-2.6.so.0
> #18 0x00a87d40 in wxEvtHandler::SearchDynamicEventTable () from 
> /usr/lib/libwx_baseu-2.6.so.0
> #19 0x00a87fe5 in wxEvtHandler::ProcessEvent () from 
> /usr/lib/libwx_baseu-2.6.so.0
> #20 0x00f07fda in wxWinModule::wxCreateObject () from 
> /usr/lib/libwx_gtk2u_core-2.6.so.0
> [...]
>
> There seems to be a null pointer being used somewhere, but looking at 
> vtkImagePlaneWidget::ProcessEvents() the only candidate for that would 
> be the parameter "clientdata" as it is the only one used in the 
> method. This is so deep within VTK that I don't know what's going on. 
> Perhaps I'm setting things up slightly wrong or maybe there's a 
> problem with the wxVTKRenderWindowInteractor.
>
> Any help would be greatly appreciated,
> Paul
>
> ===============================
> #!/usr/bin/env python
> import sys
> import wx
>
> import vtk
> from vtk.wx.wxVTKRenderWindowInteractor import 
> wxVTKRenderWindowInteractor
>
> from vtk.util.misc import vtkGetDataRoot
> VTK_DATA_ROOT = vtkGetDataRoot()
>
> class MainFrame(wx.Frame):
>      def __init__(self, parent, title):
>        wx.Frame.__init__(self, parent, -1, title)
>              self.button = wx.Button(self, -1, "Load!")              
> self.button.SetDefault()
>        self.Bind(wx.EVT_BUTTON, self.OnLoad, self.button)
>
>        self.vtk_widget = wxVTKRenderWindowInteractor(self, -1, 
> size=wx.Size(800,600))              
> self.vtk_widget.Enable(1)                                    sizer = 
> wx.BoxSizer(wx.VERTICAL)              sizer.Add(self.button, 0, 
> wx.EXPAND)
>        sizer.Add(self.vtk_widget, 1, wx.EXPAND|wx.ALL, 1)             
>        self.CreateStatusBar()
>        self.SetStatusText("")
>              self.vtk_renderer = vtk.vtkRenderer()
>        self.vtk_renderer.AddObserver("StartEvent", lambda o,e: 
> self.OnRenderingStart(o,e))
>        self.vtk_renderer.AddObserver("EndEvent", lambda o,e: 
> self.OnRenderingEnd(o,e))                    
> self.vtk_widget.GetRenderWindow().AddRenderer(self.vtk_renderer)
>              self.SetSizer(sizer)
>        sizer.SetSizeHints(self)  
>    def OnRenderingStart(self, obj, evt):
>        self.SetStatusText("Rendering")
>        self.Update()
>        wx.Yield()                def OnRenderingEnd(self, obj, evt):
>        self.SetStatusText("")
>        self.Update()
>        wx.Yield()                def OnLoad(self, evt):
>
>        # Load a volume, use the widget to control what's volume
>        # rendered. Basically the idea is that the vtkBoxWidget 
> provides a box
>        # which clips the volume rendering.
>        v16 = vtk.vtkVolume16Reader()
>        v16.SetDataDimensions(64, 64)
>        v16.GetOutput().SetOrigin(0.0, 0.0, 0.0)
>        v16.SetDataByteOrderToLittleEndian()
>              v16.SetFilePrefix(VTK_DATA_ROOT+ "/Data/headsq/quarter")
>        v16.SetImageRange(1, 93)
>        v16.SetDataSpacing(3.2, 3.2, 1.5)
>                      print "scalar range:", 
> v16.GetOutput().GetScalarRange()
>
>        tfun = vtk.vtkPiecewiseFunction()
>        tfun.AddPoint(70.0, 0.0)
>        tfun.AddPoint(599.0, 0)
>        tfun.AddPoint(600.0, 0)
>        tfun.AddPoint(1195.0, 0)
>        tfun.AddPoint(1200, .2)
>        tfun.AddPoint(1300, .3)
>        tfun.AddPoint(2000, .3)
>        tfun.AddPoint(4095.0, 1.0)
>
>        ctfun = vtk.vtkColorTransferFunction()
>        ctfun.AddRGBPoint(0.0, 0.5, 0.0, 0.0)
>        ctfun.AddRGBPoint(600.0, 1.0, 0.5, 0.5)
>        ctfun.AddRGBPoint(1280.0, 0.9, 0.2, 0.3)
>        ctfun.AddRGBPoint(1960.0, 0.81, 0.27, 0.1)
>        ctfun.AddRGBPoint(4095.0, 0.5, 0.5, 0.5)
>
>        compositeFunction = vtk.vtkVolumeRayCastCompositeFunction()
>
>        volumeMapper = vtk.vtkVolumeRayCastMapper()
>        volumeMapper.SetInputConnection(v16.GetOutputPort())
>        volumeMapper.SetVolumeRayCastFunction(compositeFunction)
>
>        volumeProperty = vtk.vtkVolumeProperty()
>        volumeProperty.SetColor(ctfun)
>        volumeProperty.SetScalarOpacity(tfun)
>        volumeProperty.SetInterpolationTypeToLinear()
>        volumeProperty.ShadeOn()
>
>        newvol = vtk.vtkVolume()
>        newvol.SetMapper(volumeMapper)
>        newvol.SetProperty(volumeProperty)
>              self.vtk_renderer.AddVolume(newvol)
>        self.vtk_renderer.SetBackground(0, 0, 0)
>
>        # Show an outline (box)
>        if False:                      outline = vtk.vtkOutlineFilter()
>            outline.SetInputConnection(v16.GetOutputPort())
>            outlineMapper = vtk.vtkPolyDataMapper()
>            outlineMapper.SetInputConnection(outline.GetOutputPort())
>            outlineActor = vtk.vtkActor()
>            outlineActor.SetMapper(outlineMapper)
>            
> self.vtk_renderer.AddActor(outlineActor)                       
>                      # vtkImagePlaneWidget
>        if False:
>            ipw = vtk.vtkImagePlaneWidget()                  
> ipw.SetInput(v16.GetOutput())                                  
> ipw.SetPlaneOrientationToXAxes()
>            ipw.SetSliceIndex(1)
>            ipw.DisplayTextOn()
>                      picker = vtk.vtkCellPicker()
>            ipw.SetPicker(picker)
>                      
> ipw.SetInteractor(self.vtk_widget._Iren)                          
> ipw.PlaceWidget()
>            ipw.On()
>                  # vtkSphereWidget
>        if False:
>            w = vtk.vtkSphereWidget()
>            w.SetInput(v16.GetOutput())
>            w.SetInteractor(self.vtk_widget._Iren)
>            w.PlaceWidget()
>            w.On()
>
> class MyApp(wx.App):
>      def OnInit(self):
>        frame = MainFrame(None, "VTK")              
>        self.SetTopWindow(frame)
>        frame.Show(True)
>
>        return True
>
> app = MyApp(redirect=False)
>
> app.MainLoop()
>
> ==========================
>
>
> _______________________________________________
> This is the private VTK discussion list. Please keep messages 
> on-topic. Check the FAQ at: http://www.vtk.org/Wiki/VTK_FAQ
> Follow this link to subscribe/unsubscribe:
> http://www.vtk.org/mailman/listinfo/vtkusers





More information about the vtkusers mailing list