exportPov.h 9.5 KB
Newer Older
Pierre Kraemer's avatar
Pierre Kraemer committed
1
#ifndef EXPORT_POV_H
2
#define EXPORT_POV_H
Pierre Kraemer's avatar
Pierre Kraemer committed
3
4

#include "Topology/generic/attributeHandler.h"
5
#include "Utils/cgognStream.h"
6
#include "Algo/Geometry/normal.h"
Pierre Kraemer's avatar
Pierre Kraemer committed
7
8
9
10
11
12
13

namespace CGoGN
{

namespace Algo
{

14
15
16
namespace Surface
{

Pierre Kraemer's avatar
Pierre Kraemer committed
17
18
19
20
namespace ExportPov
{

template <typename PFP>
21
void exportTriangleWire(std::ofstream& out,typename PFP::VEC3& p1,typename PFP::VEC3& p2,typename PFP::VEC3& p3, float width)
Pierre Kraemer's avatar
Pierre Kraemer committed
22
{
23
		out << "cylinder { <" << p1[0] << "," << p1[1] << "," << p1[2] << ">, <" << p2[0] << "," << p2[1] << "," << p2[2] << ">, " << width << "}" << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
24

25
		out << "cylinder { <" << p1[0] << "," << p1[1] << "," << p1[2] << ">, <" << p3[0] << "," << p3[1] << "," << p3[2] << ">, " << width << "}" << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
26

27
		out << "cylinder { <" << p3[0] << "," << p3[1] << "," << p3[2] << ">, <" << p2[0] << "," << p2[1] << "," << p2[2] << ">, " << width << "}" << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
28
29
30
31
32
}

template <typename PFP>
void exportTrianglePlain(std::ofstream& out,typename PFP::VEC3& p1,typename PFP::VEC3& p2,typename PFP::VEC3& p3)
{
Thomas's avatar
Thomas committed
33
34
35
36
37
		out << "triangle {" << std::endl;
		out << "<" << p1[0] << "," << p1[2] << "," << p1[1] << ">," << std::endl;
		out << "<" << p2[0] << "," << p2[2] << "," << p2[1] << ">, " << std::endl;
		out << "<" << p3[0] << "," << p3[2] << "," << p3[1] << "> " << std::endl;
		out << "}" << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
38
39
40
}

template <typename PFP>
41
void exportMeshPlain(std::ofstream& out, typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& position, const std::string& meshName)
Pierre Kraemer's avatar
Pierre Kraemer committed
42
{
Thomas's avatar
Thomas committed
43
	out << "#declare " << meshName << "= union {" << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
44

45
	TraversorF<typename PFP::MAP > travF(map);
Pierre Kraemer's avatar
Pierre Kraemer committed
46

47
	for(Dart d = travF.begin() ; d!= travF.end() ; d = travF.next())
48
	{
49
50
51
		unsigned int nb = map.faceDegree(d);

		if(nb == 3)
Sylvain Thery's avatar
Sylvain Thery committed
52
			exportTrianglePlain<PFP>(out,position[d],position[map.phi1(d)],position[map.phi1(map.phi1(d))]);
53
54
55
56
57
		else
		{
			out << "polygon{ " << nb+1 << std::endl;
			Dart dd = d;
			do
58
			{
59
60
61
62
63
				out << "<" << position[dd][0] << "," << position[dd][2] << "," << position[dd][1] << ">," << std::endl;
				dd = map.phi1(dd);
			} while(dd!=d);
			out << "<" << position[d][0] << "," << position[d][2] << "," << position[d][1] << ">" << std::endl;
			out << "}" << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
64
		}
65

Pierre Kraemer's avatar
Pierre Kraemer committed
66
67
	}

Thomas's avatar
Thomas committed
68
	out << "}" << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
69
70
}

71
template <typename PFP>
72
void export3MeshPlainSmooth(std::ofstream& out, typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& position, const std::string& meshName)
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
{
	typedef typename PFP::VEC3 VEC3;

	out << "#declare " << meshName << "= mesh2 {" << std::endl;

	unsigned int nbDarts = map.getNbDarts() ;

	//vector containing the degree of faces
	std::vector<unsigned int> facesSize ;
	//vector containing the list of index of vertices
	std::vector<std::vector<unsigned int> > facesIdx ;
	facesSize.reserve(nbDarts/3) ;
	facesIdx.reserve(nbDarts/3) ;

	//map : attribute place / index in declaration (for vertices and normals)
	std::map<unsigned int, unsigned int> vIndex ;
	//index : start from 0 and increase (used to ignore the gaps potentially present in the container)
	unsigned int vCpt = 0 ;

	//remember the attribute lines
	std::vector<unsigned int> vertices ;

	std::vector<VEC3> normals ;
	vertices.reserve(nbDarts/6) ;
	normals.reserve(nbDarts/6) ;

99
	CellMarker<VERTEX> markV(map) ;
100
101
102
103
	DartMarker markF(map) ;
	for(Dart d = map.begin(); d != map.end(); map.next(d))
	{

104
		if(!markF.isMarked(d) && map.phi3(d)==d)
105
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
106
			markF.markOrbit<FACE>(d) ;
107
108
109
110
111
			std::vector<unsigned int> fidx ;
			fidx.reserve(4) ;
			Dart dd = d ;
			do
			{
112
				unsigned int vNum = map.getEmbedding<VERTEX>(dd) ;
113
114
115
				if(!markV.isMarked(dd))
				{
					markV.mark(dd) ;
116
					VEC3 norm = Geometry::vertexBorderNormal<PFP>(map,dd,position);
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168

					vIndex[vNum] = vCpt++ ;
					vertices.push_back(vNum) ;

					normals.push_back(norm) ;
				}

				fidx.push_back(vIndex[vNum]) ;

				dd = map.phi1(dd) ;
			} while(dd != d) ;

			facesSize.push_back(map.faceDegree(d)) ;
			facesIdx.push_back(fidx) ;
		}
	}

