loading a stl 3d model file
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10

Thread: loading a stl 3d model file

  1. #1
    Join Date
    Aug 2001
    Posts
    18

    loading a stl 3d model file

    i'm now try to write a program in opengl to load and render stl file(stereolithography file).
    i be able to read the binary stl and render with the glbegin(GL_TRIANGLE)...glEnd the result is facet rendering ..

    now i'm trying to render with smooth shading...
    this required the calculation of vertex normal...
    i'm now facing problem of how to calculate the faces indices...can anyone help me ????








  2. #2
    Join Date
    Oct 2001
    Location
    lake of fire and brimstone
    Posts
    1,628

    Re: loading a stl 3d model file

    I also want to read in a .stl file and visualise it. However, for now I can only readin .asc-files.
    These files are quite simple, human readable and I think they have faces indices standard. There are good 3D converters for .stl to .asc conversion available. If nothing else works, try it that way. By the way, where did you find information about how an .stl is composed, and what information it contains? Could you perhaps send the code to read-in a .stl file? You would really make me happy.

    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞

  3. #3
    Join Date
    Aug 2001
    Posts
    18

    Re: loading a stl 3d model file

    for now i manage to load only binary stl
    i enclose my code here..( in C & opengl)
    could you send you ascii stl code to me.....
    however thank for your help


  4. #4
    Join Date
    Aug 2001
    Posts
    18

    Re: loading a stl 3d model file

    for now i manage to load only binary stl
    i enclose my code here..( in C & opengl)
    could you send you ascii stl code to me.....
    however thank for your help

    Code:
    #include <windows.h>
    #include <gl/gl.h>
    #include <gl/glu.h>
    #include <gl/glut.h>
    #include <math.h>
    
    	GLfloat	 lightPos[] = {-300.0f, 100.0f, 100.0f, 0.0f };
    
    // Define a constant for the value of PI
    #define GL_PI 3.1415f
    
    // Rotation amounts
    static GLfloat xRot = 0.0f;
    static GLfloat yRot = 0.0f;
    
    float vertex[3][3];
    # include < stdio.h>
    # include < stdlib.h>
    # include < string.h>
    
    struct group{
    
    	float normal[3];
    
    	float vertex1[3];
    	float vertex2[3];
    	float vertex3[3];
    
    	char unuse [2];
    
    } ;
    
    /*struct group{
    
        float normal[3];
    
    float vertexs[3][3];
    
    	char unuse [2];
    
    } ;
    */
    
     struct group facet[500000] ;
    	  
    	int i,j,num;
    	
    	char filename[80];
    	int numfacet[1];
      
    
    // Reduces a normal vector specified as a set of three coordinates,
    // to a unit normal vector of length one.
    void ReduceToUnit(float vector[3])
    	{
    	float length;
    	
    	// Calculate the length of the vector		
    	length = (float)sqrt((vector[0]*vector[0]) + 
    						(vector[1]*vector[1]) +
    						(vector[2]*vector[2]));
    
    	// Keep the program from blowing up by providing an exceptable
    	// value for vectors that may calculated too close to zero.
    	if(length == 0.0f)
    		length = 1.0f;
    
    	// Dividing each element by the length will result in a
    	// unit normal vector.
    	vector[0] /= length;
    	vector[1] /= length;
    	vector[2] /= length;
    	}
    
    
    // Points p1, p2, & p3 specified in counter clock-wise order
    void calcNormal(struct group *facet, float out[3])
    	{
    	float v1[3],v2[3];
    	static const int x = 0;
    	static const int y = 1;
    	static const int z = 2;
    
    	// Calculate two vectors from the three points
    	v1[x] = (*facet).vertex1[x] -(*facet).vertex2[x];
    	v1[y] = (*facet).vertex1[y] - (*facet).vertex2[y];
    	v1[z] = (*facet).vertex1[z] - (*facet).vertex2[z];
    
    	v2[x] = (*facet).vertex2[x] - (*facet).vertex3[x];
    	v2[y] = (*facet).vertex2[y] - (*facet).vertex3[y];
    	v2[z] = (*facet).vertex2[z] - (*facet).vertex3[z];
    
    	// Take the cross product of the two vectors to get
    	// the normal vector which will be stored in out
    	out[x] = v1[y]*v2[z] - v1[z]*v2[y];
    	out[y] = v1[z]*v2[x] - v1[x]*v2[z];
    	out[z] = v1[x]*v2[y] - v1[y]*v2[x];
    
    	// Normalize the vector (shorten length to one)
    	ReduceToUnit(out);
    	}
    
    
    // Called to draw scene
    void RenderScene(void)
    	{
    
    float normal[3];
    
    
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    
    glMatrixMode(GL_MODELVIEW);
    	glLoadIdentity();
    
    
    	//glTranslatef(0.0f,0.0f,-500.0f);
    
    	glMatrixMode(GL_MODELVIEW);
    	glLoadIdentity();
    
    	glTranslatef(-2.5,0.0,0.0);
    
    	glPushMatrix();
    
    	glRotatef(xRot,1,0,0);
    	glRotatef(yRot,0,1,0);
    
    	glColor3ub(128, 128, 128);
    
    	glBegin(GL_TRIANGLES);
    
    	{
    
    
    for(j=0;j<num;j++)
    	{
    	
    	
    facet[j].vertex1;
    facet[j].vertex2;
    facet[j].vertex3;
    
    	//float v[3][3]={ facet[j].vertexs[3][3]};
    			calcNormal(&facet[j],normal);
    		glNormal3fv(normal);
    		glVertex3fv(facet[j].vertex1);
    		glVertex3fv(facet[j].vertex2);
    		glVertex3fv(facet[j].vertex3);
    		}
    
    	}glEnd();
    
    	/*{
    		//for(n=0;n<8;n++)
    
    	{
    			float v[3][3]={{0.000000,0.000000,-200.000000},
    		{400.000000,0.000000,0.000000},
    		{0.000000,0.000000,0.000000}};
    
    			calcNormal(v,normal);
    		glNormal3fv(normal);
    		glVertex3fv(v[0]);
    		glVertex3fv(v[1]);
    		glVertex3fv(v[2]);
    		}
    	//}glEnd();
    
    		{
    			float v[3][3]={{0.000000,0.000000,-200.000000},
    		{400.000000,0.000000,0.000000},
    		{0.000000,0.000000,0.000000}};
    
    			calcNormal(v,normal);
    		glNormal3fv(normal);
    		glVertex3fv(v[0]);
    		glVertex3fv(v[1]);
    		glVertex3fv(v[2]);
    		}
    
    
    		{
    			float v[3][3]={{0.000000,50.000000,0.000000},
    		{0.000000,0.000000,0.000000},
    		{400.000000,0.000000,0.000000}};
    			calcNormal(v,normal);
    		glNormal3fv(normal);
    		glVertex3fv(v[0]);
    		glVertex3fv(v[1]);
    		glVertex3fv(v[2]);
    		}
    
    		{
    			float v[3][3]={{0.000000,50.000000,-200.000000},
    		{0.000000,0.000000,-200.000000},
    		{0.000000,0.000000,0.000000}};
    
    				calcNormal(v,normal);
    		glNormal3fv(normal);
    		glVertex3fv(v[0]);
    		glVertex3fv(v[1]);
    		glVertex3fv(v[2]);
    		}
    
    
    	{
    			float v[3][3]={{0.000000,50.000000,-200.000000},
    		{0.000000,0.000000,0.000000},
    		{0.000000,50.000000,0.000000}};
    
    			calcNormal(v,normal);
    		glNormal3fv(normal);
    		glVertex3fv(v[0]);
    		glVertex3fv(v[1]);
    		glVertex3fv(v[2]);
    		}
    
    {
    			float v[3][3]={{400.000000,50.000000,0.000000},
    		{400.000000,0.000000,0.000000},
    		{0.000000,0.000000,-200.000000}};
    
    			calcNormal(v,normal);
    		glNormal3fv(normal);
    		glVertex3fv(v[0]);
    		glVertex3fv(v[1]);
    		glVertex3fv(v[2]);
    		}
    
     
    
    {
    			float v[3][3]={{400.000000,50.000000,0.000000},
    		{0.000000,50.000000,0.000000},
    		{400.000000,0.000000,0.000000}};
    
    			calcNormal(v,normal);
    		glNormal3fv(normal);
    		glVertex3fv(v[0]);
    		glVertex3fv(v[1]);
    		glVertex3fv(v[2]);
    		}
    
     
     {
    			float v[3][3]={{400.000000,50.000000,0.000000},
    		{0.000000,0.000000,-200.000000},
    		{0.000000,50.000000,-200.000000}};
    
    				calcNormal(v,normal);
    		glNormal3fv(normal);
    		glVertex3fv(v[0]);
    		glVertex3fv(v[1]);
    		glVertex3fv(v[2]);
    		}
    
     
     {
    			float v[3][3]={{400.000000,50.000000,0.000000},
    		{0.000000,50.000000,-200.000000},
    		{0.000000,50.000000,0.000000}};
    
    			calcNormal(v,normal);
    		glNormal3fv(normal);
    		glVertex3fv(v[0]);
    		glVertex3fv(v[1]);
    		glVertex3fv(v[2]);
    		}
    
    	}
    
    	glEnd();*/
    
    	glPopMatrix();
     
     glutSwapBuffers();
    	}
    
    // This function does any needed initialization on the rendering
    // context. 
    void SetupRC()
    	{
    
    	GLfloat ambient[]={ 0.6f,0.6f,0.7f,1.0f};
    	GLfloat diffuse[]={0.7f,0.7f,0.7f,1.0f};
    	GLfloat spec[]={1.0f,1.0f,1.0f,1.0f};
    	GLfloat specma[]={1.0f,1.0f,1.0f,1.0f};
    
    
    	// Light values and coordinates
    		glShadeModel(GL_SMOOTH);
    	glEnable(GL_DEPTH_TEST);	// Hidden surface removal
    	glFrontFace(GL_CCW);		// Counter clock-wise polygons face out
    glEnable(GL_CULL_FACE);		// Do not calculate inside of jet
    
    	// Enable lighting
    
    glEnable(GL_LIGHTING);
    
    	// Setup and enable light 0
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambient);
    glLightfv(GL_LIGHT0,GL_AMBIENT,ambient);
    glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuse);
    glLightfv(GL_LIGHT0,GL_SPECULAR,spec);
    
    	// Enable color tracking
    	
    	glEnable(GL_LIGHT0);
    	// Set Material properties to follow glColor values
    glEnable(GL_COLOR_MATERIAL);
    glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);
    glMaterialfv(GL_FRONT,GL_SPECULAR,specma);
    glMateriali(GL_FRONT,GL_SHININESS,128);
    
    
    	// Light blue background
    	glClearColor(0.0f, 0.0f, 0.0f, 1.0f );
    	}
    
    void SpecialKeys(int key, int x, int y)
    	{
    	if(key == GLUT_KEY_UP)
    		xRot-= 5.0f;
    
    	if(key == GLUT_KEY_DOWN)
    		xRot += 5.0f;
    
    	if(key == GLUT_KEY_LEFT)
    		yRot -= 5.0f;
    
    	if(key == GLUT_KEY_RIGHT)
    		yRot += 5.0f;
    
    	//if(key > 356.0f)
    	//	xRot = 0.0f;
    
    	//if(key < -1.0f)
    	//	xRot = 355.0f;
    
    //	if(key > 356.0f)
    //		yRot = 0.0f;
    
    //	if(key < -1.0f)
    //		yRot = 355.0f;
    
    	// Refresh the Window
    	glutPostRedisplay();
    	}
    
    
    void ChangeSize(int w, int h)
    	{
    	//
    	GLfloat nRange = 3.0f;
    
    /*
    
    GLfloat aspect;
    aspect = (GLfloat)w/(GLfloat)h;
    
    glViewport(0,0,w,h);
    
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    
    
    gluPerspective(1000.0f,aspect,1.0,1000.0);
    
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    */
    
    
    
    	// Prevent a divide by zero
    	if(h == 0)
    		h = 1;                                     
    
    	// Set Viewport to window dimensions
        glViewport(0, 0, w, h);
    
    	// Reset coordinate system
    	glMatrixMode(GL_PROJECTION);
    	glLoadIdentity();
    
    	// Establish clipping volume (left, right, bottom, top, near, far)
        if (w <= h) 
    		glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w, 2.0*(-nRange), 2.0*(nRange));
        else 
    		glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, 2.0*(-nRange), 2.0*(nRange));
    
    	glMatrixMode(GL_MODELVIEW);
    	glLoadIdentity();
    
    	glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
    
    	}
    
    int main(int argc, char* argv[])
    	{
    
    
    /////////////////////////stl loader..............
    
    FILE *binary;
    FILE *out;
    
    if( (binary =fopen("C:\\program files\\proe2000i\\bin\\carb_restruct.stl","rb"))==NULL )////stl file location
    
    {
    	printf(" \n the is failed to accessed");
    	exit(1);
    }
    
    out = fopen("C:\\my documents\\stlexperi3.txt","w");
    
    
    
    fread(filename,sizeof(char),80,binary) ;
    fread(numfacet,sizeof(int),1,binary);
    
    for(i=0;i<80;i++)
    fprintf(out,"%c",filename[i]);
    
    for (i=0;i<1;i++)
    fprintf(out,"\n%d\n\n",numfacet[i]);
    num=numfacet[0];
    
    
     
    for (j=0;j<num;j++)
    {
    
    fread(facet[j].normal,sizeof(float),3,binary);
    fread(facet[j].vertex1,sizeof(float),3,binary);
    fread(facet[j].vertex2,sizeof(float),3,binary);
    fread(facet[j].vertex3,sizeof(float),3,binary);
    fread(facet[j].unuse,sizeof(char),2,binary);
    }
    
    //////////////////////stl loader
    
    	glutInit(&argc, argv);
    	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    	glutInitWindowSize(500,500);
    	glutCreateWindow("Lighted Jet");
    	glutReshapeFunc(ChangeSize);
    	glutSpecialFunc(SpecialKeys);
    	glutDisplayFunc(RenderScene);
    	SetupRC();
    	glutMainLoop();
    
    	return 0;
    	}
    Last edited by 2kaud; June 13th, 2017 at 09:08 AM. Reason: Added code tags

  5. #5
    Join Date
    Aug 2001
    Posts
    18

    Re: loading a stl 3d model file

    maybe this can help.........


    Stereolithography File Formats

    Binary Format (.stl)

    Binary (.stl) files are organized as an 84 byte header followed by = 50-byte records each of which describes one triangle facet:=20.

    # of | bytes | description
    -------------------------------------------------------------------
    80 | Any text such as the creator's name
    4 | int equal to the number of facets in file
    ----here is where the facets start (triangle 1)-----------------
    4 | float normal x
    4 | float normal y
    4 | float normal z
    4 | float vertex1 x
    4 | float vertex1 y
    4 | float vertex1 z
    4 | float vertex2 x
    4 | float vertex2 y
    4 | float vertex2 z
    4 | float vertex3 x
    4 | float vertex3 y
    4 | float vertex3 z
    2 | unused (padding to make 50-bytes)
    --------------------------------facet 2-------------------------
    4 | float normal x
    4 | float normal y
    4 | float normal z
    4 | float vertex1 x
    4 | float vertex1 y
    4 | float vertex1 z
    4 | float vertex2 x
    4 | float vertex2 y
    4 | float vertex2 z
    4 | float vertex3 x
    4 | float vertex3 y
    4 | float vertex3 z
    2 | unused (padding to make 50-bytes)
    --------------------------------facet 3-------------------------
    etc. ...

    A facet entry begins with the x,y,z components of the triangle's face normal vector. The normal vector points in a direction away from the surface and it should be
    normalized to unit length. The x,y,z = coordinates of the triangle's three vertices come next. They are stored in CCW = order when viewing the facet from outside the
    surface. The direction of the normal vector follows the "right-hand-rule" when traversing the triangle vertices from 1 to 3, i.e., with the fingers of your right hand curled
    in the direction of vertex 1 to 2 to 3, your thumb points in the = direction of the surface normal.

    Notice that each facet entry is 50 bytes. So adding the 84 bytes in the header space, a binary file should have a size in bytes =3D 84 + (number of facets) * 50.

    Notice the 2 extra bytes thrown in at the end of each entry to make it a nice even 50. 50 is a nice number for people, but not for most 32-bit computers because they
    store values on 4-byte boundaries. Therefore, when writing programs to read and write .stl files the programmer has to take care to design data structures that
    accomodate this problem.

    The Velocity2 software writes a binary .stl file having the general organization described above. The first 84 bytes of the file form the = header, a C-language
    structure having the definition:

    Code:
    typedef struct _STLHeader{
            char id[22];
            char date[26];
            float xmin, xmax;        // The x, y and z bounds on the data.
            float ymin, ymax;
            float zmin, zmax;
            float xpixelsize;        // Dimensions of grid for this model
            float ypixelsize;        // in user units.
            unsigned int nfacets;
    } STLHeader ;
    * 'id' is a null-terminated string of the form "filename.stl", where = filename is the name of the converted ".bin" file.
    * 'date' is the date stamp in UNIX ctime() format.
    * 'xmin' - 'zmax' are the geometric bounds on the data (floats are = in MIPS big-endian byte order, i.e. NOT byte-swapped).
    * 'xpixelsize' and 'ypixelsize' are the original image pixel = dimensions (floats are in MIPS native byte order).
    * 'nfacets' equals the number of facets to follow (number of 50-byte = records).
    This value is byte-swapped (see below).

    By convention, 4-byte integers and 4-byte float values in a binary .stl = file are in little-endian byte order. When read or written by machines that have = big-endian
    byte organization, such as MIPS Computer and Intel machines, such values must be byte swapped.

    Each triangle facet is read/written as a 48-byte C structure plus = 2-bytes of "padding". The structures that define a facet are:

    Code:
    typedef struct _Vertex{
            float x;
            float y;
            float z;
    } Vertex;
    
    typedef struct _Facet {
            Vertex normal;  // facet surface normal
            Vertex v1;      // vertex 1
            Vertex v2;      // vertex 2
            Vertex v3;      // vertex 3
    } Facet;
    The routine "lswap" byte swaps a 4-byte value. :

    Code:
    void lswap(unsigned int *v) // Byte swaps a 4-byte val
    {
            unsigned int r;
    
            r =3D *v;
            *v =3D ((r & 0xff) << 24) | ((r & 0xff00) << 8) | ((r & 0xff0000) >> 8)
            | ((r & 0xff000000) >> 24);
    }
    The following code fragments illustrate writing a binary .stl file:
    Code:
    ...
    int i, n;
    // "padding" is used to flesh out the facet's file record to=20
    // 50 bytes
    short padding =3D 0;
    Facet facet;
    STLHeader header;
    FILE *fp;
    ...
    
    // Open a file for write
    fp =3D fopen (...
    // Fill in the header values
    header.id =3D ...
    ...
    
    header.nfacets =3D number_of_facets;
    // Byte swap the number
    lswap(&header.nfacets);
    // Write the header
    n =3D fwrite((void *)&header, 1, sizeof(STLHeader), fp);
    if (n !=3D ... // Check for errors
    ...
    
    // Next, write all of the facet data
    for (i=3D0; i<number_of_facets; i++) {
    // Fill 'facet' with triangle data
    facet.normal.x =3D ...
    lswap((unsigned int *)&facet.normal.x);
    ...
    
    facet.v1.x =3D ...
    lswap((unsigned int *)&facet.v1.x);
    ...
    
    // Write the 48-byte facet structure
    n =3D fwrite((void *)&facet, 1, sizeof(Facet), fp);
    if (n !=3D ... // Check for errors
    =09
    // This next is to make each record 50 bytes in size
    // according to STL specification.
    n =3D fwrite((void *)&padding, 1, sizeof(short), fp);
    if (n !=3D ... // Check for errors
    }
    ...
    To read an .stl file into a 'big-endian' machine, one would use an = 'inverse' of the write operation, first reading the header, fishing out the number = of facets from the
    header (byte swapping the value), and then reading Facet structures plus their 2-byte padding to make up 50-byte records.

    ASCII Text Format (.sla) Files

    Text format stereolithography data files are much easier to read and = write. The only problem with them is that they are about six times the size of = a binary, .stl,
    file. They have the general format:

    -------------------------------------------------------------------
    solid name_of_object
    facet normal x y z
    outer loop
    vertex x y z
    vertex x y z
    vertex x y z
    endloop
    endfacet
    facet normal x y z
    outer loop
    vertex x y z
    vertex x y z
    vertex x y z
    endloop
    endfacet
    ...
    endsolid name_of_object
    -------------------------------------------------------------------

    Normal vector components and vertex coordinate data are written in = scientific notation (+-d.ddddddE+-ee).

    Here is an abbreviated listing of an actual .sla file:

    solid bottletop.bin
    facet normal -4.470293E-02 7.003503E-01 -7.123981E-01
    outer loop
    vertex -2.812284E+00 2.298693E+01 0.000000E+00
    vertex -2.812284E+00 2.296699E+01 -1.960784E-02
    vertex -3.124760E+00 2.296699E+01 0.000000E+00
    endloop
    endfacet
    facet normal -7.853186E-02 6.811538E-01 -7.279164E-01
    outer loop
    vertex -2.343570E+00 2.296699E+01 -7.017544E-02
    vertex -2.812284E+00 2.296699E+01 -1.960784E-02
    vertex -2.343570E+00 2.304198E+01 0.000000E+00
    endloop
    endfacet
    ...
    ...
    facet normal 1.138192E-01 -7.113919E-01 6.935177E-01
    outer loop
    vertex 1.874856E+00 -2.674482E+01 2.450000E+01
    vertex 2.050624E+00 -2.671670E+01 2.450000E+01
    vertex 1.874856E+00 -2.671670E+01 2.452885E+01
    endloop
    endfacet
    endsolid bottletop.bin
    Last edited by 2kaud; June 13th, 2017 at 09:10 AM. Reason: Added code tags

  6. #6
    Join Date
    Oct 2001
    Location
    lake of fire and brimstone
    Posts
    1,628

    Re: loading a stl 3d model file

    My way of loading from a 3D studio ascii file is rather simple, but the visualisation of an object is really complex, adding all that code would be impossible. However I add here below the code to readin 3D objects only. Unfortunately, some of the variables are not clear, like for instance single[], which is a complex class. However I hope you can modify this code and that it is of use to you.

    Code:
    void ObjectGroup_3DS::Load_3DS_Object( char *filename, int N, 
    									   Boolean turn_normals, Real scale )
    {
       FILE *Binary; // file pointer
       long i;
       char *Thefile = NULL;
       long size_of_file;
    
       // open file ( binary mode | read | write ) 
       Binary = fopen( filename , "r+b" );
       if ( !Binary )
           SafeExit( StrCat( "Cannot load file ", filename ) );
       
       fseek( Binary, 0L, SEEK_END );
       size_of_file = ftell( Binary );
    
       ALLOC_ARRAY(	char, Thefile , size_of_file , " Thefile " );
       fseek( Binary, 0L, SEEK_SET );
    
       //Write( "File_size: ", size_of_file );
       fread( Thefile, 1, size_of_file, Binary );
      	  for ( i = 0; i < size_of_file; i++ ) 
    	   {
    		   if ( Thefile[i] == ',' ) Thefile[i] = '.' ;
    	   }
       fseek( Binary, 0L, SEEK_SET );
       fwrite( Thefile, 1, size_of_file, Binary );
       FREE_ARRAY(	char, Thefile , size_of_file , " Thefile " );
    
       fclose( Binary );
       
       char buff[255];
       FILE *stream; // ASCII file pointer
      
       long no_vertices,no_faces;
       long face;
       GLfloat X,Y,Z,U,V;
       
       stream = fopen( filename , "r" );
       if ( !stream )
           SafeExit( StrCat( "Cannot load file ", filename ) );
       number_of_objects = N;
       single = NULL;
       ALLOC_ARRAY( Object3DS, single , N , "Objects" ); 
    
       //fgets( buff , 255 , stream ); 
    
       for ( i = 0; i < N; i++ )
       {
    	   single[i].Mapped = 0; // Set mapping to false (default)
    	   //fgets( buff, 255, stream );
    	   
    	   //fgets(buff,255,stream);// Named    
    	   Scan( stream, buff ,"Nam" ); 
    	   
    	   fscanf(stream,"%s",buff);
    	   Scan( stream, buff ,"Tri" );// Tri mesh
    	   fscanf(stream,"%s",buff);
    	   fscanf(stream,"%d",&no_vertices); // Vertices
    	   fscanf(stream,"%s",buff);
    	   fscanf(stream,"%d",&no_faces); // Faces
    	   //Write( "Number of Vertices: ", no_vertices );
    	   //fgets(buff,255,stream);
    		
    	   while ( StrCmp( buff, "Ver", 3 ) )// Vertex list 	
    	   {
    	      fscanf(stream,"%s",buff);	// check if object is mapped
    	 	  if ( !StrCmp( buff, "Map", 3 ) ) single[i].Mapped = 1;
    	   }
       
    	   single[i].number_of_vertices = no_vertices;
    	   single[i].number_of_faces = no_faces;
    
    	   single[i].face_pool = NULL;
    	   single[i].coord_pool = NULL;
    	   single[i].uv_pool = NULL;
    	   
    	   ALLOC_ARRAY( GLint, single[i].face_pool , 3 * single[i].number_of_faces, "Faces" ); 
    	   ALLOC_ARRAY( GLfloat, single[i].coord_pool , 3 * single[i].number_of_vertices, "Vertex" );
    	   if ( single[i].Mapped ) 
           {
    			ALLOC_ARRAY( GLfloat, single[i].uv_pool , 2 * single[i].number_of_vertices, "UVcoords" );
           }
    	  
    	   register int j = 0; 
      
    	   register GLfloat *tv = single[i].coord_pool, *hi_tv = tv + 3 * no_vertices;
    	   register GLfloat *tuv = single[i].uv_pool;
    	   long long_dummy;
     	
    	   // get x and y coordinates
           float s0 = (float) scale;
    	   while ( tv < hi_tv )
    	   {
    		   fscanf(stream,"%s",buff);
    		   Scan( stream, buff ,"Ver" );
    		   if ( single[i].Mapped ) 
    		   {
    				fscanf(stream,"%d%s%2s%f%2s%f%2s%f%2s%f%2s%f", 
    					   &long_dummy,buff, buff, 
    					   &X, buff, &Y, buff, &Z, buff, &U, buff, &V);
    				*tuv++ = U;
    				*tuv++ = V;
    		   }
    		   else fscanf(stream,"%d%s%2s%f%2s%f%2s%f%", &long_dummy,buff, buff, 
    					   &X, buff, &Y, buff, &Z );
    
    		   *tv++ = s0 * X;
    		   *tv++ = s0 * Y;
    		   *tv++ = s0 * Z;
    	   }
    	   tv = single[i].coord_pool;
     
    		fscanf(stream,"%s",buff);
    		Scan( stream, buff ,"Face" );
    	   /* faces */
    	   
    		j = 0;
    	   register GLint *tf = single[i].face_pool;
    	   // read faces
    	   for ( face=0; face < no_faces ; face++, tf += 3 )
    	   {
                fscanf(stream,"%s",buff);
                Scan( stream, buff ,"Face" );
    			if ( turn_normals )
                   fscanf(stream,"%d:    A:%d B:%d C:%d %s",
    			         &long_dummy,&tf[1],&tf[2],&tf[0],buff);
    			else
                   fscanf(stream,"%d:    A:%d B:%d C:%d %s",
    			         &long_dummy,&tf[2],&tf[1],&tf[0],buff);
           }
       }
       fclose(stream);
    }
    Last edited by 2kaud; June 13th, 2017 at 09:11 AM. Reason: Added code tags
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞

  7. #7
    Join Date
    Aug 2001
    Posts
    18

    Re: loading a stl 3d model file

    Thanks for your code .....

    do you know how to apply smooth shading or phong shading on the loaded stl model in opengl to increase the model realism ???

    do you know any available help or resources ???

    for now i only manage to apply facet shading on my model .......



  8. #8
    Join Date
    Oct 2001
    Location
    lake of fire and brimstone
    Posts
    1,628

    Re: loading a stl 3d model file

    You could check out http://www.codeguru.com/opengl/normals.shtml which has a demo program attached. Also a good site is http://norecess.planet-d.net/download.htm, which allows you to download the source code of some graphic programs. http://www.cs.rochester.edu/u/choman...GL/OpenGL.html is a good tutorial on the basics, smooth shading is also mentioned. I hope these sites provide you with sufficient information.

    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞
    ۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞۞

  9. #9
    Join Date
    Jun 2017
    Posts
    1

    Re: loading a stl 3d model file

    hey I am doing same work in c# visual studio. I am done with reading work for both asckii and binary. but not able to display an object using opengl.. I dont have any idea about opengl please guide me.

  10. #10
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    5,641

    Re: loading a stl 3d model file

    As this is a c++ forum, I suggest you start a new thread in the c# forum outlining what you are trying to do and the issues.
    All advice is offered in good faith only. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/

    C, C++ Compiler: Microsoft VS2017.2

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This a Codeguru.com survey!


On-Demand Webinars (sponsored)