CAD programming & selection rendering...

Hello !

I want to develop a CAD-based application powered by OpenGL. Of course, I have to implement “object picking”. I know two ways to do that. First, the selection rendering with “RenderMode(GL_SELECT)” but it costs one rendering… Second, the ray intersection method which is CPU-time consuming. In fact, all I want to do is to store a user defined 32-bits value for each pixel that OpenGL rasterize. I’ve tried to use z-buffer to store them but now, I want to use z-buffer for z-buffering.
Is it possible to create a buffer like that ? Is there any other way used by real CAD-based software ? Is OpenGL’s selection mode fast enough ?

Thanks for any helps…

-- Spotaszn --

I’m doing CAD application programming too. I use the picking by ray casting. It’s fast enough, as you can optimize the ray casting in your model representation (bounding boxes etc.).
How big will your models be? Single parts or assemblies? Which 3d-kernel are you using? The common ones support picking as far as I know.


[This message has been edited by Kilam Malik (edited 12-11-2000).]

I’m sure ray casting is fast enough for most common applications but it prevent to pick vertices and lines… I think (?).
Then, I don’t use 3d-kernel other than OpenGL API… Sorry, I hate high-level APIs !
The models that I want to manipulate will be as big as possible and I want to be able to pick polygons, edges, vertices, curves like LightWave does…
Thanks for your answer, I will use ray casting for simple models and real time rendering and I’m going on to deal with OpenGL’s Selection Mode for all other cases.

– Spotaszn –

One thing I have experienced playing with editors that have only one 3D view is that you’re not always be able to pick the right vertex. Thus you will need three actually only two 2D views one to differentiate the depth and the other the height or width.

The best setup is having three 2D windows and one 3D window and instead of picking objects in the 3D window use the 2D views for picking. Anytime you querying info from video card you’re stalling the graphics pipeline and discarding info from the cache, I think That’s why it’s best to keep copies of the transform matrices and send the originals to video card.

But the bottom line is: You will loose one degree of freedom when picking in 3D view and will either have to rotate the model or rotate the world in order to get to the other unseen and overlaid vertex. This has been my experience so far

You’re right ! For convenience, I will use four-views editor with only one perspective view (3D view), but even if I use “2D” OpenGL rendered views, I don’t know which is the best way to implement object picking…

I’ve done some benchmarks with most common software (3DS Max, LightWave, Maya, etc). I know that 3DS Max and Maya use OpenGL and it seems that one selection take the average time of one simple rendering.

I’ve done some tests with OpenGL’s Selection Mode… Even if I’m not totally satisfied, it appears to be the best way I’ve found.

Thanks !

– Spotaszn –

Spotaszn, the red book mentioned something about going into your back buffer and query the color under the mouse pointer. Based on that color you could id the primitive. I’m not sure if this is what you meant or not but if yes then you have to give each primitive different color. I haven’t done any picking yet so I don’t know what I’m talking about

Anyway, couldn’t you just use the windowing i.e. os api like win32, mfc, etc. for the 2D views and have only the 3D view be opengl? I’m doing an editor like this and so far no problems. Good luck!

Well ! I’m stupid… I’ve done what you said using the z-buffer to store IDs… I should have use back-buffer ! Thanks ! I’m going to explore this way…

I’ve tried to use Win32 GDI functions but they are very slow. Why use GDI on GeForce-based cards when OpenGL is incredibly faster !

– Spotaszn who thanks you –

Hi there,

I’ve done the thing JD mentions. You just give every primitive a 24bit id. When it’s time to update the screen, render the ‘normal’ scene with lighting, shading, texturing etc. to the backbuffer. Swapbuffers and now render the selection scene again without texturing, shading and lighting with each primitive assigned the color composed of it’s id. The backbuffer now contains a complete render of your scene where each primative has a unique color.
Use glReadPixels() to read the pixel in the backbuffer. Use the color of the pixel to recreate your Id.

Note this example is for 24bit you can make it work in 8,16 bit but you’ll have less id’s of course

