1 
2 #include <interface/xmlinterface.h>
3 #include <core_api/logging.h>
4 #include <core_api/environment.h>
5 #include <core_api/scene.h>
6 #include <core_api/params.h>
7 
8 __BEGIN_YAFRAY
9 
xmlInterface_t()10 xmlInterface_t::xmlInterface_t(): last_mat(nullptr), nextObj(0), XMLGamma(1.f), XMLColorSpace(RAW_MANUAL_GAMMA)
11 {
12 	xmlName = "yafaray.xml";
13 }
14 
15 // xml environment doesn't need any plugins...
loadPlugins(const char * path)16 void xmlInterface_t::loadPlugins(const char *path) { }
17 
18 
clearAll()19 void xmlInterface_t::clearAll()
20 {
21 	Y_VERBOSE << "XMLInterface: cleaning up..." << yendl;
22 	env->clearAll();
23 	materials.clear();
24 	if(xmlFile.is_open())
25 	{
26 		xmlFile.flush();
27 		xmlFile.close();
28 	}
29 	params->clear();
30 	eparams->clear();
31 	cparams = params;
32 	nmat = 0;
33 	nextObj = 0;
34 }
35 
startScene(int type)36 bool xmlInterface_t::startScene(int type)
37 {
38 	xmlFile.open(xmlName.c_str());
39 	if(!xmlFile.is_open())
40 	{
41 		Y_ERROR << "XMLInterface: Couldn't open " << xmlName << yendl;
42 		return false;
43 	}
44 	else Y_INFO << "XMLInterface: Writing scene to: " << xmlName << yendl;
45 	xmlFile << std::boolalpha;
46 	xmlFile << "<?xml version=\"1.0\"?>" << yendl;
47 	xmlFile << "<scene type=\"";
48 	if(type==0) xmlFile << "triangle";
49 	else 		xmlFile << "universal";
50 	xmlFile << "\">" << yendl;
51 	return true;
52 }
53 
setLoggingAndBadgeSettings()54 bool xmlInterface_t::setLoggingAndBadgeSettings()
55 {
56 	xmlFile << "\n<logging_badge name=\"logging_badge\">\n";
57 	writeParamMap(*params);
58 	params->clear();
59 	xmlFile << "</logging_badge>\n";
60 	return true;
61 }
62 
setupRenderPasses()63 bool xmlInterface_t::setupRenderPasses()
64 {
65 	xmlFile << "\n<render_passes name=\"render_passes\">\n";
66 	writeParamMap(*params);
67 	params->clear();
68 	xmlFile << "</render_passes>\n";
69 	return true;
70 }
71 
setOutfile(const char * fname)72 void xmlInterface_t::setOutfile(const char *fname)
73 {
74 	xmlName = std::string(fname);
75 }
76 
startGeometry()77 bool xmlInterface_t::startGeometry() { return true; }
78 
endGeometry()79 bool xmlInterface_t::endGeometry() { return true; }
80 
getNextFreeID()81 unsigned int xmlInterface_t::getNextFreeID() {
82 	return ++nextObj;
83 }
84 
85 
startTriMesh(unsigned int id,int vertices,int triangles,bool hasOrco,bool hasUV,int type,int obj_pass_index)86 bool xmlInterface_t::startTriMesh(unsigned int id, int vertices, int triangles, bool hasOrco, bool hasUV, int type, int obj_pass_index)
87 {
88 	last_mat = nullptr;
89 	n_uvs = 0;
90 	xmlFile << "\n<mesh id=\"" << id << "\" vertices=\"" << vertices << "\" faces=\"" << triangles
91 			<< "\" has_orco=\"" << hasOrco << "\" has_uv=\"" << hasUV << "\" type=\"" << type << "\" obj_pass_index=\"" << obj_pass_index << "\">\n";
92 	return true;
93 }
94 
startCurveMesh(unsigned int id,int vertices,int obj_pass_index)95 bool xmlInterface_t::startCurveMesh(unsigned int id, int vertices, int obj_pass_index)
96 {
97 	xmlFile << "\n<curve id=\"" << id << "\" vertices=\"" << vertices << "\" obj_pass_index=\"" << obj_pass_index << "\">\n";
98 	return true;
99 }
100 
startTriMeshPtr(unsigned int * id,int vertices,int triangles,bool hasOrco,bool hasUV,int type,int obj_pass_index)101 bool xmlInterface_t::startTriMeshPtr(unsigned int *id, int vertices, int triangles, bool hasOrco, bool hasUV, int type, int obj_pass_index)
102 {
103 	*id = ++nextObj;
104 	last_mat = nullptr;
105 	n_uvs = 0;
106 	xmlFile << "\n<mesh vertices=\"" << vertices << "\" faces=\"" << triangles
107 			<< "\" has_orco=\"" << hasOrco << "\" has_uv=\"" << hasUV << "\" type=\"" << type << "\" obj_pass_index=\"" << obj_pass_index << "\">\n";
108 	return true;
109 }
110 
endTriMesh()111 bool xmlInterface_t::endTriMesh()
112 {
113 	xmlFile << "</mesh>\n";
114 	return true;
115 }
116 
endCurveMesh(const material_t * mat,float strandStart,float strandEnd,float strandShape)117 bool xmlInterface_t::endCurveMesh(const material_t *mat, float strandStart, float strandEnd, float strandShape)
118 {
119 	auto i = materials.find(mat);
120 	if(i == materials.end()) return false;
121 	xmlFile << "\t\t\t<set_material sval=\"" << i->second << "\"/>\n"
122 			<< "\t\t\t<strand_start fval=\"" << strandStart << "\"/>\n"
123 			<< "\t\t\t<strand_end fval=\"" << strandEnd << "\"/>\n"
124 			<< "\t\t\t<strand_shape fval=\"" << strandShape << "\"/>\n"
125 			<< "</curve>\n";
126 	return true;
127 }
128 
addVertex(double x,double y,double z)129 int  xmlInterface_t::addVertex(double x, double y, double z)
130 {
131 	xmlFile << "\t\t\t<p x=\"" << x << "\" y=\"" << y << "\" z=\"" << z << "\"/>\n";
132 	return 0;
133 }
134 
addVertex(double x,double y,double z,double ox,double oy,double oz)135 int  xmlInterface_t::addVertex(double x, double y, double z, double ox, double oy, double oz)
136 {
137 	xmlFile << "\t\t\t<p x=\"" << x << "\" y=\"" << y << "\" z=\"" << z
138 			<< "\" ox=\"" << ox << "\" oy=\"" << oy << "\" oz=\"" << oz << "\"/>\n";
139 	return 0;
140 }
141 
addNormal(double x,double y,double z)142 void xmlInterface_t::addNormal(double x, double y, double z)
143 {
144 	xmlFile << "\t\t\t<n x=\"" << x << "\" y=\"" << y << "\" z=\"" << z << "\"/>\n";
145 }
146 
addTriangle(int a,int b,int c,const material_t * mat)147 bool xmlInterface_t::addTriangle(int a, int b, int c, const material_t *mat)
148 {
149 	if(mat != last_mat) //need to set current material
150 	{
151 		auto i = materials.find(mat);
152 		if(i == materials.end()) return false;
153 		xmlFile << "\t\t\t<set_material sval=\"" << i->second << "\"/>\n";
154 		last_mat = mat;
155 	}
156 	xmlFile << "\t\t\t<f a=\"" << a << "\" b=\"" << b << "\" c=\"" << c << "\"/>\n";
157 	return true;
158 }
159 
addTriangle(int a,int b,int c,int uv_a,int uv_b,int uv_c,const material_t * mat)160 bool xmlInterface_t::addTriangle(int a, int b, int c, int uv_a, int uv_b, int uv_c, const material_t *mat)
161 {
162 	if(mat != last_mat) //need to set current material
163 	{
164 		auto i = materials.find(mat);
165 		if(i == materials.end()) return false;
166 		xmlFile << "\t\t\t<set_material sval=\"" << i->second << "\"/>\n";
167 		last_mat = mat;
168 	}
169 	xmlFile << "\t\t\t<f a=\"" << a << "\" b=\"" << b << "\" c=\"" << c
170 			<< "\" uv_a=\"" << uv_a << "\" uv_b=\"" << uv_b << "\" uv_c=\"" << uv_c << "\"/>\n";
171 	return true;
172 }
173 
addUV(float u,float v)174 int xmlInterface_t::addUV(float u, float v)
175 {
176 	xmlFile << "\t\t\t<uv u=\"" << u << "\" v=\"" << v << "\"/>\n";
177 	return n_uvs++;
178 }
179 
smoothMesh(unsigned int id,double angle)180 bool xmlInterface_t::smoothMesh(unsigned int id, double angle)
181 {
182 	xmlFile << "<smooth ID=\"" << id << "\" angle=\"" << angle << "\"/>\n";
183 	return true;
184 }
185 
writeParam(const std::string & name,const parameter_t & param,std::ofstream & xmlFile,colorSpaces_t XMLColorSpace,float XMLGamma)186 inline void writeParam(const std::string &name, const parameter_t &param, std::ofstream &xmlFile, colorSpaces_t XMLColorSpace, float XMLGamma)
187 {
188 	int i=0;
189 	bool b=false;
190 	double f=0.0;
191 	const std::string *s = nullptr;
192 	colorA_t c(0.f);
193 	point3d_t p(0.f);
194 	switch( param.type() )
195 	{
196 		case TYPE_INT:
197 			param.getVal(i);
198 			xmlFile << "<" << name << " ival=\"" << i << "\"/>\n"; break;
199 		case TYPE_BOOL:
200 			param.getVal(b);
201 			xmlFile << "<" << name << " bval=\"" << b << "\"/>\n"; break;
202 		case TYPE_FLOAT:
203 			param.getVal(f);
204 			xmlFile << "<" << name << " fval=\"" << f << "\"/>\n"; break;
205 		case TYPE_STRING:
206 			param.getVal(s);
207 			if(!s) break;
208 			xmlFile << "<" << name << " sval=\"" << *s << "\"/>\n"; break;
209 		case TYPE_POINT:
210 			param.getVal(p);
211 			xmlFile << "<" << name << " x=\"" << p.x << "\" y=\"" << p.y << "\" z=\"" << p.z << "\"/>\n"; break;
212 		case TYPE_COLOR:
213 			param.getVal(c);
214 			c.ColorSpace_from_linearRGB(XMLColorSpace, XMLGamma);	//Color values are encoded to the desired color space before saving them to the XML file
215 			xmlFile << "<" << name << " r=\"" << c.R << "\" g=\"" << c.G << "\" b=\"" << c.B << "\" a=\"" << c.A << "\"/>\n"; break;
216 		default:
217 			std::cerr << "unknown parameter type!\n";
218 	}
219 }
220 
writeMatrix(const std::string & name,const matrix4x4_t & m,std::ofstream & xmlFile)221 void writeMatrix(const std::string &name, const matrix4x4_t &m, std::ofstream &xmlFile)
222 {
223 	xmlFile << "<" << name << " m00=\"" << m[0][0] << "\" m01=\"" << m[0][1] << "\" m02=\"" << m[0][2]  << "\" m03=\"" << m[0][3] << "\""
224 						   << " m10=\"" << m[1][0] << "\" m11=\"" << m[1][1] << "\" m12=\"" << m[1][2]  << "\" m13=\"" << m[1][3] << "\""
225 						   << " m20=\"" << m[2][0] << "\" m21=\"" << m[2][1] << "\" m22=\"" << m[2][2]  << "\" m23=\"" << m[2][3] << "\""
226 						   << " m30=\"" << m[3][0] << "\" m31=\"" << m[3][1] << "\" m32=\"" << m[3][2]  << "\" m33=\"" << m[3][3] << "\"/>";
227 }
228 
addInstance(unsigned int baseObjectId,matrix4x4_t objToWorld)229 bool xmlInterface_t::addInstance(unsigned int baseObjectId, matrix4x4_t objToWorld)
230 {
231 	xmlFile << "\n<instance base_object_id=\"" << baseObjectId << "\" >\n\t";
232 	writeMatrix("transform",objToWorld,xmlFile);
233 	xmlFile << "\n</instance>\n";
234 	return true;
235 }
236 
writeParamMap(const paraMap_t & pmap,int indent)237 void xmlInterface_t::writeParamMap(const paraMap_t &pmap, int indent)
238 {
239 	std::string tabs(indent, '\t');
240 	const std::map< std::string, parameter_t > *dict = pmap.getDict();
241 	for(auto ip = dict->begin(); ip!= dict->end(); ++ip)
242 	{
243 		xmlFile << tabs;
244 		writeParam(ip->first, ip->second, xmlFile, XMLColorSpace, XMLGamma);
245 	}
246 	const std::map< std::string, matrix4x4_t > *mdict = pmap.getMDict();
247 	for(auto im = mdict->begin(); im!= mdict->end(); ++im)
248 	{
249 		xmlFile << tabs;
250 		writeMatrix(im->first, im->second, xmlFile);
251 	}
252 }
253 
writeParamList(int indent)254 void xmlInterface_t::writeParamList(int indent)
255 {
256 	std::string tabs(indent, '\t');
257 
258 	auto ip=eparams->begin();
259 	auto end=eparams->end();
260 
261 	for(; ip!= end; ++ip)
262 	{
263 		xmlFile << tabs << "<list_element>\n";
264 		writeParamMap(*ip, indent+1);
265 		xmlFile << tabs << "</list_element>\n";
266 	}
267 }
268 
createLight(const char * name)269 light_t* 		xmlInterface_t::createLight(const char* name)
270 {
271 	xmlFile << "\n<light name=\"" << name << "\">\n";
272 	writeParamMap(*params);
273 	xmlFile << "</light>\n";
274 	return nullptr;
275 }
276 
createTexture(const char * name)277 texture_t* 		xmlInterface_t::createTexture(const char* name)
278 {
279 	xmlFile << "\n<texture name=\"" << name << "\">\n";
280 	writeParamMap(*params);
281 	xmlFile << "</texture>\n";
282 	return nullptr;
283 }
284 
createMaterial(const char * name)285 material_t* 	xmlInterface_t::createMaterial(const char* name)
286 {
287 	material_t* matp = (material_t*)++nmat;
288 	materials[matp] = std::string(name);
289 	xmlFile << "\n<material name=\"" << name << "\">\n";
290 	writeParamMap(*params);
291 	writeParamList(1);
292 	xmlFile << "</material>\n";
293 	return matp;
294 }
createCamera(const char * name)295 camera_t* 		xmlInterface_t::createCamera(const char* name)
296 {
297 	xmlFile << "\n<camera name=\"" << name << "\">\n";
298 	writeParamMap(*params);
299 	xmlFile << "</camera>\n";
300 	return nullptr;
301 }
createBackground(const char * name)302 background_t* 	xmlInterface_t::createBackground(const char* name)
303 {
304 	xmlFile << "\n<background name=\"" << name << "\">\n";
305 	writeParamMap(*params);
306 	xmlFile << "</background>\n";
307 	return nullptr;
308 }
createIntegrator(const char * name)309 integrator_t* 	xmlInterface_t::createIntegrator(const char* name)
310 {
311 	xmlFile << "\n<integrator name=\"" << name << "\">\n";
312 	writeParamMap(*params);
313 	xmlFile << "</integrator>\n";
314 	return nullptr;
315 }
316 
createVolumeRegion(const char * name)317 VolumeRegion* 	xmlInterface_t::createVolumeRegion(const char* name)
318 {
319 	xmlFile << "\n<volumeregion name=\"" << name << "\">\n";
320 	writeParamMap(*params);
321 	xmlFile << "</volumeregion>\n";
322 	return nullptr;
323 }
324 
createObject(const char * name)325 unsigned int 	xmlInterface_t::createObject(const char* name)
326 {
327 	xmlFile << "\n<object name=\"" << name << "\">\n";
328 	writeParamMap(*params);
329 	xmlFile << "</object>\n";
330 	return ++nextObj;
331 }
332 
render(colorOutput_t & output,progressBar_t * pb)333 void xmlInterface_t::render(colorOutput_t &output, progressBar_t *pb)
334 {
335 	xmlFile << "\n<render>\n";
336 	writeParamMap(*params);
337 	xmlFile << "</render>\n";
338 	xmlFile << "</scene>" << yendl;
339 	xmlFile.flush();
340 	xmlFile.close();
341 }
342 
setXMLColorSpace(std::string color_space_string,float gammaVal)343 void xmlInterface_t::setXMLColorSpace(std::string color_space_string, float gammaVal)
344 {
345 	if(color_space_string == "sRGB") XMLColorSpace = SRGB;
346 	else if(color_space_string == "XYZ") XMLColorSpace = XYZ_D65;
347 	else if(color_space_string == "LinearRGB") XMLColorSpace = LINEAR_RGB;
348 	else if(color_space_string == "Raw_Manual_Gamma") XMLColorSpace = RAW_MANUAL_GAMMA;
349 	else XMLColorSpace = SRGB;
350 
351 	XMLGamma = gammaVal;
352 }
353 
354 extern "C"
355 {
getYafrayXML()356 	YAFRAYPLUGIN_EXPORT xmlInterface_t* getYafrayXML()
357 	{
358 		return new xmlInterface_t();
359 	}
360 }
361 
362 __END_YAFRAY
363