Fanning Software Consulting

Object Graphics Math Exception Errors

QUESTION: I have an object graphics program and every time I render the object graphics hierarchy I generate a math exception error. These are filling up my console window! Isn't there something I can do about this? They don't seem to affect my program, but they are just exceedingly annoying.

ANSWER: This, apparently, is an extremely common problem with object graphics rendering. The problem first showed up for me when I upgraded my computer to a 64-bit Windows 7 operating system. Tons of math exception errors where they hadn't appeared before.

   % Program caused arithmetic error: Floating illegal operand
   % Detected at FSC_SURFACE_DRAW_EVENTS  588 C:\IDL\coyote\fsc_surface.pro
   % Program caused arithmetic error: Floating illegal operand
   % Detected at FSC_SURFACE_DRAW_EVENTS  588 C:\IDL\coyote\fsc_surface.pro
   % Program caused arithmetic error: Floating illegal operand
   % Detected at FSC_SURFACE_DRAW_EVENTS  588 C:\IDL\coyote\fsc_surface.pro
   % Program caused arithmetic error: Floating illegal operand
   % Detected at FSC_SURFACE_DRAW_EVENTS  588 C:\IDL\coyote\fsc_surface.pro
   % Program caused arithmetic error: Floating illegal operand
   % Detected at FSC_SURFACE_DRAW_EVENTS  588 C:\IDL\coyote\fsc_surface.pro
   % Program caused arithmetic error: Floating illegal operand
   % Detected at FSC_SURFACE_DRAW_EVENTS  588 C:\IDL\coyote\fsc_surface.pro
   % Program caused arithmetic error: Floating illegal operand
   % Detected at FSC_SURFACE_DRAW_EVENTS  588 C:\IDL\coyote\fsc_surface.pro

I found I could fix my problem in several different ways. First, after an hour or so of fooling around, I discovered that the problem was being caused a RETAIN=2 keyword in my draw widget creation routine. This keyword tells IDL to be responsible for the backing store of the graphics window. (The backing store is what allows the window to repair itself when it has been "damaged" by moving another window in front of it, for example. It is, essentially, a copy of the window in memory.)

   drawID = Widget_Draw(tlb, XSize=400, YSize=400, Graphics_Level=2, $
      Event_Pro='FSC_Surface_Draw_Events', Button_Events=1, Retain=2) 

Removing the keyword solved my immediate problem, but--of course--my graphics window could no longer be restored properly. I knew I could always repair my graphics window myself, by turning expose events on for the graphics window, so I tried this. Originally, IDL did not ever keep track of backing store for object graphics programs, so this program had already been written with an event handler that responds to expose events, although none are generated unless this keyword is turned on for the draw widget.

   drawID = Widget_Draw(tlb, XSize=400, YSize=400, Graphics_Level=2, $
      Event_Pro='FSC_Surface_Draw_Events', Button_Events=1, Expose_Events=1)

This did, indeed, solve my problem, but I saw from my notes that I originally removed the expose events in this program and asked IDL to maintain the backing store to work around a problem with XManager in which expose events didn't work properly in blocking widgets. Who knew if that problem had been fixed. My notes were not complete enough for me to recreate the problem, so I couldn't be sure this was a fool-proof solution.

I discovered another solution was to perform the graphics rendering using the built-in software OpenGL library supplied with IDL, rather than to use the default hardware rendering performed by my graphics card. Most object graphics problems are caused by hardware graphics drivers. So always be absolutely sure you have the latest graphics drivers from your vendor before you spend a lot of time exploring other solutions. In my case, I did have the latest drivers, but that is no guarantee they would work properly. I almost always use software rendering in my "public" programs because there is no guarantee anyone will be as fastidious at maintaining their graphics drivers as I am and it saves me a lot of support headaches. I am not sure why I wasn't using software rendering in this program, but I wasn't. But the solution I ended up with asks IDL to maintain the backing store (for my UNIX friends) and uses software rendering to avoid the math errors.

    drawID = Widget_Draw(tlb, XSize=400, YSize=400, Graphics_Level=2, $
      Event_Pro='FSC_Surface_Draw_Events', Button_Events=1, Retain=2, Renderer=1)

But even this might not fix all your math exception error problems. Sometimes the only solution is to turn the damn math exception errors off. If you went that route, you would turn math exception handling off while you were drawing your graphics hierarchy. The code might look like this.

    currentExcept = !Except    !Except = 0
   info.thisWindow -> Draw, info.thisView    dummy = Check_Math()
   !Except = currentExcept 

Version of IDL used to prepare this article: IDL 7.1.2

Google
 
Web Coyote's Guide to IDL Programming