diff options
author | Michael Fox <mfoxdogg@gmail.com> | 2009-01-16 03:58:33 +0300 |
---|---|---|
committer | Michael Fox <mfoxdogg@gmail.com> | 2009-01-16 03:58:33 +0300 |
commit | 087b8b104a9769dc9facc4f20bc18a0e26ec6c0f (patch) | |
tree | 20208c6efcde45960044eb17fbeeb56a3721a59e /source/blender/editors/space_view3d/view3d_edit.c | |
parent | 54fa55394b262536534256c29d1af6e84fda60ac (diff) |
2.5
*****
- ported BorderZoom , shift-b
- currently disabled in camera view as to not conflict with setting render border
Diffstat (limited to 'source/blender/editors/space_view3d/view3d_edit.c')
-rw-r--r-- | source/blender/editors/space_view3d/view3d_edit.c | 288 |
1 files changed, 163 insertions, 125 deletions
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index b2907cde8e7..45226f93d93 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -955,6 +955,169 @@ void VIEW3D_OT_render_border(wmOperatorType *ot) RNA_def_property(ot->srna, "ymax", PROP_INT, PROP_NONE); } +/* ********************* Border Zoom operator ****************** */ + +static int view3d_border_zoom_exec(bContext *C, wmOperator *op) +{ + ScrArea *sa= CTX_wm_area(C); + ARegion *ar= CTX_wm_region(C); + View3D *v3d= sa->spacedata.first; + Scene *scene= CTX_data_scene(C); + + /* Zooms in on a border drawn by the user */ + rcti rect; + float dvec[3], vb[2], xscale, yscale, scale; + + /* SMOOTHVIEW */ + float new_dist; + float new_ofs[3]; + + /* ZBuffer depth vars */ + bglMats mats; + float depth, depth_close= MAXFLOAT; + int had_depth = 0; + double cent[2], p[3]; + int xs, ys; + + /* note; otherwise opengl won't work */ + view3d_operator_needs_opengl(C); + + /* get border select values using rna */ + rect.xmin= RNA_int_get(op->ptr, "xmin"); + rect.ymin= RNA_int_get(op->ptr, "ymin"); + rect.xmax= RNA_int_get(op->ptr, "xmax"); + rect.ymax= RNA_int_get(op->ptr, "ymax"); + + /* Get Z Depths, needed for perspective, nice for ortho */ + bgl_get_mats(&mats); + draw_depth(scene, ar, v3d, NULL); + + /* force updating */ + if (v3d->depths) { + had_depth = 1; + v3d->depths->damaged = 1; + } + + view3d_update_depths(ar, v3d); + + /* Constrain rect to depth bounds */ + if (rect.xmin < 0) rect.xmin = 0; + if (rect.ymin < 0) rect.ymin = 0; + if (rect.xmax >= v3d->depths->w) rect.xmax = v3d->depths->w-1; + if (rect.ymax >= v3d->depths->h) rect.ymax = v3d->depths->h-1; + + /* Find the closest Z pixel */ + for (xs=rect.xmin; xs < rect.xmax; xs++) { + for (ys=rect.ymin; ys < rect.ymax; ys++) { + depth= v3d->depths->depths[ys*v3d->depths->w+xs]; + if(depth < v3d->depths->depth_range[1] && depth > v3d->depths->depth_range[0]) { + if (depth_close > depth) { + depth_close = depth; + } + } + } + } + + if (had_depth==0) { + MEM_freeN(v3d->depths->depths); + v3d->depths->depths = NULL; + } + v3d->depths->damaged = 1; + + cent[0] = (((double)rect.xmin)+((double)rect.xmax)) / 2; + cent[1] = (((double)rect.ymin)+((double)rect.ymax)) / 2; + + if (v3d->persp==V3D_PERSP) { + double p_corner[3]; + + /* no depths to use, we cant do anything! */ + if (depth_close==MAXFLOAT) + return OPERATOR_CANCELLED; + + /* convert border to 3d coordinates */ + if (( !gluUnProject(cent[0], cent[1], depth_close, mats.modelview, mats.projection, (GLint *)mats.viewport, &p[0], &p[1], &p[2])) || + ( !gluUnProject((double)rect.xmin, (double)rect.ymin, depth_close, mats.modelview, mats.projection, (GLint *)mats.viewport, &p_corner[0], &p_corner[1], &p_corner[2]))) + return OPERATOR_CANCELLED; + + dvec[0] = p[0]-p_corner[0]; + dvec[1] = p[1]-p_corner[1]; + dvec[2] = p[2]-p_corner[2]; + + new_dist = VecLength(dvec); + if(new_dist <= v3d->near*1.5) new_dist= v3d->near*1.5; + + new_ofs[0] = -p[0]; + new_ofs[1] = -p[1]; + new_ofs[2] = -p[2]; + + } else { /* othographic */ + /* find the current window width and height */ + vb[0] = ar->winx; + vb[1] = ar->winy; + + new_dist = v3d->dist; + + /* convert the drawn rectangle into 3d space */ + if (depth_close!=MAXFLOAT && gluUnProject(cent[0], cent[1], depth_close, mats.modelview, mats.projection, (GLint *)mats.viewport, &p[0], &p[1], &p[2])) { + new_ofs[0] = -p[0]; + new_ofs[1] = -p[1]; + new_ofs[2] = -p[2]; + } else { + /* We cant use the depth, fallback to the old way that dosnt set the center depth */ + new_ofs[0] = v3d->ofs[0]; + new_ofs[1] = v3d->ofs[1]; + new_ofs[2] = v3d->ofs[2]; + + initgrabz(v3d, -new_ofs[0], -new_ofs[1], -new_ofs[2]); + + window_to_3d(ar, v3d, dvec, (rect.xmin+rect.xmax-vb[0])/2, (rect.ymin+rect.ymax-vb[1])/2); + /* center the view to the center of the rectangle */ + VecSubf(new_ofs, new_ofs, dvec); + } + + /* work out the ratios, so that everything selected fits when we zoom */ + xscale = ((rect.xmax-rect.xmin)/vb[0]); + yscale = ((rect.ymax-rect.ymin)/vb[1]); + scale = (xscale >= yscale)?xscale:yscale; + + /* zoom in as required, or as far as we can go */ + new_dist = ((new_dist*scale) >= 0.001*v3d->grid)? new_dist*scale:0.001*v3d->grid; + } + + smooth_view(C, NULL, NULL, new_ofs, NULL, &new_dist, NULL); + + return OPERATOR_FINISHED; +} +static int view3d_border_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + ScrArea *sa= CTX_wm_area(C); + View3D *v3d= sa->spacedata.first; + + /* if in camera view do not exec the operator so we do not conflict with set render border*/ + if (v3d->persp != V3D_CAMOB) return WM_border_select_invoke(C, op, event); + else return OPERATOR_PASS_THROUGH; +} +void VIEW3D_OT_border_zoom(wmOperatorType *ot) +{ + + /* identifiers */ + ot->name= "Border Zoom"; + ot->idname= "VIEW3D_OT_border_zoom"; + + /* api callbacks */ + ot->invoke= view3d_border_zoom_invoke; + ot->exec= view3d_border_zoom_exec; + ot->modal= WM_border_select_modal; + + ot->poll= ED_operator_view3d_active; + + /* rna */ + RNA_def_property(ot->srna, "xmin", PROP_INT, PROP_NONE); + RNA_def_property(ot->srna, "xmax", PROP_INT, PROP_NONE); + RNA_def_property(ot->srna, "ymin", PROP_INT, PROP_NONE); + RNA_def_property(ot->srna, "ymax", PROP_INT, PROP_NONE); + +} /* ********************* Changing view operator ****************** */ static EnumPropertyItem prop_view_items[] = { @@ -1343,131 +1506,6 @@ void VIEW3D_OT_drawtype(wmOperatorType *ot) RNA_def_property_int_default(prop, -1); } -/* ********************************************************* */ - -void view3d_border_zoom(Scene *scene, ARegion *ar, View3D *v3d) -{ - - /* Zooms in on a border drawn by the user */ - rcti rect; - short val; - float dvec[3], vb[2], xscale, yscale, scale; - - - /* SMOOTHVIEW */ - float new_dist; - float new_ofs[3]; - - /* ZBuffer depth vars */ - bglMats mats; - float depth, depth_close= MAXFLOAT; - int had_depth = 0; - double cent[2], p[3]; - int xs, ys; - - /* Get the border input */ - val = 0; // XXX get_border(&rect, 3); - if(!val) return; - - /* Get Z Depths, needed for perspective, nice for ortho */ - bgl_get_mats(&mats); - draw_depth(scene, ar, v3d, NULL); - - /* force updating */ - if (v3d->depths) { - had_depth = 1; - v3d->depths->damaged = 1; - } - - view3d_update_depths(ar, v3d); - - /* Constrain rect to depth bounds */ - if (rect.xmin < 0) rect.xmin = 0; - if (rect.ymin < 0) rect.ymin = 0; - if (rect.xmax >= v3d->depths->w) rect.xmax = v3d->depths->w-1; - if (rect.ymax >= v3d->depths->h) rect.ymax = v3d->depths->h-1; - - /* Find the closest Z pixel */ - for (xs=rect.xmin; xs < rect.xmax; xs++) { - for (ys=rect.ymin; ys < rect.ymax; ys++) { - depth= v3d->depths->depths[ys*v3d->depths->w+xs]; - if(depth < v3d->depths->depth_range[1] && depth > v3d->depths->depth_range[0]) { - if (depth_close > depth) { - depth_close = depth; - } - } - } - } - - if (had_depth==0) { - MEM_freeN(v3d->depths->depths); - v3d->depths->depths = NULL; - } - v3d->depths->damaged = 1; - - cent[0] = (((double)rect.xmin)+((double)rect.xmax)) / 2; - cent[1] = (((double)rect.ymin)+((double)rect.ymax)) / 2; - - if (v3d->persp==V3D_PERSP) { - double p_corner[3]; - - /* no depths to use, we cant do anything! */ - if (depth_close==MAXFLOAT) - return; - - /* convert border to 3d coordinates */ - if (( !gluUnProject(cent[0], cent[1], depth_close, mats.modelview, mats.projection, (GLint *)mats.viewport, &p[0], &p[1], &p[2])) || - ( !gluUnProject((double)rect.xmin, (double)rect.ymin, depth_close, mats.modelview, mats.projection, (GLint *)mats.viewport, &p_corner[0], &p_corner[1], &p_corner[2]))) - return; - - dvec[0] = p[0]-p_corner[0]; - dvec[1] = p[1]-p_corner[1]; - dvec[2] = p[2]-p_corner[2]; - - new_dist = VecLength(dvec); - if(new_dist <= v3d->near*1.5) new_dist= v3d->near*1.5; - - new_ofs[0] = -p[0]; - new_ofs[1] = -p[1]; - new_ofs[2] = -p[2]; - - } else { /* othographic */ - /* find the current window width and height */ - vb[0] = ar->winx; - vb[1] = ar->winy; - - new_dist = v3d->dist; - - /* convert the drawn rectangle into 3d space */ - if (depth_close!=MAXFLOAT && gluUnProject(cent[0], cent[1], depth_close, mats.modelview, mats.projection, (GLint *)mats.viewport, &p[0], &p[1], &p[2])) { - new_ofs[0] = -p[0]; - new_ofs[1] = -p[1]; - new_ofs[2] = -p[2]; - } else { - /* We cant use the depth, fallback to the old way that dosnt set the center depth */ - new_ofs[0] = v3d->ofs[0]; - new_ofs[1] = v3d->ofs[1]; - new_ofs[2] = v3d->ofs[2]; - - initgrabz(v3d, -new_ofs[0], -new_ofs[1], -new_ofs[2]); - - window_to_3d(ar, v3d, dvec, (rect.xmin+rect.xmax-vb[0])/2, (rect.ymin+rect.ymax-vb[1])/2); - /* center the view to the center of the rectangle */ - VecSubf(new_ofs, new_ofs, dvec); - } - - /* work out the ratios, so that everything selected fits when we zoom */ - xscale = ((rect.xmax-rect.xmin)/vb[0]); - yscale = ((rect.ymax-rect.ymin)/vb[1]); - scale = (xscale >= yscale)?xscale:yscale; - - /* zoom in as required, or as far as we can go */ - new_dist = ((new_dist*scale) >= 0.001*v3d->grid)? new_dist*scale:0.001*v3d->grid; - } - - smooth_view(NULL, NULL, NULL, new_ofs, NULL, &new_dist, NULL); // XXX -} - /* ***************** 3d cursor cursor op ******************* */ /* mx my in region coords */ |