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