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.
This commit is contained in:
2013-01-28 17:37:51 +00:00
parent 74e5132d11
commit 5ac4b38a20
10 changed files with 141 additions and 82 deletions

View File

@@ -39,6 +39,7 @@ class CyclesRender(bpy.types.RenderEngine):
bl_idname = 'CYCLES' bl_idname = 'CYCLES'
bl_label = "Cycles Render" bl_label = "Cycles Render"
bl_use_shading_nodes = True bl_use_shading_nodes = True
bl_use_preview = True
def __init__(self): def __init__(self):
self.session = None self.session = None
@@ -48,6 +49,13 @@ class CyclesRender(bpy.types.RenderEngine):
# final render # final render
def update(self, data, scene): def update(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:
if not self.session: if not self.session:
engine.create(self, data, scene) engine.create(self, data, scene)
else: else:
@@ -58,13 +66,6 @@ class CyclesRender(bpy.types.RenderEngine):
def render(self, scene): def render(self, scene):
engine.render(self) engine.render(self)
# preview render
# def preview_update(self, context, id):
# pass
#
# def preview_render(self):
# pass
# viewport render # viewport render
def view_update(self, context): def view_update(self, context):
if not self.session: if not self.session:

View File

@@ -30,7 +30,7 @@ def init():
_cycles.init(path, user_path) _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 bpy
import _cycles import _cycles
@@ -44,7 +44,7 @@ def create(engine, data, scene, region=0, v3d=0, rv3d=0):
if rv3d: if rv3d:
rv3d = rv3d.as_pointer() 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): def free(engine):

View File

@@ -1175,6 +1175,9 @@ def get_panels():
types.PARTICLE_PT_force_fields, types.PARTICLE_PT_force_fields,
types.PARTICLE_PT_vertexgroups, types.PARTICLE_PT_vertexgroups,
types.PARTICLE_PT_custom_props, types.PARTICLE_PT_custom_props,
types.MATERIAL_PT_preview,
types.DATA_PT_preview,
types.WORLD_PT_preview,
) )

View File

@@ -52,8 +52,9 @@ static PyObject *init_func(PyObject *self, PyObject *args)
static PyObject *create_func(PyObject *self, PyObject *args) static PyObject *create_func(PyObject *self, PyObject *args)
{ {
PyObject *pyengine, *pyuserpref, *pydata, *pyscene, *pyregion, *pyv3d, *pyrv3d; 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; return NULL;
/* RNA */ /* RNA */
@@ -91,14 +92,22 @@ static PyObject *create_func(PyObject *self, PyObject *args)
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
if(rv3d) { if(rv3d) {
/* interactive session */ /* interactive viewport session */
int width = region.width(); int width = region.width();
int height = region.height(); int height = region.height();
session = new BlenderSession(engine, userpref, data, scene, v3d, rv3d, width, height); session = new BlenderSession(engine, userpref, data, scene, v3d, rv3d, width, height);
} }
else { 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); session = new BlenderSession(engine, userpref, data, scene);
} }

View File

