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 ¶m, 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