diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2013-01-28 21:37:51 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2013-01-28 21:37:51 +0400 |
commit | 5ac4b38a207ab7c40d50a0fe54cc41439ce82c63 (patch) | |
tree | c0908b86645dc00559056e687afcc95cced92969 | |
parent | 74e5132d111ca3e24cc09b7e30b3bc35f71fdcfd (diff) |
Cycles: preview rendering support for world/material/lamp.
Patch by Sergey, .blend by Thomas and some further tweaks by me.
Still to solve later: allow external engines to specify own preview .blend, for
now the code here is doing too much magic hacking on the preview scene still.
-rw-r--r-- | intern/cycles/blender/addon/__init__.py | 21 | ||||
-rw-r--r-- | intern/cycles/blender/addon/engine.py | 4 | ||||
-rw-r--r-- | intern/cycles/blender/addon/ui.py | 3 | ||||
-rw-r--r-- | intern/cycles/blender/blender_python.cpp | 15 | ||||
-rw-r--r-- | intern/cycles/blender/blender_session.cpp | 9 | ||||
-rw-r--r-- | release/datafiles/preview_cycles.blend | bin | 0 -> 1031316 bytes | |||
-rw-r--r-- | source/blender/editors/datafiles/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/editors/datafiles/SConscript | 1 | ||||
-rw-r--r-- | source/blender/editors/include/ED_datafiles.h | 6 | ||||
-rw-r--r-- | source/blender/editors/render/render_preview.c | 157 |
10 files changed, 138 insertions, 79 deletions
diff --git a/intern/cycles/blender/addon/__init__.py b/intern/cycles/blender/addon/__init__.py index 36fb5c0418d..16cfdca8977 100644 --- a/intern/cycles/blender/addon/__init__.py +++ b/intern/cycles/blender/addon/__init__.py @@ -39,6 +39,7 @@ class CyclesRender(bpy.types.RenderEngine): bl_idname = 'CYCLES' bl_label = "Cycles Render" bl_use_shading_nodes = True + bl_use_preview = True def __init__(self): self.session = None @@ -48,23 +49,23 @@ class CyclesRender(bpy.types.RenderEngine): # final render def update(self, data, scene): - if not self.session: - engine.create(self, data, scene) + if self.is_preview: + if not self.session: + use_osl = bpy.context.scene.cycles.shading_system + + engine.create(self, data, scene, + None, None, None, use_osl) else: - engine.reset(self, data, scene) + if not self.session: + engine.create(self, data, scene) + else: + engine.reset(self, data, scene) engine.update(self, data, scene) def render(self, scene): engine.render(self) - # preview render - # def preview_update(self, context, id): - # pass - # - # def preview_render(self): - # pass - # 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 ef700ba26f1..8958ca3e42e 100644 --- a/intern/cycles/blender/addon/engine.py +++ b/intern/cycles/blender/addon/engine.py @@ -30,7 +30,7 @@ def init(): _cycles.init(path, user_path) -def create(engine, data, scene, region=0, v3d=0, rv3d=0): +def create(engine, data, scene, region=0, v3d=0, rv3d=0, preview_osl=False): import bpy import _cycles @@ -44,7 +44,7 @@ def create(engine, data, scene, region=0, v3d=0, rv3d=0): if rv3d: rv3d = rv3d.as_pointer() - engine.session = _cycles.create(engine.as_pointer(), userpref, data, scene, region, v3d, rv3d) + engine.session = _cycles.create(engine.as_pointer(), userpref, data, scene, region, v3d, rv3d, preview_osl) def free(engine): diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index fded07ab227..d05ceb51148 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -1175,6 +1175,9 @@ def get_panels(): types.PARTICLE_PT_force_fields, types.PARTICLE_PT_vertexgroups, types.PARTICLE_PT_custom_props, + types.MATERIAL_PT_preview, + types.DATA_PT_preview, + types.WORLD_PT_preview, ) diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp index d164920ceff..676fba76ddf 100644 --- a/intern/cycles/blender/blender_python.cpp +++ b/intern/cycles/blender/blender_python.cpp @@ -52,8 +52,9 @@ static PyObject *init_func(PyObject *self, PyObject *args) static PyObject *create_func(PyObject *self, PyObject *args) { PyObject *pyengine, *pyuserpref, *pydata, *pyscene, *pyregion, *pyv3d, *pyrv3d; + int preview_osl; - if(!PyArg_ParseTuple(args, "OOOOOOO", &pyengine, &pyuserpref, &pydata, &pyscene, &pyregion, &pyv3d, &pyrv3d)) + if(!PyArg_ParseTuple(args, "OOOOOOOp", &pyengine, &pyuserpref, &pydata, &pyscene, &pyregion, &pyv3d, &pyrv3d, &preview_osl)) return NULL; /* RNA */ @@ -91,14 +92,22 @@ static PyObject *create_func(PyObject *self, PyObject *args) Py_BEGIN_ALLOW_THREADS if(rv3d) { - /* interactive session */ + /* interactive viewport session */ int width = region.width(); int height = region.height(); session = new BlenderSession(engine, userpref, data, scene, v3d, rv3d, width, height); } else { - /* offline session */ + /* override some settings for preview */ + if(engine.is_preview()) { + PointerRNA cscene = RNA_pointer_get(&sceneptr, "cycles"); + + RNA_boolean_set(&cscene, "shading_system", preview_osl); + RNA_boolean_set(&cscene, "use_progressive_refine", true); + } + + /* offline session or preview render */ session = new BlenderSession(engine, userpref, data, scene); } diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index 3913323c21c..650d3d387ee 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -288,7 +288,14 @@ void BlenderSession::write_render_tile(RenderTile& rtile) void BlenderSession::update_render_tile(RenderTile& rtile) { - do_write_update_render_tile(rtile, true); + /* use final write for preview renders, otherwise render result wouldn't be + * be updated in blender side + * would need to be investigated a bit further, but for now shall be fine + */ + if (!b_engine.is_preview()) + do_write_update_render_tile(rtile, true); + else + do_write_update_render_tile(rtile, false); } void BlenderSession::render() diff --git a/release/datafiles/preview_cycles.blend b/release/datafiles/preview_cycles.blend Binary files differnew file mode 100644 index 00000000000..dbf2f3cea8a --- /dev/null +++ b/release/datafiles/preview_cycles.blend diff --git a/source/blender/editors/datafiles/CMakeLists.txt b/source/blender/editors/datafiles/CMakeLists.txt index e9b33a6c2a6..ed3088696b1 100644 --- a/source/blender/editors/datafiles/CMakeLists.txt +++ b/source/blender/editors/datafiles/CMakeLists.txt @@ -43,6 +43,7 @@ if(WITH_BLENDER) # blends data_to_c_simple(../../../../release/datafiles/preview.blend SRC) + data_to_c_simple(../../../../release/datafiles/preview_cycles.blend SRC) # images data_to_c_simple(../../../../release/datafiles/splash.png SRC) diff --git a/source/blender/editors/datafiles/SConscript b/source/blender/editors/datafiles/SConscript index 49888d573a0..fb1f9f37975 100644 --- a/source/blender/editors/datafiles/SConscript +++ b/source/blender/editors/datafiles/SConscript @@ -46,6 +46,7 @@ sources.extend(( os.path.join(env['DATA_SOURCES'], "startup.blend.c"), os.path.join(env['DATA_SOURCES'], "preview.blend.c"), + os.path.join(env['DATA_SOURCES'], "preview_cycles.blend.c"), os.path.join(env['DATA_SOURCES'], "add.png.c"), os.path.join(env['DATA_SOURCES'], "blob.png.c"), diff --git a/source/blender/editors/include/ED_datafiles.h b/source/blender/editors/include/ED_datafiles.h index afe23090ae3..19552d60387 100644 --- a/source/blender/editors/include/ED_datafiles.h +++ b/source/blender/editors/include/ED_datafiles.h @@ -36,6 +36,12 @@ extern int datatoc_startup_blend_size; extern char datatoc_startup_blend[]; +extern int datatoc_preview_blend_size; +extern char datatoc_preview_blend[]; + +extern int datatoc_preview_cycles_blend_size; +extern char datatoc_preview_cycles_blend[]; + extern int datatoc_blender_icons16_png_size; extern char datatoc_blender_icons16_png[]; diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 25ad1f61aaf..16ebaf58a59 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -97,6 +97,7 @@ #include "WM_api.h" #include "WM_types.h" +#include "ED_datafiles.h" #include "ED_render.h" #include "ED_view3d.h" @@ -168,7 +169,8 @@ typedef struct ShaderPreview { int sizex, sizey; unsigned int *pr_rect; int pr_method; - + + Main *pr_main; } ShaderPreview; typedef struct IconPreviewSize { @@ -187,23 +189,33 @@ typedef struct IconPreview { /* *************************** Preview for buttons *********************** */ static Main *pr_main = NULL; +static Main *pr_main_cycles = NULL; -void ED_preview_init_dbase(void) -{ #ifndef WITH_HEADLESS - BlendFileData *bfd; - extern int datatoc_preview_blend_size; - extern char datatoc_preview_blend[]; +static Main *load_main_from_memory(char *blend, int blend_size) +{ const int fileflags = G.fileflags; - + Main *bmain = NULL; + BlendFileData *bfd; + G.fileflags |= G_FILE_NO_UI; - bfd = BLO_read_from_memory(datatoc_preview_blend, datatoc_preview_blend_size, NULL); + bfd = BLO_read_from_memory(blend, blend_size, NULL); if (bfd) { - pr_main = bfd->main; - + bmain = bfd->main; + MEM_freeN(bfd); } G.fileflags = fileflags; + + return bmain; +} +#endif + +void ED_preview_init_dbase(void) +{ +#ifndef WITH_HEADLESS + pr_main = load_main_from_memory(datatoc_preview_blend, datatoc_preview_blend_size); + pr_main_cycles = load_main_from_memory(datatoc_preview_cycles_blend, datatoc_preview_cycles_blend_size); #endif } @@ -211,6 +223,9 @@ void ED_preview_free_dbase(void) { if (pr_main) free_main(pr_main); + + if (pr_main_cycles) + free_main(pr_main_cycles); } static int preview_mat_has_sss(Material *mat, bNodeTree *ntree) @@ -239,7 +254,7 @@ static int preview_mat_has_sss(Material *mat, bNodeTree *ntree) return 0; } -static Scene *preview_get_scene(void) +static Scene *preview_get_scene(Main *pr_main) { if (pr_main == NULL) return NULL; @@ -253,8 +268,9 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre { Scene *sce; Base *base; + Main *pr_main = sp->pr_main; - sce = preview_get_scene(); + sce = preview_get_scene(pr_main); if (sce) { /* this flag tells render to not execute depsgraph or ipos etc */ @@ -299,45 +315,47 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre sp->matcopy = mat; BLI_addtail(&pr_main->mat, mat); - init_render_material(mat, 0, NULL); /* call that retrieves mode_l */ - end_render_material(mat); - - /* un-useful option */ - if (sp->pr_method == PR_ICON_RENDER) - mat->shade_flag &= ~MA_OBCOLOR; - - /* turn on raytracing if needed */ - if (mat->mode_l & MA_RAYMIRROR) - sce->r.mode |= R_RAYTRACE; - if (mat->material_type == MA_TYPE_VOLUME) - sce->r.mode |= R_RAYTRACE; - if ((mat->mode_l & MA_RAYTRANSP) && (mat->mode_l & MA_TRANSP)) - sce->r.mode |= R_RAYTRACE; - if (preview_mat_has_sss(mat, NULL)) - sce->r.mode |= R_SSS; - - /* turn off fake shadows if needed */ - /* this only works in a specific case where the preview.blend contains - * an object starting with 'c' which has a material linked to it (not the obdata) - * and that material has a fake shadow texture in the active texture slot */ - for (base = sce->base.first; base; base = base->next) { - if (base->object->id.name[2] == 'c') { - Material *shadmat = give_current_material(base->object, base->object->actcol); - if (shadmat) { - if (mat->mode & MA_SHADBUF) shadmat->septex = 0; - else shadmat->septex |= 1; + if (!BKE_scene_use_new_shading_nodes(scene)) { + init_render_material(mat, 0, NULL); /* call that retrieves mode_l */ + end_render_material(mat); + + /* un-useful option */ + if (sp->pr_method == PR_ICON_RENDER) + mat->shade_flag &= ~MA_OBCOLOR; + + /* turn on raytracing if needed */ + if (mat->mode_l & MA_RAYMIRROR) + sce->r.mode |= R_RAYTRACE; + if (mat->material_type == MA_TYPE_VOLUME) + sce->r.mode |= R_RAYTRACE; + if ((mat->mode_l & MA_RAYTRANSP) && (mat->mode_l & MA_TRANSP)) + sce->r.mode |= R_RAYTRACE; + if (preview_mat_has_sss(mat, NULL)) + sce->r.mode |= R_SSS; + + /* turn off fake shadows if needed */ + /* this only works in a specific case where the preview.blend contains + * an object starting with 'c' which has a material linked to it (not the obdata) + * and that material has a fake shadow texture in the active texture slot */ + for (base = sce->base.first; base; base = base->next) { + if (base->object->id.name[2] == 'c') { + Material *shadmat = give_current_material(base->object, base->object->actcol); + if (shadmat) { + if (mat->mode & MA_SHADBUF) shadmat->septex = 0; + else shadmat->septex |= 1; + } } } - } - - /* turn off bounce lights for volume, - * doesn't make much visual difference and slows it down too */ - if (mat->material_type == MA_TYPE_VOLUME) { - for (base = sce->base.first; base; base = base->next) { - if (base->object->type == OB_LAMP) { - /* if doesn't match 'Lamp.002' --> main key light */ - if (strcmp(base->object->id.name + 2, "Lamp.002") != 0) { - base->object->restrictflag |= OB_RESTRICT_RENDER; + + /* turn off bounce lights for volume, + * doesn't make much visual difference and slows it down too */ + if (mat->material_type == MA_TYPE_VOLUME) { + for (base = sce->base.first; base; base = base->next) { + if (base->object->type == OB_LAMP) { + /* if doesn't match 'Lamp.002' --> main key light */ + if (strcmp(base->object->id.name + 2, "Lamp.002") != 0) { + base->object->restrictflag |= OB_RESTRICT_RENDER; + } } } } @@ -432,19 +450,21 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre sp->lampcopy = la; BLI_addtail(&pr_main->lamp, la); } - - if (la && la->type == LA_SUN && (la->sun_effect_type & LA_SUN_EFFECT_SKY)) { - sce->lay = 1 << MA_ATMOS; - sce->world = scene->world; - sce->camera = (Object *)BLI_findstring(&pr_main->object, "CameraAtmo", offsetof(ID, name) + 2); - } - else { - sce->lay = 1 << MA_LAMP; - sce->world = NULL; - sce->camera = (Object *)BLI_findstring(&pr_main->object, "Camera", offsetof(ID, name) + 2); + + sce->lay = 1 << MA_LAMP; + + if (!BKE_scene_use_new_shading_nodes(scene)) { + if (la && la->type == LA_SUN && (la->sun_effect_type & LA_SUN_EFFECT_SKY)) { + sce->lay = 1 << MA_ATMOS; + sce->world = scene->world; + sce->camera = (Object *)BLI_findstring(&pr_main->object, "CameraAtmo", offsetof(ID, name) + 2); + } + else { + sce->world = NULL; + sce->camera = (Object *)BLI_findstring(&pr_main->object, "Camera", offsetof(ID, name) + 2); + } } - sce->r.mode &= ~R_SHADOW; - + for (base = sce->base.first; base; base = base->next) { if (base->object->id.name[2] == 'p') { if (base->object->type == OB_LAMP) @@ -639,6 +659,7 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs short idtype = GS(id->name); char name[32]; int sizex; + Main *pr_main = sp->pr_main; /* in case of split preview, use border render */ if (split) { @@ -648,7 +669,7 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs else sizex = sp->sizex; /* we have to set preview variables first */ - sce = preview_get_scene(); + sce = preview_get_scene(pr_main); if (sce) { sce->r.xsch = sizex; sce->r.ysch = sp->sizey; @@ -749,6 +770,7 @@ static void shader_preview_startjob(void *customdata, short *stop, short *do_upd static void shader_preview_free(void *customdata) { ShaderPreview *sp = customdata; + Main *pr_main = sp->pr_main; if (sp->matcopy) { struct IDProperty *properties; @@ -1076,13 +1098,14 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M Object *ob = CTX_data_active_object(C); wmJob *wm_job; ShaderPreview *sp; + Scene *scene = CTX_data_scene(C); wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), owner, "Shader Preview", WM_JOB_EXCL_RENDER, WM_JOB_TYPE_RENDER_PREVIEW); sp = MEM_callocN(sizeof(ShaderPreview), "shader preview"); /* customdata for preview thread */ - sp->scene = CTX_data_scene(C); + sp->scene = scene; sp->owner = owner; sp->sizex = sizex; sp->sizey = sizey; @@ -1090,6 +1113,14 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M sp->id = id; sp->parent = parent; sp->slot = slot; + + /* hardcoded preview .blend for cycles/internal, this should be solved + * once with custom preview .blend path for external engines */ + if (BKE_scene_use_new_shading_nodes(scene)) + sp->pr_main = pr_main_cycles; + else + sp->pr_main = pr_main; + if (ob && ob->totcol) copy_v4_v4(sp->col, ob->col); else sp->col[0] = sp->col[1] = sp->col[2] = sp->col[3] = 1.0f; |