PDA

View Full Version : DXF normals

Pody
07-14-2002, 06:48 AM
I'm doing a program to display and manipulate 3D files. I chose to use dxf files... now i can read and display 3Dface objects properly in wireframe, but when i render them i have some problems.
I calculated the normals for each triangle (V0-V1)x(V1-V2):some trangles are rendered well,but others have the normals inverted.
What am i doing wrong?
Bye

satan
07-14-2002, 07:06 AM
If your normals get inverted it is most probably a problem of your crossproduct.

If (V0-V1)x(V1-V2) calculates the correct normal then (V1-V2)x(V0-V1) calculates the inverted one.
So you have to make sure, that the 'winding for your crossproduct' stays the same for all normal calculations.
Also keep in mind that OpenGL uses vertex and not face normals.

hih

[This message has been edited by satan (edited 07-14-2002).]

Pody
07-14-2002, 09:15 AM
The problem is that i calculate the normal for each vertex of each triangle in the same way, and some triangles are rendered well while other triangles not. http://www.opengl.org/discussion_boards/ubb/redface.gif(

Bob
07-14-2002, 09:37 AM
Then you don't have any specific order in which you store your vertices.

You have to store your vertices in either clockwise or counter clockwise order. If you mix them you will have a hard time to figure out the correct normal.

Pody
07-14-2002, 10:27 AM
I read the vertexes in the order they are in the dxf file. I thought they were already in the right order... am I doing something wrong?

Bob
07-14-2002, 10:33 AM
Reading them from the file in the correct order is not enough. The vertices also have to be stored in the correct order.

The source of the problem is probably that the mode itself is modelled without respect to the winding order of the vertices. If you want it to be correct in the first place, you have to fix the model itself.

Pody
07-14-2002, 10:44 AM
I store them in the order i read them

Jambolo
07-14-2002, 12:04 PM
I'm not sure if this is relavant.
In triangle strips, the winding order alternates. Given the vertices in a strip ...,vi,vi+1,vi+2,vi+3,..., the winding order of the triangle (vi,vi+1,vi+2) is opposite of the next triangle (vi+1,vi+2,vi+3).

You must negate every other face normal in the strip.

Miguel_dup1
07-14-2002, 04:52 PM
Try glEnable( GL_CULL_FACE ); to see if you can still see the object properly... If you cant see it properly is because the winding of the triangles are alternating somehow...
If they look good, then you are fine...

I would say that you compute the average normals... When I load my 3ds models and light them up without averaging the normals, the lighing looks really weird... I fix it with average normals...

Miguel_dup1
07-14-2002, 04:57 PM
Jambolo, a trick for avoiding the whole negating normals with triangle strips is that you read

vi, vi+1, vi+2
and then
vi+3, vi+2, vi+1

So, in a loop you read pairs of triangles with the order I mentioned rather than reading one triangle at a time and negating every other normal.

http://www.opengl.org/discussion_boards/ubb/smile.gif

Pody
07-14-2002, 11:51 PM
mmm... I was using GL_TRIANGLES, non GL_TRIANGLE_STRIP.
With glEnable(GL_CULL_FACE) and GL_TRIANGLES the sphere looks strange... I try with GL_TRIANGLE_STRIP and let you know.
Thanks

Pody
07-15-2002, 01:43 AM
GL_TRIANGLE_STRIP doesn't work: I have to use GL_TRIANGLES.

Here's the link to the picture of what i'm getting (with GL_TRIANGLES): http://spazioinwind.libero.it/galilee/sphere.jpg

http://www.opengl.org/discussion_boards/ubb/frown.gif

Pody
07-15-2002, 02:10 AM
(to see the above link, copy and paste it in the browser's address bar, clicking on it doesn't seem to work).
I loaded a model of a teapot in DXF with faces made up of 4 vertexes: the front part renders well, but the back part has the normals inverted (with light in front of it is black, with light behind it is white).
http://www.opengl.org/discussion_boards/ubb/frown.gif

satan
07-15-2002, 03:10 AM
I still think that it is a problem with the order of your crossproduct. For some vertices you seem to get the correct order for others not.
Try drawing your normals (unlit) just to see what they actually look like.
Since you use sphere and teapot as examples i think you average your normals, right?
Sure your averaging code is correct?
Do you use any edge preservation technique?
What about trying a simple cube ?
You could calculate your normals by hand and see what they should be and what your code calculates.

