Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDalai Felinto <dfelinto@gmail.com>2014-01-03 01:05:07 +0400
committerDalai Felinto <dfelinto@gmail.com>2014-05-03 04:19:09 +0400
commiteec3eaba084725a978f4aefb773a16ae9c0420db (patch)
tree68e34c3e8ff42af5263c010895b6649961f82eb6 /intern/cycles/blender
parent97641a0ec946005d9a042f075697109c6590a28d (diff)
Cycles Bake
Expand Cycles to use the new baking API in Blender. It works on the selected object, and the panel can be accessed in the Render panel (similar to where it is for the Blender Internal). It bakes for the active texture of each material of the object. The active texture is currently defined as the active Image Texture node present in the material nodetree. If you don't want the baking to override an existent material, make sure the active Image Texture node is not connected to the nodetree. The active texture is also the texture shown in the viewport in the rendered mode. Remember to save your images after the baking is complete. Note: Bake currently only works in the CPU Note: This is not supported by Cycles standalone because a lot of the work is done in Blender as part of the operator only, not the engine (Cycles). Documentation: http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Bake Supported Passes: ----------------- Data Passes * Normal * UV * Diffuse/Glossy/Transmission/Subsurface/Emit Color Light Passes * AO * Combined * Shadow * Diffuse/Glossy/Transmission/Subsurface/Emit Direct/Indirect * Environment Review: D421 Reviewed by: Campbell Barton, Brecht van Lommel, Sergey Sharybin, Thomas Dinge Original design by Brecht van Lommel. The entire commit history can be found on the branch: bake-cycles
Diffstat (limited to 'intern/cycles/blender')
-rw-r--r--intern/cycles/blender/addon/__init__.py3
-rw-r--r--intern/cycles/blender/addon/engine.py6
-rw-r--r--intern/cycles/blender/addon/properties.py27
-rw-r--r--intern/cycles/blender/addon/ui.py48
-rw-r--r--intern/cycles/blender/blender_python.cpp33
-rw-r--r--intern/cycles/blender/blender_session.cpp155
-rw-r--r--intern/cycles/blender/blender_session.h3
7 files changed, 275 insertions, 0 deletions
diff --git a/intern/cycles/blender/addon/__init__.py b/intern/cycles/blender/addon/__init__.py
index 9f42cc9bb00..27d986900c8 100644
--- a/intern/cycles/blender/addon/__init__.py
+++ b/intern/cycles/blender/addon/__init__.py
@@ -67,6 +67,9 @@ class CyclesRender(bpy.types.RenderEngine):
def render(self, scene):
engine.render(self)
+ def bake(self, scene, obj, pass_type, pixel_array, num_pixels, depth, result):
+ engine.bake(self, obj, pass_type, pixel_array, num_pixels, depth, result)
+
# viewport render
def view_update(self, context):
if not self.session:
diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py
index b9ce65588df..25a9e97a99b 100644
--- a/intern/cycles/blender/addon/engine.py
+++ b/intern/cycles/blender/addon/engine.py
@@ -59,6 +59,12 @@ def render(engine):
_cycles.render(engine.session)
+def bake(engine, obj, pass_type, pixel_array, num_pixels, depth, result):
+ import _cycles
+ session = getattr(engine, "session", None)
+ if session is not None:
+ _cycles.bake(engine.session, obj.as_pointer(), pass_type, pixel_array.as_pointer(), num_pixels, depth, result.as_pointer())
+
def reset(engine, data, scene):
import _cycles
data = data.as_pointer()
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 2b05c2148eb..7205a272395 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -471,6 +471,33 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
default=False,
)
+ cls.bake_type = EnumProperty(
+ name="Bake Type",
+ default='COMBINED',
+ description="Type of pass to bake",
+ items = (
+ ('COMBINED', "Combined", ""),
+ ('AO', "Ambient Occlusion", ""),
+ ('SHADOW', "Shadow", ""),
+ ('NORMAL', "Normal", ""),
+ ('UV', "UV", ""),
+ ('EMIT', "Emit", ""),
+ ('ENVIRONMENT', "Environment", ""),
+ ('DIFFUSE_DIRECT', "Diffuse Direct", ""),
+ ('DIFFUSE_INDIRECT', "Diffuse Indirect", ""),
+ ('DIFFUSE_COLOR', "Diffuse Color", ""),
+ ('GLOSSY_DIRECT', "Glossy Direct", ""),
+ ('GLOSSY_INDIRECT', "Glossy Indirect", ""),
+ ('GLOSSY_COLOR', "Glossy Color", ""),
+ ('TRANSMISSION_DIRECT', "Transmission Direct", ""),
+ ('TRANSMISSION_INDIRECT', "Transmission Indirect", ""),
+ ('TRANSMISSION_COLOR', "Transmission Color", ""),
+ ('SUBSURFACE_DIRECT', "Subsurface Direct", ""),
+ ('SUBSURFACE_INDIRECT', "Subsurface Indirect", ""),
+ ('SUBSURFACE_COLOR', "Subsurface Color", ""),
+ ),
+ )
+
@classmethod
def unregister(cls):
del bpy.types.Scene.cycles
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index f35cb1abd2e..5c8115b6612 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -1227,6 +1227,54 @@ class CyclesRender_PT_CurveRendering(CyclesButtonsPanel, Panel):
row.prop(ccscene, "maximum_width", text="Max Ext.")
+class CyclesRender_PT_bake(CyclesButtonsPanel, Panel):
+ bl_label = "Bake"
+ bl_context = "render"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'CYCLES'}
+
+ def draw(self, context):
+ layout = self.layout
+
+ scene = context.scene
+ cscene = scene.cycles
+
+ cbk = scene.render.bake
+
+ layout.operator("object.bake", icon='RENDER_STILL').type = \
+ cscene.bake_type
+
+ col = layout.column()
+ col.prop(cscene, "bake_type")
+
+ col.separator()
+ split = layout.split()
+
+ sub = split.column()
+ sub.prop(cbk, "use_clear")
+ sub.prop(cbk, "margin")
+
+ sub = split.column()
+ sub.prop(cbk, "use_selected_to_active")
+ sub = sub.column()
+
+ sub.active = cbk.use_selected_to_active
+ sub.prop(cbk, "cage_extrusion", text="Distance")
+ sub.prop_search(cbk, "cage", scene, "objects")
+
+ if cscene.bake_type == 'NORMAL':
+ col.separator()
+ box = col.box()
+ box.label(text="Normal Settings:")
+ box.prop(cbk, "normal_space", text="Space")
+
+ row = box.row(align=True)
+ row.label(text = "Swizzle:")
+ row.prop(cbk, "normal_r", text="")
+ row.prop(cbk, "normal_g", text="")
+ row.prop(cbk, "normal_b", text="")
+
+
class CyclesParticle_PT_CurveSettings(CyclesButtonsPanel, Panel):
bl_label = "Cycles Hair Settings"
bl_context = "particle"
diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp
index 8b04a869a85..658fccaf12e 100644
--- a/intern/cycles/blender/blender_python.cpp
+++ b/intern/cycles/blender/blender_python.cpp
@@ -147,6 +147,38 @@ static PyObject *render_func(PyObject *self, PyObject *value)
Py_RETURN_NONE;
}
+/* pixel_array and result passed as pointers */
+static PyObject *bake_func(PyObject *self, PyObject *args)
+{
+ PyObject *pysession, *pyobject;
+ PyObject *pypixel_array, *pyresult;
+ const char *pass_type;
+ int num_pixels, depth;
+
+ if(!PyArg_ParseTuple(args, "OOsOiiO", &pysession, &pyobject, &pass_type, &pypixel_array, &num_pixels, &depth, &pyresult))
+ return NULL;
+
+ Py_BEGIN_ALLOW_THREADS
+
+ BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
+
+ PointerRNA objectptr;
+ RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyobject), &objectptr);
+ BL::Object b_object(objectptr);
+
+ void *b_result = PyLong_AsVoidPtr(pyresult);
+
+ PointerRNA bakepixelptr;
+ RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pypixel_array), &bakepixelptr);
+ BL::BakePixel b_bake_pixel(bakepixelptr);
+
+ session->bake(b_object, pass_type, b_bake_pixel, num_pixels, depth, (float *)b_result);
+
+ Py_END_ALLOW_THREADS
+
+ Py_RETURN_NONE;
+}
+
static PyObject *draw_func(PyObject *self, PyObject *args)
{
PyObject *pysession, *pyv3d, *pyrv3d;
@@ -418,6 +450,7 @@ static PyMethodDef methods[] = {
{"create", create_func, METH_VARARGS, ""},
{"free", free_func, METH_O, ""},
{"render", render_func, METH_O, ""},
+ {"bake", bake_func, METH_VARARGS, ""},
{"draw", draw_func, METH_VARARGS, ""},
{"sync", sync_func, METH_O, ""},
{"reset", reset_func, METH_VARARGS, ""},
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index f5e696bc582..6f959d42680 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -14,6 +14,8 @@
* limitations under the License
*/
+#include <stdlib.h>
+
#include "background.h"
#include "buffers.h"
#include "camera.h"
@@ -21,6 +23,8 @@
#include "integrator.h"
#include "film.h"
#include "light.h"
+#include "mesh.h"
+#include "object.h"
#include "scene.h"
#include "session.h"
#include "shader.h"
@@ -259,6 +263,58 @@ static PassType get_pass_type(BL::RenderPass b_pass)
return PASS_NONE;
}
+static ShaderEvalType get_shader_type(const string& pass_type)
+{
+ const char *shader_type = pass_type.c_str();
+
+ /* data passes */
+ if(strcmp(shader_type, "NORMAL")==0)
+ return SHADER_EVAL_NORMAL;
+ else if(strcmp(shader_type, "UV")==0)
+ return SHADER_EVAL_UV;
+ else if(strcmp(shader_type, "DIFFUSE_COLOR")==0)
+ return SHADER_EVAL_DIFFUSE_COLOR;
+ else if(strcmp(shader_type, "GLOSSY_COLOR")==0)
+ return SHADER_EVAL_GLOSSY_COLOR;
+ else if(strcmp(shader_type, "TRANSMISSION_COLOR")==0)
+ return SHADER_EVAL_TRANSMISSION_COLOR;
+ else if(strcmp(shader_type, "SUBSURFACE_COLOR")==0)
+ return SHADER_EVAL_SUBSURFACE_COLOR;
+ else if(strcmp(shader_type, "EMIT")==0)
+ return SHADER_EVAL_EMISSION;
+
+ /* light passes */
+ else if(strcmp(shader_type, "AO")==0)
+ return SHADER_EVAL_AO;
+ else if(strcmp(shader_type, "COMBINED")==0)
+ return SHADER_EVAL_COMBINED;
+ else if(strcmp(shader_type, "SHADOW")==0)
+ return SHADER_EVAL_SHADOW;
+ else if(strcmp(shader_type, "DIFFUSE_DIRECT")==0)
+ return SHADER_EVAL_DIFFUSE_DIRECT;
+ else if(strcmp(shader_type, "GLOSSY_DIRECT")==0)
+ return SHADER_EVAL_GLOSSY_DIRECT;
+ else if(strcmp(shader_type, "TRANSMISSION_DIRECT")==0)
+ return SHADER_EVAL_TRANSMISSION_DIRECT;
+ else if(strcmp(shader_type, "SUBSURFACE_DIRECT")==0)
+ return SHADER_EVAL_SUBSURFACE_DIRECT;
+ else if(strcmp(shader_type, "DIFFUSE_INDIRECT")==0)
+ return SHADER_EVAL_DIFFUSE_INDIRECT;
+ else if(strcmp(shader_type, "GLOSSY_INDIRECT")==0)
+ return SHADER_EVAL_GLOSSY_INDIRECT;
+ else if(strcmp(shader_type, "TRANSMISSION_INDIRECT")==0)
+ return SHADER_EVAL_TRANSMISSION_INDIRECT;
+ else if(strcmp(shader_type, "SUBSURFACE_INDIRECT")==0)
+ return SHADER_EVAL_SUBSURFACE_INDIRECT;
+
+ /* extra */
+ else if(strcmp(shader_type, "ENVIRONMENT")==0)
+ return SHADER_EVAL_ENVIRONMENT;
+
+ else
+ return SHADER_EVAL_BAKE;
+}
+
static BL::RenderResult begin_render_result(BL::RenderEngine b_engine, int x, int y, int w, int h, const char *layername)
{
return b_engine.begin_result(x, y, w, h, layername);
@@ -425,6 +481,105 @@ void BlenderSession::render()
sync = NULL;
}
+static void populate_bake_data(BakeData *data, BL::BakePixel pixel_array, const int num_pixels)
+{
+ BL::BakePixel bp = pixel_array;
+
+ int i;
+ for(i=0; i < num_pixels; i++) {
+ data->set(i, bp.primitive_id(), bp.uv());
+ bp = bp.next();
+ }
+}
+
+static bool is_light_pass(ShaderEvalType type)
+{
+ switch (type) {
+ case SHADER_EVAL_AO:
+ case SHADER_EVAL_COMBINED:
+ case SHADER_EVAL_SHADOW:
+ case SHADER_EVAL_DIFFUSE_DIRECT:
+ case SHADER_EVAL_GLOSSY_DIRECT:
+ case SHADER_EVAL_TRANSMISSION_DIRECT:
+ case SHADER_EVAL_SUBSURFACE_DIRECT:
+ case SHADER_EVAL_DIFFUSE_INDIRECT:
+ case SHADER_EVAL_GLOSSY_INDIRECT:
+ case SHADER_EVAL_TRANSMISSION_INDIRECT:
+ case SHADER_EVAL_SUBSURFACE_INDIRECT:
+ return true;
+ default:
+ return false;
+ }
+}
+
+void BlenderSession::bake(BL::Object b_object, const string& pass_type, BL::BakePixel pixel_array, int num_pixels, int depth, float result[])
+{
+ ShaderEvalType shader_type = get_shader_type(pass_type);
+ size_t object_index = OBJECT_NONE;
+ int tri_offset = 0;
+
+ if(shader_type == SHADER_EVAL_UV) {
+ /* force UV to be available */
+ Pass::add(PASS_UV, scene->film->passes);
+ }
+
+ if(is_light_pass(shader_type)) {
+ /* force use_light_pass to be true */
+ Pass::add(PASS_LIGHT, scene->film->passes);
+ }
+
+ /* create device and update scene */
+ scene->film->tag_update(scene);
+ scene->integrator->tag_update(scene);
+
+ /* update scene */
+ sync->sync_camera(b_render, b_engine.camera_override(), width, height);
+ sync->sync_data(b_v3d, b_engine.camera_override(), &python_thread_state);
+
+ /* get buffer parameters */
+ SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
+ BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_scene, b_v3d, b_rv3d, scene->camera, width, height);
+
+ scene->bake_manager->set_baking(true);
+
+ /* set number of samples */
+ session->tile_manager.set_samples(session_params.samples);
+ session->reset(buffer_params, session_params.samples);
+ session->update_scene();
+
+ /* find object index. todo: is arbitrary - copied from mesh_displace.cpp */
+ for(size_t i = 0; i < scene->objects.size(); i++) {
+ if(strcmp(scene->objects[i]->name.c_str(), b_object.name().c_str()) == 0) {
+ object_index = i;
+ tri_offset = scene->objects[i]->mesh->tri_offset;
+ break;
+ }
+ }
+
+ /* when used, non-instanced convention: object = ~object */
+ int object = ~object_index;
+
+ BakeData *bake_data = scene->bake_manager->init(object, tri_offset, num_pixels);
+
+ populate_bake_data(bake_data, pixel_array, num_pixels);
+
+ /* set number of samples */
+ session->tile_manager.set_samples(session_params.samples);
+ session->reset(buffer_params, session_params.samples);
+ session->update_scene();
+
+ scene->bake_manager->bake(scene->device, &scene->dscene, scene, session->progress, shader_type, bake_data, result);
+
+ /* free all memory used (host and device), so we wouldn't leave render
+ * engine with extra memory allocated
+ */
+
+ session->device_free();
+
+ delete sync;
+ sync = NULL;
+}
+
void BlenderSession::do_write_update_render_result(BL::RenderResult b_rr, BL::RenderLayer b_rlay, RenderTile& rtile, bool do_update_only)
{
RenderBuffers *buffers = rtile.buffers;
diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h
index d30e3eda870..0e44493d674 100644
--- a/intern/cycles/blender/blender_session.h
+++ b/intern/cycles/blender/blender_session.h
@@ -20,6 +20,7 @@
#include "device.h"
#include "scene.h"
#include "session.h"
+#include "bake.h"
#include "util_vector.h"
@@ -51,6 +52,8 @@ public:
/* offline render */
void render();
+ void bake(BL::Object b_object, const string& pass_type, BL::BakePixel pixel_array, int num_pixels, int depth, float pixels[]);
+
void write_render_result(BL::RenderResult b_rr, BL::RenderLayer b_rlay, RenderTile& rtile);
void write_render_tile(RenderTile& rtile);