Subversion Repositories gelsvn

Rev

Rev 595 | Rev 605 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 595 Rev 601
1
/* ----------------------------------------------------------------------- *
1
/* ----------------------------------------------------------------------- *
2
 * This file is part of GEL, http://www.imm.dtu.dk/GEL
2
 * This file is part of GEL, http://www.imm.dtu.dk/GEL
3
 * Copyright (C) the authors and DTU Informatics
3
 * Copyright (C) the authors and DTU Informatics
4
 * For license and list of authors, see ../../doc/intro.pdf
4
 * For license and list of authors, see ../../doc/intro.pdf
5
 * ----------------------------------------------------------------------- */
5
 * ----------------------------------------------------------------------- */
6
 
6
 
7
#include "TriMesh.h"
7
#include "TriMesh.h"
8
#include <CGLA/Vec3f.h>
8
#include "../CGLA/Vec3f.h"
9
#include <fstream>
9
#include <fstream>
10
#include <iostream>
10
#include <iostream>
11
 
11
 
12
using namespace std;
12
using namespace std;
13
using namespace CGLA;
13
using namespace CGLA;
14
 
14
 
15
namespace Geometry {
15
namespace Geometry {
16
    
16
    
17
	namespace
17
	namespace
18
	{
18
	{
19
		string get_path(const string& _filename)
19
		string get_path(const string& _filename)
20
		{
20
		{
21
			// Make sure we only have slashes and not backslashes
21
			// Make sure we only have slashes and not backslashes
22
			string filename = _filename;
22
			string filename = _filename;
23
			replace(filename.begin(),filename.end(),'\\','/');
23
			replace(filename.begin(),filename.end(),'\\','/');
24
			
24
			
25
			// Find the last occurrence of slash.
25
			// Find the last occurrence of slash.
26
			// Everything before is path.
26
			// Everything before is path.
27
			size_t n = filename.rfind("/");
27
			size_t n = filename.rfind("/");
28
			if(n > filename.size())
28
			if(n > filename.size())
29
				return "./";
29
				return "./";
30
			string pathname(filename,0,n);
30
			string pathname(filename,0,n);
31
			pathname.append("/");
31
			pathname.append("/");
32
			return pathname;
32
			return pathname;
33
		}
33
		}
34
	}
34
	}
35
	class TriMeshObjLoader
35
	class TriMeshObjLoader
36
	{
36
	{
37
		TriMesh *mesh;
37
		TriMesh *mesh;
38
		std::string pathname;
38
		std::string pathname;
39
        
39
        
40
		int get_vert(int i) {
40
		int get_vert(int i) {
41
			assert(i!=0);
41
			assert(i!=0);
42
			if (i<0) {
42
			if (i<0) {
43
				return mesh->geometry.no_vertices()+i;
43
				return mesh->geometry.no_vertices()+i;
44
			} else
44
			} else
45
				return i-1;
45
				return i-1;
46
		}
46
		}
47
        
47
        
48
		int get_normal(int i) {
48
		int get_normal(int i) {
49
			if (i<0) {
49
			if (i<0) {
50
				return mesh->normals.no_vertices()+i;
50
				return mesh->normals.no_vertices()+i;
51
			} else
51
			} else
52
				return i-1;
52
				return i-1;
53
		}
53
		}
54
        
54
        
55
		int get_texcoord(int i) {
55
		int get_texcoord(int i) {
56
			if (i<0) {
56
			if (i<0) {
57
				return mesh->texcoords.no_vertices()+i;
57
				return mesh->texcoords.no_vertices()+i;
58
			} else
58
			} else
59
				return i-1;
59
				return i-1;
60
		}
60
		}
61
		
61
		
62
	public:
62
	public:
63
        
63
        
64
		TriMeshObjLoader(TriMesh *_mesh): mesh(_mesh) {}
64
		TriMeshObjLoader(TriMesh *_mesh): mesh(_mesh) {}
65
		
65
		
66
		void load(const std::string& filename);
66
		void load(const std::string& filename);
67
        
67
        
68
		void read_material_library(const string& filename);
68
		void read_material_library(const string& filename);
69
        
69
        
70
	};
70
	};
71
	
71
	
72
	void TriMeshObjLoader::read_material_library(const string& filename)
72
	void TriMeshObjLoader::read_material_library(const string& filename)
73
	{
73
	{
74
		string fn = pathname + filename;
74
		string fn = pathname + filename;
75
        ifstream material_file(fn.data());
75
        ifstream material_file(fn.data());
76
        
76
        
77
		if(material_file)
77
		if(material_file)
78
        {
78
        {
79
            string buf;
79
            string buf;
80
            unsigned int nummaterials=0;
80
            unsigned int nummaterials=0;
81
            while(material_file >> buf)
81
            while(material_file >> buf)
82
            {
82
            {
83
                switch(buf[0])
83
                switch(buf[0])
84
                {
84
                {
85
                    case 'n':
85
                    case 'n':
86
                        ++nummaterials;
86
                        ++nummaterials;
87
                        mesh->materials.push_back(Material());
87
                        mesh->materials.push_back(Material());
88
                        material_file >> mesh->materials[nummaterials].name;
88
                        material_file >> mesh->materials[nummaterials].name;
89
                        break;
89
                        break;
90
                    case 'N':
90
                    case 'N':
91
                        switch(buf[1])
91
                        switch(buf[1])
92
                    {
92
                    {
93
                        case 's':
93
                        case 's':
94
                            material_file >> mesh->materials[nummaterials].shininess;
94
                            material_file >> mesh->materials[nummaterials].shininess;
95
                            mesh->materials[nummaterials].shininess *= 128.0/1000.0;
95
                            mesh->materials[nummaterials].shininess *= 128.0/1000.0;
96
                            break;
96
                            break;
97
                        case 'i':
97
                        case 'i':
98
                            material_file >> mesh->materials[nummaterials].ior_in;
98
                            material_file >> mesh->materials[nummaterials].ior_in;
99
                            break;
99
                            break;
100
                    }
100
                    }
101
                        break;
101
                        break;
102
                    case 'K':
102
                    case 'K':
103
                        switch(buf[1])
103
                        switch(buf[1])
104
					{
104
					{
105
                        case 'd':
105
                        case 'd':
106
                            material_file >> mesh->materials[nummaterials].diffuse;
106
                            material_file >> mesh->materials[nummaterials].diffuse;
107
                            break;
107
                            break;
108
                        case 's':
108
                        case 's':
109
                            material_file >> mesh->materials[nummaterials].specular;
109
                            material_file >> mesh->materials[nummaterials].specular;
110
                            break;
110
                            break;
111
                        case 'a':
111
                        case 'a':
112
                            material_file >> mesh->materials[nummaterials].ambient;
112
                            material_file >> mesh->materials[nummaterials].ambient;
113
                            break;
113
                            break;
114
					}
114
					}
115
                        break;
115
                        break;
116
                    case 'T':
116
                    case 'T':
117
                        material_file >> mesh->materials[nummaterials].transmission;
117
                        material_file >> mesh->materials[nummaterials].transmission;
118
                        break;
118
                        break;
119
                    case 'i':
119
                    case 'i':
120
                        material_file >> mesh->materials[nummaterials].illum;
120
                        material_file >> mesh->materials[nummaterials].illum;
121
                        break;
121
                        break;
122
                    case 'm': // Map ... all maps are treated equally.
122
                    case 'm': // Map ... all maps are treated equally.
123
                        material_file >> mesh->materials[nummaterials].tex_name;
123
                        material_file >> mesh->materials[nummaterials].tex_name;
124
                        mesh->materials[nummaterials].has_texture = true;
124
                        mesh->materials[nummaterials].has_texture = true;
125
                        mesh->materials[nummaterials].tex_path = pathname;
125
                        mesh->materials[nummaterials].tex_path = pathname;
126
                        break;
126
                        break;
127
                    case '#':
127
                    case '#':
128
                    default:
128
                    default:
129
                        material_file.ignore(1024, '\n');
129
                        material_file.ignore(1024, '\n');
130
                        break;
130
                        break;
131
                        
131
                        
132
                }
132
                }
133
            }
133
            }
134
        }
134
        }
135
    }
135
    }
136
    
136
    
137
    
137
    
138
	void TriMeshObjLoader::load(const std::string& filename)
138
	void TriMeshObjLoader::load(const std::string& filename)
139
	{
139
	{
140
		pathname = get_path(filename);
140
		pathname = get_path(filename);
141
        ifstream obj_file(filename.data());
141
        ifstream obj_file(filename.data());
142
        if(obj_file)
142
        if(obj_file)
143
        {
143
        {
144
            mesh->materials.resize(1);
144
            mesh->materials.resize(1);
145
            string buf;
145
            string buf;
146
            int current_material=0;
146
            int current_material=0;
147
            while(obj_file >> buf)
147
            while(obj_file >> buf)
148
            {
148
            {
149
                cout << buf[0] << endl;
149
                cout << buf[0] << endl;
150
                switch(buf[0])
150
                switch(buf[0])
151
                {
151
                {
152
                    case 'v': // v, vn, vt
152
                    case 'v': // v, vn, vt
153
                    {
153
                    {
154
                        if(buf == "v")
154
                        if(buf == "v")
155
                        {
155
                        {
156
                            Vec3f v_geo;
156
                            Vec3f v_geo;
157
                            obj_file >> v_geo;
157
                            obj_file >> v_geo;
158
                            mesh->geometry.add_vertex(v_geo);
158
                            mesh->geometry.add_vertex(v_geo);
159
                        }
159
                        }
160
                        else if(buf == "vn")
160
                        else if(buf == "vn")
161
                        {
161
                        {
162
                            Vec3f v_norm;
162
                            Vec3f v_norm;
163
                            obj_file >> v_norm;
163
                            obj_file >> v_norm;
164
                            mesh->normals.add_vertex(v_norm);
164
                            mesh->normals.add_vertex(v_norm);
165
                        }
165
                        }
166
                        else if(buf == "vt")
166
                        else if(buf == "vt")
167
                        {
167
                        {
168
                            Vec3f v_tex;
168
                            Vec3f v_tex;
169
                            obj_file >> v_tex[0] >> v_tex[1];
169
                            obj_file >> v_tex[0] >> v_tex[1];
170
                            v_tex[2]=1;
170
                            v_tex[2]=1;
171
                            mesh->texcoords.add_vertex(v_tex);
171
                            mesh->texcoords.add_vertex(v_tex);
172
                        }
172
                        }
173
                    }
173
                    }
174
                        break;
174
                        break;
175
                    case 'f':
175
                    case 'f':
176
                    {
176
                    {
177
                        char line[1024];
177
                        char line[1024];
178
                        
178
                        
179
                        vector<int> v_indices;
179
                        vector<int> v_indices;
180
                        vector<int> t_indices;
180
                        vector<int> t_indices;
181
                        vector<int> n_indices;
181
                        vector<int> n_indices;
182
                        
182
                        
183
                        obj_file.getline(line, 1022);
183
                        obj_file.getline(line, 1022);
184
                        char* pch = strtok(line, " \t");
184
                        char* pch = strtok(line, " \t");
185
                        while(pch != 0)
185
                        while(pch != 0)
186
                        {
186
                        {
187
                            int v,t,n;
187
                            int v,t,n;
188
                            if(sscanf(pch, "%d/%d/%d", &v, &t, &n)==3)
188
                            if(sscanf(pch, "%d/%d/%d", &v, &t, &n)==3)
189
                            {
189
                            {
190
                                v_indices.push_back(get_vert(v));
190
                                v_indices.push_back(get_vert(v));
191
                                t_indices.push_back(get_texcoord(t));
191
                                t_indices.push_back(get_texcoord(t));
192
                                n_indices.push_back(get_normal(n));
192
                                n_indices.push_back(get_normal(n));
193
                            }
193
                            }
194
                            else if(sscanf(pch, "%d//%d", &v, &n)==2)
194
                            else if(sscanf(pch, "%d//%d", &v, &n)==2)
195
                            {
195
                            {
196
                                v_indices.push_back(get_vert(v));
196
                                v_indices.push_back(get_vert(v));
197
                                n_indices.push_back(get_normal(n));
197
                                n_indices.push_back(get_normal(n));
198
                            }
198
                            }
199
                            else if(sscanf(pch, "%d/%d", &v, &t)==2)
199
                            else if(sscanf(pch, "%d/%d", &v, &t)==2)
200
                            {
200
                            {
201
                                v_indices.push_back(get_vert(v));
201
                                v_indices.push_back(get_vert(v));
202
                                t_indices.push_back(get_texcoord(t));
202
                                t_indices.push_back(get_texcoord(t));
203
                            }
203
                            }
204
                            else if(sscanf(pch, "%d", &v)==1)
204
                            else if(sscanf(pch, "%d", &v)==1)
205
                                v_indices.push_back(get_vert(v));
205
                                v_indices.push_back(get_vert(v));
206
                            pch = strtok(0, " \t");
206
                            pch = strtok(0, " \t");
207
                        }
207
                        }
208
                        if(v_indices.size()>=3)
208
                        if(v_indices.size()>=3)
209
                            for(int i=0;i<=(v_indices.size()-3);++i)
209
                            for(int i=0;i<=(v_indices.size()-3);++i)
210
                            {
210
                            {
211
                                int idx = mesh->geometry.add_face(Vec3i(v_indices[0], v_indices[i+1], v_indices[i+2]));
211
                                int idx = mesh->geometry.add_face(Vec3i(v_indices[0], v_indices[i+1], v_indices[i+2]));
212
                                if(t_indices.size())
212
                                if(t_indices.size())
213
                                    mesh->texcoords.add_face(Vec3i(t_indices[0], t_indices[i+1], t_indices[i+2]), idx);
213
                                    mesh->texcoords.add_face(Vec3i(t_indices[0], t_indices[i+1], t_indices[i+2]), idx);
214
                                if(n_indices.size())
214
                                if(n_indices.size())
215
                                    mesh->normals.add_face(Vec3i(n_indices[0], n_indices[i+1], n_indices[i+2]), idx);
215
                                    mesh->normals.add_face(Vec3i(n_indices[0], n_indices[i+1], n_indices[i+2]), idx);
216
                                mesh->mat_idx.push_back(current_material);
216
                                mesh->mat_idx.push_back(current_material);
217
                            }
217
                            }
218
                    }
218
                    }
219
                        break;
219
                        break;
220
                    case 'm':
220
                    case 'm':
221
                        obj_file >> buf;
221
                        obj_file >> buf;
222
                        read_material_library(buf);
222
                        read_material_library(buf);
223
                        break;
223
                        break;
224
                    case 'u':
224
                    case 'u':
225
                        obj_file >> buf;
225
                        obj_file >> buf;
226
                        current_material = mesh->find_material(buf);
226
                        current_material = mesh->find_material(buf);
227
                        break;
227
                        break;
228
                    case '#':
228
                    case '#':
229
                    default:
229
                    default:
230
                        obj_file.ignore(1024, '\n');
230
                        obj_file.ignore(1024, '\n');
231
                        break;
231
                        break;
232
                        
232
                        
233
                }
233
                }
234
            }
234
            }
235
        }
235
        }
236
    }
236
    }
237
    
237
    
238
	void obj_load(const string& filename, TriMesh &mesh)
238
	void obj_load(const string& filename, TriMesh &mesh)
239
	{
239
	{
240
		TriMeshObjLoader loader(&mesh);
240
		TriMeshObjLoader loader(&mesh);
241
		loader.load(filename);
241
		loader.load(filename);
242
	}
242
	}
243
    
243
    
244
    /// Load materials from an MRL file
244
    /// Load materials from an MRL file
245
    void mtl_load(const std::string& filename, std::vector<Material>& materials)
245
    void mtl_load(const std::string& filename, std::vector<Material>& materials)
246
    {
246
    {
247
        TriMesh m;
247
        TriMesh m;
248
		TriMeshObjLoader loader(&m);
248
		TriMeshObjLoader loader(&m);
249
		loader.read_material_library(filename);
249
		loader.read_material_library(filename);
250
        materials = m.materials;
250
        materials = m.materials;
251
    }
251
    }
252
    
252
    
253
    
253
    
254
}
254
}
255
 
255