1 #if defined(SWIGRUBY)
2 %module yafaray_v3_interface_ruby
3 #else
4 %module yafaray_v3_interface
5 #endif
6
7 %include "cpointer.i"
8 %pointer_functions(float, floatp);
9 %pointer_functions(int, intp);
10 %pointer_functions(unsigned int, uintp);
11
12 %include "carrays.i"
13 %include "std_string.i"
14 %include "std_vector.i"
15
16 %array_functions(float, floatArray);
17
18 #ifdef SWIGPYTHON // Begining of python specific code
19
20 %{
21 #include <sstream>
22 #include <yafraycore/monitor.h>
23 #include <core_api/output.h>
24 #include <interface/yafrayinterface.h>
25 #include <core_api/renderpasses.h>
26
27 struct yafTilePixel_t
28 {
29 float r;
30 float g;
31 float b;
32 float a;
33 };
34
35 struct YafTileObject_t
36 {
37 PyObject_HEAD
38 int resx, resy;
39 int x0, x1, y0, y1;
40 int w, h;
41 yafTilePixel_t *mem;
42 int tileType; //RGBA (4), RGB (3) or Grayscale (1). Grayscale would use component "r" only for the grayscale value.
43 };
44
45
yaf_tile_length(YafTileObject_t * self)46 static Py_ssize_t yaf_tile_length(YafTileObject_t *self)
47 {
48 self->w = (self->x1 - self->x0);
49 self->h = (self->y1 - self->y0);
50
51 return self->w * self->h;
52 }
53
54
yaf_tile_subscript_int(YafTileObject_t * self,int keynum)55 static PyObject *yaf_tile_subscript_int(YafTileObject_t *self, int keynum)
56 {
57 // Check boundaries and fill w and h
58 if (keynum >= yaf_tile_length(self) || keynum < 0)
59 {
60 if(self->tileType == yafaray::PASS_EXT_TILE_1_GRAYSCALE)
61 {
62 PyObject* groupPix = PyTuple_New(1);
63 PyTuple_SET_ITEM(groupPix, 0, PyFloat_FromDouble(0.f));
64 return groupPix;
65 }
66 else if(self->tileType == yafaray::PASS_EXT_TILE_3_RGB)
67 {
68 PyObject* groupPix = PyTuple_New(3);
69 PyTuple_SET_ITEM(groupPix, 0, PyFloat_FromDouble(0.f));
70 PyTuple_SET_ITEM(groupPix, 1, PyFloat_FromDouble(0.f));
71 PyTuple_SET_ITEM(groupPix, 2, PyFloat_FromDouble(0.f));
72 return groupPix;
73 }
74 else
75 {
76 PyObject* groupPix = PyTuple_New(4);
77 PyTuple_SET_ITEM(groupPix, 0, PyFloat_FromDouble(0.f));
78 PyTuple_SET_ITEM(groupPix, 1, PyFloat_FromDouble(0.f));
79 PyTuple_SET_ITEM(groupPix, 2, PyFloat_FromDouble(0.f));
80 PyTuple_SET_ITEM(groupPix, 3, PyFloat_FromDouble(1.f));
81 return groupPix;
82 }
83 }
84
85 // Calc position of the tile in the image region
86 int vy = keynum / self->w;
87 int vx = keynum - vy * self->w;
88
89 // Map tile position to image buffer
90 vx = self->x0 + vx;
91 vy = (self->y0 + self->h - 1) - vy;
92
93 // Get pixel
94 yafTilePixel_t &pix = self->mem[ self->resx * vy + vx ];
95
96 if(self->tileType == yafaray::PASS_EXT_TILE_1_GRAYSCALE)
97 {
98 PyObject* groupPix = PyTuple_New(1);
99 PyTuple_SET_ITEM(groupPix, 0, PyFloat_FromDouble(pix.r));
100 return groupPix;
101 }
102 else if(self->tileType == yafaray::PASS_EXT_TILE_3_RGB)
103 {
104 PyObject* groupPix = PyTuple_New(3);
105 PyTuple_SET_ITEM(groupPix, 0, PyFloat_FromDouble(pix.r));
106 PyTuple_SET_ITEM(groupPix, 1, PyFloat_FromDouble(pix.g));
107 PyTuple_SET_ITEM(groupPix, 2, PyFloat_FromDouble(pix.b));
108 return groupPix;
109 }
110 else
111 {
112 PyObject* groupPix = PyTuple_New(4);
113 PyTuple_SET_ITEM(groupPix, 0, PyFloat_FromDouble(pix.r));
114 PyTuple_SET_ITEM(groupPix, 1, PyFloat_FromDouble(pix.g));
115 PyTuple_SET_ITEM(groupPix, 2, PyFloat_FromDouble(pix.b));
116 PyTuple_SET_ITEM(groupPix, 3, PyFloat_FromDouble(pix.a));
117 return groupPix;
118 }
119 }
120
yaf_tile_dealloc(YafTileObject_t * self)121 static void yaf_tile_dealloc(YafTileObject_t *self)
122 {
123 SWIG_PYTHON_THREAD_BEGIN_BLOCK;
124 PyObject_Del(self);
125 SWIG_PYTHON_THREAD_END_BLOCK;
126 }
127
128 PySequenceMethods sequence_methods =
129 {
130 ( lenfunc ) yaf_tile_length,
131 nullptr,
132 nullptr,
133 ( ssizeargfunc ) yaf_tile_subscript_int
134 };
135
136 PyTypeObject yafTile_Type =
137 {
138 PyVarObject_HEAD_INIT(nullptr, 0)
139 "yaf_tile", /* tp_name */
140 sizeof(YafTileObject_t), /* tp_basicsize */
141 0, /* tp_itemsize */
142 ( destructor ) yaf_tile_dealloc, /* tp_dealloc */
143 0, /* tp_print / tp_vectorcall_offset */
144 nullptr, /* getattrfunc tp_getattr; */
145 nullptr, /* setattrfunc tp_setattr; */
146 nullptr, /* tp_compare */ /* DEPRECATED in python 3.0! */
147 nullptr, /* tp_repr */
148 nullptr, /* PyNumberMethods *tp_as_number; */
149 &sequence_methods, /* PySequenceMethods *tp_as_sequence; */
150 nullptr, /* PyMappingMethods *tp_as_mapping; */
151 nullptr, /* hashfunc tp_hash; */
152 nullptr, /* ternaryfunc tp_call; */
153 nullptr, /* reprfunc tp_str; */
154 nullptr, /* getattrofunc tp_getattro; */
155 nullptr, /* setattrofunc tp_setattro; */
156 nullptr, /* PyBufferProcs *tp_as_buffer; */
157 Py_TPFLAGS_DEFAULT, /* long tp_flags; */
158 };
159
160
161 class pyOutput_t : public yafaray::colorOutput_t
162 {
163
164 public:
165
pyOutput_t(int x,int y,int borderStartX,int borderStartY,bool prev,PyObject * drawAreaCallback,PyObject * flushCallback)166 pyOutput_t(int x, int y, int borderStartX, int borderStartY, bool prev, PyObject *drawAreaCallback, PyObject *flushCallback) :
167 resx(x),
168 resy(y),
169 bsX(borderStartX),
170 bsY(borderStartY),
171 preview(prev),
172 mDrawArea(drawAreaCallback),
173 mFlush(flushCallback)
174 {
175 }
176
initTilesPasses(int totalViews,int numExtPasses)177 virtual void initTilesPasses(int totalViews, int numExtPasses)
178 {
179 SWIG_PYTHON_THREAD_BEGIN_BLOCK;
180 PyGILState_STATE gstate;
181 gstate = PyGILState_Ensure();
182
183 tilesPasses.resize(totalViews);
184
185 for(size_t view = 0; view < tilesPasses.size(); ++view)
186 {
187 for(int idx = 0; idx < numExtPasses; ++idx)
188 {
189 YafTileObject_t* tile = PyObject_New(YafTileObject_t, &yafTile_Type);
190 tilesPasses.at(view).push_back(tile);
191 tilesPasses.at(view)[idx]->mem = new yafTilePixel_t[resx*resy];
192 tilesPasses.at(view)[idx]->resx = resx;
193 tilesPasses.at(view)[idx]->resy = resy;
194 }
195 }
196
197 PyGILState_Release(gstate);
198 SWIG_PYTHON_THREAD_END_BLOCK;
199 }
200
~pyOutput_t()201 virtual ~pyOutput_t()
202 {
203 SWIG_PYTHON_THREAD_BEGIN_BLOCK;
204 PyGILState_STATE gstate;
205 gstate = PyGILState_Ensure();
206
207 for(size_t view = 0; view < tilesPasses.size(); ++view)
208 {
209 for(size_t idx = 0; idx < tilesPasses.at(view).size(); ++idx)
210 {
211 if(tilesPasses.at(view)[idx]->mem) delete [] tilesPasses.at(view)[idx]->mem;
212 //Py_XDECREF(tilesPasses.at(view)[idx]);
213 }
214 tilesPasses.at(view).clear();
215 }
216 tilesPasses.clear();
217
218 PyGILState_Release(gstate);
219 SWIG_PYTHON_THREAD_END_BLOCK;
220 }
221
222 virtual bool putPixel(int numView, int x, int y, const yafaray::renderPasses_t *renderPasses, int idx, const yafaray::colorA_t &color, bool alpha = true)
223 {
224 if(idx < (int) tilesPasses.at(numView).size())
225 {
226 yafTilePixel_t &pix= tilesPasses.at(numView)[idx]->mem[resx * y + x];
227 pix.r = color.R;
228 pix.g = color.G;
229 pix.b = color.B;
230 pix.a = (alpha || idx > 0) ? color.A : 1.0f;
231 }
232
233 return true;
234 }
235
236 virtual bool putPixel(int numView, int x, int y, const yafaray::renderPasses_t *renderPasses, const std::vector<yafaray::colorA_t> &colExtPasses, bool alpha = true)
237 {
238 for(size_t idx = 0; idx < tilesPasses.at(numView).size(); ++idx)
239 {
240 yafTilePixel_t &pix= tilesPasses.at(numView)[idx]->mem[resx * y + x];
241 pix.r = colExtPasses[idx].R;
242 pix.g = colExtPasses[idx].G;
243 pix.b = colExtPasses[idx].B;
244 pix.a = (alpha || idx > 0) ? colExtPasses[idx].A : 1.0f;
245 }
246
247 return true;
248 }
249
isPreview()250 virtual bool isPreview() { return preview; }
251
flush(int numView_unused,const yafaray::renderPasses_t * renderPasses)252 virtual void flush(int numView_unused, const yafaray::renderPasses_t *renderPasses)
253 {
254 SWIG_PYTHON_THREAD_BEGIN_BLOCK;
255 PyGILState_STATE gstate;
256 gstate = PyGILState_Ensure();
257
258 PyObject* groupTile = PyTuple_New(tilesPasses.size() * tilesPasses.at(0).size());
259
260 for(size_t view = 0; view < tilesPasses.size(); ++view)
261 {
262 std::string view_name = renderPasses->view_names.at(view);
263
264 for(size_t idx = 0; idx < tilesPasses.at(view).size(); ++idx)
265 {
266 tilesPasses.at(view)[idx]->x0 = 0;
267 tilesPasses.at(view)[idx]->x1 = resx;
268 tilesPasses.at(view)[idx]->y0 = 0;
269 tilesPasses.at(view)[idx]->y1 = resy;
270
271 tilesPasses.at(view)[idx]->tileType = renderPasses->tileType(idx);
272
273 std::stringstream extPassName;
274 extPassName << renderPasses->extPassTypeStringFromIndex(idx);
275 PyObject* groupItem = Py_BuildValue("ssO", view_name.c_str(), extPassName.str().c_str(), tilesPasses.at(view)[idx]);
276 PyTuple_SET_ITEM(groupTile, tilesPasses.at(view).size()*view + idx, (PyObject*) groupItem);
277
278 //std::cout << "flush: groupItem->ob_refcnt=" << groupItem->ob_refcnt << std::endl;
279 }
280 }
281 PyObject* result = PyObject_CallFunction(mFlush, "iiiO", resx, resy, 0, groupTile);
282
283 Py_XDECREF(result);
284 Py_XDECREF(groupTile);
285
286 //std::cout << "flush: result->ob_refcnt=" << result->ob_refcnt << std::endl;
287 //std::cout << "flush: groupTile->ob_refcnt=" << groupTile->ob_refcnt << std::endl;
288
289 PyGILState_Release(gstate);
290 SWIG_PYTHON_THREAD_END_BLOCK;
291 }
292
flushArea(int numView,int x0,int y0,int x1,int y1,const yafaray::renderPasses_t * renderPasses)293 virtual void flushArea(int numView, int x0, int y0, int x1, int y1, const yafaray::renderPasses_t *renderPasses)
294 {
295 SWIG_PYTHON_THREAD_BEGIN_BLOCK;
296 std::string view_name = renderPasses->view_names.at(numView);
297
298 // Do nothing if we are rendering preview renders
299 if(preview) return;
300
301 int w = x1 - x0;
302 int h = y1 - y0;
303
304 PyGILState_STATE gstate;
305 gstate = PyGILState_Ensure();
306
307 PyObject* groupTile = PyTuple_New(tilesPasses.at(numView).size());
308
309 for(size_t idx = 0; idx < tilesPasses.at(numView).size(); ++idx)
310 {
311 tilesPasses.at(numView)[idx]->x0 = x0 - bsX;
312 tilesPasses.at(numView)[idx]->x1 = x1 - bsX;
313 tilesPasses.at(numView)[idx]->y0 = y0 - bsY;
314 tilesPasses.at(numView)[idx]->y1 = y1 - bsY;
315
316 tilesPasses.at(numView)[idx]->tileType = renderPasses->tileType(idx);
317
318 std::stringstream extPassName;
319 extPassName << renderPasses->extPassTypeStringFromIndex(idx);
320 PyObject* groupItem = Py_BuildValue("ssO", view_name.c_str(), extPassName.str().c_str(), tilesPasses.at(numView)[idx]);
321 PyTuple_SET_ITEM(groupTile, idx, (PyObject*) groupItem);
322
323 //std::cout << "flushArea: groupItem->ob_refcnt=" << groupItem->ob_refcnt << std::endl;
324 }
325
326 PyObject* result = PyObject_CallFunction(mDrawArea, "iiiiiO", tilesPasses.at(numView)[0]->x0, resy - tilesPasses.at(numView)[0]->y1, w, h, numView, groupTile);
327
328 Py_XDECREF(result);
329 Py_XDECREF(groupTile);
330 //std::cout << "flushArea: result->ob_refcnt=" << result->ob_refcnt << std::endl;
331 //std::cout << "flushArea: groupTile->ob_refcnt=" << groupTile->ob_refcnt << std::endl;
332
333 PyGILState_Release(gstate);
334 SWIG_PYTHON_THREAD_END_BLOCK;
335 }
336
highliteArea(int numView,int x0,int y0,int x1,int y1)337 virtual void highliteArea(int numView, int x0, int y0, int x1, int y1)
338 {
339 SWIG_PYTHON_THREAD_BEGIN_BLOCK;
340 std::string view_name = "";
341
342 // Do nothing if we are rendering preview renders
343 if(preview) return;
344
345 tilesPasses.at(numView)[0]->x0 = x0 - bsX;
346 tilesPasses.at(numView)[0]->x1 = x1 - bsX;
347 tilesPasses.at(numView)[0]->y0 = y0 - bsY;
348 tilesPasses.at(numView)[0]->y1 = y1 - bsY;
349
350 int w = x1 - x0;
351 int h = y1 - y0;
352 int lineL = std::min( 4, std::min( h - 1, w - 1 ) );
353
354 drawCorner(numView, tilesPasses.at(numView)[0]->x0, tilesPasses.at(numView)[0]->y0, lineL, TL_CORNER);
355 drawCorner(numView, tilesPasses.at(numView)[0]->x1, tilesPasses.at(numView)[0]->y0, lineL, TR_CORNER);
356 drawCorner(numView, tilesPasses.at(numView)[0]->x0, tilesPasses.at(numView)[0]->y1, lineL, BL_CORNER);
357 drawCorner(numView, tilesPasses.at(numView)[0]->x1, tilesPasses.at(numView)[0]->y1, lineL, BR_CORNER);
358
359 PyGILState_STATE gstate;
360 gstate = PyGILState_Ensure();
361
362
363 PyObject* groupTile = PyTuple_New(1);
364
365 tilesPasses.at(numView)[0]->tileType = yafaray::PASS_EXT_TILE_4_RGBA;
366
367 PyObject* groupItem = Py_BuildValue("ssO", view_name.c_str(), "Combined", tilesPasses.at(numView)[0]);
368 PyTuple_SET_ITEM(groupTile, 0, (PyObject*) groupItem);
369
370 //std::cout << "highliteArea: groupItem->ob_refcnt=" << groupItem->ob_refcnt << std::endl;
371
372 PyObject* result = PyObject_CallFunction(mDrawArea, "iiiiiO", tilesPasses.at(numView)[0]->x0, resy - tilesPasses.at(numView)[0]->y1, w, h, numView, groupTile);
373
374 Py_XDECREF(result);
375 Py_XDECREF(groupTile);
376
377 //std::cout << "highliteArea: result->ob_refcnt=" << result->ob_refcnt << std::endl;
378 //std::cout << "highliteArea: groupTile->ob_refcnt=" << groupTile->ob_refcnt << std::endl;
379
380 PyGILState_Release(gstate);
381 SWIG_PYTHON_THREAD_END_BLOCK;
382 }
383
384 private:
385
386 enum corner
387 {
388 TL_CORNER,
389 TR_CORNER,
390 BL_CORNER,
391 BR_CORNER
392 };
393
drawCorner(int numView,int x,int y,int len,corner pos)394 void drawCorner(int numView, int x, int y, int len, corner pos)
395 {
396 int minX = 0;
397 int minY = 0;
398 int maxX = 0;
399 int maxY = 0;
400
401 switch(pos)
402 {
403 case TL_CORNER:
404 minX = x;
405 minY = y;
406 maxX = x + len;
407 maxY = y + len;
408 break;
409
410 case TR_CORNER:
411 minX = x - len - 1;
412 minY = y;
413 maxX = x - 1;
414 maxY = y + len;
415 --x;
416 break;
417
418 case BL_CORNER:
419 minX = x;
420 minY = y - len - 1;
421 maxX = x + len;
422 maxY = y - 1;
423 --y;
424 break;
425
426 case BR_CORNER:
427 minX = x - len - 1;
428 minY = y - len - 1;
429 maxX = x;
430 maxY = y - 1;
431 --x;
432 --y;
433 break;
434 }
435
436 for(int i = minX; i < maxX; ++i)
437 {
438 yafTilePixel_t &pix = tilesPasses.at(numView)[0]->mem[resx * y + i];
439 pix.r = 0.625f;
440 pix.g = 0.f;
441 pix.b = 0.f;
442 pix.a = 1.f;
443 }
444
445 for(int j = minY; j < maxY; ++j)
446 {
447 yafTilePixel_t &pix = tilesPasses.at(numView)[0]->mem[resx * j + x];
448 pix.r = 0.625f;
449 pix.g = 0.f;
450 pix.b = 0.f;
451 pix.a = 1.f;
452 }
453 }
454
455 int resx, resy;
456 int bsX, bsY;
457 bool preview;
458 PyObject *mDrawArea;
459 PyObject *mFlush;
460 std::vector< std::vector<YafTileObject_t*> > tilesPasses;
461 };
462
463 class pyProgress : public yafaray::progressBar_t
464 {
465
466 public:
467
pyProgress(PyObject * callback)468 pyProgress(PyObject *callback) : callb(callback) {}
469
report_progress(float percent)470 void report_progress(float percent)
471 {
472 PyGILState_STATE gstate;
473 gstate = PyGILState_Ensure();
474 PyObject* result = PyObject_CallFunction(callb, "sf", "progress", percent);
475 Py_XDECREF(result);
476 //std::cout << "report_progress: result->ob_refcnt=" << result->ob_refcnt << std::endl;
477 PyGILState_Release(gstate);
478 }
479
init(int totalSteps)480 virtual void init(int totalSteps)
481 {
482 nSteps = totalSteps;
483 steps_to_percent = 1.f / (float) nSteps;
484 doneSteps = 0;
485 report_progress(0.f);
486 }
487
488 virtual void update(int steps = 1)
489 {
490 doneSteps += steps;
491 report_progress(doneSteps * steps_to_percent);
492 }
493
done()494 virtual void done()
495 {
496 report_progress(1.f);
497 }
498
setTag(const char * text)499 virtual void setTag(const char* text)
500 {
501 tag = std::string(text);
502 PyGILState_STATE gstate;
503 gstate = PyGILState_Ensure();
504 PyObject* result = PyObject_CallFunction(callb, "ss", "tag", text);
505 Py_XDECREF(result);
506 //std::cout << "setTag: result->ob_refcnt=" << result->ob_refcnt << std::endl;
507 PyGILState_Release(gstate);
508 }
509
setTag(std::string text)510 virtual void setTag(std::string text)
511 {
512 tag = text;
513 PyGILState_STATE gstate;
514 gstate = PyGILState_Ensure();
515 PyObject* result = PyObject_CallFunction(callb, "ss", "tag", text.c_str());
516 Py_XDECREF(result);
517 //std::cout << "setTag: result->ob_refcnt=" << result->ob_refcnt << std::endl;
518 PyGILState_Release(gstate);
519 }
520
getTag()521 virtual std::string getTag() const
522 {
523 return tag;
524 }
525
getPercent()526 virtual float getPercent() const { return 100.f * std::min(1.f, (float) doneSteps * steps_to_percent); }
getTotalSteps()527 virtual float getTotalSteps() const { return nSteps; }
528
529 private:
530
531 PyObject *callb;
532 float steps_to_percent;
533 int doneSteps, nSteps;
534 std::string tag;
535 };
536
537 %}
538
539 %init %{
540 PyType_Ready(&yafTile_Type);
541 %}
542
543 %typemap(in) PyObject *pyfunc
544 {
545 if (!PyCallable_Check($input))
546 {
547 PyErr_SetString(PyExc_TypeError, "Need a callback method.");
548 return nullptr;
549 }
550
551 $1 = $input;
552 }
553
554 %extend yafaray::yafrayInterface_t
555 {
render(int x,int y,int borderStartX,int borderStartY,bool prev,PyObject * drawAreaCallBack,PyObject * flushCallBack,PyObject * progressCallback)556 void render(int x, int y, int borderStartX, int borderStartY, bool prev, PyObject *drawAreaCallBack, PyObject *flushCallBack, PyObject *progressCallback)
557 {
558 pyOutput_t output_wrap(x, y, borderStartX, borderStartY, prev, drawAreaCallBack, flushCallBack);
559 pyProgress *pbar_wrap = new pyProgress(progressCallback);
560
561 Py_BEGIN_ALLOW_THREADS;
562 self->render(output_wrap, pbar_wrap);
563 Py_END_ALLOW_THREADS;
564 }
565 }
566
567 %exception yafaray::yafrayInterface_t::loadPlugins
568 {
569 Py_BEGIN_ALLOW_THREADS
570 $action
571 Py_END_ALLOW_THREADS
572 }
573
574 #endif // End of python specific code
575
576 %{
577 #include <yafray_constants.h>
578 #include <interface/yafrayinterface.h>
579 #include <interface/xmlinterface.h>
580 #include <yafraycore/imageOutput.h>
581 #include <yafraycore/memoryIO.h>
582 #include <core_api/matrix4.h>
583 using namespace yafaray;
584 %}
585
586 #ifdef SWIGRUBY
587 %feature("director") colorOutput_t::putPixel;
588 %feature("director") colorOutput_t::flush;
589 %feature("director") colorOutput_t::flushArea;
590 #endif
591
592 namespace yafaray
593 {
594 // Required abstracts
595
596 class colorOutput_t
597 {
598 public:
~colorOutput_t()599 virtual ~colorOutput_t() {};
initTilesPasses(int totalViews,int numExtPasses)600 virtual void initTilesPasses(int totalViews, int numExtPasses) {};
601 virtual bool putPixel(int numView, int x, int y, const renderPasses_t *renderPasses, int idx, const colorA_t &color, bool alpha = true)=0;
602 virtual bool putPixel(int numView, int x, int y, const renderPasses_t *renderPasses, const std::vector<colorA_t> &colExtPasses, bool alpha = true)=0;
603 virtual void flush(int numView, const renderPasses_t *renderPasses)=0;
604 virtual void flushArea(int numView, int x0, int y0, int x1, int y1, const renderPasses_t *renderPasses)=0;
highliteArea(int numView,int x0,int y0,int x1,int y1)605 virtual void highliteArea(int numView, int x0, int y0, int x1, int y1){};
isImageOutput()606 virtual bool isImageOutput() { return false; }
isPreview()607 virtual bool isPreview() { return false; }
getDenoiseParams()608 virtual std::string getDenoiseParams() const { return ""; }
609 };
610
611 class imageHandler_t
612 {
613 public:
~imageHandler_t()614 virtual ~imageHandler_t() {}
615 virtual bool loadFromFile(const std::string &name) = 0;
loadFromMemory(const yByte * data,size_t size)616 virtual bool loadFromMemory(const yByte *data, size_t size) {return false; }
617 virtual bool saveToFile(const std::string &name, int imgIndex = 0) = 0;
saveToFileMultiChannel(const std::string & name,const renderPasses_t * renderPasses)618 virtual bool saveToFileMultiChannel(const std::string &name, const renderPasses_t *renderPasses) { return false; };
isHDR()619 virtual bool isHDR() { return false; }
isMultiLayer()620 virtual bool isMultiLayer() { return m_MultiLayer; }
denoiseEnabled()621 virtual bool denoiseEnabled() { return m_Denoise; }
getTextureOptimization()622 int getTextureOptimization() { return m_textureOptimization; }
setTextureOptimization(int texture_optimization)623 void setTextureOptimization(int texture_optimization) { m_textureOptimization = texture_optimization; }
setGrayScaleSetting(bool grayscale)624 void setGrayScaleSetting(bool grayscale) { m_grayscale = grayscale; }
625 int getWidth(int imgIndex = 0) { return imgBuffer.at(imgIndex)->getWidth(); }
626 int getHeight(int imgIndex = 0) { return imgBuffer.at(imgIndex)->getHeight(); }
627 std::string getDenoiseParams() const;
628 void generateMipMaps();
getHighestImgIndex()629 int getHighestImgIndex() const { return (int) imgBuffer.size() - 1; }
setColorSpace(colorSpaces_t color_space,float gamma)630 void setColorSpace(colorSpaces_t color_space, float gamma) { m_colorSpace = color_space; m_gamma = gamma; }
631 void putPixel(int x, int y, const colorA_t &rgba, int imgIndex = 0);
632 colorA_t getPixel(int x, int y, int imgIndex = 0);
633 void initForOutput(int width, int height, const renderPasses_t *renderPasses, bool denoiseEnabled, int denoiseHLum, int denoiseHCol, float denoiseMix, bool withAlpha = false, bool multi_layer = false, bool grayscale = false);
634 void clearImgBuffers();
635 };
636
637 // Outputs
638
639 class imageOutput_t : public colorOutput_t
640 {
641 public:
642 imageOutput_t(imageHandler_t *handle, const std::string &name, int bx, int by);
643 imageOutput_t(); //!< Dummy initializer
644 virtual ~imageOutput_t();
645 virtual bool putPixel(int numView, int x, int y, const renderPasses_t *renderPasses, int idx, const colorA_t &color, bool alpha = true);
646 virtual bool putPixel(int numView, int x, int y, const renderPasses_t *renderPasses, const std::vector<colorA_t> &colExtPasses, bool alpha = true);
647 virtual void flush(int numView, const renderPasses_t *renderPasses);
flushArea(int numView,int x0,int y0,int x1,int y1,const renderPasses_t * renderPasses)648 virtual void flushArea(int numView, int x0, int y0, int x1, int y1, const renderPasses_t *renderPasses) {} // not used by images... yet
isImageOutput()649 virtual bool isImageOutput() { return true; }
getDenoiseParams()650 virtual std::string getDenoiseParams() const
651 {
652 if(image) return image->getDenoiseParams();
653 else return "";
654 }
655 void saveImageFile(std::string filename, int idx);
656 void saveImageFileMultiChannel(std::string filename, const renderPasses_t *renderPasses);
657 };
658
659 class memoryIO_t : public colorOutput_t
660 {
661 public:
662 memoryIO_t(int resx, int resy, float* iMem);
663 virtual bool putPixel(int numView, int x, int y, const renderPasses_t *renderPasses, int idx, const colorA_t &color, bool alpha = true);
664 virtual bool putPixel(int numView, int x, int y, const renderPasses_t *renderPasses, const std::vector<colorA_t> &colExtPasses, bool alpha = true);
665 void flush(int numView, const renderPasses_t *renderPasses);
flushArea(int numView,int x0,int y0,int x1,int y1,const renderPasses_t * renderPasses)666 virtual void flushArea(int numView, int x0, int y0, int x1, int y1, const renderPasses_t *renderPasses) {}; // no tiled file format used...yet
667 virtual ~memoryIO_t();
668 };
669
670 // Utility classes
671
672 class matrix4x4_t
673 {
674 public:
matrix4x4_t()675 matrix4x4_t() {};
676 matrix4x4_t(const float init);
677 matrix4x4_t(const matrix4x4_t & source);
678 matrix4x4_t(const float source[4][4]);
679 matrix4x4_t(const double source[4][4]);
~matrix4x4_t()680 ~matrix4x4_t() {};
681 /*! attention, this function can cause the matrix to become invalid!
682 unless you are sure the matrix is invertible, check invalid() afterwards! */
683 matrix4x4_t & inverse();
684 matrix4x4_t & transpose();
685 void identity();
686 void translate(float dx,float dy,float dz);
687 void rotateX(float degrees);
688 void rotateY(float degrees);
689 void rotateZ(float degrees);
690 void scale(float sx, float sy, float sz);
invalid()691 int invalid() const { return _invalid; }
692 // ignored by swig
693 //const float * operator [] (int i) const { return matrix[i]; }
694 //float * operator [] (int i) { return matrix[i]; }
setVal(int row,int col,float val)695 void setVal(int row, int col, float val)
696 {
697 matrix[row][col] = val;
698 }
699
getVal(int row,int col)700 float getVal(int row, int col)
701 {
702 return matrix[row][col];
703 }
704 };
705
706 // Interfaces
707
708 class yafrayInterface_t
709 {
710 public:
711 yafrayInterface_t();
712 virtual ~yafrayInterface_t();
713 // directly related to scene_t:
714 virtual void loadPlugins(const char *path); //!< load plugins from path, if nullptr load from default path, if available.
715 virtual bool startGeometry(); //!< call before creating geometry; only meshes and vmaps can be created in this state
716 virtual bool endGeometry(); //!< call after creating geometry;
717 /*! start a triangle mesh
718 in this state only vertices, UVs and triangles can be created
719 \param id returns the ID of the created mesh
720 */
721 virtual unsigned int getNextFreeID();
722 virtual bool startTriMesh(unsigned int id, int vertices, int triangles, bool hasOrco, bool hasUV=false, int type=0, int obj_pass_index=0);
723 virtual bool startCurveMesh(unsigned int id, int vertices, int obj_pass_index=0);
724 virtual bool startTriMeshPtr(unsigned int *id, int vertices, int triangles, bool hasOrco, bool hasUV=false, int type=0, int obj_pass_index=0);
725 virtual bool endTriMesh(); //!< end current mesh and return to geometry state
726 virtual bool endCurveMesh(const material_t *mat, float strandStart, float strandEnd, float strandShape); //!< end current mesh and return to geometry state
727 virtual int addVertex(double x, double y, double z); //!< add vertex to mesh; returns index to be used for addTriangle
728 virtual int addVertex(double x, double y, double z, double ox, double oy, double oz); //!< add vertex with Orco to mesh; returns index to be used for addTriangle
729 virtual void addNormal(double nx, double ny, double nz); //!< add vertex normal to mesh; the vertex that will be attached to is the last one inserted by addVertex method
730 virtual bool addTriangle(int a, int b, int c, const material_t *mat); //!< add a triangle given vertex indices and material pointer
731 virtual bool addTriangle(int a, int b, int c, int uv_a, int uv_b, int uv_c, const material_t *mat); //!< add a triangle given vertex and uv indices and material pointer
732 virtual int addUV(float u, float v); //!< add a UV coordinate pair; returns index to be used for addTriangle
733 virtual bool smoothMesh(unsigned int id, double angle); //!< smooth vertex normals of mesh with given ID and angle (in degrees)
734 virtual bool addInstance(unsigned int baseObjectId, matrix4x4_t objToWorld);
735 // functions to build paramMaps instead of passing them from Blender
736 // (decouling implementation details of STL containers, paraMap_t etc. as much as possible)
737 virtual void paramsSetPoint(const char* name, double x, double y, double z);
738 virtual void paramsSetString(const char* name, const char* s);
739 virtual void paramsSetBool(const char* name, bool b);
740 virtual void paramsSetInt(const char* name, int i);
741 virtual void paramsSetFloat(const char* name, double f);
742 virtual void paramsSetColor(const char* name, float r, float g, float b, float a=1.f);
743 virtual void paramsSetColor(const char* name, float *rgb, bool with_alpha=false);
744 virtual void paramsSetMatrix(const char* name, float m[4][4], bool transpose=false);
745 virtual void paramsSetMatrix(const char* name, double m[4][4], bool transpose=false);
746 virtual void paramsSetMemMatrix(const char* name, float* matrix, bool transpose=false);
747 virtual void paramsSetMemMatrix(const char* name, double* matrix, bool transpose=false);
748 virtual void paramsClearAll(); //!< clear the paramMap and paramList
749 virtual void paramsStartList(); //!< start writing parameters to the extended paramList (used by materials)
750 virtual void paramsPushList(); //!< push new list item in paramList (e.g. new shader node description)
751 virtual void paramsEndList(); //!< revert to writing to normal paramMap
752 // functions directly related to renderEnvironment_t
753 virtual light_t* createLight (const char* name);
754 virtual texture_t* createTexture (const char* name);
755 virtual material_t* createMaterial (const char* name);
756 virtual camera_t* createCamera (const char* name);
757 virtual background_t* createBackground (const char* name);
758 virtual integrator_t* createIntegrator (const char* name);
759 virtual VolumeRegion* createVolumeRegion (const char* name);
760 virtual imageHandler_t* createImageHandler (const char* name, bool addToTable = true); //!< The addToTable parameter, if true, allows to avoid the interface from taking ownership of the image handler
761 virtual unsigned int createObject (const char* name);
762 virtual void clearAll(); //!< clear the whole environment + scene, i.e. free (hopefully) all memory.
763 virtual void render(colorOutput_t &output, progressBar_t *pb = nullptr); //!< render the scene...
764 virtual bool startScene(int type=0); //!< start a new scene; Must be called before any of the scene_t related callbacks!
765 virtual bool setLoggingAndBadgeSettings();
766 virtual bool setupRenderPasses(); //!< setup render passes information
767 bool setInteractive(bool interactive);
768 virtual void abort();
getRenderParameters()769 virtual paraMap_t* getRenderParameters() { return params; }
770 virtual bool getRenderedImage(int numView, colorOutput_t &output); //!< put the rendered image to output
771 virtual std::vector<std::string> listImageHandlers();
772 virtual std::vector<std::string> listImageHandlersFullName();
773 virtual std::string getImageFormatFromFullName(const std::string &fullname);
774 virtual std::string getImageFullNameFromFormat(const std::string &format);
775
776 void setConsoleVerbosityLevel(const std::string &strVLevel);
777 void setLogVerbosityLevel(const std::string &strVLevel);
778
779 virtual void setParamsBadgePosition(const std::string &badgePosition = "none");
780 virtual bool getDrawParams();
781
782 std::string getVersion() const; //!< Get version to check against the exporters
783
784 /*! Console Printing wrappers to report in color with yafaray's own console coloring */
785 void printDebug(const std::string &msg);
786 void printVerbose(const std::string &msg);
787 void printInfo(const std::string &msg);
788 void printParams(const std::string &msg);
789 void printWarning(const std::string &msg);
790 void printError(const std::string &msg);
791
792 void setInputColorSpace(std::string color_space_string, float gammaVal);
793 void setOutput2(colorOutput_t *out2);
794 };
795
796 class xmlInterface_t: public yafrayInterface_t
797 {
798 public:
799 xmlInterface_t();
800 // directly related to scene_t:
801 virtual void loadPlugins(const char *path);
802 virtual bool setLoggingAndBadgeSettings();
803 virtual bool setupRenderPasses(); //!< setup render passes information
804 virtual bool startGeometry();
805 virtual bool endGeometry();
806 virtual unsigned int getNextFreeID();
807 virtual bool startTriMesh(unsigned int id, int vertices, int triangles, bool hasOrco, bool hasUV=false, int type=0, int obj_pass_index=0);
808 virtual bool startTriMeshPtr(unsigned int *id, int vertices, int triangles, bool hasOrco, bool hasUV=false, int type=0, int obj_pass_index=0);
809 virtual bool startCurveMesh(unsigned int id, int vertices, int obj_pass_index=0);
810 virtual bool endTriMesh();
811 virtual bool addInstance(unsigned int baseObjectId, matrix4x4_t objToWorld);
812 virtual bool endCurveMesh(const material_t *mat, float strandStart, float strandEnd, float strandShape);
813 virtual int addVertex(double x, double y, double z); //!< add vertex to mesh; returns index to be used for addTriangle
814 virtual int addVertex(double x, double y, double z, double ox, double oy, double oz); //!< add vertex with Orco to mesh; returns index to be used for addTriangle
815 virtual void addNormal(double nx, double ny, double nz); //!< add vertex normal to mesh; the vertex that will be attached to is the last one inserted by addVertex method
816 virtual bool addTriangle(int a, int b, int c, const material_t *mat);
817 virtual bool addTriangle(int a, int b, int c, int uv_a, int uv_b, int uv_c, const material_t *mat);
818 virtual int addUV(float u, float v);
819 virtual bool smoothMesh(unsigned int id, double angle);
820
821 // functions directly related to renderEnvironment_t
822 virtual light_t* createLight (const char* name);
823 virtual texture_t* createTexture (const char* name);
824 virtual material_t* createMaterial (const char* name);
825 virtual camera_t* createCamera (const char* name);
826 virtual background_t* createBackground (const char* name);
827 virtual integrator_t* createIntegrator (const char* name);
828 virtual VolumeRegion* createVolumeRegion (const char* name);
829 virtual unsigned int createObject (const char* name);
830 virtual void clearAll(); //!< clear the whole environment + scene, i.e. free (hopefully) all memory.
831 virtual void render(colorOutput_t &output, progressBar_t *pb = nullptr); //!< render the scene...
832 virtual bool startScene(int type=0); //!< start a new scene; Must be called before any of the scene_t related callbacks!
833
834 virtual void setOutfile(const char *fname);
835
836 void setXMLColorSpace(std::string color_space_string, float gammaVal);
837 };
838
839 }
840