Пример #1
0
void ofxObjLoader::save(string path, ofMesh& mesh){
    path = ofToDataPath(path);
    
    GLuint writeMode = GLM_NONE;
    
    GLMmodel* m = new GLMmodel();
    if(mesh.getNumVertices() > 0){
        m->numvertices = mesh.getNumVertices();
	    m->vertices = new GLfloat[m->numvertices*3+1];
        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*3+1];
        memcpy(&m->normals[3], &mesh.getNormals()[0].x, sizeof(ofVec3f)*mesh.getNumNormals());
        writeMode |= GLM_SMOOTH;
    }
	
    if(mesh.getNumTexCoords() > 0){
        m->numtexcoords = mesh.getNumTexCoords();
        m->texcoords = new GLfloat[m->numtexcoords*2+1];
        memcpy(&m->texcoords[2], &mesh.getTexCoords()[0].x, sizeof(ofVec2f)*mesh.getNumTexCoords());
        writeMode |= GLM_TEXTURE;
    }
    
    if(mesh.getNumIndices() > 0){
        //create triangles
		m->numtriangles = mesh.getNumIndices()/3;
        m->triangles = new GLMtriangle[m->numtriangles];
        
        //add them all to one group
        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()/3; i++){
            memcpy(m->triangles[i].vindices, &mesh.getIndices()[i*3], sizeof(GLuint)*3);
            memcpy(m->triangles[i].nindices, &mesh.getIndices()[i*3], sizeof(GLuint)*3);
            memcpy(m->triangles[i].tindices, &mesh.getIndices()[i*3], sizeof(GLuint)*3);
            m->groups->triangles[i] = i;
        }
    }
    
    glmWriteOBJ(m, (char*)path.c_str(), writeMode);
    glmDelete(m);
}
Пример #2
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);
}
Пример #3
0
void save(string path, const ofMesh& mesh_, const ofPixels& tex, string imgext)
{
    ofMesh mesh = mesh_;
    
    path = ofToDataPath(path);
    
    ofFilePath::createEnclosingDirectory(path);
    
    GLuint writeMode = GLM_NONE;
    GLMmodel* m = new GLMmodel();
    
    {
        ofFile file(path);
        string base_path = file.getEnclosingDirectory();
        string material_name = file.getBaseName();
        
        string image_name = material_name + "." + imgext;

        ofPixels pix = tex;
        
        // 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();
        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;
        }
    }

    glmWriteOBJ(m, (char*)path.c_str(), writeMode);
    glmDelete(m);
}
Пример #4
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();
}