Jump to content
  • Advertisement
Sign in to follow this  
SuBXaX

Delphi 7 obj reading

This topic is 3079 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello everybody, i'm reading an obj file with delphi 7. Problem is that when i'm just calculating vertices, faces and normals, the count of them is great. But if i try to read, the count of faces, vertices and normals divides by 3 or 2 times. That is very strange issue, wich i can't figure out.

The code:

Here i'm just calculating vertices, faces and normals

procedure TForm1.Import(failas : string);
var F : TextFile;
begin
AssignFile(F,failas);
Reset(F);
vertexCount := 0;
facesCount := 0;
texCoordsCount := 0;
normalsCount := 0;
while not Eof(F) do
begin
Readln(F,buffer[0]);
if buffer[0] = 'v' then
begin
vertexCount := vertexCount + 1;
//Read(F,buffer[0],vertex[vertexCount].x,vertex[vertexCount].y,vertex[vertexCount].z);
end
else if buffer[0] = 'f' then
begin
facesCount := facesCount + 1;
//Read(F, buffer[0], vertices[facesCount].v1, texNormals[facesCount].v1, normals[facesCount].v1,
//vertices[facesCount].v2, texNormals[facesCount].v2, normals[facesCount].v2,
//vertices[facesCount].v3, texNormals[facesCount].v3, normals[facesCount].v3);

end
else if buffer[0] = 'n' then
begin
normalsCount := normalsCount + 1;
//Read(F, buffer[0], normals2[normalsCount].x, normals2[normalsCount].y, normals2[normalsCount].z);
end
else if buffer[0] = 't' then
begin
texCoordsCount := texCoordsCount + 1;
//Read(F, buffer[0], texCoords[texCoordsCount].x,texCoords[texCoordsCount].y,texCoords[texCoordsCount].z);
end
end;
memo1.Lines.add('FacesCount = ' + IntToStr(facesCount));
memo1.Lines.add('VertexCount = ' + IntToStr(vertexCount));
memo1.Lines.add('NormalsCount = ' + IntToStr(normalsCount));
CloseFile(F);
end;


Result:

FacesCount = 2256
VertexCount = 1178
NormalsCount = 1178


If i try to read, result is:

FacesCount = 1128
VertexCount = 589
NormalsCount = 589


Any ideas?

Share this post


Link to post
Share on other sites
Advertisement
First, I'm not familiar with Delphi. However, it appears that the sequence:

Readln(...);
Read(...);

would read 2 lines from the file. If that's correct, then you Readln a line, then Read another line without increasing the count.

According to the documentation, Readln() moves the read position of the file to the beginning of the next line. So a subsequent Read() is not from the same line you've just counted.

Example:

If the file is something like:

v x0 y0 z0
v x1 y1 z1

Then:
Readln(); // get x0,y0,z0 - count is 1
Readln(); // get x1,y1,z1 - count is 2

However:
Readln(); // get x0,y0,z0 - count is 1
Read(); // get x1,y1,z1 - count is still 1!

Share this post


Link to post
Share on other sites
Quote:
Original post by Whatz

How is buffer declared? Is it big enough to hold the data you read in?


Buffer = array [0..5000] of string[1]


[Edited by - SuBXaX on July 11, 2010 7:30:35 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by Buckeye
First, I'm not familiar with Delphi. However, it appears that the sequence:

Readln(...);
Read(...);

would read 2 lines from the file. If that's correct, then you Readln a line, then Read another line without increasing the count.

According to the documentation, Readln() moves the read position of the file to the beginning of the next line. So a subsequent Read() is not from the same line you've just counted.

Example:

If the file is something like:

v x0 y0 z0
v x1 y1 z1

Then:
Readln(); // get x0,y0,z0 - count is 1
Readln(); // get x1,y1,z1 - count is 2

However:
Readln(); // get x0,y0,z0 - count is 1
Read(); // get x1,y1,z1 - count is still 1!


I'v tried using Readln and Read function the result is the same :(

Share this post


Link to post
Share on other sites
Quote:
I'v tried using Readln and Read function the result is the same :(

You missed my point. If you uncomment the //Read() lines, you only increment the count once for each two lines you read.

Readln(); // read in vertex 1. After Readln(), file pointer is at beginning of line 2
count = count+1 // count = 1
Read(); // read in vertex 2. After Read(), file pointer is at end of line 2 or beginning of line 3

Readln(); // read in vertex 3
count = count+1 // count = 2
Read(); // read in vertex 4

4 vertices read. count = 2

After you do a Readln() and determine whether it's a vertex, normal, etc., you have to get the vertex/face/etc. data from the buf you just read in. Don't do another Read or Readln!

Something like:

Readln(buf);
if( buf[0]=='v')
{
increase v count;
// get the vertex data from buf. Don't do another Read or Readln
} else if( buf[0]=='f' )
{
increase f count;
// get the face data from buf. Don't do another Read or Readln
} .. //etc.

Share this post


Link to post
Share on other sites
Simultaneous posts. I edited my previous post.

After you do a Readln() and determine if it's a v, f, etc., process the vertex/face/etc. data you just read into your buffer.

Perhaps you can do something like:

Read(F,character C) // read in first character of line
if( C = 'v' )
{
vcount = vcount+1;
Readln(.. vertex values); // read in rest of line
} else if ( C='f' )
{
fcount = fcount+1;
Readln(.. face values);
} .. etc.

I'm not a Delphi person, but something like that should work.

Share this post


Link to post
Share on other sites
It's working, but it's very slow, program get's stuck. Ohh i wish there would be a way to make it faster, because i'v writen obj loader on C++ and it's very fast. On delphi program get's stuck.

Share this post


Link to post
Share on other sites
If Delphi is like the old Turbo Pascal I used to use, there is a lot of run-time type checking to keep things "safe" for you. That may be the problem. But it shouldn't be really slow.

When you say it gets "stuck," do you mean it loops indefinitely and you have to kill the program? If so, you may have to check for EOF after each Read and Readln.

This article does something like you're doing. You may want to take a look at it.

EDIT: You have to handle lines that don't begin with a recognized character. OBJ files allow comment lines, blank lines, etc.

For instance, if you have a comment line in your OBJ file:

Read(F,letter); // read in "/"
if( letter='..') // readln
else if( letter='..' // readln

then you won't read and throw away the comment line. The next time you Read(F,letter) it will be just the next character in the comment line.

That may why it's so slow. If you have a line that doesn't begin with v, f, n or t you read the entire line character by character.

Your "if, else if" sequence must account for all possibilities.

I can't remember if Delphi has the equivalent of a switch statement, but a better approach would be:

Read(F,letter);
switch( letter )
{
case 'v': // handle vertices
case 'f': // handle faces
...
default: Readln(F,text); // throw away an unrecognized line??
}


[Edited by - Buckeye on July 11, 2010 9:05:23 AM]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!