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:
@@ -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:
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
@@ -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,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
BIN
release/datafiles/preview_cycles.blend
Normal file
BIN
release/datafiles/preview_cycles.blend
Normal file
Binary file not shown.
@@ -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)
|
||||||
|
|||||||
@@ -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"),
|
||||||
|
|||||||
@@ -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[];
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user