Coupure prévue mardi 3 Août au matin pour maintenance du serveur. Nous faisons au mieux pour que celle-ci soit la plus brève possible.

exportPov.h 10.2 KB
Newer Older
Pierre Kraemer's avatar
Pierre Kraemer committed
1
#ifndef EXPORT_POV_H
Thomas's avatar
Thomas committed
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
14
15
16
17
18
19

namespace CGoGN
{

namespace Algo
{

namespace ExportPov
{

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

Thomas's avatar
Thomas committed
22
		out << "cylinder { <" << p1[0] << "," << p1[2] << "," << p1[1] << ">, <" << p3[0] << "," << p3[2] << "," << p3[1] << ">, 0.5 }" << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
23

Thomas's avatar
Thomas committed
24
		out << "cylinder { <" << p3[0] << "," << p3[2] << "," << p3[1] << ">, <" << p2[0] << "," << p2[2] << "," << p2[1] << ">, 0.5 }" << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
25
26
27
28
29
}

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
30
31
32
33
34
		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
35
36
37
38
39
}

template <typename PFP>
void exportMeshPlain(std::ofstream& out, typename PFP::MAP& map, typename PFP::TVEC3& position, const std::string& meshName, const FunctorSelect& good = SelectorTrue())
{
Thomas's avatar
Thomas committed
40
	out << "#declare " << meshName << "= union {" << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
41
42
43
44
45
46
47
48

	DartMarkerStore traite(map);

	for(Dart d = map.begin() ; d!= map.end() ; map.next(d)) {
		if(good(d) && !traite.isMarked(d)) {
			unsigned int nb=0;
			Dart dd=d;
			do {
49
				traite.mark(dd);
Pierre Kraemer's avatar
Pierre Kraemer committed
50
51
52
53
54
55
56
57
				dd = map.phi1(dd);
				nb++;
			} while(dd!=d);

			if(nb==3) {
				Algo::ExportPov::exportTrianglePlain<PFP>(out,position[dd],position[map.phi1(dd)],position[map.phi1(map.phi1(dd))]);
			}
			else {
Thomas's avatar
Thomas committed
58
					out << "polygon{ " << nb+1 << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
59
60
					dd=d;
					do {
Thomas's avatar
Thomas committed
61
						out << "<" << position[dd][0] << "," << position[dd][2] << "," << position[dd][1] << ">," << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
62
63
						dd = map.phi1(dd);
					}while(dd!=d);
Thomas's avatar
Thomas committed
64
65
					out << "<" << position[d][0] << "," << position[d][2] << "," << position[d][1] << ">" << std::endl;
					out << "}" << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
66
67
68
69
			}
		}
	}

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

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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
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
169
170
template <typename PFP>
void export3MeshPlainSmooth(std::ofstream& out, typename PFP::MAP& map, typename PFP::TVEC3& position, const std::string& meshName, const FunctorSelect& good = SelectorTrue())
{
	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) ;

	CellMarker markV(map, VERTEX) ;
	DartMarker markF(map) ;
	for(Dart d = map.begin(); d != map.end(); map.next(d))
	{

		if(good(d) && !markF.isMarked(d) && map.phi3(d)==d)
		{
			markF.markOrbit(FACE, d) ;
			std::vector<unsigned int> fidx ;
			fidx.reserve(4) ;
			Dart dd = d ;
			do
			{
				unsigned int vNum = map.getEmbedding(VERTEX, dd) ;
				if(!markV.isMarked(dd))
				{
					markV.mark(dd) ;
					VEC3 norm = Algo::Geometry::vertexBorderNormal<PFP>(map,dd,position);

					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
171
172
173
template <typename PFP>
void exportMeshWire(std::ofstream& out, typename PFP::MAP& map, typename PFP::TVEC3& position, const std::string& meshName, const FunctorSelect& good = SelectorTrue())
{
Thomas's avatar
Thomas committed
174
	out << "#declare " << meshName << "= union {" << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
175
176
177
178
179
180
181
182

	DartMarkerStore traite(map);

	for(Dart d = map.begin() ; d!= map.end() ; map.next(d)) {
		if(good(d) && !traite.isMarked(d)) {
			unsigned int nb=0;
			Dart dd=d;
			do {
183
				traite.markOrbit(DART,dd);
Pierre Kraemer's avatar
Pierre Kraemer committed
184
185
186
187
188
189
190
191
192
193
194
				dd = map.phi1(dd);
				nb++;
			} while(dd!=d);

			if(nb==3) {
				Algo::ExportPov::exportTriangleWire<PFP>(out,position[dd],position[map.phi1(dd)],position[map.phi1(map.phi1(dd))]);
			}
			else {
					dd=d;
					do {
						if(position[dd][0]!=position[map.phi1(dd)][0] || position[dd][1]!=position[map.phi1(dd)][1] || position[dd][2]!=position[map.phi1(dd)][2]) {
Thomas's avatar
Thomas committed
195
196
197
198
							out << "cylinder{ " << std::endl;
							out << "<" << position[dd][0] << "," << position[dd][2] << "," << position[dd][1] << ">," << std::endl;
							out << "<" << position[map.phi1(dd)][0] << "," << position[map.phi1(dd)][2] << "," << position[map.phi1(dd)][1] << ">, 0.5" << std::endl;
							out << "}" << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
199
200
201
202
203
204
205
						}
						dd = map.phi1(dd);
					}while(dd!=d);
			}
		}
	}

Thomas's avatar
Thomas committed
206
	out << "}" << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
207
208
209
210
211
212
213
}

template <typename PFP>
bool exportScenePov(typename PFP::MAP& map, typename PFP::TVEC3& 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,const FunctorSelect& good = SelectorTrue())
{
	std::ofstream out(filename.c_str(), std::ios::out);
	if (!out.good()) {
214
		CGoGNerr << "(export) Unable to open file " << filename << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
215
216
217
218
219
220
221
222
		return false;
	}

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

	//define the camera position
Thomas's avatar
Thomas committed
223
	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
224
	//set a "infinite" plane 
Thomas's avatar
Thomas committed
225
// 	out << "plane { y, -1 pigment { color rgb 1 } }" << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
226
	//set a sky sphere
Thomas's avatar
Thomas committed
227
228
	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
229
	//put some lights
Thomas's avatar
Thomas committed
230
231
	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
232
	//set a high quality rendering
Thomas's avatar
Thomas committed
233
234
235
	out << "global_settings {" << std::endl;
	out << "radiosity {" << std::endl;
	out << "pretrace_start 0.08 pretrace_end 0.04" << std::endl;
236
237
	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
238
239
240

	Algo::ExportPov::exportMeshPlain<PFP>(out,map,position,"myMesh",good);

Thomas's avatar
Thomas committed
241
242
243
244
	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
245
246
247
248
249

	out.close();
	return true;
}

250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
template <typename PFP>
bool exportScenePovSmooth(typename PFP::MAP& map, typename PFP::TVEC3& 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,const FunctorSelect& good = SelectorTrue())
{
	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;

	Algo::ExportPov::export3MeshPlainSmooth<PFP>(out,map,position,"myMesh",good);

	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;
}

Pierre Kraemer's avatar
Pierre Kraemer committed
295
296
297
298
299
300
}

}

}

untereiner's avatar
untereiner committed
301
#endif