MESH_DECIMATE Crashes IDL

QUESTION: I have a simple, over-determined polygon and I am trying to use MESH_DECIMATE to eliminate some of the unneccesary vertices. But every time I call it, no matter which parameters I give it, IDL crashes with a segmentation fault. Is this function broken, or am I doing something wrong?

ANSWER: I think (personally) that the answer is “yes” and “yes”. The function is broken (no function, even if called incorrectly, should crash IDL) and you are probably calling it incorrectly.

The MESH_DECIMATE documentation fails to mention it, but if your polygon is not specified in a counter-clockwise fashion, then MESH_DECIMATE is likely to crash IDL. (I do not know why this is so, or how I came to discover this. Perhaps I just remembered reading something about counter-clockwise connectivity lists.) For example, I created a polygon around a section of Greenland I was studying. The polygon was a 3x701 double array. Since this polygon was constructed with FIND_BOUNDARY, which uses a chain-code algorithm to find adjacent pixels, I knew that the connectivity array could be constructed simply, like this:

   IDL> connect = Lindgen(701)

Initially, I called MESH_DECIMATE like this, which illustrates another weird property of the program:

   IDL> nverts = Mesh_Decimate(polygon, connect, VERTICES=verts, PERCENT_VERTICES=30)

The variables polygon and connect are input variables, containing the polygon vertices and the connectivity array, respectively. The keyword VERTICES will return the new vertices list, after decimation, and I have asked the program to retain 30 percent of the original vertices. The return value of the function is the number of triangles contained in the output vertex array after the decimation.

Oddly enough, the program won't run like this, and I received an Incorrect Number of Arguments error. After experimenting (I received no help from the documentation), I discovered that a third positional parameter, the output connectivity array for the new polygon, also has to be passed into the program. This is the first time in over 20 years of IDL programming experience I encounterd an output parameter that was a required parameter. “Strangely written program,” I remember thinking.

In any case, I called it like this, and promptly got dumped out of IDL:

   IDL> nverts = Mesh_Decimate(polygon, connect, outconn, VERTICES=verts, PERCENT_VERTICES=30)

I tried this in both IDL 6.3 and IDL 6.4, and on both a Windows and LINUX machine, and always with the same disasterous result.

After several hours of fooling around with various parameters, etc. I hit on the idea of reversing the connectivity array to produce a counter-clockwise polygon (the chain-code algorithm of FIND_BOUNDARY works in a clockwise fashion). That worked perfectly. My final code looked like this:

   IDL> s = Size(polygon, /DIMENSIONS)
   IDL> connect = Lindgen(s[1])
   IDL> rconnect = Reverse(connect)
   IDL> nverts = Mesh_Decimate(polygon, rconnect, outconn, VERTICES=verts, PERCENT_VERTICES=30)
   IDL> Help, nverts, verts
         NVERTS          LONG      =          206
         VERTS           FLOAT     = Array[3, 209]

Google
 
Web Coyote's Guide to IDL Programming