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:
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c3
-rw-r--r--source/blender/blenlib/BLI_math_matrix.h2
-rw-r--r--source/blender/blenlib/intern/math_matrix.c10
-rw-r--r--source/blender/blenloader/intern/readfile.c4
-rw-r--r--source/blender/editors/include/ED_render.h4
-rw-r--r--source/blender/editors/render/render_intern.h2
-rw-r--r--source/blender/editors/render/render_internal.c362
-rw-r--r--source/blender/editors/render/render_preview.c1
-rw-r--r--source/blender/editors/render/render_update.c40
-rw-r--r--source/blender/editors/space_api/spacetypes.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c3
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp8
-rw-r--r--source/blender/render/extern/include/RE_engine.h6
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h6
-rw-r--r--source/blender/render/intern/include/envmap.h1
-rw-r--r--source/blender/render/intern/include/initrender.h2
-rw-r--r--source/blender/render/intern/include/render_types.h1
-rw-r--r--source/blender/render/intern/source/convertblender.c34
-rw-r--r--source/blender/render/intern/source/envmap.c41
-rw-r--r--source/blender/render/intern/source/external_engine.c12
-rw-r--r--source/blender/render/intern/source/pipeline.c64
-rw-r--r--source/blender/render/intern/source/render_result.c1
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c7
23 files changed, 565 insertions, 51 deletions
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 3a531cf32ae..0a4a15cca09 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -2341,7 +2341,8 @@ void DAG_ids_check_recalc(Main *bmain, Scene *scene, int time)
/* we tag based on first ID type character to avoid
* looping over all ID's in case there are no tags */
- if (id && bmain->id_tag_update[id->name[0]]) {
+ /* XXX very weak... added check for '27' to ignore freestyle added objects */
+ if (id && id->name[2] > 27 && bmain->id_tag_update[id->name[0]]) {
updated = 1;
break;
}
diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h
index 97cd6a60862..9c5d3c5b93c 100644
--- a/source/blender/blenlib/BLI_math_matrix.h
+++ b/source/blender/blenlib/BLI_math_matrix.h
@@ -122,6 +122,8 @@ void mul_v4d_m4v4d(double r[4], float M[4][4], double v[4]);
void transpose_m3(float R[3][3]);
void transpose_m4(float R[4][4]);
+int compare_m4m4(float mat1[4][4], float mat2[4][4], float limit);
+
void normalize_m3(float R[3][3]);
void normalize_m3_m3(float R[3][3], float A[3][3]);
void normalize_m4(float R[4][4]);
diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c
index f116c9b8443..1ec63f11c3d 100644
--- a/source/blender/blenlib/intern/math_matrix.c
+++ b/source/blender/blenlib/intern/math_matrix.c
@@ -722,6 +722,16 @@ void transpose_m4(float mat[4][4])
mat[3][2] = t;
}
+int compare_m4m4(float mat1[4][4], float mat2[4][4], float limit)
+{
+ if (compare_v4v4(mat1[0], mat2[0], limit))
+ if (compare_v4v4(mat1[1], mat2[1], limit))
+ if (compare_v4v4(mat1[2], mat2[2], limit))
+ if (compare_v4v4(mat1[3], mat2[3], limit))
+ return 1;
+ return 0;
+}
+
void orthogonalize_m3(float mat[3][3], int axis)
{
float size[3];
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index fdbf2927464..e7e8d6f3b99 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -6209,9 +6209,9 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
v3d->properties_storage = NULL;
v3d->defmaterial = NULL;
- /* render can be quite heavy, set to wire on load */
+ /* render can be quite heavy, set to solid on load */
if (v3d->drawtype == OB_RENDER)
- v3d->drawtype = OB_WIRE;
+ v3d->drawtype = OB_SOLID;
blo_do_versions_view3d_split_250(v3d, &sl->regionbase);
}
diff --git a/source/blender/editors/include/ED_render.h b/source/blender/editors/include/ED_render.h
index 39e2c28a61a..c1ddd9a6294 100644
--- a/source/blender/editors/include/ED_render.h
+++ b/source/blender/editors/include/ED_render.h
@@ -38,6 +38,8 @@ struct Render;
struct RenderInfo;
struct Scene;
struct ScrArea;
+struct RegionView3D;
+struct RenderEngine;
/* render_ops.c */
@@ -85,4 +87,6 @@ void ED_preview_draw(const struct bContext *C, void *idp, void *parentp, void *s
void ED_render_clear_mtex_copybuf(void);
+void ED_render_internal_init(void);
+
#endif
diff --git a/source/blender/editors/render/render_intern.h b/source/blender/editors/render/render_intern.h
index 88c00601933..edd61bfc5c3 100644
--- a/source/blender/editors/render/render_intern.h
+++ b/source/blender/editors/render/render_intern.h
@@ -83,6 +83,8 @@ void TEXTURE_OT_envmap_clear_all(struct wmOperatorType *ot);
/* render_internal.c */
void RENDER_OT_render(struct wmOperatorType *ot);
+void render_view3d(struct RenderEngine *engine, const struct bContext *C);
+void render_view3d_draw(struct RenderEngine *engine, const struct bContext *C);
/* render_opengl.c uses this */
void image_buffer_rect_update(struct Scene *scene, struct RenderResult *rr, struct ImBuf *ibuf, volatile struct rcti *renrect);
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 6832cd5baa0..f599fa1bde8 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -42,9 +42,11 @@
#include "BLF_translation.h"
#include "DNA_scene_types.h"
+#include "DNA_view3d_types.h"
#include "BKE_blender.h"
#include "BKE_context.h"
+#include "BKE_freestyle.h"
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_library.h"
@@ -59,14 +61,23 @@
#include "WM_api.h"
#include "WM_types.h"
-#include "ED_screen.h"
#include "ED_object.h"
+#include "ED_render.h"
+#include "ED_screen.h"
+#include "ED_view3d.h"
#include "RE_pipeline.h"
+#include "RE_engine.h"
+
#include "IMB_colormanagement.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
+#include "GPU_extensions.h"
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+
#include "RNA_access.h"
#include "RNA_define.h"
@@ -681,3 +692,352 @@ void RENDER_OT_render(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
+
+/* ************** preview for 3d viewport ***************** */
+
+#define PR_UPDATE_VIEW 1
+#define PR_UPDATE_RENDERSIZE 2
+#define PR_UPDATE_MATERIAL 4
+
+typedef struct RenderPreview {
+ /* from wmJob */
+ void *owner;
+ short *stop, *do_update;
+
+ Scene *scene;
+ ScrArea *sa;
+ ARegion *ar;
+ View3D *v3d;
+ RegionView3D *rv3d;
+ Main *bmain;
+ RenderEngine *engine;
+
+ int keep_data;
+} RenderPreview;
+
+static int render_view3d_disprect(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, rcti *disprect)
+{
+ /* copied code from view3d_draw.c */
+ rctf viewborder;
+ int draw_border;
+
+ if (rv3d->persp == RV3D_CAMOB)
+ draw_border = (scene->r.mode & R_BORDER) != 0;
+ else
+ draw_border = (v3d->flag2 & V3D_RENDER_BORDER) != 0;
+
+ if (draw_border) {
+ if (rv3d->persp == RV3D_CAMOB) {
+ ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, false);
+
+ disprect->xmin = viewborder.xmin + scene->r.border.xmin * BLI_rctf_size_x(&viewborder);
+ disprect->ymin = viewborder.ymin + scene->r.border.ymin * BLI_rctf_size_y(&viewborder);
+ disprect->xmax = viewborder.xmin + scene->r.border.xmax * BLI_rctf_size_x(&viewborder);
+ disprect->ymax = viewborder.ymin + scene->r.border.ymax * BLI_rctf_size_y(&viewborder);
+ }
+ else {
+ disprect->xmin = v3d->render_border.xmin * ar->winx;
+ disprect->xmax = v3d->render_border.xmax * ar->winx;
+ disprect->ymin = v3d->render_border.ymin * ar->winy;
+ disprect->ymax = v3d->render_border.ymax * ar->winy;
+ }
+
+ return 1;
+ }
+
+ BLI_rcti_init(disprect, 0, 0, 0, 0);
+ return 0;
+}
+
+/* returns 1 if OK */
+static int render_view3d_get_rects(ARegion *ar, View3D *v3d, RegionView3D *rv3d, rctf *viewplane, RenderEngine *engine, float *clipsta, float *clipend, int *ortho)
+{
+
+ if (ar->winx < 4 || ar->winy < 4) return 0;
+
+ *ortho = ED_view3d_viewplane_get(v3d, rv3d, ar->winx, ar->winy, viewplane, clipsta, clipend);
+
+ engine->resolution_x = ar->winx;
+ engine->resolution_y = ar->winy;
+
+ return 1;
+}
+
+/* called by renderer, checks job value */
+static int render_view3d_break(void *rpv)
+{
+ RenderPreview *rp = rpv;
+
+ if (G.is_break)
+ return 1;
+
+ /* during render, rv3d->engine can get freed */
+ if (rp->rv3d->render_engine == NULL)
+ *rp->stop = 1;
+
+ return *(rp->stop);
+}
+
+static void render_view3d_draw_update(void *rpv, RenderResult *UNUSED(rr), volatile struct rcti *UNUSED(rect))
+{
+ RenderPreview *rp = rpv;
+
+ *(rp->do_update) = TRUE;
+}
+
+static void render_view3d_renderinfo_cb(void *rjp, RenderStats *rs)
+{
+ RenderPreview *rp = rjp;
+
+ /* during render, rv3d->engine can get freed */
+ if (rp->rv3d->render_engine == NULL)
+ *rp->stop = 1;
+ else if (rp->engine->text) {
+ make_renderinfo_string(rs, rp->scene, rp->engine->text);
+
+ /* make jobs timer to send notifier */
+ *(rp->do_update) = TRUE;
+ }
+}
+
+
+static void render_view3d_startjob(void *customdata, short *stop, short *do_update, float *UNUSED(progress))
+{
+ RenderPreview *rp = customdata;
+ Render *re;
+ RenderStats *rstats;
+ RenderData rdata;
+ rctf viewplane;
+ rcti cliprct;
+ float clipsta, clipend;
+ int orth, restore = 0;
+ char name[32];
+
+ G.is_break = FALSE;
+
+ if (0 == render_view3d_get_rects(rp->ar, rp->v3d, rp->rv3d, &viewplane, rp->engine, &clipsta, &clipend, &orth))
+ return;
+
+ rp->stop = stop;
+ rp->do_update = do_update;
+
+// printf("Enter previewrender\n");
+
+ /* ok, are we rendering all over? */
+ sprintf(name, "View3dPreview %p", (void *)rp->ar);
+ re= rp->engine->re = RE_GetRender(name);
+
+ if (rp->engine->re == NULL) {
+
+ re = rp->engine->re= RE_NewRender(name);
+
+ rp->keep_data = 0;
+ }
+
+ /* set this always, rp is different for each job */
+ RE_test_break_cb(re, rp, render_view3d_break);
+ RE_display_draw_cb(re, rp, render_view3d_draw_update);
+ RE_stats_draw_cb(re, rp, render_view3d_renderinfo_cb);
+
+ rstats= RE_GetStats(re);
+
+ if (rp->keep_data == 0 || rstats->convertdone == 0 || (rp->keep_data & PR_UPDATE_RENDERSIZE)) {
+ /* no osa, blur, seq, layers, etc for preview render */
+ rdata = rp->scene->r;
+ rdata.mode &= ~(R_OSA | R_MBLUR | R_BORDER | R_PANORAMA);
+ rdata.scemode &= ~(R_DOSEQ | R_DOCOMP | R_FREE_IMAGE);
+ rdata.scemode |= R_PREVIEWBUTS;
+
+ /* we do use layers, but only active */
+ rdata.scemode |= R_SINGLE_LAYER;
+
+ /* initalize always */
+ if (render_view3d_disprect(rp->scene, rp->ar, rp->v3d, rp->rv3d, &cliprct)) {
+ rdata.mode |= R_BORDER;
+ RE_InitState(re, NULL, &rdata, NULL, rp->sa->winx, rp->sa->winy, &cliprct);
+ }
+ else
+ RE_InitState(re, NULL, &rdata, NULL, rp->sa->winx, rp->sa->winy, NULL);
+ }
+
+ if (orth)
+ RE_SetOrtho(re, &viewplane, clipsta, clipend);
+ else
+ RE_SetWindow(re, &viewplane, clipsta, clipend);
+
+ /* database free can crash on a empty Render... */
+ if (rp->keep_data == 0 && rstats->convertdone)
+ RE_Database_Free(re);
+
+ if (rstats->convertdone == 0) {
+ unsigned int lay = rp->scene->lay;
+
+ /* allow localview render for objects with lights in normal layers */
+ if (rp->v3d->lay & 0xFF000000)
+ lay |= rp->v3d->lay;
+ else lay = rp->v3d->lay;
+
+ RE_SetView(re, rp->rv3d->viewmat);
+
+ RE_Database_FromScene(re, rp->bmain, rp->scene, lay, 0); // 0= dont use camera view
+// printf("dbase update\n");
+ }
+ else {
+// printf("dbase rotate\n");
+ RE_DataBase_IncrementalView(re, rp->rv3d->viewmat, 0);
+ restore = 1;
+ }
+
+ RE_DataBase_ApplyWindow(re);
+
+ /* OK, can we enter render code? */
+ if (rstats->convertdone) {
+ RE_TileProcessor(re);
+// printf("tile processor\n");
+
+ if (restore)
+ RE_DataBase_IncrementalView(re, rp->rv3d->viewmat, 1);
+
+ rp->engine->flag &= ~RE_ENGINE_DO_UPDATE;
+ }
+
+// printf("done\n\n");
+}
+
+static void render_view3d_free(void *customdata)
+{
+ RenderPreview *rp = customdata;
+
+ MEM_freeN(rp);
+}
+
+static void render_view3d_do(RenderEngine *engine, const bContext *C, int keep_data)
+{
+ wmJob *wm_job;
+ RenderPreview *rp;
+ Scene *scene = CTX_data_scene(C);
+
+ if (CTX_wm_window(C) == NULL) {
+ engine->flag |= RE_ENGINE_DO_UPDATE;
+
+ return;
+ }
+
+ wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), CTX_wm_region(C), "Render Preview",
+ WM_JOB_EXCL_RENDER, WM_JOB_TYPE_RENDER_PREVIEW);
+ rp = MEM_callocN(sizeof(RenderPreview), "render preview");
+
+ /* customdata for preview thread */
+ rp->scene = scene;
+ rp->engine = engine;
+ rp->sa = CTX_wm_area(C);
+ rp->ar = CTX_wm_region(C);
+ rp->v3d = rp->sa->spacedata.first;
+ rp->rv3d = CTX_wm_region_view3d(C);
+ rp->bmain = CTX_data_main(C);
+ rp->keep_data = keep_data;
+
+ /* dont alloc in threads */
+ if (engine->text == NULL)
+ engine->text = MEM_callocN(IMA_MAX_RENDER_TEXT, "rendertext");
+
+ /* setup job */
+ WM_jobs_customdata_set(wm_job, rp, render_view3d_free);
+ WM_jobs_timer(wm_job, 0.1, NC_SPACE|ND_SPACE_VIEW3D, NC_SPACE|ND_SPACE_VIEW3D);
+ WM_jobs_callbacks(wm_job, render_view3d_startjob, NULL, NULL, NULL);
+
+ WM_jobs_start(CTX_wm_manager(C), wm_job);
+
+ engine->flag &= ~RE_ENGINE_DO_UPDATE;
+
+}
+
+/* callback for render engine , on changes */
+void render_view3d(RenderEngine *engine, const bContext *C)
+{
+ render_view3d_do(engine, C, 0);
+}
+
+static int render_view3d_changed(RenderEngine *engine, const bContext *C)
+{
+ ARegion *ar = CTX_wm_region(C);
+ Render *re;
+ int update = 0;
+ char name[32];
+
+ sprintf(name, "View3dPreview %p", (void *)ar);
+ re = RE_GetRender(name);
+
+ if (re) {
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ Scene *scene = CTX_data_scene(C);
+ rctf viewplane, viewplane1;
+ rcti disprect, disprect1;
+ float mat[4][4];
+ float clipsta, clipend;
+ int orth;
+
+ if (engine->update_flag == RE_ENGINE_UPDATE_MA)
+ update |= PR_UPDATE_MATERIAL;
+ engine->update_flag = 0;
+
+ if (engine->resolution_x != ar->winx || engine->resolution_y != ar->winy)
+ update |= PR_UPDATE_RENDERSIZE;
+
+ /* view updating fails on raytrace */
+ RE_GetView(re, mat);
+ if (compare_m4m4(mat, rv3d->viewmat, 0.00001f) == 0) {
+ if ((scene->r.mode & R_RAYTRACE)==0)
+ update |= PR_UPDATE_VIEW;
+ else
+ engine->flag |= RE_ENGINE_DO_UPDATE;
+ }
+
+ render_view3d_get_rects(ar, v3d, rv3d, &viewplane, engine, &clipsta, &clipend, &orth);
+ RE_GetViewPlane(re, &viewplane1, &disprect1);
+
+ if (BLI_rctf_compare(&viewplane, &viewplane1, 0.00001f) == 0)
+ update |= PR_UPDATE_VIEW;
+
+ render_view3d_disprect(scene, ar, v3d, rv3d, &disprect);
+ if (BLI_rcti_compare(&disprect, &disprect1) == 0)
+ update |= PR_UPDATE_RENDERSIZE;
+
+ if (update)
+ engine->flag |= RE_ENGINE_DO_UPDATE;
+// if (update)
+// printf("changed ma %d res %d view %d\n", update & PR_UPDATE_MATERIAL, update & PR_UPDATE_RENDERSIZE, update & PR_UPDATE_VIEW);
+
+ }
+
+ return update;
+}
+
+void render_view3d_draw(RenderEngine *engine, const bContext *C)
+{
+ Render *re = engine->re;
+ RenderResult rres;
+ int keep_data = render_view3d_changed(engine, C);
+
+ if (engine->flag & RE_ENGINE_DO_UPDATE)
+ render_view3d_do(engine, C, keep_data);
+
+ if (re == NULL) return;
+
+ RE_AcquireResultImage(re, &rres);
+ RE_ReleaseResultImage(re);
+
+ if (rres.rectf) {
+ unsigned char *rect_byte = MEM_mallocN(rres.rectx * rres.recty * sizeof(int), "ed_preview_draw_rect");
+
+ RE_ResultGet32(re, (unsigned int *)rect_byte);
+
+ glEnable(GL_BLEND);
+ glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+ glaDrawPixelsTex(rres.xof, rres.yof, rres.rectx, rres.recty, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR, rect_byte);
+ glDisable(GL_BLEND);
+
+ MEM_freeN(rect_byte);
+ }
+}
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 0caf4a7351f..7ef84b9d6eb 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -93,7 +93,6 @@
#include "RE_pipeline.h"
-
#include "WM_api.h"
#include "WM_types.h"
diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c
index f19ea08f381..5653d14e590 100644
--- a/source/blender/editors/render/render_update.c
+++ b/source/blender/editors/render/render_update.c
@@ -116,6 +116,7 @@ void ED_render_scene_update(Main *bmain, Scene *scene, int updated)
engine = rv3d->render_engine;
if (engine && (updated || (engine->flag & RE_ENGINE_DO_UPDATE))) {
+
CTX_wm_screen_set(C, sc);
CTX_wm_area_set(C, sa);
CTX_wm_region_set(C, ar);
@@ -177,6 +178,32 @@ void ED_render_engine_changed(Main *bmain)
* editor level updates when the ID changes. when these ID blocks are in *
* the dependency graph, we can get rid of the manual dependency checks */
+static void render_engine_flag_changed(Main *bmain, int update_flag)
+{
+ bScreen *sc;
+ ScrArea *sa;
+ ARegion *ar;
+
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
+ for (sa = sc->areabase.first; sa; sa = sa->next) {
+ if (sa->spacetype != SPACE_VIEW3D)
+ continue;
+
+ for (ar = sa->regionbase.first; ar; ar = ar->next) {
+ RegionView3D *rv3d;
+
+ if (ar->regiontype != RGN_TYPE_WINDOW)
+ continue;
+
+ rv3d = ar->regiondata;
+ if (rv3d->render_engine)
+ rv3d->render_engine->update_flag |= update_flag;
+
+ }
+ }
+ }
+}
+
static int mtex_use_tex(MTex **mtex, int tot, Tex *tex)
{
int a;
@@ -472,6 +499,7 @@ void ED_render_id_flush_update(Main *bmain, ID *id)
switch (GS(id->name)) {
case ID_MA:
material_changed(bmain, (Material *)id);
+ render_engine_flag_changed(bmain, RE_ENGINE_UPDATE_MA);
break;
case ID_TE:
texture_changed(bmain, (Tex *)id);
@@ -487,9 +515,21 @@ void ED_render_id_flush_update(Main *bmain, ID *id)
break;
case ID_SCE:
scene_changed(bmain, (Scene *)id);
+ render_engine_flag_changed(bmain, RE_ENGINE_UPDATE_OTHER);
break;
default:
+ render_engine_flag_changed(bmain, RE_ENGINE_UPDATE_OTHER);
break;
}
+
}
+
+void ED_render_internal_init(void)
+{
+ RenderEngineType *ret = RE_engines_find("BLENDER_RENDER");
+
+ ret->view_update = render_view3d;
+ ret->view_draw = render_view3d_draw;
+
+}
diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c
index 35344f2c5a4..2739d41a73d 100644
--- a/source/blender/editors/space_api/spacetypes.c
+++ b/source/blender/editors/space_api/spacetypes.c
@@ -149,6 +149,8 @@ void ED_spacetypes_init(void)
type->dropboxes();
}
+ /* register internal render callbacks */
+ ED_render_internal_init();
}
/* called in wm.c */
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index b227d32d987..7552e09ebbd 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -199,7 +199,8 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera
sms.to_camera = true; /* restore view3d values in end */
}
- if (C && U.smooth_viewtx) {
+ /* skip smooth viewing for render engine draw */
+ if (C && U.smooth_viewtx && v3d->drawtype != OB_RENDER) {
bool changed = false; /* zero means no difference */
if (oldcamera != camera)
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
index 0bd990ad03a..dd75e4d0dd5 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
+++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
@@ -478,9 +478,11 @@ Object *BlenderStrokeRenderer::NewMesh() const
char name[MAX_ID_NAME];
unsigned int mesh_id = get_stroke_mesh_id();
- BLI_snprintf(name, MAX_ID_NAME, "0%08xOB", mesh_id);
+ /* XXX this is for later review, for now we start names with 27 (DEL)
+ to allow ignoring them in DAG_ids_check_recalc() */
+ BLI_snprintf(name, MAX_ID_NAME, "%c0%08xOB", 27, mesh_id);
ob = BKE_object_add_only_object(G.main, OB_MESH, name);
- BLI_snprintf(name, MAX_ID_NAME, "0%08xME", mesh_id);
+ BLI_snprintf(name, MAX_ID_NAME, "%c0%08xME", 27, mesh_id);
ob->data = BKE_mesh_add(G.main, name);
ob->lay = 1;
@@ -491,7 +493,7 @@ Object *BlenderStrokeRenderer::NewMesh() const
#else
(void)base;
#endif
- ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
+ ob->recalc = OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
return ob;
}
diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h
index cb35b0045f7..7c1bc4d12d6 100644
--- a/source/blender/render/extern/include/RE_engine.h
+++ b/source/blender/render/extern/include/RE_engine.h
@@ -66,6 +66,10 @@ struct Scene;
#define RE_ENGINE_HIGHLIGHT_TILES 32
#define RE_ENGINE_USED_FOR_VIEWPORT 64
+/* RenderEngine.update_flag, used by internal now */
+#define RE_ENGINE_UPDATE_MA 1
+#define RE_ENGINE_UPDATE_OTHER 2
+
extern ListBase R_engines;
typedef struct RenderEngineType {
@@ -92,7 +96,7 @@ typedef struct RenderEngine {
RenderEngineType *type;
void *py_instance;
- int flag;
+ int flag, update_flag;
struct Object *camera_override;
int tile_x;
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index 96106296443..9a8b1620f71 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -197,12 +197,18 @@ void RE_SetPixelSize(struct Render *re, float pixsize);
/* option to set viewmatrix before making dbase */
void RE_SetView(struct Render *re, float mat[4][4]);
+/* get current view and window transform */
+void RE_GetView(struct Render *re, float mat[4][4]);
+void RE_GetViewPlane(struct Render *re, rctf *viewplane, rcti *disprect);
+
/* make or free the dbase */
void RE_Database_FromScene(struct Render *re, struct Main *bmain, struct Scene *scene, unsigned int lay, int use_camera_view);
void RE_Database_Free(struct Render *re);
/* project dbase again, when viewplane/perspective changed */
void RE_DataBase_ApplyWindow(struct Render *re);
+/* rotate scene again, for incremental render */
+void RE_DataBase_IncrementalView(struct Render *re, float viewmat[4][4], int restore);
/* override the scene setting for amount threads, commandline */
void RE_set_max_threads(int threads);
diff --git a/source/blender/render/intern/include/envmap.h b/source/blender/render/intern/include/envmap.h
index a6c6d46e2e9..79233a5d625 100644
--- a/source/blender/render/intern/include/envmap.h
+++ b/source/blender/render/intern/include/envmap.h
@@ -48,6 +48,7 @@ struct ImagePool;
void make_envmaps(struct Render *re);
int envmaptex(struct Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres, struct ImagePool *pool);
+void env_rotate_scene(struct Render *re, float mat[4][4], int mode);
#endif /* __ENVMAP_H__ */
diff --git a/source/blender/render/intern/include/initrender.h b/source/blender/render/intern/include/initrender.h
index 73dc29c8feb..69706ecc933 100644
--- a/source/blender/render/intern/include/initrender.h
+++ b/source/blender/render/intern/include/initrender.h
@@ -40,9 +40,9 @@ struct Object;
void free_sample_tables(Render *re);
void make_sample_tables(Render *re);
-void RE_parts_clamp(Render *re);
void RE_parts_init(Render *re, int do_crop);
void RE_parts_free(Render *re);
+void RE_parts_clamp(Render *re);
#endif /* __INITRENDER_H__ */
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index f3cd60d8031..eb2f1cb5826 100644
--- a/source/blender/render/intern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -166,6 +166,7 @@ struct Render
float grvec[3]; /* for world */
float imat[3][3]; /* copy of viewinv */
float viewmat[4][4], viewinv[4][4];
+ float viewmat_orig[4][4]; /* for incremental render */
float winmat[4][4];
/* clippping */
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 76179b25871..d83df4e78b0 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -4851,10 +4851,11 @@ void RE_Database_Free(Render *re)
/* free orco */
free_mesh_orco_hash(re);
- end_render_materials(re->main);
- end_render_textures(re);
-
- free_pointdensities(re);
+ if (re->main) {
+ end_render_materials(re->main);
+ end_render_textures(re);
+ free_pointdensities(re);
+ }
free_camera_inside_volumes(re);
@@ -5202,14 +5203,17 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int lay, int use_camera_view)
{
Scene *sce;
+ Object *camera;
float mat[4][4];
float amb[3];
- Object *camera= RE_GetCamera(re);
re->main= bmain;
re->scene= scene;
re->lay= lay;
+ /* scene needs to be set to get camera */
+ camera= RE_GetCamera(re);
+
/* per second, per object, stats print this */
re->i.infostr= "Preparing Scene data";
re->i.cfra= scene->r.cfra;
@@ -5246,6 +5250,9 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l
camera->recalc= OB_RECALC_OB; /* force correct matrix for scaled cameras */
}
+ /* store for incremental render, viewmat rotates dbase */
+ copy_m4_m4(re->viewmat_orig, re->viewmat);
+
init_render_world(re); /* do first, because of ambient. also requires re->osa set correct */
if (re->r.mode & R_RAYTRACE) {
init_render_qmcsampler(re);
@@ -5354,6 +5361,23 @@ void RE_DataBase_ApplyWindow(Render *re)
project_renderdata(re, projectverto, 0, 0, 0);
}
+/* exported call to rotate render data again, when viewmat changed */
+void RE_DataBase_IncrementalView(Render *re, float viewmat[4][4], int restore)
+{
+ float oldviewinv[4][4], tmat[4][4];
+
+ invert_m4_m4(oldviewinv, re->viewmat_orig);
+
+ /* we have to correct for the already rotated vertexcoords */
+ mult_m4_m4m4(tmat, viewmat, oldviewinv);
+
+ copy_m4_m4(re->viewmat, viewmat);
+ invert_m4_m4(re->viewinv, re->viewmat);
+
+ env_rotate_scene(re, tmat, !restore);
+}
+
+
void RE_DataBase_GetView(Render *re, float mat[4][4])
{
copy_m4_m4(mat, re->viewmat);
diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c
index c5872c52e0f..6423bfa9486 100644
--- a/source/blender/render/intern/source/envmap.c
+++ b/source/blender/render/intern/source/envmap.c
@@ -246,10 +246,26 @@ static void envmap_transmatrix(float mat[4][4], int part)
NULL, NULL, NULL,
NULL, NULL, NULL);
}
+/* ------------------------------------------------------------------------- */
+
+static void env_set_imats(Render *re)
+{
+ Base *base;
+ float mat[4][4];
+
+ base = re->scene->base.first;
+ while (base) {
+ mult_m4_m4m4(mat, re->viewmat, base->object->obmat);
+ invert_m4_m4(base->object->imat, mat);
+
+ base = base->next;
+ }
+
+}
/* ------------------------------------------------------------------------- */
-static void env_rotate_scene(Render *re, float mat[4][4], int mode)
+void env_rotate_scene(Render *re, float mat[4][4], int mode)
{
GroupObject *go;
ObjectRen *obr;
@@ -328,6 +344,10 @@ static void env_rotate_scene(Render *re, float mat[4][4], int mode)
}
}
+ if (mode) {
+ init_render_world(re);
+ env_set_imats(re);
+ }
}
/* ------------------------------------------------------------------------- */
@@ -395,23 +415,6 @@ static void env_showobjects(Render *re)
/* ------------------------------------------------------------------------- */
-static void env_set_imats(Render *re)
-{
- Base *base;
- float mat[4][4];
-
- base = re->scene->base.first;
- while (base) {
- mult_m4_m4m4(mat, re->viewmat, base->object->obmat);
- invert_m4_m4(base->object->imat, mat);
-
- base = base->next;
- }
-
-}
-
-/* ------------------------------------------------------------------------- */
-
static void render_envmap(Render *re, EnvMap *env)
{
/* only the cubemap and planar map is implemented */
@@ -454,11 +457,9 @@ static void render_envmap(Render *re, EnvMap *env)
invert_m4_m4(env->imat, tmat);
env_rotate_scene(envre, tmat, 1);
- init_render_world(envre);
project_renderdata(envre, projectverto, 0, 0, 1);
env_layerflags(envre, env->notlay);
env_hideobject(envre, env->object);
- env_set_imats(envre);
if (re->test_break(re->tbh) == 0) {
RE_TileProcessor(envre);
diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c
index 90528fddc85..7ce5d9f72de 100644
--- a/source/blender/render/intern/source/external_engine.c
+++ b/source/blender/render/intern/source/external_engine.c
@@ -116,6 +116,18 @@ RenderEngineType *RE_engines_find(const char *idname)
if (!type)
type = &internal_render_type;
+ /* XXX Hack to make this a debug-only option, remove section to make it available default */
+ if (type == &internal_render_type) {
+ static RenderEngineType rtype;
+
+ if (type->view_update == NULL)
+ rtype = internal_render_type;
+ else if (G.debug_value != -1) {
+ type = &rtype;
+ }
+ }
+ /* XXX end hack */
+
return type;
}
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index da756447f96..7f2c3b5ad04 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -328,6 +328,9 @@ void RE_AcquireResultImage(Render *re, RenderResult *rr)
rr->have_combined = (re->result->rectf != NULL);
rr->layers = re->result->layers;
+
+ rr->xof = re->disprect.xmin;
+ rr->yof = re->disprect.ymin;
}
}
}
@@ -402,7 +405,10 @@ void RE_FreeRender(Render *re)
BLI_rw_mutex_end(&re->resultmutex);
- free_renderdata_tables(re);
+ /* main dbase can already be invalid now, some database-free code checks it */
+ re->main = NULL;
+
+ RE_Database_Free(re); /* view render can still have full database */
free_sample_tables(re);
render_result_free(re->result);
@@ -564,13 +570,9 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, SceneRenderLayer *
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
if (re->r.scemode & R_PREVIEWBUTS) {
- if (re->result && re->result->rectx == re->rectx && re->result->recty == re->recty) {
- /* pass */
- }
- else {
- render_result_free(re->result);
- re->result = NULL;
- }
+ /* always fresh, freestyle layers need it */
+ render_result_free(re->result);
+ re->result = NULL;
}
else {
@@ -580,6 +582,9 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, SceneRenderLayer *
re->result->rectx = re->rectx;
re->result->recty = re->recty;
}
+
+ /* ensure renderdatabase can use part settings correct */
+ RE_parts_clamp(re);
BLI_rw_mutex_unlock(&re->resultmutex);
@@ -627,6 +632,22 @@ void RE_SetView(Render *re, float mat[4][4])
invert_m4_m4(re->viewinv, re->viewmat);
}
+void RE_GetViewPlane(Render *re, rctf *viewplane, rcti *disprect)
+{
+ *viewplane = re->viewplane;
+
+ /* make disprect zero when no border render, is needed to detect changes in 3d view render */
+ if (re->r.mode & R_BORDER)
+ *disprect = re->disprect;
+ else
+ BLI_rcti_init(disprect, 0, 0, 0, 0);
+}
+
+void RE_GetView(Render *re, float mat[4][4])
+{
+ copy_m4_m4(mat, re->viewmat);
+}
+
/* image and movie output has to move to either imbuf or kernel */
void RE_display_init_cb(Render *re, void *handle, void (*f)(void *handle, RenderResult *rr))
{
@@ -1035,18 +1056,37 @@ static void threaded_tile_processor(Render *re)
re->viewplane = viewplane; /* restore viewplane, modified by pano render */
}
+#ifdef WITH_FREESTYLE
+static void add_freestyle(Render *re);
+static void free_all_freestyle_renders(Scene *scene);
+#endif
+
/* currently only called by preview renders and envmap */
void RE_TileProcessor(Render *re)
{
threaded_tile_processor(re);
-}
-
-/* ************ This part uses API, for rendering Blender scenes ********** */
+
+ re->i.lastframetime = PIL_check_seconds_timer() - re->i.starttime;
+ re->stats_draw(re->sdh, &re->i);
#ifdef WITH_FREESTYLE
-static void add_freestyle(Render *re);
+ /* Freestyle */
+ if (re->r.mode & R_EDGE_FRS) {
+ if (!re->test_break(re->tbh)) {
+ add_freestyle(re);
+
+ free_all_freestyle_renders(re->scene);
+
+ re->i.lastframetime = PIL_check_seconds_timer() - re->i.starttime;
+ re->stats_draw(re->sdh, &re->i);
+ }
+ }
#endif
+}
+
+/* ************ This part uses API, for rendering Blender scenes ********** */
+
static void do_render_3d(Render *re)
{
float cfra;
diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c
index 0fee1e41e32..f719e09769d 100644
--- a/source/blender/render/intern/source/render_result.c
+++ b/source/blender/render/intern/source/render_result.c
@@ -569,6 +569,7 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
}
/* border render; calculate offset for use in compositor. compo is centralized coords */
+ /* XXX obsolete? I now use it for drawing border render offset (ton) */
rr->xof = re->disprect.xmin + BLI_rcti_cent_x(&re->disprect) - (re->winx / 2);
rr->yof = re->disprect.ymin + BLI_rcti_cent_y(&re->disprect) - (re->winy / 2);
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index 9810d1ecf72..31f2b412a7f 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -438,6 +438,10 @@ void WM_exit_ext(bContext *C, const short do_python)
BKE_mball_cubeTable_free();
+ /* render code might still access databases */
+ RE_FreeAllRender();
+ RE_engines_exit();
+
ED_preview_free_dbase(); /* frees a Main dbase, before free_blender! */
if (C && wm)
@@ -468,9 +472,6 @@ void WM_exit_ext(bContext *C, const short do_python)
ANIM_keyingset_infos_exit();
- RE_FreeAllRender();
- RE_engines_exit();
-
// free_txt_data();