bool KAbstractObjParserPrivate::parse()
{
  for (;;)
  {
    switch (nextToken())
    {
    case PT_ERROR:
      qFatal("Encountered an error! Aborting");
      return false;
    case PT_EOF:
      return true;
    case PT_VERTEX:
      parseVertex();
      break;
    case PT_TEXTURE:
      parseTexture();
      break;
    case PT_NORMAL:
      parseNormal();
      break;
    case PT_PARAMETER:
      parseParameter();
      break;
    case PT_FACE:
      parseFace();
    case PT_ENDSTATEMENT:
      break;
    }
  }
}
    void parse(std::ifstream& file, ObjStore& obj) {
        std::string line;
        std::stringstream lineStream;
        char firstChar;

        std::cout << "Parsing Obj!" << std::endl;

        while ( std::getline( file, line ) ) {

            // reject empty lines
            if ( line.empty() ) {
                continue;
            }

            // make stream from line
            lineStream.clear();
            lineStream.str(line);

            // check first char to determine type
            lineStream.get(firstChar);

            if (firstChar == 'v') {
                parseVertex(lineStream, obj);
            }
            else if (firstChar == 'f') {
                parseFace(lineStream, obj);
            }
        }
    }
Exemple #3
0
void Obj2::load(std::string const& path) {
	ifstream file;
	string work;
	file.open(path.c_str(), ios::in);
	//check ouverture
	if (!file.good()) {
		throw FileError(0,"Error in OBJ load : \n\timpossible to open " + path + ".");
	}
	objects.clear();
	vertices.clear();
	//boucle de parcours pour tout le fichier
	int cptr = 0;
	Object *currentObject = nullptr;
	while (!file.eof()) {
		cptr++;
		file >> work;//premier mot de la ligne
		//cas face
		if (work == "f") {//on ne désespère pas. un jour on pourra switcher sur des strings. ptt.
			if (currentObject == nullptr) throw FileError(1,"Error in OBJ load : \n\tface before first object at line " + to_string(cptr));
			getline(file, work); 
			currentObject->addFace(parseFace(work));
		}//cas vertice
		else if (work == "v") {
			getline(file, work);
			addVertex(parseVertex(work));
		}//cas objet
		else if (work == "o") {
			file >> work;
			if (currentObject != nullptr) {
				currentObject->setDimension((currentObject->nbrFaces() == 6) ? 0 : 1);
				addObject(*currentObject);
			}currentObject = new Object(work, 1);
		}//cas commentaire
		else if (work == "#") {
void ModelLoader::parseLine(char *line)
{
	//check for an empty string
	if(!strlen(line))
	{
		return;
	}

	char *linetype;
	linetype = strtok(strdup(line), " ");

	if(!strcmp(linetype, "v"))
	{
		parseVertex(line); //line is a vertex
	}

	else if(!strcmp(linetype, "vn"))
	{
		parseNormal(line); //line is a normal
	}

	else if(!strcmp(linetype, "vt"))
	{
		parseTexel(line); //line is a texel
	}

	else if(!strcmp(linetype, "f"))
	{
		parseFace(line); //line is a face
	}

	return;
}
void WFObject::parseLine(char *line)
{
	if(!strlen(line))
	{
		return;
	}

	char *lineType;
	lineType = strtok(_strdup(line), " ");

	// Decide what to do
	if(!strcmp(lineType, "v"))		// Vertex
	{
		parseVertex(line);
	}
	else if (!strcmp(lineType, "vt"))
	{
		parseTexture(line);
	}
	else if(!strcmp(lineType, "vn"))	// Normal
	{
		parseNormal(line);
	}
	else if(!strcmp(lineType, "f"))	// Face
	{
		parseFace(line);
	}

	return;
}
Exemple #6
0
void Mesh::parseLine(std::stringstream&& sin)
{
	std::string s;
	sin >> s;
	if (s.compare("v") == 0) parseVertex(sin);
	else if (s.compare("vt") == 0) parseTexcoord(sin);
	else if (s.compare("vn") == 0) parseNormal(sin);
	else if (s.compare("f") == 0) parseFace(sin);
}
Exemple #7
0
void Geometry::parseObjFile(const std::string filePath, std::vector<GLfloat>& vboData, std::vector<GLushort>& iboData)
{
	//temporary save values in arrays
	std::vector<glm::vec3> vertices;
	std::vector<glm::vec3> normals;

	//save which data vbo already contains
	std::list<IndexCombination> combinations;
	//save next vbo index to use
	GLushort nextVboIndex = 0;

	//open file
	std::ifstream objFile;
	objFile.exceptions(std::ifstream::badbit | std::ifstream::failbit);
	
	objFile.open(filePath);
	std::string line;
	while (!objFile.eof()) {
		try {
			std::getline(objFile, line);
		}
		catch (const std::exception &ex) {
			if (!objFile.eof()) {
				throw ex;
			}
			else {
				continue;
			}
		}
		std::istringstream lstream(line);
		std::string type;
		lstream >> type;
		if (type.compare("v") == 0) {
			parseVertex(lstream, vertices);
		}
		else if (type.compare("vn") == 0) {
			parseNormal(lstream, normals);
		}
		else if (type.compare("f") == 0) {
			parseFace(lstream, vboData, iboData, vertices, normals, &nextVboIndex, combinations);
		}
		else if (type.compare("s") == 0) {
			//ignore line
		}
		else if (type.compare("o") == 0) {
			//ignore line
		}
		else if (type.compare("#") == 0) {
			//ignore line
		}
		else {
			throw std::logic_error("Unknown start of line");
		}
	}
	objFile.close();
}
Exemple #8
0
 bool MapParser::parseFaces(const BBox& worldBounds, Model::FaceList& faces) {
     size_t oldSize = faces.size();
     try {
         Model::Face* face = NULL;
         while ((face = parseFace(worldBounds)) != NULL)
             faces.push_back(face);
         return !faces.empty();
     } catch (MapParserException e) {
         Utility::deleteAll(faces, oldSize);
         m_tokenizer.reset();
         return false;
     }
 }
Exemple #9
0
void Model::parseMesh(std::string fileName) {
  std::string line;
  std::ifstream myFile(fileName.c_str());
  if (myFile.is_open()) {
    while (getline(myFile, line)) {
      if (line.at(0) == 'o') {
        meshName = parseName(line);
      } else if (line.at(0) == 'v' && line.at(1) == ' ') {
        vertexArray.push_back(parseVertex(line));
      } else if (line.at(0) == 'f') {
        std::vector<std::string> elements = split(line, ' ');
        if ((elements.size() - 1) == 4) {
          quadArray.push_back(parseFace(elements));
        } else if ((elements.size() - 1) == 3) {
          triArray.push_back(parseFace(elements));
        }
        elements.clear();
      } else {
        // N-Gons
      }
    }
  }
  myFile.close();
}
int objLoad(char* filePath) {
   FILE* file = fopen(filePath, "r");
   char* line = (char*)calloc(LINE_SIZE, sizeof(char));
   char* token = NULL, * delim = " \n\t";

   int vertexCount = 0, textureCount = 0, normalCount = 0, faceCount = 0;
   while(fgets(line, LINE_SIZE, file) != NULL) {
      if(prefix("vt", line)) ++textureCount;
      else if(prefix("vn", line)) ++normalCount;
      else if(prefix("v", line))  ++vertexCount;
      else if(prefix("f", line))  ++faceCount;
   }
   rewind(file);

   obj* object = (obj*)calloc(1, sizeof(obj));
   object->faceCount = faceCount;
   object->vertexCount = vertexCount;
   object->vertices = (vec3*)calloc(vertexCount, sizeof(vec3));
   object->shared = (int*)calloc(vertexCount, sizeof(int));
   object->normals = (vec3*)calloc(normalCount, sizeof(vec3));
   object->tangents = (vec3*)calloc(vertexCount, sizeof(vec3));
   object->bitangents = (vec3*)calloc(vertexCount, sizeof(vec3));
   object->textures = (vec2*)calloc(textureCount, sizeof(vec2));
   object->faces = (face*)calloc(faceCount, sizeof(face));

   int vertexTally = 0, normalTally = 0, textureTally = 0, faceTally = 0;

   while(fgets(line, LINE_SIZE, file) != NULL) {
      if(prefix("vt", line)) {
         parseVec2(line, &object->textures[textureTally]);
         object->textures[textureTally].y = 1.0 - object->textures[textureTally].y;
         ++textureTally;
      }
      else if(prefix("vn", line)) parseVec3(line, &object->normals[normalTally++]);
      else if(prefix("v", line)) parseVec3(line, &object->vertices[vertexTally++]);
      else if(prefix("f", line)) parseFace(line, object->faces[faceTally++]);
   }
   uniqueMap(object);

   free(line);
   fclose(file);

   int index = nextIndex();
   objects[index] = object;
   return index;
}
 Model::Brush* MapParser::parseBrush(const BBox& worldBounds, Utility::ProgressIndicator* indicator) {
     Token token = m_tokenizer.nextToken();
     if (token.type() == TokenType::Eof)
         return NULL;
     
     expect(TokenType::OBrace | TokenType::CBrace, token);
     if (token.type() == TokenType::CBrace)
         return NULL;
     
     Model::Brush* brush = new Model::Brush(worldBounds);
     brush->setFilePosition(token.line());
     
     while ((token = m_tokenizer.nextToken()).type() != TokenType::Eof) {
         switch (token.type()) {
             case TokenType::OParenthesis: {
                 m_tokenizer.pushToken(token);
                 Model::Face* face = parseFace(worldBounds);
                 if (face != NULL && brush != NULL) {
                     if (!brush->addFace(face)) {
                         m_console.warn("Skipping malformed brush at line %i", brush->filePosition());
                         delete brush;
                         brush = NULL;
                     }
                 } else {
                     delete face;
                 }
                 break;
             }
             case TokenType::CBrace:
                 if (indicator != NULL) indicator->update(static_cast<int>(token.position()));
                 if (brush != NULL && !brush->closed()) {
                     m_console.warn("Non-closed brush at line %i", brush->filePosition());
                     // delete brush;
                     // brush = NULL;
                 }
                 return brush;
             default:
                 delete brush;
                 throw MapParserException(token, TokenType::OParenthesis | TokenType::CParenthesis);
         }
     }
     
     return NULL;
 }
bool rcMeshLoaderObj::load(const char* filename)
{
	char* buf = 0;
	FILE* fp = fopen(filename, "rb");
	if (!fp)
		return false;
	fseek(fp, 0, SEEK_END);
	int bufSize = ftell(fp);
	fseek(fp, 0, SEEK_SET);
	buf = new char[bufSize];
	if (!buf)
	{
		fclose(fp);
		return false;
	}
	fread(buf, bufSize, 1, fp);
	fclose(fp);

	char* src = buf;
	char* srcEnd = buf + bufSize;
	char row[512];
	int face[32];
	float x,y,z;
	int nv;
	int vcap = 0;
	int tcap = 0;
	
	while (src < srcEnd)
	{
		// Parse one row
		row[0] = '\0';
		src = parseRow(src, srcEnd, row, sizeof(row)/sizeof(char));
		// Skip comments
		if (row[0] == '#') continue;
		if (row[0] == 'v' && row[1] != 'n' && row[1] != 't')
		{
			// Vertex pos
			sscanf(row+1, "%f %f %f", &x, &y, &z);
			addVertex(x, y, z, vcap);
		}
		if (row[0] == 'f')
		{
			// Faces
			nv = parseFace(row+1, face, 32, m_vertCount);
			for (int i = 2; i < nv; ++i)
			{
				const int a = face[0];
				const int b = face[i-1];
				const int c = face[i];
				if (a < 0 || a >= m_vertCount || b < 0 || b >= m_vertCount || c < 0 || c >= m_vertCount)
					continue;
				addTriangle(a, b, c, tcap);
			}
		}
	}

	delete [] buf;

	// Calculate normals.
	m_normals = new float[m_triCount*3];
	for (int i = 0; i < m_triCount*3; i += 3)
	{
		const float* v0 = &m_verts[m_tris[i]*3];
		const float* v1 = &m_verts[m_tris[i+1]*3];
		const float* v2 = &m_verts[m_tris[i+2]*3];
		float e0[3], e1[3];
		for (int j = 0; j < 3; ++j)
		{
			e0[j] = v1[j] - v0[j];
			e1[j] = v2[j] - v0[j];
		}
		float* n = &m_normals[i];
		n[0] = e0[1]*e1[2] - e0[2]*e1[1];
		n[1] = e0[2]*e1[0] - e0[0]*e1[2];
		n[2] = e0[0]*e1[1] - e0[1]*e1[0];
		float d = sqrtf(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]);
		if (d > 0)
		{
			d = 1.0f/d;
			n[0] *= d;
			n[1] *= d;
			n[2] *= d;
		}
	}
	
	strncpy(m_filename, filename, sizeof(m_filename));
	m_filename[sizeof(m_filename)-1] = '\0';
	
	return true;
}
Exemple #13
0
Mesh *Mesh::fromObjFile(QString filename) {
    QFile file(filename);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
        return 0;

    Mesh *M = new Mesh();
    vector<Vector3f> normals;

    //first pass to add all vertices and normals to mesh
    while (!file.atEnd()) {
        QByteArray lineBytes = file.readLine();

        if (lineBytes.at(0) == 'v' && lineBytes.at(1) == 'n') {
            // parse normal if line starts with 'vn'
            Vector3f normal;

            if (!parseCoordinate(QString(lineBytes), normal)) {
                delete M;
                return false;
            }

            normals.push_back(normal);
        } else if (lineBytes.at(0) == 'v' && lineBytes.at(1) == ' ') {
            // parse vertex if line starts with just 'v'
            Vertex V;
            if (!parseCoordinate(QString(lineBytes), V.pos)) {
                delete M;
                return false;
            }
            M->m_vertices.push_back(V);
        }
    }

    //second pass to add faces to the mesh
    file.reset();
    while (!file.atEnd()) {
        QByteArray lineBytes = file.readLine();
        if (lineBytes.at(0) == 'f') {
            uint V[4];
            uint N[4];
            bool hasNormals;

            if (!parseFace(QString(lineBytes), V, N, hasNormals)) {
                delete M;
                return false;
            }

            if (hasNormals) {
                //use normals if they are provided
                Vector3f faceNormals[4];
                for (uint i = 0; i < 4; i++) {
                    if (N[i] < normals.size())
                        faceNormals[i] = normals[N[i]];
                }
                M->addFace(V[0],V[1],V[2],V[3], faceNormals);
            } else {
                //interpolate normals if they are not provided
                M->addFace(V[0],V[1],V[2],V[3]);
            }
        }
    }

    return M;
}
Exemple #14
0
GLLObjFile::GLLObjFile(CFURLRef location)
{
    std::string filename = GLLStringFromFileURL(location);
    
    int fdes = ::open(filename.c_str(), O_RDONLY);
    if (fdes < 0) {
        throw std::runtime_error("Could not open file");
    }
    
    struct stat statistics;
    if (fstat(fdes, &statistics) < 0) {
        close(fdes);
        throw std::runtime_error("Could not get file size");
    }
    
    const char *buffer = (const char *) mmap(nullptr, statistics.st_size, PROT_READ, MAP_PRIVATE, fdes, 0);
    close(fdes);
    const char *current = buffer;
    const char *end = &buffer[statistics.st_size];
    
    materialLibraryURLs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
    std::string activeMaterial("");
    unsigned activeMaterialStart = 0;
    bool hasFirstMaterial = false;
    while(current != end)
    {
        while (current != end && (*current == ' ' || *current == '\n' || *current == '\r')) {
            current++;
        }
        if (current == end)
            break;
        
        switch (*current) {
            case 'f':
                parseFace(current, end);
                break;
            case 'v':
                current += 1;
                switch (*current) {
                    case 'n': // Normals
                        current += 1;
                        parseVector(current, end, normals, 3);
                        break;
                    case 't': // Tex coords
                        current += 1;
                        parseVector(current, end, texCoords, 2);
                        break;
                    case 'c': // Colors
                        current += 1;
                        parseVector(current, end, colors, 4);
                        break;
                    case ' ': // Vertex
                        parseVector(current, end, vertices, 3);
                        break;
                    default:
                        skipToEndOfLine(current, end);
                        break;
                }
                break;
            case 'm':
                if (followsString(current, end, "mtllib")) {
                    std::string mtllib = stringToEndOfLine(current, end);
                    
                    try
                    {
                        CFURLRef mtllibLocation = GLLCreateURLFromString(mtllib, location);
                        CFArrayAppendValue(materialLibraryURLs, mtllibLocation);
                        CFRelease(mtllibLocation);
                    }
                    catch (std::exception &e)
                    {
                        std::cerr << "Ignoring mtllib: " << e.what() << std::endl;
                    }
                } else {
                    skipToEndOfLine(current, end);
                }
                break;
            case 'u':
                if (followsString(current, end, "usemtl")) {
                    if (hasFirstMaterial)
                    {
                        // End previous material run
                        materialRanges.push_back(MaterialRange(activeMaterialStart, (unsigned) originalIndices.size(), activeMaterial));
                    }
                    else
                        hasFirstMaterial = true;
                    
                    current += 1;
                    activeMaterial = stringToEndOfLine(current, end);
                    activeMaterialStart = (unsigned) originalIndices.size();
                } else {
                    skipToEndOfLine(current, end);
                }
                break;
            case '#': // Comment
            default:
                skipToEndOfLine(current, end);
                break;
        }
    }
    munmap((void *) buffer, statistics.st_size);
    
    // Wrap up final material group
    materialRanges.push_back(MaterialRange(activeMaterialStart, (unsigned) originalIndices.size(), activeMaterial));
    
    fillIndices();
}
Exemple #15
0
bool rcMeshLoaderObj::loadContents(const char* contents) // TODO: PATCH
{
	int bufSize = strlen(contents);

	char* buf = const_cast<char*>(contents);
	
	char* src = buf;
	//char* src = 0;

	char* srcEnd = buf + bufSize;
	char row[512];
	int face[32];
	float x,y,z;
	int nv;
	int vcap = 0;
	int tcap = 0;
	
	while (src < srcEnd)
	{
		// Parse one row
		row[0] = '\0';
		src = parseRow(src, srcEnd, row, sizeof(row)/sizeof(char));
		// Skip comments
		if (row[0] == '#') continue;
		if (row[0] == 'v' && row[1] != 'n' && row[1] != 't')
		{
			// Vertex pos
			sscanf(row+1, "%f %f %f", &x, &y, &z);
			addVertex(x, y, z, vcap);
		}
		if (row[0] == 'f')
		{
			// Faces
			nv = parseFace(row+1, face, 32, m_vertCount);
			for (int i = 2; i < nv; ++i)
			{
				const int a = face[0];
				const int b = face[i-1];
				const int c = face[i];
				if (a < 0 || a >= m_vertCount || b < 0 || b >= m_vertCount || c < 0 || c >= m_vertCount)
					continue;
				addTriangle(a, b, c, tcap);
			}
		}
	}

	//delete [] buf;

	// Calculate normals.
	m_normals = new float[m_triCount*3];
	for (int i = 0; i < m_triCount*3; i += 3)
	{
		const float* v0 = &m_verts[m_tris[i]*3];
		const float* v1 = &m_verts[m_tris[i+1]*3];
		const float* v2 = &m_verts[m_tris[i+2]*3];
		float e0[3], e1[3];
		for (int j = 0; j < 3; ++j)
		{
			e0[j] = v1[j] - v0[j];
			e1[j] = v2[j] - v0[j];
		}
		float* n = &m_normals[i];
		n[0] = e0[1]*e1[2] - e0[2]*e1[1];
		n[1] = e0[2]*e1[0] - e0[0]*e1[2];
		n[2] = e0[0]*e1[1] - e0[1]*e1[0];
		float d = sqrtf(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]);
		if (d > 0)
		{
			d = 1.0f/d;
			n[0] *= d;
			n[1] *= d;
			n[2] *= d;
		}
	}
	
	return true;
}
Exemple #16
0
        Model::Brush* MapParser::parseBrush(const BBox& worldBounds, Utility::ProgressIndicator* indicator) {
            Token token = m_tokenizer.nextToken();
            if (token.type() == TokenType::Eof)
                return NULL;
            
            expect(TokenType::OBrace | TokenType::CBrace, token);
            if (token.type() == TokenType::CBrace)
                return NULL;
            
            const size_t firstLine = token.line();
            Model::FaceList faces;
            
            while ((token = m_tokenizer.nextToken()).type() != TokenType::Eof) {
                switch (token.type()) {
                    case TokenType::OParenthesis: {
                        m_tokenizer.pushToken(token);
                        Model::Face* face = parseFace(worldBounds);
                        if (face != NULL)
                            faces.push_back(face);
                        break;
                    }
                    case TokenType::CBrace: {
                        if (indicator != NULL) indicator->update(static_cast<int>(token.position()));
                        
                        Model::Brush* brush = new Model::Brush(worldBounds);

                        // sort the faces by the weight of their plane normals like QBSP does
                        Model::FaceList sortedFaces = faces;
                        std::sort(sortedFaces.begin(), sortedFaces.end(), Model::Face::WeightOrder(Plane::WeightOrder(true)));
                        std::sort(sortedFaces.begin(), sortedFaces.end(), Model::Face::WeightOrder(Plane::WeightOrder(false)));
                        
                        Model::FaceList::iterator faceIt = sortedFaces.begin();
                        Model::FaceList::iterator faceEnd = sortedFaces.end();
                        while (faceIt != faceEnd) {
                            Model::Face* face = *faceIt++;
                            if (!brush->addFace(face)) {
                                m_console.warn("Skipping malformed brush at line %i", firstLine);
                                delete brush;
                                brush = NULL;
                                break;
                            }
                        }
                        
                        // if something went wrong, we must delete all faces that have not been added to the brush yet
                        if (faceIt != faceEnd)
                            Utility::deleteAll(sortedFaces, faceIt);
                        
                        if (brush != NULL) {
                            brush->setFilePosition(firstLine, token.line() - firstLine);
                            if (!brush->closed())
                                m_console.warn("Non-closed brush at line %i", firstLine);
                        }
                        return brush;
                    }
                    default: {
                        Utility::deleteAll(faces);
                        throw MapParserException(token, TokenType::OParenthesis | TokenType::CParenthesis);
                    }
                }
            }
            
            return NULL;
        }