It has worked great so far and it’s as accurate as your monitors resolution.

over here in the OpenGL faq there’s more info

Some arguments, why picking with ray casting can be faster:
When you got very big models, so that your rendering time will be > 2 Seconds, it will be hard to pick something. You could prevent that by drawing the picking objects with less triangles. But then you need 2 representations of your models or a mesh decimation algorithm (PM e.g.). With ray casting you could select your objects by bounding boxes and then try to pick the specific object/triangle/edge/vertex with your ray.

With color picking, when the user picks the screen, you only find the object in front. Maybe you want to give him the choice of all objects lying on the ray. That could be interesting, when the objects are transparent. Or (you said you do a CAD application) e.g. look at SolidEdge. The give you the choice of all faces lying on the ray when you pick. Then you don’t have to turn your model.

Maybe this are sophisticated things that you will put in later into your application. Now the color picking is easier to implement. But later, you would have a hard work to change it.


[This message has been edited by Kilam Malik (edited 12-14-2000).]

How do I select a single vertex or an edge with Ray Casting ? :wink:

I think the best way is to implement Selection Mode and Color Picking… And Ray Casting for some polygon selections.

-- Spotaszn --

Hello Kilam,

How the ray casting way work ? can someone give me a tutorial, or some part of code, to explain ?

Thank you for the moment
Best regards

Ok, a quick overview how I do ray casting in my models.

First I have to say, I save my models in a b-rep called “winged edges”. That means, I have no triangles but complete polygons with holes (concave and convex).

First Step:
Calculate the section of the ray with the bounding box of each object (In my case I have assemblies built up of many mechanical parts like plates, fasteners, nuts etc.). Then you get a set of objects that may be hit by the ray.

Second Step:
For each of that candidates, calculate the section of the ray with each polygon. That sounds harder than it is. I reduced the problem to 2D: You calculate the section point of the plane (in which the polygon lies) and the ray. Now you convert the complete polygon with the 3D ray intersection point into 2D-coordinates. Then you do the well known “point in polygon” test. With this test you get the information, if the point is inside, outside or on a edge or vertex of the polygon.

Thats it!

[This message has been edited by Kilam Malik (edited 12-15-2000).]

I do not agree that using RenderMode(GL_SELECT) would be such a performance drag. Since during the selection pass you can limit rendering to a very small Frustrum or Ortho Volume centered around your mouse position. So this pass will not use a lot of fillrate or geometric processing.

Kilam, which solid modeling kernel are you using? I am doing some CAD work as well. I looked at ACIS and Parasolid, but in the end I went with PTC’s Pro/Desktop (built on the Parasolid kernel) because I decided that a higher level API was better suited to what I’m doing. However I’d be interested to hear if you have any strong recommendation for whatever kernel you’re using.

I use my own modeling kernel. But it only works on plane polygons. So curved surfaces are approximated. It’s a feature based modeler with export capabilities to other CAD’s. As only the features are exported, there is no need to use the same internal structures as the other kernels like NURBS.

So I can’t give you any advise for a good kernel. We have tested ACIS, but it had many bugs. When I compare the CAD’s using ACIS and Parasolid, I have to say, Parasolid must be better… So I think your choice was good :slight_smile:


To Rob and Kilam,

I am interested in starting my own CAD application. Are there more 3D-Kernels which might be used for this besides ACIS and Parasolid. I was thinking about OpenCascade.

What do you think?

I only had a brief look on OpenCascade, but it seems very similar to ACIS and ParaSolid. So there’s no reason not to use it. And the best thing is, that it’s free.
I only think, that for sophisticated usage of surfaces, the ACIS or ParaSolid could be better, as they are on the market now for a long time.


Do you have any idea on how much it would cost to use Parasolid or ACIS as a 3D Kernel?

ACIS wants a fee per sold seat. It’s about 50$. I think ParaSolid is more expensive, as you can see ACIS in nearly every CAD for 200$. But the ParaSolid can only be found in expensive CAD’s.