示例#1
0
/*! \brief load a OBJ material file
 *  \param mtlFilename is the full path to the material file
 */
void ObjReader::loadMTL(const std::string &mtlFilename)
{
    std::ifstream ifs;
    ifs.open(mtlFilename.c_str());
    if (!ifs.is_open()) {
        std::cerr << "can't open " << mtlFilename << std::endl;
        return;
    }
    std::shared_ptr<Material> mat;
    while (ifs.peek() != EOF) {
        char line[MAX_LINE_LENGTH];
        ifs.getline(line, sizeof(line), '\n');
        const char* token = line + strspn(line, " \t"); // ignore spaces and tabs
        if (token[0] == 0) continue; // ignore empty lines
        if (token[0] == '#') continue; // ignore comments

        if (!strncmp(token, "newmtl", 6)) {
            parseSep(token += 6);
            std::string name(token); printf("Name of the material %s\n", name.c_str());
            materials[name] = mat = std::shared_ptr<Material>(new Material (name));
            continue;
        }

        if (!mat) throw std::runtime_error("invalid material file: newmtl expected first");
        
        if (!strncmp(token, "d", 1)) { parseSep(token += 1); mat->d = getFloat(token); continue; }
        if (!strncmp(token, "Ns", 1)) { parseSep(token += 2); mat->Ns = getFloat(token); continue; }
        if (!strncmp(token, "Ns", 1)) { parseSep(token += 2); mat->Ni = getFloat(token); continue; }
        if (!strncmp(token, "Ka", 2)) { parseSep(token += 2); mat->Ka = getVec3f(token); continue; }
        if (!strncmp(token, "Kd", 2)) { parseSep(token += 2); mat->Kd = getVec3f(token); continue; }
        if (!strncmp(token, "Ks", 2)) { parseSep(token += 2); mat->Ks = getVec3f(token); continue; }
    }
    ifs.close();
}
示例#2
0
/*! \brief load the geometry defined in an OBJ/Wavefront file
 *  \param filename is the path to the OJB file
 */
