exportPov.h 9.78 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, const FunctorSelect& good = allDarts)
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
		if(good(d))
50
		{
51
			unsigned int nb = map.faceDegree(d);
Pierre Kraemer's avatar
Pierre Kraemer committed
52

53
			if(nb == 3)
54
				exportTrianglePlain<PFP>(out,position[d],position[map.phi1(d)],position[map.phi1(map.phi1(d))]);
55 56
			else
			{
Thomas's avatar
Thomas committed
57
					out << "polygon{ " << nb+1 << std::endl;
58
					Dart dd = d;
59 60
					do
					{
61
						out << "<" << position[dd][0] << "," << position[dd][2] << "," << position[dd][1] << ">," << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
62
						dd = map.phi1(dd);
63
					} while(dd!=d);
64
					out << "<" << position[d][0] << "," << position[d][2] << "," << position[d][1] << ">" << std::endl;
Thomas's avatar
Thomas committed
65
					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
template <typename PFP>
74
void export3MeshPlainSmooth(std::ofstream& out, typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& position, const std::string& meshName, const FunctorSelect& good = allDarts)
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
{
	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) ;

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

		if(good(d) && !markF.isMarked(d) && map.phi3(d)==d)
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
108
			markF.markOrbit<FACE>(d) ;
109 110 111 112 113
			std::vector<unsigned int> fidx ;
			fidx.reserve(4) ;
			Dart dd = d ;
			do
			{
114
				unsigned int vNum = map.getEmbedding<VERTEX>(dd) ;
115 116 117
				if(!markV.isMarked(dd))
				{
					markV.mark(dd) ;
118
					VEC3 norm = Geometry::vertexBorderNormal<PFP>(map,dd,position);
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

					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
template <typename PFP>
172
void exportMeshWire(std::ofstream& out, typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& position, const std::string& meshName, const FunctorSelect& good = allDarts)
Pierre Kraemer's avatar
Pierre Kraemer committed
173
{
Thomas's avatar
Thomas committed
174
	out << "#declare " << meshName << "= union {" << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
175

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

178
	for(Dart d = travE.begin() ; d!= travE.end() ; d = travE.next())
179
	{
180
		if(good(d))
181
		{
182
			Dart dd = map.phi2(d);
Pierre Kraemer's avatar
Pierre Kraemer committed
183

184 185
			out << "cylinder{ " << std::endl;
			out << "<" << position[d][0] << "," << position[d][1] << "," << position[d][2] << ">," << std::endl;
186
			out << "<" << position[dd][0] << "," << position[dd][1] << "," << position[dd][2] << ">," << 0.5 << std::endl;
187
			out << "}" << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
188 189 190
		}
	}

Thomas's avatar
Thomas committed
191
	out << "}" << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
192 193 194
}

template <typename PFP>
195
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,const FunctorSelect& good = allDarts)
Pierre Kraemer's avatar
Pierre Kraemer committed
196 197
{
	std::ofstream out(filename.c_str(), std::ios::out);
198 199
	if (!out.good())
	{
200
		CGoGNerr << "(export) Unable to open file " << filename << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
201 202 203 204 205 206 207 208
		return false;
	}

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

	//define the camera position
Thomas's avatar
Thomas committed
209
	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
210
	//set a "infinite" plane 
Thomas's avatar
Thomas committed
211
// 	out << "plane { y, -1 pigment { color rgb 1 } }" << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
212
	//set a sky sphere
Thomas's avatar
Thomas committed
213 214
	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
215
	//put some lights
Thomas's avatar
Thomas committed
216 217
	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
218
	//set a high quality rendering
Thomas's avatar
Thomas committed
219 220 221
	out << "global_settings {" << std::endl;
	out << "radiosity {" << std::endl;
	out << "pretrace_start 0.08 pretrace_end 0.04" << std::endl;
222 223
	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
224

225
	exportMeshPlain<PFP>(out,map,position,"myMesh",good);
Pierre Kraemer's avatar
Pierre Kraemer committed
226

Thomas's avatar
Thomas committed
227 228 229 230
	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
231 232 233 234 235

	out.close();
	return true;
}

236
template <typename PFP>
237
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,const FunctorSelect& good = allDarts)
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 266 267 268
{
	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;

269
	export3MeshPlainSmooth<PFP>(out,map,position,"myMesh",good);
270 271 272 273 274 275 276 277 278 279 280

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

281
} // namespace ExportPov
Pierre Kraemer's avatar
Pierre Kraemer committed
282

283 284
}

285
} // namespace Algo
Pierre Kraemer's avatar
Pierre Kraemer committed
286

287
} // namespace CGoGN
Pierre Kraemer's avatar
Pierre Kraemer committed
288

untereiner's avatar
untereiner committed
289
#endif