	//export all vertices
	out << "vertex_vectors {" << std::endl;
	out << vertices.size() << "," << std::endl;
	for(unsigned int i = 0; i < vertices.size(); ++i)
	{
		const VEC3& v = position[vertices[i]] ;
		out << "<" << v[0] << ", " << v[1] << ", " << v[2] << ">"<< std::endl ;
	}
	out << "}" << std::endl;

	//export all normals
	out << "normal_vectors {" << std::endl;
	out << normals.size() << "," << std::endl;
	for(unsigned int i = 0; i < normals.size(); ++i)
	{
		const VEC3& v = normals[i];
		out << "<" << v[0] << ", " << v[1] << ", " << v[2] << ">"<< std::endl ;
	}
	out << "}" << std::endl;

	//export all faces
	out << "face_indices {" << std::endl;
	out << facesSize.size() << "," << std::endl;
	for(unsigned int i = 0; i < facesSize.size(); ++i)
	{
		out << "<" << facesIdx[i][0];
		for(unsigned int j = 1; j < facesIdx[i].size(); ++j)
			out << ", " << facesIdx[i][j] ;
		out << ">" << std::endl ;
	}
	out << "}" << std::endl;

	out << "}" << std::endl;
}

Pierre Kraemer's avatar
Pierre Kraemer committed
169
template <typename PFP>
170
void exportMeshWire(std::ofstream& out, typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& position, const std::string& meshName)
Pierre Kraemer's avatar
Pierre Kraemer committed
171
{
Thomas's avatar
Thomas committed
172
	out << "#declare " << meshName << "= union {" << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
173

174
	TraversorE<typename PFP::MAP > travE(map);
Pierre Kraemer's avatar
Pierre Kraemer committed
175

176
	for(Dart d = travE.begin() ; d!= travE.end() ; d = travE.next())
177
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
178

179
180
181
182
183
184
185
		Dart dd = map.phi2(d);

		out << "cylinder{ " << std::endl;
		out << "<" << position[d][0] << "," << position[d][1] << "," << position[d][2] << ">," << std::endl;
		out << "<" << position[dd][0] << "," << position[dd][1] << "," << position[dd][2] << ">," << 0.5 << std::endl;
		out << "}" << std::endl;

Pierre Kraemer's avatar
Pierre Kraemer committed
186
187
	}

Thomas's avatar
Thomas committed
188
	out << "}" << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
189
190
191
}

template <typename PFP>
192
bool exportScenePov(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& position, const std::string& filename, typename PFP::VEC3 cameraPos, typename PFP::VEC3 cameraLook, typename PFP::VEC3 translate, float angle_X, float angle_Y, float angle_Z)
Pierre Kraemer's avatar
Pierre Kraemer committed
193
194
{
	std::ofstream out(filename.c_str(), std::ios::out);
195
196
	if (!out.good())
	{
197
		CGoGNerr << "(export) Unable to open file " << filename << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
198
199
200
201
202
203
204
205
		return false;
	}

	float angleX = angle_X;
	float angleY = angle_Y;
	float angleZ = angle_Z;

	//define the camera position
Thomas's avatar
Thomas committed
206
	out << "camera { location <" << cameraPos[0] << "," << cameraPos[1] << "," << cameraPos[2] << "> look_at <" << cameraLook[0] << "," << cameraLook[1] << "," << cameraLook[2] <<">}" << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
207
	//set a "infinite" plane 
Thomas's avatar
Thomas committed
208
// 	out << "plane { y, -1 pigment { color rgb 1 } }" << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
209
	//set a sky sphere
Thomas's avatar
Thomas committed
210
211
	out << "sphere { <0, 0, 0>, 5000";
	out << "texture{ pigment { color rgb <1, 1, 1>}	finish { ambient 1 diffuse 0 } } }" << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
212
	//put some lights
Thomas's avatar
Thomas committed
213
214
	out << "light_source { <" << cameraPos[0] << "," << cameraPos[1] << "," << cameraPos[2] << "> color rgb 0.45}" << std::endl;
// 	out << "light_source { <-120, -300, -10> color rgb 0.25 }"<< std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
215
	//set a high quality rendering
Thomas's avatar
Thomas committed
216
217
218
	out << "global_settings {" << std::endl;
	out << "radiosity {" << std::endl;
	out << "pretrace_start 0.08 pretrace_end 0.04" << std::endl;
219
220
	out << "count 100 nearest_count 10 error_bound 0.15 recursion_limit 1 low_error_factor 0.2 gray_threshold 0.0 minimum_reuse 0.015 brightness 1 adc_bailout 0.01/2 normal off media off}" << std::endl;
	out << "max_trace_level 255}" << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
221

Sylvain Thery's avatar
Sylvain Thery committed
222
	exportMeshPlain<PFP>(out,map,position,"myMesh");
Pierre Kraemer's avatar
Pierre Kraemer committed
223

Thomas's avatar
Thomas committed
224
225
226
227
	out << "object {myMesh" << std::endl;
 	out << "translate <" << translate[0] << "," << translate[1] << "," << translate[2] << ">" << std::endl;
 	out << "rotate <" << angleX << "," << angleY << "," << angleZ << "> " << std::endl;
 	out << "texture{ pigment{ color rgb<1.0,1.0,1>} finish { ambient rgb 0.05 brilliance 0.5 } } }" << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
228
229
230
231
232

	out.close();
	return true;
}

233
template <typename PFP>
234
bool exportScenePovSmooth(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& position, const std::string& filename, typename PFP::VEC3 cameraPos, typename PFP::VEC3 cameraLook, typename PFP::VEC3 translate, float angle_X, float angle_Y, float angle_Z)
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
{
	std::ofstream out(filename.c_str(), std::ios::out);
	if (!out.good()) {
		CGoGNerr << "(export) Unable to open file " << filename << CGoGNendl;
		return false;
	}

	float angleX = angle_X;
	float angleY = angle_Y;
	float angleZ = angle_Z;

	//define the camera position
	out << "camera { location <" << cameraPos[0] << "," << cameraPos[1] << "," << cameraPos[2] << "> look_at <" << cameraLook[0] << "," << cameraLook[1] << "," << cameraLook[2] <<">}" << std::endl;

	//set a "infinite" plane
// 	out << "plane { y, -1 pigment { color rgb 1 } }" << std::endl;

	//set a sky sphere
	out << "sphere { <0, 0, 0>, 5000";
	out << "texture{ pigment { color rgb <1, 1, 1>}	finish { ambient 1 diffuse 0 } } }" << std::endl;

	//put some lights
	out << "light_source { <" << cameraPos[0] << "," << cameraPos[1] << "," << cameraPos[2] << "> color rgb 0.45}" << std::endl;

	//set a high quality rendering
	out << "global_settings {" << std::endl;
//	out << "radiosity {" << std::endl;
//	out << "pretrace_start 0.08 pretrace_end 0.04" << std::endl;
//	out << "count 300 nearest_count 10 error_bound 0.15 recursion_limit 1 low_error_factor 0.2 gray_threshold 0.0 minimum_reuse 0.015 brightness 1 adc_bailout 0.01/2 normal off media off}" << std::endl;
	out << "max_trace_level 60}" << std::endl;

Sylvain Thery's avatar
Sylvain Thery committed
266
	export3MeshPlainSmooth<PFP>(out,map,position,"myMesh");
267
268
269
270
271
272
273
274
275
276
277

	out << "object {myMesh" << std::endl;
 	out << "translate <" << translate[0] << "," << translate[1] << "," << translate[2] << ">" << std::endl;
 	out << "rotate <" << angleX << "," << angleY << "," << angleZ << "> " << std::endl;
 	out << "double_illuminate" << std::endl;
 	out << "texture{ pigment{ color rgb <0.5,1.0,0.5>} finish { ambient 0.5 roughness 0.2 } } }" << std::endl;

	out.close();
	return true;
}

278
} // namespace ExportPov
Pierre Kraemer's avatar
Pierre Kraemer committed
279

280
281
}

282
} // namespace Algo
Pierre Kraemer's avatar
Pierre Kraemer committed
283

284
} // namespace CGoGN
Pierre Kraemer's avatar
Pierre Kraemer committed
285

untereiner's avatar
untereiner committed
286
#endif