1 /****************************************************************************
2  *      renderpasses.cc: Render Passes operations
3  *      This is part of the yafaray package
4  *      Copyright (C) 2015  David Bluecame
5  *
6  *      This library is free software; you can redistribute it and/or
7  *      modify it under the terms of the GNU Lesser General Public
8  *      License as published by the Free Software Foundation; either
9  *      version 2.1 of the License, or (at your option) any later version.
10  *
11  *      This library is distributed in the hope that it will be useful,
12  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *      Lesser General Public License for more details.
15  *
16  *      You should have received a copy of the GNU Lesser General Public
17  *      License along with this library; if not, write to the Free Software
18  *      Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  */
20 
21 #include <core_api/color.h>
22 #include <core_api/renderpasses.h>
23 #include <core_api/logging.h>
24 
25 __BEGIN_YAFRAY
26 
27 
28 ////////////////////////////
29 // --  renderPasses_t  -- //
30 ////////////////////////////
31 
renderPasses_t()32 renderPasses_t::renderPasses_t():indexExtPasses(std::vector<int>(PASS_EXT_TOTAL_PASSES, -1)), indexIntPasses(std::vector<int>(PASS_INT_TOTAL_PASSES, -1)) //Creation of the external and internal passes indexes, initially all -1 (disabled)
33 {
34 	generate_pass_maps();
35 
36 	extPass_add("Combined", "combined");	//by default we will have an external/internal Combined pass
37 }
38 
extPassesSize() const39 int renderPasses_t::extPassesSize() const
40 {
41 	return extPasses.size();
42 }
43 
auxPassesSize() const44 int renderPasses_t::auxPassesSize() const
45 {
46 	return auxPasses.size();
47 }
48 
intPassesSize() const49 int renderPasses_t::intPassesSize() const
50 {
51 	return intPasses.size();
52 }
53 
generate_pass_maps()54 void renderPasses_t::generate_pass_maps()
55 {
56 	//External Render passes - mapping String and External Pass Type
57 	//IMPORTANT: the external strings MUST MATCH the pass property names in Blender. These must also match the property names in Blender-Exporter without the "pass_" prefix.
58 	extPassMapStringInt["Combined"] = PASS_EXT_COMBINED;
59 	extPassMapStringInt["Depth"] = PASS_EXT_Z_DEPTH;	//From here, specific ext.passes for Blender Exporter
60 	extPassMapStringInt["Vector"] = PASS_EXT_VECTOR;
61 	extPassMapStringInt["Normal"] = PASS_EXT_NORMAL;
62 	extPassMapStringInt["UV"] = PASS_EXT_UV;
63 	extPassMapStringInt["Color"] = PASS_EXT_COLOR;
64 	extPassMapStringInt["Emit"] = PASS_EXT_EMIT;
65 	extPassMapStringInt["Mist"] = PASS_EXT_MIST;
66 	extPassMapStringInt["Diffuse"] = PASS_EXT_DIFFUSE;
67 	extPassMapStringInt["Spec"] = PASS_EXT_SPECULAR;
68 	extPassMapStringInt["AO"] = PASS_EXT_AO;
69 	extPassMapStringInt["Env"] = PASS_EXT_ENV;
70 	extPassMapStringInt["Indirect"] = PASS_EXT_INDIRECT;
71 	extPassMapStringInt["Shadow"] = PASS_EXT_SHADOW;
72 	extPassMapStringInt["Reflect"] = PASS_EXT_REFLECT;
73 	extPassMapStringInt["Refract"] = PASS_EXT_REFRACT;
74 	extPassMapStringInt["IndexOB"] = PASS_EXT_OBJ_INDEX;
75 	extPassMapStringInt["IndexMA"] = PASS_EXT_MAT_INDEX;
76 	extPassMapStringInt["DiffDir"] = PASS_EXT_DIFFUSE_DIRECT;
77 	extPassMapStringInt["DiffInd"] = PASS_EXT_DIFFUSE_INDIRECT;
78 	extPassMapStringInt["DiffCol"] = PASS_EXT_DIFFUSE_COLOR;
79 	extPassMapStringInt["GlossDir"] = PASS_EXT_GLOSSY_DIRECT;
80 	extPassMapStringInt["GlossInd"] = PASS_EXT_GLOSSY_INDIRECT;
81 	extPassMapStringInt["GlossCol"] = PASS_EXT_GLOSSY_COLOR;
82 	extPassMapStringInt["TransDir"] = PASS_EXT_TRANS_DIRECT;
83 	extPassMapStringInt["TransInd"] = PASS_EXT_TRANS_INDIRECT;
84 	extPassMapStringInt["TransCol"] = PASS_EXT_TRANS_COLOR;
85 	extPassMapStringInt["SubsurfaceDir"] = PASS_EXT_SUBSURFACE_DIRECT;
86 	extPassMapStringInt["SubsurfaceInd"] = PASS_EXT_SUBSURFACE_INDIRECT;
87 	extPassMapStringInt["SubsurfaceCol"] = PASS_EXT_SUBSURFACE_COLOR;
88 	extPassMapStringInt["RenderPass_1"] = PASS_EXT_1;	//From here, generic ext.passes for other exporters and plugins
89 	extPassMapStringInt["RenderPass_2"] = PASS_EXT_2;
90 	extPassMapStringInt["RenderPass_3"] = PASS_EXT_3;
91 	extPassMapStringInt["RenderPass_4"] = PASS_EXT_4;
92 	extPassMapStringInt["RenderPass_5"] = PASS_EXT_5;
93 	extPassMapStringInt["RenderPass_6"] = PASS_EXT_6;
94 	extPassMapStringInt["RenderPass_7"] = PASS_EXT_7;
95 	extPassMapStringInt["RenderPass_8"] = PASS_EXT_8;
96 	extPassMapStringInt["RenderPass_9"] = PASS_EXT_9;
97 	extPassMapStringInt["RenderPass_10"] = PASS_EXT_10;
98 	extPassMapStringInt["RenderPass_11"] = PASS_EXT_11;
99 	extPassMapStringInt["RenderPass_12"] = PASS_EXT_12;
100 	extPassMapStringInt["RenderPass_13"] = PASS_EXT_13;
101 	extPassMapStringInt["RenderPass_14"] = PASS_EXT_14;
102 	extPassMapStringInt["RenderPass_15"] = PASS_EXT_15;
103 	extPassMapStringInt["RenderPass_16"] = PASS_EXT_16;
104 	extPassMapStringInt["RenderPass_17"] = PASS_EXT_17;
105 	extPassMapStringInt["RenderPass_18"] = PASS_EXT_18;
106 	extPassMapStringInt["RenderPass_19"] = PASS_EXT_19;
107 	extPassMapStringInt["RenderPass_20"] = PASS_EXT_20;
108 	extPassMapStringInt["RenderPass_21"] = PASS_EXT_21;
109 	extPassMapStringInt["RenderPass_22"] = PASS_EXT_22;
110 	extPassMapStringInt["RenderPass_23"] = PASS_EXT_23;
111 	extPassMapStringInt["RenderPass_24"] = PASS_EXT_24;
112 	extPassMapStringInt["RenderPass_25"] = PASS_EXT_25;
113 	extPassMapStringInt["RenderPass_26"] = PASS_EXT_26;
114 	extPassMapStringInt["RenderPass_27"] = PASS_EXT_27;
115 	extPassMapStringInt["RenderPass_28"] = PASS_EXT_28;
116 	extPassMapStringInt["RenderPass_29"] = PASS_EXT_29;
117 	extPassMapStringInt["RenderPass_30"] = PASS_EXT_30;
118 	extPassMapStringInt["RenderPass_31"] = PASS_EXT_31;
119 	extPassMapStringInt["RenderPass_32"] = PASS_EXT_32;
120 
121 	//Generation of reverse map (pass type -> pass_string)
122 	for(auto it = extPassMapStringInt.begin(); it != extPassMapStringInt.end(); ++it)
123 	{
124 		extPassMapIntString[it->second] = it->first;
125 	}
126 
127 	//Internal YafaRay Render passes - mapping String and Internal YafaRay Render passes
128 	//IMPORTANT: the internal strings MUST MATCH the valid values for the pass properties in Blender Exporter
129 	intPassMapStringInt["disabled"] = PASS_INT_DISABLED;
130 	intPassMapStringInt["combined"] = PASS_INT_COMBINED;
131 	intPassMapStringInt["z-depth-norm"] = PASS_INT_Z_DEPTH_NORM;
132 	intPassMapStringInt["z-depth-abs"] = PASS_INT_Z_DEPTH_ABS;
133 	intPassMapStringInt["debug-normal-smooth"] = PASS_INT_NORMAL_SMOOTH;
134 	intPassMapStringInt["debug-normal-geom"] = PASS_INT_NORMAL_GEOM;
135 	intPassMapStringInt["adv-radiance"] = PASS_INT_RADIANCE;
136 	intPassMapStringInt["debug-uv"] = PASS_INT_UV;
137 	intPassMapStringInt["emit"] = PASS_INT_EMIT;
138 	intPassMapStringInt["mist"] = PASS_INT_MIST;
139 	intPassMapStringInt["diffuse"] = PASS_INT_DIFFUSE;
140 	intPassMapStringInt["diffuse-noshadow"] = PASS_INT_DIFFUSE_NO_SHADOW;
141 	intPassMapStringInt["ao"] = PASS_INT_AO;
142 	intPassMapStringInt["ao-clay"] = PASS_INT_AO_CLAY;
143 	intPassMapStringInt["env"] = PASS_INT_ENV;
144 	intPassMapStringInt["indirect"] = PASS_INT_INDIRECT_ALL;
145 	intPassMapStringInt["adv-indirect"] = PASS_INT_INDIRECT;
146 	intPassMapStringInt["shadow"] = PASS_INT_SHADOW;
147 	intPassMapStringInt["reflect"] = PASS_INT_REFLECT_ALL;
148 	intPassMapStringInt["refract"] = PASS_INT_REFRACT_ALL;
149 	intPassMapStringInt["adv-reflect"] = PASS_INT_REFLECT_PERFECT;
150 	intPassMapStringInt["adv-refract"] = PASS_INT_REFRACT_PERFECT;
151 	intPassMapStringInt["obj-index-abs"] = PASS_INT_OBJ_INDEX_ABS;
152 	intPassMapStringInt["obj-index-norm"] = PASS_INT_OBJ_INDEX_NORM;
153 	intPassMapStringInt["obj-index-auto"] = PASS_INT_OBJ_INDEX_AUTO;
154 	intPassMapStringInt["obj-index-auto-abs"] = PASS_INT_OBJ_INDEX_AUTO_ABS;
155 	intPassMapStringInt["obj-index-mask"] = PASS_INT_OBJ_INDEX_MASK;
156 	intPassMapStringInt["obj-index-mask-shadow"] = PASS_INT_OBJ_INDEX_MASK_SHADOW;
157 	intPassMapStringInt["obj-index-mask-all"] = PASS_INT_OBJ_INDEX_MASK_ALL;
158 	intPassMapStringInt["mat-index-abs"] = PASS_INT_MAT_INDEX_ABS;
159 	intPassMapStringInt["mat-index-norm"] = PASS_INT_MAT_INDEX_NORM;
160 	intPassMapStringInt["mat-index-auto"] = PASS_INT_MAT_INDEX_AUTO;
161 	intPassMapStringInt["mat-index-auto-abs"] = PASS_INT_MAT_INDEX_AUTO_ABS;
162 	intPassMapStringInt["mat-index-mask"] = PASS_INT_MAT_INDEX_MASK;
163 	intPassMapStringInt["mat-index-mask-shadow"] = PASS_INT_MAT_INDEX_MASK_SHADOW;
164 	intPassMapStringInt["mat-index-mask-all"] = PASS_INT_MAT_INDEX_MASK_ALL;
165 	intPassMapStringInt["adv-diffuse-indirect"] = PASS_INT_DIFFUSE_INDIRECT;
166 	intPassMapStringInt["adv-diffuse-color"] = PASS_INT_DIFFUSE_COLOR;
167 	intPassMapStringInt["adv-glossy"] = PASS_INT_GLOSSY;
168 	intPassMapStringInt["adv-glossy-indirect"] = PASS_INT_GLOSSY_INDIRECT;
169 	intPassMapStringInt["adv-glossy-color"] = PASS_INT_GLOSSY_COLOR;
170 	intPassMapStringInt["adv-trans"] = PASS_INT_TRANS;
171 	intPassMapStringInt["adv-trans-indirect"] = PASS_INT_TRANS_INDIRECT;
172 	intPassMapStringInt["adv-trans-color"] = PASS_INT_TRANS_COLOR;
173 	intPassMapStringInt["adv-subsurface"] = PASS_INT_SUBSURFACE;
174 	intPassMapStringInt["adv-subsurface-indirect"] = PASS_INT_SUBSURFACE_INDIRECT;
175 	intPassMapStringInt["adv-subsurface-color"] = PASS_INT_SUBSURFACE_COLOR;
176 	intPassMapStringInt["debug-normal-smooth"] = PASS_INT_NORMAL_SMOOTH;
177 	intPassMapStringInt["debug-normal-geom"] = PASS_INT_NORMAL_GEOM;
178 	intPassMapStringInt["debug-nu"] = PASS_INT_DEBUG_NU;
179 	intPassMapStringInt["debug-nv"] = PASS_INT_DEBUG_NV;
180 	intPassMapStringInt["debug-dpdu"] = PASS_INT_DEBUG_DPDU;
181 	intPassMapStringInt["debug-dpdv"] = PASS_INT_DEBUG_DPDV;
182 	intPassMapStringInt["debug-dsdu"] = PASS_INT_DEBUG_DSDU;
183 	intPassMapStringInt["debug-dsdv"] = PASS_INT_DEBUG_DSDV;
184 	intPassMapStringInt["adv-surface-integration"] = PASS_INT_SURFACE_INTEGRATION;
185 	intPassMapStringInt["adv-volume-integration"] = PASS_INT_VOLUME_INTEGRATION;
186 	intPassMapStringInt["adv-volume-transmittance"] = PASS_INT_VOLUME_TRANSMITTANCE;
187 	intPassMapStringInt["debug-aa-samples"] = PASS_INT_AA_SAMPLES;
188 	intPassMapStringInt["debug-light-estimation-light-dirac"] = PASS_INT_DEBUG_LIGHT_ESTIMATION_LIGHT_DIRAC;
189 	intPassMapStringInt["debug-light-estimation-light-sampling"] = PASS_INT_DEBUG_LIGHT_ESTIMATION_LIGHT_SAMPLING;
190 	intPassMapStringInt["debug-light-estimation-mat-sampling"] = PASS_INT_DEBUG_LIGHT_ESTIMATION_MAT_SAMPLING;
191 	intPassMapStringInt["debug-wireframe"] = PASS_INT_DEBUG_WIREFRAME;
192 	intPassMapStringInt["debug-faces-edges"] = PASS_INT_DEBUG_FACES_EDGES;
193 	intPassMapStringInt["debug-objects-edges"] = PASS_INT_DEBUG_OBJECTS_EDGES;
194 	intPassMapStringInt["toon"] = PASS_INT_TOON;
195 	intPassMapStringInt["debug-sampling-factor"] = PASS_INT_DEBUG_SAMPLING_FACTOR;
196 	intPassMapStringInt["debug-dp-lengths"] = PASS_INT_DEBUG_DP_LENGTHS;
197 	intPassMapStringInt["debug-dpdx"] = PASS_INT_DEBUG_DPDX;
198 	intPassMapStringInt["debug-dpdy"] = PASS_INT_DEBUG_DPDY;
199 	intPassMapStringInt["debug-dpdxy"] = PASS_INT_DEBUG_DPDXY;
200 	intPassMapStringInt["debug-dudx-dvdx"] = PASS_INT_DEBUG_DUDX_DVDX;
201 	intPassMapStringInt["debug-dudy-dvdy"] = PASS_INT_DEBUG_DUDY_DVDY;
202 	intPassMapStringInt["debug-dudxy-dvdxy"] = PASS_INT_DEBUG_DUDXY_DVDXY;
203 
204 	//Generation of reverse map (pass type -> pass_string)
205 	for(auto it = intPassMapStringInt.begin(); it != intPassMapStringInt.end(); ++it)
206 	{
207 		intPassMapIntString[it->second] = it->first;
208 	}
209 }
210 
extPass_add(const std::string & sExternalPass,const std::string & sInternalPass)211 void renderPasses_t::extPass_add(const std::string& sExternalPass, const std::string& sInternalPass)
212 {
213 	extPassTypes_t extPassType = extPassTypeFromString(sExternalPass);
214 	if(extPassType == PASS_EXT_DISABLED)
215 	{
216 		Y_ERROR << "Render Passes: error creating external pass \"" << sExternalPass << "\" (linked to internal pass \"" << sInternalPass << "\")" << yendl;
217 		return;
218 	}
219 
220 	intPassTypes_t intPassType = intPassTypeFromString(sInternalPass);
221 	if(intPassType == PASS_INT_DISABLED)
222 	{
223 		Y_ERROR << "Render Passes: error creating internal pass \"" << sInternalPass << "\" (linked to external pass \"" << sExternalPass << "\")" << yendl;
224 		return;
225 	}
226 
227 	if(indexExtPasses.at(extPassType) != -1)
228 	{
229 		//Y_VERBOSE << "Render Passes: external pass type \"" << sExternalPass << "\" already exists, skipping." << yendl;
230 		return;
231 	}
232 
233 	extPasses.push_back(extPass_t(extPassType, intPassType));
234 	indexExtPasses.at(extPassType) = extPasses.end() - extPasses.begin() - 1;	//Each external index entry represents one of the possible external passes types and will have the (sequence) index of the external pass actually using that index
235 
236 	if(sExternalPass != "Combined") Y_INFO << "Render Passes: added pass \"" << sExternalPass << "\" [" << extPassType << "]  (internal pass: \"" << sInternalPass << "\" [" << intPassType << "])" << yendl;
237 
238     intPass_add(intPassType);
239 }
240 
auxPass_add(intPassTypes_t intPassType)241 void renderPasses_t::auxPass_add(intPassTypes_t intPassType)
242 {
243 	if(intPassType == PASS_INT_DISABLED) return;
244 
245 	for(int idx = 0; idx < extPassesSize(); ++idx)
246 	{
247 		if(intPassTypeFromExtPassIndex(idx) == intPassType) return;		//If the internal pass is already rendered into a certain external pass, the auxiliary pass is not necessary.
248 	}
249 
250 	for(int idx = 0; idx < auxPassesSize(); ++idx)
251 	{
252 		if(intPassTypeFromAuxPassIndex(idx) == intPassType) return;		//If the auxiliary pass already exists, do nothing.
253 	}
254 
255 	auxPasses.push_back(auxPass_t(intPassType));
256 
257     intPass_add(intPassType);
258 
259     Y_VERBOSE << "Render Passes: auxiliary Render pass generated for internal pass type: \"" << intPassTypeStringFromType(intPassType) << "\" [" << intPassType << "]" << yendl;
260 }
261 
intPass_add(intPassTypes_t intPassType)262 void renderPasses_t::intPass_add(intPassTypes_t intPassType)
263 {
264 	//if(std::binary_search(intPasses.begin(), intPasses.end(), intPassType))
265 	if(indexIntPasses.at(intPassType) != -1)
266 	{
267 		//Y_VERBOSE << "Render Passes: internal pass \"" << intPassTypeStringFromType(intPassType) << "\" [" << intPassType << "] already exists, skipping..." << yendl;
268 		return;
269 	}
270 	intPasses.push_back(intPassType);
271 	//std::sort(intPasses.begin(), intPasses.end());
272 	indexIntPasses.at(intPassType) = intPasses.end() - intPasses.begin() - 1;	//Each internal index entry represents one of the possible internal passes types and will have the (sequence) index of the internal pass actually using that index
273 
274 	if(intPassType != PASS_INT_COMBINED) Y_VERBOSE << "Render Passes: created internal pass: \"" << intPassTypeStringFromType(intPassType) << "\" [" << intPassType << "]" << yendl;
275 }
276 
auxPasses_generate()277 void renderPasses_t::auxPasses_generate()
278 {
279 	auxPass_add(PASS_INT_DEBUG_SAMPLING_FACTOR);	//This auxiliary pass will always be needed for material-specific number of samples calculation
280 
281 	for(size_t idx=1; idx < intPasses.size(); ++idx)
282 	{
283 		//If any internal pass needs an auxiliary internal pass and/or auxiliary Render pass, enable also the auxiliary passes.
284 		switch(intPasses.at(idx))
285 		{
286 			case PASS_INT_REFLECT_ALL:
287 				intPass_add(PASS_INT_REFLECT_PERFECT);
288 				intPass_add(PASS_INT_GLOSSY);
289 				intPass_add(PASS_INT_GLOSSY_INDIRECT);
290 				break;
291 
292 			case PASS_INT_REFRACT_ALL:
293 				intPass_add(PASS_INT_REFRACT_PERFECT);
294 				intPass_add(PASS_INT_TRANS);
295 				intPass_add(PASS_INT_TRANS_INDIRECT);
296 				break;
297 
298 			case PASS_INT_INDIRECT_ALL:
299 				intPass_add(PASS_INT_INDIRECT);
300 				intPass_add(PASS_INT_DIFFUSE_INDIRECT);
301 				break;
302 
303 			case PASS_INT_OBJ_INDEX_MASK_ALL:
304 				intPass_add(PASS_INT_OBJ_INDEX_MASK);
305 				intPass_add(PASS_INT_OBJ_INDEX_MASK_SHADOW);
306 				break;
307 
308 			case PASS_INT_MAT_INDEX_MASK_ALL:
309 				intPass_add(PASS_INT_MAT_INDEX_MASK);
310 				intPass_add(PASS_INT_MAT_INDEX_MASK_SHADOW);
311 				break;
312 
313 			case PASS_INT_DEBUG_FACES_EDGES:
314 				auxPass_add(PASS_INT_NORMAL_GEOM);
315 				auxPass_add(PASS_INT_Z_DEPTH_NORM);
316 				break;
317 
318 			case PASS_INT_DEBUG_OBJECTS_EDGES:
319 				auxPass_add(PASS_INT_NORMAL_SMOOTH);
320 				auxPass_add(PASS_INT_Z_DEPTH_NORM);
321 				break;
322 
323 			case PASS_INT_TOON:
324 				auxPass_add(PASS_INT_DEBUG_OBJECTS_EDGES);
325 				break;
326 
327 			default:
328 				break;
329 		}
330 	}
331 }
332 
extPassTypeFromIndex(int extPassIndex) const333 extPassTypes_t renderPasses_t::extPassTypeFromIndex(int extPassIndex) const { return extPasses.at(extPassIndex).extPassType; }
intPassTypeFromIndex(int intPassIndex) const334 intPassTypes_t renderPasses_t::intPassTypeFromIndex(int intPassIndex) const { return intPasses.at(intPassIndex); }
335 
extPassTypeStringFromIndex(int extPassIndex) const336 std::string renderPasses_t::extPassTypeStringFromIndex(int extPassIndex) const
337 {
338 	auto map_iterator = extPassMapIntString.find(extPasses.at(extPassIndex).extPassType);
339 	if(map_iterator == extPassMapIntString.end()) return "not found";
340 	else return map_iterator->second;
341 }
342 
extPassTypeStringFromType(extPassTypes_t extPassType) const343 std::string renderPasses_t::extPassTypeStringFromType(extPassTypes_t extPassType) const
344 {
345 	auto map_iterator = extPassMapIntString.find(extPassType);
346 	if(map_iterator == extPassMapIntString.end()) return "not found";
347 	else return map_iterator->second;
348 }
349 
intPassTypeStringFromType(intPassTypes_t intPassType) const350 std::string renderPasses_t::intPassTypeStringFromType(intPassTypes_t intPassType) const
351 {
352 	auto map_iterator = intPassMapIntString.find(intPassType);
353 	if(map_iterator == intPassMapIntString.end()) return "not found";
354 	else return map_iterator->second;
355 }
356 
extPassTypeFromString(std::string extPassTypeString) const357 extPassTypes_t renderPasses_t::extPassTypeFromString(std::string extPassTypeString) const
358 {
359 	auto map_iterator = extPassMapStringInt.find(extPassTypeString);
360 	if(map_iterator == extPassMapStringInt.end()) return PASS_EXT_DISABLED;	//PASS_EXT_DISABLED is returned if the string cannot be found
361 	else return map_iterator->second;
362 }
363 
intPassTypeFromString(std::string intPassTypeString) const364 intPassTypes_t renderPasses_t::intPassTypeFromString(std::string intPassTypeString) const
365 {
366 	auto map_iterator = intPassMapStringInt.find(intPassTypeString);
367 	if(map_iterator == intPassMapStringInt.end()) return PASS_INT_DISABLED;	//PASS_INT_DISABLED is returned if the string cannot be found
368 	else return map_iterator->second;
369 }
370 
tileType(int extPassIndex) const371 externalPassTileTypes_t renderPasses_t::tileType(int extPassIndex) const { return extPasses.at(extPassIndex).tileType; }
372 
intPassTypeFromExtPassIndex(int extPassIndex) const373 intPassTypes_t renderPasses_t::intPassTypeFromExtPassIndex(int extPassIndex) const
374 {
375     if(extPassesSize() > extPassIndex) return extPasses.at(extPassIndex).intPassType;
376     else return PASS_INT_DISABLED;
377 }
378 
intPassTypeFromAuxPassIndex(int auxPassIndex) const379 intPassTypes_t renderPasses_t::intPassTypeFromAuxPassIndex(int auxPassIndex) const
380 {
381     if(auxPassesSize() > auxPassIndex) return auxPasses.at(auxPassIndex).intPassType;
382     else return PASS_INT_DISABLED;
383 }
384 
extPassIndexFromType(extPassTypes_t extPassType) const385 int renderPasses_t::extPassIndexFromType(extPassTypes_t extPassType) const
386 {
387 	return indexExtPasses.at(extPassType);
388 }
389 
intPassIndexFromType(intPassTypes_t intPassType) const390 int renderPasses_t::intPassIndexFromType(intPassTypes_t intPassType) const
391 {
392 	return indexIntPasses.at(intPassType);
393 }
394 
set_pass_mask_obj_index(float new_obj_index)395 void renderPasses_t::set_pass_mask_obj_index(float new_obj_index) { pass_mask_obj_index = new_obj_index; }
set_pass_mask_mat_index(float new_mat_index)396 void renderPasses_t::set_pass_mask_mat_index(float new_mat_index) { pass_mask_mat_index = new_mat_index; }
set_pass_mask_invert(bool mask_invert)397 void renderPasses_t::set_pass_mask_invert(bool mask_invert) { pass_mask_invert = mask_invert; }
set_pass_mask_only(bool mask_only)398 void renderPasses_t::set_pass_mask_only(bool mask_only) { pass_mask_only = mask_only; }
399 
400 
401 
402 ////////////////////////////
403 // --    extPass_t     -- //
404 ////////////////////////////
405 
extPass_t(extPassTypes_t extPassType,intPassTypes_t intPassType)406 extPass_t::extPass_t(extPassTypes_t extPassType, intPassTypes_t intPassType):
407 			extPassType(extPassType), intPassType(intPassType)
408 {
409 	switch(extPassType)  //These are the tyle types needed for Blender
410 	{
411 		case PASS_EXT_COMBINED:		tileType = PASS_EXT_TILE_4_RGBA;		break;
412 		case PASS_EXT_Z_DEPTH:		tileType = PASS_EXT_TILE_1_GRAYSCALE;	break;
413 		case PASS_EXT_VECTOR:		tileType = PASS_EXT_TILE_4_RGBA;		break;
414 		case PASS_EXT_COLOR:		tileType = PASS_EXT_TILE_4_RGBA;		break;
415 		case PASS_EXT_MIST:			tileType = PASS_EXT_TILE_1_GRAYSCALE;	break;
416 		case PASS_EXT_OBJ_INDEX:	tileType = PASS_EXT_TILE_1_GRAYSCALE;	break;
417 		case PASS_EXT_MAT_INDEX:	tileType = PASS_EXT_TILE_1_GRAYSCALE;	break;
418 		default: 					tileType = PASS_EXT_TILE_3_RGB;			break;
419 	}
420 }
421 
422 
423 
424 ////////////////////////////
425 // --    auxPass_t     -- //
426 ////////////////////////////
427 
auxPass_t(intPassTypes_t intPassType)428 auxPass_t::auxPass_t(intPassTypes_t intPassType):
429 			intPassType(intPassType)
430 {
431 	//empty
432 }
433 
434 
435 
436 /////////////////////////
437 // -- colorPasses_t -- //
438 /////////////////////////
439 
colorPasses_t(const renderPasses_t * renderPasses)440 colorPasses_t::colorPasses_t(const renderPasses_t *renderPasses):passDefinitions(renderPasses)
441 {
442 	//for performance, even if we don't actually use all the possible internal passes, we reserve a contiguous memory block
443 	colVector.reserve(passDefinitions->intPasses.size());
444 	for(auto it = passDefinitions->intPasses.begin(); it != passDefinitions->intPasses.end(); ++it)
445 	{
446 		colVector.push_back(init_color(passDefinitions->intPassTypeFromIndex(it - passDefinitions->intPasses.begin())));
447 	}
448 }
449 
enabled(intPassTypes_t intPassType) const450 bool colorPasses_t::enabled(intPassTypes_t intPassType) const
451 {
452 	if(passDefinitions->intPassIndexFromType(intPassType) == -1) return false;
453 	else return true;
454 }
455 
intPassTypeFromIndex(int intPassIndex) const456 intPassTypes_t colorPasses_t::intPassTypeFromIndex(int intPassIndex) const
457 {
458 	return passDefinitions->intPassTypeFromIndex(intPassIndex);
459 }
460 
color(intPassTypes_t intPassType)461 colorA_t& colorPasses_t::color(intPassTypes_t intPassType)
462 {
463 	return colVector.at(passDefinitions->intPassIndexFromType(intPassType));
464 }
465 
color(int intPassIndex)466 colorA_t& colorPasses_t::color(int intPassIndex)
467 {
468 	return colVector.at(intPassIndex);
469 }
470 
operator ()(intPassTypes_t intPassType)471 colorA_t& colorPasses_t::operator()(intPassTypes_t intPassType)
472 {
473 	return color(intPassType);
474 }
475 
operator ()(int intPassIndex)476 colorA_t& colorPasses_t::operator()(int intPassIndex)
477 {
478 	return color(intPassIndex);
479 }
480 
reset_colors()481 void colorPasses_t::reset_colors()
482 {
483 	for(auto it = colVector.begin(); it != colVector.end(); ++it)
484 	{
485 		*it = init_color(intPassTypeFromIndex(it - colVector.begin()));
486 	}
487 }
488 
init_color(intPassTypes_t intPassType)489 colorA_t colorPasses_t::init_color(intPassTypes_t intPassType)
490 {
491 	switch(intPassType)    //Default initialization color in general is black/opaque, except for SHADOW and MASK passes where the default is black/transparent for easier masking
492 	{
493 		case PASS_INT_DEBUG_WIREFRAME:
494 		case PASS_INT_SHADOW:
495 		case PASS_INT_OBJ_INDEX_MASK:
496 		case PASS_INT_OBJ_INDEX_MASK_SHADOW:
497 		case PASS_INT_OBJ_INDEX_MASK_ALL:
498 		case PASS_INT_MAT_INDEX_MASK:
499 		case PASS_INT_MAT_INDEX_MASK_SHADOW:
500 		case PASS_INT_MAT_INDEX_MASK_ALL: return colorA_t(0.f, 0.f, 0.f, 0.f); break;
501 		default: return colorA_t(0.f, 0.f, 0.f, 1.f); break;
502 	}
503 }
504 
multiply_colors(float factor)505 void colorPasses_t::multiply_colors(float factor)
506 {
507 	for(auto it = colVector.begin(); it != colVector.end(); ++it)
508 	{
509 		*it *= factor;
510 	}
511 }
512 
probe_set(const intPassTypes_t & intPassType,const colorA_t & renderedColor,const bool & condition)513 colorA_t colorPasses_t::probe_set(const intPassTypes_t& intPassType, const colorA_t& renderedColor, const bool& condition /*= true */)
514 {
515 	if(condition && enabled(intPassType)) color(passDefinitions->intPassIndexFromType(intPassType)) = renderedColor;
516 
517 	return renderedColor;
518 }
519 
probe_set(const intPassTypes_t & intPassType,const colorPasses_t & colorPasses,const bool & condition)520 colorA_t colorPasses_t::probe_set(const intPassTypes_t& intPassType, const colorPasses_t& colorPasses, const bool& condition /*= true */)
521 {
522 	if(condition && enabled(intPassType) && colorPasses.enabled(intPassType))
523 	{
524 		int intPassIndex = passDefinitions->intPassIndexFromType(intPassType);
525 		colVector.at(intPassIndex) = colorPasses.colVector.at(intPassIndex);
526 		return colorPasses.colVector.at(intPassIndex);
527 	}
528 	else return colorA_t(0.f);
529 }
530 
probe_add(const intPassTypes_t & intPassType,const colorA_t & renderedColor,const bool & condition)531 colorA_t colorPasses_t::probe_add(const intPassTypes_t& intPassType, const colorA_t& renderedColor, const bool& condition /*= true */)
532 {
533 	if(condition && enabled(intPassType)) color(passDefinitions->intPassIndexFromType(intPassType)) += renderedColor;
534 
535 	return renderedColor;
536 }
537 
probe_add(const intPassTypes_t & intPassType,const colorPasses_t & colorPasses,const bool & condition)538 colorA_t colorPasses_t::probe_add(const intPassTypes_t& intPassType, const colorPasses_t& colorPasses, const bool& condition /*= true */)
539 {
540 	if(condition && enabled(intPassType) && colorPasses.enabled(intPassType))
541 	{
542 		int intPassIndex = passDefinitions->intPassIndexFromType(intPassType);
543 		colVector.at(intPassIndex) += colorPasses.colVector.at(intPassIndex);
544 		return  colorPasses.colVector.at(intPassIndex);
545 	}
546 	else return colorA_t(0.f);
547 }
548 
probe_mult(const intPassTypes_t & intPassType,const colorA_t & renderedColor,const bool & condition)549 colorA_t colorPasses_t::probe_mult(const intPassTypes_t& intPassType, const colorA_t& renderedColor, const bool& condition /*= true */)
550 {
551 	if(condition && enabled(intPassType)) color(passDefinitions->intPassIndexFromType(intPassType)) *= renderedColor;
552 
553 	return renderedColor;
554 }
555 
probe_mult(const intPassTypes_t & intPassType,const colorPasses_t & colorPasses,const bool & condition)556 colorA_t colorPasses_t::probe_mult(const intPassTypes_t& intPassType, const colorPasses_t& colorPasses, const bool& condition /*= true */)
557 {
558 	if(condition && enabled(intPassType) && colorPasses.enabled(intPassType))
559 	{
560 		int intPassIndex = passDefinitions->intPassIndexFromType(intPassType);
561 		colVector.at(intPassIndex) *= colorPasses.colVector.at(intPassIndex);
562 		return colorPasses.colVector.at(intPassIndex);
563 	}
564 	else return colorA_t(0.f);
565 }
566 
operator *=(float f)567 colorPasses_t & colorPasses_t::operator *= (float f)
568 {
569 	for(auto it = colVector.begin(); it != colVector.end(); ++it)
570 	{
571 		*it *= f;
572 	}
573 	return *this;
574 }
575 
operator *=(const color_t & a)576 colorPasses_t & colorPasses_t::operator *= (const color_t &a)
577 {
578 	for(auto it = colVector.begin(); it != colVector.end(); ++it)
579 	{
580 		*it *= a;
581 	}
582 	return *this;
583 }
584 
operator *=(const colorA_t & a)585 colorPasses_t & colorPasses_t::operator *= (const colorA_t &a)
586 {
587 	for(auto it = colVector.begin(); it != colVector.end(); ++it)
588 	{
589 		*it *= a;
590 	}
591 	return *this;
592 }
593 
operator +=(const colorPasses_t & a)594 colorPasses_t & colorPasses_t::operator += (const colorPasses_t &a)
595 {
596 	for(auto it = colVector.begin(); it != colVector.end(); ++it)
597 	{
598 		*it += a.colVector.at(it - colVector.begin());
599 	}
600 	return *this;
601 }
602 
get_pass_mask_obj_index() const603 float colorPasses_t::get_pass_mask_obj_index() const { return passDefinitions->pass_mask_obj_index; }
get_pass_mask_mat_index() const604 float colorPasses_t::get_pass_mask_mat_index() const { return passDefinitions->pass_mask_mat_index; }
get_pass_mask_invert() const605 bool colorPasses_t::get_pass_mask_invert() const { return passDefinitions->pass_mask_invert; }
get_pass_mask_only() const606 bool colorPasses_t::get_pass_mask_only() const { return passDefinitions->pass_mask_only; }
607 
608 
609 
size() const610 int colorPasses_t::size() const { return colVector.size(); }
611 
612 
613 __END_YAFRAY
614