Hello, I have developed an application which renders a complex object using OpenGL. I now need to export this rendering to a machine that accepts STL as its native input format. I would like to somehow use OpenGL’s feedback functions to produce the list of exposed (front and back-facing but non-hidden) tesselized triangles that form my 3D object as these triangles are piped through the OpenGL pipeline, thus resulting in an STL format file that describes the exposed surface of the object(s) being rendered. Does anyone know of a a quick and dirty way to do this? Much thanks, Gregory Hassett

Should be relatively straight forward. Just be sure to disable polygon culling, use an orthognal projection, use a viewpoint that places your object completely within the bounds of the viewport, and make your feedback array large enough to hold all the values returned. You’ll know if the array is large enough when glRenderMode returns a positive value when you switch OpenGL out of feedback mode.

Thanks – good advice (esp. the orthogonal projection – I had forgotten about that). Since I am using GL_QUAD_STRIP’s and GL_TRIANGLES and Quadrics (Spheres and Cylinders), I am not sure that the feedback buffer will infact return the TRIANGLES that OpenGL creates when rendering these objects. Is it true that the ordinary feedback buffer can be used to get the series of triangles that OpenGL creates when rendering a sphere, cylinder, quad-strip, triangle-strip, etc.? // thanks // greg //

As long as the polygon mode is set to fill, and the feedback mode is enabled, OpenGL will fill the feedback array with polygon data. Most, if not all of those polygons will be triangles. If OpenGL happens to send polygons that are not triangles, it is a simple matter to decompose them into the triangles the STL file needs.

Also one other detail, since OpenGL will return vertices in window coordinates, you will likely need to convert them into something more suitable as well.

Thanks for the help so far – I did as was suggested and did in fact get a nice list of tesselized triangles. Unfortunately they are the triangles that are drawn after the 3d model is projected into a 2-d rendering, i.e., they all have the same Z coordinate. What I need are the triangles that are created when I call gluSphere, gluCylinder, etc., as they exist in 3 dimensions, not the triangles that describe the 2-d projection… any help is, as always, very much appreciated… // greg //

Hi,

Are you talking about STL file format, the one exported by major CAD systems?

If so I have done some work on this. I found that to get a good smooth rendered object from an STL data you need to preform some initial calculations which determine the connectivity of the triangles. This proved to be to time consuming…

Hi, yes I am talking about the STL format. I neet to create an STL file from a working OpenGL rendering application, not the other way around, though. I get the triangles from OpenGL’s feedback mode, but they’re for the 2D projection instead of the 3D model. Help! // thanks // greg //

Uh, that is surprising. Ok, another idea is to use a perspective projection, and then apply the inverse transform to the coordinates to get back into world coordinates. Or failing that, continue using the orthographic projection, but do so from 2 different orthognal viewing directions, and match up the points (much like is done in a medical scan) to retrieve a complete 3D data set.

Dear DFrey, thank you for keeping up on this topic. Yes, I agree, it is VERY strange that the triangles are returned are all on the same Z-plane (I view the STL file that I create in a viewer and it looks like a perfect tringle mesh of the object OpenGL drew onto the screen – until I rotate it, and the entire triangle mesh rotates as though it was drawn on a sheet of paper (it has no depth).

What puzzles me is: If OpenGL was going to return the triangles that it would draw to render the PROJECTED image (on a 2D screen), then why have the GL_3D mode available in glFeedbackBuffer() at all? I am sure that I must be doing somethign wrong, but after trying every conceivable permutation of coding this thing, nothing works (they all produce my “flatlanders” version of the triangle mesh… I wish there was a way to show it to you).

Here is the code I’m using (I’ve tried many variants of this, including glOrtho() projections, starting rendering in different MatrixMode’s, etc… but they all turn out the same, essentially: a flat triangle mesh). Your help is really, really appreciated …

// ------

pBuf = new GLfloat [500000]; // gph todo: this constant is BAD BAD BAD

glFeedbackBuffer (500000, GL_3D, pBuf);viewport[0] = viewport[1] = 0;

viewport[2] = m_rcPos.right-m_rcPos.left;

viewport[3] = m_rcPos.bottom-m_rcPos.top;glMatrixMode (GL_MODELVIEW);

glPushMatrix ();glLoadIdentity ();

gluPerspective (m_fViewAngleDeg, (GLfloat)viewport[2]/(GLfloat)viewport[3], 0.1, 1000);glRenderMode (GL_FEEDBACK);

DrawScene (NULL, viewport[2], viewport[3]);

glMatrixMode (GL_MODELVIEW);

glPopMatrix ();

// ------

Also puzzling: the Z coordinates returned into the feedback buffer are all VERY CLOSE to 1.0, but they’re not exactly 1.0. They’re so close that in the viewer, the triangles all appear to be on the same plane. Here are some sample triangles (as written by my code in STL format):

solid

facet normal 0.0 0.0 0.0

outer loop

vertex 191.140137 310.162109 0.998425

vertex 189.373047 309.271484 0.998413

vertex 185.835449 310.101563 0.998408

endloop

endfacet

facet normal 0.0 0.0 0.0

outer loop

vertex 187.203125 311.090820 0.998419

vertex 191.140137 310.162109 0.998425

vertex 185.835449 310.101563 0.998408

endloop

endfacet

facet normal 0.0 0.0 0.0

outer loop

vertex 192.947754 311.609863 0.998436

vertex 191.140137 310.162109 0.998425

vertex 187.203125 311.090820 0.998419

endloop

endfacet

…

endsolid

Ok, major insight achieved.

The Z “coordinates” that are being returned in the feedback buffer actually DO contain the relative position of each vertex on the Z axis. Unlike the X- and Y-coordinates, though, the Z coordinate seems to be scaled into a number between 0 and 1 (this would have been a helpful thing to point out somewhere in the glFeedbackBuffer documentation).

In my case, for reasons as yet undiscovered, the values returned in the Z “coordinates” range from a minimum of 0.99700 to a maximum of about 0.99900. Thus, if I scale the coordinate appropriately, using values determined empirically, I can see the depth in my triangles with I load the generated STL file into an STL viewer. This is a big step forward!

However, I still don’t understand what values I SHOULD be using to scale the Z coordinate value to be consistent with its corresponding X- and Y-values. It might have something to do with how I set my clipping planes in the call to glOrtho or gluPerspective, but I’m baffled… can anyone provide any more insight?

[This message has been edited by ghassett (edited 01-09-2002).]

The z-value is always between 0.0 and 1.0. This represents the area between the near and far clipping plane (defined in glOrtho or gluPerspective).

So,

zNear + z * (zFar - zNear)

should give you the correct z-value.

Kilam.

Hi

You get the renderd vertices. They go through the modelview matrix, the projection matrix and then through the perspective divide, followed by the viewports transform

what about using gluUnproject to transform the winx,winy,winz(feedbacks return)to objx,objy,objz.

bye

ScottManDeath

Originally posted by ghassett:

…

gluPerspective (m_fViewAngleDeg, (GLfloat)viewport[2]/(GLfloat)viewport[3], 0.1, 1000);

ghasset,

in addition to the info from ScottManDeath you may want to consider increasing the near value to 1 or 10. This will increase the z-buffer accuracy and hence decrease the errors you’ll get when gluUnprojecting.

(as you may know, the ratio near / far has an impact on the distribution of z-values)

HTH

Jean-Marc

Hello,

Every now and then a story needs a happy ending: With everyone’s help, I was able to get the triangles that I wanted. I would not have been able to do it without the helpful people on this board. Thanks to everyone!