Exemplo n.º 1
0
OFX_OBJLOADER_BEGIN_NAMESPACE

void load(string path, ofMesh& mesh, bool generateNormals, bool flipFace)
{
	path = ofToDataPath(path);

	mesh.clear();

	GLMmodel* m;

	m = glmReadOBJ((char*)path.c_str());

	if (generateNormals)
	{
		glmFacetNormals(m);
		glmVertexNormals(m, 90);
	}

	if (flipFace)
	{
		glmReverseWinding(m);
	}

	for (int j = 0; j < m->numtriangles; j++)
	{
		const GLMtriangle &tri = m->triangles[j];

		for (int k = 0; k < 3; k++)
		{
			GLfloat *v = m->vertices + (tri.vindices[k] * 3);
			mesh.addVertex(ofVec3f(v[0], v[1], v[2]));

			if (m->colors)
			{
				GLfloat *c = m->colors + (tri.vindices[k] * 3);
				mesh.addColor(ofFloatColor(c[0], c[1], c[2]));
			}

			if (m->normals && ofInRange(tri.nindices[k], 0, m->numnormals))
			{
				GLfloat *n = m->normals + (tri.nindices[k] * 3);
				mesh.addNormal(ofVec3f(n[0], n[1], n[2]));
			}

			if (m->texcoords && ofInRange(tri.tindices[k], 0, m->numtexcoords))
			{
				GLfloat *c = m->texcoords + (tri.tindices[k] * 2);
				mesh.addTexCoord(ofVec2f(c[0], c[1]));
			}
		}
	}

	glmDelete(m);
}
Exemplo n.º 2
0
void loadGroup(string path, map<string, ofMesh>& groups, bool generateNormals)
{
	path = ofToDataPath(path);

	groups.clear();

	GLMmodel* m;

	m = glmReadOBJ((char*)path.c_str());

	if (generateNormals)
	{
		glmFacetNormals(m);
	}

	glmReverseWinding(m);

	GLMgroup *g = m->groups;

	while (g)
	{
		string name = g->name;

		ofMesh t;
		GLMtriangle *p = m->triangles;

		for (int j = 0; j < g->numtriangles; j++)
		{
			GLMtriangle tri = p[g->triangles[j]];

			for (int k = 0; k < 3; k++)
			{
				GLfloat *v = m->vertices + (tri.vindices[k] * 3);
				t.addVertex(ofVec3f(v[0], v[1], v[2]));

				if (m->colors)
				{
					GLfloat *c = m->colors + (tri.vindices[k] * 3);
					t.addColor(ofFloatColor(c[0], c[1], c[2]));
				}

				if (m->normals && ofInRange(tri.nindices[k], 0, m->numnormals))
				{
					GLfloat *n = m->normals + (tri.nindices[k] * 3);
					t.addNormal(ofVec3f(n[0], n[1], n[2]));
				}

				if (m->texcoords && ofInRange(tri.tindices[k], 0, m->numtexcoords))
				{
					GLfloat *c = m->texcoords + (tri.tindices[k] * 2);
					t.addTexCoord(ofVec2f(c[0], c[1]));
				}
			}
		}

		groups[name] = t;
		g = g->next;
	}

	glmDelete(m);
}
Exemplo n.º 3
0
void saveGroup(string path, const vector<ofMesh> & meshGroup, bool flipFace, bool flipNormals) {
	path = ofToDataPath(path);
	
	ofFilePath::createEnclosingDirectory(path);
    
	GLuint writeMode = GLM_NONE;
	GLMmodel * m = new GLMmodel();
    GLMgroup * group = NULL;

    int numOfVerticesTotal = 0;
    int numOfNormalsTotal = 0;
    int numOfTexCoordsTotal = 0;
    int numOfIndicesTotal = 0;
    int numOfTrianglesTotal = 0;
    
    for(int i=0; i<meshGroup.size(); i++) {
        const ofMesh & mesh = meshGroup[i];
        
        numOfVerticesTotal += mesh.getNumVertices();
        numOfNormalsTotal += mesh.getNumNormals();
        numOfTexCoordsTotal += mesh.getNumTexCoords();

        if(mesh.getNumIndices() > 0) {
            numOfIndicesTotal += mesh.getNumIndices();
        } else {
            numOfIndicesTotal += mesh.getNumVertices();
        }
    }
    
    // glm skips the first array element when exporting.
    // not sure why?
    // but it means everything needs to be padded by 1.
    
    numOfVerticesTotal += 1;
    numOfNormalsTotal += 1;
    numOfTexCoordsTotal += 1;
    
    if(numOfVerticesTotal > 0) {
        m->numvertices = numOfVerticesTotal;
        m->vertices = new GLfloat[m->numvertices * 3];
    }
    
    if(numOfNormalsTotal > 0) {
        m->numnormals = numOfNormalsTotal;
        m->normals = new GLfloat[m->numnormals * 3];
    }
    
    if(numOfTexCoordsTotal > 0) {
        m->numtexcoords = numOfTexCoordsTotal;
        m->texcoords = new GLfloat[m->numtexcoords * 2];
    }
    
    if(numOfIndicesTotal > 0) {
        numOfTrianglesTotal = numOfIndicesTotal / 3;
        m->numtriangles = numOfTrianglesTotal;
        m->triangles = new GLMtriangle[m->numtriangles];
    }
    
    int numOfVertices = 0;
    int numOfNormals = 0;
    int numOfTexCoords = 0;
    int numOfIndices = 0;
    int numOfTriangles = 0;
    
    int indexVertices = 1;
    int indexNormals = 1;
    int indexTexCoords = 1;
    int indexIndices = 0;
    int indexTriangles = 0;
    
    for(int k=0; k<meshGroup.size(); k++) {
        const ofMesh & mesh = meshGroup[k];
        
        if(numOfVerticesTotal > 0) {
            numOfVertices = mesh.getNumVertices();
            memcpy(&m->vertices[indexVertices * 3], &mesh.getVertices()[0].x, sizeof(ofVec3f) * numOfVertices);
            indexVertices += numOfVertices;
        } else {
            ofLogError("ofxObjLoader::save -- No vertices to save!");
            return;
        }
        
        if(numOfNormalsTotal > 0) {
            numOfNormals = mesh.getNumNormals();
            vector<ofVec3f> normals = mesh.getNormals();
            
            if(flipNormals) {
                for(int i = 0; i < normals.size(); i++) {
                    normals[i] *= -1;
                }
            }
            
            memcpy(&m->normals[indexNormals * 3], &normals[0].x, sizeof(ofVec3f) * numOfNormals);
            indexNormals += numOfNormals;
            
            writeMode |= GLM_SMOOTH;
        }
        
        if(numOfTexCoordsTotal > 0) {
            numOfTexCoords = mesh.getNumTexCoords();
            memcpy(&m->texcoords[indexTexCoords * 2], &mesh.getTexCoords()[0].x, sizeof(ofVec2f) * numOfTexCoords);
            indexTexCoords += numOfTexCoords;

            writeMode |= GLM_TEXTURE;
        }
        
        numOfIndices = mesh.getNumIndices();
        if(numOfIndices > 0) {
            numOfTriangles = numOfIndices / 3;
        } else {
            numOfTriangles = numOfVertices / 3;
        }
        
        GLMgroup * groupPrev = group;
        group = new GLMgroup();
        group->next = NULL;
        group->material = NULL;
        
        if(m->groups == NULL) {
            m->groups = group;
            m->numgroups = 1;
        }
        if(groupPrev != NULL) {
            groupPrev->next = group;
            m->numgroups += 1;
        }
        
        string name = "ofMesh_" + ofToString(k);
        group->name = (char*)malloc(sizeof(char) * name.length() + 1);
        strcpy(group->name, name.c_str());
        
        group->numtriangles = numOfTriangles;
        group->triangles = new GLuint[group->numtriangles];
        
        const vector<ofIndexType> & indices = mesh.getIndices();
        int index = 0;
        
        for(int i=0; i<numOfTriangles; i++) {
            
            int t = i + indexTriangles;
            
            for(int j=0; j<3; j++) {
                
                int idx = i * 3 + j;
            
                if(numOfIndices > 0) {
                    index = indices[idx];
                } else {
                    index = idx;
                }
                
                index += (indexIndices + 1);
                
                m->triangles[t].vindices[j] = index;
                m->triangles[t].nindices[j] = index;
                m->triangles[t].tindices[j] = index;
            }
            
            group->triangles[i] = t;
        }
        
        indexIndices += numOfVertices;
        indexTriangles += numOfTriangles;
    }
	
	if(flipFace == true) {
		glmReverseWinding(m);
    }
    
	glmWriteOBJ(m, (char*)path.c_str(), writeMode);
	glmDelete(m);
}
Exemplo n.º 4
0
void save(string path, const ofMesh& mesh_, bool flipFace, bool flipNormals, bool export_vertexcolor_to_texture)
{
	ofMesh mesh = mesh_;
	
	path = ofToDataPath(path);
	
	ofFilePath::createEnclosingDirectory(path);

	GLuint writeMode = GLM_NONE;
	GLMmodel* m = new GLMmodel();
	
	if (export_vertexcolor_to_texture)
	{
		if (mesh.getMode() != OF_PRIMITIVE_TRIANGLES)
		{
			ofLogError("ofxObjLoader::save") << "vertex color to texture supported only triangle primitive";
		}
		else
		{
			ofImage image;
			
			vertexColorToFaceColor(mesh);
			faceColorToTexture(mesh, image);
			
			ofFile file(path);
			string base_path = file.getEnclosingDirectory();
			string material_name = file.getBaseName();
			
			string image_name = material_name + ".png";
			ofPixels pix = image.getPixelsRef();
			
			// flip save texture
			pix.mirror(true, false);
			ofSaveImage(pix, ofFilePath::join(base_path, image_name));
			
			string mtl_filename = material_name + ".mtl";
			
			writeMode |= GLM_MATERIAL;
			m->mtllibname = (char*)malloc(mtl_filename.size());
			strcpy(m->mtllibname, mtl_filename.c_str());
			
			m->nummaterials = 1;
			m->materials = (GLMmaterial*)malloc(sizeof(GLMmaterial));
			GLMmaterial *mat = &m->materials[0];
			memset(mat, 0, sizeof(GLMmaterial));
			
			for (int i = 0; i < 4; i++)
			{
				mat->diffuse[i] = 1;
				mat->ambient[i] = 1;
				mat->specular[i] = 1;
				mat->emmissive[i] = 1;
			}
			mat->shininess = 1;
			
			mat->name = (char*)malloc(material_name.size());
			strcpy(mat->name, material_name.c_str());
			
			mat->texture_path = (char*)malloc(image_name.size());
			strcpy(mat->texture_path, image_name.c_str());
		}
	}

	if (mesh.getNumVertices() > 0)
	{
		m->numvertices = mesh.getNumVertices();
		m->vertices = new GLfloat[(m->numvertices + 1) * 3];
		memcpy(&m->vertices[3], &mesh.getVertices()[0].x, sizeof(ofVec3f) * mesh.getNumVertices());
	}
	else
	{
		ofLogError("ofxObjLoader::save -- No vertices to save!");
		return;
	}

	if (mesh.getNumNormals() > 0)
	{
		m->numnormals = mesh.getNumNormals();
		m->normals = new GLfloat[(m->numnormals + 1) * 3];
		vector<ofVec3f> normals = mesh.getNormals();
		
		if (flipNormals)
			for (int i = 0; i < normals.size(); i++)
				normals[i] *= -1;
		
		memcpy(&m->normals[3], &normals[0].x, sizeof(ofVec3f) * normals.size());
		writeMode |= GLM_SMOOTH;
	}

	if (mesh.getNumTexCoords() > 0)
	{
		m->numtexcoords = mesh.getNumTexCoords();
		m->texcoords = new GLfloat[(m->numtexcoords + 1) * 2];
		memcpy(&m->texcoords[2], &mesh.getTexCoords()[0].x, sizeof(ofVec2f) * mesh.getNumTexCoords());
		writeMode |= GLM_TEXTURE;
	}

	if (mesh.getNumIndices() > 0)
	{
		m->numtriangles = mesh.getNumIndices() / 3;
		m->triangles = new GLMtriangle[m->numtriangles];

		m->groups = new GLMgroup();
		m->groups->next = NULL;
		m->groups->material = NULL;
		
		string name = "ofMesh";
		m->groups->name = (char*)malloc(sizeof(char) * name.length() + 1);
		strcpy(m->groups->name, name.c_str());

		m->groups->numtriangles = mesh.getNumIndices() / 3;
		m->groups->triangles = new GLuint[m->groups->numtriangles];
		m->numgroups = 1;

		for (int i = 0; i < mesh.getNumIndices(); i += 3)
		{
			int idx = i / 3;
			for (int j = 0; j < 3; j++)
			{
				m->triangles[idx].vindices[j] = mesh.getIndices()[i + j] + 1;
				m->triangles[idx].nindices[j] = mesh.getIndices()[i + j] + 1;
				m->triangles[idx].tindices[j] = mesh.getIndices()[i + j] + 1;
			}
			m->groups->triangles[idx] = idx;
		}
	}
	else
	{
		m->numtriangles = mesh.getNumVertices() / 3;
		m->triangles = new GLMtriangle[m->numtriangles];

		m->groups = new GLMgroup();
		m->groups->next = NULL;
		m->groups->material = NULL;
		
		string name = "ofMesh";
		m->groups->name = (char*)malloc(sizeof(char) * name.length() + 1);
		strcpy(m->groups->name, name.c_str());

		m->groups->numtriangles = mesh.getNumVertices() / 3;
		m->groups->triangles = new GLuint[m->groups->numtriangles];
		m->numgroups = 1;

		for (int i = 0; i < mesh.getNumVertices(); i += 3)
		{
			int idx = i / 3;
			for (int j = 0; j < 3; j++)
			{
				m->triangles[idx].vindices[j] = i + j + 1;
				m->triangles[idx].nindices[j] = i + j + 1;
				m->triangles[idx].tindices[j] = i + j + 1;
			}
			m->groups->triangles[idx] = idx;
		}
	}
	
	if (flipFace)
		glmReverseWinding(m);

	glmWriteOBJ(m, (char*)path.c_str(), writeMode);
	glmDelete(m);
}
Exemplo n.º 5
0
void
keyboard(unsigned char key, int x, int y)
{
    GLint params[2];
    
    switch (key) {
    case 'h':
        printf("help\n\n");
        printf("w         -  Toggle wireframe/filled\n");
        printf("c         -  Toggle culling\n");
        printf("n         -  Toggle facet/smooth normal\n");
        printf("b         -  Toggle bounding box\n");
        printf("r         -  Reverse polygon winding\n");
        printf("m         -  Toggle color/material/none mode\n");
        printf("p         -  Toggle performance indicator\n");
        printf("s/S       -  Scale model smaller/larger\n");
        printf("t         -  Show model stats\n");
        printf("o         -  Weld vertices in model\n");
        printf("+/-       -  Increase/decrease smoothing angle\n");
        printf("W         -  Write model to file (out.obj)\n");
        printf("q/escape  -  Quit\n\n");
        break;
        
    case 't':
        stats = !stats;
        break;
        
    case 'p':
        performance = !performance;
        break;
        
    case 'm':
        material_mode++;
        if (material_mode > 2)
            material_mode = 0;
        printf("material_mode = %d\n", material_mode);
        lists();
        break;
        
    case 'd':
        glmDelete(model);
        init();
        lists();
        break;
        
    case 'w':
        glGetIntegerv(GL_POLYGON_MODE, params);
        if (params[0] == GL_FILL)
            glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        else
            glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
        break;
        
    case 'c':
        if (glIsEnabled(GL_CULL_FACE))
            glDisable(GL_CULL_FACE);
        else
            glEnable(GL_CULL_FACE);
        break;
        
    case 'b':
        bounding_box = !bounding_box;
        break;
        
    case 'n':
        facet_normal = !facet_normal;
        lists();
        break;
        
    case 'r':
        glmReverseWinding(model);
        lists();
        break;
        
    case 's':
        glmScale(model, 0.8);
        lists();
        break;
        
    case 'S':
        glmScale(model, 1.25);
        lists();
        break;
        
    case 'o':
        //printf("Welded %d\n", glmWeld(model, weld_distance));
        glmVertexNormals(model, smoothing_angle);
        lists();
        break;
        
    case 'O':
        weld_distance += 0.01;
        printf("Weld distance: %.2f\n", weld_distance);
        glmWeld(model, weld_distance);
        glmFacetNormals(model);
        glmVertexNormals(model, smoothing_angle);
        lists();
        break;
        
    case '-':
        smoothing_angle -= 1.0;
        printf("Smoothing angle: %.1f\n", smoothing_angle);
        glmVertexNormals(model, smoothing_angle);
        lists();
        break;
        
    case '+':
        smoothing_angle += 1.0;
        printf("Smoothing angle: %.1f\n", smoothing_angle);
        glmVertexNormals(model, smoothing_angle);
        lists();
        break;
        
    case 'W':
        glmScale(model, 1.0/scale);
        glmWriteOBJ(model, "out.obj", GLM_SMOOTH | GLM_MATERIAL);
        break;
        
    case 'R':
        {
            GLuint i;
            GLfloat swap;
            for (i = 1; i <= model->numvertices; i++) {
                swap = model->vertices[3 * i + 1];
                model->vertices[3 * i + 1] = model->vertices[3 * i + 2];
                model->vertices[3 * i + 2] = -swap;
            }
            glmFacetNormals(model);
            lists();
            break;
        }
        
    case 27:
        exit(0);
        break;
    }
    
    glutPostRedisplay();
}