[GRASS-dev] Re: GRASS-dev] Is wxNVIZ supposed to work?

Michael Barton michael.barton at asu.edu
Fri Nov 20 18:16:58 EST 2009


Glynn,

I just compiled 6.5 Wednesday night and 7.0 trunk last night. wxNVIZ  
works fine on both.

I'm using a Mac with OS 10.5.6, Python 2.5.1, and wxPython 2.8.9.2

Michael




On Nov 20, 2009, at 10:05 AM, grass-dev-request at lists.osgeo.org wrote:

> Date: Thu, 19 Nov 2009 21:32:10 +0000
> From: Glynn Clements <glynn at gclements.plus.com>
> Subject: [GRASS-dev] Is wxNVIZ supposed to work?
> To: grass-dev at lists.osgeo.org
> Message-ID: <19205.47450.333317.639924 at cerise.gclements.plus.com>
> Content-Type: text/plain; charset=us-ascii
>
>
> The wxGUI nviz module is broken for me in both 6.4.0-RC5 and 7.0-head.
>
> In both cases, selecting "3D view" in the map display window results
> in a segfault in the wxClientDC constructor.
>
> The last few stack frames are:
>
> #0  wxWindowDC (this=0xb225028, window=0x0)
>    at /var/tmp/portage/x11-libs/wxGTK-2.8.10.1-r1/work/wxPython- 
> src-2.8.10.1/src/gtk/dcclient.cpp:294
> #1  0xb7558189 in wxClientDC (this=0xb225028, win=0x0)
>    at /var/tmp/portage/x11-libs/wxGTK-2.8.10.1-r1/work/wxPython- 
> src-2.8.10.1/src/gtk/dcclient.cpp:2473
> #2  0xb755834c in wxPaintDC (this=0xb225028, win=0xb11e420)
>    at /var/tmp/portage/x11-libs/wxGTK-2.8.10.1-r1/work/wxPython- 
> src-2.8.10.1/src/gtk/dcclient.cpp:2436
> #3  0xb6648a49 in _wrap_new_PaintDC (args=0x0, kwargs=0x0)
>    at src/gtk/_gdi_wrap.cpp:24778
> #4  0xb7fd7971 in PyCFunction_Call (func=0xa11f7cc, arg=0xae1074c,
>    kw=0xb11e420) at Objects/methodobject.c:85
>
> Enabling debugging, the last message before it crashes is:
>
> GUI D3/5: GLCanvas.OnPaint()
>
> Combined, these point to it crashing here (nviz_mapdisp.py:156)
>
> 153    def OnPaint(self, event):
> 154        Debug.msg(3, "GLCanvas.OnPaint()")
> 155
> 156        dc = wx.PaintDC(self)
> 157        self.SetCurrent()
> 158
> 159        if not self.initView:
> 160            self.nvizClass.InitView()
> 161            self.initView = True
>
> If I comment out that line (it doesn't need the DC, but apparently
> this is needed on Windows to force the window contents to be marked as
> "valid", otherwise it will just try to repaint it again), it crashes
> within OpenGL:
>
> #0  0xb41ed346 in glDisable () at ../../../src/mesa/x86/glapi_x86.S: 
> 368
> #1  0xb42566a5 in gsd_set_clipplane (num=0, able=0) at gsd_prim.c:1028
> #2  0xb424d5f0 in gsd_cplane_off (num=0) at gsd_cplane.c:129
> #3  0xb423eeba in GS_unset_cplane (num=0) at GS2.c:3156
> #4  0xb4938abc in Nviz_off_cplane (data=0xaef4188, id=0) at  
> cplanes_obj.c:51
> #5  0xb493a348 in Nviz_init_data (data=0xaef4188) at nviz.c:42
> #6  0xb42c1c8d in Nviz::InitView ()
>   from /usr/local/src/grass/svn/dist.i686-pc-linux-gnu/etc/wxpython/ 
> nviz/_grass7_wxnviz.so
> #7  0xb42d82dc in _wrap_Nviz_InitView ()
>   from /usr/local/src/grass/svn/dist.i686-pc-linux-gnu/etc/wxpython/ 
> nviz/_grass7_wxnviz.so
> #8  0xb7eb29e9 in PyCFunction_Call (func=0xa8e784c, arg=0xabdd6ac,
>    kw=0xaef4188) at Objects/methodobject.c:116
>
> My first instinct is that the widget isn't getting "realised" (i.e.
> "made real", meaning that the underlying X window has been created by
> the X server).
>
> But how is it getting a paint event if it hasn't been realised?
>
> Ah: mapdisp.py:425 calls OnPaint immediately after creating the  
> window:
>
> 419            if not self.MapWindow3D:
> 420                self.MapWindow3D = nviz.GLWindow(self,  
> id=wx.ID_ANY,
> 421                                                 Map=self.Map,  
> tree=self.tree, lmgr=self._layerManager)
> 422                # -> show after paint
> 423                self.nvizToolWin = nviz.NvizToolWindow(self,  
> id=wx.ID_ANY,
> 424                                                        
> mapWindow=self.MapWindow3D)
> 425                self.MapWindow3D.OnPaint(None) # -> LoadData
> 426                self.MapWindow3D.Show()
> 427                self.MapWindow3D.UpdateView(None)
>
> If I comment out line 425, it gets further before crashing in layout:
>
> #0  0xb74fa1c3 in wxWindow::DoSetSize (this=0xa4fd178, x=1, y=81,  
> width=768,
>    height=463, sizeFlags=4)
>    at /var/tmp/portage/x11-libs/wxGTK-2.8.10.1-r1/work/wxPython- 
> src-2.8.10.1/src/gtk/window.cpp:2763
> #1  0xb75fa54f in wxSizerItem::SetDimension (this=0xa39e670,  
> pos_=@0x0,
>    size_=@0x0)
>    at /var/tmp/portage/x11-libs/wxGTK-2.8.10.1-r1/work/wxPython- 
> src-2.8.10.1/include/wx/window.h:225
> #2  0xb75fe29d in wxBoxSizer::RecalcSizes (this=0xa3b0980)
>    at /var/tmp/portage/x11-libs/wxGTK-2.8.10.1-r1/work/wxPython- 
> src-2.8.10.1/src/common/sizer.cpp:1751
> #3  0xb75fb6a4 in wxSizer::Layout (this=0xa3b0980)
>    at /var/tmp/portage/x11-libs/wxGTK-2.8.10.1-r1/work/wxPython- 
> src-2.8.10.1/src/common/sizer.cpp:880
> #4  0xb75fa2b9 in wxSizer::SetDimension (this=0x1, x=0, y=0,  
> width=0, height=0)
>    at /var/tmp/portage/x11-libs/wxGTK-2.8.10.1-r1/work/wxPython- 
> src-2.8.10.1/src/common/sizer.cpp:976
>
> At which point, I'm lost.
>
> I think that this is an issue of trying to make calls before the
> toolkit is ready for them. E.g. you can't create a widget then assume
> that it's immediately ready for use; you have to wait for the toolkit
> to report the appropriate event.
>
> The comment at mapdisp.py:425:
>
> 425                self.MapWindow3D.OnPaint(None) # -> LoadData
>
> suggests that it's relying upon the OnPaint method to load the data,
> and the contents of the OnPaint method seem to support that.
>
> But many of the things which are occuring there rely upon OpenGL
> having been initialised. It's safe to assume that's the case if the
> handler is called in response to an EVT_PAINT event, but it probably
> won't be true if the program calls it itself as soon as the widget has
> been created.
>
> However, removing that call means that the nviz library and the binary
> grass7_wxnviz module won't have been initialised, and UpdateView(),
> OnSize() etc assume that they have. IOW, the code both needs to call
> OnPaint() at that point but cannot call OnPaint() at that point.
>
> The only solution is to check that initialisation has happened before
> relying upon it. Being able to force initialisation as soon as the
> widget is created would make life simpler, but unfortunately it isn't
> possible; you have to wait until the widget is ready.
>
> --
> Glynn Clements <glynn at gclements.plus.com>



More information about the grass-dev mailing list