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