ccdemos/common_ply.h
author Radek Brich <radek.brich@devl.cz>
Tue, 26 Jul 2016 18:19:37 +0200
branchpyrit
changeset 104 2274a07510c1
parent 100 c005054bf4c1
permissions -rw-r--r--
Cleanup, dropped Windows support

#include <iostream>
#include <fstream>
#include <iomanip>
#include "raytracer.h"
#include "mempool.h"

void load_ply(Raytracer &rt, const char *filename, Material *mat, const Vector &scale, const Vector &transp)
{
	MemoryPool<Triangle> *mp_tri;
	MemoryPool<NormalVertex> *mp_vert;
	vector<NormalVertex*> vertices;
	vector<int> vertex_face_num;
	Vector *normals;
	ifstream f(filename);
	string token = "a";
	if (!f.is_open())
	{
		cout << "File not found: " << filename <<endl;
		exit(1);
	}
	// read header
	int vertex_num, face_num;
	while (token != "end_header")
	{
		f >> token;
		if (token == "element")
		{
			f >> token;
			if (token == "vertex")
				f >> vertex_num;
			if (token == "face")
				f >> face_num;
		}
		f.ignore(1000,'\n');
	}

	// read vertices
	Vector P;
	int num = vertex_num;
	mp_vert = new MemoryPool<NormalVertex>(vertex_num);
	normals = new Vector[vertex_num];
	while (num--)
	{
		f >> P.x >> P.y >> P.z;
		P.x = scale.x*P.x + transp.x;
		P.y = scale.y*P.y + transp.y;
		P.z = scale.z*P.z + transp.z;
		vertices.push_back(new (mp_vert->alloc()) NormalVertex(P));
		vertex_face_num.push_back(0);
		f.ignore(1000,'\n');
	}

	// read faces
	Triangle *face;
	int v1, v2, v3;
	mp_tri = new MemoryPool<Triangle>(face_num);
	while (face_num--)
	{
		f >> num;
		if (num != 3)
		{
			printf("ply error: faces of %d vertices not supported", num);
			continue;
		}
		f >> v1 >> v2 >> v3;

		// check for invalid faces and ignore them
		if (vertices[v1]->P == vertices[v2]->P
		 || vertices[v1]->P == vertices[v3]->P
		 || vertices[v2]->P == vertices[v3]->P)
		{
			f.ignore(1000,'\n');
			continue;
		}

		face = new (mp_tri->alloc()) Triangle(vertices[v1], vertices[v3], vertices[v2], mat);
		rt.addShape(face);

		normals[v1] += face->getNormal();
		vertex_face_num.at(v1)++;
		normals[v2] += face->getNormal();
		vertex_face_num.at(v2)++;
		normals[v3] += face->getNormal();
		vertex_face_num.at(v3)++;
		f.ignore(1000,'\n');
	}

	for (int i = 0; i < vertex_num; i++)
		if (vertex_face_num.at(i))
		{
			normals[i] /= (Float)vertex_face_num.at(i);
			normals[i].normalize();
			vertices.at(i)->N = normals[i];
		}

	delete[] normals;
	f.close();
}