p.s.:I just saw that you said your sphere looks strange when you enable GL_CULL_FACE, that means that the winding of your triangles is wrong for some of them. You should fix this and then your problem with the normals should disappear. Keep backfaceculling enabled, lighting disabled and make sure that the winding is the same for all tris.

[This message has been edited by satan (edited 07-15-2002).]

Pody
07-15-2002, 04:15 AM
I don't average normals: before going into that I wanted to make this work.
I tried to paint the normals with a DXF cube: normals come out from only 3 faces, probably the others point downside the cube and are overlapped with the edges and the other normals.
Now i try with a hand-made cube and see what happens.

satan
07-15-2002, 05:18 AM
3 faces?
That should be 12 normals.

Put this three lines of code in your glsetup routine and render your dxf cuber again:

glFrontFace(GL_CCW);
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);

Does it show up right?

Pody
07-15-2002, 05:42 AM
My god.
I create a DXF of a cube manually, and i added a function to draw the normals.
Now, i have normals coming out from each point of the cube (now i do (v0-v1)x(v2-v1)).
BUT:
-with lighting enabled but no light in the scene, i can see the faces far from the camera and INSIDE the cube
-with a light in the scene, if i place the light near the camera, everytithing's black; if i move it behind the object, the inside part of the far faces becomes visible http://www.opengl.org/discussion_boards/ubb/frown.gif

To have an idea of what i'm talkin about, copy and paste: http://spazioinwind.libero.it/galilee/cube.jpg

satan
07-15-2002, 06:21 AM

Make sure that all your triangles are oriented the same way, default is counter clockwise.
That seems to have been your problem all the time.Like Bob said.

Miguel_dup1
07-15-2002, 06:37 AM
Ahhhhhhhhh...
I checked http://spazioinwind.libero.it/galilee/sphere.jpg

Thet normals are fine... Try

It should help a bit... And with average normals you are set to go...

Pody
07-15-2002, 06:51 AM
But, if the normals point outside, why aren't the face lighted???
I inserted the triangles of the cube manually, and they are in counter clockwise order.
I really don't know what else to try http://www.opengl.org/discussion_boards/ubb/frown.gif

Pody
07-15-2002, 06:53 AM
That normals are not fine...
In the top-left quarter of the sphere are fine, but apart from that it's all messy!

Pody
07-15-2002, 07:07 AM
Something's happening!
My Handed-cube vertex seems like they where in clock wise order (but looking from which point????).
Now the light works fine on the cube, and is doing well on the sphere too, but the sphere is still messy.
Question is: why, since i load it in the same way as the cube?

Miguel_dup1
07-15-2002, 07:09 AM
Ok, is that supossed to be a perfect sphere, cause it looks like a sphere on one side and the other looks like one but after world war 2.

If it is a perfect sphere I take my comments back...
Post some code for your normal computations...

Bob
07-15-2002, 12:18 PM
My Handed-cube vertex seems like they where in clock wise order (but looking from which point????).

The CW and CCW stuff is not relative a point in space, but from a direction relative the face itself. A triangle's vertices are in CCW order if they are seen in CCW order when looking at the triangle's front face. Looking at the back side will give you a different winding order. Take a piece of paper, make three points in CCW order and look at from the front side (the side on which you drew the points). Flip (not rotate) the paper, and you are looking at the back side. You will also see that the point are now in CW order instead.

So, CW/CCW is relative the front face (generally the face the normal is pointing out from) of the triangle, not a point in space.

Pody
07-15-2002, 11:36 PM
Well, if CCW order is as seeing it from the front face, my hand-made cube vertexes are in CCW order.

I ended up with the following:
if I calculate the normals so that my hand-made cube is displayed well, using
glFrontFace(GL_CW)
and normals calculated as (v0-v1)x(v2-v1),
the sphere is better but still has parts with normals inverted, a head model I downloaded from the net is displayed well, but many other models have the back side of the faces lighted instead of the front ones.

If I calculate normals so that my hand-made cube has the back side of the faces lighted, using
"glFrontFace(GL_CCW)"
and normals calculated as (v0-v1)x(v1-v2),
all the models that were previously lighted wrong are lighted well, but the sphere and the head are not.

I'm going nuts...
By the way if I give three point a,b,c, with GL_TRIANGLES how are they painted?In a picture in the openGL programming guide (addison-wesley) the indexes are in lcockwise order!

