From 9be4c94204eaaddbfbbe4851eb517a684c853c54 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 16 Oct 2012 11:57:46 +0000 Subject: Cycles: non-camera viewport render border support This makes it possible to do a border render inside a viewport even when not looking through the camera. Render border could be defined by Ctrl-B shortcut (works for both camera render border and viewport render border). Camera render border could still be defined using Shift-B (so no muscule memory would be broken). Currently used a special flag of operator to do this, otherwise you'll need to either two operators with different poll callback or it could go into conflict with a border zoom, Border render of a viewport could be enabled/disabled in View panel using "Render Border" option. --- source/blender/blenkernel/BKE_blender.h | 2 +- source/blender/blenloader/intern/readfile.c | 88 +++++++++----- source/blender/editors/space_view3d/view3d_draw.c | 39 +++++-- source/blender/editors/space_view3d/view3d_edit.c | 128 ++++++++++++++++----- .../blender/editors/space_view3d/view3d_intern.h | 1 + source/blender/editors/space_view3d/view3d_ops.c | 9 +- source/blender/makesdna/DNA_view3d_types.h | 2 + source/blender/makesrna/intern/rna_space.c | 34 +++++- 8 files changed, 231 insertions(+), 72 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index e1c79f8d6c1..95d41a86239 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -42,7 +42,7 @@ extern "C" { * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 264 -#define BLENDER_SUBVERSION 2 +#define BLENDER_SUBVERSION 3 /* 262 was the last editmesh release but its has compatibility code for bmesh data, * so set the minversion to 2.61 */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 884a6432dda..35b6b400559 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -8046,40 +8046,63 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } - /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ - /* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */ - - { - Object *ob; + if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 3)) { + /* smoke branch */ + { + Object *ob; - for (ob = main->object.first; ob; ob = ob->id.next) { - ModifierData *md; - for (md = ob->modifiers.first; md; md = md->next) { - if (md->type == eModifierType_Smoke) { - SmokeModifierData *smd = (SmokeModifierData *)md; - if ((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain) { - /* keep branch saves if possible */ - if (!smd->domain->flame_max_temp) { - smd->domain->burning_rate = 0.75f; - smd->domain->flame_smoke = 1.0f; - smd->domain->flame_vorticity = 0.5f; - smd->domain->flame_ignition = 1.25f; - smd->domain->flame_max_temp = 1.75f; - smd->domain->adapt_threshold = 0.02f; - smd->domain->adapt_margin = 4; - smd->domain->flame_smoke_color[0] = 0.7f; - smd->domain->flame_smoke_color[1] = 0.7f; - smd->domain->flame_smoke_color[2] = 0.7f; + for (ob = main->object.first; ob; ob = ob->id.next) { + ModifierData *md; + for (md = ob->modifiers.first; md; md = md->next) { + if (md->type == eModifierType_Smoke) { + SmokeModifierData *smd = (SmokeModifierData *)md; + if ((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain) { + /* keep branch saves if possible */ + if (!smd->domain->flame_max_temp) { + smd->domain->burning_rate = 0.75f; + smd->domain->flame_smoke = 1.0f; + smd->domain->flame_vorticity = 0.5f; + smd->domain->flame_ignition = 1.25f; + smd->domain->flame_max_temp = 1.75f; + smd->domain->adapt_threshold = 0.02f; + smd->domain->adapt_margin = 4; + smd->domain->flame_smoke_color[0] = 0.7f; + smd->domain->flame_smoke_color[1] = 0.7f; + smd->domain->flame_smoke_color[2] = 0.7f; + } + } + else if ((smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow) { + if (!smd->flow->texture_size) { + smd->flow->fuel_amount = 1.0; + smd->flow->surface_distance = 1.5; + smd->flow->color[0] = 0.7f; + smd->flow->color[1] = 0.7f; + smd->flow->color[2] = 0.7f; + smd->flow->texture_size = 1.0f; + } } } - else if ((smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow) { - if (!smd->flow->texture_size) { - smd->flow->fuel_amount = 1.0; - smd->flow->surface_distance = 1.5; - smd->flow->color[0] = 0.7f; - smd->flow->color[1] = 0.7f; - smd->flow->color[2] = 0.7f; - smd->flow->texture_size = 1.0f; + } + } + } + + /* render border for viewport */ + { + bScreen *sc; + + for (sc = main->screen.first; sc; sc = sc->id.next) { + ScrArea *sa; + for (sa = sc->areabase.first; sa; sa = sa->next) { + SpaceLink *sl; + for (sl = sa->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; + if (v3d->render_border.xmin == 0.0f && v3d->render_border.ymin == 0.0f && + v3d->render_border.xmax == 0.0f && v3d->render_border.ymax == 0.0f) + { + v3d->render_border.xmax = 1.0f; + v3d->render_border.ymax = 1.0f; + } } } } @@ -8087,6 +8110,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ + /* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */ + /* don't forget to set version number in blender.c! */ } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 88375c409b8..8e1b0716136 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -2878,12 +2878,20 @@ static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar, int draw rctf viewborder; rcti cliprct; - ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, FALSE); + if (rv3d->persp == RV3D_CAMOB) { + ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, FALSE); - cliprct.xmin = viewborder.xmin + scene->r.border.xmin * BLI_rctf_size_x(&viewborder); - cliprct.ymin = viewborder.ymin + scene->r.border.ymin * BLI_rctf_size_y(&viewborder); - cliprct.xmax = viewborder.xmin + scene->r.border.xmax * BLI_rctf_size_x(&viewborder); - cliprct.ymax = viewborder.ymin + scene->r.border.ymax * BLI_rctf_size_y(&viewborder); + cliprct.xmin = viewborder.xmin + scene->r.border.xmin * BLI_rctf_size_x(&viewborder); + cliprct.ymin = viewborder.ymin + scene->r.border.ymin * BLI_rctf_size_y(&viewborder); + cliprct.xmax = viewborder.xmin + scene->r.border.xmax * BLI_rctf_size_x(&viewborder); + cliprct.ymax = viewborder.ymin + scene->r.border.ymax * BLI_rctf_size_y(&viewborder); + } + else { + cliprct.xmin = v3d->render_border.xmin * ar->winx; + cliprct.xmax = v3d->render_border.xmax * ar->winx; + cliprct.ymin = v3d->render_border.ymin * ar->winy; + cliprct.ymax = v3d->render_border.ymax * ar->winy; + } cliprct.xmin += ar->winrct.xmin; cliprct.xmax += ar->winrct.xmin; @@ -3129,8 +3137,20 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha Object *ob; - if (rv3d->persp == RV3D_CAMOB) + if (rv3d->persp == RV3D_CAMOB) { drawviewborder(scene, ar, v3d); + } + else if (v3d->flag2 & V3D_RENDER_BORDER) { + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + setlinestyle(3); + cpack(0x4040FF); + + glRectf(v3d->render_border.xmin * ar->winx, v3d->render_border.ymin * ar->winy, + v3d->render_border.xmax * ar->winx, v3d->render_border.ymax * ar->winy); + + setlinestyle(0); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */ @@ -3180,7 +3200,12 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); const char *grid_unit = NULL; - int draw_border = (rv3d->persp == RV3D_CAMOB && (scene->r.mode & R_BORDER)); + int draw_border = FALSE; + + if (rv3d->persp == RV3D_CAMOB) + draw_border = scene->r.mode & R_BORDER; + else + draw_border = v3d->flag2 & V3D_RENDER_BORDER; /* draw viewport using opengl */ if (v3d->drawtype != OB_RENDER || !view3d_main_area_do_render_draw(C) || draw_border) { diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 2a210ef0ee4..96264081f10 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -929,18 +929,6 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, wmEvent *event) } } -static int view3d_camera_active_poll(bContext *C) -{ - if (ED_operator_view3d_active(C)) { - RegionView3D *rv3d = CTX_wm_region_view3d(C); - if (rv3d && rv3d->persp == RV3D_CAMOB) { - return 1; - } - } - - return 0; -} - /* test for unlocked camera view in quad view */ static int view3d_camera_user_poll(bContext *C) { @@ -2633,42 +2621,71 @@ static int render_border_exec(bContext *C, wmOperator *op) View3D *v3d = CTX_wm_view3d(C); ARegion *ar = CTX_wm_region(C); RegionView3D *rv3d = ED_view3d_context_rv3d(C); + Scene *scene = CTX_data_scene(C); rcti rect; - rctf vb; + rctf vb, border; + + int camera_only = RNA_boolean_get(op->ptr, "camera_only"); + + if (camera_only && rv3d->persp != RV3D_CAMOB) + return OPERATOR_PASS_THROUGH; /* get border select values using rna */ WM_operator_properties_border_to_rcti(op, &rect); /* calculate range */ - ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &vb, FALSE); - scene->r.border.xmin = ((float)rect.xmin - vb.xmin) / BLI_rctf_size_x(&vb); - scene->r.border.ymin = ((float)rect.ymin - vb.ymin) / BLI_rctf_size_y(&vb); - scene->r.border.xmax = ((float)rect.xmax - vb.xmin) / BLI_rctf_size_x(&vb); - scene->r.border.ymax = ((float)rect.ymax - vb.ymin) / BLI_rctf_size_y(&vb); + if (rv3d->persp == RV3D_CAMOB) { + ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &vb, FALSE); + } + else { + vb.xmin = 0; + vb.ymin = 0; + vb.xmax = ar->winx; + vb.ymax = ar->winy; + } + + border.xmin = ((float)rect.xmin - vb.xmin) / BLI_rctf_size_x(&vb); + border.ymin = ((float)rect.ymin - vb.ymin) / BLI_rctf_size_y(&vb); + border.xmax = ((float)rect.xmax - vb.xmin) / BLI_rctf_size_x(&vb); + border.ymax = ((float)rect.ymax - vb.ymin) / BLI_rctf_size_y(&vb); /* actually set border */ - CLAMP(scene->r.border.xmin, 0.0f, 1.0f); - CLAMP(scene->r.border.ymin, 0.0f, 1.0f); - CLAMP(scene->r.border.xmax, 0.0f, 1.0f); - CLAMP(scene->r.border.ymax, 0.0f, 1.0f); + CLAMP(border.xmin, 0.0f, 1.0f); + CLAMP(border.ymin, 0.0f, 1.0f); + CLAMP(border.xmax, 0.0f, 1.0f); + CLAMP(border.ymax, 0.0f, 1.0f); + + if (rv3d->persp == RV3D_CAMOB) { + scene->r.border = border; + + WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, NULL); + } + else { + v3d->render_border = border; + + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL); + } /* drawing a border surrounding the entire camera view switches off border rendering * or the border covers no pixels */ - if ((scene->r.border.xmin <= 0.0f && scene->r.border.xmax >= 1.0f && - scene->r.border.ymin <= 0.0f && scene->r.border.ymax >= 1.0f) || - (scene->r.border.xmin == scene->r.border.xmax || - scene->r.border.ymin == scene->r.border.ymax)) + if ((border.xmin <= 0.0f && border.xmax >= 1.0f && + border.ymin <= 0.0f && border.ymax >= 1.0f) || + (border.xmin == border.xmax || border.ymin == border.ymax)) { - scene->r.mode &= ~R_BORDER; + if (rv3d->persp == RV3D_CAMOB) + scene->r.mode &= ~R_BORDER; + else + v3d->flag2 &= ~V3D_RENDER_BORDER; } else { - scene->r.mode |= R_BORDER; + if (rv3d->persp == RV3D_CAMOB) + scene->r.mode |= R_BORDER; + else + v3d->flag2 |= V3D_RENDER_BORDER; } - - WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, NULL); return OPERATOR_FINISHED; @@ -2687,7 +2704,7 @@ void VIEW3D_OT_render_border(wmOperatorType *ot) ot->modal = WM_border_select_modal; ot->cancel = WM_border_select_cancel; - ot->poll = view3d_camera_active_poll; + ot->poll = ED_operator_view3d_active; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -2695,7 +2712,56 @@ void VIEW3D_OT_render_border(wmOperatorType *ot) /* rna */ WM_operator_properties_border(ot); + RNA_def_boolean(ot->srna, "camera_only", 0, "Camera Only", "Set render border for camera view and final render only"); +} + +/* ********************* Set render border operator ****************** */ + +static int clear_render_border_exec(bContext *C, wmOperator *UNUSED(op)) +{ + View3D *v3d = CTX_wm_view3d(C); + RegionView3D *rv3d = ED_view3d_context_rv3d(C); + + Scene *scene = CTX_data_scene(C); + rctf *border = NULL; + + if (rv3d->persp == RV3D_CAMOB) { + scene->r.mode &= ~R_BORDER; + border = &scene->r.border; + + WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, NULL); + } + else { + v3d->flag2 &= ~V3D_RENDER_BORDER; + border = &v3d->render_border; + + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL); + } + + border->xmin = 0.0f; + border->ymin = 0.0f; + border->xmax = 1.0f; + border->ymax = 1.0f; + + return OPERATOR_FINISHED; + } + +void VIEW3D_OT_clear_render_border(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Clear Render Border"; + ot->description = "Clear the boundaries of the border render and enables border render"; + ot->idname = "VIEW3D_OT_clear_render_border"; + + /* api callbacks */ + ot->exec = clear_render_border_exec; + ot->poll = ED_operator_view3d_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + /* ********************* Border Zoom operator ****************** */ static int view3d_zoom_border_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index e364014c42f..8f7656a1f37 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -98,6 +98,7 @@ void VIEW3D_OT_cursor3d(struct wmOperatorType *ot); void VIEW3D_OT_manipulator(struct wmOperatorType *ot); void VIEW3D_OT_enable_manipulator(struct wmOperatorType *ot); void VIEW3D_OT_render_border(struct wmOperatorType *ot); +void VIEW3D_OT_clear_render_border(struct wmOperatorType *ot); void VIEW3D_OT_zoom_border(struct wmOperatorType *ot); void view3d_boxview_copy(ScrArea *sa, ARegion *ar); diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index cb4f85430c5..73f1563417c 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -83,6 +83,7 @@ void view3d_operatortypes(void) WM_operatortype_append(VIEW3D_OT_select_circle); WM_operatortype_append(VIEW3D_OT_smoothview); WM_operatortype_append(VIEW3D_OT_render_border); + WM_operatortype_append(VIEW3D_OT_clear_render_border); WM_operatortype_append(VIEW3D_OT_zoom_border); WM_operatortype_append(VIEW3D_OT_manipulator); WM_operatortype_append(VIEW3D_OT_enable_manipulator); @@ -345,7 +346,13 @@ void view3d_keymap(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "VIEW3D_OT_clip_border", BKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_zoom_border", BKEY, KM_PRESS, KM_SHIFT, 0); - WM_keymap_add_item(keymap, "VIEW3D_OT_render_border", BKEY, KM_PRESS, KM_SHIFT, 0); + + kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_render_border", BKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "camera_only", TRUE); + kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_render_border", BKEY, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "camera_only", FALSE); + + WM_keymap_add_item(keymap, "VIEW3D_OT_clear_render_border", BKEY, KM_PRESS, KM_CTRL | KM_ALT, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_camera_to_view", PAD0, KM_PRESS, KM_ALT | KM_CTRL, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_object_as_camera", PAD0, KM_PRESS, KM_CTRL, 0); diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index 9da10381af0..c83b0bc366f 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -169,6 +169,7 @@ typedef struct View3D { short view DNA_DEPRECATED; struct Object *camera, *ob_centre; + rctf render_border; struct ListBase bgpicbase; struct BGpic *bgpic DNA_DEPRECATED; /* deprecated, use bgpicbase, only kept for do_versions(...) */ @@ -267,6 +268,7 @@ typedef struct View3D { #define V3D_SHOW_CAMERAPATH 256 #define V3D_SHOW_BUNDLENAME 512 #define V3D_BACKFACE_CULLING 1024 +#define V3D_RENDER_BORDER 2048 /* View3D->around */ #define V3D_CENTER 0 diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index bfd0f731626..13aa5557964 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -1494,7 +1494,39 @@ static void rna_def_space_view3d(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Camera", "Active camera used in this view (when unlocked from the scene's active camera)"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); - + + /* render border */ + prop = RNA_def_property(srna, "use_render_border", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_RENDER_BORDER); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, "Render Border", + "use a user-defined border region within the frame size for rendered viewport"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + + prop = RNA_def_property(srna, "render_border_min_x", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "render_border.xmin"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Border Minimum X", "Minimum X value to for the render border"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + + prop = RNA_def_property(srna, "render_border_min_y", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "render_border.ymin"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Border Minimum Y", "Minimum Y value for the render border"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + + prop = RNA_def_property(srna, "render_border_max_x", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "render_border.xmax"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Border Maximum X", "Maximum X value for the render border"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + + prop = RNA_def_property(srna, "render_border_max_y", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "render_border.ymax"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Border Maximum Y", "Maximum Y value for the render border"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + prop = RNA_def_property(srna, "lock_object", PROP_POINTER, PROP_NONE); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_pointer_sdna(prop, NULL, "ob_centre"); -- cgit v1.2.3