ObjReader::ObjReader(const char *filename)
{
    std::ifstream ifs;
    // extract the path from the filename (used to read the material file)
    std::string path = getFilePath(filename);
    try {
        ifs.open(filename);
        if (ifs.fail()) throw std::runtime_error("can't open file " + std::string(filename));

        // create a default material
        std::shared_ptr<Material> defaultMaterial(new Material("Default"));
        curMaterial = defaultMaterial;

        char line[MAX_LINE_LENGTH]; // line buffer
        
        while (ifs.peek() != EOF) // read each line until EOF is found
        {
            ifs.getline(line, sizeof(line), '\n');
            const char* token = line + strspn(line, " \t"); // ignore space and tabs

			//printf("strncmp(token, vt,  2) --> %d\n", strncmp(token, "vt",  2));
            if (token[0] == 0) continue; // line is empty, ignore
            // read a vertex
            if (token[0] == 'v' && isSep(token[1])) { v.push_back(getVec3f(token += 2)); continue; }
            // read a normal
            if (!strncmp(token, "vn",  2) && isSep(token[2])) { vn.push_back(getVec3f(token += 3)); continue; }
            // read a texture coordinates
            if (!strncmp(token, "vt",  2) && isSep(token[2])) { vt.push_back(getVec2f(token += 3)); continue; }
            //if (!strncmp(token, "vt",  2) && isSep(token[2])) { printf("vt: %.3f\n", getVec2f(token += 3).x); continue; }
            // read a face
            if (token[0] == 'f' && isSep(token[1])) {
                parseSep(token += 1);
                std::vector<Vertex> face;
                while (token[0]) {
                    face.push_back(getInt3(token));
                    parseSepOpt(token);
                }
                curGroup.push_back(face);
                continue;
            }
            
            /*! use material */
            if (!strncmp(token, "usemtl", 6) && isSep(token[6]))
            {
                flushFaceGroup();
                std::string name(parseSep(token += 6));
                if (materials.find(name) == materials.end()) curMaterial = defaultMaterial;
                else curMaterial = materials[name];
                continue;
            }
            
            /* load material library */
            if (!strncmp(token, "mtllib", 6) && isSep(token[6])) {
                loadMTL(path + "/" + std::string(parseSep(token += 6)));
                continue;
            }
        }
    }
    catch (const std::exception &e) {
        std::cerr << e.what() << std::endl;
    }
    flushFaceGroup(); // flush the last loaded object
    ifs.close();
}
  /* load material file */
  void OBJLoader::loadMTL(const FileName &fileName)
  {
    std::ifstream cin;
    cin.open(fileName.c_str());
    if (!cin.is_open()) {
      std::cerr << "cannot open " << fileName.str() << std::endl;
      return;
    }

    char line[10000];
    memset(line, 0, sizeof(line));

    OBJMaterial* cur = nullptr;
    while (cin.peek() != -1)
    {
      /* load next multiline */
      char* pline = line;
      while (true) {
        cin.getline(pline, sizeof(line) - (pline - line) - 16, '\n');
        ssize_t last = strlen(pline) - 1;
        if (last < 0 || pline[last] != '\\') break;
        pline += last;
        *pline++ = ' ';
      }
      const char* token = trimEnd(line + strspn(line, " \t"));

      if (token[0] == 0  ) continue; // ignore empty lines
      if (token[0] == '#') continue; // ignore comments

      if (!strncmp(token, "newmtl", 6)) {
        parseSep(token+=6);
        std::string name(token);
        Material objmtl; new (&objmtl) OBJMaterial;
        Ref<SceneGraph::MaterialNode> mtl = new SceneGraph::MaterialNode(objmtl);
        material[name] = mtl;
        cur = (OBJMaterial*) &mtl->material;
        continue;
      }

      if (!cur) THROW_RUNTIME_ERROR("invalid material file: newmtl expected first");

      if (!strncmp(token, "illum", 5)) { parseSep(token += 5);  continue; }

      if (!strncmp(token, "d",  1)) { parseSep(token += 1);  cur->d  = getFloat(token); continue; }
      if (!strncmp(token, "Ns", 2)) { parseSep(token += 2);  cur->Ns = getFloat(token); continue; }
      if (!strncmp(token, "Ni", 2)) { parseSep(token += 2);  cur->Ni = getFloat(token); continue; }

      if (!strncmp(token, "Ka_map", 6)) { continue; }
      if (!strncmp(token, "Kd_map", 6) || !strncmp(token, "map_Kd", 6)) {
        parseSep(token += 6);
        cur->map_Kd = loadTexture(path + FileName(token));
        continue;
      }


      if (!strncmp(token, "Ks_map", 6)) { continue; }
      if (!strncmp(token, "Tf_map", 6)) { continue; }
      if (!strncmp(token, "Displ_map", 9) || !strncmp(token, "map_Displ", 9)) {
        parseSep(token += 9);
        cur->map_Displ = loadTexture(path + FileName(token));
        continue;
      }
      
      if (!strncmp(token, "Ka", 2)) { parseSep(token += 2);  cur->Ka = getVec3f(token); continue; }
      if (!strncmp(token, "Kd", 2)) { parseSep(token += 2);  cur->Kd = getVec3f(token); continue; }
      if (!strncmp(token, "Ks", 2)) { parseSep(token += 2);  cur->Ks = getVec3f(token); continue; }
      if (!strncmp(token, "Tf", 2)) { parseSep(token += 2);  cur->Kt = getVec3f(token); continue; }
    }
    cin.close();
  }
  OBJLoader::OBJLoader(const FileName &fileName, const bool subdivMode) 
    : path(fileName.path()), group(new SceneGraph::GroupNode), subdivMode(subdivMode)
  {
    /* open file */
    std::ifstream cin;
    cin.open(fileName.c_str());
    if (!cin.is_open()) {
      THROW_RUNTIME_ERROR("cannot open " + fileName.str());
      return;
    }

    /* generate default material */
    Material objmtl; new (&objmtl) OBJMaterial;
    Ref<SceneGraph::MaterialNode> defaultMaterial = new SceneGraph::MaterialNode(objmtl);
    curMaterial = defaultMaterial;

    char line[10000];
    memset(line, 0, sizeof(line));

    while (cin.peek() != -1)
    {
      /* load next multiline */
      char* pline = line;
      while (true) {
        cin.getline(pline, sizeof(line) - (pline - line) - 16, '\n');
        ssize_t last = strlen(pline) - 1;
        if (last < 0 || pline[last] != '\\') break;
        pline += last;
        *pline++ = ' ';
      }

      const char* token = trimEnd(line + strspn(line, " \t"));
      if (token[0] == 0) continue;

      /*! parse position */
      if (token[0] == 'v' && isSep(token[1])) { 
        v.push_back(getVec3f(token += 2)); continue;
      }

      /* parse normal */
      if (token[0] == 'v' && token[1] == 'n' && isSep(token[2])) { 
        vn.push_back(getVec3f(token += 3)); 
        continue; 
      }

      /* parse texcoord */
      if (token[0] == 'v' && token[1] == 't' && isSep(token[2])) { vt.push_back(getVec2f(token += 3)); continue; }

      /*! parse face */
      if (token[0] == 'f' && isSep(token[1]))
      {
        parseSep(token += 1);

        std::vector<Vertex> face;
        while (token[0]) {
	  Vertex vtx = getInt3(token);
          face.push_back(vtx);
          parseSepOpt(token);
        }
        curGroup.push_back(face);
        continue;
      }

      /*! parse edge crease */
      if (token[0] == 'e' && token[1] == 'c' && isSep(token[2]))
      {
	parseSep(token += 2);
	float w = getFloat(token);
	parseSepOpt(token);
	int a = fix_v(getInt(token));
	parseSepOpt(token);
	int b = fix_v(getInt(token));
	parseSepOpt(token);
	ec.push_back(Crease(w, a, b));
	continue;
      }

      /*! use material */
      if (!strncmp(token, "usemtl", 6) && isSep(token[6]))
      {
        flushFaceGroup();
        std::string name(parseSep(token += 6));
        if (material.find(name) == material.end()) curMaterial = defaultMaterial;
        else curMaterial = material[name];
        continue;
      }

      /* load material library */
      if (!strncmp(token, "mtllib", 6) && isSep(token[6])) {
        loadMTL(path + std::string(parseSep(token += 6)));
        continue;
      }

      // ignore unknown stuff
    }
    flushFaceGroup();

    cin.close();
  }