satan
07-16-2002, 01:12 AM
Default is counterclockwise for front faces.
Best to do is enable GL_CULL_FACE, since then only front faces are drawn and assuming that averaged only 50% of your models faces are visible you gain some speed not drawing the back faces. And of course you see if the order of your tris is correct, too. If your models don't show up correct with backfaceculling enabled forget about lighting and fix your order problems first.
I do not know how dxf stores it's vertices but it seems like the format does not care about any special order (or there is something wrong in your loading routine).
So you have to make sure that all vertices are in the correct order for opengl (or debug your loading routine).
I just took a look at some dxf description (i never used this format) and I found an interesting sentence:
'vertices CAN be order either clockwise or anticlockwise'
So you see that just loading your vertices is not enough for what you try to achieve. It depends on the dxf file if the vertices are ordered or not. So in your loading routine you have to take care of ordering yourself. Perhaps dxf is not the best format to work with, at least from what I have read I don't like it.

Think you have some work to do now http://www.opengl.org/discussion_boards/ubb/smile.gif.

Mezz
07-16-2002, 01:28 AM
Originally posted by Pody:

...
I calculated the normals for each triangle (V0-V1)x(V1-V2):some trangles are rendered well,but others have the normals inverted.
What am i doing wrong?
Bye

If you are calculating the normal with those subtractions then I think they are probably wrong, you need to have the vectors pointing the same way:

(v0-v1)x(v2-v1)

Then you have them both pointing outward from v1. You can do it with any point, but your vectors must point in the same direction.

-Mezz

Pody
07-16-2002, 01:32 AM
Yep, if I don't solve these problems today, i think i'm givin' up with that damn DXF (throwing away weeks of work http://www.opengl.org/discussion_boards/ubb/frown.gif ).
Now i'm doing some experiments with my hand-made DXF-cube: if i set CCW order,inside faces are lighted. Ok, but if i reverse the sign of the normals shouldn't it be ok?
It is not! It is rendered in the same way!
If I change order to CW it goes well.
What the \$#&%!!!
It seems openGL doesn't care of the sign of the normal, but only if the order is set to CCW or CW http://www.opengl.org/discussion_boards/ubb/frown.gif

Pody
07-16-2002, 01:38 AM
Correction: if I invert the sign of the normals, the faces are lit in the same way (inside), but with the light positioned in the opposite point.

Pody
07-16-2002, 02:41 AM
Ok, f%\$# the DXf.
I go with another format.
Any suggetion? 3DS?

Mezz
07-16-2002, 03:30 AM
Why not design your own model format and then write an exporter from a modeler?

You can get the 3DS MAX SDK and write quite simple exporters with it, if you don't try for stuff like bones etc.

Alternatively, perhaps Quake2's models (.md2) as they are quite easy to work with.

-Mezz

Pody
07-16-2002, 03:51 AM
Thanks, but for now I think I'll use the DXF files that work well.
I spent many days working on DXF, and I don't want to begin from zero again.

Turbo_Pascal
07-22-2002, 09:25 AM
Originally posted by Pody:
Thanks, but for now I think I'll use the DXF files that work well.
I spent many days working on DXF, and I don't want to begin from zero again.

Yea, the file format is not the problem, it only stored the vertices in what ever the way your DXF writer/reader rutine do. The adventage with DXF is they are ease to read/write, they are TXT file and severals CAD program can suport it. The disventage is that it mostly store just the vertices, but it lack other info like texturing data, etc.

Like the guys above said, disable the lights, disable the normals, enable the cullface and draw your model, check if all face in your model are rendered well.

For making all things go well all your faces model should have to be defined in the same direction, that is from counter clock wise or anti-counter close wise, this have to be done when your model was ORIGINAL drawn.

I suspect that you downloaded your teapot DXF model from Internet, or you are drawing your self the model using a CAD program. if so then most probably is that when the model was drawn in the CAD, some faces are defined in close-wise and some in anti-close wise, this is very comun when one is drawing in CAD tools. This not matter when you have the cull-face disabled cose all faces are rendered from both sides (back and front) so your model always can be see correctly, however when the cull-face is enabled or when the normalized is used then defining what faces are back and what faces are front is very important and relevant.

good luck.

tp.

Pody
07-22-2002, 09:42 AM
Ok, so it's not my fault if some polygons are reversed!
http://www.opengl.org/discussion_boards/ubb/smile.gif
thanks for the explanation!
Bye
Luca

Pody
07-22-2002, 09:45 AM
In fact, for example, i exported in DXF a face from 3ds Max, and my program renders it very well! http://www.opengl.org/discussion_boards/ubb/smile.gif