• Advertisement

Archived

This topic is now archived and is closed to further replies.

Organizing code

This topic is 5845 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

Hi. I''m trying to develop a 3D sculpting application and find myself doubting a lot. How do the pro''s use C++ class implementation to handle relationship between points and faces? and what should be the base class?

Share this post


Link to post
Share on other sites
Advertisement
I am not sure there is really a solid relationship between faces and points as far as class implementation is concerned. I think you will probably have a Vertex class at the very least. Now, you could also make a Face class, but that may be overkill. The reason is that as far as i know the best way to manage the vertices in a mesh is just by keeping them in an array:

Vertex verts[1000];

The relationship to faces then comes into play indirectly because you consider every 3 vertices to be a face. For instance, (verts[0], verts[1], verts[2]) defines the first face.

Another method uses index arrays as well. where the face are defined by indices into the vertex array. For instance, (verts[indices[0], verts[indices[1]], verts[indices[2]]) defines the first face.

It comes down to the fact that when you render something using DirectX (thats the API I know), you dont want render each face one at a time you want them all to be in one buffer so you can render them at one time. Its basically a push and pull between how granular you want your class structure to how optimized you want it to be.

I hope I even remotely answered your question.

-BrianH

Share this post


Link to post
Share on other sites
well I don't know how pros do it but I'll tell you how I did it. I use ASE files for my meshes so I just created a mesh class which mirrors the way these store the data.


    
class vertexHandler {
public:
void Copy(vertexHandler v);

vectorHandler position;
vectorHandler normal;
vectorHandler colour;
};

class triangleHandler {
public:
unsigned int pointA, pointB, pointC;
vectorHandler tcoordsA, tcoordsB, tcoordsC;
vectorHandler normal;
};

class meshHandler {
public:
meshHandler();
~meshHandler();

void LoadASE(char* filename);
void Draw(void);

unsigned int vertexCount;
vertexHandler* vertex;

unsigned int triangleCount;
triangleHandler* triangle;
};

void meshHandler::Draw(void)
{
register unsigned int i;

for (i=0; i<triangleCount; i++) {

glBegin(GL_TRIANGLES);
glTexCoord2f( triangle[i].tcoordsA.x,
triangle[i].tcoordsA.y);
glVertex3f( vertex[triangle[i].pointA].position.x,
vertex[triangle[i].pointA].position.y,
vertex[triangle[i].pointA].position.z);

glTexCoord2f( triangle[i].tcoordsB.x,
triangle[i].tcoordsB.y);
glVertex3f( vertex[triangle[i].pointB].position.x,
vertex[triangle[i].pointB].position.y,
vertex[triangle[i].pointB].position.z);

glTexCoord2f( triangle[i].tcoordsC.x,
triangle[i].tcoordsC.y);
glVertex3f( vertex[triangle[i].pointC].position.x,
vertex[triangle[i].pointC].position.y,
vertex[triangle[i].pointC].position.z);
glEnd();
}
}


note that the triangle class doesn't store verteces - this would mean duplicating a lot of data - instead it stores integers which refer to verteces in the array stored in a mesh object. A triangle object is therefore useless on its own - it is only there to assist the mesh class. I haven't included the LoadASE function - its too big - also vertex colour as stored in the vertex class is ignored - this is there in case I want to do "pre-lit" objects or other odd things but usually I'm using vertex colour for lighting. It may not the "best" way of storing mesh data but it's very simple and pretty fast. Hope that helps.

EDIT: oh yeah, a "vectorHandler" is just four floats x, y, z and w (w is not used here). Also, for reasons unknown, instances of the word "triangle" are turning purple in my source box! Needless to say you should ignore this purpleness.
-

Geocyte Has Committed Suicide.

[edited by - geocyte on April 22, 2002 8:10:20 AM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
You could do it like this for a face

// First a class to hold vertex data
class CVertex {
public:
CVertex();
CVertex(float x, float y, float z, // Position
float nx, float ny, float nz, // Normal
int dr, int dg, int db, // Diffuse Color
int sr, int sg, int sb, Specular Color
float tu, float tv); // Tex Coord set 1
~CVertex();

public:
void Set(float x, float y, float z, // Position
float nx, float ny, float nz, // Normal
int dr, int dg, int db, // Diffuse Color
int sr, int sg, int sb, Specular Color
float tu, float tv); // Tex coord set 1

public:
D3DVECTOR m_vPos;
D3DVECTOR m_vNorm;
D3DCOLOR m_Diffuse;
D3DCOLOR m_Specular;
float m_tu, m_tv;
};


// Now you can define a face class like this
class CFace {
public:
CFace();
~CFace();

public:
void SetProps(int VertID /* 0 to 2 */, D3DVECTOR Position,
D3DCOLOR Color);
Render();

protected:
CVertex m_pVertex[3]; // Holds 3 vertices for the face
};

The function SetProps is called 3 times 1 for each vertex then the face is drawn from the vertices
void CFace::SetProps(int VertID /* 0 to 2 */, D3DVECTOR Position,
D3DCOLOR Color)
{
if (VertID < 0 || VertID > 2)
return; // Invalid point

m_pVertex[VertID].m_vPos = Position;
m_pVertex[VertID].Diffuse = Color;
}

You can expand this of course but the relation you wanted is there. the face class holds a pointer to 3 vertex classes.

IS this what you need???
I don''t even bother with this method as it''s great for single faces I just use a vertex and index buffer now to define a list of faces however I still use my vertex class to hold each vertex''s data and copy the data from each vertex class instance into 1 big vertex buffer. The index buffer then references this list of vertices to define its faces.

Drawing singular faces each with 3 vertices to define meshes is unoptimized.

Share this post


Link to post
Share on other sites

  • Advertisement