diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2013-03-18 04:48:59 +0400 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2013-03-18 04:48:59 +0400 |
commit | c1ceab1281ccf061f03f8000bf190a082a5385d8 (patch) | |
tree | 01b9a9cfca80432d316bdad6c18c74eb025e9eb0 /source/blender/editors/space_view3d | |
parent | 0d9c98c4bbfbc8c70c4772086dd09a51d01921ef (diff) | |
parent | 66a35e089a64d27bfc09c2225a530069eca05875 (diff) |
Merged changes in the trunk up to revision 55357.
Resolved conflicts:
release/datafiles/startup.blend
source/blender/editors/space_nla/nla_buttons.c
Also updated source/blender/blenkernel/intern/linestyle.c as a follow-up of
recent changes for the use of bool.
Diffstat (limited to 'source/blender/editors/space_view3d')
-rw-r--r-- | source/blender/editors/space_view3d/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/drawmesh.c | 8 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/drawobject.c | 29 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/space_view3d.c | 39 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_draw.c | 164 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_edit.c | 94 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_fly.c | 8 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_header.c | 18 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_intern.h | 3 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_ops.c | 1 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_project.c | 96 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_ruler.c | 939 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_select.c | 50 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_toolbar.c | 2 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_view.c | 41 |
15 files changed, 1264 insertions, 229 deletions
diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt index 462619a7e8b..a04371a5ed9 100644 --- a/source/blender/editors/space_view3d/CMakeLists.txt +++ b/source/blender/editors/space_view3d/CMakeLists.txt @@ -54,6 +54,7 @@ set(SRC view3d_iterators.c view3d_ops.c view3d_project.c + view3d_ruler.c view3d_select.c view3d_snap.c view3d_toolbar.c diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index 2cef10e1981..9000ccbf324 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -428,7 +428,9 @@ static DMDrawOption draw_tface__set_draw_legacy(MTFace *tface, int has_mcol, int return DM_DRAW_OPTION_NO_MCOL; /* Don't set color */ } else if (!has_mcol) { - if (tface) glColor3f(1.0, 1.0, 1.0); + if (tface) { + glColor3f(1.0, 1.0, 1.0); + } else { if (ma) { float col[3]; @@ -437,7 +439,9 @@ static DMDrawOption draw_tface__set_draw_legacy(MTFace *tface, int has_mcol, int glColor3fv(col); } - else glColor3f(1.0, 1.0, 1.0); + else { + glColor3f(1.0, 1.0, 1.0); + } } return DM_DRAW_OPTION_NO_MCOL; /* Don't set color */ } diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 158b75c494a..743b53ce16c 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -615,7 +615,7 @@ static void draw_empty_image(Object *ob, const short dflag, const unsigned char glColor4fv(ob->col); /* Draw the Image on the screen */ - glaDrawPixelsTex(ofs_x, ofs_y, ima_x, ima_y, GL_UNSIGNED_BYTE, ibuf->rect); + glaDrawPixelsTex(ofs_x, ofs_y, ima_x, ima_y, GL_UNSIGNED_BYTE, GL_LINEAR, ibuf->rect); glPixelTransferf(GL_ALPHA_SCALE, 1.0f); glDisable(GL_BLEND); @@ -812,17 +812,6 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, floa } for (vos = strings->first; vos; vos = vos->next) { - /* too slow, reading opengl info while drawing is very bad, - * better to see if we can use the zbuffer while in pixel space - campbell */ -#if 0 - if (v3d->zbuf && (vos->flag & V3D_CACHE_TEXT_ZBUF)) { - gluProject(vos->vec[0], vos->vec[1], vos->vec[2], mats.modelview, mats.projection, (GLint *)mats.viewport, &ux, &uy, &uz); - glReadPixels(ar->winrct.xmin + vos->mval[0] + vos->xoffs, ar->winrct.ymin + vos->mval[1], 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth); - - if (uz > depth) - continue; - } -#endif if (vos->sco[0] != IS_CLIPPED) { const char *str = (char *)(vos + 1); @@ -3862,7 +3851,7 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas if (v3d->flag2 & V3D_BACKFACE_CULLING) { /* not all displists use same in/out normal direction convention */ glEnable(GL_CULL_FACE); - glCullFace((base->object->type == OB_MBALL) ? GL_BACK : GL_FRONT); + glCullFace((base->object->type == OB_MBALL || base->object->derivedFinal) ? GL_BACK : GL_FRONT); } retval = drawDispList_nobackface(scene, v3d, rv3d, base, dt, dflag, ob_wire_col); @@ -3968,7 +3957,9 @@ static void draw_particle(ParticleKey *state, int draw_as, short draw, float pix if (draw_as == PART_DRAW_AXIS) { copy_v3_v3(vec2, state->co); } - else sub_v3_v3v3(vec2, state->co, vec); + else { + sub_v3_v3v3(vec2, state->co, vec); + } add_v3_v3(vec, state->co); copy_v3_v3(pdd->vd, vec); pdd->vd += 3; @@ -3980,7 +3971,9 @@ static void draw_particle(ParticleKey *state, int draw_as, short draw, float pix if (draw_as == PART_DRAW_AXIS) { copy_v3_v3(vec2, state->co); } - else sub_v3_v3v3(vec2, state->co, vec); + else { + sub_v3_v3v3(vec2, state->co, vec); + } add_v3_v3(vec, state->co); @@ -6055,8 +6048,10 @@ static void drawtexspace(Object *ob) copy_v3_v3(size, mb->size); copy_v3_v3(loc, mb->loc); } - else return; - + else { + return; + } + vec[0][0] = vec[1][0] = vec[2][0] = vec[3][0] = loc[0] - size[0]; vec[4][0] = vec[5][0] = vec[6][0] = vec[7][0] = loc[0] + size[0]; diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 57755231240..d332fb9f8b3 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -48,10 +48,12 @@ #include "BKE_object.h" #include "BKE_screen.h" +#include "ED_render.h" #include "ED_space_api.h" #include "ED_screen.h" #include "ED_object.h" +#include "GPU_extensions.h" #include "GPU_material.h" #include "BIF_gl.h" @@ -350,7 +352,7 @@ static void view3d_free(SpaceLink *sl) /* spacetype; init callback */ -static void view3d_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa)) +static void view3d_init(wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa)) { } @@ -469,7 +471,22 @@ static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar) } -static int view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event)) +static void view3d_main_area_exit(wmWindowManager *UNUSED(wm), ARegion *ar) +{ + RegionView3D *rv3d = ar->regiondata; + + if (rv3d->render_engine) { + RE_engine_free(rv3d->render_engine); + rv3d->render_engine = NULL; + } + + if (rv3d->gpuoffscreen) { + GPU_offscreen_free(rv3d->gpuoffscreen); + rv3d->gpuoffscreen = NULL; + } +} + +static int view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) { if (drag->type == WM_DRAG_ID) { ID *id = (ID *)drag->poin; @@ -479,7 +496,7 @@ static int view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSE return 0; } -static int view3d_group_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event)) +static int view3d_group_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) { if (drag->type == WM_DRAG_ID) { ID *id = (ID *)drag->poin; @@ -489,7 +506,7 @@ static int view3d_group_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UN return 0; } -static int view3d_mat_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event)) +static int view3d_mat_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) { if (drag->type == WM_DRAG_ID) { ID *id = (ID *)drag->poin; @@ -499,7 +516,7 @@ static int view3d_mat_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUS return 0; } -static int view3d_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event)) +static int view3d_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) { if (drag->type == WM_DRAG_ID) { ID *id = (ID *)drag->poin; @@ -513,7 +530,7 @@ static int view3d_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUS return 0; } -static int view3d_ima_bg_drop_poll(bContext *C, wmDrag *drag, wmEvent *event) +static int view3d_ima_bg_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) { if (event->ctrl) return false; @@ -524,7 +541,7 @@ static int view3d_ima_bg_drop_poll(bContext *C, wmDrag *drag, wmEvent *event) return 0; } -static int view3d_ima_empty_drop_poll(bContext *C, wmDrag *drag, wmEvent *event) +static int view3d_ima_empty_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) { Base *base = ED_view3d_give_base_under_cursor(C, event->mval); @@ -535,7 +552,7 @@ static int view3d_ima_empty_drop_poll(bContext *C, wmDrag *drag, wmEvent *event) return 0; } -static int view3d_ima_mesh_drop_poll(bContext *C, wmDrag *drag, wmEvent *event) +static int view3d_ima_mesh_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) { Base *base = ED_view3d_give_base_under_cursor(C, event->mval); @@ -615,6 +632,10 @@ static void view3d_main_area_free(ARegion *ar) if (rv3d->sms) { MEM_freeN(rv3d->sms); } + if (rv3d->gpuoffscreen) { + GPU_offscreen_free(rv3d->gpuoffscreen); + } + MEM_freeN(rv3d); ar->regiondata = NULL; } @@ -633,6 +654,7 @@ static void *view3d_main_area_duplicate(void *poin) new->clipbb = MEM_dupallocN(rv3d->clipbb); new->depths = NULL; + new->gpuoffscreen = NULL; new->ri = NULL; new->render_engine = NULL; new->gpd = NULL; @@ -1216,6 +1238,7 @@ void ED_spacetype_view3d(void) art->keymapflag = ED_KEYMAP_GPENCIL; art->draw = view3d_main_area_draw; art->init = view3d_main_area_init; + art->exit = view3d_main_area_exit; art->free = view3d_main_area_free; art->duplicate = view3d_main_area_duplicate; art->listener = view3d_main_area_listener; diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 4aaa3332252..8fdc9416513 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -219,15 +219,12 @@ void ED_view3d_clipping_enable(void) } } -static int view3d_clipping_test(const float vec[3], float clip[6][4]) +static int view3d_clipping_test(const float co[3], float clip[6][4]) { - float view[3]; - copy_v3_v3(view, vec); - - if (0.0f < clip[0][3] + dot_v3v3(view, clip[0])) - if (0.0f < clip[1][3] + dot_v3v3(view, clip[1])) - if (0.0f < clip[2][3] + dot_v3v3(view, clip[2])) - if (0.0f < clip[3][3] + dot_v3v3(view, clip[3])) + if (0.0f < clip[0][3] + dot_v3v3(co, clip[0])) + if (0.0f < clip[1][3] + dot_v3v3(co, clip[1])) + if (0.0f < clip[2][3] + dot_v3v3(co, clip[2])) + if (0.0f < clip[3][3] + dot_v3v3(co, clip[3])) return 0; return 1; @@ -235,9 +232,9 @@ static int view3d_clipping_test(const float vec[3], float clip[6][4]) /* for 'local' ED_view3d_clipping_local must run first * then all comparisons can be done in localspace */ -int ED_view3d_clipping_test(RegionView3D *rv3d, const float vec[3], const int is_local) +int ED_view3d_clipping_test(RegionView3D *rv3d, const float co[3], const bool is_local) { - return view3d_clipping_test(vec, is_local ? rv3d->clip_local : rv3d->clip); + return view3d_clipping_test(co, is_local ? rv3d->clip_local : rv3d->clip); } /* ********* end custom clipping *********** */ @@ -971,7 +968,7 @@ static void draw_selected_name(Scene *scene, Object *ob, rcti *rect) } static void view3d_camera_border(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, - rctf *viewborder_r, short no_shift, short no_zoom) + rctf *r_viewborder, const bool no_shift, const bool no_zoom) { CameraParams params; rctf rect_view, rect_camera; @@ -995,25 +992,25 @@ static void view3d_camera_border(Scene *scene, ARegion *ar, View3D *v3d, RegionV rect_camera = params.viewplane; /* get camera border within viewport */ - viewborder_r->xmin = ((rect_camera.xmin - rect_view.xmin) / BLI_rctf_size_x(&rect_view)) * ar->winx; - viewborder_r->xmax = ((rect_camera.xmax - rect_view.xmin) / BLI_rctf_size_x(&rect_view)) * ar->winx; - viewborder_r->ymin = ((rect_camera.ymin - rect_view.ymin) / BLI_rctf_size_y(&rect_view)) * ar->winy; - viewborder_r->ymax = ((rect_camera.ymax - rect_view.ymin) / BLI_rctf_size_y(&rect_view)) * ar->winy; + r_viewborder->xmin = ((rect_camera.xmin - rect_view.xmin) / BLI_rctf_size_x(&rect_view)) * ar->winx; + r_viewborder->xmax = ((rect_camera.xmax - rect_view.xmin) / BLI_rctf_size_x(&rect_view)) * ar->winx; + r_viewborder->ymin = ((rect_camera.ymin - rect_view.ymin) / BLI_rctf_size_y(&rect_view)) * ar->winy; + r_viewborder->ymax = ((rect_camera.ymax - rect_view.ymin) / BLI_rctf_size_y(&rect_view)) * ar->winy; } -void ED_view3d_calc_camera_border_size(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, float size_r[2]) +void ED_view3d_calc_camera_border_size(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, float r_size[2]) { rctf viewborder; view3d_camera_border(scene, ar, v3d, rv3d, &viewborder, TRUE, TRUE); - size_r[0] = BLI_rctf_size_x(&viewborder); - size_r[1] = BLI_rctf_size_y(&viewborder); + r_size[0] = BLI_rctf_size_x(&viewborder); + r_size[1] = BLI_rctf_size_y(&viewborder); } void ED_view3d_calc_camera_border(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, - rctf *viewborder_r, short no_shift) + rctf *viewborder_r, const bool no_shift) { - view3d_camera_border(scene, ar, v3d, rv3d, viewborder_r, no_shift, FALSE); + view3d_camera_border(scene, ar, v3d, rv3d, viewborder_r, no_shift, false); } static void drawviewborder_grid3(float x1, float x2, float y1, float y2, float fac) @@ -1316,11 +1313,6 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d) { /* do nothing */ } - else if ((base && (base->object->mode & OB_MODE_TEXTURE_PAINT)) && - scene->toolsettings && (scene->toolsettings->imapaint.flag & IMAGEPAINT_PROJECT_DISABLE)) - { - /* do nothing */ - } else if ((base && (base->object->mode & OB_MODE_PARTICLE_EDIT)) && v3d->drawtype > OB_WIRE && (v3d->flag & V3D_ZBUF_SELECT)) { @@ -1356,7 +1348,35 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d) if (multisample_enabled) glDisable(GL_MULTISAMPLE_ARB); - glScissor(ar->winrct.xmin, ar->winrct.ymin, BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct)); + if (U.ogl_multisamples != USER_MULTISAMPLE_NONE) { + /* for multisample we use an offscreen FBO. multisample drawing can fail + * with color coded selection drawing, and reading back depths from such + * a buffer can also cause a few seconds freeze on OS X / NVidia. */ + int w = BLI_rcti_size_x(&ar->winrct); + int h = BLI_rcti_size_y(&ar->winrct); + char error[256]; + + if (rv3d->gpuoffscreen) { + if (GPU_offscreen_width(rv3d->gpuoffscreen) != w || + GPU_offscreen_height(rv3d->gpuoffscreen) != h) + { + GPU_offscreen_free(rv3d->gpuoffscreen); + rv3d->gpuoffscreen = NULL; + } + } + + if (!rv3d->gpuoffscreen) { + rv3d->gpuoffscreen = GPU_offscreen_create(w, h, error); + + if (!rv3d->gpuoffscreen) + fprintf(stderr, "Failed to create offscreen selection buffer for multisample: %s\n", error); + } + } + + if (rv3d->gpuoffscreen) + GPU_offscreen_bind(rv3d->gpuoffscreen); + else + glScissor(ar->winrct.xmin, ar->winrct.ymin, BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct)); glClearColor(0.0, 0.0, 0.0, 0.0); if (v3d->zbuf) { @@ -1375,9 +1395,13 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d) if (base && (base->lay & v3d->lay)) draw_object_backbufsel(scene, v3d, rv3d, base->object); + + if (rv3d->gpuoffscreen) + GPU_offscreen_unbind(rv3d->gpuoffscreen); + else + ar->swap = 0; /* mark invalid backbuf for wm draw */ v3d->flag &= ~V3D_INVALID_BACKBUF; - ar->swap = 0; /* mark invalid backbuf for wm draw */ G.f &= ~G_BACKBUFSEL; v3d->zbuf = FALSE; @@ -1394,6 +1418,21 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d) } +void view3d_opengl_read_pixels(ARegion *ar, int x, int y, int w, int h, int format, int type, void *data) +{ + RegionView3D *rv3d = ar->regiondata; + + if (rv3d->gpuoffscreen) { + GPU_offscreen_bind(rv3d->gpuoffscreen); + glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); + glReadPixels(x, y, w, h, format, type, data); + GPU_offscreen_unbind(rv3d->gpuoffscreen); + } + else { + glReadPixels(ar->winrct.xmin + x, ar->winrct.ymin + y, w, h, format, type, data); + } +} + void view3d_validate_backbuf(ViewContext *vc) { if (vc->v3d->flag & V3D_INVALID_BACKBUF) @@ -1409,12 +1448,9 @@ unsigned int view3d_sample_backbuf(ViewContext *vc, int x, int y) return 0; } - x += vc->ar->winrct.xmin; - y += vc->ar->winrct.ymin; - view3d_validate_backbuf(vc); - glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col); + view3d_opengl_read_pixels(vc->ar, x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col); glReadBuffer(GL_BACK); if (ENDIAN_ORDER == B_ENDIAN) { @@ -1445,8 +1481,8 @@ ImBuf *view3d_read_backbuf(ViewContext *vc, short xmin, short ymin, short xmax, view3d_validate_backbuf(vc); - glReadPixels(vc->ar->winrct.xmin + xminc, - vc->ar->winrct.ymin + yminc, + view3d_opengl_read_pixels(vc->ar, + xminc, yminc, (xmaxc - xminc + 1), (ymaxc - yminc + 1), GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); @@ -1573,7 +1609,7 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, float fac, asp, zoomx, zoomy; float x1, y1, x2, y2; - ImBuf *ibuf = NULL, *freeibuf; + ImBuf *ibuf = NULL, *freeibuf, *releaseibuf; Image *ima; MovieClip *clip; @@ -1583,6 +1619,7 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, continue; freeibuf = NULL; + releaseibuf = NULL; if (bgpic->source == V3D_BGPIC_IMAGE) { ima = bgpic->ima; if (ima == NULL) @@ -1593,7 +1630,7 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, } else { ibuf = BKE_image_acquire_ibuf(ima, &bgpic->iuser, NULL); - freeibuf = ibuf; + releaseibuf = ibuf; } image_aspect[0] = ima->aspx; @@ -1608,7 +1645,9 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, if (scene->camera) clip = BKE_object_movieclip_get(scene, scene->camera, 1); } - else clip = bgpic->clip; + else { + clip = bgpic->clip; + } if (clip == NULL) continue; @@ -1636,6 +1675,8 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, if ((ibuf->rect == NULL && ibuf->rect_float == NULL) || ibuf->channels != 4) { /* invalid image format */ if (freeibuf) IMB_freeImBuf(freeibuf); + if (releaseibuf) + BKE_image_release_ibuf(ima, releaseibuf, NULL); continue; } @@ -1708,10 +1749,12 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, float tvec[3]; float sco[2]; const float mval_f[2] = {1.0f, 0.0f}; + const float co_zero[3] = {0}; + float zfac; /* calc window coord */ - initgrabz(rv3d, 0.0, 0.0, 0.0); - ED_view3d_win_to_delta(ar, mval_f, tvec); + zfac = ED_view3d_calc_zfac(rv3d, co_zero, NULL); + ED_view3d_win_to_delta(ar, mval_f, tvec, zfac); fac = max_ff(fabsf(tvec[0]), max_ff(fabsf(tvec[1]), fabsf(tvec[2]))); /* largest abs axis */ fac = 1.0f / fac; @@ -1731,6 +1774,8 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, if (x2 < 0 || y2 < 0 || x1 > ar->winx || y1 > ar->winy) { if (freeibuf) IMB_freeImBuf(freeibuf); + if (releaseibuf) + BKE_image_release_ibuf(ima, releaseibuf, NULL); continue; } @@ -1774,7 +1819,7 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, glPixelZoom(zoomx, zoomy); glColor4f(1.0f, 1.0f, 1.0f, 1.0f - bgpic->blend); - glaDrawPixelsTex(x1, y1, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, ibuf->rect); + glaDrawPixelsAuto(x1, y1, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, GL_LINEAR, ibuf->rect); glPixelZoom(1.0, 1.0); glPixelTransferf(GL_ALPHA_SCALE, 1.0f); @@ -1789,9 +1834,10 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, glDepthMask(1); if (v3d->zbuf) glEnable(GL_DEPTH_TEST); - if (freeibuf) { + if (freeibuf) IMB_freeImBuf(freeibuf); - } + if (releaseibuf) + BKE_image_release_ibuf(ima, releaseibuf, NULL); } } } @@ -2102,7 +2148,7 @@ void view3d_update_depths_rect(ARegion *ar, ViewDepths *d, rcti *rect) } if (d->damaged) { - glReadPixels(ar->winrct.xmin + d->x, ar->winrct.ymin + d->y, d->w, d->h, GL_DEPTH_COMPONENT, GL_FLOAT, d->depths); + view3d_opengl_read_pixels(ar, d->x, d->y, d->w, d->h, GL_DEPTH_COMPONENT, GL_FLOAT, d->depths); glGetDoublev(GL_DEPTH_RANGE, d->depth_range); d->damaged = FALSE; } @@ -2130,9 +2176,7 @@ void ED_view3d_depth_update(ARegion *ar) } if (d->damaged) { - glReadPixels(ar->winrct.xmin, ar->winrct.ymin, d->w, d->h, - GL_DEPTH_COMPONENT, GL_FLOAT, d->depths); - + view3d_opengl_read_pixels(ar, 0, 0, d->w, d->h, GL_DEPTH_COMPONENT, GL_FLOAT, d->depths); glGetDoublev(GL_DEPTH_RANGE, d->depth_range); d->damaged = 0; @@ -2999,7 +3043,7 @@ static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar) #define VIEWGRAD_RES_Y 16 GLubyte grid_col[VIEWGRAD_RES_X][VIEWGRAD_RES_Y][4]; - static float grid_pos[VIEWGRAD_RES_X][VIEWGRAD_RES_Y][2]; + static float grid_pos[VIEWGRAD_RES_X][VIEWGRAD_RES_Y][3]; static GLushort indices[VIEWGRAD_RES_X - 1][VIEWGRAD_RES_X - 1][4]; static char buf_calculated = FALSE; @@ -3008,8 +3052,6 @@ static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar) IMB_colormanagement_pixel_to_display_space_v3(col_zen, &scene->world->zenr, &scene->view_settings, &scene->display_settings); - glClear(GL_DEPTH_BUFFER_BIT); - glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); @@ -3029,6 +3071,7 @@ static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar) /* -1..1 range */ grid_pos[x][y][0] = (xf - 0.5f) * 2.0f; grid_pos[x][y][1] = (yf - 0.5f) * 2.0f; + grid_pos[x][y][2] = 1.0; } } @@ -3082,15 +3125,22 @@ static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar) } } + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_ALWAYS); + glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); - glVertexPointer(2, GL_FLOAT, 0, grid_pos); + glVertexPointer(3, GL_FLOAT, 0, grid_pos); glColorPointer(4, GL_UNSIGNED_BYTE, 0, grid_col); glDrawElements(GL_QUADS, (VIEWGRAD_RES_X - 1) * (VIEWGRAD_RES_Y - 1) * 4, GL_UNSIGNED_SHORT, indices); + glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY); + glDepthFunc(GL_LEQUAL); + glDisable(GL_DEPTH_TEST); + glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); @@ -3112,9 +3162,6 @@ static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar) } else { if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) { - /* only clear depth buffer here */ - glClear(GL_DEPTH_BUFFER_BIT); - glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); @@ -3122,17 +3169,22 @@ static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar) glPushMatrix(); glLoadIdentity(); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_ALWAYS); glShadeModel(GL_SMOOTH); glBegin(GL_QUADS); UI_ThemeColor(TH_LOW_GRAD); - glVertex2f(-1.0, -1.0); - glVertex2f(1.0, -1.0); + glVertex3f(-1.0, -1.0, 1.0); + glVertex3f(1.0, -1.0, 1.0); UI_ThemeColor(TH_HIGH_GRAD); - glVertex2f(1.0, 1.0); - glVertex2f(-1.0, 1.0); + glVertex3f(1.0, 1.0, 1.0); + glVertex3f(-1.0, 1.0, 1.0); glEnd(); glShadeModel(GL_FLAT); + glDepthFunc(GL_LEQUAL); + glDisable(GL_DEPTH_TEST); + glMatrixMode(GL_PROJECTION); glPopMatrix(); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 5f54f0dcfc8..8c8332075a2 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -368,6 +368,7 @@ typedef struct ViewOpsData { float reverse, dist0, camzoom0; float grid, far; short axis_snap; /* view rotate only */ + float zfac; /* use for orbit selection and auto-dist */ float ofs[3], dyn_ofs[3]; @@ -407,7 +408,7 @@ static void calctrackballvec(const rcti *rect, int mx, int my, float vec[3]) } -static void viewops_data_create(bContext *C, wmOperator *op, wmEvent *event) +static void viewops_data_create(bContext *C, wmOperator *op, const wmEvent *event) { static float lastofs[3] = {0, 0, 0}; RegionView3D *rv3d; @@ -504,7 +505,11 @@ static void viewops_data_create(bContext *C, wmOperator *op, wmEvent *event) calctrackballvec(&vod->ar->winrct, event->x, event->y, vod->trackvec); - initgrabz(rv3d, -rv3d->ofs[0], -rv3d->ofs[1], -rv3d->ofs[2]); + { + float tvec[3]; + negate_v3_v3(tvec, rv3d->ofs); + vod->zfac = ED_view3d_calc_zfac(rv3d, tvec, NULL); + } vod->reverse = 1.0f; if (rv3d->persmat[2][1] < 0.0f) @@ -836,7 +841,7 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y) ED_region_tag_redraw(vod->ar); } -static int viewrotate_modal(bContext *C, wmOperator *op, wmEvent *event) +static int viewrotate_modal(bContext *C, wmOperator *op, const wmEvent *event) { ViewOpsData *vod = op->customdata; short event_code = VIEW_PASS; @@ -885,7 +890,7 @@ static int viewrotate_modal(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_RUNNING_MODAL; } -static int viewrotate_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event) { ViewOpsData *vod; RegionView3D *rv3d; @@ -1092,7 +1097,7 @@ static void view3d_ndof_orbit(const struct wmNDOFMotionData *ndof, RegionView3D * -- zooming * -- panning in rotationally-locked views */ -static int ndof_orbit_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int ndof_orbit_invoke(bContext *C, wmOperator *op, const wmEvent *event) { if (event->type != NDOF_MOTION) @@ -1174,7 +1179,7 @@ void VIEW3D_OT_ndof_orbit(struct wmOperatorType *ot) } -static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *event) { if (event->type != NDOF_MOTION) @@ -1272,7 +1277,7 @@ void VIEW3D_OT_ndof_orbit_zoom(struct wmOperatorType *ot) /* -- "pan" navigation * -- zoom or dolly? */ -static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event) +static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) { if (event->type != NDOF_MOTION) return OPERATOR_CANCELLED; @@ -1366,7 +1371,7 @@ void VIEW3D_OT_ndof_pan(struct wmOperatorType *ot) /* * this is basically just the pan only code + the rotate only code crammed into one function that does both */ -static int ndof_all_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int ndof_all_invoke(bContext *C, wmOperator *op, const wmEvent *event) { if (event->type != NDOF_MOTION) { return OPERATOR_CANCELLED; @@ -1508,7 +1513,7 @@ static void viewmove_apply(ViewOpsData *vod, int x, int y) mval_f[0] = x - vod->oldx; mval_f[1] = y - vod->oldy; - ED_view3d_win_to_delta(vod->ar, mval_f, dvec); + ED_view3d_win_to_delta(vod->ar, mval_f, dvec, vod->zfac); add_v3_v3(vod->rv3d->ofs, dvec); @@ -1525,7 +1530,7 @@ static void viewmove_apply(ViewOpsData *vod, int x, int y) } -static int viewmove_modal(bContext *C, wmOperator *op, wmEvent *event) +static int viewmove_modal(bContext *C, wmOperator *op, const wmEvent *event) { ViewOpsData *vod = op->customdata; @@ -1568,7 +1573,7 @@ static int viewmove_modal(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_RUNNING_MODAL; } -static int viewmove_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int viewmove_invoke(bContext *C, wmOperator *op, const wmEvent *event) { ViewOpsData *vod; @@ -1665,15 +1670,16 @@ static void view_zoom_mouseloc(ARegion *ar, float dfac, int mx, int my) float tpos[3]; float mval_f[2]; float new_dist; + float zfac; negate_v3_v3(tpos, rv3d->ofs); - /* Project cursor position into 3D space */ - initgrabz(rv3d, tpos[0], tpos[1], tpos[2]); - mval_f[0] = (float)(((mx - ar->winrct.xmin) * 2) - ar->winx) / 2.0f; mval_f[1] = (float)(((my - ar->winrct.ymin) * 2) - ar->winy) / 2.0f; - ED_view3d_win_to_delta(ar, mval_f, dvec); + + /* Project cursor position into 3D space */ + zfac = ED_view3d_calc_zfac(rv3d, tpos, NULL); + ED_view3d_win_to_delta(ar, mval_f, dvec, zfac); /* Calculate view target position for dolly */ add_v3_v3v3(tvec, tpos, dvec); @@ -1788,7 +1794,7 @@ static void viewzoom_apply(ViewOpsData *vod, const int x, const int y, const sho } -static int viewzoom_modal(bContext *C, wmOperator *op, wmEvent *event) +static int viewzoom_modal(bContext *C, wmOperator *op, const wmEvent *event) { ViewOpsData *vod = op->customdata; short event_code = VIEW_PASS; @@ -1933,7 +1939,7 @@ void viewdolly_modal_keymap(wmKeyConfig *keyconf) } /* viewdolly_invoke() copied this function, changes here may apply there */ -static int viewzoom_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int viewzoom_invoke(bContext *C, wmOperator *op, const wmEvent *event) { ViewOpsData *vod; @@ -2053,7 +2059,7 @@ static void viewdolly_apply(ViewOpsData *vod, int x, int y, const short zoom_inv } -static int viewdolly_modal(bContext *C, wmOperator *op, wmEvent *event) +static int viewdolly_modal(bContext *C, wmOperator *op, const wmEvent *event) { ViewOpsData *vod = op->customdata; short event_code = VIEW_PASS; @@ -2145,7 +2151,7 @@ static int viewdolly_exec(bContext *C, wmOperator *op) } /* copied from viewzoom_invoke(), changes here may apply there */ -static int viewdolly_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int viewdolly_invoke(bContext *C, wmOperator *op, const wmEvent *event) { ViewOpsData *vod; @@ -2957,14 +2963,20 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op) } else { float mval_f[2]; + float zfac; + /* We cant use the depth, fallback to the old way that dosnt set the center depth */ copy_v3_v3(new_ofs, rv3d->ofs); - initgrabz(rv3d, -new_ofs[0], -new_ofs[1], -new_ofs[2]); + { + float tvec[3]; + negate_v3_v3(tvec, new_ofs); + zfac = ED_view3d_calc_zfac(rv3d, tvec, NULL); + } mval_f[0] = (rect.xmin + rect.xmax - vb[0]) / 2.0f; mval_f[1] = (rect.ymin + rect.ymax - vb[1]) / 2.0f; - ED_view3d_win_to_delta(ar, mval_f, dvec); + ED_view3d_win_to_delta(ar, mval_f, dvec, zfac); /* center the view to the center of the rectangle */ sub_v3_v3(new_ofs, dvec); } @@ -2997,7 +3009,7 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static int view3d_zoom_border_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int view3d_zoom_border_invoke(bContext *C, wmOperator *op, const wmEvent *event) { View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); @@ -3415,16 +3427,19 @@ static int viewpan_exec(bContext *C, wmOperator *op) ARegion *ar = CTX_wm_region(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); float vec[3]; + const float co_zero[3] = {0.0f}; float mval_f[2] = {0.0f, 0.0f}; + float zfac; int pandir; pandir = RNA_enum_get(op->ptr, "type"); - initgrabz(rv3d, 0.0, 0.0, 0.0); - if (pandir == V3D_VIEW_PANRIGHT) { mval_f[0] = -32.0f; ED_view3d_win_to_delta(ar, mval_f, vec); } - else if (pandir == V3D_VIEW_PANLEFT) { mval_f[0] = 32.0f; ED_view3d_win_to_delta(ar, mval_f, vec); } - else if (pandir == V3D_VIEW_PANUP) { mval_f[1] = -25.0f; ED_view3d_win_to_delta(ar, mval_f, vec); } - else if (pandir == V3D_VIEW_PANDOWN) { mval_f[1] = 25.0f; ED_view3d_win_to_delta(ar, mval_f, vec); } + zfac = ED_view3d_calc_zfac(rv3d, co_zero, NULL); + if (pandir == V3D_VIEW_PANRIGHT) { mval_f[0] = -32.0f; } + else if (pandir == V3D_VIEW_PANLEFT) { mval_f[0] = 32.0f; } + else if (pandir == V3D_VIEW_PANUP) { mval_f[1] = -25.0f; } + else if (pandir == V3D_VIEW_PANDOWN) { mval_f[1] = 25.0f; } + ED_view3d_win_to_delta(ar, mval_f, vec, zfac); add_v3_v3(rv3d->ofs, vec); if (rv3d->viewlock & RV3D_BOXVIEW) @@ -3506,7 +3521,7 @@ static int background_image_add_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_FINISHED; } -static int background_image_add_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) +static int background_image_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { View3D *v3d = CTX_wm_view3d(C); Image *ima = NULL; @@ -3661,7 +3676,7 @@ static int view3d_clipping_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static int view3d_clipping_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int view3d_clipping_invoke(bContext *C, wmOperator *op, const wmEvent *event) { RegionView3D *rv3d = CTX_wm_region_view3d(C); ARegion *ar = CTX_wm_region(C); @@ -3713,15 +3728,16 @@ void ED_view3d_cursor3d_position(bContext *C, float fp[3], const int mval[2]) View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); float mval_fl[2]; - int flip; + float zfac; + bool flip; - flip = initgrabz(rv3d, fp[0], fp[1], fp[2]); + zfac = ED_view3d_calc_zfac(rv3d, fp, &flip); /* reset the depth based on the view offset (we _know_ the offset is infront of us) */ if (flip) { negate_v3_v3(fp, rv3d->ofs); /* re initialize, no need to check flip again */ - /* flip = */ initgrabz(rv3d, fp[0], fp[1], fp[2]); + zfac = ED_view3d_calc_zfac(rv3d, fp, NULL /* &flip */ ); } if (ED_view3d_project_float_global(ar, fp, mval_fl, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { @@ -3736,17 +3752,17 @@ void ED_view3d_cursor3d_position(bContext *C, float fp[3], const int mval[2]) if (depth_used == FALSE) { float dvec[3]; VECSUB2D(mval_fl, mval_fl, mval); - ED_view3d_win_to_delta(ar, mval_fl, dvec); + ED_view3d_win_to_delta(ar, mval_fl, dvec, zfac); sub_v3_v3(fp, dvec); } } else { - const float dx = ((float)(mval[0] - (ar->winx / 2))) * rv3d->zfac / (ar->winx / 2); - const float dy = ((float)(mval[1] - (ar->winy / 2))) * rv3d->zfac / (ar->winy / 2); + const float dx = ((float)(mval[0] - (ar->winx / 2))) * zfac / (ar->winx / 2); + const float dy = ((float)(mval[1] - (ar->winy / 2))) * zfac / (ar->winy / 2); const float fz = (rv3d->persmat[0][3] * fp[0] + rv3d->persmat[1][3] * fp[1] + rv3d->persmat[2][3] * fp[2] + - rv3d->persmat[3][3]) / rv3d->zfac; + rv3d->persmat[3][3]) / zfac; fp[0] = (rv3d->persinv[0][0] * dx + rv3d->persinv[1][0] * dy + rv3d->persinv[2][0] * fz) - rv3d->ofs[0]; fp[1] = (rv3d->persinv[0][1] * dx + rv3d->persinv[1][1] * dy + rv3d->persinv[2][1] * fz) - rv3d->ofs[1]; @@ -3755,7 +3771,7 @@ void ED_view3d_cursor3d_position(bContext *C, float fp[3], const int mval[2]) } -static int view3d_cursor3d_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event) +static int view3d_cursor3d_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) { Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); @@ -3794,7 +3810,7 @@ void VIEW3D_OT_cursor3d(wmOperatorType *ot) /* ***************** manipulator op ******************* */ -static int manipulator_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int manipulator_invoke(bContext *C, wmOperator *op, const wmEvent *event) { View3D *v3d = CTX_wm_view3d(C); @@ -3830,7 +3846,7 @@ void VIEW3D_OT_manipulator(wmOperatorType *ot) Transform_Properties(ot, P_CONSTRAINT); } -static int enable_manipulator_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) +static int enable_manipulator_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { View3D *v3d = CTX_wm_view3d(C); diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c index c2e75a1c5d9..700027d62a2 100644 --- a/source/blender/editors/space_view3d/view3d_fly.c +++ b/source/blender/editors/space_view3d/view3d_fly.c @@ -272,7 +272,7 @@ static void drawFlyPixel(const struct bContext *UNUSED(C), ARegion *UNUSED(ar), #define FLY_CANCEL 1 #define FLY_CONFIRM 2 -static int initFlyInfo(bContext *C, FlyInfo *fly, wmOperator *op, wmEvent *event) +static int initFlyInfo(bContext *C, FlyInfo *fly, wmOperator *op, const wmEvent *event) { wmWindow *win = CTX_wm_window(C); float upvec[3]; /* tmp */ @@ -486,7 +486,7 @@ static int flyEnd(bContext *C, FlyInfo *fly) return OPERATOR_CANCELLED; } -static void flyEvent(FlyInfo *fly, wmEvent *event) +static void flyEvent(FlyInfo *fly, const wmEvent *event) { if (event->type == TIMER && event->customdata == fly->timer) { fly->redraw = 1; @@ -1179,7 +1179,7 @@ static int flyApply_ndof(bContext *C, FlyInfo *fly) return OPERATOR_FINISHED; } -static int fly_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int fly_invoke(bContext *C, wmOperator *op, const wmEvent *event) { RegionView3D *rv3d = CTX_wm_region_view3d(C); FlyInfo *fly; @@ -1214,7 +1214,7 @@ static int fly_cancel(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } -static int fly_modal(bContext *C, wmOperator *op, wmEvent *event) +static int fly_modal(bContext *C, wmOperator *op, const wmEvent *event) { int exit_code; short do_draw = FALSE; diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index e078fa8eda1..430ed8698d7 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -28,7 +28,6 @@ * \ingroup spview3d */ - #include <string.h> #include <stdio.h> #include <stdlib.h> @@ -37,8 +36,6 @@ #include "DNA_object_types.h" #include "DNA_mesh_types.h" -#include "RNA_access.h" - #include "MEM_guardedalloc.h" #include "BLI_math.h" @@ -57,18 +54,19 @@ #include "BKE_screen.h" #include "BKE_tessmesh.h" +#include "RNA_access.h" +#include "RNA_define.h" +#include "RNA_enum_types.h" + +#include "WM_api.h" +#include "WM_types.h" + #include "ED_mesh.h" #include "ED_util.h" #include "ED_screen.h" #include "ED_transform.h" #include "ED_types.h" -#include "WM_api.h" -#include "WM_types.h" - -#include "RNA_define.h" -#include "RNA_enum_types.h" - #include "UI_interface.h" #include "UI_resources.h" @@ -209,7 +207,7 @@ static int view3d_layers_exec(bContext *C, wmOperator *op) /* applies shift and alt, lazy coding or ok? :) */ /* the local per-keymap-entry keymap will solve it */ -static int view3d_layers_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int view3d_layers_invoke(bContext *C, wmOperator *op, const wmEvent *event) { if (event->ctrl || event->oskey) return OPERATOR_PASS_THROUGH; diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index d4cfa9076a6..26ed8e1885c 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -108,6 +108,9 @@ float ndof_to_axis_angle(const struct wmNDOFMotionData *ndof, float axis[3]); void view3d_keymap(struct wmKeyConfig *keyconf); void VIEW3D_OT_fly(struct wmOperatorType *ot); +/* view3d_ruler.c */ +void VIEW3D_OT_ruler(struct wmOperatorType *ot); + /* drawanim.c */ void draw_motion_paths_init(View3D *v3d, struct ARegion *ar); void draw_motion_path_instance(Scene *scene, diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index bf1c5404c0e..e567ebda4b7 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -166,6 +166,7 @@ void view3d_operatortypes(void) WM_operatortype_append(VIEW3D_OT_localview); WM_operatortype_append(VIEW3D_OT_game_start); WM_operatortype_append(VIEW3D_OT_fly); + WM_operatortype_append(VIEW3D_OT_ruler); WM_operatortype_append(VIEW3D_OT_layers); WM_operatortype_append(VIEW3D_OT_copybuffer); WM_operatortype_append(VIEW3D_OT_pastebuffer); diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c index bc1656ff7c6..30a100283cc 100644 --- a/source/blender/editors/space_view3d/view3d_project.c +++ b/source/blender/editors/space_view3d/view3d_project.c @@ -73,7 +73,7 @@ void ED_view3d_project_float_v2_m4(const ARegion *ar, const float co[3], float r /** * \note use #ED_view3d_ob_project_mat_get to get projecting mat */ -void ED_view3d_project_float_v3_m4(ARegion *ar, const float vec[3], float r_co[3], float mat[4][4]) +void ED_view3d_project_float_v3_m4(const ARegion *ar, const float vec[3], float r_co[3], float mat[4][4]) { float vec4[4]; @@ -97,7 +97,7 @@ void ED_view3d_project_float_v3_m4(ARegion *ar, const float vec[3], float r_co[3 /* Clipping Projection Functions * ***************************** */ -eV3DProjStatus ED_view3d_project_base(struct ARegion *ar, struct Base *base) +eV3DProjStatus ED_view3d_project_base(const struct ARegion *ar, struct Base *base) { eV3DProjStatus ret = ED_view3d_project_short_global(ar, base->object->obmat[3], &base->sx, V3D_PROJ_TEST_CLIP_DEFAULT); @@ -113,8 +113,8 @@ eV3DProjStatus ED_view3d_project_base(struct ARegion *ar, struct Base *base) * - 'rv3d->perspmat', is_local == FALSE * - 'rv3d->persmatob', is_local == TRUE */ -static eV3DProjStatus ed_view3d_project__internal(ARegion *ar, - float perspmat[4][4], const int is_local, /* normally hidden */ +static eV3DProjStatus ed_view3d_project__internal(const ARegion *ar, + float perspmat[4][4], const bool is_local, /* normally hidden */ const float co[3], float r_co[2], const eV3DProjTest flag) { float vec4[4]; @@ -171,7 +171,7 @@ static eV3DProjStatus ed_view3d_project__internal(ARegion *ar, return V3D_PROJ_RET_OK; } -eV3DProjStatus ED_view3d_project_short_ex(ARegion *ar, float perspmat[4][4], const int is_local, +eV3DProjStatus ED_view3d_project_short_ex(const ARegion *ar, float perspmat[4][4], const bool is_local, const float co[3], short r_co[2], const eV3DProjTest flag) { float tvec[2]; @@ -190,7 +190,7 @@ eV3DProjStatus ED_view3d_project_short_ex(ARegion *ar, float perspmat[4][4], con return ret; } -eV3DProjStatus ED_view3d_project_int_ex(ARegion *ar, float perspmat[4][4], const int is_local, +eV3DProjStatus ED_view3d_project_int_ex(const ARegion *ar, float perspmat[4][4], const bool is_local, const float co[3], int r_co[2], const eV3DProjTest flag) { float tvec[2]; @@ -209,7 +209,7 @@ eV3DProjStatus ED_view3d_project_int_ex(ARegion *ar, float perspmat[4][4], const return ret; } -eV3DProjStatus ED_view3d_project_float_ex(ARegion *ar, float perspmat[4][4], const int is_local, +eV3DProjStatus ED_view3d_project_float_ex(const ARegion *ar, float perspmat[4][4], const bool is_local, const float co[3], float r_co[2], const eV3DProjTest flag) { float tvec[2]; @@ -228,39 +228,39 @@ eV3DProjStatus ED_view3d_project_float_ex(ARegion *ar, float perspmat[4][4], con } /* --- short --- */ -eV3DProjStatus ED_view3d_project_short_global(ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag) +eV3DProjStatus ED_view3d_project_short_global(const ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag) { RegionView3D *rv3d = ar->regiondata; return ED_view3d_project_short_ex(ar, rv3d->persmat, FALSE, co, r_co, flag); } /* object space, use ED_view3d_init_mats_rv3d before calling */ -eV3DProjStatus ED_view3d_project_short_object(ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag) +eV3DProjStatus ED_view3d_project_short_object(const ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag) { RegionView3D *rv3d = ar->regiondata; return ED_view3d_project_short_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag); } /* --- int --- */ -eV3DProjStatus ED_view3d_project_int_global(ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag) +eV3DProjStatus ED_view3d_project_int_global(const ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag) { RegionView3D *rv3d = ar->regiondata; return ED_view3d_project_int_ex(ar, rv3d->persmat, FALSE, co, r_co, flag); } /* object space, use ED_view3d_init_mats_rv3d before calling */ -eV3DProjStatus ED_view3d_project_int_object(ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag) +eV3DProjStatus ED_view3d_project_int_object(const ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag) { RegionView3D *rv3d = ar->regiondata; return ED_view3d_project_int_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag); } /* --- float --- */ -eV3DProjStatus ED_view3d_project_float_global(ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag) +eV3DProjStatus ED_view3d_project_float_global(const ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag) { RegionView3D *rv3d = ar->regiondata; return ED_view3d_project_float_ex(ar, rv3d->persmat, FALSE, co, r_co, flag); } /* object space, use ED_view3d_init_mats_rv3d before calling */ -eV3DProjStatus ED_view3d_project_float_object(ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag) +eV3DProjStatus ED_view3d_project_float_object(const ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag) { RegionView3D *rv3d = ar->regiondata; return ED_view3d_project_float_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag); @@ -271,28 +271,30 @@ eV3DProjStatus ED_view3d_project_float_object(ARegion *ar, const float co[3], fl /* More Generic Window/Ray/Vector projection functions * *************************************************** */ -/* odd function, need to document better */ -int initgrabz(RegionView3D *rv3d, float x, float y, float z) +/** + * Caculate a depth value from \a co, use with #ED_view3d_win_to_delta + */ +float ED_view3d_calc_zfac(const RegionView3D *rv3d, const float co[3], bool *r_flip) { - int flip = FALSE; - if (rv3d == NULL) return flip; - rv3d->zfac = rv3d->persmat[0][3] * x + rv3d->persmat[1][3] * y + rv3d->persmat[2][3] * z + rv3d->persmat[3][3]; - if (rv3d->zfac < 0.0f) - flip = TRUE; + float zfac = mul_project_m4_v3_zfac((float (*)[4])rv3d->persmat, co); + + if (r_flip) { + *r_flip = (zfac < 0.0f); + } + /* if x,y,z is exactly the viewport offset, zfac is 0 and we don't want that - * (accounting for near zero values) - */ - if (rv3d->zfac < 1.e-6f && rv3d->zfac > -1.e-6f) rv3d->zfac = 1.0f; + * (accounting for near zero values) */ + if (zfac < 1.e-6f && zfac > -1.e-6f) { + zfac = 1.0f; + } /* Negative zfac means x, y, z was behind the camera (in perspective). - * This gives flipped directions, so revert back to ok default case. - */ - /* NOTE: I've changed this to flip zfac to be positive again for now so that GPencil draws ok - * Aligorith, 2009Aug31 */ - //if (rv3d->zfac < 0.0f) rv3d->zfac = 1.0f; - if (rv3d->zfac < 0.0f) rv3d->zfac = -rv3d->zfac; - - return flip; + * This gives flipped directions, so revert back to ok default case. */ + if (zfac < 0.0f) { + zfac = -zfac; + } + + return zfac; } /** @@ -306,7 +308,7 @@ int initgrabz(RegionView3D *rv3d, float x, float y, float z) * \param ray_start The world-space starting point of the segment. * \param ray_normal The normalized world-space direction of towards mval. */ -void ED_view3d_win_to_ray(ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_normal[3]) +void ED_view3d_win_to_ray(const ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_normal[3]) { float ray_end[3]; @@ -322,7 +324,7 @@ void ED_view3d_win_to_ray(ARegion *ar, View3D *v3d, const float mval[2], float r * \param coord The world-space location. * \param vec The resulting normalized vector. */ -void ED_view3d_global_to_vector(RegionView3D *rv3d, const float coord[3], float vec[3]) +void ED_view3d_global_to_vector(const RegionView3D *rv3d, const float coord[3], float vec[3]) { if (rv3d->is_persp) { float p1[4], p2[4]; @@ -331,11 +333,11 @@ void ED_view3d_global_to_vector(RegionView3D *rv3d, const float coord[3], float p1[3] = 1.0f; copy_v3_v3(p2, p1); p2[3] = 1.0f; - mul_m4_v4(rv3d->viewmat, p2); + mul_m4_v4((float (*)[4])rv3d->viewmat, p2); mul_v3_fl(p2, 2.0f); - mul_m4_v4(rv3d->viewinv, p2); + mul_m4_v4((float (*)[4])rv3d->viewinv, p2); sub_v3_v3v3(vec, p1, p2); } @@ -352,7 +354,7 @@ void ED_view3d_global_to_vector(RegionView3D *rv3d, const float coord[3], float * \param mval The area relative location (such as event->mval converted to floats). * \param out The resulting world-space location. */ -void ED_view3d_win_to_3d(ARegion *ar, const float depth_pt[3], const float mval[2], float out[3]) +void ED_view3d_win_to_3d(const ARegion *ar, const float depth_pt[3], const float mval[2], float out[3]) { RegionView3D *rv3d = ar->regiondata; @@ -384,19 +386,19 @@ void ED_view3d_win_to_3d(ARegion *ar, const float depth_pt[3], const float mval[ /** * Calculate a 3d difference vector from 2d window offset. - * note that initgrabz() must be called first to determine + * note that ED_view3d_calc_zfac() must be called first to determine * the depth used to calculate the delta. * \param ar The region (used for the window width and height). * \param mval The area relative 2d difference (such as event->mval[0] - other_x). * \param out The resulting world-space delta. */ -void ED_view3d_win_to_delta(ARegion *ar, const float mval[2], float out[3]) +void ED_view3d_win_to_delta(const ARegion *ar, const float mval[2], float out[3], const float zfac) { RegionView3D *rv3d = ar->regiondata; float dx, dy; - dx = 2.0f * mval[0] * rv3d->zfac / ar->winx; - dy = 2.0f * mval[1] * rv3d->zfac / ar->winy; + dx = 2.0f * mval[0] * zfac / ar->winx; + dy = 2.0f * mval[1] * zfac / ar->winy; out[0] = (rv3d->persinv[0][0] * dx + rv3d->persinv[1][0] * dy); out[1] = (rv3d->persinv[0][1] * dx + rv3d->persinv[1][1] * dy); @@ -408,7 +410,7 @@ void ED_view3d_win_to_delta(ARegion *ar, const float mval[2], float out[3]) * This direction vector starts and the view in the direction of the 2d window coordinates. * In orthographic view all window coordinates yield the same vector. * - * \note doesn't rely on initgrabz + * \note doesn't rely on ED_view3d_calc_zfac * for perspective view, get the vector direction to * the mouse cursor as a normalized vector. * @@ -416,7 +418,7 @@ void ED_view3d_win_to_delta(ARegion *ar, const float mval[2], float out[3]) * \param mval The area relative 2d location (such as event->mval converted to floats). * \param out The resulting normalized world-space direction vector. */ -void ED_view3d_win_to_vector(ARegion *ar, const float mval[2], float out[3]) +void ED_view3d_win_to_vector(const ARegion *ar, const float mval[2], float out[3]) { RegionView3D *rv3d = ar->regiondata; @@ -433,7 +435,7 @@ void ED_view3d_win_to_vector(ARegion *ar, const float mval[2], float out[3]) normalize_v3(out); } -void ED_view3d_win_to_segment(ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3]) +void ED_view3d_win_to_segment(const ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3]) { RegionView3D *rv3d = ar->regiondata; @@ -472,7 +474,7 @@ void ED_view3d_win_to_segment(ARegion *ar, View3D *v3d, const float mval[2], flo * \param ray_end The world-space end point of the segment. * \return success, FALSE if the segment is totally clipped. */ -int ED_view3d_win_to_segment_clip(ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3]) +int ED_view3d_win_to_segment_clip(const ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3]) { RegionView3D *rv3d = ar->regiondata; ED_view3d_win_to_segment(ar, v3d, mval, ray_start, ray_end); @@ -503,12 +505,12 @@ int ED_view3d_win_to_segment_clip(ARegion *ar, View3D *v3d, const float mval[2], /* Utility functions for projection * ******************************** */ -void ED_view3d_ob_project_mat_get(RegionView3D *rv3d, Object *ob, float pmat[4][4]) +void ED_view3d_ob_project_mat_get(const RegionView3D *rv3d, Object *ob, float pmat[4][4]) { float vmat[4][4]; - mult_m4_m4m4(vmat, rv3d->viewmat, ob->obmat); - mult_m4_m4m4(pmat, rv3d->winmat, vmat); + mult_m4_m4m4(vmat, (float (*)[4])rv3d->viewmat, ob->obmat); + mult_m4_m4m4(pmat, (float (*)[4])rv3d->winmat, vmat); } /** diff --git a/source/blender/editors/space_view3d/view3d_ruler.c b/source/blender/editors/space_view3d/view3d_ruler.c new file mode 100644 index 00000000000..410d20a1dc0 --- /dev/null +++ b/source/blender/editors/space_view3d/view3d_ruler.c @@ -0,0 +1,939 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_view3d/view3d_ruler.c + * \ingroup spview3d + */ + +/* defines VIEW3D_OT_ruler modal operator */ + +#include "DNA_scene_types.h" +#include "DNA_gpencil_types.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_math.h" +#include "BLI_blenlib.h" + +#include "BKE_context.h" +#include "BKE_unit.h" +#include "BKE_gpencil.h" + +#include "BIF_gl.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_screen.h" +#include "ED_space_api.h" + +#include "BLF_api.h" +#include "BIF_glutil.h" + +#include "UI_resources.h" +#include "UI_interface.h" + +#include "view3d_intern.h" /* own include */ + + +/* -------------------------------------------------------------------- */ +/* Snapping (could be own function) */ +/* NOTE - this is not very nice use of transform snapping */ +#include "ED_transform.h" +#include "../transform/transform.h" + +static bool ED_view3d_snap_co(bContext *C, float r_co[3], const float co_ss[2], + bool use_vert, bool use_edge, bool use_face) +{ + TransInfo t = {0}; + int dist = 12; /* snap dist */ + float r_no_dummy[3]; + bool ret = false; + char backup_snap_mode; + Base *backup_baseact; + + t.scene = CTX_data_scene(C); + t.view = CTX_wm_view3d(C); + t.ar = CTX_wm_region(C); + t.obedit = CTX_data_edit_object(C); + + backup_snap_mode = t.scene->toolsettings->snap_mode; + backup_baseact = t.scene->basact; + t.scene->basact = NULL; + + /* try snap edge, then face if it fails */ + if (use_vert) { + t.scene->toolsettings->snap_mode = SCE_SNAP_MODE_VERTEX; + ret = snapObjectsTransform(&t, co_ss, &dist, r_co, r_no_dummy, SNAP_ALL); + } + if (use_edge && (ret == false)) { + t.scene->toolsettings->snap_mode = SCE_SNAP_MODE_EDGE; + ret = snapObjectsTransform(&t, co_ss, &dist, r_co, r_no_dummy, SNAP_ALL); + } + if (use_face && (ret == false)) { + t.scene->toolsettings->snap_mode = SCE_SNAP_MODE_FACE; + ret = snapObjectsTransform(&t, co_ss, &dist, r_co, r_no_dummy, SNAP_ALL); + } + + t.scene->toolsettings->snap_mode = backup_snap_mode; + t.scene->basact = backup_baseact; + + return ret; +} +/* done snapping */ + + +/* -------------------------------------------------------------------- */ +/* Ruler Item (we can have many) */ +enum { + RULERITEM_USE_ANGLE = (1 << 0), /* use protractor */ + RULERITEM_USE_RAYCAST = (1 << 1) +}; + +enum { + RULERITEM_DIRECTION_IN = 0, + RULERITEM_DIRECTION_OUT +}; + +#define RULER_PICK_DIST 75.0f +#define RULER_PICK_DIST_SQ (RULER_PICK_DIST * RULER_PICK_DIST) + +typedef struct RulerItem { + struct RulerItem *next, *prev; + + /* worldspace coords, middle being optional */ + float co[3][3]; + + /* selected coord */ + char co_index; /* 0 -> 2*/ + + int flag; + int raycast_dir; /* RULER_DIRECTION_* */ +} RulerItem; + +enum { + RULER_STATE_NORMAL = 0, + RULER_STATE_DRAG +}; + + +/* -------------------------------------------------------------------- */ +/* Ruler Info (one per session) */ + +typedef struct RulerInfo { + ListBase items; + int item_active; + int flag; + int snap_flag; + int state; + + /* --- */ + ARegion *ar; + void *draw_handle_pixel; +} RulerInfo; + +/* -------------------------------------------------------------------- */ +/* local functions */ +static RulerItem *ruler_item_add(RulerInfo *ruler_info) +{ + RulerItem *ruler_item = MEM_callocN(sizeof(RulerItem), "RulerItem"); + BLI_addtail(&ruler_info->items, ruler_item); + return ruler_item; +} + +static void ruler_item_remove(RulerInfo *ruler_info, RulerItem *ruler_item) +{ + BLI_remlink(&ruler_info->items, ruler_item); + MEM_freeN(ruler_item); +} + +static RulerItem *ruler_item_active_get(RulerInfo *ruler_info) +{ + return BLI_findlink(&ruler_info->items, ruler_info->item_active); +} + +static void ruler_item_active_set(RulerInfo *ruler_info, RulerItem *ruler_item) +{ + ruler_info->item_active = BLI_findindex(&ruler_info->items, ruler_item); +} + +static void ruler_item_as_string(RulerItem *ruler_item, UnitSettings *unit, + char *numstr, size_t numstr_size, int prec) +{ + const int do_split = unit->flag & USER_UNIT_OPT_SPLIT; + + if (ruler_item->flag & RULERITEM_USE_ANGLE) { + const float ruler_angle = angle_v3v3v3(ruler_item->co[0], + ruler_item->co[1], + ruler_item->co[2]); + + if (unit->system == USER_UNIT_NONE) { + BLI_snprintf(numstr, numstr_size, "%.*f°", prec, RAD2DEGF(ruler_angle)); + } + else { + bUnit_AsString(numstr, numstr_size, + (double)ruler_angle, + prec, unit->system, B_UNIT_ROTATION, do_split, false); + } + } + else { + const float ruler_len = len_v3v3(ruler_item->co[0], + ruler_item->co[2]); + + if (unit->system == USER_UNIT_NONE) { + BLI_snprintf(numstr, numstr_size, "%.*f", prec, ruler_len); + } + else { + bUnit_AsString(numstr, numstr_size, + (double)(ruler_len * unit->scale_length), + prec, unit->system, B_UNIT_LENGTH, do_split, false); + } + } + +} + +static bool view3d_ruler_pick(RulerInfo *ruler_info, const float mval[2], + RulerItem **r_ruler_item, int *r_co_index) +{ + ARegion *ar = ruler_info->ar; + RulerItem *ruler_item; + + float dist_best = RULER_PICK_DIST_SQ; + RulerItem *ruler_item_best = NULL; + int co_index_best = -1; + + for (ruler_item = ruler_info->items.first; ruler_item; ruler_item = ruler_item->next) { + float co_ss[3][2]; + float dist; + int j; + + /* should these be checked? - ok for now not to */ + for (j = 0; j < 3; j++) { + ED_view3d_project_float_global(ar, ruler_item->co[j], co_ss[j], V3D_PROJ_TEST_NOP); + } + + if (ruler_item->flag & RULERITEM_USE_ANGLE) { + dist = min_ff(dist_squared_to_line_segment_v2(mval, co_ss[0], co_ss[1]), + dist_squared_to_line_segment_v2(mval, co_ss[1], co_ss[2])); + if (dist < dist_best) { + dist_best = dist; + ruler_item_best = ruler_item; + + { + float dist_points[3] = {len_squared_v2v2(co_ss[0], mval), + len_squared_v2v2(co_ss[1], mval), + len_squared_v2v2(co_ss[2], mval)}; + if (min_fff(UNPACK3(dist_points)) < RULER_PICK_DIST_SQ) { + co_index_best = min_axis_v3(dist_points); + } + else { + co_index_best = -1; + } + } + } + } + else { + dist = dist_squared_to_line_segment_v2(mval, co_ss[0], co_ss[2]); + if (dist < dist_best) { + dist_best = dist; + ruler_item_best = ruler_item; + + { + float dist_points[2] = {len_squared_v2v2(co_ss[0], mval), + len_squared_v2v2(co_ss[2], mval)}; + if (min_ff(UNPACK2(dist_points)) < RULER_PICK_DIST_SQ) { + co_index_best = (dist_points[0] < dist_points[1]) ? 0 : 2; + } + else { + co_index_best = -1; + } + } + } + } + } + + if (ruler_item_best) { + *r_ruler_item = ruler_item_best; + *r_co_index = co_index_best; + return true; + } + else { + *r_ruler_item = NULL; + *r_co_index = -1; + return false; + } +} + +#define RULER_ID "RulerData3D" +static bool view3d_ruler_to_gpencil(bContext *C, RulerInfo *ruler_info) +{ + Scene *scene = CTX_data_scene(C); + bGPDlayer *gpl; + bGPDframe *gpf; + bGPDstroke *gps; + RulerItem *ruler_item; + const char *ruler_name = RULER_ID; + bool change = false; + + if (scene->gpd == NULL) { + scene->gpd = gpencil_data_addnew("GPencil"); + } + + gpl = BLI_findstring(&scene->gpd->layers, ruler_name, offsetof(bGPDlayer, info)); + if (gpl == NULL) { + gpl = gpencil_layer_addnew(scene->gpd, ruler_name, false); + gpl->thickness = 1; + gpl->flag |= GP_LAYER_HIDE; + } + + gpf = gpencil_layer_getframe(gpl, CFRA, true); + free_gpencil_strokes(gpf); + + for (ruler_item = ruler_info->items.first; ruler_item; ruler_item = ruler_item->next) { + bGPDspoint *pt; + int j; + + /* allocate memory for a new stroke */ + gps = MEM_callocN(sizeof(bGPDstroke), "gp_stroke"); + if (ruler_item->flag & RULERITEM_USE_ANGLE) { + gps->totpoints = 3; + pt = gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points"); + for (j = 0; j < 3; j++) { + copy_v3_v3(&pt->x, ruler_item->co[j]); + pt->pressure = 1.0f; + pt++; + } + } + else { + gps->totpoints = 2; + pt = gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points"); + for (j = 0; j < 3; j += 2) { + copy_v3_v3(&pt->x, ruler_item->co[j]); + pt->pressure = 1.0f; + pt++; + } + } + gps->flag = GP_STROKE_3DSPACE; + BLI_addtail(&gpf->strokes, gps); + change = true; + } + + return change; +} + +static bool view3d_ruler_from_gpencil(bContext *C, RulerInfo *ruler_info) +{ + Scene *scene = CTX_data_scene(C); + bool change = false; + + if (scene->gpd) { + bGPDlayer *gpl; + const char *ruler_name = RULER_ID; + gpl = BLI_findstring(&scene->gpd->layers, ruler_name, offsetof(bGPDlayer, info)); + if (gpl) { + bGPDframe *gpf; + gpf = gpencil_layer_getframe(gpl, CFRA, false); + if (gpf) { + bGPDstroke *gps; + for (gps = gpf->strokes.first; gps; gps = gps->next) { + bGPDspoint *pt = gps->points; + int j; + if (gps->totpoints == 3) { + RulerItem *ruler_item = ruler_item_add(ruler_info); + for (j = 0; j < 3; j++) { + copy_v3_v3(ruler_item->co[j], &pt->x); + pt++; + } + ruler_item->flag |= RULERITEM_USE_ANGLE; + change = true; + } + else if (gps->totpoints == 2) { + RulerItem *ruler_item = ruler_item_add(ruler_info); + for (j = 0; j < 3; j += 2) { + copy_v3_v3(ruler_item->co[j], &pt->x); + pt++; + } + change = true; + } + } + } + } + } + + return change; +} + +/* -------------------------------------------------------------------- */ +/* local callbacks */ + +static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *arg) +{ + Scene *scene = CTX_data_scene(C); + UnitSettings *unit = &scene->unit; + RulerItem *ruler_item; + RulerInfo *ruler_info = arg; + RegionView3D *rv3d = ruler_info->ar->regiondata; +// ARegion *ar = ruler_info->ar; + const float cap_size = 4.0f; + const float bg_margin = 4.0f * U.pixelsize; + const float bg_radius = 4.0f * U.pixelsize; + const float arc_size = 64.0f * U.pixelsize; +#define ARC_STEPS 24 + const int arc_steps = ARC_STEPS; + int i; + //unsigned int color_act = 0x666600; + unsigned int color_act = 0xffffff; + unsigned int color_base = 0x0; + unsigned char color_back[4] = {0xff, 0xff, 0xff, 0x80}; + unsigned char color_text[3]; + unsigned char color_wire[3]; + + /* anti-aliased lines for more consistent appearance */ + glEnable(GL_LINE_SMOOTH); + + BLF_enable(blf_mono_font, BLF_ROTATION); + BLF_size(blf_mono_font, 14 * U.pixelsize, U.dpi); + BLF_rotation(blf_mono_font, 0.0f); + + UI_GetThemeColor3ubv(TH_TEXT, color_text); + UI_GetThemeColor3ubv(TH_WIRE, color_wire); + + for (ruler_item = ruler_info->items.first, i = 0; ruler_item; ruler_item = ruler_item->next, i++) { + const bool is_act = (i == ruler_info->item_active); + float dir_ruler[2]; + float co_ss[3][2]; + int j; + + /* should these be checked? - ok for now not to */ + for (j = 0; j < 3; j++) { + ED_view3d_project_float_global(ar, ruler_item->co[j], co_ss[j], V3D_PROJ_TEST_NOP); + } + + glEnable(GL_BLEND); + + cpack(is_act ? color_act : color_base); + + if (ruler_item->flag & RULERITEM_USE_ANGLE) { + glBegin(GL_LINE_STRIP); + for (j = 0; j < 3; j++) { + glVertex2fv(co_ss[j]); + } + glEnd(); + cpack(0xaaaaaa); + setlinestyle(3); + glBegin(GL_LINE_STRIP); + for (j = 0; j < 3; j++) { + glVertex2fv(co_ss[j]); + } + glEnd(); + setlinestyle(0); + + /* arc */ + { + float dir_tmp[3]; + float co_tmp[3]; + float arc_ss_coords[ARC_STEPS + 1][2]; + + float dir_a[3]; + float dir_b[3]; + float quat[4]; + float axis[3]; + float angle; + const float px_scale = (ED_view3d_pixel_size(rv3d, ruler_item->co[1]) * + min_fff(arc_size, + len_v2v2(co_ss[0], co_ss[1]) / 2.0f, + len_v2v2(co_ss[2], co_ss[1]) / 2.0f)); + + sub_v3_v3v3(dir_a, ruler_item->co[0], ruler_item->co[1]); + sub_v3_v3v3(dir_b, ruler_item->co[2], ruler_item->co[1]); + normalize_v3(dir_a); + normalize_v3(dir_b); + + cross_v3_v3v3(axis, dir_a, dir_b); + angle = angle_normalized_v3v3(dir_a, dir_b); + + axis_angle_to_quat(quat, axis, angle / arc_steps); + + copy_v3_v3(dir_tmp, dir_a); + + glColor3ubv(color_wire); + + for (j = 0; j <= arc_steps; j++) { + madd_v3_v3v3fl(co_tmp, ruler_item->co[1], dir_tmp, px_scale); + ED_view3d_project_float_global(ar, co_tmp, arc_ss_coords[j], V3D_PROJ_TEST_NOP); + mul_qt_v3(quat, dir_tmp); + } + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, arc_ss_coords); + glDrawArrays(GL_LINE_STRIP, 0, arc_steps + 1); + glDisableClientState(GL_VERTEX_ARRAY); + } + + /* text */ + { + char numstr[256]; + float numstr_size[2]; + float pos[2]; + const int prec = 2; /* XXX, todo, make optional */ + + ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec); + + BLF_width_and_height(blf_mono_font, numstr, &numstr_size[0], &numstr_size[1]); + + pos[0] = co_ss[1][0] + (cap_size * 2.0f); + pos[1] = co_ss[1][1] - (numstr_size[1] / 2.0f); + + /* draw text (bg) */ + glColor4ubv(color_back); + uiSetRoundBox(UI_CNR_ALL); + uiRoundBox(pos[0] - bg_margin, pos[1] - bg_margin, + pos[0] + bg_margin + numstr_size[0], pos[1] + bg_margin + numstr_size[1], + bg_radius); + /* draw text */ + glColor3ubv(color_text); + BLF_position(blf_mono_font, pos[0], pos[1], 0.0f); + BLF_rotation(blf_mono_font, 0.0f); + BLF_draw(blf_mono_font, numstr, sizeof(numstr)); + } + + /* capping */ + { + float rot_90_vec_a[2]; + float rot_90_vec_b[2]; + float cap[2]; + + sub_v2_v2v2(dir_ruler, co_ss[0], co_ss[1]); + rot_90_vec_a[0] = -dir_ruler[1]; + rot_90_vec_a[1] = dir_ruler[0]; + normalize_v2(rot_90_vec_a); + + sub_v2_v2v2(dir_ruler, co_ss[1], co_ss[2]); + rot_90_vec_b[0] = -dir_ruler[1]; + rot_90_vec_b[1] = dir_ruler[0]; + normalize_v2(rot_90_vec_b); + + glEnable(GL_BLEND); + + glColor3ubv(color_wire); + + glBegin(GL_LINES); + + madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec_a, cap_size); + glVertex2fv(cap); + madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec_a, -cap_size); + glVertex2fv(cap); + + madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec_b, cap_size); + glVertex2fv(cap); + madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec_b, -cap_size); + glVertex2fv(cap); + + /* angle vertex */ + glVertex2f(co_ss[1][0] - cap_size, co_ss[1][1] - cap_size); + glVertex2f(co_ss[1][0] + cap_size, co_ss[1][1] + cap_size); + glVertex2f(co_ss[1][0] - cap_size, co_ss[1][1] + cap_size); + glVertex2f(co_ss[1][0] + cap_size, co_ss[1][1] - cap_size); + glEnd(); + + glDisable(GL_BLEND); + } + } + else { + glBegin(GL_LINE_STRIP); + for (j = 0; j < 3; j += 2) { + glVertex2fv(co_ss[j]); + } + glEnd(); + cpack(0xaaaaaa); + setlinestyle(3); + glBegin(GL_LINE_STRIP); + for (j = 0; j < 3; j += 2) { + glVertex2fv(co_ss[j]); + } + glEnd(); + setlinestyle(0); + + sub_v2_v2v2(dir_ruler, co_ss[0], co_ss[2]); + + /* text */ + { + char numstr[256]; + float numstr_size[2]; + const int prec = 6; /* XXX, todo, make optional */ + float pos[2]; + + ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec); + + BLF_width_and_height(blf_mono_font, numstr, &numstr_size[0], &numstr_size[1]); + + mid_v2_v2v2(pos, co_ss[0], co_ss[2]); + + /* center text */ + pos[0] -= numstr_size[0] / 2.0f; + pos[1] -= numstr_size[1] / 2.0f; + + /* draw text (bg) */ + glColor4ubv(color_back); + uiSetRoundBox(UI_CNR_ALL); + uiRoundBox(pos[0] - bg_margin, pos[1] - bg_margin, + pos[0] + bg_margin + numstr_size[0], pos[1] + bg_margin + numstr_size[1], + bg_radius); + /* draw text */ + glColor3ubv(color_text); + BLF_position(blf_mono_font, pos[0], pos[1], 0.0f); + BLF_draw(blf_mono_font, numstr, sizeof(numstr)); + } + + /* capping */ + { + float rot_90_vec[2] = {-dir_ruler[1], dir_ruler[0]}; + float cap[2]; + + normalize_v2(rot_90_vec); + + glEnable(GL_BLEND); + glColor3ubv(color_wire); + + glBegin(GL_LINES); + madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec, cap_size); + glVertex2fv(cap); + madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec, -cap_size); + glVertex2fv(cap); + + madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec, cap_size); + glVertex2fv(cap); + madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec, -cap_size); + glVertex2fv(cap); + glEnd(); + + glDisable(GL_BLEND); + } + } + } + + glDisable(GL_LINE_SMOOTH); + + BLF_disable(blf_mono_font, BLF_ROTATION); + +#undef ARC_STEPS +} + +/* free, use for both cancel and finish */ +static void view3d_ruler_end(const struct bContext *UNUSED(C), RulerInfo *ruler_info) +{ + ED_region_draw_cb_exit(ruler_info->ar->type, ruler_info->draw_handle_pixel); +} + +static void view3d_ruler_free(RulerInfo *ruler_info) +{ + BLI_freelistN(&ruler_info->items); + MEM_freeN(ruler_info); +} + +static void view3d_ruler_item_project(RulerInfo *ruler_info, float r_co[3], + const int xy[2]) +{ + view3d_get_view_aligned_coordinate(ruler_info->ar, r_co, xy, true); +} + +/* use for mousemove events */ +static bool view3d_ruler_item_mousemove(bContext *C, RulerInfo *ruler_info, const int mval[2], const bool do_snap) +{ + RulerItem *ruler_item = ruler_item_active_get(ruler_info); + + if (ruler_item) { + float *co = ruler_item->co[ruler_item->co_index]; + view3d_ruler_item_project(ruler_info, co, mval); + if (do_snap) { + const float mval_fl[2] = {UNPACK2(mval)}; + ED_view3d_snap_co(C, co, mval_fl, true, true, true); + } + return true; + } + else { + return false; + } +} + +static void view3d_ruler_header_update(ScrArea *sa) +{ + const char *text = "Ctrl+LMB: Add, " + "Del: Remove, " + "Ctrl+Drag: Snap, " + "Ctrl+C: Copy Value, " + "Enter: Store, " + "Esc: Cancel"; + + ED_area_headerprint(sa, text); +} + +/* -------------------------------------------------------------------- */ +/* Operator callbacks */ + +static int view3d_ruler_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + wmWindow *win = CTX_wm_window(C); + ScrArea *sa = CTX_wm_area(C); + ARegion *ar = CTX_wm_region(C); + RulerInfo *ruler_info; + + ruler_info = MEM_callocN(sizeof(RulerInfo), "RulerInfo"); + + if (view3d_ruler_from_gpencil(C, ruler_info)) { + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL); + } + + op->customdata = ruler_info; + + ruler_info->ar = ar; + ruler_info->draw_handle_pixel = ED_region_draw_cb_activate(ar->type, ruler_info_draw_pixel, + ruler_info, REGION_DRAW_POST_PIXEL); + + view3d_ruler_header_update(sa); + + WM_cursor_modal(win, BC_CROSSCURSOR); + WM_event_add_modal_handler(C, op); + + return OPERATOR_RUNNING_MODAL; +} + +static int view3d_ruler_cancel(bContext *C, wmOperator *op) +{ + RulerInfo *ruler_info = op->customdata; + + view3d_ruler_end(C, ruler_info); + view3d_ruler_free(ruler_info); + op->customdata = NULL; + + return OPERATOR_CANCELLED; +} + +static int view3d_ruler_modal(bContext *C, wmOperator *op, const wmEvent *event) +{ + bool do_draw = false; + int exit_code = OPERATOR_RUNNING_MODAL; + RulerInfo *ruler_info = op->customdata; + ARegion *ar = ruler_info->ar; + RegionView3D *rv3d = ar->regiondata; + + (void)C; + + switch (event->type) { + case LEFTMOUSE: + if (event->val == KM_RELEASE) { + if (ruler_info->state == RULER_STATE_DRAG) { + /* rubber-band angle removal */ + RulerItem *ruler_item = ruler_item_active_get(ruler_info); + if (ruler_item && (ruler_item->co_index == 1) && (ruler_item->flag & RULERITEM_USE_ANGLE)) { + if (!BLI_rcti_isect_pt_v(&ar->winrct, &event->x)) { + ruler_item->flag &= ~RULERITEM_USE_ANGLE; + do_draw = true; + } + } + ruler_info->state = RULER_STATE_NORMAL; + } + } + else { + if (ruler_info->state == RULER_STATE_NORMAL) { + + if (event->ctrl || + /* weak - but user friendly */ + (ruler_info->items.first == NULL)) + { + /* Create new line */ + RulerItem *ruler_item; + /* check if we want to drag an existing point or add a new one */ + ruler_info->state = RULER_STATE_DRAG; + + ruler_item = ruler_item_add(ruler_info); + ruler_item_active_set(ruler_info, ruler_item); + + negate_v3_v3(ruler_item->co[0], rv3d->ofs); + view3d_ruler_item_project(ruler_info, ruler_item->co[0], event->mval); + + /* snap the first point added, not essential but handy */ + { + ruler_item->co_index = 0; + view3d_ruler_item_mousemove(C, ruler_info, event->mval, true); + } + + copy_v3_v3(ruler_item->co[2], ruler_item->co[0]); + ruler_item->co_index = 2; + + do_draw = true; + } + else { + float mval_fl[2] = {UNPACK2(event->mval)}; + RulerItem *ruler_item_pick; + int co_index; + + /* select and drag */ + if (view3d_ruler_pick(ruler_info, mval_fl, &ruler_item_pick, &co_index)) { + if (co_index == -1) { + if ((ruler_item_pick->flag & RULERITEM_USE_ANGLE) == 0) { + /* Add Center Point */ + ruler_item_active_set(ruler_info, ruler_item_pick); + ruler_item_pick->flag |= RULERITEM_USE_ANGLE; + ruler_item_pick->co_index = 1; + ruler_info->state = RULER_STATE_DRAG; + + /* find the factor */ + { + float co_ss[2][2]; + float fac; + + ED_view3d_project_float_global(ar, ruler_item_pick->co[0], co_ss[0], V3D_PROJ_TEST_NOP); + ED_view3d_project_float_global(ar, ruler_item_pick->co[2], co_ss[1], V3D_PROJ_TEST_NOP); + + fac = line_point_factor_v2(mval_fl, co_ss[0], co_ss[1]); + CLAMP(fac, 0.0f, 1.0f); + + interp_v3_v3v3(ruler_item_pick->co[1], + ruler_item_pick->co[0], + ruler_item_pick->co[2], fac); + } + + /* update the new location */ + view3d_ruler_item_mousemove(C, ruler_info, event->mval, event->ctrl != 0); + do_draw = true; + } + } + else { + ruler_item_active_set(ruler_info, ruler_item_pick); + ruler_item_pick->co_index = co_index; + ruler_info->state = RULER_STATE_DRAG; + do_draw = true; + } + } + else { + exit_code = OPERATOR_PASS_THROUGH; + } + + } + } + } + break; + case CKEY: + { + if (event->ctrl) { + RulerItem *ruler_item = ruler_item_active_get(ruler_info); + if (ruler_item) { + const int prec = 8; + char numstr[256]; + Scene *scene = CTX_data_scene(C); + UnitSettings *unit = &scene->unit; + + ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec); + WM_clipboard_text_set((void *) numstr, false); + } + } + } + case RIGHTCTRLKEY: + case LEFTCTRLKEY: + { + WM_event_add_mousemove(C); + break; + } + case MOUSEMOVE: + { + if (ruler_info->state == RULER_STATE_DRAG) { + if (view3d_ruler_item_mousemove(C, ruler_info, event->mval, event->ctrl != 0)) { + do_draw = true; + } + } + break; + } + case ESCKEY: + { + do_draw = true; + exit_code = OPERATOR_CANCELLED; + break; + } + case RETKEY: + { + view3d_ruler_to_gpencil(C, ruler_info); + do_draw = true; + exit_code = OPERATOR_FINISHED; + break; + } + case DELKEY: + { + if (event->val == KM_PRESS) { + if (ruler_info->state == RULER_STATE_NORMAL) { + RulerItem *ruler_item = ruler_item_active_get(ruler_info); + if (ruler_item) { + ruler_item_remove(ruler_info, ruler_item); + ruler_info->item_active = -1; + do_draw = true; + } + } + } + break; + } + default: + exit_code = OPERATOR_PASS_THROUGH; + break; + + } + + if (do_draw) { + ScrArea *sa = CTX_wm_area(C); + + view3d_ruler_header_update(sa); + + /* all 3d views draw rulers */ + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL); + } + + if (ELEM(exit_code, OPERATOR_FINISHED, OPERATOR_CANCELLED)) { + wmWindow *win = CTX_wm_window(C); + ScrArea *sa = CTX_wm_area(C); + + WM_cursor_restore(win); + + view3d_ruler_end(C, ruler_info); + view3d_ruler_free(ruler_info); + op->customdata = NULL; + + ED_area_headerprint(sa, NULL); + } + + return exit_code; +} + +void VIEW3D_OT_ruler(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "3D Ruler & Protractor"; + ot->description = "Interactive ruler"; + ot->idname = "VIEW3D_OT_ruler"; + + /* api callbacks */ + ot->invoke = view3d_ruler_invoke; + ot->cancel = view3d_ruler_cancel; + ot->modal = view3d_ruler_modal; + ot->poll = ED_operator_view3d_active; + + /* flags */ + ot->flag = 0; +} diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 24260898066..b441e48f59d 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -108,23 +108,23 @@ void view3d_set_viewcontext(bContext *C, ViewContext *vc) vc->obedit = CTX_data_edit_object(C); } -int view3d_get_view_aligned_coordinate(ViewContext *vc, float fp[3], const int mval[2], const short do_fallback) +/** + * Re-project \a fp so it stays on the same view-plane but is under \a mval (normally the cursor location). + */ +bool view3d_get_view_aligned_coordinate(ARegion *ar, float fp[3], const int mval[2], const bool do_fallback) { + RegionView3D *rv3d = ar->regiondata; float dvec[3]; int mval_cpy[2]; eV3DProjStatus ret; - mval_cpy[0] = mval[0]; - mval_cpy[1] = mval[1]; - - ret = ED_view3d_project_int_global(vc->ar, fp, mval_cpy, V3D_PROJ_TEST_NOP); - - initgrabz(vc->rv3d, fp[0], fp[1], fp[2]); + ret = ED_view3d_project_int_global(ar, fp, mval_cpy, V3D_PROJ_TEST_NOP); if (ret == V3D_PROJ_RET_OK) { const float mval_f[2] = {(float)(mval_cpy[0] - mval[0]), (float)(mval_cpy[1] - mval[1])}; - ED_view3d_win_to_delta(vc->ar, mval_f, dvec); + const float zfac = ED_view3d_calc_zfac(rv3d, fp, NULL); + ED_view3d_win_to_delta(ar, mval_f, dvec, zfac); sub_v3_v3(fp, dvec); return TRUE; @@ -132,11 +132,11 @@ int view3d_get_view_aligned_coordinate(ViewContext *vc, float fp[3], const int m else { /* fallback to the view center */ if (do_fallback) { - negate_v3_v3(fp, vc->rv3d->ofs); - return view3d_get_view_aligned_coordinate(vc, fp, mval, FALSE); + negate_v3_v3(fp, rv3d->ofs); + return view3d_get_view_aligned_coordinate(ar, fp, mval, false); } else { - return FALSE; + return false; } } } @@ -177,10 +177,9 @@ static void edbm_backbuf_check_and_select_verts(BMEditMesh *em, int select) { BMVert *eve; BMIter iter; - int index = bm_wireoffs; + unsigned int index = bm_wireoffs; - eve = BM_iter_new(&iter, em->bm, BM_VERTS_OF_MESH, NULL); - for (; eve; eve = BM_iter_step(&iter), index++) { + for (eve = BM_iter_new(&iter, em->bm, BM_VERTS_OF_MESH, NULL); eve; eve = BM_iter_step(&iter), index++) { if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { if (EDBM_backbuf_check(index)) { BM_vert_select_set(em->bm, eve, select); @@ -209,7 +208,7 @@ static void edbm_backbuf_check_and_select_faces(BMEditMesh *em, int select) { BMFace *efa; BMIter iter; - int index = 1; + unsigned int index = 1; efa = BM_iter_new(&iter, em->bm, BM_FACES_OF_MESH, NULL); for (; efa; efa = BM_iter_step(&iter), index++) { @@ -226,11 +225,11 @@ static void edbm_backbuf_check_and_select_faces(BMEditMesh *em, int select) static void edbm_backbuf_check_and_select_verts_obmode(Mesh *me, int select) { MVert *mv = me->mvert; - int a; + unsigned int index; if (mv) { - for (a = 1; a <= me->totvert; a++, mv++) { - if (EDBM_backbuf_check(a)) { + for (index = 1; index <= me->totvert; index++, mv++) { + if (EDBM_backbuf_check(index)) { if (!(mv->flag & ME_HIDE)) { mv->flag = select ? (mv->flag | SELECT) : (mv->flag & ~SELECT); } @@ -243,11 +242,11 @@ static void edbm_backbuf_check_and_select_verts_obmode(Mesh *me, int select) static void edbm_backbuf_check_and_select_tfaces(Mesh *me, int select) { MPoly *mpoly = me->mpoly; - int a; + unsigned int index; if (mpoly) { - for (a = 1; a <= me->totpoly; a++, mpoly++) { - if (EDBM_backbuf_check(a)) { + for (index = 1; index <= me->totpoly; index++, mpoly++) { + if (EDBM_backbuf_check(index)) { mpoly->flag = select ? (mpoly->flag | ME_FACE_SEL) : (mpoly->flag & ~ME_FACE_SEL); } } @@ -733,7 +732,7 @@ static void do_lasso_select_meta(ViewContext *vc, const int mcords[][2], short m MetaBall *mb = (MetaBall *)vc->obedit->data; if (extend == 0 && select) - BKE_mball_deselect_all(mb); + BKE_mball_deselect_all(mb); BLI_lasso_boundbox(&rect, mcords, moves); @@ -780,9 +779,6 @@ static void do_lasso_select_paintvert(ViewContext *vc, const int mcords[][2], sh } else { LassoSelectUserData data; - rcti rect; - - BLI_lasso_boundbox(&rect, mcords, moves); view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select); @@ -1054,7 +1050,7 @@ static int object_select_menu_exec(bContext *C, wmOperator *op) CTX_DATA_BEGIN (C, Base *, base, selectable_bases) { /* this is a bit dodjy, there should only be ONE object with this name, but library objects can mess this up */ - if (strcmp(name, base->object->id.name + 2) == 0) { + if (STREQ(name, base->object->id.name + 2)) { ED_base_object_activate(C, base); ED_base_object_select(base, BA_SELECT); changed = 1; @@ -2230,7 +2226,7 @@ static int mouse_weight_paint_vertex_select(bContext *C, const int mval[2], shor /* ****** Mouse Select ****** */ -static int view3d_select_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int view3d_select_invoke(bContext *C, wmOperator *op, const wmEvent *event) { Object *obedit = CTX_data_edit_object(C); Object *obact = CTX_data_active_object(C); diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c index bb5b7aa6911..d3bf8a30792 100644 --- a/source/blender/editors/space_view3d/view3d_toolbar.c +++ b/source/blender/editors/space_view3d/view3d_toolbar.c @@ -156,7 +156,7 @@ static void operator_search_cb(const struct bContext *C, void *UNUSED(arg), cons { GHashIterator *iter = WM_operatortype_iter(); - for (; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) { + for (; BLI_ghashIterator_notDone(iter); BLI_ghashIterator_step(iter)) { wmOperatorType *ot = BLI_ghashIterator_getValue(iter); if (BLI_strcasestr(ot->name, str)) { diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index fba1ce328ba..b2e10fa8457 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -294,7 +294,7 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera } /* only meant for timer usage */ -static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event) +static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) { View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); @@ -667,22 +667,29 @@ void ED_view3d_depth_tag_update(RegionView3D *rv3d) } /* copies logic of get_view3d_viewplane(), keep in sync */ -int ED_view3d_clip_range_get(View3D *v3d, RegionView3D *rv3d, float *clipsta, float *clipend) +bool ED_view3d_clip_range_get(View3D *v3d, RegionView3D *rv3d, float *r_clipsta, float *r_clipend, + const bool use_ortho_factor) { CameraParams params; BKE_camera_params_init(¶ms); BKE_camera_params_from_view3d(¶ms, v3d, rv3d); - if (clipsta) *clipsta = params.clipsta; - if (clipend) *clipend = params.clipend; + if (use_ortho_factor && params.is_ortho) { + const float fac = 2.0f / (params.clipend - params.clipsta); + params.clipsta *= fac; + params.clipend *= fac; + } + + if (r_clipsta) *r_clipsta = params.clipsta; + if (r_clipend) *r_clipend = params.clipend; return params.is_ortho; } /* also exposed in previewrender.c */ -int ED_view3d_viewplane_get(View3D *v3d, RegionView3D *rv3d, int winx, int winy, - rctf *viewplane, float *clipsta, float *clipend) +bool ED_view3d_viewplane_get(View3D *v3d, RegionView3D *rv3d, int winx, int winy, + rctf *r_viewplane, float *r_clipsta, float *r_clipend) { CameraParams params; @@ -690,9 +697,9 @@ int ED_view3d_viewplane_get(View3D *v3d, RegionView3D *rv3d, int winx, int winy, BKE_camera_params_from_view3d(¶ms, v3d, rv3d); BKE_camera_params_compute_viewplane(¶ms, winx, winy, 1.0f, 1.0f); - if (viewplane) *viewplane = params.viewplane; - if (clipsta) *clipsta = params.clipsta; - if (clipend) *clipend = params.clipend; + if (r_viewplane) *r_viewplane = params.viewplane; + if (r_clipsta) *r_clipsta = params.clipsta; + if (r_clipend) *r_clipend = params.clipend; return params.is_ortho; } @@ -791,7 +798,7 @@ static void obmat_to_viewmat(View3D *v3d, RegionView3D *rv3d, Object *ob, short #define QUATSET(a, b, c, d, e) { a[0] = b; a[1] = c; a[2] = d; a[3] = e; } (void)0 -int ED_view3d_lock(RegionView3D *rv3d) +bool ED_view3d_lock(RegionView3D *rv3d) { switch (rv3d->view) { case RV3D_VIEW_BOTTOM: @@ -818,10 +825,10 @@ int ED_view3d_lock(RegionView3D *rv3d) QUATSET(rv3d->viewquat, 0.5, -0.5, -0.5, -0.5); break; default: - return FALSE; + return false; } - return TRUE; + return true; } /* don't set windows active in here, is used by renderwin too */ @@ -863,7 +870,9 @@ void setviewmatrixview3d(Scene *scene, View3D *v3d, RegionView3D *rv3d) copy_v3_v3(vec, give_cursor(scene, v3d)); translate_m4(rv3d->viewmat, -vec[0], -vec[1], -vec[2]); } - else translate_m4(rv3d->viewmat, rv3d->ofs[0], rv3d->ofs[1], rv3d->ofs[2]); + else { + translate_m4(rv3d->viewmat, rv3d->ofs[0], rv3d->ofs[1], rv3d->ofs[2]); + } } } @@ -1558,11 +1567,7 @@ static void UNUSED_FUNCTION(view3d_align_axis_to_vector)(View3D *v3d, RegionView float ED_view3d_pixel_size(RegionView3D *rv3d, const float co[3]) { - return (rv3d->persmat[3][3] + ( - rv3d->persmat[0][3] * co[0] + - rv3d->persmat[1][3] * co[1] + - rv3d->persmat[2][3] * co[2]) - ) * rv3d->pixsize * U.pixelsize; + return mul_project_m4_v3_zfac(rv3d->persmat, co) * rv3d->pixsize * U.pixelsize; } float ED_view3d_radius_to_persp_dist(const float angle, const float radius) |