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_label = "Cycles Render"
|
||||
bl_use_shading_nodes = True
|
||||
bl_use_preview = True
|
||||
|
||||
def __init__(self):
|
||||
self.session = None
|
||||
@@ -48,6 +49,13 @@ class CyclesRender(bpy.types.RenderEngine):
|
||||
|
||||
# final render
|
||||
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:
|
||||
engine.create(self, data, scene)
|
||||
else:
|
||||
@@ -58,13 +66,6 @@ class CyclesRender(bpy.types.RenderEngine):
|
||||
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:
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -288,7 +288,14 @@ void BlenderSession::write_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);
|
||||
else
|
||||
do_write_update_render_tile(rtile, false);
|
||||
}
|
||||
|
||||
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
|
||||
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)
|
||||
|
||||
@@ -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"),
|
||||
|
||||
@@ -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[];
|
||||
|
||||
|
||||
@@ -97,6 +97,7 @@
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "ED_datafiles.h"
|
||||
#include "ED_render.h"
|
||||
#include "ED_view3d.h"
|
||||
|
||||
@@ -169,6 +170,7 @@ typedef struct ShaderPreview {
|
||||
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,6 +315,7 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
|
||||
sp->matcopy = 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 */
|
||||
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) {
|
||||
@@ -433,17 +451,19 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
|
||||
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)) {
|
||||
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->r.mode &= ~R_SHADOW;
|
||||
}
|
||||
|
||||
for (base = sce->base.first; base; base = base->next) {
|
||||
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);
|
||||
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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user