@@ -288,7 +288,14 @@ void BlenderSession::write_render_tile(RenderTile& rtile)
void BlenderSession::update_render_tile(RenderTile& rtile) void BlenderSession::update_render_tile(RenderTile& rtile)
{ {
/* 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); do_write_update_render_tile(rtile, true);
else
do_write_update_render_tile(rtile, false);
} }
void BlenderSession::render() void BlenderSession::render()

Binary file not shown.

View File

@@ -43,6 +43,7 @@ if(WITH_BLENDER)
# blends # blends
data_to_c_simple(../../../../release/datafiles/preview.blend SRC) data_to_c_simple(../../../../release/datafiles/preview.blend SRC)
data_to_c_simple(../../../../release/datafiles/preview_cycles.blend SRC)
# images # images
data_to_c_simple(../../../../release/datafiles/splash.png SRC) data_to_c_simple(../../../../release/datafiles/splash.png SRC)

View File

@@ -46,6 +46,7 @@ sources.extend((
os.path.join(env['DATA_SOURCES'], "startup.blend.c"), 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.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'], "add.png.c"),
os.path.join(env['DATA_SOURCES'], "blob.png.c"), os.path.join(env['DATA_SOURCES'], "blob.png.c"),

View File

@@ -36,6 +36,12 @@
extern int datatoc_startup_blend_size; extern int datatoc_startup_blend_size;
extern char datatoc_startup_blend[]; 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 int datatoc_blender_icons16_png_size;
extern char datatoc_blender_icons16_png[]; extern char datatoc_blender_icons16_png[];

View File

@@ -97,6 +97,7 @@
#include "WM_api.h" #include "WM_api.h"
#include "WM_types.h" #include "WM_types.h"
#include "ED_datafiles.h"
#include "ED_render.h" #include "ED_render.h"
#include "ED_view3d.h" #include "ED_view3d.h"
@@ -169,6 +170,7 @@ typedef struct ShaderPreview {
unsigned int *pr_rect; unsigned int *pr_rect;
int pr_method; int pr_method;
Main *pr_main;
} ShaderPreview; } ShaderPreview;
typedef struct IconPreviewSize { typedef struct IconPreviewSize {
@@ -187,23 +189,33 @@ typedef struct IconPreview {
/* *************************** Preview for buttons *********************** */ /* *************************** Preview for buttons *********************** */
static Main *pr_main = NULL; static Main *pr_main = NULL;
static Main *pr_main_cycles = NULL;
void ED_preview_init_dbase(void)
{
#ifndef WITH_HEADLESS #ifndef WITH_HEADLESS
BlendFileData *bfd; static Main *load_main_from_memory(char *blend, int blend_size)
extern int datatoc_preview_blend_size; {
extern char datatoc_preview_blend[];
const int fileflags = G.fileflags; const int fileflags = G.fileflags;
Main *bmain = NULL;
BlendFileData *bfd;
G.fileflags |= G_FILE_NO_UI; 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) { if (bfd) {
pr_main = bfd->main; bmain = bfd->main;
MEM_freeN(bfd); MEM_freeN(bfd);
} }
G.fileflags = fileflags; 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 #endif
} }
@@ -211,6 +223,9 @@ void ED_preview_free_dbase(void)
{ {
if (pr_main) if (pr_main)
free_main(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) 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; return 0;
} }
static Scene *preview_get_scene(void) static Scene *preview_get_scene(Main *pr_main)
{ {
if (pr_main == NULL) return NULL; 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; Scene *sce;
Base *base; Base *base;
Main *pr_main = sp->pr_main;
sce = preview_get_scene(); sce = preview_get_scene(pr_main);
if (sce) { if (sce) {
/* this flag tells render to not execute depsgraph or ipos etc */ /* this flag tells render to not execute depsgraph or ipos etc */
@@ -299,6 +315,7 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
sp->matcopy = mat; sp->matcopy = mat;
BLI_addtail(&pr_main->mat, mat); BLI_addtail(&pr_main->mat, mat);
if (!BKE_scene_use_new_shading_nodes(scene)) {
init_render_material(mat, 0, NULL); /* call that retrieves mode_l */ init_render_material(mat, 0, NULL); /* call that retrieves mode_l */
end_render_material(mat); end_render_material(mat);
@@ -342,6 +359,7 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
} }
} }
} }
}
if (sp->pr_method == PR_ICON_RENDER) { if (sp->pr_method == PR_ICON_RENDER) {
@@ -433,17 +451,19 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
BLI_addtail(&pr_main->lamp, la); BLI_addtail(&pr_main->lamp, la);
} }
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)) { if (la && la->type == LA_SUN && (la->sun_effect_type & LA_SUN_EFFECT_SKY)) {
sce->lay = 1 << MA_ATMOS; sce->lay = 1 << MA_ATMOS;
sce->world = scene->world; sce->world = scene->world;
sce->camera = (Object *)BLI_findstring(&pr_main->object, "CameraAtmo", offsetof(ID, name) + 2); sce->camera = (Object *)BLI_findstring(&pr_main->object, "CameraAtmo", offsetof(ID, name) + 2);
} }
else { else {
sce->lay = 1 << MA_LAMP;
sce->world = NULL; sce->world = NULL;
sce->camera = (Object *)BLI_findstring(&pr_main->object, "Camera", offsetof(ID, name) + 2); 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) { for (base = sce->base.first; base; base = base->next) {
if (base->object->id.name[2] == 'p') { if (base->object->id.name[2] == 'p') {
@@ -639,6 +659,7 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
short idtype = GS(id->name); short idtype = GS(id->name);
char name[32]; char name[32];
int sizex; int sizex;
Main *pr_main = sp->pr_main;
/* in case of split preview, use border render */ /* in case of split preview, use border render */
if (split) { if (split) {
@@ -648,7 +669,7 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
else sizex = sp->sizex; else sizex = sp->sizex;
/* we have to set preview variables first */ /* we have to set preview variables first */
sce = preview_get_scene(); sce = preview_get_scene(pr_main);
if (sce) { if (sce) {
sce->r.xsch = sizex; sce->r.xsch = sizex;
sce->r.ysch = sp->sizey; 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) static void shader_preview_free(void *customdata)
{ {
ShaderPreview *sp = customdata; ShaderPreview *sp = customdata;
Main *pr_main = sp->pr_main;
if (sp->matcopy) { if (sp->matcopy) {
struct IDProperty *properties; 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); Object *ob = CTX_data_active_object(C);
wmJob *wm_job; wmJob *wm_job;
ShaderPreview *sp; 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 = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), owner, "Shader Preview",
WM_JOB_EXCL_RENDER, WM_JOB_TYPE_RENDER_PREVIEW); WM_JOB_EXCL_RENDER, WM_JOB_TYPE_RENDER_PREVIEW);
sp = MEM_callocN(sizeof(ShaderPreview), "shader preview"); sp = MEM_callocN(sizeof(ShaderPreview), "shader preview");
/* customdata for preview thread */ /* customdata for preview thread */
sp->scene = CTX_data_scene(C); sp->scene = scene;
sp->owner = owner; sp->owner = owner;
sp->sizex = sizex; sp->sizex = sizex;
sp->sizey = sizey; 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->id = id;
sp->parent = parent; sp->parent = parent;
sp->slot = slot; 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); 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; else sp->col[0] = sp->col[1] = sp->col[2] = sp->col[3] = 1.0f;