| 
									
										
										
										
											2012-04-30 14:24:11 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2013-01-24 08:14:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  |  * ***** BEGIN GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version.  | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							|  |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is Copyright (C) 2006 Blender Foundation. | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is: all of this file. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Contributor(s): none yet. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ***** END GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-05 01:48:10 +00:00
										 |  |  | /** \file blender/render/intern/source/external_engine.c
 | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  |  *  \ingroup render | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <stddef.h>
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-03 21:42:21 +00:00
										 |  |  | #include "BLF_translation.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | #include "BLI_listbase.h"
 | 
					
						
							|  |  |  | #include "BLI_string.h"
 | 
					
						
							|  |  |  | #include "BLI_utildefines.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-12 11:32:23 +00:00
										 |  |  | #include "BKE_global.h"
 | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | #include "BKE_report.h"
 | 
					
						
							|  |  |  | #include "BKE_scene.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "IMB_imbuf.h"
 | 
					
						
							|  |  |  | #include "IMB_imbuf_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-10 20:26:34 +00:00
										 |  |  | #include "RNA_access.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-22 17:01:54 +00:00
										 |  |  | #ifdef WITH_PYTHON
 | 
					
						
							|  |  |  | #include "BPY_extern.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | #include "RE_engine.h"
 | 
					
						
							|  |  |  | #include "RE_pipeline.h"
 | 
					
						
							| 
									
										
											  
											
												Bake API - bpy.ops.object.bake()
New operator that can calls a bake function to the current render engine when available. This commit provides no feature for the users, but allows external engines to be accessed by the operator and be integrated with the baking api.
The API itself is simple. Blender sends a populated array of BakePixels to the renderer, and gets back an array of floats with the result.
The Blender Internal (and multires) system is still running independent, but we eventually will pipe it through the API as well. Cycles baking will come next as a separated commit
Python Operator:
----------------
The operator can be called with some arguments, or a user interface can be created for it. In that case the arguments can be ommited and the interface can expose the settings from bpy.context.scene.render.bake
bpy.ops.object.bake(type='COMBINED', filepath="", width=512, height=512, margin=16, use_selected_to_active=False, cage_extrusion=0, cage="", normal_space='TANGENT', normal_r='POS_X', normal_g='POS_Y', normal_b='POS_Z', save_mode='INTERNAL', use_clear=False, use_split_materials=False, use_automatic_name=False)
Note: external save mode is currently disabled.
Supported Features:
------------------
 * Margin - Baked result is extended this many pixels beyond the border of each UV "island," to soften seams in the texture.
 * Selected to Active - bake shading on the surface of selected object to the active object. The rays are cast from the lowpoly object inwards towards the highpoly object. If the highpoly object is not entirely involved by the lowpoly object, you can tweak the rays start point with Cage Extrusion. For even more control of the cage you can use a Cage object.
 * Cage Extrusion - distance to use for the inward ray cast when using selected to active
 * Custom Cage - object to use as cage (instead of the lowpoly object).
 * Normal swizzle - change the axis that gets mapped to RGB
 * Normal space - save as tangent or object normal spaces
Supported Passes:
-----------------
Any pass that is supported by Blender renderlayer system. Though it's up to the external engine to provide a valid enum with its supported passes. Normal passes get a special treatment since we post-process them to converted and "swizzled"
Development Notes for External Engines:
---------------------------------------
(read them in bake_api.c)
* For a complete implementation example look at the Cycles Bake commit (next).
Review: D421
Reviewed by: Campbell Barton, Brecht van Lommel, Sergey Sharybin, Thomas Dinge
Normal map pipeline "consulting" by Andy Davies (metalliandy)
Original design by Brecht van Lommel.
The entire commit history can be found on the branch: bake-cycles
											
										 
											2014-01-02 19:05:07 -02:00
										 |  |  | #include "RE_bake.h"
 | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-04 13:29:07 +00:00
										 |  |  | #include "initrender.h"
 | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | #include "render_types.h"
 | 
					
						
							| 
									
										
										
										
											2012-01-05 17:50:09 +00:00
										 |  |  | #include "render_result.h"
 | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-22 17:01:54 +00:00
										 |  |  | /* Render Engine Types */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static RenderEngineType internal_render_type = { | 
					
						
							|  |  |  | 	NULL, NULL, | 
					
						
							| 
									
										
										
										
											2012-03-03 21:42:21 +00:00
										 |  |  | 	"BLENDER_RENDER", N_("Blender Render"), RE_INTERNAL, | 
					
						
							| 
									
										
											  
											
												Bake API - bpy.ops.object.bake()
New operator that can calls a bake function to the current render engine when available. This commit provides no feature for the users, but allows external engines to be accessed by the operator and be integrated with the baking api.
The API itself is simple. Blender sends a populated array of BakePixels to the renderer, and gets back an array of floats with the result.
The Blender Internal (and multires) system is still running independent, but we eventually will pipe it through the API as well. Cycles baking will come next as a separated commit
Python Operator:
----------------
The operator can be called with some arguments, or a user interface can be created for it. In that case the arguments can be ommited and the interface can expose the settings from bpy.context.scene.render.bake
bpy.ops.object.bake(type='COMBINED', filepath="", width=512, height=512, margin=16, use_selected_to_active=False, cage_extrusion=0, cage="", normal_space='TANGENT', normal_r='POS_X', normal_g='POS_Y', normal_b='POS_Z', save_mode='INTERNAL', use_clear=False, use_split_materials=False, use_automatic_name=False)
Note: external save mode is currently disabled.
Supported Features:
------------------
 * Margin - Baked result is extended this many pixels beyond the border of each UV "island," to soften seams in the texture.
 * Selected to Active - bake shading on the surface of selected object to the active object. The rays are cast from the lowpoly object inwards towards the highpoly object. If the highpoly object is not entirely involved by the lowpoly object, you can tweak the rays start point with Cage Extrusion. For even more control of the cage you can use a Cage object.
 * Cage Extrusion - distance to use for the inward ray cast when using selected to active
 * Custom Cage - object to use as cage (instead of the lowpoly object).
 * Normal swizzle - change the axis that gets mapped to RGB
 * Normal space - save as tangent or object normal spaces
Supported Passes:
-----------------
Any pass that is supported by Blender renderlayer system. Though it's up to the external engine to provide a valid enum with its supported passes. Normal passes get a special treatment since we post-process them to converted and "swizzled"
Development Notes for External Engines:
---------------------------------------
(read them in bake_api.c)
* For a complete implementation example look at the Cycles Bake commit (next).
Review: D421
Reviewed by: Campbell Barton, Brecht van Lommel, Sergey Sharybin, Thomas Dinge
Normal map pipeline "consulting" by Andy Davies (metalliandy)
Original design by Brecht van Lommel.
The entire commit history can be found on the branch: bake-cycles
											
										 
											2014-01-02 19:05:07 -02:00
										 |  |  | 	NULL, NULL, NULL, NULL, NULL, NULL, | 
					
						
							| 
									
										
										
										
											2012-06-16 16:57:16 +00:00
										 |  |  | 	{NULL, NULL, NULL} | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2011-10-22 17:01:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef WITH_GAMEENGINE
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static RenderEngineType internal_game_type = { | 
					
						
							|  |  |  | 	NULL, NULL, | 
					
						
							| 
									
										
										
										
											2012-06-16 16:57:16 +00:00
										 |  |  | 	"BLENDER_GAME", N_("Blender Game"), RE_INTERNAL | RE_GAME, | 
					
						
							| 
									
										
											  
											
												Bake API - bpy.ops.object.bake()
New operator that can calls a bake function to the current render engine when available. This commit provides no feature for the users, but allows external engines to be accessed by the operator and be integrated with the baking api.
The API itself is simple. Blender sends a populated array of BakePixels to the renderer, and gets back an array of floats with the result.
The Blender Internal (and multires) system is still running independent, but we eventually will pipe it through the API as well. Cycles baking will come next as a separated commit
Python Operator:
----------------
The operator can be called with some arguments, or a user interface can be created for it. In that case the arguments can be ommited and the interface can expose the settings from bpy.context.scene.render.bake
bpy.ops.object.bake(type='COMBINED', filepath="", width=512, height=512, margin=16, use_selected_to_active=False, cage_extrusion=0, cage="", normal_space='TANGENT', normal_r='POS_X', normal_g='POS_Y', normal_b='POS_Z', save_mode='INTERNAL', use_clear=False, use_split_materials=False, use_automatic_name=False)
Note: external save mode is currently disabled.
Supported Features:
------------------
 * Margin - Baked result is extended this many pixels beyond the border of each UV "island," to soften seams in the texture.
 * Selected to Active - bake shading on the surface of selected object to the active object. The rays are cast from the lowpoly object inwards towards the highpoly object. If the highpoly object is not entirely involved by the lowpoly object, you can tweak the rays start point with Cage Extrusion. For even more control of the cage you can use a Cage object.
 * Cage Extrusion - distance to use for the inward ray cast when using selected to active
 * Custom Cage - object to use as cage (instead of the lowpoly object).
 * Normal swizzle - change the axis that gets mapped to RGB
 * Normal space - save as tangent or object normal spaces
Supported Passes:
-----------------
Any pass that is supported by Blender renderlayer system. Though it's up to the external engine to provide a valid enum with its supported passes. Normal passes get a special treatment since we post-process them to converted and "swizzled"
Development Notes for External Engines:
---------------------------------------
(read them in bake_api.c)
* For a complete implementation example look at the Cycles Bake commit (next).
Review: D421
Reviewed by: Campbell Barton, Brecht van Lommel, Sergey Sharybin, Thomas Dinge
Normal map pipeline "consulting" by Andy Davies (metalliandy)
Original design by Brecht van Lommel.
The entire commit history can be found on the branch: bake-cycles
											
										 
											2014-01-02 19:05:07 -02:00
										 |  |  | 	NULL, NULL, NULL, NULL, NULL, NULL, | 
					
						
							| 
									
										
										
										
											2012-06-16 16:57:16 +00:00
										 |  |  | 	{NULL, NULL, NULL} | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2011-10-22 17:01:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ListBase R_engines = {NULL, NULL}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RE_engines_init(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BLI_addtail(&R_engines, &internal_render_type); | 
					
						
							|  |  |  | #ifdef WITH_GAMEENGINE
 | 
					
						
							|  |  |  | 	BLI_addtail(&R_engines, &internal_game_type); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RE_engines_exit(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	RenderEngineType *type, *next; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-16 16:57:16 +00:00
										 |  |  | 	for (type = R_engines.first; type; type = next) { | 
					
						
							|  |  |  | 		next = type->next; | 
					
						
							| 
									
										
										
										
											2011-10-22 17:01:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		BLI_remlink(&R_engines, type); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		if (!(type->flag & RE_INTERNAL)) { | 
					
						
							|  |  |  | 			if (type->ext.free) | 
					
						
							| 
									
										
										
										
											2011-10-22 17:01:54 +00:00
										 |  |  | 				type->ext.free(type->ext.data); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			MEM_freeN(type); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | RenderEngineType *RE_engines_find(const char *idname) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	RenderEngineType *type; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-06-16 16:57:16 +00:00
										 |  |  | 	type = BLI_findstring(&R_engines, idname, offsetof(RenderEngineType, idname)); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (!type) | 
					
						
							| 
									
										
										
										
											2012-06-16 16:57:16 +00:00
										 |  |  | 		type = &internal_render_type; | 
					
						
							| 
									
										
											  
											
												Blender Internal Render in viewport
Because of our release soon, feature has been added behind the Debug Menu.
CTRL+ALT+D and set it to -1. Or commandline --debug-value -1.
When debug set to -1, you can put the viewport to 'render' mode, just like
for Cycles. Notes for testers: (and please no bugs in tracker for this :)
- It renders without AA, MBlur, Panorama, Sequence, Composite
- Only active render layer gets rendered. Select another layer will re-render.
- But yes: it works for FreeStyle renders!
- Also does great for local view.
- BI is not well suited for incremental renders on view changes. This only
  works for non-raytrace scenes, or zoom in ortho or camera mode, or for 
  Material changes. In most cases a full re-render is being done.
- ESC works to stop the preview render.
- Borders render as well. (CTRL+B)
- Force a refresh with arrow key left/right. A lot of settings don't trigger
  re-render yet.
Tech notes:
- FreeStyle is adding a lot of temp objects/meshes in the Main database. This
caused DepsGraph to trigger changes (and redraws). I've prepended the names
for these temp objects with char number 27 (ESC), and made these names be
ignored for tag update checking.
- Fixed some bugs that were noticable with such excessive re-renders, like 
  for opening file window, quit during renders.
											
										 
											2013-04-16 17:39:20 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2011-10-22 17:01:54 +00:00
										 |  |  | 	return type; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-03 18:55:59 +11:00
										 |  |  | bool RE_engine_is_external(Render *re) | 
					
						
							| 
									
										
										
										
											2011-11-26 18:33:31 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-06-16 16:57:16 +00:00
										 |  |  | 	RenderEngineType *type = RE_engines_find(re->r.engine); | 
					
						
							| 
									
										
										
										
											2011-11-26 18:33:31 +00:00
										 |  |  | 	return (type && type->render); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-22 17:01:54 +00:00
										 |  |  | /* Create, Free */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | RenderEngine *RE_engine_create(RenderEngineType *type) | 
					
						
							| 
									
										
										
										
											2013-01-24 08:14:20 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-04-01 11:34:00 +11:00
										 |  |  | 	return RE_engine_create_ex(type, false); | 
					
						
							| 
									
										
										
										
											2013-01-24 08:14:20 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-20 23:14:18 +00:00
										 |  |  | RenderEngine *RE_engine_create_ex(RenderEngineType *type, bool use_for_viewport) | 
					
						
							| 
									
										
										
										
											2011-10-22 17:01:54 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	RenderEngine *engine = MEM_callocN(sizeof(RenderEngine), "RenderEngine"); | 
					
						
							| 
									
										
										
										
											2012-06-16 16:57:16 +00:00
										 |  |  | 	engine->type = type; | 
					
						
							| 
									
										
										
										
											2011-10-22 17:01:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-24 08:14:20 +00:00
										 |  |  | 	if (use_for_viewport) { | 
					
						
							|  |  |  | 		engine->flag |= RE_ENGINE_USED_FOR_VIEWPORT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		BLI_begin_threaded_malloc(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-22 17:01:54 +00:00
										 |  |  | 	return engine; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RE_engine_free(RenderEngine *engine) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-11-02 14:33:14 +00:00
										 |  |  | #ifdef WITH_PYTHON
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (engine->py_instance) { | 
					
						
							| 
									
										
										
										
											2012-10-26 10:54:02 +00:00
										 |  |  | 		BPY_DECREF_RNA_INVALIDATE(engine->py_instance); | 
					
						
							| 
									
										
										
										
											2011-11-02 14:33:14 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-24 08:14:20 +00:00
										 |  |  | 	if (engine->flag & RE_ENGINE_USED_FOR_VIEWPORT) { | 
					
						
							|  |  |  | 		BLI_end_threaded_malloc(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-22 17:01:54 +00:00
										 |  |  | 	MEM_freeN(engine); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Render Results */ | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-01 16:15:13 +00:00
										 |  |  | static RenderPart *get_part_from_result(Render *re, RenderResult *result) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	RenderPart *pa; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (pa = re->parts.first; pa; pa = pa->next) { | 
					
						
							|  |  |  | 		if (result->tilerect.xmin == pa->disprect.xmin - re->disprect.xmin && | 
					
						
							|  |  |  | 		    result->tilerect.ymin == pa->disprect.ymin - re->disprect.ymin && | 
					
						
							|  |  |  | 		    result->tilerect.xmax == pa->disprect.xmax - re->disprect.xmin && | 
					
						
							|  |  |  | 		    result->tilerect.ymax == pa->disprect.ymax - re->disprect.ymin) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			return pa; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-04 13:29:07 +00:00
										 |  |  | RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w, int h, const char *layername) | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-06-16 16:57:16 +00:00
										 |  |  | 	Render *re = engine->re; | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | 	RenderResult *result; | 
					
						
							|  |  |  | 	rcti disprect; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* ensure the coordinates are within the right limits */ | 
					
						
							|  |  |  | 	CLAMP(x, 0, re->result->rectx); | 
					
						
							|  |  |  | 	CLAMP(y, 0, re->result->recty); | 
					
						
							|  |  |  | 	CLAMP(w, 0, re->result->rectx); | 
					
						
							|  |  |  | 	CLAMP(h, 0, re->result->recty); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (x + w > re->result->rectx) | 
					
						
							| 
									
										
										
										
											2012-06-16 16:57:16 +00:00
										 |  |  | 		w = re->result->rectx - x; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (y + h > re->result->recty) | 
					
						
							| 
									
										
										
										
											2012-06-16 16:57:16 +00:00
										 |  |  | 		h = re->result->recty - y; | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* allocate a render result */ | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 	disprect.xmin = x; | 
					
						
							| 
									
										
										
										
											2012-06-16 16:57:16 +00:00
										 |  |  | 	disprect.xmax = x + w; | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 	disprect.ymin = y; | 
					
						
							| 
									
										
										
										
											2012-06-16 16:57:16 +00:00
										 |  |  | 	disprect.ymax = y + h; | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-04 13:29:07 +00:00
										 |  |  | 	result = render_result_new(re, &disprect, 0, RR_USE_MEM, layername); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* todo: make this thread safe */ | 
					
						
							| 
									
										
										
										
											2012-07-06 14:24:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* can be NULL if we CLAMP the width or height to 0 */ | 
					
						
							|  |  |  | 	if (result) { | 
					
						
							| 
									
										
										
										
											2013-01-01 16:15:13 +00:00
										 |  |  | 		RenderPart *pa; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-08 15:43:49 +11:00
										 |  |  | 		/* Copy EXR tile settings, so pipeline knows whether this is a result
 | 
					
						
							|  |  |  | 		 * for Save Buffers enabled rendering. | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		result->do_exr_tile = re->result->do_exr_tile; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-06 14:24:41 +00:00
										 |  |  | 		BLI_addtail(&engine->fullresult, result); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		result->tilerect.xmin += re->disprect.xmin; | 
					
						
							|  |  |  | 		result->tilerect.xmax += re->disprect.xmin; | 
					
						
							|  |  |  | 		result->tilerect.ymin += re->disprect.ymin; | 
					
						
							|  |  |  | 		result->tilerect.ymax += re->disprect.ymin; | 
					
						
							| 
									
										
										
										
											2013-01-01 16:15:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		pa = get_part_from_result(re, result); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (pa) | 
					
						
							|  |  |  | 			pa->status = PART_STATUS_IN_PROGRESS; | 
					
						
							| 
									
										
										
										
											2012-07-06 14:24:41 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RE_engine_update_result(RenderEngine *engine, RenderResult *result) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-06-16 16:57:16 +00:00
										 |  |  | 	Render *re = engine->re; | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (result) { | 
					
						
							| 
									
										
										
										
											2012-07-07 22:51:57 +00:00
										 |  |  | 		result->renlay = result->layers.first; /* weak, draws first layer always */ | 
					
						
							| 
									
										
										
										
											2013-12-17 23:42:38 +06:00
										 |  |  | 		re->display_update(re->duh, result, NULL); | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 23:42:38 +06:00
										 |  |  | void RE_engine_end_result(RenderEngine *engine, RenderResult *result, int cancel, int merge_results) | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-06-16 16:57:16 +00:00
										 |  |  | 	Render *re = engine->re; | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-04 18:27:47 +00:00
										 |  |  | 	if (!result) { | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2012-09-04 18:27:47 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* merge. on break, don't merge in result for preview renders, looks nicer */ | 
					
						
							| 
									
										
										
										
											2012-09-04 13:29:07 +00:00
										 |  |  | 	if (!cancel) { | 
					
						
							|  |  |  | 		/* for exr tile render, detect tiles that are done */ | 
					
						
							| 
									
										
										
										
											2013-01-01 16:15:13 +00:00
										 |  |  | 		RenderPart *pa = get_part_from_result(re, result); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-11 12:22:29 +00:00
										 |  |  | 		if (pa) { | 
					
						
							| 
									
										
										
										
											2013-01-01 16:15:13 +00:00
										 |  |  | 			pa->status = PART_STATUS_READY; | 
					
						
							| 
									
										
										
										
											2013-07-11 12:22:29 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else if (re->result->do_exr_tile) { | 
					
						
							|  |  |  | 			/* if written result does not match any tile and we are using save
 | 
					
						
							|  |  |  | 			 * buffers, we are going to get openexr save errors */ | 
					
						
							|  |  |  | 			fprintf(stderr, "RenderEngine.end_result: dimensions do not match any OpenEXR tile.\n"); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-12-17 23:42:38 +06:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 23:42:38 +06:00
										 |  |  | 	if (!cancel || merge_results) { | 
					
						
							| 
									
										
										
										
											2014-01-01 16:59:38 +06:00
										 |  |  | 		if (re->result->do_exr_tile) { | 
					
						
							|  |  |  | 			if (!cancel) { | 
					
						
							|  |  |  | 				render_result_exr_file_merge(re->result, result); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-05-15 17:09:45 +00:00
										 |  |  | 		else if (!(re->test_break(re->tbh) && (re->r.scemode & R_BUTS_PREVIEW))) | 
					
						
							| 
									
										
										
										
											2012-09-04 13:29:07 +00:00
										 |  |  | 			render_result_merge(re->result, result); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* draw */ | 
					
						
							|  |  |  | 		if (!re->test_break(re->tbh)) { | 
					
						
							|  |  |  | 			result->renlay = result->layers.first; /* weak, draws first layer always */ | 
					
						
							| 
									
										
										
										
											2013-12-17 23:42:38 +06:00
										 |  |  | 			re->display_update(re->duh, result, NULL); | 
					
						
							| 
									
										
										
										
											2012-09-04 13:29:07 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* free */ | 
					
						
							| 
									
										
										
										
											2012-09-04 13:29:07 +00:00
										 |  |  | 	BLI_remlink(&engine->fullresult, result); | 
					
						
							|  |  |  | 	render_result_free(result); | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Cancel */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int RE_engine_test_break(RenderEngine *engine) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-06-16 16:57:16 +00:00
										 |  |  | 	Render *re = engine->re; | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (re) | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | 		return re->test_break(re->tbh); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Statistics */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RE_engine_update_stats(RenderEngine *engine, const char *stats, const char *info) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-06-16 16:57:16 +00:00
										 |  |  | 	Render *re = engine->re; | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-22 17:01:54 +00:00
										 |  |  | 	/* stats draw callback */ | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (re) { | 
					
						
							| 
									
										
										
										
											2012-06-16 16:57:16 +00:00
										 |  |  | 		re->i.statstr = stats; | 
					
						
							|  |  |  | 		re->i.infostr = info; | 
					
						
							| 
									
										
										
										
											2011-10-22 17:01:54 +00:00
										 |  |  | 		re->stats_draw(re->sdh, &re->i); | 
					
						
							| 
									
										
										
										
											2012-06-16 16:57:16 +00:00
										 |  |  | 		re->i.infostr = NULL; | 
					
						
							|  |  |  | 		re->i.statstr = NULL; | 
					
						
							| 
									
										
										
										
											2011-10-22 17:01:54 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-11-02 14:33:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* set engine text */ | 
					
						
							| 
									
										
										
										
											2013-07-12 20:31:30 +00:00
										 |  |  | 	engine->text[0] = '\0'; | 
					
						
							| 
									
										
										
										
											2011-11-02 14:33:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (stats && stats[0] && info && info[0]) | 
					
						
							| 
									
										
										
										
											2013-07-12 20:31:30 +00:00
										 |  |  | 		BLI_snprintf(engine->text, sizeof(engine->text), "%s | %s", stats, info); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	else if (info && info[0]) | 
					
						
							| 
									
										
										
										
											2013-07-12 20:31:30 +00:00
										 |  |  | 		BLI_strncpy(engine->text, info, sizeof(engine->text)); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	else if (stats && stats[0]) | 
					
						
							| 
									
										
										
										
											2013-07-26 10:11:18 +00:00
										 |  |  | 		BLI_strncpy(engine->text, stats, sizeof(engine->text)); | 
					
						
							| 
									
										
										
										
											2011-10-22 17:01:54 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RE_engine_update_progress(RenderEngine *engine, float progress) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-06-16 16:57:16 +00:00
										 |  |  | 	Render *re = engine->re; | 
					
						
							| 
									
										
										
										
											2011-10-22 17:01:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (re) { | 
					
						
							| 
									
										
										
										
											2011-10-22 17:01:54 +00:00
										 |  |  | 		CLAMP(progress, 0.0f, 1.0f); | 
					
						
							|  |  |  | 		re->progress(re->prh, progress); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-05 08:04:57 +00:00
										 |  |  | void RE_engine_update_memory_stats(RenderEngine *engine, float mem_used, float mem_peak) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Render *re = engine->re; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (re) { | 
					
						
							|  |  |  | 		re->i.mem_used = mem_used; | 
					
						
							|  |  |  | 		re->i.mem_peak = mem_peak; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | void RE_engine_report(RenderEngine *engine, int type, const char *msg) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-11-03 14:32:26 +00:00
										 |  |  | 	Render *re = engine->re; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (re) | 
					
						
							|  |  |  | 		BKE_report(engine->re->reports, type, msg); | 
					
						
							| 
									
										
										
										
											2012-11-07 01:02:28 +00:00
										 |  |  | 	else if (engine->reports) | 
					
						
							| 
									
										
										
										
											2012-11-03 14:32:26 +00:00
										 |  |  | 		BKE_report(engine->reports, type, msg); | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-01 16:15:13 +00:00
										 |  |  | void RE_engine_get_current_tiles(Render *re, int *total_tiles_r, rcti **tiles_r) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	RenderPart *pa; | 
					
						
							|  |  |  | 	int total_tiles = 0; | 
					
						
							|  |  |  | 	rcti *tiles = NULL; | 
					
						
							|  |  |  | 	int allocation_size = 0, allocation_step = BLENDER_MAX_THREADS; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (re->engine && (re->engine->flag & RE_ENGINE_HIGHLIGHT_TILES) == 0) { | 
					
						
							|  |  |  | 		*total_tiles_r = 0; | 
					
						
							|  |  |  | 		*tiles_r = NULL; | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (pa = re->parts.first; pa; pa = pa->next) { | 
					
						
							|  |  |  | 		if (pa->status == PART_STATUS_IN_PROGRESS) { | 
					
						
							|  |  |  | 			if (total_tiles >= allocation_size) { | 
					
						
							|  |  |  | 				if (tiles == NULL) | 
					
						
							|  |  |  | 					tiles = MEM_mallocN(allocation_step * sizeof(rcti), "current engine tiles"); | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					tiles = MEM_reallocN(tiles, (total_tiles + allocation_step) * sizeof(rcti)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				allocation_size += allocation_step; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			tiles[total_tiles] = pa->disprect; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (pa->crop) { | 
					
						
							|  |  |  | 				tiles[total_tiles].xmin += pa->crop; | 
					
						
							|  |  |  | 				tiles[total_tiles].ymin += pa->crop; | 
					
						
							|  |  |  | 				tiles[total_tiles].xmax -= pa->crop; | 
					
						
							|  |  |  | 				tiles[total_tiles].ymax -= pa->crop; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			total_tiles++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	*total_tiles_r = total_tiles; | 
					
						
							|  |  |  | 	*tiles_r = tiles; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-14 07:38:37 +00:00
										 |  |  | RenderData *RE_engine_get_render_data(Render *re) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return &re->r; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Bake API - bpy.ops.object.bake()
New operator that can calls a bake function to the current render engine when available. This commit provides no feature for the users, but allows external engines to be accessed by the operator and be integrated with the baking api.
The API itself is simple. Blender sends a populated array of BakePixels to the renderer, and gets back an array of floats with the result.
The Blender Internal (and multires) system is still running independent, but we eventually will pipe it through the API as well. Cycles baking will come next as a separated commit
Python Operator:
----------------
The operator can be called with some arguments, or a user interface can be created for it. In that case the arguments can be ommited and the interface can expose the settings from bpy.context.scene.render.bake
bpy.ops.object.bake(type='COMBINED', filepath="", width=512, height=512, margin=16, use_selected_to_active=False, cage_extrusion=0, cage="", normal_space='TANGENT', normal_r='POS_X', normal_g='POS_Y', normal_b='POS_Z', save_mode='INTERNAL', use_clear=False, use_split_materials=False, use_automatic_name=False)
Note: external save mode is currently disabled.
Supported Features:
------------------
 * Margin - Baked result is extended this many pixels beyond the border of each UV "island," to soften seams in the texture.
 * Selected to Active - bake shading on the surface of selected object to the active object. The rays are cast from the lowpoly object inwards towards the highpoly object. If the highpoly object is not entirely involved by the lowpoly object, you can tweak the rays start point with Cage Extrusion. For even more control of the cage you can use a Cage object.
 * Cage Extrusion - distance to use for the inward ray cast when using selected to active
 * Custom Cage - object to use as cage (instead of the lowpoly object).
 * Normal swizzle - change the axis that gets mapped to RGB
 * Normal space - save as tangent or object normal spaces
Supported Passes:
-----------------
Any pass that is supported by Blender renderlayer system. Though it's up to the external engine to provide a valid enum with its supported passes. Normal passes get a special treatment since we post-process them to converted and "swizzled"
Development Notes for External Engines:
---------------------------------------
(read them in bake_api.c)
* For a complete implementation example look at the Cycles Bake commit (next).
Review: D421
Reviewed by: Campbell Barton, Brecht van Lommel, Sergey Sharybin, Thomas Dinge
Normal map pipeline "consulting" by Andy Davies (metalliandy)
Original design by Brecht van Lommel.
The entire commit history can be found on the branch: bake-cycles
											
										 
											2014-01-02 19:05:07 -02:00
										 |  |  | /* Bake */ | 
					
						
							|  |  |  | void RE_bake_engine_set_engine_parameters(Render *re, Main *bmain, Scene *scene) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	re->scene = scene; | 
					
						
							|  |  |  | 	re->main = bmain; | 
					
						
							|  |  |  | 	re->r = scene->r; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* prevent crash when freeing the scene
 | 
					
						
							|  |  |  | 	 but it potentially leaves unfreed memory blocks | 
					
						
							|  |  |  | 	 not sure how to fix this yet -- dfelinto */ | 
					
						
							|  |  |  | 	re->r.layers.first = re->r.layers.last = NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool RE_bake_has_engine(Render *re) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	RenderEngineType *type = RE_engines_find(re->r.engine); | 
					
						
							|  |  |  | 	return (bool)(type->bake); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool RE_bake_engine( | 
					
						
							|  |  |  |         Render *re, Object *object, const BakePixel pixel_array[], | 
					
						
							|  |  |  |         const int num_pixels, const int depth, | 
					
						
							|  |  |  |         const ScenePassType pass_type, float result[]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	RenderEngineType *type = RE_engines_find(re->r.engine); | 
					
						
							|  |  |  | 	RenderEngine *engine; | 
					
						
							|  |  |  | 	int persistent_data = re->r.mode & R_PERSISTENT_DATA; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* set render info */ | 
					
						
							|  |  |  | 	re->i.cfra = re->scene->r.cfra; | 
					
						
							|  |  |  | 	BLI_strncpy(re->i.scene_name, re->scene->id.name + 2, sizeof(re->i.scene_name) - 2); | 
					
						
							|  |  |  | 	re->i.totface = re->i.totvert = re->i.totstrand = re->i.totlamp = re->i.tothalo = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* render */ | 
					
						
							|  |  |  | 	engine = re->engine; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!engine) { | 
					
						
							|  |  |  | 		engine = RE_engine_create(type); | 
					
						
							|  |  |  | 		re->engine = engine; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	engine->flag |= RE_ENGINE_RENDERING; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* TODO: actually link to a parent which shouldn't happen */ | 
					
						
							|  |  |  | 	engine->re = re; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	engine->resolution_x = re->winx; | 
					
						
							|  |  |  | 	engine->resolution_y = re->winy; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	RE_parts_init(re, false); | 
					
						
							|  |  |  | 	engine->tile_x = re->partx; | 
					
						
							|  |  |  | 	engine->tile_y = re->party; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* update is only called so we create the engine.session */ | 
					
						
							|  |  |  | 	if (type->update) | 
					
						
							|  |  |  | 		type->update(engine, re->main, re->scene); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (type->bake) | 
					
						
							|  |  |  | 		type->bake(engine, re->scene, object, pass_type, pixel_array, num_pixels, depth, result); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	engine->tile_x = 0; | 
					
						
							|  |  |  | 	engine->tile_y = 0; | 
					
						
							|  |  |  | 	engine->flag &= ~RE_ENGINE_RENDERING; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* re->engine becomes zero if user changed active render engine during render */ | 
					
						
							|  |  |  | 	if (!persistent_data || !re->engine) { | 
					
						
							|  |  |  | 		RE_engine_free(engine); | 
					
						
							|  |  |  | 		re->engine = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	RE_parts_free(re); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (BKE_reports_contain(re->reports, RPT_ERROR)) | 
					
						
							|  |  |  | 		G.is_break = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-21 15:47:11 +02:00
										 |  |  | void RE_engine_frame_set(RenderEngine *engine, int frame, float subframe) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Render *re = engine->re; | 
					
						
							|  |  |  | 	Scene *scene = re->scene; | 
					
						
							|  |  |  | 	double cfra = (double)frame + (double)subframe; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	CLAMP(cfra, MINAFRAME, MAXFRAME); | 
					
						
							|  |  |  | 	BKE_scene_frame_set(scene, cfra); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef WITH_PYTHON
 | 
					
						
							|  |  |  | 	BPy_BEGIN_ALLOW_THREADS; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* It's possible that here we're including layers which were never visible before. */ | 
					
						
							|  |  |  | 	BKE_scene_update_for_newframe_ex(re->eval_ctx, re->main, scene, (1 << 20) - 1, true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef WITH_PYTHON
 | 
					
						
							|  |  |  | 	BPy_END_ALLOW_THREADS; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BKE_scene_camera_switch_update(scene); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | /* Render */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-10 20:26:34 +00:00
										 |  |  | static bool render_layer_exclude_animated(Scene *scene, SceneRenderLayer *srl) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PointerRNA ptr; | 
					
						
							|  |  |  | 	PropertyRNA *prop; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	RNA_pointer_create(&scene->id, &RNA_SceneRenderLayer, srl, &ptr); | 
					
						
							|  |  |  | 	prop = RNA_struct_find_property(&ptr, "layers_exclude"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return RNA_property_animated(&ptr, prop); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | int RE_engine_render(Render *re, int do_all) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-06-16 16:57:16 +00:00
										 |  |  | 	RenderEngineType *type = RE_engines_find(re->r.engine); | 
					
						
							| 
									
										
										
										
											2011-10-22 17:01:54 +00:00
										 |  |  | 	RenderEngine *engine; | 
					
						
							| 
									
										
										
										
											2012-11-13 11:00:46 +00:00
										 |  |  | 	int persistent_data = re->r.mode & R_PERSISTENT_DATA; | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-22 17:01:54 +00:00
										 |  |  | 	/* verify if we can render */ | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (!type->render) | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2013-05-15 17:09:45 +00:00
										 |  |  | 	if ((re->r.scemode & R_BUTS_PREVIEW) && !(type->flag & RE_USE_PREVIEW)) | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (do_all && !(type->flag & RE_USE_POSTPROCESS)) | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (!do_all && (type->flag & RE_USE_POSTPROCESS)) | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | 		return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-27 18:52:41 +06:00
										 |  |  | 	/* Lock drawing in UI during data phase. */ | 
					
						
							|  |  |  | 	if (re->draw_lock) { | 
					
						
							|  |  |  | 		re->draw_lock(re->dlh, 1); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-16 12:03:21 +00:00
										 |  |  | 	/* update animation here so any render layer animation is applied before
 | 
					
						
							|  |  |  | 	 * creating the render result */ | 
					
						
							| 
									
										
										
										
											2013-06-10 13:53:38 +00:00
										 |  |  | 	if ((re->r.scemode & (R_NO_FRAME_UPDATE | R_BUTS_PREVIEW)) == 0) { | 
					
						
							|  |  |  | 		unsigned int lay = re->lay; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* don't update layers excluded on all render layers */ | 
					
						
							|  |  |  | 		if (type->flag & RE_USE_EXCLUDE_LAYERS) { | 
					
						
							|  |  |  | 			SceneRenderLayer *srl; | 
					
						
							|  |  |  | 			unsigned int non_excluded_lay = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (re->r.scemode & R_SINGLE_LAYER) { | 
					
						
							|  |  |  | 				srl = BLI_findlink(&re->r.layers, re->r.actlay); | 
					
						
							| 
									
										
										
										
											2013-09-10 20:26:34 +00:00
										 |  |  | 				if (srl) { | 
					
						
							| 
									
										
										
										
											2013-06-10 13:53:38 +00:00
										 |  |  | 					non_excluded_lay |= ~srl->lay_exclude; | 
					
						
							| 
									
										
										
										
											2013-09-10 20:26:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					/* in this case we must update all because animation for
 | 
					
						
							|  |  |  | 					 * the scene has not been updated yet, and so may not be | 
					
						
							|  |  |  | 					 * up to date until after BKE_scene_update_for_newframe */ | 
					
						
							|  |  |  | 					if (render_layer_exclude_animated(re->scene, srl)) | 
					
						
							|  |  |  | 						non_excluded_lay |= ~0; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2013-06-10 13:53:38 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2013-09-10 20:26:34 +00:00
										 |  |  | 				for (srl = re->r.layers.first; srl; srl = srl->next) { | 
					
						
							|  |  |  | 					if (!(srl->layflag & SCE_LAY_DISABLE)) { | 
					
						
							| 
									
										
										
										
											2013-06-10 13:53:38 +00:00
										 |  |  | 						non_excluded_lay |= ~srl->lay_exclude; | 
					
						
							| 
									
										
										
										
											2013-09-10 20:26:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 						if (render_layer_exclude_animated(re->scene, srl)) | 
					
						
							|  |  |  | 							non_excluded_lay |= ~0; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2013-06-10 13:53:38 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			lay &= non_excluded_lay; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-26 17:24:42 +06:00
										 |  |  | 		BKE_scene_update_for_newframe(re->eval_ctx, re->main, re->scene, lay); | 
					
						
							| 
									
										
										
										
											2013-06-10 13:53:38 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-05-16 12:03:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | 	/* create render result */ | 
					
						
							|  |  |  | 	BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); | 
					
						
							| 
									
										
										
										
											2013-05-15 17:09:45 +00:00
										 |  |  | 	if (re->result == NULL || !(re->r.scemode & R_BUTS_PREVIEW)) { | 
					
						
							| 
									
										
										
										
											2013-07-11 12:22:29 +00:00
										 |  |  | 		int savebuffers = RR_USE_MEM; | 
					
						
							| 
									
										
										
										
											2012-09-04 13:29:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		if (re->result) | 
					
						
							| 
									
										
										
										
											2012-01-05 17:50:09 +00:00
										 |  |  | 			render_result_free(re->result); | 
					
						
							| 
									
										
										
										
											2012-09-04 13:29:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-11 12:22:29 +00:00
										 |  |  | 		if ((type->flag & RE_USE_SAVE_BUFFERS) && (re->r.scemode & R_EXR_TILE_FILE)) | 
					
						
							|  |  |  | 			savebuffers = RR_USE_EXR; | 
					
						
							| 
									
										
										
										
											2012-09-04 13:29:07 +00:00
										 |  |  | 		re->result = render_result_new(re, &re->disprect, 0, savebuffers, RR_ALL_LAYERS); | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	BLI_rw_mutex_unlock(&re->resultmutex); | 
					
						
							| 
									
										
										
										
											2012-09-04 13:29:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-27 18:52:41 +06:00
										 |  |  | 	if (re->result == NULL) { | 
					
						
							|  |  |  | 		/* Clear UI drawing locks. */ | 
					
						
							|  |  |  | 		if (re->draw_lock) { | 
					
						
							|  |  |  | 			re->draw_lock(re->dlh, 0); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | 		return 1; | 
					
						
							| 
									
										
										
										
											2013-12-27 18:52:41 +06:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-16 12:47:37 +00:00
										 |  |  | 	/* set render info */ | 
					
						
							| 
									
										
										
										
											2012-06-16 16:57:16 +00:00
										 |  |  | 	re->i.cfra = re->scene->r.cfra; | 
					
						
							| 
									
										
										
										
											2012-07-08 00:04:41 +00:00
										 |  |  | 	BLI_strncpy(re->i.scene_name, re->scene->id.name + 2, sizeof(re->i.scene_name)); | 
					
						
							| 
									
										
										
										
											2012-06-16 16:57:16 +00:00
										 |  |  | 	re->i.totface = re->i.totvert = re->i.totstrand = re->i.totlamp = re->i.tothalo = 0; | 
					
						
							| 
									
										
										
										
											2011-11-16 12:47:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-22 17:01:54 +00:00
										 |  |  | 	/* render */ | 
					
						
							| 
									
										
										
										
											2012-11-09 08:46:53 +00:00
										 |  |  | 	engine = re->engine; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-13 11:00:46 +00:00
										 |  |  | 	if (!engine) { | 
					
						
							|  |  |  | 		engine = RE_engine_create(type); | 
					
						
							| 
									
										
										
										
											2013-01-01 16:15:13 +00:00
										 |  |  | 		re->engine = engine; | 
					
						
							| 
									
										
										
										
											2012-11-13 11:00:46 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	engine->flag |= RE_ENGINE_RENDERING; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-09 08:46:53 +00:00
										 |  |  | 	/* TODO: actually link to a parent which shouldn't happen */ | 
					
						
							| 
									
										
										
										
											2012-06-16 16:57:16 +00:00
										 |  |  | 	engine->re = re; | 
					
						
							| 
									
										
										
										
											2011-10-22 17:01:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (re->flag & R_ANIMATION) | 
					
						
							| 
									
										
										
										
											2011-11-02 13:36:28 +00:00
										 |  |  | 		engine->flag |= RE_ENGINE_ANIMATION; | 
					
						
							| 
									
										
										
										
											2013-05-15 17:09:45 +00:00
										 |  |  | 	if (re->r.scemode & R_BUTS_PREVIEW) | 
					
						
							| 
									
										
										
										
											2011-11-02 13:36:28 +00:00
										 |  |  | 		engine->flag |= RE_ENGINE_PREVIEW; | 
					
						
							| 
									
										
										
										
											2012-04-13 17:42:03 +00:00
										 |  |  | 	engine->camera_override = re->camera_override; | 
					
						
							| 
									
										
										
										
											2011-11-02 13:36:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-04 13:29:07 +00:00
										 |  |  | 	engine->resolution_x = re->winx; | 
					
						
							|  |  |  | 	engine->resolution_y = re->winy; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-01 11:34:00 +11:00
										 |  |  | 	RE_parts_init(re, false); | 
					
						
							| 
									
										
										
										
											2012-09-04 13:29:07 +00:00
										 |  |  | 	engine->tile_x = re->partx; | 
					
						
							|  |  |  | 	engine->tile_y = re->party; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (re->result->do_exr_tile) | 
					
						
							|  |  |  | 		render_result_exr_file_begin(re); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (type->update) | 
					
						
							| 
									
										
										
										
											2011-11-02 14:33:14 +00:00
										 |  |  | 		type->update(engine, re->main, re->scene); | 
					
						
							| 
									
										
										
										
											2013-12-27 18:52:41 +06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* Clear UI drawing locks. */ | 
					
						
							|  |  |  | 	if (re->draw_lock) { | 
					
						
							|  |  |  | 		re->draw_lock(re->dlh, 0); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (type->render) | 
					
						
							| 
									
										
										
										
											2011-11-02 14:33:14 +00:00
										 |  |  | 		type->render(engine, re->scene); | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-13 11:00:46 +00:00
										 |  |  | 	engine->tile_x = 0; | 
					
						
							|  |  |  | 	engine->tile_y = 0; | 
					
						
							|  |  |  | 	engine->flag &= ~RE_ENGINE_RENDERING; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-19 16:42:14 +00:00
										 |  |  | 	render_result_free_list(&engine->fullresult, engine->fullresult.first); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-13 11:00:46 +00:00
										 |  |  | 	/* re->engine becomes zero if user changed active render engine during render */ | 
					
						
							|  |  |  | 	if (!persistent_data || !re->engine) { | 
					
						
							|  |  |  | 		RE_engine_free(engine); | 
					
						
							| 
									
										
										
										
											2012-11-09 23:54:58 +00:00
										 |  |  | 		re->engine = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-04 13:29:07 +00:00
										 |  |  | 	if (re->result->do_exr_tile) { | 
					
						
							|  |  |  | 		BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); | 
					
						
							|  |  |  | 		render_result_exr_file_end(re); | 
					
						
							|  |  |  | 		BLI_rw_mutex_unlock(&re->resultmutex); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-21 10:20:38 +00:00
										 |  |  | 	RE_parts_free(re); | 
					
						
							| 
									
										
										
										
											2012-09-04 13:29:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (BKE_reports_contain(re->reports, RPT_ERROR)) | 
					
						
							| 
									
										
										
										
											2014-04-01 11:34:00 +11:00
										 |  |  | 		G.is_break = true; | 
					
						
							| 
									
										
										
										
											2012-03-12 11:32:23 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2011-10-22 16:24:28 +00:00
										 |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 |