Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/space_view3d')
-rw-r--r--source/blender/editors/space_view3d/CMakeLists.txt108
-rw-r--r--source/blender/editors/space_view3d/drawobject.c766
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c2395
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c2573
-rw-r--r--source/blender/editors/space_view3d/view3d_camera_control.c428
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c2961
-rw-r--r--source/blender/editors/space_view3d/view3d_draw_legacy.c1573
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c7785
-rw-r--r--source/blender/editors/space_view3d/view3d_fly.c1782
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_armature.c268
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_camera.c778
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_empty.c247
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_forcefield.c121
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_light.c377
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_navigate.c488
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c747
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_preselect.c64
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c678
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_ruler.c1681
-rw-r--r--source/blender/editors/space_view3d/view3d_header.c241
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h154
-rw-r--r--source/blender/editors/space_view3d/view3d_iterators.c696
-rw-r--r--source/blender/editors/space_view3d/view3d_ops.c264
-rw-r--r--source/blender/editors/space_view3d/view3d_project.c923
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c6208
-rw-r--r--source/blender/editors/space_view3d/view3d_snap.c1363
-rw-r--r--source/blender/editors/space_view3d/view3d_toolbar.c28
-rw-r--r--source/blender/editors/space_view3d/view3d_utils.c2004
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c2316
-rw-r--r--source/blender/editors/space_view3d/view3d_walk.c2067
30 files changed, 21544 insertions, 20540 deletions
diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt
index 837671d6f94..279c6913064 100644
--- a/source/blender/editors/space_view3d/CMakeLists.txt
+++ b/source/blender/editors/space_view3d/CMakeLists.txt
@@ -16,84 +16,84 @@
# ***** END GPL LICENSE BLOCK *****
set(INC
- ../include
- ../../blenfont
- ../../blenkernel
- ../../blenlib
- ../../blentranslation
- ../../bmesh
- ../../draw
- ../../gpu
- ../../imbuf
- ../../makesdna
- ../../makesrna
- ../../render/extern/include
- ../../windowmanager
- ../../depsgraph
- ../../../../intern/guardedalloc
- ../../../../intern/glew-mx
- ../../../../intern/smoke/extern
+ ../include
+ ../../blenfont
+ ../../blenkernel
+ ../../blenlib
+ ../../blentranslation
+ ../../bmesh
+ ../../draw
+ ../../gpu
+ ../../imbuf
+ ../../makesdna
+ ../../makesrna
+ ../../render/extern/include
+ ../../windowmanager
+ ../../depsgraph
+ ../../../../intern/guardedalloc
+ ../../../../intern/glew-mx
+ ../../../../intern/smoke/extern
)
set(INC_SYS
- ${GLEW_INCLUDE_PATH}
+ ${GLEW_INCLUDE_PATH}
)
set(SRC
- drawobject.c
- space_view3d.c
- view3d_buttons.c
- view3d_camera_control.c
- view3d_draw.c
- view3d_draw_legacy.c
- view3d_edit.c
- view3d_fly.c
- view3d_gizmo_armature.c
- view3d_gizmo_camera.c
- view3d_gizmo_empty.c
- view3d_gizmo_forcefield.c
- view3d_gizmo_light.c
- view3d_gizmo_navigate.c
- view3d_gizmo_navigate_type.c
- view3d_gizmo_preselect.c
- view3d_gizmo_preselect_type.c
- view3d_gizmo_ruler.c
- view3d_header.c
- view3d_iterators.c
- view3d_ops.c
- view3d_project.c
- view3d_select.c
- view3d_snap.c
- view3d_toolbar.c
- view3d_utils.c
- view3d_view.c
- view3d_walk.c
+ drawobject.c
+ space_view3d.c
+ view3d_buttons.c
+ view3d_camera_control.c
+ view3d_draw.c
+ view3d_draw_legacy.c
+ view3d_edit.c
+ view3d_fly.c
+ view3d_gizmo_armature.c
+ view3d_gizmo_camera.c
+ view3d_gizmo_empty.c
+ view3d_gizmo_forcefield.c
+ view3d_gizmo_light.c
+ view3d_gizmo_navigate.c
+ view3d_gizmo_navigate_type.c
+ view3d_gizmo_preselect.c
+ view3d_gizmo_preselect_type.c
+ view3d_gizmo_ruler.c
+ view3d_header.c
+ view3d_iterators.c
+ view3d_ops.c
+ view3d_project.c
+ view3d_select.c
+ view3d_snap.c
+ view3d_toolbar.c
+ view3d_utils.c
+ view3d_view.c
+ view3d_walk.c
- view3d_intern.h
+ view3d_intern.h
)
set(LIB
- bf_editor_lattice
- bf_editor_mesh
+ bf_editor_lattice
+ bf_editor_mesh
)
if(WITH_PYTHON)
- blender_include_dirs(../../python)
- add_definitions(-DWITH_PYTHON)
+ blender_include_dirs(../../python)
+ add_definitions(-DWITH_PYTHON)
endif()
add_definitions(${GL_DEFINITIONS})
if(WITH_INTERNATIONAL)
- add_definitions(-DWITH_INTERNATIONAL)
+ add_definitions(-DWITH_INTERNATIONAL)
endif()
if(WITH_FREESTYLE)
- add_definitions(-DWITH_FREESTYLE)
+ add_definitions(-DWITH_FREESTYLE)
endif()
if(WITH_MOD_SMOKE)
- add_definitions(-DWITH_SMOKE)
+ add_definitions(-DWITH_SMOKE)
endif()
blender_add_lib(bf_editor_space_view3d "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index d4745247ae3..c304642c4c3 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -49,34 +49,34 @@
#include "DRW_engine.h"
-#include "view3d_intern.h" /* bad level include */
+#include "view3d_intern.h" /* bad level include */
-#include "../../draw/intern/draw_cache_impl.h" /* bad level include (temporary) */
+#include "../../draw/intern/draw_cache_impl.h" /* bad level include (temporary) */
int view3d_effective_drawtype(const struct View3D *v3d)
{
- if (v3d->shading.type == OB_RENDER) {
- return v3d->shading.prev_type;
- }
- return v3d->shading.type;
+ if (v3d->shading.type == OB_RENDER) {
+ return v3d->shading.prev_type;
+ }
+ return v3d->shading.type;
}
static bool check_ob_drawface_dot(Scene *sce, View3D *vd, char dt)
{
- if ((sce->toolsettings->selectmode & SCE_SELECT_FACE) == 0) {
- return false;
- }
+ if ((sce->toolsettings->selectmode & SCE_SELECT_FACE) == 0) {
+ return false;
+ }
- if (G.f & G_FLAG_BACKBUFSEL) {
- return false;
- }
+ if (G.f & G_FLAG_BACKBUFSEL) {
+ return false;
+ }
- /* if its drawing textures with zbuf sel, then don't draw dots */
- if (dt == OB_TEXTURE && vd->shading.type == OB_TEXTURE) {
- return false;
- }
+ /* if its drawing textures with zbuf sel, then don't draw dots */
+ if (dt == OB_TEXTURE && vd->shading.type == OB_TEXTURE) {
+ return false;
+ }
- return true;
+ return true;
}
/* OpenGL Circle Drawing - Tables for Optimized Drawing Speed */
@@ -84,102 +84,51 @@ static bool check_ob_drawface_dot(Scene *sce, View3D *vd, char dt)
#define CIRCLE_RESOL 32
static const float sinval[CIRCLE_RESOL] = {
- 0.00000000,
- 0.20129852,
- 0.39435585,
- 0.57126821,
- 0.72479278,
- 0.84864425,
- 0.93775213,
- 0.98846832,
- 0.99871650,
- 0.96807711,
- 0.89780453,
- 0.79077573,
- 0.65137248,
- 0.48530196,
- 0.29936312,
- 0.10116832,
- -0.10116832,
- -0.29936312,
- -0.48530196,
- -0.65137248,
- -0.79077573,
- -0.89780453,
- -0.96807711,
- -0.99871650,
- -0.98846832,
- -0.93775213,
- -0.84864425,
- -0.72479278,
- -0.57126821,
- -0.39435585,
- -0.20129852,
- 0.00000000,
+ 0.00000000, 0.20129852, 0.39435585, 0.57126821, 0.72479278, 0.84864425, 0.93775213,
+ 0.98846832, 0.99871650, 0.96807711, 0.89780453, 0.79077573, 0.65137248, 0.48530196,
+ 0.29936312, 0.10116832, -0.10116832, -0.29936312, -0.48530196, -0.65137248, -0.79077573,
+ -0.89780453, -0.96807711, -0.99871650, -0.98846832, -0.93775213, -0.84864425, -0.72479278,
+ -0.57126821, -0.39435585, -0.20129852, 0.00000000,
};
/* 32 values of cos function (still same result!) */
static const float cosval[CIRCLE_RESOL] = {
- 1.00000000,
- 0.97952994,
- 0.91895781,
- 0.82076344,
- 0.68896691,
- 0.52896401,
- 0.34730525,
- 0.15142777,
- -0.05064916,
- -0.25065253,
- -0.44039415,
- -0.61210598,
- -0.75875812,
- -0.87434661,
- -0.95413925,
- -0.99486932,
- -0.99486932,
- -0.95413925,
- -0.87434661,
- -0.75875812,
- -0.61210598,
- -0.44039415,
- -0.25065253,
- -0.05064916,
- 0.15142777,
- 0.34730525,
- 0.52896401,
- 0.68896691,
- 0.82076344,
- 0.91895781,
- 0.97952994,
- 1.00000000,
+ 1.00000000, 0.97952994, 0.91895781, 0.82076344, 0.68896691, 0.52896401, 0.34730525,
+ 0.15142777, -0.05064916, -0.25065253, -0.44039415, -0.61210598, -0.75875812, -0.87434661,
+ -0.95413925, -0.99486932, -0.99486932, -0.95413925, -0.87434661, -0.75875812, -0.61210598,
+ -0.44039415, -0.25065253, -0.05064916, 0.15142777, 0.34730525, 0.52896401, 0.68896691,
+ 0.82076344, 0.91895781, 0.97952994, 1.00000000,
};
-static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float cent[3], float rad, const float tmat[4][4])
+static void circball_array_fill(float verts[CIRCLE_RESOL][3],
+ const float cent[3],
+ float rad,
+ const float tmat[4][4])
{
- float vx[3], vy[3];
- float *viter = (float *)verts;
+ float vx[3], vy[3];
+ float *viter = (float *)verts;
- mul_v3_v3fl(vx, tmat[0], rad);
- mul_v3_v3fl(vy, tmat[1], rad);
+ mul_v3_v3fl(vx, tmat[0], rad);
+ mul_v3_v3fl(vy, tmat[1], rad);
- for (uint a = 0; a < CIRCLE_RESOL; a++, viter += 3) {
- viter[0] = cent[0] + sinval[a] * vx[0] + cosval[a] * vy[0];
- viter[1] = cent[1] + sinval[a] * vx[1] + cosval[a] * vy[1];
- viter[2] = cent[2] + sinval[a] * vx[2] + cosval[a] * vy[2];
- }
+ for (uint a = 0; a < CIRCLE_RESOL; a++, viter += 3) {
+ viter[0] = cent[0] + sinval[a] * vx[0] + cosval[a] * vy[0];
+ viter[1] = cent[1] + sinval[a] * vx[1] + cosval[a] * vy[1];
+ viter[2] = cent[2] + sinval[a] * vx[2] + cosval[a] * vy[2];
+ }
}
void imm_drawcircball(const float cent[3], float rad, const float tmat[4][4], unsigned pos)
{
- float verts[CIRCLE_RESOL][3];
+ float verts[CIRCLE_RESOL][3];
- circball_array_fill(verts, cent, rad, tmat);
+ circball_array_fill(verts, cent, rad, tmat);
- immBegin(GPU_PRIM_LINE_LOOP, CIRCLE_RESOL);
- for (int i = 0; i < CIRCLE_RESOL; ++i) {
- immVertex3fv(pos, verts[i]);
- }
- immEnd();
+ immBegin(GPU_PRIM_LINE_LOOP, CIRCLE_RESOL);
+ for (int i = 0; i < CIRCLE_RESOL; ++i) {
+ immVertex3fv(pos, verts[i]);
+ }
+ immEnd();
}
#ifdef VIEW3D_CAMERA_BORDER_HACK
@@ -192,344 +141,359 @@ bool view3d_camera_border_hack_test = false;
/** See #DRW_shgroup_world_clip_planes_from_rv3d, same function for draw manager. */
static void bbs_world_clip_planes_from_rv3d(GPUBatch *batch, const float world_clip_planes[6][4])
{
- GPU_batch_uniform_4fv_array(batch, "WorldClipPlanes", 6, world_clip_planes[0]);
+ GPU_batch_uniform_4fv_array(batch, "WorldClipPlanes", 6, world_clip_planes[0]);
}
static void bbs_mesh_verts(GPUBatch *batch, int offset, const float world_clip_planes[6][4])
{
- GPU_point_size(UI_GetThemeValuef(TH_VERTEX_SIZE));
-
- const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED : GPU_SHADER_CFG_DEFAULT;
- GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, sh_cfg);
- GPU_batch_uniform_1ui(batch, "offset", offset);
- if (world_clip_planes != NULL) {
- bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
- }
- GPU_batch_draw(batch);
+ GPU_point_size(UI_GetThemeValuef(TH_VERTEX_SIZE));
+
+ const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
+ GPU_SHADER_CFG_DEFAULT;
+ GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, sh_cfg);
+ GPU_batch_uniform_1ui(batch, "offset", offset);
+ if (world_clip_planes != NULL) {
+ bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
+ }
+ GPU_batch_draw(batch);
}
static void bbs_mesh_wire(GPUBatch *batch, int offset, const float world_clip_planes[6][4])
{
- GPU_line_width(1.0f);
- glProvokingVertex(GL_FIRST_VERTEX_CONVENTION);
-
- const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED : GPU_SHADER_CFG_DEFAULT;
- GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, sh_cfg);
- GPU_batch_uniform_1ui(batch, "offset", offset);
- if (world_clip_planes != NULL) {
- bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
- }
- GPU_batch_draw(batch);
-
- glProvokingVertex(GL_LAST_VERTEX_CONVENTION);
+ GPU_line_width(1.0f);
+ glProvokingVertex(GL_FIRST_VERTEX_CONVENTION);
+
+ const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
+ GPU_SHADER_CFG_DEFAULT;
+ GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, sh_cfg);
+ GPU_batch_uniform_1ui(batch, "offset", offset);
+ if (world_clip_planes != NULL) {
+ bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
+ }
+ GPU_batch_draw(batch);
+
+ glProvokingVertex(GL_LAST_VERTEX_CONVENTION);
}
/* two options, facecolors or black */
-static void bbs_mesh_face(GPUBatch *batch, const bool use_select, const float world_clip_planes[6][4])
+static void bbs_mesh_face(GPUBatch *batch,
+ const bool use_select,
+ const float world_clip_planes[6][4])
{
- if (use_select) {
- const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED : GPU_SHADER_CFG_DEFAULT;
- GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, sh_cfg);
- GPU_batch_uniform_1ui(batch, "offset", 1);
- if (world_clip_planes != NULL) {
- bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
- }
- GPU_batch_draw(batch);
- }
- else {
- const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED : GPU_SHADER_CFG_DEFAULT;
- GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_UNIFORM_SELECT_ID, sh_cfg);
- GPU_batch_uniform_1ui(batch, "id", 0);
- if (world_clip_planes != NULL) {
- bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
- }
- GPU_batch_draw(batch);
- }
+ if (use_select) {
+ const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
+ GPU_SHADER_CFG_DEFAULT;
+ GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, sh_cfg);
+ GPU_batch_uniform_1ui(batch, "offset", 1);
+ if (world_clip_planes != NULL) {
+ bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
+ }
+ GPU_batch_draw(batch);
+ }
+ else {
+ const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
+ GPU_SHADER_CFG_DEFAULT;
+ GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_UNIFORM_SELECT_ID, sh_cfg);
+ GPU_batch_uniform_1ui(batch, "id", 0);
+ if (world_clip_planes != NULL) {
+ bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
+ }
+ GPU_batch_draw(batch);
+ }
}
static void bbs_mesh_face_dot(GPUBatch *batch, const float world_clip_planes[6][4])
{
- const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED : GPU_SHADER_CFG_DEFAULT;
- GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, sh_cfg);
- GPU_batch_uniform_1ui(batch, "offset", 1);
- if (world_clip_planes != NULL) {
- bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
- }
- GPU_batch_draw(batch);
+ const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
+ GPU_SHADER_CFG_DEFAULT;
+ GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, sh_cfg);
+ GPU_batch_uniform_1ui(batch, "offset", 1);
+ if (world_clip_planes != NULL) {
+ bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
+ }
+ GPU_batch_draw(batch);
}
-static void bbs_mesh_solid_verts(
- Depsgraph *UNUSED(depsgraph), Scene *UNUSED(scene), Object *ob, const float world_clip_planes[6][4])
+static void bbs_mesh_solid_verts(Depsgraph *UNUSED(depsgraph),
+ Scene *UNUSED(scene),
+ Object *ob,
+ const float world_clip_planes[6][4])
{
- Mesh *me = ob->data;
+ Mesh *me = ob->data;
- GPUBatch *geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me);
- GPUBatch *geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me);
- DRW_mesh_batch_cache_create_requested(ob, me, NULL, false, true);
+ GPUBatch *geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me);
+ GPUBatch *geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me);
+ DRW_mesh_batch_cache_create_requested(ob, me, NULL, false, true);
- /* Only draw faces to mask out verts, we don't want their selection ID's. */
- bbs_mesh_face(geom_faces, false, world_clip_planes);
- bbs_mesh_verts(geom_verts, 1, world_clip_planes);
+ /* Only draw faces to mask out verts, we don't want their selection ID's. */
+ bbs_mesh_face(geom_faces, false, world_clip_planes);
+ bbs_mesh_verts(geom_verts, 1, world_clip_planes);
- bm_vertoffs = me->totvert + 1;
+ bm_vertoffs = me->totvert + 1;
}
-static void bbs_mesh_solid_faces(Scene *UNUSED(scene), Object *ob, const float world_clip_planes[6][4])
+static void bbs_mesh_solid_faces(Scene *UNUSED(scene),
+ Object *ob,
+ const float world_clip_planes[6][4])
{
- Mesh *me = ob->data;
- Mesh *me_orig = DEG_get_original_object(ob)->data;
+ Mesh *me = ob->data;
+ Mesh *me_orig = DEG_get_original_object(ob)->data;
- const bool use_hide = (me_orig->editflag & ME_EDIT_PAINT_FACE_SEL);
- GPUBatch *geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me);
- DRW_mesh_batch_cache_create_requested(ob, me, NULL, false, use_hide);
+ const bool use_hide = (me_orig->editflag & ME_EDIT_PAINT_FACE_SEL);
+ GPUBatch *geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me);
+ DRW_mesh_batch_cache_create_requested(ob, me, NULL, false, use_hide);
- bbs_mesh_face(geom_faces, true, world_clip_planes);
+ bbs_mesh_face(geom_faces, true, world_clip_planes);
}
-void draw_object_select_id(
- Depsgraph *depsgraph, Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob,
- short select_mode)
+void draw_object_select_id(Depsgraph *depsgraph,
+ Scene *scene,
+ View3D *v3d,
+ RegionView3D *rv3d,
+ Object *ob,
+ short select_mode)
{
- ToolSettings *ts = scene->toolsettings;
- if (select_mode == -1) {
- select_mode = ts->selectmode;
- }
-
- GPU_matrix_mul(ob->obmat);
- GPU_depth_test(true);
-
- const float (*world_clip_planes)[4] = NULL;
- if (rv3d->rflag & RV3D_CLIPPING) {
- ED_view3d_clipping_local(rv3d, ob->obmat);
- world_clip_planes = rv3d->clip_local;
- }
-
- switch (ob->type) {
- case OB_MESH:
- if (ob->mode & OB_MODE_EDIT) {
- Mesh *me = ob->data;
- BMEditMesh *em = me->edit_mesh;
- const bool draw_facedot = check_ob_drawface_dot(scene, v3d, ob->dt);
- const bool use_faceselect = (select_mode & SCE_SELECT_FACE) != 0;
-
- BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE | BM_FACE);
-
- GPUBatch *geom_faces, *geom_edges, *geom_verts, *geom_facedots;
- geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me);
- if (select_mode & SCE_SELECT_EDGE) {
- geom_edges = DRW_mesh_batch_cache_get_edges_with_select_id(me);
- }
- if (select_mode & SCE_SELECT_VERTEX) {
- geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me);
- }
- if (draw_facedot) {
- geom_facedots = DRW_mesh_batch_cache_get_facedots_with_select_id(me);
- }
- DRW_mesh_batch_cache_create_requested(ob, me, NULL, false, true);
-
- bbs_mesh_face(geom_faces, use_faceselect, world_clip_planes);
-
- if (use_faceselect && draw_facedot) {
- bbs_mesh_face_dot(geom_facedots, world_clip_planes);
- }
-
- if (select_mode & SCE_SELECT_FACE) {
- bm_solidoffs = 1 + em->bm->totface;
- }
- else {
- bm_solidoffs = 1;
- }
-
- ED_view3d_polygon_offset(rv3d, 1.0);
-
- /* we draw edges if edge select mode */
- if (select_mode & SCE_SELECT_EDGE) {
- bbs_mesh_wire(geom_edges, bm_solidoffs, world_clip_planes);
- bm_wireoffs = bm_solidoffs + em->bm->totedge;
- }
- else {
- /* `bm_vertoffs` is calculated from `bm_wireoffs`. (otherwise see T53512) */
- bm_wireoffs = bm_solidoffs;
- }
-
- ED_view3d_polygon_offset(rv3d, 1.1);
-
- /* we draw verts if vert select mode. */
- if (select_mode & SCE_SELECT_VERTEX) {
- bbs_mesh_verts(geom_verts, bm_wireoffs, world_clip_planes);
- bm_vertoffs = bm_wireoffs + em->bm->totvert;
- }
- else {
- bm_vertoffs = bm_wireoffs;
- }
-
- ED_view3d_polygon_offset(rv3d, 0.0);
- }
- else {
- Mesh *me = DEG_get_original_object(ob)->data;
- if ((me->editflag & ME_EDIT_PAINT_VERT_SEL) &&
- /* currently vertex select supports weight paint and vertex paint*/
- ((ob->mode & OB_MODE_WEIGHT_PAINT) || (ob->mode & OB_MODE_VERTEX_PAINT)))
- {
- bbs_mesh_solid_verts(depsgraph, scene, ob, world_clip_planes);
- }
- else {
- bbs_mesh_solid_faces(scene, ob, world_clip_planes);
- }
- }
- break;
- case OB_CURVE:
- case OB_SURF:
- break;
- }
-
- GPU_matrix_set(rv3d->viewmat);
+ ToolSettings *ts = scene->toolsettings;
+ if (select_mode == -1) {
+ select_mode = ts->selectmode;
+ }
+
+ GPU_matrix_mul(ob->obmat);
+ GPU_depth_test(true);
+
+ const float(*world_clip_planes)[4] = NULL;
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ ED_view3d_clipping_local(rv3d, ob->obmat);
+ world_clip_planes = rv3d->clip_local;
+ }
+
+ switch (ob->type) {
+ case OB_MESH:
+ if (ob->mode & OB_MODE_EDIT) {
+ Mesh *me = ob->data;
+ BMEditMesh *em = me->edit_mesh;
+ const bool draw_facedot = check_ob_drawface_dot(scene, v3d, ob->dt);
+ const bool use_faceselect = (select_mode & SCE_SELECT_FACE) != 0;
+
+ BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE | BM_FACE);
+
+ GPUBatch *geom_faces, *geom_edges, *geom_verts, *geom_facedots;
+ geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me);
+ if (select_mode & SCE_SELECT_EDGE) {
+ geom_edges = DRW_mesh_batch_cache_get_edges_with_select_id(me);
+ }
+ if (select_mode & SCE_SELECT_VERTEX) {
+ geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me);
+ }
+ if (draw_facedot) {
+ geom_facedots = DRW_mesh_batch_cache_get_facedots_with_select_id(me);
+ }
+ DRW_mesh_batch_cache_create_requested(ob, me, NULL, false, true);
+
+ bbs_mesh_face(geom_faces, use_faceselect, world_clip_planes);
+
+ if (use_faceselect && draw_facedot) {
+ bbs_mesh_face_dot(geom_facedots, world_clip_planes);
+ }
+
+ if (select_mode & SCE_SELECT_FACE) {
+ bm_solidoffs = 1 + em->bm->totface;
+ }
+ else {
+ bm_solidoffs = 1;
+ }
+
+ ED_view3d_polygon_offset(rv3d, 1.0);
+
+ /* we draw edges if edge select mode */
+ if (select_mode & SCE_SELECT_EDGE) {
+ bbs_mesh_wire(geom_edges, bm_solidoffs, world_clip_planes);
+ bm_wireoffs = bm_solidoffs + em->bm->totedge;
+ }
+ else {
+ /* `bm_vertoffs` is calculated from `bm_wireoffs`. (otherwise see T53512) */
+ bm_wireoffs = bm_solidoffs;
+ }
+
+ ED_view3d_polygon_offset(rv3d, 1.1);
+
+ /* we draw verts if vert select mode. */
+ if (select_mode & SCE_SELECT_VERTEX) {
+ bbs_mesh_verts(geom_verts, bm_wireoffs, world_clip_planes);
+ bm_vertoffs = bm_wireoffs + em->bm->totvert;
+ }
+ else {
+ bm_vertoffs = bm_wireoffs;
+ }
+
+ ED_view3d_polygon_offset(rv3d, 0.0);
+ }
+ else {
+ Mesh *me = DEG_get_original_object(ob)->data;
+ if ((me->editflag & ME_EDIT_PAINT_VERT_SEL) &&
+ /* currently vertex select supports weight paint and vertex paint*/
+ ((ob->mode & OB_MODE_WEIGHT_PAINT) || (ob->mode & OB_MODE_VERTEX_PAINT))) {
+ bbs_mesh_solid_verts(depsgraph, scene, ob, world_clip_planes);
+ }
+ else {
+ bbs_mesh_solid_faces(scene, ob, world_clip_planes);
+ }
+ }
+ break;
+ case OB_CURVE:
+ case OB_SURF:
+ break;
+ }
+
+ GPU_matrix_set(rv3d->viewmat);
}
void draw_object_depth(RegionView3D *rv3d, Object *ob)
{
- GPU_matrix_mul(ob->obmat);
- GPU_depth_test(true);
-
- const float (*world_clip_planes)[4] = NULL;
- if (rv3d->rflag & RV3D_CLIPPING) {
- ED_view3d_clipping_local(rv3d, ob->obmat);
- world_clip_planes = rv3d->clip_local;
- }
-
- switch (ob->type) {
- case OB_MESH:
- {
- GPUBatch *batch;
-
- Mesh *me = ob->data;
-
- if (ob->mode & OB_MODE_EDIT) {
- batch = DRW_mesh_batch_cache_get_edit_triangles(me);
- }
- else {
- batch = DRW_mesh_batch_cache_get_surface(me);
- }
-
- DRW_mesh_batch_cache_create_requested(ob, me, NULL, false, true);
-
- DRW_opengl_context_enable();
- const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED : GPU_SHADER_CFG_DEFAULT;
- GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_DEPTH_ONLY, sh_cfg);
- if (world_clip_planes != NULL) {
- bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
- }
-
- GPU_batch_draw(batch);
- DRW_opengl_context_disable();
- }
- break;
- case OB_CURVE:
- case OB_SURF:
- break;
- }
-
- GPU_matrix_set(rv3d->viewmat);
+ GPU_matrix_mul(ob->obmat);
+ GPU_depth_test(true);
+
+ const float(*world_clip_planes)[4] = NULL;
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ ED_view3d_clipping_local(rv3d, ob->obmat);
+ world_clip_planes = rv3d->clip_local;
+ }
+
+ switch (ob->type) {
+ case OB_MESH: {
+ GPUBatch *batch;
+
+ Mesh *me = ob->data;
+
+ if (ob->mode & OB_MODE_EDIT) {
+ batch = DRW_mesh_batch_cache_get_edit_triangles(me);
+ }
+ else {
+ batch = DRW_mesh_batch_cache_get_surface(me);
+ }
+
+ DRW_mesh_batch_cache_create_requested(ob, me, NULL, false, true);
+
+ DRW_opengl_context_enable();
+ const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
+ GPU_SHADER_CFG_DEFAULT;
+ GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_DEPTH_ONLY, sh_cfg);
+ if (world_clip_planes != NULL) {
+ bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
+ }
+
+ GPU_batch_draw(batch);
+ DRW_opengl_context_disable();
+ } break;
+ case OB_CURVE:
+ case OB_SURF:
+ break;
+ }
+
+ GPU_matrix_set(rv3d->viewmat);
}
-
-void ED_draw_object_facemap(
- Depsgraph *depsgraph, Object *ob, const float col[4], const int facemap)
+void ED_draw_object_facemap(Depsgraph *depsgraph,
+ Object *ob,
+ const float col[4],
+ const int facemap)
{
- /* happens on undo */
- if (ob->type != OB_MESH || !ob->data) {
- return;
- }
-
- Mesh *me = ob->data;
- {
- Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
- if (ob_eval->runtime.mesh_eval) {
- me = ob_eval->runtime.mesh_eval;
- }
- }
-
- glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
-
- /* Just to create the data to pass to immediate mode, grr! */
- const int *facemap_data = CustomData_get_layer(&me->pdata, CD_FACEMAP);
- if (facemap_data) {
- GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- GPU_blend(true);
-
- const MVert *mvert = me->mvert;
- const MPoly *mpoly = me->mpoly;
- const MLoop *mloop = me->mloop;
-
- int mpoly_len = me->totpoly;
- int mloop_len = me->totloop;
-
- facemap_data = CustomData_get_layer(&me->pdata, CD_FACEMAP);
-
- /* use gawain immediate mode fore now */
- const int looptris_len = poly_to_tri_count(mpoly_len, mloop_len);
- const int vbo_len_capacity = looptris_len * 3;
- int vbo_len_used = 0;
-
- GPUVertFormat format_pos = { 0 };
- const uint pos_id = GPU_vertformat_attr_add(&format_pos, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
-
- GPUVertBuf *vbo_pos = GPU_vertbuf_create_with_format(&format_pos);
- GPU_vertbuf_data_alloc(vbo_pos, vbo_len_capacity);
-
- GPUVertBufRaw pos_step;
- GPU_vertbuf_attr_get_raw_data(vbo_pos, pos_id, &pos_step);
-
- const MPoly *mp;
- int i;
- if (me->runtime.looptris.array) {
- MLoopTri *mlt = me->runtime.looptris.array;
- for (mp = mpoly, i = 0; i < mpoly_len; i++, mp++) {
- if (facemap_data[i] == facemap) {
- for (int j = 2; j < mp->totloop; j++) {
- copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[mloop[mlt->tri[0]].v].co);
- copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[mloop[mlt->tri[1]].v].co);
- copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[mloop[mlt->tri[2]].v].co);
- vbo_len_used += 3;
- mlt++;
- }
- }
- else {
- mlt += mp->totloop - 2;
- }
- }
- }
- else {
- /* No tessellation data, fan-fill. */
- for (mp = mpoly, i = 0; i < mpoly_len; i++, mp++) {
- if (facemap_data[i] == facemap) {
- const MLoop *ml_start = &mloop[mp->loopstart];
- const MLoop *ml_a = ml_start + 1;
- const MLoop *ml_b = ml_start + 2;
- for (int j = 2; j < mp->totloop; j++) {
- copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[ml_start->v].co);
- copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[ml_a->v].co);
- copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[ml_b->v].co);
- vbo_len_used += 3;
-
- ml_a++;
- ml_b++;
- }
- }
- }
- }
-
- if (vbo_len_capacity != vbo_len_used) {
- GPU_vertbuf_data_resize(vbo_pos, vbo_len_used);
- }
-
- GPUBatch *draw_batch = GPU_batch_create(GPU_PRIM_TRIS, vbo_pos, NULL);
- GPU_batch_program_set_builtin(draw_batch, GPU_SHADER_3D_UNIFORM_COLOR);
- GPU_batch_uniform_4fv(draw_batch, "color", col);
- GPU_batch_draw(draw_batch);
- GPU_batch_discard(draw_batch);
- GPU_vertbuf_discard(vbo_pos);
-
- GPU_blend(false);
- }
+ /* happens on undo */
+ if (ob->type != OB_MESH || !ob->data) {
+ return;
+ }
+
+ Mesh *me = ob->data;
+ {
+ Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
+ if (ob_eval->runtime.mesh_eval) {
+ me = ob_eval->runtime.mesh_eval;
+ }
+ }
+
+ glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
+
+ /* Just to create the data to pass to immediate mode, grr! */
+ const int *facemap_data = CustomData_get_layer(&me->pdata, CD_FACEMAP);
+ if (facemap_data) {
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(true);
+
+ const MVert *mvert = me->mvert;
+ const MPoly *mpoly = me->mpoly;
+ const MLoop *mloop = me->mloop;
+
+ int mpoly_len = me->totpoly;
+ int mloop_len = me->totloop;
+
+ facemap_data = CustomData_get_layer(&me->pdata, CD_FACEMAP);
+
+ /* use gawain immediate mode fore now */
+ const int looptris_len = poly_to_tri_count(mpoly_len, mloop_len);
+ const int vbo_len_capacity = looptris_len * 3;
+ int vbo_len_used = 0;
+
+ GPUVertFormat format_pos = {0};
+ const uint pos_id = GPU_vertformat_attr_add(
+ &format_pos, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+
+ GPUVertBuf *vbo_pos = GPU_vertbuf_create_with_format(&format_pos);
+ GPU_vertbuf_data_alloc(vbo_pos, vbo_len_capacity);
+
+ GPUVertBufRaw pos_step;
+ GPU_vertbuf_attr_get_raw_data(vbo_pos, pos_id, &pos_step);
+
+ const MPoly *mp;
+ int i;
+ if (me->runtime.looptris.array) {
+ MLoopTri *mlt = me->runtime.looptris.array;
+ for (mp = mpoly, i = 0; i < mpoly_len; i++, mp++) {
+ if (facemap_data[i] == facemap) {
+ for (int j = 2; j < mp->totloop; j++) {
+ copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[mloop[mlt->tri[0]].v].co);
+ copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[mloop[mlt->tri[1]].v].co);
+ copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[mloop[mlt->tri[2]].v].co);
+ vbo_len_used += 3;
+ mlt++;
+ }
+ }
+ else {
+ mlt += mp->totloop - 2;
+ }
+ }
+ }
+ else {
+ /* No tessellation data, fan-fill. */
+ for (mp = mpoly, i = 0; i < mpoly_len; i++, mp++) {
+ if (facemap_data[i] == facemap) {
+ const MLoop *ml_start = &mloop[mp->loopstart];
+ const MLoop *ml_a = ml_start + 1;
+ const MLoop *ml_b = ml_start + 2;
+ for (int j = 2; j < mp->totloop; j++) {
+ copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[ml_start->v].co);
+ copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[ml_a->v].co);
+ copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[ml_b->v].co);
+ vbo_len_used += 3;
+
+ ml_a++;
+ ml_b++;
+ }
+ }
+ }
+ }
+
+ if (vbo_len_capacity != vbo_len_used) {
+ GPU_vertbuf_data_resize(vbo_pos, vbo_len_used);
+ }
+
+ GPUBatch *draw_batch = GPU_batch_create(GPU_PRIM_TRIS, vbo_pos, NULL);
+ GPU_batch_program_set_builtin(draw_batch, GPU_SHADER_3D_UNIFORM_COLOR);
+ GPU_batch_uniform_4fv(draw_batch, "color", col);
+ GPU_batch_draw(draw_batch);
+ GPU_batch_discard(draw_batch);
+ GPU_vertbuf_discard(vbo_pos);
+
+ GPU_blend(false);
+ }
}
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 42860b62ae5..434f379c6fe 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -21,7 +21,6 @@
* \ingroup spview3d
*/
-
#include <string.h>
#include <stdio.h>
@@ -79,75 +78,75 @@
#include "DEG_depsgraph.h"
-#include "view3d_intern.h" /* own include */
+#include "view3d_intern.h" /* own include */
/* ******************** manage regions ********************* */
ARegion *view3d_has_buttons_region(ScrArea *sa)
{
- ARegion *ar, *arnew;
+ ARegion *ar, *arnew;
- ar = BKE_area_find_region_type(sa, RGN_TYPE_UI);
- if (ar) {
- return ar;
- }
+ ar = BKE_area_find_region_type(sa, RGN_TYPE_UI);
+ if (ar) {
+ return ar;
+ }
- /* add subdiv level; after header */
- ar = BKE_area_find_region_type(sa, RGN_TYPE_HEADER);
+ /* add subdiv level; after header */
+ ar = BKE_area_find_region_type(sa, RGN_TYPE_HEADER);
- /* is error! */
- if (ar == NULL) {
- return NULL;
- }
+ /* is error! */
+ if (ar == NULL) {
+ return NULL;
+ }
- arnew = MEM_callocN(sizeof(ARegion), "buttons for view3d");
+ arnew = MEM_callocN(sizeof(ARegion), "buttons for view3d");
- BLI_insertlinkafter(&sa->regionbase, ar, arnew);
- arnew->regiontype = RGN_TYPE_UI;
- arnew->alignment = RGN_ALIGN_RIGHT;
+ BLI_insertlinkafter(&sa->regionbase, ar, arnew);
+ arnew->regiontype = RGN_TYPE_UI;
+ arnew->alignment = RGN_ALIGN_RIGHT;
- arnew->flag = RGN_FLAG_HIDDEN;
+ arnew->flag = RGN_FLAG_HIDDEN;
- return arnew;
+ return arnew;
}
ARegion *view3d_has_tools_region(ScrArea *sa)
{
- ARegion *ar, *artool = NULL, *arhead;
-
- for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->regiontype == RGN_TYPE_TOOLS) {
- artool = ar;
- }
- }
-
- /* tool region hide/unhide also hides props */
- if (artool) {
- return artool;
- }
-
- if (artool == NULL) {
- /* add subdiv level; after header */
- for (arhead = sa->regionbase.first; arhead; arhead = arhead->next) {
- if (arhead->regiontype == RGN_TYPE_HEADER) {
- break;
- }
- }
-
- /* is error! */
- if (arhead == NULL) {
- return NULL;
- }
-
- artool = MEM_callocN(sizeof(ARegion), "tools for view3d");
-
- BLI_insertlinkafter(&sa->regionbase, arhead, artool);
- artool->regiontype = RGN_TYPE_TOOLS;
- artool->alignment = RGN_ALIGN_LEFT;
- artool->flag = RGN_FLAG_HIDDEN;
- }
-
- return artool;
+ ARegion *ar, *artool = NULL, *arhead;
+
+ for (ar = sa->regionbase.first; ar; ar = ar->next) {
+ if (ar->regiontype == RGN_TYPE_TOOLS) {
+ artool = ar;
+ }
+ }
+
+ /* tool region hide/unhide also hides props */
+ if (artool) {
+ return artool;
+ }
+
+ if (artool == NULL) {
+ /* add subdiv level; after header */
+ for (arhead = sa->regionbase.first; arhead; arhead = arhead->next) {
+ if (arhead->regiontype == RGN_TYPE_HEADER) {
+ break;
+ }
+ }
+
+ /* is error! */
+ if (arhead == NULL) {
+ return NULL;
+ }
+
+ artool = MEM_callocN(sizeof(ARegion), "tools for view3d");
+
+ BLI_insertlinkafter(&sa->regionbase, arhead, artool);
+ artool->regiontype = RGN_TYPE_TOOLS;
+ artool->alignment = RGN_ALIGN_LEFT;
+ artool->flag = RGN_FLAG_HIDDEN;
+ }
+
+ return artool;
}
/* ****************************************************** */
@@ -155,74 +154,75 @@ ARegion *view3d_has_tools_region(ScrArea *sa)
/* function to always find a regionview3d context inside 3D window */
RegionView3D *ED_view3d_context_rv3d(bContext *C)
{
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
-
- if (rv3d == NULL) {
- ScrArea *sa = CTX_wm_area(C);
- if (sa && sa->spacetype == SPACE_VIEW3D) {
- ARegion *ar = BKE_area_find_region_active_win(sa);
- if (ar) {
- rv3d = ar->regiondata;
- }
- }
- }
- return rv3d;
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+
+ if (rv3d == NULL) {
+ ScrArea *sa = CTX_wm_area(C);
+ if (sa && sa->spacetype == SPACE_VIEW3D) {
+ ARegion *ar = BKE_area_find_region_active_win(sa);
+ if (ar) {
+ rv3d = ar->regiondata;
+ }
+ }
+ }
+ return rv3d;
}
/* ideally would return an rv3d but in some cases the region is needed too
* so return that, the caller can then access the ar->regiondata */
bool ED_view3d_context_user_region(bContext *C, View3D **r_v3d, ARegion **r_ar)
{
- ScrArea *sa = CTX_wm_area(C);
-
- *r_v3d = NULL;
- *r_ar = NULL;
-
- if (sa && sa->spacetype == SPACE_VIEW3D) {
- ARegion *ar = CTX_wm_region(C);
- View3D *v3d = (View3D *)sa->spacedata.first;
-
- if (ar) {
- RegionView3D *rv3d;
- if ((ar->regiontype == RGN_TYPE_WINDOW) && (rv3d = ar->regiondata) && (rv3d->viewlock & RV3D_LOCKED) == 0) {
- *r_v3d = v3d;
- *r_ar = ar;
- return true;
- }
- else {
- ARegion *ar_unlock_user = NULL;
- ARegion *ar_unlock = NULL;
- for (ar = sa->regionbase.first; ar; ar = ar->next) {
- /* find the first unlocked rv3d */
- if (ar->regiondata && ar->regiontype == RGN_TYPE_WINDOW) {
- rv3d = ar->regiondata;
- if ((rv3d->viewlock & RV3D_LOCKED) == 0) {
- ar_unlock = ar;
- if (rv3d->persp == RV3D_PERSP || rv3d->persp == RV3D_CAMOB) {
- ar_unlock_user = ar;
- break;
- }
- }
- }
- }
-
- /* camera/perspective view get priority when the active region is locked */
- if (ar_unlock_user) {
- *r_v3d = v3d;
- *r_ar = ar_unlock_user;
- return true;
- }
-
- if (ar_unlock) {
- *r_v3d = v3d;
- *r_ar = ar_unlock;
- return true;
- }
- }
- }
- }
-
- return false;
+ ScrArea *sa = CTX_wm_area(C);
+
+ *r_v3d = NULL;
+ *r_ar = NULL;
+
+ if (sa && sa->spacetype == SPACE_VIEW3D) {
+ ARegion *ar = CTX_wm_region(C);
+ View3D *v3d = (View3D *)sa->spacedata.first;
+
+ if (ar) {
+ RegionView3D *rv3d;
+ if ((ar->regiontype == RGN_TYPE_WINDOW) && (rv3d = ar->regiondata) &&
+ (rv3d->viewlock & RV3D_LOCKED) == 0) {
+ *r_v3d = v3d;
+ *r_ar = ar;
+ return true;
+ }
+ else {
+ ARegion *ar_unlock_user = NULL;
+ ARegion *ar_unlock = NULL;
+ for (ar = sa->regionbase.first; ar; ar = ar->next) {
+ /* find the first unlocked rv3d */
+ if (ar->regiondata && ar->regiontype == RGN_TYPE_WINDOW) {
+ rv3d = ar->regiondata;
+ if ((rv3d->viewlock & RV3D_LOCKED) == 0) {
+ ar_unlock = ar;
+ if (rv3d->persp == RV3D_PERSP || rv3d->persp == RV3D_CAMOB) {
+ ar_unlock_user = ar;
+ break;
+ }
+ }
+ }
+ }
+
+ /* camera/perspective view get priority when the active region is locked */
+ if (ar_unlock_user) {
+ *r_v3d = v3d;
+ *r_ar = ar_unlock_user;
+ return true;
+ }
+
+ if (ar_unlock) {
+ *r_v3d = v3d;
+ *r_ar = ar_unlock;
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
}
/* Most of the time this isn't needed since you could assume the view matrix was
@@ -238,1325 +238,1340 @@ bool ED_view3d_context_user_region(bContext *C, View3D **r_v3d, ARegion **r_ar)
*/
void ED_view3d_init_mats_rv3d(struct Object *ob, struct RegionView3D *rv3d)
{
- /* local viewmat and persmat, to calculate projections */
- mul_m4_m4m4(rv3d->viewmatob, rv3d->viewmat, ob->obmat);
- mul_m4_m4m4(rv3d->persmatob, rv3d->persmat, ob->obmat);
+ /* local viewmat and persmat, to calculate projections */
+ mul_m4_m4m4(rv3d->viewmatob, rv3d->viewmat, ob->obmat);
+ mul_m4_m4m4(rv3d->persmatob, rv3d->persmat, ob->obmat);
- /* initializes object space clipping, speeds up clip tests */
- ED_view3d_clipping_local(rv3d, ob->obmat);
+ /* initializes object space clipping, speeds up clip tests */
+ ED_view3d_clipping_local(rv3d, ob->obmat);
}
void ED_view3d_init_mats_rv3d_gl(struct Object *ob, struct RegionView3D *rv3d)
{
- ED_view3d_init_mats_rv3d(ob, rv3d);
+ ED_view3d_init_mats_rv3d(ob, rv3d);
- /* we have to multiply instead of loading viewmatob to make
- * it work with duplis using displists, otherwise it will
- * override the dupli-matrix */
- GPU_matrix_mul(ob->obmat);
+ /* we have to multiply instead of loading viewmatob to make
+ * it work with duplis using displists, otherwise it will
+ * override the dupli-matrix */
+ GPU_matrix_mul(ob->obmat);
}
#ifdef DEBUG
/* ensure we correctly initialize */
void ED_view3d_clear_mats_rv3d(struct RegionView3D *rv3d)
{
- zero_m4(rv3d->viewmatob);
- zero_m4(rv3d->persmatob);
+ zero_m4(rv3d->viewmatob);
+ zero_m4(rv3d->persmatob);
}
void ED_view3d_check_mats_rv3d(struct RegionView3D *rv3d)
{
- BLI_ASSERT_ZERO_M4(rv3d->viewmatob);
- BLI_ASSERT_ZERO_M4(rv3d->persmatob);
+ BLI_ASSERT_ZERO_M4(rv3d->viewmatob);
+ BLI_ASSERT_ZERO_M4(rv3d->persmatob);
}
#endif
void ED_view3d_stop_render_preview(wmWindowManager *wm, ARegion *ar)
{
- RegionView3D *rv3d = ar->regiondata;
+ RegionView3D *rv3d = ar->regiondata;
- if (rv3d->render_engine) {
+ if (rv3d->render_engine) {
#ifdef WITH_PYTHON
- BPy_BEGIN_ALLOW_THREADS;
+ BPy_BEGIN_ALLOW_THREADS;
#endif
- WM_jobs_kill_type(wm, ar, WM_JOB_TYPE_RENDER_PREVIEW);
+ WM_jobs_kill_type(wm, ar, WM_JOB_TYPE_RENDER_PREVIEW);
#ifdef WITH_PYTHON
- BPy_END_ALLOW_THREADS;
+ BPy_END_ALLOW_THREADS;
#endif
- RE_engine_free(rv3d->render_engine);
- rv3d->render_engine = NULL;
- }
+ RE_engine_free(rv3d->render_engine);
+ rv3d->render_engine = NULL;
+ }
}
void ED_view3d_shade_update(Main *bmain, View3D *v3d, ScrArea *sa)
{
- wmWindowManager *wm = bmain->wm.first;
-
- if (v3d->shading.type != OB_RENDER) {
- ARegion *ar;
-
- for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if ((ar->regiontype == RGN_TYPE_WINDOW) && ar->regiondata) {
- ED_view3d_stop_render_preview(wm, ar);
- break;
- }
- }
- }
+ wmWindowManager *wm = bmain->wm.first;
+
+ if (v3d->shading.type != OB_RENDER) {
+ ARegion *ar;
+
+ for (ar = sa->regionbase.first; ar; ar = ar->next) {
+ if ((ar->regiontype == RGN_TYPE_WINDOW) && ar->regiondata) {
+ ED_view3d_stop_render_preview(wm, ar);
+ break;
+ }
+ }
+ }
}
/* ******************** default callbacks for view3d space ***************** */
static SpaceLink *view3d_new(const ScrArea *UNUSED(sa), const Scene *scene)
{
- ARegion *ar;
- View3D *v3d;
- RegionView3D *rv3d;
-
- v3d = MEM_callocN(sizeof(View3D), "initview3d");
- v3d->spacetype = SPACE_VIEW3D;
- if (scene) {
- v3d->camera = scene->camera;
- }
- v3d->scenelock = true;
- v3d->grid = 1.0f;
- v3d->gridlines = 16;
- v3d->gridsubdiv = 10;
- BKE_screen_view3d_shading_init(&v3d->shading);
-
- v3d->overlay.wireframe_threshold = 1.0f;
- v3d->overlay.xray_alpha_bone = 0.5f;
- v3d->overlay.texture_paint_mode_opacity = 1.0f;
- v3d->overlay.weight_paint_mode_opacity = 1.0f;
- v3d->overlay.vertex_paint_mode_opacity = 1.0f;
- v3d->overlay.edit_flag = V3D_OVERLAY_EDIT_FACES |
- V3D_OVERLAY_EDIT_SEAMS |
- V3D_OVERLAY_EDIT_SHARP |
- V3D_OVERLAY_EDIT_FREESTYLE_EDGE |
- V3D_OVERLAY_EDIT_FREESTYLE_FACE |
- V3D_OVERLAY_EDIT_EDGES |
- V3D_OVERLAY_EDIT_CREASES |
- V3D_OVERLAY_EDIT_BWEIGHTS |
- V3D_OVERLAY_EDIT_CU_HANDLES |
- V3D_OVERLAY_EDIT_CU_NORMALS;
-
- v3d->gridflag = V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_FLOOR;
-
- v3d->flag = V3D_SELECT_OUTLINE;
- v3d->flag2 = V3D_SHOW_RECONSTRUCTION | V3D_SHOW_ANNOTATION;
-
- v3d->lens = 50.0f;
- v3d->clip_start = 0.01f;
- v3d->clip_end = 1000.0f;
-
- v3d->overlay.gpencil_paper_opacity = 0.5f;
- v3d->overlay.gpencil_grid_opacity = 0.9f;
-
- v3d->bundle_size = 0.2f;
- v3d->bundle_drawtype = OB_PLAINAXES;
-
- /* stereo */
- v3d->stereo3d_camera = STEREO_3D_ID;
- v3d->stereo3d_flag |= V3D_S3D_DISPPLANE;
- v3d->stereo3d_convergence_alpha = 0.15f;
- v3d->stereo3d_volume_alpha = 0.05f;
-
- /* grease pencil settings */
- v3d->vertex_opacity = 1.0f;
- v3d->gp_flag |= V3D_GP_SHOW_EDIT_LINES;
-
- /* header */
- ar = MEM_callocN(sizeof(ARegion), "header for view3d");
-
- BLI_addtail(&v3d->regionbase, ar);
- ar->regiontype = RGN_TYPE_HEADER;
- ar->alignment = (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_BOTTOM : RGN_ALIGN_TOP;
-
- /* tool shelf */
- ar = MEM_callocN(sizeof(ARegion), "toolshelf for view3d");
-
- BLI_addtail(&v3d->regionbase, ar);
- ar->regiontype = RGN_TYPE_TOOLS;
- ar->alignment = RGN_ALIGN_LEFT;
- ar->flag = RGN_FLAG_HIDDEN;
-
- /* buttons/list view */
- ar = MEM_callocN(sizeof(ARegion), "buttons for view3d");
-
- BLI_addtail(&v3d->regionbase, ar);
- ar->regiontype = RGN_TYPE_UI;
- ar->alignment = RGN_ALIGN_RIGHT;
- ar->flag = RGN_FLAG_HIDDEN;
-
- /* main region */
- ar = MEM_callocN(sizeof(ARegion), "main region for view3d");
-
- BLI_addtail(&v3d->regionbase, ar);
- ar->regiontype = RGN_TYPE_WINDOW;
-
- ar->regiondata = MEM_callocN(sizeof(RegionView3D), "region view3d");
- rv3d = ar->regiondata;
- rv3d->viewquat[0] = 1.0f;
- rv3d->persp = RV3D_PERSP;
- rv3d->view = RV3D_VIEW_USER;
- rv3d->dist = 10.0;
-
- return (SpaceLink *)v3d;
+ ARegion *ar;
+ View3D *v3d;
+ RegionView3D *rv3d;
+
+ v3d = MEM_callocN(sizeof(View3D), "initview3d");
+ v3d->spacetype = SPACE_VIEW3D;
+ if (scene) {
+ v3d->camera = scene->camera;
+ }
+ v3d->scenelock = true;
+ v3d->grid = 1.0f;
+ v3d->gridlines = 16;
+ v3d->gridsubdiv = 10;
+ BKE_screen_view3d_shading_init(&v3d->shading);
+
+ v3d->overlay.wireframe_threshold = 1.0f;
+ v3d->overlay.xray_alpha_bone = 0.5f;
+ v3d->overlay.texture_paint_mode_opacity = 1.0f;
+ v3d->overlay.weight_paint_mode_opacity = 1.0f;
+ v3d->overlay.vertex_paint_mode_opacity = 1.0f;
+ v3d->overlay.edit_flag = V3D_OVERLAY_EDIT_FACES | V3D_OVERLAY_EDIT_SEAMS |
+ V3D_OVERLAY_EDIT_SHARP | V3D_OVERLAY_EDIT_FREESTYLE_EDGE |
+ V3D_OVERLAY_EDIT_FREESTYLE_FACE | V3D_OVERLAY_EDIT_EDGES |
+ V3D_OVERLAY_EDIT_CREASES | V3D_OVERLAY_EDIT_BWEIGHTS |
+ V3D_OVERLAY_EDIT_CU_HANDLES | V3D_OVERLAY_EDIT_CU_NORMALS;
+
+ v3d->gridflag = V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_FLOOR;
+
+ v3d->flag = V3D_SELECT_OUTLINE;
+ v3d->flag2 = V3D_SHOW_RECONSTRUCTION | V3D_SHOW_ANNOTATION;
+
+ v3d->lens = 50.0f;
+ v3d->clip_start = 0.01f;
+ v3d->clip_end = 1000.0f;
+
+ v3d->overlay.gpencil_paper_opacity = 0.5f;
+ v3d->overlay.gpencil_grid_opacity = 0.9f;
+
+ v3d->bundle_size = 0.2f;
+ v3d->bundle_drawtype = OB_PLAINAXES;
+
+ /* stereo */
+ v3d->stereo3d_camera = STEREO_3D_ID;
+ v3d->stereo3d_flag |= V3D_S3D_DISPPLANE;
+ v3d->stereo3d_convergence_alpha = 0.15f;
+ v3d->stereo3d_volume_alpha = 0.05f;
+
+ /* grease pencil settings */
+ v3d->vertex_opacity = 1.0f;
+ v3d->gp_flag |= V3D_GP_SHOW_EDIT_LINES;
+
+ /* header */
+ ar = MEM_callocN(sizeof(ARegion), "header for view3d");
+
+ BLI_addtail(&v3d->regionbase, ar);
+ ar->regiontype = RGN_TYPE_HEADER;
+ ar->alignment = (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_BOTTOM : RGN_ALIGN_TOP;
+
+ /* tool shelf */
+ ar = MEM_callocN(sizeof(ARegion), "toolshelf for view3d");
+
+ BLI_addtail(&v3d->regionbase, ar);
+ ar->regiontype = RGN_TYPE_TOOLS;
+ ar->alignment = RGN_ALIGN_LEFT;
+ ar->flag = RGN_FLAG_HIDDEN;
+
+ /* buttons/list view */
+ ar = MEM_callocN(sizeof(ARegion), "buttons for view3d");
+
+ BLI_addtail(&v3d->regionbase, ar);
+ ar->regiontype = RGN_TYPE_UI;
+ ar->alignment = RGN_ALIGN_RIGHT;
+ ar->flag = RGN_FLAG_HIDDEN;
+
+ /* main region */
+ ar = MEM_callocN(sizeof(ARegion), "main region for view3d");
+
+ BLI_addtail(&v3d->regionbase, ar);
+ ar->regiontype = RGN_TYPE_WINDOW;
+
+ ar->regiondata = MEM_callocN(sizeof(RegionView3D), "region view3d");
+ rv3d = ar->regiondata;
+ rv3d->viewquat[0] = 1.0f;
+ rv3d->persp = RV3D_PERSP;
+ rv3d->view = RV3D_VIEW_USER;
+ rv3d->dist = 10.0;
+
+ return (SpaceLink *)v3d;
}
/* not spacelink itself */
static void view3d_free(SpaceLink *sl)
{
- View3D *vd = (View3D *) sl;
-
- if (vd->localvd) {
- MEM_freeN(vd->localvd);
- }
-
- if (vd->runtime.properties_storage) {
- MEM_freeN(vd->runtime.properties_storage);
- }
-
- if (vd->fx_settings.ssao) {
- MEM_freeN(vd->fx_settings.ssao);
- }
- if (vd->fx_settings.dof) {
- MEM_freeN(vd->fx_settings.dof);
- }
+ View3D *vd = (View3D *)sl;
+
+ if (vd->localvd) {
+ MEM_freeN(vd->localvd);
+ }
+
+ if (vd->runtime.properties_storage) {
+ MEM_freeN(vd->runtime.properties_storage);
+ }
+
+ if (vd->fx_settings.ssao) {
+ MEM_freeN(vd->fx_settings.ssao);
+ }
+ if (vd->fx_settings.dof) {
+ MEM_freeN(vd->fx_settings.dof);
+ }
}
-
/* spacetype; init callback */
static void view3d_init(wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa))
{
-
}
static SpaceLink *view3d_duplicate(SpaceLink *sl)
{
- View3D *v3do = (View3D *)sl;
- View3D *v3dn = MEM_dupallocN(sl);
+ View3D *v3do = (View3D *)sl;
+ View3D *v3dn = MEM_dupallocN(sl);
- /* clear or remove stuff from old */
+ /* clear or remove stuff from old */
- if (v3dn->localvd) {
- v3dn->localvd = NULL;
- v3dn->runtime.properties_storage = NULL;
- }
+ if (v3dn->localvd) {
+ v3dn->localvd = NULL;
+ v3dn->runtime.properties_storage = NULL;
+ }
- if (v3dn->shading.type == OB_RENDER) {
- v3dn->shading.type = OB_SOLID;
- }
+ if (v3dn->shading.type == OB_RENDER) {
+ v3dn->shading.type = OB_SOLID;
+ }
- /* copy or clear inside new stuff */
+ /* copy or clear inside new stuff */
- v3dn->runtime.properties_storage = NULL;
- if (v3dn->fx_settings.dof) {
- v3dn->fx_settings.dof = MEM_dupallocN(v3do->fx_settings.dof);
- }
- if (v3dn->fx_settings.ssao) {
- v3dn->fx_settings.ssao = MEM_dupallocN(v3do->fx_settings.ssao);
- }
+ v3dn->runtime.properties_storage = NULL;
+ if (v3dn->fx_settings.dof) {
+ v3dn->fx_settings.dof = MEM_dupallocN(v3do->fx_settings.dof);
+ }
+ if (v3dn->fx_settings.ssao) {
+ v3dn->fx_settings.ssao = MEM_dupallocN(v3do->fx_settings.ssao);
+ }
- return (SpaceLink *)v3dn;
+ return (SpaceLink *)v3dn;
}
/* add handlers, stuff you only do once or on area/region changes */
static void view3d_main_region_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *lb;
- wmKeyMap *keymap;
-
- /* object ops. */
+ ListBase *lb;
+ wmKeyMap *keymap;
- /* important to be before Pose keymap since they can both be enabled at once */
- keymap = WM_keymap_ensure(wm->defaultconf, "Face Mask", 0, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ /* object ops. */
+ /* important to be before Pose keymap since they can both be enabled at once */
+ keymap = WM_keymap_ensure(wm->defaultconf, "Face Mask", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
- keymap = WM_keymap_ensure(wm->defaultconf, "Weight Paint Vertex Selection", 0, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ keymap = WM_keymap_ensure(wm->defaultconf, "Weight Paint Vertex Selection", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
- /* pose is not modal, operator poll checks for this */
- keymap = WM_keymap_ensure(wm->defaultconf, "Pose", 0, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ /* pose is not modal, operator poll checks for this */
+ keymap = WM_keymap_ensure(wm->defaultconf, "Pose", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
- keymap = WM_keymap_ensure(wm->defaultconf, "Object Mode", 0, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ keymap = WM_keymap_ensure(wm->defaultconf, "Object Mode", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
- keymap = WM_keymap_ensure(wm->defaultconf, "Paint Curve", 0, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ keymap = WM_keymap_ensure(wm->defaultconf, "Paint Curve", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
- keymap = WM_keymap_ensure(wm->defaultconf, "Curve", 0, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ keymap = WM_keymap_ensure(wm->defaultconf, "Curve", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
- keymap = WM_keymap_ensure(wm->defaultconf, "Image Paint", 0, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ keymap = WM_keymap_ensure(wm->defaultconf, "Image Paint", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
- keymap = WM_keymap_ensure(wm->defaultconf, "Vertex Paint", 0, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ keymap = WM_keymap_ensure(wm->defaultconf, "Vertex Paint", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
- keymap = WM_keymap_ensure(wm->defaultconf, "Weight Paint", 0, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ keymap = WM_keymap_ensure(wm->defaultconf, "Weight Paint", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
- keymap = WM_keymap_ensure(wm->defaultconf, "Sculpt", 0, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ keymap = WM_keymap_ensure(wm->defaultconf, "Sculpt", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
- keymap = WM_keymap_ensure(wm->defaultconf, "Mesh", 0, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ keymap = WM_keymap_ensure(wm->defaultconf, "Mesh", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
- keymap = WM_keymap_ensure(wm->defaultconf, "Curve", 0, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ keymap = WM_keymap_ensure(wm->defaultconf, "Curve", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
- keymap = WM_keymap_ensure(wm->defaultconf, "Armature", 0, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ keymap = WM_keymap_ensure(wm->defaultconf, "Armature", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
- keymap = WM_keymap_ensure(wm->defaultconf, "Pose", 0, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ keymap = WM_keymap_ensure(wm->defaultconf, "Pose", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
- keymap = WM_keymap_ensure(wm->defaultconf, "Metaball", 0, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ keymap = WM_keymap_ensure(wm->defaultconf, "Metaball", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
- keymap = WM_keymap_ensure(wm->defaultconf, "Lattice", 0, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ keymap = WM_keymap_ensure(wm->defaultconf, "Lattice", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
- keymap = WM_keymap_ensure(wm->defaultconf, "Particle", 0, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ keymap = WM_keymap_ensure(wm->defaultconf, "Particle", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
- /* editfont keymap swallows all... */
- keymap = WM_keymap_ensure(wm->defaultconf, "Font", 0, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ /* editfont keymap swallows all... */
+ keymap = WM_keymap_ensure(wm->defaultconf, "Font", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
- keymap = WM_keymap_ensure(wm->defaultconf, "Object Non-modal", 0, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ keymap = WM_keymap_ensure(wm->defaultconf, "Object Non-modal", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
- keymap = WM_keymap_ensure(wm->defaultconf, "Frames", 0, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ keymap = WM_keymap_ensure(wm->defaultconf, "Frames", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
- /* own keymap, last so modes can override it */
- keymap = WM_keymap_ensure(wm->defaultconf, "3D View Generic", SPACE_VIEW3D, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ /* own keymap, last so modes can override it */
+ keymap = WM_keymap_ensure(wm->defaultconf, "3D View Generic", SPACE_VIEW3D, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
- keymap = WM_keymap_ensure(wm->defaultconf, "3D View", SPACE_VIEW3D, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ keymap = WM_keymap_ensure(wm->defaultconf, "3D View", SPACE_VIEW3D, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
- /* add drop boxes */
- lb = WM_dropboxmap_find("View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW);
-
- WM_event_add_dropbox_handler(&ar->handlers, lb);
+ /* add drop boxes */
+ lb = WM_dropboxmap_find("View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW);
+ WM_event_add_dropbox_handler(&ar->handlers, lb);
}
static void view3d_main_region_exit(wmWindowManager *wm, ARegion *ar)
{
- ED_view3d_stop_render_preview(wm, ar);
+ ED_view3d_stop_render_preview(wm, ar);
}
-static bool view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip))
+static bool view3d_ob_drop_poll(bContext *UNUSED(C),
+ wmDrag *drag,
+ const wmEvent *UNUSED(event),
+ const char **UNUSED(tooltip))
{
- return WM_drag_ID(drag, ID_OB) != NULL;
+ return WM_drag_ID(drag, ID_OB) != NULL;
}
-static bool view3d_collection_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip))
+static bool view3d_collection_drop_poll(bContext *UNUSED(C),
+ wmDrag *drag,
+ const wmEvent *UNUSED(event),
+ const char **UNUSED(tooltip))
{
- return WM_drag_ID(drag, ID_GR) != NULL;
+ return WM_drag_ID(drag, ID_GR) != NULL;
}
-static bool view3d_mat_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip))
+static bool view3d_mat_drop_poll(bContext *UNUSED(C),
+ wmDrag *drag,
+ const wmEvent *UNUSED(event),
+ const char **UNUSED(tooltip))
{
- return WM_drag_ID(drag, ID_MA) != NULL;
+ return WM_drag_ID(drag, ID_MA) != NULL;
}
-static bool view3d_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip))
+static bool view3d_ima_drop_poll(bContext *UNUSED(C),
+ wmDrag *drag,
+ const wmEvent *UNUSED(event),
+ const char **UNUSED(tooltip))
{
- if (drag->type == WM_DRAG_PATH) {
- /* rule might not work? */
- return (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE));
- }
- else {
- return WM_drag_ID(drag, ID_IM) != NULL;
- }
+ if (drag->type == WM_DRAG_PATH) {
+ /* rule might not work? */
+ return (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE));
+ }
+ else {
+ return WM_drag_ID(drag, ID_IM) != NULL;
+ }
}
static bool view3d_ima_bg_is_camera_view(bContext *C)
{
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
- if ((rv3d && (rv3d->persp == RV3D_CAMOB))) {
- View3D *v3d = CTX_wm_view3d(C);
- if (v3d && v3d->camera && v3d->camera->type == OB_CAMERA) {
- return true;
- }
- }
- return false;
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ if ((rv3d && (rv3d->persp == RV3D_CAMOB))) {
+ View3D *v3d = CTX_wm_view3d(C);
+ if (v3d && v3d->camera && v3d->camera->type == OB_CAMERA) {
+ return true;
+ }
+ }
+ return false;
}
-static bool view3d_ima_bg_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **tooltip)
+static bool view3d_ima_bg_drop_poll(bContext *C,
+ wmDrag *drag,
+ const wmEvent *event,
+ const char **tooltip)
{
- if (!view3d_ima_drop_poll(C, drag, event, tooltip)) {
- return false;
- }
+ if (!view3d_ima_drop_poll(C, drag, event, tooltip)) {
+ return false;
+ }
- if (ED_view3d_is_object_under_cursor(C, event->mval)) {
- return false;
- }
+ if (ED_view3d_is_object_under_cursor(C, event->mval)) {
+ return false;
+ }
- return view3d_ima_bg_is_camera_view(C);
+ return view3d_ima_bg_is_camera_view(C);
}
-static bool view3d_ima_empty_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **tooltip)
+static bool view3d_ima_empty_drop_poll(bContext *C,
+ wmDrag *drag,
+ const wmEvent *event,
+ const char **tooltip)
{
- if (!view3d_ima_drop_poll(C, drag, event, tooltip)) {
- return false;
- }
+ if (!view3d_ima_drop_poll(C, drag, event, tooltip)) {
+ return false;
+ }
- Object *ob = ED_view3d_give_object_under_cursor(C, event->mval);
+ Object *ob = ED_view3d_give_object_under_cursor(C, event->mval);
- if (ob == NULL) {
- return true;
- }
+ if (ob == NULL) {
+ return true;
+ }
- if (ob->type == OB_EMPTY && ob->empty_drawtype == OB_EMPTY_IMAGE) {
- return true;
- }
+ if (ob->type == OB_EMPTY && ob->empty_drawtype == OB_EMPTY_IMAGE) {
+ return true;
+ }
- return false;
+ return false;
}
static void view3d_ob_drop_copy(wmDrag *drag, wmDropBox *drop)
{
- ID *id = WM_drag_ID(drag, ID_OB);
+ ID *id = WM_drag_ID(drag, ID_OB);
- RNA_string_set(drop->ptr, "name", id->name + 2);
+ RNA_string_set(drop->ptr, "name", id->name + 2);
}
static void view3d_collection_drop_copy(wmDrag *drag, wmDropBox *drop)
{
- ID *id = WM_drag_ID(drag, ID_GR);
+ ID *id = WM_drag_ID(drag, ID_GR);
- drop->opcontext = WM_OP_EXEC_DEFAULT;
- RNA_string_set(drop->ptr, "name", id->name + 2);
+ drop->opcontext = WM_OP_EXEC_DEFAULT;
+ RNA_string_set(drop->ptr, "name", id->name + 2);
}
static void view3d_id_drop_copy(wmDrag *drag, wmDropBox *drop)
{
- ID *id = WM_drag_ID(drag, 0);
+ ID *id = WM_drag_ID(drag, 0);
- RNA_string_set(drop->ptr, "name", id->name + 2);
+ RNA_string_set(drop->ptr, "name", id->name + 2);
}
static void view3d_id_path_drop_copy(wmDrag *drag, wmDropBox *drop)
{
- ID *id = WM_drag_ID(drag, 0);
-
- if (id) {
- RNA_string_set(drop->ptr, "name", id->name + 2);
- RNA_struct_property_unset(drop->ptr, "filepath");
- }
- else if (drag->path[0]) {
- RNA_string_set(drop->ptr, "filepath", drag->path);
- RNA_struct_property_unset(drop->ptr, "image");
- }
+ ID *id = WM_drag_ID(drag, 0);
+
+ if (id) {
+ RNA_string_set(drop->ptr, "name", id->name + 2);
+ RNA_struct_property_unset(drop->ptr, "filepath");
+ }
+ else if (drag->path[0]) {
+ RNA_string_set(drop->ptr, "filepath", drag->path);
+ RNA_struct_property_unset(drop->ptr, "image");
+ }
}
static void view3d_lightcache_update(bContext *C)
{
- PointerRNA op_ptr;
+ PointerRNA op_ptr;
- Scene *scene = CTX_data_scene(C);
+ Scene *scene = CTX_data_scene(C);
- if (strcmp(scene->r.engine, RE_engine_id_BLENDER_EEVEE) != 0) {
- /* Only do auto bake if eevee is the active engine */
- return;
- }
+ if (strcmp(scene->r.engine, RE_engine_id_BLENDER_EEVEE) != 0) {
+ /* Only do auto bake if eevee is the active engine */
+ return;
+ }
- WM_operator_properties_create(&op_ptr, "SCENE_OT_light_cache_bake");
- RNA_int_set(&op_ptr, "delay", 200);
- RNA_enum_set_identifier(C, &op_ptr, "subset", "DIRTY");
+ WM_operator_properties_create(&op_ptr, "SCENE_OT_light_cache_bake");
+ RNA_int_set(&op_ptr, "delay", 200);
+ RNA_enum_set_identifier(C, &op_ptr, "subset", "DIRTY");
- WM_operator_name_call(C, "SCENE_OT_light_cache_bake", WM_OP_INVOKE_DEFAULT, &op_ptr);
+ WM_operator_name_call(C, "SCENE_OT_light_cache_bake", WM_OP_INVOKE_DEFAULT, &op_ptr);
- WM_operator_properties_free(&op_ptr);
+ WM_operator_properties_free(&op_ptr);
}
/* region dropbox definition */
static void view3d_dropboxes(void)
{
- ListBase *lb = WM_dropboxmap_find("View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW);
-
- WM_dropbox_add(lb, "OBJECT_OT_add_named", view3d_ob_drop_poll, view3d_ob_drop_copy);
- WM_dropbox_add(lb, "OBJECT_OT_drop_named_material", view3d_mat_drop_poll, view3d_id_drop_copy);
- WM_dropbox_add(lb, "VIEW3D_OT_background_image_add", view3d_ima_bg_drop_poll, view3d_id_path_drop_copy);
- WM_dropbox_add(lb, "OBJECT_OT_drop_named_image", view3d_ima_empty_drop_poll, view3d_id_path_drop_copy);
- WM_dropbox_add(lb, "OBJECT_OT_collection_instance_add", view3d_collection_drop_poll, view3d_collection_drop_copy);
+ ListBase *lb = WM_dropboxmap_find("View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW);
+
+ WM_dropbox_add(lb, "OBJECT_OT_add_named", view3d_ob_drop_poll, view3d_ob_drop_copy);
+ WM_dropbox_add(lb, "OBJECT_OT_drop_named_material", view3d_mat_drop_poll, view3d_id_drop_copy);
+ WM_dropbox_add(
+ lb, "VIEW3D_OT_background_image_add", view3d_ima_bg_drop_poll, view3d_id_path_drop_copy);
+ WM_dropbox_add(
+ lb, "OBJECT_OT_drop_named_image", view3d_ima_empty_drop_poll, view3d_id_path_drop_copy);
+ WM_dropbox_add(lb,
+ "OBJECT_OT_collection_instance_add",
+ view3d_collection_drop_poll,
+ view3d_collection_drop_copy);
}
static void view3d_widgets(void)
{
- wmGizmoMapType *gzmap_type = WM_gizmomaptype_ensure(
- &(const struct wmGizmoMapType_Params){SPACE_VIEW3D, RGN_TYPE_WINDOW});
-
- WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_xform_gizmo_context);
- WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_light_spot);
- WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_light_area);
- WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_light_target);
- WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_force_field);
- WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_camera);
- WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_camera_view);
- WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_empty_image);
- WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_armature_spline);
-
- WM_gizmogrouptype_append(VIEW3D_GGT_xform_gizmo);
- WM_gizmogrouptype_append(VIEW3D_GGT_xform_cage);
- WM_gizmogrouptype_append(VIEW3D_GGT_xform_shear);
- WM_gizmogrouptype_append(VIEW3D_GGT_xform_extrude);
- WM_gizmogrouptype_append(VIEW3D_GGT_mesh_preselect_elem);
- WM_gizmogrouptype_append(VIEW3D_GGT_mesh_preselect_edgering);
-
- WM_gizmogrouptype_append(VIEW3D_GGT_ruler);
- WM_gizmotype_append(VIEW3D_GT_ruler_item);
-
- WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_navigate);
- WM_gizmotype_append(VIEW3D_GT_navigate_rotate);
+ wmGizmoMapType *gzmap_type = WM_gizmomaptype_ensure(
+ &(const struct wmGizmoMapType_Params){SPACE_VIEW3D, RGN_TYPE_WINDOW});
+
+ WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_xform_gizmo_context);
+ WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_light_spot);
+ WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_light_area);
+ WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_light_target);
+ WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_force_field);
+ WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_camera);
+ WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_camera_view);
+ WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_empty_image);
+ WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_armature_spline);
+
+ WM_gizmogrouptype_append(VIEW3D_GGT_xform_gizmo);
+ WM_gizmogrouptype_append(VIEW3D_GGT_xform_cage);
+ WM_gizmogrouptype_append(VIEW3D_GGT_xform_shear);
+ WM_gizmogrouptype_append(VIEW3D_GGT_xform_extrude);
+ WM_gizmogrouptype_append(VIEW3D_GGT_mesh_preselect_elem);
+ WM_gizmogrouptype_append(VIEW3D_GGT_mesh_preselect_edgering);
+
+ WM_gizmogrouptype_append(VIEW3D_GGT_ruler);
+ WM_gizmotype_append(VIEW3D_GT_ruler_item);
+
+ WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_navigate);
+ WM_gizmotype_append(VIEW3D_GT_navigate_rotate);
}
-
/* type callback, not region itself */
static void view3d_main_region_free(ARegion *ar)
{
- RegionView3D *rv3d = ar->regiondata;
-
- if (rv3d) {
- if (rv3d->localvd) {
- MEM_freeN(rv3d->localvd);
- }
- if (rv3d->clipbb) {
- MEM_freeN(rv3d->clipbb);
- }
-
- if (rv3d->render_engine) {
- RE_engine_free(rv3d->render_engine);
- }
-
- if (rv3d->depths) {
- if (rv3d->depths->depths) {
- MEM_freeN(rv3d->depths->depths);
- }
- MEM_freeN(rv3d->depths);
- }
- if (rv3d->sms) {
- MEM_freeN(rv3d->sms);
- }
-
- MEM_freeN(rv3d);
- ar->regiondata = NULL;
- }
+ RegionView3D *rv3d = ar->regiondata;
+
+ if (rv3d) {
+ if (rv3d->localvd) {
+ MEM_freeN(rv3d->localvd);
+ }
+ if (rv3d->clipbb) {
+ MEM_freeN(rv3d->clipbb);
+ }
+
+ if (rv3d->render_engine) {
+ RE_engine_free(rv3d->render_engine);
+ }
+
+ if (rv3d->depths) {
+ if (rv3d->depths->depths) {
+ MEM_freeN(rv3d->depths->depths);
+ }
+ MEM_freeN(rv3d->depths);
+ }
+ if (rv3d->sms) {
+ MEM_freeN(rv3d->sms);
+ }
+
+ MEM_freeN(rv3d);
+ ar->regiondata = NULL;
+ }
}
/* copy regiondata */
static void *view3d_main_region_duplicate(void *poin)
{
- if (poin) {
- RegionView3D *rv3d = poin, *new;
-
- new = MEM_dupallocN(rv3d);
- if (rv3d->localvd) {
- new->localvd = MEM_dupallocN(rv3d->localvd);
- }
- if (rv3d->clipbb) {
- new->clipbb = MEM_dupallocN(rv3d->clipbb);
- }
-
- new->depths = NULL;
- new->render_engine = NULL;
- new->sms = NULL;
- new->smooth_timer = NULL;
-
- return new;
- }
- return NULL;
+ if (poin) {
+ RegionView3D *rv3d = poin, *new;
+
+ new = MEM_dupallocN(rv3d);
+ if (rv3d->localvd) {
+ new->localvd = MEM_dupallocN(rv3d->localvd);
+ }
+ if (rv3d->clipbb) {
+ new->clipbb = MEM_dupallocN(rv3d->clipbb);
+ }
+
+ new->depths = NULL;
+ new->render_engine = NULL;
+ new->sms = NULL;
+ new->smooth_timer = NULL;
+
+ return new;
+ }
+ return NULL;
}
static void view3d_main_region_listener(
- wmWindow *UNUSED(win), ScrArea *sa, ARegion *ar,
- wmNotifier *wmn, const Scene *scene)
+ wmWindow *UNUSED(win), ScrArea *sa, ARegion *ar, wmNotifier *wmn, const Scene *scene)
{
- View3D *v3d = sa->spacedata.first;
- RegionView3D *rv3d = ar->regiondata;
- wmGizmoMap *gzmap = ar->gizmo_map;
-
- /* context changes */
- switch (wmn->category) {
- case NC_WM:
- if (ELEM(wmn->data, ND_UNDO)) {
- WM_gizmomap_tag_refresh(gzmap);
- }
- break;
- case NC_ANIMATION:
- switch (wmn->data) {
- case ND_KEYFRAME_PROP:
- case ND_NLA_ACTCHANGE:
- ED_region_tag_redraw(ar);
- break;
- case ND_NLA:
- case ND_KEYFRAME:
- if (ELEM(wmn->action, NA_EDITED, NA_ADDED, NA_REMOVED)) {
- ED_region_tag_redraw(ar);
- }
- break;
- case ND_ANIMCHAN:
- if (ELEM(wmn->action, NA_EDITED, NA_ADDED, NA_REMOVED, NA_SELECTED)) {
- ED_region_tag_redraw(ar);
- }
- break;
- }
- break;
- case NC_SCENE:
- switch (wmn->data) {
- case ND_SCENEBROWSE:
- case ND_LAYER_CONTENT:
- ED_region_tag_redraw(ar);
- WM_gizmomap_tag_refresh(gzmap);
- break;
- case ND_LAYER:
- if (wmn->reference) {
- BKE_screen_view3d_sync(v3d, wmn->reference);
- }
- ED_region_tag_redraw(ar);
- WM_gizmomap_tag_refresh(gzmap);
- break;
- case ND_OB_ACTIVE:
- case ND_OB_SELECT:
- ATTR_FALLTHROUGH;
- case ND_FRAME:
- case ND_TRANSFORM:
- case ND_OB_VISIBLE:
- case ND_RENDER_OPTIONS:
- case ND_MARKERS:
- case ND_MODE:
- ED_region_tag_redraw(ar);
- WM_gizmomap_tag_refresh(gzmap);
- break;
- case ND_WORLD:
- /* handled by space_view3d_listener() for v3d access */
- break;
- case ND_DRAW_RENDER_VIEWPORT:
- {
- if (v3d->camera && (scene == wmn->reference)) {
- if (rv3d->persp == RV3D_CAMOB) {
- ED_region_tag_redraw(ar);
- }
- }
- break;
- }
- }
- if (wmn->action == NA_EDITED) {
- ED_region_tag_redraw(ar);
- }
- break;
- case NC_OBJECT:
- switch (wmn->data) {
- case ND_BONE_ACTIVE:
- case ND_BONE_SELECT:
- case ND_TRANSFORM:
- case ND_POSE:
- case ND_DRAW:
- case ND_MODIFIER:
- case ND_CONSTRAINT:
- case ND_KEYS:
- case ND_PARTICLE:
- case ND_POINTCACHE:
- case ND_LOD:
- ED_region_tag_redraw(ar);
- WM_gizmomap_tag_refresh(gzmap);
- break;
- }
- switch (wmn->action) {
- case NA_ADDED:
- ED_region_tag_redraw(ar);
- break;
- }
- break;
- case NC_GEOM:
- switch (wmn->data) {
- case ND_SELECT:
- {
- WM_gizmomap_tag_refresh(gzmap);
- ATTR_FALLTHROUGH;
- }
- case ND_DATA:
- case ND_VERTEX_GROUP:
- ED_region_tag_redraw(ar);
- break;
- }
- switch (wmn->action) {
- case NA_EDITED:
- ED_region_tag_redraw(ar);
- break;
- }
- break;
- case NC_CAMERA:
- switch (wmn->data) {
- case ND_DRAW_RENDER_VIEWPORT:
- {
- if (v3d->camera && (v3d->camera->data == wmn->reference)) {
- if (rv3d->persp == RV3D_CAMOB) {
- ED_region_tag_redraw(ar);
- }
- }
- break;
- }
- }
- break;
- case NC_GROUP:
- /* all group ops for now */
- ED_region_tag_redraw(ar);
- break;
- case NC_BRUSH:
- switch (wmn->action) {
- case NA_EDITED:
- ED_region_tag_redraw_overlay(ar);
- break;
- case NA_SELECTED:
- /* used on brush changes - needed because 3d cursor
- * has to be drawn if clone brush is selected */
- ED_region_tag_redraw(ar);
- break;
- }
- break;
- case NC_MATERIAL:
- switch (wmn->data) {
- case ND_SHADING:
- case ND_NODES:
- /* TODO(sergey) This is a bit too much updates, but needed to
- * have proper material drivers update in the viewport.
- *
- * How to solve?
- */
- ED_region_tag_redraw(ar);
- break;
- case ND_SHADING_DRAW:
- case ND_SHADING_LINKS:
- ED_region_tag_redraw(ar);
- break;
- }
- break;
- case NC_WORLD:
- switch (wmn->data) {
- case ND_WORLD_DRAW:
- /* handled by space_view3d_listener() for v3d access */
- break;
- case ND_WORLD:
- /* Needed for updating world materials */
- ED_region_tag_redraw(ar);
- break;
- }
- break;
- case NC_LAMP:
- switch (wmn->data) {
- case ND_LIGHTING:
- /* TODO(sergey): This is a bit too much, but needed to
- * handle updates from new depsgraph.
- */
- ED_region_tag_redraw(ar);
- break;
- case ND_LIGHTING_DRAW:
- ED_region_tag_redraw(ar);
- WM_gizmomap_tag_refresh(gzmap);
- break;
- }
- break;
- case NC_LIGHTPROBE:
- ED_area_tag_refresh(sa);
- break;
- case NC_IMAGE:
- /* this could be more fine grained checks if we had
- * more context than just the region */
- ED_region_tag_redraw(ar);
- break;
- case NC_TEXTURE:
- /* same as above */
- ED_region_tag_redraw(ar);
- break;
- case NC_MOVIECLIP:
- if (wmn->data == ND_DISPLAY || wmn->action == NA_EDITED) {
- ED_region_tag_redraw(ar);
- }
- break;
- case NC_SPACE:
- if (wmn->data == ND_SPACE_VIEW3D) {
- if (wmn->subtype == NS_VIEW3D_GPU) {
- rv3d->rflag |= RV3D_GPULIGHT_UPDATE;
- }
- ED_region_tag_redraw(ar);
- WM_gizmomap_tag_refresh(gzmap);
- }
- break;
- case NC_ID:
- if (wmn->action == NA_RENAME) {
- ED_region_tag_redraw(ar);
- }
- break;
- case NC_SCREEN:
- switch (wmn->data) {
- case ND_ANIMPLAY:
- case ND_SKETCH:
- ED_region_tag_redraw(ar);
- break;
- case ND_LAYOUTBROWSE:
- case ND_LAYOUTDELETE:
- case ND_LAYOUTSET:
- WM_gizmomap_tag_refresh(gzmap);
- ED_region_tag_redraw(ar);
- break;
- case ND_LAYER:
- ED_region_tag_redraw(ar);
- break;
- }
-
- break;
- case NC_GPENCIL:
- if (wmn->data == ND_DATA || ELEM(wmn->action, NA_EDITED, NA_SELECTED)) {
- ED_region_tag_redraw(ar);
- }
- break;
- }
+ View3D *v3d = sa->spacedata.first;
+ RegionView3D *rv3d = ar->regiondata;
+ wmGizmoMap *gzmap = ar->gizmo_map;
+
+ /* context changes */
+ switch (wmn->category) {
+ case NC_WM:
+ if (ELEM(wmn->data, ND_UNDO)) {
+ WM_gizmomap_tag_refresh(gzmap);
+ }
+ break;
+ case NC_ANIMATION:
+ switch (wmn->data) {
+ case ND_KEYFRAME_PROP:
+ case ND_NLA_ACTCHANGE:
+ ED_region_tag_redraw(ar);
+ break;
+ case ND_NLA:
+ case ND_KEYFRAME:
+ if (ELEM(wmn->action, NA_EDITED, NA_ADDED, NA_REMOVED)) {
+ ED_region_tag_redraw(ar);
+ }
+ break;
+ case ND_ANIMCHAN:
+ if (ELEM(wmn->action, NA_EDITED, NA_ADDED, NA_REMOVED, NA_SELECTED)) {
+ ED_region_tag_redraw(ar);
+ }
+ break;
+ }
+ break;
+ case NC_SCENE:
+ switch (wmn->data) {
+ case ND_SCENEBROWSE:
+ case ND_LAYER_CONTENT:
+ ED_region_tag_redraw(ar);
+ WM_gizmomap_tag_refresh(gzmap);
+ break;
+ case ND_LAYER:
+ if (wmn->reference) {
+ BKE_screen_view3d_sync(v3d, wmn->reference);
+ }
+ ED_region_tag_redraw(ar);
+ WM_gizmomap_tag_refresh(gzmap);
+ break;
+ case ND_OB_ACTIVE:
+ case ND_OB_SELECT:
+ ATTR_FALLTHROUGH;
+ case ND_FRAME:
+ case ND_TRANSFORM:
+ case ND_OB_VISIBLE:
+ case ND_RENDER_OPTIONS:
+ case ND_MARKERS:
+ case ND_MODE:
+ ED_region_tag_redraw(ar);
+ WM_gizmomap_tag_refresh(gzmap);
+ break;
+ case ND_WORLD:
+ /* handled by space_view3d_listener() for v3d access */
+ break;
+ case ND_DRAW_RENDER_VIEWPORT: {
+ if (v3d->camera && (scene == wmn->reference)) {
+ if (rv3d->persp == RV3D_CAMOB) {
+ ED_region_tag_redraw(ar);
+ }
+ }
+ break;
+ }
+ }
+ if (wmn->action == NA_EDITED) {
+ ED_region_tag_redraw(ar);
+ }
+ break;
+ case NC_OBJECT:
+ switch (wmn->data) {
+ case ND_BONE_ACTIVE:
+ case ND_BONE_SELECT:
+ case ND_TRANSFORM:
+ case ND_POSE:
+ case ND_DRAW:
+ case ND_MODIFIER:
+ case ND_CONSTRAINT:
+ case ND_KEYS:
+ case ND_PARTICLE:
+ case ND_POINTCACHE:
+ case ND_LOD:
+ ED_region_tag_redraw(ar);
+ WM_gizmomap_tag_refresh(gzmap);
+ break;
+ }
+ switch (wmn->action) {
+ case NA_ADDED:
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ break;
+ case NC_GEOM:
+ switch (wmn->data) {
+ case ND_SELECT: {
+ WM_gizmomap_tag_refresh(gzmap);
+ ATTR_FALLTHROUGH;
+ }
+ case ND_DATA:
+ case ND_VERTEX_GROUP:
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ switch (wmn->action) {
+ case NA_EDITED:
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ break;
+ case NC_CAMERA:
+ switch (wmn->data) {
+ case ND_DRAW_RENDER_VIEWPORT: {
+ if (v3d->camera && (v3d->camera->data == wmn->reference)) {
+ if (rv3d->persp == RV3D_CAMOB) {
+ ED_region_tag_redraw(ar);
+ }
+ }
+ break;
+ }
+ }
+ break;
+ case NC_GROUP:
+ /* all group ops for now */
+ ED_region_tag_redraw(ar);
+ break;
+ case NC_BRUSH:
+ switch (wmn->action) {
+ case NA_EDITED:
+ ED_region_tag_redraw_overlay(ar);
+ break;
+ case NA_SELECTED:
+ /* used on brush changes - needed because 3d cursor
+ * has to be drawn if clone brush is selected */
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ break;
+ case NC_MATERIAL:
+ switch (wmn->data) {
+ case ND_SHADING:
+ case ND_NODES:
+ /* TODO(sergey) This is a bit too much updates, but needed to
+ * have proper material drivers update in the viewport.
+ *
+ * How to solve?
+ */
+ ED_region_tag_redraw(ar);
+ break;
+ case ND_SHADING_DRAW:
+ case ND_SHADING_LINKS:
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ break;
+ case NC_WORLD:
+ switch (wmn->data) {
+ case ND_WORLD_DRAW:
+ /* handled by space_view3d_listener() for v3d access */
+ break;
+ case ND_WORLD:
+ /* Needed for updating world materials */
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ break;
+ case NC_LAMP:
+ switch (wmn->data) {
+ case ND_LIGHTING:
+ /* TODO(sergey): This is a bit too much, but needed to
+ * handle updates from new depsgraph.
+ */
+ ED_region_tag_redraw(ar);
+ break;
+ case ND_LIGHTING_DRAW:
+ ED_region_tag_redraw(ar);
+ WM_gizmomap_tag_refresh(gzmap);
+ break;
+ }
+ break;
+ case NC_LIGHTPROBE:
+ ED_area_tag_refresh(sa);
+ break;
+ case NC_IMAGE:
+ /* this could be more fine grained checks if we had
+ * more context than just the region */
+ ED_region_tag_redraw(ar);
+ break;
+ case NC_TEXTURE:
+ /* same as above */
+ ED_region_tag_redraw(ar);
+ break;
+ case NC_MOVIECLIP:
+ if (wmn->data == ND_DISPLAY || wmn->action == NA_EDITED) {
+ ED_region_tag_redraw(ar);
+ }
+ break;
+ case NC_SPACE:
+ if (wmn->data == ND_SPACE_VIEW3D) {
+ if (wmn->subtype == NS_VIEW3D_GPU) {
+ rv3d->rflag |= RV3D_GPULIGHT_UPDATE;
+ }
+ ED_region_tag_redraw(ar);
+ WM_gizmomap_tag_refresh(gzmap);
+ }
+ break;
+ case NC_ID:
+ if (wmn->action == NA_RENAME) {
+ ED_region_tag_redraw(ar);
+ }
+ break;
+ case NC_SCREEN:
+ switch (wmn->data) {
+ case ND_ANIMPLAY:
+ case ND_SKETCH:
+ ED_region_tag_redraw(ar);
+ break;
+ case ND_LAYOUTBROWSE:
+ case ND_LAYOUTDELETE:
+ case ND_LAYOUTSET:
+ WM_gizmomap_tag_refresh(gzmap);
+ ED_region_tag_redraw(ar);
+ break;
+ case ND_LAYER:
+ ED_region_tag_redraw(ar);
+ break;
+ }
+
+ break;
+ case NC_GPENCIL:
+ if (wmn->data == ND_DATA || ELEM(wmn->action, NA_EDITED, NA_SELECTED)) {
+ ED_region_tag_redraw(ar);
+ }
+ break;
+ }
}
-static void view3d_main_region_message_subscribe(
- const struct bContext *C,
- struct WorkSpace *UNUSED(workspace), struct Scene *UNUSED(scene),
- struct bScreen *UNUSED(screen), struct ScrArea *sa, struct ARegion *ar,
- struct wmMsgBus *mbus)
+static void view3d_main_region_message_subscribe(const struct bContext *C,
+ struct WorkSpace *UNUSED(workspace),
+ struct Scene *UNUSED(scene),
+ struct bScreen *UNUSED(screen),
+ struct ScrArea *sa,
+ struct ARegion *ar,
+ struct wmMsgBus *mbus)
{
- /* Developer note: there are many properties that impact 3D view drawing,
- * so instead of subscribing to individual properties, just subscribe to types
- * accepting some redundant redraws.
- *
- * For other space types we might try avoid this, keep the 3D view as an exceptional case! */
- wmMsgParams_RNA msg_key_params = {{{0}}};
-
- /* Only subscribe to types. */
- StructRNA *type_array[] = {
- &RNA_Window,
-
- /* These object have properties that impact drawing. */
- &RNA_AreaLight,
- &RNA_Camera,
- &RNA_Light,
- &RNA_Speaker,
- &RNA_SunLight,
-
- /* General types the 3D view depends on. */
- &RNA_Object,
- &RNA_UnitSettings, /* grid-floor */
-
- &RNA_View3DOverlay,
- &RNA_View3DShading,
- &RNA_World,
- };
-
- wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
- .owner = ar,
- .user_data = ar,
- .notify = ED_region_do_msg_notify_tag_redraw,
- };
-
- for (int i = 0; i < ARRAY_SIZE(type_array); i++) {
- msg_key_params.ptr.type = type_array[i];
- WM_msg_subscribe_rna_params(
- mbus,
- &msg_key_params,
- &msg_sub_value_region_tag_redraw,
- __func__);
- }
-
- /* Subscribe to a handful of other properties. */
- RegionView3D *rv3d = ar->regiondata;
-
- WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, engine, &msg_sub_value_region_tag_redraw);
- WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, resolution_x, &msg_sub_value_region_tag_redraw);
- WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, resolution_y, &msg_sub_value_region_tag_redraw);
- WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, pixel_aspect_x, &msg_sub_value_region_tag_redraw);
- WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, pixel_aspect_y, &msg_sub_value_region_tag_redraw);
- if (rv3d->persp == RV3D_CAMOB) {
- WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, use_border, &msg_sub_value_region_tag_redraw);
- }
-
- WM_msg_subscribe_rna_anon_type(mbus, SceneEEVEE, &msg_sub_value_region_tag_redraw);
- WM_msg_subscribe_rna_anon_type(mbus, SceneDisplay, &msg_sub_value_region_tag_redraw);
- WM_msg_subscribe_rna_anon_type(mbus, ObjectDisplay, &msg_sub_value_region_tag_redraw);
-
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *obact = OBACT(view_layer);
- if (obact != NULL) {
- switch (obact->mode) {
- case OB_MODE_PARTICLE_EDIT:
- WM_msg_subscribe_rna_anon_type(mbus, ParticleEdit, &msg_sub_value_region_tag_redraw);
- break;
- default:
- break;
- }
- }
-
- {
- wmMsgSubscribeValue msg_sub_value_region_tag_refresh = {
- .owner = ar,
- .user_data = sa,
- .notify = WM_toolsystem_do_msg_notify_tag_refresh,
- };
- WM_msg_subscribe_rna_anon_prop(
- mbus, Object, mode,
- &msg_sub_value_region_tag_refresh);
- WM_msg_subscribe_rna_anon_prop(
- mbus, LayerObjects, active,
- &msg_sub_value_region_tag_refresh);
- }
+ /* Developer note: there are many properties that impact 3D view drawing,
+ * so instead of subscribing to individual properties, just subscribe to types
+ * accepting some redundant redraws.
+ *
+ * For other space types we might try avoid this, keep the 3D view as an exceptional case! */
+ wmMsgParams_RNA msg_key_params = {{{0}}};
+
+ /* Only subscribe to types. */
+ StructRNA *type_array[] = {
+ &RNA_Window,
+
+ /* These object have properties that impact drawing. */
+ &RNA_AreaLight,
+ &RNA_Camera,
+ &RNA_Light,
+ &RNA_Speaker,
+ &RNA_SunLight,
+
+ /* General types the 3D view depends on. */
+ &RNA_Object,
+ &RNA_UnitSettings, /* grid-floor */
+
+ &RNA_View3DOverlay,
+ &RNA_View3DShading,
+ &RNA_World,
+ };
+
+ wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
+ .owner = ar,
+ .user_data = ar,
+ .notify = ED_region_do_msg_notify_tag_redraw,
+ };
+
+ for (int i = 0; i < ARRAY_SIZE(type_array); i++) {
+ msg_key_params.ptr.type = type_array[i];
+ WM_msg_subscribe_rna_params(mbus, &msg_key_params, &msg_sub_value_region_tag_redraw, __func__);
+ }
+
+ /* Subscribe to a handful of other properties. */
+ RegionView3D *rv3d = ar->regiondata;
+
+ WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, engine, &msg_sub_value_region_tag_redraw);
+ WM_msg_subscribe_rna_anon_prop(
+ mbus, RenderSettings, resolution_x, &msg_sub_value_region_tag_redraw);
+ WM_msg_subscribe_rna_anon_prop(
+ mbus, RenderSettings, resolution_y, &msg_sub_value_region_tag_redraw);
+ WM_msg_subscribe_rna_anon_prop(
+ mbus, RenderSettings, pixel_aspect_x, &msg_sub_value_region_tag_redraw);
+ WM_msg_subscribe_rna_anon_prop(
+ mbus, RenderSettings, pixel_aspect_y, &msg_sub_value_region_tag_redraw);
+ if (rv3d->persp == RV3D_CAMOB) {
+ WM_msg_subscribe_rna_anon_prop(
+ mbus, RenderSettings, use_border, &msg_sub_value_region_tag_redraw);
+ }
+
+ WM_msg_subscribe_rna_anon_type(mbus, SceneEEVEE, &msg_sub_value_region_tag_redraw);
+ WM_msg_subscribe_rna_anon_type(mbus, SceneDisplay, &msg_sub_value_region_tag_redraw);
+ WM_msg_subscribe_rna_anon_type(mbus, ObjectDisplay, &msg_sub_value_region_tag_redraw);
+
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *obact = OBACT(view_layer);
+ if (obact != NULL) {
+ switch (obact->mode) {
+ case OB_MODE_PARTICLE_EDIT:
+ WM_msg_subscribe_rna_anon_type(mbus, ParticleEdit, &msg_sub_value_region_tag_redraw);
+ break;
+ default:
+ break;
+ }
+ }
+
+ {
+ wmMsgSubscribeValue msg_sub_value_region_tag_refresh = {
+ .owner = ar,
+ .user_data = sa,
+ .notify = WM_toolsystem_do_msg_notify_tag_refresh,
+ };
+ WM_msg_subscribe_rna_anon_prop(mbus, Object, mode, &msg_sub_value_region_tag_refresh);
+ WM_msg_subscribe_rna_anon_prop(mbus, LayerObjects, active, &msg_sub_value_region_tag_refresh);
+ }
}
/* concept is to retrieve cursor type context-less */
static void view3d_main_region_cursor(wmWindow *win, ScrArea *sa, ARegion *ar)
{
- if (WM_cursor_set_from_tool(win, sa, ar)) {
- return;
- }
-
- ViewLayer *view_layer = WM_window_get_active_view_layer(win);
- Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer);
- if (obedit) {
- WM_cursor_set(win, CURSOR_EDIT);
- }
- else {
- WM_cursor_set(win, CURSOR_STD);
- }
+ if (WM_cursor_set_from_tool(win, sa, ar)) {
+ return;
+ }
+
+ ViewLayer *view_layer = WM_window_get_active_view_layer(win);
+ Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer);
+ if (obedit) {
+ WM_cursor_set(win, CURSOR_EDIT);
+ }
+ else {
+ WM_cursor_set(win, CURSOR_STD);
+ }
}
/* add handlers, stuff you only do once or on area/region changes */
static void view3d_header_region_init(wmWindowManager *wm, ARegion *ar)
{
- wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "3D View Generic", SPACE_VIEW3D, 0);
+ wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "3D View Generic", SPACE_VIEW3D, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
- ED_region_header_init(ar);
+ ED_region_header_init(ar);
}
static void view3d_header_region_draw(const bContext *C, ARegion *ar)
{
- ED_region_header(C, ar);
+ ED_region_header(C, ar);
}
-static void view3d_header_region_listener(
- wmWindow *UNUSED(win), ScrArea *UNUSED(sa), ARegion *ar,
- wmNotifier *wmn, const Scene *UNUSED(scene))
+static void view3d_header_region_listener(wmWindow *UNUSED(win),
+ ScrArea *UNUSED(sa),
+ ARegion *ar,
+ wmNotifier *wmn,
+ const Scene *UNUSED(scene))
{
- /* context changes */
- switch (wmn->category) {
- case NC_SCENE:
- switch (wmn->data) {
- case ND_FRAME:
- case ND_OB_ACTIVE:
- case ND_OB_SELECT:
- case ND_OB_VISIBLE:
- case ND_MODE:
- case ND_LAYER:
- case ND_TOOLSETTINGS:
- case ND_LAYER_CONTENT:
- case ND_RENDER_OPTIONS:
- ED_region_tag_redraw(ar);
- break;
- }
- break;
- case NC_SPACE:
- if (wmn->data == ND_SPACE_VIEW3D) {
- ED_region_tag_redraw(ar);
- }
- break;
- case NC_GPENCIL:
- if (wmn->data & ND_GPENCIL_EDITMODE) {
- ED_region_tag_redraw(ar);
- }
- break;
- }
+ /* context changes */
+ switch (wmn->category) {
+ case NC_SCENE:
+ switch (wmn->data) {
+ case ND_FRAME:
+ case ND_OB_ACTIVE:
+ case ND_OB_SELECT:
+ case ND_OB_VISIBLE:
+ case ND_MODE:
+ case ND_LAYER:
+ case ND_TOOLSETTINGS:
+ case ND_LAYER_CONTENT:
+ case ND_RENDER_OPTIONS:
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ break;
+ case NC_SPACE:
+ if (wmn->data == ND_SPACE_VIEW3D) {
+ ED_region_tag_redraw(ar);
+ }
+ break;
+ case NC_GPENCIL:
+ if (wmn->data & ND_GPENCIL_EDITMODE) {
+ ED_region_tag_redraw(ar);
+ }
+ break;
+ }
}
-static void view3d_header_region_message_subscribe(
- const struct bContext *UNUSED(C),
- struct WorkSpace *UNUSED(workspace), struct Scene *UNUSED(scene),
- struct bScreen *UNUSED(screen), struct ScrArea *UNUSED(sa), struct ARegion *ar,
- struct wmMsgBus *mbus)
+static void view3d_header_region_message_subscribe(const struct bContext *UNUSED(C),
+ struct WorkSpace *UNUSED(workspace),
+ struct Scene *UNUSED(scene),
+ struct bScreen *UNUSED(screen),
+ struct ScrArea *UNUSED(sa),
+ struct ARegion *ar,
+ struct wmMsgBus *mbus)
{
- wmMsgParams_RNA msg_key_params = {{{0}}};
-
- /* Only subscribe to types. */
- StructRNA *type_array[] = {
- &RNA_View3DShading,
- };
-
- wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
- .owner = ar,
- .user_data = ar,
- .notify = ED_region_do_msg_notify_tag_redraw,
- };
-
- for (int i = 0; i < ARRAY_SIZE(type_array); i++) {
- msg_key_params.ptr.type = type_array[i];
- WM_msg_subscribe_rna_params(
- mbus,
- &msg_key_params,
- &msg_sub_value_region_tag_redraw,
- __func__);
- }
+ wmMsgParams_RNA msg_key_params = {{{0}}};
+
+ /* Only subscribe to types. */
+ StructRNA *type_array[] = {
+ &RNA_View3DShading,
+ };
+
+ wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
+ .owner = ar,
+ .user_data = ar,
+ .notify = ED_region_do_msg_notify_tag_redraw,
+ };
+
+ for (int i = 0; i < ARRAY_SIZE(type_array); i++) {
+ msg_key_params.ptr.type = type_array[i];
+ WM_msg_subscribe_rna_params(mbus, &msg_key_params, &msg_sub_value_region_tag_redraw, __func__);
+ }
}
-
/* add handlers, stuff you only do once or on area/region changes */
static void view3d_buttons_region_init(wmWindowManager *wm, ARegion *ar)
{
- wmKeyMap *keymap;
+ wmKeyMap *keymap;
- ED_region_panels_init(wm, ar);
+ ED_region_panels_init(wm, ar);
- keymap = WM_keymap_ensure(wm->defaultconf, "3D View Generic", SPACE_VIEW3D, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ keymap = WM_keymap_ensure(wm->defaultconf, "3D View Generic", SPACE_VIEW3D, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
}
static void view3d_buttons_region_draw(const bContext *C, ARegion *ar)
{
- ED_region_panels_ex(C, ar, (const char * []){CTX_data_mode_string(C), NULL}, -1, true);
+ ED_region_panels_ex(C, ar, (const char *[]){CTX_data_mode_string(C), NULL}, -1, true);
}
-static void view3d_buttons_region_listener(
- wmWindow *UNUSED(win), ScrArea *UNUSED(sa), ARegion *ar,
- wmNotifier *wmn, const Scene *UNUSED(scene))
+static void view3d_buttons_region_listener(wmWindow *UNUSED(win),
+ ScrArea *UNUSED(sa),
+ ARegion *ar,
+ wmNotifier *wmn,
+ const Scene *UNUSED(scene))
{
- /* context changes */
- switch (wmn->category) {
- case NC_ANIMATION:
- switch (wmn->data) {
- case ND_KEYFRAME_PROP:
- case ND_NLA_ACTCHANGE:
- ED_region_tag_redraw(ar);
- break;
- case ND_NLA:
- case ND_KEYFRAME:
- if (ELEM(wmn->action, NA_EDITED, NA_ADDED, NA_REMOVED)) {
- ED_region_tag_redraw(ar);
- }
- break;
- }
- break;
- case NC_SCENE:
- switch (wmn->data) {
- case ND_FRAME:
- case ND_OB_ACTIVE:
- case ND_OB_SELECT:
- case ND_OB_VISIBLE:
- case ND_MODE:
- case ND_LAYER:
- case ND_LAYER_CONTENT:
- case ND_TOOLSETTINGS:
- ED_region_tag_redraw(ar);
- break;
- }
- switch (wmn->action) {
- case NA_EDITED:
- ED_region_tag_redraw(ar);
- break;
- }
- break;
- case NC_OBJECT:
- switch (wmn->data) {
- case ND_BONE_ACTIVE:
- case ND_BONE_SELECT:
- case ND_TRANSFORM:
- case ND_POSE:
- case ND_DRAW:
- case ND_KEYS:
- case ND_MODIFIER:
- ED_region_tag_redraw(ar);
- break;
- }
- break;
- case NC_GEOM:
- switch (wmn->data) {
- case ND_DATA:
- case ND_VERTEX_GROUP:
- case ND_SELECT:
- ED_region_tag_redraw(ar);
- break;
- }
- if (wmn->action == NA_EDITED) {
- ED_region_tag_redraw(ar);
- }
- break;
- case NC_TEXTURE:
- case NC_MATERIAL:
- /* for brush textures */
- ED_region_tag_redraw(ar);
- break;
- case NC_BRUSH:
- /* NA_SELECTED is used on brush changes */
- if (ELEM(wmn->action, NA_EDITED, NA_SELECTED)) {
- ED_region_tag_redraw(ar);
- }
- break;
- case NC_SPACE:
- if (wmn->data == ND_SPACE_VIEW3D) {
- ED_region_tag_redraw(ar);
- }
- break;
- case NC_ID:
- if (wmn->action == NA_RENAME) {
- ED_region_tag_redraw(ar);
- }
- break;
- case NC_GPENCIL:
- if ((wmn->data & (ND_DATA | ND_GPENCIL_EDITMODE)) || (wmn->action == NA_EDITED)) {
- ED_region_tag_redraw(ar);
- }
- break;
- case NC_IMAGE:
- /* Update for the image layers in texture paint. */
- if (wmn->action == NA_EDITED) {
- ED_region_tag_redraw(ar);
- }
- break;
- }
+ /* context changes */
+ switch (wmn->category) {
+ case NC_ANIMATION:
+ switch (wmn->data) {
+ case ND_KEYFRAME_PROP:
+ case ND_NLA_ACTCHANGE:
+ ED_region_tag_redraw(ar);
+ break;
+ case ND_NLA:
+ case ND_KEYFRAME:
+ if (ELEM(wmn->action, NA_EDITED, NA_ADDED, NA_REMOVED)) {
+ ED_region_tag_redraw(ar);
+ }
+ break;
+ }
+ break;
+ case NC_SCENE:
+ switch (wmn->data) {
+ case ND_FRAME:
+ case ND_OB_ACTIVE:
+ case ND_OB_SELECT:
+ case ND_OB_VISIBLE:
+ case ND_MODE:
+ case ND_LAYER:
+ case ND_LAYER_CONTENT:
+ case ND_TOOLSETTINGS:
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ switch (wmn->action) {
+ case NA_EDITED:
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ break;
+ case NC_OBJECT:
+ switch (wmn->data) {
+ case ND_BONE_ACTIVE:
+ case ND_BONE_SELECT:
+ case ND_TRANSFORM:
+ case ND_POSE:
+ case ND_DRAW:
+ case ND_KEYS:
+ case ND_MODIFIER:
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ break;
+ case NC_GEOM:
+ switch (wmn->data) {
+ case ND_DATA:
+ case ND_VERTEX_GROUP:
+ case ND_SELECT:
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ if (wmn->action == NA_EDITED) {
+ ED_region_tag_redraw(ar);
+ }
+ break;
+ case NC_TEXTURE:
+ case NC_MATERIAL:
+ /* for brush textures */
+ ED_region_tag_redraw(ar);
+ break;
+ case NC_BRUSH:
+ /* NA_SELECTED is used on brush changes */
+ if (ELEM(wmn->action, NA_EDITED, NA_SELECTED)) {
+ ED_region_tag_redraw(ar);
+ }
+ break;
+ case NC_SPACE:
+ if (wmn->data == ND_SPACE_VIEW3D) {
+ ED_region_tag_redraw(ar);
+ }
+ break;
+ case NC_ID:
+ if (wmn->action == NA_RENAME) {
+ ED_region_tag_redraw(ar);
+ }
+ break;
+ case NC_GPENCIL:
+ if ((wmn->data & (ND_DATA | ND_GPENCIL_EDITMODE)) || (wmn->action == NA_EDITED)) {
+ ED_region_tag_redraw(ar);
+ }
+ break;
+ case NC_IMAGE:
+ /* Update for the image layers in texture paint. */
+ if (wmn->action == NA_EDITED) {
+ ED_region_tag_redraw(ar);
+ }
+ break;
+ }
}
/* add handlers, stuff you only do once or on area/region changes */
static void view3d_tools_region_init(wmWindowManager *wm, ARegion *ar)
{
- wmKeyMap *keymap;
+ wmKeyMap *keymap;
- ED_region_panels_init(wm, ar);
+ ED_region_panels_init(wm, ar);
- keymap = WM_keymap_ensure(wm->defaultconf, "3D View Generic", SPACE_VIEW3D, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ keymap = WM_keymap_ensure(wm->defaultconf, "3D View Generic", SPACE_VIEW3D, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
}
static void view3d_tools_region_draw(const bContext *C, ARegion *ar)
{
- ED_region_panels_ex(C, ar, (const char * []){CTX_data_mode_string(C), NULL}, -1, true);
+ ED_region_panels_ex(C, ar, (const char *[]){CTX_data_mode_string(C), NULL}, -1, true);
}
/* area (not region) level listener */
-static void space_view3d_listener(
- wmWindow *UNUSED(win), ScrArea *sa, struct wmNotifier *wmn, Scene *UNUSED(scene))
+static void space_view3d_listener(wmWindow *UNUSED(win),
+ ScrArea *sa,
+ struct wmNotifier *wmn,
+ Scene *UNUSED(scene))
{
- View3D *v3d = sa->spacedata.first;
-
- /* context changes */
- switch (wmn->category) {
- case NC_SCENE:
- switch (wmn->data) {
- case ND_WORLD:
- if (v3d->flag2 & V3D_HIDE_OVERLAYS) {
- ED_area_tag_redraw_regiontype(sa, RGN_TYPE_WINDOW);
- }
- break;
- }
- break;
- case NC_WORLD:
- switch (wmn->data) {
- case ND_WORLD_DRAW:
- case ND_WORLD:
- if (v3d->shading.background_type == V3D_SHADING_BACKGROUND_WORLD) {
- ED_area_tag_redraw_regiontype(sa, RGN_TYPE_WINDOW);
- }
- break;
- }
- break;
- case NC_MATERIAL:
- switch (wmn->data) {
- case ND_NODES:
- if (v3d->shading.type == OB_TEXTURE) {
- ED_area_tag_redraw_regiontype(sa, RGN_TYPE_WINDOW);
- }
- break;
- }
- break;
- }
+ View3D *v3d = sa->spacedata.first;
+
+ /* context changes */
+ switch (wmn->category) {
+ case NC_SCENE:
+ switch (wmn->data) {
+ case ND_WORLD:
+ if (v3d->flag2 & V3D_HIDE_OVERLAYS) {
+ ED_area_tag_redraw_regiontype(sa, RGN_TYPE_WINDOW);
+ }
+ break;
+ }
+ break;
+ case NC_WORLD:
+ switch (wmn->data) {
+ case ND_WORLD_DRAW:
+ case ND_WORLD:
+ if (v3d->shading.background_type == V3D_SHADING_BACKGROUND_WORLD) {
+ ED_area_tag_redraw_regiontype(sa, RGN_TYPE_WINDOW);
+ }
+ break;
+ }
+ break;
+ case NC_MATERIAL:
+ switch (wmn->data) {
+ case ND_NODES:
+ if (v3d->shading.type == OB_TEXTURE) {
+ ED_area_tag_redraw_regiontype(sa, RGN_TYPE_WINDOW);
+ }
+ break;
+ }
+ break;
+ }
}
static void space_view3d_refresh(const bContext *C, ScrArea *UNUSED(sa))
{
- Scene *scene = CTX_data_scene(C);
- LightCache *lcache = scene->eevee.light_cache;
+ Scene *scene = CTX_data_scene(C);
+ LightCache *lcache = scene->eevee.light_cache;
- if (lcache && (lcache->flag & LIGHTCACHE_UPDATE_AUTO) != 0) {
- lcache->flag &= ~LIGHTCACHE_UPDATE_AUTO;
- view3d_lightcache_update((bContext *)C);
- }
+ if (lcache && (lcache->flag & LIGHTCACHE_UPDATE_AUTO) != 0) {
+ lcache->flag &= ~LIGHTCACHE_UPDATE_AUTO;
+ view3d_lightcache_update((bContext *)C);
+ }
}
const char *view3d_context_dir[] = {
- "active_base", "active_object", NULL,
+ "active_base",
+ "active_object",
+ NULL,
};
static int view3d_context(const bContext *C, const char *member, bContextDataResult *result)
{
- /* fallback to the scene layer,
- * allows duplicate and other object operators to run outside the 3d view */
-
- if (CTX_data_dir(member)) {
- CTX_data_dir_set(result, view3d_context_dir);
- }
- else if (CTX_data_equals(member, "active_base")) {
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- if (view_layer->basact) {
- Object *ob = view_layer->basact->object;
- /* if hidden but in edit mode, we still display, can happen with animation */
- if ((view_layer->basact->flag & BASE_VISIBLE) != 0 || (ob->mode & OB_MODE_EDIT)) {
- CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, view_layer->basact);
- }
- }
-
- return 1;
- }
- else if (CTX_data_equals(member, "active_object")) {
- ViewLayer *view_layer = CTX_data_view_layer(C);
- if (view_layer->basact) {
- Object *ob = view_layer->basact->object;
- /* if hidden but in edit mode, we still display, can happen with animation */
- if ((view_layer->basact->flag & BASE_VISIBLE) != 0 || (ob->mode & OB_MODE_EDIT) != 0) {
- CTX_data_id_pointer_set(result, &ob->id);
- }
- }
-
- return 1;
- }
- else {
- return 0; /* not found */
- }
-
- return -1; /* found but not available */
+ /* fallback to the scene layer,
+ * allows duplicate and other object operators to run outside the 3d view */
+
+ if (CTX_data_dir(member)) {
+ CTX_data_dir_set(result, view3d_context_dir);
+ }
+ else if (CTX_data_equals(member, "active_base")) {
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ if (view_layer->basact) {
+ Object *ob = view_layer->basact->object;
+ /* if hidden but in edit mode, we still display, can happen with animation */
+ if ((view_layer->basact->flag & BASE_VISIBLE) != 0 || (ob->mode & OB_MODE_EDIT)) {
+ CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, view_layer->basact);
+ }
+ }
+
+ return 1;
+ }
+ else if (CTX_data_equals(member, "active_object")) {
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ if (view_layer->basact) {
+ Object *ob = view_layer->basact->object;
+ /* if hidden but in edit mode, we still display, can happen with animation */
+ if ((view_layer->basact->flag & BASE_VISIBLE) != 0 || (ob->mode & OB_MODE_EDIT) != 0) {
+ CTX_data_id_pointer_set(result, &ob->id);
+ }
+ }
+
+ return 1;
+ }
+ else {
+ return 0; /* not found */
+ }
+
+ return -1; /* found but not available */
}
static void view3d_id_remap(ScrArea *sa, SpaceLink *slink, ID *old_id, ID *new_id)
{
- View3D *v3d;
- ARegion *ar;
- bool is_local = false;
-
- if (!ELEM(GS(old_id->name), ID_OB, ID_MA, ID_IM, ID_MC)) {
- return;
- }
-
- for (v3d = (View3D *)slink; v3d; v3d = v3d->localvd, is_local = true) {
- if ((ID *)v3d->camera == old_id) {
- v3d->camera = (Object *)new_id;
- if (!new_id) {
- /* 3D view might be inactive, in that case needs to use slink->regionbase */
- ListBase *regionbase = (slink == sa->spacedata.first) ? &sa->regionbase : &slink->regionbase;
- for (ar = regionbase->first; ar; ar = ar->next) {
- if (ar->regiontype == RGN_TYPE_WINDOW) {
- RegionView3D *rv3d = is_local ? ((RegionView3D *)ar->regiondata)->localvd : ar->regiondata;
- if (rv3d && (rv3d->persp == RV3D_CAMOB)) {
- rv3d->persp = RV3D_PERSP;
- }
- }
- }
- }
- }
-
- /* Values in local-view aren't used, see: T52663 */
- if (is_local == false) {
- if ((ID *)v3d->ob_centre == old_id) {
- v3d->ob_centre = (Object *)new_id;
- /* Otherwise, bonename may remain valid...
- * We could be smart and check this, too? */
- if (new_id == NULL) {
- v3d->ob_centre_bone[0] = '\0';
- }
- }
- }
-
- if (is_local) {
- break;
- }
- }
+ View3D *v3d;
+ ARegion *ar;
+ bool is_local = false;
+
+ if (!ELEM(GS(old_id->name), ID_OB, ID_MA, ID_IM, ID_MC)) {
+ return;
+ }
+
+ for (v3d = (View3D *)slink; v3d; v3d = v3d->localvd, is_local = true) {
+ if ((ID *)v3d->camera == old_id) {
+ v3d->camera = (Object *)new_id;
+ if (!new_id) {
+ /* 3D view might be inactive, in that case needs to use slink->regionbase */
+ ListBase *regionbase = (slink == sa->spacedata.first) ? &sa->regionbase :
+ &slink->regionbase;
+ for (ar = regionbase->first; ar; ar = ar->next) {
+ if (ar->regiontype == RGN_TYPE_WINDOW) {
+ RegionView3D *rv3d = is_local ? ((RegionView3D *)ar->regiondata)->localvd :
+ ar->regiondata;
+ if (rv3d && (rv3d->persp == RV3D_CAMOB)) {
+ rv3d->persp = RV3D_PERSP;
+ }
+ }
+ }
+ }
+ }
+
+ /* Values in local-view aren't used, see: T52663 */
+ if (is_local == false) {
+ if ((ID *)v3d->ob_centre == old_id) {
+ v3d->ob_centre = (Object *)new_id;
+ /* Otherwise, bonename may remain valid...
+ * We could be smart and check this, too? */
+ if (new_id == NULL) {
+ v3d->ob_centre_bone[0] = '\0';
+ }
+ }
+ }
+
+ if (is_local) {
+ break;
+ }
+ }
}
/* only called once, from space/spacetypes.c */
void ED_spacetype_view3d(void)
{
- SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype view3d");
- ARegionType *art;
-
- st->spaceid = SPACE_VIEW3D;
- strncpy(st->name, "View3D", BKE_ST_MAXNAME);
-
- st->new = view3d_new;
- st->free = view3d_free;
- st->init = view3d_init;
- st->listener = space_view3d_listener;
- st->refresh = space_view3d_refresh;
- st->duplicate = view3d_duplicate;
- st->operatortypes = view3d_operatortypes;
- st->keymap = view3d_keymap;
- st->dropboxes = view3d_dropboxes;
- st->gizmos = view3d_widgets;
- st->context = view3d_context;
- st->id_remap = view3d_id_remap;
-
- /* regions: main window */
- art = MEM_callocN(sizeof(ARegionType), "spacetype view3d main region");
- art->regionid = RGN_TYPE_WINDOW;
- art->keymapflag = ED_KEYMAP_GIZMO | ED_KEYMAP_TOOL | ED_KEYMAP_GPENCIL;
- art->draw = view3d_main_region_draw;
- art->init = view3d_main_region_init;
- art->exit = view3d_main_region_exit;
- art->free = view3d_main_region_free;
- art->duplicate = view3d_main_region_duplicate;
- art->listener = view3d_main_region_listener;
- art->message_subscribe = view3d_main_region_message_subscribe;
- art->cursor = view3d_main_region_cursor;
- art->lock = 1; /* can become flag, see BKE_spacedata_draw_locks */
- BLI_addhead(&st->regiontypes, art);
-
- /* regions: listview/buttons */
- art = MEM_callocN(sizeof(ARegionType), "spacetype view3d buttons region");
- art->regionid = RGN_TYPE_UI;
- art->prefsizex = 180; /* XXX */
- art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES;
- art->listener = view3d_buttons_region_listener;
- art->init = view3d_buttons_region_init;
- art->draw = view3d_buttons_region_draw;
- BLI_addhead(&st->regiontypes, art);
-
- view3d_buttons_register(art);
-
- /* regions: tool(bar) */
- art = MEM_callocN(sizeof(ARegionType), "spacetype view3d tools region");
- art->regionid = RGN_TYPE_TOOLS;
- art->prefsizex = 58; /* XXX */
- art->prefsizey = 50; /* XXX */
- art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES;
- art->listener = view3d_buttons_region_listener;
- art->message_subscribe = ED_region_generic_tools_region_message_subscribe;
- art->snap_size = ED_region_generic_tools_region_snap_size;
- art->init = view3d_tools_region_init;
- art->draw = view3d_tools_region_draw;
- BLI_addhead(&st->regiontypes, art);
-
- /* regions: header */
- art = MEM_callocN(sizeof(ARegionType), "spacetype view3d header region");
- art->regionid = RGN_TYPE_HEADER;
- art->prefsizey = HEADERY;
- art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | ED_KEYMAP_HEADER;
- art->listener = view3d_header_region_listener;
- art->init = view3d_header_region_init;
- art->draw = view3d_header_region_draw;
- art->message_subscribe = view3d_header_region_message_subscribe;
- BLI_addhead(&st->regiontypes, art);
-
- /* regions: hud */
- art = ED_area_type_hud(st->spaceid);
- BLI_addhead(&st->regiontypes, art);
-
- BKE_spacetype_register(st);
+ SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype view3d");
+ ARegionType *art;
+
+ st->spaceid = SPACE_VIEW3D;
+ strncpy(st->name, "View3D", BKE_ST_MAXNAME);
+
+ st->new = view3d_new;
+ st->free = view3d_free;
+ st->init = view3d_init;
+ st->listener = space_view3d_listener;
+ st->refresh = space_view3d_refresh;
+ st->duplicate = view3d_duplicate;
+ st->operatortypes = view3d_operatortypes;
+ st->keymap = view3d_keymap;
+ st->dropboxes = view3d_dropboxes;
+ st->gizmos = view3d_widgets;
+ st->context = view3d_context;
+ st->id_remap = view3d_id_remap;
+
+ /* regions: main window */
+ art = MEM_callocN(sizeof(ARegionType), "spacetype view3d main region");
+ art->regionid = RGN_TYPE_WINDOW;
+ art->keymapflag = ED_KEYMAP_GIZMO | ED_KEYMAP_TOOL | ED_KEYMAP_GPENCIL;
+ art->draw = view3d_main_region_draw;
+ art->init = view3d_main_region_init;
+ art->exit = view3d_main_region_exit;
+ art->free = view3d_main_region_free;
+ art->duplicate = view3d_main_region_duplicate;
+ art->listener = view3d_main_region_listener;
+ art->message_subscribe = view3d_main_region_message_subscribe;
+ art->cursor = view3d_main_region_cursor;
+ art->lock = 1; /* can become flag, see BKE_spacedata_draw_locks */
+ BLI_addhead(&st->regiontypes, art);
+
+ /* regions: listview/buttons */
+ art = MEM_callocN(sizeof(ARegionType), "spacetype view3d buttons region");
+ art->regionid = RGN_TYPE_UI;
+ art->prefsizex = 180; /* XXX */
+ art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES;
+ art->listener = view3d_buttons_region_listener;
+ art->init = view3d_buttons_region_init;
+ art->draw = view3d_buttons_region_draw;
+ BLI_addhead(&st->regiontypes, art);
+
+ view3d_buttons_register(art);
+
+ /* regions: tool(bar) */
+ art = MEM_callocN(sizeof(ARegionType), "spacetype view3d tools region");
+ art->regionid = RGN_TYPE_TOOLS;
+ art->prefsizex = 58; /* XXX */
+ art->prefsizey = 50; /* XXX */
+ art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES;
+ art->listener = view3d_buttons_region_listener;
+ art->message_subscribe = ED_region_generic_tools_region_message_subscribe;
+ art->snap_size = ED_region_generic_tools_region_snap_size;
+ art->init = view3d_tools_region_init;
+ art->draw = view3d_tools_region_draw;
+ BLI_addhead(&st->regiontypes, art);
+
+ /* regions: header */
+ art = MEM_callocN(sizeof(ARegionType), "spacetype view3d header region");
+ art->regionid = RGN_TYPE_HEADER;
+ art->prefsizey = HEADERY;
+ art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | ED_KEYMAP_HEADER;
+ art->listener = view3d_header_region_listener;
+ art->init = view3d_header_region_init;
+ art->draw = view3d_header_region_draw;
+ art->message_subscribe = view3d_header_region_message_subscribe;
+ BLI_addhead(&st->regiontypes, art);
+
+ /* regions: hud */
+ art = ED_area_type_hud(st->spaceid);
+ BLI_addhead(&st->regiontypes, art);
+
+ BKE_spacetype_register(st);
}
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index ca30e3d3b01..abe36b1d563 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -21,7 +21,6 @@
* \ingroup spview3d
*/
-
#include <string.h>
#include <stdio.h>
#include <math.h>
@@ -70,49 +69,47 @@
#include "UI_interface.h"
#include "UI_resources.h"
-#include "view3d_intern.h" /* own include */
-
+#include "view3d_intern.h" /* own include */
/* ******************* view3d space & buttons ************** */
enum {
- B_REDR = 2,
- B_TRANSFORM_PANEL_MEDIAN = 1008,
- B_TRANSFORM_PANEL_DIMS = 1009,
+ B_REDR = 2,
+ B_TRANSFORM_PANEL_MEDIAN = 1008,
+ B_TRANSFORM_PANEL_DIMS = 1009,
};
/* All must start w/ location */
typedef struct {
- float location[3];
+ float location[3];
} TransformMedian_Generic;
typedef struct {
- float location[3], bv_weight, be_weight, skin[2], crease;
+ float location[3], bv_weight, be_weight, skin[2], crease;
} TransformMedian_Mesh;
typedef struct {
- float location[3], weight, b_weight, radius, tilt;
+ float location[3], weight, b_weight, radius, tilt;
} TransformMedian_Curve;
typedef struct {
- float location[3], weight;
+ float location[3], weight;
} TransformMedian_Lattice;
-
typedef union {
- TransformMedian_Generic generic;
- TransformMedian_Mesh mesh;
- TransformMedian_Curve curve;
- TransformMedian_Lattice lattice;
+ TransformMedian_Generic generic;
+ TransformMedian_Mesh mesh;
+ TransformMedian_Curve curve;
+ TransformMedian_Lattice lattice;
} TransformMedian;
/* temporary struct for storing transform properties */
typedef struct {
- float ob_dims_orig[3];
- float ob_dims[3];
- /* Floats only (treated as an array). */
- TransformMedian ve_median, median;
+ float ob_dims_orig[3];
+ float ob_dims[3];
+ /* Floats only (treated as an array). */
+ TransformMedian ve_median, median;
} TransformProperties;
#define TRANSFORM_MEDIAN_ARRAY_LEN (sizeof(TransformMedian) / sizeof(float))
@@ -124,30 +121,30 @@ typedef struct {
*/
static float compute_scale_factor(const float ve_median, const float median)
{
- if (ve_median <= 0.0f) {
- return 0.0f;
- }
- else if (ve_median >= 1.0f) {
- return 1.0f;
- }
- else {
- /* Scale value to target median. */
- float median_new = ve_median;
- float median_orig = ve_median - median; /* Previous median value. */
-
- /* In case of floating point error. */
- CLAMP(median_orig, 0.0f, 1.0f);
- CLAMP(median_new, 0.0f, 1.0f);
-
- if (median_new <= median_orig) {
- /* Scale down. */
- return median_new / median_orig;
- }
- else {
- /* Scale up, negative to indicate it... */
- return -(1.0f - median_new) / (1.0f - median_orig);
- }
- }
+ if (ve_median <= 0.0f) {
+ return 0.0f;
+ }
+ else if (ve_median >= 1.0f) {
+ return 1.0f;
+ }
+ else {
+ /* Scale value to target median. */
+ float median_new = ve_median;
+ float median_orig = ve_median - median; /* Previous median value. */
+
+ /* In case of floating point error. */
+ CLAMP(median_orig, 0.0f, 1.0f);
+ CLAMP(median_new, 0.0f, 1.0f);
+
+ if (median_new <= median_orig) {
+ /* Scale down. */
+ return median_new / median_orig;
+ }
+ else {
+ /* Scale up, negative to indicate it... */
+ return -(1.0f - median_new) / (1.0f - median_orig);
+ }
+ }
}
/* Apply helpers.
@@ -156,1167 +153,1531 @@ static float compute_scale_factor(const float ve_median, const float median)
*/
static void apply_raw_diff(float *val, const int tot, const float ve_median, const float median)
{
- *val = (tot == 1) ? ve_median : (*val + median);
+ *val = (tot == 1) ? ve_median : (*val + median);
}
-static void apply_raw_diff_v3(float val[3], const int tot, const float ve_median[3], const float median[3])
+static void apply_raw_diff_v3(float val[3],
+ const int tot,
+ const float ve_median[3],
+ const float median[3])
{
- if (tot == 1) {
- copy_v3_v3(val, ve_median);
- }
- else {
- add_v3_v3(val, median);
- }
+ if (tot == 1) {
+ copy_v3_v3(val, ve_median);
+ }
+ else {
+ add_v3_v3(val, median);
+ }
}
-static void apply_scale_factor(float *val, const int tot, const float ve_median, const float median, const float sca)
+static void apply_scale_factor(
+ float *val, const int tot, const float ve_median, const float median, const float sca)
{
- if (tot == 1 || ve_median == median) {
- *val = ve_median;
- }
- else {
- *val *= sca;
- }
+ if (tot == 1 || ve_median == median) {
+ *val = ve_median;
+ }
+ else {
+ *val *= sca;
+ }
}
-static void apply_scale_factor_clamp(float *val, const int tot, const float ve_median, const float sca)
+static void apply_scale_factor_clamp(float *val,
+ const int tot,
+ const float ve_median,
+ const float sca)
{
- if (tot == 1) {
- *val = ve_median;
- CLAMP(*val, 0.0f, 1.0f);
- }
- else if (ELEM(sca, 0.0f, 1.0f)) {
- *val = sca;
- }
- else {
- *val = (sca > 0.0f) ? (*val * sca) : (1.0f + ((1.0f - *val) * sca));
- CLAMP(*val, 0.0f, 1.0f);
- }
+ if (tot == 1) {
+ *val = ve_median;
+ CLAMP(*val, 0.0f, 1.0f);
+ }
+ else if (ELEM(sca, 0.0f, 1.0f)) {
+ *val = sca;
+ }
+ else {
+ *val = (sca > 0.0f) ? (*val * sca) : (1.0f + ((1.0f - *val) * sca));
+ CLAMP(*val, 0.0f, 1.0f);
+ }
}
static TransformProperties *v3d_transform_props_ensure(View3D *v3d)
{
- if (v3d->runtime.properties_storage == NULL) {
- v3d->runtime.properties_storage = MEM_callocN(sizeof(TransformProperties), "TransformProperties");
- }
- return v3d->runtime.properties_storage;
+ if (v3d->runtime.properties_storage == NULL) {
+ v3d->runtime.properties_storage = MEM_callocN(sizeof(TransformProperties),
+ "TransformProperties");
+ }
+ return v3d->runtime.properties_storage;
}
/* is used for both read and write... */
static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float lim)
{
- uiBlock *block = (layout) ? uiLayoutAbsoluteBlock(layout) : NULL;
- TransformProperties *tfp = v3d_transform_props_ensure(v3d);
- TransformMedian median_basis, ve_median_basis;
- int tot, totedgedata, totcurvedata, totlattdata, totcurvebweight;
- bool has_meshdata = false;
- bool has_skinradius = false;
- PointerRNA data_ptr;
-
- copy_vn_fl((float *)&median_basis, TRANSFORM_MEDIAN_ARRAY_LEN, 0.0f);
- tot = totedgedata = totcurvedata = totlattdata = totcurvebweight = 0;
-
- if (ob->type == OB_MESH) {
- TransformMedian_Mesh *median = &median_basis.mesh;
- Mesh *me = ob->data;
- BMEditMesh *em = me->edit_mesh;
- BMesh *bm = em->bm;
- BMVert *eve;
- BMEdge *eed;
- BMIter iter;
-
- const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
- const int cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN);
- const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
- const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
-
- has_skinradius = (cd_vert_skin_offset != -1);
-
- if (bm->totvertsel) {
- BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
- if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- tot++;
- add_v3_v3(median->location, eve->co);
-
- if (cd_vert_bweight_offset != -1) {
- median->bv_weight += BM_ELEM_CD_GET_FLOAT(eve, cd_vert_bweight_offset);
- }
-
- if (has_skinradius) {
- MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset);
- add_v2_v2(median->skin, vs->radius); /* Third val not used currently. */
- }
- }
- }
- }
-
- if ((cd_edge_bweight_offset != -1) || (cd_edge_crease_offset != -1)) {
- if (bm->totedgesel) {
- BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
- if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
- if (cd_edge_bweight_offset != -1) {
- median->be_weight += BM_ELEM_CD_GET_FLOAT(eed, cd_edge_bweight_offset);
- }
-
- if (cd_edge_crease_offset != -1) {
- median->crease += BM_ELEM_CD_GET_FLOAT(eed, cd_edge_crease_offset);
- }
-
- totedgedata++;
- }
- }
- }
- }
- else {
- totedgedata = bm->totedgesel;
- }
-
- has_meshdata = (tot || totedgedata);
- }
- else if (ob->type == OB_CURVE || ob->type == OB_SURF) {
- TransformMedian_Curve *median = &median_basis.curve;
- Curve *cu = ob->data;
- Nurb *nu;
- BPoint *bp;
- BezTriple *bezt;
- int a;
- ListBase *nurbs = BKE_curve_editNurbs_get(cu);
- StructRNA *seltype = NULL;
- void *selp = NULL;
-
- nu = nurbs->first;
- while (nu) {
- if (nu->type == CU_BEZIER) {
- bezt = nu->bezt;
- a = nu->pntsu;
- while (a--) {
- if (bezt->f2 & SELECT) {
- add_v3_v3(median->location, bezt->vec[1]);
- tot++;
- median->weight += bezt->weight;
- median->radius += bezt->radius;
- median->tilt += bezt->tilt;
- if (!totcurvedata) { /* I.e. first time... */
- selp = bezt;
- seltype = &RNA_BezierSplinePoint;
- }
- totcurvedata++;
- }
- else {
- if (bezt->f1 & SELECT) {
- add_v3_v3(median->location, bezt->vec[0]);
- tot++;
- }
- if (bezt->f3 & SELECT) {
- add_v3_v3(median->location, bezt->vec[2]);
- tot++;
- }
- }
- bezt++;
- }
- }
- else {
- bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
- while (a--) {
- if (bp->f1 & SELECT) {
- add_v3_v3(median->location, bp->vec);
- median->b_weight += bp->vec[3];
- totcurvebweight++;
- tot++;
- median->weight += bp->weight;
- median->radius += bp->radius;
- median->tilt += bp->tilt;
- if (!totcurvedata) { /* I.e. first time... */
- selp = bp;
- seltype = &RNA_SplinePoint;
- }
- totcurvedata++;
- }
- bp++;
- }
- }
- nu = nu->next;
- }
-
- if (totcurvedata == 1) {
- RNA_pointer_create(&cu->id, seltype, selp, &data_ptr);
- }
- }
- else if (ob->type == OB_LATTICE) {
- Lattice *lt = ob->data;
- TransformMedian_Lattice *median = &median_basis.lattice;
- BPoint *bp;
- int a;
- StructRNA *seltype = NULL;
- void *selp = NULL;
-
- a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw;
- bp = lt->editlatt->latt->def;
- while (a--) {
- if (bp->f1 & SELECT) {
- add_v3_v3(median->location, bp->vec);
- tot++;
- median->weight += bp->weight;
- if (!totlattdata) { /* I.e. first time... */
- selp = bp;
- seltype = &RNA_LatticePoint;
- }
- totlattdata++;
- }
- bp++;
- }
-
- if (totlattdata == 1) {
- RNA_pointer_create(&lt->id, seltype, selp, &data_ptr);
- }
- }
-
- if (tot == 0) {
- uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_("Nothing selected"), 0, 130, 200, 20, NULL, 0, 0, 0, 0, "");
- return;
- }
-
- /* Location, X/Y/Z */
- mul_v3_fl(median_basis.generic.location, 1.0f / (float)tot);
- if (v3d->flag & V3D_GLOBAL_STATS) {
- mul_m4_v3(ob->obmat, median_basis.generic.location);
- }
-
- if (has_meshdata) {
- TransformMedian_Mesh *median = &median_basis.mesh;
- if (totedgedata) {
- median->crease /= (float)totedgedata;
- median->be_weight /= (float)totedgedata;
- }
- if (tot) {
- median->bv_weight /= (float)tot;
- if (has_skinradius) {
- median->skin[0] /= (float)tot;
- median->skin[1] /= (float)tot;
- }
- }
- }
- else if (totcurvedata) {
- TransformMedian_Curve *median = &median_basis.curve;
- if (totcurvebweight) {
- median->b_weight /= (float)totcurvebweight;
- }
- median->weight /= (float)totcurvedata;
- median->radius /= (float)totcurvedata;
- median->tilt /= (float)totcurvedata;
- }
- else if (totlattdata) {
- TransformMedian_Lattice *median = &median_basis.lattice;
- median->weight /= (float)totlattdata;
- }
-
- if (block) { /* buttons */
- uiBut *but;
- int yi = 200;
- const float tilt_limit = DEG2RADF(21600.0f);
- const int butw = 200;
- const int buth = 20 * UI_DPI_FAC;
- const int but_margin = 2;
- const char *c;
-
- memcpy(&tfp->ve_median, &median_basis, sizeof(tfp->ve_median));
-
- UI_block_align_begin(block);
- if (tot == 1) {
- if (totcurvedata) {
- /* Curve */
- c = IFACE_("Control Point:");
- }
- else {
- /* Mesh or lattice */
- c = IFACE_("Vertex:");
- }
- }
- else {
- c = IFACE_("Median:");
- }
- uiDefBut(block, UI_BTYPE_LABEL, 0, c, 0, yi -= buth, butw, buth, NULL, 0, 0, 0, 0, "");
-
- UI_block_align_begin(block);
-
- /* Should be no need to translate these. */
- but = uiDefButF(block, UI_BTYPE_NUM, B_TRANSFORM_PANEL_MEDIAN, IFACE_("X:"), 0, yi -= buth, butw, buth,
- &tfp->ve_median.generic.location[0], -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, "");
- UI_but_unit_type_set(but, PROP_UNIT_LENGTH);
- but = uiDefButF(block, UI_BTYPE_NUM, B_TRANSFORM_PANEL_MEDIAN, IFACE_("Y:"), 0, yi -= buth, butw, buth,
- &tfp->ve_median.generic.location[1], -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, "");
- UI_but_unit_type_set(but, PROP_UNIT_LENGTH);
- but = uiDefButF(block, UI_BTYPE_NUM, B_TRANSFORM_PANEL_MEDIAN, IFACE_("Z:"), 0, yi -= buth, butw, buth,
- &tfp->ve_median.generic.location[2], -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, "");
- UI_but_unit_type_set(but, PROP_UNIT_LENGTH);
-
- if (totcurvebweight == tot) {
- uiDefButF(block, UI_BTYPE_NUM, B_TRANSFORM_PANEL_MEDIAN, IFACE_("W:"), 0, yi -= buth, butw, buth,
- &(tfp->ve_median.curve.b_weight), 0.01, 100.0, 1, 3, "");
- }
-
- UI_block_align_begin(block);
- uiDefButBitS(block, UI_BTYPE_TOGGLE, V3D_GLOBAL_STATS, B_REDR, IFACE_("Global"),
- 0, yi -= buth + but_margin, 100, buth,
- &v3d->flag, 0, 0, 0, 0, TIP_("Displays global values"));
- uiDefButBitS(block, UI_BTYPE_TOGGLE_N, V3D_GLOBAL_STATS, B_REDR, IFACE_("Local"),
- 100, yi, 100, buth,
- &v3d->flag, 0, 0, 0, 0, TIP_("Displays local values"));
- UI_block_align_end(block);
-
- /* Meshes... */
- if (has_meshdata) {
- TransformMedian_Mesh *ve_median = &tfp->ve_median.mesh;
- if (tot) {
- uiDefBut(block, UI_BTYPE_LABEL, 0, tot == 1 ? IFACE_("Vertex Data:") : IFACE_("Vertices Data:"),
- 0, yi -= buth + but_margin, butw, buth, NULL, 0.0, 0.0, 0, 0, "");
- /* customdata layer added on demand */
- uiDefButF(block, UI_BTYPE_NUM, B_TRANSFORM_PANEL_MEDIAN,
- tot == 1 ? IFACE_("Bevel Weight:") : IFACE_("Mean Bevel Weight:"),
- 0, yi -= buth + but_margin, butw, buth,
- &ve_median->bv_weight, 0.0, 1.0, 1, 2, TIP_("Vertex weight used by Bevel modifier"));
- }
- if (has_skinradius) {
- UI_block_align_begin(block);
- uiDefButF(block, UI_BTYPE_NUM, B_TRANSFORM_PANEL_MEDIAN,
- tot == 1 ? IFACE_("Radius X:") : IFACE_("Mean Radius X:"),
- 0, yi -= buth + but_margin, butw, buth,
- &ve_median->skin[0], 0.0, 100.0, 1, 3, TIP_("X radius used by Skin modifier"));
- uiDefButF(block, UI_BTYPE_NUM, B_TRANSFORM_PANEL_MEDIAN,
- tot == 1 ? IFACE_("Radius Y:") : IFACE_("Mean Radius Y:"),
- 0, yi -= buth + but_margin, butw, buth,
- &ve_median->skin[1], 0.0, 100.0, 1, 3, TIP_("Y radius used by Skin modifier"));
- UI_block_align_end(block);
- }
- if (totedgedata) {
- uiDefBut(block, UI_BTYPE_LABEL, 0, totedgedata == 1 ? IFACE_("Edge Data:") : IFACE_("Edges Data:"),
- 0, yi -= buth + but_margin, butw, buth, NULL, 0.0, 0.0, 0, 0, "");
- /* customdata layer added on demand */
- uiDefButF(block, UI_BTYPE_NUM, B_TRANSFORM_PANEL_MEDIAN,
- totedgedata == 1 ? IFACE_("Bevel Weight:") : IFACE_("Mean Bevel Weight:"),
- 0, yi -= buth + but_margin, butw, buth,
- &ve_median->be_weight, 0.0, 1.0, 1, 2, TIP_("Edge weight used by Bevel modifier"));
- /* customdata layer added on demand */
- uiDefButF(block, UI_BTYPE_NUM, B_TRANSFORM_PANEL_MEDIAN,
- totedgedata == 1 ? IFACE_("Crease:") : IFACE_("Mean Crease:"),
- 0, yi -= buth + but_margin, butw, buth,
- &ve_median->crease, 0.0, 1.0, 1, 2, TIP_("Weight used by the Subdivision Surface modifier"));
- }
- }
- /* Curve... */
- else if (totcurvedata) {
- TransformMedian_Curve *ve_median = &tfp->ve_median.curve;
- if (totcurvedata == 1) {
- uiDefButR(block, UI_BTYPE_NUM, 0, IFACE_("Weight:"), 0, yi -= buth + but_margin, butw, buth,
- &data_ptr, "weight_softbody", 0, 0.0, 1.0, 1, 3, NULL);
- uiDefButR(block, UI_BTYPE_NUM, 0, IFACE_("Radius:"), 0, yi -= buth + but_margin, butw, buth,
- &data_ptr, "radius", 0, 0.0, 100.0, 1, 3, NULL);
- uiDefButR(block, UI_BTYPE_NUM, 0, IFACE_("Tilt:"), 0, yi -= buth + but_margin, butw, buth,
- &data_ptr, "tilt", 0, -tilt_limit, tilt_limit, 1, 3, NULL);
- }
- else if (totcurvedata > 1) {
- uiDefButF(block, UI_BTYPE_NUM, B_TRANSFORM_PANEL_MEDIAN, IFACE_("Mean Weight:"),
- 0, yi -= buth + but_margin, butw, buth,
- &ve_median->weight, 0.0, 1.0, 1, 3, TIP_("Weight used for Soft Body Goal"));
- uiDefButF(block, UI_BTYPE_NUM, B_TRANSFORM_PANEL_MEDIAN, IFACE_("Mean Radius:"),
- 0, yi -= buth + but_margin, butw, buth,
- &ve_median->radius, 0.0, 100.0, 1, 3, TIP_("Radius of curve control points"));
- but = uiDefButF(block, UI_BTYPE_NUM, B_TRANSFORM_PANEL_MEDIAN, IFACE_("Mean Tilt:"),
- 0, yi -= buth + but_margin, butw, buth,
- &ve_median->tilt, -tilt_limit, tilt_limit, 1, 3,
- TIP_("Tilt of curve control points"));
- UI_but_unit_type_set(but, PROP_UNIT_ROTATION);
- }
- }
- /* Lattice... */
- else if (totlattdata) {
- TransformMedian_Lattice *ve_median = &tfp->ve_median.lattice;
- if (totlattdata == 1) {
- uiDefButR(block, UI_BTYPE_NUM, 0, IFACE_("Weight:"), 0, yi -= buth + but_margin, butw, buth,
- &data_ptr, "weight_softbody", 0, 0.0, 1.0, 1, 3, NULL);
- }
- else if (totlattdata > 1) {
- uiDefButF(block, UI_BTYPE_NUM, B_TRANSFORM_PANEL_MEDIAN, IFACE_("Mean Weight:"),
- 0, yi -= buth + but_margin, butw, buth,
- &ve_median->weight, 0.0, 1.0, 1, 3, TIP_("Weight used for Soft Body Goal"));
- }
- }
-
- UI_block_align_end(block);
- }
- else { /* apply */
- memcpy(&ve_median_basis, &tfp->ve_median, sizeof(tfp->ve_median));
-
- if (v3d->flag & V3D_GLOBAL_STATS) {
- invert_m4_m4(ob->imat, ob->obmat);
- mul_m4_v3(ob->imat, median_basis.generic.location);
- mul_m4_v3(ob->imat, ve_median_basis.generic.location);
- }
- sub_vn_vnvn(
- (float *)&median_basis,
- (float *)&ve_median_basis,
- (float *)&median_basis,
- TRANSFORM_MEDIAN_ARRAY_LEN);
-
- /* Note with a single element selected, we always do. */
- const bool apply_vcos = (tot == 1) || (len_squared_v3(median_basis.generic.location) != 0.0f);
-
- if ((ob->type == OB_MESH) &&
- (apply_vcos || median_basis.mesh.bv_weight || median_basis.mesh.skin[0] || median_basis.mesh.skin[1] ||
- median_basis.mesh.be_weight || median_basis.mesh.crease))
- {
- const TransformMedian_Mesh *median = &median_basis.mesh, *ve_median = &ve_median_basis.mesh;
- Mesh *me = ob->data;
- BMEditMesh *em = me->edit_mesh;
- BMesh *bm = em->bm;
- BMIter iter;
- BMVert *eve;
- BMEdge *eed;
-
- int cd_vert_bweight_offset = -1;
- int cd_vert_skin_offset = -1;
- int cd_edge_bweight_offset = -1;
- int cd_edge_crease_offset = -1;
-
- float scale_bv_weight = 1.0f;
- float scale_skin[2] = {1.0f, 1.0f};
- float scale_be_weight = 1.0f;
- float scale_crease = 1.0f;
-
- /* Vertices */
-
- if (apply_vcos || median->bv_weight || median->skin[0] || median->skin[1]) {
- if (median->bv_weight) {
- BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_VERT_BWEIGHT);
- cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
- BLI_assert(cd_vert_bweight_offset != -1);
-
- scale_bv_weight = compute_scale_factor(ve_median->bv_weight, median->bv_weight);
- }
-
- for (int i = 0; i < 2; i++) {
- if (median->skin[i]) {
- cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN);
- BLI_assert(cd_vert_skin_offset != -1);
-
- if (ve_median->skin[i] != median->skin[i]) {
- scale_skin[i] = ve_median->skin[i] / (ve_median->skin[i] - median->skin[i]);
- }
- }
- }
-
- BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
- if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- if (apply_vcos) {
- apply_raw_diff_v3(eve->co, tot, ve_median->location, median->location);
- }
-
- if (cd_vert_bweight_offset != -1) {
- float *b_weight = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_bweight_offset);
- apply_scale_factor_clamp(b_weight, tot, ve_median->bv_weight, scale_bv_weight);
- }
-
- if (cd_vert_skin_offset != -1) {
- MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset);
-
- /* That one is not clamped to [0.0, 1.0]. */
- for (int i = 0; i < 2; i++) {
- if (median->skin[i] != 0.0f) {
- apply_scale_factor(
- &vs->radius[i], tot, ve_median->skin[i], median->skin[i],
- scale_skin[i]);
- }
- }
- }
- }
- }
- }
-
- if (apply_vcos) {
- EDBM_mesh_normals_update(em);
- }
-
- /* Edges */
-
- if (median->be_weight || median->crease) {
- if (median->be_weight) {
- BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_EDGE_BWEIGHT);
- cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
- BLI_assert(cd_edge_bweight_offset != -1);
-
- scale_be_weight = compute_scale_factor(ve_median->be_weight, median->be_weight);
- }
-
- if (median->crease) {
- BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_EDGE_CREASE);
- cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
- BLI_assert(cd_edge_crease_offset != -1);
-
- scale_crease = compute_scale_factor(ve_median->crease, median->crease);
- }
-
- BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
- if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
- if (median->be_weight != 0.0f) {
- float *b_weight = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_bweight_offset);
- apply_scale_factor_clamp(b_weight, tot, ve_median->be_weight, scale_be_weight);
- }
-
- if (median->crease != 0.0f) {
- float *crease = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_crease_offset);
- apply_scale_factor_clamp(crease, tot, ve_median->crease, scale_crease);
- }
- }
- }
- }
- }
- else if (ELEM(ob->type, OB_CURVE, OB_SURF) &&
- (apply_vcos ||
- median_basis.curve.b_weight ||
- median_basis.curve.weight ||
- median_basis.curve.radius ||
- median_basis.curve.tilt))
- {
- const TransformMedian_Curve *median = &median_basis.curve, *ve_median = &ve_median_basis.curve;
- Curve *cu = ob->data;
- Nurb *nu;
- BPoint *bp;
- BezTriple *bezt;
- int a;
- ListBase *nurbs = BKE_curve_editNurbs_get(cu);
- const float scale_w = compute_scale_factor(ve_median->weight, median->weight);
-
- nu = nurbs->first;
- while (nu) {
- if (nu->type == CU_BEZIER) {
- for (a = nu->pntsu, bezt = nu->bezt; a--; bezt++) {
- if (bezt->f2 & SELECT) {
- if (apply_vcos) {
- /* Here we always have to use the diff... :/
- * Cannot avoid some glitches when going e.g. from 3 to 0.0001 (see T37327),
- * unless we use doubles.
- */
- add_v3_v3(bezt->vec[0], median->location);
- add_v3_v3(bezt->vec[1], median->location);
- add_v3_v3(bezt->vec[2], median->location);
- }
- if (median->weight) {
- apply_scale_factor_clamp(&bezt->weight, tot, ve_median->weight, scale_w);
- }
- if (median->radius) {
- apply_raw_diff(&bezt->radius, tot, ve_median->radius, median->radius);
- }
- if (median->tilt) {
- apply_raw_diff(&bezt->tilt, tot, ve_median->tilt, median->tilt);
- }
- }
- else if (apply_vcos) {
- /* Handles can only have their coordinates changed here. */
- if (bezt->f1 & SELECT) {
- apply_raw_diff_v3(bezt->vec[0], tot, ve_median->location, median->location);
- }
- if (bezt->f3 & SELECT) {
- apply_raw_diff_v3(bezt->vec[2], tot, ve_median->location, median->location);
- }
- }
- }
- }
- else {
- for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a--; bp++) {
- if (bp->f1 & SELECT) {
- if (apply_vcos) {
- apply_raw_diff_v3(bp->vec, tot, ve_median->location, median->location);
- }
- if (median->b_weight) {
- apply_raw_diff(&bp->vec[3], tot, ve_median->b_weight, median->b_weight);
- }
- if (median->weight) {
- apply_scale_factor_clamp(&bp->weight, tot, ve_median->weight, scale_w);
- }
- if (median->radius) {
- apply_raw_diff(&bp->radius, tot, ve_median->radius, median->radius);
- }
- if (median->tilt) {
- apply_raw_diff(&bp->tilt, tot, ve_median->tilt, median->tilt);
- }
- }
- }
- }
- BKE_nurb_test_2d(nu);
- BKE_nurb_handles_test(nu, true); /* test for bezier too */
-
- nu = nu->next;
- }
- }
- else if ((ob->type == OB_LATTICE) &&
- (apply_vcos || median_basis.lattice.weight))
- {
- const TransformMedian_Lattice *median = &median_basis.lattice, *ve_median = &ve_median_basis.lattice;
- Lattice *lt = ob->data;
- BPoint *bp;
- int a;
- const float scale_w = compute_scale_factor(ve_median->weight, median->weight);
-
- a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw;
- bp = lt->editlatt->latt->def;
- while (a--) {
- if (bp->f1 & SELECT) {
- if (apply_vcos) {
- apply_raw_diff_v3(bp->vec, tot, ve_median->location, median->location);
- }
- if (median->weight) {
- apply_scale_factor_clamp(&bp->weight, tot, ve_median->weight, scale_w);
- }
- }
- bp++;
- }
- }
-
-/* ED_undo_push(C, "Transform properties"); */
- }
+ uiBlock *block = (layout) ? uiLayoutAbsoluteBlock(layout) : NULL;
+ TransformProperties *tfp = v3d_transform_props_ensure(v3d);
+ TransformMedian median_basis, ve_median_basis;
+ int tot, totedgedata, totcurvedata, totlattdata, totcurvebweight;
+ bool has_meshdata = false;
+ bool has_skinradius = false;
+ PointerRNA data_ptr;
+
+ copy_vn_fl((float *)&median_basis, TRANSFORM_MEDIAN_ARRAY_LEN, 0.0f);
+ tot = totedgedata = totcurvedata = totlattdata = totcurvebweight = 0;
+
+ if (ob->type == OB_MESH) {
+ TransformMedian_Mesh *median = &median_basis.mesh;
+ Mesh *me = ob->data;
+ BMEditMesh *em = me->edit_mesh;
+ BMesh *bm = em->bm;
+ BMVert *eve;
+ BMEdge *eed;
+ BMIter iter;
+
+ const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
+ const int cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN);
+ const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
+ const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
+
+ has_skinradius = (cd_vert_skin_offset != -1);
+
+ if (bm->totvertsel) {
+ BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+ if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+ tot++;
+ add_v3_v3(median->location, eve->co);
+
+ if (cd_vert_bweight_offset != -1) {
+ median->bv_weight += BM_ELEM_CD_GET_FLOAT(eve, cd_vert_bweight_offset);
+ }
+
+ if (has_skinradius) {
+ MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset);
+ add_v2_v2(median->skin, vs->radius); /* Third val not used currently. */
+ }
+ }
+ }
+ }
+
+ if ((cd_edge_bweight_offset != -1) || (cd_edge_crease_offset != -1)) {
+ if (bm->totedgesel) {
+ BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
+ if (cd_edge_bweight_offset != -1) {
+ median->be_weight += BM_ELEM_CD_GET_FLOAT(eed, cd_edge_bweight_offset);
+ }
+
+ if (cd_edge_crease_offset != -1) {
+ median->crease += BM_ELEM_CD_GET_FLOAT(eed, cd_edge_crease_offset);
+ }
+
+ totedgedata++;
+ }
+ }
+ }
+ }
+ else {
+ totedgedata = bm->totedgesel;
+ }
+
+ has_meshdata = (tot || totedgedata);
+ }
+ else if (ob->type == OB_CURVE || ob->type == OB_SURF) {
+ TransformMedian_Curve *median = &median_basis.curve;
+ Curve *cu = ob->data;
+ Nurb *nu;
+ BPoint *bp;
+ BezTriple *bezt;
+ int a;
+ ListBase *nurbs = BKE_curve_editNurbs_get(cu);
+ StructRNA *seltype = NULL;
+ void *selp = NULL;
+
+ nu = nurbs->first;
+ while (nu) {
+ if (nu->type == CU_BEZIER) {
+ bezt = nu->bezt;
+ a = nu->pntsu;
+ while (a--) {
+ if (bezt->f2 & SELECT) {
+ add_v3_v3(median->location, bezt->vec[1]);
+ tot++;
+ median->weight += bezt->weight;
+ median->radius += bezt->radius;
+ median->tilt += bezt->tilt;
+ if (!totcurvedata) { /* I.e. first time... */
+ selp = bezt;
+ seltype = &RNA_BezierSplinePoint;
+ }
+ totcurvedata++;
+ }
+ else {
+ if (bezt->f1 & SELECT) {
+ add_v3_v3(median->location, bezt->vec[0]);
+ tot++;
+ }
+ if (bezt->f3 & SELECT) {
+ add_v3_v3(median->location, bezt->vec[2]);
+ tot++;
+ }
+ }
+ bezt++;
+ }
+ }
+ else {
+ bp = nu->bp;
+ a = nu->pntsu * nu->pntsv;
+ while (a--) {
+ if (bp->f1 & SELECT) {
+ add_v3_v3(median->location, bp->vec);
+ median->b_weight += bp->vec[3];
+ totcurvebweight++;
+ tot++;
+ median->weight += bp->weight;
+ median->radius += bp->radius;
+ median->tilt += bp->tilt;
+ if (!totcurvedata) { /* I.e. first time... */
+ selp = bp;
+ seltype = &RNA_SplinePoint;
+ }
+ totcurvedata++;
+ }
+ bp++;
+ }
+ }
+ nu = nu->next;
+ }
+
+ if (totcurvedata == 1) {
+ RNA_pointer_create(&cu->id, seltype, selp, &data_ptr);
+ }
+ }
+ else if (ob->type == OB_LATTICE) {
+ Lattice *lt = ob->data;
+ TransformMedian_Lattice *median = &median_basis.lattice;
+ BPoint *bp;
+ int a;
+ StructRNA *seltype = NULL;
+ void *selp = NULL;
+
+ a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw;
+ bp = lt->editlatt->latt->def;
+ while (a--) {
+ if (bp->f1 & SELECT) {
+ add_v3_v3(median->location, bp->vec);
+ tot++;
+ median->weight += bp->weight;
+ if (!totlattdata) { /* I.e. first time... */
+ selp = bp;
+ seltype = &RNA_LatticePoint;
+ }
+ totlattdata++;
+ }
+ bp++;
+ }
+
+ if (totlattdata == 1) {
+ RNA_pointer_create(&lt->id, seltype, selp, &data_ptr);
+ }
+ }
+
+ if (tot == 0) {
+ uiDefBut(block,
+ UI_BTYPE_LABEL,
+ 0,
+ IFACE_("Nothing selected"),
+ 0,
+ 130,
+ 200,
+ 20,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ "");
+ return;
+ }
+
+ /* Location, X/Y/Z */
+ mul_v3_fl(median_basis.generic.location, 1.0f / (float)tot);
+ if (v3d->flag & V3D_GLOBAL_STATS) {
+ mul_m4_v3(ob->obmat, median_basis.generic.location);
+ }
+
+ if (has_meshdata) {
+ TransformMedian_Mesh *median = &median_basis.mesh;
+ if (totedgedata) {
+ median->crease /= (float)totedgedata;
+ median->be_weight /= (float)totedgedata;
+ }
+ if (tot) {
+ median->bv_weight /= (float)tot;
+ if (has_skinradius) {
+ median->skin[0] /= (float)tot;
+ median->skin[1] /= (float)tot;
+ }
+ }
+ }
+ else if (totcurvedata) {
+ TransformMedian_Curve *median = &median_basis.curve;
+ if (totcurvebweight) {
+ median->b_weight /= (float)totcurvebweight;
+ }
+ median->weight /= (float)totcurvedata;
+ median->radius /= (float)totcurvedata;
+ median->tilt /= (float)totcurvedata;
+ }
+ else if (totlattdata) {
+ TransformMedian_Lattice *median = &median_basis.lattice;
+ median->weight /= (float)totlattdata;
+ }
+
+ if (block) { /* buttons */
+ uiBut *but;
+ int yi = 200;
+ const float tilt_limit = DEG2RADF(21600.0f);
+ const int butw = 200;
+ const int buth = 20 * UI_DPI_FAC;
+ const int but_margin = 2;
+ const char *c;
+
+ memcpy(&tfp->ve_median, &median_basis, sizeof(tfp->ve_median));
+
+ UI_block_align_begin(block);
+ if (tot == 1) {
+ if (totcurvedata) {
+ /* Curve */
+ c = IFACE_("Control Point:");
+ }
+ else {
+ /* Mesh or lattice */
+ c = IFACE_("Vertex:");
+ }
+ }
+ else {
+ c = IFACE_("Median:");
+ }
+ uiDefBut(block, UI_BTYPE_LABEL, 0, c, 0, yi -= buth, butw, buth, NULL, 0, 0, 0, 0, "");
+
+ UI_block_align_begin(block);
+
+ /* Should be no need to translate these. */
+ but = uiDefButF(block,
+ UI_BTYPE_NUM,
+ B_TRANSFORM_PANEL_MEDIAN,
+ IFACE_("X:"),
+ 0,
+ yi -= buth,
+ butw,
+ buth,
+ &tfp->ve_median.generic.location[0],
+ -lim,
+ lim,
+ 10,
+ RNA_TRANSLATION_PREC_DEFAULT,
+ "");
+ UI_but_unit_type_set(but, PROP_UNIT_LENGTH);
+ but = uiDefButF(block,
+ UI_BTYPE_NUM,
+ B_TRANSFORM_PANEL_MEDIAN,
+ IFACE_("Y:"),
+ 0,
+ yi -= buth,
+ butw,
+ buth,
+ &tfp->ve_median.generic.location[1],
+ -lim,
+ lim,
+ 10,
+ RNA_TRANSLATION_PREC_DEFAULT,
+ "");
+ UI_but_unit_type_set(but, PROP_UNIT_LENGTH);
+ but = uiDefButF(block,
+ UI_BTYPE_NUM,
+ B_TRANSFORM_PANEL_MEDIAN,
+ IFACE_("Z:"),
+ 0,
+ yi -= buth,
+ butw,
+ buth,
+ &tfp->ve_median.generic.location[2],
+ -lim,
+ lim,
+ 10,
+ RNA_TRANSLATION_PREC_DEFAULT,
+ "");
+ UI_but_unit_type_set(but, PROP_UNIT_LENGTH);
+
+ if (totcurvebweight == tot) {
+ uiDefButF(block,
+ UI_BTYPE_NUM,
+ B_TRANSFORM_PANEL_MEDIAN,
+ IFACE_("W:"),
+ 0,
+ yi -= buth,
+ butw,
+ buth,
+ &(tfp->ve_median.curve.b_weight),
+ 0.01,
+ 100.0,
+ 1,
+ 3,
+ "");
+ }
+
+ UI_block_align_begin(block);
+ uiDefButBitS(block,
+ UI_BTYPE_TOGGLE,
+ V3D_GLOBAL_STATS,
+ B_REDR,
+ IFACE_("Global"),
+ 0,
+ yi -= buth + but_margin,
+ 100,
+ buth,
+ &v3d->flag,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Displays global values"));
+ uiDefButBitS(block,
+ UI_BTYPE_TOGGLE_N,
+ V3D_GLOBAL_STATS,
+ B_REDR,
+ IFACE_("Local"),
+ 100,
+ yi,
+ 100,
+ buth,
+ &v3d->flag,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Displays local values"));
+ UI_block_align_end(block);
+
+ /* Meshes... */
+ if (has_meshdata) {
+ TransformMedian_Mesh *ve_median = &tfp->ve_median.mesh;
+ if (tot) {
+ uiDefBut(block,
+ UI_BTYPE_LABEL,
+ 0,
+ tot == 1 ? IFACE_("Vertex Data:") : IFACE_("Vertices Data:"),
+ 0,
+ yi -= buth + but_margin,
+ butw,
+ buth,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ "");
+ /* customdata layer added on demand */
+ uiDefButF(block,
+ UI_BTYPE_NUM,
+ B_TRANSFORM_PANEL_MEDIAN,
+ tot == 1 ? IFACE_("Bevel Weight:") : IFACE_("Mean Bevel Weight:"),
+ 0,
+ yi -= buth + but_margin,
+ butw,
+ buth,
+ &ve_median->bv_weight,
+ 0.0,
+ 1.0,
+ 1,
+ 2,
+ TIP_("Vertex weight used by Bevel modifier"));
+ }
+ if (has_skinradius) {
+ UI_block_align_begin(block);
+ uiDefButF(block,
+ UI_BTYPE_NUM,
+ B_TRANSFORM_PANEL_MEDIAN,
+ tot == 1 ? IFACE_("Radius X:") : IFACE_("Mean Radius X:"),
+ 0,
+ yi -= buth + but_margin,
+ butw,
+ buth,
+ &ve_median->skin[0],
+ 0.0,
+ 100.0,
+ 1,
+ 3,
+ TIP_("X radius used by Skin modifier"));
+ uiDefButF(block,
+ UI_BTYPE_NUM,
+ B_TRANSFORM_PANEL_MEDIAN,
+ tot == 1 ? IFACE_("Radius Y:") : IFACE_("Mean Radius Y:"),
+ 0,
+ yi -= buth + but_margin,
+ butw,
+ buth,
+ &ve_median->skin[1],
+ 0.0,
+ 100.0,
+ 1,
+ 3,
+ TIP_("Y radius used by Skin modifier"));
+ UI_block_align_end(block);
+ }
+ if (totedgedata) {
+ uiDefBut(block,
+ UI_BTYPE_LABEL,
+ 0,
+ totedgedata == 1 ? IFACE_("Edge Data:") : IFACE_("Edges Data:"),
+ 0,
+ yi -= buth + but_margin,
+ butw,
+ buth,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ "");
+ /* customdata layer added on demand */
+ uiDefButF(block,
+ UI_BTYPE_NUM,
+ B_TRANSFORM_PANEL_MEDIAN,
+ totedgedata == 1 ? IFACE_("Bevel Weight:") : IFACE_("Mean Bevel Weight:"),
+ 0,
+ yi -= buth + but_margin,
+ butw,
+ buth,
+ &ve_median->be_weight,
+ 0.0,
+ 1.0,
+ 1,
+ 2,
+ TIP_("Edge weight used by Bevel modifier"));
+ /* customdata layer added on demand */
+ uiDefButF(block,
+ UI_BTYPE_NUM,
+ B_TRANSFORM_PANEL_MEDIAN,
+ totedgedata == 1 ? IFACE_("Crease:") : IFACE_("Mean Crease:"),
+ 0,
+ yi -= buth + but_margin,
+ butw,
+ buth,
+ &ve_median->crease,
+ 0.0,
+ 1.0,
+ 1,
+ 2,
+ TIP_("Weight used by the Subdivision Surface modifier"));
+ }
+ }
+ /* Curve... */
+ else if (totcurvedata) {
+ TransformMedian_Curve *ve_median = &tfp->ve_median.curve;
+ if (totcurvedata == 1) {
+ uiDefButR(block,
+ UI_BTYPE_NUM,
+ 0,
+ IFACE_("Weight:"),
+ 0,
+ yi -= buth + but_margin,
+ butw,
+ buth,
+ &data_ptr,
+ "weight_softbody",
+ 0,
+ 0.0,
+ 1.0,
+ 1,
+ 3,
+ NULL);
+ uiDefButR(block,
+ UI_BTYPE_NUM,
+ 0,
+ IFACE_("Radius:"),
+ 0,
+ yi -= buth + but_margin,
+ butw,
+ buth,
+ &data_ptr,
+ "radius",
+ 0,
+ 0.0,
+ 100.0,
+ 1,
+ 3,
+ NULL);
+ uiDefButR(block,
+ UI_BTYPE_NUM,
+ 0,
+ IFACE_("Tilt:"),
+ 0,
+ yi -= buth + but_margin,
+ butw,
+ buth,
+ &data_ptr,
+ "tilt",
+ 0,
+ -tilt_limit,
+ tilt_limit,
+ 1,
+ 3,
+ NULL);
+ }
+ else if (totcurvedata > 1) {
+ uiDefButF(block,
+ UI_BTYPE_NUM,
+ B_TRANSFORM_PANEL_MEDIAN,
+ IFACE_("Mean Weight:"),
+ 0,
+ yi -= buth + but_margin,
+ butw,
+ buth,
+ &ve_median->weight,
+ 0.0,
+ 1.0,
+ 1,
+ 3,
+ TIP_("Weight used for Soft Body Goal"));
+ uiDefButF(block,
+ UI_BTYPE_NUM,
+ B_TRANSFORM_PANEL_MEDIAN,
+ IFACE_("Mean Radius:"),
+ 0,
+ yi -= buth + but_margin,
+ butw,
+ buth,
+ &ve_median->radius,
+ 0.0,
+ 100.0,
+ 1,
+ 3,
+ TIP_("Radius of curve control points"));
+ but = uiDefButF(block,
+ UI_BTYPE_NUM,
+ B_TRANSFORM_PANEL_MEDIAN,
+ IFACE_("Mean Tilt:"),
+ 0,
+ yi -= buth + but_margin,
+ butw,
+ buth,
+ &ve_median->tilt,
+ -tilt_limit,
+ tilt_limit,
+ 1,
+ 3,
+ TIP_("Tilt of curve control points"));
+ UI_but_unit_type_set(but, PROP_UNIT_ROTATION);
+ }
+ }
+ /* Lattice... */
+ else if (totlattdata) {
+ TransformMedian_Lattice *ve_median = &tfp->ve_median.lattice;
+ if (totlattdata == 1) {
+ uiDefButR(block,
+ UI_BTYPE_NUM,
+ 0,
+ IFACE_("Weight:"),
+ 0,
+ yi -= buth + but_margin,
+ butw,
+ buth,
+ &data_ptr,
+ "weight_softbody",
+ 0,
+ 0.0,
+ 1.0,
+ 1,
+ 3,
+ NULL);
+ }
+ else if (totlattdata > 1) {
+ uiDefButF(block,
+ UI_BTYPE_NUM,
+ B_TRANSFORM_PANEL_MEDIAN,
+ IFACE_("Mean Weight:"),
+ 0,
+ yi -= buth + but_margin,
+ butw,
+ buth,
+ &ve_median->weight,
+ 0.0,
+ 1.0,
+ 1,
+ 3,
+ TIP_("Weight used for Soft Body Goal"));
+ }
+ }
+
+ UI_block_align_end(block);
+ }
+ else { /* apply */
+ memcpy(&ve_median_basis, &tfp->ve_median, sizeof(tfp->ve_median));
+
+ if (v3d->flag & V3D_GLOBAL_STATS) {
+ invert_m4_m4(ob->imat, ob->obmat);
+ mul_m4_v3(ob->imat, median_basis.generic.location);
+ mul_m4_v3(ob->imat, ve_median_basis.generic.location);
+ }
+ sub_vn_vnvn((float *)&median_basis,
+ (float *)&ve_median_basis,
+ (float *)&median_basis,
+ TRANSFORM_MEDIAN_ARRAY_LEN);
+
+ /* Note with a single element selected, we always do. */
+ const bool apply_vcos = (tot == 1) || (len_squared_v3(median_basis.generic.location) != 0.0f);
+
+ if ((ob->type == OB_MESH) &&
+ (apply_vcos || median_basis.mesh.bv_weight || median_basis.mesh.skin[0] ||
+ median_basis.mesh.skin[1] || median_basis.mesh.be_weight || median_basis.mesh.crease)) {
+ const TransformMedian_Mesh *median = &median_basis.mesh, *ve_median = &ve_median_basis.mesh;
+ Mesh *me = ob->data;
+ BMEditMesh *em = me->edit_mesh;
+ BMesh *bm = em->bm;
+ BMIter iter;
+ BMVert *eve;
+ BMEdge *eed;
+
+ int cd_vert_bweight_offset = -1;
+ int cd_vert_skin_offset = -1;
+ int cd_edge_bweight_offset = -1;
+ int cd_edge_crease_offset = -1;
+
+ float scale_bv_weight = 1.0f;
+ float scale_skin[2] = {1.0f, 1.0f};
+ float scale_be_weight = 1.0f;
+ float scale_crease = 1.0f;
+
+ /* Vertices */
+
+ if (apply_vcos || median->bv_weight || median->skin[0] || median->skin[1]) {
+ if (median->bv_weight) {
+ BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_VERT_BWEIGHT);
+ cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
+ BLI_assert(cd_vert_bweight_offset != -1);
+
+ scale_bv_weight = compute_scale_factor(ve_median->bv_weight, median->bv_weight);
+ }
+
+ for (int i = 0; i < 2; i++) {
+ if (median->skin[i]) {
+ cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN);
+ BLI_assert(cd_vert_skin_offset != -1);
+
+ if (ve_median->skin[i] != median->skin[i]) {
+ scale_skin[i] = ve_median->skin[i] / (ve_median->skin[i] - median->skin[i]);
+ }
+ }
+ }
+
+ BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+ if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+ if (apply_vcos) {
+ apply_raw_diff_v3(eve->co, tot, ve_median->location, median->location);
+ }
+
+ if (cd_vert_bweight_offset != -1) {
+ float *b_weight = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_bweight_offset);
+ apply_scale_factor_clamp(b_weight, tot, ve_median->bv_weight, scale_bv_weight);
+ }
+
+ if (cd_vert_skin_offset != -1) {
+ MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset);
+
+ /* That one is not clamped to [0.0, 1.0]. */
+ for (int i = 0; i < 2; i++) {
+ if (median->skin[i] != 0.0f) {
+ apply_scale_factor(
+ &vs->radius[i], tot, ve_median->skin[i], median->skin[i], scale_skin[i]);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (apply_vcos) {
+ EDBM_mesh_normals_update(em);
+ }
+
+ /* Edges */
+
+ if (median->be_weight || median->crease) {
+ if (median->be_weight) {
+ BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_EDGE_BWEIGHT);
+ cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
+ BLI_assert(cd_edge_bweight_offset != -1);
+
+ scale_be_weight = compute_scale_factor(ve_median->be_weight, median->be_weight);
+ }
+
+ if (median->crease) {
+ BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_EDGE_CREASE);
+ cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
+ BLI_assert(cd_edge_crease_offset != -1);
+
+ scale_crease = compute_scale_factor(ve_median->crease, median->crease);
+ }
+
+ BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
+ if (median->be_weight != 0.0f) {
+ float *b_weight = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_bweight_offset);
+ apply_scale_factor_clamp(b_weight, tot, ve_median->be_weight, scale_be_weight);
+ }
+
+ if (median->crease != 0.0f) {
+ float *crease = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_crease_offset);
+ apply_scale_factor_clamp(crease, tot, ve_median->crease, scale_crease);
+ }
+ }
+ }
+ }
+ }
+ else if (ELEM(ob->type, OB_CURVE, OB_SURF) &&
+ (apply_vcos || median_basis.curve.b_weight || median_basis.curve.weight ||
+ median_basis.curve.radius || median_basis.curve.tilt)) {
+ const TransformMedian_Curve *median = &median_basis.curve,
+ *ve_median = &ve_median_basis.curve;
+ Curve *cu = ob->data;
+ Nurb *nu;
+ BPoint *bp;
+ BezTriple *bezt;
+ int a;
+ ListBase *nurbs = BKE_curve_editNurbs_get(cu);
+ const float scale_w = compute_scale_factor(ve_median->weight, median->weight);
+
+ nu = nurbs->first;
+ while (nu) {
+ if (nu->type == CU_BEZIER) {
+ for (a = nu->pntsu, bezt = nu->bezt; a--; bezt++) {
+ if (bezt->f2 & SELECT) {
+ if (apply_vcos) {
+ /* Here we always have to use the diff... :/
+ * Cannot avoid some glitches when going e.g. from 3 to 0.0001 (see T37327),
+ * unless we use doubles.
+ */
+ add_v3_v3(bezt->vec[0], median->location);
+ add_v3_v3(bezt->vec[1], median->location);
+ add_v3_v3(bezt->vec[2], median->location);
+ }
+ if (median->weight) {
+ apply_scale_factor_clamp(&bezt->weight, tot, ve_median->weight, scale_w);
+ }
+ if (median->radius) {
+ apply_raw_diff(&bezt->radius, tot, ve_median->radius, median->radius);
+ }
+ if (median->tilt) {
+ apply_raw_diff(&bezt->tilt, tot, ve_median->tilt, median->tilt);
+ }
+ }
+ else if (apply_vcos) {
+ /* Handles can only have their coordinates changed here. */
+ if (bezt->f1 & SELECT) {
+ apply_raw_diff_v3(bezt->vec[0], tot, ve_median->location, median->location);
+ }
+ if (bezt->f3 & SELECT) {
+ apply_raw_diff_v3(bezt->vec[2], tot, ve_median->location, median->location);
+ }
+ }
+ }
+ }
+ else {
+ for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a--; bp++) {
+ if (bp->f1 & SELECT) {
+ if (apply_vcos) {
+ apply_raw_diff_v3(bp->vec, tot, ve_median->location, median->location);
+ }
+ if (median->b_weight) {
+ apply_raw_diff(&bp->vec[3], tot, ve_median->b_weight, median->b_weight);
+ }
+ if (median->weight) {
+ apply_scale_factor_clamp(&bp->weight, tot, ve_median->weight, scale_w);
+ }
+ if (median->radius) {
+ apply_raw_diff(&bp->radius, tot, ve_median->radius, median->radius);
+ }
+ if (median->tilt) {
+ apply_raw_diff(&bp->tilt, tot, ve_median->tilt, median->tilt);
+ }
+ }
+ }
+ }
+ BKE_nurb_test_2d(nu);
+ BKE_nurb_handles_test(nu, true); /* test for bezier too */
+
+ nu = nu->next;
+ }
+ }
+ else if ((ob->type == OB_LATTICE) && (apply_vcos || median_basis.lattice.weight)) {
+ const TransformMedian_Lattice *median = &median_basis.lattice,
+ *ve_median = &ve_median_basis.lattice;
+ Lattice *lt = ob->data;
+ BPoint *bp;
+ int a;
+ const float scale_w = compute_scale_factor(ve_median->weight, median->weight);
+
+ a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw;
+ bp = lt->editlatt->latt->def;
+ while (a--) {
+ if (bp->f1 & SELECT) {
+ if (apply_vcos) {
+ apply_raw_diff_v3(bp->vec, tot, ve_median->location, median->location);
+ }
+ if (median->weight) {
+ apply_scale_factor_clamp(&bp->weight, tot, ve_median->weight, scale_w);
+ }
+ }
+ bp++;
+ }
+ }
+
+ /* ED_undo_push(C, "Transform properties"); */
+ }
}
#undef TRANSFORM_MEDIAN_ARRAY_LEN
static void v3d_object_dimension_buts(bContext *C, uiLayout *layout, View3D *v3d, Object *ob)
{
- uiBlock *block = (layout) ? uiLayoutAbsoluteBlock(layout) : NULL;
- TransformProperties *tfp = v3d_transform_props_ensure(v3d);
-
- if (block) {
- BLI_assert(C == NULL);
- int yi = 200;
- const int butw = 200;
- const int buth = 20 * UI_DPI_FAC;
-
- BKE_object_dimensions_get(ob, tfp->ob_dims);
- copy_v3_v3(tfp->ob_dims_orig, tfp->ob_dims);
-
- uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_("Dimensions:"), 0, yi -= buth, butw, buth, NULL, 0, 0, 0, 0, "");
- UI_block_align_begin(block);
- const float lim = 10000;
- for (int i = 0; i < 3; i++) {
- uiBut *but;
- char text[3] = {'X' + i, ':', '\0'};
- but = uiDefButF(
- block, UI_BTYPE_NUM, B_TRANSFORM_PANEL_DIMS, text, 0, yi -= buth, butw, buth,
- &(tfp->ob_dims[i]), 0.0f, lim, 10, 3, "");
- UI_but_unit_type_set(but, PROP_UNIT_LENGTH);
- }
- UI_block_align_end(block);
- }
- else { /* apply */
- int axis_mask = 0;
- for (int i = 0; i < 3; i++) {
- if (tfp->ob_dims[i] == tfp->ob_dims_orig[i]) {
- axis_mask |= (1 << i);
- }
- }
- BKE_object_dimensions_set(ob, tfp->ob_dims, axis_mask);
-
- PointerRNA obptr;
- RNA_id_pointer_create(&ob->id, &obptr);
- PropertyRNA *prop = RNA_struct_find_property(&obptr, "scale");
- RNA_property_update(C, &obptr, prop);
- }
+ uiBlock *block = (layout) ? uiLayoutAbsoluteBlock(layout) : NULL;
+ TransformProperties *tfp = v3d_transform_props_ensure(v3d);
+
+ if (block) {
+ BLI_assert(C == NULL);
+ int yi = 200;
+ const int butw = 200;
+ const int buth = 20 * UI_DPI_FAC;
+
+ BKE_object_dimensions_get(ob, tfp->ob_dims);
+ copy_v3_v3(tfp->ob_dims_orig, tfp->ob_dims);
+
+ uiDefBut(block,
+ UI_BTYPE_LABEL,
+ 0,
+ IFACE_("Dimensions:"),
+ 0,
+ yi -= buth,
+ butw,
+ buth,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ "");
+ UI_block_align_begin(block);
+ const float lim = 10000;
+ for (int i = 0; i < 3; i++) {
+ uiBut *but;
+ char text[3] = {'X' + i, ':', '\0'};
+ but = uiDefButF(block,
+ UI_BTYPE_NUM,
+ B_TRANSFORM_PANEL_DIMS,
+ text,
+ 0,
+ yi -= buth,
+ butw,
+ buth,
+ &(tfp->ob_dims[i]),
+ 0.0f,
+ lim,
+ 10,
+ 3,
+ "");
+ UI_but_unit_type_set(but, PROP_UNIT_LENGTH);
+ }
+ UI_block_align_end(block);
+ }
+ else { /* apply */
+ int axis_mask = 0;
+ for (int i = 0; i < 3; i++) {
+ if (tfp->ob_dims[i] == tfp->ob_dims_orig[i]) {
+ axis_mask |= (1 << i);
+ }
+ }
+ BKE_object_dimensions_set(ob, tfp->ob_dims, axis_mask);
+
+ PointerRNA obptr;
+ RNA_id_pointer_create(&ob->id, &obptr);
+ PropertyRNA *prop = RNA_struct_find_property(&obptr, "scale");
+ RNA_property_update(C, &obptr, prop);
+ }
}
-#define B_VGRP_PNL_EDIT_SINGLE 8 /* or greater */
+#define B_VGRP_PNL_EDIT_SINGLE 8 /* or greater */
static void do_view3d_vgroup_buttons(bContext *C, void *UNUSED(arg), int event)
{
- if (event < B_VGRP_PNL_EDIT_SINGLE) {
- /* not for me */
- return;
- }
- else {
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *ob = view_layer->basact->object;
- ED_vgroup_vert_active_mirror(ob, event - B_VGRP_PNL_EDIT_SINGLE);
- DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
- }
+ if (event < B_VGRP_PNL_EDIT_SINGLE) {
+ /* not for me */
+ return;
+ }
+ else {
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *ob = view_layer->basact->object;
+ ED_vgroup_vert_active_mirror(ob, event - B_VGRP_PNL_EDIT_SINGLE);
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
+ }
}
static bool view3d_panel_vgroup_poll(const bContext *C, PanelType *UNUSED(pt))
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *ob = OBACT(view_layer);
- if (ob && (BKE_object_is_in_editmode_vgroup(ob) ||
- BKE_object_is_in_wpaint_select_vert(ob)))
- {
- MDeformVert *dvert_act = ED_mesh_active_dvert_get_only(ob);
- if (dvert_act) {
- return (dvert_act->totweight != 0);
- }
- }
-
- return false;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *ob = OBACT(view_layer);
+ if (ob && (BKE_object_is_in_editmode_vgroup(ob) || BKE_object_is_in_wpaint_select_vert(ob))) {
+ MDeformVert *dvert_act = ED_mesh_active_dvert_get_only(ob);
+ if (dvert_act) {
+ return (dvert_act->totweight != 0);
+ }
+ }
+
+ return false;
}
-
static void view3d_panel_vgroup(const bContext *C, Panel *pa)
{
- uiBlock *block = uiLayoutAbsoluteBlock(pa->layout);
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *ob = view_layer->basact->object;
-
- MDeformVert *dv;
-
- dv = ED_mesh_active_dvert_get_only(ob);
-
- if (dv && dv->totweight) {
- ToolSettings *ts = scene->toolsettings;
-
- wmOperatorType *ot;
- PointerRNA op_ptr, tools_ptr;
- PointerRNA *but_ptr;
-
- uiLayout *col, *bcol;
- uiLayout *row;
- uiBut *but;
- bDeformGroup *dg;
- uint i;
- int subset_count, vgroup_tot;
- const bool *vgroup_validmap;
- eVGroupSelect subset_type = ts->vgroupsubset;
- int yco = 0;
- int lock_count = 0;
-
- UI_block_func_handle_set(block, do_view3d_vgroup_buttons, NULL);
-
- bcol = uiLayoutColumn(pa->layout, true);
- row = uiLayoutRow(bcol, true); /* The filter button row */
-
- RNA_pointer_create(NULL, &RNA_ToolSettings, ts, &tools_ptr);
- uiItemR(row, &tools_ptr, "vertex_group_subset", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
-
- col = uiLayoutColumn(bcol, true);
-
- vgroup_validmap = BKE_object_defgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
- for (i = 0, dg = ob->defbase.first; dg; i++, dg = dg->next) {
- bool locked = (dg->flag & DG_LOCK_WEIGHT) != 0;
- if (vgroup_validmap[i]) {
- MDeformWeight *dw = defvert_find_index(dv, i);
- if (dw) {
- int x, xco = 0;
- int icon;
- uiLayout *split = uiLayoutSplit(col, 0.45, true);
- row = uiLayoutRow(split, true);
-
- /* The Weight Group Name */
-
- ot = WM_operatortype_find("OBJECT_OT_vertex_weight_set_active", true);
- but = uiDefButO_ptr(block, UI_BTYPE_BUT, ot, WM_OP_EXEC_DEFAULT, dg->name,
- xco, yco, (x = UI_UNIT_X * 5), UI_UNIT_Y, "");
- but_ptr = UI_but_operator_ptr_get(but);
- RNA_int_set(but_ptr, "weight_group", i);
- UI_but_drawflag_enable(but, UI_BUT_TEXT_RIGHT);
- if (ob->actdef != i + 1) {
- UI_but_flag_enable(but, UI_BUT_INACTIVE);
- }
- xco += x;
-
- row = uiLayoutRow(split, true);
- uiLayoutSetEnabled(row, !locked);
-
- /* The weight group value */
- /* To be reworked still */
- but = uiDefButF(block, UI_BTYPE_NUM, B_VGRP_PNL_EDIT_SINGLE + i, "",
- xco, yco, (x = UI_UNIT_X * 4), UI_UNIT_Y,
- &dw->weight, 0.0, 1.0, 1, 3, "");
- UI_but_drawflag_enable(but, UI_BUT_TEXT_LEFT);
- if (locked) {
- lock_count++;
- }
- xco += x;
-
- /* The weight group paste function */
- icon = (locked) ? ICON_BLANK1 : ICON_PASTEDOWN;
- uiItemFullO(row, "OBJECT_OT_vertex_weight_paste", "", icon, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
- RNA_int_set(&op_ptr, "weight_group", i);
-
- /* The weight entry delete function */
- icon = (locked) ? ICON_LOCKED : ICON_X;
- uiItemFullO(row, "OBJECT_OT_vertex_weight_delete", "", icon, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
- RNA_int_set(&op_ptr, "weight_group", i);
-
- yco -= UI_UNIT_Y;
- }
- }
- }
- MEM_freeN((void *)vgroup_validmap);
-
- yco -= 2;
-
- col = uiLayoutColumn(pa->layout, true);
- row = uiLayoutRow(col, true);
-
- ot = WM_operatortype_find("OBJECT_OT_vertex_weight_normalize_active_vertex", 1);
- but = uiDefButO_ptr(block, UI_BTYPE_BUT, ot, WM_OP_EXEC_DEFAULT, "Normalize",
- 0, yco, UI_UNIT_X * 5, UI_UNIT_Y,
- TIP_("Normalize weights of active vertex (if affected groups are unlocked)"));
- if (lock_count) {
- UI_but_flag_enable(but, UI_BUT_DISABLED);
- }
-
- ot = WM_operatortype_find("OBJECT_OT_vertex_weight_copy", 1);
- but = uiDefButO_ptr(block, UI_BTYPE_BUT, ot, WM_OP_EXEC_DEFAULT, "Copy",
- UI_UNIT_X * 5, yco, UI_UNIT_X * 5, UI_UNIT_Y,
- TIP_("Copy active vertex to other selected vertices (if affected groups are unlocked)"));
- if (lock_count) {
- UI_but_flag_enable(but, UI_BUT_DISABLED);
- }
-
- }
+ uiBlock *block = uiLayoutAbsoluteBlock(pa->layout);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *ob = view_layer->basact->object;
+
+ MDeformVert *dv;
+
+ dv = ED_mesh_active_dvert_get_only(ob);
+
+ if (dv && dv->totweight) {
+ ToolSettings *ts = scene->toolsettings;
+
+ wmOperatorType *ot;
+ PointerRNA op_ptr, tools_ptr;
+ PointerRNA *but_ptr;
+
+ uiLayout *col, *bcol;
+ uiLayout *row;
+ uiBut *but;
+ bDeformGroup *dg;
+ uint i;
+ int subset_count, vgroup_tot;
+ const bool *vgroup_validmap;
+ eVGroupSelect subset_type = ts->vgroupsubset;
+ int yco = 0;
+ int lock_count = 0;
+
+ UI_block_func_handle_set(block, do_view3d_vgroup_buttons, NULL);
+
+ bcol = uiLayoutColumn(pa->layout, true);
+ row = uiLayoutRow(bcol, true); /* The filter button row */
+
+ RNA_pointer_create(NULL, &RNA_ToolSettings, ts, &tools_ptr);
+ uiItemR(row, &tools_ptr, "vertex_group_subset", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+
+ col = uiLayoutColumn(bcol, true);
+
+ vgroup_validmap = BKE_object_defgroup_subset_from_select_type(
+ ob, subset_type, &vgroup_tot, &subset_count);
+ for (i = 0, dg = ob->defbase.first; dg; i++, dg = dg->next) {
+ bool locked = (dg->flag & DG_LOCK_WEIGHT) != 0;
+ if (vgroup_validmap[i]) {
+ MDeformWeight *dw = defvert_find_index(dv, i);
+ if (dw) {
+ int x, xco = 0;
+ int icon;
+ uiLayout *split = uiLayoutSplit(col, 0.45, true);
+ row = uiLayoutRow(split, true);
+
+ /* The Weight Group Name */
+
+ ot = WM_operatortype_find("OBJECT_OT_vertex_weight_set_active", true);
+ but = uiDefButO_ptr(block,
+ UI_BTYPE_BUT,
+ ot,
+ WM_OP_EXEC_DEFAULT,
+ dg->name,
+ xco,
+ yco,
+ (x = UI_UNIT_X * 5),
+ UI_UNIT_Y,
+ "");
+ but_ptr = UI_but_operator_ptr_get(but);
+ RNA_int_set(but_ptr, "weight_group", i);
+ UI_but_drawflag_enable(but, UI_BUT_TEXT_RIGHT);
+ if (ob->actdef != i + 1) {
+ UI_but_flag_enable(but, UI_BUT_INACTIVE);
+ }
+ xco += x;
+
+ row = uiLayoutRow(split, true);
+ uiLayoutSetEnabled(row, !locked);
+
+ /* The weight group value */
+ /* To be reworked still */
+ but = uiDefButF(block,
+ UI_BTYPE_NUM,
+ B_VGRP_PNL_EDIT_SINGLE + i,
+ "",
+ xco,
+ yco,
+ (x = UI_UNIT_X * 4),
+ UI_UNIT_Y,
+ &dw->weight,
+ 0.0,
+ 1.0,
+ 1,
+ 3,
+ "");
+ UI_but_drawflag_enable(but, UI_BUT_TEXT_LEFT);
+ if (locked) {
+ lock_count++;
+ }
+ xco += x;
+
+ /* The weight group paste function */
+ icon = (locked) ? ICON_BLANK1 : ICON_PASTEDOWN;
+ uiItemFullO(row,
+ "OBJECT_OT_vertex_weight_paste",
+ "",
+ icon,
+ NULL,
+ WM_OP_INVOKE_DEFAULT,
+ 0,
+ &op_ptr);
+ RNA_int_set(&op_ptr, "weight_group", i);
+
+ /* The weight entry delete function */
+ icon = (locked) ? ICON_LOCKED : ICON_X;
+ uiItemFullO(row,
+ "OBJECT_OT_vertex_weight_delete",
+ "",
+ icon,
+ NULL,
+ WM_OP_INVOKE_DEFAULT,
+ 0,
+ &op_ptr);
+ RNA_int_set(&op_ptr, "weight_group", i);
+
+ yco -= UI_UNIT_Y;
+ }
+ }
+ }
+ MEM_freeN((void *)vgroup_validmap);
+
+ yco -= 2;
+
+ col = uiLayoutColumn(pa->layout, true);
+ row = uiLayoutRow(col, true);
+
+ ot = WM_operatortype_find("OBJECT_OT_vertex_weight_normalize_active_vertex", 1);
+ but = uiDefButO_ptr(
+ block,
+ UI_BTYPE_BUT,
+ ot,
+ WM_OP_EXEC_DEFAULT,
+ "Normalize",
+ 0,
+ yco,
+ UI_UNIT_X * 5,
+ UI_UNIT_Y,
+ TIP_("Normalize weights of active vertex (if affected groups are unlocked)"));
+ if (lock_count) {
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
+ }
+
+ ot = WM_operatortype_find("OBJECT_OT_vertex_weight_copy", 1);
+ but = uiDefButO_ptr(
+ block,
+ UI_BTYPE_BUT,
+ ot,
+ WM_OP_EXEC_DEFAULT,
+ "Copy",
+ UI_UNIT_X * 5,
+ yco,
+ UI_UNIT_X * 5,
+ UI_UNIT_Y,
+ TIP_("Copy active vertex to other selected vertices (if affected groups are unlocked)"));
+ if (lock_count) {
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
+ }
+ }
}
static void v3d_transform_butsR(uiLayout *layout, PointerRNA *ptr)
{
- uiLayout *split, *colsub;
-
- split = uiLayoutSplit(layout, 0.8f, false);
-
- if (ptr->type == &RNA_PoseBone) {
- PointerRNA boneptr;
- Bone *bone;
-
- boneptr = RNA_pointer_get(ptr, "bone");
- bone = boneptr.data;
- uiLayoutSetActive(split, !(bone->parent && bone->flag & BONE_CONNECTED));
- }
- colsub = uiLayoutColumn(split, true);
- uiItemR(colsub, ptr, "location", 0, NULL, ICON_NONE);
- colsub = uiLayoutColumn(split, true);
- uiLayoutSetEmboss(colsub, UI_EMBOSS_NONE);
- uiItemL(colsub, "", ICON_NONE);
- uiItemR(colsub, ptr, "lock_location", UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY, "", ICON_DECORATE_UNLOCKED);
-
- split = uiLayoutSplit(layout, 0.8f, false);
-
- switch (RNA_enum_get(ptr, "rotation_mode")) {
- case ROT_MODE_QUAT: /* quaternion */
- colsub = uiLayoutColumn(split, true);
- uiItemR(colsub, ptr, "rotation_quaternion", 0, IFACE_("Rotation"), ICON_NONE);
- colsub = uiLayoutColumn(split, true);
- uiLayoutSetEmboss(colsub, UI_EMBOSS_NONE);
- uiItemR(colsub, ptr, "lock_rotations_4d", UI_ITEM_R_TOGGLE, IFACE_("4L"), ICON_NONE);
- if (RNA_boolean_get(ptr, "lock_rotations_4d")) {
- uiItemR(colsub, ptr, "lock_rotation_w", UI_ITEM_R_TOGGLE + UI_ITEM_R_ICON_ONLY, "", ICON_DECORATE_UNLOCKED);
- }
- else {
- uiItemL(colsub, "", ICON_NONE);
- }
- uiItemR(colsub, ptr, "lock_rotation", UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY, "", ICON_DECORATE_UNLOCKED);
- break;
- case ROT_MODE_AXISANGLE: /* axis angle */
- colsub = uiLayoutColumn(split, true);
- uiItemR(colsub, ptr, "rotation_axis_angle", 0, IFACE_("Rotation"), ICON_NONE);
- colsub = uiLayoutColumn(split, true);
- uiLayoutSetEmboss(colsub, UI_EMBOSS_NONE);
- uiItemR(colsub, ptr, "lock_rotations_4d", UI_ITEM_R_TOGGLE, IFACE_("4L"), ICON_NONE);
- if (RNA_boolean_get(ptr, "lock_rotations_4d")) {
- uiItemR(colsub, ptr, "lock_rotation_w", UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY, "", ICON_DECORATE_UNLOCKED);
- }
- else {
- uiItemL(colsub, "", ICON_NONE);
- }
- uiItemR(colsub, ptr, "lock_rotation", UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY, "", ICON_DECORATE_UNLOCKED);
- break;
- default: /* euler rotations */
- colsub = uiLayoutColumn(split, true);
- uiItemR(colsub, ptr, "rotation_euler", 0, IFACE_("Rotation"), ICON_NONE);
- colsub = uiLayoutColumn(split, true);
- uiLayoutSetEmboss(colsub, UI_EMBOSS_NONE);
- uiItemL(colsub, "", ICON_NONE);
- uiItemR(colsub, ptr, "lock_rotation", UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY, "", ICON_DECORATE_UNLOCKED);
- break;
- }
- uiItemR(layout, ptr, "rotation_mode", 0, "", ICON_NONE);
-
- split = uiLayoutSplit(layout, 0.8f, false);
- colsub = uiLayoutColumn(split, true);
- uiItemR(colsub, ptr, "scale", 0, NULL, ICON_NONE);
- colsub = uiLayoutColumn(split, true);
- uiLayoutSetEmboss(colsub, UI_EMBOSS_NONE);
- uiItemL(colsub, "", ICON_NONE);
- uiItemR(colsub, ptr, "lock_scale", UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY, "", ICON_DECORATE_UNLOCKED);
+ uiLayout *split, *colsub;
+
+ split = uiLayoutSplit(layout, 0.8f, false);
+
+ if (ptr->type == &RNA_PoseBone) {
+ PointerRNA boneptr;
+ Bone *bone;
+
+ boneptr = RNA_pointer_get(ptr, "bone");
+ bone = boneptr.data;
+ uiLayoutSetActive(split, !(bone->parent && bone->flag & BONE_CONNECTED));
+ }
+ colsub = uiLayoutColumn(split, true);
+ uiItemR(colsub, ptr, "location", 0, NULL, ICON_NONE);
+ colsub = uiLayoutColumn(split, true);
+ uiLayoutSetEmboss(colsub, UI_EMBOSS_NONE);
+ uiItemL(colsub, "", ICON_NONE);
+ uiItemR(colsub,
+ ptr,
+ "lock_location",
+ UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY,
+ "",
+ ICON_DECORATE_UNLOCKED);
+
+ split = uiLayoutSplit(layout, 0.8f, false);
+
+ switch (RNA_enum_get(ptr, "rotation_mode")) {
+ case ROT_MODE_QUAT: /* quaternion */
+ colsub = uiLayoutColumn(split, true);
+ uiItemR(colsub, ptr, "rotation_quaternion", 0, IFACE_("Rotation"), ICON_NONE);
+ colsub = uiLayoutColumn(split, true);
+ uiLayoutSetEmboss(colsub, UI_EMBOSS_NONE);
+ uiItemR(colsub, ptr, "lock_rotations_4d", UI_ITEM_R_TOGGLE, IFACE_("4L"), ICON_NONE);
+ if (RNA_boolean_get(ptr, "lock_rotations_4d")) {
+ uiItemR(colsub,
+ ptr,
+ "lock_rotation_w",
+ UI_ITEM_R_TOGGLE + UI_ITEM_R_ICON_ONLY,
+ "",
+ ICON_DECORATE_UNLOCKED);
+ }
+ else {
+ uiItemL(colsub, "", ICON_NONE);
+ }
+ uiItemR(colsub,
+ ptr,
+ "lock_rotation",
+ UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY,
+ "",
+ ICON_DECORATE_UNLOCKED);
+ break;
+ case ROT_MODE_AXISANGLE: /* axis angle */
+ colsub = uiLayoutColumn(split, true);
+ uiItemR(colsub, ptr, "rotation_axis_angle", 0, IFACE_("Rotation"), ICON_NONE);
+ colsub = uiLayoutColumn(split, true);
+ uiLayoutSetEmboss(colsub, UI_EMBOSS_NONE);
+ uiItemR(colsub, ptr, "lock_rotations_4d", UI_ITEM_R_TOGGLE, IFACE_("4L"), ICON_NONE);
+ if (RNA_boolean_get(ptr, "lock_rotations_4d")) {
+ uiItemR(colsub,
+ ptr,
+ "lock_rotation_w",
+ UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY,
+ "",
+ ICON_DECORATE_UNLOCKED);
+ }
+ else {
+ uiItemL(colsub, "", ICON_NONE);
+ }
+ uiItemR(colsub,
+ ptr,
+ "lock_rotation",
+ UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY,
+ "",
+ ICON_DECORATE_UNLOCKED);
+ break;
+ default: /* euler rotations */
+ colsub = uiLayoutColumn(split, true);
+ uiItemR(colsub, ptr, "rotation_euler", 0, IFACE_("Rotation"), ICON_NONE);
+ colsub = uiLayoutColumn(split, true);
+ uiLayoutSetEmboss(colsub, UI_EMBOSS_NONE);
+ uiItemL(colsub, "", ICON_NONE);
+ uiItemR(colsub,
+ ptr,
+ "lock_rotation",
+ UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY,
+ "",
+ ICON_DECORATE_UNLOCKED);
+ break;
+ }
+ uiItemR(layout, ptr, "rotation_mode", 0, "", ICON_NONE);
+
+ split = uiLayoutSplit(layout, 0.8f, false);
+ colsub = uiLayoutColumn(split, true);
+ uiItemR(colsub, ptr, "scale", 0, NULL, ICON_NONE);
+ colsub = uiLayoutColumn(split, true);
+ uiLayoutSetEmboss(colsub, UI_EMBOSS_NONE);
+ uiItemL(colsub, "", ICON_NONE);
+ uiItemR(colsub,
+ ptr,
+ "lock_scale",
+ UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY,
+ "",
+ ICON_DECORATE_UNLOCKED);
}
static void v3d_posearmature_buts(uiLayout *layout, Object *ob)
{
- bPoseChannel *pchan;
- PointerRNA pchanptr;
- uiLayout *col;
+ bPoseChannel *pchan;
+ PointerRNA pchanptr;
+ uiLayout *col;
- pchan = BKE_pose_channel_active(ob);
+ pchan = BKE_pose_channel_active(ob);
- if (!pchan) {
- uiItemL(layout, IFACE_("No Bone Active"), ICON_NONE);
- return;
- }
+ if (!pchan) {
+ uiItemL(layout, IFACE_("No Bone Active"), ICON_NONE);
+ return;
+ }
- RNA_pointer_create(&ob->id, &RNA_PoseBone, pchan, &pchanptr);
+ RNA_pointer_create(&ob->id, &RNA_PoseBone, pchan, &pchanptr);
- col = uiLayoutColumn(layout, false);
+ col = uiLayoutColumn(layout, false);
- /* XXX: RNA buts show data in native types (i.e. quats, 4-component axis/angle, etc.)
- * but old-school UI shows in eulers always. Do we want to be able to still display in Eulers?
- * Maybe needs RNA/ui options to display rotations as different types... */
- v3d_transform_butsR(col, &pchanptr);
+ /* XXX: RNA buts show data in native types (i.e. quats, 4-component axis/angle, etc.)
+ * but old-school UI shows in eulers always. Do we want to be able to still display in Eulers?
+ * Maybe needs RNA/ui options to display rotations as different types... */
+ v3d_transform_butsR(col, &pchanptr);
}
static void v3d_editarmature_buts(uiLayout *layout, Object *ob)
{
- bArmature *arm = ob->data;
- EditBone *ebone;
- uiLayout *col;
- PointerRNA eboneptr;
-
- ebone = arm->act_edbone;
-
- if (!ebone || (ebone->layer & arm->layer) == 0) {
- uiItemL(layout, IFACE_("Nothing selected"), ICON_NONE);
- return;
- }
-
- RNA_pointer_create(&arm->id, &RNA_EditBone, ebone, &eboneptr);
-
- col = uiLayoutColumn(layout, false);
- uiItemR(col, &eboneptr, "head", 0, NULL, ICON_NONE);
- if (ebone->parent && ebone->flag & BONE_CONNECTED) {
- PointerRNA parptr = RNA_pointer_get(&eboneptr, "parent");
- uiItemR(col, &parptr, "tail_radius", 0, IFACE_("Radius (Parent)"), ICON_NONE);
- }
- else {
- uiItemR(col, &eboneptr, "head_radius", 0, IFACE_("Radius"), ICON_NONE);
- }
-
- uiItemR(col, &eboneptr, "tail", 0, NULL, ICON_NONE);
- uiItemR(col, &eboneptr, "tail_radius", 0, IFACE_("Radius"), ICON_NONE);
-
- uiItemR(col, &eboneptr, "roll", 0, NULL, ICON_NONE);
- uiItemR(col, &eboneptr, "envelope_distance", 0, IFACE_("Envelope"), ICON_NONE);
+ bArmature *arm = ob->data;
+ EditBone *ebone;
+ uiLayout *col;
+ PointerRNA eboneptr;
+
+ ebone = arm->act_edbone;
+
+ if (!ebone || (ebone->layer & arm->layer) == 0) {
+ uiItemL(layout, IFACE_("Nothing selected"), ICON_NONE);
+ return;
+ }
+
+ RNA_pointer_create(&arm->id, &RNA_EditBone, ebone, &eboneptr);
+
+ col = uiLayoutColumn(layout, false);
+ uiItemR(col, &eboneptr, "head", 0, NULL, ICON_NONE);
+ if (ebone->parent && ebone->flag & BONE_CONNECTED) {
+ PointerRNA parptr = RNA_pointer_get(&eboneptr, "parent");
+ uiItemR(col, &parptr, "tail_radius", 0, IFACE_("Radius (Parent)"), ICON_NONE);
+ }
+ else {
+ uiItemR(col, &eboneptr, "head_radius", 0, IFACE_("Radius"), ICON_NONE);
+ }
+
+ uiItemR(col, &eboneptr, "tail", 0, NULL, ICON_NONE);
+ uiItemR(col, &eboneptr, "tail_radius", 0, IFACE_("Radius"), ICON_NONE);
+
+ uiItemR(col, &eboneptr, "roll", 0, NULL, ICON_NONE);
+ uiItemR(col, &eboneptr, "envelope_distance", 0, IFACE_("Envelope"), ICON_NONE);
}
static void v3d_editmetaball_buts(uiLayout *layout, Object *ob)
{
- PointerRNA mbptr, ptr;
- MetaBall *mball = ob->data;
- uiLayout *col;
-
- if (!mball || !(mball->lastelem)) {
- return;
- }
-
- RNA_pointer_create(&mball->id, &RNA_MetaBall, mball, &mbptr);
-
- RNA_pointer_create(&mball->id, &RNA_MetaElement, mball->lastelem, &ptr);
-
- col = uiLayoutColumn(layout, false);
- uiItemR(col, &ptr, "co", 0, NULL, ICON_NONE);
-
- uiItemR(col, &ptr, "radius", 0, NULL, ICON_NONE);
- uiItemR(col, &ptr, "stiffness", 0, NULL, ICON_NONE);
-
- uiItemR(col, &ptr, "type", 0, NULL, ICON_NONE);
-
- col = uiLayoutColumn(layout, true);
- switch (RNA_enum_get(&ptr, "type")) {
- case MB_BALL:
- break;
- case MB_CUBE:
- uiItemL(col, IFACE_("Size:"), ICON_NONE);
- uiItemR(col, &ptr, "size_x", 0, "X", ICON_NONE);
- uiItemR(col, &ptr, "size_y", 0, "Y", ICON_NONE);
- uiItemR(col, &ptr, "size_z", 0, "Z", ICON_NONE);
- break;
- case MB_TUBE:
- uiItemL(col, IFACE_("Size:"), ICON_NONE);
- uiItemR(col, &ptr, "size_x", 0, "X", ICON_NONE);
- break;
- case MB_PLANE:
- uiItemL(col, IFACE_("Size:"), ICON_NONE);
- uiItemR(col, &ptr, "size_x", 0, "X", ICON_NONE);
- uiItemR(col, &ptr, "size_y", 0, "Y", ICON_NONE);
- break;
- case MB_ELIPSOID:
- uiItemL(col, IFACE_("Size:"), ICON_NONE);
- uiItemR(col, &ptr, "size_x", 0, "X", ICON_NONE);
- uiItemR(col, &ptr, "size_y", 0, "Y", ICON_NONE);
- uiItemR(col, &ptr, "size_z", 0, "Z", ICON_NONE);
- break;
- }
+ PointerRNA mbptr, ptr;
+ MetaBall *mball = ob->data;
+ uiLayout *col;
+
+ if (!mball || !(mball->lastelem)) {
+ return;
+ }
+
+ RNA_pointer_create(&mball->id, &RNA_MetaBall, mball, &mbptr);
+
+ RNA_pointer_create(&mball->id, &RNA_MetaElement, mball->lastelem, &ptr);
+
+ col = uiLayoutColumn(layout, false);
+ uiItemR(col, &ptr, "co", 0, NULL, ICON_NONE);
+
+ uiItemR(col, &ptr, "radius", 0, NULL, ICON_NONE);
+ uiItemR(col, &ptr, "stiffness", 0, NULL, ICON_NONE);
+
+ uiItemR(col, &ptr, "type", 0, NULL, ICON_NONE);
+
+ col = uiLayoutColumn(layout, true);
+ switch (RNA_enum_get(&ptr, "type")) {
+ case MB_BALL:
+ break;
+ case MB_CUBE:
+ uiItemL(col, IFACE_("Size:"), ICON_NONE);
+ uiItemR(col, &ptr, "size_x", 0, "X", ICON_NONE);
+ uiItemR(col, &ptr, "size_y", 0, "Y", ICON_NONE);
+ uiItemR(col, &ptr, "size_z", 0, "Z", ICON_NONE);
+ break;
+ case MB_TUBE:
+ uiItemL(col, IFACE_("Size:"), ICON_NONE);
+ uiItemR(col, &ptr, "size_x", 0, "X", ICON_NONE);
+ break;
+ case MB_PLANE:
+ uiItemL(col, IFACE_("Size:"), ICON_NONE);
+ uiItemR(col, &ptr, "size_x", 0, "X", ICON_NONE);
+ uiItemR(col, &ptr, "size_y", 0, "Y", ICON_NONE);
+ break;
+ case MB_ELIPSOID:
+ uiItemL(col, IFACE_("Size:"), ICON_NONE);
+ uiItemR(col, &ptr, "size_x", 0, "X", ICON_NONE);
+ uiItemR(col, &ptr, "size_y", 0, "Y", ICON_NONE);
+ uiItemR(col, &ptr, "size_z", 0, "Z", ICON_NONE);
+ break;
+ }
}
static void do_view3d_region_buttons(bContext *C, void *UNUSED(index), int event)
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- View3D *v3d = CTX_wm_view3d(C);
- Object *ob = OBACT(view_layer);
-
- switch (event) {
-
- case B_REDR:
- ED_area_tag_redraw(CTX_wm_area(C));
- return; /* no notifier! */
-
- case B_TRANSFORM_PANEL_MEDIAN:
- if (ob) {
- v3d_editvertex_buts(NULL, v3d, ob, 1.0);
- DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
- }
- break;
- case B_TRANSFORM_PANEL_DIMS:
- if (ob) {
- v3d_object_dimension_buts(C, NULL, v3d, ob);
- }
- break;
- }
-
- /* default for now */
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ Object *ob = OBACT(view_layer);
+
+ switch (event) {
+
+ case B_REDR:
+ ED_area_tag_redraw(CTX_wm_area(C));
+ return; /* no notifier! */
+
+ case B_TRANSFORM_PANEL_MEDIAN:
+ if (ob) {
+ v3d_editvertex_buts(NULL, v3d, ob, 1.0);
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ }
+ break;
+ case B_TRANSFORM_PANEL_DIMS:
+ if (ob) {
+ v3d_object_dimension_buts(C, NULL, v3d, ob);
+ }
+ break;
+ }
+
+ /* default for now */
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
}
static bool view3d_panel_transform_poll(const bContext *C, PanelType *UNUSED(pt))
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- return (view_layer->basact != NULL);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ return (view_layer->basact != NULL);
}
static void view3d_panel_transform(const bContext *C, Panel *pa)
{
- uiBlock *block;
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *ob = view_layer->basact->object;
- Object *obedit = OBEDIT_FROM_OBACT(ob);
- uiLayout *col;
-
- block = uiLayoutGetBlock(pa->layout);
- UI_block_func_handle_set(block, do_view3d_region_buttons, NULL);
-
- col = uiLayoutColumn(pa->layout, false);
-
- if (ob == obedit) {
- if (ob->type == OB_ARMATURE) {
- v3d_editarmature_buts(col, ob);
- }
- else if (ob->type == OB_MBALL) {
- v3d_editmetaball_buts(col, ob);
- }
- else {
- View3D *v3d = CTX_wm_view3d(C);
- Scene *scene = CTX_data_scene(C);
- const float lim = 10000.0f * max_ff(1.0f, ED_view3d_grid_scale(scene, v3d, NULL));
- v3d_editvertex_buts(col, v3d, ob, lim);
- }
- }
- else if (ob->mode & OB_MODE_POSE) {
- v3d_posearmature_buts(col, ob);
- }
- else {
- PointerRNA obptr;
-
- RNA_id_pointer_create(&ob->id, &obptr);
- v3d_transform_butsR(col, &obptr);
-
- /* dimensions and editmode just happen to be the same checks */
- if (OB_TYPE_SUPPORT_EDITMODE(ob->type)) {
- View3D *v3d = CTX_wm_view3d(C);
- v3d_object_dimension_buts(NULL, col, v3d, ob);
- }
- }
+ uiBlock *block;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *ob = view_layer->basact->object;
+ Object *obedit = OBEDIT_FROM_OBACT(ob);
+ uiLayout *col;
+
+ block = uiLayoutGetBlock(pa->layout);
+ UI_block_func_handle_set(block, do_view3d_region_buttons, NULL);
+
+ col = uiLayoutColumn(pa->layout, false);
+
+ if (ob == obedit) {
+ if (ob->type == OB_ARMATURE) {
+ v3d_editarmature_buts(col, ob);
+ }
+ else if (ob->type == OB_MBALL) {
+ v3d_editmetaball_buts(col, ob);
+ }
+ else {
+ View3D *v3d = CTX_wm_view3d(C);
+ Scene *scene = CTX_data_scene(C);
+ const float lim = 10000.0f * max_ff(1.0f, ED_view3d_grid_scale(scene, v3d, NULL));
+ v3d_editvertex_buts(col, v3d, ob, lim);
+ }
+ }
+ else if (ob->mode & OB_MODE_POSE) {
+ v3d_posearmature_buts(col, ob);
+ }
+ else {
+ PointerRNA obptr;
+
+ RNA_id_pointer_create(&ob->id, &obptr);
+ v3d_transform_butsR(col, &obptr);
+
+ /* dimensions and editmode just happen to be the same checks */
+ if (OB_TYPE_SUPPORT_EDITMODE(ob->type)) {
+ View3D *v3d = CTX_wm_view3d(C);
+ v3d_object_dimension_buts(NULL, col, v3d, ob);
+ }
+ }
}
static void hide_collections_menu_draw(const bContext *C, Menu *menu)
{
- ED_collection_hide_menu_draw(C, menu->layout);
+ ED_collection_hide_menu_draw(C, menu->layout);
}
void view3d_buttons_register(ARegionType *art)
{
- PanelType *pt;
-
- pt = MEM_callocN(sizeof(PanelType), "spacetype view3d panel object");
- strcpy(pt->idname, "VIEW3D_PT_transform");
- strcpy(pt->label, N_("Transform")); /* XXX C panels unavailable through RNA bpy.types! */
- strcpy(pt->category, "View");
- strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw = view3d_panel_transform;
- pt->poll = view3d_panel_transform_poll;
- BLI_addtail(&art->paneltypes, pt);
-
- pt = MEM_callocN(sizeof(PanelType), "spacetype view3d panel vgroup");
- strcpy(pt->idname, "VIEW3D_PT_vgroup");
- strcpy(pt->label, N_("Vertex Weights")); /* XXX C panels unavailable through RNA bpy.types! */
- strcpy(pt->category, "View");
- strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw = view3d_panel_vgroup;
- pt->poll = view3d_panel_vgroup_poll;
- BLI_addtail(&art->paneltypes, pt);
-
- MenuType *mt;
-
- mt = MEM_callocN(sizeof(MenuType), "spacetype view3d menu collections");
- strcpy(mt->idname, "VIEW3D_MT_collection");
- strcpy(mt->label, N_("Collection"));
- strcpy(mt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
- mt->draw = hide_collections_menu_draw;
- WM_menutype_add(mt);
+ PanelType *pt;
+
+ pt = MEM_callocN(sizeof(PanelType), "spacetype view3d panel object");
+ strcpy(pt->idname, "VIEW3D_PT_transform");
+ strcpy(pt->label, N_("Transform")); /* XXX C panels unavailable through RNA bpy.types! */
+ strcpy(pt->category, "View");
+ strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ pt->draw = view3d_panel_transform;
+ pt->poll = view3d_panel_transform_poll;
+ BLI_addtail(&art->paneltypes, pt);
+
+ pt = MEM_callocN(sizeof(PanelType), "spacetype view3d panel vgroup");
+ strcpy(pt->idname, "VIEW3D_PT_vgroup");
+ strcpy(pt->label, N_("Vertex Weights")); /* XXX C panels unavailable through RNA bpy.types! */
+ strcpy(pt->category, "View");
+ strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ pt->draw = view3d_panel_vgroup;
+ pt->poll = view3d_panel_vgroup_poll;
+ BLI_addtail(&art->paneltypes, pt);
+
+ MenuType *mt;
+
+ mt = MEM_callocN(sizeof(MenuType), "spacetype view3d menu collections");
+ strcpy(mt->idname, "VIEW3D_MT_collection");
+ strcpy(mt->label, N_("Collection"));
+ strcpy(mt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ mt->draw = hide_collections_menu_draw;
+ WM_menutype_add(mt);
}
static int view3d_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op))
{
- ScrArea *sa = CTX_wm_area(C);
- ARegion *ar = view3d_has_buttons_region(sa);
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = view3d_has_buttons_region(sa);
- if (ar) {
- ED_region_toggle_hidden(C, ar);
- }
+ if (ar) {
+ ED_region_toggle_hidden(C, ar);
+ }
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void VIEW3D_OT_properties(wmOperatorType *ot)
{
- ot->name = "Toggle Sidebar";
- ot->description = "Toggle the properties region visibility";
- ot->idname = "VIEW3D_OT_properties";
+ ot->name = "Toggle Sidebar";
+ ot->description = "Toggle the properties region visibility";
+ ot->idname = "VIEW3D_OT_properties";
- ot->exec = view3d_properties_toggle_exec;
- ot->poll = ED_operator_view3d_active;
+ ot->exec = view3d_properties_toggle_exec;
+ ot->poll = ED_operator_view3d_active;
- /* flags */
- ot->flag = 0;
+ /* flags */
+ ot->flag = 0;
}
static int view3d_object_mode_menu(bContext *C, wmOperator *op)
{
- Object *ob = CTX_data_active_object(C);
- if (ob == NULL) {
- BKE_report(op->reports, RPT_WARNING, "No active object found");
- return OPERATOR_CANCELLED;
- }
- else if (((ob->mode & OB_MODE_EDIT) == 0) && (ELEM(ob->type, OB_ARMATURE))) {
- ED_object_mode_toggle(C, OB_MODE_POSE);
- return OPERATOR_CANCELLED;
- }
- else {
- UI_pie_menu_invoke(C, "VIEW3D_MT_object_mode_pie", CTX_wm_window(C)->eventstate);
- return OPERATOR_CANCELLED;
- }
+ Object *ob = CTX_data_active_object(C);
+ if (ob == NULL) {
+ BKE_report(op->reports, RPT_WARNING, "No active object found");
+ return OPERATOR_CANCELLED;
+ }
+ else if (((ob->mode & OB_MODE_EDIT) == 0) && (ELEM(ob->type, OB_ARMATURE))) {
+ ED_object_mode_toggle(C, OB_MODE_POSE);
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ UI_pie_menu_invoke(C, "VIEW3D_MT_object_mode_pie", CTX_wm_window(C)->eventstate);
+ return OPERATOR_CANCELLED;
+ }
}
void VIEW3D_OT_object_mode_pie_or_toggle(wmOperatorType *ot)
{
- ot->name = "Object Mode Menu";
- ot->idname = "VIEW3D_OT_object_mode_pie_or_toggle";
+ ot->name = "Object Mode Menu";
+ ot->idname = "VIEW3D_OT_object_mode_pie_or_toggle";
- ot->exec = view3d_object_mode_menu;
- ot->poll = ED_operator_view3d_active;
+ ot->exec = view3d_object_mode_menu;
+ ot->poll = ED_operator_view3d_active;
- /* flags */
- ot->flag = 0;
+ /* flags */
+ ot->flag = 0;
}
diff --git a/source/blender/editors/space_view3d/view3d_camera_control.c b/source/blender/editors/space_view3d/view3d_camera_control.c
index 3f7356de465..c8059c25e15 100644
--- a/source/blender/editors/space_view3d/view3d_camera_control.c
+++ b/source/blender/editors/space_view3d/view3d_camera_control.c
@@ -51,287 +51,277 @@
#include "ED_screen.h"
-#include "view3d_intern.h" /* own include */
+#include "view3d_intern.h" /* own include */
#include "BLI_strict_flags.h"
-
typedef struct View3DCameraControl {
- /* -------------------------------------------------------------------- */
- /* Context (assign these to vars before use) */
- Scene *ctx_scene;
- View3D *ctx_v3d;
- RegionView3D *ctx_rv3d;
-
-
- /* -------------------------------------------------------------------- */
- /* internal vars */
+ /* -------------------------------------------------------------------- */
+ /* Context (assign these to vars before use) */
+ Scene *ctx_scene;
+ View3D *ctx_v3d;
+ RegionView3D *ctx_rv3d;
- /* for parenting calculation */
- float view_mat_prev[4][4];
+ /* -------------------------------------------------------------------- */
+ /* internal vars */
+ /* for parenting calculation */
+ float view_mat_prev[4][4];
- /* -------------------------------------------------------------------- */
- /* optional capabilities */
+ /* -------------------------------------------------------------------- */
+ /* optional capabilities */
- bool use_parent_root;
+ bool use_parent_root;
+ /* -------------------------------------------------------------------- */
+ /* initial values */
- /* -------------------------------------------------------------------- */
- /* initial values */
+ /* root most parent */
+ Object *root_parent;
- /* root most parent */
- Object *root_parent;
+ /* backup values */
+ float dist_backup;
+ /* backup the views distance since we use a zero dist for fly mode */
+ float ofs_backup[3];
+ /* backup the views offset in case the user cancels flying in non camera mode */
- /* backup values */
- float dist_backup;
- /* backup the views distance since we use a zero dist for fly mode */
- float ofs_backup[3];
- /* backup the views offset in case the user cancels flying in non camera mode */
+ /* backup the views quat in case the user cancels flying in non camera mode.
+ * (quat for view, eul for camera) */
+ float rot_backup[4];
+ /* remember if were ortho or not, only used for restoring the view if it was a ortho view */
+ char persp_backup;
- /* backup the views quat in case the user cancels flying in non camera mode.
- * (quat for view, eul for camera) */
- float rot_backup[4];
- /* remember if were ortho or not, only used for restoring the view if it was a ortho view */
- char persp_backup;
+ /* are we flying an ortho camera in perspective view,
+ * which was originally in ortho view?
+ * could probably figure it out but better be explicit */
+ bool is_ortho_cam;
- /* are we flying an ortho camera in perspective view,
- * which was originally in ortho view?
- * could probably figure it out but better be explicit */
- bool is_ortho_cam;
-
- /* backup the objects transform */
- void *obtfm;
+ /* backup the objects transform */
+ void *obtfm;
} View3DCameraControl;
-
BLI_INLINE Object *view3d_cameracontrol_object(View3DCameraControl *vctrl)
{
- return vctrl->root_parent ? vctrl->root_parent : vctrl->ctx_v3d->camera;
+ return vctrl->root_parent ? vctrl->root_parent : vctrl->ctx_v3d->camera;
}
-
/**
* Returns the object which is being manipulated or NULL.
*/
Object *ED_view3d_cameracontrol_object_get(View3DCameraControl *vctrl)
{
- RegionView3D *rv3d = vctrl->ctx_rv3d;
-
- if (rv3d->persp == RV3D_CAMOB) {
- return view3d_cameracontrol_object(vctrl);
- }
- else {
- return NULL;
- }
+ RegionView3D *rv3d = vctrl->ctx_rv3d;
+
+ if (rv3d->persp == RV3D_CAMOB) {
+ return view3d_cameracontrol_object(vctrl);
+ }
+ else {
+ return NULL;
+ }
}
-
/**
* Creates a #View3DCameraControl handle and sets up
* the view for first-person style navigation.
*/
-struct View3DCameraControl *ED_view3d_cameracontrol_acquire(
- Depsgraph *depsgraph, Scene *scene, View3D *v3d, RegionView3D *rv3d,
- const bool use_parent_root)
+struct View3DCameraControl *ED_view3d_cameracontrol_acquire(Depsgraph *depsgraph,
+ Scene *scene,
+ View3D *v3d,
+ RegionView3D *rv3d,
+ const bool use_parent_root)
{
- View3DCameraControl *vctrl;
-
- vctrl = MEM_callocN(sizeof(View3DCameraControl), __func__);
-
- /* Store context */
- vctrl->ctx_scene = scene;
- vctrl->ctx_v3d = v3d;
- vctrl->ctx_rv3d = rv3d;
-
- vctrl->use_parent_root = use_parent_root;
-
- vctrl->persp_backup = rv3d->persp;
- vctrl->dist_backup = rv3d->dist;
-
- /* check for flying ortho camera - which we cant support well
- * we _could_ also check for an ortho camera but this is easier */
- if ((rv3d->persp == RV3D_CAMOB) &&
- (rv3d->is_persp == false))
- {
- ((Camera *)v3d->camera->data)->type = CAM_PERSP;
- vctrl->is_ortho_cam = true;
- }
-
- if (rv3d->persp == RV3D_CAMOB) {
- Object *ob_back;
- if (use_parent_root && (vctrl->root_parent = v3d->camera->parent)) {
- while (vctrl->root_parent->parent) {
- vctrl->root_parent = vctrl->root_parent->parent;
- }
- ob_back = vctrl->root_parent;
- }
- else {
- ob_back = v3d->camera;
- }
-
- /* store the original camera loc and rot */
- vctrl->obtfm = BKE_object_tfm_backup(ob_back);
-
- BKE_object_where_is_calc(depsgraph, scene, v3d->camera);
- negate_v3_v3(rv3d->ofs, v3d->camera->obmat[3]);
-
- rv3d->dist = 0.0;
- }
- else {
- /* perspective or ortho */
- if (rv3d->persp == RV3D_ORTHO) {
- /* if ortho projection, make perspective */
- rv3d->persp = RV3D_PERSP;
- }
-
- copy_qt_qt(vctrl->rot_backup, rv3d->viewquat);
- copy_v3_v3(vctrl->ofs_backup, rv3d->ofs);
-
- /* the dist defines a vector that is infront of the offset
- * to rotate the view about.
- * this is no good for fly mode because we
- * want to rotate about the viewers center.
- * but to correct the dist removal we must
- * alter offset so the view doesn't jump. */
-
- ED_view3d_distance_set(rv3d, 0.0f);
- /* Done with correcting for the dist */
- }
-
- ED_view3d_to_m4(vctrl->view_mat_prev, rv3d->ofs, rv3d->viewquat, rv3d->dist);
-
- return vctrl;
+ View3DCameraControl *vctrl;
+
+ vctrl = MEM_callocN(sizeof(View3DCameraControl), __func__);
+
+ /* Store context */
+ vctrl->ctx_scene = scene;
+ vctrl->ctx_v3d = v3d;
+ vctrl->ctx_rv3d = rv3d;
+
+ vctrl->use_parent_root = use_parent_root;
+
+ vctrl->persp_backup = rv3d->persp;
+ vctrl->dist_backup = rv3d->dist;
+
+ /* check for flying ortho camera - which we cant support well
+ * we _could_ also check for an ortho camera but this is easier */
+ if ((rv3d->persp == RV3D_CAMOB) && (rv3d->is_persp == false)) {
+ ((Camera *)v3d->camera->data)->type = CAM_PERSP;
+ vctrl->is_ortho_cam = true;
+ }
+
+ if (rv3d->persp == RV3D_CAMOB) {
+ Object *ob_back;
+ if (use_parent_root && (vctrl->root_parent = v3d->camera->parent)) {
+ while (vctrl->root_parent->parent) {
+ vctrl->root_parent = vctrl->root_parent->parent;
+ }
+ ob_back = vctrl->root_parent;
+ }
+ else {
+ ob_back = v3d->camera;
+ }
+
+ /* store the original camera loc and rot */
+ vctrl->obtfm = BKE_object_tfm_backup(ob_back);
+
+ BKE_object_where_is_calc(depsgraph, scene, v3d->camera);
+ negate_v3_v3(rv3d->ofs, v3d->camera->obmat[3]);
+
+ rv3d->dist = 0.0;
+ }
+ else {
+ /* perspective or ortho */
+ if (rv3d->persp == RV3D_ORTHO) {
+ /* if ortho projection, make perspective */
+ rv3d->persp = RV3D_PERSP;
+ }
+
+ copy_qt_qt(vctrl->rot_backup, rv3d->viewquat);
+ copy_v3_v3(vctrl->ofs_backup, rv3d->ofs);
+
+ /* the dist defines a vector that is infront of the offset
+ * to rotate the view about.
+ * this is no good for fly mode because we
+ * want to rotate about the viewers center.
+ * but to correct the dist removal we must
+ * alter offset so the view doesn't jump. */
+
+ ED_view3d_distance_set(rv3d, 0.0f);
+ /* Done with correcting for the dist */
+ }
+
+ ED_view3d_to_m4(vctrl->view_mat_prev, rv3d->ofs, rv3d->viewquat, rv3d->dist);
+
+ return vctrl;
}
-
/**
* Updates cameras from the ``rv3d`` values, optionally auto-keyframing.
*/
-void ED_view3d_cameracontrol_update(
- View3DCameraControl *vctrl,
- /* args for keyframing */
- const bool use_autokey,
- struct bContext *C, const bool do_rotate, const bool do_translate)
+void ED_view3d_cameracontrol_update(View3DCameraControl *vctrl,
+ /* args for keyframing */
+ const bool use_autokey,
+ struct bContext *C,
+ const bool do_rotate,
+ const bool do_translate)
{
- /* we are in camera view so apply the view ofs and quat to the view matrix and set the camera
- * to the view */
+ /* we are in camera view so apply the view ofs and quat to the view matrix and set the camera
+ * to the view */
- Scene *scene = vctrl->ctx_scene;
- View3D *v3d = vctrl->ctx_v3d;
- RegionView3D *rv3d = vctrl->ctx_rv3d;
+ Scene *scene = vctrl->ctx_scene;
+ View3D *v3d = vctrl->ctx_v3d;
+ RegionView3D *rv3d = vctrl->ctx_rv3d;
- ID *id_key;
+ ID *id_key;
- /* transform the parent or the camera? */
- if (vctrl->root_parent) {
- Object *ob_update;
+ /* transform the parent or the camera? */
+ if (vctrl->root_parent) {
+ Object *ob_update;
- float view_mat[4][4];
- float prev_view_imat[4][4];
- float diff_mat[4][4];
- float parent_mat[4][4];
+ float view_mat[4][4];
+ float prev_view_imat[4][4];
+ float diff_mat[4][4];
+ float parent_mat[4][4];
- invert_m4_m4(prev_view_imat, vctrl->view_mat_prev);
- ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist);
- mul_m4_m4m4(diff_mat, view_mat, prev_view_imat);
- mul_m4_m4m4(parent_mat, diff_mat, vctrl->root_parent->obmat);
+ invert_m4_m4(prev_view_imat, vctrl->view_mat_prev);
+ ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist);
+ mul_m4_m4m4(diff_mat, view_mat, prev_view_imat);
+ mul_m4_m4m4(parent_mat, diff_mat, vctrl->root_parent->obmat);
- BKE_object_apply_mat4(vctrl->root_parent, parent_mat, true, false);
+ BKE_object_apply_mat4(vctrl->root_parent, parent_mat, true, false);
- ob_update = v3d->camera->parent;
- while (ob_update) {
- DEG_id_tag_update(&ob_update->id, ID_RECALC_TRANSFORM);
- ob_update = ob_update->parent;
- }
+ ob_update = v3d->camera->parent;
+ while (ob_update) {
+ DEG_id_tag_update(&ob_update->id, ID_RECALC_TRANSFORM);
+ ob_update = ob_update->parent;
+ }
- copy_m4_m4(vctrl->view_mat_prev, view_mat);
+ copy_m4_m4(vctrl->view_mat_prev, view_mat);
- id_key = &vctrl->root_parent->id;
- }
- else {
- float view_mat[4][4];
- float scale_mat[4][4];
- float scale_back[3];
+ id_key = &vctrl->root_parent->id;
+ }
+ else {
+ float view_mat[4][4];
+ float scale_mat[4][4];
+ float scale_back[3];
- /* even though we handle the scale matrix, this still changes over time */
- copy_v3_v3(scale_back, v3d->camera->scale);
+ /* even though we handle the scale matrix, this still changes over time */
+ copy_v3_v3(scale_back, v3d->camera->scale);
- ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist);
- size_to_mat4(scale_mat, v3d->camera->scale);
- mul_m4_m4m4(view_mat, view_mat, scale_mat);
+ ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist);
+ size_to_mat4(scale_mat, v3d->camera->scale);
+ mul_m4_m4m4(view_mat, view_mat, scale_mat);
- BKE_object_apply_mat4(v3d->camera, view_mat, true, true);
+ BKE_object_apply_mat4(v3d->camera, view_mat, true, true);
- DEG_id_tag_update(&v3d->camera->id, ID_RECALC_TRANSFORM);
+ DEG_id_tag_update(&v3d->camera->id, ID_RECALC_TRANSFORM);
- copy_v3_v3(v3d->camera->scale, scale_back);
+ copy_v3_v3(v3d->camera->scale, scale_back);
- id_key = &v3d->camera->id;
- }
+ id_key = &v3d->camera->id;
+ }
- /* record the motion */
- if (use_autokey) {
- ED_view3d_camera_autokey(scene, id_key, C, do_rotate, do_translate);
- }
+ /* record the motion */
+ if (use_autokey) {
+ ED_view3d_camera_autokey(scene, id_key, C, do_rotate, do_translate);
+ }
}
-
/**
* Release view control.
*
* \param restore: Sets the view state to the values that were set
* before #ED_view3d_control_acquire was called.
*/
-void ED_view3d_cameracontrol_release(
- View3DCameraControl *vctrl,
- const bool restore)
+void ED_view3d_cameracontrol_release(View3DCameraControl *vctrl, const bool restore)
{
- View3D *v3d = vctrl->ctx_v3d;
- RegionView3D *rv3d = vctrl->ctx_rv3d;
-
- if (restore) {
- /* Revert to original view? */
- if (vctrl->persp_backup == RV3D_CAMOB) { /* a camera view */
- Object *ob_back = view3d_cameracontrol_object(vctrl);
-
- /* store the original camera loc and rot */
- BKE_object_tfm_restore(ob_back, vctrl->obtfm);
-
- DEG_id_tag_update(&ob_back->id, ID_RECALC_TRANSFORM);
- }
- else {
- /* Non Camera we need to reset the view back
- * to the original location because the user canceled. */
- copy_qt_qt(rv3d->viewquat, vctrl->rot_backup);
- rv3d->persp = vctrl->persp_backup;
- }
- /* always, is set to zero otherwise */
- copy_v3_v3(rv3d->ofs, vctrl->ofs_backup);
- rv3d->dist = vctrl->dist_backup;
- }
- else if (vctrl->persp_backup == RV3D_CAMOB) { /* camera */
- DEG_id_tag_update((ID *)view3d_cameracontrol_object(vctrl), ID_RECALC_TRANSFORM);
-
- /* always, is set to zero otherwise */
- copy_v3_v3(rv3d->ofs, vctrl->ofs_backup);
- rv3d->dist = vctrl->dist_backup;
- }
- else { /* not camera */
- /* Apply the fly mode view */
- /* restore the dist */
- ED_view3d_distance_set(rv3d, vctrl->dist_backup);
- /* Done with correcting for the dist */
- }
-
- if (vctrl->is_ortho_cam) {
- ((Camera *)v3d->camera->data)->type = CAM_ORTHO;
- }
-
- if (vctrl->obtfm) {
- MEM_freeN(vctrl->obtfm);
- }
-
- MEM_freeN(vctrl);
+ View3D *v3d = vctrl->ctx_v3d;
+ RegionView3D *rv3d = vctrl->ctx_rv3d;
+
+ if (restore) {
+ /* Revert to original view? */
+ if (vctrl->persp_backup == RV3D_CAMOB) { /* a camera view */
+ Object *ob_back = view3d_cameracontrol_object(vctrl);
+
+ /* store the original camera loc and rot */
+ BKE_object_tfm_restore(ob_back, vctrl->obtfm);
+
+ DEG_id_tag_update(&ob_back->id, ID_RECALC_TRANSFORM);
+ }
+ else {
+ /* Non Camera we need to reset the view back
+ * to the original location because the user canceled. */
+ copy_qt_qt(rv3d->viewquat, vctrl->rot_backup);
+ rv3d->persp = vctrl->persp_backup;
+ }
+ /* always, is set to zero otherwise */
+ copy_v3_v3(rv3d->ofs, vctrl->ofs_backup);
+ rv3d->dist = vctrl->dist_backup;
+ }
+ else if (vctrl->persp_backup == RV3D_CAMOB) { /* camera */
+ DEG_id_tag_update((ID *)view3d_cameracontrol_object(vctrl), ID_RECALC_TRANSFORM);
+
+ /* always, is set to zero otherwise */
+ copy_v3_v3(rv3d->ofs, vctrl->ofs_backup);
+ rv3d->dist = vctrl->dist_backup;
+ }
+ else { /* not camera */
+ /* Apply the fly mode view */
+ /* restore the dist */
+ ED_view3d_distance_set(rv3d, vctrl->dist_backup);
+ /* Done with correcting for the dist */
+ }
+
+ if (vctrl->is_ortho_cam) {
+ ((Camera *)v3d->camera->data)->type = CAM_ORTHO;
+ }
+
+ if (vctrl->obtfm) {
+ MEM_freeN(vctrl->obtfm);
+ }
+
+ MEM_freeN(vctrl);
}
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 3399bda1cfa..4610111aafa 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -30,7 +30,6 @@
#include "BLI_threads.h"
#include "BLI_jitter_2d.h"
-
#include "BKE_camera.h"
#include "BKE_collection.h"
#include "BKE_context.h"
@@ -91,7 +90,7 @@
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
-#include "view3d_intern.h" /* own include */
+#include "view3d_intern.h" /* own include */
/* -------------------------------------------------------------------- */
/** \name General Functions
@@ -100,125 +99,131 @@
/**
* \note keep this synced with #ED_view3d_mats_rv3d_backup/#ED_view3d_mats_rv3d_restore
*/
-void ED_view3d_update_viewmat(
- Depsgraph *depsgraph, Scene *scene, View3D *v3d, ARegion *ar,
- float viewmat[4][4], float winmat[4][4], const rcti *rect)
+void ED_view3d_update_viewmat(Depsgraph *depsgraph,
+ Scene *scene,
+ View3D *v3d,
+ ARegion *ar,
+ float viewmat[4][4],
+ float winmat[4][4],
+ const rcti *rect)
{
- RegionView3D *rv3d = ar->regiondata;
-
- /* setup window matrices */
- if (winmat) {
- copy_m4_m4(rv3d->winmat, winmat);
- }
- else {
- view3d_winmatrix_set(depsgraph, ar, v3d, rect);
- }
-
- /* setup view matrix */
- if (viewmat) {
- copy_m4_m4(rv3d->viewmat, viewmat);
- }
- else {
- float rect_scale[2];
- if (rect) {
- rect_scale[0] = (float)BLI_rcti_size_x(rect) / (float)ar->winx;
- rect_scale[1] = (float)BLI_rcti_size_y(rect) / (float)ar->winy;
- }
- /* note: calls BKE_object_where_is_calc for camera... */
- view3d_viewmatrix_set(depsgraph, scene, v3d, rv3d, rect ? rect_scale : NULL);
- }
- /* update utility matrices */
- mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
- invert_m4_m4(rv3d->persinv, rv3d->persmat);
- invert_m4_m4(rv3d->viewinv, rv3d->viewmat);
-
- /* calculate GLSL view dependent values */
-
- /* store window coordinates scaling/offset */
- if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
- rctf cameraborder;
- ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &cameraborder, false);
- rv3d->viewcamtexcofac[0] = (float)ar->winx / BLI_rctf_size_x(&cameraborder);
- rv3d->viewcamtexcofac[1] = (float)ar->winy / BLI_rctf_size_y(&cameraborder);
-
- rv3d->viewcamtexcofac[2] = -rv3d->viewcamtexcofac[0] * cameraborder.xmin / (float)ar->winx;
- rv3d->viewcamtexcofac[3] = -rv3d->viewcamtexcofac[1] * cameraborder.ymin / (float)ar->winy;
- }
- else {
- rv3d->viewcamtexcofac[0] = rv3d->viewcamtexcofac[1] = 1.0f;
- rv3d->viewcamtexcofac[2] = rv3d->viewcamtexcofac[3] = 0.0f;
- }
-
- /* calculate pixelsize factor once, is used for lights and obcenters */
- {
- /* note: '1.0f / len_v3(v1)' replaced 'len_v3(rv3d->viewmat[0])'
- * because of float point precision problems at large values [#23908] */
- float v1[3], v2[3];
- float len_px, len_sc;
-
- v1[0] = rv3d->persmat[0][0];
- v1[1] = rv3d->persmat[1][0];
- v1[2] = rv3d->persmat[2][0];
-
- v2[0] = rv3d->persmat[0][1];
- v2[1] = rv3d->persmat[1][1];
- v2[2] = rv3d->persmat[2][1];
-
- len_px = 2.0f / sqrtf(min_ff(len_squared_v3(v1), len_squared_v3(v2)));
- len_sc = (float)MAX2(ar->winx, ar->winy);
-
- rv3d->pixsize = len_px / len_sc;
- }
+ RegionView3D *rv3d = ar->regiondata;
+
+ /* setup window matrices */
+ if (winmat) {
+ copy_m4_m4(rv3d->winmat, winmat);
+ }
+ else {
+ view3d_winmatrix_set(depsgraph, ar, v3d, rect);
+ }
+
+ /* setup view matrix */
+ if (viewmat) {
+ copy_m4_m4(rv3d->viewmat, viewmat);
+ }
+ else {
+ float rect_scale[2];
+ if (rect) {
+ rect_scale[0] = (float)BLI_rcti_size_x(rect) / (float)ar->winx;
+ rect_scale[1] = (float)BLI_rcti_size_y(rect) / (float)ar->winy;
+ }
+ /* note: calls BKE_object_where_is_calc for camera... */
+ view3d_viewmatrix_set(depsgraph, scene, v3d, rv3d, rect ? rect_scale : NULL);
+ }
+ /* update utility matrices */
+ mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
+ invert_m4_m4(rv3d->persinv, rv3d->persmat);
+ invert_m4_m4(rv3d->viewinv, rv3d->viewmat);
+
+ /* calculate GLSL view dependent values */
+
+ /* store window coordinates scaling/offset */
+ if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
+ rctf cameraborder;
+ ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &cameraborder, false);
+ rv3d->viewcamtexcofac[0] = (float)ar->winx / BLI_rctf_size_x(&cameraborder);
+ rv3d->viewcamtexcofac[1] = (float)ar->winy / BLI_rctf_size_y(&cameraborder);
+
+ rv3d->viewcamtexcofac[2] = -rv3d->viewcamtexcofac[0] * cameraborder.xmin / (float)ar->winx;
+ rv3d->viewcamtexcofac[3] = -rv3d->viewcamtexcofac[1] * cameraborder.ymin / (float)ar->winy;
+ }
+ else {
+ rv3d->viewcamtexcofac[0] = rv3d->viewcamtexcofac[1] = 1.0f;
+ rv3d->viewcamtexcofac[2] = rv3d->viewcamtexcofac[3] = 0.0f;
+ }
+
+ /* calculate pixelsize factor once, is used for lights and obcenters */
+ {
+ /* note: '1.0f / len_v3(v1)' replaced 'len_v3(rv3d->viewmat[0])'
+ * because of float point precision problems at large values [#23908] */
+ float v1[3], v2[3];
+ float len_px, len_sc;
+
+ v1[0] = rv3d->persmat[0][0];
+ v1[1] = rv3d->persmat[1][0];
+ v1[2] = rv3d->persmat[2][0];
+
+ v2[0] = rv3d->persmat[0][1];
+ v2[1] = rv3d->persmat[1][1];
+ v2[2] = rv3d->persmat[2][1];
+
+ len_px = 2.0f / sqrtf(min_ff(len_squared_v3(v1), len_squared_v3(v2)));
+ len_sc = (float)MAX2(ar->winx, ar->winy);
+
+ rv3d->pixsize = len_px / len_sc;
+ }
}
-static void view3d_main_region_setup_view(
- Depsgraph *depsgraph, Scene *scene,
- View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4], const rcti *rect)
+static void view3d_main_region_setup_view(Depsgraph *depsgraph,
+ Scene *scene,
+ View3D *v3d,
+ ARegion *ar,
+ float viewmat[4][4],
+ float winmat[4][4],
+ const rcti *rect)
{
- RegionView3D *rv3d = ar->regiondata;
+ RegionView3D *rv3d = ar->regiondata;
- ED_view3d_update_viewmat(depsgraph, scene, v3d, ar, viewmat, winmat, rect);
+ ED_view3d_update_viewmat(depsgraph, scene, v3d, ar, viewmat, winmat, rect);
- /* set for opengl */
- GPU_matrix_projection_set(rv3d->winmat);
- GPU_matrix_set(rv3d->viewmat);
+ /* set for opengl */
+ GPU_matrix_projection_set(rv3d->winmat);
+ GPU_matrix_set(rv3d->viewmat);
}
static bool view3d_stereo3d_active(wmWindow *win, Scene *scene, View3D *v3d, RegionView3D *rv3d)
{
- if ((scene->r.scemode & R_MULTIVIEW) == 0) {
- return false;
- }
-
- if ((v3d->camera == NULL) || (v3d->camera->type != OB_CAMERA) || rv3d->persp != RV3D_CAMOB) {
- return false;
- }
-
- switch (v3d->stereo3d_camera) {
- case STEREO_MONO_ID:
- return false;
- break;
- case STEREO_3D_ID:
- /* win will be NULL when calling this from the selection or draw loop. */
- if ((win == NULL) || (WM_stereo3d_enabled(win, true) == false)) {
- return false;
- }
- if (((scene->r.views_format & SCE_VIEWS_FORMAT_MULTIVIEW) != 0) &&
- !BKE_scene_multiview_is_stereo3d(&scene->r))
- {
- return false;
- }
- break;
- /* We always need the stereo calculation for left and right cameras. */
- case STEREO_LEFT_ID:
- case STEREO_RIGHT_ID:
- default:
- break;
- }
- return true;
+ if ((scene->r.scemode & R_MULTIVIEW) == 0) {
+ return false;
+ }
+
+ if ((v3d->camera == NULL) || (v3d->camera->type != OB_CAMERA) || rv3d->persp != RV3D_CAMOB) {
+ return false;
+ }
+
+ switch (v3d->stereo3d_camera) {
+ case STEREO_MONO_ID:
+ return false;
+ break;
+ case STEREO_3D_ID:
+ /* win will be NULL when calling this from the selection or draw loop. */
+ if ((win == NULL) || (WM_stereo3d_enabled(win, true) == false)) {
+ return false;
+ }
+ if (((scene->r.views_format & SCE_VIEWS_FORMAT_MULTIVIEW) != 0) &&
+ !BKE_scene_multiview_is_stereo3d(&scene->r)) {
+ return false;
+ }
+ break;
+ /* We always need the stereo calculation for left and right cameras. */
+ case STEREO_LEFT_ID:
+ case STEREO_RIGHT_ID:
+ default:
+ break;
+ }
+ return true;
}
-
/* setup the view and win matrices for the multiview cameras
*
* unlike view3d_stereo3d_setup_offscreen, when view3d_stereo3d_setup is called
@@ -228,72 +233,77 @@ static bool view3d_stereo3d_active(wmWindow *win, Scene *scene, View3D *v3d, Reg
* view3d)main_region_setup_view() code to account for that.
*/
static void view3d_stereo3d_setup(
- Depsgraph *depsgraph, Scene *scene, View3D *v3d, ARegion *ar, const rcti *rect)
+ Depsgraph *depsgraph, Scene *scene, View3D *v3d, ARegion *ar, const rcti *rect)
{
- bool is_left;
- const char *names[2] = { STEREO_LEFT_NAME, STEREO_RIGHT_NAME };
- const char *viewname;
+ bool is_left;
+ const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
+ const char *viewname;
- /* show only left or right camera */
- if (v3d->stereo3d_camera != STEREO_3D_ID) {
- v3d->multiview_eye = v3d->stereo3d_camera;
- }
+ /* show only left or right camera */
+ if (v3d->stereo3d_camera != STEREO_3D_ID) {
+ v3d->multiview_eye = v3d->stereo3d_camera;
+ }
- is_left = v3d->multiview_eye == STEREO_LEFT_ID;
- viewname = names[is_left ? STEREO_LEFT_ID : STEREO_RIGHT_ID];
+ is_left = v3d->multiview_eye == STEREO_LEFT_ID;
+ viewname = names[is_left ? STEREO_LEFT_ID : STEREO_RIGHT_ID];
- /* update the viewport matrices with the new camera */
- if (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D) {
- Camera *data, *data_eval;
- float viewmat[4][4];
- float shiftx;
+ /* update the viewport matrices with the new camera */
+ if (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D) {
+ Camera *data, *data_eval;
+ float viewmat[4][4];
+ float shiftx;
- data = (Camera *)v3d->camera->data;
- data_eval = (Camera *)DEG_get_evaluated_id(depsgraph, &data->id);
+ data = (Camera *)v3d->camera->data;
+ data_eval = (Camera *)DEG_get_evaluated_id(depsgraph, &data->id);
- shiftx = data_eval->shiftx;
+ shiftx = data_eval->shiftx;
- BLI_thread_lock(LOCK_VIEW3D);
- data_eval->shiftx = BKE_camera_multiview_shift_x(&scene->r, v3d->camera, viewname);
+ BLI_thread_lock(LOCK_VIEW3D);
+ data_eval->shiftx = BKE_camera_multiview_shift_x(&scene->r, v3d->camera, viewname);
- BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat);
- view3d_main_region_setup_view(depsgraph, scene, v3d, ar, viewmat, NULL, rect);
+ BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat);
+ view3d_main_region_setup_view(depsgraph, scene, v3d, ar, viewmat, NULL, rect);
- data_eval->shiftx = shiftx;
- BLI_thread_unlock(LOCK_VIEW3D);
- }
- else { /* SCE_VIEWS_FORMAT_MULTIVIEW */
- float viewmat[4][4];
- Object *view_ob = v3d->camera;
- Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
+ data_eval->shiftx = shiftx;
+ BLI_thread_unlock(LOCK_VIEW3D);
+ }
+ else { /* SCE_VIEWS_FORMAT_MULTIVIEW */
+ float viewmat[4][4];
+ Object *view_ob = v3d->camera;
+ Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
- BLI_thread_lock(LOCK_VIEW3D);
- v3d->camera = camera;
+ BLI_thread_lock(LOCK_VIEW3D);
+ v3d->camera = camera;
- BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat);
- view3d_main_region_setup_view(depsgraph, scene, v3d, ar, viewmat, NULL, rect);
+ BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat);
+ view3d_main_region_setup_view(depsgraph, scene, v3d, ar, viewmat, NULL, rect);
- v3d->camera = view_ob;
- BLI_thread_unlock(LOCK_VIEW3D);
- }
+ v3d->camera = view_ob;
+ BLI_thread_unlock(LOCK_VIEW3D);
+ }
}
/**
* Set the correct matrices
*/
-void ED_view3d_draw_setup_view(
- wmWindow *win, Depsgraph *depsgraph, Scene *scene, ARegion *ar, View3D *v3d,
- float viewmat[4][4], float winmat[4][4], const rcti *rect)
+void ED_view3d_draw_setup_view(wmWindow *win,
+ Depsgraph *depsgraph,
+ Scene *scene,
+ ARegion *ar,
+ View3D *v3d,
+ float viewmat[4][4],
+ float winmat[4][4],
+ const rcti *rect)
{
- RegionView3D *rv3d = ar->regiondata;
-
- /* Setup the view matrix. */
- if (view3d_stereo3d_active(win, scene, v3d, rv3d)) {
- view3d_stereo3d_setup(depsgraph, scene, v3d, ar, rect);
- }
- else {
- view3d_main_region_setup_view(depsgraph, scene, v3d, ar, viewmat, winmat, rect);
- }
+ RegionView3D *rv3d = ar->regiondata;
+
+ /* Setup the view matrix. */
+ if (view3d_stereo3d_active(win, scene, v3d, rv3d)) {
+ view3d_stereo3d_setup(depsgraph, scene, v3d, ar, rect);
+ }
+ else {
+ view3d_main_region_setup_view(depsgraph, scene, v3d, ar, viewmat, winmat, rect);
+ }
}
/** \} */
@@ -302,471 +312,493 @@ void ED_view3d_draw_setup_view(
/** \name Draw View Border
* \{ */
-static void view3d_camera_border(
- const Scene *scene, struct Depsgraph *depsgraph,
- const ARegion *ar, const View3D *v3d, const RegionView3D *rv3d,
- rctf *r_viewborder, const bool no_shift, const bool no_zoom)
+static void view3d_camera_border(const Scene *scene,
+ struct Depsgraph *depsgraph,
+ const ARegion *ar,
+ const View3D *v3d,
+ const RegionView3D *rv3d,
+ rctf *r_viewborder,
+ const bool no_shift,
+ const bool no_zoom)
{
- CameraParams params;
- rctf rect_view, rect_camera;
- Object *camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera);
-
- /* get viewport viewplane */
- BKE_camera_params_init(&params);
- BKE_camera_params_from_view3d(&params, depsgraph, v3d, rv3d);
- if (no_zoom) {
- params.zoom = 1.0f;
- }
- BKE_camera_params_compute_viewplane(&params, ar->winx, ar->winy, 1.0f, 1.0f);
- rect_view = params.viewplane;
-
- /* get camera viewplane */
- BKE_camera_params_init(&params);
- /* fallback for non camera objects */
- params.clip_start = v3d->clip_start;
- params.clip_end = v3d->clip_end;
- BKE_camera_params_from_object(&params, camera_eval);
- if (no_shift) {
- params.shiftx = 0.0f;
- params.shifty = 0.0f;
- }
- BKE_camera_params_compute_viewplane(&params, scene->r.xsch, scene->r.ysch, scene->r.xasp, scene->r.yasp);
- rect_camera = params.viewplane;
-
- /* get camera border within viewport */
- 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;
+ CameraParams params;
+ rctf rect_view, rect_camera;
+ Object *camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera);
+
+ /* get viewport viewplane */
+ BKE_camera_params_init(&params);
+ BKE_camera_params_from_view3d(&params, depsgraph, v3d, rv3d);
+ if (no_zoom) {
+ params.zoom = 1.0f;
+ }
+ BKE_camera_params_compute_viewplane(&params, ar->winx, ar->winy, 1.0f, 1.0f);
+ rect_view = params.viewplane;
+
+ /* get camera viewplane */
+ BKE_camera_params_init(&params);
+ /* fallback for non camera objects */
+ params.clip_start = v3d->clip_start;
+ params.clip_end = v3d->clip_end;
+ BKE_camera_params_from_object(&params, camera_eval);
+ if (no_shift) {
+ params.shiftx = 0.0f;
+ params.shifty = 0.0f;
+ }
+ BKE_camera_params_compute_viewplane(
+ &params, scene->r.xsch, scene->r.ysch, scene->r.xasp, scene->r.yasp);
+ rect_camera = params.viewplane;
+
+ /* get camera border within viewport */
+ 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(
- const Scene *scene, Depsgraph *depsgraph,
- const ARegion *ar, const View3D *v3d, const RegionView3D *rv3d,
- float r_size[2])
+void ED_view3d_calc_camera_border_size(const Scene *scene,
+ Depsgraph *depsgraph,
+ const ARegion *ar,
+ const View3D *v3d,
+ const RegionView3D *rv3d,
+ float r_size[2])
{
- rctf viewborder;
+ rctf viewborder;
- view3d_camera_border(scene, depsgraph, ar, v3d, rv3d, &viewborder, true, true);
- r_size[0] = BLI_rctf_size_x(&viewborder);
- r_size[1] = BLI_rctf_size_y(&viewborder);
+ view3d_camera_border(scene, depsgraph, ar, v3d, rv3d, &viewborder, true, true);
+ r_size[0] = BLI_rctf_size_x(&viewborder);
+ r_size[1] = BLI_rctf_size_y(&viewborder);
}
-void ED_view3d_calc_camera_border(
- const Scene *scene, Depsgraph *depsgraph,
- const ARegion *ar, const View3D *v3d, const RegionView3D *rv3d,
- rctf *r_viewborder, const bool no_shift)
+void ED_view3d_calc_camera_border(const Scene *scene,
+ Depsgraph *depsgraph,
+ const ARegion *ar,
+ const View3D *v3d,
+ const RegionView3D *rv3d,
+ rctf *r_viewborder,
+ const bool no_shift)
{
- view3d_camera_border(scene, depsgraph, ar, v3d, rv3d, r_viewborder, no_shift, false);
+ view3d_camera_border(scene, depsgraph, ar, v3d, rv3d, r_viewborder, no_shift, false);
}
static void drawviewborder_grid3(uint shdr_pos, float x1, float x2, float y1, float y2, float fac)
{
- float x3, y3, x4, y4;
+ float x3, y3, x4, y4;
- x3 = x1 + fac * (x2 - x1);
- y3 = y1 + fac * (y2 - y1);
- x4 = x1 + (1.0f - fac) * (x2 - x1);
- y4 = y1 + (1.0f - fac) * (y2 - y1);
+ x3 = x1 + fac * (x2 - x1);
+ y3 = y1 + fac * (y2 - y1);
+ x4 = x1 + (1.0f - fac) * (x2 - x1);
+ y4 = y1 + (1.0f - fac) * (y2 - y1);
- immBegin(GPU_PRIM_LINES, 8);
+ immBegin(GPU_PRIM_LINES, 8);
- immVertex2f(shdr_pos, x1, y3);
- immVertex2f(shdr_pos, x2, y3);
+ immVertex2f(shdr_pos, x1, y3);
+ immVertex2f(shdr_pos, x2, y3);
- immVertex2f(shdr_pos, x1, y4);
- immVertex2f(shdr_pos, x2, y4);
+ immVertex2f(shdr_pos, x1, y4);
+ immVertex2f(shdr_pos, x2, y4);
- immVertex2f(shdr_pos, x3, y1);
- immVertex2f(shdr_pos, x3, y2);
+ immVertex2f(shdr_pos, x3, y1);
+ immVertex2f(shdr_pos, x3, y2);
- immVertex2f(shdr_pos, x4, y1);
- immVertex2f(shdr_pos, x4, y2);
+ immVertex2f(shdr_pos, x4, y1);
+ immVertex2f(shdr_pos, x4, y2);
- immEnd();
+ immEnd();
}
/* harmonious triangle */
static void drawviewborder_triangle(
- uint shdr_pos, float x1, float x2, float y1, float y2, const char golden, const char dir)
+ uint shdr_pos, float x1, float x2, float y1, float y2, const char golden, const char dir)
{
- float ofs;
- float w = x2 - x1;
- float h = y2 - y1;
-
- immBegin(GPU_PRIM_LINES, 6);
-
- if (w > h) {
- if (golden) {
- ofs = w * (1.0f - (1.0f / 1.61803399f));
- }
- else {
- ofs = h * (h / w);
- }
- if (dir == 'B') {
- SWAP(float, y1, y2);
- }
-
- immVertex2f(shdr_pos, x1, y1);
- immVertex2f(shdr_pos, x2, y2);
-
- immVertex2f(shdr_pos, x2, y1);
- immVertex2f(shdr_pos, x1 + (w - ofs), y2);
-
- immVertex2f(shdr_pos, x1, y2);
- immVertex2f(shdr_pos, x1 + ofs, y1);
- }
- else {
- if (golden) {
- ofs = h * (1.0f - (1.0f / 1.61803399f));
- }
- else {
- ofs = w * (w / h);
- }
- if (dir == 'B') {
- SWAP(float, x1, x2);
- }
-
- immVertex2f(shdr_pos, x1, y1);
- immVertex2f(shdr_pos, x2, y2);
-
- immVertex2f(shdr_pos, x2, y1);
- immVertex2f(shdr_pos, x1, y1 + ofs);
-
- immVertex2f(shdr_pos, x1, y2);
- immVertex2f(shdr_pos, x2, y1 + (h - ofs));
- }
-
- immEnd();
+ float ofs;
+ float w = x2 - x1;
+ float h = y2 - y1;
+
+ immBegin(GPU_PRIM_LINES, 6);
+
+ if (w > h) {
+ if (golden) {
+ ofs = w * (1.0f - (1.0f / 1.61803399f));
+ }
+ else {
+ ofs = h * (h / w);
+ }
+ if (dir == 'B') {
+ SWAP(float, y1, y2);
+ }
+
+ immVertex2f(shdr_pos, x1, y1);
+ immVertex2f(shdr_pos, x2, y2);
+
+ immVertex2f(shdr_pos, x2, y1);
+ immVertex2f(shdr_pos, x1 + (w - ofs), y2);
+
+ immVertex2f(shdr_pos, x1, y2);
+ immVertex2f(shdr_pos, x1 + ofs, y1);
+ }
+ else {
+ if (golden) {
+ ofs = h * (1.0f - (1.0f / 1.61803399f));
+ }
+ else {
+ ofs = w * (w / h);
+ }
+ if (dir == 'B') {
+ SWAP(float, x1, x2);
+ }
+
+ immVertex2f(shdr_pos, x1, y1);
+ immVertex2f(shdr_pos, x2, y2);
+
+ immVertex2f(shdr_pos, x2, y1);
+ immVertex2f(shdr_pos, x1, y1 + ofs);
+
+ immVertex2f(shdr_pos, x1, y2);
+ immVertex2f(shdr_pos, x2, y1 + (h - ofs));
+ }
+
+ immEnd();
}
static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *ar, View3D *v3d)
{
- float x1, x2, y1, y2;
- float x1i, x2i, y1i, y2i;
-
- rctf viewborder;
- Camera *ca = NULL;
- RegionView3D *rv3d = ar->regiondata;
-
- if (v3d->camera == NULL) {
- return;
- }
- if (v3d->camera->type == OB_CAMERA) {
- ca = v3d->camera->data;
- }
-
- ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &viewborder, false);
- /* the offsets */
- x1 = viewborder.xmin;
- y1 = viewborder.ymin;
- x2 = viewborder.xmax;
- y2 = viewborder.ymax;
-
- GPU_line_width(1.0f);
-
- /* apply offsets so the real 3D camera shows through */
-
- /* note: quite un-scientific but without this bit extra
- * 0.0001 on the lower left the 2D border sometimes
- * obscures the 3D camera border */
- /* note: with VIEW3D_CAMERA_BORDER_HACK defined this error isn't noticeable
- * but keep it here in case we need to remove the workaround */
- x1i = (int)(x1 - 1.0001f);
- y1i = (int)(y1 - 1.0001f);
- x2i = (int)(x2 + (1.0f - 0.0001f));
- y2i = (int)(y2 + (1.0f - 0.0001f));
-
- uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-
- /* First, solid lines. */
- {
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
- /* passepartout, specified in camera edit buttons */
- if (ca && (ca->flag & CAM_SHOWPASSEPARTOUT) && ca->passepartalpha > 0.000001f) {
- const float winx = (ar->winx + 1);
- const float winy = (ar->winy + 1);
-
- float alpha = 1.0f;
-
- if (ca->passepartalpha != 1.0f) {
- GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- GPU_blend(true);
- alpha = ca->passepartalpha;
- }
-
- immUniformColor4f(0.0f, 0.0f, 0.0f, alpha);
-
- if (x1i > 0.0f) {
- immRectf(shdr_pos, 0.0f, winy, x1i, 0.0f);
- }
- if (x2i < winx) {
- immRectf(shdr_pos, x2i, winy, winx, 0.0f);
- }
- if (y2i < winy) {
- immRectf(shdr_pos, x1i, winy, x2i, y2i);
- }
- if (y2i > 0.0f) {
- immRectf(shdr_pos, x1i, y1i, x2i, 0.0f);
- }
-
- GPU_blend(false);
- }
-
- immUniformThemeColor(TH_BACK);
- imm_draw_box_wire_2d(shdr_pos, x1i, y1i, x2i, y2i);
+ float x1, x2, y1, y2;
+ float x1i, x2i, y1i, y2i;
+
+ rctf viewborder;
+ Camera *ca = NULL;
+ RegionView3D *rv3d = ar->regiondata;
+
+ if (v3d->camera == NULL) {
+ return;
+ }
+ if (v3d->camera->type == OB_CAMERA) {
+ ca = v3d->camera->data;
+ }
+
+ ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &viewborder, false);
+ /* the offsets */
+ x1 = viewborder.xmin;
+ y1 = viewborder.ymin;
+ x2 = viewborder.xmax;
+ y2 = viewborder.ymax;
+
+ GPU_line_width(1.0f);
+
+ /* apply offsets so the real 3D camera shows through */
+
+ /* note: quite un-scientific but without this bit extra
+ * 0.0001 on the lower left the 2D border sometimes
+ * obscures the 3D camera border */
+ /* note: with VIEW3D_CAMERA_BORDER_HACK defined this error isn't noticeable
+ * but keep it here in case we need to remove the workaround */
+ x1i = (int)(x1 - 1.0001f);
+ y1i = (int)(y1 - 1.0001f);
+ x2i = (int)(x2 + (1.0f - 0.0001f));
+ y2i = (int)(y2 + (1.0f - 0.0001f));
+
+ uint shdr_pos = GPU_vertformat_attr_add(
+ immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+
+ /* First, solid lines. */
+ {
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ /* passepartout, specified in camera edit buttons */
+ if (ca && (ca->flag & CAM_SHOWPASSEPARTOUT) && ca->passepartalpha > 0.000001f) {
+ const float winx = (ar->winx + 1);
+ const float winy = (ar->winy + 1);
+
+ float alpha = 1.0f;
+
+ if (ca->passepartalpha != 1.0f) {
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(true);
+ alpha = ca->passepartalpha;
+ }
+
+ immUniformColor4f(0.0f, 0.0f, 0.0f, alpha);
+
+ if (x1i > 0.0f) {
+ immRectf(shdr_pos, 0.0f, winy, x1i, 0.0f);
+ }
+ if (x2i < winx) {
+ immRectf(shdr_pos, x2i, winy, winx, 0.0f);
+ }
+ if (y2i < winy) {
+ immRectf(shdr_pos, x1i, winy, x2i, y2i);
+ }
+ if (y2i > 0.0f) {
+ immRectf(shdr_pos, x1i, y1i, x2i, 0.0f);
+ }
+
+ GPU_blend(false);
+ }
+
+ immUniformThemeColor(TH_BACK);
+ imm_draw_box_wire_2d(shdr_pos, x1i, y1i, x2i, y2i);
#ifdef VIEW3D_CAMERA_BORDER_HACK
- if (view3d_camera_border_hack_test == true) {
- immUniformColor3ubv(view3d_camera_border_hack_col);
- imm_draw_box_wire_2d(shdr_pos, x1i + 1, y1i + 1, x2i - 1, y2i - 1);
- view3d_camera_border_hack_test = false;
- }
+ if (view3d_camera_border_hack_test == true) {
+ immUniformColor3ubv(view3d_camera_border_hack_col);
+ imm_draw_box_wire_2d(shdr_pos, x1i + 1, y1i + 1, x2i - 1, y2i - 1);
+ view3d_camera_border_hack_test = false;
+ }
#endif
- immUnbindProgram();
- }
+ immUnbindProgram();
+ }
- /* When overlays are disabled, only show camera outline & passepartout. */
- if (v3d->flag2 & V3D_HIDE_OVERLAYS) {
- return;
- }
+ /* When overlays are disabled, only show camera outline & passepartout. */
+ if (v3d->flag2 & V3D_HIDE_OVERLAYS) {
+ return;
+ }
- /* And now, the dashed lines! */
- immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
+ /* And now, the dashed lines! */
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
- {
- float viewport_size[4];
- GPU_viewport_size_get_f(viewport_size);
- immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+ {
+ float viewport_size[4];
+ GPU_viewport_size_get_f(viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
- immUniform1i("colors_len", 0); /* "simple" mode */
- immUniform1f("dash_width", 6.0f);
- immUniform1f("dash_factor", 0.5f);
+ immUniform1i("colors_len", 0); /* "simple" mode */
+ immUniform1f("dash_width", 6.0f);
+ immUniform1f("dash_factor", 0.5f);
- /* outer line not to confuse with object selection */
- if (v3d->flag2 & V3D_LOCK_CAMERA) {
- immUniformThemeColor(TH_REDALERT);
- imm_draw_box_wire_2d(shdr_pos, x1i - 1, y1i - 1, x2i + 1, y2i + 1);
- }
+ /* outer line not to confuse with object selection */
+ if (v3d->flag2 & V3D_LOCK_CAMERA) {
+ immUniformThemeColor(TH_REDALERT);
+ imm_draw_box_wire_2d(shdr_pos, x1i - 1, y1i - 1, x2i + 1, y2i + 1);
+ }
- immUniformThemeColor(TH_VIEW_OVERLAY);
- imm_draw_box_wire_2d(shdr_pos, x1i, y1i, x2i, y2i);
- }
+ immUniformThemeColor(TH_VIEW_OVERLAY);
+ imm_draw_box_wire_2d(shdr_pos, x1i, y1i, x2i, y2i);
+ }
- /* Render Border. */
- if (scene->r.mode & R_BORDER) {
- float x3, y3, x4, y4;
+ /* Render Border. */
+ if (scene->r.mode & R_BORDER) {
+ float x3, y3, x4, y4;
- x3 = floorf(x1 + (scene->r.border.xmin * (x2 - x1))) - 1;
- y3 = floorf(y1 + (scene->r.border.ymin * (y2 - y1))) - 1;
- x4 = floorf(x1 + (scene->r.border.xmax * (x2 - x1))) + (U.pixelsize - 1);
- y4 = floorf(y1 + (scene->r.border.ymax * (y2 - y1))) + (U.pixelsize - 1);
-
- immUniformColor3f(1.0f, 0.25f, 0.25f);
- imm_draw_box_wire_2d(shdr_pos, x3, y3, x4, y4);
- }
-
- /* safety border */
- if (ca) {
- immUniformThemeColorBlend(TH_VIEW_OVERLAY, TH_BACK, 0.25f);
-
- if (ca->dtx & CAM_DTX_CENTER) {
- float x3, y3;
-
- x3 = x1 + 0.5f * (x2 - x1);
- y3 = y1 + 0.5f * (y2 - y1);
-
- immBegin(GPU_PRIM_LINES, 4);
-
- immVertex2f(shdr_pos, x1, y3);
- immVertex2f(shdr_pos, x2, y3);
-
- immVertex2f(shdr_pos, x3, y1);
- immVertex2f(shdr_pos, x3, y2);
-
- immEnd();
- }
-
- if (ca->dtx & CAM_DTX_CENTER_DIAG) {
- immBegin(GPU_PRIM_LINES, 4);
-
- immVertex2f(shdr_pos, x1, y1);
- immVertex2f(shdr_pos, x2, y2);
-
- immVertex2f(shdr_pos, x1, y2);
- immVertex2f(shdr_pos, x2, y1);
-
- immEnd();
- }
-
- if (ca->dtx & CAM_DTX_THIRDS) {
- drawviewborder_grid3(shdr_pos, x1, x2, y1, y2, 1.0f / 3.0f);
- }
-
- if (ca->dtx & CAM_DTX_GOLDEN) {
- drawviewborder_grid3(shdr_pos, x1, x2, y1, y2, 1.0f - (1.0f / 1.61803399f));
- }
-
- if (ca->dtx & CAM_DTX_GOLDEN_TRI_A) {
- drawviewborder_triangle(shdr_pos, x1, x2, y1, y2, 0, 'A');
- }
-
- if (ca->dtx & CAM_DTX_GOLDEN_TRI_B) {
- drawviewborder_triangle(shdr_pos, x1, x2, y1, y2, 0, 'B');
- }
-
- if (ca->dtx & CAM_DTX_HARMONY_TRI_A) {
- drawviewborder_triangle(shdr_pos, x1, x2, y1, y2, 1, 'A');
- }
-
- if (ca->dtx & CAM_DTX_HARMONY_TRI_B) {
- drawviewborder_triangle(shdr_pos, x1, x2, y1, y2, 1, 'B');
- }
-
- if (ca->flag & CAM_SHOW_SAFE_MARGINS) {
- UI_draw_safe_areas(
- shdr_pos, x1, x2, y1, y2,
- scene->safe_areas.title, scene->safe_areas.action);
-
- if (ca->flag & CAM_SHOW_SAFE_CENTER) {
- UI_draw_safe_areas(
- shdr_pos, x1, x2, y1, y2,
- scene->safe_areas.title_center, scene->safe_areas.action_center);
- }
- }
-
- if (ca->flag & CAM_SHOWSENSOR) {
- /* determine sensor fit, and get sensor x/y, for auto fit we
- * assume and square sensor and only use sensor_x */
- float sizex = scene->r.xsch * scene->r.xasp;
- float sizey = scene->r.ysch * scene->r.yasp;
- int sensor_fit = BKE_camera_sensor_fit(ca->sensor_fit, sizex, sizey);
- float sensor_x = ca->sensor_x;
- float sensor_y = (ca->sensor_fit == CAMERA_SENSOR_FIT_AUTO) ? ca->sensor_x : ca->sensor_y;
-
- /* determine sensor plane */
- rctf rect;
-
- if (sensor_fit == CAMERA_SENSOR_FIT_HOR) {
- float sensor_scale = (x2i - x1i) / sensor_x;
- float sensor_height = sensor_scale * sensor_y;
-
- rect.xmin = x1i;
- rect.xmax = x2i;
- rect.ymin = (y1i + y2i) * 0.5f - sensor_height * 0.5f;
- rect.ymax = rect.ymin + sensor_height;
- }
- else {
- float sensor_scale = (y2i - y1i) / sensor_y;
- float sensor_width = sensor_scale * sensor_x;
-
- rect.xmin = (x1i + x2i) * 0.5f - sensor_width * 0.5f;
- rect.xmax = rect.xmin + sensor_width;
- rect.ymin = y1i;
- rect.ymax = y2i;
- }
-
- /* draw */
- immUniformThemeColorShade(TH_VIEW_OVERLAY, 100);
-
- /* TODO Was using UI_draw_roundbox_4fv(false, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 2.0f, color).
- * We'll probably need a new imm_draw_line_roundbox_dashed dor that - though in practice the
- * 2.0f round corner effect was nearly not visible anyway... */
- imm_draw_box_wire_2d(shdr_pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
- }
- }
-
- immUnbindProgram();
- /* end dashed lines */
-
- /* camera name - draw in highlighted text color */
- if (ca && ((v3d->overlay.flag & V3D_OVERLAY_HIDE_TEXT) == 0) && (ca->flag & CAM_SHOWNAME)) {
- UI_FontThemeColor(BLF_default(), TH_TEXT_HI);
- BLF_draw_default(
- x1i, y1i - (0.7f * U.widget_unit), 0.0f,
- v3d->camera->id.name + 2, sizeof(v3d->camera->id.name) - 2);
- }
+ x3 = floorf(x1 + (scene->r.border.xmin * (x2 - x1))) - 1;
+ y3 = floorf(y1 + (scene->r.border.ymin * (y2 - y1))) - 1;
+ x4 = floorf(x1 + (scene->r.border.xmax * (x2 - x1))) + (U.pixelsize - 1);
+ y4 = floorf(y1 + (scene->r.border.ymax * (y2 - y1))) + (U.pixelsize - 1);
+
+ immUniformColor3f(1.0f, 0.25f, 0.25f);
+ imm_draw_box_wire_2d(shdr_pos, x3, y3, x4, y4);
+ }
+
+ /* safety border */
+ if (ca) {
+ immUniformThemeColorBlend(TH_VIEW_OVERLAY, TH_BACK, 0.25f);
+
+ if (ca->dtx & CAM_DTX_CENTER) {
+ float x3, y3;
+
+ x3 = x1 + 0.5f * (x2 - x1);
+ y3 = y1 + 0.5f * (y2 - y1);
+
+ immBegin(GPU_PRIM_LINES, 4);
+
+ immVertex2f(shdr_pos, x1, y3);
+ immVertex2f(shdr_pos, x2, y3);
+
+ immVertex2f(shdr_pos, x3, y1);
+ immVertex2f(shdr_pos, x3, y2);
+
+ immEnd();
+ }
+
+ if (ca->dtx & CAM_DTX_CENTER_DIAG) {
+ immBegin(GPU_PRIM_LINES, 4);
+
+ immVertex2f(shdr_pos, x1, y1);
+ immVertex2f(shdr_pos, x2, y2);
+
+ immVertex2f(shdr_pos, x1, y2);
+ immVertex2f(shdr_pos, x2, y1);
+
+ immEnd();
+ }
+
+ if (ca->dtx & CAM_DTX_THIRDS) {
+ drawviewborder_grid3(shdr_pos, x1, x2, y1, y2, 1.0f / 3.0f);
+ }
+
+ if (ca->dtx & CAM_DTX_GOLDEN) {
+ drawviewborder_grid3(shdr_pos, x1, x2, y1, y2, 1.0f - (1.0f / 1.61803399f));
+ }
+
+ if (ca->dtx & CAM_DTX_GOLDEN_TRI_A) {
+ drawviewborder_triangle(shdr_pos, x1, x2, y1, y2, 0, 'A');
+ }
+
+ if (ca->dtx & CAM_DTX_GOLDEN_TRI_B) {
+ drawviewborder_triangle(shdr_pos, x1, x2, y1, y2, 0, 'B');
+ }
+
+ if (ca->dtx & CAM_DTX_HARMONY_TRI_A) {
+ drawviewborder_triangle(shdr_pos, x1, x2, y1, y2, 1, 'A');
+ }
+
+ if (ca->dtx & CAM_DTX_HARMONY_TRI_B) {
+ drawviewborder_triangle(shdr_pos, x1, x2, y1, y2, 1, 'B');
+ }
+
+ if (ca->flag & CAM_SHOW_SAFE_MARGINS) {
+ UI_draw_safe_areas(
+ shdr_pos, x1, x2, y1, y2, scene->safe_areas.title, scene->safe_areas.action);
+
+ if (ca->flag & CAM_SHOW_SAFE_CENTER) {
+ UI_draw_safe_areas(shdr_pos,
+ x1,
+ x2,
+ y1,
+ y2,
+ scene->safe_areas.title_center,
+ scene->safe_areas.action_center);
+ }
+ }
+
+ if (ca->flag & CAM_SHOWSENSOR) {
+ /* determine sensor fit, and get sensor x/y, for auto fit we
+ * assume and square sensor and only use sensor_x */
+ float sizex = scene->r.xsch * scene->r.xasp;
+ float sizey = scene->r.ysch * scene->r.yasp;
+ int sensor_fit = BKE_camera_sensor_fit(ca->sensor_fit, sizex, sizey);
+ float sensor_x = ca->sensor_x;
+ float sensor_y = (ca->sensor_fit == CAMERA_SENSOR_FIT_AUTO) ? ca->sensor_x : ca->sensor_y;
+
+ /* determine sensor plane */
+ rctf rect;
+
+ if (sensor_fit == CAMERA_SENSOR_FIT_HOR) {
+ float sensor_scale = (x2i - x1i) / sensor_x;
+ float sensor_height = sensor_scale * sensor_y;
+
+ rect.xmin = x1i;
+ rect.xmax = x2i;
+ rect.ymin = (y1i + y2i) * 0.5f - sensor_height * 0.5f;
+ rect.ymax = rect.ymin + sensor_height;
+ }
+ else {
+ float sensor_scale = (y2i - y1i) / sensor_y;
+ float sensor_width = sensor_scale * sensor_x;
+
+ rect.xmin = (x1i + x2i) * 0.5f - sensor_width * 0.5f;
+ rect.xmax = rect.xmin + sensor_width;
+ rect.ymin = y1i;
+ rect.ymax = y2i;
+ }
+
+ /* draw */
+ immUniformThemeColorShade(TH_VIEW_OVERLAY, 100);
+
+ /* TODO Was using UI_draw_roundbox_4fv(false, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 2.0f, color).
+ * We'll probably need a new imm_draw_line_roundbox_dashed dor that - though in practice the
+ * 2.0f round corner effect was nearly not visible anyway... */
+ imm_draw_box_wire_2d(shdr_pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
+ }
+ }
+
+ immUnbindProgram();
+ /* end dashed lines */
+
+ /* camera name - draw in highlighted text color */
+ if (ca && ((v3d->overlay.flag & V3D_OVERLAY_HIDE_TEXT) == 0) && (ca->flag & CAM_SHOWNAME)) {
+ UI_FontThemeColor(BLF_default(), TH_TEXT_HI);
+ BLF_draw_default(x1i,
+ y1i - (0.7f * U.widget_unit),
+ 0.0f,
+ v3d->camera->id.name + 2,
+ sizeof(v3d->camera->id.name) - 2);
+ }
}
static void drawrenderborder(ARegion *ar, View3D *v3d)
{
- /* use the same program for everything */
- uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ /* use the same program for everything */
+ uint shdr_pos = GPU_vertformat_attr_add(
+ immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- GPU_line_width(1.0f);
+ GPU_line_width(1.0f);
- immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
- float viewport_size[4];
- GPU_viewport_size_get_f(viewport_size);
- immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+ float viewport_size[4];
+ GPU_viewport_size_get_f(viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
- immUniform1i("colors_len", 0); /* "simple" mode */
- immUniform4f("color", 1.0f, 0.25f, 0.25f, 1.0f);
- immUniform1f("dash_width", 6.0f);
- immUniform1f("dash_factor", 0.5f);
+ immUniform1i("colors_len", 0); /* "simple" mode */
+ immUniform4f("color", 1.0f, 0.25f, 0.25f, 1.0f);
+ immUniform1f("dash_width", 6.0f);
+ immUniform1f("dash_factor", 0.5f);
- imm_draw_box_wire_2d(shdr_pos,
- v3d->render_border.xmin * ar->winx, v3d->render_border.ymin * ar->winy,
- v3d->render_border.xmax * ar->winx, v3d->render_border.ymax * ar->winy);
+ imm_draw_box_wire_2d(shdr_pos,
+ v3d->render_border.xmin * ar->winx,
+ v3d->render_border.ymin * ar->winy,
+ v3d->render_border.xmax * ar->winx,
+ v3d->render_border.ymax * ar->winy);
- immUnbindProgram();
+ immUnbindProgram();
}
-void ED_view3d_draw_depth(
- Depsgraph *depsgraph,
- ARegion *ar, View3D *v3d, bool alphaoverride)
+void ED_view3d_draw_depth(Depsgraph *depsgraph, ARegion *ar, View3D *v3d, bool alphaoverride)
{
- struct bThemeState theme_state;
- Scene *scene = DEG_get_evaluated_scene(depsgraph);
- RegionView3D *rv3d = ar->regiondata;
+ struct bThemeState theme_state;
+ Scene *scene = DEG_get_evaluated_scene(depsgraph);
+ RegionView3D *rv3d = ar->regiondata;
- short flag = v3d->flag;
- float glalphaclip = U.glalphaclip;
- int obcenter_dia = U.obcenter_dia;
- /* temp set drawtype to solid */
- /* Setting these temporarily is not nice */
- v3d->flag &= ~V3D_SELECT_OUTLINE;
+ short flag = v3d->flag;
+ float glalphaclip = U.glalphaclip;
+ int obcenter_dia = U.obcenter_dia;
+ /* temp set drawtype to solid */
+ /* Setting these temporarily is not nice */
+ v3d->flag &= ~V3D_SELECT_OUTLINE;
- /* not that nice but means we wont zoom into billboards */
- U.glalphaclip = alphaoverride ? 0.5f : glalphaclip;
+ /* not that nice but means we wont zoom into billboards */
+ U.glalphaclip = alphaoverride ? 0.5f : glalphaclip;
- U.obcenter_dia = 0;
+ U.obcenter_dia = 0;
- /* Tools may request depth outside of regular drawing code. */
- UI_Theme_Store(&theme_state);
- UI_SetTheme(SPACE_VIEW3D, RGN_TYPE_WINDOW);
+ /* Tools may request depth outside of regular drawing code. */
+ UI_Theme_Store(&theme_state);
+ UI_SetTheme(SPACE_VIEW3D, RGN_TYPE_WINDOW);
- ED_view3d_draw_setup_view(NULL, depsgraph, scene, ar, v3d, NULL, NULL, NULL);
+ ED_view3d_draw_setup_view(NULL, depsgraph, scene, ar, v3d, NULL, NULL, NULL);
- GPU_clear(GPU_DEPTH_BIT);
+ GPU_clear(GPU_DEPTH_BIT);
- if (rv3d->rflag & RV3D_CLIPPING) {
- ED_view3d_clipping_set(rv3d);
- }
- /* get surface depth without bias */
- rv3d->rflag |= RV3D_ZOFFSET_DISABLED;
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ ED_view3d_clipping_set(rv3d);
+ }
+ /* get surface depth without bias */
+ rv3d->rflag |= RV3D_ZOFFSET_DISABLED;
- GPU_depth_test(true);
+ GPU_depth_test(true);
- GPUViewport *viewport = WM_draw_region_get_viewport(ar, 0);
- DRW_draw_depth_loop(depsgraph, ar, v3d, viewport);
+ GPUViewport *viewport = WM_draw_region_get_viewport(ar, 0);
+ DRW_draw_depth_loop(depsgraph, ar, v3d, viewport);
- if (rv3d->rflag & RV3D_CLIPPING) {
- ED_view3d_clipping_disable();
- }
- rv3d->rflag &= ~RV3D_ZOFFSET_DISABLED;
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ ED_view3d_clipping_disable();
+ }
+ rv3d->rflag &= ~RV3D_ZOFFSET_DISABLED;
- /* Reset default for UI */
- GPU_depth_test(false);
+ /* Reset default for UI */
+ GPU_depth_test(false);
- U.glalphaclip = glalphaclip;
- v3d->flag = flag;
- U.obcenter_dia = obcenter_dia;
+ U.glalphaclip = glalphaclip;
+ v3d->flag = flag;
+ U.obcenter_dia = obcenter_dia;
- UI_Theme_Restore(&theme_state);
+ UI_Theme_Restore(&theme_state);
}
/* ******************** other elements ***************** */
@@ -774,241 +806,244 @@ void ED_view3d_draw_depth(
/** could move this elsewhere, but tied into #ED_view3d_grid_scale */
float ED_scene_grid_scale(Scene *scene, const char **grid_unit)
{
- /* apply units */
- if (scene->unit.system) {
- const void *usys;
- int len;
-
- bUnit_GetSystem(scene->unit.system, B_UNIT_LENGTH, &usys, &len);
-
- if (usys) {
- int i = bUnit_GetBaseUnit(usys);
- if (grid_unit) {
- *grid_unit = bUnit_GetNameDisplay(usys, i);
- }
- return (float)bUnit_GetScaler(usys, i) / scene->unit.scale_length;
- }
- }
-
- return 1.0f;
+ /* apply units */
+ if (scene->unit.system) {
+ const void *usys;
+ int len;
+
+ bUnit_GetSystem(scene->unit.system, B_UNIT_LENGTH, &usys, &len);
+
+ if (usys) {
+ int i = bUnit_GetBaseUnit(usys);
+ if (grid_unit) {
+ *grid_unit = bUnit_GetNameDisplay(usys, i);
+ }
+ return (float)bUnit_GetScaler(usys, i) / scene->unit.scale_length;
+ }
+ }
+
+ return 1.0f;
}
float ED_view3d_grid_scale(Scene *scene, View3D *v3d, const char **grid_unit)
{
- return v3d->grid * ED_scene_grid_scale(scene, grid_unit);
+ return v3d->grid * ED_scene_grid_scale(scene, grid_unit);
}
/* Simulates the grid scale that is actually viewed.
* The actual code is seen in `object_grid_frag.glsl` (see `grid_res`).
* Currently the simulation is only done when RV3D_VIEW_IS_AXIS. */
-float ED_view3d_grid_view_scale(
- Scene *scene, View3D *v3d, RegionView3D *rv3d, const char **grid_unit)
+float ED_view3d_grid_view_scale(Scene *scene,
+ View3D *v3d,
+ RegionView3D *rv3d,
+ const char **grid_unit)
{
- float grid_scale = ED_view3d_grid_scale(scene, v3d, grid_unit);
- if (!rv3d->is_persp && RV3D_VIEW_IS_AXIS(rv3d->view)) {
- /* Decrease the distance between grid snap points depending on zoom. */
- float grid_subdiv = v3d->gridsubdiv;
- if (grid_subdiv > 1) {
- /* Allow 3 more subdivisions (see OBJECT_engine_init). */
- grid_scale /= powf(grid_subdiv, 3);
-
- /* `3.0` was a value obtained by trial and error in order to get
- * a nice snap distance.*/
- float grid_res = 3.0 * (rv3d->dist / v3d->lens);
- float lvl = (logf(grid_res / grid_scale) / logf(grid_subdiv));
-
- CLAMP_MIN(lvl, 0.0f);
-
- grid_scale *= pow(grid_subdiv, (int)lvl);
- }
- }
-
- return grid_scale;
+ float grid_scale = ED_view3d_grid_scale(scene, v3d, grid_unit);
+ if (!rv3d->is_persp && RV3D_VIEW_IS_AXIS(rv3d->view)) {
+ /* Decrease the distance between grid snap points depending on zoom. */
+ float grid_subdiv = v3d->gridsubdiv;
+ if (grid_subdiv > 1) {
+ /* Allow 3 more subdivisions (see OBJECT_engine_init). */
+ grid_scale /= powf(grid_subdiv, 3);
+
+ /* `3.0` was a value obtained by trial and error in order to get
+ * a nice snap distance.*/
+ float grid_res = 3.0 * (rv3d->dist / v3d->lens);
+ float lvl = (logf(grid_res / grid_scale) / logf(grid_subdiv));
+
+ CLAMP_MIN(lvl, 0.0f);
+
+ grid_scale *= pow(grid_subdiv, (int)lvl);
+ }
+ }
+
+ return grid_scale;
}
static void draw_view_axis(RegionView3D *rv3d, const rcti *rect)
{
- const float k = U.rvisize * U.pixelsize; /* axis size */
- /* axis alpha offset (rvibright has range 0-10) */
- const int bright = - 20 * (10 - U.rvibright);
-
- /* Axis center in screen coordinates.
- *
- * - Unit size offset so small text doesn't draw outside the screen
- * - Extra X offset because of the panel expander.
- */
- const float startx = rect->xmax - (k + UI_UNIT_X * 1.5);
- const float starty = rect->ymax - (k + UI_UNIT_Y);
-
- float axis_pos[3][2];
- uchar axis_col[3][4];
-
- int axis_order[3] = {0, 1, 2};
- axis_sort_v3(rv3d->viewinv[2], axis_order);
-
- for (int axis_i = 0; axis_i < 3; axis_i++) {
- int i = axis_order[axis_i];
-
- /* get position of each axis tip on screen */
- float vec[3] = { 0.0f };
- vec[i] = 1.0f;
- mul_qt_v3(rv3d->viewquat, vec);
- axis_pos[i][0] = startx + vec[0] * k;
- axis_pos[i][1] = starty + vec[1] * k;
-
- /* get color of each axis */
- UI_GetThemeColorShade3ubv(TH_AXIS_X + i, bright, axis_col[i]); /* rgb */
- axis_col[i][3] = 255 * hypotf(vec[0], vec[1]); /* alpha */
- }
-
- /* draw axis lines */
- GPU_line_width(2.0f);
- GPU_line_smooth(true);
- GPU_blend(true);
- GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
-
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
-
- immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
- immBegin(GPU_PRIM_LINES, 6);
-
- for (int axis_i = 0; axis_i < 3; axis_i++) {
- int i = axis_order[axis_i];
-
- immAttr4ubv(col, axis_col[i]);
- immVertex2f(pos, startx, starty);
- immAttr4ubv(col, axis_col[i]);
- immVertex2fv(pos, axis_pos[i]);
- }
-
- immEnd();
- immUnbindProgram();
- GPU_line_smooth(false);
-
- /* draw axis names */
- for (int axis_i = 0; axis_i < 3; axis_i++) {
- int i = axis_order[axis_i];
-
- const char axis_text[2] = {'x' + i, '\0'};
- BLF_color4ubv(BLF_default(), axis_col[i]);
- BLF_draw_default_ascii(axis_pos[i][0] + 2, axis_pos[i][1] + 2, 0.0f, axis_text, 1);
- }
+ const float k = U.rvisize * U.pixelsize; /* axis size */
+ /* axis alpha offset (rvibright has range 0-10) */
+ const int bright = -20 * (10 - U.rvibright);
+
+ /* Axis center in screen coordinates.
+ *
+ * - Unit size offset so small text doesn't draw outside the screen
+ * - Extra X offset because of the panel expander.
+ */
+ const float startx = rect->xmax - (k + UI_UNIT_X * 1.5);
+ const float starty = rect->ymax - (k + UI_UNIT_Y);
+
+ float axis_pos[3][2];
+ uchar axis_col[3][4];
+
+ int axis_order[3] = {0, 1, 2};
+ axis_sort_v3(rv3d->viewinv[2], axis_order);
+
+ for (int axis_i = 0; axis_i < 3; axis_i++) {
+ int i = axis_order[axis_i];
+
+ /* get position of each axis tip on screen */
+ float vec[3] = {0.0f};
+ vec[i] = 1.0f;
+ mul_qt_v3(rv3d->viewquat, vec);
+ axis_pos[i][0] = startx + vec[0] * k;
+ axis_pos[i][1] = starty + vec[1] * k;
+
+ /* get color of each axis */
+ UI_GetThemeColorShade3ubv(TH_AXIS_X + i, bright, axis_col[i]); /* rgb */
+ axis_col[i][3] = 255 * hypotf(vec[0], vec[1]); /* alpha */
+ }
+
+ /* draw axis lines */
+ GPU_line_width(2.0f);
+ GPU_line_smooth(true);
+ GPU_blend(true);
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
+ immBegin(GPU_PRIM_LINES, 6);
+
+ for (int axis_i = 0; axis_i < 3; axis_i++) {
+ int i = axis_order[axis_i];
+
+ immAttr4ubv(col, axis_col[i]);
+ immVertex2f(pos, startx, starty);
+ immAttr4ubv(col, axis_col[i]);
+ immVertex2fv(pos, axis_pos[i]);
+ }
+
+ immEnd();
+ immUnbindProgram();
+ GPU_line_smooth(false);
+
+ /* draw axis names */
+ for (int axis_i = 0; axis_i < 3; axis_i++) {
+ int i = axis_order[axis_i];
+
+ const char axis_text[2] = {'x' + i, '\0'};
+ BLF_color4ubv(BLF_default(), axis_col[i]);
+ BLF_draw_default_ascii(axis_pos[i][0] + 2, axis_pos[i][1] + 2, 0.0f, axis_text, 1);
+ }
}
#ifdef WITH_INPUT_NDOF
/* draw center and axis of rotation for ongoing 3D mouse navigation */
static void draw_rotation_guide(const RegionView3D *rv3d)
{
- float o[3]; /* center of rotation */
- float end[3]; /* endpoints for drawing */
-
- GLubyte color[4] = {0, 108, 255, 255}; /* bright blue so it matches device LEDs */
-
- negate_v3_v3(o, rv3d->ofs);
-
- GPU_blend(true);
- GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- glDepthMask(GL_FALSE); /* don't overwrite zbuf */
-
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
-
- immBindBuiltinProgram(GPU_SHADER_3D_SMOOTH_COLOR);
-
- if (rv3d->rot_angle != 0.0f) {
- /* -- draw rotation axis -- */
- float scaled_axis[3];
- const float scale = rv3d->dist;
- mul_v3_v3fl(scaled_axis, rv3d->rot_axis, scale);
-
-
- immBegin(GPU_PRIM_LINE_STRIP, 3);
- color[3] = 0; /* more transparent toward the ends */
- immAttr4ubv(col, color);
- add_v3_v3v3(end, o, scaled_axis);
- immVertex3fv(pos, end);
-
-#if 0
- color[3] = 0.2f + fabsf(rv3d->rot_angle); /* modulate opacity with angle */
- /* ^^ neat idea, but angle is frame-rate dependent, so it's usually close to 0.2 */
-#endif
-
- color[3] = 127; /* more opaque toward the center */
- immAttr4ubv(col, color);
- immVertex3fv(pos, o);
-
- color[3] = 0;
- immAttr4ubv(col, color);
- sub_v3_v3v3(end, o, scaled_axis);
- immVertex3fv(pos, end);
- immEnd();
-
- /* -- draw ring around rotation center -- */
- {
-#define ROT_AXIS_DETAIL 13
-
- const float s = 0.05f * scale;
- const float step = 2.0f * (float)(M_PI / ROT_AXIS_DETAIL);
-
- float q[4]; /* rotate ring so it's perpendicular to axis */
- const int upright = fabsf(rv3d->rot_axis[2]) >= 0.95f;
- if (!upright) {
- const float up[3] = {0.0f, 0.0f, 1.0f};
- float vis_angle, vis_axis[3];
-
- cross_v3_v3v3(vis_axis, up, rv3d->rot_axis);
- vis_angle = acosf(dot_v3v3(up, rv3d->rot_axis));
- axis_angle_to_quat(q, vis_axis, vis_angle);
- }
-
- immBegin(GPU_PRIM_LINE_LOOP, ROT_AXIS_DETAIL);
- color[3] = 63; /* somewhat faint */
- immAttr4ubv(col, color);
- float angle = 0.0f;
- for (int i = 0; i < ROT_AXIS_DETAIL; ++i, angle += step) {
- float p[3] = {s * cosf(angle), s * sinf(angle), 0.0f};
-
- if (!upright) {
- mul_qt_v3(q, p);
- }
-
- add_v3_v3(p, o);
- immVertex3fv(pos, p);
- }
- immEnd();
-
-#undef ROT_AXIS_DETAIL
- }
-
- color[3] = 255; /* solid dot */
- }
- else {
- color[3] = 127; /* see-through dot */
- }
-
- immUnbindProgram();
-
- /* -- draw rotation center -- */
- immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR);
- GPU_point_size(5.0f);
- immBegin(GPU_PRIM_POINTS, 1);
- immAttr4ubv(col, color);
- immVertex3fv(pos, o);
- immEnd();
- immUnbindProgram();
-
-#if 0
- /* find screen coordinates for rotation center, then draw pretty icon */
- mul_m4_v3(rv3d->persinv, rot_center);
- UI_icon_draw(rot_center[0], rot_center[1], ICON_NDOF_TURN);
- /* ^^ just playing around, does not work */
-#endif
-
- GPU_blend(false);
- glDepthMask(GL_TRUE);
+ float o[3]; /* center of rotation */
+ float end[3]; /* endpoints for drawing */
+
+ GLubyte color[4] = {0, 108, 255, 255}; /* bright blue so it matches device LEDs */
+
+ negate_v3_v3(o, rv3d->ofs);
+
+ GPU_blend(true);
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ glDepthMask(GL_FALSE); /* don't overwrite zbuf */
+
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_SMOOTH_COLOR);
+
+ if (rv3d->rot_angle != 0.0f) {
+ /* -- draw rotation axis -- */
+ float scaled_axis[3];
+ const float scale = rv3d->dist;
+ mul_v3_v3fl(scaled_axis, rv3d->rot_axis, scale);
+
+ immBegin(GPU_PRIM_LINE_STRIP, 3);
+ color[3] = 0; /* more transparent toward the ends */
+ immAttr4ubv(col, color);
+ add_v3_v3v3(end, o, scaled_axis);
+ immVertex3fv(pos, end);
+
+# if 0
+ color[3] = 0.2f + fabsf(rv3d->rot_angle); /* modulate opacity with angle */
+ /* ^^ neat idea, but angle is frame-rate dependent, so it's usually close to 0.2 */
+# endif
+
+ color[3] = 127; /* more opaque toward the center */
+ immAttr4ubv(col, color);
+ immVertex3fv(pos, o);
+
+ color[3] = 0;
+ immAttr4ubv(col, color);
+ sub_v3_v3v3(end, o, scaled_axis);
+ immVertex3fv(pos, end);
+ immEnd();
+
+ /* -- draw ring around rotation center -- */
+ {
+# define ROT_AXIS_DETAIL 13
+
+ const float s = 0.05f * scale;
+ const float step = 2.0f * (float)(M_PI / ROT_AXIS_DETAIL);
+
+ float q[4]; /* rotate ring so it's perpendicular to axis */
+ const int upright = fabsf(rv3d->rot_axis[2]) >= 0.95f;
+ if (!upright) {
+ const float up[3] = {0.0f, 0.0f, 1.0f};
+ float vis_angle, vis_axis[3];
+
+ cross_v3_v3v3(vis_axis, up, rv3d->rot_axis);
+ vis_angle = acosf(dot_v3v3(up, rv3d->rot_axis));
+ axis_angle_to_quat(q, vis_axis, vis_angle);
+ }
+
+ immBegin(GPU_PRIM_LINE_LOOP, ROT_AXIS_DETAIL);
+ color[3] = 63; /* somewhat faint */
+ immAttr4ubv(col, color);
+ float angle = 0.0f;
+ for (int i = 0; i < ROT_AXIS_DETAIL; ++i, angle += step) {
+ float p[3] = {s * cosf(angle), s * sinf(angle), 0.0f};
+
+ if (!upright) {
+ mul_qt_v3(q, p);
+ }
+
+ add_v3_v3(p, o);
+ immVertex3fv(pos, p);
+ }
+ immEnd();
+
+# undef ROT_AXIS_DETAIL
+ }
+
+ color[3] = 255; /* solid dot */
+ }
+ else {
+ color[3] = 127; /* see-through dot */
+ }
+
+ immUnbindProgram();
+
+ /* -- draw rotation center -- */
+ immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR);
+ GPU_point_size(5.0f);
+ immBegin(GPU_PRIM_POINTS, 1);
+ immAttr4ubv(col, color);
+ immVertex3fv(pos, o);
+ immEnd();
+ immUnbindProgram();
+
+# if 0
+ /* find screen coordinates for rotation center, then draw pretty icon */
+ mul_m4_v3(rv3d->persinv, rot_center);
+ UI_icon_draw(rot_center[0], rot_center[1], ICON_NDOF_TURN);
+ /* ^^ just playing around, does not work */
+# endif
+
+ GPU_blend(false);
+ glDepthMask(GL_TRUE);
}
#endif /* WITH_INPUT_NDOF */
@@ -1017,17 +1052,17 @@ static void draw_rotation_guide(const RegionView3D *rv3d)
*/
static void view3d_draw_border(const bContext *C, ARegion *ar)
{
- Scene *scene = CTX_data_scene(C);
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- RegionView3D *rv3d = ar->regiondata;
- View3D *v3d = CTX_wm_view3d(C);
-
- if (rv3d->persp == RV3D_CAMOB) {
- drawviewborder(scene, depsgraph, ar, v3d);
- }
- else if (v3d->flag2 & V3D_RENDER_BORDER) {
- drawrenderborder(ar, v3d);
- }
+ Scene *scene = CTX_data_scene(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ RegionView3D *rv3d = ar->regiondata;
+ View3D *v3d = CTX_wm_view3d(C);
+
+ if (rv3d->persp == RV3D_CAMOB) {
+ drawviewborder(scene, depsgraph, ar, v3d);
+ }
+ else if (v3d->flag2 & V3D_RENDER_BORDER) {
+ drawrenderborder(ar, v3d);
+ }
}
/** \} */
@@ -1041,7 +1076,7 @@ static void view3d_draw_border(const bContext *C, ARegion *ar)
*/
static void view3d_draw_grease_pencil(const bContext *UNUSED(C))
{
- /* TODO viewport */
+ /* TODO viewport */
}
/**
@@ -1049,119 +1084,120 @@ static void view3d_draw_grease_pencil(const bContext *UNUSED(C))
*/
static const char *view3d_get_name(View3D *v3d, RegionView3D *rv3d)
{
- const char *name = NULL;
-
- switch (rv3d->view) {
- case RV3D_VIEW_FRONT:
- if (rv3d->persp == RV3D_ORTHO) {
- name = IFACE_("Front Orthographic");
- }
- else {
- name = IFACE_("Front Perspective");
- }
- break;
- case RV3D_VIEW_BACK:
- if (rv3d->persp == RV3D_ORTHO) {
- name = IFACE_("Back Orthographic");
- }
- else {
- name = IFACE_("Back Perspective");
- }
- break;
- case RV3D_VIEW_TOP:
- if (rv3d->persp == RV3D_ORTHO) {
- name = IFACE_("Top Orthographic");
- }
- else {
- name = IFACE_("Top Perspective");
- }
- break;
- case RV3D_VIEW_BOTTOM:
- if (rv3d->persp == RV3D_ORTHO) {
- name = IFACE_("Bottom Orthographic");
- }
- else {
- name = IFACE_("Bottom Perspective");
- }
- break;
- case RV3D_VIEW_RIGHT:
- if (rv3d->persp == RV3D_ORTHO) {
- name = IFACE_("Right Orthographic");
- }
- else {
- name = IFACE_("Right Perspective");
- }
- break;
- case RV3D_VIEW_LEFT:
- if (rv3d->persp == RV3D_ORTHO) {
- name = IFACE_("Left Orthographic");
- }
- else {
- name = IFACE_("Left Perspective");
- }
- break;
-
- default:
- if (rv3d->persp == RV3D_CAMOB) {
- if ((v3d->camera) && (v3d->camera->type == OB_CAMERA)) {
- Camera *cam;
- cam = v3d->camera->data;
- if (cam->type == CAM_PERSP) {
- name = IFACE_("Camera Perspective");
- }
- else if (cam->type == CAM_ORTHO) {
- name = IFACE_("Camera Orthographic");
- }
- else {
- BLI_assert(cam->type == CAM_PANO);
- name = IFACE_("Camera Panoramic");
- }
- }
- else {
- name = IFACE_("Object as Camera");
- }
- }
- else {
- name = (rv3d->persp == RV3D_ORTHO) ? IFACE_("User Orthographic") : IFACE_("User Perspective");
- }
- }
-
- return name;
+ const char *name = NULL;
+
+ switch (rv3d->view) {
+ case RV3D_VIEW_FRONT:
+ if (rv3d->persp == RV3D_ORTHO) {
+ name = IFACE_("Front Orthographic");
+ }
+ else {
+ name = IFACE_("Front Perspective");
+ }
+ break;
+ case RV3D_VIEW_BACK:
+ if (rv3d->persp == RV3D_ORTHO) {
+ name = IFACE_("Back Orthographic");
+ }
+ else {
+ name = IFACE_("Back Perspective");
+ }
+ break;
+ case RV3D_VIEW_TOP:
+ if (rv3d->persp == RV3D_ORTHO) {
+ name = IFACE_("Top Orthographic");
+ }
+ else {
+ name = IFACE_("Top Perspective");
+ }
+ break;
+ case RV3D_VIEW_BOTTOM:
+ if (rv3d->persp == RV3D_ORTHO) {
+ name = IFACE_("Bottom Orthographic");
+ }
+ else {
+ name = IFACE_("Bottom Perspective");
+ }
+ break;
+ case RV3D_VIEW_RIGHT:
+ if (rv3d->persp == RV3D_ORTHO) {
+ name = IFACE_("Right Orthographic");
+ }
+ else {
+ name = IFACE_("Right Perspective");
+ }
+ break;
+ case RV3D_VIEW_LEFT:
+ if (rv3d->persp == RV3D_ORTHO) {
+ name = IFACE_("Left Orthographic");
+ }
+ else {
+ name = IFACE_("Left Perspective");
+ }
+ break;
+
+ default:
+ if (rv3d->persp == RV3D_CAMOB) {
+ if ((v3d->camera) && (v3d->camera->type == OB_CAMERA)) {
+ Camera *cam;
+ cam = v3d->camera->data;
+ if (cam->type == CAM_PERSP) {
+ name = IFACE_("Camera Perspective");
+ }
+ else if (cam->type == CAM_ORTHO) {
+ name = IFACE_("Camera Orthographic");
+ }
+ else {
+ BLI_assert(cam->type == CAM_PANO);
+ name = IFACE_("Camera Panoramic");
+ }
+ }
+ else {
+ name = IFACE_("Object as Camera");
+ }
+ }
+ else {
+ name = (rv3d->persp == RV3D_ORTHO) ? IFACE_("User Orthographic") :
+ IFACE_("User Perspective");
+ }
+ }
+
+ return name;
}
static void draw_viewport_name(ARegion *ar, View3D *v3d, int xoffset, int *yoffset)
{
- RegionView3D *rv3d = ar->regiondata;
- const char *name = view3d_get_name(v3d, rv3d);
- const int font_id = BLF_default();
+ RegionView3D *rv3d = ar->regiondata;
+ const char *name = view3d_get_name(v3d, rv3d);
+ const int font_id = BLF_default();
- /* increase size for unicode languages (Chinese in utf-8...) */
+ /* increase size for unicode languages (Chinese in utf-8...) */
#ifdef WITH_INTERNATIONAL
- char tmpstr[96];
+ char tmpstr[96];
#else
- char tmpstr[32];
+ char tmpstr[32];
#endif
- BLF_enable(font_id, BLF_SHADOW);
- BLF_shadow(font_id, 5, (const float[4]){0.0f, 0.0f, 0.0f, 1.0f});
- BLF_shadow_offset(font_id, 1, -1);
+ BLF_enable(font_id, BLF_SHADOW);
+ BLF_shadow(font_id, 5, (const float[4]){0.0f, 0.0f, 0.0f, 1.0f});
+ BLF_shadow_offset(font_id, 1, -1);
- if (v3d->localvd) {
- BLI_snprintf(tmpstr, sizeof(tmpstr), IFACE_("%s (Local)"), name);
- name = tmpstr;
- }
+ if (v3d->localvd) {
+ BLI_snprintf(tmpstr, sizeof(tmpstr), IFACE_("%s (Local)"), name);
+ name = tmpstr;
+ }
- UI_FontThemeColor(BLF_default(), TH_TEXT_HI);
+ UI_FontThemeColor(BLF_default(), TH_TEXT_HI);
- *yoffset -= U.widget_unit;
+ *yoffset -= U.widget_unit;
#ifdef WITH_INTERNATIONAL
- BLF_draw_default(xoffset, *yoffset, 0.0f, name, sizeof(tmpstr));
+ BLF_draw_default(xoffset, *yoffset, 0.0f, name, sizeof(tmpstr));
#else
- BLF_draw_default_ascii(xoffset, *yoffset, 0.0f, name, sizeof(tmpstr));
+ BLF_draw_default_ascii(xoffset, *yoffset, 0.0f, name, sizeof(tmpstr));
#endif
- BLF_disable(font_id, BLF_SHADOW);
+ BLF_disable(font_id, BLF_SHADOW);
}
/**
@@ -1169,125 +1205,130 @@ static void draw_viewport_name(ARegion *ar, View3D *v3d, int xoffset, int *yoffs
* framenum, collection, object name, bone name (if available), marker name (if available)
*/
-static void draw_selected_name(Scene *scene, ViewLayer *view_layer, Object *ob, int xoffset, int *yoffset)
+static void draw_selected_name(
+ Scene *scene, ViewLayer *view_layer, Object *ob, int xoffset, int *yoffset)
{
- const int cfra = CFRA;
- const char *msg_pin = " (Pinned)";
- const char *msg_sep = " : ";
-
- const int font_id = BLF_default();
-
- char info[300];
- char *s = info;
-
- s += sprintf(s, "(%d)", cfra);
-
- if ((ob == NULL) || (ob->mode == OB_MODE_OBJECT)) {
- LayerCollection *layer_collection = view_layer->active_collection;
- s += sprintf(s, " %s%s", BKE_collection_ui_name_get(layer_collection->collection), (ob == NULL) ? "" : " |");
- }
-
- /*
- * info can contain:
- * - a frame (7 + 2)
- * - a collection name (MAX_NAME + 3)
- * - 3 object names (MAX_NAME)
- * - 2 BREAD_CRUMB_SEPARATORs (6)
- * - a SHAPE_KEY_PINNED marker and a trailing '\0' (9+1) - translated, so give some room!
- * - a marker name (MAX_NAME + 3)
- */
-
- /* get name of marker on current frame (if available) */
- const char *markern = BKE_scene_find_marker_name(scene, cfra);
-
- /* check if there is an object */
- if (ob) {
- *s++ = ' ';
- s += BLI_strcpy_rlen(s, ob->id.name + 2);
-
- /* name(s) to display depends on type of object */
- if (ob->type == OB_ARMATURE) {
- bArmature *arm = ob->data;
-
- /* show name of active bone too (if possible) */
- if (arm->edbo) {
- if (arm->act_edbone) {
- s += BLI_strcpy_rlen(s, msg_sep);
- s += BLI_strcpy_rlen(s, arm->act_edbone->name);
- }
- }
- else if (ob->mode & OB_MODE_POSE) {
- if (arm->act_bone) {
-
- if (arm->act_bone->layer & arm->layer) {
- s += BLI_strcpy_rlen(s, msg_sep);
- s += BLI_strcpy_rlen(s, arm->act_bone->name);
- }
- }
- }
- }
- else if (ELEM(ob->type, OB_MESH, OB_LATTICE, OB_CURVE)) {
- /* try to display active bone and active shapekey too (if they exist) */
-
- if (ob->type == OB_MESH && ob->mode & OB_MODE_WEIGHT_PAINT) {
- Object *armobj = BKE_object_pose_armature_get(ob);
- if (armobj && armobj->mode & OB_MODE_POSE) {
- bArmature *arm = armobj->data;
- if (arm->act_bone) {
- if (arm->act_bone->layer & arm->layer) {
- s += BLI_strcpy_rlen(s, msg_sep);
- s += BLI_strcpy_rlen(s, arm->act_bone->name);
- }
- }
- }
- }
-
- Key *key = BKE_key_from_object(ob);
- if (key) {
- KeyBlock *kb = BLI_findlink(&key->block, ob->shapenr - 1);
- if (kb) {
- s += BLI_strcpy_rlen(s, msg_sep);
- s += BLI_strcpy_rlen(s, kb->name);
- if (ob->shapeflag & OB_SHAPE_LOCK) {
- s += BLI_strcpy_rlen(s, IFACE_(msg_pin));
- }
- }
- }
- }
-
- /* color depends on whether there is a keyframe */
- if (id_frame_has_keyframe((ID *)ob, /* BKE_scene_frame_get(scene) */ (float)cfra, ANIMFILTER_KEYS_LOCAL)) {
- UI_FontThemeColor(font_id, TH_TIME_KEYFRAME);
- }
- else if (ED_gpencil_has_keyframe_v3d(scene, ob, cfra)) {
- UI_FontThemeColor(font_id, TH_TIME_GP_KEYFRAME);
- }
- else {
- UI_FontThemeColor(font_id, TH_TEXT_HI);
- }
- }
- else {
- /* no object */
- if (ED_gpencil_has_keyframe_v3d(scene, NULL, cfra)) {
- UI_FontThemeColor(font_id, TH_TIME_GP_KEYFRAME);
- }
- else {
- UI_FontThemeColor(font_id, TH_TEXT_HI);
- }
- }
-
- if (markern) {
- s += sprintf(s, " <%s>", markern);
- }
-
- BLF_enable(font_id, BLF_SHADOW);
- BLF_shadow(font_id, 5, (const float[4]){0.0f, 0.0f, 0.0f, 1.0f});
- BLF_shadow_offset(font_id, 1, -1);
-
- *yoffset -= U.widget_unit;
- BLF_draw_default(xoffset, *yoffset, 0.0f, info, sizeof(info));
-
- BLF_disable(font_id, BLF_SHADOW);
+ const int cfra = CFRA;
+ const char *msg_pin = " (Pinned)";
+ const char *msg_sep = " : ";
+
+ const int font_id = BLF_default();
+
+ char info[300];
+ char *s = info;
+
+ s += sprintf(s, "(%d)", cfra);
+
+ if ((ob == NULL) || (ob->mode == OB_MODE_OBJECT)) {
+ LayerCollection *layer_collection = view_layer->active_collection;
+ s += sprintf(s,
+ " %s%s",
+ BKE_collection_ui_name_get(layer_collection->collection),
+ (ob == NULL) ? "" : " |");
+ }
+
+ /*
+ * info can contain:
+ * - a frame (7 + 2)
+ * - a collection name (MAX_NAME + 3)
+ * - 3 object names (MAX_NAME)
+ * - 2 BREAD_CRUMB_SEPARATORs (6)
+ * - a SHAPE_KEY_PINNED marker and a trailing '\0' (9+1) - translated, so give some room!
+ * - a marker name (MAX_NAME + 3)
+ */
+
+ /* get name of marker on current frame (if available) */
+ const char *markern = BKE_scene_find_marker_name(scene, cfra);
+
+ /* check if there is an object */
+ if (ob) {
+ *s++ = ' ';
+ s += BLI_strcpy_rlen(s, ob->id.name + 2);
+
+ /* name(s) to display depends on type of object */
+ if (ob->type == OB_ARMATURE) {
+ bArmature *arm = ob->data;
+
+ /* show name of active bone too (if possible) */
+ if (arm->edbo) {
+ if (arm->act_edbone) {
+ s += BLI_strcpy_rlen(s, msg_sep);
+ s += BLI_strcpy_rlen(s, arm->act_edbone->name);
+ }
+ }
+ else if (ob->mode & OB_MODE_POSE) {
+ if (arm->act_bone) {
+
+ if (arm->act_bone->layer & arm->layer) {
+ s += BLI_strcpy_rlen(s, msg_sep);
+ s += BLI_strcpy_rlen(s, arm->act_bone->name);
+ }
+ }
+ }
+ }
+ else if (ELEM(ob->type, OB_MESH, OB_LATTICE, OB_CURVE)) {
+ /* try to display active bone and active shapekey too (if they exist) */
+
+ if (ob->type == OB_MESH && ob->mode & OB_MODE_WEIGHT_PAINT) {
+ Object *armobj = BKE_object_pose_armature_get(ob);
+ if (armobj && armobj->mode & OB_MODE_POSE) {
+ bArmature *arm = armobj->data;
+ if (arm->act_bone) {
+ if (arm->act_bone->layer & arm->layer) {
+ s += BLI_strcpy_rlen(s, msg_sep);
+ s += BLI_strcpy_rlen(s, arm->act_bone->name);
+ }
+ }
+ }
+ }
+
+ Key *key = BKE_key_from_object(ob);
+ if (key) {
+ KeyBlock *kb = BLI_findlink(&key->block, ob->shapenr - 1);
+ if (kb) {
+ s += BLI_strcpy_rlen(s, msg_sep);
+ s += BLI_strcpy_rlen(s, kb->name);
+ if (ob->shapeflag & OB_SHAPE_LOCK) {
+ s += BLI_strcpy_rlen(s, IFACE_(msg_pin));
+ }
+ }
+ }
+ }
+
+ /* color depends on whether there is a keyframe */
+ if (id_frame_has_keyframe(
+ (ID *)ob, /* BKE_scene_frame_get(scene) */ (float)cfra, ANIMFILTER_KEYS_LOCAL)) {
+ UI_FontThemeColor(font_id, TH_TIME_KEYFRAME);
+ }
+ else if (ED_gpencil_has_keyframe_v3d(scene, ob, cfra)) {
+ UI_FontThemeColor(font_id, TH_TIME_GP_KEYFRAME);
+ }
+ else {
+ UI_FontThemeColor(font_id, TH_TEXT_HI);
+ }
+ }
+ else {
+ /* no object */
+ if (ED_gpencil_has_keyframe_v3d(scene, NULL, cfra)) {
+ UI_FontThemeColor(font_id, TH_TIME_GP_KEYFRAME);
+ }
+ else {
+ UI_FontThemeColor(font_id, TH_TEXT_HI);
+ }
+ }
+
+ if (markern) {
+ s += sprintf(s, " <%s>", markern);
+ }
+
+ BLF_enable(font_id, BLF_SHADOW);
+ BLF_shadow(font_id, 5, (const float[4]){0.0f, 0.0f, 0.0f, 1.0f});
+ BLF_shadow_offset(font_id, 1, -1);
+
+ *yoffset -= U.widget_unit;
+ BLF_draw_default(xoffset, *yoffset, 0.0f, info, sizeof(info));
+
+ BLF_disable(font_id, BLF_SHADOW);
}
/**
@@ -1295,83 +1336,77 @@ static void draw_selected_name(Scene *scene, ViewLayer *view_layer, Object *ob,
*/
void view3d_draw_region_info(const bContext *C, ARegion *ar)
{
- RegionView3D *rv3d = ar->regiondata;
- View3D *v3d = CTX_wm_view3d(C);
- Scene *scene = CTX_data_scene(C);
- wmWindowManager *wm = CTX_wm_manager(C);
+ RegionView3D *rv3d = ar->regiondata;
+ View3D *v3d = CTX_wm_view3d(C);
+ Scene *scene = CTX_data_scene(C);
+ wmWindowManager *wm = CTX_wm_manager(C);
#ifdef WITH_INPUT_NDOF
- if ((U.ndof_flag & NDOF_SHOW_GUIDE) &&
- ((rv3d->viewlock & RV3D_LOCKED) == 0) &&
- (rv3d->persp != RV3D_CAMOB))
- {
- /* TODO: draw something else (but not this) during fly mode */
- draw_rotation_guide(rv3d);
- }
+ if ((U.ndof_flag & NDOF_SHOW_GUIDE) && ((rv3d->viewlock & RV3D_LOCKED) == 0) &&
+ (rv3d->persp != RV3D_CAMOB)) {
+ /* TODO: draw something else (but not this) during fly mode */
+ draw_rotation_guide(rv3d);
+ }
#endif
- /* correct projection matrix */
- ED_region_pixelspace(ar);
+ /* correct projection matrix */
+ ED_region_pixelspace(ar);
- /* local coordinate visible rect inside region, to accommodate overlapping ui */
- rcti rect;
- ED_region_visible_rect(ar, &rect);
+ /* local coordinate visible rect inside region, to accommodate overlapping ui */
+ rcti rect;
+ ED_region_visible_rect(ar, &rect);
+ view3d_draw_border(C, ar);
+ view3d_draw_grease_pencil(C);
- view3d_draw_border(C, ar);
- view3d_draw_grease_pencil(C);
+ BLF_batch_draw_begin();
- BLF_batch_draw_begin();
+ if ((U.uiflag & USER_SHOW_GIZMO_AXIS) ||
+ /* No need to display gizmo and this info. */
+ (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_NAVIGATE))) {
+ /* pass */
+ }
+ else {
+ draw_view_axis(rv3d, &rect);
+ }
- if ((U.uiflag & USER_SHOW_GIZMO_AXIS) ||
- /* No need to display gizmo and this info. */
- (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_NAVIGATE)))
- {
- /* pass */
- }
- else {
- draw_view_axis(rv3d, &rect);
- }
+ int xoffset = rect.xmin + U.widget_unit;
+ int yoffset = rect.ymax;
- int xoffset = rect.xmin + U.widget_unit;
- int yoffset = rect.ymax;
+ if ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0 && (v3d->overlay.flag & V3D_OVERLAY_HIDE_TEXT) == 0) {
+ if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_no_scrub(wm)) {
+ ED_scene_draw_fps(scene, xoffset, &yoffset);
+ }
+ else if (U.uiflag & USER_SHOW_VIEWPORTNAME) {
+ draw_viewport_name(ar, v3d, xoffset, &yoffset);
+ }
- if ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0 &&
- (v3d->overlay.flag & V3D_OVERLAY_HIDE_TEXT) == 0)
- {
- if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_no_scrub(wm)) {
- ED_scene_draw_fps(scene, xoffset, &yoffset);
- }
- else if (U.uiflag & USER_SHOW_VIEWPORTNAME) {
- draw_viewport_name(ar, v3d, xoffset, &yoffset);
- }
-
- if (U.uiflag & USER_DRAWVIEWINFO) {
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *ob = OBACT(view_layer);
- draw_selected_name(scene, view_layer, ob, xoffset, &yoffset);
- }
+ if (U.uiflag & USER_DRAWVIEWINFO) {
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *ob = OBACT(view_layer);
+ draw_selected_name(scene, view_layer, ob, xoffset, &yoffset);
+ }
#if 0 /* TODO */
- if (grid_unit) { /* draw below the viewport name */
- char numstr[32] = "";
+ if (grid_unit) { /* draw below the viewport name */
+ char numstr[32] = "";
- UI_FontThemeColor(BLF_default(), TH_TEXT_HI);
- if (v3d->grid != 1.0f) {
- BLI_snprintf(numstr, sizeof(numstr), "%s x %.4g", grid_unit, v3d->grid);
- }
+ UI_FontThemeColor(BLF_default(), TH_TEXT_HI);
+ if (v3d->grid != 1.0f) {
+ BLI_snprintf(numstr, sizeof(numstr), "%s x %.4g", grid_unit, v3d->grid);
+ }
- *yoffset -= U.widget_unit;
- BLF_draw_default_ascii(xoffset, *yoffset, numstr[0] ? numstr : grid_unit, sizeof(numstr));
- }
+ *yoffset -= U.widget_unit;
+ BLF_draw_default_ascii(xoffset, *yoffset, numstr[0] ? numstr : grid_unit, sizeof(numstr));
+ }
#endif
- }
+ }
- if ((v3d->overlay.flag & V3D_OVERLAY_HIDE_TEXT) == 0) {
- DRW_draw_region_engine_info(xoffset, yoffset);
- }
+ if ((v3d->overlay.flag & V3D_OVERLAY_HIDE_TEXT) == 0) {
+ DRW_draw_region_engine_info(xoffset, yoffset);
+ }
- BLF_batch_draw_end();
+ BLF_batch_draw_end();
}
/** \} */
@@ -1382,43 +1417,50 @@ void view3d_draw_region_info(const bContext *C, ARegion *ar)
static void view3d_draw_view(const bContext *C, ARegion *ar)
{
- ED_view3d_draw_setup_view(CTX_wm_window(C), CTX_data_depsgraph(C), CTX_data_scene(C), ar, CTX_wm_view3d(C), NULL, NULL, NULL);
-
- /* Only 100% compliant on new spec goes below */
- DRW_draw_view(C);
+ ED_view3d_draw_setup_view(CTX_wm_window(C),
+ CTX_data_depsgraph(C),
+ CTX_data_scene(C),
+ ar,
+ CTX_wm_view3d(C),
+ NULL,
+ NULL,
+ NULL);
+
+ /* Only 100% compliant on new spec goes below */
+ DRW_draw_view(C);
}
RenderEngineType *ED_view3d_engine_type(Scene *scene, int drawtype)
{
- /*
- * Temporary viewport draw modes until we have a proper system.
- * all modes are done in the draw manager, except
- * cycles material as it is an external render engine.
- */
- if (strcmp(scene->r.engine, RE_engine_id_CYCLES) == 0 && drawtype == OB_MATERIAL) {
- return RE_engines_find(RE_engine_id_BLENDER_EEVEE);
- }
- return RE_engines_find(scene->r.engine);
+ /*
+ * Temporary viewport draw modes until we have a proper system.
+ * all modes are done in the draw manager, except
+ * cycles material as it is an external render engine.
+ */
+ if (strcmp(scene->r.engine, RE_engine_id_CYCLES) == 0 && drawtype == OB_MATERIAL) {
+ return RE_engines_find(RE_engine_id_BLENDER_EEVEE);
+ }
+ return RE_engines_find(scene->r.engine);
}
void view3d_main_region_draw(const bContext *C, ARegion *ar)
{
- Main *bmain = CTX_data_main(C);
- View3D *v3d = CTX_wm_view3d(C);
+ Main *bmain = CTX_data_main(C);
+ View3D *v3d = CTX_wm_view3d(C);
- view3d_draw_view(C, ar);
+ view3d_draw_view(C, ar);
- GPU_free_images_old(bmain);
- GPU_pass_cache_garbage_collect();
+ GPU_free_images_old(bmain);
+ GPU_pass_cache_garbage_collect();
- /* XXX This is in order to draw UI batches with the DRW
- * olg context since we now use it for drawing the entire area */
- gpu_batch_presets_reset();
+ /* XXX This is in order to draw UI batches with the DRW
+ * olg context since we now use it for drawing the entire area */
+ gpu_batch_presets_reset();
- /* No depth test for drawing action zones afterwards. */
- GPU_depth_test(false);
+ /* No depth test for drawing action zones afterwards. */
+ GPU_depth_test(false);
- v3d->flag |= V3D_INVALID_BACKBUF;
+ v3d->flag |= V3D_INVALID_BACKBUF;
}
/** \} */
@@ -1427,92 +1469,103 @@ void view3d_main_region_draw(const bContext *C, ARegion *ar)
/** \name Offscreen Drawing
* \{ */
-static void view3d_stereo3d_setup_offscreen(
- Depsgraph *depsgraph, Scene *scene, View3D *v3d, ARegion *ar,
- float winmat[4][4], const char *viewname)
+static void view3d_stereo3d_setup_offscreen(Depsgraph *depsgraph,
+ Scene *scene,
+ View3D *v3d,
+ ARegion *ar,
+ float winmat[4][4],
+ const char *viewname)
{
- /* update the viewport matrices with the new camera */
- if (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D) {
- float viewmat[4][4];
- const bool is_left = STREQ(viewname, STEREO_LEFT_NAME);
-
- BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat);
- view3d_main_region_setup_view(depsgraph, scene, v3d, ar, viewmat, winmat, NULL);
- }
- else { /* SCE_VIEWS_FORMAT_MULTIVIEW */
- float viewmat[4][4];
- Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
-
- BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat);
- view3d_main_region_setup_view(depsgraph, scene, v3d, ar, viewmat, winmat, NULL);
- }
+ /* update the viewport matrices with the new camera */
+ if (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D) {
+ float viewmat[4][4];
+ const bool is_left = STREQ(viewname, STEREO_LEFT_NAME);
+
+ BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat);
+ view3d_main_region_setup_view(depsgraph, scene, v3d, ar, viewmat, winmat, NULL);
+ }
+ else { /* SCE_VIEWS_FORMAT_MULTIVIEW */
+ float viewmat[4][4];
+ Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
+
+ BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat);
+ view3d_main_region_setup_view(depsgraph, scene, v3d, ar, viewmat, winmat, NULL);
+ }
}
-void ED_view3d_draw_offscreen(
- Depsgraph *depsgraph, Scene *scene,
- int drawtype,
- View3D *v3d, ARegion *ar, int winx, int winy,
- float viewmat[4][4], float winmat[4][4],
- bool do_sky, bool UNUSED(is_persp), const char *viewname,
- GPUFXSettings *UNUSED(fx_settings), const bool do_color_management,
- GPUOffScreen *ofs, GPUViewport *viewport)
+void ED_view3d_draw_offscreen(Depsgraph *depsgraph,
+ Scene *scene,
+ int drawtype,
+ View3D *v3d,
+ ARegion *ar,
+ int winx,
+ int winy,
+ float viewmat[4][4],
+ float winmat[4][4],
+ bool do_sky,
+ bool UNUSED(is_persp),
+ const char *viewname,
+ GPUFXSettings *UNUSED(fx_settings),
+ const bool do_color_management,
+ GPUOffScreen *ofs,
+ GPUViewport *viewport)
{
- RegionView3D *rv3d = ar->regiondata;
- RenderEngineType *engine_type = ED_view3d_engine_type(scene, drawtype);
-
- /* set temporary new size */
- int bwinx = ar->winx;
- int bwiny = ar->winy;
- rcti brect = ar->winrct;
-
- ar->winx = winx;
- ar->winy = winy;
- ar->winrct.xmin = 0;
- ar->winrct.ymin = 0;
- ar->winrct.xmax = winx;
- ar->winrct.ymax = winy;
-
- struct bThemeState theme_state;
- UI_Theme_Store(&theme_state);
- UI_SetTheme(SPACE_VIEW3D, RGN_TYPE_WINDOW);
-
- /* set flags */
- G.f |= G_FLAG_RENDER_VIEWPORT;
-
- {
- /* free images which can have changed on frame-change
- * warning! can be slow so only free animated images - campbell */
- GPU_free_images_anim(G.main); /* XXX :((( */
- }
-
- GPU_matrix_push_projection();
- GPU_matrix_identity_set();
- GPU_matrix_push();
- GPU_matrix_identity_set();
-
- if ((viewname != NULL && viewname[0] != '\0') && (viewmat == NULL) && rv3d->persp == RV3D_CAMOB && v3d->camera) {
- view3d_stereo3d_setup_offscreen(depsgraph, scene, v3d, ar, winmat, viewname);
- }
- else {
- view3d_main_region_setup_view(depsgraph, scene, v3d, ar, viewmat, winmat, NULL);
- }
-
- /* main drawing call */
- DRW_draw_render_loop_offscreen(
- depsgraph, engine_type, ar, v3d,
- do_sky, do_color_management, ofs, viewport);
-
- /* restore size */
- ar->winx = bwinx;
- ar->winy = bwiny;
- ar->winrct = brect;
-
- GPU_matrix_pop_projection();
- GPU_matrix_pop();
-
- UI_Theme_Restore(&theme_state);
-
- G.f &= ~G_FLAG_RENDER_VIEWPORT;
+ RegionView3D *rv3d = ar->regiondata;
+ RenderEngineType *engine_type = ED_view3d_engine_type(scene, drawtype);
+
+ /* set temporary new size */
+ int bwinx = ar->winx;
+ int bwiny = ar->winy;
+ rcti brect = ar->winrct;
+
+ ar->winx = winx;
+ ar->winy = winy;
+ ar->winrct.xmin = 0;
+ ar->winrct.ymin = 0;
+ ar->winrct.xmax = winx;
+ ar->winrct.ymax = winy;
+
+ struct bThemeState theme_state;
+ UI_Theme_Store(&theme_state);
+ UI_SetTheme(SPACE_VIEW3D, RGN_TYPE_WINDOW);
+
+ /* set flags */
+ G.f |= G_FLAG_RENDER_VIEWPORT;
+
+ {
+ /* free images which can have changed on frame-change
+ * warning! can be slow so only free animated images - campbell */
+ GPU_free_images_anim(G.main); /* XXX :((( */
+ }
+
+ GPU_matrix_push_projection();
+ GPU_matrix_identity_set();
+ GPU_matrix_push();
+ GPU_matrix_identity_set();
+
+ if ((viewname != NULL && viewname[0] != '\0') && (viewmat == NULL) &&
+ rv3d->persp == RV3D_CAMOB && v3d->camera) {
+ view3d_stereo3d_setup_offscreen(depsgraph, scene, v3d, ar, winmat, viewname);
+ }
+ else {
+ view3d_main_region_setup_view(depsgraph, scene, v3d, ar, viewmat, winmat, NULL);
+ }
+
+ /* main drawing call */
+ DRW_draw_render_loop_offscreen(
+ depsgraph, engine_type, ar, v3d, do_sky, do_color_management, ofs, viewport);
+
+ /* restore size */
+ ar->winx = bwinx;
+ ar->winy = bwiny;
+ ar->winrct = brect;
+
+ GPU_matrix_pop_projection();
+ GPU_matrix_pop();
+
+ UI_Theme_Restore(&theme_state);
+
+ G.f &= ~G_FLAG_RENDER_VIEWPORT;
}
/**
@@ -1521,189 +1574,242 @@ void ED_view3d_draw_offscreen(
* \param ofs: Optional off-screen buffer, can be NULL.
* (avoids re-creating when doing multiple GL renders).
*/
-ImBuf *ED_view3d_draw_offscreen_imbuf(
- Depsgraph *depsgraph, Scene *scene,
- int drawtype,
- View3D *v3d, ARegion *ar, int sizex, int sizey,
- uint flag, uint draw_flags,
- int alpha_mode, int samples, const char *viewname,
- /* output vars */
- GPUOffScreen *ofs, char err_out[256])
+ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
+ Scene *scene,
+ int drawtype,
+ View3D *v3d,
+ ARegion *ar,
+ int sizex,
+ int sizey,
+ uint flag,
+ uint draw_flags,
+ int alpha_mode,
+ int samples,
+ const char *viewname,
+ /* output vars */
+ GPUOffScreen *ofs,
+ char err_out[256])
{
- RegionView3D *rv3d = ar->regiondata;
- const bool draw_sky = (alpha_mode == R_ADDSKY);
- const bool use_full_sample = (draw_flags & V3D_OFSDRAW_USE_FULL_SAMPLE);
-
- /* view state */
- GPUFXSettings fx_settings = v3d->fx_settings;
- bool is_ortho = false;
- float winmat[4][4];
-
- if (ofs && ((GPU_offscreen_width(ofs) != sizex) || (GPU_offscreen_height(ofs) != sizey))) {
- /* sizes differ, can't reuse */
- ofs = NULL;
- }
-
- GPUFrameBuffer *old_fb = GPU_framebuffer_active_get();
-
- if (old_fb) {
- GPU_framebuffer_restore();
- }
-
- const bool own_ofs = (ofs == NULL);
- DRW_opengl_context_enable();
-
- if (own_ofs) {
- /* bind */
- ofs = GPU_offscreen_create(sizex, sizey, use_full_sample ? 0 : samples, true, false, err_out);
- if (ofs == NULL) {
- DRW_opengl_context_disable();
- return NULL;
- }
- }
-
- GPU_offscreen_bind(ofs, true);
-
- /* read in pixels & stamp */
- ImBuf *ibuf = IMB_allocImBuf(sizex, sizey, 32, flag);
-
- /* render 3d view */
- if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
- CameraParams params;
- Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
- const Object *camera_eval = DEG_get_evaluated_object(
- depsgraph,
- camera);
-
- BKE_camera_params_init(&params);
- /* fallback for non camera objects */
- params.clip_start = v3d->clip_start;
- params.clip_end = v3d->clip_end;
- BKE_camera_params_from_object(&params, camera_eval);
- BKE_camera_multiview_params(&scene->r, &params, camera_eval, viewname);
- BKE_camera_params_compute_viewplane(&params, sizex, sizey, scene->r.xasp, scene->r.yasp);
- BKE_camera_params_compute_matrix(&params);
-
- BKE_camera_to_gpu_dof(camera, &fx_settings);
-
- is_ortho = params.is_ortho;
- copy_m4_m4(winmat, params.winmat);
- }
- else {
- rctf viewplane;
- float clip_start, clipend;
-
- is_ortho = ED_view3d_viewplane_get(depsgraph, v3d, rv3d, sizex, sizey, &viewplane, &clip_start, &clipend, NULL);
- if (is_ortho) {
- orthographic_m4(winmat, viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, -clipend, clipend);
- }
- else {
- perspective_m4(winmat, viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clip_start, clipend);
- }
- }
-
- if ((samples && use_full_sample) == 0) {
- const bool do_color_management = (ibuf->rect_float == NULL);
- /* Single-pass render, common case */
- ED_view3d_draw_offscreen(
- depsgraph, scene, drawtype,
- v3d, ar, sizex, sizey, NULL, winmat,
- draw_sky, !is_ortho, viewname,
- &fx_settings, do_color_management, ofs, NULL);
-
- if (ibuf->rect_float) {
- GPU_offscreen_read_pixels(ofs, GL_FLOAT, ibuf->rect_float);
- }
- else if (ibuf->rect) {
- GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, ibuf->rect);
- }
- }
- else {
- /* Multi-pass render, use accumulation buffer & jitter for 'full' oversampling.
- * Use because OpenGL may use a lower quality MSAA, and only over-sample edges. */
- static float jit_ofs[32][2];
- float winmat_jitter[4][4];
- float *rect_temp = (ibuf->rect_float) ? ibuf->rect_float : MEM_mallocN(sizex * sizey * sizeof(float[4]), "rect_temp");
- float *accum_buffer = MEM_mallocN(sizex * sizey * sizeof(float[4]), "accum_buffer");
- GPUViewport *viewport = GPU_viewport_create_from_offscreen(ofs);
-
- BLI_jitter_init(jit_ofs, samples);
-
- /* first sample buffer, also initializes 'rv3d->persmat' */
- ED_view3d_draw_offscreen(
- depsgraph, scene, drawtype,
- v3d, ar, sizex, sizey, NULL, winmat,
- draw_sky, !is_ortho, viewname,
- &fx_settings, false, ofs, viewport);
- GPU_offscreen_read_pixels(ofs, GL_FLOAT, accum_buffer);
-
- /* skip the first sample */
- for (int j = 1; j < samples; j++) {
- copy_m4_m4(winmat_jitter, winmat);
- window_translate_m4(
- winmat_jitter, rv3d->persmat,
- (jit_ofs[j][0] * 2.0f) / sizex,
- (jit_ofs[j][1] * 2.0f) / sizey);
-
- ED_view3d_draw_offscreen(
- depsgraph, scene, drawtype,
- v3d, ar, sizex, sizey, NULL, winmat_jitter,
- draw_sky, !is_ortho, viewname,
- &fx_settings, false, ofs, viewport);
- GPU_offscreen_read_pixels(ofs, GL_FLOAT, rect_temp);
-
- uint i = sizex * sizey * 4;
- while (i--) {
- accum_buffer[i] += rect_temp[i];
- }
- }
-
- {
- /* don't free data owned by 'ofs' */
- GPU_viewport_clear_from_offscreen(viewport);
- GPU_viewport_free(viewport);
- }
-
- if (ibuf->rect_float == NULL) {
- MEM_freeN(rect_temp);
- }
-
- if (ibuf->rect_float) {
- float *rect_float = ibuf->rect_float;
- uint i = sizex * sizey * 4;
- while (i--) {
- rect_float[i] = accum_buffer[i] / samples;
- }
- }
- else {
- uchar *rect_ub = (uchar *)ibuf->rect;
- uint i = sizex * sizey * 4;
- while (i--) {
- rect_ub[i] = (uchar)(255.0f * accum_buffer[i] / samples);
- }
- }
-
- MEM_freeN(accum_buffer);
- }
-
- /* unbind */
- GPU_offscreen_unbind(ofs, true);
-
- if (own_ofs) {
- GPU_offscreen_free(ofs);
- }
-
- DRW_opengl_context_disable();
-
- if (old_fb) {
- GPU_framebuffer_bind(old_fb);
- }
-
- if (ibuf->rect_float && ibuf->rect) {
- IMB_rect_from_float(ibuf);
- }
-
- return ibuf;
+ RegionView3D *rv3d = ar->regiondata;
+ const bool draw_sky = (alpha_mode == R_ADDSKY);
+ const bool use_full_sample = (draw_flags & V3D_OFSDRAW_USE_FULL_SAMPLE);
+
+ /* view state */
+ GPUFXSettings fx_settings = v3d->fx_settings;
+ bool is_ortho = false;
+ float winmat[4][4];
+
+ if (ofs && ((GPU_offscreen_width(ofs) != sizex) || (GPU_offscreen_height(ofs) != sizey))) {
+ /* sizes differ, can't reuse */
+ ofs = NULL;
+ }
+
+ GPUFrameBuffer *old_fb = GPU_framebuffer_active_get();
+
+ if (old_fb) {
+ GPU_framebuffer_restore();
+ }
+
+ const bool own_ofs = (ofs == NULL);
+ DRW_opengl_context_enable();
+
+ if (own_ofs) {
+ /* bind */
+ ofs = GPU_offscreen_create(sizex, sizey, use_full_sample ? 0 : samples, true, false, err_out);
+ if (ofs == NULL) {
+ DRW_opengl_context_disable();
+ return NULL;
+ }
+ }
+
+ GPU_offscreen_bind(ofs, true);
+
+ /* read in pixels & stamp */
+ ImBuf *ibuf = IMB_allocImBuf(sizex, sizey, 32, flag);
+
+ /* render 3d view */
+ if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
+ CameraParams params;
+ Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
+ const Object *camera_eval = DEG_get_evaluated_object(depsgraph, camera);
+
+ BKE_camera_params_init(&params);
+ /* fallback for non camera objects */
+ params.clip_start = v3d->clip_start;
+ params.clip_end = v3d->clip_end;
+ BKE_camera_params_from_object(&params, camera_eval);
+ BKE_camera_multiview_params(&scene->r, &params, camera_eval, viewname);
+ BKE_camera_params_compute_viewplane(&params, sizex, sizey, scene->r.xasp, scene->r.yasp);
+ BKE_camera_params_compute_matrix(&params);
+
+ BKE_camera_to_gpu_dof(camera, &fx_settings);
+
+ is_ortho = params.is_ortho;
+ copy_m4_m4(winmat, params.winmat);
+ }
+ else {
+ rctf viewplane;
+ float clip_start, clipend;
+
+ is_ortho = ED_view3d_viewplane_get(
+ depsgraph, v3d, rv3d, sizex, sizey, &viewplane, &clip_start, &clipend, NULL);
+ if (is_ortho) {
+ orthographic_m4(winmat,
+ viewplane.xmin,
+ viewplane.xmax,
+ viewplane.ymin,
+ viewplane.ymax,
+ -clipend,
+ clipend);
+ }
+ else {
+ perspective_m4(winmat,
+ viewplane.xmin,
+ viewplane.xmax,
+ viewplane.ymin,
+ viewplane.ymax,
+ clip_start,
+ clipend);
+ }
+ }
+
+ if ((samples && use_full_sample) == 0) {
+ const bool do_color_management = (ibuf->rect_float == NULL);
+ /* Single-pass render, common case */
+ ED_view3d_draw_offscreen(depsgraph,
+ scene,
+ drawtype,
+ v3d,
+ ar,
+ sizex,
+ sizey,
+ NULL,
+ winmat,
+ draw_sky,
+ !is_ortho,
+ viewname,
+ &fx_settings,
+ do_color_management,
+ ofs,
+ NULL);
+
+ if (ibuf->rect_float) {
+ GPU_offscreen_read_pixels(ofs, GL_FLOAT, ibuf->rect_float);
+ }
+ else if (ibuf->rect) {
+ GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, ibuf->rect);
+ }
+ }
+ else {
+ /* Multi-pass render, use accumulation buffer & jitter for 'full' oversampling.
+ * Use because OpenGL may use a lower quality MSAA, and only over-sample edges. */
+ static float jit_ofs[32][2];
+ float winmat_jitter[4][4];
+ float *rect_temp = (ibuf->rect_float) ?
+ ibuf->rect_float :
+ MEM_mallocN(sizex * sizey * sizeof(float[4]), "rect_temp");
+ float *accum_buffer = MEM_mallocN(sizex * sizey * sizeof(float[4]), "accum_buffer");
+ GPUViewport *viewport = GPU_viewport_create_from_offscreen(ofs);
+
+ BLI_jitter_init(jit_ofs, samples);
+
+ /* first sample buffer, also initializes 'rv3d->persmat' */
+ ED_view3d_draw_offscreen(depsgraph,
+ scene,
+ drawtype,
+ v3d,
+ ar,
+ sizex,
+ sizey,
+ NULL,
+ winmat,
+ draw_sky,
+ !is_ortho,
+ viewname,
+ &fx_settings,
+ false,
+ ofs,
+ viewport);
+ GPU_offscreen_read_pixels(ofs, GL_FLOAT, accum_buffer);
+
+ /* skip the first sample */
+ for (int j = 1; j < samples; j++) {
+ copy_m4_m4(winmat_jitter, winmat);
+ window_translate_m4(winmat_jitter,
+ rv3d->persmat,
+ (jit_ofs[j][0] * 2.0f) / sizex,
+ (jit_ofs[j][1] * 2.0f) / sizey);
+
+ ED_view3d_draw_offscreen(depsgraph,
+ scene,
+ drawtype,
+ v3d,
+ ar,
+ sizex,
+ sizey,
+ NULL,
+ winmat_jitter,
+ draw_sky,
+ !is_ortho,
+ viewname,
+ &fx_settings,
+ false,
+ ofs,
+ viewport);
+ GPU_offscreen_read_pixels(ofs, GL_FLOAT, rect_temp);
+
+ uint i = sizex * sizey * 4;
+ while (i--) {
+ accum_buffer[i] += rect_temp[i];
+ }
+ }
+
+ {
+ /* don't free data owned by 'ofs' */
+ GPU_viewport_clear_from_offscreen(viewport);
+ GPU_viewport_free(viewport);
+ }
+
+ if (ibuf->rect_float == NULL) {
+ MEM_freeN(rect_temp);
+ }
+
+ if (ibuf->rect_float) {
+ float *rect_float = ibuf->rect_float;
+ uint i = sizex * sizey * 4;
+ while (i--) {
+ rect_float[i] = accum_buffer[i] / samples;
+ }
+ }
+ else {
+ uchar *rect_ub = (uchar *)ibuf->rect;
+ uint i = sizex * sizey * 4;
+ while (i--) {
+ rect_ub[i] = (uchar)(255.0f * accum_buffer[i] / samples);
+ }
+ }
+
+ MEM_freeN(accum_buffer);
+ }
+
+ /* unbind */
+ GPU_offscreen_unbind(ofs, true);
+
+ if (own_ofs) {
+ GPU_offscreen_free(ofs);
+ }
+
+ DRW_opengl_context_disable();
+
+ if (old_fb) {
+ GPU_framebuffer_bind(old_fb);
+ }
+
+ if (ibuf->rect_float && ibuf->rect) {
+ IMB_rect_from_float(ibuf);
+ }
+
+ return ibuf;
}
/**
@@ -1714,71 +1820,86 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(
*
* \note used by the sequencer
*/
-ImBuf *ED_view3d_draw_offscreen_imbuf_simple(
- Depsgraph *depsgraph, Scene *scene,
- int drawtype,
- Object *camera, int width, int height,
- uint flag, uint draw_flags,
- int alpha_mode, int samples, const char *viewname,
- GPUOffScreen *ofs, char err_out[256])
+ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Depsgraph *depsgraph,
+ Scene *scene,
+ int drawtype,
+ Object *camera,
+ int width,
+ int height,
+ uint flag,
+ uint draw_flags,
+ int alpha_mode,
+ int samples,
+ const char *viewname,
+ GPUOffScreen *ofs,
+ char err_out[256])
{
- View3D v3d = {NULL};
- ARegion ar = {NULL};
- RegionView3D rv3d = {{{0}}};
-
- /* connect data */
- v3d.regionbase.first = v3d.regionbase.last = &ar;
- ar.regiondata = &rv3d;
- ar.regiontype = RGN_TYPE_WINDOW;
-
- v3d.camera = camera;
- v3d.shading.type = drawtype;
- v3d.flag2 = V3D_HIDE_OVERLAYS;
-
- if (draw_flags & V3D_OFSDRAW_USE_GPENCIL) {
- v3d.flag2 |= V3D_SHOW_ANNOTATION;
- }
-
- v3d.shading.background_type = V3D_SHADING_BACKGROUND_WORLD;
-
- if (draw_flags & V3D_OFSDRAW_USE_CAMERA_DOF) {
- if (camera->type == OB_CAMERA) {
- v3d.fx_settings.dof = &((Camera *)camera->data)->gpu_dof;
- v3d.fx_settings.fx_flag |= GPU_FX_FLAG_DOF;
- }
- }
-
- rv3d.persp = RV3D_CAMOB;
-
- copy_m4_m4(rv3d.viewinv, v3d.camera->obmat);
- normalize_m4(rv3d.viewinv);
- invert_m4_m4(rv3d.viewmat, rv3d.viewinv);
-
- {
- CameraParams params;
- const Object *view_camera_eval = DEG_get_evaluated_object(
- depsgraph,
- BKE_camera_multiview_render(scene, v3d.camera, viewname));
-
- BKE_camera_params_init(&params);
- BKE_camera_params_from_object(&params, view_camera_eval);
- BKE_camera_multiview_params(&scene->r, &params, view_camera_eval, viewname);
- BKE_camera_params_compute_viewplane(&params, width, height, scene->r.xasp, scene->r.yasp);
- BKE_camera_params_compute_matrix(&params);
-
- copy_m4_m4(rv3d.winmat, params.winmat);
- v3d.clip_start = params.clip_start;
- v3d.clip_end = params.clip_end;
- v3d.lens = params.lens;
- }
-
- mul_m4_m4m4(rv3d.persmat, rv3d.winmat, rv3d.viewmat);
- invert_m4_m4(rv3d.persinv, rv3d.viewinv);
-
- return ED_view3d_draw_offscreen_imbuf(
- depsgraph, scene, drawtype,
- &v3d, &ar, width, height, flag,
- draw_flags, alpha_mode, samples, viewname, ofs, err_out);
+ View3D v3d = {NULL};
+ ARegion ar = {NULL};
+ RegionView3D rv3d = {{{0}}};
+
+ /* connect data */
+ v3d.regionbase.first = v3d.regionbase.last = &ar;
+ ar.regiondata = &rv3d;
+ ar.regiontype = RGN_TYPE_WINDOW;
+
+ v3d.camera = camera;
+ v3d.shading.type = drawtype;
+ v3d.flag2 = V3D_HIDE_OVERLAYS;
+
+ if (draw_flags & V3D_OFSDRAW_USE_GPENCIL) {
+ v3d.flag2 |= V3D_SHOW_ANNOTATION;
+ }
+
+ v3d.shading.background_type = V3D_SHADING_BACKGROUND_WORLD;
+
+ if (draw_flags & V3D_OFSDRAW_USE_CAMERA_DOF) {
+ if (camera->type == OB_CAMERA) {
+ v3d.fx_settings.dof = &((Camera *)camera->data)->gpu_dof;
+ v3d.fx_settings.fx_flag |= GPU_FX_FLAG_DOF;
+ }
+ }
+
+ rv3d.persp = RV3D_CAMOB;
+
+ copy_m4_m4(rv3d.viewinv, v3d.camera->obmat);
+ normalize_m4(rv3d.viewinv);
+ invert_m4_m4(rv3d.viewmat, rv3d.viewinv);
+
+ {
+ CameraParams params;
+ const Object *view_camera_eval = DEG_get_evaluated_object(
+ depsgraph, BKE_camera_multiview_render(scene, v3d.camera, viewname));
+
+ BKE_camera_params_init(&params);
+ BKE_camera_params_from_object(&params, view_camera_eval);
+ BKE_camera_multiview_params(&scene->r, &params, view_camera_eval, viewname);
+ BKE_camera_params_compute_viewplane(&params, width, height, scene->r.xasp, scene->r.yasp);
+ BKE_camera_params_compute_matrix(&params);
+
+ copy_m4_m4(rv3d.winmat, params.winmat);
+ v3d.clip_start = params.clip_start;
+ v3d.clip_end = params.clip_end;
+ v3d.lens = params.lens;
+ }
+
+ mul_m4_m4m4(rv3d.persmat, rv3d.winmat, rv3d.viewmat);
+ invert_m4_m4(rv3d.persinv, rv3d.viewinv);
+
+ return ED_view3d_draw_offscreen_imbuf(depsgraph,
+ scene,
+ drawtype,
+ &v3d,
+ &ar,
+ width,
+ height,
+ flag,
+ draw_flags,
+ alpha_mode,
+ samples,
+ viewname,
+ ofs,
+ err_out);
}
/** \} */
@@ -1789,24 +1910,24 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(
static bool view3d_clipping_test(const float co[3], const float clip[6][4])
{
- if (plane_point_side_v3(clip[0], co) > 0.0f) {
- if (plane_point_side_v3(clip[1], co) > 0.0f) {
- if (plane_point_side_v3(clip[2], co) > 0.0f) {
- if (plane_point_side_v3(clip[3], co) > 0.0f) {
- return false;
- }
- }
- }
- }
-
- return true;
+ if (plane_point_side_v3(clip[0], co) > 0.0f) {
+ if (plane_point_side_v3(clip[1], co) > 0.0f) {
+ if (plane_point_side_v3(clip[2], co) > 0.0f) {
+ if (plane_point_side_v3(clip[3], co) > 0.0f) {
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
}
/* for 'local' ED_view3d_clipping_local must run first
* then all comparisons can be done in localspace */
bool ED_view3d_clipping_test(const RegionView3D *rv3d, const float co[3], const bool is_local)
{
- return view3d_clipping_test(co, is_local ? rv3d->clip_local : rv3d->clip);
+ return view3d_clipping_test(co, is_local ? rv3d->clip_local : rv3d->clip);
}
/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c
index f7fcd5cb11f..85bc0fba36b 100644
--- a/source/blender/editors/space_view3d/view3d_draw_legacy.c
+++ b/source/blender/editors/space_view3d/view3d_draw_legacy.c
@@ -102,7 +102,7 @@
#include "DRW_engine.h"
-#include "view3d_intern.h" /* own include */
+#include "view3d_intern.h" /* own include */
/* ********* custom clipping *********** */
@@ -113,206 +113,207 @@
void ED_view3d_clipping_set(RegionView3D *rv3d)
{
#ifdef USE_CLIP_PLANES
- double plane[4];
- const uint tot = (rv3d->viewlock & RV3D_BOXCLIP) ? 4 : 6;
-
- for (unsigned a = 0; a < tot; a++) {
- copy_v4db_v4fl(plane, rv3d->clip[a]);
- glClipPlane(GL_CLIP_PLANE0 + a, plane);
- glEnable(GL_CLIP_PLANE0 + a);
- glEnable(GL_CLIP_DISTANCE0 + a);
- }
+ double plane[4];
+ const uint tot = (rv3d->viewlock & RV3D_BOXCLIP) ? 4 : 6;
+
+ for (unsigned a = 0; a < tot; a++) {
+ copy_v4db_v4fl(plane, rv3d->clip[a]);
+ glClipPlane(GL_CLIP_PLANE0 + a, plane);
+ glEnable(GL_CLIP_PLANE0 + a);
+ glEnable(GL_CLIP_DISTANCE0 + a);
+ }
#else
- for (unsigned a = 0; a < 6; a++) {
- glEnable(GL_CLIP_DISTANCE0 + a);
- }
+ for (unsigned a = 0; a < 6; a++) {
+ glEnable(GL_CLIP_DISTANCE0 + a);
+ }
#endif
}
/* use these to temp disable/enable clipping when 'rv3d->rflag & RV3D_CLIPPING' is set */
void ED_view3d_clipping_disable(void)
{
- for (unsigned a = 0; a < 6; a++) {
+ for (unsigned a = 0; a < 6; a++) {
#ifdef USE_CLIP_PLANES
- glDisable(GL_CLIP_PLANE0 + a);
+ glDisable(GL_CLIP_PLANE0 + a);
#endif
- glDisable(GL_CLIP_DISTANCE0 + a);
- }
+ glDisable(GL_CLIP_DISTANCE0 + a);
+ }
}
void ED_view3d_clipping_enable(void)
{
- for (unsigned a = 0; a < 6; a++) {
+ for (unsigned a = 0; a < 6; a++) {
#ifdef USE_CLIP_PLANES
- glEnable(GL_CLIP_PLANE0 + a);
+ glEnable(GL_CLIP_PLANE0 + a);
#endif
- glEnable(GL_CLIP_DISTANCE0 + a);
- }
+ glEnable(GL_CLIP_DISTANCE0 + a);
+ }
}
/* *********************** backdraw for selection *************** */
-static void validate_object_select_id(
- struct Depsgraph *depsgraph, Scene *scene,
- ARegion *ar, View3D *v3d,
- Object *obact, Object *obedit,
- short select_mode)
+static void validate_object_select_id(struct Depsgraph *depsgraph,
+ Scene *scene,
+ ARegion *ar,
+ View3D *v3d,
+ Object *obact,
+ Object *obedit,
+ short select_mode)
{
- RegionView3D *rv3d = ar->regiondata;
- Scene *scene_eval = (Scene *)DEG_get_evaluated_id(depsgraph, &scene->id);
- Object *obact_eval = DEG_get_evaluated_object(depsgraph, obact);
-
- BLI_assert(ar->regiontype == RGN_TYPE_WINDOW);
-
- if (obact_eval && (obact_eval->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT) ||
- BKE_paint_select_face_test(obact_eval)))
- {
- /* do nothing */
- }
- /* texture paint mode sampling */
- else if (obact_eval && (obact_eval->mode & OB_MODE_TEXTURE_PAINT) &&
- (v3d->shading.type > OB_WIRE))
- {
- /* do nothing */
- }
- else if ((obact_eval && (obact_eval->mode & OB_MODE_PARTICLE_EDIT)) &&
- !XRAY_ENABLED(v3d))
- {
- /* do nothing */
- }
- else if ((obedit && (obedit->mode & OB_MODE_EDIT)) &&
- !XRAY_FLAG_ENABLED(v3d))
- {
- /* do nothing */
- }
- else {
- v3d->flag &= ~V3D_INVALID_BACKBUF;
- return;
- }
-
- if (!(v3d->flag & V3D_INVALID_BACKBUF)) {
- return;
- }
+ RegionView3D *rv3d = ar->regiondata;
+ Scene *scene_eval = (Scene *)DEG_get_evaluated_id(depsgraph, &scene->id);
+ Object *obact_eval = DEG_get_evaluated_object(depsgraph, obact);
+
+ BLI_assert(ar->regiontype == RGN_TYPE_WINDOW);
+
+ if (obact_eval && (obact_eval->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT) ||
+ BKE_paint_select_face_test(obact_eval))) {
+ /* do nothing */
+ }
+ /* texture paint mode sampling */
+ else if (obact_eval && (obact_eval->mode & OB_MODE_TEXTURE_PAINT) &&
+ (v3d->shading.type > OB_WIRE)) {
+ /* do nothing */
+ }
+ else if ((obact_eval && (obact_eval->mode & OB_MODE_PARTICLE_EDIT)) && !XRAY_ENABLED(v3d)) {
+ /* do nothing */
+ }
+ else if ((obedit && (obedit->mode & OB_MODE_EDIT)) && !XRAY_FLAG_ENABLED(v3d)) {
+ /* do nothing */
+ }
+ else {
+ v3d->flag &= ~V3D_INVALID_BACKBUF;
+ return;
+ }
+
+ if (!(v3d->flag & V3D_INVALID_BACKBUF)) {
+ return;
+ }
#if 0
- if (test) {
- if (qtest()) {
- addafterqueue(ar->win, BACKBUFDRAW, 1);
- return;
- }
- }
+ if (test) {
+ if (qtest()) {
+ addafterqueue(ar->win, BACKBUFDRAW, 1);
+ return;
+ }
+ }
#endif
#if 0 /* v3d->zbuf deprecated */
- if (v3d->shading.type > OB_WIRE) {
- v3d->zbuf = true;
- }
+ if (v3d->shading.type > OB_WIRE) {
+ v3d->zbuf = true;
+ }
#endif
- G.f |= G_FLAG_BACKBUFSEL;
+ G.f |= G_FLAG_BACKBUFSEL;
- if (obact_eval && ((obact_eval->base_flag & BASE_VISIBLE) != 0)) {
- DRW_framebuffer_select_id_setup(ar, true);
- draw_object_select_id(depsgraph, scene_eval, v3d, rv3d, obact_eval, select_mode);
- DRW_framebuffer_select_id_release(ar);
- }
+ if (obact_eval && ((obact_eval->base_flag & BASE_VISIBLE) != 0)) {
+ DRW_framebuffer_select_id_setup(ar, true);
+ draw_object_select_id(depsgraph, scene_eval, v3d, rv3d, obact_eval, select_mode);
+ DRW_framebuffer_select_id_release(ar);
+ }
- /* TODO: Create a flag in `DRW_manager` because the drawing is no longer
- * made on the backbuffer in this case. */
- v3d->flag &= ~V3D_INVALID_BACKBUF;
+ /* TODO: Create a flag in `DRW_manager` because the drawing is no longer
+ * made on the backbuffer in this case. */
+ v3d->flag &= ~V3D_INVALID_BACKBUF;
- G.f &= ~G_FLAG_BACKBUFSEL;
+ G.f &= ~G_FLAG_BACKBUFSEL;
}
-void view3d_opengl_read_pixels(ARegion *ar, int x, int y, int w, int h, int format, int type, void *data)
+void view3d_opengl_read_pixels(
+ ARegion *ar, int x, int y, int w, int h, int format, int type, void *data)
{
- glReadPixels(ar->winrct.xmin + x, ar->winrct.ymin + y, w, h, format, type, data);
+ glReadPixels(ar->winrct.xmin + x, ar->winrct.ymin + y, w, h, format, type, data);
}
/* TODO: Creating, attaching texture, and destroying a framebuffer is quite slow.
* Calling this function should be avoided during interactive drawing. */
static void view3d_opengl_read_Z_pixels(GPUViewport *viewport, rcti *rect, void *data)
{
- DefaultTextureList *dtxl = (DefaultTextureList *)GPU_viewport_texture_list_get(viewport);
+ DefaultTextureList *dtxl = (DefaultTextureList *)GPU_viewport_texture_list_get(viewport);
- GPUFrameBuffer *tmp_fb = GPU_framebuffer_create();
- GPU_framebuffer_texture_attach(tmp_fb, dtxl->depth, 0, 0);
- GPU_framebuffer_bind(tmp_fb);
- glDisable(GL_SCISSOR_TEST);
+ GPUFrameBuffer *tmp_fb = GPU_framebuffer_create();
+ GPU_framebuffer_texture_attach(tmp_fb, dtxl->depth, 0, 0);
+ GPU_framebuffer_bind(tmp_fb);
+ glDisable(GL_SCISSOR_TEST);
- glReadPixels(rect->xmin, rect->ymin,
- BLI_rcti_size_x(rect), BLI_rcti_size_y(rect),
- GL_DEPTH_COMPONENT, GL_FLOAT, data);
+ glReadPixels(rect->xmin,
+ rect->ymin,
+ BLI_rcti_size_x(rect),
+ BLI_rcti_size_y(rect),
+ GL_DEPTH_COMPONENT,
+ GL_FLOAT,
+ data);
- glEnable(GL_SCISSOR_TEST);
- GPU_framebuffer_restore();
+ glEnable(GL_SCISSOR_TEST);
+ GPU_framebuffer_restore();
- GPU_framebuffer_free(tmp_fb);
+ GPU_framebuffer_free(tmp_fb);
}
void ED_view3d_select_id_validate_with_select_mode(ViewContext *vc, short select_mode)
{
- /* TODO: Create a flag in `DRW_manager` because the drawing is no longer
- * made on the backbuffer in this case. */
- if (vc->v3d->flag & V3D_INVALID_BACKBUF) {
- validate_object_select_id(
- vc->depsgraph, vc->scene, vc->ar, vc->v3d,
- vc->obact, vc->obedit, select_mode);
- }
+ /* TODO: Create a flag in `DRW_manager` because the drawing is no longer
+ * made on the backbuffer in this case. */
+ if (vc->v3d->flag & V3D_INVALID_BACKBUF) {
+ validate_object_select_id(
+ vc->depsgraph, vc->scene, vc->ar, vc->v3d, vc->obact, vc->obedit, select_mode);
+ }
}
void ED_view3d_select_id_validate(ViewContext *vc)
{
- ED_view3d_select_id_validate_with_select_mode(vc, -1);
+ ED_view3d_select_id_validate_with_select_mode(vc, -1);
}
void ED_view3d_backbuf_depth_validate(ViewContext *vc)
{
- if (vc->v3d->flag & V3D_INVALID_BACKBUF) {
- ARegion *ar = vc->ar;
- RegionView3D *rv3d = ar->regiondata;
- Object *obact_eval = DEG_get_evaluated_object(vc->depsgraph, vc->obact);
+ if (vc->v3d->flag & V3D_INVALID_BACKBUF) {
+ ARegion *ar = vc->ar;
+ RegionView3D *rv3d = ar->regiondata;
+ Object *obact_eval = DEG_get_evaluated_object(vc->depsgraph, vc->obact);
- if (obact_eval && ((obact_eval->base_flag & BASE_VISIBLE) != 0)) {
- GPU_scissor(ar->winrct.xmin, ar->winrct.ymin,
- BLI_rcti_size_x(&ar->winrct),
- BLI_rcti_size_y(&ar->winrct));
+ if (obact_eval && ((obact_eval->base_flag & BASE_VISIBLE) != 0)) {
+ GPU_scissor(ar->winrct.xmin,
+ ar->winrct.ymin,
+ BLI_rcti_size_x(&ar->winrct),
+ BLI_rcti_size_y(&ar->winrct));
- GPU_depth_test(true);
- GPU_clear(GPU_DEPTH_BIT);
+ GPU_depth_test(true);
+ GPU_clear(GPU_DEPTH_BIT);
- if (rv3d->rflag & RV3D_CLIPPING) {
- ED_view3d_clipping_set(rv3d);
- }
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ ED_view3d_clipping_set(rv3d);
+ }
- draw_object_depth(rv3d, obact_eval);
+ draw_object_depth(rv3d, obact_eval);
- if (rv3d->rflag & RV3D_CLIPPING) {
- ED_view3d_clipping_disable();
- }
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ ED_view3d_clipping_disable();
+ }
- GPU_depth_test(false);
- }
+ GPU_depth_test(false);
+ }
- vc->v3d->flag &= ~V3D_INVALID_BACKBUF;
- }
+ vc->v3d->flag &= ~V3D_INVALID_BACKBUF;
+ }
}
uint *ED_view3d_select_id_read_rect(ViewContext *vc, const rcti *clip, uint *r_buf_len)
{
- ED_view3d_select_id_validate(vc);
+ ED_view3d_select_id_validate(vc);
- uint width = BLI_rcti_size_x(clip);
- uint height = BLI_rcti_size_y(clip);
- uint buf_len = width * height;
- uint *buf = MEM_mallocN(buf_len * sizeof(*buf), __func__);
+ uint width = BLI_rcti_size_x(clip);
+ uint height = BLI_rcti_size_y(clip);
+ uint buf_len = width * height;
+ uint *buf = MEM_mallocN(buf_len * sizeof(*buf), __func__);
- DRW_framebuffer_select_id_read(clip, buf);
+ DRW_framebuffer_select_id_read(clip, buf);
- if (r_buf_len) {
- *r_buf_len = buf_len;
- }
+ if (r_buf_len) {
+ *r_buf_len = buf_len;
+ }
- return buf;
+ return buf;
}
/**
@@ -321,611 +322,623 @@ uint *ED_view3d_select_id_read_rect(ViewContext *vc, const rcti *clip, uint *r_b
*/
int ED_view3d_backbuf_sample_size_clamp(ARegion *ar, const float dist)
{
- return (int)min_ff(ceilf(dist), (float)max_ii(ar->winx, ar->winx));
+ return (int)min_ff(ceilf(dist), (float)max_ii(ar->winx, ar->winx));
}
/* samples a single pixel (copied from vpaint) */
-uint ED_view3d_select_id_sample(
- ViewContext *vc, int x, int y)
+uint ED_view3d_select_id_sample(ViewContext *vc, int x, int y)
{
- if (x >= vc->ar->winx || y >= vc->ar->winy) {
- return 0;
- }
+ if (x >= vc->ar->winx || y >= vc->ar->winy) {
+ return 0;
+ }
- uint buf_len;
- uint *buf = ED_view3d_select_id_read(vc, x, y, x, y, &buf_len);
- BLI_assert(0 != buf_len);
- uint ret = buf[0];
- MEM_freeN(buf);
+ uint buf_len;
+ uint *buf = ED_view3d_select_id_read(vc, x, y, x, y, &buf_len);
+ BLI_assert(0 != buf_len);
+ uint ret = buf[0];
+ MEM_freeN(buf);
- return ret;
+ return ret;
}
/* reads full rect, converts indices */
uint *ED_view3d_select_id_read(
- ViewContext *vc, int xmin, int ymin, int xmax, int ymax, uint *r_buf_len)
+ ViewContext *vc, int xmin, int ymin, int xmax, int ymax, uint *r_buf_len)
{
- if (UNLIKELY((xmin > xmax) || (ymin > ymax))) {
- return NULL;
- }
+ if (UNLIKELY((xmin > xmax) || (ymin > ymax))) {
+ return NULL;
+ }
- const rcti rect = {
- .xmin = xmin, .xmax = xmax + 1,
- .ymin = ymin, .ymax = ymax + 1,
- };
+ const rcti rect = {
+ .xmin = xmin,
+ .xmax = xmax + 1,
+ .ymin = ymin,
+ .ymax = ymax + 1,
+ };
- uint buf_len;
- uint *buf = ED_view3d_select_id_read_rect(vc, &rect, &buf_len);
+ uint buf_len;
+ uint *buf = ED_view3d_select_id_read_rect(vc, &rect, &buf_len);
- if (r_buf_len) {
- *r_buf_len = buf_len;
- }
+ if (r_buf_len) {
+ *r_buf_len = buf_len;
+ }
- return buf;
+ return buf;
}
/* smart function to sample a rect spiralling outside, nice for backbuf selection */
-uint ED_view3d_select_id_read_nearest(
- struct ViewContext *UNUSED(vc), const int mval[2],
- const uint id_min, const uint id_max, uint *r_dist)
+uint ED_view3d_select_id_read_nearest(struct ViewContext *UNUSED(vc),
+ const int mval[2],
+ const uint id_min,
+ const uint id_max,
+ uint *r_dist)
{
- /* Create region around mouse cursor. This must be square and have an odd
- * width, the spiralling algorithm does not work with arbitrary rectangles. */
- rcti rect;
- BLI_rcti_init_pt_radius(&rect, mval, *r_dist);
- rect.xmax += 1;
- rect.ymax += 1;
-
- int width = BLI_rcti_size_x(&rect);
- int height = width;
- BLI_assert(width == height);
-
- /* Read from selection framebuffer. */
- uint *buf = MEM_mallocN(width * height * sizeof(*buf), __func__);
- DRW_framebuffer_select_id_read(&rect, buf);
-
- /* Spiral, starting from center of buffer. */
- int spiral_offset = height * (int)(width / 2) + (height / 2);
- int spiral_direction = 0;
-
- uint index = 0;
-
- for (int nr = 1; nr <= height; nr++) {
- for (int a = 0; a < 2; a++) {
- for (int b = 0; b < nr; b++) {
- /* Find hit within the specified range. */
- uint hit_id = buf[spiral_offset];
-
- if (hit_id && hit_id >= id_min && hit_id < id_max) {
- /* Get x/y from spiral offset. */
- int hit_x = spiral_offset % width;
- int hit_y = spiral_offset / width;
-
- int center_x = width / 2;
- int center_y = height / 2;
-
- /* Manhatten distance in keeping with other screen-based selection. */
- *r_dist = (uint)(abs(hit_x - center_x) + abs(hit_y - center_y));
-
- /* Indices start at 1 here. */
- index = (hit_id - id_min) + 1;
- goto exit;
- }
-
- /* Next spiral step. */
- if (spiral_direction == 0) {
- spiral_offset += 1; /* right */
- }
- else if (spiral_direction == 1) {
- spiral_offset -= width; /* down */
- }
- else if (spiral_direction == 2) {
- spiral_offset -= 1; /* left */
- }
- else {
- spiral_offset += width; /* up */
- }
-
- /* Stop if we are outside the buffer. */
- if (spiral_offset < 0 || spiral_offset >= width * height) {
- goto exit;
- }
- }
-
- spiral_direction = (spiral_direction + 1) % 4;
- }
- }
+ /* Create region around mouse cursor. This must be square and have an odd
+ * width, the spiralling algorithm does not work with arbitrary rectangles. */
+ rcti rect;
+ BLI_rcti_init_pt_radius(&rect, mval, *r_dist);
+ rect.xmax += 1;
+ rect.ymax += 1;
+
+ int width = BLI_rcti_size_x(&rect);
+ int height = width;
+ BLI_assert(width == height);
+
+ /* Read from selection framebuffer. */
+ uint *buf = MEM_mallocN(width * height * sizeof(*buf), __func__);
+ DRW_framebuffer_select_id_read(&rect, buf);
+
+ /* Spiral, starting from center of buffer. */
+ int spiral_offset = height * (int)(width / 2) + (height / 2);
+ int spiral_direction = 0;
+
+ uint index = 0;
+
+ for (int nr = 1; nr <= height; nr++) {
+ for (int a = 0; a < 2; a++) {
+ for (int b = 0; b < nr; b++) {
+ /* Find hit within the specified range. */
+ uint hit_id = buf[spiral_offset];
+
+ if (hit_id && hit_id >= id_min && hit_id < id_max) {
+ /* Get x/y from spiral offset. */
+ int hit_x = spiral_offset % width;
+ int hit_y = spiral_offset / width;
+
+ int center_x = width / 2;
+ int center_y = height / 2;
+
+ /* Manhatten distance in keeping with other screen-based selection. */
+ *r_dist = (uint)(abs(hit_x - center_x) + abs(hit_y - center_y));
+
+ /* Indices start at 1 here. */
+ index = (hit_id - id_min) + 1;
+ goto exit;
+ }
+
+ /* Next spiral step. */
+ if (spiral_direction == 0) {
+ spiral_offset += 1; /* right */
+ }
+ else if (spiral_direction == 1) {
+ spiral_offset -= width; /* down */
+ }
+ else if (spiral_direction == 2) {
+ spiral_offset -= 1; /* left */
+ }
+ else {
+ spiral_offset += width; /* up */
+ }
+
+ /* Stop if we are outside the buffer. */
+ if (spiral_offset < 0 || spiral_offset >= width * height) {
+ goto exit;
+ }
+ }
+
+ spiral_direction = (spiral_direction + 1) % 4;
+ }
+ }
exit:
- MEM_freeN(buf);
- return index;
+ MEM_freeN(buf);
+ return index;
}
-
/* ************************************************************* */
static void view3d_stereo_bgpic_setup(Scene *scene, View3D *v3d, Image *ima, ImageUser *iuser)
{
- if (BKE_image_is_stereo(ima)) {
- iuser->flag |= IMA_SHOW_STEREO;
-
- if ((scene->r.scemode & R_MULTIVIEW) == 0) {
- iuser->multiview_eye = STEREO_LEFT_ID;
- }
- else if (v3d->stereo3d_camera != STEREO_3D_ID) {
- /* show only left or right camera */
- iuser->multiview_eye = v3d->stereo3d_camera;
- }
-
- BKE_image_multiview_index(ima, iuser);
- }
- else {
- iuser->flag &= ~IMA_SHOW_STEREO;
- }
+ if (BKE_image_is_stereo(ima)) {
+ iuser->flag |= IMA_SHOW_STEREO;
+
+ if ((scene->r.scemode & R_MULTIVIEW) == 0) {
+ iuser->multiview_eye = STEREO_LEFT_ID;
+ }
+ else if (v3d->stereo3d_camera != STEREO_3D_ID) {
+ /* show only left or right camera */
+ iuser->multiview_eye = v3d->stereo3d_camera;
+ }
+
+ BKE_image_multiview_index(ima, iuser);
+ }
+ else {
+ iuser->flag &= ~IMA_SHOW_STEREO;
+ }
}
-static void view3d_draw_bgpic(Scene *scene, Depsgraph *depsgraph,
- ARegion *ar, View3D *v3d,
- const bool do_foreground, const bool do_camera_frame)
+static void view3d_draw_bgpic(Scene *scene,
+ Depsgraph *depsgraph,
+ ARegion *ar,
+ View3D *v3d,
+ const bool do_foreground,
+ const bool do_camera_frame)
{
- RegionView3D *rv3d = ar->regiondata;
- int fg_flag = do_foreground ? CAM_BGIMG_FLAG_FOREGROUND : 0;
- if (v3d->camera == NULL || v3d->camera->type != OB_CAMERA) {
- return;
- }
- Camera *cam = v3d->camera->data;
-
- for (CameraBGImage *bgpic = cam->bg_images.first; bgpic; bgpic = bgpic->next) {
- if ((bgpic->flag & CAM_BGIMG_FLAG_FOREGROUND) != fg_flag) {
- continue;
- }
-
- {
- float image_aspect[2];
- float x1, y1, x2, y2, centx, centy;
-
- void *lock;
-
- Image *ima = NULL;
-
- /* disable individual images */
- if ((bgpic->flag & CAM_BGIMG_FLAG_DISABLED)) {
- continue;
- }
-
- ImBuf *ibuf = NULL;
- ImBuf *freeibuf = NULL;
- ImBuf *releaseibuf = NULL;
- if (bgpic->source == CAM_BGIMG_SOURCE_IMAGE) {
- ima = bgpic->ima;
- if (ima == NULL) {
- continue;
- }
-
- ImageUser iuser = bgpic->iuser;
- iuser.scene = scene; /* Needed for render results. */
- BKE_image_user_frame_calc(&iuser, (int)DEG_get_ctime(depsgraph));
- if (ima->source == IMA_SRC_SEQUENCE && !(iuser.flag & IMA_USER_FRAME_IN_RANGE)) {
- ibuf = NULL; /* frame is out of range, dont show */
- }
- else {
- view3d_stereo_bgpic_setup(scene, v3d, ima, &iuser);
- ibuf = BKE_image_acquire_ibuf(ima, &iuser, &lock);
- releaseibuf = ibuf;
- }
-
- image_aspect[0] = ima->aspx;
- image_aspect[1] = ima->aspy;
- }
- else if (bgpic->source == CAM_BGIMG_SOURCE_MOVIE) {
- /* TODO: skip drawing when out of frame range (as image sequences do above) */
- MovieClip *clip = NULL;
-
- if (bgpic->flag & CAM_BGIMG_FLAG_CAMERACLIP) {
- if (scene->camera) {
- clip = BKE_object_movieclip_get(scene, scene->camera, true);
- }
- }
- else {
- clip = bgpic->clip;
- }
-
- if (clip == NULL) {
- continue;
- }
-
- BKE_movieclip_user_set_frame(&bgpic->cuser, (int)DEG_get_ctime(depsgraph));
- ibuf = BKE_movieclip_get_ibuf(clip, &bgpic->cuser);
-
- image_aspect[0] = clip->aspx;
- image_aspect[1] = clip->aspy;
-
- /* working with ibuf from image and clip has got different workflow now.
- * ibuf acquired from clip is referenced by cache system and should
- * be dereferenced after usage. */
- freeibuf = ibuf;
- }
- else {
- /* perhaps when loading future files... */
- BLI_assert(0);
- copy_v2_fl(image_aspect, 1.0f);
- }
-
- if (ibuf == NULL) {
- continue;
- }
-
- 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, lock);
- }
-
- continue;
- }
-
- if (ibuf->rect == NULL) {
- IMB_rect_from_float(ibuf);
- }
-
- BLI_assert(rv3d->persp == RV3D_CAMOB);
- {
- if (do_camera_frame) {
- rctf vb;
- ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &vb, false);
- x1 = vb.xmin;
- y1 = vb.ymin;
- x2 = vb.xmax;
- y2 = vb.ymax;
- }
- else {
- x1 = ar->winrct.xmin;
- y1 = ar->winrct.ymin;
- x2 = ar->winrct.xmax;
- y2 = ar->winrct.ymax;
- }
-
- /* apply offset last - camera offset is different to offset in blender units */
- /* so this has some sane way of working - this matches camera's shift _exactly_ */
- {
- const float max_dim = max_ff(x2 - x1, y2 - y1);
- const float xof_scale = bgpic->offset[0] * max_dim;
- const float yof_scale = bgpic->offset[1] * max_dim;
-
- x1 += xof_scale;
- y1 += yof_scale;
- x2 += xof_scale;
- y2 += yof_scale;
- }
-
- centx = (x1 + x2) * 0.5f;
- centy = (y1 + y2) * 0.5f;
-
- /* aspect correction */
- if (bgpic->flag & CAM_BGIMG_FLAG_CAMERA_ASPECT) {
- /* apply aspect from clip */
- const float w_src = ibuf->x * image_aspect[0];
- const float h_src = ibuf->y * image_aspect[1];
-
- /* destination aspect is already applied from the camera frame */
- const float w_dst = x1 - x2;
- const float h_dst = y1 - y2;
-
- const float asp_src = w_src / h_src;
- const float asp_dst = w_dst / h_dst;
-
- if (fabsf(asp_src - asp_dst) >= FLT_EPSILON) {
- if ((asp_src > asp_dst) == ((bgpic->flag & CAM_BGIMG_FLAG_CAMERA_CROP) != 0)) {
- /* fit X */
- const float div = asp_src / asp_dst;
- x1 = ((x1 - centx) * div) + centx;
- x2 = ((x2 - centx) * div) + centx;
- }
- else {
- /* fit Y */
- const float div = asp_dst / asp_src;
- y1 = ((y1 - centy) * div) + centy;
- y2 = ((y2 - centy) * div) + centy;
- }
- }
- }
- }
-
- /* complete clip? */
- rctf clip_rect;
- BLI_rctf_init(&clip_rect, x1, x2, y1, y2);
- if (bgpic->rotation) {
- BLI_rctf_rotate_expand(&clip_rect, &clip_rect, bgpic->rotation);
- }
-
- if (clip_rect.xmax < 0 || clip_rect.ymax < 0 || clip_rect.xmin > ar->winx || clip_rect.ymin > ar->winy) {
- if (freeibuf) {
- IMB_freeImBuf(freeibuf);
- }
- if (releaseibuf) {
- BKE_image_release_ibuf(ima, releaseibuf, lock);
- }
-
- continue;
- }
-
- float zoomx = (x2 - x1) / ibuf->x;
- float zoomy = (y2 - y1) / ibuf->y;
-
- /* For some reason; zoom-levels down refuses to use GL_ALPHA_SCALE. */
- if (zoomx < 1.0f || zoomy < 1.0f) {
- float tzoom = min_ff(zoomx, zoomy);
- int mip = 0;
-
- if ((ibuf->userflags & IB_MIPMAP_INVALID) != 0) {
- IMB_remakemipmap(ibuf, 0);
- ibuf->userflags &= ~IB_MIPMAP_INVALID;
- }
- else if (ibuf->mipmap[0] == NULL) {
- IMB_makemipmap(ibuf, 0);
- }
-
- while (tzoom < 1.0f && mip < 8 && ibuf->mipmap[mip]) {
- tzoom *= 2.0f;
- zoomx *= 2.0f;
- zoomy *= 2.0f;
- mip++;
- }
- if (mip > 0) {
- ibuf = ibuf->mipmap[mip - 1];
- }
- }
-
- GPU_depth_test(!do_foreground);
- glDepthMask(GL_FALSE);
-
- GPU_blend(true);
- GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
-
- GPU_matrix_push_projection();
- GPU_matrix_push();
- ED_region_pixelspace(ar);
-
- GPU_matrix_translate_2f(centx, centy);
- GPU_matrix_scale_1f(bgpic->scale);
- GPU_matrix_rotate_2d(RAD2DEGF(-bgpic->rotation));
-
- if (bgpic->flag & CAM_BGIMG_FLAG_FLIP_X) {
- zoomx *= -1.0f;
- x1 = x2;
- }
- if (bgpic->flag & CAM_BGIMG_FLAG_FLIP_Y) {
- zoomy *= -1.0f;
- y1 = y2;
- }
-
- float col[4] = {1.0f, 1.0f, 1.0f, bgpic->alpha};
- IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
- immDrawPixelsTex(&state, x1 - centx, y1 - centy, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR, ibuf->rect,
- zoomx, zoomy, col);
-
- GPU_matrix_pop_projection();
- GPU_matrix_pop();
-
- GPU_blend(false);
-
- glDepthMask(GL_TRUE);
- GPU_depth_test(true);
-
- if (freeibuf) {
- IMB_freeImBuf(freeibuf);
- }
- if (releaseibuf) {
- BKE_image_release_ibuf(ima, releaseibuf, lock);
- }
- }
- }
+ RegionView3D *rv3d = ar->regiondata;
+ int fg_flag = do_foreground ? CAM_BGIMG_FLAG_FOREGROUND : 0;
+ if (v3d->camera == NULL || v3d->camera->type != OB_CAMERA) {
+ return;
+ }
+ Camera *cam = v3d->camera->data;
+
+ for (CameraBGImage *bgpic = cam->bg_images.first; bgpic; bgpic = bgpic->next) {
+ if ((bgpic->flag & CAM_BGIMG_FLAG_FOREGROUND) != fg_flag) {
+ continue;
+ }
+
+ {
+ float image_aspect[2];
+ float x1, y1, x2, y2, centx, centy;
+
+ void *lock;
+
+ Image *ima = NULL;
+
+ /* disable individual images */
+ if ((bgpic->flag & CAM_BGIMG_FLAG_DISABLED)) {
+ continue;
+ }
+
+ ImBuf *ibuf = NULL;
+ ImBuf *freeibuf = NULL;
+ ImBuf *releaseibuf = NULL;
+ if (bgpic->source == CAM_BGIMG_SOURCE_IMAGE) {
+ ima = bgpic->ima;
+ if (ima == NULL) {
+ continue;
+ }
+
+ ImageUser iuser = bgpic->iuser;
+ iuser.scene = scene; /* Needed for render results. */
+ BKE_image_user_frame_calc(&iuser, (int)DEG_get_ctime(depsgraph));
+ if (ima->source == IMA_SRC_SEQUENCE && !(iuser.flag & IMA_USER_FRAME_IN_RANGE)) {
+ ibuf = NULL; /* frame is out of range, dont show */
+ }
+ else {
+ view3d_stereo_bgpic_setup(scene, v3d, ima, &iuser);
+ ibuf = BKE_image_acquire_ibuf(ima, &iuser, &lock);
+ releaseibuf = ibuf;
+ }
+
+ image_aspect[0] = ima->aspx;
+ image_aspect[1] = ima->aspy;
+ }
+ else if (bgpic->source == CAM_BGIMG_SOURCE_MOVIE) {
+ /* TODO: skip drawing when out of frame range (as image sequences do above) */
+ MovieClip *clip = NULL;
+
+ if (bgpic->flag & CAM_BGIMG_FLAG_CAMERACLIP) {
+ if (scene->camera) {
+ clip = BKE_object_movieclip_get(scene, scene->camera, true);
+ }
+ }
+ else {
+ clip = bgpic->clip;
+ }
+
+ if (clip == NULL) {
+ continue;
+ }
+
+ BKE_movieclip_user_set_frame(&bgpic->cuser, (int)DEG_get_ctime(depsgraph));
+ ibuf = BKE_movieclip_get_ibuf(clip, &bgpic->cuser);
+
+ image_aspect[0] = clip->aspx;
+ image_aspect[1] = clip->aspy;
+
+ /* working with ibuf from image and clip has got different workflow now.
+ * ibuf acquired from clip is referenced by cache system and should
+ * be dereferenced after usage. */
+ freeibuf = ibuf;
+ }
+ else {
+ /* perhaps when loading future files... */
+ BLI_assert(0);
+ copy_v2_fl(image_aspect, 1.0f);
+ }
+
+ if (ibuf == NULL) {
+ continue;
+ }
+
+ 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, lock);
+ }
+
+ continue;
+ }
+
+ if (ibuf->rect == NULL) {
+ IMB_rect_from_float(ibuf);
+ }
+
+ BLI_assert(rv3d->persp == RV3D_CAMOB);
+ {
+ if (do_camera_frame) {
+ rctf vb;
+ ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &vb, false);
+ x1 = vb.xmin;
+ y1 = vb.ymin;
+ x2 = vb.xmax;
+ y2 = vb.ymax;
+ }
+ else {
+ x1 = ar->winrct.xmin;
+ y1 = ar->winrct.ymin;
+ x2 = ar->winrct.xmax;
+ y2 = ar->winrct.ymax;
+ }
+
+ /* apply offset last - camera offset is different to offset in blender units */
+ /* so this has some sane way of working - this matches camera's shift _exactly_ */
+ {
+ const float max_dim = max_ff(x2 - x1, y2 - y1);
+ const float xof_scale = bgpic->offset[0] * max_dim;
+ const float yof_scale = bgpic->offset[1] * max_dim;
+
+ x1 += xof_scale;
+ y1 += yof_scale;
+ x2 += xof_scale;
+ y2 += yof_scale;
+ }
+
+ centx = (x1 + x2) * 0.5f;
+ centy = (y1 + y2) * 0.5f;
+
+ /* aspect correction */
+ if (bgpic->flag & CAM_BGIMG_FLAG_CAMERA_ASPECT) {
+ /* apply aspect from clip */
+ const float w_src = ibuf->x * image_aspect[0];
+ const float h_src = ibuf->y * image_aspect[1];
+
+ /* destination aspect is already applied from the camera frame */
+ const float w_dst = x1 - x2;
+ const float h_dst = y1 - y2;
+
+ const float asp_src = w_src / h_src;
+ const float asp_dst = w_dst / h_dst;
+
+ if (fabsf(asp_src - asp_dst) >= FLT_EPSILON) {
+ if ((asp_src > asp_dst) == ((bgpic->flag & CAM_BGIMG_FLAG_CAMERA_CROP) != 0)) {
+ /* fit X */
+ const float div = asp_src / asp_dst;
+ x1 = ((x1 - centx) * div) + centx;
+ x2 = ((x2 - centx) * div) + centx;
+ }
+ else {
+ /* fit Y */
+ const float div = asp_dst / asp_src;
+ y1 = ((y1 - centy) * div) + centy;
+ y2 = ((y2 - centy) * div) + centy;
+ }
+ }
+ }
+ }
+
+ /* complete clip? */
+ rctf clip_rect;
+ BLI_rctf_init(&clip_rect, x1, x2, y1, y2);
+ if (bgpic->rotation) {
+ BLI_rctf_rotate_expand(&clip_rect, &clip_rect, bgpic->rotation);
+ }
+
+ if (clip_rect.xmax < 0 || clip_rect.ymax < 0 || clip_rect.xmin > ar->winx ||
+ clip_rect.ymin > ar->winy) {
+ if (freeibuf) {
+ IMB_freeImBuf(freeibuf);
+ }
+ if (releaseibuf) {
+ BKE_image_release_ibuf(ima, releaseibuf, lock);
+ }
+
+ continue;
+ }
+
+ float zoomx = (x2 - x1) / ibuf->x;
+ float zoomy = (y2 - y1) / ibuf->y;
+
+ /* For some reason; zoom-levels down refuses to use GL_ALPHA_SCALE. */
+ if (zoomx < 1.0f || zoomy < 1.0f) {
+ float tzoom = min_ff(zoomx, zoomy);
+ int mip = 0;
+
+ if ((ibuf->userflags & IB_MIPMAP_INVALID) != 0) {
+ IMB_remakemipmap(ibuf, 0);
+ ibuf->userflags &= ~IB_MIPMAP_INVALID;
+ }
+ else if (ibuf->mipmap[0] == NULL) {
+ IMB_makemipmap(ibuf, 0);
+ }
+
+ while (tzoom < 1.0f && mip < 8 && ibuf->mipmap[mip]) {
+ tzoom *= 2.0f;
+ zoomx *= 2.0f;
+ zoomy *= 2.0f;
+ mip++;
+ }
+ if (mip > 0) {
+ ibuf = ibuf->mipmap[mip - 1];
+ }
+ }
+
+ GPU_depth_test(!do_foreground);
+ glDepthMask(GL_FALSE);
+
+ GPU_blend(true);
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+
+ GPU_matrix_push_projection();
+ GPU_matrix_push();
+ ED_region_pixelspace(ar);
+
+ GPU_matrix_translate_2f(centx, centy);
+ GPU_matrix_scale_1f(bgpic->scale);
+ GPU_matrix_rotate_2d(RAD2DEGF(-bgpic->rotation));
+
+ if (bgpic->flag & CAM_BGIMG_FLAG_FLIP_X) {
+ zoomx *= -1.0f;
+ x1 = x2;
+ }
+ if (bgpic->flag & CAM_BGIMG_FLAG_FLIP_Y) {
+ zoomy *= -1.0f;
+ y1 = y2;
+ }
+
+ float col[4] = {1.0f, 1.0f, 1.0f, bgpic->alpha};
+ IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
+ immDrawPixelsTex(&state,
+ x1 - centx,
+ y1 - centy,
+ ibuf->x,
+ ibuf->y,
+ GL_RGBA,
+ GL_UNSIGNED_BYTE,
+ GL_LINEAR,
+ ibuf->rect,
+ zoomx,
+ zoomy,
+ col);
+
+ GPU_matrix_pop_projection();
+ GPU_matrix_pop();
+
+ GPU_blend(false);
+
+ glDepthMask(GL_TRUE);
+ GPU_depth_test(true);
+
+ if (freeibuf) {
+ IMB_freeImBuf(freeibuf);
+ }
+ if (releaseibuf) {
+ BKE_image_release_ibuf(ima, releaseibuf, lock);
+ }
+ }
+ }
}
-void ED_view3d_draw_bgpic_test(
- Scene *scene, Depsgraph *depsgraph,
- ARegion *ar, View3D *v3d,
- const bool do_foreground, const bool do_camera_frame)
+void ED_view3d_draw_bgpic_test(Scene *scene,
+ Depsgraph *depsgraph,
+ ARegion *ar,
+ View3D *v3d,
+ const bool do_foreground,
+ const bool do_camera_frame)
{
- RegionView3D *rv3d = ar->regiondata;
-
- if ((rv3d->persp == RV3D_CAMOB) && v3d->camera && (v3d->camera->type == OB_CAMERA)) {
- Camera *cam = v3d->camera->data;
- if ((cam->flag & CAM_SHOW_BG_IMAGE) == 0) {
- return;
- }
- }
- else {
- return;
- }
-
- /* disabled - mango request, since footage /w only render is quite useful
- * and this option is easy to disable all background images at once */
+ RegionView3D *rv3d = ar->regiondata;
+
+ if ((rv3d->persp == RV3D_CAMOB) && v3d->camera && (v3d->camera->type == OB_CAMERA)) {
+ Camera *cam = v3d->camera->data;
+ if ((cam->flag & CAM_SHOW_BG_IMAGE) == 0) {
+ return;
+ }
+ }
+ else {
+ return;
+ }
+
+ /* disabled - mango request, since footage /w only render is quite useful
+ * and this option is easy to disable all background images at once */
#if 0
- if (v3d->flag2 & V3D_HIDE_OVERLAYS) {
- return;
- }
+ if (v3d->flag2 & V3D_HIDE_OVERLAYS) {
+ return;
+ }
#endif
- if ((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) {
- if (rv3d->persp == RV3D_CAMOB) {
- view3d_draw_bgpic(scene, depsgraph, ar, v3d, do_foreground, do_camera_frame);
- }
- }
- else {
- view3d_draw_bgpic(scene, depsgraph, ar, v3d, do_foreground, do_camera_frame);
- }
+ if ((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) {
+ if (rv3d->persp == RV3D_CAMOB) {
+ view3d_draw_bgpic(scene, depsgraph, ar, v3d, do_foreground, do_camera_frame);
+ }
+ }
+ else {
+ view3d_draw_bgpic(scene, depsgraph, ar, v3d, do_foreground, do_camera_frame);
+ }
}
/* *********************** */
void view3d_update_depths_rect(ARegion *ar, ViewDepths *d, rcti *rect)
{
- /* clamp rect by region */
- rcti r = {
- .xmin = 0,
- .xmax = ar->winx - 1,
- .ymin = 0,
- .ymax = ar->winy - 1,
- };
-
- /* Constrain rect to depth bounds */
- BLI_rcti_isect(&r, rect, rect);
-
- /* assign values to compare with the ViewDepths */
- int x = rect->xmin;
- int y = rect->ymin;
-
- int w = BLI_rcti_size_x(rect);
- int h = BLI_rcti_size_y(rect);
-
- if (w <= 0 || h <= 0) {
- if (d->depths) {
- MEM_freeN(d->depths);
- }
- d->depths = NULL;
-
- d->damaged = false;
- }
- else if (d->w != w ||
- d->h != h ||
- d->x != x ||
- d->y != y ||
- d->depths == NULL
- )
- {
- d->x = x;
- d->y = y;
- d->w = w;
- d->h = h;
-
- if (d->depths) {
- MEM_freeN(d->depths);
- }
-
- d->depths = MEM_mallocN(sizeof(float) * d->w * d->h, "View depths Subset");
-
- d->damaged = true;
- }
-
- if (d->damaged) {
- GPUViewport *viewport = WM_draw_region_get_viewport(ar, 0);
- view3d_opengl_read_Z_pixels(viewport, rect, d->depths);
- glGetDoublev(GL_DEPTH_RANGE, d->depth_range);
- d->damaged = false;
- }
+ /* clamp rect by region */
+ rcti r = {
+ .xmin = 0,
+ .xmax = ar->winx - 1,
+ .ymin = 0,
+ .ymax = ar->winy - 1,
+ };
+
+ /* Constrain rect to depth bounds */
+ BLI_rcti_isect(&r, rect, rect);
+
+ /* assign values to compare with the ViewDepths */
+ int x = rect->xmin;
+ int y = rect->ymin;
+
+ int w = BLI_rcti_size_x(rect);
+ int h = BLI_rcti_size_y(rect);
+
+ if (w <= 0 || h <= 0) {
+ if (d->depths) {
+ MEM_freeN(d->depths);
+ }
+ d->depths = NULL;
+
+ d->damaged = false;
+ }
+ else if (d->w != w || d->h != h || d->x != x || d->y != y || d->depths == NULL) {
+ d->x = x;
+ d->y = y;
+ d->w = w;
+ d->h = h;
+
+ if (d->depths) {
+ MEM_freeN(d->depths);
+ }
+
+ d->depths = MEM_mallocN(sizeof(float) * d->w * d->h, "View depths Subset");
+
+ d->damaged = true;
+ }
+
+ if (d->damaged) {
+ GPUViewport *viewport = WM_draw_region_get_viewport(ar, 0);
+ view3d_opengl_read_Z_pixels(viewport, rect, d->depths);
+ glGetDoublev(GL_DEPTH_RANGE, d->depth_range);
+ d->damaged = false;
+ }
}
/* note, with nouveau drivers the glReadPixels() is very slow. [#24339] */
void ED_view3d_depth_update(ARegion *ar)
{
- RegionView3D *rv3d = ar->regiondata;
-
- /* Create storage for, and, if necessary, copy depth buffer */
- if (!rv3d->depths) {
- rv3d->depths = MEM_callocN(sizeof(ViewDepths), "ViewDepths");
- }
- if (rv3d->depths) {
- ViewDepths *d = rv3d->depths;
- if (d->w != ar->winx ||
- d->h != ar->winy ||
- !d->depths)
- {
- d->w = ar->winx;
- d->h = ar->winy;
- if (d->depths) {
- MEM_freeN(d->depths);
- }
- d->depths = MEM_mallocN(sizeof(float) * d->w * d->h, "View depths");
- d->damaged = true;
- }
-
- if (d->damaged) {
- 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 = false;
- }
- }
+ RegionView3D *rv3d = ar->regiondata;
+
+ /* Create storage for, and, if necessary, copy depth buffer */
+ if (!rv3d->depths) {
+ rv3d->depths = MEM_callocN(sizeof(ViewDepths), "ViewDepths");
+ }
+ if (rv3d->depths) {
+ ViewDepths *d = rv3d->depths;
+ if (d->w != ar->winx || d->h != ar->winy || !d->depths) {
+ d->w = ar->winx;
+ d->h = ar->winy;
+ if (d->depths) {
+ MEM_freeN(d->depths);
+ }
+ d->depths = MEM_mallocN(sizeof(float) * d->w * d->h, "View depths");
+ d->damaged = true;
+ }
+
+ if (d->damaged) {
+ 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 = false;
+ }
+ }
}
/* utility function to find the closest Z value, use for autodepth */
float view3d_depth_near(ViewDepths *d)
{
- /* convert to float for comparisons */
- const float near = (float)d->depth_range[0];
- const float far_real = (float)d->depth_range[1];
- float far = far_real;
-
- const float *depths = d->depths;
- float depth = FLT_MAX;
- int i = (int)d->w * (int)d->h; /* cast to avoid short overflow */
-
- /* far is both the starting 'far' value
- * and the closest value found. */
- while (i--) {
- depth = *depths++;
- if ((depth < far) && (depth > near)) {
- far = depth;
- }
- }
-
- return far == far_real ? FLT_MAX : far;
+ /* convert to float for comparisons */
+ const float near = (float)d->depth_range[0];
+ const float far_real = (float)d->depth_range[1];
+ float far = far_real;
+
+ const float *depths = d->depths;
+ float depth = FLT_MAX;
+ int i = (int)d->w * (int)d->h; /* cast to avoid short overflow */
+
+ /* far is both the starting 'far' value
+ * and the closest value found. */
+ while (i--) {
+ depth = *depths++;
+ if ((depth < far) && (depth > near)) {
+ far = depth;
+ }
+ }
+
+ return far == far_real ? FLT_MAX : far;
}
-void ED_view3d_draw_depth_gpencil(
- Depsgraph *depsgraph, Scene *scene, ARegion *ar, View3D *v3d)
+void ED_view3d_draw_depth_gpencil(Depsgraph *depsgraph, Scene *scene, ARegion *ar, View3D *v3d)
{
- /* Setup view matrix. */
- ED_view3d_draw_setup_view(NULL, depsgraph, scene, ar, v3d, NULL, NULL, NULL);
+ /* Setup view matrix. */
+ ED_view3d_draw_setup_view(NULL, depsgraph, scene, ar, v3d, NULL, NULL, NULL);
- GPU_clear(GPU_DEPTH_BIT);
+ GPU_clear(GPU_DEPTH_BIT);
- GPU_depth_test(true);
+ GPU_depth_test(true);
- GPUViewport *viewport = WM_draw_region_get_viewport(ar, 0);
- DRW_draw_depth_loop_gpencil(depsgraph, ar, v3d, viewport);
+ GPUViewport *viewport = WM_draw_region_get_viewport(ar, 0);
+ DRW_draw_depth_loop_gpencil(depsgraph, ar, v3d, viewport);
- GPU_depth_test(false);
+ GPU_depth_test(false);
}
/* *********************** customdata **************** */
-void ED_view3d_datamask(
- const bContext *C, const Scene *UNUSED(scene), const View3D *v3d, CustomData_MeshMasks *r_cddata_masks)
+void ED_view3d_datamask(const bContext *C,
+ const Scene *UNUSED(scene),
+ const View3D *v3d,
+ CustomData_MeshMasks *r_cddata_masks)
{
- const int drawtype = view3d_effective_drawtype(v3d);
+ const int drawtype = view3d_effective_drawtype(v3d);
- if (ELEM(drawtype, OB_TEXTURE, OB_MATERIAL)) {
- r_cddata_masks->lmask |= CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL;
+ if (ELEM(drawtype, OB_TEXTURE, OB_MATERIAL)) {
+ r_cddata_masks->lmask |= CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL;
- if (drawtype == OB_MATERIAL) {
- r_cddata_masks->vmask |= CD_MASK_ORCO;
- }
- }
+ if (drawtype == OB_MATERIAL) {
+ r_cddata_masks->vmask |= CD_MASK_ORCO;
+ }
+ }
- if ((CTX_data_mode_enum(C) == CTX_MODE_EDIT_MESH) &&
- (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_WEIGHT))
- {
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
- }
+ if ((CTX_data_mode_enum(C) == CTX_MODE_EDIT_MESH) &&
+ (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_WEIGHT)) {
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ }
}
/* goes over all modes and view3d settings */
-void ED_view3d_screen_datamask(
- const bContext *C, const Scene *scene, const bScreen *screen, CustomData_MeshMasks *r_cddata_masks)
+void ED_view3d_screen_datamask(const bContext *C,
+ const Scene *scene,
+ const bScreen *screen,
+ CustomData_MeshMasks *r_cddata_masks)
{
- CustomData_MeshMasks_update(r_cddata_masks, &CD_MASK_BAREMESH);
-
- /* check if we need tfaces & mcols due to view mode */
- for (const ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
- if (sa->spacetype == SPACE_VIEW3D) {
- ED_view3d_datamask(C, scene, sa->spacedata.first, r_cddata_masks);
- }
- }
+ CustomData_MeshMasks_update(r_cddata_masks, &CD_MASK_BAREMESH);
+
+ /* check if we need tfaces & mcols due to view mode */
+ for (const ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
+ if (sa->spacetype == SPACE_VIEW3D) {
+ ED_view3d_datamask(C, scene, sa->spacedata.first, r_cddata_masks);
+ }
+ }
}
/**
@@ -935,38 +948,38 @@ void ED_view3d_screen_datamask(
* Values set by #ED_view3d_update_viewmat should be handled here.
*/
struct RV3DMatrixStore {
- float winmat[4][4];
- float viewmat[4][4];
- float viewinv[4][4];
- float persmat[4][4];
- float persinv[4][4];
- float viewcamtexcofac[4];
- float pixsize;
+ float winmat[4][4];
+ float viewmat[4][4];
+ float viewinv[4][4];
+ float persmat[4][4];
+ float persinv[4][4];
+ float viewcamtexcofac[4];
+ float pixsize;
};
struct RV3DMatrixStore *ED_view3d_mats_rv3d_backup(struct RegionView3D *rv3d)
{
- struct RV3DMatrixStore *rv3dmat = MEM_mallocN(sizeof(*rv3dmat), __func__);
- copy_m4_m4(rv3dmat->winmat, rv3d->winmat);
- copy_m4_m4(rv3dmat->viewmat, rv3d->viewmat);
- copy_m4_m4(rv3dmat->persmat, rv3d->persmat);
- copy_m4_m4(rv3dmat->persinv, rv3d->persinv);
- copy_m4_m4(rv3dmat->viewinv, rv3d->viewinv);
- copy_v4_v4(rv3dmat->viewcamtexcofac, rv3d->viewcamtexcofac);
- rv3dmat->pixsize = rv3d->pixsize;
- return (void *)rv3dmat;
+ struct RV3DMatrixStore *rv3dmat = MEM_mallocN(sizeof(*rv3dmat), __func__);
+ copy_m4_m4(rv3dmat->winmat, rv3d->winmat);
+ copy_m4_m4(rv3dmat->viewmat, rv3d->viewmat);
+ copy_m4_m4(rv3dmat->persmat, rv3d->persmat);
+ copy_m4_m4(rv3dmat->persinv, rv3d->persinv);
+ copy_m4_m4(rv3dmat->viewinv, rv3d->viewinv);
+ copy_v4_v4(rv3dmat->viewcamtexcofac, rv3d->viewcamtexcofac);
+ rv3dmat->pixsize = rv3d->pixsize;
+ return (void *)rv3dmat;
}
void ED_view3d_mats_rv3d_restore(struct RegionView3D *rv3d, struct RV3DMatrixStore *rv3dmat_pt)
{
- struct RV3DMatrixStore *rv3dmat = rv3dmat_pt;
- copy_m4_m4(rv3d->winmat, rv3dmat->winmat);
- copy_m4_m4(rv3d->viewmat, rv3dmat->viewmat);
- copy_m4_m4(rv3d->persmat, rv3dmat->persmat);
- copy_m4_m4(rv3d->persinv, rv3dmat->persinv);
- copy_m4_m4(rv3d->viewinv, rv3dmat->viewinv);
- copy_v4_v4(rv3d->viewcamtexcofac, rv3dmat->viewcamtexcofac);
- rv3d->pixsize = rv3dmat->pixsize;
+ struct RV3DMatrixStore *rv3dmat = rv3dmat_pt;
+ copy_m4_m4(rv3d->winmat, rv3dmat->winmat);
+ copy_m4_m4(rv3d->viewmat, rv3dmat->viewmat);
+ copy_m4_m4(rv3d->persmat, rv3dmat->persmat);
+ copy_m4_m4(rv3d->persinv, rv3dmat->persinv);
+ copy_m4_m4(rv3d->viewinv, rv3dmat->viewinv);
+ copy_v4_v4(rv3d->viewcamtexcofac, rv3dmat->viewcamtexcofac);
+ rv3d->pixsize = rv3dmat->pixsize;
}
/**
@@ -975,115 +988,117 @@ void ED_view3d_mats_rv3d_restore(struct RegionView3D *rv3d, struct RV3DMatrixSto
*/
void ED_scene_draw_fps(Scene *scene, int xoffset, int *yoffset)
{
- ScreenFrameRateInfo *fpsi = scene->fps_info;
- char printable[16];
+ ScreenFrameRateInfo *fpsi = scene->fps_info;
+ char printable[16];
- if (!fpsi || !fpsi->lredrawtime || !fpsi->redrawtime) {
- return;
- }
+ if (!fpsi || !fpsi->lredrawtime || !fpsi->redrawtime) {
+ return;
+ }
- printable[0] = '\0';
+ printable[0] = '\0';
#if 0
- /* this is too simple, better do an average */
- fps = (float)(1.0 / (fpsi->lredrawtime - fpsi->redrawtime))
+ /* this is too simple, better do an average */
+ fps = (float)(1.0 / (fpsi->lredrawtime - fpsi->redrawtime))
#else
- fpsi->redrawtimes_fps[fpsi->redrawtime_index] = (float)(1.0 / (fpsi->lredrawtime - fpsi->redrawtime));
-
- float fps = 0.0f;
- int tot = 0;
- for (int i = 0; i < REDRAW_FRAME_AVERAGE; i++) {
- if (fpsi->redrawtimes_fps[i]) {
- fps += fpsi->redrawtimes_fps[i];
- tot++;
- }
- }
- if (tot) {
- fpsi->redrawtime_index = (fpsi->redrawtime_index + 1) % REDRAW_FRAME_AVERAGE;
-
- //fpsi->redrawtime_index++;
- //if (fpsi->redrawtime >= REDRAW_FRAME_AVERAGE) {
- // fpsi->redrawtime = 0;
- //}
-
- fps = fps / tot;
- }
+ fpsi->redrawtimes_fps[fpsi->redrawtime_index] = (float)(1.0 /
+ (fpsi->lredrawtime - fpsi->redrawtime));
+
+ float fps = 0.0f;
+ int tot = 0;
+ for (int i = 0; i < REDRAW_FRAME_AVERAGE; i++) {
+ if (fpsi->redrawtimes_fps[i]) {
+ fps += fpsi->redrawtimes_fps[i];
+ tot++;
+ }
+ }
+ if (tot) {
+ fpsi->redrawtime_index = (fpsi->redrawtime_index + 1) % REDRAW_FRAME_AVERAGE;
+
+ //fpsi->redrawtime_index++;
+ //if (fpsi->redrawtime >= REDRAW_FRAME_AVERAGE) {
+ // fpsi->redrawtime = 0;
+ //}
+
+ fps = fps / tot;
+ }
#endif
- const int font_id = BLF_default();
+ const int font_id = BLF_default();
- /* is this more than half a frame behind? */
- if (fps + 0.5f < (float)(FPS)) {
- UI_FontThemeColor(font_id, TH_REDALERT);
- BLI_snprintf(printable, sizeof(printable), IFACE_("fps: %.2f"), fps);
- }
- else {
- UI_FontThemeColor(font_id, TH_TEXT_HI);
- BLI_snprintf(printable, sizeof(printable), IFACE_("fps: %i"), (int)(fps + 0.5f));
- }
+ /* is this more than half a frame behind? */
+ if (fps + 0.5f < (float)(FPS)) {
+ UI_FontThemeColor(font_id, TH_REDALERT);
+ BLI_snprintf(printable, sizeof(printable), IFACE_("fps: %.2f"), fps);
+ }
+ else {
+ UI_FontThemeColor(font_id, TH_TEXT_HI);
+ BLI_snprintf(printable, sizeof(printable), IFACE_("fps: %i"), (int)(fps + 0.5f));
+ }
- BLF_enable(font_id, BLF_SHADOW);
- BLF_shadow(font_id, 5, (const float[4]){0.0f, 0.0f, 0.0f, 1.0f});
- BLF_shadow_offset(font_id, 1, -1);
+ BLF_enable(font_id, BLF_SHADOW);
+ BLF_shadow(font_id, 5, (const float[4]){0.0f, 0.0f, 0.0f, 1.0f});
+ BLF_shadow_offset(font_id, 1, -1);
- *yoffset -= U.widget_unit;
+ *yoffset -= U.widget_unit;
#ifdef WITH_INTERNATIONAL
- BLF_draw_default(xoffset, *yoffset, 0.0f, printable, sizeof(printable));
+ BLF_draw_default(xoffset, *yoffset, 0.0f, printable, sizeof(printable));
#else
- BLF_draw_default_ascii(xoffset, *yoffset, 0.0f, printable, sizeof(printable));
+ BLF_draw_default_ascii(xoffset, *yoffset, 0.0f, printable, sizeof(printable));
#endif
- BLF_disable(font_id, BLF_SHADOW);
+ BLF_disable(font_id, BLF_SHADOW);
}
static bool view3d_main_region_do_render_draw(const Scene *scene)
{
- RenderEngineType *type = RE_engines_find(scene->r.engine);
- return (type && type->view_update && type->view_draw);
+ RenderEngineType *type = RE_engines_find(scene->r.engine);
+ return (type && type->view_update && type->view_draw);
}
-bool ED_view3d_calc_render_border(const Scene *scene, Depsgraph *depsgraph, View3D *v3d, ARegion *ar, rcti *rect)
+bool ED_view3d_calc_render_border(
+ const Scene *scene, Depsgraph *depsgraph, View3D *v3d, ARegion *ar, rcti *rect)
{
- RegionView3D *rv3d = ar->regiondata;
- bool use_border;
-
- /* test if there is a 3d view rendering */
- if (v3d->shading.type != OB_RENDER || !view3d_main_region_do_render_draw(scene)) {
- return false;
- }
-
- /* test if there is a border render */
- if (rv3d->persp == RV3D_CAMOB) {
- use_border = (scene->r.mode & R_BORDER) != 0;
- }
- else {
- use_border = (v3d->flag2 & V3D_RENDER_BORDER) != 0;
- }
-
- if (!use_border) {
- return false;
- }
-
- /* compute border */
- if (rv3d->persp == RV3D_CAMOB) {
- rctf viewborder;
- ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &viewborder, false);
-
- rect->xmin = viewborder.xmin + scene->r.border.xmin * BLI_rctf_size_x(&viewborder);
- rect->ymin = viewborder.ymin + scene->r.border.ymin * BLI_rctf_size_y(&viewborder);
- rect->xmax = viewborder.xmin + scene->r.border.xmax * BLI_rctf_size_x(&viewborder);
- rect->ymax = viewborder.ymin + scene->r.border.ymax * BLI_rctf_size_y(&viewborder);
- }
- else {
- rect->xmin = v3d->render_border.xmin * ar->winx;
- rect->xmax = v3d->render_border.xmax * ar->winx;
- rect->ymin = v3d->render_border.ymin * ar->winy;
- rect->ymax = v3d->render_border.ymax * ar->winy;
- }
-
- BLI_rcti_translate(rect, ar->winrct.xmin, ar->winrct.ymin);
- BLI_rcti_isect(&ar->winrct, rect, rect);
-
- return true;
+ RegionView3D *rv3d = ar->regiondata;
+ bool use_border;
+
+ /* test if there is a 3d view rendering */
+ if (v3d->shading.type != OB_RENDER || !view3d_main_region_do_render_draw(scene)) {
+ return false;
+ }
+
+ /* test if there is a border render */
+ if (rv3d->persp == RV3D_CAMOB) {
+ use_border = (scene->r.mode & R_BORDER) != 0;
+ }
+ else {
+ use_border = (v3d->flag2 & V3D_RENDER_BORDER) != 0;
+ }
+
+ if (!use_border) {
+ return false;
+ }
+
+ /* compute border */
+ if (rv3d->persp == RV3D_CAMOB) {
+ rctf viewborder;
+ ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &viewborder, false);
+
+ rect->xmin = viewborder.xmin + scene->r.border.xmin * BLI_rctf_size_x(&viewborder);
+ rect->ymin = viewborder.ymin + scene->r.border.ymin * BLI_rctf_size_y(&viewborder);
+ rect->xmax = viewborder.xmin + scene->r.border.xmax * BLI_rctf_size_x(&viewborder);
+ rect->ymax = viewborder.ymin + scene->r.border.ymax * BLI_rctf_size_y(&viewborder);
+ }
+ else {
+ rect->xmin = v3d->render_border.xmin * ar->winx;
+ rect->xmax = v3d->render_border.xmax * ar->winx;
+ rect->ymin = v3d->render_border.ymin * ar->winy;
+ rect->ymax = v3d->render_border.ymax * ar->winy;
+ }
+
+ BLI_rcti_translate(rect, ar->winrct.xmin, ar->winrct.ymin);
+ BLI_rcti_isect(&ar->winrct, rect, rect);
+
+ return true;
}
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index e74703baf2d..1d2d361d868 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -78,12 +78,11 @@
#include "PIL_time.h"
-#include "view3d_intern.h" /* own include */
-
+#include "view3d_intern.h" /* own include */
enum {
- HAS_TRANSLATE = (1 << 0),
- HAS_ROTATE = (1 << 0),
+ HAS_TRANSLATE = (1 << 0),
+ HAS_ROTATE = (1 << 0),
};
/* -------------------------------------------------------------------- */
@@ -91,35 +90,37 @@ enum {
* \{ */
enum eV3D_OpPropFlag {
- V3D_OP_PROP_MOUSE_CO = (1 << 0),
- V3D_OP_PROP_DELTA = (1 << 1),
- V3D_OP_PROP_USE_ALL_REGIONS = (1 << 2),
- V3D_OP_PROP_USE_MOUSE_INIT = (1 << 3),
+ V3D_OP_PROP_MOUSE_CO = (1 << 0),
+ V3D_OP_PROP_DELTA = (1 << 1),
+ V3D_OP_PROP_USE_ALL_REGIONS = (1 << 2),
+ V3D_OP_PROP_USE_MOUSE_INIT = (1 << 3),
};
static void view3d_operator_properties_common(wmOperatorType *ot, const enum eV3D_OpPropFlag flag)
{
- if (flag & V3D_OP_PROP_MOUSE_CO) {
- PropertyRNA *prop;
- prop = RNA_def_int(ot->srna, "mx", 0, 0, INT_MAX, "Region Position X", "", 0, INT_MAX);
- RNA_def_property_flag(prop, PROP_HIDDEN);
- prop = RNA_def_int(ot->srna, "my", 0, 0, INT_MAX, "Region Position Y", "", 0, INT_MAX);
- RNA_def_property_flag(prop, PROP_HIDDEN);
- }
- if (flag & V3D_OP_PROP_DELTA) {
- RNA_def_int(ot->srna, "delta", 0, INT_MIN, INT_MAX, "Delta", "", INT_MIN, INT_MAX);
- }
- if (flag & V3D_OP_PROP_USE_ALL_REGIONS) {
- PropertyRNA *prop;
- prop = RNA_def_boolean(ot->srna, "use_all_regions", 0, "All Regions", "View selected for all regions");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- }
- if (flag & V3D_OP_PROP_USE_MOUSE_INIT) {
- /* Disable when view operators are initialized from buttons. */
- PropertyRNA *prop;
- prop = RNA_def_boolean(ot->srna, "use_mouse_init", true, "Mouse Init", "Use initial mouse position");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
- }
+ if (flag & V3D_OP_PROP_MOUSE_CO) {
+ PropertyRNA *prop;
+ prop = RNA_def_int(ot->srna, "mx", 0, 0, INT_MAX, "Region Position X", "", 0, INT_MAX);
+ RNA_def_property_flag(prop, PROP_HIDDEN);
+ prop = RNA_def_int(ot->srna, "my", 0, 0, INT_MAX, "Region Position Y", "", 0, INT_MAX);
+ RNA_def_property_flag(prop, PROP_HIDDEN);
+ }
+ if (flag & V3D_OP_PROP_DELTA) {
+ RNA_def_int(ot->srna, "delta", 0, INT_MIN, INT_MAX, "Delta", "", INT_MIN, INT_MAX);
+ }
+ if (flag & V3D_OP_PROP_USE_ALL_REGIONS) {
+ PropertyRNA *prop;
+ prop = RNA_def_boolean(
+ ot->srna, "use_all_regions", 0, "All Regions", "View selected for all regions");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ }
+ if (flag & V3D_OP_PROP_USE_MOUSE_INIT) {
+ /* Disable when view operators are initialized from buttons. */
+ PropertyRNA *prop;
+ prop = RNA_def_boolean(
+ ot->srna, "use_mouse_init", true, "Mouse Init", "Use initial mouse position");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
+ }
}
/** \} */
@@ -129,87 +130,87 @@ static void view3d_operator_properties_common(wmOperatorType *ot, const enum eV3
* \{ */
typedef struct ViewOpsData {
- /** Context pointers (assigned by #viewops_data_alloc). */
- Main *bmain;
- Scene *scene;
- ScrArea *sa;
- ARegion *ar;
- View3D *v3d;
- RegionView3D *rv3d;
- Depsgraph *depsgraph;
-
- /** Needed for continuous zoom. */
- wmTimer *timer;
-
- /** Viewport state on initialization, don't change afterwards. */
- struct {
- float dist;
- float camzoom;
- float quat[4];
- /** #wmEvent.x, y. */
- int event_xy[2];
- /** Offset to use when #VIEWOPS_FLAG_USE_MOUSE_INIT is not set.
- * so we can simulate pressing in the middle of the screen. */
- int event_xy_offset[2];
- /** #wmEvent.type that triggered the operator. */
- int event_type;
- float ofs[3];
- /** Initial distance to 'ofs'. */
- float zfac;
-
- /** Trackball rotation only. */
- float trackvec[3];
- /** Dolly only. */
- float mousevec[3];
- } init;
-
- /** Previous state (previous modal event handled). */
- struct {
- int event_xy[2];
- /** For operators that use time-steps (continuous zoom). */
- double time;
- } prev;
-
- /** Current state. */
- struct {
- /** Working copy of #RegionView3D.viewquat, needed for rotation calculation
- * so we can apply snap to the view-port while keeping the unsnapped rotation
- * here to use when snap is disabled and for continued calculation. */
- float viewquat[4];
- } curr;
-
- float reverse;
- bool axis_snap; /* view rotate only */
-
- /** Use for orbit selection and auto-dist. */
- float dyn_ofs[3];
- bool use_dyn_ofs;
+ /** Context pointers (assigned by #viewops_data_alloc). */
+ Main *bmain;
+ Scene *scene;
+ ScrArea *sa;
+ ARegion *ar;
+ View3D *v3d;
+ RegionView3D *rv3d;
+ Depsgraph *depsgraph;
+
+ /** Needed for continuous zoom. */
+ wmTimer *timer;
+
+ /** Viewport state on initialization, don't change afterwards. */
+ struct {
+ float dist;
+ float camzoom;
+ float quat[4];
+ /** #wmEvent.x, y. */
+ int event_xy[2];
+ /** Offset to use when #VIEWOPS_FLAG_USE_MOUSE_INIT is not set.
+ * so we can simulate pressing in the middle of the screen. */
+ int event_xy_offset[2];
+ /** #wmEvent.type that triggered the operator. */
+ int event_type;
+ float ofs[3];
+ /** Initial distance to 'ofs'. */
+ float zfac;
+
+ /** Trackball rotation only. */
+ float trackvec[3];
+ /** Dolly only. */
+ float mousevec[3];
+ } init;
+
+ /** Previous state (previous modal event handled). */
+ struct {
+ int event_xy[2];
+ /** For operators that use time-steps (continuous zoom). */
+ double time;
+ } prev;
+
+ /** Current state. */
+ struct {
+ /** Working copy of #RegionView3D.viewquat, needed for rotation calculation
+ * so we can apply snap to the view-port while keeping the unsnapped rotation
+ * here to use when snap is disabled and for continued calculation. */
+ float viewquat[4];
+ } curr;
+
+ float reverse;
+ bool axis_snap; /* view rotate only */
+
+ /** Use for orbit selection and auto-dist. */
+ float dyn_ofs[3];
+ bool use_dyn_ofs;
} ViewOpsData;
-#define TRACKBALLSIZE (1.1f)
+#define TRACKBALLSIZE (1.1f)
static void calctrackballvec(const rcti *rect, const int event_xy[2], float vec[3])
{
- const float radius = TRACKBALLSIZE;
- const float t = radius / (float)M_SQRT2;
- float x, y, z, d;
+ const float radius = TRACKBALLSIZE;
+ const float t = radius / (float)M_SQRT2;
+ float x, y, z, d;
- /* normalize x and y */
- x = BLI_rcti_cent_x(rect) - event_xy[0];
- x /= (float)(BLI_rcti_size_x(rect) / 4);
- y = BLI_rcti_cent_y(rect) - event_xy[1];
- y /= (float)(BLI_rcti_size_y(rect) / 2);
- d = sqrtf(x * x + y * y);
- if (d < t) { /* Inside sphere */
- z = sqrtf(radius * radius - d * d);
- }
- else { /* On hyperbola */
- z = t * t / d;
- }
+ /* normalize x and y */
+ x = BLI_rcti_cent_x(rect) - event_xy[0];
+ x /= (float)(BLI_rcti_size_x(rect) / 4);
+ y = BLI_rcti_cent_y(rect) - event_xy[1];
+ y /= (float)(BLI_rcti_size_y(rect) / 2);
+ d = sqrtf(x * x + y * y);
+ if (d < t) { /* Inside sphere */
+ z = sqrtf(radius * radius - d * d);
+ }
+ else { /* On hyperbola */
+ z = t * t / d;
+ }
- vec[0] = x;
- vec[1] = y;
- vec[2] = -z; /* yah yah! */
+ vec[0] = x;
+ vec[1] = y;
+ vec[2] = -z; /* yah yah! */
}
/**
@@ -217,331 +218,330 @@ static void calctrackballvec(const rcti *rect, const int event_xy[2], float vec[
*/
static void viewops_data_alloc(bContext *C, wmOperator *op)
{
- ViewOpsData *vod = MEM_callocN(sizeof(ViewOpsData), "viewops data");
+ ViewOpsData *vod = MEM_callocN(sizeof(ViewOpsData), "viewops data");
- /* store data */
- op->customdata = vod;
- vod->bmain = CTX_data_main(C);
- vod->depsgraph = CTX_data_depsgraph(C);
- vod->scene = CTX_data_scene(C);
- vod->sa = CTX_wm_area(C);
- vod->ar = CTX_wm_region(C);
- vod->v3d = vod->sa->spacedata.first;
- vod->rv3d = vod->ar->regiondata;
+ /* store data */
+ op->customdata = vod;
+ vod->bmain = CTX_data_main(C);
+ vod->depsgraph = CTX_data_depsgraph(C);
+ vod->scene = CTX_data_scene(C);
+ vod->sa = CTX_wm_area(C);
+ vod->ar = CTX_wm_region(C);
+ vod->v3d = vod->sa->spacedata.first;
+ vod->rv3d = vod->ar->regiondata;
}
-void view3d_orbit_apply_dyn_ofs(
- float r_ofs[3], const float ofs_init[3], const float viewquat_old[4],
- const float viewquat_new[4], const float dyn_ofs[3])
+void view3d_orbit_apply_dyn_ofs(float r_ofs[3],
+ const float ofs_init[3],
+ const float viewquat_old[4],
+ const float viewquat_new[4],
+ const float dyn_ofs[3])
{
- float q[4];
- invert_qt_qt_normalized(q, viewquat_old);
- mul_qt_qtqt(q, q, viewquat_new);
+ float q[4];
+ invert_qt_qt_normalized(q, viewquat_old);
+ mul_qt_qtqt(q, q, viewquat_new);
- invert_qt_normalized(q);
+ invert_qt_normalized(q);
- sub_v3_v3v3(r_ofs, ofs_init, dyn_ofs);
- mul_qt_v3(q, r_ofs);
- add_v3_v3(r_ofs, dyn_ofs);
+ sub_v3_v3v3(r_ofs, ofs_init, dyn_ofs);
+ mul_qt_v3(q, r_ofs);
+ add_v3_v3(r_ofs, dyn_ofs);
}
static bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3])
{
- static float lastofs[3] = {0, 0, 0};
- bool is_set = false;
-
- const Depsgraph *depsgraph = CTX_data_depsgraph(C);
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer_eval = DEG_get_evaluated_view_layer(depsgraph);
- View3D *v3d = CTX_wm_view3d(C);
- Object *ob_act_eval = OBACT(view_layer_eval);
- Object *ob_act = DEG_get_original_object(ob_act_eval);
-
- if (ob_act && (ob_act->mode & OB_MODE_ALL_PAINT) &&
- /* with weight-paint + pose-mode, fall through to using calculateTransformCenter */
- ((ob_act->mode & OB_MODE_WEIGHT_PAINT) && BKE_object_pose_armature_get(ob_act)) == 0)
- {
- /* in case of sculpting use last average stroke position as a rotation
- * center, in other cases it's not clear what rotation center shall be
- * so just rotate around object origin
- */
- if (ob_act->mode & (OB_MODE_SCULPT | OB_MODE_TEXTURE_PAINT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) {
- float stroke[3];
- BKE_paint_stroke_get_average(scene, ob_act_eval, stroke);
- copy_v3_v3(lastofs, stroke);
- }
- else {
- copy_v3_v3(lastofs, ob_act_eval->obmat[3]);
- }
- is_set = true;
- }
- else if (ob_act && (ob_act->mode & OB_MODE_EDIT) && (ob_act->type == OB_FONT)) {
- Curve *cu = ob_act_eval->data;
- EditFont *ef = cu->editfont;
- int i;
-
- zero_v3(lastofs);
- for (i = 0; i < 4; i++) {
- add_v2_v2(lastofs, ef->textcurs[i]);
- }
- mul_v2_fl(lastofs, 1.0f / 4.0f);
-
- mul_m4_v3(ob_act_eval->obmat, lastofs);
-
- is_set = true;
- }
- else if (ob_act == NULL || ob_act->mode == OB_MODE_OBJECT) {
- /* object mode use boundbox centers */
- Base *base_eval;
- uint tot = 0;
- float select_center[3];
-
- zero_v3(select_center);
- for (base_eval = FIRSTBASE(view_layer_eval); base_eval; base_eval = base_eval->next) {
- if (BASE_SELECTED(v3d, base_eval)) {
- /* use the boundbox if we can */
- Object *ob_eval = base_eval->object;
-
- if (ob_eval->runtime.bb && !(ob_eval->runtime.bb->flag & BOUNDBOX_DIRTY)) {
- float cent[3];
-
- BKE_boundbox_calc_center_aabb(ob_eval->runtime.bb, cent);
-
- mul_m4_v3(ob_eval->obmat, cent);
- add_v3_v3(select_center, cent);
- }
- else {
- add_v3_v3(select_center, ob_eval->obmat[3]);
- }
- tot++;
- }
- }
- if (tot) {
- mul_v3_fl(select_center, 1.0f / (float)tot);
- copy_v3_v3(lastofs, select_center);
- is_set = true;
- }
- }
- else {
- /* If there's no selection, lastofs is unmodified and last value since static */
- is_set = calculateTransformCenter(C, V3D_AROUND_CENTER_MEDIAN, lastofs, NULL);
- }
-
- copy_v3_v3(r_dyn_ofs, lastofs);
-
- return is_set;
+ static float lastofs[3] = {0, 0, 0};
+ bool is_set = false;
+
+ const Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer_eval = DEG_get_evaluated_view_layer(depsgraph);
+ View3D *v3d = CTX_wm_view3d(C);
+ Object *ob_act_eval = OBACT(view_layer_eval);
+ Object *ob_act = DEG_get_original_object(ob_act_eval);
+
+ if (ob_act && (ob_act->mode & OB_MODE_ALL_PAINT) &&
+ /* with weight-paint + pose-mode, fall through to using calculateTransformCenter */
+ ((ob_act->mode & OB_MODE_WEIGHT_PAINT) && BKE_object_pose_armature_get(ob_act)) == 0) {
+ /* in case of sculpting use last average stroke position as a rotation
+ * center, in other cases it's not clear what rotation center shall be
+ * so just rotate around object origin
+ */
+ if (ob_act->mode &
+ (OB_MODE_SCULPT | OB_MODE_TEXTURE_PAINT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) {
+ float stroke[3];
+ BKE_paint_stroke_get_average(scene, ob_act_eval, stroke);
+ copy_v3_v3(lastofs, stroke);
+ }
+ else {
+ copy_v3_v3(lastofs, ob_act_eval->obmat[3]);
+ }
+ is_set = true;
+ }
+ else if (ob_act && (ob_act->mode & OB_MODE_EDIT) && (ob_act->type == OB_FONT)) {
+ Curve *cu = ob_act_eval->data;
+ EditFont *ef = cu->editfont;
+ int i;
+
+ zero_v3(lastofs);
+ for (i = 0; i < 4; i++) {
+ add_v2_v2(lastofs, ef->textcurs[i]);
+ }
+ mul_v2_fl(lastofs, 1.0f / 4.0f);
+
+ mul_m4_v3(ob_act_eval->obmat, lastofs);
+
+ is_set = true;
+ }
+ else if (ob_act == NULL || ob_act->mode == OB_MODE_OBJECT) {
+ /* object mode use boundbox centers */
+ Base *base_eval;
+ uint tot = 0;
+ float select_center[3];
+
+ zero_v3(select_center);
+ for (base_eval = FIRSTBASE(view_layer_eval); base_eval; base_eval = base_eval->next) {
+ if (BASE_SELECTED(v3d, base_eval)) {
+ /* use the boundbox if we can */
+ Object *ob_eval = base_eval->object;
+
+ if (ob_eval->runtime.bb && !(ob_eval->runtime.bb->flag & BOUNDBOX_DIRTY)) {
+ float cent[3];
+
+ BKE_boundbox_calc_center_aabb(ob_eval->runtime.bb, cent);
+
+ mul_m4_v3(ob_eval->obmat, cent);
+ add_v3_v3(select_center, cent);
+ }
+ else {
+ add_v3_v3(select_center, ob_eval->obmat[3]);
+ }
+ tot++;
+ }
+ }
+ if (tot) {
+ mul_v3_fl(select_center, 1.0f / (float)tot);
+ copy_v3_v3(lastofs, select_center);
+ is_set = true;
+ }
+ }
+ else {
+ /* If there's no selection, lastofs is unmodified and last value since static */
+ is_set = calculateTransformCenter(C, V3D_AROUND_CENTER_MEDIAN, lastofs, NULL);
+ }
+
+ copy_v3_v3(r_dyn_ofs, lastofs);
+
+ return is_set;
}
enum eViewOpsFlag {
- /** When enabled, rotate around the selection. */
- VIEWOPS_FLAG_ORBIT_SELECT = (1 << 0),
- /** When enabled, use the depth under the cursor for navigation. */
- VIEWOPS_FLAG_DEPTH_NAVIGATE = (1 << 1),
- /**
- * When enabled run #ED_view3d_persp_ensure this may switch out of
- * camera view when orbiting or switch from ortho to perspective when auto-persp is enabled.
- * Some operations don't require this (view zoom/pan or ndof where subtle rotation is common
- * so we don't want it to trigger auto-perspective). */
- VIEWOPS_FLAG_PERSP_ENSURE = (1 << 2),
- /** When set, ignore any options that depend on initial cursor location. */
- VIEWOPS_FLAG_USE_MOUSE_INIT = (1 << 3),
+ /** When enabled, rotate around the selection. */
+ VIEWOPS_FLAG_ORBIT_SELECT = (1 << 0),
+ /** When enabled, use the depth under the cursor for navigation. */
+ VIEWOPS_FLAG_DEPTH_NAVIGATE = (1 << 1),
+ /**
+ * When enabled run #ED_view3d_persp_ensure this may switch out of
+ * camera view when orbiting or switch from ortho to perspective when auto-persp is enabled.
+ * Some operations don't require this (view zoom/pan or ndof where subtle rotation is common
+ * so we don't want it to trigger auto-perspective). */
+ VIEWOPS_FLAG_PERSP_ENSURE = (1 << 2),
+ /** When set, ignore any options that depend on initial cursor location. */
+ VIEWOPS_FLAG_USE_MOUSE_INIT = (1 << 3),
};
static enum eViewOpsFlag viewops_flag_from_args(bool use_select, bool use_depth)
{
- enum eViewOpsFlag flag = 0;
- if (use_select) {
- flag |= VIEWOPS_FLAG_ORBIT_SELECT;
- }
- if (use_depth) {
- flag |= VIEWOPS_FLAG_DEPTH_NAVIGATE;
- }
+ enum eViewOpsFlag flag = 0;
+ if (use_select) {
+ flag |= VIEWOPS_FLAG_ORBIT_SELECT;
+ }
+ if (use_depth) {
+ flag |= VIEWOPS_FLAG_DEPTH_NAVIGATE;
+ }
- return flag;
+ return flag;
}
static enum eViewOpsFlag viewops_flag_from_prefs(void)
{
- return viewops_flag_from_args(
- (U.uiflag & USER_ORBIT_SELECTION) != 0,
- (U.uiflag & USER_DEPTH_NAVIGATE) != 0);
+ return viewops_flag_from_args((U.uiflag & USER_ORBIT_SELECTION) != 0,
+ (U.uiflag & USER_DEPTH_NAVIGATE) != 0);
}
/**
* Calculate the values for #ViewOpsData
*/
-static void viewops_data_create(
- bContext *C, wmOperator *op, const wmEvent *event,
- enum eViewOpsFlag viewops_flag)
-{
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- ViewOpsData *vod = op->customdata;
- RegionView3D *rv3d = vod->rv3d;
-
- /* Could do this more nicely. */
- if ((viewops_flag & VIEWOPS_FLAG_USE_MOUSE_INIT) == 0) {
- viewops_flag &= ~VIEWOPS_FLAG_DEPTH_NAVIGATE;
- }
-
- /* we need the depth info before changing any viewport options */
- if (viewops_flag & VIEWOPS_FLAG_DEPTH_NAVIGATE) {
- float fallback_depth_pt[3];
-
- view3d_operator_needs_opengl(C); /* needed for zbuf drawing */
-
- negate_v3_v3(fallback_depth_pt, rv3d->ofs);
-
- vod->use_dyn_ofs = ED_view3d_autodist(
- depsgraph, vod->ar, vod->v3d,
- event->mval, vod->dyn_ofs, true, fallback_depth_pt);
- }
- else {
- vod->use_dyn_ofs = false;
- }
-
- if (viewops_flag & VIEWOPS_FLAG_PERSP_ENSURE) {
- if (ED_view3d_persp_ensure(depsgraph, vod->v3d, vod->ar)) {
- /* If we're switching from camera view to the perspective one,
- * need to tag viewport update, so camera vuew and borders
- * are properly updated.
- */
- ED_region_tag_redraw(vod->ar);
- }
- }
-
- /* set the view from the camera, if view locking is enabled.
- * we may want to make this optional but for now its needed always */
- ED_view3d_camera_lock_init(depsgraph, vod->v3d, vod->rv3d);
-
- vod->init.dist = rv3d->dist;
- vod->init.camzoom = rv3d->camzoom;
- copy_qt_qt(vod->init.quat, rv3d->viewquat);
- vod->init.event_xy[0] = vod->prev.event_xy[0] = event->x;
- vod->init.event_xy[1] = vod->prev.event_xy[1] = event->y;
-
- if (viewops_flag & VIEWOPS_FLAG_USE_MOUSE_INIT) {
- vod->init.event_xy_offset[0] = 0;
- vod->init.event_xy_offset[1] = 0;
- }
- else {
- /* Simulate the event starting in the middle of the region. */
- vod->init.event_xy_offset[0] = BLI_rcti_cent_x(&vod->ar->winrct) - event->x;
- vod->init.event_xy_offset[1] = BLI_rcti_cent_y(&vod->ar->winrct) - event->y;
- }
-
- vod->init.event_type = event->type;
- copy_v3_v3(vod->init.ofs, rv3d->ofs);
-
- copy_qt_qt(vod->curr.viewquat, rv3d->viewquat);
-
- if (viewops_flag & VIEWOPS_FLAG_ORBIT_SELECT) {
- float ofs[3];
- if (view3d_orbit_calc_center(C, ofs) || (vod->use_dyn_ofs == false)) {
- vod->use_dyn_ofs = true;
- negate_v3_v3(vod->dyn_ofs, ofs);
- viewops_flag &= ~VIEWOPS_FLAG_DEPTH_NAVIGATE;
- }
- }
-
- if (viewops_flag & VIEWOPS_FLAG_DEPTH_NAVIGATE) {
- if (vod->use_dyn_ofs) {
- if (rv3d->is_persp) {
- float my_origin[3]; /* original G.vd->ofs */
- float my_pivot[3]; /* view */
- float dvec[3];
-
- /* locals for dist correction */
- float mat[3][3];
- float upvec[3];
-
- negate_v3_v3(my_origin, rv3d->ofs); /* ofs is flipped */
-
- /* Set the dist value to be the distance from this 3d point this means youll
- * always be able to zoom into it and panning wont go bad when dist was zero */
-
- /* remove dist value */
- upvec[0] = upvec[1] = 0;
- upvec[2] = rv3d->dist;
- copy_m3_m4(mat, rv3d->viewinv);
-
- mul_m3_v3(mat, upvec);
- sub_v3_v3v3(my_pivot, rv3d->ofs, upvec);
- negate_v3(my_pivot); /* ofs is flipped */
-
- /* find a new ofs value that is along the view axis
- * (rather than the mouse location) */
- closest_to_line_v3(dvec, vod->dyn_ofs, my_pivot, my_origin);
- vod->init.dist = rv3d->dist = len_v3v3(my_pivot, dvec);
-
- negate_v3_v3(rv3d->ofs, dvec);
- }
- else {
- const float mval_ar_mid[2] = {
- (float)vod->ar->winx / 2.0f,
- (float)vod->ar->winy / 2.0f};
-
- ED_view3d_win_to_3d(vod->v3d, vod->ar, vod->dyn_ofs, mval_ar_mid, rv3d->ofs);
- negate_v3(rv3d->ofs);
- }
- negate_v3(vod->dyn_ofs);
- copy_v3_v3(vod->init.ofs, rv3d->ofs);
- }
- }
-
- /* For dolly */
- ED_view3d_win_to_vector(vod->ar, (const float[2]){UNPACK2(event->mval)}, vod->init.mousevec);
-
- {
- const int event_xy_offset[2] = {
- event->x + vod->init.event_xy_offset[0],
- event->y + vod->init.event_xy_offset[1],
- };
- /* For rotation with trackball rotation. */
- calctrackballvec(&vod->ar->winrct, event_xy_offset, vod->init.trackvec);
- }
-
- {
- float tvec[3];
- negate_v3_v3(tvec, rv3d->ofs);
- vod->init.zfac = ED_view3d_calc_zfac(rv3d, tvec, NULL);
- }
-
- vod->reverse = 1.0f;
- if (rv3d->persmat[2][1] < 0.0f) {
- vod->reverse = -1.0f;
- }
-
- rv3d->rflag |= RV3D_NAVIGATING;
+static void viewops_data_create(bContext *C,
+ wmOperator *op,
+ const wmEvent *event,
+ enum eViewOpsFlag viewops_flag)
+{
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ ViewOpsData *vod = op->customdata;
+ RegionView3D *rv3d = vod->rv3d;
+
+ /* Could do this more nicely. */
+ if ((viewops_flag & VIEWOPS_FLAG_USE_MOUSE_INIT) == 0) {
+ viewops_flag &= ~VIEWOPS_FLAG_DEPTH_NAVIGATE;
+ }
+
+ /* we need the depth info before changing any viewport options */
+ if (viewops_flag & VIEWOPS_FLAG_DEPTH_NAVIGATE) {
+ float fallback_depth_pt[3];
+
+ view3d_operator_needs_opengl(C); /* needed for zbuf drawing */
+
+ negate_v3_v3(fallback_depth_pt, rv3d->ofs);
+
+ vod->use_dyn_ofs = ED_view3d_autodist(
+ depsgraph, vod->ar, vod->v3d, event->mval, vod->dyn_ofs, true, fallback_depth_pt);
+ }
+ else {
+ vod->use_dyn_ofs = false;
+ }
+
+ if (viewops_flag & VIEWOPS_FLAG_PERSP_ENSURE) {
+ if (ED_view3d_persp_ensure(depsgraph, vod->v3d, vod->ar)) {
+ /* If we're switching from camera view to the perspective one,
+ * need to tag viewport update, so camera vuew and borders
+ * are properly updated.
+ */
+ ED_region_tag_redraw(vod->ar);
+ }
+ }
+
+ /* set the view from the camera, if view locking is enabled.
+ * we may want to make this optional but for now its needed always */
+ ED_view3d_camera_lock_init(depsgraph, vod->v3d, vod->rv3d);
+
+ vod->init.dist = rv3d->dist;
+ vod->init.camzoom = rv3d->camzoom;
+ copy_qt_qt(vod->init.quat, rv3d->viewquat);
+ vod->init.event_xy[0] = vod->prev.event_xy[0] = event->x;
+ vod->init.event_xy[1] = vod->prev.event_xy[1] = event->y;
+
+ if (viewops_flag & VIEWOPS_FLAG_USE_MOUSE_INIT) {
+ vod->init.event_xy_offset[0] = 0;
+ vod->init.event_xy_offset[1] = 0;
+ }
+ else {
+ /* Simulate the event starting in the middle of the region. */
+ vod->init.event_xy_offset[0] = BLI_rcti_cent_x(&vod->ar->winrct) - event->x;
+ vod->init.event_xy_offset[1] = BLI_rcti_cent_y(&vod->ar->winrct) - event->y;
+ }
+
+ vod->init.event_type = event->type;
+ copy_v3_v3(vod->init.ofs, rv3d->ofs);
+
+ copy_qt_qt(vod->curr.viewquat, rv3d->viewquat);
+
+ if (viewops_flag & VIEWOPS_FLAG_ORBIT_SELECT) {
+ float ofs[3];
+ if (view3d_orbit_calc_center(C, ofs) || (vod->use_dyn_ofs == false)) {
+ vod->use_dyn_ofs = true;
+ negate_v3_v3(vod->dyn_ofs, ofs);
+ viewops_flag &= ~VIEWOPS_FLAG_DEPTH_NAVIGATE;
+ }
+ }
+
+ if (viewops_flag & VIEWOPS_FLAG_DEPTH_NAVIGATE) {
+ if (vod->use_dyn_ofs) {
+ if (rv3d->is_persp) {
+ float my_origin[3]; /* original G.vd->ofs */
+ float my_pivot[3]; /* view */
+ float dvec[3];
+
+ /* locals for dist correction */
+ float mat[3][3];
+ float upvec[3];
+
+ negate_v3_v3(my_origin, rv3d->ofs); /* ofs is flipped */
+
+ /* Set the dist value to be the distance from this 3d point this means youll
+ * always be able to zoom into it and panning wont go bad when dist was zero */
+
+ /* remove dist value */
+ upvec[0] = upvec[1] = 0;
+ upvec[2] = rv3d->dist;
+ copy_m3_m4(mat, rv3d->viewinv);
+
+ mul_m3_v3(mat, upvec);
+ sub_v3_v3v3(my_pivot, rv3d->ofs, upvec);
+ negate_v3(my_pivot); /* ofs is flipped */
+
+ /* find a new ofs value that is along the view axis
+ * (rather than the mouse location) */
+ closest_to_line_v3(dvec, vod->dyn_ofs, my_pivot, my_origin);
+ vod->init.dist = rv3d->dist = len_v3v3(my_pivot, dvec);
+
+ negate_v3_v3(rv3d->ofs, dvec);
+ }
+ else {
+ const float mval_ar_mid[2] = {(float)vod->ar->winx / 2.0f, (float)vod->ar->winy / 2.0f};
+
+ ED_view3d_win_to_3d(vod->v3d, vod->ar, vod->dyn_ofs, mval_ar_mid, rv3d->ofs);
+ negate_v3(rv3d->ofs);
+ }
+ negate_v3(vod->dyn_ofs);
+ copy_v3_v3(vod->init.ofs, rv3d->ofs);
+ }
+ }
+
+ /* For dolly */
+ ED_view3d_win_to_vector(vod->ar, (const float[2]){UNPACK2(event->mval)}, vod->init.mousevec);
+
+ {
+ const int event_xy_offset[2] = {
+ event->x + vod->init.event_xy_offset[0],
+ event->y + vod->init.event_xy_offset[1],
+ };
+ /* For rotation with trackball rotation. */
+ calctrackballvec(&vod->ar->winrct, event_xy_offset, vod->init.trackvec);
+ }
+
+ {
+ float tvec[3];
+ negate_v3_v3(tvec, rv3d->ofs);
+ vod->init.zfac = ED_view3d_calc_zfac(rv3d, tvec, NULL);
+ }
+
+ vod->reverse = 1.0f;
+ if (rv3d->persmat[2][1] < 0.0f) {
+ vod->reverse = -1.0f;
+ }
+
+ rv3d->rflag |= RV3D_NAVIGATING;
}
static void viewops_data_free(bContext *C, wmOperator *op)
{
- ARegion *ar;
+ ARegion *ar;
#if 0
- Paint *p = BKE_paint_get_active_from_context(C);
+ Paint *p = BKE_paint_get_active_from_context(C);
#endif
- if (op->customdata) {
- ViewOpsData *vod = op->customdata;
- ar = vod->ar;
- vod->rv3d->rflag &= ~RV3D_NAVIGATING;
-
- if (vod->timer) {
- WM_event_remove_timer(CTX_wm_manager(C), vod->timer->win, vod->timer);
- }
-
- MEM_freeN(vod);
- op->customdata = NULL;
- }
- else {
- ar = CTX_wm_region(C);
- }
+ if (op->customdata) {
+ ViewOpsData *vod = op->customdata;
+ ar = vod->ar;
+ vod->rv3d->rflag &= ~RV3D_NAVIGATING;
+
+ if (vod->timer) {
+ WM_event_remove_timer(CTX_wm_manager(C), vod->timer->win, vod->timer);
+ }
+
+ MEM_freeN(vod);
+ op->customdata = NULL;
+ }
+ else {
+ ar = CTX_wm_region(C);
+ }
#if 0
- if (p && (p->flags & PAINT_FAST_NAVIGATE))
+ if (p && (p->flags & PAINT_FAST_NAVIGATE))
#endif
- {
- ED_region_tag_redraw(ar);
- }
+ {
+ ED_region_tag_redraw(ar);
+ }
}
/** \} */
@@ -551,444 +551,445 @@ static void viewops_data_free(bContext *C, wmOperator *op)
* \{ */
enum {
- VIEW_PASS = 0,
- VIEW_APPLY,
- VIEW_CONFIRM,
+ VIEW_PASS = 0,
+ VIEW_APPLY,
+ VIEW_CONFIRM,
};
/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */
enum {
- VIEW_MODAL_CONFIRM = 1, /* used for all view operations */
- VIEWROT_MODAL_AXIS_SNAP_ENABLE = 2,
- VIEWROT_MODAL_AXIS_SNAP_DISABLE = 3,
- VIEWROT_MODAL_SWITCH_ZOOM = 4,
- VIEWROT_MODAL_SWITCH_MOVE = 5,
- VIEWROT_MODAL_SWITCH_ROTATE = 6,
+ VIEW_MODAL_CONFIRM = 1, /* used for all view operations */
+ VIEWROT_MODAL_AXIS_SNAP_ENABLE = 2,
+ VIEWROT_MODAL_AXIS_SNAP_DISABLE = 3,
+ VIEWROT_MODAL_SWITCH_ZOOM = 4,
+ VIEWROT_MODAL_SWITCH_MOVE = 5,
+ VIEWROT_MODAL_SWITCH_ROTATE = 6,
};
/* called in transform_ops.c, on each regeneration of keymaps */
void viewrotate_modal_keymap(wmKeyConfig *keyconf)
{
- static const EnumPropertyItem modal_items[] = {
- {VIEW_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
+ static const EnumPropertyItem modal_items[] = {
+ {VIEW_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
- {VIEWROT_MODAL_AXIS_SNAP_ENABLE, "AXIS_SNAP_ENABLE", 0, "Axis Snap", ""},
- {VIEWROT_MODAL_AXIS_SNAP_DISABLE, "AXIS_SNAP_DISABLE", 0, "Axis Snap (Off)", ""},
+ {VIEWROT_MODAL_AXIS_SNAP_ENABLE, "AXIS_SNAP_ENABLE", 0, "Axis Snap", ""},
+ {VIEWROT_MODAL_AXIS_SNAP_DISABLE, "AXIS_SNAP_DISABLE", 0, "Axis Snap (Off)", ""},
- {VIEWROT_MODAL_SWITCH_ZOOM, "SWITCH_TO_ZOOM", 0, "Switch to Zoom"},
- {VIEWROT_MODAL_SWITCH_MOVE, "SWITCH_TO_MOVE", 0, "Switch to Move"},
+ {VIEWROT_MODAL_SWITCH_ZOOM, "SWITCH_TO_ZOOM", 0, "Switch to Zoom"},
+ {VIEWROT_MODAL_SWITCH_MOVE, "SWITCH_TO_MOVE", 0, "Switch to Move"},
- {0, NULL, 0, NULL, NULL},
- };
+ {0, NULL, 0, NULL, NULL},
+ };
- wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Rotate Modal");
+ wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Rotate Modal");
- /* this function is called for each spacetype, only needs to add map once */
- if (keymap && keymap->modal_items) {
- return;
- }
+ /* this function is called for each spacetype, only needs to add map once */
+ if (keymap && keymap->modal_items) {
+ return;
+ }
- keymap = WM_modalkeymap_add(keyconf, "View3D Rotate Modal", modal_items);
+ keymap = WM_modalkeymap_add(keyconf, "View3D Rotate Modal", modal_items);
- /* disabled mode switching for now, can re-implement better, later on */
+ /* disabled mode switching for now, can re-implement better, later on */
#if 0
- WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ZOOM);
- WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ZOOM);
- WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_MOVE);
+ WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ZOOM);
+ WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ZOOM);
+ WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_MOVE);
#endif
- /* assign map to operators */
- WM_modalkeymap_assign(keymap, "VIEW3D_OT_rotate");
+ /* assign map to operators */
+ WM_modalkeymap_assign(keymap, "VIEW3D_OT_rotate");
}
static void viewrotate_apply_dyn_ofs(ViewOpsData *vod, const float viewquat_new[4])
{
- if (vod->use_dyn_ofs) {
- RegionView3D *rv3d = vod->rv3d;
- view3d_orbit_apply_dyn_ofs(rv3d->ofs, vod->init.ofs, vod->init.quat, viewquat_new, vod->dyn_ofs);
- }
+ if (vod->use_dyn_ofs) {
+ RegionView3D *rv3d = vod->rv3d;
+ view3d_orbit_apply_dyn_ofs(
+ rv3d->ofs, vod->init.ofs, vod->init.quat, viewquat_new, vod->dyn_ofs);
+ }
}
static void viewrotate_apply_snap(ViewOpsData *vod)
{
- const float axis_limit = DEG2RADF(45 / 3);
-
- RegionView3D *rv3d = vod->rv3d;
-
- float viewquat_inv[4];
- float zaxis[3] = {0, 0, 1};
- float zaxis_best[3];
- int x, y, z;
- bool found = false;
-
- invert_qt_qt_normalized(viewquat_inv, vod->curr.viewquat);
-
- mul_qt_v3(viewquat_inv, zaxis);
- normalize_v3(zaxis);
-
-
- for (x = -1; x < 2; x++) {
- for (y = -1; y < 2; y++) {
- for (z = -1; z < 2; z++) {
- if (x || y || z) {
- float zaxis_test[3] = {x, y, z};
-
- normalize_v3(zaxis_test);
-
- if (angle_normalized_v3v3(zaxis_test, zaxis) < axis_limit) {
- copy_v3_v3(zaxis_best, zaxis_test);
- found = true;
- }
- }
- }
- }
- }
-
- if (found) {
-
- /* find the best roll */
- float quat_roll[4], quat_final[4], quat_best[4], quat_snap[4];
- float viewquat_align[4]; /* viewquat aligned to zaxis_best */
- float viewquat_align_inv[4]; /* viewquat aligned to zaxis_best */
- float best_angle = axis_limit;
- int j;
-
- /* viewquat_align is the original viewquat aligned to the snapped axis
- * for testing roll */
- rotation_between_vecs_to_quat(viewquat_align, zaxis_best, zaxis);
- normalize_qt(viewquat_align);
- mul_qt_qtqt(viewquat_align, vod->curr.viewquat, viewquat_align);
- normalize_qt(viewquat_align);
- invert_qt_qt_normalized(viewquat_align_inv, viewquat_align);
-
- vec_to_quat(quat_snap, zaxis_best, OB_NEGZ, OB_POSY);
- normalize_qt(quat_snap);
- invert_qt_normalized(quat_snap);
-
- /* check if we can find the roll */
- found = false;
-
- /* find best roll */
- for (j = 0; j < 8; j++) {
- float angle;
- float xaxis1[3] = {1, 0, 0};
- float xaxis2[3] = {1, 0, 0};
- float quat_final_inv[4];
-
- axis_angle_to_quat(quat_roll, zaxis_best, (float)j * DEG2RADF(45.0f));
- normalize_qt(quat_roll);
-
- mul_qt_qtqt(quat_final, quat_snap, quat_roll);
- normalize_qt(quat_final);
-
- /* compare 2 vector angles to find the least roll */
- invert_qt_qt_normalized(quat_final_inv, quat_final);
- mul_qt_v3(viewquat_align_inv, xaxis1);
- mul_qt_v3(quat_final_inv, xaxis2);
- angle = angle_v3v3(xaxis1, xaxis2);
-
- if (angle <= best_angle) {
- found = true;
- best_angle = angle;
- copy_qt_qt(quat_best, quat_final);
- }
- }
-
- if (found) {
- /* lock 'quat_best' to an axis view if we can */
- rv3d->view = ED_view3d_quat_to_axis_view(quat_best, 0.01f);
- if (rv3d->view != RV3D_VIEW_USER) {
- ED_view3d_quat_from_axis_view(rv3d->view, quat_best);
- }
- }
- else {
- copy_qt_qt(quat_best, viewquat_align);
- }
-
- copy_qt_qt(rv3d->viewquat, quat_best);
-
- viewrotate_apply_dyn_ofs(vod, rv3d->viewquat);
- }
+ const float axis_limit = DEG2RADF(45 / 3);
+
+ RegionView3D *rv3d = vod->rv3d;
+
+ float viewquat_inv[4];
+ float zaxis[3] = {0, 0, 1};
+ float zaxis_best[3];
+ int x, y, z;
+ bool found = false;
+
+ invert_qt_qt_normalized(viewquat_inv, vod->curr.viewquat);
+
+ mul_qt_v3(viewquat_inv, zaxis);
+ normalize_v3(zaxis);
+
+ for (x = -1; x < 2; x++) {
+ for (y = -1; y < 2; y++) {
+ for (z = -1; z < 2; z++) {
+ if (x || y || z) {
+ float zaxis_test[3] = {x, y, z};
+
+ normalize_v3(zaxis_test);
+
+ if (angle_normalized_v3v3(zaxis_test, zaxis) < axis_limit) {
+ copy_v3_v3(zaxis_best, zaxis_test);
+ found = true;
+ }
+ }
+ }
+ }
+ }
+
+ if (found) {
+
+ /* find the best roll */
+ float quat_roll[4], quat_final[4], quat_best[4], quat_snap[4];
+ float viewquat_align[4]; /* viewquat aligned to zaxis_best */
+ float viewquat_align_inv[4]; /* viewquat aligned to zaxis_best */
+ float best_angle = axis_limit;
+ int j;
+
+ /* viewquat_align is the original viewquat aligned to the snapped axis
+ * for testing roll */
+ rotation_between_vecs_to_quat(viewquat_align, zaxis_best, zaxis);
+ normalize_qt(viewquat_align);
+ mul_qt_qtqt(viewquat_align, vod->curr.viewquat, viewquat_align);
+ normalize_qt(viewquat_align);
+ invert_qt_qt_normalized(viewquat_align_inv, viewquat_align);
+
+ vec_to_quat(quat_snap, zaxis_best, OB_NEGZ, OB_POSY);
+ normalize_qt(quat_snap);
+ invert_qt_normalized(quat_snap);
+
+ /* check if we can find the roll */
+ found = false;
+
+ /* find best roll */
+ for (j = 0; j < 8; j++) {
+ float angle;
+ float xaxis1[3] = {1, 0, 0};
+ float xaxis2[3] = {1, 0, 0};
+ float quat_final_inv[4];
+
+ axis_angle_to_quat(quat_roll, zaxis_best, (float)j * DEG2RADF(45.0f));
+ normalize_qt(quat_roll);
+
+ mul_qt_qtqt(quat_final, quat_snap, quat_roll);
+ normalize_qt(quat_final);
+
+ /* compare 2 vector angles to find the least roll */
+ invert_qt_qt_normalized(quat_final_inv, quat_final);
+ mul_qt_v3(viewquat_align_inv, xaxis1);
+ mul_qt_v3(quat_final_inv, xaxis2);
+ angle = angle_v3v3(xaxis1, xaxis2);
+
+ if (angle <= best_angle) {
+ found = true;
+ best_angle = angle;
+ copy_qt_qt(quat_best, quat_final);
+ }
+ }
+
+ if (found) {
+ /* lock 'quat_best' to an axis view if we can */
+ rv3d->view = ED_view3d_quat_to_axis_view(quat_best, 0.01f);
+ if (rv3d->view != RV3D_VIEW_USER) {
+ ED_view3d_quat_from_axis_view(rv3d->view, quat_best);
+ }
+ }
+ else {
+ copy_qt_qt(quat_best, viewquat_align);
+ }
+
+ copy_qt_qt(rv3d->viewquat, quat_best);
+
+ viewrotate_apply_dyn_ofs(vod, rv3d->viewquat);
+ }
}
static void viewrotate_apply(ViewOpsData *vod, const int event_xy[2])
{
- RegionView3D *rv3d = vod->rv3d;
+ RegionView3D *rv3d = vod->rv3d;
- rv3d->view = RV3D_VIEW_USER; /* need to reset every time because of view snapping */
+ rv3d->view = RV3D_VIEW_USER; /* need to reset every time because of view snapping */
- if (U.flag & USER_TRACKBALL) {
- float axis[3], q1[4], dvec[3], newvec[3];
- float angle;
+ if (U.flag & USER_TRACKBALL) {
+ float axis[3], q1[4], dvec[3], newvec[3];
+ float angle;
- {
- const int event_xy_offset[2] = {
- event_xy[0] + vod->init.event_xy_offset[0],
- event_xy[1] + vod->init.event_xy_offset[1],
- };
- calctrackballvec(&vod->ar->winrct, event_xy_offset, newvec);
- }
+ {
+ const int event_xy_offset[2] = {
+ event_xy[0] + vod->init.event_xy_offset[0],
+ event_xy[1] + vod->init.event_xy_offset[1],
+ };
+ calctrackballvec(&vod->ar->winrct, event_xy_offset, newvec);
+ }
- sub_v3_v3v3(dvec, newvec, vod->init.trackvec);
+ sub_v3_v3v3(dvec, newvec, vod->init.trackvec);
- angle = (len_v3(dvec) / (2.0f * TRACKBALLSIZE)) * (float)M_PI;
+ angle = (len_v3(dvec) / (2.0f * TRACKBALLSIZE)) * (float)M_PI;
- /* Allow for rotation beyond the interval [-pi, pi] */
- angle = angle_wrap_rad(angle);
+ /* Allow for rotation beyond the interval [-pi, pi] */
+ angle = angle_wrap_rad(angle);
- /* This relation is used instead of the actual angle between vectors
- * so that the angle of rotation is linearly proportional to
- * the distance that the mouse is dragged. */
+ /* This relation is used instead of the actual angle between vectors
+ * so that the angle of rotation is linearly proportional to
+ * the distance that the mouse is dragged. */
- cross_v3_v3v3(axis, vod->init.trackvec, newvec);
- axis_angle_to_quat(q1, axis, angle);
+ cross_v3_v3v3(axis, vod->init.trackvec, newvec);
+ axis_angle_to_quat(q1, axis, angle);
- mul_qt_qtqt(vod->curr.viewquat, q1, vod->init.quat);
+ mul_qt_qtqt(vod->curr.viewquat, q1, vod->init.quat);
- viewrotate_apply_dyn_ofs(vod, vod->curr.viewquat);
- }
- else {
- /* New turntable view code by John Aughey */
- float quat_local_x[4], quat_global_z[4];
- float m[3][3];
- float m_inv[3][3];
- const float zvec_global[3] = {0.0f, 0.0f, 1.0f};
- float xaxis[3];
+ viewrotate_apply_dyn_ofs(vod, vod->curr.viewquat);
+ }
+ else {
+ /* New turntable view code by John Aughey */
+ float quat_local_x[4], quat_global_z[4];
+ float m[3][3];
+ float m_inv[3][3];
+ const float zvec_global[3] = {0.0f, 0.0f, 1.0f};
+ float xaxis[3];
- /* Sensitivity will control how fast the viewport rotates. 0.007 was
- * obtained experimentally by looking at viewport rotation sensitivities
- * on other modeling programs. */
- /* Perhaps this should be a configurable user parameter. */
- const float sensitivity = 0.007f;
+ /* Sensitivity will control how fast the viewport rotates. 0.007 was
+ * obtained experimentally by looking at viewport rotation sensitivities
+ * on other modeling programs. */
+ /* Perhaps this should be a configurable user parameter. */
+ const float sensitivity = 0.007f;
- /* Get the 3x3 matrix and its inverse from the quaternion */
- quat_to_mat3(m, vod->curr.viewquat);
- invert_m3_m3(m_inv, m);
+ /* Get the 3x3 matrix and its inverse from the quaternion */
+ quat_to_mat3(m, vod->curr.viewquat);
+ invert_m3_m3(m_inv, m);
- /* avoid gimble lock */
+ /* avoid gimble lock */
#if 1
- if (len_squared_v3v3(zvec_global, m_inv[2]) > 0.001f) {
- float fac;
- cross_v3_v3v3(xaxis, zvec_global, m_inv[2]);
- if (dot_v3v3(xaxis, m_inv[0]) < 0) {
- negate_v3(xaxis);
- }
- fac = angle_normalized_v3v3(zvec_global, m_inv[2]) / (float)M_PI;
- fac = fabsf(fac - 0.5f) * 2;
- fac = fac * fac;
- interp_v3_v3v3(xaxis, xaxis, m_inv[0], fac);
- }
- else {
- copy_v3_v3(xaxis, m_inv[0]);
- }
+ if (len_squared_v3v3(zvec_global, m_inv[2]) > 0.001f) {
+ float fac;
+ cross_v3_v3v3(xaxis, zvec_global, m_inv[2]);
+ if (dot_v3v3(xaxis, m_inv[0]) < 0) {
+ negate_v3(xaxis);
+ }
+ fac = angle_normalized_v3v3(zvec_global, m_inv[2]) / (float)M_PI;
+ fac = fabsf(fac - 0.5f) * 2;
+ fac = fac * fac;
+ interp_v3_v3v3(xaxis, xaxis, m_inv[0], fac);
+ }
+ else {
+ copy_v3_v3(xaxis, m_inv[0]);
+ }
#else
- copy_v3_v3(xaxis, m_inv[0]);
+ copy_v3_v3(xaxis, m_inv[0]);
#endif
- /* Determine the direction of the x vector (for rotating up and down) */
- /* This can likely be computed directly from the quaternion. */
+ /* Determine the direction of the x vector (for rotating up and down) */
+ /* This can likely be computed directly from the quaternion. */
- /* Perform the up/down rotation */
- axis_angle_to_quat(quat_local_x, xaxis, sensitivity * -(event_xy[1] - vod->prev.event_xy[1]));
- mul_qt_qtqt(quat_local_x, vod->curr.viewquat, quat_local_x);
+ /* Perform the up/down rotation */
+ axis_angle_to_quat(quat_local_x, xaxis, sensitivity * -(event_xy[1] - vod->prev.event_xy[1]));
+ mul_qt_qtqt(quat_local_x, vod->curr.viewquat, quat_local_x);
- /* Perform the orbital rotation */
- axis_angle_to_quat_single(quat_global_z, 'Z', sensitivity * vod->reverse * (event_xy[0] - vod->prev.event_xy[0]));
- mul_qt_qtqt(vod->curr.viewquat, quat_local_x, quat_global_z);
+ /* Perform the orbital rotation */
+ axis_angle_to_quat_single(
+ quat_global_z, 'Z', sensitivity * vod->reverse * (event_xy[0] - vod->prev.event_xy[0]));
+ mul_qt_qtqt(vod->curr.viewquat, quat_local_x, quat_global_z);
- viewrotate_apply_dyn_ofs(vod, vod->curr.viewquat);
- }
+ viewrotate_apply_dyn_ofs(vod, vod->curr.viewquat);
+ }
- /* avoid precision loss over time */
- normalize_qt(vod->curr.viewquat);
+ /* avoid precision loss over time */
+ normalize_qt(vod->curr.viewquat);
- /* use a working copy so view rotation locking doesn't overwrite the locked
- * rotation back into the view we calculate with */
- copy_qt_qt(rv3d->viewquat, vod->curr.viewquat);
+ /* use a working copy so view rotation locking doesn't overwrite the locked
+ * rotation back into the view we calculate with */
+ copy_qt_qt(rv3d->viewquat, vod->curr.viewquat);
- /* check for view snap,
- * note: don't apply snap to vod->viewquat so the view wont jam up */
- if (vod->axis_snap) {
- viewrotate_apply_snap(vod);
- }
- vod->prev.event_xy[0] = event_xy[0];
- vod->prev.event_xy[1] = event_xy[1];
+ /* check for view snap,
+ * note: don't apply snap to vod->viewquat so the view wont jam up */
+ if (vod->axis_snap) {
+ viewrotate_apply_snap(vod);
+ }
+ vod->prev.event_xy[0] = event_xy[0];
+ vod->prev.event_xy[1] = event_xy[1];
- ED_view3d_camera_lock_sync(vod->depsgraph, vod->v3d, rv3d);
+ ED_view3d_camera_lock_sync(vod->depsgraph, vod->v3d, rv3d);
- ED_region_tag_redraw(vod->ar);
+ ED_region_tag_redraw(vod->ar);
}
static int viewrotate_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
- ViewOpsData *vod = op->customdata;
- short event_code = VIEW_PASS;
- bool use_autokey = false;
- int ret = OPERATOR_RUNNING_MODAL;
-
- /* execute the events */
- if (event->type == MOUSEMOVE) {
- event_code = VIEW_APPLY;
- }
- else if (event->type == EVT_MODAL_MAP) {
- switch (event->val) {
- case VIEW_MODAL_CONFIRM:
- event_code = VIEW_CONFIRM;
- break;
- case VIEWROT_MODAL_AXIS_SNAP_ENABLE:
- vod->axis_snap = true;
- event_code = VIEW_APPLY;
- break;
- case VIEWROT_MODAL_AXIS_SNAP_DISABLE:
- vod->axis_snap = false;
- event_code = VIEW_APPLY;
- break;
- case VIEWROT_MODAL_SWITCH_ZOOM:
- WM_operator_name_call(C, "VIEW3D_OT_zoom", WM_OP_INVOKE_DEFAULT, NULL);
- event_code = VIEW_CONFIRM;
- break;
- case VIEWROT_MODAL_SWITCH_MOVE:
- WM_operator_name_call(C, "VIEW3D_OT_move", WM_OP_INVOKE_DEFAULT, NULL);
- event_code = VIEW_CONFIRM;
- break;
- }
- }
- else if (event->type == vod->init.event_type && event->val == KM_RELEASE) {
- event_code = VIEW_CONFIRM;
- }
-
- if (event_code == VIEW_APPLY) {
- viewrotate_apply(vod, &event->x);
- if (ED_screen_animation_playing(CTX_wm_manager(C))) {
- use_autokey = true;
- }
- }
- else if (event_code == VIEW_CONFIRM) {
- ED_view3d_depth_tag_update(vod->rv3d);
- use_autokey = true;
- ret = OPERATOR_FINISHED;
- }
-
- if (use_autokey) {
- ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, true, true);
- }
-
- if (ret & OPERATOR_FINISHED) {
- viewops_data_free(C, op);
- }
-
- return ret;
+ ViewOpsData *vod = op->customdata;
+ short event_code = VIEW_PASS;
+ bool use_autokey = false;
+ int ret = OPERATOR_RUNNING_MODAL;
+
+ /* execute the events */
+ if (event->type == MOUSEMOVE) {
+ event_code = VIEW_APPLY;
+ }
+ else if (event->type == EVT_MODAL_MAP) {
+ switch (event->val) {
+ case VIEW_MODAL_CONFIRM:
+ event_code = VIEW_CONFIRM;
+ break;
+ case VIEWROT_MODAL_AXIS_SNAP_ENABLE:
+ vod->axis_snap = true;
+ event_code = VIEW_APPLY;
+ break;
+ case VIEWROT_MODAL_AXIS_SNAP_DISABLE:
+ vod->axis_snap = false;
+ event_code = VIEW_APPLY;
+ break;
+ case VIEWROT_MODAL_SWITCH_ZOOM:
+ WM_operator_name_call(C, "VIEW3D_OT_zoom", WM_OP_INVOKE_DEFAULT, NULL);
+ event_code = VIEW_CONFIRM;
+ break;
+ case VIEWROT_MODAL_SWITCH_MOVE:
+ WM_operator_name_call(C, "VIEW3D_OT_move", WM_OP_INVOKE_DEFAULT, NULL);
+ event_code = VIEW_CONFIRM;
+ break;
+ }
+ }
+ else if (event->type == vod->init.event_type && event->val == KM_RELEASE) {
+ event_code = VIEW_CONFIRM;
+ }
+
+ if (event_code == VIEW_APPLY) {
+ viewrotate_apply(vod, &event->x);
+ if (ED_screen_animation_playing(CTX_wm_manager(C))) {
+ use_autokey = true;
+ }
+ }
+ else if (event_code == VIEW_CONFIRM) {
+ ED_view3d_depth_tag_update(vod->rv3d);
+ use_autokey = true;
+ ret = OPERATOR_FINISHED;
+ }
+
+ if (use_autokey) {
+ ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, true, true);
+ }
+
+ if (ret & OPERATOR_FINISHED) {
+ viewops_data_free(C, op);
+ }
+
+ return ret;
}
static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- ViewOpsData *vod;
+ ViewOpsData *vod;
- const bool use_mouse_init = RNA_boolean_get(op->ptr, "use_mouse_init");
+ const bool use_mouse_init = RNA_boolean_get(op->ptr, "use_mouse_init");
- /* makes op->customdata */
- viewops_data_alloc(C, op);
- vod = op->customdata;
+ /* makes op->customdata */
+ viewops_data_alloc(C, op);
+ vod = op->customdata;
- /* poll should check but in some cases fails, see poll func for details */
- if (vod->rv3d->viewlock & RV3D_LOCKED) {
- viewops_data_free(C, op);
- return OPERATOR_PASS_THROUGH;
- }
+ /* poll should check but in some cases fails, see poll func for details */
+ if (vod->rv3d->viewlock & RV3D_LOCKED) {
+ viewops_data_free(C, op);
+ return OPERATOR_PASS_THROUGH;
+ }
- ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->ar);
+ ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->ar);
- viewops_data_create(
- C, op, event,
- viewops_flag_from_prefs() |
- VIEWOPS_FLAG_PERSP_ENSURE |
- (use_mouse_init ? VIEWOPS_FLAG_USE_MOUSE_INIT : 0));
+ viewops_data_create(C,
+ op,
+ event,
+ viewops_flag_from_prefs() | VIEWOPS_FLAG_PERSP_ENSURE |
+ (use_mouse_init ? VIEWOPS_FLAG_USE_MOUSE_INIT : 0));
- if (ELEM(event->type, MOUSEPAN, MOUSEROTATE)) {
- /* Rotate direction we keep always same */
- int event_xy[2];
+ if (ELEM(event->type, MOUSEPAN, MOUSEROTATE)) {
+ /* Rotate direction we keep always same */
+ int event_xy[2];
- if (event->type == MOUSEPAN) {
- if (U.uiflag2 & USER_TRACKPAD_NATURAL) {
- event_xy[0] = 2 * event->x - event->prevx;
- event_xy[1] = 2 * event->y - event->prevy;
- }
- else {
- event_xy[0] = event->prevx;
- event_xy[1] = event->prevy;
- }
- }
- else {
- /* MOUSEROTATE performs orbital rotation, so y axis delta is set to 0 */
- event_xy[0] = event->prevx;
- event_xy[1] = event->y;
- }
+ if (event->type == MOUSEPAN) {
+ if (U.uiflag2 & USER_TRACKPAD_NATURAL) {
+ event_xy[0] = 2 * event->x - event->prevx;
+ event_xy[1] = 2 * event->y - event->prevy;
+ }
+ else {
+ event_xy[0] = event->prevx;
+ event_xy[1] = event->prevy;
+ }
+ }
+ else {
+ /* MOUSEROTATE performs orbital rotation, so y axis delta is set to 0 */
+ event_xy[0] = event->prevx;
+ event_xy[1] = event->y;
+ }
- viewrotate_apply(vod, event_xy);
- ED_view3d_depth_tag_update(vod->rv3d);
+ viewrotate_apply(vod, event_xy);
+ ED_view3d_depth_tag_update(vod->rv3d);
- viewops_data_free(C, op);
+ viewops_data_free(C, op);
- return OPERATOR_FINISHED;
- }
- else {
- /* add temp handler */
- WM_event_add_modal_handler(C, op);
+ return OPERATOR_FINISHED;
+ }
+ else {
+ /* add temp handler */
+ WM_event_add_modal_handler(C, op);
- return OPERATOR_RUNNING_MODAL;
- }
+ return OPERATOR_RUNNING_MODAL;
+ }
}
/* test for unlocked camera view in quad view */
static bool view3d_camera_user_poll(bContext *C)
{
- View3D *v3d;
- ARegion *ar;
+ View3D *v3d;
+ ARegion *ar;
- if (ED_view3d_context_user_region(C, &v3d, &ar)) {
- RegionView3D *rv3d = ar->regiondata;
- if (rv3d->persp == RV3D_CAMOB) {
- return 1;
- }
- }
+ if (ED_view3d_context_user_region(C, &v3d, &ar)) {
+ RegionView3D *rv3d = ar->regiondata;
+ if (rv3d->persp == RV3D_CAMOB) {
+ return 1;
+ }
+ }
- return 0;
+ return 0;
}
static bool view3d_lock_poll(bContext *C)
{
- View3D *v3d = CTX_wm_view3d(C);
- if (v3d) {
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
- if (rv3d) {
- return ED_view3d_offset_lock_check(v3d, rv3d);
- }
- }
- return false;
+ View3D *v3d = CTX_wm_view3d(C);
+ if (v3d) {
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ if (rv3d) {
+ return ED_view3d_offset_lock_check(v3d, rv3d);
+ }
+ }
+ return false;
}
static void viewrotate_cancel(bContext *C, wmOperator *op)
{
- viewops_data_free(C, op);
+ viewops_data_free(C, op);
}
void VIEW3D_OT_rotate(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Rotate View";
- ot->description = "Rotate the view";
- ot->idname = "VIEW3D_OT_rotate";
+ /* identifiers */
+ ot->name = "Rotate View";
+ ot->description = "Rotate the view";
+ ot->idname = "VIEW3D_OT_rotate";
- /* api callbacks */
- ot->invoke = viewrotate_invoke;
- ot->modal = viewrotate_modal;
- ot->poll = ED_operator_region_view3d_active;
- ot->cancel = viewrotate_cancel;
+ /* api callbacks */
+ ot->invoke = viewrotate_invoke;
+ ot->modal = viewrotate_modal;
+ ot->poll = ED_operator_region_view3d_active;
+ ot->cancel = viewrotate_cancel;
- /* flags */
- ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR;
+ /* flags */
+ ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR;
- view3d_operator_properties_common(ot, V3D_OP_PROP_USE_MOUSE_INIT);
+ view3d_operator_properties_common(ot, V3D_OP_PROP_USE_MOUSE_INIT);
}
/** \} */
@@ -998,48 +999,48 @@ void VIEW3D_OT_rotate(wmOperatorType *ot)
* \{ */
#ifdef WITH_INPUT_NDOF
-#define NDOF_HAS_TRANSLATE ((!ED_view3d_offset_lock_check(v3d, rv3d)) && !is_zero_v3(ndof->tvec))
-#define NDOF_HAS_ROTATE (((rv3d->viewlock & RV3D_LOCKED) == 0) && !is_zero_v3(ndof->rvec))
+# define NDOF_HAS_TRANSLATE ((!ED_view3d_offset_lock_check(v3d, rv3d)) && !is_zero_v3(ndof->tvec))
+# define NDOF_HAS_ROTATE (((rv3d->viewlock & RV3D_LOCKED) == 0) && !is_zero_v3(ndof->rvec))
/**
* \param depth_pt: A point to calculate the depth (in perspective mode)
*/
static float view3d_ndof_pan_speed_calc_ex(RegionView3D *rv3d, const float depth_pt[3])
{
- float speed = rv3d->pixsize * NDOF_PIXELS_PER_SECOND;
+ float speed = rv3d->pixsize * NDOF_PIXELS_PER_SECOND;
- if (rv3d->is_persp) {
- speed *= ED_view3d_calc_zfac(rv3d, depth_pt, NULL);
- }
+ if (rv3d->is_persp) {
+ speed *= ED_view3d_calc_zfac(rv3d, depth_pt, NULL);
+ }
- return speed;
+ return speed;
}
static float view3d_ndof_pan_speed_calc_from_dist(RegionView3D *rv3d, const float dist)
{
- float viewinv[4];
- float tvec[3];
+ float viewinv[4];
+ float tvec[3];
- BLI_assert(dist >= 0.0f);
+ BLI_assert(dist >= 0.0f);
- copy_v3_fl3(tvec, 0.0f, 0.0f, dist);
- /* rv3d->viewinv isn't always valid */
-#if 0
- mul_mat3_m4_v3(rv3d->viewinv, tvec);
-#else
- invert_qt_qt_normalized(viewinv, rv3d->viewquat);
- mul_qt_v3(viewinv, tvec);
-#endif
+ copy_v3_fl3(tvec, 0.0f, 0.0f, dist);
+ /* rv3d->viewinv isn't always valid */
+# if 0
+ mul_mat3_m4_v3(rv3d->viewinv, tvec);
+# else
+ invert_qt_qt_normalized(viewinv, rv3d->viewquat);
+ mul_qt_v3(viewinv, tvec);
+# endif
- return view3d_ndof_pan_speed_calc_ex(rv3d, tvec);
+ return view3d_ndof_pan_speed_calc_ex(rv3d, tvec);
}
static float view3d_ndof_pan_speed_calc(RegionView3D *rv3d)
{
- float tvec[3];
- negate_v3_v3(tvec, rv3d->ofs);
+ float tvec[3];
+ negate_v3_v3(tvec, rv3d->ofs);
- return view3d_ndof_pan_speed_calc_ex(rv3d, tvec);
+ return view3d_ndof_pan_speed_calc_ex(rv3d, tvec);
}
/**
@@ -1047,261 +1048,265 @@ static float view3d_ndof_pan_speed_calc(RegionView3D *rv3d)
*
* \param has_zoom: zoom, otherwise dolly, often `!rv3d->is_persp` since it doesn't make sense to dolly in ortho.
*/
-static void view3d_ndof_pan_zoom(
- const struct wmNDOFMotionData *ndof, ScrArea *sa, ARegion *ar,
- const bool has_translate, const bool has_zoom)
+static void view3d_ndof_pan_zoom(const struct wmNDOFMotionData *ndof,
+ ScrArea *sa,
+ ARegion *ar,
+ const bool has_translate,
+ const bool has_zoom)
{
- RegionView3D *rv3d = ar->regiondata;
- float view_inv[4];
- float pan_vec[3];
+ RegionView3D *rv3d = ar->regiondata;
+ float view_inv[4];
+ float pan_vec[3];
- if (has_translate == false && has_zoom == false) {
- return;
- }
+ if (has_translate == false && has_zoom == false) {
+ return;
+ }
- WM_event_ndof_pan_get(ndof, pan_vec, false);
+ WM_event_ndof_pan_get(ndof, pan_vec, false);
- if (has_zoom) {
- /* zoom with Z */
+ if (has_zoom) {
+ /* zoom with Z */
- /* Zoom!
- * velocity should be proportional to the linear velocity attained by rotational motion of same strength
- * [got that?]
- * proportional to arclength = radius * angle
- */
+ /* Zoom!
+ * velocity should be proportional to the linear velocity attained by rotational motion of same strength
+ * [got that?]
+ * proportional to arclength = radius * angle
+ */
- pan_vec[2] = 0.0f;
+ pan_vec[2] = 0.0f;
- /* "zoom in" or "translate"? depends on zoom mode in user settings? */
- if (ndof->tvec[2]) {
- float zoom_distance = rv3d->dist * ndof->dt * ndof->tvec[2];
+ /* "zoom in" or "translate"? depends on zoom mode in user settings? */
+ if (ndof->tvec[2]) {
+ float zoom_distance = rv3d->dist * ndof->dt * ndof->tvec[2];
- if (U.ndof_flag & NDOF_ZOOM_INVERT) {
- zoom_distance = -zoom_distance;
- }
+ if (U.ndof_flag & NDOF_ZOOM_INVERT) {
+ zoom_distance = -zoom_distance;
+ }
- rv3d->dist += zoom_distance;
- }
- }
- else {
- /* dolly with Z */
+ rv3d->dist += zoom_distance;
+ }
+ }
+ else {
+ /* dolly with Z */
- /* all callers must check */
- if (has_translate) {
- BLI_assert(ED_view3d_offset_lock_check((View3D *)sa->spacedata.first, rv3d) == false);
- }
- }
+ /* all callers must check */
+ if (has_translate) {
+ BLI_assert(ED_view3d_offset_lock_check((View3D *)sa->spacedata.first, rv3d) == false);
+ }
+ }
- if (has_translate) {
- const float speed = view3d_ndof_pan_speed_calc(rv3d);
+ if (has_translate) {
+ const float speed = view3d_ndof_pan_speed_calc(rv3d);
- mul_v3_fl(pan_vec, speed * ndof->dt);
+ mul_v3_fl(pan_vec, speed * ndof->dt);
- /* transform motion from view to world coordinates */
- invert_qt_qt_normalized(view_inv, rv3d->viewquat);
- mul_qt_v3(view_inv, pan_vec);
+ /* transform motion from view to world coordinates */
+ invert_qt_qt_normalized(view_inv, rv3d->viewquat);
+ mul_qt_v3(view_inv, pan_vec);
- /* move center of view opposite of hand motion (this is camera mode, not object mode) */
- sub_v3_v3(rv3d->ofs, pan_vec);
+ /* move center of view opposite of hand motion (this is camera mode, not object mode) */
+ sub_v3_v3(rv3d->ofs, pan_vec);
- if (rv3d->viewlock & RV3D_BOXVIEW) {
- view3d_boxview_sync(sa, ar);
- }
- }
+ if (rv3d->viewlock & RV3D_BOXVIEW) {
+ view3d_boxview_sync(sa, ar);
+ }
+ }
}
-
-static void view3d_ndof_orbit(
- const struct wmNDOFMotionData *ndof, ScrArea *sa, ARegion *ar,
- ViewOpsData *vod, const bool apply_dyn_ofs)
+static void view3d_ndof_orbit(const struct wmNDOFMotionData *ndof,
+ ScrArea *sa,
+ ARegion *ar,
+ ViewOpsData *vod,
+ const bool apply_dyn_ofs)
{
- View3D *v3d = sa->spacedata.first;
- RegionView3D *rv3d = ar->regiondata;
+ View3D *v3d = sa->spacedata.first;
+ RegionView3D *rv3d = ar->regiondata;
- float view_inv[4];
+ float view_inv[4];
- BLI_assert((rv3d->viewlock & RV3D_LOCKED) == 0);
+ BLI_assert((rv3d->viewlock & RV3D_LOCKED) == 0);
- ED_view3d_persp_ensure(vod->depsgraph, v3d, ar);
+ ED_view3d_persp_ensure(vod->depsgraph, v3d, ar);
- rv3d->view = RV3D_VIEW_USER;
+ rv3d->view = RV3D_VIEW_USER;
- invert_qt_qt_normalized(view_inv, rv3d->viewquat);
+ invert_qt_qt_normalized(view_inv, rv3d->viewquat);
- if (U.ndof_flag & NDOF_TURNTABLE) {
- float rot[3];
+ if (U.ndof_flag & NDOF_TURNTABLE) {
+ float rot[3];
- /* turntable view code by John Aughey, adapted for 3D mouse by [mce] */
- float angle, quat[4];
- float xvec[3] = {1, 0, 0};
+ /* turntable view code by John Aughey, adapted for 3D mouse by [mce] */
+ float angle, quat[4];
+ float xvec[3] = {1, 0, 0};
- /* only use XY, ignore Z */
- WM_event_ndof_rotate_get(ndof, rot);
+ /* only use XY, ignore Z */
+ WM_event_ndof_rotate_get(ndof, rot);
- /* Determine the direction of the x vector (for rotating up and down) */
- mul_qt_v3(view_inv, xvec);
+ /* Determine the direction of the x vector (for rotating up and down) */
+ mul_qt_v3(view_inv, xvec);
- /* Perform the up/down rotation */
- angle = ndof->dt * rot[0];
- axis_angle_to_quat(quat, xvec, angle);
- mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, quat);
+ /* Perform the up/down rotation */
+ angle = ndof->dt * rot[0];
+ axis_angle_to_quat(quat, xvec, angle);
+ mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, quat);
- /* Perform the orbital rotation */
- angle = ndof->dt * rot[1];
+ /* Perform the orbital rotation */
+ angle = ndof->dt * rot[1];
- /* update the onscreen doo-dad */
- rv3d->rot_angle = angle;
- rv3d->rot_axis[0] = 0;
- rv3d->rot_axis[1] = 0;
- rv3d->rot_axis[2] = 1;
+ /* update the onscreen doo-dad */
+ rv3d->rot_angle = angle;
+ rv3d->rot_axis[0] = 0;
+ rv3d->rot_axis[1] = 0;
+ rv3d->rot_axis[2] = 1;
- axis_angle_to_quat_single(quat, 'Z', angle);
- mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, quat);
- }
- else {
- float quat[4];
- float axis[3];
- float angle = WM_event_ndof_to_axis_angle(ndof, axis);
+ axis_angle_to_quat_single(quat, 'Z', angle);
+ mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, quat);
+ }
+ else {
+ float quat[4];
+ float axis[3];
+ float angle = WM_event_ndof_to_axis_angle(ndof, axis);
- /* transform rotation axis from view to world coordinates */
- mul_qt_v3(view_inv, axis);
+ /* transform rotation axis from view to world coordinates */
+ mul_qt_v3(view_inv, axis);
- /* update the onscreen doo-dad */
- rv3d->rot_angle = angle;
- copy_v3_v3(rv3d->rot_axis, axis);
+ /* update the onscreen doo-dad */
+ rv3d->rot_angle = angle;
+ copy_v3_v3(rv3d->rot_axis, axis);
- axis_angle_to_quat(quat, axis, angle);
+ axis_angle_to_quat(quat, axis, angle);
- /* apply rotation */
- mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, quat);
- }
+ /* apply rotation */
+ mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, quat);
+ }
- if (apply_dyn_ofs) {
- viewrotate_apply_dyn_ofs(vod, rv3d->viewquat);
- }
+ if (apply_dyn_ofs) {
+ viewrotate_apply_dyn_ofs(vod, rv3d->viewquat);
+ }
}
/**
* Called from both fly mode and walk mode,
*/
-void view3d_ndof_fly(
- const wmNDOFMotionData *ndof,
- View3D *v3d, RegionView3D *rv3d,
- const bool use_precision, const short protectflag,
- bool *r_has_translate, bool *r_has_rotate)
-{
- bool has_translate = NDOF_HAS_TRANSLATE;
- bool has_rotate = NDOF_HAS_ROTATE;
-
- float view_inv[4];
- invert_qt_qt_normalized(view_inv, rv3d->viewquat);
-
- rv3d->rot_angle = 0.0f; /* disable onscreen rotation doo-dad */
-
- if (has_translate) {
- /* ignore real 'dist' since fly has its own speed settings,
- * also its overwritten at this point. */
- float speed = view3d_ndof_pan_speed_calc_from_dist(rv3d, 1.0f);
- float trans[3], trans_orig_y;
-
- if (use_precision) {
- speed *= 0.2f;
- }
-
- WM_event_ndof_pan_get(ndof, trans, false);
- mul_v3_fl(trans, speed * ndof->dt);
- trans_orig_y = trans[1];
-
- if (U.ndof_flag & NDOF_FLY_HELICOPTER) {
- trans[1] = 0.0f;
- }
-
- /* transform motion from view to world coordinates */
- mul_qt_v3(view_inv, trans);
-
- if (U.ndof_flag & NDOF_FLY_HELICOPTER) {
- /* replace world z component with device y (yes it makes sense) */
- trans[2] = trans_orig_y;
- }
-
- if (rv3d->persp == RV3D_CAMOB) {
- /* respect camera position locks */
- if (protectflag & OB_LOCK_LOCX) {
- trans[0] = 0.0f;
- }
- if (protectflag & OB_LOCK_LOCY) {
- trans[1] = 0.0f;
- }
- if (protectflag & OB_LOCK_LOCZ) {
- trans[2] = 0.0f;
- }
- }
-
- if (!is_zero_v3(trans)) {
- /* move center of view opposite of hand motion
- * (this is camera mode, not object mode) */
- sub_v3_v3(rv3d->ofs, trans);
- has_translate = true;
- }
- else {
- has_translate = false;
- }
- }
-
- if (has_rotate) {
- const float turn_sensitivity = 1.0f;
-
- float rotation[4];
- float axis[3];
- float angle = turn_sensitivity * WM_event_ndof_to_axis_angle(ndof, axis);
-
- if (fabsf(angle) > 0.0001f) {
- has_rotate = true;
-
- if (use_precision) {
- angle *= 0.2f;
- }
-
- /* transform rotation axis from view to world coordinates */
- mul_qt_v3(view_inv, axis);
-
- /* apply rotation to view */
- axis_angle_to_quat(rotation, axis, angle);
- mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rotation);
-
- if (U.ndof_flag & NDOF_LOCK_HORIZON) {
- /* force an upright viewpoint
- * TODO: make this less... sudden */
- float view_horizon[3] = {1.0f, 0.0f, 0.0f}; /* view +x */
- float view_direction[3] = {0.0f, 0.0f, -1.0f}; /* view -z (into screen) */
-
- /* find new inverse since viewquat has changed */
- invert_qt_qt_normalized(view_inv, rv3d->viewquat);
- /* could apply reverse rotation to existing view_inv to save a few cycles */
-
- /* transform view vectors to world coordinates */
- mul_qt_v3(view_inv, view_horizon);
- mul_qt_v3(view_inv, view_direction);
-
-
- /* find difference between view & world horizons
- * true horizon lives in world xy plane, so look only at difference in z */
- angle = -asinf(view_horizon[2]);
-
- /* rotate view so view horizon = world horizon */
- axis_angle_to_quat(rotation, view_direction, angle);
- mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rotation);
- }
-
- rv3d->view = RV3D_VIEW_USER;
- }
- else {
- has_rotate = false;
- }
- }
-
- *r_has_translate = has_translate;
- *r_has_rotate = has_rotate;
+void view3d_ndof_fly(const wmNDOFMotionData *ndof,
+ View3D *v3d,
+ RegionView3D *rv3d,
+ const bool use_precision,
+ const short protectflag,
+ bool *r_has_translate,
+ bool *r_has_rotate)
+{
+ bool has_translate = NDOF_HAS_TRANSLATE;
+ bool has_rotate = NDOF_HAS_ROTATE;
+
+ float view_inv[4];
+ invert_qt_qt_normalized(view_inv, rv3d->viewquat);
+
+ rv3d->rot_angle = 0.0f; /* disable onscreen rotation doo-dad */
+
+ if (has_translate) {
+ /* ignore real 'dist' since fly has its own speed settings,
+ * also its overwritten at this point. */
+ float speed = view3d_ndof_pan_speed_calc_from_dist(rv3d, 1.0f);
+ float trans[3], trans_orig_y;
+
+ if (use_precision) {
+ speed *= 0.2f;
+ }
+
+ WM_event_ndof_pan_get(ndof, trans, false);
+ mul_v3_fl(trans, speed * ndof->dt);
+ trans_orig_y = trans[1];
+
+ if (U.ndof_flag & NDOF_FLY_HELICOPTER) {
+ trans[1] = 0.0f;
+ }
+
+ /* transform motion from view to world coordinates */
+ mul_qt_v3(view_inv, trans);
+
+ if (U.ndof_flag & NDOF_FLY_HELICOPTER) {
+ /* replace world z component with device y (yes it makes sense) */
+ trans[2] = trans_orig_y;
+ }
+
+ if (rv3d->persp == RV3D_CAMOB) {
+ /* respect camera position locks */
+ if (protectflag & OB_LOCK_LOCX) {
+ trans[0] = 0.0f;
+ }
+ if (protectflag & OB_LOCK_LOCY) {
+ trans[1] = 0.0f;
+ }
+ if (protectflag & OB_LOCK_LOCZ) {
+ trans[2] = 0.0f;
+ }
+ }
+
+ if (!is_zero_v3(trans)) {
+ /* move center of view opposite of hand motion
+ * (this is camera mode, not object mode) */
+ sub_v3_v3(rv3d->ofs, trans);
+ has_translate = true;
+ }
+ else {
+ has_translate = false;
+ }
+ }
+
+ if (has_rotate) {
+ const float turn_sensitivity = 1.0f;
+
+ float rotation[4];
+ float axis[3];
+ float angle = turn_sensitivity * WM_event_ndof_to_axis_angle(ndof, axis);
+
+ if (fabsf(angle) > 0.0001f) {
+ has_rotate = true;
+
+ if (use_precision) {
+ angle *= 0.2f;
+ }
+
+ /* transform rotation axis from view to world coordinates */
+ mul_qt_v3(view_inv, axis);
+
+ /* apply rotation to view */
+ axis_angle_to_quat(rotation, axis, angle);
+ mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rotation);
+
+ if (U.ndof_flag & NDOF_LOCK_HORIZON) {
+ /* force an upright viewpoint
+ * TODO: make this less... sudden */
+ float view_horizon[3] = {1.0f, 0.0f, 0.0f}; /* view +x */
+ float view_direction[3] = {0.0f, 0.0f, -1.0f}; /* view -z (into screen) */
+
+ /* find new inverse since viewquat has changed */
+ invert_qt_qt_normalized(view_inv, rv3d->viewquat);
+ /* could apply reverse rotation to existing view_inv to save a few cycles */
+
+ /* transform view vectors to world coordinates */
+ mul_qt_v3(view_inv, view_horizon);
+ mul_qt_v3(view_inv, view_direction);
+
+ /* find difference between view & world horizons
+ * true horizon lives in world xy plane, so look only at difference in z */
+ angle = -asinf(view_horizon[2]);
+
+ /* rotate view so view horizon = world horizon */
+ axis_angle_to_quat(rotation, view_direction, angle);
+ mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rotation);
+ }
+
+ rv3d->view = RV3D_VIEW_USER;
+ }
+ else {
+ has_rotate = false;
+ }
+ }
+
+ *r_has_translate = has_translate;
+ *r_has_rotate = has_rotate;
}
/** \} */
@@ -1312,76 +1317,76 @@ void view3d_ndof_fly(
static int ndof_orbit_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (event->type != NDOF_MOTION) {
- return OPERATOR_CANCELLED;
- }
+ if (event->type != NDOF_MOTION) {
+ return OPERATOR_CANCELLED;
+ }
- const Depsgraph *depsgraph = CTX_data_depsgraph(C);
- ViewOpsData *vod;
- View3D *v3d;
- RegionView3D *rv3d;
- char xform_flag = 0;
+ const Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ ViewOpsData *vod;
+ View3D *v3d;
+ RegionView3D *rv3d;
+ char xform_flag = 0;
- const wmNDOFMotionData *ndof = event->customdata;
+ const wmNDOFMotionData *ndof = event->customdata;
- viewops_data_alloc(C, op);
- viewops_data_create(
- C, op, event,
- viewops_flag_from_args((U.uiflag & USER_ORBIT_SELECTION) != 0, false));
- vod = op->customdata;
+ viewops_data_alloc(C, op);
+ viewops_data_create(
+ C, op, event, viewops_flag_from_args((U.uiflag & USER_ORBIT_SELECTION) != 0, false));
+ vod = op->customdata;
- ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->ar);
+ ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->ar);
- v3d = vod->v3d;
- rv3d = vod->rv3d;
+ v3d = vod->v3d;
+ rv3d = vod->rv3d;
- /* off by default, until changed later this function */
- rv3d->rot_angle = 0.0f;
+ /* off by default, until changed later this function */
+ rv3d->rot_angle = 0.0f;
- ED_view3d_camera_lock_init_ex(depsgraph, v3d, rv3d, false);
+ ED_view3d_camera_lock_init_ex(depsgraph, v3d, rv3d, false);
- if (ndof->progress != P_FINISHING) {
- const bool has_rotation = NDOF_HAS_ROTATE;
- /* if we can't rotate, fallback to translate (locked axis views) */
- const bool has_translate = NDOF_HAS_TRANSLATE && (rv3d->viewlock & RV3D_LOCKED);
- const bool has_zoom = (ndof->tvec[2] != 0.0f) && !rv3d->is_persp;
+ if (ndof->progress != P_FINISHING) {
+ const bool has_rotation = NDOF_HAS_ROTATE;
+ /* if we can't rotate, fallback to translate (locked axis views) */
+ const bool has_translate = NDOF_HAS_TRANSLATE && (rv3d->viewlock & RV3D_LOCKED);
+ const bool has_zoom = (ndof->tvec[2] != 0.0f) && !rv3d->is_persp;
- if (has_translate || has_zoom) {
- view3d_ndof_pan_zoom(ndof, vod->sa, vod->ar, has_translate, has_zoom);
- xform_flag |= HAS_TRANSLATE;
- }
+ if (has_translate || has_zoom) {
+ view3d_ndof_pan_zoom(ndof, vod->sa, vod->ar, has_translate, has_zoom);
+ xform_flag |= HAS_TRANSLATE;
+ }
- if (has_rotation) {
- view3d_ndof_orbit(ndof, vod->sa, vod->ar, vod, true);
- xform_flag |= HAS_ROTATE;
- }
- }
+ if (has_rotation) {
+ view3d_ndof_orbit(ndof, vod->sa, vod->ar, vod, true);
+ xform_flag |= HAS_ROTATE;
+ }
+ }
- ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
- if (xform_flag) {
- ED_view3d_camera_lock_autokey(v3d, rv3d, C, xform_flag & HAS_ROTATE, xform_flag & HAS_TRANSLATE);
- }
+ ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
+ if (xform_flag) {
+ ED_view3d_camera_lock_autokey(
+ v3d, rv3d, C, xform_flag & HAS_ROTATE, xform_flag & HAS_TRANSLATE);
+ }
- ED_region_tag_redraw(vod->ar);
+ ED_region_tag_redraw(vod->ar);
- viewops_data_free(C, op);
+ viewops_data_free(C, op);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void VIEW3D_OT_ndof_orbit(struct wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "NDOF Orbit View";
- ot->description = "Orbit the view using the 3D mouse";
- ot->idname = "VIEW3D_OT_ndof_orbit";
+ /* identifiers */
+ ot->name = "NDOF Orbit View";
+ ot->description = "Orbit the view using the 3D mouse";
+ ot->idname = "VIEW3D_OT_ndof_orbit";
- /* api callbacks */
- ot->invoke = ndof_orbit_invoke;
- ot->poll = ED_operator_view3d_active;
+ /* api callbacks */
+ ot->invoke = ndof_orbit_invoke;
+ ot->poll = ED_operator_view3d_active;
- /* flags */
- ot->flag = 0;
+ /* flags */
+ ot->flag = 0;
}
/** \} */
@@ -1392,112 +1397,110 @@ void VIEW3D_OT_ndof_orbit(struct wmOperatorType *ot)
static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (event->type != NDOF_MOTION) {
- return OPERATOR_CANCELLED;
- }
+ if (event->type != NDOF_MOTION) {
+ return OPERATOR_CANCELLED;
+ }
- const Depsgraph *depsgraph = CTX_data_depsgraph(C);
- ViewOpsData *vod;
- View3D *v3d;
- RegionView3D *rv3d;
- char xform_flag = 0;
+ const Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ ViewOpsData *vod;
+ View3D *v3d;
+ RegionView3D *rv3d;
+ char xform_flag = 0;
- const wmNDOFMotionData *ndof = event->customdata;
+ const wmNDOFMotionData *ndof = event->customdata;
- viewops_data_alloc(C, op);
- viewops_data_create(
- C, op, event,
- viewops_flag_from_args((U.uiflag & USER_ORBIT_SELECTION) != 0, false));
+ viewops_data_alloc(C, op);
+ viewops_data_create(
+ C, op, event, viewops_flag_from_args((U.uiflag & USER_ORBIT_SELECTION) != 0, false));
- vod = op->customdata;
+ vod = op->customdata;
- ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->ar);
+ ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->ar);
- v3d = vod->v3d;
- rv3d = vod->rv3d;
+ v3d = vod->v3d;
+ rv3d = vod->rv3d;
- /* off by default, until changed later this function */
- rv3d->rot_angle = 0.0f;
+ /* off by default, until changed later this function */
+ rv3d->rot_angle = 0.0f;
- ED_view3d_camera_lock_init_ex(depsgraph, v3d, rv3d, false);
+ ED_view3d_camera_lock_init_ex(depsgraph, v3d, rv3d, false);
- if (ndof->progress == P_FINISHING) {
- /* pass */
- }
- else if ((rv3d->persp == RV3D_ORTHO) && RV3D_VIEW_IS_AXIS(rv3d->view)) {
- /* if we can't rotate, fallback to translate (locked axis views) */
- const bool has_translate = NDOF_HAS_TRANSLATE;
- const bool has_zoom = (ndof->tvec[2] != 0.0f) && ED_view3d_offset_lock_check(v3d, rv3d);
+ if (ndof->progress == P_FINISHING) {
+ /* pass */
+ }
+ else if ((rv3d->persp == RV3D_ORTHO) && RV3D_VIEW_IS_AXIS(rv3d->view)) {
+ /* if we can't rotate, fallback to translate (locked axis views) */
+ const bool has_translate = NDOF_HAS_TRANSLATE;
+ const bool has_zoom = (ndof->tvec[2] != 0.0f) && ED_view3d_offset_lock_check(v3d, rv3d);
- if (has_translate || has_zoom) {
- view3d_ndof_pan_zoom(ndof, vod->sa, vod->ar, has_translate, true);
- xform_flag |= HAS_TRANSLATE;
- }
- }
- else if ((U.ndof_flag & NDOF_MODE_ORBIT) ||
- ED_view3d_offset_lock_check(v3d, rv3d))
- {
- const bool has_rotation = NDOF_HAS_ROTATE;
- const bool has_zoom = (ndof->tvec[2] != 0.0f);
+ if (has_translate || has_zoom) {
+ view3d_ndof_pan_zoom(ndof, vod->sa, vod->ar, has_translate, true);
+ xform_flag |= HAS_TRANSLATE;
+ }
+ }
+ else if ((U.ndof_flag & NDOF_MODE_ORBIT) || ED_view3d_offset_lock_check(v3d, rv3d)) {
+ const bool has_rotation = NDOF_HAS_ROTATE;
+ const bool has_zoom = (ndof->tvec[2] != 0.0f);
- if (has_zoom) {
- view3d_ndof_pan_zoom(ndof, vod->sa, vod->ar, false, has_zoom);
- xform_flag |= HAS_TRANSLATE;
- }
+ if (has_zoom) {
+ view3d_ndof_pan_zoom(ndof, vod->sa, vod->ar, false, has_zoom);
+ xform_flag |= HAS_TRANSLATE;
+ }
- if (has_rotation) {
- view3d_ndof_orbit(ndof, vod->sa, vod->ar, vod, true);
- xform_flag |= HAS_ROTATE;
- }
- }
- else { /* free/explore (like fly mode) */
- const bool has_rotation = NDOF_HAS_ROTATE;
- const bool has_translate = NDOF_HAS_TRANSLATE;
- const bool has_zoom = (ndof->tvec[2] != 0.0f) && !rv3d->is_persp;
+ if (has_rotation) {
+ view3d_ndof_orbit(ndof, vod->sa, vod->ar, vod, true);
+ xform_flag |= HAS_ROTATE;
+ }
+ }
+ else { /* free/explore (like fly mode) */
+ const bool has_rotation = NDOF_HAS_ROTATE;
+ const bool has_translate = NDOF_HAS_TRANSLATE;
+ const bool has_zoom = (ndof->tvec[2] != 0.0f) && !rv3d->is_persp;
- float dist_backup;
+ float dist_backup;
- if (has_translate || has_zoom) {
- view3d_ndof_pan_zoom(ndof, vod->sa, vod->ar, has_translate, has_zoom);
- xform_flag |= HAS_TRANSLATE;
- }
+ if (has_translate || has_zoom) {
+ view3d_ndof_pan_zoom(ndof, vod->sa, vod->ar, has_translate, has_zoom);
+ xform_flag |= HAS_TRANSLATE;
+ }
- dist_backup = rv3d->dist;
- ED_view3d_distance_set(rv3d, 0.0f);
+ dist_backup = rv3d->dist;
+ ED_view3d_distance_set(rv3d, 0.0f);
- if (has_rotation) {
- view3d_ndof_orbit(ndof, vod->sa, vod->ar, vod, false);
- xform_flag |= HAS_ROTATE;
- }
+ if (has_rotation) {
+ view3d_ndof_orbit(ndof, vod->sa, vod->ar, vod, false);
+ xform_flag |= HAS_ROTATE;
+ }
- ED_view3d_distance_set(rv3d, dist_backup);
- }
+ ED_view3d_distance_set(rv3d, dist_backup);
+ }
- ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
- if (xform_flag) {
- ED_view3d_camera_lock_autokey(v3d, rv3d, C, xform_flag & HAS_ROTATE, xform_flag & HAS_TRANSLATE);
- }
+ ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
+ if (xform_flag) {
+ ED_view3d_camera_lock_autokey(
+ v3d, rv3d, C, xform_flag & HAS_ROTATE, xform_flag & HAS_TRANSLATE);
+ }
- ED_region_tag_redraw(vod->ar);
+ ED_region_tag_redraw(vod->ar);
- viewops_data_free(C, op);
+ viewops_data_free(C, op);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void VIEW3D_OT_ndof_orbit_zoom(struct wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "NDOF Orbit View with Zoom";
- ot->description = "Orbit and zoom the view using the 3D mouse";
- ot->idname = "VIEW3D_OT_ndof_orbit_zoom";
+ /* identifiers */
+ ot->name = "NDOF Orbit View with Zoom";
+ ot->description = "Orbit and zoom the view using the 3D mouse";
+ ot->idname = "VIEW3D_OT_ndof_orbit_zoom";
- /* api callbacks */
- ot->invoke = ndof_orbit_zoom_invoke;
- ot->poll = ED_operator_view3d_active;
+ /* api callbacks */
+ ot->invoke = ndof_orbit_zoom_invoke;
+ ot->poll = ED_operator_view3d_active;
- /* flags */
- ot->flag = 0;
+ /* flags */
+ ot->flag = 0;
}
/** \} */
@@ -1508,61 +1511,61 @@ void VIEW3D_OT_ndof_orbit_zoom(struct wmOperatorType *ot)
static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
- if (event->type != NDOF_MOTION) {
- return OPERATOR_CANCELLED;
- }
+ if (event->type != NDOF_MOTION) {
+ return OPERATOR_CANCELLED;
+ }
- const Depsgraph *depsgraph = CTX_data_depsgraph(C);
- View3D *v3d = CTX_wm_view3d(C);
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
- const wmNDOFMotionData *ndof = event->customdata;
- char xform_flag = 0;
+ const Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ const wmNDOFMotionData *ndof = event->customdata;
+ char xform_flag = 0;
- const bool has_translate = NDOF_HAS_TRANSLATE;
- const bool has_zoom = (ndof->tvec[2] != 0.0f) && !rv3d->is_persp;
+ const bool has_translate = NDOF_HAS_TRANSLATE;
+ const bool has_zoom = (ndof->tvec[2] != 0.0f) && !rv3d->is_persp;
- /* we're panning here! so erase any leftover rotation from other operators */
- rv3d->rot_angle = 0.0f;
+ /* we're panning here! so erase any leftover rotation from other operators */
+ rv3d->rot_angle = 0.0f;
- if (!(has_translate || has_zoom)) {
- return OPERATOR_CANCELLED;
- }
+ if (!(has_translate || has_zoom)) {
+ return OPERATOR_CANCELLED;
+ }
- ED_view3d_camera_lock_init_ex(depsgraph, v3d, rv3d, false);
+ ED_view3d_camera_lock_init_ex(depsgraph, v3d, rv3d, false);
- if (ndof->progress != P_FINISHING) {
- ScrArea *sa = CTX_wm_area(C);
- ARegion *ar = CTX_wm_region(C);
+ if (ndof->progress != P_FINISHING) {
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = CTX_wm_region(C);
- if (has_translate || has_zoom) {
- view3d_ndof_pan_zoom(ndof, sa, ar, has_translate, has_zoom);
- xform_flag |= HAS_TRANSLATE;
- }
- }
+ if (has_translate || has_zoom) {
+ view3d_ndof_pan_zoom(ndof, sa, ar, has_translate, has_zoom);
+ xform_flag |= HAS_TRANSLATE;
+ }
+ }
- ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
- if (xform_flag) {
- ED_view3d_camera_lock_autokey(v3d, rv3d, C, false, xform_flag & HAS_TRANSLATE);
- }
+ ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
+ if (xform_flag) {
+ ED_view3d_camera_lock_autokey(v3d, rv3d, C, false, xform_flag & HAS_TRANSLATE);
+ }
- ED_region_tag_redraw(CTX_wm_region(C));
+ ED_region_tag_redraw(CTX_wm_region(C));
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void VIEW3D_OT_ndof_pan(struct wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "NDOF Pan View";
- ot->description = "Pan the view with the 3D mouse";
- ot->idname = "VIEW3D_OT_ndof_pan";
+ /* identifiers */
+ ot->name = "NDOF Pan View";
+ ot->description = "Pan the view with the 3D mouse";
+ ot->idname = "VIEW3D_OT_ndof_pan";
- /* api callbacks */
- ot->invoke = ndof_pan_invoke;
- ot->poll = ED_operator_view3d_active;
+ /* api callbacks */
+ ot->invoke = ndof_pan_invoke;
+ ot->poll = ED_operator_view3d_active;
- /* flags */
- ot->flag = 0;
+ /* flags */
+ ot->flag = 0;
}
/** \} */
@@ -1576,32 +1579,32 @@ void VIEW3D_OT_ndof_pan(struct wmOperatorType *ot)
*/
static int ndof_all_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- /* weak!, but it works */
- const int ndof_flag = U.ndof_flag;
- int ret;
+ /* weak!, but it works */
+ const int ndof_flag = U.ndof_flag;
+ int ret;
- U.ndof_flag &= ~NDOF_MODE_ORBIT;
+ U.ndof_flag &= ~NDOF_MODE_ORBIT;
- ret = ndof_orbit_zoom_invoke(C, op, event);
+ ret = ndof_orbit_zoom_invoke(C, op, event);
- U.ndof_flag = ndof_flag;
+ U.ndof_flag = ndof_flag;
- return ret;
+ return ret;
}
void VIEW3D_OT_ndof_all(struct wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "NDOF Transform View";
- ot->description = "Pan and rotate the view with the 3D mouse";
- ot->idname = "VIEW3D_OT_ndof_all";
+ /* identifiers */
+ ot->name = "NDOF Transform View";
+ ot->description = "Pan and rotate the view with the 3D mouse";
+ ot->idname = "VIEW3D_OT_ndof_all";
- /* api callbacks */
- ot->invoke = ndof_all_invoke;
- ot->poll = ED_operator_view3d_active;
+ /* api callbacks */
+ ot->invoke = ndof_all_invoke;
+ ot->poll = ED_operator_view3d_active;
- /* flags */
- ot->flag = 0;
+ /* flags */
+ ot->flag = 0;
}
#endif /* WITH_INPUT_NDOF */
@@ -1617,188 +1620,187 @@ void VIEW3D_OT_ndof_all(struct wmOperatorType *ot)
/* called in transform_ops.c, on each regeneration of keymaps */
void viewmove_modal_keymap(wmKeyConfig *keyconf)
{
- static const EnumPropertyItem modal_items[] = {
- {VIEW_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
+ static const EnumPropertyItem modal_items[] = {
+ {VIEW_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
- {VIEWROT_MODAL_SWITCH_ZOOM, "SWITCH_TO_ZOOM", 0, "Switch to Zoom"},
- {VIEWROT_MODAL_SWITCH_ROTATE, "SWITCH_TO_ROTATE", 0, "Switch to Rotate"},
+ {VIEWROT_MODAL_SWITCH_ZOOM, "SWITCH_TO_ZOOM", 0, "Switch to Zoom"},
+ {VIEWROT_MODAL_SWITCH_ROTATE, "SWITCH_TO_ROTATE", 0, "Switch to Rotate"},
- {0, NULL, 0, NULL, NULL},
- };
+ {0, NULL, 0, NULL, NULL},
+ };
- wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Move Modal");
+ wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Move Modal");
- /* this function is called for each spacetype, only needs to add map once */
- if (keymap && keymap->modal_items) {
- return;
- }
+ /* this function is called for each spacetype, only needs to add map once */
+ if (keymap && keymap->modal_items) {
+ return;
+ }
- keymap = WM_modalkeymap_add(keyconf, "View3D Move Modal", modal_items);
+ keymap = WM_modalkeymap_add(keyconf, "View3D Move Modal", modal_items);
- /* items for modal map */
- WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, VIEW_MODAL_CONFIRM);
- WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, VIEW_MODAL_CONFIRM);
+ /* items for modal map */
+ WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, VIEW_MODAL_CONFIRM);
+ WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, VIEW_MODAL_CONFIRM);
- /* disabled mode switching for now, can re-implement better, later on */
+ /* disabled mode switching for now, can re-implement better, later on */
#if 0
- WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ZOOM);
- WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ZOOM);
- WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ROTATE);
+ WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ZOOM);
+ WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ZOOM);
+ WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ROTATE);
#endif
- /* assign map to operators */
- WM_modalkeymap_assign(keymap, "VIEW3D_OT_move");
+ /* assign map to operators */
+ WM_modalkeymap_assign(keymap, "VIEW3D_OT_move");
}
-
static void viewmove_apply(ViewOpsData *vod, int x, int y)
{
- if (ED_view3d_offset_lock_check(vod->v3d, vod->rv3d)) {
- vod->rv3d->ofs_lock[0] -= ((vod->prev.event_xy[0] - x) * 2.0f) / (float)vod->ar->winx;
- vod->rv3d->ofs_lock[1] -= ((vod->prev.event_xy[1] - y) * 2.0f) / (float)vod->ar->winy;
- }
- else if ((vod->rv3d->persp == RV3D_CAMOB) && !ED_view3d_camera_lock_check(vod->v3d, vod->rv3d)) {
- const float zoomfac = BKE_screen_view3d_zoom_to_fac(vod->rv3d->camzoom) * 2.0f;
- vod->rv3d->camdx += (vod->prev.event_xy[0] - x) / (vod->ar->winx * zoomfac);
- vod->rv3d->camdy += (vod->prev.event_xy[1] - y) / (vod->ar->winy * zoomfac);
- CLAMP(vod->rv3d->camdx, -1.0f, 1.0f);
- CLAMP(vod->rv3d->camdy, -1.0f, 1.0f);
- }
- else {
- float dvec[3];
- float mval_f[2];
+ if (ED_view3d_offset_lock_check(vod->v3d, vod->rv3d)) {
+ vod->rv3d->ofs_lock[0] -= ((vod->prev.event_xy[0] - x) * 2.0f) / (float)vod->ar->winx;
+ vod->rv3d->ofs_lock[1] -= ((vod->prev.event_xy[1] - y) * 2.0f) / (float)vod->ar->winy;
+ }
+ else if ((vod->rv3d->persp == RV3D_CAMOB) && !ED_view3d_camera_lock_check(vod->v3d, vod->rv3d)) {
+ const float zoomfac = BKE_screen_view3d_zoom_to_fac(vod->rv3d->camzoom) * 2.0f;
+ vod->rv3d->camdx += (vod->prev.event_xy[0] - x) / (vod->ar->winx * zoomfac);
+ vod->rv3d->camdy += (vod->prev.event_xy[1] - y) / (vod->ar->winy * zoomfac);
+ CLAMP(vod->rv3d->camdx, -1.0f, 1.0f);
+ CLAMP(vod->rv3d->camdy, -1.0f, 1.0f);
+ }
+ else {
+ float dvec[3];
+ float mval_f[2];
- mval_f[0] = x - vod->prev.event_xy[0];
- mval_f[1] = y - vod->prev.event_xy[1];
- ED_view3d_win_to_delta(vod->ar, mval_f, dvec, vod->init.zfac);
+ mval_f[0] = x - vod->prev.event_xy[0];
+ mval_f[1] = y - vod->prev.event_xy[1];
+ ED_view3d_win_to_delta(vod->ar, mval_f, dvec, vod->init.zfac);
- add_v3_v3(vod->rv3d->ofs, dvec);
+ add_v3_v3(vod->rv3d->ofs, dvec);
- if (vod->rv3d->viewlock & RV3D_BOXVIEW) {
- view3d_boxview_sync(vod->sa, vod->ar);
- }
- }
+ if (vod->rv3d->viewlock & RV3D_BOXVIEW) {
+ view3d_boxview_sync(vod->sa, vod->ar);
+ }
+ }
- vod->prev.event_xy[0] = x;
- vod->prev.event_xy[1] = y;
+ vod->prev.event_xy[0] = x;
+ vod->prev.event_xy[1] = y;
- ED_view3d_camera_lock_sync(vod->depsgraph, vod->v3d, vod->rv3d);
+ ED_view3d_camera_lock_sync(vod->depsgraph, vod->v3d, vod->rv3d);
- ED_region_tag_redraw(vod->ar);
+ ED_region_tag_redraw(vod->ar);
}
-
static int viewmove_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
- ViewOpsData *vod = op->customdata;
- short event_code = VIEW_PASS;
- bool use_autokey = false;
- int ret = OPERATOR_RUNNING_MODAL;
-
- /* execute the events */
- if (event->type == MOUSEMOVE) {
- event_code = VIEW_APPLY;
- }
- else if (event->type == EVT_MODAL_MAP) {
- switch (event->val) {
- case VIEW_MODAL_CONFIRM:
- event_code = VIEW_CONFIRM;
- break;
- case VIEWROT_MODAL_SWITCH_ZOOM:
- WM_operator_name_call(C, "VIEW3D_OT_zoom", WM_OP_INVOKE_DEFAULT, NULL);
- event_code = VIEW_CONFIRM;
- break;
- case VIEWROT_MODAL_SWITCH_ROTATE:
- WM_operator_name_call(C, "VIEW3D_OT_rotate", WM_OP_INVOKE_DEFAULT, NULL);
- event_code = VIEW_CONFIRM;
- break;
- }
- }
- else if (event->type == vod->init.event_type && event->val == KM_RELEASE) {
- event_code = VIEW_CONFIRM;
- }
-
- if (event_code == VIEW_APPLY) {
- viewmove_apply(vod, event->x, event->y);
- if (ED_screen_animation_playing(CTX_wm_manager(C))) {
- use_autokey = true;
- }
- }
- else if (event_code == VIEW_CONFIRM) {
- ED_view3d_depth_tag_update(vod->rv3d);
- use_autokey = true;
- ret = OPERATOR_FINISHED;
- }
-
- if (use_autokey) {
- ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, false, true);
- }
-
- if (ret & OPERATOR_FINISHED) {
- viewops_data_free(C, op);
- }
-
- return ret;
+ ViewOpsData *vod = op->customdata;
+ short event_code = VIEW_PASS;
+ bool use_autokey = false;
+ int ret = OPERATOR_RUNNING_MODAL;
+
+ /* execute the events */
+ if (event->type == MOUSEMOVE) {
+ event_code = VIEW_APPLY;
+ }
+ else if (event->type == EVT_MODAL_MAP) {
+ switch (event->val) {
+ case VIEW_MODAL_CONFIRM:
+ event_code = VIEW_CONFIRM;
+ break;
+ case VIEWROT_MODAL_SWITCH_ZOOM:
+ WM_operator_name_call(C, "VIEW3D_OT_zoom", WM_OP_INVOKE_DEFAULT, NULL);
+ event_code = VIEW_CONFIRM;
+ break;
+ case VIEWROT_MODAL_SWITCH_ROTATE:
+ WM_operator_name_call(C, "VIEW3D_OT_rotate", WM_OP_INVOKE_DEFAULT, NULL);
+ event_code = VIEW_CONFIRM;
+ break;
+ }
+ }
+ else if (event->type == vod->init.event_type && event->val == KM_RELEASE) {
+ event_code = VIEW_CONFIRM;
+ }
+
+ if (event_code == VIEW_APPLY) {
+ viewmove_apply(vod, event->x, event->y);
+ if (ED_screen_animation_playing(CTX_wm_manager(C))) {
+ use_autokey = true;
+ }
+ }
+ else if (event_code == VIEW_CONFIRM) {
+ ED_view3d_depth_tag_update(vod->rv3d);
+ use_autokey = true;
+ ret = OPERATOR_FINISHED;
+ }
+
+ if (use_autokey) {
+ ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, false, true);
+ }
+
+ if (ret & OPERATOR_FINISHED) {
+ viewops_data_free(C, op);
+ }
+
+ return ret;
}
static int viewmove_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- ViewOpsData *vod;
+ ViewOpsData *vod;
- const bool use_mouse_init = RNA_boolean_get(op->ptr, "use_mouse_init");
+ const bool use_mouse_init = RNA_boolean_get(op->ptr, "use_mouse_init");
- /* makes op->customdata */
- viewops_data_alloc(C, op);
- viewops_data_create(
- C, op, event,
- (viewops_flag_from_prefs() & ~VIEWOPS_FLAG_ORBIT_SELECT) |
- (use_mouse_init ? VIEWOPS_FLAG_USE_MOUSE_INIT : 0));
- vod = op->customdata;
+ /* makes op->customdata */
+ viewops_data_alloc(C, op);
+ viewops_data_create(C,
+ op,
+ event,
+ (viewops_flag_from_prefs() & ~VIEWOPS_FLAG_ORBIT_SELECT) |
+ (use_mouse_init ? VIEWOPS_FLAG_USE_MOUSE_INIT : 0));
+ vod = op->customdata;
- ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->ar);
+ ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->ar);
- if (event->type == MOUSEPAN) {
- /* invert it, trackpad scroll follows same principle as 2d windows this way */
- viewmove_apply(vod, 2 * event->x - event->prevx, 2 * event->y - event->prevy);
- ED_view3d_depth_tag_update(vod->rv3d);
+ if (event->type == MOUSEPAN) {
+ /* invert it, trackpad scroll follows same principle as 2d windows this way */
+ viewmove_apply(vod, 2 * event->x - event->prevx, 2 * event->y - event->prevy);
+ ED_view3d_depth_tag_update(vod->rv3d);
- viewops_data_free(C, op);
+ viewops_data_free(C, op);
- return OPERATOR_FINISHED;
- }
- else {
- /* add temp handler */
- WM_event_add_modal_handler(C, op);
+ return OPERATOR_FINISHED;
+ }
+ else {
+ /* add temp handler */
+ WM_event_add_modal_handler(C, op);
- return OPERATOR_RUNNING_MODAL;
- }
+ return OPERATOR_RUNNING_MODAL;
+ }
}
static void viewmove_cancel(bContext *C, wmOperator *op)
{
- viewops_data_free(C, op);
+ viewops_data_free(C, op);
}
void VIEW3D_OT_move(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Pan View";
- ot->description = "Move the view";
- ot->idname = "VIEW3D_OT_move";
+ /* identifiers */
+ ot->name = "Pan View";
+ ot->description = "Move the view";
+ ot->idname = "VIEW3D_OT_move";
- /* api callbacks */
- ot->invoke = viewmove_invoke;
- ot->modal = viewmove_modal;
- ot->poll = ED_operator_view3d_active;
- ot->cancel = viewmove_cancel;
+ /* api callbacks */
+ ot->invoke = viewmove_invoke;
+ ot->modal = viewmove_modal;
+ ot->poll = ED_operator_view3d_active;
+ ot->cancel = viewmove_cancel;
- /* flags */
- ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR;
+ /* flags */
+ ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR;
- /* properties */
- view3d_operator_properties_common(ot, V3D_OP_PROP_USE_MOUSE_INIT);
+ /* properties */
+ view3d_operator_properties_common(ot, V3D_OP_PROP_USE_MOUSE_INIT);
}
/** \} */
@@ -1811,82 +1813,81 @@ void VIEW3D_OT_move(wmOperatorType *ot)
/* called in transform_ops.c, on each regeneration of keymaps */
void viewzoom_modal_keymap(wmKeyConfig *keyconf)
{
- static const EnumPropertyItem modal_items[] = {
- {VIEW_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
+ static const EnumPropertyItem modal_items[] = {
+ {VIEW_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
- {VIEWROT_MODAL_SWITCH_ROTATE, "SWITCH_TO_ROTATE", 0, "Switch to Rotate"},
- {VIEWROT_MODAL_SWITCH_MOVE, "SWITCH_TO_MOVE", 0, "Switch to Move"},
+ {VIEWROT_MODAL_SWITCH_ROTATE, "SWITCH_TO_ROTATE", 0, "Switch to Rotate"},
+ {VIEWROT_MODAL_SWITCH_MOVE, "SWITCH_TO_MOVE", 0, "Switch to Move"},
- {0, NULL, 0, NULL, NULL},
- };
+ {0, NULL, 0, NULL, NULL},
+ };
- wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Zoom Modal");
+ wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Zoom Modal");
- /* this function is called for each spacetype, only needs to add map once */
- if (keymap && keymap->modal_items) {
- return;
- }
+ /* this function is called for each spacetype, only needs to add map once */
+ if (keymap && keymap->modal_items) {
+ return;
+ }
- keymap = WM_modalkeymap_add(keyconf, "View3D Zoom Modal", modal_items);
+ keymap = WM_modalkeymap_add(keyconf, "View3D Zoom Modal", modal_items);
- /* disabled mode switching for now, can re-implement better, later on */
+ /* disabled mode switching for now, can re-implement better, later on */
#if 0
- WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ROTATE);
- WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ROTATE);
- WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_MOVE);
+ WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ROTATE);
+ WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ROTATE);
+ WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_MOVE);
#endif
- /* assign map to operators */
- WM_modalkeymap_assign(keymap, "VIEW3D_OT_zoom");
+ /* assign map to operators */
+ WM_modalkeymap_assign(keymap, "VIEW3D_OT_zoom");
}
/**
* \param zoom_xy: Optionally zoom to window location (coords compatible w/ #wmEvent.x, y). Use when not NULL.
*/
static void view_zoom_to_window_xy_camera(
- Scene *scene, Depsgraph *depsgraph, View3D *v3d,
- ARegion *ar, float dfac, const int zoom_xy[2])
+ Scene *scene, Depsgraph *depsgraph, View3D *v3d, ARegion *ar, float dfac, const int zoom_xy[2])
{
- RegionView3D *rv3d = ar->regiondata;
- const float zoomfac = BKE_screen_view3d_zoom_to_fac(rv3d->camzoom);
- const float zoomfac_new = clamp_f(zoomfac * (1.0f / dfac), RV3D_CAMZOOM_MIN_FACTOR, RV3D_CAMZOOM_MAX_FACTOR);
- const float camzoom_new = BKE_screen_view3d_zoom_from_fac(zoomfac_new);
-
+ RegionView3D *rv3d = ar->regiondata;
+ const float zoomfac = BKE_screen_view3d_zoom_to_fac(rv3d->camzoom);
+ const float zoomfac_new = clamp_f(
+ zoomfac * (1.0f / dfac), RV3D_CAMZOOM_MIN_FACTOR, RV3D_CAMZOOM_MAX_FACTOR);
+ const float camzoom_new = BKE_screen_view3d_zoom_from_fac(zoomfac_new);
- if (zoom_xy != NULL) {
- float zoomfac_px;
- rctf camera_frame_old;
- rctf camera_frame_new;
+ if (zoom_xy != NULL) {
+ float zoomfac_px;
+ rctf camera_frame_old;
+ rctf camera_frame_new;
- const float pt_src[2] = {zoom_xy[0], zoom_xy[1]};
- float pt_dst[2];
- float delta_px[2];
+ const float pt_src[2] = {zoom_xy[0], zoom_xy[1]};
+ float pt_dst[2];
+ float delta_px[2];
- ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &camera_frame_old, false);
- BLI_rctf_translate(&camera_frame_old, ar->winrct.xmin, ar->winrct.ymin);
+ ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &camera_frame_old, false);
+ BLI_rctf_translate(&camera_frame_old, ar->winrct.xmin, ar->winrct.ymin);
- rv3d->camzoom = camzoom_new;
- CLAMP(rv3d->camzoom, RV3D_CAMZOOM_MIN, RV3D_CAMZOOM_MAX);
+ rv3d->camzoom = camzoom_new;
+ CLAMP(rv3d->camzoom, RV3D_CAMZOOM_MIN, RV3D_CAMZOOM_MAX);
- ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &camera_frame_new, false);
- BLI_rctf_translate(&camera_frame_new, ar->winrct.xmin, ar->winrct.ymin);
+ ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &camera_frame_new, false);
+ BLI_rctf_translate(&camera_frame_new, ar->winrct.xmin, ar->winrct.ymin);
- BLI_rctf_transform_pt_v(&camera_frame_new, &camera_frame_old, pt_dst, pt_src);
- sub_v2_v2v2(delta_px, pt_dst, pt_src);
+ BLI_rctf_transform_pt_v(&camera_frame_new, &camera_frame_old, pt_dst, pt_src);
+ sub_v2_v2v2(delta_px, pt_dst, pt_src);
- /* translate the camera offset using pixel space delta
- * mapped back to the camera (same logic as panning in camera view) */
- zoomfac_px = BKE_screen_view3d_zoom_to_fac(rv3d->camzoom) * 2.0f;
+ /* translate the camera offset using pixel space delta
+ * mapped back to the camera (same logic as panning in camera view) */
+ zoomfac_px = BKE_screen_view3d_zoom_to_fac(rv3d->camzoom) * 2.0f;
- rv3d->camdx += delta_px[0] / (ar->winx * zoomfac_px);
- rv3d->camdy += delta_px[1] / (ar->winy * zoomfac_px);
- CLAMP(rv3d->camdx, -1.0f, 1.0f);
- CLAMP(rv3d->camdy, -1.0f, 1.0f);
- }
- else {
- rv3d->camzoom = camzoom_new;
- CLAMP(rv3d->camzoom, RV3D_CAMZOOM_MIN, RV3D_CAMZOOM_MAX);
- }
+ rv3d->camdx += delta_px[0] / (ar->winx * zoomfac_px);
+ rv3d->camdy += delta_px[1] / (ar->winy * zoomfac_px);
+ CLAMP(rv3d->camdx, -1.0f, 1.0f);
+ CLAMP(rv3d->camdy, -1.0f, 1.0f);
+ }
+ else {
+ rv3d->camzoom = camzoom_new;
+ CLAMP(rv3d->camzoom, RV3D_CAMZOOM_MIN, RV3D_CAMZOOM_MAX);
+ }
}
/**
@@ -1894,441 +1895,472 @@ static void view_zoom_to_window_xy_camera(
*/
static void view_zoom_to_window_xy_3d(ARegion *ar, float dfac, const int zoom_xy[2])
{
- RegionView3D *rv3d = ar->regiondata;
- const float dist_new = rv3d->dist * dfac;
-
- if (zoom_xy != NULL) {
- float dvec[3];
- float tvec[3];
- float tpos[3];
- float mval_f[2];
-
- float zfac;
-
- negate_v3_v3(tpos, rv3d->ofs);
-
- mval_f[0] = (float)(((zoom_xy[0] - ar->winrct.xmin) * 2) - ar->winx) / 2.0f;
- mval_f[1] = (float)(((zoom_xy[1] - ar->winrct.ymin) * 2) - ar->winy) / 2.0f;
-
- /* 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);
- negate_v3(tvec);
-
- /* Offset to target position and dolly */
- copy_v3_v3(rv3d->ofs, tvec);
- rv3d->dist = dist_new;
-
- /* Calculate final offset */
- madd_v3_v3v3fl(rv3d->ofs, tvec, dvec, dfac);
- }
- else {
- rv3d->dist = dist_new;
- }
-}
-
-static float viewzoom_scale_value(
- const rcti *winrct,
- const short viewzoom,
- const bool zoom_invert, const bool zoom_invert_force,
- const int xy_curr[2], const int xy_init[2],
- const float val, const float val_orig,
- double *r_timer_lastdraw)
-{
- float zfac;
-
- if (viewzoom == USER_ZOOM_CONT) {
- double time = PIL_check_seconds_timer();
- float time_step = (float)(time - *r_timer_lastdraw);
- float fac;
-
- if (U.uiflag & USER_ZOOM_HORIZ) {
- fac = (float)(xy_init[0] - xy_curr[0]);
- }
- else {
- fac = (float)(xy_init[1] - xy_curr[1]);
- }
-
- if (zoom_invert != zoom_invert_force) {
- fac = -fac;
- }
-
- /* oldstyle zoom */
- zfac = 1.0f + ((fac / 20.0f) * time_step);
- *r_timer_lastdraw = time;
- }
- else if (viewzoom == USER_ZOOM_SCALE) {
- /* method which zooms based on how far you move the mouse */
-
- const int ctr[2] = {
- BLI_rcti_cent_x(winrct),
- BLI_rcti_cent_y(winrct),
- };
- float len_new = 5 + len_v2v2_int(ctr, xy_curr);
- float len_old = 5 + len_v2v2_int(ctr, xy_init);
-
- /* intentionally ignore 'zoom_invert' for scale */
- if (zoom_invert_force) {
- SWAP(float, len_new, len_old);
- }
-
- zfac = val_orig * (len_old / max_ff(len_new, 1.0f)) / val;
- }
- else { /* USER_ZOOM_DOLLY */
- float len_new = 5;
- float len_old = 5;
-
- if (U.uiflag & USER_ZOOM_HORIZ) {
- len_new += (winrct->xmax - (xy_curr[0]));
- len_old += (winrct->xmax - (xy_init[0]));
- }
- else {
- len_new += (winrct->ymax - (xy_curr[1]));
- len_old += (winrct->ymax - (xy_init[1]));
- }
-
- if (zoom_invert != zoom_invert_force) {
- SWAP(float, len_new, len_old);
- }
-
- zfac = val_orig * (2.0f * ((len_new / max_ff(len_old, 1.0f)) - 1.0f) + 1.0f) / val;
- }
-
-
- return zfac;
-}
-
-static float viewzoom_scale_value_offset(
- const rcti *winrct,
- const short viewzoom,
- const bool zoom_invert, const bool zoom_invert_force,
- const int xy_curr[2], const int xy_init[2], const int xy_offset[2],
- const float val, const float val_orig,
- double *r_timer_lastdraw)
-{
- const int xy_curr_offset[2] = {
- xy_curr[0] + xy_offset[0],
- xy_curr[1] + xy_offset[1],
- };
- const int xy_init_offset[2] = {
- xy_init[0] + xy_offset[0],
- xy_init[1] + xy_offset[1],
- };
- return viewzoom_scale_value(
- winrct, viewzoom, zoom_invert, zoom_invert_force,
- xy_curr_offset, xy_init_offset,
- val, val_orig, r_timer_lastdraw);
-}
-
-static void viewzoom_apply_camera(
- ViewOpsData *vod, const int xy[2],
- const short viewzoom, const bool zoom_invert, const bool zoom_to_pos)
-{
- float zfac;
- float zoomfac_prev = BKE_screen_view3d_zoom_to_fac(vod->init.camzoom) * 2.0f;
- float zoomfac = BKE_screen_view3d_zoom_to_fac(vod->rv3d->camzoom) * 2.0f;
-
- zfac = viewzoom_scale_value_offset(
- &vod->ar->winrct, viewzoom, zoom_invert, true,
- xy, vod->init.event_xy, vod->init.event_xy_offset,
- zoomfac, zoomfac_prev,
- &vod->prev.time);
-
- if (zfac != 1.0f && zfac != 0.0f) {
- /* calculate inverted, then invert again (needed because of camera zoom scaling) */
- zfac = 1.0f / zfac;
- view_zoom_to_window_xy_camera(
- vod->scene, vod->depsgraph, vod->v3d,
- vod->ar, zfac, zoom_to_pos ? vod->prev.event_xy : NULL);
- }
-
- ED_region_tag_redraw(vod->ar);
-}
-
-static void viewzoom_apply_3d(
- ViewOpsData *vod, const int xy[2],
- const short viewzoom, const bool zoom_invert, const bool zoom_to_pos)
-{
- float zfac;
- float dist_range[2];
-
- ED_view3d_dist_range_get(vod->v3d, dist_range);
-
- zfac = viewzoom_scale_value_offset(
- &vod->ar->winrct, viewzoom, zoom_invert, false,
- xy, vod->init.event_xy, vod->init.event_xy_offset,
- vod->rv3d->dist, vod->init.dist,
- &vod->prev.time);
-
- if (zfac != 1.0f) {
- const float zfac_min = dist_range[0] / vod->rv3d->dist;
- const float zfac_max = dist_range[1] / vod->rv3d->dist;
- CLAMP(zfac, zfac_min, zfac_max);
-
- view_zoom_to_window_xy_3d(
- vod->ar, zfac, zoom_to_pos ? vod->prev.event_xy : NULL);
- }
-
- /* these limits were in old code too */
- CLAMP(vod->rv3d->dist, dist_range[0], dist_range[1]);
-
- if (vod->rv3d->viewlock & RV3D_BOXVIEW) {
- view3d_boxview_sync(vod->sa, vod->ar);
- }
-
- ED_view3d_camera_lock_sync(vod->depsgraph, vod->v3d, vod->rv3d);
-
- ED_region_tag_redraw(vod->ar);
-}
-
-static void viewzoom_apply(
- ViewOpsData *vod, const int xy[2],
- const short viewzoom, const bool zoom_invert, const bool zoom_to_pos)
-{
- if ((vod->rv3d->persp == RV3D_CAMOB) &&
- (vod->rv3d->is_persp && ED_view3d_camera_lock_check(vod->v3d, vod->rv3d)) == 0)
- {
- viewzoom_apply_camera(vod, xy, viewzoom, zoom_invert, zoom_to_pos);
- }
- else {
- viewzoom_apply_3d(vod, xy, viewzoom, zoom_invert, zoom_to_pos);
- }
+ RegionView3D *rv3d = ar->regiondata;
+ const float dist_new = rv3d->dist * dfac;
+
+ if (zoom_xy != NULL) {
+ float dvec[3];
+ float tvec[3];
+ float tpos[3];
+ float mval_f[2];
+
+ float zfac;
+
+ negate_v3_v3(tpos, rv3d->ofs);
+
+ mval_f[0] = (float)(((zoom_xy[0] - ar->winrct.xmin) * 2) - ar->winx) / 2.0f;
+ mval_f[1] = (float)(((zoom_xy[1] - ar->winrct.ymin) * 2) - ar->winy) / 2.0f;
+
+ /* 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);
+ negate_v3(tvec);
+
+ /* Offset to target position and dolly */
+ copy_v3_v3(rv3d->ofs, tvec);
+ rv3d->dist = dist_new;
+
+ /* Calculate final offset */
+ madd_v3_v3v3fl(rv3d->ofs, tvec, dvec, dfac);
+ }
+ else {
+ rv3d->dist = dist_new;
+ }
+}
+
+static float viewzoom_scale_value(const rcti *winrct,
+ const short viewzoom,
+ const bool zoom_invert,
+ const bool zoom_invert_force,
+ const int xy_curr[2],
+ const int xy_init[2],
+ const float val,
+ const float val_orig,
+ double *r_timer_lastdraw)
+{
+ float zfac;
+
+ if (viewzoom == USER_ZOOM_CONT) {
+ double time = PIL_check_seconds_timer();
+ float time_step = (float)(time - *r_timer_lastdraw);
+ float fac;
+
+ if (U.uiflag & USER_ZOOM_HORIZ) {
+ fac = (float)(xy_init[0] - xy_curr[0]);
+ }
+ else {
+ fac = (float)(xy_init[1] - xy_curr[1]);
+ }
+
+ if (zoom_invert != zoom_invert_force) {
+ fac = -fac;
+ }
+
+ /* oldstyle zoom */
+ zfac = 1.0f + ((fac / 20.0f) * time_step);
+ *r_timer_lastdraw = time;
+ }
+ else if (viewzoom == USER_ZOOM_SCALE) {
+ /* method which zooms based on how far you move the mouse */
+
+ const int ctr[2] = {
+ BLI_rcti_cent_x(winrct),
+ BLI_rcti_cent_y(winrct),
+ };
+ float len_new = 5 + len_v2v2_int(ctr, xy_curr);
+ float len_old = 5 + len_v2v2_int(ctr, xy_init);
+
+ /* intentionally ignore 'zoom_invert' for scale */
+ if (zoom_invert_force) {
+ SWAP(float, len_new, len_old);
+ }
+
+ zfac = val_orig * (len_old / max_ff(len_new, 1.0f)) / val;
+ }
+ else { /* USER_ZOOM_DOLLY */
+ float len_new = 5;
+ float len_old = 5;
+
+ if (U.uiflag & USER_ZOOM_HORIZ) {
+ len_new += (winrct->xmax - (xy_curr[0]));
+ len_old += (winrct->xmax - (xy_init[0]));
+ }
+ else {
+ len_new += (winrct->ymax - (xy_curr[1]));
+ len_old += (winrct->ymax - (xy_init[1]));
+ }
+
+ if (zoom_invert != zoom_invert_force) {
+ SWAP(float, len_new, len_old);
+ }
+
+ zfac = val_orig * (2.0f * ((len_new / max_ff(len_old, 1.0f)) - 1.0f) + 1.0f) / val;
+ }
+
+ return zfac;
+}
+
+static float viewzoom_scale_value_offset(const rcti *winrct,
+ const short viewzoom,
+ const bool zoom_invert,
+ const bool zoom_invert_force,
+ const int xy_curr[2],
+ const int xy_init[2],
+ const int xy_offset[2],
+ const float val,
+ const float val_orig,
+ double *r_timer_lastdraw)
+{
+ const int xy_curr_offset[2] = {
+ xy_curr[0] + xy_offset[0],
+ xy_curr[1] + xy_offset[1],
+ };
+ const int xy_init_offset[2] = {
+ xy_init[0] + xy_offset[0],
+ xy_init[1] + xy_offset[1],
+ };
+ return viewzoom_scale_value(winrct,
+ viewzoom,
+ zoom_invert,
+ zoom_invert_force,
+ xy_curr_offset,
+ xy_init_offset,
+ val,
+ val_orig,
+ r_timer_lastdraw);
+}
+
+static void viewzoom_apply_camera(ViewOpsData *vod,
+ const int xy[2],
+ const short viewzoom,
+ const bool zoom_invert,
+ const bool zoom_to_pos)
+{
+ float zfac;
+ float zoomfac_prev = BKE_screen_view3d_zoom_to_fac(vod->init.camzoom) * 2.0f;
+ float zoomfac = BKE_screen_view3d_zoom_to_fac(vod->rv3d->camzoom) * 2.0f;
+
+ zfac = viewzoom_scale_value_offset(&vod->ar->winrct,
+ viewzoom,
+ zoom_invert,
+ true,
+ xy,
+ vod->init.event_xy,
+ vod->init.event_xy_offset,
+ zoomfac,
+ zoomfac_prev,
+ &vod->prev.time);
+
+ if (zfac != 1.0f && zfac != 0.0f) {
+ /* calculate inverted, then invert again (needed because of camera zoom scaling) */
+ zfac = 1.0f / zfac;
+ view_zoom_to_window_xy_camera(vod->scene,
+ vod->depsgraph,
+ vod->v3d,
+ vod->ar,
+ zfac,
+ zoom_to_pos ? vod->prev.event_xy : NULL);
+ }
+
+ ED_region_tag_redraw(vod->ar);
+}
+
+static void viewzoom_apply_3d(ViewOpsData *vod,
+ const int xy[2],
+ const short viewzoom,
+ const bool zoom_invert,
+ const bool zoom_to_pos)
+{
+ float zfac;
+ float dist_range[2];
+
+ ED_view3d_dist_range_get(vod->v3d, dist_range);
+
+ zfac = viewzoom_scale_value_offset(&vod->ar->winrct,
+ viewzoom,
+ zoom_invert,
+ false,
+ xy,
+ vod->init.event_xy,
+ vod->init.event_xy_offset,
+ vod->rv3d->dist,
+ vod->init.dist,
+ &vod->prev.time);
+
+ if (zfac != 1.0f) {
+ const float zfac_min = dist_range[0] / vod->rv3d->dist;
+ const float zfac_max = dist_range[1] / vod->rv3d->dist;
+ CLAMP(zfac, zfac_min, zfac_max);
+
+ view_zoom_to_window_xy_3d(vod->ar, zfac, zoom_to_pos ? vod->prev.event_xy : NULL);
+ }
+
+ /* these limits were in old code too */
+ CLAMP(vod->rv3d->dist, dist_range[0], dist_range[1]);
+
+ if (vod->rv3d->viewlock & RV3D_BOXVIEW) {
+ view3d_boxview_sync(vod->sa, vod->ar);
+ }
+
+ ED_view3d_camera_lock_sync(vod->depsgraph, vod->v3d, vod->rv3d);
+
+ ED_region_tag_redraw(vod->ar);
+}
+
+static void viewzoom_apply(ViewOpsData *vod,
+ const int xy[2],
+ const short viewzoom,
+ const bool zoom_invert,
+ const bool zoom_to_pos)
+{
+ if ((vod->rv3d->persp == RV3D_CAMOB) &&
+ (vod->rv3d->is_persp && ED_view3d_camera_lock_check(vod->v3d, vod->rv3d)) == 0) {
+ viewzoom_apply_camera(vod, xy, viewzoom, zoom_invert, zoom_to_pos);
+ }
+ else {
+ viewzoom_apply_3d(vod, xy, viewzoom, zoom_invert, zoom_to_pos);
+ }
}
static int viewzoom_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
- ViewOpsData *vod = op->customdata;
- short event_code = VIEW_PASS;
- bool use_autokey = false;
- int ret = OPERATOR_RUNNING_MODAL;
-
- /* execute the events */
- if (event->type == TIMER && event->customdata == vod->timer) {
- /* continuous zoom */
- event_code = VIEW_APPLY;
- }
- else if (event->type == MOUSEMOVE) {
- event_code = VIEW_APPLY;
- }
- else if (event->type == EVT_MODAL_MAP) {
- switch (event->val) {
- case VIEW_MODAL_CONFIRM:
- event_code = VIEW_CONFIRM;
- break;
- case VIEWROT_MODAL_SWITCH_MOVE:
- WM_operator_name_call(C, "VIEW3D_OT_move", WM_OP_INVOKE_DEFAULT, NULL);
- event_code = VIEW_CONFIRM;
- break;
- case VIEWROT_MODAL_SWITCH_ROTATE:
- WM_operator_name_call(C, "VIEW3D_OT_rotate", WM_OP_INVOKE_DEFAULT, NULL);
- event_code = VIEW_CONFIRM;
- break;
- }
- }
- else if (event->type == vod->init.event_type && event->val == KM_RELEASE) {
- event_code = VIEW_CONFIRM;
- }
-
- if (event_code == VIEW_APPLY) {
- const bool use_mouse_init = RNA_boolean_get(op->ptr, "use_mouse_init");
- viewzoom_apply(
- vod, &event->x, U.viewzoom,
- (U.uiflag & USER_ZOOM_INVERT) != 0,
- (use_mouse_init && (U.uiflag & USER_ZOOM_TO_MOUSEPOS)));
- if (ED_screen_animation_playing(CTX_wm_manager(C))) {
- use_autokey = true;
- }
- }
- else if (event_code == VIEW_CONFIRM) {
- ED_view3d_depth_tag_update(vod->rv3d);
- use_autokey = true;
- ret = OPERATOR_FINISHED;
- }
-
- if (use_autokey) {
- ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, false, true);
- }
-
- if (ret & OPERATOR_FINISHED) {
- viewops_data_free(C, op);
- }
-
- return ret;
+ ViewOpsData *vod = op->customdata;
+ short event_code = VIEW_PASS;
+ bool use_autokey = false;
+ int ret = OPERATOR_RUNNING_MODAL;
+
+ /* execute the events */
+ if (event->type == TIMER && event->customdata == vod->timer) {
+ /* continuous zoom */
+ event_code = VIEW_APPLY;
+ }
+ else if (event->type == MOUSEMOVE) {
+ event_code = VIEW_APPLY;
+ }
+ else if (event->type == EVT_MODAL_MAP) {
+ switch (event->val) {
+ case VIEW_MODAL_CONFIRM:
+ event_code = VIEW_CONFIRM;
+ break;
+ case VIEWROT_MODAL_SWITCH_MOVE:
+ WM_operator_name_call(C, "VIEW3D_OT_move", WM_OP_INVOKE_DEFAULT, NULL);
+ event_code = VIEW_CONFIRM;
+ break;
+ case VIEWROT_MODAL_SWITCH_ROTATE:
+ WM_operator_name_call(C, "VIEW3D_OT_rotate", WM_OP_INVOKE_DEFAULT, NULL);
+ event_code = VIEW_CONFIRM;
+ break;
+ }
+ }
+ else if (event->type == vod->init.event_type && event->val == KM_RELEASE) {
+ event_code = VIEW_CONFIRM;
+ }
+
+ if (event_code == VIEW_APPLY) {
+ const bool use_mouse_init = RNA_boolean_get(op->ptr, "use_mouse_init");
+ viewzoom_apply(vod,
+ &event->x,
+ U.viewzoom,
+ (U.uiflag & USER_ZOOM_INVERT) != 0,
+ (use_mouse_init && (U.uiflag & USER_ZOOM_TO_MOUSEPOS)));
+ if (ED_screen_animation_playing(CTX_wm_manager(C))) {
+ use_autokey = true;
+ }
+ }
+ else if (event_code == VIEW_CONFIRM) {
+ ED_view3d_depth_tag_update(vod->rv3d);
+ use_autokey = true;
+ ret = OPERATOR_FINISHED;
+ }
+
+ if (use_autokey) {
+ ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, false, true);
+ }
+
+ if (ret & OPERATOR_FINISHED) {
+ viewops_data_free(C, op);
+ }
+
+ return ret;
}
static int viewzoom_exec(bContext *C, wmOperator *op)
{
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- Scene *scene = CTX_data_scene(C);
- View3D *v3d;
- RegionView3D *rv3d;
- ScrArea *sa;
- ARegion *ar;
- bool use_cam_zoom;
- float dist_range[2];
-
- const int delta = RNA_int_get(op->ptr, "delta");
- const bool use_mouse_init = RNA_boolean_get(op->ptr, "use_mouse_init");
-
- if (op->customdata) {
- ViewOpsData *vod = op->customdata;
-
- sa = vod->sa;
- ar = vod->ar;
- }
- else {
- sa = CTX_wm_area(C);
- ar = CTX_wm_region(C);
- }
-
- v3d = sa->spacedata.first;
- rv3d = ar->regiondata;
-
-
- use_cam_zoom = (rv3d->persp == RV3D_CAMOB) && !(rv3d->is_persp && ED_view3d_camera_lock_check(v3d, rv3d));
-
- int zoom_xy_buf[2];
- const int *zoom_xy = NULL;
- if (use_mouse_init && (U.uiflag & USER_ZOOM_TO_MOUSEPOS)) {
- zoom_xy_buf[0] = RNA_struct_property_is_set(op->ptr, "mx") ? RNA_int_get(op->ptr, "mx") : ar->winx / 2;
- zoom_xy_buf[1] = RNA_struct_property_is_set(op->ptr, "my") ? RNA_int_get(op->ptr, "my") : ar->winy / 2;
- zoom_xy = zoom_xy_buf;
- }
-
- ED_view3d_dist_range_get(v3d, dist_range);
-
- if (delta < 0) {
- const float step = 1.2f;
- /* this min and max is also in viewmove() */
- if (use_cam_zoom) {
- view_zoom_to_window_xy_camera(scene, depsgraph, v3d, ar, step, zoom_xy);
- }
- else {
- if (rv3d->dist < dist_range[1]) {
- view_zoom_to_window_xy_3d(ar, step, zoom_xy);
- }
- }
- }
- else {
- const float step = 1.0f / 1.2f;
- if (use_cam_zoom) {
- view_zoom_to_window_xy_camera(scene, depsgraph, v3d, ar, step, zoom_xy);
- }
- else {
- if (rv3d->dist > dist_range[0]) {
- view_zoom_to_window_xy_3d(ar, step, zoom_xy);
- }
- }
- }
-
- if (rv3d->viewlock & RV3D_BOXVIEW) {
- view3d_boxview_sync(sa, ar);
- }
-
- ED_view3d_depth_tag_update(rv3d);
-
- ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
- ED_view3d_camera_lock_autokey(v3d, rv3d, C, false, true);
-
- ED_region_tag_redraw(ar);
-
- viewops_data_free(C, op);
-
- return OPERATOR_FINISHED;
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ Scene *scene = CTX_data_scene(C);
+ View3D *v3d;
+ RegionView3D *rv3d;
+ ScrArea *sa;
+ ARegion *ar;
+ bool use_cam_zoom;
+ float dist_range[2];
+
+ const int delta = RNA_int_get(op->ptr, "delta");
+ const bool use_mouse_init = RNA_boolean_get(op->ptr, "use_mouse_init");
+
+ if (op->customdata) {
+ ViewOpsData *vod = op->customdata;
+
+ sa = vod->sa;
+ ar = vod->ar;
+ }
+ else {
+ sa = CTX_wm_area(C);
+ ar = CTX_wm_region(C);
+ }
+
+ v3d = sa->spacedata.first;
+ rv3d = ar->regiondata;
+
+ use_cam_zoom = (rv3d->persp == RV3D_CAMOB) &&
+ !(rv3d->is_persp && ED_view3d_camera_lock_check(v3d, rv3d));
+
+ int zoom_xy_buf[2];
+ const int *zoom_xy = NULL;
+ if (use_mouse_init && (U.uiflag & USER_ZOOM_TO_MOUSEPOS)) {
+ zoom_xy_buf[0] = RNA_struct_property_is_set(op->ptr, "mx") ? RNA_int_get(op->ptr, "mx") :
+ ar->winx / 2;
+ zoom_xy_buf[1] = RNA_struct_property_is_set(op->ptr, "my") ? RNA_int_get(op->ptr, "my") :
+ ar->winy / 2;
+ zoom_xy = zoom_xy_buf;
+ }
+
+ ED_view3d_dist_range_get(v3d, dist_range);
+
+ if (delta < 0) {
+ const float step = 1.2f;
+ /* this min and max is also in viewmove() */
+ if (use_cam_zoom) {
+ view_zoom_to_window_xy_camera(scene, depsgraph, v3d, ar, step, zoom_xy);
+ }
+ else {
+ if (rv3d->dist < dist_range[1]) {
+ view_zoom_to_window_xy_3d(ar, step, zoom_xy);
+ }
+ }
+ }
+ else {
+ const float step = 1.0f / 1.2f;
+ if (use_cam_zoom) {
+ view_zoom_to_window_xy_camera(scene, depsgraph, v3d, ar, step, zoom_xy);
+ }
+ else {
+ if (rv3d->dist > dist_range[0]) {
+ view_zoom_to_window_xy_3d(ar, step, zoom_xy);
+ }
+ }
+ }
+
+ if (rv3d->viewlock & RV3D_BOXVIEW) {
+ view3d_boxview_sync(sa, ar);
+ }
+
+ ED_view3d_depth_tag_update(rv3d);
+
+ ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
+ ED_view3d_camera_lock_autokey(v3d, rv3d, C, false, true);
+
+ ED_region_tag_redraw(ar);
+
+ viewops_data_free(C, op);
+
+ return OPERATOR_FINISHED;
}
/* viewdolly_invoke() copied this function, changes here may apply there */
static int viewzoom_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- ViewOpsData *vod;
-
- const bool use_mouse_init = RNA_boolean_get(op->ptr, "use_mouse_init");
-
- /* makes op->customdata */
- viewops_data_alloc(C, op);
- viewops_data_create(
- C, op, event,
- (viewops_flag_from_prefs() & ~VIEWOPS_FLAG_ORBIT_SELECT) |
- (use_mouse_init ? VIEWOPS_FLAG_USE_MOUSE_INIT : 0));
- vod = op->customdata;
-
- ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->ar);
-
- /* if one or the other zoom position aren't set, set from event */
- if (!RNA_struct_property_is_set(op->ptr, "mx") || !RNA_struct_property_is_set(op->ptr, "my")) {
- RNA_int_set(op->ptr, "mx", event->x);
- RNA_int_set(op->ptr, "my", event->y);
- }
-
- if (RNA_struct_property_is_set(op->ptr, "delta")) {
- viewzoom_exec(C, op);
- }
- else {
- if (event->type == MOUSEZOOM || event->type == MOUSEPAN) {
-
- if (U.uiflag & USER_ZOOM_HORIZ) {
- vod->init.event_xy[0] = vod->prev.event_xy[0] = event->x;
- }
- else {
- /* Set y move = x move as MOUSEZOOM uses only x axis to pass magnification value */
- vod->init.event_xy[1] = vod->prev.event_xy[1] = vod->init.event_xy[1] + event->x - event->prevx;
- }
- viewzoom_apply(
- vod, &event->prevx, USER_ZOOM_DOLLY,
- (U.uiflag & USER_ZOOM_INVERT) != 0,
- (use_mouse_init && (U.uiflag & USER_ZOOM_TO_MOUSEPOS)));
- ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, false, true);
-
- ED_view3d_depth_tag_update(vod->rv3d);
-
- viewops_data_free(C, op);
- return OPERATOR_FINISHED;
- }
- else {
- if (U.viewzoom == USER_ZOOM_CONT) {
- /* needs a timer to continue redrawing */
- vod->timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f);
- vod->prev.time = PIL_check_seconds_timer();
- }
-
- /* add temp handler */
- WM_event_add_modal_handler(C, op);
-
- return OPERATOR_RUNNING_MODAL;
- }
- }
- return OPERATOR_FINISHED;
+ ViewOpsData *vod;
+
+ const bool use_mouse_init = RNA_boolean_get(op->ptr, "use_mouse_init");
+
+ /* makes op->customdata */
+ viewops_data_alloc(C, op);
+ viewops_data_create(C,
+ op,
+ event,
+ (viewops_flag_from_prefs() & ~VIEWOPS_FLAG_ORBIT_SELECT) |
+ (use_mouse_init ? VIEWOPS_FLAG_USE_MOUSE_INIT : 0));
+ vod = op->customdata;
+
+ ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->ar);
+
+ /* if one or the other zoom position aren't set, set from event */
+ if (!RNA_struct_property_is_set(op->ptr, "mx") || !RNA_struct_property_is_set(op->ptr, "my")) {
+ RNA_int_set(op->ptr, "mx", event->x);
+ RNA_int_set(op->ptr, "my", event->y);
+ }
+
+ if (RNA_struct_property_is_set(op->ptr, "delta")) {
+ viewzoom_exec(C, op);
+ }
+ else {
+ if (event->type == MOUSEZOOM || event->type == MOUSEPAN) {
+
+ if (U.uiflag & USER_ZOOM_HORIZ) {
+ vod->init.event_xy[0] = vod->prev.event_xy[0] = event->x;
+ }
+ else {
+ /* Set y move = x move as MOUSEZOOM uses only x axis to pass magnification value */
+ vod->init.event_xy[1] = vod->prev.event_xy[1] = vod->init.event_xy[1] + event->x -
+ event->prevx;
+ }
+ viewzoom_apply(vod,
+ &event->prevx,
+ USER_ZOOM_DOLLY,
+ (U.uiflag & USER_ZOOM_INVERT) != 0,
+ (use_mouse_init && (U.uiflag & USER_ZOOM_TO_MOUSEPOS)));
+ ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, false, true);
+
+ ED_view3d_depth_tag_update(vod->rv3d);
+
+ viewops_data_free(C, op);
+ return OPERATOR_FINISHED;
+ }
+ else {
+ if (U.viewzoom == USER_ZOOM_CONT) {
+ /* needs a timer to continue redrawing */
+ vod->timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f);
+ vod->prev.time = PIL_check_seconds_timer();
+ }
+
+ /* add temp handler */
+ WM_event_add_modal_handler(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
+ }
+ }
+ return OPERATOR_FINISHED;
}
static void viewzoom_cancel(bContext *C, wmOperator *op)
{
- viewops_data_free(C, op);
+ viewops_data_free(C, op);
}
void VIEW3D_OT_zoom(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Zoom View";
- ot->description = "Zoom in/out in the view";
- ot->idname = "VIEW3D_OT_zoom";
+ /* identifiers */
+ ot->name = "Zoom View";
+ ot->description = "Zoom in/out in the view";
+ ot->idname = "VIEW3D_OT_zoom";
- /* api callbacks */
- ot->invoke = viewzoom_invoke;
- ot->exec = viewzoom_exec;
- ot->modal = viewzoom_modal;
- ot->poll = ED_operator_region_view3d_active;
- ot->cancel = viewzoom_cancel;
+ /* api callbacks */
+ ot->invoke = viewzoom_invoke;
+ ot->exec = viewzoom_exec;
+ ot->modal = viewzoom_modal;
+ ot->poll = ED_operator_region_view3d_active;
+ ot->cancel = viewzoom_cancel;
- /* flags */
- ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR;
+ /* flags */
+ ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR;
- /* properties */
- view3d_operator_properties_common(
- ot,
- V3D_OP_PROP_DELTA | V3D_OP_PROP_MOUSE_CO | V3D_OP_PROP_USE_MOUSE_INIT);
+ /* properties */
+ view3d_operator_properties_common(
+ ot, V3D_OP_PROP_DELTA | V3D_OP_PROP_MOUSE_CO | V3D_OP_PROP_USE_MOUSE_INIT);
}
/** \} */
@@ -2344,304 +2376,304 @@ void VIEW3D_OT_zoom(wmOperatorType *ot)
/* called in transform_ops.c, on each regeneration of keymaps */
void viewdolly_modal_keymap(wmKeyConfig *keyconf)
{
- static const EnumPropertyItem modal_items[] = {
- {VIEW_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
+ static const EnumPropertyItem modal_items[] = {
+ {VIEW_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
- {VIEWROT_MODAL_SWITCH_ROTATE, "SWITCH_TO_ROTATE", 0, "Switch to Rotate"},
- {VIEWROT_MODAL_SWITCH_MOVE, "SWITCH_TO_MOVE", 0, "Switch to Move"},
+ {VIEWROT_MODAL_SWITCH_ROTATE, "SWITCH_TO_ROTATE", 0, "Switch to Rotate"},
+ {VIEWROT_MODAL_SWITCH_MOVE, "SWITCH_TO_MOVE", 0, "Switch to Move"},
- {0, NULL, 0, NULL, NULL},
- };
+ {0, NULL, 0, NULL, NULL},
+ };
- wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Dolly Modal");
+ wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Dolly Modal");
- /* this function is called for each spacetype, only needs to add map once */
- if (keymap && keymap->modal_items) {
- return;
- }
+ /* this function is called for each spacetype, only needs to add map once */
+ if (keymap && keymap->modal_items) {
+ return;
+ }
- keymap = WM_modalkeymap_add(keyconf, "View3D Dolly Modal", modal_items);
+ keymap = WM_modalkeymap_add(keyconf, "View3D Dolly Modal", modal_items);
- /* disabled mode switching for now, can re-implement better, later on */
+ /* disabled mode switching for now, can re-implement better, later on */
#if 0
- WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ROTATE);
- WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ROTATE);
- WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_MOVE);
+ WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ROTATE);
+ WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ROTATE);
+ WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_MOVE);
#endif
- /* assign map to operators */
- WM_modalkeymap_assign(keymap, "VIEW3D_OT_dolly");
+ /* assign map to operators */
+ WM_modalkeymap_assign(keymap, "VIEW3D_OT_dolly");
}
static bool viewdolly_offset_lock_check(bContext *C, wmOperator *op)
{
- View3D *v3d = CTX_wm_view3d(C);
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
- if (ED_view3d_offset_lock_check(v3d, rv3d)) {
- BKE_report(op->reports, RPT_WARNING, "Cannot dolly when the view offset is locked");
- return true;
- }
- else {
- return false;
- }
+ View3D *v3d = CTX_wm_view3d(C);
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ if (ED_view3d_offset_lock_check(v3d, rv3d)) {
+ BKE_report(op->reports, RPT_WARNING, "Cannot dolly when the view offset is locked");
+ return true;
+ }
+ else {
+ return false;
+ }
}
static void view_dolly_to_vector_3d(ARegion *ar, float orig_ofs[3], float dvec[3], float dfac)
{
- RegionView3D *rv3d = ar->regiondata;
- madd_v3_v3v3fl(rv3d->ofs, orig_ofs, dvec, -(1.0f - dfac));
+ RegionView3D *rv3d = ar->regiondata;
+ madd_v3_v3v3fl(rv3d->ofs, orig_ofs, dvec, -(1.0f - dfac));
}
static void viewdolly_apply(ViewOpsData *vod, const int xy[2], const short zoom_invert)
{
- float zfac = 1.0;
+ float zfac = 1.0;
- {
- float len1, len2;
+ {
+ float len1, len2;
- if (U.uiflag & USER_ZOOM_HORIZ) {
- len1 = (vod->ar->winrct.xmax - xy[0]) + 5;
- len2 = (vod->ar->winrct.xmax - vod->init.event_xy[0]) + 5;
- }
- else {
- len1 = (vod->ar->winrct.ymax - xy[1]) + 5;
- len2 = (vod->ar->winrct.ymax - vod->init.event_xy[1]) + 5;
- }
- if (zoom_invert) {
- SWAP(float, len1, len2);
- }
+ if (U.uiflag & USER_ZOOM_HORIZ) {
+ len1 = (vod->ar->winrct.xmax - xy[0]) + 5;
+ len2 = (vod->ar->winrct.xmax - vod->init.event_xy[0]) + 5;
+ }
+ else {
+ len1 = (vod->ar->winrct.ymax - xy[1]) + 5;
+ len2 = (vod->ar->winrct.ymax - vod->init.event_xy[1]) + 5;
+ }
+ if (zoom_invert) {
+ SWAP(float, len1, len2);
+ }
- zfac = 1.0f + ((len1 - len2) * 0.01f * vod->rv3d->dist);
- }
+ zfac = 1.0f + ((len1 - len2) * 0.01f * vod->rv3d->dist);
+ }
- if (zfac != 1.0f) {
- view_dolly_to_vector_3d(vod->ar, vod->init.ofs, vod->init.mousevec, zfac);
- }
+ if (zfac != 1.0f) {
+ view_dolly_to_vector_3d(vod->ar, vod->init.ofs, vod->init.mousevec, zfac);
+ }
- if (vod->rv3d->viewlock & RV3D_BOXVIEW) {
- view3d_boxview_sync(vod->sa, vod->ar);
- }
+ if (vod->rv3d->viewlock & RV3D_BOXVIEW) {
+ view3d_boxview_sync(vod->sa, vod->ar);
+ }
- ED_view3d_camera_lock_sync(vod->depsgraph, vod->v3d, vod->rv3d);
+ ED_view3d_camera_lock_sync(vod->depsgraph, vod->v3d, vod->rv3d);
- ED_region_tag_redraw(vod->ar);
+ ED_region_tag_redraw(vod->ar);
}
-
static int viewdolly_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
- ViewOpsData *vod = op->customdata;
- short event_code = VIEW_PASS;
- bool use_autokey = false;
- int ret = OPERATOR_RUNNING_MODAL;
-
- /* execute the events */
- if (event->type == MOUSEMOVE) {
- event_code = VIEW_APPLY;
- }
- else if (event->type == EVT_MODAL_MAP) {
- switch (event->val) {
- case VIEW_MODAL_CONFIRM:
- event_code = VIEW_CONFIRM;
- break;
- case VIEWROT_MODAL_SWITCH_MOVE:
- WM_operator_name_call(C, "VIEW3D_OT_move", WM_OP_INVOKE_DEFAULT, NULL);
- event_code = VIEW_CONFIRM;
- break;
- case VIEWROT_MODAL_SWITCH_ROTATE:
- WM_operator_name_call(C, "VIEW3D_OT_rotate", WM_OP_INVOKE_DEFAULT, NULL);
- event_code = VIEW_CONFIRM;
- break;
- }
- }
- else if (event->type == vod->init.event_type && event->val == KM_RELEASE) {
- event_code = VIEW_CONFIRM;
- }
-
- if (event_code == VIEW_APPLY) {
- viewdolly_apply(vod, &event->x, (U.uiflag & USER_ZOOM_INVERT) != 0);
- if (ED_screen_animation_playing(CTX_wm_manager(C))) {
- use_autokey = true;
- }
- }
- else if (event_code == VIEW_CONFIRM) {
- ED_view3d_depth_tag_update(vod->rv3d);
- use_autokey = true;
- ret = OPERATOR_FINISHED;
- }
-
- if (use_autokey) {
- ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, false, true);
- }
-
- if (ret & OPERATOR_FINISHED) {
- viewops_data_free(C, op);
- }
-
- return ret;
+ ViewOpsData *vod = op->customdata;
+ short event_code = VIEW_PASS;
+ bool use_autokey = false;
+ int ret = OPERATOR_RUNNING_MODAL;
+
+ /* execute the events */
+ if (event->type == MOUSEMOVE) {
+ event_code = VIEW_APPLY;
+ }
+ else if (event->type == EVT_MODAL_MAP) {
+ switch (event->val) {
+ case VIEW_MODAL_CONFIRM:
+ event_code = VIEW_CONFIRM;
+ break;
+ case VIEWROT_MODAL_SWITCH_MOVE:
+ WM_operator_name_call(C, "VIEW3D_OT_move", WM_OP_INVOKE_DEFAULT, NULL);
+ event_code = VIEW_CONFIRM;
+ break;
+ case VIEWROT_MODAL_SWITCH_ROTATE:
+ WM_operator_name_call(C, "VIEW3D_OT_rotate", WM_OP_INVOKE_DEFAULT, NULL);
+ event_code = VIEW_CONFIRM;
+ break;
+ }
+ }
+ else if (event->type == vod->init.event_type && event->val == KM_RELEASE) {
+ event_code = VIEW_CONFIRM;
+ }
+
+ if (event_code == VIEW_APPLY) {
+ viewdolly_apply(vod, &event->x, (U.uiflag & USER_ZOOM_INVERT) != 0);
+ if (ED_screen_animation_playing(CTX_wm_manager(C))) {
+ use_autokey = true;
+ }
+ }
+ else if (event_code == VIEW_CONFIRM) {
+ ED_view3d_depth_tag_update(vod->rv3d);
+ use_autokey = true;
+ ret = OPERATOR_FINISHED;
+ }
+
+ if (use_autokey) {
+ ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, false, true);
+ }
+
+ if (ret & OPERATOR_FINISHED) {
+ viewops_data_free(C, op);
+ }
+
+ return ret;
}
static int viewdolly_exec(bContext *C, wmOperator *op)
{
- View3D *v3d;
- RegionView3D *rv3d;
- ScrArea *sa;
- ARegion *ar;
- float mousevec[3];
+ View3D *v3d;
+ RegionView3D *rv3d;
+ ScrArea *sa;
+ ARegion *ar;
+ float mousevec[3];
- const int delta = RNA_int_get(op->ptr, "delta");
+ const int delta = RNA_int_get(op->ptr, "delta");
- if (op->customdata) {
- ViewOpsData *vod = op->customdata;
+ if (op->customdata) {
+ ViewOpsData *vod = op->customdata;
- sa = vod->sa;
- ar = vod->ar;
- copy_v3_v3(mousevec, vod->init.mousevec);
- }
- else {
- sa = CTX_wm_area(C);
- ar = CTX_wm_region(C);
- negate_v3_v3(mousevec, ((RegionView3D *)ar->regiondata)->viewinv[2]);
- normalize_v3(mousevec);
- }
+ sa = vod->sa;
+ ar = vod->ar;
+ copy_v3_v3(mousevec, vod->init.mousevec);
+ }
+ else {
+ sa = CTX_wm_area(C);
+ ar = CTX_wm_region(C);
+ negate_v3_v3(mousevec, ((RegionView3D *)ar->regiondata)->viewinv[2]);
+ normalize_v3(mousevec);
+ }
- v3d = sa->spacedata.first;
- rv3d = ar->regiondata;
+ v3d = sa->spacedata.first;
+ rv3d = ar->regiondata;
- const bool use_mouse_init = RNA_boolean_get(op->ptr, "use_mouse_init");
+ const bool use_mouse_init = RNA_boolean_get(op->ptr, "use_mouse_init");
- /* overwrite the mouse vector with the view direction (zoom into the center) */
- if ((use_mouse_init && (U.uiflag & USER_ZOOM_TO_MOUSEPOS)) == 0) {
- normalize_v3_v3(mousevec, rv3d->viewinv[2]);
- }
+ /* overwrite the mouse vector with the view direction (zoom into the center) */
+ if ((use_mouse_init && (U.uiflag & USER_ZOOM_TO_MOUSEPOS)) == 0) {
+ normalize_v3_v3(mousevec, rv3d->viewinv[2]);
+ }
- view_dolly_to_vector_3d(ar, rv3d->ofs, mousevec, delta < 0 ? 0.2f : 1.8f);
+ view_dolly_to_vector_3d(ar, rv3d->ofs, mousevec, delta < 0 ? 0.2f : 1.8f);
- if (rv3d->viewlock & RV3D_BOXVIEW) {
- view3d_boxview_sync(sa, ar);
- }
+ if (rv3d->viewlock & RV3D_BOXVIEW) {
+ view3d_boxview_sync(sa, ar);
+ }
- ED_view3d_depth_tag_update(rv3d);
+ ED_view3d_depth_tag_update(rv3d);
- ED_view3d_camera_lock_sync(CTX_data_depsgraph(C), v3d, rv3d);
+ ED_view3d_camera_lock_sync(CTX_data_depsgraph(C), v3d, rv3d);
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(ar);
- viewops_data_free(C, op);
+ viewops_data_free(C, op);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
/* copied from viewzoom_invoke(), changes here may apply there */
static int viewdolly_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- ViewOpsData *vod;
-
- if (viewdolly_offset_lock_check(C, op)) {
- return OPERATOR_CANCELLED;
- }
-
- /* makes op->customdata */
- viewops_data_alloc(C, op);
- vod = op->customdata;
-
- /* poll should check but in some cases fails, see poll func for details */
- if (vod->rv3d->viewlock & RV3D_LOCKED) {
- viewops_data_free(C, op);
- return OPERATOR_PASS_THROUGH;
- }
-
- ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->ar);
-
- /* needs to run before 'viewops_data_create' so the backup 'rv3d->ofs' is correct */
- /* switch from camera view when: */
- if (vod->rv3d->persp != RV3D_PERSP) {
- if (vod->rv3d->persp == RV3D_CAMOB) {
- /* ignore rv3d->lpersp because dolly only makes sense in perspective mode */
- const Depsgraph *depsgraph = CTX_data_depsgraph(C);
- ED_view3d_persp_switch_from_camera(depsgraph, vod->v3d, vod->rv3d, RV3D_PERSP);
- }
- else {
- vod->rv3d->persp = RV3D_PERSP;
- }
- ED_region_tag_redraw(vod->ar);
- }
-
- const bool use_mouse_init = RNA_boolean_get(op->ptr, "use_mouse_init");
-
- viewops_data_create(
- C, op, event,
- (viewops_flag_from_prefs() & ~VIEWOPS_FLAG_ORBIT_SELECT) |
- (use_mouse_init ? VIEWOPS_FLAG_USE_MOUSE_INIT : 0));
-
-
- /* if one or the other zoom position aren't set, set from event */
- if (!RNA_struct_property_is_set(op->ptr, "mx") || !RNA_struct_property_is_set(op->ptr, "my")) {
- RNA_int_set(op->ptr, "mx", event->x);
- RNA_int_set(op->ptr, "my", event->y);
- }
-
- if (RNA_struct_property_is_set(op->ptr, "delta")) {
- viewdolly_exec(C, op);
- }
- else {
- /* overwrite the mouse vector with the view direction (zoom into the center) */
- if ((use_mouse_init && (U.uiflag & USER_ZOOM_TO_MOUSEPOS)) == 0) {
- negate_v3_v3(vod->init.mousevec, vod->rv3d->viewinv[2]);
- normalize_v3(vod->init.mousevec);
- }
-
- if (event->type == MOUSEZOOM) {
- /* Bypass Zoom invert flag for track pads (pass false always) */
-
- if (U.uiflag & USER_ZOOM_HORIZ) {
- vod->init.event_xy[0] = vod->prev.event_xy[0] = event->x;
- }
- else {
- /* Set y move = x move as MOUSEZOOM uses only x axis to pass magnification value */
- vod->init.event_xy[1] = vod->prev.event_xy[1] = vod->init.event_xy[1] + event->x - event->prevx;
- }
- viewdolly_apply(vod, &event->prevx, (U.uiflag & USER_ZOOM_INVERT) == 0);
- ED_view3d_depth_tag_update(vod->rv3d);
-
- viewops_data_free(C, op);
- return OPERATOR_FINISHED;
- }
- else {
- /* add temp handler */
- WM_event_add_modal_handler(C, op);
-
- return OPERATOR_RUNNING_MODAL;
- }
- }
- return OPERATOR_FINISHED;
+ ViewOpsData *vod;
+
+ if (viewdolly_offset_lock_check(C, op)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* makes op->customdata */
+ viewops_data_alloc(C, op);
+ vod = op->customdata;
+
+ /* poll should check but in some cases fails, see poll func for details */
+ if (vod->rv3d->viewlock & RV3D_LOCKED) {
+ viewops_data_free(C, op);
+ return OPERATOR_PASS_THROUGH;
+ }
+
+ ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->ar);
+
+ /* needs to run before 'viewops_data_create' so the backup 'rv3d->ofs' is correct */
+ /* switch from camera view when: */
+ if (vod->rv3d->persp != RV3D_PERSP) {
+ if (vod->rv3d->persp == RV3D_CAMOB) {
+ /* ignore rv3d->lpersp because dolly only makes sense in perspective mode */
+ const Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ ED_view3d_persp_switch_from_camera(depsgraph, vod->v3d, vod->rv3d, RV3D_PERSP);
+ }
+ else {
+ vod->rv3d->persp = RV3D_PERSP;
+ }
+ ED_region_tag_redraw(vod->ar);
+ }
+
+ const bool use_mouse_init = RNA_boolean_get(op->ptr, "use_mouse_init");
+
+ viewops_data_create(C,
+ op,
+ event,
+ (viewops_flag_from_prefs() & ~VIEWOPS_FLAG_ORBIT_SELECT) |
+ (use_mouse_init ? VIEWOPS_FLAG_USE_MOUSE_INIT : 0));
+
+ /* if one or the other zoom position aren't set, set from event */
+ if (!RNA_struct_property_is_set(op->ptr, "mx") || !RNA_struct_property_is_set(op->ptr, "my")) {
+ RNA_int_set(op->ptr, "mx", event->x);
+ RNA_int_set(op->ptr, "my", event->y);
+ }
+
+ if (RNA_struct_property_is_set(op->ptr, "delta")) {
+ viewdolly_exec(C, op);
+ }
+ else {
+ /* overwrite the mouse vector with the view direction (zoom into the center) */
+ if ((use_mouse_init && (U.uiflag & USER_ZOOM_TO_MOUSEPOS)) == 0) {
+ negate_v3_v3(vod->init.mousevec, vod->rv3d->viewinv[2]);
+ normalize_v3(vod->init.mousevec);
+ }
+
+ if (event->type == MOUSEZOOM) {
+ /* Bypass Zoom invert flag for track pads (pass false always) */
+
+ if (U.uiflag & USER_ZOOM_HORIZ) {
+ vod->init.event_xy[0] = vod->prev.event_xy[0] = event->x;
+ }
+ else {
+ /* Set y move = x move as MOUSEZOOM uses only x axis to pass magnification value */
+ vod->init.event_xy[1] = vod->prev.event_xy[1] = vod->init.event_xy[1] + event->x -
+ event->prevx;
+ }
+ viewdolly_apply(vod, &event->prevx, (U.uiflag & USER_ZOOM_INVERT) == 0);
+ ED_view3d_depth_tag_update(vod->rv3d);
+
+ viewops_data_free(C, op);
+ return OPERATOR_FINISHED;
+ }
+ else {
+ /* add temp handler */
+ WM_event_add_modal_handler(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
+ }
+ }
+ return OPERATOR_FINISHED;
}
static void viewdolly_cancel(bContext *C, wmOperator *op)
{
- viewops_data_free(C, op);
+ viewops_data_free(C, op);
}
void VIEW3D_OT_dolly(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Dolly View";
- ot->description = "Dolly in/out in the view";
- ot->idname = "VIEW3D_OT_dolly";
+ /* identifiers */
+ ot->name = "Dolly View";
+ ot->description = "Dolly in/out in the view";
+ ot->idname = "VIEW3D_OT_dolly";
- /* api callbacks */
- ot->invoke = viewdolly_invoke;
- ot->exec = viewdolly_exec;
- ot->modal = viewdolly_modal;
- ot->poll = ED_operator_region_view3d_active;
- ot->cancel = viewdolly_cancel;
+ /* api callbacks */
+ ot->invoke = viewdolly_invoke;
+ ot->exec = viewdolly_exec;
+ ot->modal = viewdolly_modal;
+ ot->poll = ED_operator_region_view3d_active;
+ ot->cancel = viewdolly_cancel;
- /* flags */
- ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR;
+ /* flags */
+ ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR;
- /* properties */
- view3d_operator_properties_common(
- ot, V3D_OP_PROP_DELTA | V3D_OP_PROP_MOUSE_CO | V3D_OP_PROP_USE_MOUSE_INIT);
+ /* properties */
+ view3d_operator_properties_common(
+ ot, V3D_OP_PROP_DELTA | V3D_OP_PROP_MOUSE_CO | V3D_OP_PROP_USE_MOUSE_INIT);
}
/** \} */
@@ -2652,215 +2684,228 @@ void VIEW3D_OT_dolly(wmOperatorType *ot)
* Move & Zoom the view to fit all of it's contents.
* \{ */
-static bool view3d_object_skip_minmax(
- const View3D *v3d, const RegionView3D *rv3d, const Object *ob, const bool skip_camera,
- bool *r_only_center)
-{
- BLI_assert(ob->id.orig_id == NULL);
- *r_only_center = false;
-
- if (skip_camera && (ob == v3d->camera)) {
- return true;
- }
-
- if ((ob->type == OB_EMPTY) &&
- (ob->empty_drawtype == OB_EMPTY_IMAGE) &&
- !BKE_object_empty_image_frame_is_visible_in_view3d(ob, rv3d))
- {
- *r_only_center = true;
- return false;
- }
-
- return false;
-}
-
-static void view3d_from_minmax(
- bContext *C, View3D *v3d, ARegion *ar,
- const float min[3], const float max[3],
- bool ok_dist, const int smooth_viewtx)
-{
- RegionView3D *rv3d = ar->regiondata;
- float afm[3];
- float size;
-
- ED_view3d_smooth_view_force_finish(C, v3d, ar);
-
- /* SMOOTHVIEW */
- float new_ofs[3];
- float new_dist;
-
- sub_v3_v3v3(afm, max, min);
- size = max_fff(afm[0], afm[1], afm[2]);
-
- if (ok_dist) {
- char persp;
-
- if (rv3d->is_persp) {
- if (rv3d->persp == RV3D_CAMOB && ED_view3d_camera_lock_check(v3d, rv3d)) {
- persp = RV3D_CAMOB;
- }
- else {
- persp = RV3D_PERSP;
- }
- }
- else { /* ortho */
- if (size < 0.0001f) {
- /* bounding box was a single point so do not zoom */
- ok_dist = false;
- }
- else {
- /* adjust zoom so it looks nicer */
- persp = RV3D_ORTHO;
- }
- }
-
- if (ok_dist) {
- new_dist = ED_view3d_radius_to_dist(v3d, ar, CTX_data_depsgraph(C), persp, true, (size / 2) * VIEW3D_MARGIN);
- if (rv3d->is_persp) {
- /* don't zoom closer than the near clipping plane */
- new_dist = max_ff(new_dist, v3d->clip_start * 1.5f);
- }
- }
- }
-
- mid_v3_v3v3(new_ofs, min, max);
- negate_v3(new_ofs);
-
- if (rv3d->persp == RV3D_CAMOB && !ED_view3d_camera_lock_check(v3d, rv3d)) {
- rv3d->persp = RV3D_PERSP;
- ED_view3d_smooth_view(
- C, v3d, ar, smooth_viewtx,
- &(const V3D_SmoothParams) {
- .camera_old = v3d->camera, .ofs = new_ofs,
- .dist = ok_dist ? &new_dist : NULL,
- });
- }
- else {
- ED_view3d_smooth_view(
- C, v3d, ar, smooth_viewtx,
- &(const V3D_SmoothParams) { .ofs = new_ofs, .dist = ok_dist ? &new_dist : NULL, });
- }
-
- /* smooth view does viewlock RV3D_BOXVIEW copy */
+static bool view3d_object_skip_minmax(const View3D *v3d,
+ const RegionView3D *rv3d,
+ const Object *ob,
+ const bool skip_camera,
+ bool *r_only_center)
+{
+ BLI_assert(ob->id.orig_id == NULL);
+ *r_only_center = false;
+
+ if (skip_camera && (ob == v3d->camera)) {
+ return true;
+ }
+
+ if ((ob->type == OB_EMPTY) && (ob->empty_drawtype == OB_EMPTY_IMAGE) &&
+ !BKE_object_empty_image_frame_is_visible_in_view3d(ob, rv3d)) {
+ *r_only_center = true;
+ return false;
+ }
+
+ return false;
+}
+
+static void view3d_from_minmax(bContext *C,
+ View3D *v3d,
+ ARegion *ar,
+ const float min[3],
+ const float max[3],
+ bool ok_dist,
+ const int smooth_viewtx)
+{
+ RegionView3D *rv3d = ar->regiondata;
+ float afm[3];
+ float size;
+
+ ED_view3d_smooth_view_force_finish(C, v3d, ar);
+
+ /* SMOOTHVIEW */
+ float new_ofs[3];
+ float new_dist;
+
+ sub_v3_v3v3(afm, max, min);
+ size = max_fff(afm[0], afm[1], afm[2]);
+
+ if (ok_dist) {
+ char persp;
+
+ if (rv3d->is_persp) {
+ if (rv3d->persp == RV3D_CAMOB && ED_view3d_camera_lock_check(v3d, rv3d)) {
+ persp = RV3D_CAMOB;
+ }
+ else {
+ persp = RV3D_PERSP;
+ }
+ }
+ else { /* ortho */
+ if (size < 0.0001f) {
+ /* bounding box was a single point so do not zoom */
+ ok_dist = false;
+ }
+ else {
+ /* adjust zoom so it looks nicer */
+ persp = RV3D_ORTHO;
+ }
+ }
+
+ if (ok_dist) {
+ new_dist = ED_view3d_radius_to_dist(
+ v3d, ar, CTX_data_depsgraph(C), persp, true, (size / 2) * VIEW3D_MARGIN);
+ if (rv3d->is_persp) {
+ /* don't zoom closer than the near clipping plane */
+ new_dist = max_ff(new_dist, v3d->clip_start * 1.5f);
+ }
+ }
+ }
+
+ mid_v3_v3v3(new_ofs, min, max);
+ negate_v3(new_ofs);
+
+ if (rv3d->persp == RV3D_CAMOB && !ED_view3d_camera_lock_check(v3d, rv3d)) {
+ rv3d->persp = RV3D_PERSP;
+ ED_view3d_smooth_view(C,
+ v3d,
+ ar,
+ smooth_viewtx,
+ &(const V3D_SmoothParams){
+ .camera_old = v3d->camera,
+ .ofs = new_ofs,
+ .dist = ok_dist ? &new_dist : NULL,
+ });
+ }
+ else {
+ ED_view3d_smooth_view(C,
+ v3d,
+ ar,
+ smooth_viewtx,
+ &(const V3D_SmoothParams){
+ .ofs = new_ofs,
+ .dist = ok_dist ? &new_dist : NULL,
+ });
+ }
+
+ /* smooth view does viewlock RV3D_BOXVIEW copy */
}
/**
* Same as #view3d_from_minmax but for all regions (except cameras).
*/
-static void view3d_from_minmax_multi(
- bContext *C, View3D *v3d,
- const float min[3], const float max[3],
- const bool ok_dist, const int smooth_viewtx)
-{
- ScrArea *sa = CTX_wm_area(C);
- ARegion *ar;
- for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->regiontype == RGN_TYPE_WINDOW) {
- RegionView3D *rv3d = ar->regiondata;
- /* when using all regions, don't jump out of camera view,
- * but _do_ allow locked cameras to be moved */
- if ((rv3d->persp != RV3D_CAMOB) || ED_view3d_camera_lock_check(v3d, rv3d)) {
- view3d_from_minmax(C, v3d, ar, min, max, ok_dist, smooth_viewtx);
- }
- }
- }
+static void view3d_from_minmax_multi(bContext *C,
+ View3D *v3d,
+ const float min[3],
+ const float max[3],
+ const bool ok_dist,
+ const int smooth_viewtx)
+{
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar;
+ for (ar = sa->regionbase.first; ar; ar = ar->next) {
+ if (ar->regiontype == RGN_TYPE_WINDOW) {
+ RegionView3D *rv3d = ar->regiondata;
+ /* when using all regions, don't jump out of camera view,
+ * but _do_ allow locked cameras to be moved */
+ if ((rv3d->persp != RV3D_CAMOB) || ED_view3d_camera_lock_check(v3d, rv3d)) {
+ view3d_from_minmax(C, v3d, ar, min, max, ok_dist, smooth_viewtx);
+ }
+ }
+ }
}
static int view3d_all_exec(bContext *C, wmOperator *op)
{
- ARegion *ar = CTX_wm_region(C);
- View3D *v3d = CTX_wm_view3d(C);
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
- Scene *scene = CTX_data_scene(C);
- const Depsgraph *depsgraph = CTX_data_depsgraph(C);
- ViewLayer *view_layer_eval = DEG_get_evaluated_view_layer(depsgraph);
- Base *base_eval;
- const bool use_all_regions = RNA_boolean_get(op->ptr, "use_all_regions");
- const bool skip_camera = (ED_view3d_camera_lock_check(v3d, ar->regiondata) ||
- /* any one of the regions may be locked */
- (use_all_regions && v3d->flag2 & V3D_LOCK_CAMERA));
- const bool center = RNA_boolean_get(op->ptr, "center");
- const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
-
- float min[3], max[3];
- bool changed = false;
-
- if (center) {
- /* in 2.4x this also move the cursor to (0, 0, 0) (with shift+c). */
- View3DCursor *cursor = &scene->cursor;
- zero_v3(min);
- zero_v3(max);
- zero_v3(cursor->location);
- float mat3[3][3];
- unit_m3(mat3);
- BKE_scene_cursor_mat3_to_rot(cursor, mat3, false);
- }
- else {
- INIT_MINMAX(min, max);
- }
-
- for (base_eval = view_layer_eval->object_bases.first; base_eval; base_eval = base_eval->next) {
- if (BASE_VISIBLE(v3d, base_eval)) {
- bool only_center = false;
- Object *ob = DEG_get_original_object(base_eval->object);
- if (view3d_object_skip_minmax(v3d, rv3d, ob, skip_camera, &only_center)) {
- continue;
- }
-
- if (only_center) {
- minmax_v3v3_v3(min, max, base_eval->object->obmat[3]);
- }
- else {
- BKE_object_minmax(base_eval->object, min, max, false);
- }
- changed = true;
- }
- }
-
- if (center) {
- DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
- }
-
- if (!changed) {
- ED_region_tag_redraw(ar);
- /* TODO - should this be cancel?
- * I think no, because we always move the cursor, with or without
- * object, but in this case there is no change in the scene,
- * only the cursor so I choice a ED_region_tag like
- * view3d_smooth_view do for the center_cursor.
- * See bug #22640
- */
- return OPERATOR_FINISHED;
- }
-
- if (use_all_regions) {
- view3d_from_minmax_multi(C, v3d, min, max, true, smooth_viewtx);
- }
- else {
- view3d_from_minmax(C, v3d, ar, min, max, true, smooth_viewtx);
- }
-
- return OPERATOR_FINISHED;
+ ARegion *ar = CTX_wm_region(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ Scene *scene = CTX_data_scene(C);
+ const Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ ViewLayer *view_layer_eval = DEG_get_evaluated_view_layer(depsgraph);
+ Base *base_eval;
+ const bool use_all_regions = RNA_boolean_get(op->ptr, "use_all_regions");
+ const bool skip_camera = (ED_view3d_camera_lock_check(v3d, ar->regiondata) ||
+ /* any one of the regions may be locked */
+ (use_all_regions && v3d->flag2 & V3D_LOCK_CAMERA));
+ const bool center = RNA_boolean_get(op->ptr, "center");
+ const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
+
+ float min[3], max[3];
+ bool changed = false;
+
+ if (center) {
+ /* in 2.4x this also move the cursor to (0, 0, 0) (with shift+c). */
+ View3DCursor *cursor = &scene->cursor;
+ zero_v3(min);
+ zero_v3(max);
+ zero_v3(cursor->location);
+ float mat3[3][3];
+ unit_m3(mat3);
+ BKE_scene_cursor_mat3_to_rot(cursor, mat3, false);
+ }
+ else {
+ INIT_MINMAX(min, max);
+ }
+
+ for (base_eval = view_layer_eval->object_bases.first; base_eval; base_eval = base_eval->next) {
+ if (BASE_VISIBLE(v3d, base_eval)) {
+ bool only_center = false;
+ Object *ob = DEG_get_original_object(base_eval->object);
+ if (view3d_object_skip_minmax(v3d, rv3d, ob, skip_camera, &only_center)) {
+ continue;
+ }
+
+ if (only_center) {
+ minmax_v3v3_v3(min, max, base_eval->object->obmat[3]);
+ }
+ else {
+ BKE_object_minmax(base_eval->object, min, max, false);
+ }
+ changed = true;
+ }
+ }
+
+ if (center) {
+ DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
+ }
+
+ if (!changed) {
+ ED_region_tag_redraw(ar);
+ /* TODO - should this be cancel?
+ * I think no, because we always move the cursor, with or without
+ * object, but in this case there is no change in the scene,
+ * only the cursor so I choice a ED_region_tag like
+ * view3d_smooth_view do for the center_cursor.
+ * See bug #22640
+ */
+ return OPERATOR_FINISHED;
+ }
+
+ if (use_all_regions) {
+ view3d_from_minmax_multi(C, v3d, min, max, true, smooth_viewtx);
+ }
+ else {
+ view3d_from_minmax(C, v3d, ar, min, max, true, smooth_viewtx);
+ }
+
+ return OPERATOR_FINISHED;
}
-
void VIEW3D_OT_view_all(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "View All";
- ot->description = "View all objects in scene";
- ot->idname = "VIEW3D_OT_view_all";
+ /* identifiers */
+ ot->name = "View All";
+ ot->description = "View all objects in scene";
+ ot->idname = "VIEW3D_OT_view_all";
- /* api callbacks */
- ot->exec = view3d_all_exec;
- ot->poll = ED_operator_region_view3d_active;
+ /* api callbacks */
+ ot->exec = view3d_all_exec;
+ ot->poll = ED_operator_region_view3d_active;
- /* flags */
- ot->flag = 0;
+ /* flags */
+ ot->flag = 0;
- /* properties */
- view3d_operator_properties_common(ot, V3D_OP_PROP_USE_ALL_REGIONS);
- RNA_def_boolean(ot->srna, "center", 0, "Center", "");
+ /* properties */
+ view3d_operator_properties_common(ot, V3D_OP_PROP_USE_ALL_REGIONS);
+ RNA_def_boolean(ot->srna, "center", 0, "Center", "");
}
/** \} */
@@ -2874,151 +2919,150 @@ void VIEW3D_OT_view_all(wmOperatorType *ot)
/* like a localview without local!, was centerview() in 2.4x */
static int viewselected_exec(bContext *C, wmOperator *op)
{
- ARegion *ar = CTX_wm_region(C);
- View3D *v3d = CTX_wm_view3d(C);
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
- Scene *scene = CTX_data_scene(C);
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- ViewLayer *view_layer_eval = DEG_get_evaluated_view_layer(depsgraph);
- bGPdata *gpd = CTX_data_gpencil_data(C);
- const bool is_gp_edit = GPENCIL_ANY_MODE(gpd);
- const bool is_face_map = ((is_gp_edit == false) && ar->gizmo_map &&
- WM_gizmomap_is_any_selected(ar->gizmo_map));
- Object *ob_eval = OBACT(view_layer_eval);
- Object *obedit = CTX_data_edit_object(C);
- float min[3], max[3];
- bool ok = false, ok_dist = true;
- const bool use_all_regions = RNA_boolean_get(op->ptr, "use_all_regions");
- const bool skip_camera = (ED_view3d_camera_lock_check(v3d, ar->regiondata) ||
- /* any one of the regions may be locked */
- (use_all_regions && v3d->flag2 & V3D_LOCK_CAMERA));
- const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
-
- INIT_MINMAX(min, max);
- if (is_face_map) {
- ob_eval = NULL;
- }
-
- if (ob_eval && (ob_eval->mode & OB_MODE_WEIGHT_PAINT)) {
- /* hard-coded exception, we look for the one selected armature */
- /* this is weak code this way, we should make a generic
- * active/selection callback interface once... */
- Base *base_eval;
- for (base_eval = view_layer_eval->object_bases.first; base_eval; base_eval = base_eval->next) {
- if (BASE_SELECTED_EDITABLE(v3d, base_eval)) {
- if (base_eval->object->type == OB_ARMATURE) {
- if (base_eval->object->mode & OB_MODE_POSE) {
- break;
- }
- }
- }
- }
- if (base_eval) {
- ob_eval = base_eval->object;
- }
- }
-
- if (is_gp_edit) {
- CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
- {
- /* we're only interested in selected points here... */
- if ((gps->flag & GP_STROKE_SELECT) && (gps->flag & GP_STROKE_3DSPACE)) {
- ok |= BKE_gpencil_stroke_minmax(gps, true, min, max);
- }
- }
- CTX_DATA_END;
-
- if ((ob_eval) && (ok)) {
- mul_m4_v3(ob_eval->obmat, min);
- mul_m4_v3(ob_eval->obmat, max);
- }
- }
- else if (is_face_map) {
- ok = WM_gizmomap_minmax(ar->gizmo_map, true, true, min, max);
- }
- else if (obedit) {
- /* only selected */
- FOREACH_OBJECT_IN_MODE_BEGIN (view_layer_eval, v3d, obedit->type, obedit->mode, ob_eval_iter) {
- ok |= ED_view3d_minmax_verts(ob_eval_iter, min, max);
- }
- FOREACH_OBJECT_IN_MODE_END;
- }
- else if (ob_eval && (ob_eval->mode & OB_MODE_POSE)) {
- FOREACH_OBJECT_IN_MODE_BEGIN (view_layer_eval, v3d, ob_eval->type, ob_eval->mode, ob_eval_iter) {
- ok |= BKE_pose_minmax(ob_eval_iter, min, max, true, true);
- }
- FOREACH_OBJECT_IN_MODE_END;
- }
- else if (BKE_paint_select_face_test(ob_eval)) {
- ok = paintface_minmax(ob_eval, min, max);
- }
- else if (ob_eval && (ob_eval->mode & OB_MODE_PARTICLE_EDIT)) {
- ok = PE_minmax(scene, view_layer_eval, min, max);
- }
- else if (ob_eval &&
- (ob_eval->mode & (OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)))
- {
- BKE_paint_stroke_get_average(scene, ob_eval, min);
- copy_v3_v3(max, min);
- ok = true;
- ok_dist = 0; /* don't zoom */
- }
- else {
- Base *base_eval;
- for (base_eval = FIRSTBASE(view_layer_eval); base_eval; base_eval = base_eval->next) {
- if (BASE_SELECTED(v3d, base_eval)) {
- bool only_center = false;
- Object *ob = DEG_get_original_object(base_eval->object);
- if (view3d_object_skip_minmax(v3d, rv3d, ob, skip_camera, &only_center)) {
- continue;
- }
-
- /* account for duplis */
- if (BKE_object_minmax_dupli(depsgraph, scene, base_eval->object, min, max, false) == 0) {
- /* use if duplis not found */
- if (only_center) {
- minmax_v3v3_v3(min, max, base_eval->object->obmat[3]);
- }
- else {
- BKE_object_minmax(base_eval->object, min, max, false);
- }
- }
-
- ok = 1;
- }
- }
- }
-
- if (ok == 0) {
- return OPERATOR_FINISHED;
- }
-
- if (use_all_regions) {
- view3d_from_minmax_multi(C, v3d, min, max, ok_dist, smooth_viewtx);
- }
- else {
- view3d_from_minmax(C, v3d, ar, min, max, ok_dist, smooth_viewtx);
- }
-
- return OPERATOR_FINISHED;
+ ARegion *ar = CTX_wm_region(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ Scene *scene = CTX_data_scene(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ ViewLayer *view_layer_eval = DEG_get_evaluated_view_layer(depsgraph);
+ bGPdata *gpd = CTX_data_gpencil_data(C);
+ const bool is_gp_edit = GPENCIL_ANY_MODE(gpd);
+ const bool is_face_map = ((is_gp_edit == false) && ar->gizmo_map &&
+ WM_gizmomap_is_any_selected(ar->gizmo_map));
+ Object *ob_eval = OBACT(view_layer_eval);
+ Object *obedit = CTX_data_edit_object(C);
+ float min[3], max[3];
+ bool ok = false, ok_dist = true;
+ const bool use_all_regions = RNA_boolean_get(op->ptr, "use_all_regions");
+ const bool skip_camera = (ED_view3d_camera_lock_check(v3d, ar->regiondata) ||
+ /* any one of the regions may be locked */
+ (use_all_regions && v3d->flag2 & V3D_LOCK_CAMERA));
+ const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
+
+ INIT_MINMAX(min, max);
+ if (is_face_map) {
+ ob_eval = NULL;
+ }
+
+ if (ob_eval && (ob_eval->mode & OB_MODE_WEIGHT_PAINT)) {
+ /* hard-coded exception, we look for the one selected armature */
+ /* this is weak code this way, we should make a generic
+ * active/selection callback interface once... */
+ Base *base_eval;
+ for (base_eval = view_layer_eval->object_bases.first; base_eval; base_eval = base_eval->next) {
+ if (BASE_SELECTED_EDITABLE(v3d, base_eval)) {
+ if (base_eval->object->type == OB_ARMATURE) {
+ if (base_eval->object->mode & OB_MODE_POSE) {
+ break;
+ }
+ }
+ }
+ }
+ if (base_eval) {
+ ob_eval = base_eval->object;
+ }
+ }
+
+ if (is_gp_edit) {
+ CTX_DATA_BEGIN (C, bGPDstroke *, gps, editable_gpencil_strokes) {
+ /* we're only interested in selected points here... */
+ if ((gps->flag & GP_STROKE_SELECT) && (gps->flag & GP_STROKE_3DSPACE)) {
+ ok |= BKE_gpencil_stroke_minmax(gps, true, min, max);
+ }
+ }
+ CTX_DATA_END;
+
+ if ((ob_eval) && (ok)) {
+ mul_m4_v3(ob_eval->obmat, min);
+ mul_m4_v3(ob_eval->obmat, max);
+ }
+ }
+ else if (is_face_map) {
+ ok = WM_gizmomap_minmax(ar->gizmo_map, true, true, min, max);
+ }
+ else if (obedit) {
+ /* only selected */
+ FOREACH_OBJECT_IN_MODE_BEGIN (view_layer_eval, v3d, obedit->type, obedit->mode, ob_eval_iter) {
+ ok |= ED_view3d_minmax_verts(ob_eval_iter, min, max);
+ }
+ FOREACH_OBJECT_IN_MODE_END;
+ }
+ else if (ob_eval && (ob_eval->mode & OB_MODE_POSE)) {
+ FOREACH_OBJECT_IN_MODE_BEGIN (
+ view_layer_eval, v3d, ob_eval->type, ob_eval->mode, ob_eval_iter) {
+ ok |= BKE_pose_minmax(ob_eval_iter, min, max, true, true);
+ }
+ FOREACH_OBJECT_IN_MODE_END;
+ }
+ else if (BKE_paint_select_face_test(ob_eval)) {
+ ok = paintface_minmax(ob_eval, min, max);
+ }
+ else if (ob_eval && (ob_eval->mode & OB_MODE_PARTICLE_EDIT)) {
+ ok = PE_minmax(scene, view_layer_eval, min, max);
+ }
+ else if (ob_eval && (ob_eval->mode & (OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT |
+ OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))) {
+ BKE_paint_stroke_get_average(scene, ob_eval, min);
+ copy_v3_v3(max, min);
+ ok = true;
+ ok_dist = 0; /* don't zoom */
+ }
+ else {
+ Base *base_eval;
+ for (base_eval = FIRSTBASE(view_layer_eval); base_eval; base_eval = base_eval->next) {
+ if (BASE_SELECTED(v3d, base_eval)) {
+ bool only_center = false;
+ Object *ob = DEG_get_original_object(base_eval->object);
+ if (view3d_object_skip_minmax(v3d, rv3d, ob, skip_camera, &only_center)) {
+ continue;
+ }
+
+ /* account for duplis */
+ if (BKE_object_minmax_dupli(depsgraph, scene, base_eval->object, min, max, false) == 0) {
+ /* use if duplis not found */
+ if (only_center) {
+ minmax_v3v3_v3(min, max, base_eval->object->obmat[3]);
+ }
+ else {
+ BKE_object_minmax(base_eval->object, min, max, false);
+ }
+ }
+
+ ok = 1;
+ }
+ }
+ }
+
+ if (ok == 0) {
+ return OPERATOR_FINISHED;
+ }
+
+ if (use_all_regions) {
+ view3d_from_minmax_multi(C, v3d, min, max, ok_dist, smooth_viewtx);
+ }
+ else {
+ view3d_from_minmax(C, v3d, ar, min, max, ok_dist, smooth_viewtx);
+ }
+
+ return OPERATOR_FINISHED;
}
void VIEW3D_OT_view_selected(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "View Selected";
- ot->description = "Move the view to the selection center";
- ot->idname = "VIEW3D_OT_view_selected";
+ /* identifiers */
+ ot->name = "View Selected";
+ ot->description = "Move the view to the selection center";
+ ot->idname = "VIEW3D_OT_view_selected";
- /* api callbacks */
- ot->exec = viewselected_exec;
- ot->poll = ED_operator_region_view3d_active;
+ /* api callbacks */
+ ot->exec = viewselected_exec;
+ ot->poll = ED_operator_region_view3d_active;
- /* flags */
- ot->flag = 0;
+ /* flags */
+ ot->flag = 0;
- /* properties */
- view3d_operator_properties_common(ot, V3D_OP_PROP_USE_ALL_REGIONS);
+ /* properties */
+ view3d_operator_properties_common(ot, V3D_OP_PROP_USE_ALL_REGIONS);
}
/** \} */
@@ -3029,34 +3073,34 @@ void VIEW3D_OT_view_selected(wmOperatorType *ot)
static int view_lock_clear_exec(bContext *C, wmOperator *UNUSED(op))
{
- View3D *v3d = CTX_wm_view3d(C);
+ View3D *v3d = CTX_wm_view3d(C);
- if (v3d) {
- ED_view3d_lock_clear(v3d);
+ if (v3d) {
+ ED_view3d_lock_clear(v3d);
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
- return OPERATOR_FINISHED;
- }
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
void VIEW3D_OT_view_lock_clear(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "View Lock Clear";
- ot->description = "Clear all view locking";
- ot->idname = "VIEW3D_OT_view_lock_clear";
+ /* identifiers */
+ ot->name = "View Lock Clear";
+ ot->description = "Clear all view locking";
+ ot->idname = "VIEW3D_OT_view_lock_clear";
- /* api callbacks */
- ot->exec = view_lock_clear_exec;
- ot->poll = ED_operator_region_view3d_active;
+ /* api callbacks */
+ ot->exec = view_lock_clear_exec;
+ ot->poll = ED_operator_region_view3d_active;
- /* flags */
- ot->flag = 0;
+ /* flags */
+ ot->flag = 0;
}
/** \} */
@@ -3067,53 +3111,53 @@ void VIEW3D_OT_view_lock_clear(wmOperatorType *ot)
static int view_lock_to_active_exec(bContext *C, wmOperator *UNUSED(op))
{
- View3D *v3d = CTX_wm_view3d(C);
- Object *obact = CTX_data_active_object(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ Object *obact = CTX_data_active_object(C);
- if (v3d) {
- ED_view3d_lock_clear(v3d);
+ if (v3d) {
+ ED_view3d_lock_clear(v3d);
- v3d->ob_centre = obact; /* can be NULL */
+ v3d->ob_centre = obact; /* can be NULL */
- if (obact && obact->type == OB_ARMATURE) {
- if (obact->mode & OB_MODE_POSE) {
- Object *obact_eval = DEG_get_evaluated_object(CTX_data_depsgraph(C), obact);
- bPoseChannel *pcham_act = BKE_pose_channel_active(obact_eval);
- if (pcham_act) {
- BLI_strncpy(v3d->ob_centre_bone, pcham_act->name, sizeof(v3d->ob_centre_bone));
- }
- }
- else {
- EditBone *ebone_act = ((bArmature *)obact->data)->act_edbone;
- if (ebone_act) {
- BLI_strncpy(v3d->ob_centre_bone, ebone_act->name, sizeof(v3d->ob_centre_bone));
- }
- }
- }
+ if (obact && obact->type == OB_ARMATURE) {
+ if (obact->mode & OB_MODE_POSE) {
+ Object *obact_eval = DEG_get_evaluated_object(CTX_data_depsgraph(C), obact);
+ bPoseChannel *pcham_act = BKE_pose_channel_active(obact_eval);
+ if (pcham_act) {
+ BLI_strncpy(v3d->ob_centre_bone, pcham_act->name, sizeof(v3d->ob_centre_bone));
+ }
+ }
+ else {
+ EditBone *ebone_act = ((bArmature *)obact->data)->act_edbone;
+ if (ebone_act) {
+ BLI_strncpy(v3d->ob_centre_bone, ebone_act->name, sizeof(v3d->ob_centre_bone));
+ }
+ }
+ }
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
- return OPERATOR_FINISHED;
- }
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
void VIEW3D_OT_view_lock_to_active(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "View Lock to Active";
- ot->description = "Lock the view to the active object/bone";
- ot->idname = "VIEW3D_OT_view_lock_to_active";
+ /* identifiers */
+ ot->name = "View Lock to Active";
+ ot->description = "Lock the view to the active object/bone";
+ ot->idname = "VIEW3D_OT_view_lock_to_active";
- /* api callbacks */
- ot->exec = view_lock_to_active_exec;
- ot->poll = ED_operator_region_view3d_active;
+ /* api callbacks */
+ ot->exec = view_lock_to_active_exec;
+ ot->poll = ED_operator_region_view3d_active;
- /* flags */
- ot->flag = 0;
+ /* flags */
+ ot->flag = 0;
}
/** \} */
@@ -3124,42 +3168,40 @@ void VIEW3D_OT_view_lock_to_active(wmOperatorType *ot)
static int viewcenter_cursor_exec(bContext *C, wmOperator *op)
{
- View3D *v3d = CTX_wm_view3d(C);
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
- Scene *scene = CTX_data_scene(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ Scene *scene = CTX_data_scene(C);
- if (rv3d) {
- ARegion *ar = CTX_wm_region(C);
- const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
+ if (rv3d) {
+ ARegion *ar = CTX_wm_region(C);
+ const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
- ED_view3d_smooth_view_force_finish(C, v3d, ar);
+ ED_view3d_smooth_view_force_finish(C, v3d, ar);
- /* non camera center */
- float new_ofs[3];
- negate_v3_v3(new_ofs, scene->cursor.location);
- ED_view3d_smooth_view(
- C, v3d, ar, smooth_viewtx,
- &(const V3D_SmoothParams) {.ofs = new_ofs});
+ /* non camera center */
+ float new_ofs[3];
+ negate_v3_v3(new_ofs, scene->cursor.location);
+ ED_view3d_smooth_view(C, v3d, ar, smooth_viewtx, &(const V3D_SmoothParams){.ofs = new_ofs});
- /* smooth view does viewlock RV3D_BOXVIEW copy */
- }
+ /* smooth view does viewlock RV3D_BOXVIEW copy */
+ }
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void VIEW3D_OT_view_center_cursor(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Center View to Cursor";
- ot->description = "Center the view so that the cursor is in the middle of the view";
- ot->idname = "VIEW3D_OT_view_center_cursor";
+ /* identifiers */
+ ot->name = "Center View to Cursor";
+ ot->description = "Center the view so that the cursor is in the middle of the view";
+ ot->idname = "VIEW3D_OT_view_center_cursor";
- /* api callbacks */
- ot->exec = viewcenter_cursor_exec;
- ot->poll = ED_operator_view3d_active;
+ /* api callbacks */
+ ot->exec = viewcenter_cursor_exec;
+ ot->poll = ED_operator_view3d_active;
- /* flags */
- ot->flag = 0;
+ /* flags */
+ ot->flag = 0;
}
/** \} */
@@ -3170,49 +3212,47 @@ void VIEW3D_OT_view_center_cursor(wmOperatorType *ot)
static int viewcenter_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- View3D *v3d = CTX_wm_view3d(C);
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
- ARegion *ar = CTX_wm_region(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ ARegion *ar = CTX_wm_region(C);
- if (rv3d) {
- struct Depsgraph *depsgraph = CTX_data_depsgraph(C);
- float new_ofs[3];
- const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
+ if (rv3d) {
+ struct Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ float new_ofs[3];
+ const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
- ED_view3d_smooth_view_force_finish(C, v3d, ar);
+ ED_view3d_smooth_view_force_finish(C, v3d, ar);
- view3d_operator_needs_opengl(C);
+ view3d_operator_needs_opengl(C);
- if (ED_view3d_autodist(depsgraph, ar, v3d, event->mval, new_ofs, false, NULL)) {
- /* pass */
- }
- else {
- /* fallback to simple pan */
- negate_v3_v3(new_ofs, rv3d->ofs);
- ED_view3d_win_to_3d_int(v3d, ar, new_ofs, event->mval, new_ofs);
- }
- negate_v3(new_ofs);
- ED_view3d_smooth_view(
- C, v3d, ar, smooth_viewtx,
- &(const V3D_SmoothParams) {.ofs = new_ofs});
- }
+ if (ED_view3d_autodist(depsgraph, ar, v3d, event->mval, new_ofs, false, NULL)) {
+ /* pass */
+ }
+ else {
+ /* fallback to simple pan */
+ negate_v3_v3(new_ofs, rv3d->ofs);
+ ED_view3d_win_to_3d_int(v3d, ar, new_ofs, event->mval, new_ofs);
+ }
+ negate_v3(new_ofs);
+ ED_view3d_smooth_view(C, v3d, ar, smooth_viewtx, &(const V3D_SmoothParams){.ofs = new_ofs});
+ }
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void VIEW3D_OT_view_center_pick(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Center View to Mouse";
- ot->description = "Center the view to the Z-depth position under the mouse cursor";
- ot->idname = "VIEW3D_OT_view_center_pick";
+ /* identifiers */
+ ot->name = "Center View to Mouse";
+ ot->description = "Center the view to the Z-depth position under the mouse cursor";
+ ot->idname = "VIEW3D_OT_view_center_pick";
- /* api callbacks */
- ot->invoke = viewcenter_pick_invoke;
- ot->poll = ED_operator_view3d_active;
+ /* api callbacks */
+ ot->invoke = viewcenter_pick_invoke;
+ ot->poll = ED_operator_view3d_active;
- /* flags */
- ot->flag = 0;
+ /* flags */
+ ot->flag = 0;
}
/** \} */
@@ -3223,48 +3263,48 @@ void VIEW3D_OT_view_center_pick(wmOperatorType *ot)
static int view3d_center_camera_exec(bContext *C, wmOperator *UNUSED(op))
{
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- Scene *scene = CTX_data_scene(C);
- float xfac, yfac;
- float size[2];
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ Scene *scene = CTX_data_scene(C);
+ float xfac, yfac;
+ float size[2];
- View3D *v3d;
- ARegion *ar;
- RegionView3D *rv3d;
+ View3D *v3d;
+ ARegion *ar;
+ RegionView3D *rv3d;
- /* no NULL check is needed, poll checks */
- ED_view3d_context_user_region(C, &v3d, &ar);
- rv3d = ar->regiondata;
+ /* no NULL check is needed, poll checks */
+ ED_view3d_context_user_region(C, &v3d, &ar);
+ rv3d = ar->regiondata;
- rv3d->camdx = rv3d->camdy = 0.0f;
+ rv3d->camdx = rv3d->camdy = 0.0f;
- ED_view3d_calc_camera_border_size(scene, depsgraph, ar, v3d, rv3d, size);
+ ED_view3d_calc_camera_border_size(scene, depsgraph, ar, v3d, rv3d, size);
- /* 4px is just a little room from the edge of the area */
- xfac = (float)ar->winx / (float)(size[0] + 4);
- yfac = (float)ar->winy / (float)(size[1] + 4);
+ /* 4px is just a little room from the edge of the area */
+ xfac = (float)ar->winx / (float)(size[0] + 4);
+ yfac = (float)ar->winy / (float)(size[1] + 4);
- rv3d->camzoom = BKE_screen_view3d_zoom_from_fac(min_ff(xfac, yfac));
- CLAMP(rv3d->camzoom, RV3D_CAMZOOM_MIN, RV3D_CAMZOOM_MAX);
+ rv3d->camzoom = BKE_screen_view3d_zoom_from_fac(min_ff(xfac, yfac));
+ CLAMP(rv3d->camzoom, RV3D_CAMZOOM_MIN, RV3D_CAMZOOM_MAX);
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void VIEW3D_OT_view_center_camera(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "View Camera Center";
- ot->description = "Center the camera view";
- ot->idname = "VIEW3D_OT_view_center_camera";
+ /* identifiers */
+ ot->name = "View Camera Center";
+ ot->description = "Center the camera view";
+ ot->idname = "VIEW3D_OT_view_center_camera";
- /* api callbacks */
- ot->exec = view3d_center_camera_exec;
- ot->poll = view3d_camera_user_poll;
+ /* api callbacks */
+ ot->exec = view3d_center_camera_exec;
+ ot->poll = view3d_camera_user_poll;
- /* flags */
- ot->flag = 0;
+ /* flags */
+ ot->flag = 0;
}
/** \} */
@@ -3275,28 +3315,28 @@ void VIEW3D_OT_view_center_camera(wmOperatorType *ot)
static int view3d_center_lock_exec(bContext *C, wmOperator *UNUSED(op))
{
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
- zero_v2(rv3d->ofs_lock);
+ zero_v2(rv3d->ofs_lock);
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C));
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C));
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void VIEW3D_OT_view_center_lock(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "View Lock Center";
- ot->description = "Center the view lock offset";
- ot->idname = "VIEW3D_OT_view_center_lock";
+ /* identifiers */
+ ot->name = "View Lock Center";
+ ot->description = "Center the view lock offset";
+ ot->idname = "VIEW3D_OT_view_center_lock";
- /* api callbacks */
- ot->exec = view3d_center_lock_exec;
- ot->poll = view3d_lock_poll;
+ /* api callbacks */
+ ot->exec = view3d_center_lock_exec;
+ ot->poll = view3d_lock_poll;
- /* flags */
- ot->flag = 0;
+ /* flags */
+ ot->flag = 0;
}
/** \} */
@@ -3307,97 +3347,97 @@ void VIEW3D_OT_view_center_lock(wmOperatorType *ot)
static int render_border_exec(bContext *C, wmOperator *op)
{
- View3D *v3d = CTX_wm_view3d(C);
- ARegion *ar = CTX_wm_region(C);
- RegionView3D *rv3d = ED_view3d_context_rv3d(C);
-
- Scene *scene = CTX_data_scene(C);
-
- rcti rect;
- rctf vb, border;
-
- /* get box select values using rna */
- WM_operator_properties_border_to_rcti(op, &rect);
-
- /* calculate range */
-
- if (rv3d->persp == RV3D_CAMOB) {
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &vb, false);
- }
- else {
- vb.xmin = 0;
- vb.ymin = 0;
- vb.xmax = ar->winx;
- vb.ymax = ar->winy;
- }
-
- border.xmin = ((float)rect.xmin - vb.xmin) / BLI_rctf_size_x(&vb);
- border.ymin = ((float)rect.ymin - vb.ymin) / BLI_rctf_size_y(&vb);
- border.xmax = ((float)rect.xmax - vb.xmin) / BLI_rctf_size_x(&vb);
- border.ymax = ((float)rect.ymax - vb.ymin) / BLI_rctf_size_y(&vb);
-
- /* actually set border */
- CLAMP(border.xmin, 0.0f, 1.0f);
- CLAMP(border.ymin, 0.0f, 1.0f);
- CLAMP(border.xmax, 0.0f, 1.0f);
- CLAMP(border.ymax, 0.0f, 1.0f);
-
- if (rv3d->persp == RV3D_CAMOB) {
- scene->r.border = border;
-
- WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, NULL);
- }
- else {
- v3d->render_border = border;
-
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
- }
-
- /* drawing a border outside the camera view switches off border rendering */
- if ((border.xmin == border.xmax || border.ymin == border.ymax)) {
- if (rv3d->persp == RV3D_CAMOB) {
- scene->r.mode &= ~R_BORDER;
- }
- else {
- v3d->flag2 &= ~V3D_RENDER_BORDER;
- }
- }
- else {
- if (rv3d->persp == RV3D_CAMOB) {
- scene->r.mode |= R_BORDER;
- }
- else {
- v3d->flag2 |= V3D_RENDER_BORDER;
- }
- }
-
- if (rv3d->persp == RV3D_CAMOB) {
- DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
- }
- return OPERATOR_FINISHED;
+ View3D *v3d = CTX_wm_view3d(C);
+ ARegion *ar = CTX_wm_region(C);
+ RegionView3D *rv3d = ED_view3d_context_rv3d(C);
+
+ Scene *scene = CTX_data_scene(C);
+
+ rcti rect;
+ rctf vb, border;
+
+ /* get box select values using rna */
+ WM_operator_properties_border_to_rcti(op, &rect);
+
+ /* calculate range */
+
+ if (rv3d->persp == RV3D_CAMOB) {
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &vb, false);
+ }
+ else {
+ vb.xmin = 0;
+ vb.ymin = 0;
+ vb.xmax = ar->winx;
+ vb.ymax = ar->winy;
+ }
+
+ border.xmin = ((float)rect.xmin - vb.xmin) / BLI_rctf_size_x(&vb);
+ border.ymin = ((float)rect.ymin - vb.ymin) / BLI_rctf_size_y(&vb);
+ border.xmax = ((float)rect.xmax - vb.xmin) / BLI_rctf_size_x(&vb);
+ border.ymax = ((float)rect.ymax - vb.ymin) / BLI_rctf_size_y(&vb);
+
+ /* actually set border */
+ CLAMP(border.xmin, 0.0f, 1.0f);
+ CLAMP(border.ymin, 0.0f, 1.0f);
+ CLAMP(border.xmax, 0.0f, 1.0f);
+ CLAMP(border.ymax, 0.0f, 1.0f);
+
+ if (rv3d->persp == RV3D_CAMOB) {
+ scene->r.border = border;
+
+ WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+ }
+ else {
+ v3d->render_border = border;
+
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+ }
+
+ /* drawing a border outside the camera view switches off border rendering */
+ if ((border.xmin == border.xmax || border.ymin == border.ymax)) {
+ if (rv3d->persp == RV3D_CAMOB) {
+ scene->r.mode &= ~R_BORDER;
+ }
+ else {
+ v3d->flag2 &= ~V3D_RENDER_BORDER;
+ }
+ }
+ else {
+ if (rv3d->persp == RV3D_CAMOB) {
+ scene->r.mode |= R_BORDER;
+ }
+ else {
+ v3d->flag2 |= V3D_RENDER_BORDER;
+ }
+ }
+
+ if (rv3d->persp == RV3D_CAMOB) {
+ DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
+ }
+ return OPERATOR_FINISHED;
}
void VIEW3D_OT_render_border(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Set Render Region";
- ot->description = "Set the boundaries of the border render and enable border render";
- ot->idname = "VIEW3D_OT_render_border";
+ /* identifiers */
+ ot->name = "Set Render Region";
+ ot->description = "Set the boundaries of the border render and enable border render";
+ ot->idname = "VIEW3D_OT_render_border";
- /* api callbacks */
- ot->invoke = WM_gesture_box_invoke;
- ot->exec = render_border_exec;
- ot->modal = WM_gesture_box_modal;
- ot->cancel = WM_gesture_box_cancel;
+ /* api callbacks */
+ ot->invoke = WM_gesture_box_invoke;
+ ot->exec = render_border_exec;
+ ot->modal = WM_gesture_box_modal;
+ ot->cancel = WM_gesture_box_cancel;
- ot->poll = ED_operator_view3d_active;
+ ot->poll = ED_operator_view3d_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- WM_operator_properties_border(ot);
+ /* properties */
+ WM_operator_properties_border(ot);
}
/** \} */
@@ -3408,49 +3448,49 @@ void VIEW3D_OT_render_border(wmOperatorType *ot)
static int clear_render_border_exec(bContext *C, wmOperator *UNUSED(op))
{
- View3D *v3d = CTX_wm_view3d(C);
- RegionView3D *rv3d = ED_view3d_context_rv3d(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ RegionView3D *rv3d = ED_view3d_context_rv3d(C);
- Scene *scene = CTX_data_scene(C);
- rctf *border = NULL;
+ Scene *scene = CTX_data_scene(C);
+ rctf *border = NULL;
- if (rv3d->persp == RV3D_CAMOB) {
- scene->r.mode &= ~R_BORDER;
- border = &scene->r.border;
+ if (rv3d->persp == RV3D_CAMOB) {
+ scene->r.mode &= ~R_BORDER;
+ border = &scene->r.border;
- WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, NULL);
- }
- else {
- v3d->flag2 &= ~V3D_RENDER_BORDER;
- border = &v3d->render_border;
+ WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+ }
+ else {
+ v3d->flag2 &= ~V3D_RENDER_BORDER;
+ border = &v3d->render_border;
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
- }
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+ }
- border->xmin = 0.0f;
- border->ymin = 0.0f;
- border->xmax = 1.0f;
- border->ymax = 1.0f;
+ border->xmin = 0.0f;
+ border->ymin = 0.0f;
+ border->xmax = 1.0f;
+ border->ymax = 1.0f;
- if (rv3d->persp == RV3D_CAMOB) {
- DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
- }
- return OPERATOR_FINISHED;
+ if (rv3d->persp == RV3D_CAMOB) {
+ DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
+ }
+ return OPERATOR_FINISHED;
}
void VIEW3D_OT_clear_render_border(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Clear Render Region";
- ot->description = "Clear the boundaries of the border render and disable border render";
- ot->idname = "VIEW3D_OT_clear_render_border";
+ /* identifiers */
+ ot->name = "Clear Render Region";
+ ot->description = "Clear the boundaries of the border render and disable border render";
+ ot->idname = "VIEW3D_OT_clear_render_border";
- /* api callbacks */
- ot->exec = clear_render_border_exec;
- ot->poll = ED_operator_view3d_active;
+ /* api callbacks */
+ ot->exec = clear_render_border_exec;
+ ot->poll = ED_operator_view3d_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/** \} */
@@ -3461,161 +3501,165 @@ void VIEW3D_OT_clear_render_border(wmOperatorType *ot)
static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
{
- ARegion *ar = CTX_wm_region(C);
- View3D *v3d = CTX_wm_view3d(C);
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
- const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
-
- /* Zooms in on a border drawn by the user */
- rcti rect;
- float dvec[3], vb[2], xscale, yscale;
- float dist_range[2];
-
- /* SMOOTHVIEW */
- float new_dist;
- float new_ofs[3];
-
- /* ZBuffer depth vars */
- float depth_close = FLT_MAX;
- float cent[2], p[3];
-
- /* note; otherwise opengl won't work */
- view3d_operator_needs_opengl(C);
-
- /* get box select values using rna */
- WM_operator_properties_border_to_rcti(op, &rect);
-
- /* check if zooming in/out view */
- const bool zoom_in = !RNA_boolean_get(op->ptr, "zoom_out");
-
- ED_view3d_dist_range_get(v3d, dist_range);
-
- /* Get Z Depths, needed for perspective, nice for ortho */
- ED_view3d_draw_depth(CTX_data_depsgraph(C), ar, v3d, true);
-
- {
- /* avoid allocating the whole depth buffer */
- ViewDepths depth_temp = {0};
-
- /* avoid view3d_update_depths() for speed. */
- view3d_update_depths_rect(ar, &depth_temp, &rect);
-
- /* find the closest Z pixel */
- depth_close = view3d_depth_near(&depth_temp);
-
- MEM_SAFE_FREE(depth_temp.depths);
- }
-
- cent[0] = (((float)rect.xmin) + ((float)rect.xmax)) / 2;
- cent[1] = (((float)rect.ymin) + ((float)rect.ymax)) / 2;
-
- if (rv3d->is_persp) {
- float p_corner[3];
-
- /* no depths to use, we cant do anything! */
- if (depth_close == FLT_MAX) {
- BKE_report(op->reports, RPT_ERROR, "Depth too large");
- return OPERATOR_CANCELLED;
- }
- /* convert border to 3d coordinates */
- if ((!ED_view3d_unproject(ar, cent[0], cent[1], depth_close, p)) ||
- (!ED_view3d_unproject(ar, rect.xmin, rect.ymin, depth_close, p_corner)))
- {
- return OPERATOR_CANCELLED;
- }
-
- sub_v3_v3v3(dvec, p, p_corner);
- negate_v3_v3(new_ofs, p);
-
- new_dist = len_v3(dvec);
-
- /* ignore dist_range min */
- dist_range[0] = v3d->clip_start * 1.5f;
- }
- else { /* othographic */
- /* find the current window width and height */
- vb[0] = ar->winx;
- vb[1] = ar->winy;
-
- new_dist = rv3d->dist;
-
- /* convert the drawn rectangle into 3d space */
- if (depth_close != FLT_MAX && ED_view3d_unproject(ar, cent[0], cent[1], depth_close, p)) {
- negate_v3_v3(new_ofs, p);
- }
- 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);
-
- {
- 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, zfac);
- /* center the view to the center of the rectangle */
- sub_v3_v3(new_ofs, dvec);
- }
-
- /* work out the ratios, so that everything selected fits when we zoom */
- xscale = (BLI_rcti_size_x(&rect) / vb[0]);
- yscale = (BLI_rcti_size_y(&rect) / vb[1]);
- new_dist *= max_ff(xscale, yscale);
- }
-
- if (!zoom_in) {
- sub_v3_v3v3(dvec, new_ofs, rv3d->ofs);
- new_dist = rv3d->dist * (rv3d->dist / new_dist);
- add_v3_v3v3(new_ofs, rv3d->ofs, dvec);
- }
-
- /* clamp after because we may have been zooming out */
- CLAMP(new_dist, dist_range[0], dist_range[1]);
-
- /* TODO(campbell): 'is_camera_lock' not currently working well. */
- const bool is_camera_lock = ED_view3d_camera_lock_check(v3d, rv3d);
- if ((rv3d->persp == RV3D_CAMOB) && (is_camera_lock == false)) {
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- ED_view3d_persp_switch_from_camera(depsgraph, v3d, rv3d, RV3D_PERSP);
- }
-
- ED_view3d_smooth_view(
- C, v3d, ar, smooth_viewtx,
- &(const V3D_SmoothParams) { .ofs = new_ofs, .dist = &new_dist, });
-
- if (rv3d->viewlock & RV3D_BOXVIEW) {
- view3d_boxview_sync(CTX_wm_area(C), ar);
- }
-
- return OPERATOR_FINISHED;
+ ARegion *ar = CTX_wm_region(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
+
+ /* Zooms in on a border drawn by the user */
+ rcti rect;
+ float dvec[3], vb[2], xscale, yscale;
+ float dist_range[2];
+
+ /* SMOOTHVIEW */
+ float new_dist;
+ float new_ofs[3];
+
+ /* ZBuffer depth vars */
+ float depth_close = FLT_MAX;
+ float cent[2], p[3];
+
+ /* note; otherwise opengl won't work */
+ view3d_operator_needs_opengl(C);
+
+ /* get box select values using rna */
+ WM_operator_properties_border_to_rcti(op, &rect);
+
+ /* check if zooming in/out view */
+ const bool zoom_in = !RNA_boolean_get(op->ptr, "zoom_out");
+
+ ED_view3d_dist_range_get(v3d, dist_range);
+
+ /* Get Z Depths, needed for perspective, nice for ortho */
+ ED_view3d_draw_depth(CTX_data_depsgraph(C), ar, v3d, true);
+
+ {
+ /* avoid allocating the whole depth buffer */
+ ViewDepths depth_temp = {0};
+
+ /* avoid view3d_update_depths() for speed. */
+ view3d_update_depths_rect(ar, &depth_temp, &rect);
+
+ /* find the closest Z pixel */
+ depth_close = view3d_depth_near(&depth_temp);
+
+ MEM_SAFE_FREE(depth_temp.depths);
+ }
+
+ cent[0] = (((float)rect.xmin) + ((float)rect.xmax)) / 2;
+ cent[1] = (((float)rect.ymin) + ((float)rect.ymax)) / 2;
+
+ if (rv3d->is_persp) {
+ float p_corner[3];
+
+ /* no depths to use, we cant do anything! */
+ if (depth_close == FLT_MAX) {
+ BKE_report(op->reports, RPT_ERROR, "Depth too large");
+ return OPERATOR_CANCELLED;
+ }
+ /* convert border to 3d coordinates */
+ if ((!ED_view3d_unproject(ar, cent[0], cent[1], depth_close, p)) ||
+ (!ED_view3d_unproject(ar, rect.xmin, rect.ymin, depth_close, p_corner))) {
+ return OPERATOR_CANCELLED;
+ }
+
+ sub_v3_v3v3(dvec, p, p_corner);
+ negate_v3_v3(new_ofs, p);
+
+ new_dist = len_v3(dvec);
+
+ /* ignore dist_range min */
+ dist_range[0] = v3d->clip_start * 1.5f;
+ }
+ else { /* othographic */
+ /* find the current window width and height */
+ vb[0] = ar->winx;
+ vb[1] = ar->winy;
+
+ new_dist = rv3d->dist;
+
+ /* convert the drawn rectangle into 3d space */
+ if (depth_close != FLT_MAX && ED_view3d_unproject(ar, cent[0], cent[1], depth_close, p)) {
+ negate_v3_v3(new_ofs, p);
+ }
+ 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);
+
+ {
+ 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, zfac);
+ /* center the view to the center of the rectangle */
+ sub_v3_v3(new_ofs, dvec);
+ }
+
+ /* work out the ratios, so that everything selected fits when we zoom */
+ xscale = (BLI_rcti_size_x(&rect) / vb[0]);
+ yscale = (BLI_rcti_size_y(&rect) / vb[1]);
+ new_dist *= max_ff(xscale, yscale);
+ }
+
+ if (!zoom_in) {
+ sub_v3_v3v3(dvec, new_ofs, rv3d->ofs);
+ new_dist = rv3d->dist * (rv3d->dist / new_dist);
+ add_v3_v3v3(new_ofs, rv3d->ofs, dvec);
+ }
+
+ /* clamp after because we may have been zooming out */
+ CLAMP(new_dist, dist_range[0], dist_range[1]);
+
+ /* TODO(campbell): 'is_camera_lock' not currently working well. */
+ const bool is_camera_lock = ED_view3d_camera_lock_check(v3d, rv3d);
+ if ((rv3d->persp == RV3D_CAMOB) && (is_camera_lock == false)) {
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ ED_view3d_persp_switch_from_camera(depsgraph, v3d, rv3d, RV3D_PERSP);
+ }
+
+ ED_view3d_smooth_view(C,
+ v3d,
+ ar,
+ smooth_viewtx,
+ &(const V3D_SmoothParams){
+ .ofs = new_ofs,
+ .dist = &new_dist,
+ });
+
+ if (rv3d->viewlock & RV3D_BOXVIEW) {
+ view3d_boxview_sync(CTX_wm_area(C), ar);
+ }
+
+ return OPERATOR_FINISHED;
}
void VIEW3D_OT_zoom_border(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Zoom to Border";
- ot->description = "Zoom in the view to the nearest object contained in the border";
- ot->idname = "VIEW3D_OT_zoom_border";
+ /* identifiers */
+ ot->name = "Zoom to Border";
+ ot->description = "Zoom in the view to the nearest object contained in the border";
+ ot->idname = "VIEW3D_OT_zoom_border";
- /* api callbacks */
- ot->invoke = WM_gesture_box_invoke;
- ot->exec = view3d_zoom_border_exec;
- ot->modal = WM_gesture_box_modal;
- ot->cancel = WM_gesture_box_cancel;
+ /* api callbacks */
+ ot->invoke = WM_gesture_box_invoke;
+ ot->exec = view3d_zoom_border_exec;
+ ot->modal = WM_gesture_box_modal;
+ ot->cancel = WM_gesture_box_cancel;
- ot->poll = ED_operator_region_view3d_active;
+ ot->poll = ED_operator_region_view3d_active;
- /* flags */
- ot->flag = 0;
+ /* flags */
+ ot->flag = 0;
- /* properties */
- WM_operator_properties_gesture_box_zoom(ot);
+ /* properties */
+ WM_operator_properties_gesture_box_zoom(ot);
}
/** \} */
@@ -3626,49 +3670,52 @@ void VIEW3D_OT_zoom_border(wmOperatorType *ot)
* Sets the view to 1:1 camera/render-pixel.
* \{ */
-static void view3d_set_1_to_1_viewborder(Scene *scene, Depsgraph *depsgraph, ARegion *ar, View3D *v3d)
+static void view3d_set_1_to_1_viewborder(Scene *scene,
+ Depsgraph *depsgraph,
+ ARegion *ar,
+ View3D *v3d)
{
- RegionView3D *rv3d = ar->regiondata;
- float size[2];
- int im_width = (scene->r.size * scene->r.xsch) / 100;
+ RegionView3D *rv3d = ar->regiondata;
+ float size[2];
+ int im_width = (scene->r.size * scene->r.xsch) / 100;
- ED_view3d_calc_camera_border_size(scene, depsgraph, ar, v3d, rv3d, size);
+ ED_view3d_calc_camera_border_size(scene, depsgraph, ar, v3d, rv3d, size);
- rv3d->camzoom = BKE_screen_view3d_zoom_from_fac((float)im_width / size[0]);
- CLAMP(rv3d->camzoom, RV3D_CAMZOOM_MIN, RV3D_CAMZOOM_MAX);
+ rv3d->camzoom = BKE_screen_view3d_zoom_from_fac((float)im_width / size[0]);
+ CLAMP(rv3d->camzoom, RV3D_CAMZOOM_MIN, RV3D_CAMZOOM_MAX);
}
static int view3d_zoom_1_to_1_camera_exec(bContext *C, wmOperator *UNUSED(op))
{
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- Scene *scene = CTX_data_scene(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ Scene *scene = CTX_data_scene(C);
- View3D *v3d;
- ARegion *ar;
+ View3D *v3d;
+ ARegion *ar;
- /* no NULL check is needed, poll checks */
- ED_view3d_context_user_region(C, &v3d, &ar);
+ /* no NULL check is needed, poll checks */
+ ED_view3d_context_user_region(C, &v3d, &ar);
- view3d_set_1_to_1_viewborder(scene, depsgraph, ar, v3d);
+ view3d_set_1_to_1_viewborder(scene, depsgraph, ar, v3d);
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void VIEW3D_OT_zoom_camera_1_to_1(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Zoom Camera 1:1";
- ot->description = "Match the camera to 1:1 to the render output";
- ot->idname = "VIEW3D_OT_zoom_camera_1_to_1";
+ /* identifiers */
+ ot->name = "Zoom Camera 1:1";
+ ot->description = "Match the camera to 1:1 to the render output";
+ ot->idname = "VIEW3D_OT_zoom_camera_1_to_1";
- /* api callbacks */
- ot->exec = view3d_zoom_1_to_1_camera_exec;
- ot->poll = view3d_camera_user_poll;
+ /* api callbacks */
+ ot->exec = view3d_zoom_1_to_1_camera_exec;
+ ot->poll = view3d_camera_user_poll;
- /* flags */
- ot->flag = 0;
+ /* flags */
+ ot->flag = 0;
}
/** \} */
@@ -3678,211 +3725,229 @@ void VIEW3D_OT_zoom_camera_1_to_1(wmOperatorType *ot)
* \{ */
static const EnumPropertyItem prop_view_items[] = {
- {RV3D_VIEW_LEFT, "LEFT", ICON_TRIA_LEFT, "Left", "View From the Left"},
- {RV3D_VIEW_RIGHT, "RIGHT", ICON_TRIA_RIGHT, "Right", "View From the Right"},
- {RV3D_VIEW_BOTTOM, "BOTTOM", ICON_TRIA_DOWN, "Bottom", "View From the Bottom"},
- {RV3D_VIEW_TOP, "TOP", ICON_TRIA_UP, "Top", "View From the Top"},
- {RV3D_VIEW_FRONT, "FRONT", 0, "Front", "View From the Front"},
- {RV3D_VIEW_BACK, "BACK", 0, "Back", "View From the Back"},
- {0, NULL, 0, NULL, NULL},
+ {RV3D_VIEW_LEFT, "LEFT", ICON_TRIA_LEFT, "Left", "View From the Left"},
+ {RV3D_VIEW_RIGHT, "RIGHT", ICON_TRIA_RIGHT, "Right", "View From the Right"},
+ {RV3D_VIEW_BOTTOM, "BOTTOM", ICON_TRIA_DOWN, "Bottom", "View From the Bottom"},
+ {RV3D_VIEW_TOP, "TOP", ICON_TRIA_UP, "Top", "View From the Top"},
+ {RV3D_VIEW_FRONT, "FRONT", 0, "Front", "View From the Front"},
+ {RV3D_VIEW_BACK, "BACK", 0, "Back", "View From the Back"},
+ {0, NULL, 0, NULL, NULL},
};
-
/* would like to make this a generic function - outside of transform */
/**
* \param align_to_quat: When not NULL, set the axis relative to this rotation.
*/
-static void axis_set_view(
- bContext *C, View3D *v3d, ARegion *ar,
- const float quat_[4],
- short view, int perspo,
- const float *align_to_quat,
- const int smooth_viewtx)
-{
- RegionView3D *rv3d = ar->regiondata; /* no NULL check is needed, poll checks */
- float quat[4];
- const short orig_persp = rv3d->persp;
-
-
- normalize_qt_qt(quat, quat_);
-
- if (align_to_quat) {
- mul_qt_qtqt(quat, quat, align_to_quat);
- rv3d->view = view = RV3D_VIEW_USER;
- }
-
- if (align_to_quat == NULL) {
- rv3d->view = view;
- }
-
- if (rv3d->viewlock & RV3D_LOCKED) {
- ED_region_tag_redraw(ar);
- return;
- }
-
- if (U.uiflag & USER_AUTOPERSP) {
- rv3d->persp = RV3D_VIEW_IS_AXIS(view) ? RV3D_ORTHO : perspo;
- }
- else if (rv3d->persp == RV3D_CAMOB) {
- rv3d->persp = perspo;
- }
-
- if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
- /* to camera */
- ED_view3d_smooth_view(
- C, v3d, ar, smooth_viewtx,
- &(const V3D_SmoothParams) { .camera_old = v3d->camera, .ofs = rv3d->ofs, .quat = quat, });
- }
- else if (orig_persp == RV3D_CAMOB && v3d->camera) {
- /* from camera */
- float ofs[3], dist;
-
- copy_v3_v3(ofs, rv3d->ofs);
- dist = rv3d->dist;
-
- /* so we animate _from_ the camera location */
- Object *camera_eval = DEG_get_evaluated_object(CTX_data_depsgraph(C), v3d->camera);
- ED_view3d_from_object(camera_eval, rv3d->ofs, NULL, &rv3d->dist, NULL);
-
- ED_view3d_smooth_view(
- C, v3d, ar, smooth_viewtx,
- &(const V3D_SmoothParams) { .ofs = ofs, .quat = quat, .dist = &dist, });
- }
- else {
- /* rotate around selection */
- const float *dyn_ofs_pt = NULL;
- float dyn_ofs[3];
-
- if (U.uiflag & USER_ORBIT_SELECTION) {
- if (view3d_orbit_calc_center(C, dyn_ofs)) {
- negate_v3(dyn_ofs);
- dyn_ofs_pt = dyn_ofs;
- }
- }
-
- /* no camera involved */
- ED_view3d_smooth_view(
- C, v3d, ar, smooth_viewtx,
- &(const V3D_SmoothParams) { .quat = quat, .dyn_ofs = dyn_ofs_pt, });
- }
+static void axis_set_view(bContext *C,
+ View3D *v3d,
+ ARegion *ar,
+ const float quat_[4],
+ short view,
+ int perspo,
+ const float *align_to_quat,
+ const int smooth_viewtx)
+{
+ RegionView3D *rv3d = ar->regiondata; /* no NULL check is needed, poll checks */
+ float quat[4];
+ const short orig_persp = rv3d->persp;
+
+ normalize_qt_qt(quat, quat_);
+
+ if (align_to_quat) {
+ mul_qt_qtqt(quat, quat, align_to_quat);
+ rv3d->view = view = RV3D_VIEW_USER;
+ }
+
+ if (align_to_quat == NULL) {
+ rv3d->view = view;
+ }
+
+ if (rv3d->viewlock & RV3D_LOCKED) {
+ ED_region_tag_redraw(ar);
+ return;
+ }
+
+ if (U.uiflag & USER_AUTOPERSP) {
+ rv3d->persp = RV3D_VIEW_IS_AXIS(view) ? RV3D_ORTHO : perspo;
+ }
+ else if (rv3d->persp == RV3D_CAMOB) {
+ rv3d->persp = perspo;
+ }
+
+ if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
+ /* to camera */
+ ED_view3d_smooth_view(C,
+ v3d,
+ ar,
+ smooth_viewtx,
+ &(const V3D_SmoothParams){
+ .camera_old = v3d->camera,
+ .ofs = rv3d->ofs,
+ .quat = quat,
+ });
+ }
+ else if (orig_persp == RV3D_CAMOB && v3d->camera) {
+ /* from camera */
+ float ofs[3], dist;
+
+ copy_v3_v3(ofs, rv3d->ofs);
+ dist = rv3d->dist;
+
+ /* so we animate _from_ the camera location */
+ Object *camera_eval = DEG_get_evaluated_object(CTX_data_depsgraph(C), v3d->camera);
+ ED_view3d_from_object(camera_eval, rv3d->ofs, NULL, &rv3d->dist, NULL);
+
+ ED_view3d_smooth_view(C,
+ v3d,
+ ar,
+ smooth_viewtx,
+ &(const V3D_SmoothParams){
+ .ofs = ofs,
+ .quat = quat,
+ .dist = &dist,
+ });
+ }
+ else {
+ /* rotate around selection */
+ const float *dyn_ofs_pt = NULL;
+ float dyn_ofs[3];
+
+ if (U.uiflag & USER_ORBIT_SELECTION) {
+ if (view3d_orbit_calc_center(C, dyn_ofs)) {
+ negate_v3(dyn_ofs);
+ dyn_ofs_pt = dyn_ofs;
+ }
+ }
+
+ /* no camera involved */
+ ED_view3d_smooth_view(C,
+ v3d,
+ ar,
+ smooth_viewtx,
+ &(const V3D_SmoothParams){
+ .quat = quat,
+ .dyn_ofs = dyn_ofs_pt,
+ });
+ }
}
static int view_axis_exec(bContext *C, wmOperator *op)
{
- View3D *v3d;
- ARegion *ar;
- RegionView3D *rv3d;
- static int perspo = RV3D_PERSP;
- int viewnum;
- const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
-
- /* no NULL check is needed, poll checks */
- ED_view3d_context_user_region(C, &v3d, &ar);
- rv3d = ar->regiondata;
-
- ED_view3d_smooth_view_force_finish(C, v3d, ar);
-
- viewnum = RNA_enum_get(op->ptr, "type");
-
- float align_quat_buf[4];
- float *align_quat = NULL;
-
- if (RNA_boolean_get(op->ptr, "align_active")) {
- /* align to active object */
- Object *obact = CTX_data_active_object(C);
- if (obact != NULL) {
- float twmat[3][3];
- /* same as transform gizmo when normal is set */
- ED_getTransformOrientationMatrix(C, twmat, V3D_AROUND_ACTIVE);
- align_quat = align_quat_buf;
- mat3_to_quat(align_quat, twmat);
- invert_qt_normalized(align_quat);
- }
- }
-
- if (RNA_boolean_get(op->ptr, "relative")) {
- float z_rel[3];
-
- if (viewnum == RV3D_VIEW_RIGHT) {
- negate_v3_v3(z_rel, rv3d->viewinv[0]);
- }
- else if (viewnum == RV3D_VIEW_LEFT) {
- copy_v3_v3(z_rel, rv3d->viewinv[0]);
- }
- else if (viewnum == RV3D_VIEW_TOP) {
- negate_v3_v3(z_rel, rv3d->viewinv[1]);
- }
- else if (viewnum == RV3D_VIEW_BOTTOM) {
- copy_v3_v3(z_rel, rv3d->viewinv[1]);
- }
- else if (viewnum == RV3D_VIEW_FRONT) {
- negate_v3_v3(z_rel, rv3d->viewinv[2]);
- }
- else if (viewnum == RV3D_VIEW_BACK) {
- copy_v3_v3(z_rel, rv3d->viewinv[2]);
- }
- else {
- BLI_assert(0);
- }
-
- float angle_max = FLT_MAX;
- int view_closest = -1;
- for (int i = RV3D_VIEW_FRONT; i <= RV3D_VIEW_BOTTOM; i++) {
- float quat[4];
- float mat[3][3];
- ED_view3d_quat_from_axis_view(i, quat);
- quat[0] *= -1.0f;
- quat_to_mat3(mat, quat);
- if (align_quat) {
- mul_qt_qtqt(quat, quat, align_quat);
- }
- const float angle_test = angle_normalized_v3v3(z_rel, mat[2]);
- if (angle_max > angle_test) {
- angle_max = angle_test;
- view_closest = i;
- }
- }
- if (view_closest == -1) {
- view_closest = RV3D_VIEW_FRONT;
- }
- viewnum = view_closest;
- }
-
- /* Use this to test if we started out with a camera */
- const int nextperspo = (rv3d->persp == RV3D_CAMOB) ? rv3d->lpersp : perspo;
- float quat[4];
- ED_view3d_quat_from_axis_view(viewnum, quat);
- axis_set_view(C, v3d, ar, quat, viewnum, nextperspo, align_quat, smooth_viewtx);
-
- perspo = rv3d->persp;
-
- return OPERATOR_FINISHED;
+ View3D *v3d;
+ ARegion *ar;
+ RegionView3D *rv3d;
+ static int perspo = RV3D_PERSP;
+ int viewnum;
+ const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
+
+ /* no NULL check is needed, poll checks */
+ ED_view3d_context_user_region(C, &v3d, &ar);
+ rv3d = ar->regiondata;
+
+ ED_view3d_smooth_view_force_finish(C, v3d, ar);
+
+ viewnum = RNA_enum_get(op->ptr, "type");
+
+ float align_quat_buf[4];
+ float *align_quat = NULL;
+
+ if (RNA_boolean_get(op->ptr, "align_active")) {
+ /* align to active object */
+ Object *obact = CTX_data_active_object(C);
+ if (obact != NULL) {
+ float twmat[3][3];
+ /* same as transform gizmo when normal is set */
+ ED_getTransformOrientationMatrix(C, twmat, V3D_AROUND_ACTIVE);
+ align_quat = align_quat_buf;
+ mat3_to_quat(align_quat, twmat);
+ invert_qt_normalized(align_quat);
+ }
+ }
+
+ if (RNA_boolean_get(op->ptr, "relative")) {
+ float z_rel[3];
+
+ if (viewnum == RV3D_VIEW_RIGHT) {
+ negate_v3_v3(z_rel, rv3d->viewinv[0]);
+ }
+ else if (viewnum == RV3D_VIEW_LEFT) {
+ copy_v3_v3(z_rel, rv3d->viewinv[0]);
+ }
+ else if (viewnum == RV3D_VIEW_TOP) {
+ negate_v3_v3(z_rel, rv3d->viewinv[1]);
+ }
+ else if (viewnum == RV3D_VIEW_BOTTOM) {
+ copy_v3_v3(z_rel, rv3d->viewinv[1]);
+ }
+ else if (viewnum == RV3D_VIEW_FRONT) {
+ negate_v3_v3(z_rel, rv3d->viewinv[2]);
+ }
+ else if (viewnum == RV3D_VIEW_BACK) {
+ copy_v3_v3(z_rel, rv3d->viewinv[2]);
+ }
+ else {
+ BLI_assert(0);
+ }
+
+ float angle_max = FLT_MAX;
+ int view_closest = -1;
+ for (int i = RV3D_VIEW_FRONT; i <= RV3D_VIEW_BOTTOM; i++) {
+ float quat[4];
+ float mat[3][3];
+ ED_view3d_quat_from_axis_view(i, quat);
+ quat[0] *= -1.0f;
+ quat_to_mat3(mat, quat);
+ if (align_quat) {
+ mul_qt_qtqt(quat, quat, align_quat);
+ }
+ const float angle_test = angle_normalized_v3v3(z_rel, mat[2]);
+ if (angle_max > angle_test) {
+ angle_max = angle_test;
+ view_closest = i;
+ }
+ }
+ if (view_closest == -1) {
+ view_closest = RV3D_VIEW_FRONT;
+ }
+ viewnum = view_closest;
+ }
+
+ /* Use this to test if we started out with a camera */
+ const int nextperspo = (rv3d->persp == RV3D_CAMOB) ? rv3d->lpersp : perspo;
+ float quat[4];
+ ED_view3d_quat_from_axis_view(viewnum, quat);
+ axis_set_view(C, v3d, ar, quat, viewnum, nextperspo, align_quat, smooth_viewtx);
+
+ perspo = rv3d->persp;
+
+ return OPERATOR_FINISHED;
}
-
void VIEW3D_OT_view_axis(wmOperatorType *ot)
{
- PropertyRNA *prop;
+ PropertyRNA *prop;
- /* identifiers */
- ot->name = "View Axis";
- ot->description = "Use a preset viewpoint";
- ot->idname = "VIEW3D_OT_view_axis";
+ /* identifiers */
+ ot->name = "View Axis";
+ ot->description = "Use a preset viewpoint";
+ ot->idname = "VIEW3D_OT_view_axis";
- /* api callbacks */
- ot->exec = view_axis_exec;
- ot->poll = ED_operator_rv3d_user_region_poll;
+ /* api callbacks */
+ ot->exec = view_axis_exec;
+ ot->poll = ED_operator_rv3d_user_region_poll;
- /* flags */
- ot->flag = 0;
+ /* flags */
+ ot->flag = 0;
- ot->prop = RNA_def_enum(ot->srna, "type", prop_view_items, 0, "View", "Preset viewpoint to use");
- RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "align_active", 0, "Align Active", "Align to the active object's axis");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "relative", 0, "Relative", "Rotate relative to the current orientation");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_view_items, 0, "View", "Preset viewpoint to use");
+ RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
+ prop = RNA_def_boolean(
+ ot->srna, "align_active", 0, "Align Active", "Align to the active object's axis");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_boolean(
+ ot->srna, "relative", 0, "Relative", "Rotate relative to the current orientation");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/** \} */
@@ -3893,106 +3958,111 @@ void VIEW3D_OT_view_axis(wmOperatorType *ot)
static int view_camera_exec(bContext *C, wmOperator *op)
{
- View3D *v3d;
- ARegion *ar;
- RegionView3D *rv3d;
- const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
+ View3D *v3d;
+ ARegion *ar;
+ RegionView3D *rv3d;
+ const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
- /* no NULL check is needed, poll checks */
- ED_view3d_context_user_region(C, &v3d, &ar);
- rv3d = ar->regiondata;
+ /* no NULL check is needed, poll checks */
+ ED_view3d_context_user_region(C, &v3d, &ar);
+ rv3d = ar->regiondata;
- ED_view3d_smooth_view_force_finish(C, v3d, ar);
+ ED_view3d_smooth_view_force_finish(C, v3d, ar);
- if ((rv3d->viewlock & RV3D_LOCKED) == 0) {
- /* lastview - */
+ if ((rv3d->viewlock & RV3D_LOCKED) == 0) {
+ /* lastview - */
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Scene *scene = CTX_data_scene(C);
- if (rv3d->persp != RV3D_CAMOB) {
- Object *ob = OBACT(view_layer);
+ if (rv3d->persp != RV3D_CAMOB) {
+ Object *ob = OBACT(view_layer);
- if (!rv3d->smooth_timer) {
- /* store settings of current view before allowing overwriting with camera view
- * only if we're not currently in a view transition */
+ if (!rv3d->smooth_timer) {
+ /* store settings of current view before allowing overwriting with camera view
+ * only if we're not currently in a view transition */
- ED_view3d_lastview_store(rv3d);
- }
+ ED_view3d_lastview_store(rv3d);
+ }
#if 0
- if (G.qual == LR_ALTKEY) {
- if (oldcamera && is_an_active_object(oldcamera)) {
- v3d->camera = oldcamera;
- }
- handle_view3d_lock();
- }
+ if (G.qual == LR_ALTKEY) {
+ if (oldcamera && is_an_active_object(oldcamera)) {
+ v3d->camera = oldcamera;
+ }
+ handle_view3d_lock();
+ }
#endif
- /* first get the default camera for the view lock type */
- if (v3d->scenelock) {
- /* sets the camera view if available */
- v3d->camera = scene->camera;
- }
- else {
- /* use scene camera if one is not set (even though we're unlocked) */
- if (v3d->camera == NULL) {
- v3d->camera = scene->camera;
- }
- }
-
- /* if the camera isn't found, check a number of options */
- if (v3d->camera == NULL && ob && ob->type == OB_CAMERA) {
- v3d->camera = ob;
- }
-
- if (v3d->camera == NULL) {
- v3d->camera = BKE_view_layer_camera_find(view_layer);
- }
-
- /* couldn't find any useful camera, bail out */
- if (v3d->camera == NULL) {
- return OPERATOR_CANCELLED;
- }
-
- /* important these don't get out of sync for locked scenes */
- if (v3d->scenelock && scene->camera != v3d->camera) {
- scene->camera = v3d->camera;
- DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
- }
-
- /* finally do snazzy view zooming */
- rv3d->persp = RV3D_CAMOB;
- ED_view3d_smooth_view(
- C, v3d, ar, smooth_viewtx,
- &(const V3D_SmoothParams) {
- .camera = v3d->camera, .ofs = rv3d->ofs, .quat = rv3d->viewquat,
- .dist = &rv3d->dist, .lens = &v3d->lens,
- });
- }
- else {
- /* return to settings of last view */
- /* does view3d_smooth_view too */
- axis_set_view(C, v3d, ar, rv3d->lviewquat, rv3d->lview, rv3d->lpersp, NULL, smooth_viewtx);
- }
- }
-
- return OPERATOR_FINISHED;
+ /* first get the default camera for the view lock type */
+ if (v3d->scenelock) {
+ /* sets the camera view if available */
+ v3d->camera = scene->camera;
+ }
+ else {
+ /* use scene camera if one is not set (even though we're unlocked) */
+ if (v3d->camera == NULL) {
+ v3d->camera = scene->camera;
+ }
+ }
+
+ /* if the camera isn't found, check a number of options */
+ if (v3d->camera == NULL && ob && ob->type == OB_CAMERA) {
+ v3d->camera = ob;
+ }
+
+ if (v3d->camera == NULL) {
+ v3d->camera = BKE_view_layer_camera_find(view_layer);
+ }
+
+ /* couldn't find any useful camera, bail out */
+ if (v3d->camera == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* important these don't get out of sync for locked scenes */
+ if (v3d->scenelock && scene->camera != v3d->camera) {
+ scene->camera = v3d->camera;
+ DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
+ }
+
+ /* finally do snazzy view zooming */
+ rv3d->persp = RV3D_CAMOB;
+ ED_view3d_smooth_view(C,
+ v3d,
+ ar,
+ smooth_viewtx,
+ &(const V3D_SmoothParams){
+ .camera = v3d->camera,
+ .ofs = rv3d->ofs,
+ .quat = rv3d->viewquat,
+ .dist = &rv3d->dist,
+ .lens = &v3d->lens,
+ });
+ }
+ else {
+ /* return to settings of last view */
+ /* does view3d_smooth_view too */
+ axis_set_view(C, v3d, ar, rv3d->lviewquat, rv3d->lview, rv3d->lpersp, NULL, smooth_viewtx);
+ }
+ }
+
+ return OPERATOR_FINISHED;
}
void VIEW3D_OT_view_camera(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "View Camera";
- ot->description = "Toggle the camera view";
- ot->idname = "VIEW3D_OT_view_camera";
+ /* identifiers */
+ ot->name = "View Camera";
+ ot->description = "Toggle the camera view";
+ ot->idname = "VIEW3D_OT_view_camera";
- /* api callbacks */
- ot->exec = view_camera_exec;
- ot->poll = ED_operator_rv3d_user_region_poll;
+ /* api callbacks */
+ ot->exec = view_camera_exec;
+ ot->poll = ED_operator_rv3d_user_region_poll;
- /* flags */
- ot->flag = 0;
+ /* flags */
+ ot->flag = 0;
}
/** \} */
@@ -4004,133 +4074,140 @@ void VIEW3D_OT_view_camera(wmOperatorType *ot)
* \{ */
enum {
- V3D_VIEW_STEPLEFT = 1,
- V3D_VIEW_STEPRIGHT,
- V3D_VIEW_STEPDOWN,
- V3D_VIEW_STEPUP,
+ V3D_VIEW_STEPLEFT = 1,
+ V3D_VIEW_STEPRIGHT,
+ V3D_VIEW_STEPDOWN,
+ V3D_VIEW_STEPUP,
};
static const EnumPropertyItem prop_view_orbit_items[] = {
- {V3D_VIEW_STEPLEFT, "ORBITLEFT", 0, "Orbit Left", "Orbit the view around to the Left"},
- {V3D_VIEW_STEPRIGHT, "ORBITRIGHT", 0, "Orbit Right", "Orbit the view around to the Right"},
- {V3D_VIEW_STEPUP, "ORBITUP", 0, "Orbit Up", "Orbit the view Up"},
- {V3D_VIEW_STEPDOWN, "ORBITDOWN", 0, "Orbit Down", "Orbit the view Down"},
- {0, NULL, 0, NULL, NULL},
+ {V3D_VIEW_STEPLEFT, "ORBITLEFT", 0, "Orbit Left", "Orbit the view around to the Left"},
+ {V3D_VIEW_STEPRIGHT, "ORBITRIGHT", 0, "Orbit Right", "Orbit the view around to the Right"},
+ {V3D_VIEW_STEPUP, "ORBITUP", 0, "Orbit Up", "Orbit the view Up"},
+ {V3D_VIEW_STEPDOWN, "ORBITDOWN", 0, "Orbit Down", "Orbit the view Down"},
+ {0, NULL, 0, NULL, NULL},
};
static int vieworbit_exec(bContext *C, wmOperator *op)
{
- View3D *v3d;
- ARegion *ar;
- RegionView3D *rv3d;
- int orbitdir;
- char view_opposite;
- PropertyRNA *prop_angle = RNA_struct_find_property(op->ptr, "angle");
- float angle = RNA_property_is_set(op->ptr, prop_angle) ?
- RNA_property_float_get(op->ptr, prop_angle) : DEG2RADF(U.pad_rot_angle);
-
- /* no NULL check is needed, poll checks */
- v3d = CTX_wm_view3d(C);
- ar = CTX_wm_region(C);
- rv3d = ar->regiondata;
-
- /* support for switching to the opposite view (even when in locked views) */
- view_opposite = (fabsf(angle) == (float)M_PI) ? ED_view3d_axis_view_opposite(rv3d->view) : RV3D_VIEW_USER;
- orbitdir = RNA_enum_get(op->ptr, "type");
-
- if ((rv3d->viewlock & RV3D_LOCKED) && (view_opposite == RV3D_VIEW_USER)) {
- /* no NULL check is needed, poll checks */
- ED_view3d_context_user_region(C, &v3d, &ar);
- rv3d = ar->regiondata;
- }
-
- ED_view3d_smooth_view_force_finish(C, v3d, ar);
-
- if ((rv3d->viewlock & RV3D_LOCKED) == 0 || (view_opposite != RV3D_VIEW_USER)) {
- if ((rv3d->persp != RV3D_CAMOB) || ED_view3d_camera_lock_check(v3d, rv3d)) {
- int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
- float quat_mul[4];
- float quat_new[4];
-
- if (view_opposite == RV3D_VIEW_USER) {
- const Depsgraph *depsgraph = CTX_data_depsgraph(C);
- ED_view3d_persp_ensure(depsgraph, v3d, ar);
- }
-
- if (ELEM(orbitdir, V3D_VIEW_STEPLEFT, V3D_VIEW_STEPRIGHT)) {
- if (orbitdir == V3D_VIEW_STEPRIGHT) {
- angle = -angle;
- }
-
- /* z-axis */
- axis_angle_to_quat_single(quat_mul, 'Z', angle);
- }
- else {
-
- if (orbitdir == V3D_VIEW_STEPDOWN) {
- angle = -angle;
- }
-
- /* horizontal axis */
- axis_angle_to_quat(quat_mul, rv3d->viewinv[0], angle);
- }
-
- mul_qt_qtqt(quat_new, rv3d->viewquat, quat_mul);
-
- /* avoid precision loss over time */
- normalize_qt(quat_new);
-
- if (view_opposite != RV3D_VIEW_USER) {
- rv3d->view = view_opposite;
- /* avoid float in-precision, just get a new orientation */
- ED_view3d_quat_from_axis_view(view_opposite, quat_new);
- }
- else {
- rv3d->view = RV3D_VIEW_USER;
- }
-
-
- float dyn_ofs[3], *dyn_ofs_pt = NULL;
-
- if (U.uiflag & USER_ORBIT_SELECTION) {
- if (view3d_orbit_calc_center(C, dyn_ofs)) {
- negate_v3(dyn_ofs);
- dyn_ofs_pt = dyn_ofs;
- }
- }
-
- ED_view3d_smooth_view(
- C, v3d, ar, smooth_viewtx,
- &(const V3D_SmoothParams) { .quat = quat_new, .dyn_ofs = dyn_ofs_pt, });
-
- return OPERATOR_FINISHED;
- }
- }
-
- return OPERATOR_CANCELLED;
+ View3D *v3d;
+ ARegion *ar;
+ RegionView3D *rv3d;
+ int orbitdir;
+ char view_opposite;
+ PropertyRNA *prop_angle = RNA_struct_find_property(op->ptr, "angle");
+ float angle = RNA_property_is_set(op->ptr, prop_angle) ?
+ RNA_property_float_get(op->ptr, prop_angle) :
+ DEG2RADF(U.pad_rot_angle);
+
+ /* no NULL check is needed, poll checks */
+ v3d = CTX_wm_view3d(C);
+ ar = CTX_wm_region(C);
+ rv3d = ar->regiondata;
+
+ /* support for switching to the opposite view (even when in locked views) */
+ view_opposite = (fabsf(angle) == (float)M_PI) ? ED_view3d_axis_view_opposite(rv3d->view) :
+ RV3D_VIEW_USER;
+ orbitdir = RNA_enum_get(op->ptr, "type");
+
+ if ((rv3d->viewlock & RV3D_LOCKED) && (view_opposite == RV3D_VIEW_USER)) {
+ /* no NULL check is needed, poll checks */
+ ED_view3d_context_user_region(C, &v3d, &ar);
+ rv3d = ar->regiondata;
+ }
+
+ ED_view3d_smooth_view_force_finish(C, v3d, ar);
+
+ if ((rv3d->viewlock & RV3D_LOCKED) == 0 || (view_opposite != RV3D_VIEW_USER)) {
+ if ((rv3d->persp != RV3D_CAMOB) || ED_view3d_camera_lock_check(v3d, rv3d)) {
+ int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
+ float quat_mul[4];
+ float quat_new[4];
+
+ if (view_opposite == RV3D_VIEW_USER) {
+ const Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ ED_view3d_persp_ensure(depsgraph, v3d, ar);
+ }
+
+ if (ELEM(orbitdir, V3D_VIEW_STEPLEFT, V3D_VIEW_STEPRIGHT)) {
+ if (orbitdir == V3D_VIEW_STEPRIGHT) {
+ angle = -angle;
+ }
+
+ /* z-axis */
+ axis_angle_to_quat_single(quat_mul, 'Z', angle);
+ }
+ else {
+
+ if (orbitdir == V3D_VIEW_STEPDOWN) {
+ angle = -angle;
+ }
+
+ /* horizontal axis */
+ axis_angle_to_quat(quat_mul, rv3d->viewinv[0], angle);
+ }
+
+ mul_qt_qtqt(quat_new, rv3d->viewquat, quat_mul);
+
+ /* avoid precision loss over time */
+ normalize_qt(quat_new);
+
+ if (view_opposite != RV3D_VIEW_USER) {
+ rv3d->view = view_opposite;
+ /* avoid float in-precision, just get a new orientation */
+ ED_view3d_quat_from_axis_view(view_opposite, quat_new);
+ }
+ else {
+ rv3d->view = RV3D_VIEW_USER;
+ }
+
+ float dyn_ofs[3], *dyn_ofs_pt = NULL;
+
+ if (U.uiflag & USER_ORBIT_SELECTION) {
+ if (view3d_orbit_calc_center(C, dyn_ofs)) {
+ negate_v3(dyn_ofs);
+ dyn_ofs_pt = dyn_ofs;
+ }
+ }
+
+ ED_view3d_smooth_view(C,
+ v3d,
+ ar,
+ smooth_viewtx,
+ &(const V3D_SmoothParams){
+ .quat = quat_new,
+ .dyn_ofs = dyn_ofs_pt,
+ });
+
+ return OPERATOR_FINISHED;
+ }
+ }
+
+ return OPERATOR_CANCELLED;
}
void VIEW3D_OT_view_orbit(wmOperatorType *ot)
{
- PropertyRNA *prop;
+ PropertyRNA *prop;
- /* identifiers */
- ot->name = "View Orbit";
- ot->description = "Orbit the view";
- ot->idname = "VIEW3D_OT_view_orbit";
+ /* identifiers */
+ ot->name = "View Orbit";
+ ot->description = "Orbit the view";
+ ot->idname = "VIEW3D_OT_view_orbit";
- /* api callbacks */
- ot->exec = vieworbit_exec;
- ot->poll = ED_operator_rv3d_user_region_poll;
+ /* api callbacks */
+ ot->exec = vieworbit_exec;
+ ot->poll = ED_operator_rv3d_user_region_poll;
- /* flags */
- ot->flag = 0;
+ /* flags */
+ ot->flag = 0;
- /* properties */
- prop = RNA_def_float(ot->srna, "angle", 0, -FLT_MAX, FLT_MAX, "Roll", "", -FLT_MAX, FLT_MAX);
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ /* properties */
+ prop = RNA_def_float(ot->srna, "angle", 0, -FLT_MAX, FLT_MAX, "Roll", "", -FLT_MAX, FLT_MAX);
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- ot->prop = RNA_def_enum(ot->srna, "type", prop_view_orbit_items, 0, "Orbit", "Direction of View Orbit");
+ ot->prop = RNA_def_enum(
+ ot->srna, "type", prop_view_orbit_items, 0, "Orbit", "Direction of View Orbit");
}
/** \} */
@@ -4139,253 +4216,265 @@ void VIEW3D_OT_view_orbit(wmOperatorType *ot)
/** \name View Roll Operator
* \{ */
-static void view_roll_angle(ARegion *ar, float quat[4], const float orig_quat[4], const float dvec[3], float angle)
+static void view_roll_angle(
+ ARegion *ar, float quat[4], const float orig_quat[4], const float dvec[3], float angle)
{
- RegionView3D *rv3d = ar->regiondata;
- float quat_mul[4];
+ RegionView3D *rv3d = ar->regiondata;
+ float quat_mul[4];
- /* camera axis */
- axis_angle_normalized_to_quat(quat_mul, dvec, angle);
+ /* camera axis */
+ axis_angle_normalized_to_quat(quat_mul, dvec, angle);
- mul_qt_qtqt(quat, orig_quat, quat_mul);
+ mul_qt_qtqt(quat, orig_quat, quat_mul);
- /* avoid precision loss over time */
- normalize_qt(quat);
+ /* avoid precision loss over time */
+ normalize_qt(quat);
- rv3d->view = RV3D_VIEW_USER;
+ rv3d->view = RV3D_VIEW_USER;
}
static void viewroll_apply(ViewOpsData *vod, int x, int UNUSED(y))
{
- float angle = 0.0;
+ float angle = 0.0;
- {
- float len1, len2, tot;
+ {
+ float len1, len2, tot;
- tot = vod->ar->winrct.xmax - vod->ar->winrct.xmin;
- len1 = (vod->ar->winrct.xmax - x) / tot;
- len2 = (vod->ar->winrct.xmax - vod->init.event_xy[0]) / tot;
- angle = (len1 - len2) * (float)M_PI * 4.0f;
- }
+ tot = vod->ar->winrct.xmax - vod->ar->winrct.xmin;
+ len1 = (vod->ar->winrct.xmax - x) / tot;
+ len2 = (vod->ar->winrct.xmax - vod->init.event_xy[0]) / tot;
+ angle = (len1 - len2) * (float)M_PI * 4.0f;
+ }
- if (angle != 0.0f) {
- view_roll_angle(vod->ar, vod->rv3d->viewquat, vod->init.quat, vod->init.mousevec, angle);
- }
+ if (angle != 0.0f) {
+ view_roll_angle(vod->ar, vod->rv3d->viewquat, vod->init.quat, vod->init.mousevec, angle);
+ }
- if (vod->use_dyn_ofs) {
- view3d_orbit_apply_dyn_ofs(vod->rv3d->ofs, vod->init.ofs, vod->init.quat, vod->rv3d->viewquat, vod->dyn_ofs);
- }
+ if (vod->use_dyn_ofs) {
+ view3d_orbit_apply_dyn_ofs(
+ vod->rv3d->ofs, vod->init.ofs, vod->init.quat, vod->rv3d->viewquat, vod->dyn_ofs);
+ }
- if (vod->rv3d->viewlock & RV3D_BOXVIEW) {
- view3d_boxview_sync(vod->sa, vod->ar);
- }
+ if (vod->rv3d->viewlock & RV3D_BOXVIEW) {
+ view3d_boxview_sync(vod->sa, vod->ar);
+ }
- ED_view3d_camera_lock_sync(vod->depsgraph, vod->v3d, vod->rv3d);
+ ED_view3d_camera_lock_sync(vod->depsgraph, vod->v3d, vod->rv3d);
- ED_region_tag_redraw(vod->ar);
+ ED_region_tag_redraw(vod->ar);
}
static int viewroll_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
- ViewOpsData *vod = op->customdata;
- short event_code = VIEW_PASS;
- bool use_autokey = false;
- int ret = OPERATOR_RUNNING_MODAL;
-
- /* execute the events */
- if (event->type == MOUSEMOVE) {
- event_code = VIEW_APPLY;
- }
- else if (event->type == EVT_MODAL_MAP) {
- switch (event->val) {
- case VIEW_MODAL_CONFIRM:
- event_code = VIEW_CONFIRM;
- break;
- case VIEWROT_MODAL_SWITCH_MOVE:
- WM_operator_name_call(C, "VIEW3D_OT_move", WM_OP_INVOKE_DEFAULT, NULL);
- event_code = VIEW_CONFIRM;
- break;
- case VIEWROT_MODAL_SWITCH_ROTATE:
- WM_operator_name_call(C, "VIEW3D_OT_rotate", WM_OP_INVOKE_DEFAULT, NULL);
- event_code = VIEW_CONFIRM;
- break;
- }
- }
- else if (event->type == vod->init.event_type && event->val == KM_RELEASE) {
- event_code = VIEW_CONFIRM;
- }
-
- if (event_code == VIEW_APPLY) {
- viewroll_apply(vod, event->x, event->y);
- if (ED_screen_animation_playing(CTX_wm_manager(C))) {
- use_autokey = true;
- }
- }
- else if (event_code == VIEW_CONFIRM) {
- ED_view3d_depth_tag_update(vod->rv3d);
- use_autokey = true;
- ret = OPERATOR_FINISHED;
- }
-
- if (use_autokey) {
- ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, true, false);
- }
-
- if (ret & OPERATOR_FINISHED) {
- viewops_data_free(C, op);
- }
-
- return ret;
+ ViewOpsData *vod = op->customdata;
+ short event_code = VIEW_PASS;
+ bool use_autokey = false;
+ int ret = OPERATOR_RUNNING_MODAL;
+
+ /* execute the events */
+ if (event->type == MOUSEMOVE) {
+ event_code = VIEW_APPLY;
+ }
+ else if (event->type == EVT_MODAL_MAP) {
+ switch (event->val) {
+ case VIEW_MODAL_CONFIRM:
+ event_code = VIEW_CONFIRM;
+ break;
+ case VIEWROT_MODAL_SWITCH_MOVE:
+ WM_operator_name_call(C, "VIEW3D_OT_move", WM_OP_INVOKE_DEFAULT, NULL);
+ event_code = VIEW_CONFIRM;
+ break;
+ case VIEWROT_MODAL_SWITCH_ROTATE:
+ WM_operator_name_call(C, "VIEW3D_OT_rotate", WM_OP_INVOKE_DEFAULT, NULL);
+ event_code = VIEW_CONFIRM;
+ break;
+ }
+ }
+ else if (event->type == vod->init.event_type && event->val == KM_RELEASE) {
+ event_code = VIEW_CONFIRM;
+ }
+
+ if (event_code == VIEW_APPLY) {
+ viewroll_apply(vod, event->x, event->y);
+ if (ED_screen_animation_playing(CTX_wm_manager(C))) {
+ use_autokey = true;
+ }
+ }
+ else if (event_code == VIEW_CONFIRM) {
+ ED_view3d_depth_tag_update(vod->rv3d);
+ use_autokey = true;
+ ret = OPERATOR_FINISHED;
+ }
+
+ if (use_autokey) {
+ ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, true, false);
+ }
+
+ if (ret & OPERATOR_FINISHED) {
+ viewops_data_free(C, op);
+ }
+
+ return ret;
}
static const EnumPropertyItem prop_view_roll_items[] = {
- {0, "ANGLE", 0, "Roll Angle", "Roll the view using an angle value"},
- {V3D_VIEW_STEPLEFT, "LEFT", 0, "Roll Left", "Roll the view around to the Left"},
- {V3D_VIEW_STEPRIGHT, "RIGHT", 0, "Roll Right", "Roll the view around to the Right"},
- {0, NULL, 0, NULL, NULL},
+ {0, "ANGLE", 0, "Roll Angle", "Roll the view using an angle value"},
+ {V3D_VIEW_STEPLEFT, "LEFT", 0, "Roll Left", "Roll the view around to the Left"},
+ {V3D_VIEW_STEPRIGHT, "RIGHT", 0, "Roll Right", "Roll the view around to the Right"},
+ {0, NULL, 0, NULL, NULL},
};
-
static int viewroll_exec(bContext *C, wmOperator *op)
{
- View3D *v3d;
- RegionView3D *rv3d;
- ARegion *ar;
-
- if (op->customdata) {
- ViewOpsData *vod = op->customdata;
- ar = vod->ar;
- v3d = vod->v3d;
- }
- else {
- ED_view3d_context_user_region(C, &v3d, &ar);
- }
-
- rv3d = ar->regiondata;
- if ((rv3d->persp != RV3D_CAMOB) || ED_view3d_camera_lock_check(v3d, rv3d)) {
-
- ED_view3d_smooth_view_force_finish(C, v3d, ar);
-
- int type = RNA_enum_get(op->ptr, "type");
- float angle = (type == 0) ? RNA_float_get(op->ptr, "angle") : DEG2RADF(U.pad_rot_angle);
- float mousevec[3];
- float quat_new[4];
-
- const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
-
- if (type == V3D_VIEW_STEPLEFT) {
- angle = -angle;
- }
-
- normalize_v3_v3(mousevec, rv3d->viewinv[2]);
- negate_v3(mousevec);
- view_roll_angle(ar, quat_new, rv3d->viewquat, mousevec, angle);
-
- const float *dyn_ofs_pt = NULL;
- float dyn_ofs[3];
- if (U.uiflag & USER_ORBIT_SELECTION) {
- if (view3d_orbit_calc_center(C, dyn_ofs)) {
- negate_v3(dyn_ofs);
- dyn_ofs_pt = dyn_ofs;
- }
- }
-
- ED_view3d_smooth_view(
- C, v3d, ar, smooth_viewtx,
- &(const V3D_SmoothParams) { .quat = quat_new, .dyn_ofs = dyn_ofs_pt, });
-
- viewops_data_free(C, op);
- return OPERATOR_FINISHED;
- }
- else {
- viewops_data_free(C, op);
- return OPERATOR_CANCELLED;
- }
+ View3D *v3d;
+ RegionView3D *rv3d;
+ ARegion *ar;
+
+ if (op->customdata) {
+ ViewOpsData *vod = op->customdata;
+ ar = vod->ar;
+ v3d = vod->v3d;
+ }
+ else {
+ ED_view3d_context_user_region(C, &v3d, &ar);
+ }
+
+ rv3d = ar->regiondata;
+ if ((rv3d->persp != RV3D_CAMOB) || ED_view3d_camera_lock_check(v3d, rv3d)) {
+
+ ED_view3d_smooth_view_force_finish(C, v3d, ar);
+
+ int type = RNA_enum_get(op->ptr, "type");
+ float angle = (type == 0) ? RNA_float_get(op->ptr, "angle") : DEG2RADF(U.pad_rot_angle);
+ float mousevec[3];
+ float quat_new[4];
+
+ const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
+
+ if (type == V3D_VIEW_STEPLEFT) {
+ angle = -angle;
+ }
+
+ normalize_v3_v3(mousevec, rv3d->viewinv[2]);
+ negate_v3(mousevec);
+ view_roll_angle(ar, quat_new, rv3d->viewquat, mousevec, angle);
+
+ const float *dyn_ofs_pt = NULL;
+ float dyn_ofs[3];
+ if (U.uiflag & USER_ORBIT_SELECTION) {
+ if (view3d_orbit_calc_center(C, dyn_ofs)) {
+ negate_v3(dyn_ofs);
+ dyn_ofs_pt = dyn_ofs;
+ }
+ }
+
+ ED_view3d_smooth_view(C,
+ v3d,
+ ar,
+ smooth_viewtx,
+ &(const V3D_SmoothParams){
+ .quat = quat_new,
+ .dyn_ofs = dyn_ofs_pt,
+ });
+
+ viewops_data_free(C, op);
+ return OPERATOR_FINISHED;
+ }
+ else {
+ viewops_data_free(C, op);
+ return OPERATOR_CANCELLED;
+ }
}
static int viewroll_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- ViewOpsData *vod;
+ ViewOpsData *vod;
- bool use_angle = RNA_enum_get(op->ptr, "type") != 0;
+ bool use_angle = RNA_enum_get(op->ptr, "type") != 0;
- if (use_angle || RNA_struct_property_is_set(op->ptr, "angle")) {
- viewroll_exec(C, op);
- }
- else {
- /* makes op->customdata */
- viewops_data_alloc(C, op);
- viewops_data_create(C, op, event, viewops_flag_from_prefs());
- vod = op->customdata;
+ if (use_angle || RNA_struct_property_is_set(op->ptr, "angle")) {
+ viewroll_exec(C, op);
+ }
+ else {
+ /* makes op->customdata */
+ viewops_data_alloc(C, op);
+ viewops_data_create(C, op, event, viewops_flag_from_prefs());
+ vod = op->customdata;
- ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->ar);
+ ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->ar);
- /* overwrite the mouse vector with the view direction */
- normalize_v3_v3(vod->init.mousevec, vod->rv3d->viewinv[2]);
- negate_v3(vod->init.mousevec);
+ /* overwrite the mouse vector with the view direction */
+ normalize_v3_v3(vod->init.mousevec, vod->rv3d->viewinv[2]);
+ negate_v3(vod->init.mousevec);
- if (event->type == MOUSEROTATE) {
- vod->init.event_xy[0] = vod->prev.event_xy[0] = event->x;
- viewroll_apply(vod, event->prevx, event->prevy);
- ED_view3d_depth_tag_update(vod->rv3d);
+ if (event->type == MOUSEROTATE) {
+ vod->init.event_xy[0] = vod->prev.event_xy[0] = event->x;
+ viewroll_apply(vod, event->prevx, event->prevy);
+ ED_view3d_depth_tag_update(vod->rv3d);
- viewops_data_free(C, op);
- return OPERATOR_FINISHED;
- }
- else {
- /* add temp handler */
- WM_event_add_modal_handler(C, op);
+ viewops_data_free(C, op);
+ return OPERATOR_FINISHED;
+ }
+ else {
+ /* add temp handler */
+ WM_event_add_modal_handler(C, op);
- return OPERATOR_RUNNING_MODAL;
- }
- }
- return OPERATOR_FINISHED;
+ return OPERATOR_RUNNING_MODAL;
+ }
+ }
+ return OPERATOR_FINISHED;
}
static void viewroll_cancel(bContext *C, wmOperator *op)
{
- viewops_data_free(C, op);
+ viewops_data_free(C, op);
}
void VIEW3D_OT_view_roll(wmOperatorType *ot)
{
- PropertyRNA *prop;
+ PropertyRNA *prop;
- /* identifiers */
- ot->name = "View Roll";
- ot->description = "Roll the view";
- ot->idname = "VIEW3D_OT_view_roll";
+ /* identifiers */
+ ot->name = "View Roll";
+ ot->description = "Roll the view";
+ ot->idname = "VIEW3D_OT_view_roll";
- /* api callbacks */
- ot->invoke = viewroll_invoke;
- ot->exec = viewroll_exec;
- ot->modal = viewroll_modal;
- ot->poll = ED_operator_rv3d_user_region_poll;
- ot->cancel = viewroll_cancel;
+ /* api callbacks */
+ ot->invoke = viewroll_invoke;
+ ot->exec = viewroll_exec;
+ ot->modal = viewroll_modal;
+ ot->poll = ED_operator_rv3d_user_region_poll;
+ ot->cancel = viewroll_cancel;
- /* flags */
- ot->flag = 0;
+ /* flags */
+ ot->flag = 0;
- /* properties */
- ot->prop = prop = RNA_def_float(ot->srna, "angle", 0, -FLT_MAX, FLT_MAX, "Roll", "", -FLT_MAX, FLT_MAX);
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- prop = RNA_def_enum(ot->srna, "type", prop_view_roll_items, 0, "Roll Angle Source", "How roll angle is calculated");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ /* properties */
+ ot->prop = prop = RNA_def_float(
+ ot->srna, "angle", 0, -FLT_MAX, FLT_MAX, "Roll", "", -FLT_MAX, FLT_MAX);
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_enum(ot->srna,
+ "type",
+ prop_view_roll_items,
+ 0,
+ "Roll Angle Source",
+ "How roll angle is calculated");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
enum {
- V3D_VIEW_PANLEFT = 1,
- V3D_VIEW_PANRIGHT,
- V3D_VIEW_PANDOWN,
- V3D_VIEW_PANUP,
+ V3D_VIEW_PANLEFT = 1,
+ V3D_VIEW_PANRIGHT,
+ V3D_VIEW_PANDOWN,
+ V3D_VIEW_PANUP,
};
static const EnumPropertyItem prop_view_pan_items[] = {
- {V3D_VIEW_PANLEFT, "PANLEFT", 0, "Pan Left", "Pan the view to the Left"},
- {V3D_VIEW_PANRIGHT, "PANRIGHT", 0, "Pan Right", "Pan the view to the Right"},
- {V3D_VIEW_PANUP, "PANUP", 0, "Pan Up", "Pan the view Up"},
- {V3D_VIEW_PANDOWN, "PANDOWN", 0, "Pan Down", "Pan the view Down"},
- {0, NULL, 0, NULL, NULL},
+ {V3D_VIEW_PANLEFT, "PANLEFT", 0, "Pan Left", "Pan the view to the Left"},
+ {V3D_VIEW_PANRIGHT, "PANRIGHT", 0, "Pan Right", "Pan the view to the Right"},
+ {V3D_VIEW_PANUP, "PANUP", 0, "Pan Up", "Pan the view Up"},
+ {V3D_VIEW_PANDOWN, "PANDOWN", 0, "Pan Down", "Pan the view Down"},
+ {0, NULL, 0, NULL, NULL},
};
/** \} */
@@ -4398,42 +4487,51 @@ static const EnumPropertyItem prop_view_pan_items[] = {
static int viewpan_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- int x = 0, y = 0;
- int pandir = RNA_enum_get(op->ptr, "type");
+ int x = 0, y = 0;
+ int pandir = RNA_enum_get(op->ptr, "type");
- if (pandir == V3D_VIEW_PANRIGHT) { x = -32; }
- else if (pandir == V3D_VIEW_PANLEFT) { x = 32; }
- else if (pandir == V3D_VIEW_PANUP) { y = -25; }
- else if (pandir == V3D_VIEW_PANDOWN) { y = 25; }
+ if (pandir == V3D_VIEW_PANRIGHT) {
+ x = -32;
+ }
+ else if (pandir == V3D_VIEW_PANLEFT) {
+ x = 32;
+ }
+ else if (pandir == V3D_VIEW_PANUP) {
+ y = -25;
+ }
+ else if (pandir == V3D_VIEW_PANDOWN) {
+ y = 25;
+ }
- viewops_data_alloc(C, op);
- viewops_data_create(C, op, event, (viewops_flag_from_prefs() & ~VIEWOPS_FLAG_ORBIT_SELECT));
- ViewOpsData *vod = op->customdata;
+ viewops_data_alloc(C, op);
+ viewops_data_create(C, op, event, (viewops_flag_from_prefs() & ~VIEWOPS_FLAG_ORBIT_SELECT));
+ ViewOpsData *vod = op->customdata;
- viewmove_apply(vod, vod->prev.event_xy[0] + x, vod->prev.event_xy[1] + y);
+ viewmove_apply(vod, vod->prev.event_xy[0] + x, vod->prev.event_xy[1] + y);
- ED_view3d_depth_tag_update(vod->rv3d);
- viewops_data_free(C, op);
+ ED_view3d_depth_tag_update(vod->rv3d);
+ viewops_data_free(C, op);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void VIEW3D_OT_view_pan(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Pan View Direction";
- ot->description = "Pan the view in a given direction";
- ot->idname = "VIEW3D_OT_view_pan";
+ /* identifiers */
+ ot->name = "Pan View Direction";
+ ot->description = "Pan the view in a given direction";
+ ot->idname = "VIEW3D_OT_view_pan";
- /* api callbacks */
- ot->invoke = viewpan_invoke;
- ot->poll = ED_operator_region_view3d_active;
+ /* api callbacks */
+ ot->invoke = viewpan_invoke;
+ ot->poll = ED_operator_region_view3d_active;
- /* flags */
- ot->flag = 0;
+ /* flags */
+ ot->flag = 0;
- /* Properties */
- ot->prop = RNA_def_enum(ot->srna, "type", prop_view_pan_items, 0, "Pan", "Direction of View Pan");
+ /* Properties */
+ ot->prop = RNA_def_enum(
+ ot->srna, "type", prop_view_pan_items, 0, "Pan", "Direction of View Pan");
}
/** \} */
@@ -4444,40 +4542,40 @@ void VIEW3D_OT_view_pan(wmOperatorType *ot)
static int viewpersportho_exec(bContext *C, wmOperator *UNUSED(op))
{
- View3D *v3d_dummy;
- ARegion *ar;
- RegionView3D *rv3d;
+ View3D *v3d_dummy;
+ ARegion *ar;
+ RegionView3D *rv3d;
- /* no NULL check is needed, poll checks */
- ED_view3d_context_user_region(C, &v3d_dummy, &ar);
- rv3d = ar->regiondata;
+ /* no NULL check is needed, poll checks */
+ ED_view3d_context_user_region(C, &v3d_dummy, &ar);
+ rv3d = ar->regiondata;
- if ((rv3d->viewlock & RV3D_LOCKED) == 0) {
- if (rv3d->persp != RV3D_ORTHO) {
- rv3d->persp = RV3D_ORTHO;
- }
- else {
- rv3d->persp = RV3D_PERSP;
- }
- ED_region_tag_redraw(ar);
- }
+ if ((rv3d->viewlock & RV3D_LOCKED) == 0) {
+ if (rv3d->persp != RV3D_ORTHO) {
+ rv3d->persp = RV3D_ORTHO;
+ }
+ else {
+ rv3d->persp = RV3D_PERSP;
+ }
+ ED_region_tag_redraw(ar);
+ }
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void VIEW3D_OT_view_persportho(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "View Persp/Ortho";
- ot->description = "Switch the current view from perspective/orthographic projection";
- ot->idname = "VIEW3D_OT_view_persportho";
+ /* identifiers */
+ ot->name = "View Persp/Ortho";
+ ot->description = "Switch the current view from perspective/orthographic projection";
+ ot->idname = "VIEW3D_OT_view_persportho";
- /* api callbacks */
- ot->exec = viewpersportho_exec;
- ot->poll = ED_operator_rv3d_user_region_poll;
+ /* api callbacks */
+ ot->exec = viewpersportho_exec;
+ ot->poll = ED_operator_rv3d_user_region_poll;
- /* flags */
- ot->flag = 0;
+ /* flags */
+ ot->flag = 0;
}
/** \} */
@@ -4488,33 +4586,36 @@ void VIEW3D_OT_view_persportho(wmOperatorType *ot)
* Wraps walk/fly modes.
* \{ */
-static int view3d_navigate_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
+static int view3d_navigate_invoke(bContext *C,
+ wmOperator *UNUSED(op),
+ const wmEvent *UNUSED(event))
{
- eViewNavigation_Method mode = U.navigation_mode;
+ eViewNavigation_Method mode = U.navigation_mode;
- switch (mode) {
- case VIEW_NAVIGATION_FLY:
- WM_operator_name_call(C, "VIEW3D_OT_fly", WM_OP_INVOKE_DEFAULT, NULL);
- break;
- case VIEW_NAVIGATION_WALK:
- default:
- WM_operator_name_call(C, "VIEW3D_OT_walk", WM_OP_INVOKE_DEFAULT, NULL);
- break;
- }
+ switch (mode) {
+ case VIEW_NAVIGATION_FLY:
+ WM_operator_name_call(C, "VIEW3D_OT_fly", WM_OP_INVOKE_DEFAULT, NULL);
+ break;
+ case VIEW_NAVIGATION_WALK:
+ default:
+ WM_operator_name_call(C, "VIEW3D_OT_walk", WM_OP_INVOKE_DEFAULT, NULL);
+ break;
+ }
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void VIEW3D_OT_navigate(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "View Navigation";
- ot->description = "Interactively navigate around the scene (uses the mode (walk/fly) preference)";
- ot->idname = "VIEW3D_OT_navigate";
+ /* identifiers */
+ ot->name = "View Navigation";
+ ot->description =
+ "Interactively navigate around the scene (uses the mode (walk/fly) preference)";
+ ot->idname = "VIEW3D_OT_navigate";
- /* api callbacks */
- ot->invoke = view3d_navigate_invoke;
- ot->poll = ED_operator_view3d_active;
+ /* api callbacks */
+ ot->invoke = view3d_navigate_invoke;
+ ot->poll = ED_operator_view3d_active;
}
/** \} */
@@ -4523,76 +4624,79 @@ void VIEW3D_OT_navigate(wmOperatorType *ot)
/** \name Background Image Add Operator
* \{ */
-
static Camera *background_image_camera_from_context(bContext *C)
{
- /* Needed to support drag-and-drop & camera buttons context. */
- View3D *v3d = CTX_wm_view3d(C);
- if (v3d != NULL) {
- if (v3d->camera && v3d->camera->data && v3d->camera->type == OB_CAMERA) {
- return v3d->camera->data;
- }
- return NULL;
- }
- else {
- return CTX_data_pointer_get_type(C, "camera", &RNA_Camera).data;
- }
+ /* Needed to support drag-and-drop & camera buttons context. */
+ View3D *v3d = CTX_wm_view3d(C);
+ if (v3d != NULL) {
+ if (v3d->camera && v3d->camera->data && v3d->camera->type == OB_CAMERA) {
+ return v3d->camera->data;
+ }
+ return NULL;
+ }
+ else {
+ return CTX_data_pointer_get_type(C, "camera", &RNA_Camera).data;
+ }
}
static int background_image_add_exec(bContext *C, wmOperator *UNUSED(op))
{
- Camera *cam = background_image_camera_from_context(C);
- BKE_camera_background_image_new(cam);
+ Camera *cam = background_image_camera_from_context(C);
+ BKE_camera_background_image_new(cam);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static int background_image_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- Camera *cam = background_image_camera_from_context(C);
- Image *ima;
- CameraBGImage *bgpic;
+ Camera *cam = background_image_camera_from_context(C);
+ Image *ima;
+ CameraBGImage *bgpic;
- ima = (Image *)WM_operator_drop_load_path(C, op, ID_IM);
- /* may be NULL, continue anyway */
+ ima = (Image *)WM_operator_drop_load_path(C, op, ID_IM);
+ /* may be NULL, continue anyway */
- bgpic = BKE_camera_background_image_new(cam);
- bgpic->ima = ima;
+ bgpic = BKE_camera_background_image_new(cam);
+ bgpic->ima = ima;
- cam->flag |= CAM_SHOW_BG_IMAGE;
+ cam->flag |= CAM_SHOW_BG_IMAGE;
- WM_event_add_notifier(C, NC_CAMERA | ND_DRAW_RENDER_VIEWPORT, cam);
+ WM_event_add_notifier(C, NC_CAMERA | ND_DRAW_RENDER_VIEWPORT, cam);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static bool background_image_add_poll(bContext *C)
{
- return background_image_camera_from_context(C) != NULL;
+ return background_image_camera_from_context(C) != NULL;
}
void VIEW3D_OT_background_image_add(wmOperatorType *ot)
{
- /* identifiers */
- /* note: having key shortcut here is bad practice,
- * but for now keep because this displays when dragging an image over the 3D viewport */
- ot->name = "Add Background Image";
- ot->description = "Add a new background image";
- ot->idname = "VIEW3D_OT_background_image_add";
+ /* identifiers */
+ /* note: having key shortcut here is bad practice,
+ * but for now keep because this displays when dragging an image over the 3D viewport */
+ ot->name = "Add Background Image";
+ ot->description = "Add a new background image";
+ ot->idname = "VIEW3D_OT_background_image_add";
- /* api callbacks */
- ot->invoke = background_image_add_invoke;
- ot->exec = background_image_add_exec;
- ot->poll = background_image_add_poll;
+ /* api callbacks */
+ ot->invoke = background_image_add_invoke;
+ ot->exec = background_image_add_exec;
+ ot->poll = background_image_add_poll;
- /* flags */
- ot->flag = OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
- /* properties */
- RNA_def_string(ot->srna, "name", "Image", MAX_ID_NAME - 2, "Name", "Image name to assign");
- WM_operator_properties_filesel(
- ot, FILE_TYPE_FOLDER | FILE_TYPE_IMAGE | FILE_TYPE_MOVIE, FILE_SPECIAL, FILE_OPENFILE,
- WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
+ /* properties */
+ RNA_def_string(ot->srna, "name", "Image", MAX_ID_NAME - 2, "Name", "Image name to assign");
+ WM_operator_properties_filesel(ot,
+ FILE_TYPE_FOLDER | FILE_TYPE_IMAGE | FILE_TYPE_MOVIE,
+ FILE_SPECIAL,
+ FILE_OPENFILE,
+ WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH,
+ FILE_DEFAULTDISPLAY,
+ FILE_SORT_ALPHA);
}
/** \} */
@@ -4603,44 +4707,45 @@ void VIEW3D_OT_background_image_add(wmOperatorType *ot)
static int background_image_remove_exec(bContext *C, wmOperator *op)
{
- Camera *cam = CTX_data_pointer_get_type(C, "camera", &RNA_Camera).data;
- const int index = RNA_int_get(op->ptr, "index");
- CameraBGImage *bgpic_rem = BLI_findlink(&cam->bg_images, index);
+ Camera *cam = CTX_data_pointer_get_type(C, "camera", &RNA_Camera).data;
+ const int index = RNA_int_get(op->ptr, "index");
+ CameraBGImage *bgpic_rem = BLI_findlink(&cam->bg_images, index);
- if (bgpic_rem) {
- if (bgpic_rem->source == CAM_BGIMG_SOURCE_IMAGE) {
- id_us_min((ID *)bgpic_rem->ima);
- }
- else if (bgpic_rem->source == CAM_BGIMG_SOURCE_MOVIE) {
- id_us_min((ID *)bgpic_rem->clip);
- }
+ if (bgpic_rem) {
+ if (bgpic_rem->source == CAM_BGIMG_SOURCE_IMAGE) {
+ id_us_min((ID *)bgpic_rem->ima);
+ }
+ else if (bgpic_rem->source == CAM_BGIMG_SOURCE_MOVIE) {
+ id_us_min((ID *)bgpic_rem->clip);
+ }
- BKE_camera_background_image_remove(cam, bgpic_rem);
+ BKE_camera_background_image_remove(cam, bgpic_rem);
- WM_event_add_notifier(C, NC_CAMERA | ND_DRAW_RENDER_VIEWPORT, cam);
- return OPERATOR_FINISHED;
- }
- else {
- return OPERATOR_CANCELLED;
- }
+ WM_event_add_notifier(C, NC_CAMERA | ND_DRAW_RENDER_VIEWPORT, cam);
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
void VIEW3D_OT_background_image_remove(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Remove Background Image";
- ot->description = "Remove a background image from the 3D view";
- ot->idname = "VIEW3D_OT_background_image_remove";
+ /* identifiers */
+ ot->name = "Remove Background Image";
+ ot->description = "Remove a background image from the 3D view";
+ ot->idname = "VIEW3D_OT_background_image_remove";
- /* api callbacks */
- ot->exec = background_image_remove_exec;
- ot->poll = ED_operator_camera;
+ /* api callbacks */
+ ot->exec = background_image_remove_exec;
+ ot->poll = ED_operator_camera;
- /* flags */
- ot->flag = 0;
+ /* flags */
+ ot->flag = 0;
- /* properties */
- RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "Background image index to remove", 0, INT_MAX);
+ /* properties */
+ RNA_def_int(
+ ot->srna, "index", 0, 0, INT_MAX, "Index", "Background image index to remove", 0, INT_MAX);
}
/** \} */
@@ -4653,83 +4758,83 @@ void VIEW3D_OT_background_image_remove(wmOperatorType *ot)
static void calc_local_clipping(float clip_local[6][4], BoundBox *clipbb, float mat[4][4])
{
- BoundBox clipbb_local;
- float imat[4][4];
- int i;
+ BoundBox clipbb_local;
+ float imat[4][4];
+ int i;
- invert_m4_m4(imat, mat);
+ invert_m4_m4(imat, mat);
- for (i = 0; i < 8; i++) {
- mul_v3_m4v3(clipbb_local.vec[i], imat, clipbb->vec[i]);
- }
+ for (i = 0; i < 8; i++) {
+ mul_v3_m4v3(clipbb_local.vec[i], imat, clipbb->vec[i]);
+ }
- ED_view3d_clipping_calc_from_boundbox(clip_local, &clipbb_local, is_negative_m4(mat));
+ ED_view3d_clipping_calc_from_boundbox(clip_local, &clipbb_local, is_negative_m4(mat));
}
void ED_view3d_clipping_local(RegionView3D *rv3d, float mat[4][4])
{
- if (rv3d->rflag & RV3D_CLIPPING) {
- calc_local_clipping(rv3d->clip_local, rv3d->clipbb, mat);
- }
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ calc_local_clipping(rv3d->clip_local, rv3d->clipbb, mat);
+ }
}
static int view3d_clipping_exec(bContext *C, wmOperator *op)
{
- ARegion *ar = CTX_wm_region(C);
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
- rcti rect;
+ ARegion *ar = CTX_wm_region(C);
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ rcti rect;
- WM_operator_properties_border_to_rcti(op, &rect);
+ WM_operator_properties_border_to_rcti(op, &rect);
- rv3d->rflag |= RV3D_CLIPPING;
- rv3d->clipbb = MEM_callocN(sizeof(BoundBox), "clipbb");
+ rv3d->rflag |= RV3D_CLIPPING;
+ rv3d->clipbb = MEM_callocN(sizeof(BoundBox), "clipbb");
- /* NULL object because we don't want it in object space */
- ED_view3d_clipping_calc(rv3d->clipbb, rv3d->clip, ar, NULL, &rect);
+ /* NULL object because we don't want it in object space */
+ ED_view3d_clipping_calc(rv3d->clipbb, rv3d->clip, ar, NULL, &rect);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
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);
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ ARegion *ar = CTX_wm_region(C);
- if (rv3d->rflag & RV3D_CLIPPING) {
- rv3d->rflag &= ~RV3D_CLIPPING;
- ED_region_tag_redraw(ar);
- if (rv3d->clipbb) {
- MEM_freeN(rv3d->clipbb);
- }
- rv3d->clipbb = NULL;
- return OPERATOR_FINISHED;
- }
- else {
- return WM_gesture_box_invoke(C, op, event);
- }
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ rv3d->rflag &= ~RV3D_CLIPPING;
+ ED_region_tag_redraw(ar);
+ if (rv3d->clipbb) {
+ MEM_freeN(rv3d->clipbb);
+ }
+ rv3d->clipbb = NULL;
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return WM_gesture_box_invoke(C, op, event);
+ }
}
void VIEW3D_OT_clip_border(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Clipping Region";
- ot->description = "Set the view clipping region";
- ot->idname = "VIEW3D_OT_clip_border";
+ /* identifiers */
+ ot->name = "Clipping Region";
+ ot->description = "Set the view clipping region";
+ ot->idname = "VIEW3D_OT_clip_border";
- /* api callbacks */
- ot->invoke = view3d_clipping_invoke;
- ot->exec = view3d_clipping_exec;
- ot->modal = WM_gesture_box_modal;
- ot->cancel = WM_gesture_box_cancel;
+ /* api callbacks */
+ ot->invoke = view3d_clipping_invoke;
+ ot->exec = view3d_clipping_exec;
+ ot->modal = WM_gesture_box_modal;
+ ot->cancel = WM_gesture_box_cancel;
- ot->poll = ED_operator_region_view3d_active;
+ ot->poll = ED_operator_region_view3d_active;
- /* flags */
- ot->flag = 0;
+ /* flags */
+ ot->flag = 0;
- /* properties */
- WM_operator_properties_border(ot);
+ /* properties */
+ WM_operator_properties_border(ot);
}
/** \} */
@@ -4740,263 +4845,273 @@ void VIEW3D_OT_clip_border(wmOperatorType *ot)
/* cursor position in vec, result in vec, mval in region coords */
/* note: cannot use event->mval here (called by object_add() */
-void ED_view3d_cursor3d_position(bContext *C, const int mval[2], const bool use_depth, float cursor_co[3])
-{
- ARegion *ar = CTX_wm_region(C);
- View3D *v3d = CTX_wm_view3d(C);
- RegionView3D *rv3d = ar->regiondata;
- bool flip;
- bool depth_used = false;
-
- /* normally the caller should ensure this,
- * but this is called from areas that aren't already dealing with the viewport */
- if (rv3d == NULL) {
- return;
- }
-
- ED_view3d_calc_zfac(rv3d, cursor_co, &flip);
-
- /* reset the depth based on the view offset (we _know_ the offset is infront of us) */
- if (flip) {
- negate_v3_v3(cursor_co, rv3d->ofs);
- /* re initialize, no need to check flip again */
- ED_view3d_calc_zfac(rv3d, cursor_co, NULL /* &flip */ );
- }
-
- if (use_depth) { /* maybe this should be accessed some other way */
- struct Depsgraph *depsgraph = CTX_data_depsgraph(C);
-
- view3d_operator_needs_opengl(C);
- if (ED_view3d_autodist(depsgraph, ar, v3d, mval, cursor_co, true, NULL)) {
- depth_used = true;
- }
- }
-
- if (depth_used == false) {
- float depth_pt[3];
- copy_v3_v3(depth_pt, cursor_co);
- ED_view3d_win_to_3d_int(v3d, ar, depth_pt, mval, cursor_co);
- }
-}
-
-void ED_view3d_cursor3d_position_rotation(
- bContext *C, const int mval[2],
- const bool use_depth, enum eV3DCursorOrient orientation,
- float cursor_co[3], float cursor_quat[4])
-{
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- View3D *v3d = CTX_wm_view3d(C);
- ARegion *ar = CTX_wm_region(C);
- RegionView3D *rv3d = ar->regiondata;
-
- /* XXX, caller should check. */
- if (rv3d == NULL) {
- return;
- }
-
- ED_view3d_cursor3d_position(C, mval, use_depth, cursor_co);
-
- if (orientation == V3D_CURSOR_ORIENT_NONE) {
- /* pass */
- }
- else if (orientation == V3D_CURSOR_ORIENT_VIEW) {
- copy_qt_qt(cursor_quat, rv3d->viewquat);
- cursor_quat[0] *= -1.0f;
- }
- else if (orientation == V3D_CURSOR_ORIENT_XFORM) {
- float mat[3][3];
- ED_transform_calc_orientation_from_type(C, mat);
- mat3_to_quat(cursor_quat, mat);
- }
- else if (orientation == V3D_CURSOR_ORIENT_GEOM) {
- copy_qt_qt(cursor_quat, rv3d->viewquat);
- cursor_quat[0] *= -1.0f;
-
- const float mval_fl[2] = {UNPACK2(mval)};
- float ray_no[3];
- float ray_co[3];
-
- struct SnapObjectContext *snap_context = ED_transform_snap_object_context_create_view3d(
- bmain, scene, CTX_data_depsgraph(C), 0, ar, v3d);
-
- float obmat[4][4];
- Object *ob_dummy = NULL;
- float dist_px = 0;
- if (ED_transform_snap_object_project_view3d_ex(
- snap_context,
- SCE_SNAP_MODE_FACE,
- &(const struct SnapObjectParams){
- .snap_select = SNAP_ALL,
- .use_object_edit_cage = false,
- },
- mval_fl, &dist_px,
- ray_co, ray_no, NULL,
- &ob_dummy, obmat))
- {
- if (use_depth) {
- copy_v3_v3(cursor_co, ray_co);
- }
-
- float tquat[4];
-
- /* Math normal (Z). */
- {
- float z_src[3] = {0, 0, 1};
- mul_qt_v3(cursor_quat, z_src);
- rotation_between_vecs_to_quat(tquat, z_src, ray_no);
- mul_qt_qtqt(cursor_quat, tquat, cursor_quat);
- }
-
- /* Match object matrix (X). */
- {
- const float ortho_axis_dot[3] = {
- dot_v3v3(ray_no, obmat[0]),
- dot_v3v3(ray_no, obmat[1]),
- dot_v3v3(ray_no, obmat[2]),
- };
- const int ortho_axis = axis_dominant_v3_ortho_single(ortho_axis_dot);
- float x_src[3] = {1, 0, 0};
- float x_dst[3];
- mul_qt_v3(cursor_quat, x_src);
- project_plane_v3_v3v3(x_dst, obmat[ortho_axis], ray_no);
- normalize_v3(x_dst);
- rotation_between_vecs_to_quat(tquat, x_src, x_dst);
- mul_qt_qtqt(cursor_quat, tquat, cursor_quat);
- }
- }
- ED_transform_snap_object_context_destroy(snap_context);
- }
-}
-
-void ED_view3d_cursor3d_update(
- bContext *C, const int mval[2],
- const bool use_depth, enum eV3DCursorOrient orientation)
-{
- Scene *scene = CTX_data_scene(C);
- View3D *v3d = CTX_wm_view3d(C);
- ARegion *ar = CTX_wm_region(C);
- RegionView3D *rv3d = ar->regiondata;
-
- View3DCursor *cursor_curr = &scene->cursor;
- View3DCursor cursor_prev = *cursor_curr;
-
- {
- float quat[4], quat_prev[4];
- BKE_scene_cursor_rot_to_quat(cursor_curr, quat);
- copy_qt_qt(quat_prev, quat);
- ED_view3d_cursor3d_position_rotation(
- C, mval,
- use_depth, orientation,
- cursor_curr->location, quat);
-
- if (!equals_v4v4(quat_prev, quat)) {
- if ((cursor_curr->rotation_mode == ROT_MODE_AXISANGLE) &&
- RV3D_VIEW_IS_AXIS(rv3d->view))
- {
- float tmat[3][3], cmat[3][3];
- quat_to_mat3(tmat, quat);
- negate_v3_v3(cursor_curr->rotation_axis, tmat[2]);
- axis_angle_to_mat3(cmat, cursor_curr->rotation_axis, 0.0f);
- cursor_curr->rotation_angle = angle_signed_on_axis_v3v3_v3(cmat[0], tmat[0], cursor_curr->rotation_axis);
- }
- else {
- BKE_scene_cursor_quat_to_rot(cursor_curr, quat, true);
- }
- }
- }
-
- /* offset the cursor lock to avoid jumping to new offset */
- if (v3d->ob_centre_cursor) {
- if (U.uiflag & USER_LOCK_CURSOR_ADJUST) {
-
- float co_2d_curr[2], co_2d_prev[2];
-
- if ((ED_view3d_project_float_global(
- ar, cursor_prev.location, co_2d_prev, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) &&
- (ED_view3d_project_float_global(
- ar, cursor_curr->location, co_2d_curr, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK))
- {
- rv3d->ofs_lock[0] += (co_2d_curr[0] - co_2d_prev[0]) / (ar->winx * 0.5f);
- rv3d->ofs_lock[1] += (co_2d_curr[1] - co_2d_prev[1]) / (ar->winy * 0.5f);
- }
- }
- else {
- /* Cursor may be outside of the view,
- * prevent it getting 'lost', see: T40353 & T45301 */
- zero_v2(rv3d->ofs_lock);
- }
- }
-
- if (v3d->localvd) {
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
- }
- else {
- WM_event_add_notifier(C, NC_SCENE | NA_EDITED, scene);
- }
-
- {
- struct wmMsgBus *mbus = CTX_wm_message_bus(C);
- wmMsgParams_RNA msg_key_params = {{{0}}};
- RNA_pointer_create(&scene->id, &RNA_View3DCursor, &scene->cursor, &msg_key_params.ptr);
- WM_msg_publish_rna_params(mbus, &msg_key_params);
- }
-
- DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
+void ED_view3d_cursor3d_position(bContext *C,
+ const int mval[2],
+ const bool use_depth,
+ float cursor_co[3])
+{
+ ARegion *ar = CTX_wm_region(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ RegionView3D *rv3d = ar->regiondata;
+ bool flip;
+ bool depth_used = false;
+
+ /* normally the caller should ensure this,
+ * but this is called from areas that aren't already dealing with the viewport */
+ if (rv3d == NULL) {
+ return;
+ }
+
+ ED_view3d_calc_zfac(rv3d, cursor_co, &flip);
+
+ /* reset the depth based on the view offset (we _know_ the offset is infront of us) */
+ if (flip) {
+ negate_v3_v3(cursor_co, rv3d->ofs);
+ /* re initialize, no need to check flip again */
+ ED_view3d_calc_zfac(rv3d, cursor_co, NULL /* &flip */);
+ }
+
+ if (use_depth) { /* maybe this should be accessed some other way */
+ struct Depsgraph *depsgraph = CTX_data_depsgraph(C);
+
+ view3d_operator_needs_opengl(C);
+ if (ED_view3d_autodist(depsgraph, ar, v3d, mval, cursor_co, true, NULL)) {
+ depth_used = true;
+ }
+ }
+
+ if (depth_used == false) {
+ float depth_pt[3];
+ copy_v3_v3(depth_pt, cursor_co);
+ ED_view3d_win_to_3d_int(v3d, ar, depth_pt, mval, cursor_co);
+ }
+}
+
+void ED_view3d_cursor3d_position_rotation(bContext *C,
+ const int mval[2],
+ const bool use_depth,
+ enum eV3DCursorOrient orientation,
+ float cursor_co[3],
+ float cursor_quat[4])
+{
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ ARegion *ar = CTX_wm_region(C);
+ RegionView3D *rv3d = ar->regiondata;
+
+ /* XXX, caller should check. */
+ if (rv3d == NULL) {
+ return;
+ }
+
+ ED_view3d_cursor3d_position(C, mval, use_depth, cursor_co);
+
+ if (orientation == V3D_CURSOR_ORIENT_NONE) {
+ /* pass */
+ }
+ else if (orientation == V3D_CURSOR_ORIENT_VIEW) {
+ copy_qt_qt(cursor_quat, rv3d->viewquat);
+ cursor_quat[0] *= -1.0f;
+ }
+ else if (orientation == V3D_CURSOR_ORIENT_XFORM) {
+ float mat[3][3];
+ ED_transform_calc_orientation_from_type(C, mat);
+ mat3_to_quat(cursor_quat, mat);
+ }
+ else if (orientation == V3D_CURSOR_ORIENT_GEOM) {
+ copy_qt_qt(cursor_quat, rv3d->viewquat);
+ cursor_quat[0] *= -1.0f;
+
+ const float mval_fl[2] = {UNPACK2(mval)};
+ float ray_no[3];
+ float ray_co[3];
+
+ struct SnapObjectContext *snap_context = ED_transform_snap_object_context_create_view3d(
+ bmain, scene, CTX_data_depsgraph(C), 0, ar, v3d);
+
+ float obmat[4][4];
+ Object *ob_dummy = NULL;
+ float dist_px = 0;
+ if (ED_transform_snap_object_project_view3d_ex(snap_context,
+ SCE_SNAP_MODE_FACE,
+ &(const struct SnapObjectParams){
+ .snap_select = SNAP_ALL,
+ .use_object_edit_cage = false,
+ },
+ mval_fl,
+ &dist_px,
+ ray_co,
+ ray_no,
+ NULL,
+ &ob_dummy,
+ obmat)) {
+ if (use_depth) {
+ copy_v3_v3(cursor_co, ray_co);
+ }
+
+ float tquat[4];
+
+ /* Math normal (Z). */
+ {
+ float z_src[3] = {0, 0, 1};
+ mul_qt_v3(cursor_quat, z_src);
+ rotation_between_vecs_to_quat(tquat, z_src, ray_no);
+ mul_qt_qtqt(cursor_quat, tquat, cursor_quat);
+ }
+
+ /* Match object matrix (X). */
+ {
+ const float ortho_axis_dot[3] = {
+ dot_v3v3(ray_no, obmat[0]),
+ dot_v3v3(ray_no, obmat[1]),
+ dot_v3v3(ray_no, obmat[2]),
+ };
+ const int ortho_axis = axis_dominant_v3_ortho_single(ortho_axis_dot);
+ float x_src[3] = {1, 0, 0};
+ float x_dst[3];
+ mul_qt_v3(cursor_quat, x_src);
+ project_plane_v3_v3v3(x_dst, obmat[ortho_axis], ray_no);
+ normalize_v3(x_dst);
+ rotation_between_vecs_to_quat(tquat, x_src, x_dst);
+ mul_qt_qtqt(cursor_quat, tquat, cursor_quat);
+ }
+ }
+ ED_transform_snap_object_context_destroy(snap_context);
+ }
+}
+
+void ED_view3d_cursor3d_update(bContext *C,
+ const int mval[2],
+ const bool use_depth,
+ enum eV3DCursorOrient orientation)
+{
+ Scene *scene = CTX_data_scene(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ ARegion *ar = CTX_wm_region(C);
+ RegionView3D *rv3d = ar->regiondata;
+
+ View3DCursor *cursor_curr = &scene->cursor;
+ View3DCursor cursor_prev = *cursor_curr;
+
+ {
+ float quat[4], quat_prev[4];
+ BKE_scene_cursor_rot_to_quat(cursor_curr, quat);
+ copy_qt_qt(quat_prev, quat);
+ ED_view3d_cursor3d_position_rotation(
+ C, mval, use_depth, orientation, cursor_curr->location, quat);
+
+ if (!equals_v4v4(quat_prev, quat)) {
+ if ((cursor_curr->rotation_mode == ROT_MODE_AXISANGLE) && RV3D_VIEW_IS_AXIS(rv3d->view)) {
+ float tmat[3][3], cmat[3][3];
+ quat_to_mat3(tmat, quat);
+ negate_v3_v3(cursor_curr->rotation_axis, tmat[2]);
+ axis_angle_to_mat3(cmat, cursor_curr->rotation_axis, 0.0f);
+ cursor_curr->rotation_angle = angle_signed_on_axis_v3v3_v3(
+ cmat[0], tmat[0], cursor_curr->rotation_axis);
+ }
+ else {
+ BKE_scene_cursor_quat_to_rot(cursor_curr, quat, true);
+ }
+ }
+ }
+
+ /* offset the cursor lock to avoid jumping to new offset */
+ if (v3d->ob_centre_cursor) {
+ if (U.uiflag & USER_LOCK_CURSOR_ADJUST) {
+
+ float co_2d_curr[2], co_2d_prev[2];
+
+ if ((ED_view3d_project_float_global(
+ ar, cursor_prev.location, co_2d_prev, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) &&
+ (ED_view3d_project_float_global(
+ ar, cursor_curr->location, co_2d_curr, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK)) {
+ rv3d->ofs_lock[0] += (co_2d_curr[0] - co_2d_prev[0]) / (ar->winx * 0.5f);
+ rv3d->ofs_lock[1] += (co_2d_curr[1] - co_2d_prev[1]) / (ar->winy * 0.5f);
+ }
+ }
+ else {
+ /* Cursor may be outside of the view,
+ * prevent it getting 'lost', see: T40353 & T45301 */
+ zero_v2(rv3d->ofs_lock);
+ }
+ }
+
+ if (v3d->localvd) {
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
+ }
+ else {
+ WM_event_add_notifier(C, NC_SCENE | NA_EDITED, scene);
+ }
+
+ {
+ struct wmMsgBus *mbus = CTX_wm_message_bus(C);
+ wmMsgParams_RNA msg_key_params = {{{0}}};
+ RNA_pointer_create(&scene->id, &RNA_View3DCursor, &scene->cursor, &msg_key_params.ptr);
+ WM_msg_publish_rna_params(mbus, &msg_key_params);
+ }
+
+ DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
}
static int view3d_cursor3d_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- bool use_depth = (U.uiflag & USER_DEPTH_CURSOR);
- {
- PropertyRNA *prop = RNA_struct_find_property(op->ptr, "use_depth");
- if (RNA_property_is_set(op->ptr, prop)) {
- use_depth = RNA_property_boolean_get(op->ptr, prop);
- }
- else {
- RNA_property_boolean_set(op->ptr, prop, use_depth);
- }
- }
- const enum eV3DCursorOrient orientation = RNA_enum_get(op->ptr, "orientation");
- ED_view3d_cursor3d_update(C, event->mval, use_depth, orientation);
+ bool use_depth = (U.uiflag & USER_DEPTH_CURSOR);
+ {
+ PropertyRNA *prop = RNA_struct_find_property(op->ptr, "use_depth");
+ if (RNA_property_is_set(op->ptr, prop)) {
+ use_depth = RNA_property_boolean_get(op->ptr, prop);
+ }
+ else {
+ RNA_property_boolean_set(op->ptr, prop, use_depth);
+ }
+ }
+ const enum eV3DCursorOrient orientation = RNA_enum_get(op->ptr, "orientation");
+ ED_view3d_cursor3d_update(C, event->mval, use_depth, orientation);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void VIEW3D_OT_cursor3d(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Set 3D Cursor";
- ot->description = "Set the location of the 3D cursor";
- ot->idname = "VIEW3D_OT_cursor3d";
+ /* identifiers */
+ ot->name = "Set 3D Cursor";
+ ot->description = "Set the location of the 3D cursor";
+ ot->idname = "VIEW3D_OT_cursor3d";
- /* api callbacks */
- ot->invoke = view3d_cursor3d_invoke;
+ /* api callbacks */
+ ot->invoke = view3d_cursor3d_invoke;
- ot->poll = ED_operator_region_view3d_active;
+ ot->poll = ED_operator_region_view3d_active;
- /* flags */
-// ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+ /* flags */
+ // ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
- PropertyRNA *prop;
- static const EnumPropertyItem orientation_items[] = {
- {V3D_CURSOR_ORIENT_NONE, "NONE", 0, "None", "Leave orientation unchanged"},
- {V3D_CURSOR_ORIENT_VIEW, "VIEW", 0, "View", "Orient to the viewport"},
- {V3D_CURSOR_ORIENT_XFORM, "XFORM", 0, "Transform", "Orient to the current transform setting"},
- {V3D_CURSOR_ORIENT_GEOM, "GEOM", 0, "Geometry", "Match the surface normal"},
- {0, NULL, 0, NULL, NULL},
- };
+ PropertyRNA *prop;
+ static const EnumPropertyItem orientation_items[] = {
+ {V3D_CURSOR_ORIENT_NONE, "NONE", 0, "None", "Leave orientation unchanged"},
+ {V3D_CURSOR_ORIENT_VIEW, "VIEW", 0, "View", "Orient to the viewport"},
+ {V3D_CURSOR_ORIENT_XFORM,
+ "XFORM",
+ 0,
+ "Transform",
+ "Orient to the current transform setting"},
+ {V3D_CURSOR_ORIENT_GEOM, "GEOM", 0, "Geometry", "Match the surface normal"},
+ {0, NULL, 0, NULL, NULL},
+ };
- prop = RNA_def_boolean(
- ot->srna, "use_depth", true, "Surface Project",
- "Project onto the surface");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_boolean(
+ ot->srna, "use_depth", true, "Surface Project", "Project onto the surface");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- prop = RNA_def_enum(
- ot->srna, "orientation", orientation_items, V3D_CURSOR_ORIENT_VIEW,
- "Orientation", "Preset viewpoint to use");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_enum(ot->srna,
+ "orientation",
+ orientation_items,
+ V3D_CURSOR_ORIENT_VIEW,
+ "Orientation",
+ "Preset viewpoint to use");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/** \} */
@@ -5006,120 +5121,114 @@ void VIEW3D_OT_cursor3d(wmOperatorType *ot)
* \{ */
static const EnumPropertyItem prop_shading_type_items[] = {
- {OB_WIRE, "WIREFRAME", 0, "Wireframe", "Toggle wireframe shading"},
- {OB_SOLID, "SOLID", 0, "Solid", "Toggle solid shading"},
- {OB_MATERIAL, "MATERIAL", 0, "LookDev", "Toggle lookdev shading"},
- {OB_RENDER, "RENDERED", 0, "Rendered", "Toggle rendered shading"},
- {0, NULL, 0, NULL, NULL},
+ {OB_WIRE, "WIREFRAME", 0, "Wireframe", "Toggle wireframe shading"},
+ {OB_SOLID, "SOLID", 0, "Solid", "Toggle solid shading"},
+ {OB_MATERIAL, "MATERIAL", 0, "LookDev", "Toggle lookdev shading"},
+ {OB_RENDER, "RENDERED", 0, "Rendered", "Toggle rendered shading"},
+ {0, NULL, 0, NULL, NULL},
};
static int toggle_shading_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
- View3D *v3d = CTX_wm_view3d(C);
- ScrArea *sa = CTX_wm_area(C);
- int type = RNA_enum_get(op->ptr, "type");
-
- if (type == OB_SOLID) {
- if (v3d->shading.type != type) {
- v3d->shading.type = type;
- }
- else if (v3d->shading.type == OB_WIRE) {
- v3d->shading.type = OB_SOLID;
- }
- else {
- v3d->shading.type = OB_WIRE;
- }
- }
- else {
- char *prev_type = (
- (type == OB_WIRE) ?
- &v3d->shading.prev_type_wire :
- &v3d->shading.prev_type);
- if (v3d->shading.type == type) {
- if (*prev_type == type || !ELEM(*prev_type, OB_WIRE, OB_SOLID, OB_MATERIAL, OB_RENDER)) {
- *prev_type = OB_SOLID;
- }
- v3d->shading.type = *prev_type;
- }
- else {
- *prev_type = v3d->shading.type;
- v3d->shading.type = type;
- }
- }
-
- ED_view3d_shade_update(bmain, v3d, sa);
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
-
- return OPERATOR_FINISHED;
+ Main *bmain = CTX_data_main(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ ScrArea *sa = CTX_wm_area(C);
+ int type = RNA_enum_get(op->ptr, "type");
+
+ if (type == OB_SOLID) {
+ if (v3d->shading.type != type) {
+ v3d->shading.type = type;
+ }
+ else if (v3d->shading.type == OB_WIRE) {
+ v3d->shading.type = OB_SOLID;
+ }
+ else {
+ v3d->shading.type = OB_WIRE;
+ }
+ }
+ else {
+ char *prev_type = ((type == OB_WIRE) ? &v3d->shading.prev_type_wire : &v3d->shading.prev_type);
+ if (v3d->shading.type == type) {
+ if (*prev_type == type || !ELEM(*prev_type, OB_WIRE, OB_SOLID, OB_MATERIAL, OB_RENDER)) {
+ *prev_type = OB_SOLID;
+ }
+ v3d->shading.type = *prev_type;
+ }
+ else {
+ *prev_type = v3d->shading.type;
+ v3d->shading.type = type;
+ }
+ }
+
+ ED_view3d_shade_update(bmain, v3d, sa);
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
+
+ return OPERATOR_FINISHED;
}
void VIEW3D_OT_toggle_shading(wmOperatorType *ot)
{
- PropertyRNA *prop;
+ PropertyRNA *prop;
- /* identifiers */
- ot->name = "Toggle Shading Type";
- ot->description = "Toggle shading type in 3D viewport";
- ot->idname = "VIEW3D_OT_toggle_shading";
+ /* identifiers */
+ ot->name = "Toggle Shading Type";
+ ot->description = "Toggle shading type in 3D viewport";
+ ot->idname = "VIEW3D_OT_toggle_shading";
- /* api callbacks */
- ot->exec = toggle_shading_exec;
- ot->poll = ED_operator_view3d_active;
+ /* api callbacks */
+ ot->exec = toggle_shading_exec;
+ ot->poll = ED_operator_view3d_active;
- prop = RNA_def_enum(ot->srna, "type", prop_shading_type_items, 0, "Type", "Shading type to toggle");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_enum(
+ ot->srna, "type", prop_shading_type_items, 0, "Type", "Shading type to toggle");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/** \name Toggle XRay
* \{ */
static int toggle_xray_exec(bContext *C, wmOperator *op)
{
- View3D *v3d = CTX_wm_view3d(C);
- ScrArea *sa = CTX_wm_area(C);
- Object *obact = CTX_data_active_object(C);
-
- if (obact &&
- ((obact->mode & OB_MODE_POSE) ||
- ((obact->mode & OB_MODE_WEIGHT_PAINT) && BKE_object_pose_armature_get(obact))))
- {
- v3d->overlay.flag ^= V3D_OVERLAY_BONE_SELECT;
- }
- else {
- const bool xray_active = (
- (obact && (obact->mode & OB_MODE_EDIT)) ||
- ELEM(v3d->shading.type, OB_WIRE, OB_SOLID));
-
- if (v3d->shading.type == OB_WIRE) {
- v3d->shading.flag ^= V3D_SHADING_XRAY_BONE;
- }
- else {
- v3d->shading.flag ^= V3D_SHADING_XRAY;
- }
- if (!xray_active) {
- BKE_report(op->reports, RPT_INFO, "X-Ray not available in current mode");
- }
- }
-
- ED_area_tag_redraw(sa);
-
- return OPERATOR_FINISHED;
+ View3D *v3d = CTX_wm_view3d(C);
+ ScrArea *sa = CTX_wm_area(C);
+ Object *obact = CTX_data_active_object(C);
+
+ if (obact && ((obact->mode & OB_MODE_POSE) ||
+ ((obact->mode & OB_MODE_WEIGHT_PAINT) && BKE_object_pose_armature_get(obact)))) {
+ v3d->overlay.flag ^= V3D_OVERLAY_BONE_SELECT;
+ }
+ else {
+ const bool xray_active = ((obact && (obact->mode & OB_MODE_EDIT)) ||
+ ELEM(v3d->shading.type, OB_WIRE, OB_SOLID));
+
+ if (v3d->shading.type == OB_WIRE) {
+ v3d->shading.flag ^= V3D_SHADING_XRAY_BONE;
+ }
+ else {
+ v3d->shading.flag ^= V3D_SHADING_XRAY;
+ }
+ if (!xray_active) {
+ BKE_report(op->reports, RPT_INFO, "X-Ray not available in current mode");
+ }
+ }
+
+ ED_area_tag_redraw(sa);
+
+ return OPERATOR_FINISHED;
}
void VIEW3D_OT_toggle_xray(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Toggle X-Ray";
- ot->idname = "VIEW3D_OT_toggle_xray";
+ /* identifiers */
+ ot->name = "Toggle X-Ray";
+ ot->idname = "VIEW3D_OT_toggle_xray";
- /* api callbacks */
- ot->exec = toggle_xray_exec;
- ot->poll = ED_operator_view3d_active;
+ /* api callbacks */
+ ot->exec = toggle_xray_exec;
+ ot->poll = ED_operator_view3d_active;
}
/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c
index b80ce2c49b0..8dc3abe6af5 100644
--- a/source/blender/editors/space_view3d/view3d_fly.c
+++ b/source/blender/editors/space_view3d/view3d_fly.c
@@ -38,7 +38,6 @@
#include "BLT_translation.h"
-
#include "WM_api.h"
#include "WM_types.h"
@@ -54,1068 +53,1085 @@
#include "DEG_depsgraph.h"
-#include "view3d_intern.h" /* own include */
+#include "view3d_intern.h" /* own include */
/* NOTE: these defines are saved in keymap files,
* do not change values but just add new ones */
enum {
- FLY_MODAL_CANCEL = 1,
- FLY_MODAL_CONFIRM,
- FLY_MODAL_ACCELERATE,
- FLY_MODAL_DECELERATE,
- FLY_MODAL_PAN_ENABLE,
- FLY_MODAL_PAN_DISABLE,
- FLY_MODAL_DIR_FORWARD,
- FLY_MODAL_DIR_BACKWARD,
- FLY_MODAL_DIR_LEFT,
- FLY_MODAL_DIR_RIGHT,
- FLY_MODAL_DIR_UP,
- FLY_MODAL_DIR_DOWN,
- FLY_MODAL_AXIS_LOCK_X,
- FLY_MODAL_AXIS_LOCK_Z,
- FLY_MODAL_PRECISION_ENABLE,
- FLY_MODAL_PRECISION_DISABLE,
- FLY_MODAL_FREELOOK_ENABLE,
- FLY_MODAL_FREELOOK_DISABLE,
- FLY_MODAL_SPEED, /* mousepan typically */
+ FLY_MODAL_CANCEL = 1,
+ FLY_MODAL_CONFIRM,
+ FLY_MODAL_ACCELERATE,
+ FLY_MODAL_DECELERATE,
+ FLY_MODAL_PAN_ENABLE,
+ FLY_MODAL_PAN_DISABLE,
+ FLY_MODAL_DIR_FORWARD,
+ FLY_MODAL_DIR_BACKWARD,
+ FLY_MODAL_DIR_LEFT,
+ FLY_MODAL_DIR_RIGHT,
+ FLY_MODAL_DIR_UP,
+ FLY_MODAL_DIR_DOWN,
+ FLY_MODAL_AXIS_LOCK_X,
+ FLY_MODAL_AXIS_LOCK_Z,
+ FLY_MODAL_PRECISION_ENABLE,
+ FLY_MODAL_PRECISION_DISABLE,
+ FLY_MODAL_FREELOOK_ENABLE,
+ FLY_MODAL_FREELOOK_DISABLE,
+ FLY_MODAL_SPEED, /* mousepan typically */
};
/* relative view axis locking - xlock, zlock */
typedef enum eFlyPanState {
- /* disabled */
- FLY_AXISLOCK_STATE_OFF = 0,
+ /* disabled */
+ FLY_AXISLOCK_STATE_OFF = 0,
- /* enabled but not checking because mouse hasn't moved outside the margin since locking was
- * checked an not needed when the mouse moves, locking is set to 2 so checks are done. */
- FLY_AXISLOCK_STATE_IDLE = 1,
+ /* enabled but not checking because mouse hasn't moved outside the margin since locking was
+ * checked an not needed when the mouse moves, locking is set to 2 so checks are done. */
+ FLY_AXISLOCK_STATE_IDLE = 1,
- /* mouse moved and checking needed,
- * if no view altering is done its changed back to #FLY_AXISLOCK_STATE_IDLE */
- FLY_AXISLOCK_STATE_ACTIVE = 2,
+ /* mouse moved and checking needed,
+ * if no view altering is done its changed back to #FLY_AXISLOCK_STATE_IDLE */
+ FLY_AXISLOCK_STATE_ACTIVE = 2,
} eFlyPanState;
/* called in transform_ops.c, on each regeneration of keymaps */
void fly_modal_keymap(wmKeyConfig *keyconf)
{
- static const EnumPropertyItem modal_items[] = {
- {FLY_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
- {FLY_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
+ static const EnumPropertyItem modal_items[] = {
+ {FLY_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
+ {FLY_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
- {FLY_MODAL_DIR_FORWARD, "FORWARD", 0, "Forward", ""},
- {FLY_MODAL_DIR_BACKWARD, "BACKWARD", 0, "Backward", ""},
- {FLY_MODAL_DIR_LEFT, "LEFT", 0, "Left", ""},
- {FLY_MODAL_DIR_RIGHT, "RIGHT", 0, "Right", ""},
- {FLY_MODAL_DIR_UP, "UP", 0, "Up", ""},
- {FLY_MODAL_DIR_DOWN, "DOWN", 0, "Down", ""},
+ {FLY_MODAL_DIR_FORWARD, "FORWARD", 0, "Forward", ""},
+ {FLY_MODAL_DIR_BACKWARD, "BACKWARD", 0, "Backward", ""},
+ {FLY_MODAL_DIR_LEFT, "LEFT", 0, "Left", ""},
+ {FLY_MODAL_DIR_RIGHT, "RIGHT", 0, "Right", ""},
+ {FLY_MODAL_DIR_UP, "UP", 0, "Up", ""},
+ {FLY_MODAL_DIR_DOWN, "DOWN", 0, "Down", ""},
- {FLY_MODAL_PAN_ENABLE, "PAN_ENABLE", 0, "Pan", ""},
- {FLY_MODAL_PAN_DISABLE, "PAN_DISABLE", 0, "Pan (Off)", ""},
+ {FLY_MODAL_PAN_ENABLE, "PAN_ENABLE", 0, "Pan", ""},
+ {FLY_MODAL_PAN_DISABLE, "PAN_DISABLE", 0, "Pan (Off)", ""},
- {FLY_MODAL_ACCELERATE, "ACCELERATE", 0, "Accelerate", ""},
- {FLY_MODAL_DECELERATE, "DECELERATE", 0, "Decelerate", ""},
+ {FLY_MODAL_ACCELERATE, "ACCELERATE", 0, "Accelerate", ""},
+ {FLY_MODAL_DECELERATE, "DECELERATE", 0, "Decelerate", ""},
- {FLY_MODAL_AXIS_LOCK_X, "AXIS_LOCK_X", 0, "X Axis Correction", "X axis correction (toggle)"},
- {FLY_MODAL_AXIS_LOCK_Z, "AXIS_LOCK_Z", 0, "X Axis Correction", "Z axis correction (toggle)"},
+ {FLY_MODAL_AXIS_LOCK_X, "AXIS_LOCK_X", 0, "X Axis Correction", "X axis correction (toggle)"},
+ {FLY_MODAL_AXIS_LOCK_Z, "AXIS_LOCK_Z", 0, "X Axis Correction", "Z axis correction (toggle)"},
- {FLY_MODAL_PRECISION_ENABLE, "PRECISION_ENABLE", 0, "Precision", ""},
- {FLY_MODAL_PRECISION_DISABLE, "PRECISION_DISABLE", 0, "Precision (Off)", ""},
+ {FLY_MODAL_PRECISION_ENABLE, "PRECISION_ENABLE", 0, "Precision", ""},
+ {FLY_MODAL_PRECISION_DISABLE, "PRECISION_DISABLE", 0, "Precision (Off)", ""},
- {FLY_MODAL_FREELOOK_ENABLE, "FREELOOK_ENABLE", 0, "Rotation", ""},
- {FLY_MODAL_FREELOOK_DISABLE, "FREELOOK_DISABLE", 0, "Rotation (Off)", ""},
+ {FLY_MODAL_FREELOOK_ENABLE, "FREELOOK_ENABLE", 0, "Rotation", ""},
+ {FLY_MODAL_FREELOOK_DISABLE, "FREELOOK_DISABLE", 0, "Rotation (Off)", ""},
- {0, NULL, 0, NULL, NULL},
- };
+ {0, NULL, 0, NULL, NULL},
+ };
- wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Fly Modal");
+ wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Fly Modal");
- /* this function is called for each spacetype, only needs to add map once */
- if (keymap && keymap->modal_items) {
- return;
- }
+ /* this function is called for each spacetype, only needs to add map once */
+ if (keymap && keymap->modal_items) {
+ return;
+ }
- keymap = WM_modalkeymap_add(keyconf, "View3D Fly Modal", modal_items);
+ keymap = WM_modalkeymap_add(keyconf, "View3D Fly Modal", modal_items);
- /* assign map to operators */
- WM_modalkeymap_assign(keymap, "VIEW3D_OT_fly");
+ /* assign map to operators */
+ WM_modalkeymap_assign(keymap, "VIEW3D_OT_fly");
}
typedef struct FlyInfo {
- /* context stuff */
- RegionView3D *rv3d;
- View3D *v3d;
- ARegion *ar;
- struct Depsgraph *depsgraph;
- Scene *scene;
-
- wmTimer *timer; /* needed for redraws */
-
- short state;
- bool redraw;
- bool use_precision;
- /* if the user presses shift they can look about
- * without moving the direction there looking */
- bool use_freelook;
-
- int mval[2]; /* latest 2D mouse values */
- int center_mval[2]; /* center mouse values */
- float width, height; /* camera viewport dimensions */
+ /* context stuff */
+ RegionView3D *rv3d;
+ View3D *v3d;
+ ARegion *ar;
+ struct Depsgraph *depsgraph;
+ Scene *scene;
+
+ wmTimer *timer; /* needed for redraws */
+
+ short state;
+ bool redraw;
+ bool use_precision;
+ /* if the user presses shift they can look about
+ * without moving the direction there looking */
+ bool use_freelook;
+
+ int mval[2]; /* latest 2D mouse values */
+ int center_mval[2]; /* center mouse values */
+ float width, height; /* camera viewport dimensions */
#ifdef WITH_INPUT_NDOF
- wmNDOFMotionData *ndof; /* latest 3D mouse values */
+ wmNDOFMotionData *ndof; /* latest 3D mouse values */
#endif
- /* fly state state */
- float speed; /* the speed the view is moving per redraw */
- short axis; /* Axis index to move along by default Z to move along the view */
- bool pan_view; /* when true, pan the view instead of rotating */
+ /* fly state state */
+ float speed; /* the speed the view is moving per redraw */
+ short axis; /* Axis index to move along by default Z to move along the view */
+ bool pan_view; /* when true, pan the view instead of rotating */
- eFlyPanState xlock, zlock;
- float xlock_momentum, zlock_momentum; /* nicer dynamics */
- float grid; /* world scale 1.0 default */
+ eFlyPanState xlock, zlock;
+ float xlock_momentum, zlock_momentum; /* nicer dynamics */
+ float grid; /* world scale 1.0 default */
- /* compare between last state */
- double time_lastwheel; /* used to accelerate when using the mousewheel a lot */
- double time_lastdraw; /* time between draws */
+ /* compare between last state */
+ double time_lastwheel; /* used to accelerate when using the mousewheel a lot */
+ double time_lastdraw; /* time between draws */
- void *draw_handle_pixel;
+ void *draw_handle_pixel;
- /* use for some lag */
- float dvec_prev[3]; /* old for some lag */
+ /* use for some lag */
+ float dvec_prev[3]; /* old for some lag */
- struct View3DCameraControl *v3d_camera_control;
+ struct View3DCameraControl *v3d_camera_control;
} FlyInfo;
static void drawFlyPixel(const struct bContext *UNUSED(C), ARegion *UNUSED(ar), void *arg)
{
- FlyInfo *fly = arg;
- rctf viewborder;
- int xoff, yoff;
- float x1, x2, y1, y2;
+ FlyInfo *fly = arg;
+ rctf viewborder;
+ int xoff, yoff;
+ float x1, x2, y1, y2;
- if (ED_view3d_cameracontrol_object_get(fly->v3d_camera_control)) {
- ED_view3d_calc_camera_border(fly->scene, fly->depsgraph, fly->ar, fly->v3d, fly->rv3d, &viewborder, false);
- xoff = viewborder.xmin;
- yoff = viewborder.ymin;
- }
- else {
- xoff = 0;
- yoff = 0;
- }
+ if (ED_view3d_cameracontrol_object_get(fly->v3d_camera_control)) {
+ ED_view3d_calc_camera_border(
+ fly->scene, fly->depsgraph, fly->ar, fly->v3d, fly->rv3d, &viewborder, false);
+ xoff = viewborder.xmin;
+ yoff = viewborder.ymin;
+ }
+ else {
+ xoff = 0;
+ yoff = 0;
+ }
- /* draws 4 edge brackets that frame the safe area where the
- * mouse can move during fly mode without spinning the view */
+ /* draws 4 edge brackets that frame the safe area where the
+ * mouse can move during fly mode without spinning the view */
- x1 = xoff + 0.45f * fly->width;
- y1 = yoff + 0.45f * fly->height;
- x2 = xoff + 0.55f * fly->width;
- y2 = yoff + 0.55f * fly->height;
+ x1 = xoff + 0.45f * fly->width;
+ y1 = yoff + 0.45f * fly->height;
+ x2 = xoff + 0.55f * fly->width;
+ y2 = yoff + 0.55f * fly->height;
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformThemeColor(TH_VIEW_OVERLAY);
+ immUniformThemeColor(TH_VIEW_OVERLAY);
- immBegin(GPU_PRIM_LINES, 16);
+ immBegin(GPU_PRIM_LINES, 16);
- /* bottom left */
- immVertex2f(pos, x1, y1);
- immVertex2f(pos, x1, y1 + 5);
+ /* bottom left */
+ immVertex2f(pos, x1, y1);
+ immVertex2f(pos, x1, y1 + 5);
- immVertex2f(pos, x1, y1);
- immVertex2f(pos, x1 + 5, y1);
+ immVertex2f(pos, x1, y1);
+ immVertex2f(pos, x1 + 5, y1);
- /* top right */
- immVertex2f(pos, x2, y2);
- immVertex2f(pos, x2, y2 - 5);
+ /* top right */
+ immVertex2f(pos, x2, y2);
+ immVertex2f(pos, x2, y2 - 5);
- immVertex2f(pos, x2, y2);
- immVertex2f(pos, x2 - 5, y2);
+ immVertex2f(pos, x2, y2);
+ immVertex2f(pos, x2 - 5, y2);
- /* top left */
- immVertex2f(pos, x1, y2);
- immVertex2f(pos, x1, y2 - 5);
+ /* top left */
+ immVertex2f(pos, x1, y2);
+ immVertex2f(pos, x1, y2 - 5);
- immVertex2f(pos, x1, y2);
- immVertex2f(pos, x1 + 5, y2);
+ immVertex2f(pos, x1, y2);
+ immVertex2f(pos, x1 + 5, y2);
- /* bottom right */
- immVertex2f(pos, x2, y1);
- immVertex2f(pos, x2, y1 + 5);
+ /* bottom right */
+ immVertex2f(pos, x2, y1);
+ immVertex2f(pos, x2, y1 + 5);
- immVertex2f(pos, x2, y1);
- immVertex2f(pos, x2 - 5, y1);
+ immVertex2f(pos, x2, y1);
+ immVertex2f(pos, x2 - 5, y1);
- immEnd();
- immUnbindProgram();
+ immEnd();
+ immUnbindProgram();
}
static void fly_update_header(bContext *C, wmOperator *op, FlyInfo *fly)
{
- char header[UI_MAX_DRAW_STR];
- char buf[UI_MAX_DRAW_STR];
+ char header[UI_MAX_DRAW_STR];
+ char buf[UI_MAX_DRAW_STR];
- char *p = buf;
- int available_len = sizeof(buf);
+ char *p = buf;
+ int available_len = sizeof(buf);
#define WM_MODALKEY(_id) \
- WM_modalkeymap_operator_items_to_string_buf(op->type, (_id), true, UI_MAX_SHORTCUT_STR, &available_len, &p)
-
- BLI_snprintf(header, sizeof(header), IFACE_("%s: confirm, %s: cancel, "
- "%s: pan enable, "
- "%s|%s|%s|%s|%s|%s: direction, "
- "%s: slow, %s: free look, "
- "%s: Upright x axis (%s), "
- "%s: Upright z axis (%s), "
- "%s: increase speed, %s: decrease speed"),
- WM_MODALKEY(FLY_MODAL_CONFIRM), WM_MODALKEY(FLY_MODAL_CANCEL),
- WM_MODALKEY(FLY_MODAL_PAN_ENABLE),
- WM_MODALKEY(FLY_MODAL_DIR_FORWARD), WM_MODALKEY(FLY_MODAL_DIR_LEFT),
- WM_MODALKEY(FLY_MODAL_DIR_BACKWARD), WM_MODALKEY(FLY_MODAL_DIR_RIGHT),
- WM_MODALKEY(FLY_MODAL_DIR_UP), WM_MODALKEY(FLY_MODAL_DIR_DOWN),
- WM_MODALKEY(FLY_MODAL_PRECISION_ENABLE), WM_MODALKEY(FLY_MODAL_FREELOOK_ENABLE),
- WM_MODALKEY(FLY_MODAL_AXIS_LOCK_X), WM_bool_as_string(fly->xlock != FLY_AXISLOCK_STATE_OFF),
- WM_MODALKEY(FLY_MODAL_AXIS_LOCK_Z), WM_bool_as_string(fly->zlock != FLY_AXISLOCK_STATE_OFF),
- WM_MODALKEY(FLY_MODAL_ACCELERATE), WM_MODALKEY(FLY_MODAL_DECELERATE));
+ WM_modalkeymap_operator_items_to_string_buf( \
+ op->type, (_id), true, UI_MAX_SHORTCUT_STR, &available_len, &p)
+
+ BLI_snprintf(header,
+ sizeof(header),
+ IFACE_("%s: confirm, %s: cancel, "
+ "%s: pan enable, "
+ "%s|%s|%s|%s|%s|%s: direction, "
+ "%s: slow, %s: free look, "
+ "%s: Upright x axis (%s), "
+ "%s: Upright z axis (%s), "
+ "%s: increase speed, %s: decrease speed"),
+ WM_MODALKEY(FLY_MODAL_CONFIRM),
+ WM_MODALKEY(FLY_MODAL_CANCEL),
+ WM_MODALKEY(FLY_MODAL_PAN_ENABLE),
+ WM_MODALKEY(FLY_MODAL_DIR_FORWARD),
+ WM_MODALKEY(FLY_MODAL_DIR_LEFT),
+ WM_MODALKEY(FLY_MODAL_DIR_BACKWARD),
+ WM_MODALKEY(FLY_MODAL_DIR_RIGHT),
+ WM_MODALKEY(FLY_MODAL_DIR_UP),
+ WM_MODALKEY(FLY_MODAL_DIR_DOWN),
+ WM_MODALKEY(FLY_MODAL_PRECISION_ENABLE),
+ WM_MODALKEY(FLY_MODAL_FREELOOK_ENABLE),
+ WM_MODALKEY(FLY_MODAL_AXIS_LOCK_X),
+ WM_bool_as_string(fly->xlock != FLY_AXISLOCK_STATE_OFF),
+ WM_MODALKEY(FLY_MODAL_AXIS_LOCK_Z),
+ WM_bool_as_string(fly->zlock != FLY_AXISLOCK_STATE_OFF),
+ WM_MODALKEY(FLY_MODAL_ACCELERATE),
+ WM_MODALKEY(FLY_MODAL_DECELERATE));
#undef WM_MODALKEY
- ED_workspace_status_text(C, header);
+ ED_workspace_status_text(C, header);
}
/* FlyInfo->state */
enum {
- FLY_RUNNING = 0,
- FLY_CANCEL = 1,
- FLY_CONFIRM = 2,
+ FLY_RUNNING = 0,
+ FLY_CANCEL = 1,
+ FLY_CONFIRM = 2,
};
static bool initFlyInfo(bContext *C, FlyInfo *fly, wmOperator *op, const wmEvent *event)
{
- wmWindow *win = CTX_wm_window(C);
- rctf viewborder;
+ wmWindow *win = CTX_wm_window(C);
+ rctf viewborder;
- float upvec[3]; /* tmp */
- float mat[3][3];
+ float upvec[3]; /* tmp */
+ float mat[3][3];
- fly->rv3d = CTX_wm_region_view3d(C);
- fly->v3d = CTX_wm_view3d(C);
- fly->ar = CTX_wm_region(C);
- fly->depsgraph = CTX_data_depsgraph(C);
- fly->scene = CTX_data_scene(C);
+ fly->rv3d = CTX_wm_region_view3d(C);
+ fly->v3d = CTX_wm_view3d(C);
+ fly->ar = CTX_wm_region(C);
+ fly->depsgraph = CTX_data_depsgraph(C);
+ fly->scene = CTX_data_scene(C);
#ifdef NDOF_FLY_DEBUG
- puts("\n-- fly begin --");
+ puts("\n-- fly begin --");
#endif
- /* sanity check: for rare but possible case (if lib-linking the camera fails) */
- if ((fly->rv3d->persp == RV3D_CAMOB) && (fly->v3d->camera == NULL)) {
- fly->rv3d->persp = RV3D_PERSP;
- }
-
- if (fly->rv3d->persp == RV3D_CAMOB && ID_IS_LINKED(fly->v3d->camera)) {
- BKE_report(op->reports, RPT_ERROR, "Cannot fly a camera from an external library");
- return false;
- }
-
- if (ED_view3d_offset_lock_check(fly->v3d, fly->rv3d)) {
- BKE_report(op->reports, RPT_ERROR, "Cannot fly when the view offset is locked");
- return false;
- }
-
- if (fly->rv3d->persp == RV3D_CAMOB && fly->v3d->camera->constraints.first) {
- BKE_report(op->reports, RPT_ERROR, "Cannot fly an object with constraints");
- return false;
- }
-
- fly->state = FLY_RUNNING;
- fly->speed = 0.0f;
- fly->axis = 2;
- fly->pan_view = false;
- fly->xlock = FLY_AXISLOCK_STATE_OFF;
- fly->zlock = FLY_AXISLOCK_STATE_OFF;
- fly->xlock_momentum = 0.0f;
- fly->zlock_momentum = 0.0f;
- fly->grid = 1.0f;
- fly->use_precision = false;
- fly->use_freelook = false;
+ /* sanity check: for rare but possible case (if lib-linking the camera fails) */
+ if ((fly->rv3d->persp == RV3D_CAMOB) && (fly->v3d->camera == NULL)) {
+ fly->rv3d->persp = RV3D_PERSP;
+ }
+
+ if (fly->rv3d->persp == RV3D_CAMOB && ID_IS_LINKED(fly->v3d->camera)) {
+ BKE_report(op->reports, RPT_ERROR, "Cannot fly a camera from an external library");
+ return false;
+ }
+
+ if (ED_view3d_offset_lock_check(fly->v3d, fly->rv3d)) {
+ BKE_report(op->reports, RPT_ERROR, "Cannot fly when the view offset is locked");
+ return false;
+ }
+
+ if (fly->rv3d->persp == RV3D_CAMOB && fly->v3d->camera->constraints.first) {
+ BKE_report(op->reports, RPT_ERROR, "Cannot fly an object with constraints");
+ return false;
+ }
+
+ fly->state = FLY_RUNNING;
+ fly->speed = 0.0f;
+ fly->axis = 2;
+ fly->pan_view = false;
+ fly->xlock = FLY_AXISLOCK_STATE_OFF;
+ fly->zlock = FLY_AXISLOCK_STATE_OFF;
+ fly->xlock_momentum = 0.0f;
+ fly->zlock_momentum = 0.0f;
+ fly->grid = 1.0f;
+ fly->use_precision = false;
+ fly->use_freelook = false;
#ifdef NDOF_FLY_DRAW_TOOMUCH
- fly->redraw = 1;
+ fly->redraw = 1;
#endif
- zero_v3(fly->dvec_prev);
+ zero_v3(fly->dvec_prev);
- fly->timer = WM_event_add_timer(CTX_wm_manager(C), win, TIMER, 0.01f);
+ fly->timer = WM_event_add_timer(CTX_wm_manager(C), win, TIMER, 0.01f);
- copy_v2_v2_int(fly->mval, event->mval);
+ copy_v2_v2_int(fly->mval, event->mval);
#ifdef WITH_INPUT_NDOF
- fly->ndof = NULL;
+ fly->ndof = NULL;
#endif
- fly->time_lastdraw = fly->time_lastwheel = PIL_check_seconds_timer();
-
- fly->draw_handle_pixel = ED_region_draw_cb_activate(fly->ar->type, drawFlyPixel, fly, REGION_DRAW_POST_PIXEL);
-
- fly->rv3d->rflag |= RV3D_NAVIGATING;
-
- /* detect whether to start with Z locking */
- copy_v3_fl3(upvec, 1.0f, 0.0f, 0.0f);
- copy_m3_m4(mat, fly->rv3d->viewinv);
- mul_m3_v3(mat, upvec);
- if (fabsf(upvec[2]) < 0.1f) {
- fly->zlock = FLY_AXISLOCK_STATE_IDLE;
- }
-
- fly->v3d_camera_control = ED_view3d_cameracontrol_acquire(
- CTX_data_depsgraph(C), fly->scene, fly->v3d, fly->rv3d,
- (U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0);
-
- /* calculate center */
- if (ED_view3d_cameracontrol_object_get(fly->v3d_camera_control)) {
- ED_view3d_calc_camera_border(fly->scene, fly->depsgraph, fly->ar, fly->v3d, fly->rv3d, &viewborder, false);
-
- fly->width = BLI_rctf_size_x(&viewborder);
- fly->height = BLI_rctf_size_y(&viewborder);
-
- fly->center_mval[0] = viewborder.xmin + fly->width / 2;
- fly->center_mval[1] = viewborder.ymin + fly->height / 2;
- }
- else {
- fly->width = fly->ar->winx;
- fly->height = fly->ar->winy;
-
- fly->center_mval[0] = fly->width / 2;
- fly->center_mval[1] = fly->height / 2;
- }
-
- /* center the mouse, probably the UI mafia are against this but without its quite annoying */
- WM_cursor_warp(win, fly->ar->winrct.xmin + fly->center_mval[0], fly->ar->winrct.ymin + fly->center_mval[1]);
-
- fly_update_header(C, op, fly);
- return 1;
+ fly->time_lastdraw = fly->time_lastwheel = PIL_check_seconds_timer();
+
+ fly->draw_handle_pixel = ED_region_draw_cb_activate(
+ fly->ar->type, drawFlyPixel, fly, REGION_DRAW_POST_PIXEL);
+
+ fly->rv3d->rflag |= RV3D_NAVIGATING;
+
+ /* detect whether to start with Z locking */
+ copy_v3_fl3(upvec, 1.0f, 0.0f, 0.0f);
+ copy_m3_m4(mat, fly->rv3d->viewinv);
+ mul_m3_v3(mat, upvec);
+ if (fabsf(upvec[2]) < 0.1f) {
+ fly->zlock = FLY_AXISLOCK_STATE_IDLE;
+ }
+
+ fly->v3d_camera_control = ED_view3d_cameracontrol_acquire(CTX_data_depsgraph(C),
+ fly->scene,
+ fly->v3d,
+ fly->rv3d,
+ (U.uiflag & USER_CAM_LOCK_NO_PARENT) ==
+ 0);
+
+ /* calculate center */
+ if (ED_view3d_cameracontrol_object_get(fly->v3d_camera_control)) {
+ ED_view3d_calc_camera_border(
+ fly->scene, fly->depsgraph, fly->ar, fly->v3d, fly->rv3d, &viewborder, false);
+
+ fly->width = BLI_rctf_size_x(&viewborder);
+ fly->height = BLI_rctf_size_y(&viewborder);
+
+ fly->center_mval[0] = viewborder.xmin + fly->width / 2;
+ fly->center_mval[1] = viewborder.ymin + fly->height / 2;
+ }
+ else {
+ fly->width = fly->ar->winx;
+ fly->height = fly->ar->winy;
+
+ fly->center_mval[0] = fly->width / 2;
+ fly->center_mval[1] = fly->height / 2;
+ }
+
+ /* center the mouse, probably the UI mafia are against this but without its quite annoying */
+ WM_cursor_warp(
+ win, fly->ar->winrct.xmin + fly->center_mval[0], fly->ar->winrct.ymin + fly->center_mval[1]);
+
+ fly_update_header(C, op, fly);
+ return 1;
}
static int flyEnd(bContext *C, FlyInfo *fly)
{
- wmWindow *win;
- RegionView3D *rv3d;
+ wmWindow *win;
+ RegionView3D *rv3d;
- if (fly->state == FLY_RUNNING) {
- return OPERATOR_RUNNING_MODAL;
- }
+ if (fly->state == FLY_RUNNING) {
+ return OPERATOR_RUNNING_MODAL;
+ }
#ifdef NDOF_FLY_DEBUG
- puts("\n-- fly end --");
+ puts("\n-- fly end --");
#endif
- win = CTX_wm_window(C);
- rv3d = fly->rv3d;
+ win = CTX_wm_window(C);
+ rv3d = fly->rv3d;
- WM_event_remove_timer(CTX_wm_manager(C), win, fly->timer);
+ WM_event_remove_timer(CTX_wm_manager(C), win, fly->timer);
- ED_region_draw_cb_exit(fly->ar->type, fly->draw_handle_pixel);
+ ED_region_draw_cb_exit(fly->ar->type, fly->draw_handle_pixel);
- ED_view3d_cameracontrol_release(fly->v3d_camera_control, fly->state == FLY_CANCEL);
+ ED_view3d_cameracontrol_release(fly->v3d_camera_control, fly->state == FLY_CANCEL);
- rv3d->rflag &= ~RV3D_NAVIGATING;
+ rv3d->rflag &= ~RV3D_NAVIGATING;
#ifdef WITH_INPUT_NDOF
- if (fly->ndof) {
- MEM_freeN(fly->ndof);
- }
+ if (fly->ndof) {
+ MEM_freeN(fly->ndof);
+ }
#endif
- if (fly->state == FLY_CONFIRM) {
- MEM_freeN(fly);
- return OPERATOR_FINISHED;
- }
+ if (fly->state == FLY_CONFIRM) {
+ MEM_freeN(fly);
+ return OPERATOR_FINISHED;
+ }
- MEM_freeN(fly);
- return OPERATOR_CANCELLED;
+ MEM_freeN(fly);
+ return OPERATOR_CANCELLED;
}
static void flyEvent(bContext *C, wmOperator *op, FlyInfo *fly, const wmEvent *event)
{
- if (event->type == TIMER && event->customdata == fly->timer) {
- fly->redraw = 1;
- }
- else if (event->type == MOUSEMOVE) {
- copy_v2_v2_int(fly->mval, event->mval);
- }
+ if (event->type == TIMER && event->customdata == fly->timer) {
+ fly->redraw = 1;
+ }
+ else if (event->type == MOUSEMOVE) {
+ copy_v2_v2_int(fly->mval, event->mval);
+ }
#ifdef WITH_INPUT_NDOF
- else if (event->type == NDOF_MOTION) {
- /* do these automagically get delivered? yes. */
- // puts("ndof motion detected in fly mode!");
- // static const char *tag_name = "3D mouse position";
-
- const wmNDOFMotionData *incoming_ndof = event->customdata;
- switch (incoming_ndof->progress) {
- case P_STARTING:
- /* start keeping track of 3D mouse position */
+ else if (event->type == NDOF_MOTION) {
+ /* do these automagically get delivered? yes. */
+ // puts("ndof motion detected in fly mode!");
+ // static const char *tag_name = "3D mouse position";
+
+ const wmNDOFMotionData *incoming_ndof = event->customdata;
+ switch (incoming_ndof->progress) {
+ case P_STARTING:
+ /* start keeping track of 3D mouse position */
# ifdef NDOF_FLY_DEBUG
- puts("start keeping track of 3D mouse position");
+ puts("start keeping track of 3D mouse position");
# endif
- /* fall-through */
- case P_IN_PROGRESS:
- /* update 3D mouse position */
+ /* fall-through */
+ case P_IN_PROGRESS:
+ /* update 3D mouse position */
# ifdef NDOF_FLY_DEBUG
- putchar('.'); fflush(stdout);
+ putchar('.');
+ fflush(stdout);
# endif
- if (fly->ndof == NULL) {
- // fly->ndof = MEM_mallocN(sizeof(wmNDOFMotionData), tag_name);
- fly->ndof = MEM_dupallocN(incoming_ndof);
- // fly->ndof = malloc(sizeof(wmNDOFMotionData));
- }
- else {
- memcpy(fly->ndof, incoming_ndof, sizeof(wmNDOFMotionData));
- }
- break;
- case P_FINISHING:
- /* stop keeping track of 3D mouse position */
+ if (fly->ndof == NULL) {
+ // fly->ndof = MEM_mallocN(sizeof(wmNDOFMotionData), tag_name);
+ fly->ndof = MEM_dupallocN(incoming_ndof);
+ // fly->ndof = malloc(sizeof(wmNDOFMotionData));
+ }
+ else {
+ memcpy(fly->ndof, incoming_ndof, sizeof(wmNDOFMotionData));
+ }
+ break;
+ case P_FINISHING:
+ /* stop keeping track of 3D mouse position */
# ifdef NDOF_FLY_DEBUG
- puts("stop keeping track of 3D mouse position");
+ puts("stop keeping track of 3D mouse position");
# endif
- if (fly->ndof) {
- MEM_freeN(fly->ndof);
- // free(fly->ndof);
- fly->ndof = NULL;
- }
- /* update the time else the view will jump when 2D mouse/timer resume */
- fly->time_lastdraw = PIL_check_seconds_timer();
- break;
- default:
- break; /* should always be one of the above 3 */
- }
- }
+ if (fly->ndof) {
+ MEM_freeN(fly->ndof);
+ // free(fly->ndof);
+ fly->ndof = NULL;
+ }
+ /* update the time else the view will jump when 2D mouse/timer resume */
+ fly->time_lastdraw = PIL_check_seconds_timer();
+ break;
+ default:
+ break; /* should always be one of the above 3 */
+ }
+ }
#endif /* WITH_INPUT_NDOF */
- /* handle modal keymap first */
- else if (event->type == EVT_MODAL_MAP) {
- switch (event->val) {
- case FLY_MODAL_CANCEL:
- fly->state = FLY_CANCEL;
- break;
- case FLY_MODAL_CONFIRM:
- fly->state = FLY_CONFIRM;
- break;
-
- /* speed adjusting with mousepan (trackpad) */
- case FLY_MODAL_SPEED:
- {
- float fac = 0.02f * (event->prevy - event->y);
-
- /* allowing to brake immediate */
- if (fac > 0.0f && fly->speed < 0.0f) {
- fly->speed = 0.0f;
- }
- else if (fac < 0.0f && fly->speed > 0.0f) {
- fly->speed = 0.0f;
- }
- else {
- fly->speed += fly->grid * fac;
- }
-
- break;
- }
- case FLY_MODAL_ACCELERATE:
- {
- double time_currwheel;
- float time_wheel;
-
- /* not quite correct but avoids confusion WASD/arrow keys 'locking up' */
- if (fly->axis == -1) {
- fly->axis = 2;
- fly->speed = fabsf(fly->speed);
- }
-
- time_currwheel = PIL_check_seconds_timer();
- time_wheel = (float)(time_currwheel - fly->time_lastwheel);
- fly->time_lastwheel = time_currwheel;
- /* Mouse wheel delays range from (0.5 == slow) to (0.01 == fast) */
- /* 0-0.5 -> 0-5.0 */
- time_wheel = 1.0f + (10.0f - (20.0f * min_ff(time_wheel, 0.5f)));
-
- if (fly->speed < 0.0f) {
- fly->speed = 0.0f;
- }
- else {
- fly->speed += fly->grid * time_wheel * (fly->use_precision ? 0.1f : 1.0f);
- }
- break;
- }
- case FLY_MODAL_DECELERATE:
- {
- double time_currwheel;
- float time_wheel;
-
- /* not quite correct but avoids confusion WASD/arrow keys 'locking up' */
- if (fly->axis == -1) {
- fly->axis = 2;
- fly->speed = -fabsf(fly->speed);
- }
-
- time_currwheel = PIL_check_seconds_timer();
- time_wheel = (float)(time_currwheel - fly->time_lastwheel);
- fly->time_lastwheel = time_currwheel;
- /* 0-0.5 -> 0-5.0 */
- time_wheel = 1.0f + (10.0f - (20.0f * min_ff(time_wheel, 0.5f)));
-
- if (fly->speed > 0.0f) {
- fly->speed = 0;
- }
- else {
- fly->speed -= fly->grid * time_wheel * (fly->use_precision ? 0.1f : 1.0f);
- }
- break;
- }
- case FLY_MODAL_PAN_ENABLE:
- fly->pan_view = true;
- break;
- case FLY_MODAL_PAN_DISABLE:
- fly->pan_view = false;
- break;
-
- /* implement WASD keys,
- * comments only for 'forward '*/
- case FLY_MODAL_DIR_FORWARD:
- if (fly->axis == 2 && fly->speed < 0.0f) {
- /* reverse direction stops, tap again to continue */
- fly->axis = -1;
- }
- else {
- /* flip speed rather than stopping, game like motion,
- * else increase like mousewheel if were already moving in that direction */
- if (fly->speed < 0.0f) {
- fly->speed = -fly->speed;
- }
- else if (fly->axis == 2) {
- fly->speed += fly->grid;
- }
- fly->axis = 2;
- }
- break;
- case FLY_MODAL_DIR_BACKWARD:
- if (fly->axis == 2 && fly->speed > 0.0f) {
- fly->axis = -1;
- }
- else {
- if (fly->speed > 0.0f) {
- fly->speed = -fly->speed;
- }
- else if (fly->axis == 2) {
- fly->speed -= fly->grid;
- }
-
- fly->axis = 2;
- }
- break;
- case FLY_MODAL_DIR_LEFT:
- if (fly->axis == 0 && fly->speed < 0.0f) {
- fly->axis = -1;
- }
- else {
- if (fly->speed < 0.0f) {
- fly->speed = -fly->speed;
- }
- else if (fly->axis == 0) {
- fly->speed += fly->grid;
- }
-
- fly->axis = 0;
- }
- break;
- case FLY_MODAL_DIR_RIGHT:
- if (fly->axis == 0 && fly->speed > 0.0f) {
- fly->axis = -1;
- }
- else {
- if (fly->speed > 0.0f) {
- fly->speed = -fly->speed;
- }
- else if (fly->axis == 0) {
- fly->speed -= fly->grid;
- }
-
- fly->axis = 0;
- }
- break;
- case FLY_MODAL_DIR_DOWN:
- if (fly->axis == 1 && fly->speed < 0.0f) {
- fly->axis = -1;
- }
- else {
- if (fly->speed < 0.0f) {
- fly->speed = -fly->speed;
- }
- else if (fly->axis == 1) {
- fly->speed += fly->grid;
- }
- fly->axis = 1;
- }
- break;
- case FLY_MODAL_DIR_UP:
- if (fly->axis == 1 && fly->speed > 0.0f) {
- fly->axis = -1;
- }
- else {
- if (fly->speed > 0.0f) {
- fly->speed = -fly->speed;
- }
- else if (fly->axis == 1) {
- fly->speed -= fly->grid;
- }
- fly->axis = 1;
- }
- break;
-
- case FLY_MODAL_AXIS_LOCK_X:
- if (fly->xlock != FLY_AXISLOCK_STATE_OFF) {
- fly->xlock = FLY_AXISLOCK_STATE_OFF;
- }
- else {
- fly->xlock = FLY_AXISLOCK_STATE_ACTIVE;
- fly->xlock_momentum = 0.0;
- }
- fly_update_header(C, op, fly);
- break;
- case FLY_MODAL_AXIS_LOCK_Z:
- if (fly->zlock != FLY_AXISLOCK_STATE_OFF) {
- fly->zlock = FLY_AXISLOCK_STATE_OFF;
- }
- else {
- fly->zlock = FLY_AXISLOCK_STATE_ACTIVE;
- fly->zlock_momentum = 0.0;
- }
- fly_update_header(C, op, fly);
- break;
-
- case FLY_MODAL_PRECISION_ENABLE:
- fly->use_precision = true;
- break;
- case FLY_MODAL_PRECISION_DISABLE:
- fly->use_precision = false;
- break;
-
- case FLY_MODAL_FREELOOK_ENABLE:
- fly->use_freelook = true;
- break;
- case FLY_MODAL_FREELOOK_DISABLE:
- fly->use_freelook = false;
- break;
- }
- }
+ /* handle modal keymap first */
+ else if (event->type == EVT_MODAL_MAP) {
+ switch (event->val) {
+ case FLY_MODAL_CANCEL:
+ fly->state = FLY_CANCEL;
+ break;
+ case FLY_MODAL_CONFIRM:
+ fly->state = FLY_CONFIRM;
+ break;
+
+ /* speed adjusting with mousepan (trackpad) */
+ case FLY_MODAL_SPEED: {
+ float fac = 0.02f * (event->prevy - event->y);
+
+ /* allowing to brake immediate */
+ if (fac > 0.0f && fly->speed < 0.0f) {
+ fly->speed = 0.0f;
+ }
+ else if (fac < 0.0f && fly->speed > 0.0f) {
+ fly->speed = 0.0f;
+ }
+ else {
+ fly->speed += fly->grid * fac;
+ }
+
+ break;
+ }
+ case FLY_MODAL_ACCELERATE: {
+ double time_currwheel;
+ float time_wheel;
+
+ /* not quite correct but avoids confusion WASD/arrow keys 'locking up' */
+ if (fly->axis == -1) {
+ fly->axis = 2;
+ fly->speed = fabsf(fly->speed);
+ }
+
+ time_currwheel = PIL_check_seconds_timer();
+ time_wheel = (float)(time_currwheel - fly->time_lastwheel);
+ fly->time_lastwheel = time_currwheel;
+ /* Mouse wheel delays range from (0.5 == slow) to (0.01 == fast) */
+ /* 0-0.5 -> 0-5.0 */
+ time_wheel = 1.0f + (10.0f - (20.0f * min_ff(time_wheel, 0.5f)));
+
+ if (fly->speed < 0.0f) {
+ fly->speed = 0.0f;
+ }
+ else {
+ fly->speed += fly->grid * time_wheel * (fly->use_precision ? 0.1f : 1.0f);
+ }
+ break;
+ }
+ case FLY_MODAL_DECELERATE: {
+ double time_currwheel;
+ float time_wheel;
+
+ /* not quite correct but avoids confusion WASD/arrow keys 'locking up' */
+ if (fly->axis == -1) {
+ fly->axis = 2;
+ fly->speed = -fabsf(fly->speed);
+ }
+
+ time_currwheel = PIL_check_seconds_timer();
+ time_wheel = (float)(time_currwheel - fly->time_lastwheel);
+ fly->time_lastwheel = time_currwheel;
+ /* 0-0.5 -> 0-5.0 */
+ time_wheel = 1.0f + (10.0f - (20.0f * min_ff(time_wheel, 0.5f)));
+
+ if (fly->speed > 0.0f) {
+ fly->speed = 0;
+ }
+ else {
+ fly->speed -= fly->grid * time_wheel * (fly->use_precision ? 0.1f : 1.0f);
+ }
+ break;
+ }
+ case FLY_MODAL_PAN_ENABLE:
+ fly->pan_view = true;
+ break;
+ case FLY_MODAL_PAN_DISABLE:
+ fly->pan_view = false;
+ break;
+
+ /* implement WASD keys,
+ * comments only for 'forward '*/
+ case FLY_MODAL_DIR_FORWARD:
+ if (fly->axis == 2 && fly->speed < 0.0f) {
+ /* reverse direction stops, tap again to continue */
+ fly->axis = -1;
+ }
+ else {
+ /* flip speed rather than stopping, game like motion,
+ * else increase like mousewheel if were already moving in that direction */
+ if (fly->speed < 0.0f) {
+ fly->speed = -fly->speed;
+ }
+ else if (fly->axis == 2) {
+ fly->speed += fly->grid;
+ }
+ fly->axis = 2;
+ }
+ break;
+ case FLY_MODAL_DIR_BACKWARD:
+ if (fly->axis == 2 && fly->speed > 0.0f) {
+ fly->axis = -1;
+ }
+ else {
+ if (fly->speed > 0.0f) {
+ fly->speed = -fly->speed;
+ }
+ else if (fly->axis == 2) {
+ fly->speed -= fly->grid;
+ }
+
+ fly->axis = 2;
+ }
+ break;
+ case FLY_MODAL_DIR_LEFT:
+ if (fly->axis == 0 && fly->speed < 0.0f) {
+ fly->axis = -1;
+ }
+ else {
+ if (fly->speed < 0.0f) {
+ fly->speed = -fly->speed;
+ }
+ else if (fly->axis == 0) {
+ fly->speed += fly->grid;
+ }
+
+ fly->axis = 0;
+ }
+ break;
+ case FLY_MODAL_DIR_RIGHT:
+ if (fly->axis == 0 && fly->speed > 0.0f) {
+ fly->axis = -1;
+ }
+ else {
+ if (fly->speed > 0.0f) {
+ fly->speed = -fly->speed;
+ }
+ else if (fly->axis == 0) {
+ fly->speed -= fly->grid;
+ }
+
+ fly->axis = 0;
+ }
+ break;
+ case FLY_MODAL_DIR_DOWN:
+ if (fly->axis == 1 && fly->speed < 0.0f) {
+ fly->axis = -1;
+ }
+ else {
+ if (fly->speed < 0.0f) {
+ fly->speed = -fly->speed;
+ }
+ else if (fly->axis == 1) {
+ fly->speed += fly->grid;
+ }
+ fly->axis = 1;
+ }
+ break;
+ case FLY_MODAL_DIR_UP:
+ if (fly->axis == 1 && fly->speed > 0.0f) {
+ fly->axis = -1;
+ }
+ else {
+ if (fly->speed > 0.0f) {
+ fly->speed = -fly->speed;
+ }
+ else if (fly->axis == 1) {
+ fly->speed -= fly->grid;
+ }
+ fly->axis = 1;
+ }
+ break;
+
+ case FLY_MODAL_AXIS_LOCK_X:
+ if (fly->xlock != FLY_AXISLOCK_STATE_OFF) {
+ fly->xlock = FLY_AXISLOCK_STATE_OFF;
+ }
+ else {
+ fly->xlock = FLY_AXISLOCK_STATE_ACTIVE;
+ fly->xlock_momentum = 0.0;
+ }
+ fly_update_header(C, op, fly);
+ break;
+ case FLY_MODAL_AXIS_LOCK_Z:
+ if (fly->zlock != FLY_AXISLOCK_STATE_OFF) {
+ fly->zlock = FLY_AXISLOCK_STATE_OFF;
+ }
+ else {
+ fly->zlock = FLY_AXISLOCK_STATE_ACTIVE;
+ fly->zlock_momentum = 0.0;
+ }
+ fly_update_header(C, op, fly);
+ break;
+
+ case FLY_MODAL_PRECISION_ENABLE:
+ fly->use_precision = true;
+ break;
+ case FLY_MODAL_PRECISION_DISABLE:
+ fly->use_precision = false;
+ break;
+
+ case FLY_MODAL_FREELOOK_ENABLE:
+ fly->use_freelook = true;
+ break;
+ case FLY_MODAL_FREELOOK_DISABLE:
+ fly->use_freelook = false;
+ break;
+ }
+ }
}
-static void flyMoveCamera(bContext *C, FlyInfo *fly,
- const bool do_rotate, const bool do_translate)
+static void flyMoveCamera(bContext *C, FlyInfo *fly, const bool do_rotate, const bool do_translate)
{
- ED_view3d_cameracontrol_update(fly->v3d_camera_control, true, C, do_rotate, do_translate);
+ ED_view3d_cameracontrol_update(fly->v3d_camera_control, true, C, do_rotate, do_translate);
}
static int flyApply(bContext *C, FlyInfo *fly)
{
-#define FLY_ROTATE_FAC 10.0f /* more is faster */
-#define FLY_ZUP_CORRECT_FAC 0.1f /* amount to correct per step */
+#define FLY_ROTATE_FAC 10.0f /* more is faster */
+#define FLY_ZUP_CORRECT_FAC 0.1f /* amount to correct per step */
#define FLY_ZUP_CORRECT_ACCEL 0.05f /* increase upright momentum each step */
-#define FLY_SMOOTH_FAC 20.0f /* higher value less lag */
+#define FLY_SMOOTH_FAC 20.0f /* higher value less lag */
- /* fly mode - Shift+F
- * a fly loop where the user can move move the view as if they are flying
- */
- RegionView3D *rv3d = fly->rv3d;
+ /* fly mode - Shift+F
+ * a fly loop where the user can move move the view as if they are flying
+ */
+ RegionView3D *rv3d = fly->rv3d;
- /* 3x3 copy of the view matrix so we can move along the view axis */
- float mat[3][3];
- /* this is the direction that's added to the view offset per redraw */
- float dvec[3] = {0, 0, 0};
+ /* 3x3 copy of the view matrix so we can move along the view axis */
+ float mat[3][3];
+ /* this is the direction that's added to the view offset per redraw */
+ float dvec[3] = {0, 0, 0};
- /* Camera Uprighting variables */
- float moffset[2]; /* mouse offset from the views center */
- float tmp_quat[4]; /* used for rotating the view */
+ /* Camera Uprighting variables */
+ float moffset[2]; /* mouse offset from the views center */
+ float tmp_quat[4]; /* used for rotating the view */
- /* x and y margin are define the safe area where the mouses movement wont rotate the view */
- int xmargin, ymargin;
+ /* x and y margin are define the safe area where the mouses movement wont rotate the view */
+ int xmargin, ymargin;
#ifdef NDOF_FLY_DEBUG
- {
- static uint iteration = 1;
- printf("fly timer %d\n", iteration++);
- }
+ {
+ static uint iteration = 1;
+ printf("fly timer %d\n", iteration++);
+ }
#endif
- xmargin = fly->width / 20.0f;
- ymargin = fly->height / 20.0f;
-
- {
-
- /* mouse offset from the center */
- moffset[0] = fly->mval[0] - fly->center_mval[0];
- moffset[1] = fly->mval[1] - fly->center_mval[1];
-
- /* enforce a view margin */
- if (moffset[0] > xmargin) {
- moffset[0] -= xmargin;
- }
- else if (moffset[0] < -xmargin) {
- moffset[0] += xmargin;
- }
- else {
- moffset[0] = 0;
- }
-
- if (moffset[1] > ymargin) {
- moffset[1] -= ymargin;
- }
- else if (moffset[1] < -ymargin) {
- moffset[1] += ymargin;
- }
- else {
- moffset[1] = 0;
- }
-
-
- /* scale the mouse movement by this value - scales mouse movement to the view size
- * moffset[0] / (ar->winx-xmargin * 2) - window size minus margin (same for y)
- *
- * the mouse moves isn't linear */
-
- if (moffset[0]) {
- moffset[0] /= fly->width - (xmargin * 2);
- moffset[0] *= fabsf(moffset[0]);
- }
-
- if (moffset[1]) {
- moffset[1] /= fly->height - (ymargin * 2);
- moffset[1] *= fabsf(moffset[1]);
- }
-
- /* Should we redraw? */
- if ((fly->speed != 0.0f) ||
- moffset[0] || moffset[1] ||
- (fly->zlock != FLY_AXISLOCK_STATE_OFF) ||
- (fly->xlock != FLY_AXISLOCK_STATE_OFF) ||
- dvec[0] || dvec[1] || dvec[2])
- {
- float dvec_tmp[3];
-
- /* time how fast it takes for us to redraw,
- * this is so simple scenes don't fly too fast */
- double time_current;
- float time_redraw;
- float time_redraw_clamped;
+ xmargin = fly->width / 20.0f;
+ ymargin = fly->height / 20.0f;
+
+ {
+
+ /* mouse offset from the center */
+ moffset[0] = fly->mval[0] - fly->center_mval[0];
+ moffset[1] = fly->mval[1] - fly->center_mval[1];
+
+ /* enforce a view margin */
+ if (moffset[0] > xmargin) {
+ moffset[0] -= xmargin;
+ }
+ else if (moffset[0] < -xmargin) {
+ moffset[0] += xmargin;
+ }
+ else {
+ moffset[0] = 0;
+ }
+
+ if (moffset[1] > ymargin) {
+ moffset[1] -= ymargin;
+ }
+ else if (moffset[1] < -ymargin) {
+ moffset[1] += ymargin;
+ }
+ else {
+ moffset[1] = 0;
+ }
+
+ /* scale the mouse movement by this value - scales mouse movement to the view size
+ * moffset[0] / (ar->winx-xmargin * 2) - window size minus margin (same for y)
+ *
+ * the mouse moves isn't linear */
+
+ if (moffset[0]) {
+ moffset[0] /= fly->width - (xmargin * 2);
+ moffset[0] *= fabsf(moffset[0]);
+ }
+
+ if (moffset[1]) {
+ moffset[1] /= fly->height - (ymargin * 2);
+ moffset[1] *= fabsf(moffset[1]);
+ }
+
+ /* Should we redraw? */
+ if ((fly->speed != 0.0f) || moffset[0] || moffset[1] ||
+ (fly->zlock != FLY_AXISLOCK_STATE_OFF) || (fly->xlock != FLY_AXISLOCK_STATE_OFF) ||
+ dvec[0] || dvec[1] || dvec[2]) {
+ float dvec_tmp[3];
+
+ /* time how fast it takes for us to redraw,
+ * this is so simple scenes don't fly too fast */
+ double time_current;
+ float time_redraw;
+ float time_redraw_clamped;
#ifdef NDOF_FLY_DRAW_TOOMUCH
- fly->redraw = 1;
+ fly->redraw = 1;
#endif
- time_current = PIL_check_seconds_timer();
- time_redraw = (float)(time_current - fly->time_lastdraw);
-
- /* clamp redraw time to avoid jitter in roll correction */
- time_redraw_clamped = min_ff(0.05f, time_redraw);
-
- fly->time_lastdraw = time_current;
-
- /* Scale the time to use shift to scale the speed down- just like
- * shift slows many other areas of blender down */
- if (fly->use_precision) {
- fly->speed = fly->speed * (1.0f - time_redraw_clamped);
- }
-
- copy_m3_m4(mat, rv3d->viewinv);
-
- if (fly->pan_view == true) {
- /* pan only */
- copy_v3_fl3(dvec_tmp, -moffset[0], -moffset[1], 0.0f);
-
- if (fly->use_precision) {
- dvec_tmp[0] *= 0.1f;
- dvec_tmp[1] *= 0.1f;
- }
-
- mul_m3_v3(mat, dvec_tmp);
- mul_v3_fl(dvec_tmp, time_redraw * 200.0f * fly->grid);
- }
- else {
- float roll; /* similar to the angle between the camera's up and the Z-up,
- * but its very rough so just roll */
-
- /* rotate about the X axis- look up/down */
- if (moffset[1]) {
- float upvec[3];
- copy_v3_fl3(upvec, 1.0f, 0.0f, 0.0f);
- mul_m3_v3(mat, upvec);
- /* Rotate about the relative up vec */
- axis_angle_to_quat(tmp_quat, upvec, moffset[1] * time_redraw * -FLY_ROTATE_FAC);
- mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
-
- if (fly->xlock != FLY_AXISLOCK_STATE_OFF) {
- fly->xlock = FLY_AXISLOCK_STATE_ACTIVE; /* check for rotation */
- }
- if (fly->zlock != FLY_AXISLOCK_STATE_OFF) {
- fly->zlock = FLY_AXISLOCK_STATE_ACTIVE;
- }
- fly->xlock_momentum = 0.0f;
- }
-
- /* rotate about the Y axis- look left/right */
- if (moffset[0]) {
- float upvec[3];
- /* if we're upside down invert the moffset */
- copy_v3_fl3(upvec, 0.0f, 1.0f, 0.0f);
- mul_m3_v3(mat, upvec);
-
- if (upvec[2] < 0.0f) {
- moffset[0] = -moffset[0];
- }
-
- /* make the lock vectors */
- if (fly->zlock) {
- copy_v3_fl3(upvec, 0.0f, 0.0f, 1.0f);
- }
- else {
- copy_v3_fl3(upvec, 0.0f, 1.0f, 0.0f);
- mul_m3_v3(mat, upvec);
- }
-
- /* Rotate about the relative up vec */
- axis_angle_to_quat(tmp_quat, upvec, moffset[0] * time_redraw * FLY_ROTATE_FAC);
- mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
-
- if (fly->xlock != FLY_AXISLOCK_STATE_OFF) {
- fly->xlock = FLY_AXISLOCK_STATE_ACTIVE; /* check for rotation */
- }
- if (fly->zlock != FLY_AXISLOCK_STATE_OFF) {
- fly->zlock = FLY_AXISLOCK_STATE_ACTIVE;
- }
- }
-
- if (fly->zlock == FLY_AXISLOCK_STATE_ACTIVE) {
- float upvec[3];
- copy_v3_fl3(upvec, 1.0f, 0.0f, 0.0f);
- mul_m3_v3(mat, upvec);
-
- /* make sure we have some z rolling */
- if (fabsf(upvec[2]) > 0.00001f) {
- roll = upvec[2] * 5.0f;
- /* rotate the view about this axis */
- copy_v3_fl3(upvec, 0.0f, 0.0f, 1.0f);
- mul_m3_v3(mat, upvec);
- /* Rotate about the relative up vec */
- axis_angle_to_quat(tmp_quat, upvec,
- roll * time_redraw_clamped * fly->zlock_momentum * FLY_ZUP_CORRECT_FAC);
- mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
-
- fly->zlock_momentum += FLY_ZUP_CORRECT_ACCEL;
- }
- else {
- /* don't check until the view rotates again */
- fly->zlock = FLY_AXISLOCK_STATE_IDLE;
- fly->zlock_momentum = 0.0f;
- }
- }
-
- /* only apply xcorrect when mouse isn't applying x rot */
- if (fly->xlock == FLY_AXISLOCK_STATE_ACTIVE && moffset[1] == 0) {
- float upvec[3];
- copy_v3_fl3(upvec, 0.0f, 0.0f, 1.0f);
- mul_m3_v3(mat, upvec);
- /* make sure we have some z rolling */
- if (fabsf(upvec[2]) > 0.00001f) {
- roll = upvec[2] * -5.0f;
- /* rotate the view about this axis */
- copy_v3_fl3(upvec, 1.0f, 0.0f, 0.0f);
- mul_m3_v3(mat, upvec);
-
- /* Rotate about the relative up vec */
- axis_angle_to_quat(tmp_quat, upvec, roll * time_redraw_clamped * fly->xlock_momentum * 0.1f);
- mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
-
- fly->xlock_momentum += 0.05f;
- }
- else {
- fly->xlock = FLY_AXISLOCK_STATE_IDLE; /* see above */
- fly->xlock_momentum = 0.0f;
- }
- }
-
- if (fly->axis == -1) {
- /* pause */
- zero_v3(dvec_tmp);
- }
- else if (!fly->use_freelook) {
- /* Normal operation */
- /* define dvec, view direction vector */
- zero_v3(dvec_tmp);
- /* move along the current axis */
- dvec_tmp[fly->axis] = 1.0f;
-
- mul_m3_v3(mat, dvec_tmp);
- }
- else {
- normalize_v3_v3(dvec_tmp, fly->dvec_prev);
- if (fly->speed < 0.0f) {
- negate_v3(dvec_tmp);
- }
- }
-
- mul_v3_fl(dvec_tmp, fly->speed * time_redraw * 0.25f);
- }
-
- /* impose a directional lag */
- interp_v3_v3v3(dvec, dvec_tmp, fly->dvec_prev, (1.0f / (1.0f + (time_redraw * FLY_SMOOTH_FAC))));
-
- if (rv3d->persp == RV3D_CAMOB) {
- Object *lock_ob = ED_view3d_cameracontrol_object_get(fly->v3d_camera_control);
- if (lock_ob->protectflag & OB_LOCK_LOCX) {
- dvec[0] = 0.0;
- }
- if (lock_ob->protectflag & OB_LOCK_LOCY) {
- dvec[1] = 0.0;
- }
- if (lock_ob->protectflag & OB_LOCK_LOCZ) {
- dvec[2] = 0.0;
- }
- }
-
- add_v3_v3(rv3d->ofs, dvec);
-
- if (rv3d->persp == RV3D_CAMOB) {
- const bool do_rotate = ((fly->xlock != FLY_AXISLOCK_STATE_OFF) ||
- (fly->zlock != FLY_AXISLOCK_STATE_OFF) ||
- ((moffset[0] || moffset[1]) && !fly->pan_view));
- const bool do_translate = (fly->speed != 0.0f || fly->pan_view);
- flyMoveCamera(C, fly, do_rotate, do_translate);
- }
-
- }
- else {
- /* we're not redrawing but we need to update the time else the view will jump */
- fly->time_lastdraw = PIL_check_seconds_timer();
- }
- /* end drawing */
- copy_v3_v3(fly->dvec_prev, dvec);
- }
-
- return OPERATOR_FINISHED;
+ time_current = PIL_check_seconds_timer();
+ time_redraw = (float)(time_current - fly->time_lastdraw);
+
+ /* clamp redraw time to avoid jitter in roll correction */
+ time_redraw_clamped = min_ff(0.05f, time_redraw);
+
+ fly->time_lastdraw = time_current;
+
+ /* Scale the time to use shift to scale the speed down- just like
+ * shift slows many other areas of blender down */
+ if (fly->use_precision) {
+ fly->speed = fly->speed * (1.0f - time_redraw_clamped);
+ }
+
+ copy_m3_m4(mat, rv3d->viewinv);
+
+ if (fly->pan_view == true) {
+ /* pan only */
+ copy_v3_fl3(dvec_tmp, -moffset[0], -moffset[1], 0.0f);
+
+ if (fly->use_precision) {
+ dvec_tmp[0] *= 0.1f;
+ dvec_tmp[1] *= 0.1f;
+ }
+
+ mul_m3_v3(mat, dvec_tmp);
+ mul_v3_fl(dvec_tmp, time_redraw * 200.0f * fly->grid);
+ }
+ else {
+ float roll; /* similar to the angle between the camera's up and the Z-up,
+ * but its very rough so just roll */
+
+ /* rotate about the X axis- look up/down */
+ if (moffset[1]) {
+ float upvec[3];
+ copy_v3_fl3(upvec, 1.0f, 0.0f, 0.0f);
+ mul_m3_v3(mat, upvec);
+ /* Rotate about the relative up vec */
+ axis_angle_to_quat(tmp_quat, upvec, moffset[1] * time_redraw * -FLY_ROTATE_FAC);
+ mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
+
+ if (fly->xlock != FLY_AXISLOCK_STATE_OFF) {
+ fly->xlock = FLY_AXISLOCK_STATE_ACTIVE; /* check for rotation */
+ }
+ if (fly->zlock != FLY_AXISLOCK_STATE_OFF) {
+ fly->zlock = FLY_AXISLOCK_STATE_ACTIVE;
+ }
+ fly->xlock_momentum = 0.0f;
+ }
+
+ /* rotate about the Y axis- look left/right */
+ if (moffset[0]) {
+ float upvec[3];
+ /* if we're upside down invert the moffset */
+ copy_v3_fl3(upvec, 0.0f, 1.0f, 0.0f);
+ mul_m3_v3(mat, upvec);
+
+ if (upvec[2] < 0.0f) {
+ moffset[0] = -moffset[0];
+ }
+
+ /* make the lock vectors */
+ if (fly->zlock) {
+ copy_v3_fl3(upvec, 0.0f, 0.0f, 1.0f);
+ }
+ else {
+ copy_v3_fl3(upvec, 0.0f, 1.0f, 0.0f);
+ mul_m3_v3(mat, upvec);
+ }
+
+ /* Rotate about the relative up vec */
+ axis_angle_to_quat(tmp_quat, upvec, moffset[0] * time_redraw * FLY_ROTATE_FAC);
+ mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
+
+ if (fly->xlock != FLY_AXISLOCK_STATE_OFF) {
+ fly->xlock = FLY_AXISLOCK_STATE_ACTIVE; /* check for rotation */
+ }
+ if (fly->zlock != FLY_AXISLOCK_STATE_OFF) {
+ fly->zlock = FLY_AXISLOCK_STATE_ACTIVE;
+ }
+ }
+
+ if (fly->zlock == FLY_AXISLOCK_STATE_ACTIVE) {
+ float upvec[3];
+ copy_v3_fl3(upvec, 1.0f, 0.0f, 0.0f);
+ mul_m3_v3(mat, upvec);
+
+ /* make sure we have some z rolling */
+ if (fabsf(upvec[2]) > 0.00001f) {
+ roll = upvec[2] * 5.0f;
+ /* rotate the view about this axis */
+ copy_v3_fl3(upvec, 0.0f, 0.0f, 1.0f);
+ mul_m3_v3(mat, upvec);
+ /* Rotate about the relative up vec */
+ axis_angle_to_quat(tmp_quat,
+ upvec,
+ roll * time_redraw_clamped * fly->zlock_momentum *
+ FLY_ZUP_CORRECT_FAC);
+ mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
+
+ fly->zlock_momentum += FLY_ZUP_CORRECT_ACCEL;
+ }
+ else {
+ /* don't check until the view rotates again */
+ fly->zlock = FLY_AXISLOCK_STATE_IDLE;
+ fly->zlock_momentum = 0.0f;
+ }
+ }
+
+ /* only apply xcorrect when mouse isn't applying x rot */
+ if (fly->xlock == FLY_AXISLOCK_STATE_ACTIVE && moffset[1] == 0) {
+ float upvec[3];
+ copy_v3_fl3(upvec, 0.0f, 0.0f, 1.0f);
+ mul_m3_v3(mat, upvec);
+ /* make sure we have some z rolling */
+ if (fabsf(upvec[2]) > 0.00001f) {
+ roll = upvec[2] * -5.0f;
+ /* rotate the view about this axis */
+ copy_v3_fl3(upvec, 1.0f, 0.0f, 0.0f);
+ mul_m3_v3(mat, upvec);
+
+ /* Rotate about the relative up vec */
+ axis_angle_to_quat(
+ tmp_quat, upvec, roll * time_redraw_clamped * fly->xlock_momentum * 0.1f);
+ mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
+
+ fly->xlock_momentum += 0.05f;
+ }
+ else {
+ fly->xlock = FLY_AXISLOCK_STATE_IDLE; /* see above */
+ fly->xlock_momentum = 0.0f;
+ }
+ }
+
+ if (fly->axis == -1) {
+ /* pause */
+ zero_v3(dvec_tmp);
+ }
+ else if (!fly->use_freelook) {
+ /* Normal operation */
+ /* define dvec, view direction vector */
+ zero_v3(dvec_tmp);
+ /* move along the current axis */
+ dvec_tmp[fly->axis] = 1.0f;
+
+ mul_m3_v3(mat, dvec_tmp);
+ }
+ else {
+ normalize_v3_v3(dvec_tmp, fly->dvec_prev);
+ if (fly->speed < 0.0f) {
+ negate_v3(dvec_tmp);
+ }
+ }
+
+ mul_v3_fl(dvec_tmp, fly->speed * time_redraw * 0.25f);
+ }
+
+ /* impose a directional lag */
+ interp_v3_v3v3(
+ dvec, dvec_tmp, fly->dvec_prev, (1.0f / (1.0f + (time_redraw * FLY_SMOOTH_FAC))));
+
+ if (rv3d->persp == RV3D_CAMOB) {
+ Object *lock_ob = ED_view3d_cameracontrol_object_get(fly->v3d_camera_control);
+ if (lock_ob->protectflag & OB_LOCK_LOCX) {
+ dvec[0] = 0.0;
+ }
+ if (lock_ob->protectflag & OB_LOCK_LOCY) {
+ dvec[1] = 0.0;
+ }
+ if (lock_ob->protectflag & OB_LOCK_LOCZ) {
+ dvec[2] = 0.0;
+ }
+ }
+
+ add_v3_v3(rv3d->ofs, dvec);
+
+ if (rv3d->persp == RV3D_CAMOB) {
+ const bool do_rotate = ((fly->xlock != FLY_AXISLOCK_STATE_OFF) ||
+ (fly->zlock != FLY_AXISLOCK_STATE_OFF) ||
+ ((moffset[0] || moffset[1]) && !fly->pan_view));
+ const bool do_translate = (fly->speed != 0.0f || fly->pan_view);
+ flyMoveCamera(C, fly, do_rotate, do_translate);
+ }
+ }
+ else {
+ /* we're not redrawing but we need to update the time else the view will jump */
+ fly->time_lastdraw = PIL_check_seconds_timer();
+ }
+ /* end drawing */
+ copy_v3_v3(fly->dvec_prev, dvec);
+ }
+
+ return OPERATOR_FINISHED;
}
#ifdef WITH_INPUT_NDOF
static void flyApply_ndof(bContext *C, FlyInfo *fly)
{
- Object *lock_ob = ED_view3d_cameracontrol_object_get(fly->v3d_camera_control);
- bool has_translate, has_rotate;
-
- view3d_ndof_fly(fly->ndof,
- fly->v3d, fly->rv3d,
- fly->use_precision, lock_ob ? lock_ob->protectflag : 0,
- &has_translate, &has_rotate);
-
- if (has_translate || has_rotate) {
- fly->redraw = true;
-
- if (fly->rv3d->persp == RV3D_CAMOB) {
- flyMoveCamera(C, fly, has_rotate, has_translate);
- }
- }
+ Object *lock_ob = ED_view3d_cameracontrol_object_get(fly->v3d_camera_control);
+ bool has_translate, has_rotate;
+
+ view3d_ndof_fly(fly->ndof,
+ fly->v3d,
+ fly->rv3d,
+ fly->use_precision,
+ lock_ob ? lock_ob->protectflag : 0,
+ &has_translate,
+ &has_rotate);
+
+ if (has_translate || has_rotate) {
+ fly->redraw = true;
+
+ if (fly->rv3d->persp == RV3D_CAMOB) {
+ flyMoveCamera(C, fly, has_rotate, has_translate);
+ }
+ }
}
#endif /* WITH_INPUT_NDOF */
static int fly_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
- FlyInfo *fly;
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ FlyInfo *fly;
- if (rv3d->viewlock & RV3D_LOCKED) {
- return OPERATOR_CANCELLED;
- }
+ if (rv3d->viewlock & RV3D_LOCKED) {
+ return OPERATOR_CANCELLED;
+ }
- fly = MEM_callocN(sizeof(FlyInfo), "FlyOperation");
+ fly = MEM_callocN(sizeof(FlyInfo), "FlyOperation");
- op->customdata = fly;
+ op->customdata = fly;
- if (initFlyInfo(C, fly, op, event) == false) {
- MEM_freeN(op->customdata);
- return OPERATOR_CANCELLED;
- }
+ if (initFlyInfo(C, fly, op, event) == false) {
+ MEM_freeN(op->customdata);
+ return OPERATOR_CANCELLED;
+ }
- flyEvent(C, op, fly, event);
+ flyEvent(C, op, fly, event);
- WM_event_add_modal_handler(C, op);
+ WM_event_add_modal_handler(C, op);
- return OPERATOR_RUNNING_MODAL;
+ return OPERATOR_RUNNING_MODAL;
}
static void fly_cancel(bContext *C, wmOperator *op)
{
- FlyInfo *fly = op->customdata;
+ FlyInfo *fly = op->customdata;
- fly->state = FLY_CANCEL;
- flyEnd(C, fly);
- op->customdata = NULL;
+ fly->state = FLY_CANCEL;
+ flyEnd(C, fly);
+ op->customdata = NULL;
}
static int fly_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
- int exit_code;
- bool do_draw = false;
- FlyInfo *fly = op->customdata;
- RegionView3D *rv3d = fly->rv3d;
- Object *fly_object = ED_view3d_cameracontrol_object_get(fly->v3d_camera_control);
+ int exit_code;
+ bool do_draw = false;
+ FlyInfo *fly = op->customdata;
+ RegionView3D *rv3d = fly->rv3d;
+ Object *fly_object = ED_view3d_cameracontrol_object_get(fly->v3d_camera_control);
- fly->redraw = 0;
+ fly->redraw = 0;
- flyEvent(C, op, fly, event);
+ flyEvent(C, op, fly, event);
#ifdef WITH_INPUT_NDOF
- if (fly->ndof) { /* 3D mouse overrules [2D mouse + timer] */
- if (event->type == NDOF_MOTION) {
- flyApply_ndof(C, fly);
- }
- }
- else
+ if (fly->ndof) { /* 3D mouse overrules [2D mouse + timer] */
+ if (event->type == NDOF_MOTION) {
+ flyApply_ndof(C, fly);
+ }
+ }
+ else
#endif /* WITH_INPUT_NDOF */
- if (event->type == TIMER && event->customdata == fly->timer) {
- flyApply(C, fly);
- }
+ if (event->type == TIMER && event->customdata == fly->timer) {
+ flyApply(C, fly);
+ }
- do_draw |= fly->redraw;
+ do_draw |= fly->redraw;
- exit_code = flyEnd(C, fly);
+ exit_code = flyEnd(C, fly);
- if (exit_code != OPERATOR_RUNNING_MODAL) {
- do_draw = true;
- }
+ if (exit_code != OPERATOR_RUNNING_MODAL) {
+ do_draw = true;
+ }
- if (do_draw) {
- if (rv3d->persp == RV3D_CAMOB) {
- WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, fly_object);
- }
+ if (do_draw) {
+ if (rv3d->persp == RV3D_CAMOB) {
+ WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, fly_object);
+ }
- // puts("redraw!"); // too frequent, commented with NDOF_FLY_DRAW_TOOMUCH for now
- ED_region_tag_redraw(CTX_wm_region(C));
- }
+ // puts("redraw!"); // too frequent, commented with NDOF_FLY_DRAW_TOOMUCH for now
+ ED_region_tag_redraw(CTX_wm_region(C));
+ }
- if (ELEM(exit_code, OPERATOR_FINISHED, OPERATOR_CANCELLED)) {
- ED_workspace_status_text(C, NULL);
- }
+ if (ELEM(exit_code, OPERATOR_FINISHED, OPERATOR_CANCELLED)) {
+ ED_workspace_status_text(C, NULL);
+ }
- return exit_code;
+ return exit_code;
}
void VIEW3D_OT_fly(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Fly Navigation";
- ot->description = "Interactively fly around the scene";
- ot->idname = "VIEW3D_OT_fly";
-
- /* api callbacks */
- ot->invoke = fly_invoke;
- ot->cancel = fly_cancel;
- ot->modal = fly_modal;
- ot->poll = ED_operator_region_view3d_active;
-
- /* flags */
- ot->flag = OPTYPE_BLOCKING;
+ /* identifiers */
+ ot->name = "Fly Navigation";
+ ot->description = "Interactively fly around the scene";
+ ot->idname = "VIEW3D_OT_fly";
+
+ /* api callbacks */
+ ot->invoke = fly_invoke;
+ ot->cancel = fly_cancel;
+ ot->modal = fly_modal;
+ ot->poll = ED_operator_region_view3d_active;
+
+ /* flags */
+ ot->flag = OPTYPE_BLOCKING;
}
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_armature.c b/source/blender/editors/space_view3d/view3d_gizmo_armature.c
index 64617b03c5e..ae186505456 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_armature.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_armature.c
@@ -43,8 +43,7 @@
#include "WM_api.h"
#include "WM_types.h"
-#include "view3d_intern.h" /* own include */
-
+#include "view3d_intern.h" /* own include */
/* -------------------------------------------------------------------- */
/** \name Armature Spline Gizmo
@@ -63,166 +62,165 @@
#define BBONE_SCALE_Y 3.0f
struct BoneSplineHandle {
- wmGizmo *gizmo;
- bPoseChannel *pchan;
- /* We could remove, keep since at the moment for checking the conversion. */
- float co[3];
- int index;
+ wmGizmo *gizmo;
+ bPoseChannel *pchan;
+ /* We could remove, keep since at the moment for checking the conversion. */
+ float co[3];
+ int index;
};
struct BoneSplineWidgetGroup {
- struct BoneSplineHandle handles[2];
+ struct BoneSplineHandle handles[2];
};
-static void gizmo_bbone_offset_get(
- const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop,
- void *value_p)
+static void gizmo_bbone_offset_get(const wmGizmo *UNUSED(gz),
+ wmGizmoProperty *gz_prop,
+ void *value_p)
{
- struct BoneSplineHandle *bh = gz_prop->custom_func.user_data;
- bPoseChannel *pchan = bh->pchan;
-
- float *value = value_p;
- BLI_assert(gz_prop->type->array_length == 3);
-
- if (bh->index == 0) {
- bh->co[1] = pchan->bone->ease1 / BBONE_SCALE_Y;
- bh->co[0] = pchan->curveInX;
- bh->co[2] = pchan->curveInY;
- }
- else {
- bh->co[1] = -pchan->bone->ease2 / BBONE_SCALE_Y;
- bh->co[0] = pchan->curveOutX;
- bh->co[2] = pchan->curveOutY;
- }
- copy_v3_v3(value, bh->co);
+ struct BoneSplineHandle *bh = gz_prop->custom_func.user_data;
+ bPoseChannel *pchan = bh->pchan;
+
+ float *value = value_p;
+ BLI_assert(gz_prop->type->array_length == 3);
+
+ if (bh->index == 0) {
+ bh->co[1] = pchan->bone->ease1 / BBONE_SCALE_Y;
+ bh->co[0] = pchan->curveInX;
+ bh->co[2] = pchan->curveInY;
+ }
+ else {
+ bh->co[1] = -pchan->bone->ease2 / BBONE_SCALE_Y;
+ bh->co[0] = pchan->curveOutX;
+ bh->co[2] = pchan->curveOutY;
+ }
+ copy_v3_v3(value, bh->co);
}
-static void gizmo_bbone_offset_set(
- const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop,
- const void *value_p)
+static void gizmo_bbone_offset_set(const wmGizmo *UNUSED(gz),
+ wmGizmoProperty *gz_prop,
+ const void *value_p)
{
- struct BoneSplineHandle *bh = gz_prop->custom_func.user_data;
- bPoseChannel *pchan = bh->pchan;
-
- const float *value = value_p;
-
- BLI_assert(gz_prop->type->array_length == 3);
- copy_v3_v3(bh->co, value);
-
- if (bh->index == 0) {
- pchan->bone->ease1 = max_ff(0.0f, bh->co[1] * BBONE_SCALE_Y);
- pchan->curveInX = bh->co[0];
- pchan->curveInY = bh->co[2];
- }
- else {
- pchan->bone->ease2 = max_ff(0.0f, -bh->co[1] * BBONE_SCALE_Y);
- pchan->curveOutX = bh->co[0];
- pchan->curveOutY = bh->co[2];
- }
-
+ struct BoneSplineHandle *bh = gz_prop->custom_func.user_data;
+ bPoseChannel *pchan = bh->pchan;
+
+ const float *value = value_p;
+
+ BLI_assert(gz_prop->type->array_length == 3);
+ copy_v3_v3(bh->co, value);
+
+ if (bh->index == 0) {
+ pchan->bone->ease1 = max_ff(0.0f, bh->co[1] * BBONE_SCALE_Y);
+ pchan->curveInX = bh->co[0];
+ pchan->curveInY = bh->co[2];
+ }
+ else {
+ pchan->bone->ease2 = max_ff(0.0f, -bh->co[1] * BBONE_SCALE_Y);
+ pchan->curveOutX = bh->co[0];
+ pchan->curveOutY = bh->co[2];
+ }
}
static bool WIDGETGROUP_armature_spline_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
{
- View3D *v3d = CTX_wm_view3d(C);
- if (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT)) {
- return false;
- }
-
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Base *base = BASACT(view_layer);
- if (base && BASE_SELECTABLE(v3d, base)) {
- Object *ob = BKE_object_pose_armature_get(base->object);
- if (ob) {
- const bArmature *arm = ob->data;
- if (arm->drawtype == ARM_B_BONE) {
- bPoseChannel *pchan = BKE_pose_channel_active(ob);
- if (pchan && pchan->bone->segments > 1) {
- return true;
- }
- }
- }
- }
- return false;
+ View3D *v3d = CTX_wm_view3d(C);
+ if (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT)) {
+ return false;
+ }
+
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Base *base = BASACT(view_layer);
+ if (base && BASE_SELECTABLE(v3d, base)) {
+ Object *ob = BKE_object_pose_armature_get(base->object);
+ if (ob) {
+ const bArmature *arm = ob->data;
+ if (arm->drawtype == ARM_B_BONE) {
+ bPoseChannel *pchan = BKE_pose_channel_active(ob);
+ if (pchan && pchan->bone->segments > 1) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
}
-
static void WIDGETGROUP_armature_spline_setup(const bContext *C, wmGizmoGroup *gzgroup)
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *ob = BKE_object_pose_armature_get(OBACT(view_layer));
- bPoseChannel *pchan = BKE_pose_channel_active(ob);
-
- const wmGizmoType *gzt_move = WM_gizmotype_find("GIZMO_GT_move_3d", true);
-
- struct BoneSplineWidgetGroup *bspline_group = MEM_callocN(sizeof(struct BoneSplineWidgetGroup), __func__);
- gzgroup->customdata = bspline_group;
-
- /* Handles */
- for (int i = 0; i < ARRAY_SIZE(bspline_group->handles); i++) {
- wmGizmo *gz;
- gz = bspline_group->handles[i].gizmo = WM_gizmo_new_ptr(gzt_move, gzgroup, NULL);
- RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_MOVE_STYLE_RING_2D);
- RNA_enum_set(gz->ptr, "draw_options",
- ED_GIZMO_MOVE_DRAW_FLAG_FILL | ED_GIZMO_MOVE_DRAW_FLAG_ALIGN_VIEW);
- WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_VALUE, true);
-
- UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color);
- UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
-
- gz->scale_basis = 0.06f;
-
- if (i == 0) {
- copy_v3_v3(gz->matrix_basis[3], pchan->loc);
- }
- }
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *ob = BKE_object_pose_armature_get(OBACT(view_layer));
+ bPoseChannel *pchan = BKE_pose_channel_active(ob);
+
+ const wmGizmoType *gzt_move = WM_gizmotype_find("GIZMO_GT_move_3d", true);
+
+ struct BoneSplineWidgetGroup *bspline_group = MEM_callocN(sizeof(struct BoneSplineWidgetGroup),
+ __func__);
+ gzgroup->customdata = bspline_group;
+
+ /* Handles */
+ for (int i = 0; i < ARRAY_SIZE(bspline_group->handles); i++) {
+ wmGizmo *gz;
+ gz = bspline_group->handles[i].gizmo = WM_gizmo_new_ptr(gzt_move, gzgroup, NULL);
+ RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_MOVE_STYLE_RING_2D);
+ RNA_enum_set(gz->ptr,
+ "draw_options",
+ ED_GIZMO_MOVE_DRAW_FLAG_FILL | ED_GIZMO_MOVE_DRAW_FLAG_ALIGN_VIEW);
+ WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_VALUE, true);
+
+ UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color);
+ UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
+
+ gz->scale_basis = 0.06f;
+
+ if (i == 0) {
+ copy_v3_v3(gz->matrix_basis[3], pchan->loc);
+ }
+ }
}
static void WIDGETGROUP_armature_spline_refresh(const bContext *C, wmGizmoGroup *gzgroup)
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *ob = BKE_object_pose_armature_get(OBACT(view_layer));
-
- if (!gzgroup->customdata) {
- return;
- }
-
- struct BoneSplineWidgetGroup *bspline_group = gzgroup->customdata;
- bPoseChannel *pchan = BKE_pose_channel_active(ob);
-
- /* Handles */
- for (int i = 0; i < ARRAY_SIZE(bspline_group->handles); i++) {
- wmGizmo *gz = bspline_group->handles[i].gizmo;
- bspline_group->handles[i].pchan = pchan;
- bspline_group->handles[i].index = i;
-
- float mat[4][4];
- mul_m4_m4m4(mat, ob->obmat, (i == 0) ? pchan->disp_mat : pchan->disp_tail_mat);
- copy_m4_m4(gz->matrix_space, mat);
-
- /* need to set property here for undo. TODO would prefer to do this in _init */
- WM_gizmo_target_property_def_func(
- gz, "offset",
- &(const struct wmGizmoPropertyFnParams) {
- .value_get_fn = gizmo_bbone_offset_get,
- .value_set_fn = gizmo_bbone_offset_set,
- .range_get_fn = NULL,
- .user_data = &bspline_group->handles[i],
- });
- }
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *ob = BKE_object_pose_armature_get(OBACT(view_layer));
+
+ if (!gzgroup->customdata) {
+ return;
+ }
+
+ struct BoneSplineWidgetGroup *bspline_group = gzgroup->customdata;
+ bPoseChannel *pchan = BKE_pose_channel_active(ob);
+
+ /* Handles */
+ for (int i = 0; i < ARRAY_SIZE(bspline_group->handles); i++) {
+ wmGizmo *gz = bspline_group->handles[i].gizmo;
+ bspline_group->handles[i].pchan = pchan;
+ bspline_group->handles[i].index = i;
+
+ float mat[4][4];
+ mul_m4_m4m4(mat, ob->obmat, (i == 0) ? pchan->disp_mat : pchan->disp_tail_mat);
+ copy_m4_m4(gz->matrix_space, mat);
+
+ /* need to set property here for undo. TODO would prefer to do this in _init */
+ WM_gizmo_target_property_def_func(gz,
+ "offset",
+ &(const struct wmGizmoPropertyFnParams){
+ .value_get_fn = gizmo_bbone_offset_get,
+ .value_set_fn = gizmo_bbone_offset_set,
+ .range_get_fn = NULL,
+ .user_data = &bspline_group->handles[i],
+ });
+ }
}
void VIEW3D_GGT_armature_spline(wmGizmoGroupType *gzgt)
{
- gzgt->name = "Armature Spline Widgets";
- gzgt->idname = "VIEW3D_GGT_armature_spline";
+ gzgt->name = "Armature Spline Widgets";
+ gzgt->idname = "VIEW3D_GGT_armature_spline";
- gzgt->flag = (WM_GIZMOGROUPTYPE_PERSISTENT |
- WM_GIZMOGROUPTYPE_3D);
+ gzgt->flag = (WM_GIZMOGROUPTYPE_PERSISTENT | WM_GIZMOGROUPTYPE_3D);
- gzgt->poll = WIDGETGROUP_armature_spline_poll;
- gzgt->setup = WIDGETGROUP_armature_spline_setup;
- gzgt->refresh = WIDGETGROUP_armature_spline_refresh;
+ gzgt->poll = WIDGETGROUP_armature_spline_poll;
+ gzgt->setup = WIDGETGROUP_armature_spline_setup;
+ gzgt->refresh = WIDGETGROUP_armature_spline_refresh;
}
/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_camera.c b/source/blender/editors/space_view3d/view3d_gizmo_camera.c
index 590597145a0..0b8c3b8cd28 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_camera.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_camera.c
@@ -18,7 +18,6 @@
* \ingroup spview3d
*/
-
#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
@@ -45,276 +44,279 @@
#include "DEG_depsgraph.h"
-#include "view3d_intern.h" /* own include */
-
+#include "view3d_intern.h" /* own include */
/* -------------------------------------------------------------------- */
/** \name Camera Gizmos
* \{ */
struct CameraWidgetGroup {
- wmGizmo *dop_dist;
- wmGizmo *focal_len;
- wmGizmo *ortho_scale;
+ wmGizmo *dop_dist;
+ wmGizmo *focal_len;
+ wmGizmo *ortho_scale;
};
static bool WIDGETGROUP_camera_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
{
- View3D *v3d = CTX_wm_view3d(C);
- if (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT)) {
- return false;
- }
- if ((v3d->gizmo_show_camera & V3D_GIZMO_SHOW_CAMERA_LENS) == 0 &&
- (v3d->gizmo_show_camera & V3D_GIZMO_SHOW_CAMERA_DOF_DIST) == 0)
- {
- return false;
- }
-
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Base *base = BASACT(view_layer);
- if (base && BASE_SELECTABLE(v3d, base)) {
- Object *ob = base->object;
- if (ob->type == OB_CAMERA) {
- Camera *camera = ob->data;
- /* TODO: support overrides. */
- if (camera->id.lib == NULL) {
- return true;
- }
- }
- }
- return false;
+ View3D *v3d = CTX_wm_view3d(C);
+ if (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT)) {
+ return false;
+ }
+ if ((v3d->gizmo_show_camera & V3D_GIZMO_SHOW_CAMERA_LENS) == 0 &&
+ (v3d->gizmo_show_camera & V3D_GIZMO_SHOW_CAMERA_DOF_DIST) == 0) {
+ return false;
+ }
+
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Base *base = BASACT(view_layer);
+ if (base && BASE_SELECTABLE(v3d, base)) {
+ Object *ob = base->object;
+ if (ob->type == OB_CAMERA) {
+ Camera *camera = ob->data;
+ /* TODO: support overrides. */
+ if (camera->id.lib == NULL) {
+ return true;
+ }
+ }
+ }
+ return false;
}
static void WIDGETGROUP_camera_setup(const bContext *C, wmGizmoGroup *gzgroup)
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *ob = OBACT(view_layer);
- float dir[3];
-
- const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true);
-
- struct CameraWidgetGroup *cagzgroup = MEM_callocN(sizeof(struct CameraWidgetGroup), __func__);
- gzgroup->customdata = cagzgroup;
-
- negate_v3_v3(dir, ob->obmat[2]);
-
- /* dof distance */
- {
- wmGizmo *gz;
- gz = cagzgroup->dop_dist = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL);
- RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_CROSS);
- WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_HOVER, true);
-
- UI_GetThemeColor3fv(TH_GIZMO_A, gz->color);
- UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
- }
-
- /* focal length
- * - logic/calculations are similar to BKE_camera_view_frame_ex, better keep in sync */
- {
- wmGizmo *gz;
- gz = cagzgroup->focal_len = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL);
- gz->flag |= WM_GIZMO_DRAW_NO_SCALE;
- RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_CONE);
- RNA_enum_set(gz->ptr, "transform", ED_GIZMO_ARROW_XFORM_FLAG_CONSTRAINED);
-
- UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color);
- UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
-
- gz = cagzgroup->ortho_scale = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL);
- gz->flag |= WM_GIZMO_DRAW_NO_SCALE;
- RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_CONE);
- RNA_enum_set(gz->ptr, "transform", ED_GIZMO_ARROW_XFORM_FLAG_CONSTRAINED);
-
- UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color);
- UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
- }
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *ob = OBACT(view_layer);
+ float dir[3];
+
+ const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true);
+
+ struct CameraWidgetGroup *cagzgroup = MEM_callocN(sizeof(struct CameraWidgetGroup), __func__);
+ gzgroup->customdata = cagzgroup;
+
+ negate_v3_v3(dir, ob->obmat[2]);
+
+ /* dof distance */
+ {
+ wmGizmo *gz;
+ gz = cagzgroup->dop_dist = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL);
+ RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_CROSS);
+ WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_HOVER, true);
+
+ UI_GetThemeColor3fv(TH_GIZMO_A, gz->color);
+ UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
+ }
+
+ /* focal length
+ * - logic/calculations are similar to BKE_camera_view_frame_ex, better keep in sync */
+ {
+ wmGizmo *gz;
+ gz = cagzgroup->focal_len = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL);
+ gz->flag |= WM_GIZMO_DRAW_NO_SCALE;
+ RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_CONE);
+ RNA_enum_set(gz->ptr, "transform", ED_GIZMO_ARROW_XFORM_FLAG_CONSTRAINED);
+
+ UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color);
+ UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
+
+ gz = cagzgroup->ortho_scale = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL);
+ gz->flag |= WM_GIZMO_DRAW_NO_SCALE;
+ RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_CONE);
+ RNA_enum_set(gz->ptr, "transform", ED_GIZMO_ARROW_XFORM_FLAG_CONSTRAINED);
+
+ UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color);
+ UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
+ }
}
static void WIDGETGROUP_camera_refresh(const bContext *C, wmGizmoGroup *gzgroup)
{
- if (!gzgroup->customdata) {
- return;
- }
-
- struct CameraWidgetGroup *cagzgroup = gzgroup->customdata;
- View3D *v3d = CTX_wm_view3d(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *ob = OBACT(view_layer);
- Camera *ca = ob->data;
- PointerRNA camera_ptr;
- float dir[3];
-
- RNA_pointer_create(&ca->id, &RNA_Camera, ca, &camera_ptr);
-
- negate_v3_v3(dir, ob->obmat[2]);
-
- if ((ca->flag & CAM_SHOWLIMITS) &&
- (v3d->gizmo_show_camera & V3D_GIZMO_SHOW_CAMERA_DOF_DIST))
- {
- WM_gizmo_set_matrix_location(cagzgroup->dop_dist, ob->obmat[3]);
- WM_gizmo_set_matrix_rotation_from_yz_axis(cagzgroup->dop_dist, ob->obmat[1], dir);
- WM_gizmo_set_scale(cagzgroup->dop_dist, ca->drawsize);
- WM_gizmo_set_flag(cagzgroup->dop_dist, WM_GIZMO_HIDDEN, false);
-
- /* need to set property here for undo. TODO would prefer to do this in _init */
- WM_gizmo_target_property_def_rna(cagzgroup->dop_dist, "offset", &camera_ptr, "dof_distance", -1);
- }
- else {
- WM_gizmo_set_flag(cagzgroup->dop_dist, WM_GIZMO_HIDDEN, true);
- }
-
- /* TODO - make focal length/ortho ob_scale_inv widget optional */
- const Scene *scene = CTX_data_scene(C);
- const float aspx = (float)scene->r.xsch * scene->r.xasp;
- const float aspy = (float)scene->r.ysch * scene->r.yasp;
- const bool is_ortho = (ca->type == CAM_ORTHO);
- const int sensor_fit = BKE_camera_sensor_fit(ca->sensor_fit, aspx, aspy);
- /* Important to use camera value, not calculated fit since 'AUTO' uses width always. */
- const float sensor_size = BKE_camera_sensor_size(ca->sensor_fit, ca->sensor_x, ca->sensor_y);
- wmGizmo *widget = is_ortho ? cagzgroup->ortho_scale : cagzgroup->focal_len;
- float scale_matrix;
- if (true) {
- float offset[3];
- float aspect[2];
-
- WM_gizmo_set_flag(widget, WM_GIZMO_HIDDEN, false);
- WM_gizmo_set_flag(is_ortho ? cagzgroup->focal_len : cagzgroup->ortho_scale, WM_GIZMO_HIDDEN, true);
-
-
- /* account for lens shifting */
- offset[0] = ((ob->scale[0] > 0.0f) ? -2.0f : 2.0f) * ca->shiftx;
- offset[1] = 2.0f * ca->shifty;
- offset[2] = 0.0f;
-
- /* get aspect */
- aspect[0] = (sensor_fit == CAMERA_SENSOR_FIT_HOR) ? 1.0f : aspx / aspy;
- aspect[1] = (sensor_fit == CAMERA_SENSOR_FIT_HOR) ? aspy / aspx : 1.0f;
-
- unit_m4(widget->matrix_basis);
- WM_gizmo_set_matrix_location(widget, ob->obmat[3]);
- WM_gizmo_set_matrix_rotation_from_yz_axis(widget, ob->obmat[1], dir);
-
- if (is_ortho) {
- scale_matrix = ca->ortho_scale * 0.5f;
- }
- else {
- const float ob_scale_inv[3] = {
- 1.0f / len_v3(ob->obmat[0]),
- 1.0f / len_v3(ob->obmat[1]),
- 1.0f / len_v3(ob->obmat[2]),
- };
- const float ob_scale_uniform_inv = (ob_scale_inv[0] + ob_scale_inv[1] + ob_scale_inv[2]) / 3.0f;
- scale_matrix = (ca->drawsize * 0.5f) / ob_scale_uniform_inv;
- }
- mul_v3_fl(widget->matrix_basis[0], scale_matrix);
- mul_v3_fl(widget->matrix_basis[1], scale_matrix);
-
- RNA_float_set_array(widget->ptr, "aspect", aspect);
-
- WM_gizmo_set_matrix_offset_location(widget, offset);
- }
-
- /* define & update properties */
- {
- const char *propname = is_ortho ? "ortho_scale" : "lens";
- PropertyRNA *prop = RNA_struct_find_property(&camera_ptr, propname);
- const wmGizmoPropertyType *gz_prop_type = WM_gizmotype_target_property_find(widget->type, "offset");
-
- WM_gizmo_target_property_clear_rna_ptr(widget, gz_prop_type);
-
- float min, max, range;
- float step, precision;
-
- /* get property range */
- RNA_property_float_ui_range(&camera_ptr, prop, &min, &max, &step, &precision);
- range = max - min;
-
- ED_gizmo_arrow3d_set_range_fac(
- widget, is_ortho ?
- ((range / ca->ortho_scale) * ca->drawsize) :
- (scale_matrix * range /
- /* Half sensor, intentionally use sensor from camera and not calculated above. */
- (0.5f * sensor_size)));
-
- WM_gizmo_target_property_def_rna_ptr(widget, gz_prop_type, &camera_ptr, prop, -1);
- }
-
- /* This could be handled more elegently (split into two gizmo groups). */
- if ((v3d->gizmo_show_camera & V3D_GIZMO_SHOW_CAMERA_LENS) == 0) {
- WM_gizmo_set_flag(cagzgroup->focal_len, WM_GIZMO_HIDDEN, true);
- WM_gizmo_set_flag(cagzgroup->ortho_scale, WM_GIZMO_HIDDEN, true);
- }
+ if (!gzgroup->customdata) {
+ return;
+ }
+
+ struct CameraWidgetGroup *cagzgroup = gzgroup->customdata;
+ View3D *v3d = CTX_wm_view3d(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *ob = OBACT(view_layer);
+ Camera *ca = ob->data;
+ PointerRNA camera_ptr;
+ float dir[3];
+
+ RNA_pointer_create(&ca->id, &RNA_Camera, ca, &camera_ptr);
+
+ negate_v3_v3(dir, ob->obmat[2]);
+
+ if ((ca->flag & CAM_SHOWLIMITS) && (v3d->gizmo_show_camera & V3D_GIZMO_SHOW_CAMERA_DOF_DIST)) {
+ WM_gizmo_set_matrix_location(cagzgroup->dop_dist, ob->obmat[3]);
+ WM_gizmo_set_matrix_rotation_from_yz_axis(cagzgroup->dop_dist, ob->obmat[1], dir);
+ WM_gizmo_set_scale(cagzgroup->dop_dist, ca->drawsize);
+ WM_gizmo_set_flag(cagzgroup->dop_dist, WM_GIZMO_HIDDEN, false);
+
+ /* need to set property here for undo. TODO would prefer to do this in _init */
+ WM_gizmo_target_property_def_rna(
+ cagzgroup->dop_dist, "offset", &camera_ptr, "dof_distance", -1);
+ }
+ else {
+ WM_gizmo_set_flag(cagzgroup->dop_dist, WM_GIZMO_HIDDEN, true);
+ }
+
+ /* TODO - make focal length/ortho ob_scale_inv widget optional */
+ const Scene *scene = CTX_data_scene(C);
+ const float aspx = (float)scene->r.xsch * scene->r.xasp;
+ const float aspy = (float)scene->r.ysch * scene->r.yasp;
+ const bool is_ortho = (ca->type == CAM_ORTHO);
+ const int sensor_fit = BKE_camera_sensor_fit(ca->sensor_fit, aspx, aspy);
+ /* Important to use camera value, not calculated fit since 'AUTO' uses width always. */
+ const float sensor_size = BKE_camera_sensor_size(ca->sensor_fit, ca->sensor_x, ca->sensor_y);
+ wmGizmo *widget = is_ortho ? cagzgroup->ortho_scale : cagzgroup->focal_len;
+ float scale_matrix;
+ if (true) {
+ float offset[3];
+ float aspect[2];
+
+ WM_gizmo_set_flag(widget, WM_GIZMO_HIDDEN, false);
+ WM_gizmo_set_flag(
+ is_ortho ? cagzgroup->focal_len : cagzgroup->ortho_scale, WM_GIZMO_HIDDEN, true);
+
+ /* account for lens shifting */
+ offset[0] = ((ob->scale[0] > 0.0f) ? -2.0f : 2.0f) * ca->shiftx;
+ offset[1] = 2.0f * ca->shifty;
+ offset[2] = 0.0f;
+
+ /* get aspect */
+ aspect[0] = (sensor_fit == CAMERA_SENSOR_FIT_HOR) ? 1.0f : aspx / aspy;
+ aspect[1] = (sensor_fit == CAMERA_SENSOR_FIT_HOR) ? aspy / aspx : 1.0f;
+
+ unit_m4(widget->matrix_basis);
+ WM_gizmo_set_matrix_location(widget, ob->obmat[3]);
+ WM_gizmo_set_matrix_rotation_from_yz_axis(widget, ob->obmat[1], dir);
+
+ if (is_ortho) {
+ scale_matrix = ca->ortho_scale * 0.5f;
+ }
+ else {
+ const float ob_scale_inv[3] = {
+ 1.0f / len_v3(ob->obmat[0]),
+ 1.0f / len_v3(ob->obmat[1]),
+ 1.0f / len_v3(ob->obmat[2]),
+ };
+ const float ob_scale_uniform_inv = (ob_scale_inv[0] + ob_scale_inv[1] + ob_scale_inv[2]) /
+ 3.0f;
+ scale_matrix = (ca->drawsize * 0.5f) / ob_scale_uniform_inv;
+ }
+ mul_v3_fl(widget->matrix_basis[0], scale_matrix);
+ mul_v3_fl(widget->matrix_basis[1], scale_matrix);
+
+ RNA_float_set_array(widget->ptr, "aspect", aspect);
+
+ WM_gizmo_set_matrix_offset_location(widget, offset);
+ }
+
+ /* define & update properties */
+ {
+ const char *propname = is_ortho ? "ortho_scale" : "lens";
+ PropertyRNA *prop = RNA_struct_find_property(&camera_ptr, propname);
+ const wmGizmoPropertyType *gz_prop_type = WM_gizmotype_target_property_find(widget->type,
+ "offset");
+
+ WM_gizmo_target_property_clear_rna_ptr(widget, gz_prop_type);
+
+ float min, max, range;
+ float step, precision;
+
+ /* get property range */
+ RNA_property_float_ui_range(&camera_ptr, prop, &min, &max, &step, &precision);
+ range = max - min;
+
+ ED_gizmo_arrow3d_set_range_fac(
+ widget,
+ is_ortho ?
+ ((range / ca->ortho_scale) * ca->drawsize) :
+ (scale_matrix * range /
+ /* Half sensor, intentionally use sensor from camera and not calculated above. */
+ (0.5f * sensor_size)));
+
+ WM_gizmo_target_property_def_rna_ptr(widget, gz_prop_type, &camera_ptr, prop, -1);
+ }
+
+ /* This could be handled more elegently (split into two gizmo groups). */
+ if ((v3d->gizmo_show_camera & V3D_GIZMO_SHOW_CAMERA_LENS) == 0) {
+ WM_gizmo_set_flag(cagzgroup->focal_len, WM_GIZMO_HIDDEN, true);
+ WM_gizmo_set_flag(cagzgroup->ortho_scale, WM_GIZMO_HIDDEN, true);
+ }
}
-static void WIDGETGROUP_camera_message_subscribe(
- const bContext *C, wmGizmoGroup *gzgroup, struct wmMsgBus *mbus)
+static void WIDGETGROUP_camera_message_subscribe(const bContext *C,
+ wmGizmoGroup *gzgroup,
+ struct wmMsgBus *mbus)
{
- ARegion *ar = CTX_wm_region(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *ob = OBACT(view_layer);
- Camera *ca = ob->data;
-
- wmMsgSubscribeValue msg_sub_value_gz_tag_refresh = {
- .owner = ar,
- .user_data = gzgroup->parent_gzmap,
- .notify = WM_gizmo_do_msg_notify_tag_refresh,
- };
-
- {
- extern PropertyRNA rna_Camera_dof_distance;
- extern PropertyRNA rna_Camera_display_size;
- extern PropertyRNA rna_Camera_ortho_scale;
- extern PropertyRNA rna_Camera_sensor_fit;
- extern PropertyRNA rna_Camera_sensor_width;
- extern PropertyRNA rna_Camera_sensor_height;
- extern PropertyRNA rna_Camera_shift_x;
- extern PropertyRNA rna_Camera_shift_y;
- extern PropertyRNA rna_Camera_type;
- extern PropertyRNA rna_Camera_lens;
- const PropertyRNA *props[] = {
- &rna_Camera_dof_distance,
- &rna_Camera_display_size,
- &rna_Camera_ortho_scale,
- &rna_Camera_sensor_fit,
- &rna_Camera_sensor_width,
- &rna_Camera_sensor_height,
- &rna_Camera_shift_x,
- &rna_Camera_shift_y,
- &rna_Camera_type,
- &rna_Camera_lens,
- };
-
- PointerRNA idptr;
- RNA_id_pointer_create(&ca->id, &idptr);
-
- for (int i = 0; i < ARRAY_SIZE(props); i++) {
- WM_msg_subscribe_rna(mbus, &idptr, props[i], &msg_sub_value_gz_tag_refresh, __func__);
- }
- }
-
- /* Subscribe to render settings */
- {
- WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, resolution_x, &msg_sub_value_gz_tag_refresh);
- WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, resolution_y, &msg_sub_value_gz_tag_refresh);
- WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, pixel_aspect_x, &msg_sub_value_gz_tag_refresh);
- WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, pixel_aspect_y, &msg_sub_value_gz_tag_refresh);
- }
+ ARegion *ar = CTX_wm_region(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *ob = OBACT(view_layer);
+ Camera *ca = ob->data;
+
+ wmMsgSubscribeValue msg_sub_value_gz_tag_refresh = {
+ .owner = ar,
+ .user_data = gzgroup->parent_gzmap,
+ .notify = WM_gizmo_do_msg_notify_tag_refresh,
+ };
+
+ {
+ extern PropertyRNA rna_Camera_dof_distance;
+ extern PropertyRNA rna_Camera_display_size;
+ extern PropertyRNA rna_Camera_ortho_scale;
+ extern PropertyRNA rna_Camera_sensor_fit;
+ extern PropertyRNA rna_Camera_sensor_width;
+ extern PropertyRNA rna_Camera_sensor_height;
+ extern PropertyRNA rna_Camera_shift_x;
+ extern PropertyRNA rna_Camera_shift_y;
+ extern PropertyRNA rna_Camera_type;
+ extern PropertyRNA rna_Camera_lens;
+ const PropertyRNA *props[] = {
+ &rna_Camera_dof_distance,
+ &rna_Camera_display_size,
+ &rna_Camera_ortho_scale,
+ &rna_Camera_sensor_fit,
+ &rna_Camera_sensor_width,
+ &rna_Camera_sensor_height,
+ &rna_Camera_shift_x,
+ &rna_Camera_shift_y,
+ &rna_Camera_type,
+ &rna_Camera_lens,
+ };
+
+ PointerRNA idptr;
+ RNA_id_pointer_create(&ca->id, &idptr);
+
+ for (int i = 0; i < ARRAY_SIZE(props); i++) {
+ WM_msg_subscribe_rna(mbus, &idptr, props[i], &msg_sub_value_gz_tag_refresh, __func__);
+ }
+ }
+
+ /* Subscribe to render settings */
+ {
+ WM_msg_subscribe_rna_anon_prop(
+ mbus, RenderSettings, resolution_x, &msg_sub_value_gz_tag_refresh);
+ WM_msg_subscribe_rna_anon_prop(
+ mbus, RenderSettings, resolution_y, &msg_sub_value_gz_tag_refresh);
+ WM_msg_subscribe_rna_anon_prop(
+ mbus, RenderSettings, pixel_aspect_x, &msg_sub_value_gz_tag_refresh);
+ WM_msg_subscribe_rna_anon_prop(
+ mbus, RenderSettings, pixel_aspect_y, &msg_sub_value_gz_tag_refresh);
+ }
}
void VIEW3D_GGT_camera(wmGizmoGroupType *gzgt)
{
- gzgt->name = "Camera Widgets";
- gzgt->idname = "VIEW3D_GGT_camera";
+ gzgt->name = "Camera Widgets";
+ gzgt->idname = "VIEW3D_GGT_camera";
- gzgt->flag = (WM_GIZMOGROUPTYPE_PERSISTENT |
- WM_GIZMOGROUPTYPE_3D |
- WM_GIZMOGROUPTYPE_DEPTH_3D);
+ gzgt->flag = (WM_GIZMOGROUPTYPE_PERSISTENT | WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_DEPTH_3D);
- gzgt->poll = WIDGETGROUP_camera_poll;
- gzgt->setup = WIDGETGROUP_camera_setup;
- gzgt->refresh = WIDGETGROUP_camera_refresh;
- gzgt->message_subscribe = WIDGETGROUP_camera_message_subscribe;
+ gzgt->poll = WIDGETGROUP_camera_poll;
+ gzgt->setup = WIDGETGROUP_camera_setup;
+ gzgt->refresh = WIDGETGROUP_camera_refresh;
+ gzgt->message_subscribe = WIDGETGROUP_camera_message_subscribe;
}
/** \} */
@@ -324,177 +326,191 @@ void VIEW3D_GGT_camera(wmGizmoGroupType *gzgt)
* \{ */
struct CameraViewWidgetGroup {
- Scene *scene;
- bool is_camera;
+ Scene *scene;
+ bool is_camera;
- wmGizmo *border;
+ wmGizmo *border;
- struct {
- rctf *edit_border;
- rctf view_border;
- } state;
+ struct {
+ rctf *edit_border;
+ rctf view_border;
+ } state;
};
/* scale callbacks */
-static void gizmo_render_border_prop_matrix_get(
- const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop,
- void *value_p)
+static void gizmo_render_border_prop_matrix_get(const wmGizmo *UNUSED(gz),
+ wmGizmoProperty *gz_prop,
+ void *value_p)
{
- float (*matrix)[4] = value_p;
- BLI_assert(gz_prop->type->array_length == 16);
- struct CameraViewWidgetGroup *viewgroup = gz_prop->custom_func.user_data;
- const rctf *border = viewgroup->state.edit_border;
-
- unit_m4(matrix);
- matrix[0][0] = BLI_rctf_size_x(border);
- matrix[1][1] = BLI_rctf_size_y(border);
- matrix[3][0] = BLI_rctf_cent_x(border);
- matrix[3][1] = BLI_rctf_cent_y(border);
+ float(*matrix)[4] = value_p;
+ BLI_assert(gz_prop->type->array_length == 16);
+ struct CameraViewWidgetGroup *viewgroup = gz_prop->custom_func.user_data;
+ const rctf *border = viewgroup->state.edit_border;
+
+ unit_m4(matrix);
+ matrix[0][0] = BLI_rctf_size_x(border);
+ matrix[1][1] = BLI_rctf_size_y(border);
+ matrix[3][0] = BLI_rctf_cent_x(border);
+ matrix[3][1] = BLI_rctf_cent_y(border);
}
-static void gizmo_render_border_prop_matrix_set(
- const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop,
- const void *value_p)
+static void gizmo_render_border_prop_matrix_set(const wmGizmo *UNUSED(gz),
+ wmGizmoProperty *gz_prop,
+ const void *value_p)
{
- const float (*matrix)[4] = value_p;
- struct CameraViewWidgetGroup *viewgroup = gz_prop->custom_func.user_data;
- rctf *border = viewgroup->state.edit_border;
- BLI_assert(gz_prop->type->array_length == 16);
-
- BLI_rctf_resize(border, len_v3(matrix[0]), len_v3(matrix[1]));
- BLI_rctf_recenter(border, matrix[3][0], matrix[3][1]);
- BLI_rctf_isect(&(rctf){ .xmin = 0, .ymin = 0, .xmax = 1, .ymax = 1, }, border, border);
-
- if (viewgroup->is_camera) {
- DEG_id_tag_update(&viewgroup->scene->id, ID_RECALC_COPY_ON_WRITE);
- }
+ const float(*matrix)[4] = value_p;
+ struct CameraViewWidgetGroup *viewgroup = gz_prop->custom_func.user_data;
+ rctf *border = viewgroup->state.edit_border;
+ BLI_assert(gz_prop->type->array_length == 16);
+
+ BLI_rctf_resize(border, len_v3(matrix[0]), len_v3(matrix[1]));
+ BLI_rctf_recenter(border, matrix[3][0], matrix[3][1]);
+ BLI_rctf_isect(
+ &(rctf){
+ .xmin = 0,
+ .ymin = 0,
+ .xmax = 1,
+ .ymax = 1,
+ },
+ border,
+ border);
+
+ if (viewgroup->is_camera) {
+ DEG_id_tag_update(&viewgroup->scene->id, ID_RECALC_COPY_ON_WRITE);
+ }
}
static bool WIDGETGROUP_camera_view_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
{
- Scene *scene = CTX_data_scene(C);
-
- /* This is just so the border isn't always in the way,
- * stealing mouse clicks from regular usage.
- * We could change the rules for when to show. */
- {
- ViewLayer *view_layer = CTX_data_view_layer(C);
- if (scene->camera != OBACT(view_layer)) {
- return false;
- }
- }
-
- View3D *v3d = CTX_wm_view3d(C);
- if (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT)) {
- return false;
- }
-
- ARegion *ar = CTX_wm_region(C);
- RegionView3D *rv3d = ar->regiondata;
- if (rv3d->persp == RV3D_CAMOB) {
- if (scene->r.mode & R_BORDER) {
- /* TODO: support overrides. */
- if (scene->id.lib == NULL) {
- return true;
- }
- }
- }
- else if (v3d->flag2 & V3D_RENDER_BORDER) {
- return true;
- }
- return false;
+ Scene *scene = CTX_data_scene(C);
+
+ /* This is just so the border isn't always in the way,
+ * stealing mouse clicks from regular usage.
+ * We could change the rules for when to show. */
+ {
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ if (scene->camera != OBACT(view_layer)) {
+ return false;
+ }
+ }
+
+ View3D *v3d = CTX_wm_view3d(C);
+ if (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT)) {
+ return false;
+ }
+
+ ARegion *ar = CTX_wm_region(C);
+ RegionView3D *rv3d = ar->regiondata;
+ if (rv3d->persp == RV3D_CAMOB) {
+ if (scene->r.mode & R_BORDER) {
+ /* TODO: support overrides. */
+ if (scene->id.lib == NULL) {
+ return true;
+ }
+ }
+ }
+ else if (v3d->flag2 & V3D_RENDER_BORDER) {
+ return true;
+ }
+ return false;
}
static void WIDGETGROUP_camera_view_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
{
- struct CameraViewWidgetGroup *viewgroup = MEM_mallocN(sizeof(struct CameraViewWidgetGroup), __func__);
+ struct CameraViewWidgetGroup *viewgroup = MEM_mallocN(sizeof(struct CameraViewWidgetGroup),
+ __func__);
- viewgroup->border = WM_gizmo_new("GIZMO_GT_cage_2d", gzgroup, NULL);
+ viewgroup->border = WM_gizmo_new("GIZMO_GT_cage_2d", gzgroup, NULL);
- RNA_enum_set(viewgroup->border->ptr, "transform",
- ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE | ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE);
- /* Box style is more subtle in this case. */
- RNA_enum_set(viewgroup->border->ptr, "draw_style", ED_GIZMO_CAGE2D_STYLE_BOX);
+ RNA_enum_set(viewgroup->border->ptr,
+ "transform",
+ ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE | ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE);
+ /* Box style is more subtle in this case. */
+ RNA_enum_set(viewgroup->border->ptr, "draw_style", ED_GIZMO_CAGE2D_STYLE_BOX);
-
- gzgroup->customdata = viewgroup;
+ gzgroup->customdata = viewgroup;
}
static void WIDGETGROUP_camera_view_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
{
- struct CameraViewWidgetGroup *viewgroup = gzgroup->customdata;
-
- ARegion *ar = CTX_wm_region(C);
- struct Depsgraph *depsgraph = CTX_data_depsgraph(C);
- RegionView3D *rv3d = ar->regiondata;
- if (rv3d->persp == RV3D_CAMOB) {
- Scene *scene = CTX_data_scene(C);
- View3D *v3d = CTX_wm_view3d(C);
- ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &viewgroup->state.view_border, false);
- }
- else {
- viewgroup->state.view_border = (rctf){ .xmin = 0, .ymin = 0, .xmax = ar->winx, .ymax = ar->winy, };
- }
-
- wmGizmo *gz = viewgroup->border;
- unit_m4(gz->matrix_space);
- mul_v3_fl(gz->matrix_space[0], BLI_rctf_size_x(&viewgroup->state.view_border));
- mul_v3_fl(gz->matrix_space[1], BLI_rctf_size_y(&viewgroup->state.view_border));
- gz->matrix_space[3][0] = viewgroup->state.view_border.xmin;
- gz->matrix_space[3][1] = viewgroup->state.view_border.ymin;
+ struct CameraViewWidgetGroup *viewgroup = gzgroup->customdata;
+
+ ARegion *ar = CTX_wm_region(C);
+ struct Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ RegionView3D *rv3d = ar->regiondata;
+ if (rv3d->persp == RV3D_CAMOB) {
+ Scene *scene = CTX_data_scene(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ ED_view3d_calc_camera_border(
+ scene, depsgraph, ar, v3d, rv3d, &viewgroup->state.view_border, false);
+ }
+ else {
+ viewgroup->state.view_border = (rctf){
+ .xmin = 0,
+ .ymin = 0,
+ .xmax = ar->winx,
+ .ymax = ar->winy,
+ };
+ }
+
+ wmGizmo *gz = viewgroup->border;
+ unit_m4(gz->matrix_space);
+ mul_v3_fl(gz->matrix_space[0], BLI_rctf_size_x(&viewgroup->state.view_border));
+ mul_v3_fl(gz->matrix_space[1], BLI_rctf_size_y(&viewgroup->state.view_border));
+ gz->matrix_space[3][0] = viewgroup->state.view_border.xmin;
+ gz->matrix_space[3][1] = viewgroup->state.view_border.ymin;
}
static void WIDGETGROUP_camera_view_refresh(const bContext *C, wmGizmoGroup *gzgroup)
{
- struct CameraViewWidgetGroup *viewgroup = gzgroup->customdata;
-
- View3D *v3d = CTX_wm_view3d(C);
- ARegion *ar = CTX_wm_region(C);
- RegionView3D *rv3d = ar->regiondata;
- Scene *scene = CTX_data_scene(C);
-
- viewgroup->scene = scene;
-
- {
- wmGizmo *gz = viewgroup->border;
- WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
-
- RNA_enum_set(viewgroup->border->ptr, "transform",
- ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE | ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE);
-
- if (rv3d->persp == RV3D_CAMOB) {
- viewgroup->state.edit_border = &scene->r.border;
- viewgroup->is_camera = true;
- }
- else {
- viewgroup->state.edit_border = &v3d->render_border;
- viewgroup->is_camera = false;
- }
-
- WM_gizmo_target_property_def_func(
- gz, "matrix",
- &(const struct wmGizmoPropertyFnParams) {
- .value_get_fn = gizmo_render_border_prop_matrix_get,
- .value_set_fn = gizmo_render_border_prop_matrix_set,
- .range_get_fn = NULL,
- .user_data = viewgroup,
- });
- }
-
+ struct CameraViewWidgetGroup *viewgroup = gzgroup->customdata;
+
+ View3D *v3d = CTX_wm_view3d(C);
+ ARegion *ar = CTX_wm_region(C);
+ RegionView3D *rv3d = ar->regiondata;
+ Scene *scene = CTX_data_scene(C);
+
+ viewgroup->scene = scene;
+
+ {
+ wmGizmo *gz = viewgroup->border;
+ WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
+
+ RNA_enum_set(viewgroup->border->ptr,
+ "transform",
+ ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE | ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE);
+
+ if (rv3d->persp == RV3D_CAMOB) {
+ viewgroup->state.edit_border = &scene->r.border;
+ viewgroup->is_camera = true;
+ }
+ else {
+ viewgroup->state.edit_border = &v3d->render_border;
+ viewgroup->is_camera = false;
+ }
+
+ WM_gizmo_target_property_def_func(gz,
+ "matrix",
+ &(const struct wmGizmoPropertyFnParams){
+ .value_get_fn = gizmo_render_border_prop_matrix_get,
+ .value_set_fn = gizmo_render_border_prop_matrix_set,
+ .range_get_fn = NULL,
+ .user_data = viewgroup,
+ });
+ }
}
void VIEW3D_GGT_camera_view(wmGizmoGroupType *gzgt)
{
- gzgt->name = "Camera View Widgets";
- gzgt->idname = "VIEW3D_GGT_camera_view";
+ gzgt->name = "Camera View Widgets";
+ gzgt->idname = "VIEW3D_GGT_camera_view";
- gzgt->flag = (WM_GIZMOGROUPTYPE_PERSISTENT |
- WM_GIZMOGROUPTYPE_SCALE);
+ gzgt->flag = (WM_GIZMOGROUPTYPE_PERSISTENT | WM_GIZMOGROUPTYPE_SCALE);
- gzgt->poll = WIDGETGROUP_camera_view_poll;
- gzgt->setup = WIDGETGROUP_camera_view_setup;
- gzgt->draw_prepare = WIDGETGROUP_camera_view_draw_prepare;
- gzgt->refresh = WIDGETGROUP_camera_view_refresh;
+ gzgt->poll = WIDGETGROUP_camera_view_poll;
+ gzgt->setup = WIDGETGROUP_camera_view_setup;
+ gzgt->draw_prepare = WIDGETGROUP_camera_view_draw_prepare;
+ gzgt->refresh = WIDGETGROUP_camera_view_refresh;
}
/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_empty.c b/source/blender/editors/space_view3d/view3d_gizmo_empty.c
index 8e78fe8a18e..6a3979ae458 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_empty.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_empty.c
@@ -18,7 +18,6 @@
* \ingroup spview3d
*/
-
#include "BLI_math.h"
#include "BLI_utildefines.h"
@@ -43,167 +42,165 @@
#include "WM_api.h"
#include "WM_types.h"
-#include "view3d_intern.h" /* own include */
+#include "view3d_intern.h" /* own include */
/* -------------------------------------------------------------------- */
/** \name Empty Image Gizmos
* \{ */
struct EmptyImageWidgetGroup {
- wmGizmo *gizmo;
- struct {
- Object *ob;
- float dims[2];
- } state;
+ wmGizmo *gizmo;
+ struct {
+ Object *ob;
+ float dims[2];
+ } state;
};
/* translate callbacks */
-static void gizmo_empty_image_prop_matrix_get(
- const wmGizmo *gz, wmGizmoProperty *gz_prop,
- void *value_p)
+static void gizmo_empty_image_prop_matrix_get(const wmGizmo *gz,
+ wmGizmoProperty *gz_prop,
+ void *value_p)
{
- float (*matrix)[4] = value_p;
- BLI_assert(gz_prop->type->array_length == 16);
- struct EmptyImageWidgetGroup *igzgroup = gz_prop->custom_func.user_data;
- const Object *ob = igzgroup->state.ob;
-
- unit_m4(matrix);
- matrix[0][0] = ob->empty_drawsize;
- matrix[1][1] = ob->empty_drawsize;
-
- float dims[2] = {0.0f, 0.0f};
- RNA_float_get_array(gz->ptr, "dimensions", dims);
- dims[0] *= ob->empty_drawsize;
- dims[1] *= ob->empty_drawsize;
-
- matrix[3][0] = (ob->ima_ofs[0] * dims[0]) + (0.5f * dims[0]);
- matrix[3][1] = (ob->ima_ofs[1] * dims[1]) + (0.5f * dims[1]);
+ float(*matrix)[4] = value_p;
+ BLI_assert(gz_prop->type->array_length == 16);
+ struct EmptyImageWidgetGroup *igzgroup = gz_prop->custom_func.user_data;
+ const Object *ob = igzgroup->state.ob;
+
+ unit_m4(matrix);
+ matrix[0][0] = ob->empty_drawsize;
+ matrix[1][1] = ob->empty_drawsize;
+
+ float dims[2] = {0.0f, 0.0f};
+ RNA_float_get_array(gz->ptr, "dimensions", dims);
+ dims[0] *= ob->empty_drawsize;
+ dims[1] *= ob->empty_drawsize;
+
+ matrix[3][0] = (ob->ima_ofs[0] * dims[0]) + (0.5f * dims[0]);
+ matrix[3][1] = (ob->ima_ofs[1] * dims[1]) + (0.5f * dims[1]);
}
-static void gizmo_empty_image_prop_matrix_set(
- const wmGizmo *gz, wmGizmoProperty *gz_prop,
- const void *value_p)
+static void gizmo_empty_image_prop_matrix_set(const wmGizmo *gz,
+ wmGizmoProperty *gz_prop,
+ const void *value_p)
{
- const float (*matrix)[4] = value_p;
- BLI_assert(gz_prop->type->array_length == 16);
- struct EmptyImageWidgetGroup *igzgroup = gz_prop->custom_func.user_data;
- Object *ob = igzgroup->state.ob;
+ const float(*matrix)[4] = value_p;
+ BLI_assert(gz_prop->type->array_length == 16);
+ struct EmptyImageWidgetGroup *igzgroup = gz_prop->custom_func.user_data;
+ Object *ob = igzgroup->state.ob;
- ob->empty_drawsize = matrix[0][0];
- DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
+ ob->empty_drawsize = matrix[0][0];
+ DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
- float dims[2];
- RNA_float_get_array(gz->ptr, "dimensions", dims);
- dims[0] *= ob->empty_drawsize;
- dims[1] *= ob->empty_drawsize;
+ float dims[2];
+ RNA_float_get_array(gz->ptr, "dimensions", dims);
+ dims[0] *= ob->empty_drawsize;
+ dims[1] *= ob->empty_drawsize;
- ob->ima_ofs[0] = (matrix[3][0] - (0.5f * dims[0])) / dims[0];
- ob->ima_ofs[1] = (matrix[3][1] - (0.5f * dims[1])) / dims[1];
+ ob->ima_ofs[0] = (matrix[3][0] - (0.5f * dims[0])) / dims[0];
+ ob->ima_ofs[1] = (matrix[3][1] - (0.5f * dims[1])) / dims[1];
}
static bool WIDGETGROUP_empty_image_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
{
- View3D *v3d = CTX_wm_view3d(C);
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
-
- if (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT)) {
- return false;
- }
- if ((v3d->gizmo_show_empty & V3D_GIZMO_SHOW_EMPTY_IMAGE) == 0) {
- return false;
- }
-
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Base *base = BASACT(view_layer);
- if (base && BASE_SELECTABLE(v3d, base)) {
- Object *ob = base->object;
- if (ob->type == OB_EMPTY) {
- if (ob->empty_drawtype == OB_EMPTY_IMAGE) {
- return BKE_object_empty_image_frame_is_visible_in_view3d(ob, rv3d);
- }
- }
- }
- return false;
+ View3D *v3d = CTX_wm_view3d(C);
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+
+ if (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT)) {
+ return false;
+ }
+ if ((v3d->gizmo_show_empty & V3D_GIZMO_SHOW_EMPTY_IMAGE) == 0) {
+ return false;
+ }
+
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Base *base = BASACT(view_layer);
+ if (base && BASE_SELECTABLE(v3d, base)) {
+ Object *ob = base->object;
+ if (ob->type == OB_EMPTY) {
+ if (ob->empty_drawtype == OB_EMPTY_IMAGE) {
+ return BKE_object_empty_image_frame_is_visible_in_view3d(ob, rv3d);
+ }
+ }
+ }
+ return false;
}
static void WIDGETGROUP_empty_image_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
{
- struct EmptyImageWidgetGroup *igzgroup = MEM_mallocN(sizeof(struct EmptyImageWidgetGroup), __func__);
- igzgroup->gizmo = WM_gizmo_new("GIZMO_GT_cage_2d", gzgroup, NULL);
- wmGizmo *gz = igzgroup->gizmo;
- RNA_enum_set(gz->ptr, "transform",
- ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE);
+ struct EmptyImageWidgetGroup *igzgroup = MEM_mallocN(sizeof(struct EmptyImageWidgetGroup),
+ __func__);
+ igzgroup->gizmo = WM_gizmo_new("GIZMO_GT_cage_2d", gzgroup, NULL);
+ wmGizmo *gz = igzgroup->gizmo;
+ RNA_enum_set(gz->ptr, "transform", ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE);
- gzgroup->customdata = igzgroup;
+ gzgroup->customdata = igzgroup;
- WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_HOVER, true);
+ WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_HOVER, true);
- UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color);
- UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
+ UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color);
+ UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
}
static void WIDGETGROUP_empty_image_refresh(const bContext *C, wmGizmoGroup *gzgroup)
{
- struct EmptyImageWidgetGroup *igzgroup = gzgroup->customdata;
- wmGizmo *gz = igzgroup->gizmo;
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *ob = OBACT(view_layer);
-
- copy_m4_m4(gz->matrix_basis, ob->obmat);
-
- RNA_enum_set(gz->ptr, "transform",
- ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE |
- ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE |
- ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE_UNIFORM);
-
- igzgroup->state.ob = ob;
-
- /* Use dimensions for aspect. */
- if (ob->data != NULL) {
- const Image *image = ob->data;
- ImageUser iuser = *ob->iuser;
- float size[2];
- BKE_image_get_size_fl(ob->data, &iuser, size);
-
- /* Get the image aspect even if the buffer is invalid */
- if (image->aspx > image->aspy) {
- size[1] *= image->aspy / image->aspx;
- }
- else if (image->aspx < image->aspy) {
- size[0] *= image->aspx / image->aspy;
- }
-
- const float dims_max = max_ff(size[0], size[1]);
- igzgroup->state.dims[0] = size[0] / dims_max;
- igzgroup->state.dims[1] = size[1] / dims_max;
- }
- else {
- copy_v2_fl(igzgroup->state.dims, 1.0f);
- }
- RNA_float_set_array(gz->ptr, "dimensions", igzgroup->state.dims);
-
- WM_gizmo_target_property_def_func(
- gz, "matrix",
- &(const struct wmGizmoPropertyFnParams) {
- .value_get_fn = gizmo_empty_image_prop_matrix_get,
- .value_set_fn = gizmo_empty_image_prop_matrix_set,
- .range_get_fn = NULL,
- .user_data = igzgroup,
- });
+ struct EmptyImageWidgetGroup *igzgroup = gzgroup->customdata;
+ wmGizmo *gz = igzgroup->gizmo;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *ob = OBACT(view_layer);
+
+ copy_m4_m4(gz->matrix_basis, ob->obmat);
+
+ RNA_enum_set(gz->ptr,
+ "transform",
+ ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE | ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE |
+ ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE_UNIFORM);
+
+ igzgroup->state.ob = ob;
+
+ /* Use dimensions for aspect. */
+ if (ob->data != NULL) {
+ const Image *image = ob->data;
+ ImageUser iuser = *ob->iuser;
+ float size[2];
+ BKE_image_get_size_fl(ob->data, &iuser, size);
+
+ /* Get the image aspect even if the buffer is invalid */
+ if (image->aspx > image->aspy) {
+ size[1] *= image->aspy / image->aspx;
+ }
+ else if (image->aspx < image->aspy) {
+ size[0] *= image->aspx / image->aspy;
+ }
+
+ const float dims_max = max_ff(size[0], size[1]);
+ igzgroup->state.dims[0] = size[0] / dims_max;
+ igzgroup->state.dims[1] = size[1] / dims_max;
+ }
+ else {
+ copy_v2_fl(igzgroup->state.dims, 1.0f);
+ }
+ RNA_float_set_array(gz->ptr, "dimensions", igzgroup->state.dims);
+
+ WM_gizmo_target_property_def_func(gz,
+ "matrix",
+ &(const struct wmGizmoPropertyFnParams){
+ .value_get_fn = gizmo_empty_image_prop_matrix_get,
+ .value_set_fn = gizmo_empty_image_prop_matrix_set,
+ .range_get_fn = NULL,
+ .user_data = igzgroup,
+ });
}
void VIEW3D_GGT_empty_image(wmGizmoGroupType *gzgt)
{
- gzgt->name = "Area Light Widgets";
- gzgt->idname = "VIEW3D_GGT_empty_image";
+ gzgt->name = "Area Light Widgets";
+ gzgt->idname = "VIEW3D_GGT_empty_image";
- gzgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT |
- WM_GIZMOGROUPTYPE_3D |
- WM_GIZMOGROUPTYPE_DEPTH_3D);
+ gzgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT | WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_DEPTH_3D);
- gzgt->poll = WIDGETGROUP_empty_image_poll;
- gzgt->setup = WIDGETGROUP_empty_image_setup;
- gzgt->refresh = WIDGETGROUP_empty_image_refresh;
+ gzgt->poll = WIDGETGROUP_empty_image_poll;
+ gzgt->setup = WIDGETGROUP_empty_image_setup;
+ gzgt->refresh = WIDGETGROUP_empty_image_refresh;
}
/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_forcefield.c b/source/blender/editors/space_view3d/view3d_gizmo_forcefield.c
index 34cf38b3466..7d3e22b4d70 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_forcefield.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_forcefield.c
@@ -18,7 +18,6 @@
* \ingroup spview3d
*/
-
#include "BLI_utildefines.h"
#include "BKE_context.h"
@@ -39,7 +38,7 @@
#include "WM_api.h"
#include "WM_types.h"
-#include "view3d_intern.h" /* own include */
+#include "view3d_intern.h" /* own include */
/* -------------------------------------------------------------------- */
/** \name Force Field Gizmos
@@ -47,80 +46,78 @@
static bool WIDGETGROUP_forcefield_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
{
- View3D *v3d = CTX_wm_view3d(C);
-
- if (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT)) {
- return false;
- }
- if ((v3d->gizmo_show_empty & V3D_GIZMO_SHOW_EMPTY_FORCE_FIELD) == 0) {
- return false;
- }
-
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Base *base = BASACT(view_layer);
- if (base && BASE_SELECTABLE(v3d, base)) {
- Object *ob = base->object;
- if (ob->pd && ob->pd->forcefield) {
- return true;
- }
- }
- return false;
+ View3D *v3d = CTX_wm_view3d(C);
+
+ if (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT)) {
+ return false;
+ }
+ if ((v3d->gizmo_show_empty & V3D_GIZMO_SHOW_EMPTY_FORCE_FIELD) == 0) {
+ return false;
+ }
+
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Base *base = BASACT(view_layer);
+ if (base && BASE_SELECTABLE(v3d, base)) {
+ Object *ob = base->object;
+ if (ob->pd && ob->pd->forcefield) {
+ return true;
+ }
+ }
+ return false;
}
static void WIDGETGROUP_forcefield_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
{
- /* only wind effector for now */
- wmGizmoWrapper *wwrapper = MEM_mallocN(sizeof(wmGizmoWrapper), __func__);
- gzgroup->customdata = wwrapper;
-
- wwrapper->gizmo = WM_gizmo_new("GIZMO_GT_arrow_3d", gzgroup, NULL);
- wmGizmo *gz = wwrapper->gizmo;
- RNA_enum_set(gz->ptr, "transform", ED_GIZMO_ARROW_XFORM_FLAG_CONSTRAINED);
- ED_gizmo_arrow3d_set_ui_range(gz, -200.0f, 200.0f);
- ED_gizmo_arrow3d_set_range_fac(gz, 6.0f);
-
- UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color);
- UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
+ /* only wind effector for now */
+ wmGizmoWrapper *wwrapper = MEM_mallocN(sizeof(wmGizmoWrapper), __func__);
+ gzgroup->customdata = wwrapper;
+
+ wwrapper->gizmo = WM_gizmo_new("GIZMO_GT_arrow_3d", gzgroup, NULL);
+ wmGizmo *gz = wwrapper->gizmo;
+ RNA_enum_set(gz->ptr, "transform", ED_GIZMO_ARROW_XFORM_FLAG_CONSTRAINED);
+ ED_gizmo_arrow3d_set_ui_range(gz, -200.0f, 200.0f);
+ ED_gizmo_arrow3d_set_range_fac(gz, 6.0f);
+
+ UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color);
+ UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
}
static void WIDGETGROUP_forcefield_refresh(const bContext *C, wmGizmoGroup *gzgroup)
{
- wmGizmoWrapper *wwrapper = gzgroup->customdata;
- wmGizmo *gz = wwrapper->gizmo;
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *ob = OBACT(view_layer);
- PartDeflect *pd = ob->pd;
-
- if (pd->forcefield == PFIELD_WIND) {
- const float size = (ob->type == OB_EMPTY) ? ob->empty_drawsize : 1.0f;
- const float ofs[3] = {0.0f, -size, 0.0f};
- PointerRNA field_ptr;
-
- RNA_pointer_create(&ob->id, &RNA_FieldSettings, pd, &field_ptr);
- WM_gizmo_set_matrix_location(gz, ob->obmat[3]);
- WM_gizmo_set_matrix_rotation_from_z_axis(gz, ob->obmat[2]);
- WM_gizmo_set_matrix_offset_location(gz, ofs);
- WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
- WM_gizmo_target_property_def_rna(gz, "offset", &field_ptr, "strength", -1);
- }
- else {
- WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true);
- }
+ wmGizmoWrapper *wwrapper = gzgroup->customdata;
+ wmGizmo *gz = wwrapper->gizmo;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *ob = OBACT(view_layer);
+ PartDeflect *pd = ob->pd;
+
+ if (pd->forcefield == PFIELD_WIND) {
+ const float size = (ob->type == OB_EMPTY) ? ob->empty_drawsize : 1.0f;
+ const float ofs[3] = {0.0f, -size, 0.0f};
+ PointerRNA field_ptr;
+
+ RNA_pointer_create(&ob->id, &RNA_FieldSettings, pd, &field_ptr);
+ WM_gizmo_set_matrix_location(gz, ob->obmat[3]);
+ WM_gizmo_set_matrix_rotation_from_z_axis(gz, ob->obmat[2]);
+ WM_gizmo_set_matrix_offset_location(gz, ofs);
+ WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
+ WM_gizmo_target_property_def_rna(gz, "offset", &field_ptr, "strength", -1);
+ }
+ else {
+ WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true);
+ }
}
void VIEW3D_GGT_force_field(wmGizmoGroupType *gzgt)
{
- gzgt->name = "Force Field Widgets";
- gzgt->idname = "VIEW3D_GGT_force_field";
+ gzgt->name = "Force Field Widgets";
+ gzgt->idname = "VIEW3D_GGT_force_field";
- gzgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT |
- WM_GIZMOGROUPTYPE_3D |
- WM_GIZMOGROUPTYPE_SCALE |
- WM_GIZMOGROUPTYPE_DEPTH_3D);
+ gzgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT | WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_SCALE |
+ WM_GIZMOGROUPTYPE_DEPTH_3D);
- gzgt->poll = WIDGETGROUP_forcefield_poll;
- gzgt->setup = WIDGETGROUP_forcefield_setup;
- gzgt->refresh = WIDGETGROUP_forcefield_refresh;
+ gzgt->poll = WIDGETGROUP_forcefield_poll;
+ gzgt->setup = WIDGETGROUP_forcefield_setup;
+ gzgt->refresh = WIDGETGROUP_forcefield_refresh;
}
/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_light.c b/source/blender/editors/space_view3d/view3d_gizmo_light.c
index 5fd5336f4ca..8c6f783de61 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_light.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_light.c
@@ -18,7 +18,6 @@
* \ingroup spview3d
*/
-
#include "BLI_math.h"
#include "BLI_utildefines.h"
@@ -42,7 +41,7 @@
#include "WM_api.h"
#include "WM_types.h"
-#include "view3d_intern.h" /* own include */
+#include "view3d_intern.h" /* own include */
/* -------------------------------------------------------------------- */
/** \name Spot Light Gizmos
@@ -50,74 +49,72 @@
static bool WIDGETGROUP_light_spot_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
{
- View3D *v3d = CTX_wm_view3d(C);
- if (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT)) {
- return false;
- }
- if ((v3d->gizmo_show_light & V3D_GIZMO_SHOW_LIGHT_SIZE) == 0) {
- return false;
- }
-
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Base *base = BASACT(view_layer);
- if (base && BASE_SELECTABLE(v3d, base)) {
- Object *ob = base->object;
- if (ob->type == OB_LAMP) {
- Light *la = ob->data;
- return (la->type == LA_SPOT);
- }
- }
- return false;
+ View3D *v3d = CTX_wm_view3d(C);
+ if (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT)) {
+ return false;
+ }
+ if ((v3d->gizmo_show_light & V3D_GIZMO_SHOW_LIGHT_SIZE) == 0) {
+ return false;
+ }
+
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Base *base = BASACT(view_layer);
+ if (base && BASE_SELECTABLE(v3d, base)) {
+ Object *ob = base->object;
+ if (ob->type == OB_LAMP) {
+ Light *la = ob->data;
+ return (la->type == LA_SPOT);
+ }
+ }
+ return false;
}
static void WIDGETGROUP_light_spot_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
{
- wmGizmoWrapper *wwrapper = MEM_mallocN(sizeof(wmGizmoWrapper), __func__);
+ wmGizmoWrapper *wwrapper = MEM_mallocN(sizeof(wmGizmoWrapper), __func__);
- wwrapper->gizmo = WM_gizmo_new("GIZMO_GT_arrow_3d", gzgroup, NULL);
- wmGizmo *gz = wwrapper->gizmo;
- RNA_enum_set(gz->ptr, "transform", ED_GIZMO_ARROW_XFORM_FLAG_INVERTED);
+ wwrapper->gizmo = WM_gizmo_new("GIZMO_GT_arrow_3d", gzgroup, NULL);
+ wmGizmo *gz = wwrapper->gizmo;
+ RNA_enum_set(gz->ptr, "transform", ED_GIZMO_ARROW_XFORM_FLAG_INVERTED);
- gzgroup->customdata = wwrapper;
+ gzgroup->customdata = wwrapper;
- ED_gizmo_arrow3d_set_range_fac(gz, 4.0f);
+ ED_gizmo_arrow3d_set_range_fac(gz, 4.0f);
- UI_GetThemeColor3fv(TH_GIZMO_SECONDARY, gz->color);
+ UI_GetThemeColor3fv(TH_GIZMO_SECONDARY, gz->color);
}
static void WIDGETGROUP_light_spot_refresh(const bContext *C, wmGizmoGroup *gzgroup)
{
- wmGizmoWrapper *wwrapper = gzgroup->customdata;
- wmGizmo *gz = wwrapper->gizmo;
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *ob = OBACT(view_layer);
- Light *la = ob->data;
- float dir[3];
-
- negate_v3_v3(dir, ob->obmat[2]);
-
- WM_gizmo_set_matrix_rotation_from_z_axis(gz, dir);
- WM_gizmo_set_matrix_location(gz, ob->obmat[3]);
-
- /* need to set property here for undo. TODO would prefer to do this in _init */
- PointerRNA lamp_ptr;
- const char *propname = "spot_size";
- RNA_pointer_create(&la->id, &RNA_Light, la, &lamp_ptr);
- WM_gizmo_target_property_def_rna(gz, "offset", &lamp_ptr, propname, -1);
+ wmGizmoWrapper *wwrapper = gzgroup->customdata;
+ wmGizmo *gz = wwrapper->gizmo;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *ob = OBACT(view_layer);
+ Light *la = ob->data;
+ float dir[3];
+
+ negate_v3_v3(dir, ob->obmat[2]);
+
+ WM_gizmo_set_matrix_rotation_from_z_axis(gz, dir);
+ WM_gizmo_set_matrix_location(gz, ob->obmat[3]);
+
+ /* need to set property here for undo. TODO would prefer to do this in _init */
+ PointerRNA lamp_ptr;
+ const char *propname = "spot_size";
+ RNA_pointer_create(&la->id, &RNA_Light, la, &lamp_ptr);
+ WM_gizmo_target_property_def_rna(gz, "offset", &lamp_ptr, propname, -1);
}
void VIEW3D_GGT_light_spot(wmGizmoGroupType *gzgt)
{
- gzgt->name = "Spot Light Widgets";
- gzgt->idname = "VIEW3D_GGT_light_spot";
+ gzgt->name = "Spot Light Widgets";
+ gzgt->idname = "VIEW3D_GGT_light_spot";
- gzgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT |
- WM_GIZMOGROUPTYPE_3D |
- WM_GIZMOGROUPTYPE_DEPTH_3D);
+ gzgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT | WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_DEPTH_3D);
- gzgt->poll = WIDGETGROUP_light_spot_poll;
- gzgt->setup = WIDGETGROUP_light_spot_setup;
- gzgt->refresh = WIDGETGROUP_light_spot_refresh;
+ gzgt->poll = WIDGETGROUP_light_spot_poll;
+ gzgt->setup = WIDGETGROUP_light_spot_setup;
+ gzgt->refresh = WIDGETGROUP_light_spot_refresh;
}
/** \} */
@@ -127,204 +124,200 @@ void VIEW3D_GGT_light_spot(wmGizmoGroupType *gzgt)
* \{ */
/* scale callbacks */
-static void gizmo_area_light_prop_matrix_get(
- const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop,
- void *value_p)
+static void gizmo_area_light_prop_matrix_get(const wmGizmo *UNUSED(gz),
+ wmGizmoProperty *gz_prop,
+ void *value_p)
{
- BLI_assert(gz_prop->type->array_length == 16);
- float (*matrix)[4] = value_p;
- const Light *la = gz_prop->custom_func.user_data;
+ BLI_assert(gz_prop->type->array_length == 16);
+ float(*matrix)[4] = value_p;
+ const Light *la = gz_prop->custom_func.user_data;
- matrix[0][0] = la->area_size;
- matrix[1][1] = ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_ELLIPSE) ? la->area_sizey : la->area_size;
+ matrix[0][0] = la->area_size;
+ matrix[1][1] = ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_ELLIPSE) ? la->area_sizey :
+ la->area_size;
}
-static void gizmo_area_light_prop_matrix_set(
- const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop,
- const void *value_p)
+static void gizmo_area_light_prop_matrix_set(const wmGizmo *UNUSED(gz),
+ wmGizmoProperty *gz_prop,
+ const void *value_p)
{
- const float (*matrix)[4] = value_p;
- BLI_assert(gz_prop->type->array_length == 16);
- Light *la = gz_prop->custom_func.user_data;
-
- if (ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_ELLIPSE)) {
- la->area_size = len_v3(matrix[0]);
- la->area_sizey = len_v3(matrix[1]);
- }
- else {
- la->area_size = len_v3(matrix[0]);
- }
-
- DEG_id_tag_update(&la->id, ID_RECALC_COPY_ON_WRITE);
- WM_main_add_notifier(NC_LAMP | ND_LIGHTING_DRAW, la);
+ const float(*matrix)[4] = value_p;
+ BLI_assert(gz_prop->type->array_length == 16);
+ Light *la = gz_prop->custom_func.user_data;
+
+ if (ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_ELLIPSE)) {
+ la->area_size = len_v3(matrix[0]);
+ la->area_sizey = len_v3(matrix[1]);
+ }
+ else {
+ la->area_size = len_v3(matrix[0]);
+ }
+
+ DEG_id_tag_update(&la->id, ID_RECALC_COPY_ON_WRITE);
+ WM_main_add_notifier(NC_LAMP | ND_LIGHTING_DRAW, la);
}
static bool WIDGETGROUP_light_area_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
{
- View3D *v3d = CTX_wm_view3d(C);
- if (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT)) {
- return false;
- }
- if ((v3d->gizmo_show_light & V3D_GIZMO_SHOW_LIGHT_SIZE) == 0) {
- return false;
- }
-
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Base *base = BASACT(view_layer);
- if (base && BASE_SELECTABLE(v3d, base)) {
- Object *ob = base->object;
- if (ob->type == OB_LAMP) {
- Light *la = ob->data;
- return (la->type == LA_AREA);
- }
- }
- return false;
+ View3D *v3d = CTX_wm_view3d(C);
+ if (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT)) {
+ return false;
+ }
+ if ((v3d->gizmo_show_light & V3D_GIZMO_SHOW_LIGHT_SIZE) == 0) {
+ return false;
+ }
+
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Base *base = BASACT(view_layer);
+ if (base && BASE_SELECTABLE(v3d, base)) {
+ Object *ob = base->object;
+ if (ob->type == OB_LAMP) {
+ Light *la = ob->data;
+ return (la->type == LA_AREA);
+ }
+ }
+ return false;
}
static void WIDGETGROUP_light_area_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
{
- wmGizmoWrapper *wwrapper = MEM_mallocN(sizeof(wmGizmoWrapper), __func__);
- wwrapper->gizmo = WM_gizmo_new("GIZMO_GT_cage_2d", gzgroup, NULL);
- wmGizmo *gz = wwrapper->gizmo;
- RNA_enum_set(gz->ptr, "transform",
- ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE);
+ wmGizmoWrapper *wwrapper = MEM_mallocN(sizeof(wmGizmoWrapper), __func__);
+ wwrapper->gizmo = WM_gizmo_new("GIZMO_GT_cage_2d", gzgroup, NULL);
+ wmGizmo *gz = wwrapper->gizmo;
+ RNA_enum_set(gz->ptr, "transform", ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE);
- gzgroup->customdata = wwrapper;
+ gzgroup->customdata = wwrapper;
- WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_HOVER, true);
+ WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_HOVER, true);
- UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color);
- UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
+ UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color);
+ UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
}
static void WIDGETGROUP_light_area_refresh(const bContext *C, wmGizmoGroup *gzgroup)
{
- wmGizmoWrapper *wwrapper = gzgroup->customdata;
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *ob = OBACT(view_layer);
- Light *la = ob->data;
- wmGizmo *gz = wwrapper->gizmo;
-
- copy_m4_m4(gz->matrix_basis, ob->obmat);
-
- int flag = ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE;
- if (ELEM(la->area_shape, LA_AREA_SQUARE, LA_AREA_DISK)) {
- flag |= ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE_UNIFORM;
- }
- RNA_enum_set(gz->ptr, "transform", flag);
-
- /* need to set property here for undo. TODO would prefer to do this in _init */
- WM_gizmo_target_property_def_func(
- gz, "matrix",
- &(const struct wmGizmoPropertyFnParams) {
- .value_get_fn = gizmo_area_light_prop_matrix_get,
- .value_set_fn = gizmo_area_light_prop_matrix_set,
- .range_get_fn = NULL,
- .user_data = la,
- });
+ wmGizmoWrapper *wwrapper = gzgroup->customdata;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *ob = OBACT(view_layer);
+ Light *la = ob->data;
+ wmGizmo *gz = wwrapper->gizmo;
+
+ copy_m4_m4(gz->matrix_basis, ob->obmat);
+
+ int flag = ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE;
+ if (ELEM(la->area_shape, LA_AREA_SQUARE, LA_AREA_DISK)) {
+ flag |= ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE_UNIFORM;
+ }
+ RNA_enum_set(gz->ptr, "transform", flag);
+
+ /* need to set property here for undo. TODO would prefer to do this in _init */
+ WM_gizmo_target_property_def_func(gz,
+ "matrix",
+ &(const struct wmGizmoPropertyFnParams){
+ .value_get_fn = gizmo_area_light_prop_matrix_get,
+ .value_set_fn = gizmo_area_light_prop_matrix_set,
+ .range_get_fn = NULL,
+ .user_data = la,
+ });
}
void VIEW3D_GGT_light_area(wmGizmoGroupType *gzgt)
{
- gzgt->name = "Area Light Widgets";
- gzgt->idname = "VIEW3D_GGT_light_area";
+ gzgt->name = "Area Light Widgets";
+ gzgt->idname = "VIEW3D_GGT_light_area";
- gzgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT |
- WM_GIZMOGROUPTYPE_3D |
- WM_GIZMOGROUPTYPE_DEPTH_3D);
+ gzgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT | WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_DEPTH_3D);
- gzgt->poll = WIDGETGROUP_light_area_poll;
- gzgt->setup = WIDGETGROUP_light_area_setup;
- gzgt->refresh = WIDGETGROUP_light_area_refresh;
+ gzgt->poll = WIDGETGROUP_light_area_poll;
+ gzgt->setup = WIDGETGROUP_light_area_setup;
+ gzgt->refresh = WIDGETGROUP_light_area_refresh;
}
/** \} */
-
/* -------------------------------------------------------------------- */
/** \name Light Target Gizmo
* \{ */
static bool WIDGETGROUP_light_target_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
{
- View3D *v3d = CTX_wm_view3d(C);
- if (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT)) {
- return false;
- }
- if ((v3d->gizmo_show_light & V3D_GIZMO_SHOW_LIGHT_LOOK_AT) == 0) {
- return false;
- }
-
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Base *base = BASACT(view_layer);
- if (base && BASE_SELECTABLE(v3d, base)) {
- Object *ob = base->object;
- if (ob->type == OB_LAMP) {
- Light *la = ob->data;
- return (ELEM(la->type, LA_SUN, LA_SPOT, LA_AREA));
- }
+ View3D *v3d = CTX_wm_view3d(C);
+ if (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT)) {
+ return false;
+ }
+ if ((v3d->gizmo_show_light & V3D_GIZMO_SHOW_LIGHT_LOOK_AT) == 0) {
+ return false;
+ }
+
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Base *base = BASACT(view_layer);
+ if (base && BASE_SELECTABLE(v3d, base)) {
+ Object *ob = base->object;
+ if (ob->type == OB_LAMP) {
+ Light *la = ob->data;
+ return (ELEM(la->type, LA_SUN, LA_SPOT, LA_AREA));
+ }
#if 0
- else if (ob->type == OB_CAMERA) {
- return true;
- }
+ else if (ob->type == OB_CAMERA) {
+ return true;
+ }
#endif
- }
- return false;
+ }
+ return false;
}
static void WIDGETGROUP_light_target_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
{
- wmGizmoWrapper *wwrapper = MEM_mallocN(sizeof(wmGizmoWrapper), __func__);
- wwrapper->gizmo = WM_gizmo_new("GIZMO_GT_move_3d", gzgroup, NULL);
- wmGizmo *gz = wwrapper->gizmo;
+ wmGizmoWrapper *wwrapper = MEM_mallocN(sizeof(wmGizmoWrapper), __func__);
+ wwrapper->gizmo = WM_gizmo_new("GIZMO_GT_move_3d", gzgroup, NULL);
+ wmGizmo *gz = wwrapper->gizmo;
- gzgroup->customdata = wwrapper;
+ gzgroup->customdata = wwrapper;
- UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color);
- UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
+ UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color);
+ UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
- gz->scale_basis = 0.06f;
+ gz->scale_basis = 0.06f;
- wmOperatorType *ot = WM_operatortype_find("OBJECT_OT_transform_axis_target", true);
+ wmOperatorType *ot = WM_operatortype_find("OBJECT_OT_transform_axis_target", true);
- RNA_enum_set(gz->ptr, "draw_options",
- ED_GIZMO_MOVE_DRAW_FLAG_FILL | ED_GIZMO_MOVE_DRAW_FLAG_ALIGN_VIEW);
+ RNA_enum_set(
+ gz->ptr, "draw_options", ED_GIZMO_MOVE_DRAW_FLAG_FILL | ED_GIZMO_MOVE_DRAW_FLAG_ALIGN_VIEW);
- WM_gizmo_operator_set(gz, 0, ot, NULL);
+ WM_gizmo_operator_set(gz, 0, ot, NULL);
}
static void WIDGETGROUP_light_target_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
{
- wmGizmoWrapper *wwrapper = gzgroup->customdata;
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *ob = OBACT(view_layer);
- wmGizmo *gz = wwrapper->gizmo;
-
- normalize_m4_m4(gz->matrix_basis, ob->obmat);
- unit_m4(gz->matrix_offset);
-
- if (ob->type == OB_LAMP) {
- Light *la = ob->data;
- if (la->type == LA_SPOT) {
- /* Draw just past the light size angle gizmo. */
- madd_v3_v3fl(gz->matrix_basis[3], gz->matrix_basis[2], -la->spotsize);
- }
- }
- gz->matrix_offset[3][2] -= 23.0;
- WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_OFFSET_SCALE, true);
+ wmGizmoWrapper *wwrapper = gzgroup->customdata;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *ob = OBACT(view_layer);
+ wmGizmo *gz = wwrapper->gizmo;
+
+ normalize_m4_m4(gz->matrix_basis, ob->obmat);
+ unit_m4(gz->matrix_offset);
+
+ if (ob->type == OB_LAMP) {
+ Light *la = ob->data;
+ if (la->type == LA_SPOT) {
+ /* Draw just past the light size angle gizmo. */
+ madd_v3_v3fl(gz->matrix_basis[3], gz->matrix_basis[2], -la->spotsize);
+ }
+ }
+ gz->matrix_offset[3][2] -= 23.0;
+ WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_OFFSET_SCALE, true);
}
void VIEW3D_GGT_light_target(wmGizmoGroupType *gzgt)
{
- gzgt->name = "Target Light Widgets";
- gzgt->idname = "VIEW3D_GGT_light_target";
+ gzgt->name = "Target Light Widgets";
+ gzgt->idname = "VIEW3D_GGT_light_target";
- gzgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT |
- WM_GIZMOGROUPTYPE_3D);
+ gzgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT | WM_GIZMOGROUPTYPE_3D);
- gzgt->poll = WIDGETGROUP_light_target_poll;
- gzgt->setup = WIDGETGROUP_light_target_setup;
- gzgt->draw_prepare = WIDGETGROUP_light_target_draw_prepare;
+ gzgt->poll = WIDGETGROUP_light_target_poll;
+ gzgt->setup = WIDGETGROUP_light_target_setup;
+ gzgt->draw_prepare = WIDGETGROUP_light_target_draw_prepare;
}
/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_navigate.c b/source/blender/editors/space_view3d/view3d_gizmo_navigate.c
index a6fd195b04d..f98a87e84a8 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_navigate.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_navigate.c
@@ -39,7 +39,7 @@
#include "WM_api.h"
#include "WM_types.h"
-#include "view3d_intern.h" /* own include */
+#include "view3d_intern.h" /* own include */
/* -------------------------------------------------------------------- */
/** \name View3D Navigation Gizmo Group
@@ -54,278 +54,280 @@
/* How much mini buttons offset from the primary. */
#define GIZMO_MINI_OFFSET_FAC 0.38f
-
enum {
- GZ_INDEX_MOVE = 0,
- GZ_INDEX_ROTATE = 1,
- GZ_INDEX_ZOOM = 2,
+ GZ_INDEX_MOVE = 0,
+ GZ_INDEX_ROTATE = 1,
+ GZ_INDEX_ZOOM = 2,
- /* just buttons */
- /* overlaps GZ_INDEX_ORTHO (switch between) */
- GZ_INDEX_PERSP = 3,
- GZ_INDEX_ORTHO = 4,
- GZ_INDEX_CAMERA = 5,
+ /* just buttons */
+ /* overlaps GZ_INDEX_ORTHO (switch between) */
+ GZ_INDEX_PERSP = 3,
+ GZ_INDEX_ORTHO = 4,
+ GZ_INDEX_CAMERA = 5,
- GZ_INDEX_TOTAL = 6,
+ GZ_INDEX_TOTAL = 6,
};
struct NavigateGizmoInfo {
- const char *opname;
- const char *gizmo;
- uint icon;
+ const char *opname;
+ const char *gizmo;
+ uint icon;
};
static struct NavigateGizmoInfo g_navigate_params[GZ_INDEX_TOTAL] = {
- {
- .opname = "VIEW3D_OT_move",
- .gizmo = "GIZMO_GT_button_2d",
- ICON_VIEW_PAN,
- }, {
- .opname = "VIEW3D_OT_rotate",
- .gizmo = "VIEW3D_GT_navigate_rotate",
- 0,
- }, {
- .opname = "VIEW3D_OT_zoom",
- .gizmo = "GIZMO_GT_button_2d",
- ICON_VIEW_ZOOM,
- }, {
- .opname = "VIEW3D_OT_view_persportho",
- .gizmo = "GIZMO_GT_button_2d",
- ICON_VIEW_PERSPECTIVE,
- }, {
- .opname = "VIEW3D_OT_view_persportho",
- .gizmo = "GIZMO_GT_button_2d",
- ICON_VIEW_ORTHO,
- }, {
- .opname = "VIEW3D_OT_view_camera",
- .gizmo = "GIZMO_GT_button_2d",
- ICON_VIEW_CAMERA,
- },
+ {
+ .opname = "VIEW3D_OT_move",
+ .gizmo = "GIZMO_GT_button_2d",
+ ICON_VIEW_PAN,
+ },
+ {
+ .opname = "VIEW3D_OT_rotate",
+ .gizmo = "VIEW3D_GT_navigate_rotate",
+ 0,
+ },
+ {
+ .opname = "VIEW3D_OT_zoom",
+ .gizmo = "GIZMO_GT_button_2d",
+ ICON_VIEW_ZOOM,
+ },
+ {
+ .opname = "VIEW3D_OT_view_persportho",
+ .gizmo = "GIZMO_GT_button_2d",
+ ICON_VIEW_PERSPECTIVE,
+ },
+ {
+ .opname = "VIEW3D_OT_view_persportho",
+ .gizmo = "GIZMO_GT_button_2d",
+ ICON_VIEW_ORTHO,
+ },
+ {
+ .opname = "VIEW3D_OT_view_camera",
+ .gizmo = "GIZMO_GT_button_2d",
+ ICON_VIEW_CAMERA,
+ },
};
struct NavigateWidgetGroup {
- wmGizmo *gz_array[GZ_INDEX_TOTAL];
- /* Store the view state to check for changes. */
- struct {
- rcti rect_visible;
- struct {
- char is_persp;
- char is_camera;
- char viewlock;
- } rv3d;
- } state;
- int region_size[2];
+ wmGizmo *gz_array[GZ_INDEX_TOTAL];
+ /* Store the view state to check for changes. */
+ struct {
+ rcti rect_visible;
+ struct {
+ char is_persp;
+ char is_camera;
+ char viewlock;
+ } rv3d;
+ } state;
+ int region_size[2];
};
static bool WIDGETGROUP_navigate_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
{
- View3D *v3d = CTX_wm_view3d(C);
- if (((U.uiflag & USER_SHOW_GIZMO_AXIS) == 0) ||
- (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_NAVIGATE)))
- {
- return false;
- }
- return true;
+ View3D *v3d = CTX_wm_view3d(C);
+ if (((U.uiflag & USER_SHOW_GIZMO_AXIS) == 0) ||
+ (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_NAVIGATE))) {
+ return false;
+ }
+ return true;
}
static void WIDGETGROUP_navigate_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
{
- struct NavigateWidgetGroup *navgroup = MEM_callocN(sizeof(struct NavigateWidgetGroup), __func__);
-
- navgroup->region_size[0] = -1;
- navgroup->region_size[1] = -1;
-
- wmOperatorType *ot_view_axis = WM_operatortype_find("VIEW3D_OT_view_axis", true);
- wmOperatorType *ot_view_camera = WM_operatortype_find("VIEW3D_OT_view_camera", true);
-
- for (int i = 0; i < GZ_INDEX_TOTAL; i++) {
- const struct NavigateGizmoInfo *info = &g_navigate_params[i];
- navgroup->gz_array[i] = WM_gizmo_new(info->gizmo, gzgroup, NULL);
- wmGizmo *gz = navgroup->gz_array[i];
- gz->flag |= WM_GIZMO_MOVE_CURSOR | WM_GIZMO_DRAW_MODAL;
-
- if (i == GZ_INDEX_ROTATE) {
- gz->color[3] = 0.0f;
- copy_v3_fl(gz->color_hi, 0.5f);
- gz->color_hi[3] = 0.5f;
- }
- else {
- uchar icon_color[3];
- UI_GetThemeColor3ubv(TH_TEXT, icon_color);
- int color_tint, color_tint_hi;
- if (icon_color[0] > 128) {
- color_tint = -40;
- color_tint_hi = 60;
- gz->color[3] = 0.5f;
- gz->color_hi[3] = 0.5f;
- }
- else {
- color_tint = 60;
- color_tint_hi = 60;
- gz->color[3] = 0.5f;
- gz->color_hi[3] = 0.75f;
- }
- UI_GetThemeColorShade3fv(TH_HEADER, color_tint, gz->color);
- UI_GetThemeColorShade3fv(TH_HEADER, color_tint_hi, gz->color_hi);
- }
-
- /* may be overwritten later */
- gz->scale_basis = (GIZMO_SIZE * GIZMO_MINI_FAC) / 2;
- if (info->icon != 0) {
- PropertyRNA *prop = RNA_struct_find_property(gz->ptr, "icon");
- RNA_property_enum_set(gz->ptr, prop, info->icon);
- RNA_enum_set(gz->ptr, "draw_options", ED_GIZMO_BUTTON_SHOW_OUTLINE | ED_GIZMO_BUTTON_SHOW_BACKDROP);
- }
-
- wmOperatorType *ot = WM_operatortype_find(info->opname, true);
- WM_gizmo_operator_set(gz, 0, ot, NULL);
- }
-
- {
- wmGizmo *gz = navgroup->gz_array[GZ_INDEX_CAMERA];
- WM_gizmo_operator_set(gz, 0, ot_view_camera, NULL);
- }
-
- /* Click only buttons (not modal). */
- {
- int gz_ids[] = {GZ_INDEX_PERSP, GZ_INDEX_ORTHO, GZ_INDEX_CAMERA};
- for (int i = 0; i < ARRAY_SIZE(gz_ids); i++) {
- wmGizmo *gz = navgroup->gz_array[gz_ids[i]];
- RNA_boolean_set(gz->ptr, "show_drag", false);
- }
- }
-
- /* Modal operators, don't use initial mouse location since we're clicking on a button. */
- {
- int gz_ids[] = {GZ_INDEX_MOVE, GZ_INDEX_ROTATE, GZ_INDEX_ZOOM};
- for (int i = 0; i < ARRAY_SIZE(gz_ids); i++) {
- wmGizmo *gz = navgroup->gz_array[gz_ids[i]];
- wmGizmoOpElem *gzop = WM_gizmo_operator_get(gz, 0);
- RNA_boolean_set(&gzop->ptr, "use_mouse_init", false);
- }
- }
-
- {
- wmGizmo *gz = navgroup->gz_array[GZ_INDEX_ROTATE];
- gz->scale_basis = GIZMO_SIZE / 2;
- char mapping[6] = {
- RV3D_VIEW_LEFT,
- RV3D_VIEW_RIGHT,
- RV3D_VIEW_FRONT,
- RV3D_VIEW_BACK,
- RV3D_VIEW_BOTTOM,
- RV3D_VIEW_TOP,
- };
-
- for (int part_index = 0; part_index < 6; part_index += 1) {
- PointerRNA *ptr = WM_gizmo_operator_set(gz, part_index + 1, ot_view_axis, NULL);
- RNA_enum_set(ptr, "type", mapping[part_index]);
- }
-
- /* When dragging an axis, use this instead. */
- gz->drag_part = 0;
- }
-
- gzgroup->customdata = navgroup;
+ struct NavigateWidgetGroup *navgroup = MEM_callocN(sizeof(struct NavigateWidgetGroup), __func__);
+
+ navgroup->region_size[0] = -1;
+ navgroup->region_size[1] = -1;
+
+ wmOperatorType *ot_view_axis = WM_operatortype_find("VIEW3D_OT_view_axis", true);
+ wmOperatorType *ot_view_camera = WM_operatortype_find("VIEW3D_OT_view_camera", true);
+
+ for (int i = 0; i < GZ_INDEX_TOTAL; i++) {
+ const struct NavigateGizmoInfo *info = &g_navigate_params[i];
+ navgroup->gz_array[i] = WM_gizmo_new(info->gizmo, gzgroup, NULL);
+ wmGizmo *gz = navgroup->gz_array[i];
+ gz->flag |= WM_GIZMO_MOVE_CURSOR | WM_GIZMO_DRAW_MODAL;
+
+ if (i == GZ_INDEX_ROTATE) {
+ gz->color[3] = 0.0f;
+ copy_v3_fl(gz->color_hi, 0.5f);
+ gz->color_hi[3] = 0.5f;
+ }
+ else {
+ uchar icon_color[3];
+ UI_GetThemeColor3ubv(TH_TEXT, icon_color);
+ int color_tint, color_tint_hi;
+ if (icon_color[0] > 128) {
+ color_tint = -40;
+ color_tint_hi = 60;
+ gz->color[3] = 0.5f;
+ gz->color_hi[3] = 0.5f;
+ }
+ else {
+ color_tint = 60;
+ color_tint_hi = 60;
+ gz->color[3] = 0.5f;
+ gz->color_hi[3] = 0.75f;
+ }
+ UI_GetThemeColorShade3fv(TH_HEADER, color_tint, gz->color);
+ UI_GetThemeColorShade3fv(TH_HEADER, color_tint_hi, gz->color_hi);
+ }
+
+ /* may be overwritten later */
+ gz->scale_basis = (GIZMO_SIZE * GIZMO_MINI_FAC) / 2;
+ if (info->icon != 0) {
+ PropertyRNA *prop = RNA_struct_find_property(gz->ptr, "icon");
+ RNA_property_enum_set(gz->ptr, prop, info->icon);
+ RNA_enum_set(
+ gz->ptr, "draw_options", ED_GIZMO_BUTTON_SHOW_OUTLINE | ED_GIZMO_BUTTON_SHOW_BACKDROP);
+ }
+
+ wmOperatorType *ot = WM_operatortype_find(info->opname, true);
+ WM_gizmo_operator_set(gz, 0, ot, NULL);
+ }
+
+ {
+ wmGizmo *gz = navgroup->gz_array[GZ_INDEX_CAMERA];
+ WM_gizmo_operator_set(gz, 0, ot_view_camera, NULL);
+ }
+
+ /* Click only buttons (not modal). */
+ {
+ int gz_ids[] = {GZ_INDEX_PERSP, GZ_INDEX_ORTHO, GZ_INDEX_CAMERA};
+ for (int i = 0; i < ARRAY_SIZE(gz_ids); i++) {
+ wmGizmo *gz = navgroup->gz_array[gz_ids[i]];
+ RNA_boolean_set(gz->ptr, "show_drag", false);
+ }
+ }
+
+ /* Modal operators, don't use initial mouse location since we're clicking on a button. */
+ {
+ int gz_ids[] = {GZ_INDEX_MOVE, GZ_INDEX_ROTATE, GZ_INDEX_ZOOM};
+ for (int i = 0; i < ARRAY_SIZE(gz_ids); i++) {
+ wmGizmo *gz = navgroup->gz_array[gz_ids[i]];
+ wmGizmoOpElem *gzop = WM_gizmo_operator_get(gz, 0);
+ RNA_boolean_set(&gzop->ptr, "use_mouse_init", false);
+ }
+ }
+
+ {
+ wmGizmo *gz = navgroup->gz_array[GZ_INDEX_ROTATE];
+ gz->scale_basis = GIZMO_SIZE / 2;
+ char mapping[6] = {
+ RV3D_VIEW_LEFT,
+ RV3D_VIEW_RIGHT,
+ RV3D_VIEW_FRONT,
+ RV3D_VIEW_BACK,
+ RV3D_VIEW_BOTTOM,
+ RV3D_VIEW_TOP,
+ };
+
+ for (int part_index = 0; part_index < 6; part_index += 1) {
+ PointerRNA *ptr = WM_gizmo_operator_set(gz, part_index + 1, ot_view_axis, NULL);
+ RNA_enum_set(ptr, "type", mapping[part_index]);
+ }
+
+ /* When dragging an axis, use this instead. */
+ gz->drag_part = 0;
+ }
+
+ gzgroup->customdata = navgroup;
}
static void WIDGETGROUP_navigate_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
{
- struct NavigateWidgetGroup *navgroup = gzgroup->customdata;
- ARegion *ar = CTX_wm_region(C);
- const RegionView3D *rv3d = ar->regiondata;
-
- for (int i = 0; i < 3; i++) {
- copy_v3_v3(navgroup->gz_array[GZ_INDEX_ROTATE]->matrix_offset[i], rv3d->viewmat[i]);
- }
-
- rcti rect_visible;
- ED_region_visible_rect(ar, &rect_visible);
-
- if ((navgroup->state.rect_visible.xmax == rect_visible.xmax) &&
- (navgroup->state.rect_visible.ymax == rect_visible.ymax) &&
- (navgroup->state.rv3d.is_persp == rv3d->is_persp) &&
- (navgroup->state.rv3d.is_camera == (rv3d->persp == RV3D_CAMOB)) &&
- (navgroup->state.rv3d.viewlock == rv3d->viewlock))
- {
- return;
- }
-
- navgroup->state.rect_visible = rect_visible;
- navgroup->state.rv3d.is_persp = rv3d->is_persp;
- navgroup->state.rv3d.is_camera = (rv3d->persp == RV3D_CAMOB);
- navgroup->state.rv3d.viewlock = rv3d->viewlock;
-
- const bool show_rotate = (
- ((rv3d->viewlock & RV3D_LOCKED) == 0) &&
- (navgroup->state.rv3d.is_camera == false));
- const bool show_fixed_offset = navgroup->state.rv3d.is_camera;
- const float icon_size = GIZMO_SIZE;
- const float icon_offset = (icon_size * 0.52f) * GIZMO_OFFSET_FAC * UI_DPI_FAC;
- const float icon_offset_mini = icon_size * GIZMO_MINI_OFFSET_FAC * UI_DPI_FAC;
- const float co_rotate[2] = {
- rect_visible.xmax - icon_offset,
- rect_visible.ymax - icon_offset,
- };
- const float co[2] = {
- rect_visible.xmax - ((show_rotate || show_fixed_offset) ? (icon_offset * 2.0f) : (icon_offset_mini * 0.75f)),
- rect_visible.ymax - icon_offset_mini * 0.75f,
- };
-
- wmGizmo *gz;
-
- for (uint i = 0; i < ARRAY_SIZE(navgroup->gz_array); i++) {
- gz = navgroup->gz_array[i];
- WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true);
- }
-
- /* RV3D_LOCKED or Camera: only show supported buttons. */
- if (show_rotate) {
- gz = navgroup->gz_array[GZ_INDEX_ROTATE];
- gz->matrix_basis[3][0] = co_rotate[0];
- gz->matrix_basis[3][1] = co_rotate[1];
- WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
- }
-
- int icon_mini_slot = 0;
-
- gz = navgroup->gz_array[GZ_INDEX_ZOOM];
- gz->matrix_basis[3][0] = co[0] - (icon_offset_mini * icon_mini_slot++);
- gz->matrix_basis[3][1] = co[1];
- WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
-
- gz = navgroup->gz_array[GZ_INDEX_MOVE];
- gz->matrix_basis[3][0] = co[0] - (icon_offset_mini * icon_mini_slot++);
- gz->matrix_basis[3][1] = co[1];
- WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
-
- if ((rv3d->viewlock & RV3D_LOCKED) == 0) {
- gz = navgroup->gz_array[GZ_INDEX_CAMERA];
- gz->matrix_basis[3][0] = co[0] - (icon_offset_mini * icon_mini_slot++);
- gz->matrix_basis[3][1] = co[1];
- WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
-
- if (navgroup->state.rv3d.is_camera == false) {
- gz = navgroup->gz_array[rv3d->is_persp ? GZ_INDEX_PERSP : GZ_INDEX_ORTHO];
- gz->matrix_basis[3][0] = co[0] - (icon_offset_mini * icon_mini_slot++);
- gz->matrix_basis[3][1] = co[1];
- WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
- }
- }
+ struct NavigateWidgetGroup *navgroup = gzgroup->customdata;
+ ARegion *ar = CTX_wm_region(C);
+ const RegionView3D *rv3d = ar->regiondata;
+
+ for (int i = 0; i < 3; i++) {
+ copy_v3_v3(navgroup->gz_array[GZ_INDEX_ROTATE]->matrix_offset[i], rv3d->viewmat[i]);
+ }
+
+ rcti rect_visible;
+ ED_region_visible_rect(ar, &rect_visible);
+
+ if ((navgroup->state.rect_visible.xmax == rect_visible.xmax) &&
+ (navgroup->state.rect_visible.ymax == rect_visible.ymax) &&
+ (navgroup->state.rv3d.is_persp == rv3d->is_persp) &&
+ (navgroup->state.rv3d.is_camera == (rv3d->persp == RV3D_CAMOB)) &&
+ (navgroup->state.rv3d.viewlock == rv3d->viewlock)) {
+ return;
+ }
+
+ navgroup->state.rect_visible = rect_visible;
+ navgroup->state.rv3d.is_persp = rv3d->is_persp;
+ navgroup->state.rv3d.is_camera = (rv3d->persp == RV3D_CAMOB);
+ navgroup->state.rv3d.viewlock = rv3d->viewlock;
+
+ const bool show_rotate = (((rv3d->viewlock & RV3D_LOCKED) == 0) &&
+ (navgroup->state.rv3d.is_camera == false));
+ const bool show_fixed_offset = navgroup->state.rv3d.is_camera;
+ const float icon_size = GIZMO_SIZE;
+ const float icon_offset = (icon_size * 0.52f) * GIZMO_OFFSET_FAC * UI_DPI_FAC;
+ const float icon_offset_mini = icon_size * GIZMO_MINI_OFFSET_FAC * UI_DPI_FAC;
+ const float co_rotate[2] = {
+ rect_visible.xmax - icon_offset,
+ rect_visible.ymax - icon_offset,
+ };
+ const float co[2] = {
+ rect_visible.xmax -
+ ((show_rotate || show_fixed_offset) ? (icon_offset * 2.0f) : (icon_offset_mini * 0.75f)),
+ rect_visible.ymax - icon_offset_mini * 0.75f,
+ };
+
+ wmGizmo *gz;
+
+ for (uint i = 0; i < ARRAY_SIZE(navgroup->gz_array); i++) {
+ gz = navgroup->gz_array[i];
+ WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true);
+ }
+
+ /* RV3D_LOCKED or Camera: only show supported buttons. */
+ if (show_rotate) {
+ gz = navgroup->gz_array[GZ_INDEX_ROTATE];
+ gz->matrix_basis[3][0] = co_rotate[0];
+ gz->matrix_basis[3][1] = co_rotate[1];
+ WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
+ }
+
+ int icon_mini_slot = 0;
+
+ gz = navgroup->gz_array[GZ_INDEX_ZOOM];
+ gz->matrix_basis[3][0] = co[0] - (icon_offset_mini * icon_mini_slot++);
+ gz->matrix_basis[3][1] = co[1];
+ WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
+
+ gz = navgroup->gz_array[GZ_INDEX_MOVE];
+ gz->matrix_basis[3][0] = co[0] - (icon_offset_mini * icon_mini_slot++);
+ gz->matrix_basis[3][1] = co[1];
+ WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
+
+ if ((rv3d->viewlock & RV3D_LOCKED) == 0) {
+ gz = navgroup->gz_array[GZ_INDEX_CAMERA];
+ gz->matrix_basis[3][0] = co[0] - (icon_offset_mini * icon_mini_slot++);
+ gz->matrix_basis[3][1] = co[1];
+ WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
+
+ if (navgroup->state.rv3d.is_camera == false) {
+ gz = navgroup->gz_array[rv3d->is_persp ? GZ_INDEX_PERSP : GZ_INDEX_ORTHO];
+ gz->matrix_basis[3][0] = co[0] - (icon_offset_mini * icon_mini_slot++);
+ gz->matrix_basis[3][1] = co[1];
+ WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
+ }
+ }
}
void VIEW3D_GGT_navigate(wmGizmoGroupType *gzgt)
{
- gzgt->name = "View3D Navigate";
- gzgt->idname = "VIEW3D_GGT_navigate";
+ gzgt->name = "View3D Navigate";
+ gzgt->idname = "VIEW3D_GGT_navigate";
- gzgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT |
- WM_GIZMOGROUPTYPE_SCALE |
- WM_GIZMOGROUPTYPE_DRAW_MODAL_ALL);
+ gzgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT | WM_GIZMOGROUPTYPE_SCALE |
+ WM_GIZMOGROUPTYPE_DRAW_MODAL_ALL);
- gzgt->poll = WIDGETGROUP_navigate_poll;
- gzgt->setup = WIDGETGROUP_navigate_setup;
- gzgt->draw_prepare = WIDGETGROUP_navigate_draw_prepare;
+ gzgt->poll = WIDGETGROUP_navigate_poll;
+ gzgt->setup = WIDGETGROUP_navigate_setup;
+ gzgt->draw_prepare = WIDGETGROUP_navigate_draw_prepare;
}
/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c b/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c
index f9b67a430e6..539b5d93bdf 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c
@@ -33,7 +33,6 @@
#include "BKE_context.h"
-
#include "GPU_immediate.h"
#include "GPU_immediate_util.h"
#include "GPU_matrix.h"
@@ -71,12 +70,12 @@
#define AXIS_HANDLE_OFFSET (1.0f - AXIS_HANDLE_SIZE_FG)
struct AxisDrawInfo {
- /* Matrix is needed for screen-aligned font drawing. */
+ /* Matrix is needed for screen-aligned font drawing. */
#ifdef USE_AXIS_FONT
- float matrix_final[4][4];
+ float matrix_final[4][4];
#endif
#ifdef USE_FADE_BACKGROUND
- float color_bg[3];
+ float color_bg[3];
#endif
};
@@ -86,451 +85,453 @@ struct AxisDrawInfo {
* copied into a 3x3 matrix and normalized.
*/
static void draw_xyz_wire(
- uint pos_id, const float viewmat_local_unit[3][3], const float c[3], float size, int axis)
+ uint pos_id, const float viewmat_local_unit[3][3], const float c[3], float size, int axis)
{
- int line_type;
- float buffer[4][3];
- int n = 0;
+ int line_type;
+ float buffer[4][3];
+ int n = 0;
- float v1[3] = {0.0f, 0.0f, 0.0f}, v2[3] = {0.0f, 0.0f, 0.0f};
- float dim = size * 0.1f;
- float dx[3], dy[3];
+ float v1[3] = {0.0f, 0.0f, 0.0f}, v2[3] = {0.0f, 0.0f, 0.0f};
+ float dim = size * 0.1f;
+ float dx[3], dy[3];
- dx[0] = dim; dx[1] = 0.0f; dx[2] = 0.0f;
- dy[0] = 0.0f; dy[1] = dim; dy[2] = 0.0f;
+ dx[0] = dim;
+ dx[1] = 0.0f;
+ dx[2] = 0.0f;
+ dy[0] = 0.0f;
+ dy[1] = dim;
+ dy[2] = 0.0f;
- switch (axis) {
- case 0: /* x axis */
- line_type = GPU_PRIM_LINES;
+ switch (axis) {
+ case 0: /* x axis */
+ line_type = GPU_PRIM_LINES;
- /* bottom left to top right */
- negate_v3_v3(v1, dx);
- sub_v3_v3(v1, dy);
- copy_v3_v3(v2, dx);
- add_v3_v3(v2, dy);
+ /* bottom left to top right */
+ negate_v3_v3(v1, dx);
+ sub_v3_v3(v1, dy);
+ copy_v3_v3(v2, dx);
+ add_v3_v3(v2, dy);
- copy_v3_v3(buffer[n++], v1);
- copy_v3_v3(buffer[n++], v2);
+ copy_v3_v3(buffer[n++], v1);
+ copy_v3_v3(buffer[n++], v2);
- /* top left to bottom right */
- mul_v3_fl(dy, 2.0f);
- add_v3_v3(v1, dy);
- sub_v3_v3(v2, dy);
+ /* top left to bottom right */
+ mul_v3_fl(dy, 2.0f);
+ add_v3_v3(v1, dy);
+ sub_v3_v3(v2, dy);
- copy_v3_v3(buffer[n++], v1);
- copy_v3_v3(buffer[n++], v2);
+ copy_v3_v3(buffer[n++], v1);
+ copy_v3_v3(buffer[n++], v2);
- break;
- case 1: /* y axis */
- line_type = GPU_PRIM_LINES;
+ break;
+ case 1: /* y axis */
+ line_type = GPU_PRIM_LINES;
- /* bottom left to top right */
- mul_v3_fl(dx, 0.75f);
- negate_v3_v3(v1, dx);
- sub_v3_v3(v1, dy);
- copy_v3_v3(v2, dx);
- add_v3_v3(v2, dy);
+ /* bottom left to top right */
+ mul_v3_fl(dx, 0.75f);
+ negate_v3_v3(v1, dx);
+ sub_v3_v3(v1, dy);
+ copy_v3_v3(v2, dx);
+ add_v3_v3(v2, dy);
- copy_v3_v3(buffer[n++], v1);
- copy_v3_v3(buffer[n++], v2);
+ copy_v3_v3(buffer[n++], v1);
+ copy_v3_v3(buffer[n++], v2);
- /* top left to center */
- mul_v3_fl(dy, 2.0f);
- add_v3_v3(v1, dy);
- zero_v3(v2);
+ /* top left to center */
+ mul_v3_fl(dy, 2.0f);
+ add_v3_v3(v1, dy);
+ zero_v3(v2);
- copy_v3_v3(buffer[n++], v1);
- copy_v3_v3(buffer[n++], v2);
+ copy_v3_v3(buffer[n++], v1);
+ copy_v3_v3(buffer[n++], v2);
- break;
- case 2: /* z axis */
- line_type = GPU_PRIM_LINE_STRIP;
+ break;
+ case 2: /* z axis */
+ line_type = GPU_PRIM_LINE_STRIP;
- /* start at top left */
- negate_v3_v3(v1, dx);
- add_v3_v3(v1, dy);
+ /* start at top left */
+ negate_v3_v3(v1, dx);
+ add_v3_v3(v1, dy);
- copy_v3_v3(buffer[n++], v1);
+ copy_v3_v3(buffer[n++], v1);
- mul_v3_fl(dx, 2.0f);
- add_v3_v3(v1, dx);
+ mul_v3_fl(dx, 2.0f);
+ add_v3_v3(v1, dx);
- copy_v3_v3(buffer[n++], v1);
+ copy_v3_v3(buffer[n++], v1);
- mul_v3_fl(dy, 2.0f);
- sub_v3_v3(v1, dx);
- sub_v3_v3(v1, dy);
+ mul_v3_fl(dy, 2.0f);
+ sub_v3_v3(v1, dx);
+ sub_v3_v3(v1, dy);
- copy_v3_v3(buffer[n++], v1);
+ copy_v3_v3(buffer[n++], v1);
- add_v3_v3(v1, dx);
+ add_v3_v3(v1, dx);
- copy_v3_v3(buffer[n++], v1);
+ copy_v3_v3(buffer[n++], v1);
- break;
- default:
- BLI_assert(0);
- return;
- }
+ break;
+ default:
+ BLI_assert(0);
+ return;
+ }
- for (int i = 0; i < n; i++) {
- mul_transposed_m3_v3((float (*)[3])viewmat_local_unit, buffer[i]);
- add_v3_v3(buffer[i], c);
- }
+ for (int i = 0; i < n; i++) {
+ mul_transposed_m3_v3((float(*)[3])viewmat_local_unit, buffer[i]);
+ add_v3_v3(buffer[i], c);
+ }
- immBegin(line_type, n);
- for (int i = 0; i < n; i++) {
- immVertex3fv(pos_id, buffer[i]);
- }
- immEnd();
+ immBegin(line_type, n);
+ for (int i = 0; i < n; i++) {
+ immVertex3fv(pos_id, buffer[i]);
+ }
+ immEnd();
}
-#endif /* !USE_AXIS_FONT */
+#endif /* !USE_AXIS_FONT */
/**
* \param draw_info: Extra data needed for drawing.
*/
-static void axis_geom_draw(
- const wmGizmo *gz, const float color[4], const bool select,
- const struct AxisDrawInfo *draw_info)
+static void axis_geom_draw(const wmGizmo *gz,
+ const float color[4],
+ const bool select,
+ const struct AxisDrawInfo *draw_info)
{
- GPU_line_width(gz->line_width);
-
- GPUVertFormat *format = immVertexFormat();
- const uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
-
- struct {
- float depth;
- char index;
- char axis;
- bool is_pos;
- } axis_order[6] = {
- {-gz->matrix_offset[0][2], 0, 0, false},
- {+gz->matrix_offset[0][2], 1, 0, true},
- {-gz->matrix_offset[1][2], 2, 1, false},
- {+gz->matrix_offset[1][2], 3, 1, true},
- {-gz->matrix_offset[2][2], 4, 2, false},
- {+gz->matrix_offset[2][2], 5, 2, true},
- };
-
- int axis_align = -1;
- for (int axis = 0; axis < 3; axis++) {
- if (len_squared_v2(gz->matrix_offset[axis]) < 1e-6f) {
- axis_align = axis;
- break;
- }
- }
-
- /* Show backwards pointing highlight on-top (else we can't see it at all). */
- if ((select == false) && (gz->highlight_part > 0) && (axis_align != -1)) {
- if (axis_order[gz->highlight_part - 1].is_pos == false) {
- axis_order[gz->highlight_part - 1].depth = FLT_MAX;
- }
- }
-
- qsort(&axis_order, ARRAY_SIZE(axis_order), sizeof(axis_order[0]), BLI_sortutil_cmp_float);
-
- static const float axis_highlight[4] = {1, 1, 1, 1};
- static const float axis_black[4] = {0, 0, 0, 1};
- static float axis_color[3][4];
-
- const float axis_depth_bias = 0.01f;
+ GPU_line_width(gz->line_width);
+
+ GPUVertFormat *format = immVertexFormat();
+ const uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+
+ struct {
+ float depth;
+ char index;
+ char axis;
+ bool is_pos;
+ } axis_order[6] = {
+ {-gz->matrix_offset[0][2], 0, 0, false},
+ {+gz->matrix_offset[0][2], 1, 0, true},
+ {-gz->matrix_offset[1][2], 2, 1, false},
+ {+gz->matrix_offset[1][2], 3, 1, true},
+ {-gz->matrix_offset[2][2], 4, 2, false},
+ {+gz->matrix_offset[2][2], 5, 2, true},
+ };
+
+ int axis_align = -1;
+ for (int axis = 0; axis < 3; axis++) {
+ if (len_squared_v2(gz->matrix_offset[axis]) < 1e-6f) {
+ axis_align = axis;
+ break;
+ }
+ }
+
+ /* Show backwards pointing highlight on-top (else we can't see it at all). */
+ if ((select == false) && (gz->highlight_part > 0) && (axis_align != -1)) {
+ if (axis_order[gz->highlight_part - 1].is_pos == false) {
+ axis_order[gz->highlight_part - 1].depth = FLT_MAX;
+ }
+ }
+
+ qsort(&axis_order, ARRAY_SIZE(axis_order), sizeof(axis_order[0]), BLI_sortutil_cmp_float);
+
+ static const float axis_highlight[4] = {1, 1, 1, 1};
+ static const float axis_black[4] = {0, 0, 0, 1};
+ static float axis_color[3][4];
+
+ const float axis_depth_bias = 0.01f;
#ifdef USE_AXIS_FONT
- struct {
- float matrix[4][4];
- int id;
- } font;
-
- if (select == false) {
- font.id = blf_mono_font;
- BLF_disable(font.id, BLF_ROTATION | BLF_SHADOW | BLF_MATRIX | BLF_ASPECT | BLF_WORD_WRAP);
- BLF_color4fv(font.id, axis_black);
- BLF_size(font.id, 11 * U.dpi_fac, 72);
-
- /* Calculate the inverse of the (matrix_final * matrix_offset).
- * This allows us to use the final location, while reversing the rotation so fonts
- * show without any rotation. */
- float m3[3][3];
- float m3_offset[3][3];
- copy_m3_m4(m3, draw_info->matrix_final);
- copy_m3_m4(m3_offset, gz->matrix_offset);
- mul_m3_m3m3(m3, m3, m3_offset);
- invert_m3(m3);
- copy_m4_m3(font.matrix, m3);
- }
+ struct {
+ float matrix[4][4];
+ int id;
+ } font;
+
+ if (select == false) {
+ font.id = blf_mono_font;
+ BLF_disable(font.id, BLF_ROTATION | BLF_SHADOW | BLF_MATRIX | BLF_ASPECT | BLF_WORD_WRAP);
+ BLF_color4fv(font.id, axis_black);
+ BLF_size(font.id, 11 * U.dpi_fac, 72);
+
+ /* Calculate the inverse of the (matrix_final * matrix_offset).
+ * This allows us to use the final location, while reversing the rotation so fonts
+ * show without any rotation. */
+ float m3[3][3];
+ float m3_offset[3][3];
+ copy_m3_m4(m3, draw_info->matrix_final);
+ copy_m3_m4(m3_offset, gz->matrix_offset);
+ mul_m3_m3m3(m3, m3, m3_offset);
+ invert_m3(m3);
+ copy_m4_m3(font.matrix, m3);
+ }
#endif
- /* When the cursor is over any of the gizmos (show circle backdrop). */
- const bool is_active = (color[3] != 0.0f);
-
- /* Circle defining active area. */
- if (is_active) {
- immUniformColor4fv(color);
- imm_draw_circle_fill_3d(pos_id, 0, 0, 1.0f, DIAL_RESOLUTION);
- }
-
- GPU_matrix_push();
- GPU_matrix_mul(gz->matrix_offset);
-
- for (int axis_index = 0; axis_index < ARRAY_SIZE(axis_order); axis_index++) {
- const int index = axis_order[axis_index].index;
- const int axis = axis_order[axis_index].axis;
- const bool is_pos = axis_order[axis_index].is_pos;
- const bool is_highlight = index + 1 == gz->highlight_part;
-
- UI_GetThemeColor3fv(TH_AXIS_X + axis, axis_color[axis]);
- axis_color[axis][3] = 1.0f;
-
- const int index_z = axis;
- const int index_y = (axis + 1) % 3;
- const int index_x = (axis + 2) % 3;
-
- bool ok = true;
-
- /* Skip view align axis when selecting (allows to switch to opposite side). */
- if (select && ((axis_align == axis) && (gz->matrix_offset[axis][2] > 0.0f) == is_pos)) {
- ok = false;
- }
- if (ok) {
- /* Check aligned, since the front axis won't display in this case,
- * and we want to make sure all 3 axes have a character at all times. */
- const bool show_axis_char = (is_pos || (axis == axis_align));
- const float v[3] = {0, 0, AXIS_HANDLE_OFFSET * (is_pos ? 1 : -1)};
- const float v_final[3] = {v[index_x], v[index_y], v[index_z]};
- const float *color_current = is_highlight ? axis_highlight : axis_color[axis];
- float color_current_fade[4];
-
- /* Flip the faded state when axis aligned, since we're hiding the front-mode axis
- * otherwise we see the color for the back-most axis, which is useful for
- * click-to-rotate 180d but not useful to visualize.
- *
- * Use depth bias so axis-aligned views show the positive axis as being in-front.
- * This is a detail so primary axes show as dominant.
- */
- const bool is_pos_color = (
- axis_order[axis_index].depth > (axis_depth_bias * (is_pos ? -1 : 1)));
-
-
- if (select == false) {
+ /* When the cursor is over any of the gizmos (show circle backdrop). */
+ const bool is_active = (color[3] != 0.0f);
+
+ /* Circle defining active area. */
+ if (is_active) {
+ immUniformColor4fv(color);
+ imm_draw_circle_fill_3d(pos_id, 0, 0, 1.0f, DIAL_RESOLUTION);
+ }
+
+ GPU_matrix_push();
+ GPU_matrix_mul(gz->matrix_offset);
+
+ for (int axis_index = 0; axis_index < ARRAY_SIZE(axis_order); axis_index++) {
+ const int index = axis_order[axis_index].index;
+ const int axis = axis_order[axis_index].axis;
+ const bool is_pos = axis_order[axis_index].is_pos;
+ const bool is_highlight = index + 1 == gz->highlight_part;
+
+ UI_GetThemeColor3fv(TH_AXIS_X + axis, axis_color[axis]);
+ axis_color[axis][3] = 1.0f;
+
+ const int index_z = axis;
+ const int index_y = (axis + 1) % 3;
+ const int index_x = (axis + 2) % 3;
+
+ bool ok = true;
+
+ /* Skip view align axis when selecting (allows to switch to opposite side). */
+ if (select && ((axis_align == axis) && (gz->matrix_offset[axis][2] > 0.0f) == is_pos)) {
+ ok = false;
+ }
+ if (ok) {
+ /* Check aligned, since the front axis won't display in this case,
+ * and we want to make sure all 3 axes have a character at all times. */
+ const bool show_axis_char = (is_pos || (axis == axis_align));
+ const float v[3] = {0, 0, AXIS_HANDLE_OFFSET * (is_pos ? 1 : -1)};
+ const float v_final[3] = {v[index_x], v[index_y], v[index_z]};
+ const float *color_current = is_highlight ? axis_highlight : axis_color[axis];
+ float color_current_fade[4];
+
+ /* Flip the faded state when axis aligned, since we're hiding the front-mode axis
+ * otherwise we see the color for the back-most axis, which is useful for
+ * click-to-rotate 180d but not useful to visualize.
+ *
+ * Use depth bias so axis-aligned views show the positive axis as being in-front.
+ * This is a detail so primary axes show as dominant.
+ */
+ const bool is_pos_color = (axis_order[axis_index].depth >
+ (axis_depth_bias * (is_pos ? -1 : 1)));
+
+ if (select == false) {
#ifdef USE_FADE_BACKGROUND
- interp_v3_v3v3(color_current_fade, draw_info->color_bg, color_current, is_highlight ? 1.0 : 0.5f);
- color_current_fade[3] = color_current[3];
+ interp_v3_v3v3(
+ color_current_fade, draw_info->color_bg, color_current, is_highlight ? 1.0 : 0.5f);
+ color_current_fade[3] = color_current[3];
#else
- copy_v4_v4(color_current_fade, color_current);
- color_current_fade[3] *= 0.2;
+ copy_v4_v4(color_current_fade, color_current);
+ color_current_fade[3] *= 0.2;
#endif
- }
- else {
- copy_v4_fl(color_current_fade, 1.0f);
- }
-
- /* Axis Line. */
- if (is_pos) {
- float v_start[3];
- GPU_line_width(2.0f);
- immUniformColor4fv(is_pos_color ? color_current : color_current_fade);
- immBegin(GPU_PRIM_LINES, 2);
- if (axis_align == -1) {
- zero_v3(v_start);
- }
- else {
- /* When axis aligned we don't draw the front most axis
- * (allowing us to switch to the opposite side).
- * In this case don't draw lines over axis pointing away from us
- * because it obscures character and looks noisy.
- */
- mul_v3_v3fl(v_start, v_final, 0.3f);
- }
- immVertex3fv(pos_id, v_start);
- immVertex3fv(pos_id, v_final);
- immEnd();
- }
-
- /* Axis Ball. */
- {
- GPU_matrix_push();
- GPU_matrix_translate_3fv(v_final);
- GPU_matrix_scale_1f(is_pos ? AXIS_HANDLE_SIZE_FG : AXIS_HANDLE_SIZE_BG);
-
- GPUBatch *sphere = GPU_batch_preset_sphere(0);
- GPU_batch_program_set_builtin(sphere, GPU_SHADER_3D_UNIFORM_COLOR);
-
- /* Black outlines for negative axis balls, otherwise they can be hard to see since
- * they use a faded color which can be similar to the circle backdrop in tone. */
- if (is_active && !is_highlight && !is_pos && !select && !(axis_align == axis)) {
- static const float axis_black_faded[4] = {0, 0, 0, 0.2f};
- const float scale = 1.15f;
- GPU_matrix_scale_1f(scale);
- GPU_batch_uniform_4fv(sphere, "color", axis_black_faded);
- GPU_batch_draw(sphere);
- GPU_matrix_scale_1f(1.0 / scale);
- }
-
- GPU_batch_uniform_4fv(sphere, "color", is_pos_color ? color_current : color_current_fade);
- GPU_batch_draw(sphere);
- GPU_matrix_pop();
- }
-
- /* Axis XYZ Character. */
- if (show_axis_char && (select == false)) {
+ }
+ else {
+ copy_v4_fl(color_current_fade, 1.0f);
+ }
+
+ /* Axis Line. */
+ if (is_pos) {
+ float v_start[3];
+ GPU_line_width(2.0f);
+ immUniformColor4fv(is_pos_color ? color_current : color_current_fade);
+ immBegin(GPU_PRIM_LINES, 2);
+ if (axis_align == -1) {
+ zero_v3(v_start);
+ }
+ else {
+ /* When axis aligned we don't draw the front most axis
+ * (allowing us to switch to the opposite side).
+ * In this case don't draw lines over axis pointing away from us
+ * because it obscures character and looks noisy.
+ */
+ mul_v3_v3fl(v_start, v_final, 0.3f);
+ }
+ immVertex3fv(pos_id, v_start);
+ immVertex3fv(pos_id, v_final);
+ immEnd();
+ }
+
+ /* Axis Ball. */
+ {
+ GPU_matrix_push();
+ GPU_matrix_translate_3fv(v_final);
+ GPU_matrix_scale_1f(is_pos ? AXIS_HANDLE_SIZE_FG : AXIS_HANDLE_SIZE_BG);
+
+ GPUBatch *sphere = GPU_batch_preset_sphere(0);
+ GPU_batch_program_set_builtin(sphere, GPU_SHADER_3D_UNIFORM_COLOR);
+
+ /* Black outlines for negative axis balls, otherwise they can be hard to see since
+ * they use a faded color which can be similar to the circle backdrop in tone. */
+ if (is_active && !is_highlight && !is_pos && !select && !(axis_align == axis)) {
+ static const float axis_black_faded[4] = {0, 0, 0, 0.2f};
+ const float scale = 1.15f;
+ GPU_matrix_scale_1f(scale);
+ GPU_batch_uniform_4fv(sphere, "color", axis_black_faded);
+ GPU_batch_draw(sphere);
+ GPU_matrix_scale_1f(1.0 / scale);
+ }
+
+ GPU_batch_uniform_4fv(sphere, "color", is_pos_color ? color_current : color_current_fade);
+ GPU_batch_draw(sphere);
+ GPU_matrix_pop();
+ }
+
+ /* Axis XYZ Character. */
+ if (show_axis_char && (select == false)) {
#ifdef USE_AXIS_FONT
- immUnbindProgram();
+ immUnbindProgram();
- GPU_matrix_push();
- GPU_matrix_translate_3fv(v_final);
- GPU_matrix_mul(font.matrix);
+ GPU_matrix_push();
+ GPU_matrix_translate_3fv(v_final);
+ GPU_matrix_mul(font.matrix);
- const char axis_str[2] = {'X' + axis, 0};
- float offset[2] = {0};
- BLF_width_and_height(font.id, axis_str, 2, &offset[0], &offset[1]);
- BLF_position(font.id, roundf(offset[0] * -0.5f), roundf(offset[1] * -0.5f), 0);
- BLF_draw_ascii(font.id, axis_str, 2);
- GPU_blend(true); /* XXX, blf disables */
- GPU_matrix_pop();
+ const char axis_str[2] = {'X' + axis, 0};
+ float offset[2] = {0};
+ BLF_width_and_height(font.id, axis_str, 2, &offset[0], &offset[1]);
+ BLF_position(font.id, roundf(offset[0] * -0.5f), roundf(offset[1] * -0.5f), 0);
+ BLF_draw_ascii(font.id, axis_str, 2);
+ GPU_blend(true); /* XXX, blf disables */
+ GPU_matrix_pop();
- immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
#else
- GPU_line_width(1.0f);
- float m3[3][3];
- copy_m3_m4(m3, gz->matrix_offset);
- immUniformColor4fv(axis_black);
- draw_xyz_wire(pos_id, m3, v_final, 1.0, axis);
+ GPU_line_width(1.0f);
+ float m3[3][3];
+ copy_m3_m4(m3, gz->matrix_offset);
+ immUniformColor4fv(axis_black);
+ draw_xyz_wire(pos_id, m3, v_final, 1.0, axis);
#endif
- }
- }
- }
+ }
+ }
+ }
- GPU_matrix_pop();
- immUnbindProgram();
+ GPU_matrix_pop();
+ immUnbindProgram();
}
-static void axis3d_draw_intern(
- const bContext *C, wmGizmo *gz,
- const bool select, const bool highlight)
+static void axis3d_draw_intern(const bContext *C,
+ wmGizmo *gz,
+ const bool select,
+ const bool highlight)
{
- const float *color = highlight ? gz->color_hi : gz->color;
- float matrix_final[4][4];
- float matrix_unit[4][4];
-
- unit_m4(matrix_unit);
+ const float *color = highlight ? gz->color_hi : gz->color;
+ float matrix_final[4][4];
+ float matrix_unit[4][4];
- WM_gizmo_calc_matrix_final_params(
- gz,
- &((struct WM_GizmoMatrixParams) {
- .matrix_offset = matrix_unit,
- }), matrix_final);
+ unit_m4(matrix_unit);
- GPU_matrix_push();
- GPU_matrix_mul(matrix_final);
+ WM_gizmo_calc_matrix_final_params(gz,
+ &((struct WM_GizmoMatrixParams){
+ .matrix_offset = matrix_unit,
+ }),
+ matrix_final);
+ GPU_matrix_push();
+ GPU_matrix_mul(matrix_final);
- struct AxisDrawInfo draw_info;
+ struct AxisDrawInfo draw_info;
#ifdef USE_AXIS_FONT
- if (select == false) {
- copy_m4_m4(draw_info.matrix_final, matrix_final);
- }
+ if (select == false) {
+ copy_m4_m4(draw_info.matrix_final, matrix_final);
+ }
#endif
#ifdef USE_FADE_BACKGROUND
- if (select == false) {
- ED_view3d_background_color_get(CTX_data_scene(C), CTX_wm_view3d(C), draw_info.color_bg);
- }
+ if (select == false) {
+ ED_view3d_background_color_get(CTX_data_scene(C), CTX_wm_view3d(C), draw_info.color_bg);
+ }
#else
- UNUSED_VARS(C);
+ UNUSED_VARS(C);
#endif
- GPU_blend(true);
- axis_geom_draw(
- gz, color, select,
- &draw_info);
- GPU_blend(false);
- GPU_matrix_pop();
+ GPU_blend(true);
+ axis_geom_draw(gz, color, select, &draw_info);
+ GPU_blend(false);
+ GPU_matrix_pop();
}
static void gizmo_axis_draw(const bContext *C, wmGizmo *gz)
{
- const bool is_modal = gz->state & WM_GIZMO_STATE_MODAL;
- const bool is_highlight = (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0;
+ const bool is_modal = gz->state & WM_GIZMO_STATE_MODAL;
+ const bool is_highlight = (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0;
- (void)is_modal;
+ (void)is_modal;
- GPU_blend(true);
- axis3d_draw_intern(C, gz, false, is_highlight);
- GPU_blend(false);
+ GPU_blend(true);
+ axis3d_draw_intern(C, gz, false, is_highlight);
+ GPU_blend(false);
}
-static int gizmo_axis_test_select(
- bContext *UNUSED(C), wmGizmo *gz, const int mval[2])
+static int gizmo_axis_test_select(bContext *UNUSED(C), wmGizmo *gz, const int mval[2])
{
- float point_local[2] = {UNPACK2(mval)};
- sub_v2_v2(point_local, gz->matrix_basis[3]);
- mul_v2_fl(point_local, 1.0f / (gz->scale_basis * UI_DPI_FAC));
-
- const float len_sq = len_squared_v2(point_local);
- if (len_sq > 1.0) {
- return -1;
- }
-
- int part_best = -1;
- int part_index = 1;
- /* Use 'SQUARE(HANDLE_SIZE)' if we want to be able to _not_ focus on one of the axis. */
- float i_best_len_sq = FLT_MAX;
- for (int i = 0; i < 3; i++) {
- for (int is_pos = 0; is_pos < 2; is_pos++) {
- float co[2] = {
- gz->matrix_offset[i][0] * (is_pos ? 1 : -1),
- gz->matrix_offset[i][1] * (is_pos ? 1 : -1),
- };
-
- bool ok = true;
-
- /* Check if we're viewing on an axis,
- * there is no point to clicking on the current axis so show the reverse. */
- if (len_squared_v2(co) < 1e-6f && (gz->matrix_offset[i][2] > 0.0f) == is_pos) {
- ok = false;
- }
-
- if (ok) {
- const float len_axis_sq = len_squared_v2v2(co, point_local);
- if (len_axis_sq < i_best_len_sq) {
- part_best = part_index;
- i_best_len_sq = len_axis_sq;
- }
- }
- part_index += 1;
- }
- }
-
- if (part_best != -1) {
- return part_best;
- }
-
- /* The 'gz->scale_final' is already applied when projecting. */
- if (len_sq < 1.0f) {
- return 0;
- }
-
- return -1;
+ float point_local[2] = {UNPACK2(mval)};
+ sub_v2_v2(point_local, gz->matrix_basis[3]);
+ mul_v2_fl(point_local, 1.0f / (gz->scale_basis * UI_DPI_FAC));
+
+ const float len_sq = len_squared_v2(point_local);
+ if (len_sq > 1.0) {
+ return -1;
+ }
+
+ int part_best = -1;
+ int part_index = 1;
+ /* Use 'SQUARE(HANDLE_SIZE)' if we want to be able to _not_ focus on one of the axis. */
+ float i_best_len_sq = FLT_MAX;
+ for (int i = 0; i < 3; i++) {
+ for (int is_pos = 0; is_pos < 2; is_pos++) {
+ float co[2] = {
+ gz->matrix_offset[i][0] * (is_pos ? 1 : -1),
+ gz->matrix_offset[i][1] * (is_pos ? 1 : -1),
+ };
+
+ bool ok = true;
+
+ /* Check if we're viewing on an axis,
+ * there is no point to clicking on the current axis so show the reverse. */
+ if (len_squared_v2(co) < 1e-6f && (gz->matrix_offset[i][2] > 0.0f) == is_pos) {
+ ok = false;
+ }
+
+ if (ok) {
+ const float len_axis_sq = len_squared_v2v2(co, point_local);
+ if (len_axis_sq < i_best_len_sq) {
+ part_best = part_index;
+ i_best_len_sq = len_axis_sq;
+ }
+ }
+ part_index += 1;
+ }
+ }
+
+ if (part_best != -1) {
+ return part_best;
+ }
+
+ /* The 'gz->scale_final' is already applied when projecting. */
+ if (len_sq < 1.0f) {
+ return 0;
+ }
+
+ return -1;
}
static int gizmo_axis_cursor_get(wmGizmo *gz)
{
- if (gz->highlight_part > 0) {
- return CURSOR_EDIT;
- }
- return BC_NSEW_SCROLLCURSOR;
+ if (gz->highlight_part > 0) {
+ return CURSOR_EDIT;
+ }
+ return BC_NSEW_SCROLLCURSOR;
}
void VIEW3D_GT_navigate_rotate(wmGizmoType *gzt)
{
- /* identifiers */
- gzt->idname = "VIEW3D_GT_navigate_rotate";
+ /* identifiers */
+ gzt->idname = "VIEW3D_GT_navigate_rotate";
- /* api callbacks */
- gzt->draw = gizmo_axis_draw;
- gzt->test_select = gizmo_axis_test_select;
- gzt->cursor_get = gizmo_axis_cursor_get;
+ /* api callbacks */
+ gzt->draw = gizmo_axis_draw;
+ gzt->test_select = gizmo_axis_test_select;
+ gzt->cursor_get = gizmo_axis_cursor_get;
- gzt->struct_size = sizeof(wmGizmo);
+ gzt->struct_size = sizeof(wmGizmo);
}
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_preselect.c b/source/blender/editors/space_view3d/view3d_gizmo_preselect.c
index b71c03684d6..b9dc287b9cb 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_preselect.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_preselect.c
@@ -33,7 +33,7 @@
#include "WM_types.h"
#include "WM_toolsystem.h"
-#include "view3d_intern.h" /* own include */
+#include "view3d_intern.h" /* own include */
/* -------------------------------------------------------------------- */
/** \name Mesh Pre-Select Element Gizmo
@@ -41,32 +41,32 @@
* \{ */
struct GizmoGroupPreSelElem {
- wmGizmo *gizmo;
+ wmGizmo *gizmo;
};
static void WIDGETGROUP_mesh_preselect_elem_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
{
- const wmGizmoType *gzt_presel = WM_gizmotype_find("GIZMO_GT_mesh_preselect_elem_3d", true);
- struct GizmoGroupPreSelElem *ggd = MEM_callocN(sizeof(struct GizmoGroupPreSelElem), __func__);
- gzgroup->customdata = ggd;
+ const wmGizmoType *gzt_presel = WM_gizmotype_find("GIZMO_GT_mesh_preselect_elem_3d", true);
+ struct GizmoGroupPreSelElem *ggd = MEM_callocN(sizeof(struct GizmoGroupPreSelElem), __func__);
+ gzgroup->customdata = ggd;
- wmGizmo *gz = ggd->gizmo = WM_gizmo_new_ptr(gzt_presel, gzgroup, NULL);
- UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color);
- UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
+ wmGizmo *gz = ggd->gizmo = WM_gizmo_new_ptr(gzt_presel, gzgroup, NULL);
+ UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color);
+ UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
}
void VIEW3D_GGT_mesh_preselect_elem(wmGizmoGroupType *gzgt)
{
- gzgt->name = "Mesh Preselect Element";
- gzgt->idname = "VIEW3D_GGT_mesh_preselect_elem";
+ gzgt->name = "Mesh Preselect Element";
+ gzgt->idname = "VIEW3D_GGT_mesh_preselect_elem";
- gzgt->flag = WM_GIZMOGROUPTYPE_3D;
+ gzgt->flag = WM_GIZMOGROUPTYPE_3D;
- gzgt->gzmap_params.spaceid = SPACE_VIEW3D;
- gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;
+ gzgt->gzmap_params.spaceid = SPACE_VIEW3D;
+ gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;
- gzgt->poll = ED_gizmo_poll_or_unlink_delayed_from_tool;
- gzgt->setup = WIDGETGROUP_mesh_preselect_elem_setup;
+ gzgt->poll = ED_gizmo_poll_or_unlink_delayed_from_tool;
+ gzgt->setup = WIDGETGROUP_mesh_preselect_elem_setup;
}
/** \} */
@@ -77,32 +77,34 @@ void VIEW3D_GGT_mesh_preselect_elem(wmGizmoGroupType *gzgt)
* \{ */
struct GizmoGroupPreSelEdgeRing {
- wmGizmo *gizmo;
+ wmGizmo *gizmo;
};
-static void WIDGETGROUP_mesh_preselect_edgering_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
+static void WIDGETGROUP_mesh_preselect_edgering_setup(const bContext *UNUSED(C),
+ wmGizmoGroup *gzgroup)
{
- const wmGizmoType *gzt_presel = WM_gizmotype_find("GIZMO_GT_mesh_preselect_edgering_3d", true);
- struct GizmoGroupPreSelEdgeRing *ggd = MEM_callocN(sizeof(struct GizmoGroupPreSelEdgeRing), __func__);
- gzgroup->customdata = ggd;
-
- wmGizmo *gz = ggd->gizmo = WM_gizmo_new_ptr(gzt_presel, gzgroup, NULL);
- UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color);
- UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
+ const wmGizmoType *gzt_presel = WM_gizmotype_find("GIZMO_GT_mesh_preselect_edgering_3d", true);
+ struct GizmoGroupPreSelEdgeRing *ggd = MEM_callocN(sizeof(struct GizmoGroupPreSelEdgeRing),
+ __func__);
+ gzgroup->customdata = ggd;
+
+ wmGizmo *gz = ggd->gizmo = WM_gizmo_new_ptr(gzt_presel, gzgroup, NULL);
+ UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color);
+ UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
}
void VIEW3D_GGT_mesh_preselect_edgering(wmGizmoGroupType *gzgt)
{
- gzgt->name = "Mesh Preselect Edge Ring";
- gzgt->idname = "VIEW3D_GGT_mesh_preselect_edgering";
+ gzgt->name = "Mesh Preselect Edge Ring";
+ gzgt->idname = "VIEW3D_GGT_mesh_preselect_edgering";
- gzgt->flag = WM_GIZMOGROUPTYPE_3D;
+ gzgt->flag = WM_GIZMOGROUPTYPE_3D;
- gzgt->gzmap_params.spaceid = SPACE_VIEW3D;
- gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;
+ gzgt->gzmap_params.spaceid = SPACE_VIEW3D;
+ gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;
- gzgt->poll = ED_gizmo_poll_or_unlink_delayed_from_tool;
- gzgt->setup = WIDGETGROUP_mesh_preselect_edgering_setup;
+ gzgt->poll = ED_gizmo_poll_or_unlink_delayed_from_tool;
+ gzgt->setup = WIDGETGROUP_mesh_preselect_edgering_setup;
}
/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c b/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c
index 418a9e76678..6f35c0aa748 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c
@@ -55,196 +55,194 @@
*
* \{ */
-
typedef struct MeshElemGizmo3D {
- wmGizmo gizmo;
- Base **bases;
- uint bases_len;
- int base_index;
- int vert_index;
- int edge_index;
- int face_index;
- struct EditMesh_PreSelElem *psel;
+ wmGizmo gizmo;
+ Base **bases;
+ uint bases_len;
+ int base_index;
+ int vert_index;
+ int edge_index;
+ int face_index;
+ struct EditMesh_PreSelElem *psel;
} MeshElemGizmo3D;
static void gizmo_preselect_elem_draw(const bContext *UNUSED(C), wmGizmo *gz)
{
- MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz;
- if (gz_ele->base_index != -1) {
- Object *ob = gz_ele->bases[gz_ele->base_index]->object;
- EDBM_preselect_elem_draw(gz_ele->psel, ob->obmat);
- }
+ MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz;
+ if (gz_ele->base_index != -1) {
+ Object *ob = gz_ele->bases[gz_ele->base_index]->object;
+ EDBM_preselect_elem_draw(gz_ele->psel, ob->obmat);
+ }
}
-static int gizmo_preselect_elem_test_select(
- bContext *C, wmGizmo *gz, const int mval[2])
+static int gizmo_preselect_elem_test_select(bContext *C, wmGizmo *gz, const int mval[2])
{
- MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz;
- struct {
- Object *ob;
- BMElem *ele;
- float dist;
- int base_index;
- } best = {
- .dist = ED_view3d_select_dist_px(),
- };
-
- struct {
- int base_index;
- int vert_index;
- int edge_index;
- int face_index;
- } prev = {
- .base_index = gz_ele->base_index,
- .vert_index = gz_ele->vert_index,
- .edge_index = gz_ele->edge_index,
- .face_index = gz_ele->face_index,
- };
-
- {
- ViewLayer *view_layer = CTX_data_view_layer(C);
- View3D *v3d = CTX_wm_view3d(C);
- if (((gz_ele->bases)) == NULL ||
- (gz_ele->bases[0] != view_layer->basact))
- {
- MEM_SAFE_FREE(gz_ele->bases);
- gz_ele->bases = BKE_view_layer_array_from_bases_in_edit_mode(
- view_layer, v3d, &gz_ele->bases_len);
- }
- }
-
- ViewContext vc;
- em_setup_viewcontext(C, &vc);
- copy_v2_v2_int(vc.mval, mval);
-
- {
- /* TODO: support faces. */
- int base_index = -1;
- BMVert *eve_test;
- BMEdge *eed_test;
-
- if (EDBM_unified_findnearest_from_raycast(
- &vc, gz_ele->bases, gz_ele->bases_len,
- true, &base_index, &eve_test, &eed_test, NULL))
- {
- Base *base = gz_ele->bases[base_index];
- best.ob = base->object;
- if (eve_test) {
- best.ele = (BMElem *)eve_test;
- }
- else if (eed_test) {
- best.ele = (BMElem *)eed_test;
- }
- else {
- BLI_assert(0);
- }
- best.base_index = base_index;
- /* Check above should never fail, if it does it's an internal error. */
- BLI_assert(best.base_index != -1);
- }
- }
-
- BMesh *bm = NULL;
-
- gz_ele->base_index = -1;
- gz_ele->vert_index = -1;
- gz_ele->edge_index = -1;
- gz_ele->face_index = -1;
-
- if (best.ele) {
- gz_ele->base_index = best.base_index;
- bm = BKE_editmesh_from_object(gz_ele->bases[gz_ele->base_index]->object)->bm;
- BM_mesh_elem_index_ensure(bm, best.ele->head.htype);
-
- if (best.ele->head.htype == BM_VERT) {
- gz_ele->vert_index = BM_elem_index_get(best.ele);
- }
- else if (best.ele->head.htype == BM_EDGE) {
- gz_ele->edge_index = BM_elem_index_get(best.ele);
- }
- else if (best.ele->head.htype == BM_FACE) {
- gz_ele->face_index = BM_elem_index_get(best.ele);
- }
- }
-
- if ((prev.base_index == gz_ele->base_index) &&
- (prev.vert_index == gz_ele->vert_index) &&
- (prev.edge_index == gz_ele->edge_index) &&
- (prev.face_index == gz_ele->face_index))
- {
- /* pass (only recalculate on change) */
- }
- else {
- if (best.ele) {
- const float (*coords)[3] = NULL;
- {
- Object *ob = gz_ele->bases[gz_ele->base_index]->object;
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- Mesh *me_eval = (Mesh *)DEG_get_evaluated_id(depsgraph, ob->data);
- if (me_eval->runtime.edit_data) {
- coords = me_eval->runtime.edit_data->vertexCos;
- }
- }
- EDBM_preselect_elem_update_from_single(gz_ele->psel, bm, best.ele, coords);
- }
- else {
- EDBM_preselect_elem_clear(gz_ele->psel);
- }
-
- RNA_int_set(gz->ptr, "object_index", gz_ele->base_index);
- RNA_int_set(gz->ptr, "vert_index", gz_ele->vert_index);
- RNA_int_set(gz->ptr, "edge_index", gz_ele->edge_index);
- RNA_int_set(gz->ptr, "face_index", gz_ele->face_index);
-
- ARegion *ar = CTX_wm_region(C);
- ED_region_tag_redraw(ar);
- }
-
- // return best.eed ? 0 : -1;
- return -1;
+ MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz;
+ struct {
+ Object *ob;
+ BMElem *ele;
+ float dist;
+ int base_index;
+ } best = {
+ .dist = ED_view3d_select_dist_px(),
+ };
+
+ struct {
+ int base_index;
+ int vert_index;
+ int edge_index;
+ int face_index;
+ } prev = {
+ .base_index = gz_ele->base_index,
+ .vert_index = gz_ele->vert_index,
+ .edge_index = gz_ele->edge_index,
+ .face_index = gz_ele->face_index,
+ };
+
+ {
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ if (((gz_ele->bases)) == NULL || (gz_ele->bases[0] != view_layer->basact)) {
+ MEM_SAFE_FREE(gz_ele->bases);
+ gz_ele->bases = BKE_view_layer_array_from_bases_in_edit_mode(
+ view_layer, v3d, &gz_ele->bases_len);
+ }
+ }
+
+ ViewContext vc;
+ em_setup_viewcontext(C, &vc);
+ copy_v2_v2_int(vc.mval, mval);
+
+ {
+ /* TODO: support faces. */
+ int base_index = -1;
+ BMVert *eve_test;
+ BMEdge *eed_test;
+
+ if (EDBM_unified_findnearest_from_raycast(&vc,
+ gz_ele->bases,
+ gz_ele->bases_len,
+ true,
+ &base_index,
+ &eve_test,
+ &eed_test,
+ NULL)) {
+ Base *base = gz_ele->bases[base_index];
+ best.ob = base->object;
+ if (eve_test) {
+ best.ele = (BMElem *)eve_test;
+ }
+ else if (eed_test) {
+ best.ele = (BMElem *)eed_test;
+ }
+ else {
+ BLI_assert(0);
+ }
+ best.base_index = base_index;
+ /* Check above should never fail, if it does it's an internal error. */
+ BLI_assert(best.base_index != -1);
+ }
+ }
+
+ BMesh *bm = NULL;
+
+ gz_ele->base_index = -1;
+ gz_ele->vert_index = -1;
+ gz_ele->edge_index = -1;
+ gz_ele->face_index = -1;
+
+ if (best.ele) {
+ gz_ele->base_index = best.base_index;
+ bm = BKE_editmesh_from_object(gz_ele->bases[gz_ele->base_index]->object)->bm;
+ BM_mesh_elem_index_ensure(bm, best.ele->head.htype);
+
+ if (best.ele->head.htype == BM_VERT) {
+ gz_ele->vert_index = BM_elem_index_get(best.ele);
+ }
+ else if (best.ele->head.htype == BM_EDGE) {
+ gz_ele->edge_index = BM_elem_index_get(best.ele);
+ }
+ else if (best.ele->head.htype == BM_FACE) {
+ gz_ele->face_index = BM_elem_index_get(best.ele);
+ }
+ }
+
+ if ((prev.base_index == gz_ele->base_index) && (prev.vert_index == gz_ele->vert_index) &&
+ (prev.edge_index == gz_ele->edge_index) && (prev.face_index == gz_ele->face_index)) {
+ /* pass (only recalculate on change) */
+ }
+ else {
+ if (best.ele) {
+ const float(*coords)[3] = NULL;
+ {
+ Object *ob = gz_ele->bases[gz_ele->base_index]->object;
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ Mesh *me_eval = (Mesh *)DEG_get_evaluated_id(depsgraph, ob->data);
+ if (me_eval->runtime.edit_data) {
+ coords = me_eval->runtime.edit_data->vertexCos;
+ }
+ }
+ EDBM_preselect_elem_update_from_single(gz_ele->psel, bm, best.ele, coords);
+ }
+ else {
+ EDBM_preselect_elem_clear(gz_ele->psel);
+ }
+
+ RNA_int_set(gz->ptr, "object_index", gz_ele->base_index);
+ RNA_int_set(gz->ptr, "vert_index", gz_ele->vert_index);
+ RNA_int_set(gz->ptr, "edge_index", gz_ele->edge_index);
+ RNA_int_set(gz->ptr, "face_index", gz_ele->face_index);
+
+ ARegion *ar = CTX_wm_region(C);
+ ED_region_tag_redraw(ar);
+ }
+
+ // return best.eed ? 0 : -1;
+ return -1;
}
static void gizmo_preselect_elem_setup(wmGizmo *gz)
{
- MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz;
- if (gz_ele->psel == NULL) {
- gz_ele->psel = EDBM_preselect_elem_create();
- }
- gz_ele->base_index = -1;
+ MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz;
+ if (gz_ele->psel == NULL) {
+ gz_ele->psel = EDBM_preselect_elem_create();
+ }
+ gz_ele->base_index = -1;
}
static void gizmo_preselect_elem_free(wmGizmo *gz)
{
- MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz;
- EDBM_preselect_elem_destroy(gz_ele->psel);
- gz_ele->psel = NULL;
- MEM_SAFE_FREE(gz_ele->bases);
+ MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz;
+ EDBM_preselect_elem_destroy(gz_ele->psel);
+ gz_ele->psel = NULL;
+ MEM_SAFE_FREE(gz_ele->bases);
}
-static int gizmo_preselect_elem_invoke(
- bContext *UNUSED(C), wmGizmo *UNUSED(gz), const wmEvent *UNUSED(event))
+static int gizmo_preselect_elem_invoke(bContext *UNUSED(C),
+ wmGizmo *UNUSED(gz),
+ const wmEvent *UNUSED(event))
{
- return OPERATOR_PASS_THROUGH;
+ return OPERATOR_PASS_THROUGH;
}
static void GIZMO_GT_mesh_preselect_elem_3d(wmGizmoType *gzt)
{
- /* identifiers */
- gzt->idname = "GIZMO_GT_mesh_preselect_elem_3d";
-
- /* api callbacks */
- gzt->invoke = gizmo_preselect_elem_invoke;
- gzt->draw = gizmo_preselect_elem_draw;
- gzt->test_select = gizmo_preselect_elem_test_select;
- gzt->setup = gizmo_preselect_elem_setup;
- gzt->free = gizmo_preselect_elem_free;
-
- gzt->struct_size = sizeof(MeshElemGizmo3D);
-
- RNA_def_int(gzt->srna, "object_index", -1, -1, INT_MAX, "Object Index", "", -1, INT_MAX);
- RNA_def_int(gzt->srna, "vert_index", -1, -1, INT_MAX, "Vert Index", "", -1, INT_MAX);
- RNA_def_int(gzt->srna, "edge_index", -1, -1, INT_MAX, "Edge Index", "", -1, INT_MAX);
- RNA_def_int(gzt->srna, "face_index", -1, -1, INT_MAX, "Face Index", "", -1, INT_MAX);
+ /* identifiers */
+ gzt->idname = "GIZMO_GT_mesh_preselect_elem_3d";
+
+ /* api callbacks */
+ gzt->invoke = gizmo_preselect_elem_invoke;
+ gzt->draw = gizmo_preselect_elem_draw;
+ gzt->test_select = gizmo_preselect_elem_test_select;
+ gzt->setup = gizmo_preselect_elem_setup;
+ gzt->free = gizmo_preselect_elem_free;
+
+ gzt->struct_size = sizeof(MeshElemGizmo3D);
+
+ RNA_def_int(gzt->srna, "object_index", -1, -1, INT_MAX, "Object Index", "", -1, INT_MAX);
+ RNA_def_int(gzt->srna, "vert_index", -1, -1, INT_MAX, "Vert Index", "", -1, INT_MAX);
+ RNA_def_int(gzt->srna, "edge_index", -1, -1, INT_MAX, "Edge Index", "", -1, INT_MAX);
+ RNA_def_int(gzt->srna, "face_index", -1, -1, INT_MAX, "Face Index", "", -1, INT_MAX);
}
/** \} */
@@ -255,162 +253,155 @@ static void GIZMO_GT_mesh_preselect_elem_3d(wmGizmoType *gzt)
* \{ */
typedef struct MeshEdgeRingGizmo3D {
- wmGizmo gizmo;
- Base **bases;
- uint bases_len;
- int base_index;
- int edge_index;
- struct EditMesh_PreSelEdgeRing *psel;
+ wmGizmo gizmo;
+ Base **bases;
+ uint bases_len;
+ int base_index;
+ int edge_index;
+ struct EditMesh_PreSelEdgeRing *psel;
} MeshEdgeRingGizmo3D;
static void gizmo_preselect_edgering_draw(const bContext *UNUSED(C), wmGizmo *gz)
{
- MeshEdgeRingGizmo3D *gz_ring = (MeshEdgeRingGizmo3D *)gz;
- if (gz_ring->base_index != -1) {
- Object *ob = gz_ring->bases[gz_ring->base_index]->object;
- EDBM_preselect_edgering_draw(gz_ring->psel, ob->obmat);
- }
+ MeshEdgeRingGizmo3D *gz_ring = (MeshEdgeRingGizmo3D *)gz;
+ if (gz_ring->base_index != -1) {
+ Object *ob = gz_ring->bases[gz_ring->base_index]->object;
+ EDBM_preselect_edgering_draw(gz_ring->psel, ob->obmat);
+ }
}
-static int gizmo_preselect_edgering_test_select(
- bContext *C, wmGizmo *gz, const int mval[2])
+static int gizmo_preselect_edgering_test_select(bContext *C, wmGizmo *gz, const int mval[2])
{
- MeshEdgeRingGizmo3D *gz_ring = (MeshEdgeRingGizmo3D *)gz;
- struct {
- Object *ob;
- BMEdge *eed;
- float dist;
- int base_index;
- } best = {
- .dist = ED_view3d_select_dist_px(),
- };
-
- struct {
- int base_index;
- int edge_index;
- } prev = {
- .base_index = gz_ring->base_index,
- .edge_index = gz_ring->edge_index,
- };
-
- {
- ViewLayer *view_layer = CTX_data_view_layer(C);
- View3D *v3d = CTX_wm_view3d(C);
- if (((gz_ring->bases)) == NULL ||
- (gz_ring->bases[0] != view_layer->basact))
- {
- MEM_SAFE_FREE(gz_ring->bases);
- gz_ring->bases = BKE_view_layer_array_from_bases_in_edit_mode(
- view_layer, v3d, &gz_ring->bases_len);
- }
- }
-
- ViewContext vc;
- em_setup_viewcontext(C, &vc);
- copy_v2_v2_int(vc.mval, mval);
-
- for (uint base_index = 0; base_index < gz_ring->bases_len; base_index++) {
- Object *ob_iter = gz_ring->bases[base_index]->object;
- ED_view3d_viewcontext_init_object(&vc, ob_iter);
- BMEdge *eed_test = EDBM_edge_find_nearest_ex(&vc, &best.dist, NULL, false, false, NULL);
- if (eed_test) {
- best.ob = ob_iter;
- best.eed = eed_test;
- best.base_index = base_index;
- }
- }
-
- BMesh *bm = NULL;
- if (best.eed) {
- gz_ring->base_index = best.base_index;
- bm = BKE_editmesh_from_object(gz_ring->bases[gz_ring->base_index]->object)->bm;
- BM_mesh_elem_index_ensure(bm, BM_EDGE);
- gz_ring->edge_index = BM_elem_index_get(best.eed);
- }
- else {
- gz_ring->base_index = -1;
- gz_ring->edge_index = -1;
- }
-
-
- if ((prev.base_index == gz_ring->base_index) &&
- (prev.edge_index == gz_ring->edge_index))
- {
- /* pass (only recalculate on change) */
- }
- else {
- if (best.eed) {
- const float (*coords)[3] = NULL;
- {
- Object *ob = gz_ring->bases[gz_ring->base_index]->object;
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- Mesh *me_eval = (Mesh *)DEG_get_evaluated_id(depsgraph, ob->data);
- if (me_eval->runtime.edit_data) {
- coords = me_eval->runtime.edit_data->vertexCos;
- }
- }
- EDBM_preselect_edgering_update_from_edge(gz_ring->psel, bm, best.eed, 1, coords);
- }
- else {
- EDBM_preselect_edgering_clear(gz_ring->psel);
- }
-
- RNA_int_set(gz->ptr, "object_index", gz_ring->base_index);
- RNA_int_set(gz->ptr, "edge_index", gz_ring->edge_index);
-
- ARegion *ar = CTX_wm_region(C);
- ED_region_tag_redraw(ar);
- }
-
- // return best.eed ? 0 : -1;
- return -1;
+ MeshEdgeRingGizmo3D *gz_ring = (MeshEdgeRingGizmo3D *)gz;
+ struct {
+ Object *ob;
+ BMEdge *eed;
+ float dist;
+ int base_index;
+ } best = {
+ .dist = ED_view3d_select_dist_px(),
+ };
+
+ struct {
+ int base_index;
+ int edge_index;
+ } prev = {
+ .base_index = gz_ring->base_index,
+ .edge_index = gz_ring->edge_index,
+ };
+
+ {
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ if (((gz_ring->bases)) == NULL || (gz_ring->bases[0] != view_layer->basact)) {
+ MEM_SAFE_FREE(gz_ring->bases);
+ gz_ring->bases = BKE_view_layer_array_from_bases_in_edit_mode(
+ view_layer, v3d, &gz_ring->bases_len);
+ }
+ }
+
+ ViewContext vc;
+ em_setup_viewcontext(C, &vc);
+ copy_v2_v2_int(vc.mval, mval);
+
+ for (uint base_index = 0; base_index < gz_ring->bases_len; base_index++) {
+ Object *ob_iter = gz_ring->bases[base_index]->object;
+ ED_view3d_viewcontext_init_object(&vc, ob_iter);
+ BMEdge *eed_test = EDBM_edge_find_nearest_ex(&vc, &best.dist, NULL, false, false, NULL);
+ if (eed_test) {
+ best.ob = ob_iter;
+ best.eed = eed_test;
+ best.base_index = base_index;
+ }
+ }
+
+ BMesh *bm = NULL;
+ if (best.eed) {
+ gz_ring->base_index = best.base_index;
+ bm = BKE_editmesh_from_object(gz_ring->bases[gz_ring->base_index]->object)->bm;
+ BM_mesh_elem_index_ensure(bm, BM_EDGE);
+ gz_ring->edge_index = BM_elem_index_get(best.eed);
+ }
+ else {
+ gz_ring->base_index = -1;
+ gz_ring->edge_index = -1;
+ }
+
+ if ((prev.base_index == gz_ring->base_index) && (prev.edge_index == gz_ring->edge_index)) {
+ /* pass (only recalculate on change) */
+ }
+ else {
+ if (best.eed) {
+ const float(*coords)[3] = NULL;
+ {
+ Object *ob = gz_ring->bases[gz_ring->base_index]->object;
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ Mesh *me_eval = (Mesh *)DEG_get_evaluated_id(depsgraph, ob->data);
+ if (me_eval->runtime.edit_data) {
+ coords = me_eval->runtime.edit_data->vertexCos;
+ }
+ }
+ EDBM_preselect_edgering_update_from_edge(gz_ring->psel, bm, best.eed, 1, coords);
+ }
+ else {
+ EDBM_preselect_edgering_clear(gz_ring->psel);
+ }
+
+ RNA_int_set(gz->ptr, "object_index", gz_ring->base_index);
+ RNA_int_set(gz->ptr, "edge_index", gz_ring->edge_index);
+
+ ARegion *ar = CTX_wm_region(C);
+ ED_region_tag_redraw(ar);
+ }
+
+ // return best.eed ? 0 : -1;
+ return -1;
}
static void gizmo_preselect_edgering_setup(wmGizmo *gz)
{
- MeshEdgeRingGizmo3D *gz_ring = (MeshEdgeRingGizmo3D *)gz;
- if (gz_ring->psel == NULL) {
- gz_ring->psel = EDBM_preselect_edgering_create();
- }
- gz_ring->base_index = -1;
+ MeshEdgeRingGizmo3D *gz_ring = (MeshEdgeRingGizmo3D *)gz;
+ if (gz_ring->psel == NULL) {
+ gz_ring->psel = EDBM_preselect_edgering_create();
+ }
+ gz_ring->base_index = -1;
}
static void gizmo_preselect_edgering_free(wmGizmo *gz)
{
- MeshEdgeRingGizmo3D *gz_ring = (MeshEdgeRingGizmo3D *)gz;
- EDBM_preselect_edgering_destroy(gz_ring->psel);
- gz_ring->psel = NULL;
- MEM_SAFE_FREE(gz_ring->bases);
+ MeshEdgeRingGizmo3D *gz_ring = (MeshEdgeRingGizmo3D *)gz;
+ EDBM_preselect_edgering_destroy(gz_ring->psel);
+ gz_ring->psel = NULL;
+ MEM_SAFE_FREE(gz_ring->bases);
}
-static int gizmo_preselect_edgering_invoke(
- bContext *UNUSED(C), wmGizmo *UNUSED(gz), const wmEvent *UNUSED(event))
+static int gizmo_preselect_edgering_invoke(bContext *UNUSED(C),
+ wmGizmo *UNUSED(gz),
+ const wmEvent *UNUSED(event))
{
- return OPERATOR_PASS_THROUGH;
+ return OPERATOR_PASS_THROUGH;
}
-
static void GIZMO_GT_mesh_preselect_edgering_3d(wmGizmoType *gzt)
{
- /* identifiers */
- gzt->idname = "GIZMO_GT_mesh_preselect_edgering_3d";
+ /* identifiers */
+ gzt->idname = "GIZMO_GT_mesh_preselect_edgering_3d";
- /* api callbacks */
- gzt->invoke = gizmo_preselect_edgering_invoke;
- gzt->draw = gizmo_preselect_edgering_draw;
- gzt->test_select = gizmo_preselect_edgering_test_select;
- gzt->setup = gizmo_preselect_edgering_setup;
- gzt->free = gizmo_preselect_edgering_free;
+ /* api callbacks */
+ gzt->invoke = gizmo_preselect_edgering_invoke;
+ gzt->draw = gizmo_preselect_edgering_draw;
+ gzt->test_select = gizmo_preselect_edgering_test_select;
+ gzt->setup = gizmo_preselect_edgering_setup;
+ gzt->free = gizmo_preselect_edgering_free;
- gzt->struct_size = sizeof(MeshEdgeRingGizmo3D);
+ gzt->struct_size = sizeof(MeshEdgeRingGizmo3D);
- RNA_def_int(gzt->srna, "object_index", -1, -1, INT_MAX, "Object Index", "", -1, INT_MAX);
- RNA_def_int(gzt->srna, "edge_index", -1, -1, INT_MAX, "Edge Index", "", -1, INT_MAX);
+ RNA_def_int(gzt->srna, "object_index", -1, -1, INT_MAX, "Object Index", "", -1, INT_MAX);
+ RNA_def_int(gzt->srna, "edge_index", -1, -1, INT_MAX, "Edge Index", "", -1, INT_MAX);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/** \name Gizmo API
*
@@ -418,13 +409,12 @@ static void GIZMO_GT_mesh_preselect_edgering_3d(wmGizmoType *gzt)
void ED_gizmotypes_preselect_3d(void)
{
- WM_gizmotype_append(GIZMO_GT_mesh_preselect_elem_3d);
- WM_gizmotype_append(GIZMO_GT_mesh_preselect_edgering_3d);
+ WM_gizmotype_append(GIZMO_GT_mesh_preselect_elem_3d);
+ WM_gizmotype_append(GIZMO_GT_mesh_preselect_edgering_3d);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/** \name Gizmo Accessors
*
@@ -432,53 +422,55 @@ void ED_gizmotypes_preselect_3d(void)
* the information from this gizmo.
* \{ */
-void ED_view3d_gizmo_mesh_preselect_get_active(
- bContext *C, wmGizmo *gz,
- Base **r_base, BMElem **r_ele)
+void ED_view3d_gizmo_mesh_preselect_get_active(bContext *C,
+ wmGizmo *gz,
+ Base **r_base,
+ BMElem **r_ele)
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
-
- const int object_index = RNA_int_get(gz->ptr, "object_index");
-
- /* weak, allocate an array just to access the index. */
- Base *base = NULL;
- Object *obedit = NULL;
- {
- uint bases_len;
- Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(view_layer, CTX_wm_view3d(C), &bases_len);
- if (object_index < bases_len) {
- base = bases[object_index];
- obedit = base->object;
- }
- MEM_freeN(bases);
- }
-
- *r_base = base;
- *r_ele = NULL;
-
- if (obedit) {
- BMEditMesh *em = BKE_editmesh_from_object(obedit);
- BMesh *bm = em->bm;
- PropertyRNA *prop;
-
- /* Ring select only defines edge, check properties exist first. */
- prop = RNA_struct_find_property(gz->ptr, "vert_index");
- const int vert_index = prop ? RNA_property_int_get(gz->ptr, prop) : -1;
- prop = RNA_struct_find_property(gz->ptr, "edge_index");
- const int edge_index = prop ? RNA_property_int_get(gz->ptr, prop) : -1;
- prop = RNA_struct_find_property(gz->ptr, "face_index");
- const int face_index = prop ? RNA_property_int_get(gz->ptr, prop) : -1;
-
- if (vert_index != -1) {
- *r_ele = (BMElem *)BM_vert_at_index_find(bm, vert_index);
- }
- else if (edge_index != -1) {
- *r_ele = (BMElem *)BM_edge_at_index_find(bm, edge_index);
- }
- else if (face_index != -1) {
- *r_ele = (BMElem *)BM_face_at_index_find(bm, face_index);
- }
- }
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+
+ const int object_index = RNA_int_get(gz->ptr, "object_index");
+
+ /* weak, allocate an array just to access the index. */
+ Base *base = NULL;
+ Object *obedit = NULL;
+ {
+ uint bases_len;
+ Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(
+ view_layer, CTX_wm_view3d(C), &bases_len);
+ if (object_index < bases_len) {
+ base = bases[object_index];
+ obedit = base->object;
+ }
+ MEM_freeN(bases);
+ }
+
+ *r_base = base;
+ *r_ele = NULL;
+
+ if (obedit) {
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMesh *bm = em->bm;
+ PropertyRNA *prop;
+
+ /* Ring select only defines edge, check properties exist first. */
+ prop = RNA_struct_find_property(gz->ptr, "vert_index");
+ const int vert_index = prop ? RNA_property_int_get(gz->ptr, prop) : -1;
+ prop = RNA_struct_find_property(gz->ptr, "edge_index");
+ const int edge_index = prop ? RNA_property_int_get(gz->ptr, prop) : -1;
+ prop = RNA_struct_find_property(gz->ptr, "face_index");
+ const int face_index = prop ? RNA_property_int_get(gz->ptr, prop) : -1;
+
+ if (vert_index != -1) {
+ *r_ele = (BMElem *)BM_vert_at_index_find(bm, vert_index);
+ }
+ else if (edge_index != -1) {
+ *r_ele = (BMElem *)BM_edge_at_index_find(bm, edge_index);
+ }
+ else if (face_index != -1) {
+ *r_ele = (BMElem *)BM_face_at_index_find(bm, face_index);
+ }
+ }
}
/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c
index 253e02ca639..566a15cc7b7 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c
@@ -57,7 +57,7 @@
#include "WM_types.h"
#include "WM_toolsystem.h"
-#include "view3d_intern.h" /* own include */
+#include "view3d_intern.h" /* own include */
#include "GPU_immediate.h"
#include "GPU_immediate_util.h"
@@ -68,20 +68,18 @@
static const char *view3d_gzgt_ruler_id = "VIEW3D_GGT_ruler";
-
#define MVAL_MAX_PX_DIST 12.0f
/* -------------------------------------------------------------------- */
/* Ruler Item (we can have many) */
enum {
- /** Use protractor. */
- RULERITEM_USE_ANGLE = (1 << 0),
- /** Protractor vertex is selected (deleting removes it). */
- RULERITEM_USE_ANGLE_ACTIVE = (1 << 1),
+ /** Use protractor. */
+ RULERITEM_USE_ANGLE = (1 << 0),
+ /** Protractor vertex is selected (deleting removes it). */
+ RULERITEM_USE_ANGLE_ACTIVE = (1 << 1),
};
-
/* keep smaller then selection, since we may want click elsewhere without selecting a ruler */
#define RULER_PICK_DIST 12.0f
#define RULER_PICK_DIST_SQ (RULER_PICK_DIST * RULER_PICK_DIST)
@@ -93,47 +91,47 @@ enum {
/* Ruler Info (wmGizmoGroup customdata) */
enum {
- RULER_STATE_NORMAL = 0,
- RULER_STATE_DRAG,
+ RULER_STATE_NORMAL = 0,
+ RULER_STATE_DRAG,
};
enum {
- RULER_SNAP_OK = (1 << 0),
+ RULER_SNAP_OK = (1 << 0),
};
struct RulerItem;
typedef struct RulerInfo {
- struct RulerItem *item_active;
- int flag;
- int snap_flag;
- int state;
+ struct RulerItem *item_active;
+ int flag;
+ int snap_flag;
+ int state;
- struct SnapObjectContext *snap_context;
+ struct SnapObjectContext *snap_context;
- /* wm state */
- wmWindow *win;
- ScrArea *sa;
- ARegion *ar; /* re-assigned every modal update */
+ /* wm state */
+ wmWindow *win;
+ ScrArea *sa;
+ ARegion *ar; /* re-assigned every modal update */
} RulerInfo;
/* -------------------------------------------------------------------- */
/* Ruler Item (two or three points) */
typedef struct RulerItem {
- wmGizmo gz;
+ wmGizmo gz;
- /* worldspace coords, middle being optional */
- float co[3][3];
+ /* worldspace coords, middle being optional */
+ float co[3][3];
- int flag;
- int raycast_dir; /* RULER_DIRECTION_* */
+ int flag;
+ int raycast_dir; /* RULER_DIRECTION_* */
} RulerItem;
typedef struct RulerInteraction {
- /* selected coord */
- char co_index; /* 0 -> 2 */
- float drag_start_co[3];
+ /* selected coord */
+ char co_index; /* 0 -> 2 */
+ float drag_start_co[3];
} RulerInteraction;
/* -------------------------------------------------------------------- */
@@ -142,121 +140,123 @@ typedef struct RulerInteraction {
static RulerItem *ruler_item_add(wmGizmoGroup *gzgroup)
{
- /* could pass this as an arg */
- const wmGizmoType *gzt_ruler = WM_gizmotype_find("VIEW3D_GT_ruler_item", true);
- RulerItem *ruler_item = (RulerItem *)WM_gizmo_new_ptr(gzt_ruler, gzgroup, NULL);
- WM_gizmo_set_flag(&ruler_item->gz, WM_GIZMO_DRAW_MODAL, true);
- return ruler_item;
+ /* could pass this as an arg */
+ const wmGizmoType *gzt_ruler = WM_gizmotype_find("VIEW3D_GT_ruler_item", true);
+ RulerItem *ruler_item = (RulerItem *)WM_gizmo_new_ptr(gzt_ruler, gzgroup, NULL);
+ WM_gizmo_set_flag(&ruler_item->gz, WM_GIZMO_DRAW_MODAL, true);
+ return ruler_item;
}
static void ruler_item_remove(bContext *C, wmGizmoGroup *gzgroup, RulerItem *ruler_item)
{
- RulerInfo *ruler_info = gzgroup->customdata;
- if (ruler_info->item_active == ruler_item) {
- ruler_info->item_active = NULL;
- }
- WM_gizmo_unlink(&gzgroup->gizmos, gzgroup->parent_gzmap, &ruler_item->gz, C);
+ RulerInfo *ruler_info = gzgroup->customdata;
+ if (ruler_info->item_active == ruler_item) {
+ ruler_info->item_active = NULL;
+ }
+ WM_gizmo_unlink(&gzgroup->gizmos, gzgroup->parent_gzmap, &ruler_item->gz, C);
}
-static void ruler_item_as_string(RulerItem *ruler_item, UnitSettings *unit,
- char *numstr, size_t numstr_size, int prec)
+static void ruler_item_as_string(
+ RulerItem *ruler_item, UnitSettings *unit, char *numstr, size_t numstr_size, int prec)
{
- 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_AsString2(
- numstr, numstr_size, (double)ruler_angle,
- prec, B_UNIT_ROTATION, unit, 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_AsString2(
- numstr, numstr_size, (double)(ruler_len * unit->scale_length),
- prec, B_UNIT_LENGTH, unit, false);
- }
- }
+ 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_AsString2(
+ numstr, numstr_size, (double)ruler_angle, prec, B_UNIT_ROTATION, unit, 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_AsString2(numstr,
+ numstr_size,
+ (double)(ruler_len * unit->scale_length),
+ prec,
+ B_UNIT_LENGTH,
+ unit,
+ false);
+ }
+ }
}
-static bool view3d_ruler_pick(
- wmGizmoGroup *gzgroup, RulerItem *ruler_item, const float mval[2],
- int *r_co_index)
+static bool view3d_ruler_pick(wmGizmoGroup *gzgroup,
+ RulerItem *ruler_item,
+ const float mval[2],
+ int *r_co_index)
{
- RulerInfo *ruler_info = gzgroup->customdata;
- ARegion *ar = ruler_info->ar;
- bool found = false;
-
- float dist_best = RULER_PICK_DIST_SQ;
- int co_index_best = -1;
-
- {
- 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;
- found = true;
-
- {
- const 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;
- found = true;
-
- {
- const 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;
- }
- }
- }
- }
- }
-
- *r_co_index = co_index_best;
- return found;
+ RulerInfo *ruler_info = gzgroup->customdata;
+ ARegion *ar = ruler_info->ar;
+ bool found = false;
+
+ float dist_best = RULER_PICK_DIST_SQ;
+ int co_index_best = -1;
+
+ {
+ 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;
+ found = true;
+
+ {
+ const 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;
+ found = true;
+
+ {
+ const 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;
+ }
+ }
+ }
+ }
+ }
+
+ *r_co_index = co_index_best;
+ return found;
}
/**
@@ -265,113 +265,114 @@ static bool view3d_ruler_pick(
*/
static void ruler_state_set(bContext *C, RulerInfo *ruler_info, int state)
{
- Main *bmain = CTX_data_main(C);
- if (state == ruler_info->state) {
- return;
- }
-
- /* always remove */
- if (ruler_info->snap_context) {
- ED_transform_snap_object_context_destroy(ruler_info->snap_context);
- ruler_info->snap_context = NULL;
- }
-
- if (state == RULER_STATE_NORMAL) {
- /* pass */
- }
- else if (state == RULER_STATE_DRAG) {
- ruler_info->snap_context = ED_transform_snap_object_context_create_view3d(
- bmain, CTX_data_scene(C), CTX_data_depsgraph(C), 0,
- ruler_info->ar, CTX_wm_view3d(C));
- }
- else {
- BLI_assert(0);
- }
-
- ruler_info->state = state;
+ Main *bmain = CTX_data_main(C);
+ if (state == ruler_info->state) {
+ return;
+ }
+
+ /* always remove */
+ if (ruler_info->snap_context) {
+ ED_transform_snap_object_context_destroy(ruler_info->snap_context);
+ ruler_info->snap_context = NULL;
+ }
+
+ if (state == RULER_STATE_NORMAL) {
+ /* pass */
+ }
+ else if (state == RULER_STATE_DRAG) {
+ ruler_info->snap_context = ED_transform_snap_object_context_create_view3d(
+ bmain, CTX_data_scene(C), CTX_data_depsgraph(C), 0, ruler_info->ar, CTX_wm_view3d(C));
+ }
+ else {
+ BLI_assert(0);
+ }
+
+ ruler_info->state = state;
}
-static void view3d_ruler_item_project(
- RulerInfo *ruler_info, float r_co[3],
- const int xy[2])
+static void view3d_ruler_item_project(RulerInfo *ruler_info, float r_co[3], const int xy[2])
{
- ED_view3d_win_to_3d_int(ruler_info->sa->spacedata.first, ruler_info->ar, r_co, xy, r_co);
+ ED_view3d_win_to_3d_int(ruler_info->sa->spacedata.first, ruler_info->ar, r_co, xy, r_co);
}
/* use for mousemove events */
-static bool view3d_ruler_item_mousemove(
- RulerInfo *ruler_info, RulerItem *ruler_item, const int mval[2],
- const bool do_thickness, const bool do_snap)
+static bool view3d_ruler_item_mousemove(RulerInfo *ruler_info,
+ RulerItem *ruler_item,
+ const int mval[2],
+ const bool do_thickness,
+ const bool do_snap)
{
- const float eps_bias = 0.0002f;
- float dist_px = MVAL_MAX_PX_DIST * U.pixelsize; /* snap dist */
-
- ruler_info->snap_flag &= ~RULER_SNAP_OK;
-
- if (ruler_item) {
- RulerInteraction *inter = ruler_item->gz.interaction_data;
- float *co = ruler_item->co[inter->co_index];
- /* restore the initial depth */
- copy_v3_v3(co, inter->drag_start_co);
- view3d_ruler_item_project(ruler_info, co, mval);
- if (do_thickness && inter->co_index != 1) {
- // Scene *scene = CTX_data_scene(C);
- // View3D *v3d = ruler_info->sa->spacedata.first;
- const float mval_fl[2] = {UNPACK2(mval)};
- float ray_normal[3];
- float ray_start[3];
- float *co_other;
-
- co_other = ruler_item->co[inter->co_index == 0 ? 2 : 0];
-
- if (ED_transform_snap_object_project_view3d(
- ruler_info->snap_context,
- SCE_SNAP_MODE_FACE,
- &(const struct SnapObjectParams){
- .snap_select = SNAP_ALL,
- .use_object_edit_cage = true,
- },
- mval_fl, &dist_px,
- co, ray_normal))
- {
- negate_v3(ray_normal);
- /* add some bias */
- madd_v3_v3v3fl(ray_start, co, ray_normal, eps_bias);
- ED_transform_snap_object_project_ray(
- ruler_info->snap_context,
- &(const struct SnapObjectParams){
- .snap_select = SNAP_ALL,
- .use_object_edit_cage = true,
- },
- ray_start, ray_normal, NULL,
- co_other, NULL);
- }
- }
- else if (do_snap) {
- const float mval_fl[2] = {UNPACK2(mval)};
-
- if (ED_transform_snap_object_project_view3d(
- ruler_info->snap_context,
- (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE),
- &(const struct SnapObjectParams){
- .snap_select = SNAP_ALL,
- .use_object_edit_cage = true,
- .use_occlusion_test = true,
- },
- mval_fl, &dist_px,
- co, NULL))
- {
- ruler_info->snap_flag |= RULER_SNAP_OK;
- }
- }
- return true;
- }
- else {
- return false;
- }
+ const float eps_bias = 0.0002f;
+ float dist_px = MVAL_MAX_PX_DIST * U.pixelsize; /* snap dist */
+
+ ruler_info->snap_flag &= ~RULER_SNAP_OK;
+
+ if (ruler_item) {
+ RulerInteraction *inter = ruler_item->gz.interaction_data;
+ float *co = ruler_item->co[inter->co_index];
+ /* restore the initial depth */
+ copy_v3_v3(co, inter->drag_start_co);
+ view3d_ruler_item_project(ruler_info, co, mval);
+ if (do_thickness && inter->co_index != 1) {
+ // Scene *scene = CTX_data_scene(C);
+ // View3D *v3d = ruler_info->sa->spacedata.first;
+ const float mval_fl[2] = {UNPACK2(mval)};
+ float ray_normal[3];
+ float ray_start[3];
+ float *co_other;
+
+ co_other = ruler_item->co[inter->co_index == 0 ? 2 : 0];
+
+ if (ED_transform_snap_object_project_view3d(ruler_info->snap_context,
+ SCE_SNAP_MODE_FACE,
+ &(const struct SnapObjectParams){
+ .snap_select = SNAP_ALL,
+ .use_object_edit_cage = true,
+ },
+ mval_fl,
+ &dist_px,
+ co,
+ ray_normal)) {
+ negate_v3(ray_normal);
+ /* add some bias */
+ madd_v3_v3v3fl(ray_start, co, ray_normal, eps_bias);
+ ED_transform_snap_object_project_ray(ruler_info->snap_context,
+ &(const struct SnapObjectParams){
+ .snap_select = SNAP_ALL,
+ .use_object_edit_cage = true,
+ },
+ ray_start,
+ ray_normal,
+ NULL,
+ co_other,
+ NULL);
+ }
+ }
+ else if (do_snap) {
+ const float mval_fl[2] = {UNPACK2(mval)};
+
+ if (ED_transform_snap_object_project_view3d(
+ ruler_info->snap_context,
+ (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE),
+ &(const struct SnapObjectParams){
+ .snap_select = SNAP_ALL,
+ .use_object_edit_cage = true,
+ .use_occlusion_test = true,
+ },
+ mval_fl,
+ &dist_px,
+ co,
+ NULL)) {
+ ruler_info->snap_flag |= RULER_SNAP_OK;
+ }
+ }
+ return true;
+ }
+ else {
+ return false;
+ }
}
-
/** \} */
/* -------------------------------------------------------------------- */
@@ -381,114 +382,115 @@ static bool view3d_ruler_item_mousemove(
#define RULER_ID "RulerData3D"
static bool view3d_ruler_to_gpencil(bContext *C, wmGizmoGroup *gzgroup)
{
- // RulerInfo *ruler_info = gzgroup->customdata;
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
-
- bGPdata *gpd;
- bGPDlayer *gpl;
- bGPDframe *gpf;
- bGPDstroke *gps;
- RulerItem *ruler_item;
- const char *ruler_name = RULER_ID;
- bool changed = false;
-
- if (scene->gpd == NULL) {
- scene->gpd = BKE_gpencil_data_addnew(bmain, "Annotations");
- }
- gpd = scene->gpd;
-
- gpl = BLI_findstring(&gpd->layers, ruler_name, offsetof(bGPDlayer, info));
- if (gpl == NULL) {
- gpl = BKE_gpencil_layer_addnew(gpd, ruler_name, false);
- copy_v4_v4(gpl->color, U.gpencil_new_layer_col);
- gpl->thickness = 1;
- gpl->flag |= GP_LAYER_HIDE;
- }
-
- gpf = BKE_gpencil_layer_getframe(gpl, CFRA, GP_GETFRAME_ADD_NEW);
- BKE_gpencil_free_strokes(gpf);
-
- for (ruler_item = gzgroup->gizmos.first; ruler_item; ruler_item = (RulerItem *)ruler_item->gz.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->strength = 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->strength = 1.0f;
- pt++;
- }
- }
- gps->flag = GP_STROKE_3DSPACE;
- gps->thickness = 3;
- gps->gradient_f = 1.0f;
- gps->gradient_s[0] = 1.0f;
- gps->gradient_s[1] = 1.0f;
-
- BLI_addtail(&gpf->strokes, gps);
- changed = true;
- }
-
- return changed;
+ // RulerInfo *ruler_info = gzgroup->customdata;
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+
+ bGPdata *gpd;
+ bGPDlayer *gpl;
+ bGPDframe *gpf;
+ bGPDstroke *gps;
+ RulerItem *ruler_item;
+ const char *ruler_name = RULER_ID;
+ bool changed = false;
+
+ if (scene->gpd == NULL) {
+ scene->gpd = BKE_gpencil_data_addnew(bmain, "Annotations");
+ }
+ gpd = scene->gpd;
+
+ gpl = BLI_findstring(&gpd->layers, ruler_name, offsetof(bGPDlayer, info));
+ if (gpl == NULL) {
+ gpl = BKE_gpencil_layer_addnew(gpd, ruler_name, false);
+ copy_v4_v4(gpl->color, U.gpencil_new_layer_col);
+ gpl->thickness = 1;
+ gpl->flag |= GP_LAYER_HIDE;
+ }
+
+ gpf = BKE_gpencil_layer_getframe(gpl, CFRA, GP_GETFRAME_ADD_NEW);
+ BKE_gpencil_free_strokes(gpf);
+
+ for (ruler_item = gzgroup->gizmos.first; ruler_item;
+ ruler_item = (RulerItem *)ruler_item->gz.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->strength = 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->strength = 1.0f;
+ pt++;
+ }
+ }
+ gps->flag = GP_STROKE_3DSPACE;
+ gps->thickness = 3;
+ gps->gradient_f = 1.0f;
+ gps->gradient_s[0] = 1.0f;
+ gps->gradient_s[1] = 1.0f;
+
+ BLI_addtail(&gpf->strokes, gps);
+ changed = true;
+ }
+
+ return changed;
}
static bool view3d_ruler_from_gpencil(const bContext *C, wmGizmoGroup *gzgroup)
{
- Scene *scene = CTX_data_scene(C);
- bool changed = 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 = BKE_gpencil_layer_getframe(gpl, CFRA, GP_GETFRAME_USE_PREV);
- if (gpf) {
- bGPDstroke *gps;
- for (gps = gpf->strokes.first; gps; gps = gps->next) {
- bGPDspoint *pt = gps->points;
- int j;
- RulerItem *ruler_item = NULL;
- if (gps->totpoints == 3) {
- ruler_item = ruler_item_add(gzgroup);
- for (j = 0; j < 3; j++) {
- copy_v3_v3(ruler_item->co[j], &pt->x);
- pt++;
- }
- ruler_item->flag |= RULERITEM_USE_ANGLE;
- changed = true;
- }
- else if (gps->totpoints == 2) {
- ruler_item = ruler_item_add(gzgroup);
- for (j = 0; j < 3; j += 2) {
- copy_v3_v3(ruler_item->co[j], &pt->x);
- pt++;
- }
- changed = true;
- }
- }
- }
- }
- }
-
- return changed;
+ Scene *scene = CTX_data_scene(C);
+ bool changed = 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 = BKE_gpencil_layer_getframe(gpl, CFRA, GP_GETFRAME_USE_PREV);
+ if (gpf) {
+ bGPDstroke *gps;
+ for (gps = gpf->strokes.first; gps; gps = gps->next) {
+ bGPDspoint *pt = gps->points;
+ int j;
+ RulerItem *ruler_item = NULL;
+ if (gps->totpoints == 3) {
+ ruler_item = ruler_item_add(gzgroup);
+ for (j = 0; j < 3; j++) {
+ copy_v3_v3(ruler_item->co[j], &pt->x);
+ pt++;
+ }
+ ruler_item->flag |= RULERITEM_USE_ANGLE;
+ changed = true;
+ }
+ else if (gps->totpoints == 2) {
+ ruler_item = ruler_item_add(gzgroup);
+ for (j = 0; j < 3; j += 2) {
+ copy_v3_v3(ruler_item->co[j], &pt->x);
+ pt++;
+ }
+ changed = true;
+ }
+ }
+ }
+ }
+ }
+
+ return changed;
}
/** \} */
@@ -499,488 +501,492 @@ static bool view3d_ruler_from_gpencil(const bContext *C, wmGizmoGroup *gzgroup)
static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz)
{
- Scene *scene = CTX_data_scene(C);
- UnitSettings *unit = &scene->unit;
- RulerInfo *ruler_info = gz->parent_gzgroup->customdata;
- RulerItem *ruler_item = (RulerItem *)gz;
- ARegion *ar = ruler_info->ar;
- RegionView3D *rv3d = ar->regiondata;
- const float cap_size = 4.0f;
- const float bg_margin = 4.0f * U.pixelsize;
- const float arc_size = 64.0f * U.pixelsize;
+ Scene *scene = CTX_data_scene(C);
+ UnitSettings *unit = &scene->unit;
+ RulerInfo *ruler_info = gz->parent_gzgroup->customdata;
+ RulerItem *ruler_item = (RulerItem *)gz;
+ ARegion *ar = ruler_info->ar;
+ RegionView3D *rv3d = ar->regiondata;
+ const float cap_size = 4.0f;
+ const float bg_margin = 4.0f * U.pixelsize;
+ const float arc_size = 64.0f * U.pixelsize;
#define ARC_STEPS 24
- const int arc_steps = ARC_STEPS;
- const float color_act[4] = {1.0f, 1.0f, 1.0f, 1.0f};
- const float color_base[4] = {0.0f, 0.0f, 0.0f, 1.0f};
- uchar color_text[3];
- uchar color_wire[3];
- float color_back[4] = {1.0f, 1.0f, 1.0f, 0.5f};
-
- /* anti-aliased lines for more consistent appearance */
- GPU_line_smooth(true);
- GPU_line_width(1.0f);
-
- 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);
-
- /* Avoid white on white text. (TODO Fix by using theme) */
- if ((int)color_text[0] + (int)color_text[1] + (int)color_text[2] > 127 * 3 * 0.6f) {
- copy_v3_fl(color_back, 0.0f);
- }
-
- const bool is_act = (ruler_info->item_active == ruler_item);
- 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);
- }
-
- GPU_blend(true);
-
- const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-
- if (ruler_item->flag & RULERITEM_USE_ANGLE) {
- immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
-
- float viewport_size[4];
- GPU_viewport_size_get_f(viewport_size);
- immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
-
- immUniform1i("colors_len", 2); /* "advanced" mode */
- const float *col = is_act ? color_act : color_base;
- immUniformArray4fv("colors", (float *)(float[][4]){{0.67f, 0.67f, 0.67f, 1.0f}, {col[0], col[1], col[2], col[3]}}, 2);
- immUniform1f("dash_width", 6.0f);
-
- immBegin(GPU_PRIM_LINE_STRIP, 3);
-
- immVertex2fv(shdr_pos, co_ss[0]);
- immVertex2fv(shdr_pos, co_ss[1]);
- immVertex2fv(shdr_pos, co_ss[2]);
-
- immEnd();
-
- immUnbindProgram();
+ const int arc_steps = ARC_STEPS;
+ const float color_act[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+ const float color_base[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+ uchar color_text[3];
+ uchar color_wire[3];
+ float color_back[4] = {1.0f, 1.0f, 1.0f, 0.5f};
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ /* anti-aliased lines for more consistent appearance */
+ GPU_line_smooth(true);
+ GPU_line_width(1.0f);
- /* arc */
- {
- float dir_tmp[3];
- float co_tmp[3];
- float arc_ss_coord[2];
+ BLF_enable(blf_mono_font, BLF_ROTATION);
+ BLF_size(blf_mono_font, 14 * U.pixelsize, U.dpi);
+ BLF_rotation(blf_mono_font, 0.0f);
- float dir_a[3];
- float dir_b[3];
- float quat[4];
- float axis[3];
- float angle;
- const float px_scale = (ED_view3d_pixel_size_no_ui_scale(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));
+ UI_GetThemeColor3ubv(TH_TEXT, color_text);
+ UI_GetThemeColor3ubv(TH_WIRE, color_wire);
- 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);
+ /* Avoid white on white text. (TODO Fix by using theme) */
+ if ((int)color_text[0] + (int)color_text[1] + (int)color_text[2] > 127 * 3 * 0.6f) {
+ copy_v3_fl(color_back, 0.0f);
+ }
- cross_v3_v3v3(axis, dir_a, dir_b);
- angle = angle_normalized_v3v3(dir_a, dir_b);
+ const bool is_act = (ruler_info->item_active == ruler_item);
+ float dir_ruler[2];
+ float co_ss[3][2];
+ int j;
- axis_angle_to_quat(quat, axis, angle / arc_steps);
+ /* 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);
+ }
+
+ GPU_blend(true);
+
+ const uint shdr_pos = GPU_vertformat_attr_add(
+ immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+
+ if (ruler_item->flag & RULERITEM_USE_ANGLE) {
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
+
+ float viewport_size[4];
+ GPU_viewport_size_get_f(viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
- copy_v3_v3(dir_tmp, dir_a);
+ immUniform1i("colors_len", 2); /* "advanced" mode */
+ const float *col = is_act ? color_act : color_base;
+ immUniformArray4fv(
+ "colors",
+ (float *)(float[][4]){{0.67f, 0.67f, 0.67f, 1.0f}, {col[0], col[1], col[2], col[3]}},
+ 2);
+ immUniform1f("dash_width", 6.0f);
+
+ immBegin(GPU_PRIM_LINE_STRIP, 3);
- immUniformColor3ubv(color_wire);
+ immVertex2fv(shdr_pos, co_ss[0]);
+ immVertex2fv(shdr_pos, co_ss[1]);
+ immVertex2fv(shdr_pos, co_ss[2]);
+
+ immEnd();
+
+ immUnbindProgram();
- immBegin(GPU_PRIM_LINE_STRIP, arc_steps + 1);
-
- 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_coord, V3D_PROJ_TEST_NOP);
- mul_qt_v3(quat, dir_tmp);
-
- immVertex2fv(shdr_pos, arc_ss_coord);
- }
-
- immEnd();
- }
-
- /* capping */
- {
- float rot_90_vec_a[2];
- float rot_90_vec_b[2];
- float cap[2];
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- 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);
+ /* arc */
+ {
+ float dir_tmp[3];
+ float co_tmp[3];
+ float arc_ss_coord[2];
- 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);
+ float dir_a[3];
+ float dir_b[3];
+ float quat[4];
+ float axis[3];
+ float angle;
+ const float px_scale = (ED_view3d_pixel_size_no_ui_scale(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));
- GPU_blend(true);
+ 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);
+
+ immUniformColor3ubv(color_wire);
+
+ immBegin(GPU_PRIM_LINE_STRIP, arc_steps + 1);
+
+ 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_coord, V3D_PROJ_TEST_NOP);
+ mul_qt_v3(quat, dir_tmp);
+
+ immVertex2fv(shdr_pos, arc_ss_coord);
+ }
+
+ immEnd();
+ }
+
+ /* 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);
+
+ GPU_blend(true);
- if (is_act && (ruler_item->flag & RULERITEM_USE_ANGLE_ACTIVE)) {
- GPU_line_width(3.0f);
- immUniformColor3fv(color_act);
- immBegin(GPU_PRIM_LINES, 4);
- /* angle vertex */
- immVertex2f(shdr_pos, co_ss[1][0] - cap_size, co_ss[1][1] - cap_size);
- immVertex2f(shdr_pos, co_ss[1][0] + cap_size, co_ss[1][1] + cap_size);
- immVertex2f(shdr_pos, co_ss[1][0] - cap_size, co_ss[1][1] + cap_size);
- immVertex2f(shdr_pos, co_ss[1][0] + cap_size, co_ss[1][1] - cap_size);
+ if (is_act && (ruler_item->flag & RULERITEM_USE_ANGLE_ACTIVE)) {
+ GPU_line_width(3.0f);
+ immUniformColor3fv(color_act);
+ immBegin(GPU_PRIM_LINES, 4);
+ /* angle vertex */
+ immVertex2f(shdr_pos, co_ss[1][0] - cap_size, co_ss[1][1] - cap_size);
+ immVertex2f(shdr_pos, co_ss[1][0] + cap_size, co_ss[1][1] + cap_size);
+ immVertex2f(shdr_pos, co_ss[1][0] - cap_size, co_ss[1][1] + cap_size);
+ immVertex2f(shdr_pos, co_ss[1][0] + cap_size, co_ss[1][1] - cap_size);
- immEnd();
- GPU_line_width(1.0f);
- }
+ immEnd();
+ GPU_line_width(1.0f);
+ }
- immUniformColor3ubv(color_wire);
+ immUniformColor3ubv(color_wire);
- immBegin(GPU_PRIM_LINES, 8);
+ immBegin(GPU_PRIM_LINES, 8);
- madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec_a, cap_size);
- immVertex2fv(shdr_pos, cap);
- madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec_a, -cap_size);
- immVertex2fv(shdr_pos, cap);
+ madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec_a, cap_size);
+ immVertex2fv(shdr_pos, cap);
+ madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec_a, -cap_size);
+ immVertex2fv(shdr_pos, cap);
- madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec_b, cap_size);
- immVertex2fv(shdr_pos, cap);
- madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec_b, -cap_size);
- immVertex2fv(shdr_pos, cap);
+ madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec_b, cap_size);
+ immVertex2fv(shdr_pos, cap);
+ madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec_b, -cap_size);
+ immVertex2fv(shdr_pos, cap);
- /* angle vertex */
- immVertex2f(shdr_pos, co_ss[1][0] - cap_size, co_ss[1][1] - cap_size);
- immVertex2f(shdr_pos, co_ss[1][0] + cap_size, co_ss[1][1] + cap_size);
- immVertex2f(shdr_pos, co_ss[1][0] - cap_size, co_ss[1][1] + cap_size);
- immVertex2f(shdr_pos, co_ss[1][0] + cap_size, co_ss[1][1] - cap_size);
+ /* angle vertex */
+ immVertex2f(shdr_pos, co_ss[1][0] - cap_size, co_ss[1][1] - cap_size);
+ immVertex2f(shdr_pos, co_ss[1][0] + cap_size, co_ss[1][1] + cap_size);
+ immVertex2f(shdr_pos, co_ss[1][0] - cap_size, co_ss[1][1] + cap_size);
+ immVertex2f(shdr_pos, co_ss[1][0] + cap_size, co_ss[1][1] - cap_size);
- immEnd();
+ immEnd();
- GPU_blend(false);
- }
+ GPU_blend(false);
+ }
- /* text */
- char numstr[256];
- float numstr_size[2];
- float posit[2];
- const int prec = 2; /* XXX, todo, make optional */
+ /* text */
+ char numstr[256];
+ float numstr_size[2];
+ float posit[2];
+ const int prec = 2; /* XXX, todo, make optional */
- ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec);
+ ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec);
- BLF_width_and_height(blf_mono_font, numstr, sizeof(numstr), &numstr_size[0], &numstr_size[1]);
+ BLF_width_and_height(blf_mono_font, numstr, sizeof(numstr), &numstr_size[0], &numstr_size[1]);
- posit[0] = co_ss[1][0] + (cap_size * 2.0f);
- posit[1] = co_ss[1][1] - (numstr_size[1] / 2.0f);
+ posit[0] = co_ss[1][0] + (cap_size * 2.0f);
+ posit[1] = co_ss[1][1] - (numstr_size[1] / 2.0f);
- /* draw text (bg) */
- {
- immUniformColor4fv(color_back);
- GPU_blend(true);
- immRectf(shdr_pos,
- posit[0] - bg_margin, posit[1] - bg_margin,
- posit[0] + bg_margin + numstr_size[0], posit[1] + bg_margin + numstr_size[1]);
- GPU_blend(false);
- }
+ /* draw text (bg) */
+ {
+ immUniformColor4fv(color_back);
+ GPU_blend(true);
+ immRectf(shdr_pos,
+ posit[0] - bg_margin,
+ posit[1] - bg_margin,
+ posit[0] + bg_margin + numstr_size[0],
+ posit[1] + bg_margin + numstr_size[1]);
+ GPU_blend(false);
+ }
- immUnbindProgram();
+ immUnbindProgram();
- /* draw text */
- {
- BLF_color3ubv(blf_mono_font, color_text);
- BLF_position(blf_mono_font, posit[0], posit[1], 0.0f);
- BLF_rotation(blf_mono_font, 0.0f);
- BLF_draw(blf_mono_font, numstr, sizeof(numstr));
- }
- }
- else {
- immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
+ /* draw text */
+ {
+ BLF_color3ubv(blf_mono_font, color_text);
+ BLF_position(blf_mono_font, posit[0], posit[1], 0.0f);
+ BLF_rotation(blf_mono_font, 0.0f);
+ BLF_draw(blf_mono_font, numstr, sizeof(numstr));
+ }
+ }
+ else {
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
- float viewport_size[4];
- GPU_viewport_size_get_f(viewport_size);
- immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+ float viewport_size[4];
+ GPU_viewport_size_get_f(viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
- immUniform1i("colors_len", 2); /* "advanced" mode */
- const float *col = is_act ? color_act : color_base;
- immUniformArray4fv("colors", (float *)(float[][4]){{0.67f, 0.67f, 0.67f, 1.0f}, {col[0], col[1], col[2], col[3]}}, 2);
- immUniform1f("dash_width", 6.0f);
+ immUniform1i("colors_len", 2); /* "advanced" mode */
+ const float *col = is_act ? color_act : color_base;
+ immUniformArray4fv(
+ "colors",
+ (float *)(float[][4]){{0.67f, 0.67f, 0.67f, 1.0f}, {col[0], col[1], col[2], col[3]}},
+ 2);
+ immUniform1f("dash_width", 6.0f);
- immBegin(GPU_PRIM_LINES, 2);
+ immBegin(GPU_PRIM_LINES, 2);
- immVertex2fv(shdr_pos, co_ss[0]);
- immVertex2fv(shdr_pos, co_ss[2]);
+ immVertex2fv(shdr_pos, co_ss[0]);
+ immVertex2fv(shdr_pos, co_ss[2]);
- immEnd();
+ immEnd();
- immUnbindProgram();
+ immUnbindProgram();
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- sub_v2_v2v2(dir_ruler, co_ss[0], co_ss[2]);
+ sub_v2_v2v2(dir_ruler, co_ss[0], co_ss[2]);
- /* capping */
- {
- float rot_90_vec[2] = {-dir_ruler[1], dir_ruler[0]};
- float cap[2];
+ /* capping */
+ {
+ float rot_90_vec[2] = {-dir_ruler[1], dir_ruler[0]};
+ float cap[2];
- normalize_v2(rot_90_vec);
+ normalize_v2(rot_90_vec);
- GPU_blend(true);
+ GPU_blend(true);
- immUniformColor3ubv(color_wire);
+ immUniformColor3ubv(color_wire);
- immBegin(GPU_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
- madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec, cap_size);
- immVertex2fv(shdr_pos, cap);
- madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec, -cap_size);
- immVertex2fv(shdr_pos, cap);
+ madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec, cap_size);
+ immVertex2fv(shdr_pos, cap);
+ madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec, -cap_size);
+ immVertex2fv(shdr_pos, cap);
- madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec, cap_size);
- immVertex2fv(shdr_pos, cap);
- madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec, -cap_size);
- immVertex2fv(shdr_pos, cap);
+ madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec, cap_size);
+ immVertex2fv(shdr_pos, cap);
+ madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec, -cap_size);
+ immVertex2fv(shdr_pos, cap);
- immEnd();
+ immEnd();
- GPU_blend(false);
- }
+ GPU_blend(false);
+ }
- /* text */
- char numstr[256];
- float numstr_size[2];
- const int prec = 6; /* XXX, todo, make optional */
- float posit[2];
+ /* text */
+ char numstr[256];
+ float numstr_size[2];
+ const int prec = 6; /* XXX, todo, make optional */
+ float posit[2];
- ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec);
+ ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec);
- BLF_width_and_height(blf_mono_font, numstr, sizeof(numstr), &numstr_size[0], &numstr_size[1]);
+ BLF_width_and_height(blf_mono_font, numstr, sizeof(numstr), &numstr_size[0], &numstr_size[1]);
- mid_v2_v2v2(posit, co_ss[0], co_ss[2]);
+ mid_v2_v2v2(posit, co_ss[0], co_ss[2]);
- /* center text */
- posit[0] -= numstr_size[0] / 2.0f;
- posit[1] -= numstr_size[1] / 2.0f;
+ /* center text */
+ posit[0] -= numstr_size[0] / 2.0f;
+ posit[1] -= numstr_size[1] / 2.0f;
- /* draw text (bg) */
- {
- immUniformColor4fv(color_back);
- GPU_blend(true);
- immRectf(shdr_pos,
- posit[0] - bg_margin, posit[1] - bg_margin,
- posit[0] + bg_margin + numstr_size[0], posit[1] + bg_margin + numstr_size[1]);
- GPU_blend(false);
- }
+ /* draw text (bg) */
+ {
+ immUniformColor4fv(color_back);
+ GPU_blend(true);
+ immRectf(shdr_pos,
+ posit[0] - bg_margin,
+ posit[1] - bg_margin,
+ posit[0] + bg_margin + numstr_size[0],
+ posit[1] + bg_margin + numstr_size[1]);
+ GPU_blend(false);
+ }
- immUnbindProgram();
+ immUnbindProgram();
- /* draw text */
- {
- BLF_color3ubv(blf_mono_font, color_text);
- BLF_position(blf_mono_font, posit[0], posit[1], 0.0f);
- BLF_draw(blf_mono_font, numstr, sizeof(numstr));
- }
- }
+ /* draw text */
+ {
+ BLF_color3ubv(blf_mono_font, color_text);
+ BLF_position(blf_mono_font, posit[0], posit[1], 0.0f);
+ BLF_draw(blf_mono_font, numstr, sizeof(numstr));
+ }
+ }
- GPU_line_smooth(false);
+ GPU_line_smooth(false);
- BLF_disable(blf_mono_font, BLF_ROTATION);
+ BLF_disable(blf_mono_font, BLF_ROTATION);
#undef ARC_STEPS
- /* draw snap */
- if ((ruler_info->snap_flag & RULER_SNAP_OK) &&
- (ruler_info->state == RULER_STATE_DRAG) &&
- (ruler_item->gz.interaction_data != NULL))
- {
- RulerInteraction *inter = ruler_item->gz.interaction_data;
- /* size from drawSnapping */
- const float size = 2.5f * UI_GetThemeValuef(TH_VERTEX_SIZE);
- float co_ss_snap[3];
- ED_view3d_project_float_global(ar, ruler_item->co[inter->co_index], co_ss_snap, V3D_PROJ_TEST_NOP);
+ /* draw snap */
+ if ((ruler_info->snap_flag & RULER_SNAP_OK) && (ruler_info->state == RULER_STATE_DRAG) &&
+ (ruler_item->gz.interaction_data != NULL)) {
+ RulerInteraction *inter = ruler_item->gz.interaction_data;
+ /* size from drawSnapping */
+ const float size = 2.5f * UI_GetThemeValuef(TH_VERTEX_SIZE);
+ float co_ss_snap[3];
+ ED_view3d_project_float_global(
+ ar, ruler_item->co[inter->co_index], co_ss_snap, V3D_PROJ_TEST_NOP);
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformColor4fv(color_act);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4fv(color_act);
- imm_draw_circle_wire_2d(pos, co_ss_snap[0], co_ss_snap[1], size * U.pixelsize, 32);
+ imm_draw_circle_wire_2d(pos, co_ss_snap[0], co_ss_snap[1], size * U.pixelsize, 32);
- immUnbindProgram();
- }
+ immUnbindProgram();
+ }
}
-static int gizmo_ruler_test_select(
- bContext *UNUSED(C), wmGizmo *gz, const int mval[2])
+static int gizmo_ruler_test_select(bContext *UNUSED(C), wmGizmo *gz, const int mval[2])
{
- RulerItem *ruler_item_pick = (RulerItem *)gz;
- float mval_fl[2] = {UNPACK2(mval)};
- int co_index;
-
- /* select and drag */
- if (view3d_ruler_pick(gz->parent_gzgroup, ruler_item_pick, mval_fl, &co_index)) {
- if (co_index == -1) {
- if ((ruler_item_pick->flag & RULERITEM_USE_ANGLE) == 0) {
- return PART_LINE;
- }
- }
- else {
- return co_index;
- }
- }
- return -1;
+ RulerItem *ruler_item_pick = (RulerItem *)gz;
+ float mval_fl[2] = {UNPACK2(mval)};
+ int co_index;
+
+ /* select and drag */
+ if (view3d_ruler_pick(gz->parent_gzgroup, ruler_item_pick, mval_fl, &co_index)) {
+ if (co_index == -1) {
+ if ((ruler_item_pick->flag & RULERITEM_USE_ANGLE) == 0) {
+ return PART_LINE;
+ }
+ }
+ else {
+ return co_index;
+ }
+ }
+ return -1;
}
-static int gizmo_ruler_modal(
- bContext *C, wmGizmo *gz, const wmEvent *event,
- eWM_GizmoFlagTweak UNUSED(tweak_flag))
+static int gizmo_ruler_modal(bContext *C,
+ wmGizmo *gz,
+ const wmEvent *event,
+ eWM_GizmoFlagTweak UNUSED(tweak_flag))
{
- bool do_draw = false;
- int exit_code = OPERATOR_RUNNING_MODAL;
- RulerInfo *ruler_info = gz->parent_gzgroup->customdata;
- RulerItem *ruler_item = (RulerItem *)gz;
- ARegion *ar = CTX_wm_region(C);
-
- ruler_info->ar = ar;
-
- switch (event->type) {
- case MOUSEMOVE:
- {
- if (ruler_info->state == RULER_STATE_DRAG) {
- if (view3d_ruler_item_mousemove(
- ruler_info, ruler_item, event->mval,
- event->shift != 0, event->ctrl != 0))
- {
- do_draw = true;
- }
- }
- break;
- }
- }
- if (do_draw) {
- ED_region_tag_redraw(ar);
- }
- return exit_code;
+ bool do_draw = false;
+ int exit_code = OPERATOR_RUNNING_MODAL;
+ RulerInfo *ruler_info = gz->parent_gzgroup->customdata;
+ RulerItem *ruler_item = (RulerItem *)gz;
+ ARegion *ar = CTX_wm_region(C);
+
+ ruler_info->ar = ar;
+
+ switch (event->type) {
+ case MOUSEMOVE: {
+ if (ruler_info->state == RULER_STATE_DRAG) {
+ if (view3d_ruler_item_mousemove(
+ ruler_info, ruler_item, event->mval, event->shift != 0, event->ctrl != 0)) {
+ do_draw = true;
+ }
+ }
+ break;
+ }
+ }
+ if (do_draw) {
+ ED_region_tag_redraw(ar);
+ }
+ return exit_code;
}
-static int gizmo_ruler_invoke(
- bContext *C, wmGizmo *gz, const wmEvent *event)
+static int gizmo_ruler_invoke(bContext *C, wmGizmo *gz, const wmEvent *event)
{
- wmGizmoGroup *gzgroup = gz->parent_gzgroup;
- RulerInfo *ruler_info = gzgroup->customdata;
- RulerItem *ruler_item_pick = (RulerItem *)gz;
- RulerInteraction *inter = MEM_callocN(sizeof(RulerInteraction), __func__);
- gz->interaction_data = inter;
-
- ARegion *ar = ruler_info->ar;
-
- const float mval_fl[2] = {UNPACK2(event->mval)};
-
- /* select and drag */
- if (gz->highlight_part == PART_LINE) {
- if ((ruler_item_pick->flag & RULERITEM_USE_ANGLE) == 0) {
- /* Add Center Point */
- ruler_item_pick->flag |= RULERITEM_USE_ANGLE;
- inter->co_index = 1;
- ruler_state_set(C, ruler_info, 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(
- ruler_info, ruler_item_pick, event->mval,
- event->shift != 0, event->ctrl != 0);
- }
- }
- else {
- inter->co_index = gz->highlight_part;
- ruler_state_set(C, ruler_info, RULER_STATE_DRAG);
-
- /* store the initial depth */
- copy_v3_v3(inter->drag_start_co, ruler_item_pick->co[inter->co_index]);
- }
-
- if (inter->co_index == 1) {
- ruler_item_pick->flag |= RULERITEM_USE_ANGLE_ACTIVE;
- }
- else {
- ruler_item_pick->flag &= ~RULERITEM_USE_ANGLE_ACTIVE;
- }
-
- ruler_info->item_active = ruler_item_pick;
-
- return OPERATOR_RUNNING_MODAL;
+ wmGizmoGroup *gzgroup = gz->parent_gzgroup;
+ RulerInfo *ruler_info = gzgroup->customdata;
+ RulerItem *ruler_item_pick = (RulerItem *)gz;
+ RulerInteraction *inter = MEM_callocN(sizeof(RulerInteraction), __func__);
+ gz->interaction_data = inter;
+
+ ARegion *ar = ruler_info->ar;
+
+ const float mval_fl[2] = {UNPACK2(event->mval)};
+
+ /* select and drag */
+ if (gz->highlight_part == PART_LINE) {
+ if ((ruler_item_pick->flag & RULERITEM_USE_ANGLE) == 0) {
+ /* Add Center Point */
+ ruler_item_pick->flag |= RULERITEM_USE_ANGLE;
+ inter->co_index = 1;
+ ruler_state_set(C, ruler_info, 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(
+ ruler_info, ruler_item_pick, event->mval, event->shift != 0, event->ctrl != 0);
+ }
+ }
+ else {
+ inter->co_index = gz->highlight_part;
+ ruler_state_set(C, ruler_info, RULER_STATE_DRAG);
+
+ /* store the initial depth */
+ copy_v3_v3(inter->drag_start_co, ruler_item_pick->co[inter->co_index]);
+ }
+
+ if (inter->co_index == 1) {
+ ruler_item_pick->flag |= RULERITEM_USE_ANGLE_ACTIVE;
+ }
+ else {
+ ruler_item_pick->flag &= ~RULERITEM_USE_ANGLE_ACTIVE;
+ }
+
+ ruler_info->item_active = ruler_item_pick;
+
+ return OPERATOR_RUNNING_MODAL;
}
static void gizmo_ruler_exit(bContext *C, wmGizmo *gz, const bool cancel)
{
- wmGizmoGroup *gzgroup = gz->parent_gzgroup;
- RulerInfo *ruler_info = gzgroup->customdata;
-
- if (!cancel) {
- if (ruler_info->state == RULER_STATE_DRAG) {
- if (ruler_info->snap_flag & RULER_SNAP_OK) {
- ruler_info->snap_flag &= ~RULER_SNAP_OK;
- }
- ruler_state_set(C, ruler_info, RULER_STATE_NORMAL);
- }
- /* We could convert only the current gizmo, for now just re-generate. */
- view3d_ruler_to_gpencil(C, gzgroup);
- }
-
- if (gz) {
- MEM_SAFE_FREE(gz->interaction_data);
- }
-
- ruler_state_set(C, ruler_info, RULER_STATE_NORMAL);
+ wmGizmoGroup *gzgroup = gz->parent_gzgroup;
+ RulerInfo *ruler_info = gzgroup->customdata;
+
+ if (!cancel) {
+ if (ruler_info->state == RULER_STATE_DRAG) {
+ if (ruler_info->snap_flag & RULER_SNAP_OK) {
+ ruler_info->snap_flag &= ~RULER_SNAP_OK;
+ }
+ ruler_state_set(C, ruler_info, RULER_STATE_NORMAL);
+ }
+ /* We could convert only the current gizmo, for now just re-generate. */
+ view3d_ruler_to_gpencil(C, gzgroup);
+ }
+
+ if (gz) {
+ MEM_SAFE_FREE(gz->interaction_data);
+ }
+
+ ruler_state_set(C, ruler_info, RULER_STATE_NORMAL);
}
static int gizmo_ruler_cursor_get(wmGizmo *gz)
{
- if (gz->highlight_part == PART_LINE) {
- return BC_CROSSCURSOR;
- }
- return BC_NSEW_SCROLLCURSOR;
+ if (gz->highlight_part == PART_LINE) {
+ return BC_CROSSCURSOR;
+ }
+ return BC_NSEW_SCROLLCURSOR;
}
void VIEW3D_GT_ruler_item(wmGizmoType *gzt)
{
- /* identifiers */
- gzt->idname = "VIEW3D_GT_ruler_item";
-
- /* api callbacks */
- gzt->draw = gizmo_ruler_draw;
- gzt->test_select = gizmo_ruler_test_select;
- gzt->modal = gizmo_ruler_modal;
- gzt->invoke = gizmo_ruler_invoke;
- gzt->exit = gizmo_ruler_exit;
- gzt->cursor_get = gizmo_ruler_cursor_get;
-
- gzt->struct_size = sizeof(RulerItem);
+ /* identifiers */
+ gzt->idname = "VIEW3D_GT_ruler_item";
+
+ /* api callbacks */
+ gzt->draw = gizmo_ruler_draw;
+ gzt->test_select = gizmo_ruler_test_select;
+ gzt->modal = gizmo_ruler_modal;
+ gzt->invoke = gizmo_ruler_invoke;
+ gzt->exit = gizmo_ruler_exit;
+ gzt->cursor_get = gizmo_ruler_cursor_get;
+
+ gzt->struct_size = sizeof(RulerItem);
}
/** \} */
@@ -991,34 +997,34 @@ void VIEW3D_GT_ruler_item(wmGizmoType *gzt)
static void WIDGETGROUP_ruler_setup(const bContext *C, wmGizmoGroup *gzgroup)
{
- RulerInfo *ruler_info = MEM_callocN(sizeof(RulerInfo), __func__);
+ RulerInfo *ruler_info = MEM_callocN(sizeof(RulerInfo), __func__);
- if (view3d_ruler_from_gpencil(C, gzgroup)) {
- /* nop */
- }
+ if (view3d_ruler_from_gpencil(C, gzgroup)) {
+ /* nop */
+ }
- wmWindow *win = CTX_wm_window(C);
- ScrArea *sa = CTX_wm_area(C);
- ARegion *ar = CTX_wm_region(C);
- ruler_info->win = win;
- ruler_info->sa = sa;
- ruler_info->ar = ar;
+ wmWindow *win = CTX_wm_window(C);
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = CTX_wm_region(C);
+ ruler_info->win = win;
+ ruler_info->sa = sa;
+ ruler_info->ar = ar;
- gzgroup->customdata = ruler_info;
+ gzgroup->customdata = ruler_info;
}
void VIEW3D_GGT_ruler(wmGizmoGroupType *gzgt)
{
- gzgt->name = "Ruler Widgets";
- gzgt->idname = view3d_gzgt_ruler_id;
+ gzgt->name = "Ruler Widgets";
+ gzgt->idname = view3d_gzgt_ruler_id;
- gzgt->flag |= WM_GIZMOGROUPTYPE_SCALE | WM_GIZMOGROUPTYPE_DRAW_MODAL_ALL;
+ gzgt->flag |= WM_GIZMOGROUPTYPE_SCALE | WM_GIZMOGROUPTYPE_DRAW_MODAL_ALL;
- gzgt->gzmap_params.spaceid = SPACE_VIEW3D;
- gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;
+ gzgt->gzmap_params.spaceid = SPACE_VIEW3D;
+ gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;
- gzgt->poll = ED_gizmo_poll_or_unlink_delayed_from_tool;
- gzgt->setup = WIDGETGROUP_ruler_setup;
+ gzgt->poll = ED_gizmo_poll_or_unlink_delayed_from_tool;
+ gzgt->setup = WIDGETGROUP_ruler_setup;
}
/** \} */
@@ -1029,72 +1035,68 @@ void VIEW3D_GGT_ruler(wmGizmoGroupType *gzgt)
static bool view3d_ruler_poll(bContext *C)
{
- bToolRef_Runtime *tref_rt = WM_toolsystem_runtime_from_context((bContext *)C);
- if ((tref_rt == NULL) ||
- !STREQ(view3d_gzgt_ruler_id, tref_rt->gizmo_group) ||
- CTX_wm_region_view3d(C) == NULL)
- {
- return false;
- }
- return true;
+ bToolRef_Runtime *tref_rt = WM_toolsystem_runtime_from_context((bContext *)C);
+ if ((tref_rt == NULL) || !STREQ(view3d_gzgt_ruler_id, tref_rt->gizmo_group) ||
+ CTX_wm_region_view3d(C) == NULL) {
+ return false;
+ }
+ return true;
}
static int view3d_ruler_add_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- ARegion *ar = CTX_wm_region(C);
- View3D *v3d = CTX_wm_view3d(C);
- RegionView3D *rv3d = ar->regiondata;
-
- if (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_TOOL)) {
- BKE_report(op->reports, RPT_WARNING, "Gizmos hidden in this view");
- return OPERATOR_CANCELLED;
- }
-
- wmGizmoMap *gzmap = ar->gizmo_map;
- wmGizmoGroup *gzgroup = WM_gizmomap_group_find(gzmap, view3d_gzgt_ruler_id);
- const bool use_depth = (v3d->shading.type >= OB_SOLID);
-
- /* Create new line */
- RulerItem *ruler_item;
- ruler_item = ruler_item_add(gzgroup);
-
- /* This is a little weak, but there is no real good way to tweak directly. */
- WM_gizmo_highlight_set(gzmap, &ruler_item->gz);
- if (WM_operator_name_call(
- C, "GIZMOGROUP_OT_gizmo_tweak",
- WM_OP_INVOKE_REGION_WIN, NULL) == OPERATOR_RUNNING_MODAL)
- {
- RulerInfo *ruler_info = gzgroup->customdata;
- RulerInteraction *inter = ruler_item->gz.interaction_data;
- if (use_depth) {
- /* snap the first point added, not essential but handy */
- inter->co_index = 0;
- view3d_ruler_item_mousemove(ruler_info, ruler_item, event->mval, false, true);
- copy_v3_v3(inter->drag_start_co, ruler_item->co[inter->co_index]);
- }
- else {
- negate_v3_v3(inter->drag_start_co, rv3d->ofs);
- copy_v3_v3(ruler_item->co[0], inter->drag_start_co);
- view3d_ruler_item_project(ruler_info, ruler_item->co[0], event->mval);
- }
-
- copy_v3_v3(ruler_item->co[2], ruler_item->co[0]);
- ruler_item->gz.highlight_part = inter->co_index = 2;
- }
- return OPERATOR_FINISHED;
+ ARegion *ar = CTX_wm_region(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ RegionView3D *rv3d = ar->regiondata;
+
+ if (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_TOOL)) {
+ BKE_report(op->reports, RPT_WARNING, "Gizmos hidden in this view");
+ return OPERATOR_CANCELLED;
+ }
+
+ wmGizmoMap *gzmap = ar->gizmo_map;
+ wmGizmoGroup *gzgroup = WM_gizmomap_group_find(gzmap, view3d_gzgt_ruler_id);
+ const bool use_depth = (v3d->shading.type >= OB_SOLID);
+
+ /* Create new line */
+ RulerItem *ruler_item;
+ ruler_item = ruler_item_add(gzgroup);
+
+ /* This is a little weak, but there is no real good way to tweak directly. */
+ WM_gizmo_highlight_set(gzmap, &ruler_item->gz);
+ if (WM_operator_name_call(C, "GIZMOGROUP_OT_gizmo_tweak", WM_OP_INVOKE_REGION_WIN, NULL) ==
+ OPERATOR_RUNNING_MODAL) {
+ RulerInfo *ruler_info = gzgroup->customdata;
+ RulerInteraction *inter = ruler_item->gz.interaction_data;
+ if (use_depth) {
+ /* snap the first point added, not essential but handy */
+ inter->co_index = 0;
+ view3d_ruler_item_mousemove(ruler_info, ruler_item, event->mval, false, true);
+ copy_v3_v3(inter->drag_start_co, ruler_item->co[inter->co_index]);
+ }
+ else {
+ negate_v3_v3(inter->drag_start_co, rv3d->ofs);
+ copy_v3_v3(ruler_item->co[0], inter->drag_start_co);
+ view3d_ruler_item_project(ruler_info, ruler_item->co[0], event->mval);
+ }
+
+ copy_v3_v3(ruler_item->co[2], ruler_item->co[0]);
+ ruler_item->gz.highlight_part = inter->co_index = 2;
+ }
+ return OPERATOR_FINISHED;
}
void VIEW3D_OT_ruler_add(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Ruler Add";
- ot->idname = "VIEW3D_OT_ruler_add";
+ /* identifiers */
+ ot->name = "Ruler Add";
+ ot->idname = "VIEW3D_OT_ruler_add";
- ot->invoke = view3d_ruler_add_invoke;
- ot->poll = view3d_ruler_poll;
+ ot->invoke = view3d_ruler_add_invoke;
+ ot->poll = view3d_ruler_poll;
- /* flags */
- ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
}
/** \} */
@@ -1105,46 +1107,45 @@ void VIEW3D_OT_ruler_add(wmOperatorType *ot)
static int view3d_ruler_remove_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- ARegion *ar = CTX_wm_region(C);
- View3D *v3d = CTX_wm_view3d(C);
-
- if (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_TOOL)) {
- BKE_report(op->reports, RPT_WARNING, "Gizmos hidden in this view");
- return OPERATOR_CANCELLED;
- }
-
- wmGizmoMap *gzmap = ar->gizmo_map;
- wmGizmoGroup *gzgroup = WM_gizmomap_group_find(gzmap, view3d_gzgt_ruler_id);
- if (gzgroup) {
- RulerInfo *ruler_info = gzgroup->customdata;
- if (ruler_info->item_active) {
- RulerItem *ruler_item = ruler_info->item_active;
- if ((ruler_item->flag & RULERITEM_USE_ANGLE) &&
- (ruler_item->flag & RULERITEM_USE_ANGLE_ACTIVE))
- {
- ruler_item->flag &= ~(RULERITEM_USE_ANGLE | RULERITEM_USE_ANGLE_ACTIVE);
- }
- else {
- ruler_item_remove(C, gzgroup, ruler_item);
- }
- ED_region_tag_redraw(ar);
- return OPERATOR_FINISHED;
- }
- }
- return OPERATOR_PASS_THROUGH;
+ ARegion *ar = CTX_wm_region(C);
+ View3D *v3d = CTX_wm_view3d(C);
+
+ if (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_TOOL)) {
+ BKE_report(op->reports, RPT_WARNING, "Gizmos hidden in this view");
+ return OPERATOR_CANCELLED;
+ }
+
+ wmGizmoMap *gzmap = ar->gizmo_map;
+ wmGizmoGroup *gzgroup = WM_gizmomap_group_find(gzmap, view3d_gzgt_ruler_id);
+ if (gzgroup) {
+ RulerInfo *ruler_info = gzgroup->customdata;
+ if (ruler_info->item_active) {
+ RulerItem *ruler_item = ruler_info->item_active;
+ if ((ruler_item->flag & RULERITEM_USE_ANGLE) &&
+ (ruler_item->flag & RULERITEM_USE_ANGLE_ACTIVE)) {
+ ruler_item->flag &= ~(RULERITEM_USE_ANGLE | RULERITEM_USE_ANGLE_ACTIVE);
+ }
+ else {
+ ruler_item_remove(C, gzgroup, ruler_item);
+ }
+ ED_region_tag_redraw(ar);
+ return OPERATOR_FINISHED;
+ }
+ }
+ return OPERATOR_PASS_THROUGH;
}
void VIEW3D_OT_ruler_remove(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Ruler Remove";
- ot->idname = "VIEW3D_OT_ruler_remove";
+ /* identifiers */
+ ot->name = "Ruler Remove";
+ ot->idname = "VIEW3D_OT_ruler_remove";
- ot->invoke = view3d_ruler_remove_invoke;
- ot->poll = view3d_ruler_poll;
+ ot->invoke = view3d_ruler_remove_invoke;
+ ot->poll = view3d_ruler_poll;
- /* flags */
- ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
}
/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index de3f0392ff0..6984562337c 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -57,9 +57,9 @@
static void do_view3d_header_buttons(bContext *C, void *arg, int event);
-#define B_SEL_VERT 110
-#define B_SEL_EDGE 111
-#define B_SEL_FACE 112
+#define B_SEL_VERT 110
+#define B_SEL_EDGE 111
+#define B_SEL_FACE 112
/* -------------------------------------------------------------------- */
/** \name Toggle Matcap Flip Operator
@@ -67,31 +67,31 @@ static void do_view3d_header_buttons(bContext *C, void *arg, int event);
static int toggle_matcap_flip(bContext *C, wmOperator *UNUSED(op))
{
- View3D *v3d = CTX_wm_view3d(C);
-
- if (v3d) {
- v3d->shading.flag ^= V3D_SHADING_MATCAP_FLIP_X;
- ED_view3d_shade_update(CTX_data_main(C), v3d, CTX_wm_area(C));
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
- }
- else {
- Scene *scene = CTX_data_scene(C);
- scene->display.shading.flag ^= V3D_SHADING_MATCAP_FLIP_X;
- WM_event_add_notifier(C, NC_SCENE | NA_EDITED, v3d);
- }
-
- return OPERATOR_FINISHED;
+ View3D *v3d = CTX_wm_view3d(C);
+
+ if (v3d) {
+ v3d->shading.flag ^= V3D_SHADING_MATCAP_FLIP_X;
+ ED_view3d_shade_update(CTX_data_main(C), v3d, CTX_wm_area(C));
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
+ }
+ else {
+ Scene *scene = CTX_data_scene(C);
+ scene->display.shading.flag ^= V3D_SHADING_MATCAP_FLIP_X;
+ WM_event_add_notifier(C, NC_SCENE | NA_EDITED, v3d);
+ }
+
+ return OPERATOR_FINISHED;
}
void VIEW3D_OT_toggle_matcap_flip(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Flip MatCap";
- ot->description = "Flip MatCap";
- ot->idname = "VIEW3D_OT_toggle_matcap_flip";
+ /* identifiers */
+ ot->name = "Flip MatCap";
+ ot->description = "Flip MatCap";
+ ot->idname = "VIEW3D_OT_toggle_matcap_flip";
- /* api callbacks */
- ot->exec = toggle_matcap_flip;
+ /* api callbacks */
+ ot->exec = toggle_matcap_flip;
}
/** \} */
@@ -102,95 +102,136 @@ void VIEW3D_OT_toggle_matcap_flip(wmOperatorType *ot)
static void do_view3d_header_buttons(bContext *C, void *UNUSED(arg), int event)
{
- wmWindow *win = CTX_wm_window(C);
- const int ctrl = win->eventstate->ctrl, shift = win->eventstate->shift;
-
- /* watch it: if sa->win does not exist, check that when calling direct drawing routines */
-
- switch (event) {
- case B_SEL_VERT:
- if (EDBM_selectmode_toggle(C, SCE_SELECT_VERTEX, -1, shift, ctrl)) {
- ED_undo_push(C, "Selectmode Set: Vertex");
- }
- break;
- case B_SEL_EDGE:
- if (EDBM_selectmode_toggle(C, SCE_SELECT_EDGE, -1, shift, ctrl)) {
- ED_undo_push(C, "Selectmode Set: Edge");
- }
- break;
- case B_SEL_FACE:
- if (EDBM_selectmode_toggle(C, SCE_SELECT_FACE, -1, shift, ctrl)) {
- ED_undo_push(C, "Selectmode Set: Face");
- }
- break;
- default:
- break;
- }
+ wmWindow *win = CTX_wm_window(C);
+ const int ctrl = win->eventstate->ctrl, shift = win->eventstate->shift;
+
+ /* watch it: if sa->win does not exist, check that when calling direct drawing routines */
+
+ switch (event) {
+ case B_SEL_VERT:
+ if (EDBM_selectmode_toggle(C, SCE_SELECT_VERTEX, -1, shift, ctrl)) {
+ ED_undo_push(C, "Selectmode Set: Vertex");
+ }
+ break;
+ case B_SEL_EDGE:
+ if (EDBM_selectmode_toggle(C, SCE_SELECT_EDGE, -1, shift, ctrl)) {
+ ED_undo_push(C, "Selectmode Set: Edge");
+ }
+ break;
+ case B_SEL_FACE:
+ if (EDBM_selectmode_toggle(C, SCE_SELECT_FACE, -1, shift, ctrl)) {
+ ED_undo_push(C, "Selectmode Set: Face");
+ }
+ break;
+ default:
+ break;
+ }
}
void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C)
{
- Object *obedit = CTX_data_edit_object(C);
- uiBlock *block = uiLayoutGetBlock(layout);
-
- UI_block_func_handle_set(block, do_view3d_header_buttons, NULL);
-
- if (obedit && (obedit->type == OB_MESH)) {
- BMEditMesh *em = BKE_editmesh_from_object(obedit);
- uiLayout *row;
-
- row = uiLayoutRow(layout, true);
- block = uiLayoutGetBlock(row);
- uiDefIconButBitS(block, UI_BTYPE_TOGGLE, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL,
- 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
- TIP_("Vertex select - Shift-Click for multiple modes, Ctrl-Click contracts selection"));
- uiDefIconButBitS(block, UI_BTYPE_TOGGLE, SCE_SELECT_EDGE, B_SEL_EDGE, ICON_EDGESEL,
- 0, 0, ceilf(UI_UNIT_X - U.pixelsize), UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
- TIP_("Edge select - Shift-Click for multiple modes, Ctrl-Click expands/contracts selection"));
- uiDefIconButBitS(block, UI_BTYPE_TOGGLE, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL,
- 0, 0, ceilf(UI_UNIT_X - U.pixelsize), UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
- TIP_("Face select - Shift-Click for multiple modes, Ctrl-Click expands selection"));
- }
+ Object *obedit = CTX_data_edit_object(C);
+ uiBlock *block = uiLayoutGetBlock(layout);
+
+ UI_block_func_handle_set(block, do_view3d_header_buttons, NULL);
+
+ if (obedit && (obedit->type == OB_MESH)) {
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ uiLayout *row;
+
+ row = uiLayoutRow(layout, true);
+ block = uiLayoutGetBlock(row);
+ uiDefIconButBitS(
+ block,
+ UI_BTYPE_TOGGLE,
+ SCE_SELECT_VERTEX,
+ B_SEL_VERT,
+ ICON_VERTEXSEL,
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &em->selectmode,
+ 1.0,
+ 0.0,
+ 0,
+ 0,
+ TIP_("Vertex select - Shift-Click for multiple modes, Ctrl-Click contracts selection"));
+ uiDefIconButBitS(block,
+ UI_BTYPE_TOGGLE,
+ SCE_SELECT_EDGE,
+ B_SEL_EDGE,
+ ICON_EDGESEL,
+ 0,
+ 0,
+ ceilf(UI_UNIT_X - U.pixelsize),
+ UI_UNIT_Y,
+ &em->selectmode,
+ 1.0,
+ 0.0,
+ 0,
+ 0,
+ TIP_("Edge select - Shift-Click for multiple modes, Ctrl-Click "
+ "expands/contracts selection"));
+ uiDefIconButBitS(
+ block,
+ UI_BTYPE_TOGGLE,
+ SCE_SELECT_FACE,
+ B_SEL_FACE,
+ ICON_FACESEL,
+ 0,
+ 0,
+ ceilf(UI_UNIT_X - U.pixelsize),
+ UI_UNIT_Y,
+ &em->selectmode,
+ 1.0,
+ 0.0,
+ 0,
+ 0,
+ TIP_("Face select - Shift-Click for multiple modes, Ctrl-Click expands selection"));
+ }
}
static void uiTemplatePaintModeSelection(uiLayout *layout, struct bContext *C)
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *ob = OBACT(view_layer);
-
- /* Gizmos aren't used in paint modes */
- if (!ELEM(ob->mode, OB_MODE_SCULPT, OB_MODE_PARTICLE_EDIT)) {
- /* masks aren't used for sculpt and particle painting */
- PointerRNA meshptr;
-
- RNA_pointer_create(ob->data, &RNA_Mesh, ob->data, &meshptr);
- if (ob->mode & (OB_MODE_TEXTURE_PAINT)) {
- uiItemR(layout, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
- }
- else {
- uiLayout *row = uiLayoutRow(layout, true);
- uiItemR(row, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
- uiItemR(row, &meshptr, "use_paint_mask_vertex", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
- }
- }
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *ob = OBACT(view_layer);
+
+ /* Gizmos aren't used in paint modes */
+ if (!ELEM(ob->mode, OB_MODE_SCULPT, OB_MODE_PARTICLE_EDIT)) {
+ /* masks aren't used for sculpt and particle painting */
+ PointerRNA meshptr;
+
+ RNA_pointer_create(ob->data, &RNA_Mesh, ob->data, &meshptr);
+ if (ob->mode & (OB_MODE_TEXTURE_PAINT)) {
+ uiItemR(layout, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
+ }
+ else {
+ uiLayout *row = uiLayoutRow(layout, true);
+ uiItemR(row, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
+ uiItemR(row, &meshptr, "use_paint_mask_vertex", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
+ }
+ }
}
void uiTemplateHeader3D_mode(uiLayout *layout, struct bContext *C)
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *ob = OBACT(view_layer);
- Object *obedit = CTX_data_edit_object(C);
- bGPdata *gpd = CTX_data_gpencil_data(C);
-
- bool is_paint = (
- ob && !(gpd && (gpd->flag & GP_DATA_STROKE_EDITMODE)) &&
- ELEM(ob->mode,
- OB_MODE_SCULPT, OB_MODE_VERTEX_PAINT, OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT));
-
- uiTemplateEditModeSelection(layout, C);
- if ((obedit == NULL) && is_paint) {
- uiTemplatePaintModeSelection(layout, C);
- }
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *ob = OBACT(view_layer);
+ Object *obedit = CTX_data_edit_object(C);
+ bGPdata *gpd = CTX_data_gpencil_data(C);
+
+ bool is_paint = (ob && !(gpd && (gpd->flag & GP_DATA_STROKE_EDITMODE)) &&
+ ELEM(ob->mode,
+ OB_MODE_SCULPT,
+ OB_MODE_VERTEX_PAINT,
+ OB_MODE_WEIGHT_PAINT,
+ OB_MODE_TEXTURE_PAINT));
+
+ uiTemplateEditModeSelection(layout, C);
+ if ((obedit == NULL) && is_paint) {
+ uiTemplatePaintModeSelection(layout, C);
+ }
}
/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index e85558765b6..fd306619577 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -50,9 +50,9 @@ struct wmWindowManager;
/* drawing flags: */
enum {
- DRAW_PICKING = (1 << 0),
- DRAW_CONSTCOLOR = (1 << 1),
- DRAW_SCENESET = (1 << 2),
+ DRAW_PICKING = (1 << 0),
+ DRAW_CONSTCOLOR = (1 << 1),
+ DRAW_SCENESET = (1 << 2),
};
/* view3d_header.c */
@@ -101,18 +101,22 @@ void VIEW3D_OT_toggle_xray(struct wmOperatorType *ot);
void view3d_boxview_copy(struct ScrArea *sa, struct ARegion *ar);
void view3d_boxview_sync(struct ScrArea *sa, struct ARegion *ar);
-void view3d_orbit_apply_dyn_ofs(
- float r_ofs[3], const float ofs_old[3], const float viewquat_old[4],
- const float viewquat_new[4], const float dyn_ofs[3]);
+void view3d_orbit_apply_dyn_ofs(float r_ofs[3],
+ const float ofs_old[3],
+ const float viewquat_old[4],
+ const float viewquat_new[4],
+ const float dyn_ofs[3]);
#ifdef WITH_INPUT_NDOF
struct wmNDOFMotionData;
-void view3d_ndof_fly(
- const struct wmNDOFMotionData *ndof,
- struct View3D *v3d, struct RegionView3D *rv3d,
- const bool use_precision, const short protectflag,
- bool *r_has_translate, bool *r_has_rotate);
+void view3d_ndof_fly(const struct wmNDOFMotionData *ndof,
+ struct View3D *v3d,
+ struct RegionView3D *rv3d,
+ const bool use_precision,
+ const short protectflag,
+ bool *r_has_translate,
+ bool *r_has_rotate);
#endif /* WITH_INPUT_NDOF */
/* view3d_fly.c */
@@ -123,10 +127,12 @@ void VIEW3D_OT_fly(struct wmOperatorType *ot);
void VIEW3D_OT_walk(struct wmOperatorType *ot);
/* drawobject.c */
-void draw_object_select_id(
- struct Depsgraph *depsgraph, Scene *scene,
- View3D *v3d, RegionView3D *rv3d, struct Object *ob,
- short select_mode);
+void draw_object_select_id(struct Depsgraph *depsgraph,
+ Scene *scene,
+ View3D *v3d,
+ RegionView3D *rv3d,
+ struct Object *ob,
+ short select_mode);
void draw_object_depth(RegionView3D *rv3d, struct Object *ob);
@@ -136,19 +142,30 @@ int view3d_effective_drawtype(const struct View3D *v3d);
void view3d_main_region_draw(const struct bContext *C, struct ARegion *ar);
void view3d_draw_region_info(const struct bContext *C, struct ARegion *ar);
-void ED_view3d_draw_depth(
- struct Depsgraph *depsgraph,
- struct ARegion *ar, View3D *v3d, bool alphaoverride);
+void ED_view3d_draw_depth(struct Depsgraph *depsgraph,
+ struct ARegion *ar,
+ View3D *v3d,
+ bool alphaoverride);
/* view3d_draw_legacy.c */
-void ED_view3d_draw_depth_gpencil(struct Depsgraph *depsgraph, Scene *scene, struct ARegion *ar, View3D *v3d);
-
-void ED_view3d_draw_select_loop(
- struct Depsgraph *depsgraph, ViewContext *vc, Scene *scene, struct ViewLayer *view_layer, View3D *v3d, struct ARegion *ar,
- bool use_obedit_skip, bool use_nearest);
-
-void ED_view3d_draw_depth_loop(
- struct Depsgraph *depsgraph, Scene *scene, struct ARegion *ar, View3D *v3d);
+void ED_view3d_draw_depth_gpencil(struct Depsgraph *depsgraph,
+ Scene *scene,
+ struct ARegion *ar,
+ View3D *v3d);
+
+void ED_view3d_draw_select_loop(struct Depsgraph *depsgraph,
+ ViewContext *vc,
+ Scene *scene,
+ struct ViewLayer *view_layer,
+ View3D *v3d,
+ struct ARegion *ar,
+ bool use_obedit_skip,
+ bool use_nearest);
+
+void ED_view3d_draw_depth_loop(struct Depsgraph *depsgraph,
+ Scene *scene,
+ struct ARegion *ar,
+ View3D *v3d);
void view3d_update_depths_rect(struct ARegion *ar, struct ViewDepths *d, struct rcti *rect);
float view3d_depth_near(struct ViewDepths *d);
@@ -168,37 +185,46 @@ void VIEW3D_OT_object_as_camera(struct wmOperatorType *ot);
void VIEW3D_OT_localview(struct wmOperatorType *ot);
void VIEW3D_OT_localview_remove_from(struct wmOperatorType *ot);
-bool ED_view3d_boundbox_clip_ex(const RegionView3D *rv3d, const struct BoundBox *bb, float obmat[4][4]);
+bool ED_view3d_boundbox_clip_ex(const RegionView3D *rv3d,
+ const struct BoundBox *bb,
+ float obmat[4][4]);
bool ED_view3d_boundbox_clip(RegionView3D *rv3d, const struct BoundBox *bb);
typedef struct V3D_SmoothParams {
- struct Object *camera_old, *camera;
- const float *ofs, *quat, *dist, *lens;
- /* alternate rotation center (ofs = must be NULL) */
- const float *dyn_ofs;
+ struct Object *camera_old, *camera;
+ const float *ofs, *quat, *dist, *lens;
+ /* alternate rotation center (ofs = must be NULL) */
+ const float *dyn_ofs;
} V3D_SmoothParams;
-void ED_view3d_smooth_view_ex(
- const struct Depsgraph *depsgraph,
- struct wmWindowManager *wm, struct wmWindow *win, struct ScrArea *sa,
- struct View3D *v3d, struct ARegion *ar, const int smooth_viewtx,
- const V3D_SmoothParams *sview);
-
-void ED_view3d_smooth_view(
- struct bContext *C,
- struct View3D *v3d, struct ARegion *ar, const int smooth_viewtx,
- const V3D_SmoothParams *sview);
-
-void ED_view3d_smooth_view_force_finish(
- struct bContext *C,
- struct View3D *v3d, struct ARegion *ar);
-
-void view3d_winmatrix_set(
- struct Depsgraph *depsgraph,
- struct ARegion *ar, const View3D *v3d, const rcti *rect);
-void view3d_viewmatrix_set(
- struct Depsgraph *depsgraph, Scene *scene,
- const View3D *v3d, RegionView3D *rv3d, const float rect_scale[2]);
+void ED_view3d_smooth_view_ex(const struct Depsgraph *depsgraph,
+ struct wmWindowManager *wm,
+ struct wmWindow *win,
+ struct ScrArea *sa,
+ struct View3D *v3d,
+ struct ARegion *ar,
+ const int smooth_viewtx,
+ const V3D_SmoothParams *sview);
+
+void ED_view3d_smooth_view(struct bContext *C,
+ struct View3D *v3d,
+ struct ARegion *ar,
+ const int smooth_viewtx,
+ const V3D_SmoothParams *sview);
+
+void ED_view3d_smooth_view_force_finish(struct bContext *C,
+ struct View3D *v3d,
+ struct ARegion *ar);
+
+void view3d_winmatrix_set(struct Depsgraph *depsgraph,
+ struct ARegion *ar,
+ const View3D *v3d,
+ const rcti *rect);
+void view3d_viewmatrix_set(struct Depsgraph *depsgraph,
+ Scene *scene,
+ const View3D *v3d,
+ RegionView3D *rv3d,
+ const float rect_scale[2]);
void fly_modal_keymap(struct wmKeyConfig *keyconf);
void walk_modal_keymap(struct wmKeyConfig *keyconf);
@@ -213,18 +239,18 @@ void VIEW3D_OT_object_mode_pie_or_toggle(struct wmOperatorType *ot);
void view3d_buttons_register(struct ARegionType *art);
/* view3d_camera_control.c */
-struct View3DCameraControl *ED_view3d_cameracontrol_acquire(
- struct Depsgraph *depsgraph, Scene *scene, View3D *v3d, RegionView3D *rv3d,
- const bool use_parent_root);
-void ED_view3d_cameracontrol_update(
- struct View3DCameraControl *vctrl,
- const bool use_autokey,
- struct bContext *C, const bool do_rotate, const bool do_translate);
-void ED_view3d_cameracontrol_release(
- struct View3DCameraControl *vctrl,
- const bool restore);
-struct Object *ED_view3d_cameracontrol_object_get(
- struct View3DCameraControl *vctrl);
+struct View3DCameraControl *ED_view3d_cameracontrol_acquire(struct Depsgraph *depsgraph,
+ Scene *scene,
+ View3D *v3d,
+ RegionView3D *rv3d,
+ const bool use_parent_root);
+void ED_view3d_cameracontrol_update(struct View3DCameraControl *vctrl,
+ const bool use_autokey,
+ struct bContext *C,
+ const bool do_rotate,
+ const bool do_translate);
+void ED_view3d_cameracontrol_release(struct View3DCameraControl *vctrl, const bool restore);
+struct Object *ED_view3d_cameracontrol_object_get(struct View3DCameraControl *vctrl);
/* view3d_toolbar.c */
void VIEW3D_OT_toolshelf(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c
index daa1cd38164..b6efc0ff136 100644
--- a/source/blender/editors/space_view3d/view3d_iterators.c
+++ b/source/blender/editors/space_view3d/view3d_iterators.c
@@ -49,36 +49,39 @@
#include "ED_view3d.h"
typedef struct foreachScreenObjectVert_userData {
- void (*func)(void *userData, MVert *mv, const float screen_co_b[2], int index);
- void *userData;
- ViewContext vc;
- eV3DProjTest clip_flag;
+ void (*func)(void *userData, MVert *mv, const float screen_co_b[2], int index);
+ void *userData;
+ ViewContext vc;
+ eV3DProjTest clip_flag;
} foreachScreenObjectVert_userData;
typedef struct foreachScreenVert_userData {
- void (*func)(void *userData, BMVert *eve, const float screen_co_b[2], int index);
- void *userData;
- ViewContext vc;
- eV3DProjTest clip_flag;
+ void (*func)(void *userData, BMVert *eve, const float screen_co_b[2], int index);
+ void *userData;
+ ViewContext vc;
+ eV3DProjTest clip_flag;
} foreachScreenVert_userData;
/* user data structures for derived mesh callbacks */
typedef struct foreachScreenEdge_userData {
- void (*func)(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index);
- void *userData;
- ViewContext vc;
- rctf win_rect; /* copy of: vc.ar->winx/winy, use for faster tests, minx/y will always be 0 */
- eV3DProjTest clip_flag;
+ void (*func)(void *userData,
+ BMEdge *eed,
+ const float screen_co_a[2],
+ const float screen_co_b[2],
+ int index);
+ void *userData;
+ ViewContext vc;
+ rctf win_rect; /* copy of: vc.ar->winx/winy, use for faster tests, minx/y will always be 0 */
+ eV3DProjTest clip_flag;
} foreachScreenEdge_userData;
typedef struct foreachScreenFace_userData {
- void (*func)(void *userData, BMFace *efa, const float screen_co_b[2], int index);
- void *userData;
- ViewContext vc;
- eV3DProjTest clip_flag;
+ void (*func)(void *userData, BMFace *efa, const float screen_co_b[2], int index);
+ void *userData;
+ ViewContext vc;
+ eV3DProjTest clip_flag;
} foreachScreenFace_userData;
-
/**
* \note foreach funcs should be called while drawing or directly after
* if not, #ED_view3d_init_mats_rv3d() can be used for selection tools
@@ -88,392 +91,447 @@ typedef struct foreachScreenFace_userData {
/* ------------------------------------------------------------------------ */
-
-static void meshobject_foreachScreenVert__mapFunc(void *userData, int index, const float co[3],
- const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
+static void meshobject_foreachScreenVert__mapFunc(void *userData,
+ int index,
+ const float co[3],
+ const float UNUSED(no_f[3]),
+ const short UNUSED(no_s[3]))
{
- foreachScreenObjectVert_userData *data = userData;
- struct MVert *mv = &((Mesh *)(data->vc.obact->data))->mvert[index];
+ foreachScreenObjectVert_userData *data = userData;
+ struct MVert *mv = &((Mesh *)(data->vc.obact->data))->mvert[index];
- if (!(mv->flag & ME_HIDE)) {
- float screen_co[2];
+ if (!(mv->flag & ME_HIDE)) {
+ float screen_co[2];
- if (ED_view3d_project_float_object(data->vc.ar, co, screen_co, data->clip_flag) != V3D_PROJ_RET_OK) {
- return;
- }
+ if (ED_view3d_project_float_object(data->vc.ar, co, screen_co, data->clip_flag) !=
+ V3D_PROJ_RET_OK) {
+ return;
+ }
- data->func(data->userData, mv, screen_co, index);
- }
+ data->func(data->userData, mv, screen_co, index);
+ }
}
void meshobject_foreachScreenVert(
- ViewContext *vc,
- void (*func)(void *userData, MVert *eve, const float screen_co[2], int index),
- void *userData, eV3DProjTest clip_flag)
+ ViewContext *vc,
+ void (*func)(void *userData, MVert *eve, const float screen_co[2], int index),
+ void *userData,
+ eV3DProjTest clip_flag)
{
- foreachScreenObjectVert_userData data;
- Mesh *me;
+ foreachScreenObjectVert_userData data;
+ Mesh *me;
- Scene *scene_eval = DEG_get_evaluated_scene(vc->depsgraph);
- Object *ob_eval = DEG_get_evaluated_object(vc->depsgraph, vc->obact);
+ Scene *scene_eval = DEG_get_evaluated_scene(vc->depsgraph);
+ Object *ob_eval = DEG_get_evaluated_object(vc->depsgraph, vc->obact);
- me = mesh_get_eval_deform(vc->depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH);
+ me = mesh_get_eval_deform(vc->depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH);
- ED_view3d_check_mats_rv3d(vc->rv3d);
+ ED_view3d_check_mats_rv3d(vc->rv3d);
- data.vc = *vc;
- data.func = func;
- data.userData = userData;
- data.clip_flag = clip_flag;
+ data.vc = *vc;
+ data.func = func;
+ data.userData = userData;
+ data.clip_flag = clip_flag;
- if (clip_flag & V3D_PROJ_TEST_CLIP_BB) {
- ED_view3d_clipping_local(vc->rv3d, vc->obact->obmat);
- }
+ if (clip_flag & V3D_PROJ_TEST_CLIP_BB) {
+ ED_view3d_clipping_local(vc->rv3d, vc->obact->obmat);
+ }
- BKE_mesh_foreach_mapped_vert(me, meshobject_foreachScreenVert__mapFunc, &data, MESH_FOREACH_NOP);
+ BKE_mesh_foreach_mapped_vert(me, meshobject_foreachScreenVert__mapFunc, &data, MESH_FOREACH_NOP);
}
-static void mesh_foreachScreenVert__mapFunc(void *userData, int index, const float co[3],
- const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
+static void mesh_foreachScreenVert__mapFunc(void *userData,
+ int index,
+ const float co[3],
+ const float UNUSED(no_f[3]),
+ const short UNUSED(no_s[3]))
{
- foreachScreenVert_userData *data = userData;
- BMVert *eve = BM_vert_at_index(data->vc.em->bm, index);
+ foreachScreenVert_userData *data = userData;
+ BMVert *eve = BM_vert_at_index(data->vc.em->bm, index);
- if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
- float screen_co[2];
+ if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
+ float screen_co[2];
- if (ED_view3d_project_float_object(data->vc.ar, co, screen_co, data->clip_flag) != V3D_PROJ_RET_OK) {
- return;
- }
+ if (ED_view3d_project_float_object(data->vc.ar, co, screen_co, data->clip_flag) !=
+ V3D_PROJ_RET_OK) {
+ return;
+ }
- data->func(data->userData, eve, screen_co, index);
- }
+ data->func(data->userData, eve, screen_co, index);
+ }
}
void mesh_foreachScreenVert(
- ViewContext *vc,
- void (*func)(void *userData, BMVert *eve, const float screen_co[2], int index),
- void *userData, eV3DProjTest clip_flag)
+ ViewContext *vc,
+ void (*func)(void *userData, BMVert *eve, const float screen_co[2], int index),
+ void *userData,
+ eV3DProjTest clip_flag)
{
- foreachScreenVert_userData data;
+ foreachScreenVert_userData data;
- Mesh *me = editbmesh_get_eval_cage_from_orig(vc->depsgraph, vc->scene, vc->obedit, vc->em, &CD_MASK_BAREMESH);
+ Mesh *me = editbmesh_get_eval_cage_from_orig(
+ vc->depsgraph, vc->scene, vc->obedit, vc->em, &CD_MASK_BAREMESH);
- ED_view3d_check_mats_rv3d(vc->rv3d);
+ ED_view3d_check_mats_rv3d(vc->rv3d);
- data.vc = *vc;
- data.func = func;
- data.userData = userData;
- data.clip_flag = clip_flag;
+ data.vc = *vc;
+ data.func = func;
+ data.userData = userData;
+ data.clip_flag = clip_flag;
- if (clip_flag & V3D_PROJ_TEST_CLIP_BB) {
- ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
- }
+ if (clip_flag & V3D_PROJ_TEST_CLIP_BB) {
+ ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
+ }
- BM_mesh_elem_table_ensure(vc->em->bm, BM_VERT);
- BKE_mesh_foreach_mapped_vert(me, mesh_foreachScreenVert__mapFunc, &data, MESH_FOREACH_NOP);
+ BM_mesh_elem_table_ensure(vc->em->bm, BM_VERT);
+ BKE_mesh_foreach_mapped_vert(me, mesh_foreachScreenVert__mapFunc, &data, MESH_FOREACH_NOP);
}
/* ------------------------------------------------------------------------ */
-static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, const float v0co[3], const float v1co[3])
+static void mesh_foreachScreenEdge__mapFunc(void *userData,
+ int index,
+ const float v0co[3],
+ const float v1co[3])
{
- foreachScreenEdge_userData *data = userData;
- BMEdge *eed = BM_edge_at_index(data->vc.em->bm, index);
-
- if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
- float screen_co_a[2];
- float screen_co_b[2];
- eV3DProjTest clip_flag_nowin = data->clip_flag &= ~V3D_PROJ_TEST_CLIP_WIN;
-
- if (ED_view3d_project_float_object(data->vc.ar, v0co, screen_co_a, clip_flag_nowin) != V3D_PROJ_RET_OK) {
- return;
- }
- if (ED_view3d_project_float_object(data->vc.ar, v1co, screen_co_b, clip_flag_nowin) != V3D_PROJ_RET_OK) {
- return;
- }
-
- if (data->clip_flag & V3D_PROJ_TEST_CLIP_WIN) {
- if (!BLI_rctf_isect_segment(&data->win_rect, screen_co_a, screen_co_b)) {
- return;
- }
- }
-
- data->func(data->userData, eed, screen_co_a, screen_co_b, index);
- }
+ foreachScreenEdge_userData *data = userData;
+ BMEdge *eed = BM_edge_at_index(data->vc.em->bm, index);
+
+ if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
+ float screen_co_a[2];
+ float screen_co_b[2];
+ eV3DProjTest clip_flag_nowin = data->clip_flag &= ~V3D_PROJ_TEST_CLIP_WIN;
+
+ if (ED_view3d_project_float_object(data->vc.ar, v0co, screen_co_a, clip_flag_nowin) !=
+ V3D_PROJ_RET_OK) {
+ return;
+ }
+ if (ED_view3d_project_float_object(data->vc.ar, v1co, screen_co_b, clip_flag_nowin) !=
+ V3D_PROJ_RET_OK) {
+ return;
+ }
+
+ if (data->clip_flag & V3D_PROJ_TEST_CLIP_WIN) {
+ if (!BLI_rctf_isect_segment(&data->win_rect, screen_co_a, screen_co_b)) {
+ return;
+ }
+ }
+
+ data->func(data->userData, eed, screen_co_a, screen_co_b, index);
+ }
}
-void mesh_foreachScreenEdge(
- ViewContext *vc,
- void (*func)(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index),
- void *userData, eV3DProjTest clip_flag)
+void mesh_foreachScreenEdge(ViewContext *vc,
+ void (*func)(void *userData,
+ BMEdge *eed,
+ const float screen_co_a[2],
+ const float screen_co_b[2],
+ int index),
+ void *userData,
+ eV3DProjTest clip_flag)
{
- foreachScreenEdge_userData data;
+ foreachScreenEdge_userData data;
- Mesh *me = editbmesh_get_eval_cage_from_orig(vc->depsgraph, vc->scene, vc->obedit, vc->em, &CD_MASK_BAREMESH);
+ Mesh *me = editbmesh_get_eval_cage_from_orig(
+ vc->depsgraph, vc->scene, vc->obedit, vc->em, &CD_MASK_BAREMESH);
- ED_view3d_check_mats_rv3d(vc->rv3d);
+ ED_view3d_check_mats_rv3d(vc->rv3d);
- data.vc = *vc;
+ data.vc = *vc;
- data.win_rect.xmin = 0;
- data.win_rect.ymin = 0;
- data.win_rect.xmax = vc->ar->winx;
- data.win_rect.ymax = vc->ar->winy;
+ data.win_rect.xmin = 0;
+ data.win_rect.ymin = 0;
+ data.win_rect.xmax = vc->ar->winx;
+ data.win_rect.ymax = vc->ar->winy;
- data.func = func;
- data.userData = userData;
- data.clip_flag = clip_flag;
+ data.func = func;
+ data.userData = userData;
+ data.clip_flag = clip_flag;
- if (clip_flag & V3D_PROJ_TEST_CLIP_BB) {
- ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
- }
+ if (clip_flag & V3D_PROJ_TEST_CLIP_BB) {
+ ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
+ }
- BM_mesh_elem_table_ensure(vc->em->bm, BM_EDGE);
- BKE_mesh_foreach_mapped_edge(me, mesh_foreachScreenEdge__mapFunc, &data);
+ BM_mesh_elem_table_ensure(vc->em->bm, BM_EDGE);
+ BKE_mesh_foreach_mapped_edge(me, mesh_foreachScreenEdge__mapFunc, &data);
}
/* ------------------------------------------------------------------------ */
-static void mesh_foreachScreenFace__mapFunc(void *userData, int index, const float cent[3], const float UNUSED(no[3]))
+static void mesh_foreachScreenFace__mapFunc(void *userData,
+ int index,
+ const float cent[3],
+ const float UNUSED(no[3]))
{
- foreachScreenFace_userData *data = userData;
- BMFace *efa = BM_face_at_index(data->vc.em->bm, index);
-
- if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
- float screen_co[2];
- if (ED_view3d_project_float_object(data->vc.ar, cent, screen_co, data->clip_flag) == V3D_PROJ_RET_OK) {
- data->func(data->userData, efa, screen_co, index);
- }
- }
+ foreachScreenFace_userData *data = userData;
+ BMFace *efa = BM_face_at_index(data->vc.em->bm, index);
+
+ if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
+ float screen_co[2];
+ if (ED_view3d_project_float_object(data->vc.ar, cent, screen_co, data->clip_flag) ==
+ V3D_PROJ_RET_OK) {
+ data->func(data->userData, efa, screen_co, index);
+ }
+ }
}
void mesh_foreachScreenFace(
- ViewContext *vc,
- void (*func)(void *userData, BMFace *efa, const float screen_co_b[2], int index),
- void *userData, const eV3DProjTest clip_flag)
+ ViewContext *vc,
+ void (*func)(void *userData, BMFace *efa, const float screen_co_b[2], int index),
+ void *userData,
+ const eV3DProjTest clip_flag)
{
- foreachScreenFace_userData data;
+ foreachScreenFace_userData data;
- Mesh *me = editbmesh_get_eval_cage_from_orig(vc->depsgraph, vc->scene, vc->obedit, vc->em, &CD_MASK_BAREMESH);
- ED_view3d_check_mats_rv3d(vc->rv3d);
+ Mesh *me = editbmesh_get_eval_cage_from_orig(
+ vc->depsgraph, vc->scene, vc->obedit, vc->em, &CD_MASK_BAREMESH);
+ ED_view3d_check_mats_rv3d(vc->rv3d);
- data.vc = *vc;
- data.func = func;
- data.userData = userData;
- data.clip_flag = clip_flag;
+ data.vc = *vc;
+ data.func = func;
+ data.userData = userData;
+ data.clip_flag = clip_flag;
- BM_mesh_elem_table_ensure(vc->em->bm, BM_FACE);
- BKE_mesh_foreach_mapped_face_center(me, mesh_foreachScreenFace__mapFunc, &data, MESH_FOREACH_NOP);
+ BM_mesh_elem_table_ensure(vc->em->bm, BM_FACE);
+ BKE_mesh_foreach_mapped_face_center(
+ me, mesh_foreachScreenFace__mapFunc, &data, MESH_FOREACH_NOP);
}
/* ------------------------------------------------------------------------ */
-void nurbs_foreachScreenVert(
- ViewContext *vc,
- void (*func)(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co_b[2]),
- void *userData, const eV3DProjTest clip_flag)
+void nurbs_foreachScreenVert(ViewContext *vc,
+ void (*func)(void *userData,
+ Nurb *nu,
+ BPoint *bp,
+ BezTriple *bezt,
+ int beztindex,
+ const float screen_co_b[2]),
+ void *userData,
+ const eV3DProjTest clip_flag)
{
- Curve *cu = vc->obedit->data;
- Nurb *nu;
- int i;
- ListBase *nurbs = BKE_curve_editNurbs_get(cu);
-
- ED_view3d_check_mats_rv3d(vc->rv3d);
-
- if (clip_flag & V3D_PROJ_TEST_CLIP_BB) {
- ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
- }
-
- for (nu = nurbs->first; nu; nu = nu->next) {
- if (nu->type == CU_BEZIER) {
- for (i = 0; i < nu->pntsu; i++) {
- BezTriple *bezt = &nu->bezt[i];
-
- if (bezt->hide == 0) {
- float screen_co[2];
-
- if ((vc->v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_CU_HANDLES) == 0) {
- if (ED_view3d_project_float_object(vc->ar, bezt->vec[1], screen_co,
- V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK)
- {
- func(userData, nu, NULL, bezt, 1, screen_co);
- }
- }
- else {
- if (ED_view3d_project_float_object(vc->ar, bezt->vec[0], screen_co,
- V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK)
- {
- func(userData, nu, NULL, bezt, 0, screen_co);
- }
- if (ED_view3d_project_float_object(vc->ar, bezt->vec[1], screen_co,
- V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK)
- {
- func(userData, nu, NULL, bezt, 1, screen_co);
- }
- if (ED_view3d_project_float_object(vc->ar, bezt->vec[2], screen_co,
- V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK)
- {
- func(userData, nu, NULL, bezt, 2, screen_co);
- }
- }
- }
- }
- }
- else {
- for (i = 0; i < nu->pntsu * nu->pntsv; i++) {
- BPoint *bp = &nu->bp[i];
-
- if (bp->hide == 0) {
- float screen_co[2];
- if (ED_view3d_project_float_object(vc->ar, bp->vec, screen_co,
- V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK)
- {
- func(userData, nu, bp, NULL, -1, screen_co);
- }
- }
- }
- }
- }
+ Curve *cu = vc->obedit->data;
+ Nurb *nu;
+ int i;
+ ListBase *nurbs = BKE_curve_editNurbs_get(cu);
+
+ ED_view3d_check_mats_rv3d(vc->rv3d);
+
+ if (clip_flag & V3D_PROJ_TEST_CLIP_BB) {
+ ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
+ }
+
+ for (nu = nurbs->first; nu; nu = nu->next) {
+ if (nu->type == CU_BEZIER) {
+ for (i = 0; i < nu->pntsu; i++) {
+ BezTriple *bezt = &nu->bezt[i];
+
+ if (bezt->hide == 0) {
+ float screen_co[2];
+
+ if ((vc->v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_CU_HANDLES) == 0) {
+ if (ED_view3d_project_float_object(vc->ar,
+ bezt->vec[1],
+ screen_co,
+ V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) ==
+ V3D_PROJ_RET_OK) {
+ func(userData, nu, NULL, bezt, 1, screen_co);
+ }
+ }
+ else {
+ if (ED_view3d_project_float_object(vc->ar,
+ bezt->vec[0],
+ screen_co,
+ V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) ==
+ V3D_PROJ_RET_OK) {
+ func(userData, nu, NULL, bezt, 0, screen_co);
+ }
+ if (ED_view3d_project_float_object(vc->ar,
+ bezt->vec[1],
+ screen_co,
+ V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) ==
+ V3D_PROJ_RET_OK) {
+ func(userData, nu, NULL, bezt, 1, screen_co);
+ }
+ if (ED_view3d_project_float_object(vc->ar,
+ bezt->vec[2],
+ screen_co,
+ V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) ==
+ V3D_PROJ_RET_OK) {
+ func(userData, nu, NULL, bezt, 2, screen_co);
+ }
+ }
+ }
+ }
+ }
+ else {
+ for (i = 0; i < nu->pntsu * nu->pntsv; i++) {
+ BPoint *bp = &nu->bp[i];
+
+ if (bp->hide == 0) {
+ float screen_co[2];
+ if (ED_view3d_project_float_object(
+ vc->ar, bp->vec, screen_co, V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) ==
+ V3D_PROJ_RET_OK) {
+ func(userData, nu, bp, NULL, -1, screen_co);
+ }
+ }
+ }
+ }
+ }
}
/* ------------------------------------------------------------------------ */
/* ED_view3d_init_mats_rv3d must be called first */
-void mball_foreachScreenElem(
- struct ViewContext *vc,
- void (*func)(void *userData, struct MetaElem *ml, const float screen_co_b[2]),
- void *userData, const eV3DProjTest clip_flag)
+void mball_foreachScreenElem(struct ViewContext *vc,
+ void (*func)(void *userData,
+ struct MetaElem *ml,
+ const float screen_co_b[2]),
+ void *userData,
+ const eV3DProjTest clip_flag)
{
- MetaBall *mb = (MetaBall *)vc->obedit->data;
- MetaElem *ml;
+ MetaBall *mb = (MetaBall *)vc->obedit->data;
+ MetaElem *ml;
- ED_view3d_check_mats_rv3d(vc->rv3d);
+ ED_view3d_check_mats_rv3d(vc->rv3d);
- for (ml = mb->editelems->first; ml; ml = ml->next) {
- float screen_co[2];
- if (ED_view3d_project_float_object(vc->ar, &ml->x, screen_co, clip_flag) == V3D_PROJ_RET_OK) {
- func(userData, ml, screen_co);
- }
- }
+ for (ml = mb->editelems->first; ml; ml = ml->next) {
+ float screen_co[2];
+ if (ED_view3d_project_float_object(vc->ar, &ml->x, screen_co, clip_flag) == V3D_PROJ_RET_OK) {
+ func(userData, ml, screen_co);
+ }
+ }
}
/* ------------------------------------------------------------------------ */
-void lattice_foreachScreenVert(
- ViewContext *vc,
- void (*func)(void *userData, BPoint *bp, const float screen_co[2]),
- void *userData, const eV3DProjTest clip_flag)
+void lattice_foreachScreenVert(ViewContext *vc,
+ void (*func)(void *userData, BPoint *bp, const float screen_co[2]),
+ void *userData,
+ const eV3DProjTest clip_flag)
{
- Object *obedit = vc->obedit;
- Lattice *lt = obedit->data;
- BPoint *bp = lt->editlatt->latt->def;
- DispList *dl = obedit->runtime.curve_cache ? BKE_displist_find(&obedit->runtime.curve_cache->disp, DL_VERTS) : NULL;
- const float *co = dl ? dl->verts : NULL;
- int i, N = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw;
-
- ED_view3d_check_mats_rv3d(vc->rv3d);
-
- if (clip_flag & V3D_PROJ_TEST_CLIP_BB) {
- ED_view3d_clipping_local(vc->rv3d, obedit->obmat); /* for local clipping lookups */
- }
-
- for (i = 0; i < N; i++, bp++, co += 3) {
- if (bp->hide == 0) {
- float screen_co[2];
- if (ED_view3d_project_float_object(vc->ar, dl ? co : bp->vec, screen_co, clip_flag) == V3D_PROJ_RET_OK) {
- func(userData, bp, screen_co);
- }
- }
- }
+ Object *obedit = vc->obedit;
+ Lattice *lt = obedit->data;
+ BPoint *bp = lt->editlatt->latt->def;
+ DispList *dl = obedit->runtime.curve_cache ?
+ BKE_displist_find(&obedit->runtime.curve_cache->disp, DL_VERTS) :
+ NULL;
+ const float *co = dl ? dl->verts : NULL;
+ int i, N = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw;
+
+ ED_view3d_check_mats_rv3d(vc->rv3d);
+
+ if (clip_flag & V3D_PROJ_TEST_CLIP_BB) {
+ ED_view3d_clipping_local(vc->rv3d, obedit->obmat); /* for local clipping lookups */
+ }
+
+ for (i = 0; i < N; i++, bp++, co += 3) {
+ if (bp->hide == 0) {
+ float screen_co[2];
+ if (ED_view3d_project_float_object(vc->ar, dl ? co : bp->vec, screen_co, clip_flag) ==
+ V3D_PROJ_RET_OK) {
+ func(userData, bp, screen_co);
+ }
+ }
+ }
}
/* ------------------------------------------------------------------------ */
/* ED_view3d_init_mats_rv3d must be called first */
-void armature_foreachScreenBone(
- struct ViewContext *vc,
- void (*func)(void *userData, struct EditBone *ebone, const float screen_co_a[2], const float screen_co_b[2]),
- void *userData, const eV3DProjTest clip_flag)
+void armature_foreachScreenBone(struct ViewContext *vc,
+ void (*func)(void *userData,
+ struct EditBone *ebone,
+ const float screen_co_a[2],
+ const float screen_co_b[2]),
+ void *userData,
+ const eV3DProjTest clip_flag)
{
- bArmature *arm = vc->obedit->data;
- EditBone *ebone;
-
- ED_view3d_check_mats_rv3d(vc->rv3d);
-
- for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
- if (EBONE_VISIBLE(arm, ebone)) {
- float screen_co_a[2], screen_co_b[2];
- int points_proj_tot = 0;
-
- /* project head location to screenspace */
- if (ED_view3d_project_float_object(vc->ar, ebone->head, screen_co_a, clip_flag) == V3D_PROJ_RET_OK) {
- points_proj_tot++;
- }
- else {
- screen_co_a[0] = IS_CLIPPED; /* weak */
- /* screen_co_a[1]: intentionally dont set this so we get errors on misuse */
- }
-
- /* project tail location to screenspace */
- if (ED_view3d_project_float_object(vc->ar, ebone->tail, screen_co_b, clip_flag) == V3D_PROJ_RET_OK) {
- points_proj_tot++;
- }
- else {
- screen_co_b[0] = IS_CLIPPED; /* weak */
- /* screen_co_b[1]: intentionally dont set this so we get errors on misuse */
- }
-
- if (points_proj_tot) { /* at least one point's projection worked */
- func(userData, ebone, screen_co_a, screen_co_b);
- }
- }
- }
+ bArmature *arm = vc->obedit->data;
+ EditBone *ebone;
+
+ ED_view3d_check_mats_rv3d(vc->rv3d);
+
+ for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
+ if (EBONE_VISIBLE(arm, ebone)) {
+ float screen_co_a[2], screen_co_b[2];
+ int points_proj_tot = 0;
+
+ /* project head location to screenspace */
+ if (ED_view3d_project_float_object(vc->ar, ebone->head, screen_co_a, clip_flag) ==
+ V3D_PROJ_RET_OK) {
+ points_proj_tot++;
+ }
+ else {
+ screen_co_a[0] = IS_CLIPPED; /* weak */
+ /* screen_co_a[1]: intentionally dont set this so we get errors on misuse */
+ }
+
+ /* project tail location to screenspace */
+ if (ED_view3d_project_float_object(vc->ar, ebone->tail, screen_co_b, clip_flag) ==
+ V3D_PROJ_RET_OK) {
+ points_proj_tot++;
+ }
+ else {
+ screen_co_b[0] = IS_CLIPPED; /* weak */
+ /* screen_co_b[1]: intentionally dont set this so we get errors on misuse */
+ }
+
+ if (points_proj_tot) { /* at least one point's projection worked */
+ func(userData, ebone, screen_co_a, screen_co_b);
+ }
+ }
+ }
}
/* ------------------------------------------------------------------------ */
/* ED_view3d_init_mats_rv3d must be called first */
/* almost _exact_ copy of #armature_foreachScreenBone */
-void pose_foreachScreenBone(
- struct ViewContext *vc,
- void (*func)(void *userData, struct bPoseChannel *pchan, const float screen_co_a[2], const float screen_co_b[2]),
- void *userData, const eV3DProjTest clip_flag)
+void pose_foreachScreenBone(struct ViewContext *vc,
+ void (*func)(void *userData,
+ struct bPoseChannel *pchan,
+ const float screen_co_a[2],
+ const float screen_co_b[2]),
+ void *userData,
+ const eV3DProjTest clip_flag)
{
- const Object *ob_eval = DEG_get_evaluated_object(vc->depsgraph, vc->obact);
- const bArmature *arm_eval = ob_eval->data;
- bPose *pose = vc->obact->pose;
- bPoseChannel *pchan;
-
- ED_view3d_check_mats_rv3d(vc->rv3d);
-
- for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
- if (PBONE_VISIBLE(arm_eval, pchan->bone)) {
- bPoseChannel *pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, pchan->name);
- float screen_co_a[2], screen_co_b[2];
- int points_proj_tot = 0;
-
- /* project head location to screenspace */
- if (ED_view3d_project_float_object(vc->ar, pchan_eval->pose_head, screen_co_a, clip_flag) == V3D_PROJ_RET_OK) {
- points_proj_tot++;
- }
- else {
- screen_co_a[0] = IS_CLIPPED; /* weak */
- /* screen_co_a[1]: intentionally dont set this so we get errors on misuse */
- }
-
- /* project tail location to screenspace */
- if (ED_view3d_project_float_object(vc->ar, pchan_eval->pose_tail, screen_co_b, clip_flag) == V3D_PROJ_RET_OK) {
- points_proj_tot++;
- }
- else {
- screen_co_b[0] = IS_CLIPPED; /* weak */
- /* screen_co_b[1]: intentionally dont set this so we get errors on misuse */
- }
-
- if (points_proj_tot) { /* at least one point's projection worked */
- func(userData, pchan, screen_co_a, screen_co_b);
- }
- }
- }
+ const Object *ob_eval = DEG_get_evaluated_object(vc->depsgraph, vc->obact);
+ const bArmature *arm_eval = ob_eval->data;
+ bPose *pose = vc->obact->pose;
+ bPoseChannel *pchan;
+
+ ED_view3d_check_mats_rv3d(vc->rv3d);
+
+ for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
+ if (PBONE_VISIBLE(arm_eval, pchan->bone)) {
+ bPoseChannel *pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, pchan->name);
+ float screen_co_a[2], screen_co_b[2];
+ int points_proj_tot = 0;
+
+ /* project head location to screenspace */
+ if (ED_view3d_project_float_object(vc->ar, pchan_eval->pose_head, screen_co_a, clip_flag) ==
+ V3D_PROJ_RET_OK) {
+ points_proj_tot++;
+ }
+ else {
+ screen_co_a[0] = IS_CLIPPED; /* weak */
+ /* screen_co_a[1]: intentionally dont set this so we get errors on misuse */
+ }
+
+ /* project tail location to screenspace */
+ if (ED_view3d_project_float_object(vc->ar, pchan_eval->pose_tail, screen_co_b, clip_flag) ==
+ V3D_PROJ_RET_OK) {
+ points_proj_tot++;
+ }
+ else {
+ screen_co_b[0] = IS_CLIPPED; /* weak */
+ /* screen_co_b[1]: intentionally dont set this so we get errors on misuse */
+ }
+
+ if (points_proj_tot) { /* at least one point's projection worked */
+ func(userData, pchan, screen_co_a, screen_co_b);
+ }
+ }
+ }
}
diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c
index 3efd0e32440..4e33005ebc0 100644
--- a/source/blender/editors/space_view3d/view3d_ops.c
+++ b/source/blender/editors/space_view3d/view3d_ops.c
@@ -21,11 +21,9 @@
* \ingroup spview3d
*/
-
#include <stdlib.h>
#include <math.h>
-
#include "DNA_collection_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -63,175 +61,177 @@
static int view3d_copybuffer_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
- char str[FILE_MAX];
- int num_copied = 0;
+ Main *bmain = CTX_data_main(C);
+ char str[FILE_MAX];
+ int num_copied = 0;
- BKE_copybuffer_begin(bmain);
+ BKE_copybuffer_begin(bmain);
- /* context, selection, could be generalized */
- CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
- {
- if ((ob->id.tag & LIB_TAG_DOIT) == 0) {
- BKE_copybuffer_tag_ID(&ob->id);
- num_copied++;
- }
- }
- CTX_DATA_END;
+ /* context, selection, could be generalized */
+ CTX_DATA_BEGIN (C, Object *, ob, selected_objects) {
+ if ((ob->id.tag & LIB_TAG_DOIT) == 0) {
+ BKE_copybuffer_tag_ID(&ob->id);
+ num_copied++;
+ }
+ }
+ CTX_DATA_END;
- BLI_make_file_string("/", str, BKE_tempdir_base(), "copybuffer.blend");
- BKE_copybuffer_save(bmain, str, op->reports);
+ BLI_make_file_string("/", str, BKE_tempdir_base(), "copybuffer.blend");
+ BKE_copybuffer_save(bmain, str, op->reports);
- BKE_reportf(op->reports, RPT_INFO, "Copied %d selected objects", num_copied);
+ BKE_reportf(op->reports, RPT_INFO, "Copied %d selected objects", num_copied);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static void VIEW3D_OT_copybuffer(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Copy Objects";
- ot->idname = "VIEW3D_OT_copybuffer";
- ot->description = "Selected objects are copied to the clipboard";
-
- /* api callbacks */
- ot->exec = view3d_copybuffer_exec;
- ot->poll = ED_operator_scene;
+ /* identifiers */
+ ot->name = "Copy Objects";
+ ot->idname = "VIEW3D_OT_copybuffer";
+ ot->description = "Selected objects are copied to the clipboard";
+
+ /* api callbacks */
+ ot->exec = view3d_copybuffer_exec;
+ ot->poll = ED_operator_scene;
}
static int view3d_pastebuffer_exec(bContext *C, wmOperator *op)
{
- char str[FILE_MAX];
- short flag = 0;
+ char str[FILE_MAX];
+ short flag = 0;
- if (RNA_boolean_get(op->ptr, "autoselect")) {
- flag |= FILE_AUTOSELECT;
- }
- if (RNA_boolean_get(op->ptr, "active_collection")) {
- flag |= FILE_ACTIVE_COLLECTION;
- }
+ if (RNA_boolean_get(op->ptr, "autoselect")) {
+ flag |= FILE_AUTOSELECT;
+ }
+ if (RNA_boolean_get(op->ptr, "active_collection")) {
+ flag |= FILE_ACTIVE_COLLECTION;
+ }
- BLI_make_file_string("/", str, BKE_tempdir_base(), "copybuffer.blend");
+ BLI_make_file_string("/", str, BKE_tempdir_base(), "copybuffer.blend");
- const int num_pasted = BKE_copybuffer_paste(C, str, flag, op->reports, FILTER_ID_OB);
- if (num_pasted == 0) {
- BKE_report(op->reports, RPT_INFO, "No objects to paste");
- return OPERATOR_CANCELLED;
- }
+ const int num_pasted = BKE_copybuffer_paste(C, str, flag, op->reports, FILTER_ID_OB);
+ if (num_pasted == 0) {
+ BKE_report(op->reports, RPT_INFO, "No objects to paste");
+ return OPERATOR_CANCELLED;
+ }
- WM_event_add_notifier(C, NC_WINDOW, NULL);
+ WM_event_add_notifier(C, NC_WINDOW, NULL);
- BKE_reportf(op->reports, RPT_INFO, "%d objects pasted", num_pasted);
+ BKE_reportf(op->reports, RPT_INFO, "%d objects pasted", num_pasted);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static void VIEW3D_OT_pastebuffer(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Paste Objects";
- ot->idname = "VIEW3D_OT_pastebuffer";
- ot->description = "Objects from the clipboard are pasted";
+ /* identifiers */
+ ot->name = "Paste Objects";
+ ot->idname = "VIEW3D_OT_pastebuffer";
+ ot->description = "Objects from the clipboard are pasted";
- /* api callbacks */
- ot->exec = view3d_pastebuffer_exec;
- ot->poll = ED_operator_scene_editable;
+ /* api callbacks */
+ ot->exec = view3d_pastebuffer_exec;
+ ot->poll = ED_operator_scene_editable;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- RNA_def_boolean(ot->srna, "autoselect", true, "Select", "Select pasted objects");
- RNA_def_boolean(ot->srna, "active_collection", true,
- "Active Collection", "Put pasted objects in the active collection");
+ RNA_def_boolean(ot->srna, "autoselect", true, "Select", "Select pasted objects");
+ RNA_def_boolean(ot->srna,
+ "active_collection",
+ true,
+ "Active Collection",
+ "Put pasted objects in the active collection");
}
/* ************************** registration **********************************/
void view3d_operatortypes(void)
{
- WM_operatortype_append(VIEW3D_OT_rotate);
- WM_operatortype_append(VIEW3D_OT_move);
- WM_operatortype_append(VIEW3D_OT_zoom);
- WM_operatortype_append(VIEW3D_OT_zoom_camera_1_to_1);
- WM_operatortype_append(VIEW3D_OT_dolly);
+ WM_operatortype_append(VIEW3D_OT_rotate);
+ WM_operatortype_append(VIEW3D_OT_move);
+ WM_operatortype_append(VIEW3D_OT_zoom);
+ WM_operatortype_append(VIEW3D_OT_zoom_camera_1_to_1);
+ WM_operatortype_append(VIEW3D_OT_dolly);
#ifdef WITH_INPUT_NDOF
- WM_operatortype_append(VIEW3D_OT_ndof_orbit_zoom);
- WM_operatortype_append(VIEW3D_OT_ndof_orbit);
- WM_operatortype_append(VIEW3D_OT_ndof_pan);
- WM_operatortype_append(VIEW3D_OT_ndof_all);
+ WM_operatortype_append(VIEW3D_OT_ndof_orbit_zoom);
+ WM_operatortype_append(VIEW3D_OT_ndof_orbit);
+ WM_operatortype_append(VIEW3D_OT_ndof_pan);
+ WM_operatortype_append(VIEW3D_OT_ndof_all);
#endif /* WITH_INPUT_NDOF */
- WM_operatortype_append(VIEW3D_OT_view_all);
- WM_operatortype_append(VIEW3D_OT_view_axis);
- WM_operatortype_append(VIEW3D_OT_view_camera);
- WM_operatortype_append(VIEW3D_OT_view_orbit);
- WM_operatortype_append(VIEW3D_OT_view_roll);
- WM_operatortype_append(VIEW3D_OT_view_pan);
- WM_operatortype_append(VIEW3D_OT_view_persportho);
- WM_operatortype_append(VIEW3D_OT_background_image_add);
- WM_operatortype_append(VIEW3D_OT_background_image_remove);
- WM_operatortype_append(VIEW3D_OT_view_selected);
- WM_operatortype_append(VIEW3D_OT_view_lock_clear);
- WM_operatortype_append(VIEW3D_OT_view_lock_to_active);
- WM_operatortype_append(VIEW3D_OT_view_center_cursor);
- WM_operatortype_append(VIEW3D_OT_view_center_pick);
- WM_operatortype_append(VIEW3D_OT_view_center_camera);
- WM_operatortype_append(VIEW3D_OT_view_center_lock);
- WM_operatortype_append(VIEW3D_OT_select);
- WM_operatortype_append(VIEW3D_OT_select_box);
- WM_operatortype_append(VIEW3D_OT_clip_border);
- WM_operatortype_append(VIEW3D_OT_select_circle);
- WM_operatortype_append(VIEW3D_OT_smoothview);
- WM_operatortype_append(VIEW3D_OT_render_border);
- WM_operatortype_append(VIEW3D_OT_clear_render_border);
- WM_operatortype_append(VIEW3D_OT_zoom_border);
- WM_operatortype_append(VIEW3D_OT_cursor3d);
- WM_operatortype_append(VIEW3D_OT_select_lasso);
- WM_operatortype_append(VIEW3D_OT_select_menu);
- WM_operatortype_append(VIEW3D_OT_camera_to_view);
- WM_operatortype_append(VIEW3D_OT_camera_to_view_selected);
- WM_operatortype_append(VIEW3D_OT_object_as_camera);
- WM_operatortype_append(VIEW3D_OT_localview);
- WM_operatortype_append(VIEW3D_OT_localview_remove_from);
- WM_operatortype_append(VIEW3D_OT_fly);
- WM_operatortype_append(VIEW3D_OT_walk);
- WM_operatortype_append(VIEW3D_OT_navigate);
- WM_operatortype_append(VIEW3D_OT_copybuffer);
- WM_operatortype_append(VIEW3D_OT_pastebuffer);
-
- WM_operatortype_append(VIEW3D_OT_properties);
- WM_operatortype_append(VIEW3D_OT_object_mode_pie_or_toggle);
- WM_operatortype_append(VIEW3D_OT_toolshelf);
-
- WM_operatortype_append(VIEW3D_OT_snap_selected_to_grid);
- WM_operatortype_append(VIEW3D_OT_snap_selected_to_cursor);
- WM_operatortype_append(VIEW3D_OT_snap_selected_to_active);
- WM_operatortype_append(VIEW3D_OT_snap_cursor_to_grid);
- WM_operatortype_append(VIEW3D_OT_snap_cursor_to_center);
- WM_operatortype_append(VIEW3D_OT_snap_cursor_to_selected);
- WM_operatortype_append(VIEW3D_OT_snap_cursor_to_active);
-
- WM_operatortype_append(VIEW3D_OT_toggle_shading);
- WM_operatortype_append(VIEW3D_OT_toggle_xray);
- WM_operatortype_append(VIEW3D_OT_toggle_matcap_flip);
-
- WM_operatortype_append(VIEW3D_OT_ruler_add);
- WM_operatortype_append(VIEW3D_OT_ruler_remove);
-
- transform_operatortypes();
+ WM_operatortype_append(VIEW3D_OT_view_all);
+ WM_operatortype_append(VIEW3D_OT_view_axis);
+ WM_operatortype_append(VIEW3D_OT_view_camera);
+ WM_operatortype_append(VIEW3D_OT_view_orbit);
+ WM_operatortype_append(VIEW3D_OT_view_roll);
+ WM_operatortype_append(VIEW3D_OT_view_pan);
+ WM_operatortype_append(VIEW3D_OT_view_persportho);
+ WM_operatortype_append(VIEW3D_OT_background_image_add);
+ WM_operatortype_append(VIEW3D_OT_background_image_remove);
+ WM_operatortype_append(VIEW3D_OT_view_selected);
+ WM_operatortype_append(VIEW3D_OT_view_lock_clear);
+ WM_operatortype_append(VIEW3D_OT_view_lock_to_active);
+ WM_operatortype_append(VIEW3D_OT_view_center_cursor);
+ WM_operatortype_append(VIEW3D_OT_view_center_pick);
+ WM_operatortype_append(VIEW3D_OT_view_center_camera);
+ WM_operatortype_append(VIEW3D_OT_view_center_lock);
+ WM_operatortype_append(VIEW3D_OT_select);
+ WM_operatortype_append(VIEW3D_OT_select_box);
+ WM_operatortype_append(VIEW3D_OT_clip_border);
+ WM_operatortype_append(VIEW3D_OT_select_circle);
+ WM_operatortype_append(VIEW3D_OT_smoothview);
+ WM_operatortype_append(VIEW3D_OT_render_border);
+ WM_operatortype_append(VIEW3D_OT_clear_render_border);
+ WM_operatortype_append(VIEW3D_OT_zoom_border);
+ WM_operatortype_append(VIEW3D_OT_cursor3d);
+ WM_operatortype_append(VIEW3D_OT_select_lasso);
+ WM_operatortype_append(VIEW3D_OT_select_menu);
+ WM_operatortype_append(VIEW3D_OT_camera_to_view);
+ WM_operatortype_append(VIEW3D_OT_camera_to_view_selected);
+ WM_operatortype_append(VIEW3D_OT_object_as_camera);
+ WM_operatortype_append(VIEW3D_OT_localview);
+ WM_operatortype_append(VIEW3D_OT_localview_remove_from);
+ WM_operatortype_append(VIEW3D_OT_fly);
+ WM_operatortype_append(VIEW3D_OT_walk);
+ WM_operatortype_append(VIEW3D_OT_navigate);
+ WM_operatortype_append(VIEW3D_OT_copybuffer);
+ WM_operatortype_append(VIEW3D_OT_pastebuffer);
+
+ WM_operatortype_append(VIEW3D_OT_properties);
+ WM_operatortype_append(VIEW3D_OT_object_mode_pie_or_toggle);
+ WM_operatortype_append(VIEW3D_OT_toolshelf);
+
+ WM_operatortype_append(VIEW3D_OT_snap_selected_to_grid);
+ WM_operatortype_append(VIEW3D_OT_snap_selected_to_cursor);
+ WM_operatortype_append(VIEW3D_OT_snap_selected_to_active);
+ WM_operatortype_append(VIEW3D_OT_snap_cursor_to_grid);
+ WM_operatortype_append(VIEW3D_OT_snap_cursor_to_center);
+ WM_operatortype_append(VIEW3D_OT_snap_cursor_to_selected);
+ WM_operatortype_append(VIEW3D_OT_snap_cursor_to_active);
+
+ WM_operatortype_append(VIEW3D_OT_toggle_shading);
+ WM_operatortype_append(VIEW3D_OT_toggle_xray);
+ WM_operatortype_append(VIEW3D_OT_toggle_matcap_flip);
+
+ WM_operatortype_append(VIEW3D_OT_ruler_add);
+ WM_operatortype_append(VIEW3D_OT_ruler_remove);
+
+ transform_operatortypes();
}
void view3d_keymap(wmKeyConfig *keyconf)
{
- WM_keymap_ensure(keyconf, "3D View Generic", SPACE_VIEW3D, 0);
+ WM_keymap_ensure(keyconf, "3D View Generic", SPACE_VIEW3D, 0);
- /* only for region 3D window */
- WM_keymap_ensure(keyconf, "3D View", SPACE_VIEW3D, 0);
+ /* only for region 3D window */
+ WM_keymap_ensure(keyconf, "3D View", SPACE_VIEW3D, 0);
- fly_modal_keymap(keyconf);
- walk_modal_keymap(keyconf);
- viewrotate_modal_keymap(keyconf);
- viewmove_modal_keymap(keyconf);
- viewzoom_modal_keymap(keyconf);
- viewdolly_modal_keymap(keyconf);
+ fly_modal_keymap(keyconf);
+ walk_modal_keymap(keyconf);
+ viewrotate_modal_keymap(keyconf);
+ viewmove_modal_keymap(keyconf);
+ viewzoom_modal_keymap(keyconf);
+ viewdolly_modal_keymap(keyconf);
}
diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c
index e5f8ac147de..6932e94e78d 100644
--- a/source/blender/editors/space_view3d/view3d_project.c
+++ b/source/blender/editors/space_view3d/view3d_project.c
@@ -27,7 +27,7 @@
#include "DNA_scene_types.h"
#include "DNA_view3d_types.h"
-#include "BLI_sys_types.h" /* int64_t */
+#include "BLI_sys_types.h" /* int64_t */
#include "BLI_math_vector.h"
@@ -36,7 +36,7 @@
#include "GPU_matrix.h"
-#include "ED_view3d.h" /* own include */
+#include "ED_view3d.h" /* own include */
#define BL_NEAR_CLIP 0.001
#define BL_ZERO_CLIP 0.001
@@ -47,238 +47,268 @@
/**
* \note use #ED_view3d_ob_project_mat_get to get the projection matrix
*/
-void ED_view3d_project_float_v2_m4(const ARegion *ar, const float co[3], float r_co[2], float mat[4][4])
+void ED_view3d_project_float_v2_m4(const ARegion *ar,
+ const float co[3],
+ float r_co[2],
+ float mat[4][4])
{
- float vec4[4];
+ float vec4[4];
- copy_v3_v3(vec4, co);
- vec4[3] = 1.0;
- /* r_co[0] = IS_CLIPPED; */ /* always overwritten */
+ copy_v3_v3(vec4, co);
+ vec4[3] = 1.0;
+ /* r_co[0] = IS_CLIPPED; */ /* always overwritten */
- mul_m4_v4(mat, vec4);
+ mul_m4_v4(mat, vec4);
- if (vec4[3] > FLT_EPSILON) {
- r_co[0] = (float)(ar->winx / 2.0f) + (ar->winx / 2.0f) * vec4[0] / vec4[3];
- r_co[1] = (float)(ar->winy / 2.0f) + (ar->winy / 2.0f) * vec4[1] / vec4[3];
- }
- else {
- zero_v2(r_co);
- }
+ if (vec4[3] > FLT_EPSILON) {
+ r_co[0] = (float)(ar->winx / 2.0f) + (ar->winx / 2.0f) * vec4[0] / vec4[3];
+ r_co[1] = (float)(ar->winy / 2.0f) + (ar->winy / 2.0f) * vec4[1] / vec4[3];
+ }
+ else {
+ zero_v2(r_co);
+ }
}
/**
* \note use #ED_view3d_ob_project_mat_get to get projecting mat
*/
-void ED_view3d_project_float_v3_m4(const 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];
+ float vec4[4];
- copy_v3_v3(vec4, vec);
- vec4[3] = 1.0;
- /* r_co[0] = IS_CLIPPED; */ /* always overwritten */
+ copy_v3_v3(vec4, vec);
+ vec4[3] = 1.0;
+ /* r_co[0] = IS_CLIPPED; */ /* always overwritten */
- mul_m4_v4(mat, vec4);
+ mul_m4_v4(mat, vec4);
- if (vec4[3] > FLT_EPSILON) {
- r_co[0] = (float)(ar->winx / 2.0f) + (ar->winx / 2.0f) * vec4[0] / vec4[3];
- r_co[1] = (float)(ar->winy / 2.0f) + (ar->winy / 2.0f) * vec4[1] / vec4[3];
- r_co[2] = vec4[2] / vec4[3];
- }
- else {
- zero_v3(r_co);
- }
+ if (vec4[3] > FLT_EPSILON) {
+ r_co[0] = (float)(ar->winx / 2.0f) + (ar->winx / 2.0f) * vec4[0] / vec4[3];
+ r_co[1] = (float)(ar->winy / 2.0f) + (ar->winy / 2.0f) * vec4[1] / vec4[3];
+ r_co[2] = vec4[2] / vec4[3];
+ }
+ else {
+ zero_v3(r_co);
+ }
}
-
/* Clipping Projection Functions
* ***************************** */
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);
+ eV3DProjStatus ret = ED_view3d_project_short_global(
+ ar, base->object->obmat[3], &base->sx, V3D_PROJ_TEST_CLIP_DEFAULT);
- if (ret != V3D_PROJ_RET_OK) {
- base->sx = IS_CLIPPED;
- base->sy = 0;
- }
+ if (ret != V3D_PROJ_RET_OK) {
+ base->sx = IS_CLIPPED;
+ base->sy = 0;
+ }
- return ret;
+ return ret;
}
/* perspmat is typically...
* - 'rv3d->perspmat', is_local == false
* - 'rv3d->persmatob', is_local == true
*/
-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];
-
- /* check for bad flags */
- BLI_assert((flag & V3D_PROJ_TEST_ALL) == flag);
-
- if (flag & V3D_PROJ_TEST_CLIP_BB) {
- RegionView3D *rv3d = ar->regiondata;
- if (rv3d->rflag & RV3D_CLIPPING) {
- if (ED_view3d_clipping_test(rv3d, co, is_local)) {
- return V3D_PROJ_RET_CLIP_BB;
- }
- }
- }
-
- copy_v3_v3(vec4, co);
- vec4[3] = 1.0;
- mul_m4_v4(perspmat, vec4);
-
-
-
- if (((flag & V3D_PROJ_TEST_CLIP_ZERO) == 0) || (fabsf(vec4[3]) > (float)BL_ZERO_CLIP)) {
- if (((flag & V3D_PROJ_TEST_CLIP_NEAR) == 0) || (vec4[3] > (float)BL_NEAR_CLIP)) {
- const float scalar = (vec4[3] != 0.0f) ? (1.0f / vec4[3]) : 0.0f;
- const float fx = ((float)ar->winx / 2.0f) * (1.0f + (vec4[0] * scalar));
- if (((flag & V3D_PROJ_TEST_CLIP_WIN) == 0) || (fx > 0.0f && fx < (float)ar->winx)) {
- const float fy = ((float)ar->winy / 2.0f) * (1.0f + (vec4[1] * scalar));
- if (((flag & V3D_PROJ_TEST_CLIP_WIN) == 0) || (fy > 0.0f && fy < (float)ar->winy)) {
- r_co[0] = fx;
- r_co[1] = fy;
-
- /* check if the point is behind the view, we need to flip in this case */
- if (UNLIKELY((flag & V3D_PROJ_TEST_CLIP_NEAR) == 0) && (vec4[3] < 0.0f)) {
- negate_v2(r_co);
- }
- }
- else {
- return V3D_PROJ_RET_CLIP_WIN;
- }
- }
- else {
- return V3D_PROJ_RET_CLIP_WIN;
- }
- }
- else {
- return V3D_PROJ_RET_CLIP_NEAR;
- }
- }
- else {
- return V3D_PROJ_RET_CLIP_ZERO;
- }
-
- return V3D_PROJ_RET_OK;
-}
-
-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];
- eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag);
- if (ret == V3D_PROJ_RET_OK) {
- if ((tvec[0] > -32700.0f && tvec[0] < 32700.0f) &&
- (tvec[1] > -32700.0f && tvec[1] < 32700.0f))
- {
- r_co[0] = (short)floorf(tvec[0]);
- r_co[1] = (short)floorf(tvec[1]);
- }
- else {
- ret = V3D_PROJ_RET_OVERFLOW;
- }
- }
- return ret;
-}
-
-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];
- eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag);
- if (ret == V3D_PROJ_RET_OK) {
- if ((tvec[0] > -2140000000.0f && tvec[0] < 2140000000.0f) &&
- (tvec[1] > -2140000000.0f && tvec[1] < 2140000000.0f))
- {
- r_co[0] = (int)floorf(tvec[0]);
- r_co[1] = (int)floorf(tvec[1]);
- }
- else {
- ret = V3D_PROJ_RET_OVERFLOW;
- }
- }
- return ret;
-}
-
-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];
- eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag);
- if (ret == V3D_PROJ_RET_OK) {
- if (isfinite(tvec[0]) &&
- isfinite(tvec[1]))
- {
- copy_v2_v2(r_co, tvec);
- }
- else {
- ret = V3D_PROJ_RET_OVERFLOW;
- }
- }
- return ret;
+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];
+
+ /* check for bad flags */
+ BLI_assert((flag & V3D_PROJ_TEST_ALL) == flag);
+
+ if (flag & V3D_PROJ_TEST_CLIP_BB) {
+ RegionView3D *rv3d = ar->regiondata;
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ if (ED_view3d_clipping_test(rv3d, co, is_local)) {
+ return V3D_PROJ_RET_CLIP_BB;
+ }
+ }
+ }
+
+ copy_v3_v3(vec4, co);
+ vec4[3] = 1.0;
+ mul_m4_v4(perspmat, vec4);
+
+ if (((flag & V3D_PROJ_TEST_CLIP_ZERO) == 0) || (fabsf(vec4[3]) > (float)BL_ZERO_CLIP)) {
+ if (((flag & V3D_PROJ_TEST_CLIP_NEAR) == 0) || (vec4[3] > (float)BL_NEAR_CLIP)) {
+ const float scalar = (vec4[3] != 0.0f) ? (1.0f / vec4[3]) : 0.0f;
+ const float fx = ((float)ar->winx / 2.0f) * (1.0f + (vec4[0] * scalar));
+ if (((flag & V3D_PROJ_TEST_CLIP_WIN) == 0) || (fx > 0.0f && fx < (float)ar->winx)) {
+ const float fy = ((float)ar->winy / 2.0f) * (1.0f + (vec4[1] * scalar));
+ if (((flag & V3D_PROJ_TEST_CLIP_WIN) == 0) || (fy > 0.0f && fy < (float)ar->winy)) {
+ r_co[0] = fx;
+ r_co[1] = fy;
+
+ /* check if the point is behind the view, we need to flip in this case */
+ if (UNLIKELY((flag & V3D_PROJ_TEST_CLIP_NEAR) == 0) && (vec4[3] < 0.0f)) {
+ negate_v2(r_co);
+ }
+ }
+ else {
+ return V3D_PROJ_RET_CLIP_WIN;
+ }
+ }
+ else {
+ return V3D_PROJ_RET_CLIP_WIN;
+ }
+ }
+ else {
+ return V3D_PROJ_RET_CLIP_NEAR;
+ }
+ }
+ else {
+ return V3D_PROJ_RET_CLIP_ZERO;
+ }
+
+ return V3D_PROJ_RET_OK;
+}
+
+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];
+ eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag);
+ if (ret == V3D_PROJ_RET_OK) {
+ if ((tvec[0] > -32700.0f && tvec[0] < 32700.0f) &&
+ (tvec[1] > -32700.0f && tvec[1] < 32700.0f)) {
+ r_co[0] = (short)floorf(tvec[0]);
+ r_co[1] = (short)floorf(tvec[1]);
+ }
+ else {
+ ret = V3D_PROJ_RET_OVERFLOW;
+ }
+ }
+ return ret;
+}
+
+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];
+ eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag);
+ if (ret == V3D_PROJ_RET_OK) {
+ if ((tvec[0] > -2140000000.0f && tvec[0] < 2140000000.0f) &&
+ (tvec[1] > -2140000000.0f && tvec[1] < 2140000000.0f)) {
+ r_co[0] = (int)floorf(tvec[0]);
+ r_co[1] = (int)floorf(tvec[1]);
+ }
+ else {
+ ret = V3D_PROJ_RET_OVERFLOW;
+ }
+ }
+ return ret;
+}
+
+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];
+ eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag);
+ if (ret == V3D_PROJ_RET_OK) {
+ if (isfinite(tvec[0]) && isfinite(tvec[1])) {
+ copy_v2_v2(r_co, tvec);
+ }
+ else {
+ ret = V3D_PROJ_RET_OVERFLOW;
+ }
+ }
+ return ret;
}
/* --- short --- */
-eV3DProjStatus ED_view3d_project_short_global(const 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);
+ 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(const 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;
- ED_view3d_check_mats_rv3d(rv3d);
- return ED_view3d_project_short_ex(ar, rv3d->persmatob, true, co, r_co, flag);
+ RegionView3D *rv3d = ar->regiondata;
+ ED_view3d_check_mats_rv3d(rv3d);
+ return ED_view3d_project_short_ex(ar, rv3d->persmatob, true, co, r_co, flag);
}
/* --- int --- */
-eV3DProjStatus ED_view3d_project_int_global(const 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);
+ 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(const 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;
- ED_view3d_check_mats_rv3d(rv3d);
- return ED_view3d_project_int_ex(ar, rv3d->persmatob, true, co, r_co, flag);
+ RegionView3D *rv3d = ar->regiondata;
+ ED_view3d_check_mats_rv3d(rv3d);
+ return ED_view3d_project_int_ex(ar, rv3d->persmatob, true, co, r_co, flag);
}
/* --- float --- */
-eV3DProjStatus ED_view3d_project_float_global(const 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);
+ 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(const 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;
- ED_view3d_check_mats_rv3d(rv3d);
- return ED_view3d_project_float_ex(ar, rv3d->persmatob, true, co, r_co, flag);
+ RegionView3D *rv3d = ar->regiondata;
+ ED_view3d_check_mats_rv3d(rv3d);
+ return ED_view3d_project_float_ex(ar, rv3d->persmatob, true, co, r_co, flag);
}
-
-
/* More Generic Window/Ray/Vector projection functions
* *************************************************** */
float ED_view3d_pixel_size(const RegionView3D *rv3d, const float co[3])
{
- return mul_project_m4_v3_zfac((float(*)[4])rv3d->persmat, co) * rv3d->pixsize * U.pixelsize;
+ return mul_project_m4_v3_zfac((float(*)[4])rv3d->persmat, co) * rv3d->pixsize * U.pixelsize;
}
float ED_view3d_pixel_size_no_ui_scale(const RegionView3D *rv3d, const float co[3])
{
- return mul_project_m4_v3_zfac((float(*)[4])rv3d->persmat, co) * rv3d->pixsize;
+ return mul_project_m4_v3_zfac((float(*)[4])rv3d->persmat, co) * rv3d->pixsize;
}
/**
@@ -286,70 +316,72 @@ float ED_view3d_pixel_size_no_ui_scale(const RegionView3D *rv3d, const float co[
*/
float ED_view3d_calc_zfac(const RegionView3D *rv3d, const float co[3], bool *r_flip)
{
- 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 (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. */
- if (zfac < 0.0f) {
- zfac = -zfac;
- }
-
- return zfac;
-}
-
-static void view3d_win_to_ray_segment(
- struct Depsgraph *depsgraph,
- const ARegion *ar, const View3D *v3d, const float mval[2],
- float r_ray_co[3], float r_ray_dir[3], float r_ray_start[3], float r_ray_end[3])
-{
- RegionView3D *rv3d = ar->regiondata;
- float _ray_co[3], _ray_dir[3], start_offset, end_offset;
-
- if (!r_ray_co) {
- r_ray_co = _ray_co;
- }
- if (!r_ray_dir) {
- r_ray_dir = _ray_dir;
- }
-
- ED_view3d_win_to_origin(ar, mval, r_ray_co);
- ED_view3d_win_to_vector(ar, mval, r_ray_dir);
-
- if ((rv3d->is_persp == false) && (rv3d->persp != RV3D_CAMOB)) {
- end_offset = v3d->clip_end / 2.0f;
- start_offset = -end_offset;
- }
- else {
- ED_view3d_clip_range_get(depsgraph, v3d, rv3d, &start_offset, &end_offset, false);
- }
-
- if (r_ray_start) {
- madd_v3_v3v3fl(r_ray_start, r_ray_co, r_ray_dir, start_offset);
- }
- if (r_ray_end) {
- madd_v3_v3v3fl(r_ray_end, r_ray_co, r_ray_dir, end_offset);
- }
+ 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 (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. */
+ if (zfac < 0.0f) {
+ zfac = -zfac;
+ }
+
+ return zfac;
+}
+
+static void view3d_win_to_ray_segment(struct Depsgraph *depsgraph,
+ const ARegion *ar,
+ const View3D *v3d,
+ const float mval[2],
+ float r_ray_co[3],
+ float r_ray_dir[3],
+ float r_ray_start[3],
+ float r_ray_end[3])
+{
+ RegionView3D *rv3d = ar->regiondata;
+ float _ray_co[3], _ray_dir[3], start_offset, end_offset;
+
+ if (!r_ray_co) {
+ r_ray_co = _ray_co;
+ }
+ if (!r_ray_dir) {
+ r_ray_dir = _ray_dir;
+ }
+
+ ED_view3d_win_to_origin(ar, mval, r_ray_co);
+ ED_view3d_win_to_vector(ar, mval, r_ray_dir);
+
+ if ((rv3d->is_persp == false) && (rv3d->persp != RV3D_CAMOB)) {
+ end_offset = v3d->clip_end / 2.0f;
+ start_offset = -end_offset;
+ }
+ else {
+ ED_view3d_clip_range_get(depsgraph, v3d, rv3d, &start_offset, &end_offset, false);
+ }
+
+ if (r_ray_start) {
+ madd_v3_v3v3fl(r_ray_start, r_ray_co, r_ray_dir, start_offset);
+ }
+ if (r_ray_end) {
+ madd_v3_v3v3fl(r_ray_end, r_ray_co, r_ray_dir, end_offset);
+ }
}
bool ED_view3d_clip_segment(const RegionView3D *rv3d, float ray_start[3], float ray_end[3])
{
- if ((rv3d->rflag & RV3D_CLIPPING) &&
- (clip_segment_v3_plane_n(ray_start, ray_end, rv3d->clip, 6,
- ray_start, ray_end) == false))
- {
- return false;
- }
- return true;
+ if ((rv3d->rflag & RV3D_CLIPPING) &&
+ (clip_segment_v3_plane_n(ray_start, ray_end, rv3d->clip, 6, ray_start, ray_end) == false)) {
+ return false;
+ }
+ return true;
}
/**
@@ -368,21 +400,26 @@ bool ED_view3d_clip_segment(const RegionView3D *rv3d, float ray_start[3], float
* \param do_clip_planes: Optionally clip the start of the ray by the view clipping planes.
* \return success, false if the ray is totally clipped.
*/
-bool ED_view3d_win_to_ray_clipped_ex(
- struct Depsgraph *depsgraph,
- const ARegion *ar, const View3D *v3d, const float mval[2],
- float r_ray_co[3], float r_ray_normal[3], float r_ray_start[3], bool do_clip_planes)
+bool ED_view3d_win_to_ray_clipped_ex(struct Depsgraph *depsgraph,
+ const ARegion *ar,
+ const View3D *v3d,
+ const float mval[2],
+ float r_ray_co[3],
+ float r_ray_normal[3],
+ float r_ray_start[3],
+ bool do_clip_planes)
{
- float ray_end[3];
+ float ray_end[3];
- view3d_win_to_ray_segment(depsgraph, ar, v3d, mval, r_ray_co, r_ray_normal, r_ray_start, ray_end);
+ view3d_win_to_ray_segment(
+ depsgraph, ar, v3d, mval, r_ray_co, r_ray_normal, r_ray_start, ray_end);
- /* bounds clipping */
- if (do_clip_planes) {
- return ED_view3d_clip_segment(ar->regiondata, r_ray_start, ray_end);
- }
+ /* bounds clipping */
+ if (do_clip_planes) {
+ return ED_view3d_clip_segment(ar->regiondata, r_ray_start, ray_end);
+ }
- return true;
+ return true;
}
/**
@@ -398,12 +435,16 @@ bool ED_view3d_win_to_ray_clipped_ex(
* \param do_clip_planes: Optionally clip the start of the ray by the view clipping planes.
* \return success, false if the ray is totally clipped.
*/
-bool ED_view3d_win_to_ray_clipped(
- struct Depsgraph *depsgraph,
- const ARegion *ar, const View3D *v3d, const float mval[2],
- float r_ray_start[3], float r_ray_normal[3], const bool do_clip_planes)
+bool ED_view3d_win_to_ray_clipped(struct Depsgraph *depsgraph,
+ const ARegion *ar,
+ const View3D *v3d,
+ const float mval[2],
+ float r_ray_start[3],
+ float r_ray_normal[3],
+ const bool do_clip_planes)
{
- return ED_view3d_win_to_ray_clipped_ex(depsgraph, ar, v3d, mval, NULL, r_ray_normal, r_ray_start, do_clip_planes);
+ return ED_view3d_win_to_ray_clipped_ex(
+ depsgraph, ar, v3d, mval, NULL, r_ray_normal, r_ray_start, do_clip_planes);
}
/**
@@ -416,12 +457,13 @@ bool ED_view3d_win_to_ray_clipped(
*
* \note Ignores view near/far clipping, to take this into account use #ED_view3d_win_to_ray_clipped.
*/
-void ED_view3d_win_to_ray(
- const ARegion *ar, const float mval[2],
- float r_ray_start[3], float r_ray_normal[3])
+void ED_view3d_win_to_ray(const ARegion *ar,
+ const float mval[2],
+ float r_ray_start[3],
+ float r_ray_normal[3])
{
- ED_view3d_win_to_origin(ar, mval, r_ray_start);
- ED_view3d_win_to_vector(ar, mval, r_ray_normal);
+ ED_view3d_win_to_origin(ar, mval, r_ray_start);
+ ED_view3d_win_to_vector(ar, mval, r_ray_normal);
}
/**
@@ -433,57 +475,57 @@ void ED_view3d_win_to_ray(
*/
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];
+ if (rv3d->is_persp) {
+ float p1[4], p2[4];
- copy_v3_v3(p1, coord);
- p1[3] = 1.0f;
- copy_v3_v3(p2, p1);
- p2[3] = 1.0f;
- mul_m4_v4((float (*)[4])rv3d->viewmat, p2);
+ copy_v3_v3(p1, coord);
+ p1[3] = 1.0f;
+ copy_v3_v3(p2, p1);
+ p2[3] = 1.0f;
+ mul_m4_v4((float(*)[4])rv3d->viewmat, p2);
- mul_v3_fl(p2, 2.0f);
+ mul_v3_fl(p2, 2.0f);
- mul_m4_v4((float (*)[4])rv3d->viewinv, p2);
+ mul_m4_v4((float(*)[4])rv3d->viewinv, p2);
- sub_v3_v3v3(vec, p1, p2);
- }
- else {
- copy_v3_v3(vec, rv3d->viewinv[2]);
- }
- normalize_v3(vec);
+ sub_v3_v3v3(vec, p1, p2);
+ }
+ else {
+ copy_v3_v3(vec, rv3d->viewinv[2]);
+ }
+ normalize_v3(vec);
}
/* very similar to ED_view3d_win_to_3d() but has no advantage, de-duplicating */
#if 0
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;
-
- 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])};
- 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;
- }
- else {
- /* fallback to the view center */
- if (do_fallback) {
- negate_v3_v3(fp, rv3d->ofs);
- return view3d_get_view_aligned_coordinate(ar, fp, mval, false);
- }
- else {
- return false;
- }
- }
+ RegionView3D *rv3d = ar->regiondata;
+ float dvec[3];
+ int mval_cpy[2];
+ eV3DProjStatus ret;
+
+ 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])};
+ 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;
+ }
+ else {
+ /* fallback to the view center */
+ if (do_fallback) {
+ negate_v3_v3(fp, rv3d->ofs);
+ return view3d_get_view_aligned_coordinate(ar, fp, mval, false);
+ }
+ else {
+ return false;
+ }
+ }
}
#endif
@@ -494,90 +536,93 @@ bool view3d_get_view_aligned_coordinate(ARegion *ar, float fp[3], const int mval
* \param mval: The area relative location (such as event->mval converted to floats).
* \param r_out: The resulting world-space location.
*/
-void ED_view3d_win_to_3d(
- const View3D *v3d, const ARegion *ar,
- const float depth_pt[3], const float mval[2],
- float r_out[3])
-{
- RegionView3D *rv3d = ar->regiondata;
-
- float ray_origin[3];
- float ray_direction[3];
- float lambda;
-
- if (rv3d->is_persp) {
- float plane[4];
-
- copy_v3_v3(ray_origin, rv3d->viewinv[3]);
- ED_view3d_win_to_vector(ar, mval, ray_direction);
-
- /* note, we could use isect_line_plane_v3() however we want the intersection to be infront of the
- * view no matter what, so apply the unsigned factor instead */
- plane_from_point_normal_v3(plane, depth_pt, rv3d->viewinv[2]);
-
- isect_ray_plane_v3(ray_origin, ray_direction, plane, &lambda, false);
- lambda = fabsf(lambda);
- }
- else {
- float dx = (2.0f * mval[0] / (float)ar->winx) - 1.0f;
- float dy = (2.0f * mval[1] / (float)ar->winy) - 1.0f;
-
- if (rv3d->persp == RV3D_CAMOB) {
- /* ortho camera needs offset applied */
- const Camera *cam = v3d->camera->data;
- const int sensor_fit = BKE_camera_sensor_fit(cam->sensor_fit, ar->winx, ar->winy);
- const float zoomfac = BKE_screen_view3d_zoom_to_fac(rv3d->camzoom) * 4.0f;
- const float aspx = ar->winx / (float)ar->winy;
- const float aspy = ar->winy / (float)ar->winx;
- const float shiftx = cam->shiftx * 0.5f * (sensor_fit == CAMERA_SENSOR_FIT_HOR ? 1.0f : aspy);
- const float shifty = cam->shifty * 0.5f * (sensor_fit == CAMERA_SENSOR_FIT_HOR ? aspx : 1.0f);
-
- dx += (rv3d->camdx + shiftx) * zoomfac;
- dy += (rv3d->camdy + shifty) * zoomfac;
- }
- ray_origin[0] = (rv3d->persinv[0][0] * dx) + (rv3d->persinv[1][0] * dy) + rv3d->viewinv[3][0];
- ray_origin[1] = (rv3d->persinv[0][1] * dx) + (rv3d->persinv[1][1] * dy) + rv3d->viewinv[3][1];
- ray_origin[2] = (rv3d->persinv[0][2] * dx) + (rv3d->persinv[1][2] * dy) + rv3d->viewinv[3][2];
-
- copy_v3_v3(ray_direction, rv3d->viewinv[2]);
- lambda = ray_point_factor_v3(depth_pt, ray_origin, ray_direction);
- }
-
- madd_v3_v3v3fl(r_out, ray_origin, ray_direction, lambda);
-}
-
-void ED_view3d_win_to_3d_int(
- const View3D *v3d, const ARegion *ar,
- const float depth_pt[3], const int mval[2],
- float r_out[3])
-{
- const float mval_fl[2] = {mval[0], mval[1]};
- ED_view3d_win_to_3d(v3d, ar, depth_pt, mval_fl, r_out);
-}
-
-bool ED_view3d_win_to_3d_on_plane(
- const ARegion *ar,
- const float plane[4], const float mval[2], const bool do_clip,
- float r_out[3])
-{
- float ray_co[3], ray_no[3];
- ED_view3d_win_to_origin(ar, mval, ray_co);
- ED_view3d_win_to_vector(ar, mval, ray_no);
- float lambda;
- if (isect_ray_plane_v3(ray_co, ray_no, plane, &lambda, do_clip)) {
- madd_v3_v3v3fl(r_out, ray_co, ray_no, lambda);
- return true;
- }
- return false;
+void ED_view3d_win_to_3d(const View3D *v3d,
+ const ARegion *ar,
+ const float depth_pt[3],
+ const float mval[2],
+ float r_out[3])
+{
+ RegionView3D *rv3d = ar->regiondata;
+
+ float ray_origin[3];
+ float ray_direction[3];
+ float lambda;
+
+ if (rv3d->is_persp) {
+ float plane[4];
+
+ copy_v3_v3(ray_origin, rv3d->viewinv[3]);
+ ED_view3d_win_to_vector(ar, mval, ray_direction);
+
+ /* note, we could use isect_line_plane_v3() however we want the intersection to be infront of the
+ * view no matter what, so apply the unsigned factor instead */
+ plane_from_point_normal_v3(plane, depth_pt, rv3d->viewinv[2]);
+
+ isect_ray_plane_v3(ray_origin, ray_direction, plane, &lambda, false);
+ lambda = fabsf(lambda);
+ }
+ else {
+ float dx = (2.0f * mval[0] / (float)ar->winx) - 1.0f;
+ float dy = (2.0f * mval[1] / (float)ar->winy) - 1.0f;
+
+ if (rv3d->persp == RV3D_CAMOB) {
+ /* ortho camera needs offset applied */
+ const Camera *cam = v3d->camera->data;
+ const int sensor_fit = BKE_camera_sensor_fit(cam->sensor_fit, ar->winx, ar->winy);
+ const float zoomfac = BKE_screen_view3d_zoom_to_fac(rv3d->camzoom) * 4.0f;
+ const float aspx = ar->winx / (float)ar->winy;
+ const float aspy = ar->winy / (float)ar->winx;
+ const float shiftx = cam->shiftx * 0.5f *
+ (sensor_fit == CAMERA_SENSOR_FIT_HOR ? 1.0f : aspy);
+ const float shifty = cam->shifty * 0.5f *
+ (sensor_fit == CAMERA_SENSOR_FIT_HOR ? aspx : 1.0f);
+
+ dx += (rv3d->camdx + shiftx) * zoomfac;
+ dy += (rv3d->camdy + shifty) * zoomfac;
+ }
+ ray_origin[0] = (rv3d->persinv[0][0] * dx) + (rv3d->persinv[1][0] * dy) + rv3d->viewinv[3][0];
+ ray_origin[1] = (rv3d->persinv[0][1] * dx) + (rv3d->persinv[1][1] * dy) + rv3d->viewinv[3][1];
+ ray_origin[2] = (rv3d->persinv[0][2] * dx) + (rv3d->persinv[1][2] * dy) + rv3d->viewinv[3][2];
+
+ copy_v3_v3(ray_direction, rv3d->viewinv[2]);
+ lambda = ray_point_factor_v3(depth_pt, ray_origin, ray_direction);
+ }
+
+ madd_v3_v3v3fl(r_out, ray_origin, ray_direction, lambda);
+}
+
+void ED_view3d_win_to_3d_int(const View3D *v3d,
+ const ARegion *ar,
+ const float depth_pt[3],
+ const int mval[2],
+ float r_out[3])
+{
+ const float mval_fl[2] = {mval[0], mval[1]};
+ ED_view3d_win_to_3d(v3d, ar, depth_pt, mval_fl, r_out);
+}
+
+bool ED_view3d_win_to_3d_on_plane(const ARegion *ar,
+ const float plane[4],
+ const float mval[2],
+ const bool do_clip,
+ float r_out[3])
+{
+ float ray_co[3], ray_no[3];
+ ED_view3d_win_to_origin(ar, mval, ray_co);
+ ED_view3d_win_to_vector(ar, mval, ray_no);
+ float lambda;
+ if (isect_ray_plane_v3(ray_co, ray_no, plane, &lambda, do_clip)) {
+ madd_v3_v3v3fl(r_out, ray_co, ray_no, lambda);
+ return true;
+ }
+ return false;
}
bool ED_view3d_win_to_3d_on_plane_int(
- const ARegion *ar,
- const float plane[4], const int mval[2], const bool do_clip,
- float r_out[3])
+ const ARegion *ar, const float plane[4], const int mval[2], const bool do_clip, float r_out[3])
{
- const float mval_fl[2] = {mval[0], mval[1]};
- return ED_view3d_win_to_3d_on_plane(ar, plane, mval_fl, do_clip, r_out);
+ const float mval_fl[2] = {mval[0], mval[1]};
+ return ED_view3d_win_to_3d_on_plane(ar, plane, mval_fl, do_clip, r_out);
}
/**
@@ -590,15 +635,15 @@ bool ED_view3d_win_to_3d_on_plane_int(
*/
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;
+ RegionView3D *rv3d = ar->regiondata;
+ float dx, dy;
- dx = 2.0f * mval[0] * zfac / ar->winx;
- dy = 2.0f * mval[1] * 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);
- out[2] = (rv3d->persinv[0][2] * dx + rv3d->persinv[1][2] * dy);
+ out[0] = (rv3d->persinv[0][0] * dx + rv3d->persinv[1][0] * dy);
+ out[1] = (rv3d->persinv[0][1] * dx + rv3d->persinv[1][1] * dy);
+ out[2] = (rv3d->persinv[0][2] * dx + rv3d->persinv[1][2] * dy);
}
/**
@@ -613,23 +658,23 @@ void ED_view3d_win_to_delta(const ARegion *ar, const float mval[2], float out[3]
*/
void ED_view3d_win_to_origin(const ARegion *ar, const float mval[2], float out[3])
{
- RegionView3D *rv3d = ar->regiondata;
- if (rv3d->is_persp) {
- copy_v3_v3(out, rv3d->viewinv[3]);
- }
- else {
- out[0] = 2.0f * mval[0] / ar->winx - 1.0f;
- out[1] = 2.0f * mval[1] / ar->winy - 1.0f;
+ RegionView3D *rv3d = ar->regiondata;
+ if (rv3d->is_persp) {
+ copy_v3_v3(out, rv3d->viewinv[3]);
+ }
+ else {
+ out[0] = 2.0f * mval[0] / ar->winx - 1.0f;
+ out[1] = 2.0f * mval[1] / ar->winy - 1.0f;
- if (rv3d->persp == RV3D_CAMOB) {
- out[2] = -1.0f;
- }
- else {
- out[2] = 0.0f;
- }
+ if (rv3d->persp == RV3D_CAMOB) {
+ out[2] = -1.0f;
+ }
+ else {
+ out[2] = 0.0f;
+ }
- mul_project_m4_v3(rv3d->persinv, out);
- }
+ mul_project_m4_v3(rv3d->persinv, out);
+ }
}
/**
@@ -647,19 +692,19 @@ void ED_view3d_win_to_origin(const 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;
+ RegionView3D *rv3d = ar->regiondata;
- if (rv3d->is_persp) {
- out[0] = 2.0f * (mval[0] / ar->winx) - 1.0f;
- out[1] = 2.0f * (mval[1] / ar->winy) - 1.0f;
- out[2] = -0.5f;
- mul_project_m4_v3(rv3d->persinv, out);
- sub_v3_v3(out, rv3d->viewinv[3]);
- }
- else {
- negate_v3_v3(out, rv3d->viewinv[2]);
- }
- normalize_v3(out);
+ if (rv3d->is_persp) {
+ out[0] = 2.0f * (mval[0] / ar->winx) - 1.0f;
+ out[1] = 2.0f * (mval[1] / ar->winy) - 1.0f;
+ out[2] = -0.5f;
+ mul_project_m4_v3(rv3d->persinv, out);
+ sub_v3_v3(out, rv3d->viewinv[3]);
+ }
+ else {
+ negate_v3_v3(out, rv3d->viewinv[2]);
+ }
+ normalize_v3(out);
}
/**
@@ -676,19 +721,22 @@ void ED_view3d_win_to_vector(const ARegion *ar, const float mval[2], float out[3
* \param do_clip_planes: Optionally clip the ray by the view clipping planes.
* \return success, false if the segment is totally clipped.
*/
-bool ED_view3d_win_to_segment_clipped(
- struct Depsgraph *depsgraph,
- const ARegion *ar, View3D *v3d, const float mval[2],
- float r_ray_start[3], float r_ray_end[3], const bool do_clip_planes)
+bool ED_view3d_win_to_segment_clipped(struct Depsgraph *depsgraph,
+ const ARegion *ar,
+ View3D *v3d,
+ const float mval[2],
+ float r_ray_start[3],
+ float r_ray_end[3],
+ const bool do_clip_planes)
{
- view3d_win_to_ray_segment(depsgraph, ar, v3d, mval, NULL, NULL, r_ray_start, r_ray_end);
+ view3d_win_to_ray_segment(depsgraph, ar, v3d, mval, NULL, NULL, r_ray_start, r_ray_end);
- /* bounds clipping */
- if (do_clip_planes) {
- return ED_view3d_clip_segment((RegionView3D *)ar->regiondata, r_ray_start, r_ray_end);
- }
+ /* bounds clipping */
+ if (do_clip_planes) {
+ return ED_view3d_clip_segment((RegionView3D *)ar->regiondata, r_ray_start, r_ray_end);
+ }
- return true;
+ return true;
}
/* Utility functions for projection
@@ -696,18 +744,20 @@ bool ED_view3d_win_to_segment_clipped(
void ED_view3d_ob_project_mat_get(const RegionView3D *rv3d, Object *ob, float pmat[4][4])
{
- float vmat[4][4];
+ float vmat[4][4];
- mul_m4_m4m4(vmat, (float (*)[4])rv3d->viewmat, ob->obmat);
- mul_m4_m4m4(pmat, (float (*)[4])rv3d->winmat, vmat);
+ mul_m4_m4m4(vmat, (float(*)[4])rv3d->viewmat, ob->obmat);
+ mul_m4_m4m4(pmat, (float(*)[4])rv3d->winmat, vmat);
}
-void ED_view3d_ob_project_mat_get_from_obmat(const RegionView3D *rv3d, float obmat[4][4], float pmat[4][4])
+void ED_view3d_ob_project_mat_get_from_obmat(const RegionView3D *rv3d,
+ float obmat[4][4],
+ float pmat[4][4])
{
- float vmat[4][4];
+ float vmat[4][4];
- mul_m4_m4m4(vmat, (float (*)[4])rv3d->viewmat, obmat);
- mul_m4_m4m4(pmat, (float (*)[4])rv3d->winmat, vmat);
+ mul_m4_m4m4(vmat, (float(*)[4])rv3d->viewmat, obmat);
+ mul_m4_m4m4(pmat, (float(*)[4])rv3d->winmat, vmat);
}
/**
@@ -715,18 +765,19 @@ void ED_view3d_ob_project_mat_get_from_obmat(const RegionView3D *rv3d, float obm
* a point in world space. */
void ED_view3d_project(const struct ARegion *ar, const float world[3], float region[3])
{
- // viewport is set up to make coordinates relative to the region, not window
- RegionView3D *rv3d = ar->regiondata;
- int viewport[4] = {0, 0, ar->winx, ar->winy};
+ // viewport is set up to make coordinates relative to the region, not window
+ RegionView3D *rv3d = ar->regiondata;
+ int viewport[4] = {0, 0, ar->winx, ar->winy};
- GPU_matrix_project(world, rv3d->viewmat, rv3d->winmat, viewport, region);
+ GPU_matrix_project(world, rv3d->viewmat, rv3d->winmat, viewport, region);
}
-bool ED_view3d_unproject(const struct ARegion *ar, float regionx, float regiony, float regionz, float world[3])
+bool ED_view3d_unproject(
+ const struct ARegion *ar, float regionx, float regiony, float regionz, float world[3])
{
- RegionView3D *rv3d = ar->regiondata;
- int viewport[4] = {0, 0, ar->winx, ar->winy};
- float region[3] = {regionx, regiony, regionz};
+ RegionView3D *rv3d = ar->regiondata;
+ int viewport[4] = {0, 0, ar->winx, ar->winy};
+ float region[3] = {regionx, regiony, regionz};
- return GPU_matrix_unproject(region, rv3d->viewmat, rv3d->winmat, viewport, world);
+ return GPU_matrix_unproject(region, rv3d->viewmat, rv3d->winmat, viewport, world);
}
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index f57b31b2ed2..c0f2e563365 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -21,7 +21,6 @@
* \ingroup spview3d
*/
-
#include <string.h>
#include <stdio.h>
#include <math.h>
@@ -99,50 +98,49 @@
#include "GPU_glew.h"
#include "GPU_matrix.h"
-#include "view3d_intern.h" /* own include */
+#include "view3d_intern.h" /* own include */
// #include "PIL_time_utildefines.h"
-
/* -------------------------------------------------------------------- */
/** \name Public Utilities
* \{ */
float ED_view3d_select_dist_px(void)
{
- return 75.0f * U.pixelsize;
+ return 75.0f * U.pixelsize;
}
/* TODO: should return whether there is valid context to continue */
void ED_view3d_viewcontext_init(bContext *C, ViewContext *vc)
{
- memset(vc, 0, sizeof(ViewContext));
- vc->C = C;
- vc->ar = CTX_wm_region(C);
- vc->bmain = CTX_data_main(C);
- vc->depsgraph = CTX_data_depsgraph(C);
- vc->scene = CTX_data_scene(C);
- vc->view_layer = CTX_data_view_layer(C);
- vc->v3d = CTX_wm_view3d(C);
- vc->win = CTX_wm_window(C);
- vc->rv3d = CTX_wm_region_view3d(C);
- vc->obact = CTX_data_active_object(C);
- vc->obedit = CTX_data_edit_object(C);
+ memset(vc, 0, sizeof(ViewContext));
+ vc->C = C;
+ vc->ar = CTX_wm_region(C);
+ vc->bmain = CTX_data_main(C);
+ vc->depsgraph = CTX_data_depsgraph(C);
+ vc->scene = CTX_data_scene(C);
+ vc->view_layer = CTX_data_view_layer(C);
+ vc->v3d = CTX_wm_view3d(C);
+ vc->win = CTX_wm_window(C);
+ vc->rv3d = CTX_wm_region_view3d(C);
+ vc->obact = CTX_data_active_object(C);
+ vc->obedit = CTX_data_edit_object(C);
}
void ED_view3d_viewcontext_init_object(ViewContext *vc, Object *obact)
{
- vc->obact = obact;
- if (vc->obedit) {
- BLI_assert(BKE_object_is_in_editmode(obact));
- vc->obedit = obact;
- /* previous selections are now invalid. */
- vc->v3d->flag |= V3D_INVALID_BACKBUF;
+ vc->obact = obact;
+ if (vc->obedit) {
+ BLI_assert(BKE_object_is_in_editmode(obact));
+ vc->obedit = obact;
+ /* previous selections are now invalid. */
+ vc->v3d->flag |= V3D_INVALID_BACKBUF;
- if (vc->em) {
- vc->em = BKE_editmesh_from_object(vc->obedit);
- }
- }
+ if (vc->em) {
+ vc->em = BKE_editmesh_from_object(vc->obedit);
+ }
+ }
}
/** \} */
@@ -153,31 +151,31 @@ void ED_view3d_viewcontext_init_object(ViewContext *vc, Object *obact)
static bool object_deselect_all_visible(ViewLayer *view_layer, View3D *v3d)
{
- bool changed = false;
- for (Base *base = view_layer->object_bases.first; base; base = base->next) {
- if (base->flag & BASE_SELECTED) {
- if (BASE_SELECTABLE(v3d, base)) {
- ED_object_base_select(base, BA_DESELECT);
- changed = true;
- }
- }
- }
- return changed;
+ bool changed = false;
+ for (Base *base = view_layer->object_bases.first; base; base = base->next) {
+ if (base->flag & BASE_SELECTED) {
+ if (BASE_SELECTABLE(v3d, base)) {
+ ED_object_base_select(base, BA_DESELECT);
+ changed = true;
+ }
+ }
+ }
+ return changed;
}
/* deselect all except b */
static bool object_deselect_all_except(ViewLayer *view_layer, Base *b)
{
- bool changed = false;
- for (Base *base = view_layer->object_bases.first; base; base = base->next) {
- if (base->flag & BASE_SELECTED) {
- if (b != base) {
- ED_object_base_select(base, BA_DESELECT);
- changed = true;
- }
- }
- }
- return changed;
+ bool changed = false;
+ for (Base *base = view_layer->object_bases.first; base; base = base->next) {
+ if (base->flag & BASE_SELECTED) {
+ if (b != base) {
+ ED_object_base_select(base, BA_DESELECT);
+ changed = true;
+ }
+ }
+ }
+ return changed;
}
/** \} */
@@ -188,114 +186,114 @@ static bool object_deselect_all_except(ViewLayer *view_layer, Base *b)
static bool edbm_backbuf_check_and_select_verts(BMEditMesh *em, const eSelectOp sel_op)
{
- BMVert *eve;
- BMIter iter;
- uint index = bm_wireoffs;
- bool changed = false;
-
- BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
- if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
- const bool is_select = BM_elem_flag_test(eve, BM_ELEM_SELECT);
- const bool is_inside = EDBM_backbuf_check(index);
- const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- BM_vert_select_set(em->bm, eve, sel_op_result);
- changed = true;
- }
- }
- index++;
- }
- return changed;
+ BMVert *eve;
+ BMIter iter;
+ uint index = bm_wireoffs;
+ bool changed = false;
+
+ BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
+ if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
+ const bool is_select = BM_elem_flag_test(eve, BM_ELEM_SELECT);
+ const bool is_inside = EDBM_backbuf_check(index);
+ const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
+ if (sel_op_result != -1) {
+ BM_vert_select_set(em->bm, eve, sel_op_result);
+ changed = true;
+ }
+ }
+ index++;
+ }
+ return changed;
}
static bool edbm_backbuf_check_and_select_edges(BMEditMesh *em, const eSelectOp sel_op)
{
- BMEdge *eed;
- BMIter iter;
- uint index = bm_solidoffs;
- bool changed = false;
-
- BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
- if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
- const bool is_select = BM_elem_flag_test(eed, BM_ELEM_SELECT);
- const bool is_inside = EDBM_backbuf_check(index);
- const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- BM_edge_select_set(em->bm, eed, sel_op_result);
- changed = true;
- }
- }
- index++;
- }
- return changed;
+ BMEdge *eed;
+ BMIter iter;
+ uint index = bm_solidoffs;
+ bool changed = false;
+
+ BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
+ if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
+ const bool is_select = BM_elem_flag_test(eed, BM_ELEM_SELECT);
+ const bool is_inside = EDBM_backbuf_check(index);
+ const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
+ if (sel_op_result != -1) {
+ BM_edge_select_set(em->bm, eed, sel_op_result);
+ changed = true;
+ }
+ }
+ index++;
+ }
+ return changed;
}
static bool edbm_backbuf_check_and_select_faces(BMEditMesh *em, const eSelectOp sel_op)
{
- BMFace *efa;
- BMIter iter;
- uint index = 1;
- bool changed = false;
-
- BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
- const bool is_select = BM_elem_flag_test(efa, BM_ELEM_SELECT);
- const bool is_inside = EDBM_backbuf_check(index);
- const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- BM_face_select_set(em->bm, efa, sel_op_result);
- changed = true;
- }
- }
- index++;
- }
- return changed;
+ BMFace *efa;
+ BMIter iter;
+ uint index = 1;
+ bool changed = false;
+
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
+ const bool is_select = BM_elem_flag_test(efa, BM_ELEM_SELECT);
+ const bool is_inside = EDBM_backbuf_check(index);
+ const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
+ if (sel_op_result != -1) {
+ BM_face_select_set(em->bm, efa, sel_op_result);
+ changed = true;
+ }
+ }
+ index++;
+ }
+ return changed;
}
/* object mode, edbm_ prefix is confusing here, rename? */
static bool edbm_backbuf_check_and_select_verts_obmode(Mesh *me, const eSelectOp sel_op)
{
- MVert *mv = me->mvert;
- uint index;
- bool changed = false;
-
- if (mv) {
- for (index = 1; index <= me->totvert; index++, mv++) {
- if (!(mv->flag & ME_HIDE)) {
- const bool is_select = mv->flag & SELECT;
- const bool is_inside = EDBM_backbuf_check(index);
- const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- SET_FLAG_FROM_TEST(mv->flag, sel_op_result, SELECT);
- changed = true;
- }
- }
- }
- }
- return changed;
+ MVert *mv = me->mvert;
+ uint index;
+ bool changed = false;
+
+ if (mv) {
+ for (index = 1; index <= me->totvert; index++, mv++) {
+ if (!(mv->flag & ME_HIDE)) {
+ const bool is_select = mv->flag & SELECT;
+ const bool is_inside = EDBM_backbuf_check(index);
+ const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
+ if (sel_op_result != -1) {
+ SET_FLAG_FROM_TEST(mv->flag, sel_op_result, SELECT);
+ changed = true;
+ }
+ }
+ }
+ }
+ return changed;
}
/* object mode, edbm_ prefix is confusing here, rename? */
static bool edbm_backbuf_check_and_select_tfaces(Mesh *me, const eSelectOp sel_op)
{
- MPoly *mpoly = me->mpoly;
- uint index;
- bool changed = false;
-
- if (mpoly) {
- for (index = 1; index <= me->totpoly; index++, mpoly++) {
- if (!(mpoly->flag & ME_HIDE)) {
- const bool is_select = mpoly->flag & ME_FACE_SEL;
- const bool is_inside = EDBM_backbuf_check(index);
- const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- SET_FLAG_FROM_TEST(mpoly->flag, sel_op_result, ME_FACE_SEL);
- changed = true;
- }
- }
- }
- }
- return changed;
+ MPoly *mpoly = me->mpoly;
+ uint index;
+ bool changed = false;
+
+ if (mpoly) {
+ for (index = 1; index <= me->totpoly; index++, mpoly++) {
+ if (!(mpoly->flag & ME_HIDE)) {
+ const bool is_select = mpoly->flag & ME_FACE_SEL;
+ const bool is_inside = EDBM_backbuf_check(index);
+ const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
+ if (sel_op_result != -1) {
+ SET_FLAG_FROM_TEST(mpoly->flag, sel_op_result, ME_FACE_SEL);
+ changed = true;
+ }
+ }
+ }
+ }
+ return changed;
}
/** \} */
@@ -305,871 +303,911 @@ static bool edbm_backbuf_check_and_select_tfaces(Mesh *me, const eSelectOp sel_o
* \{ */
typedef struct LassoSelectUserData {
- ViewContext *vc;
- const rcti *rect;
- const rctf *rect_fl;
- rctf _rect_fl;
- const int (*mcords)[2];
- int moves;
- eSelectOp sel_op;
-
- /* runtime */
- int pass;
- bool is_done;
- bool is_changed;
+ ViewContext *vc;
+ const rcti *rect;
+ const rctf *rect_fl;
+ rctf _rect_fl;
+ const int (*mcords)[2];
+ int moves;
+ eSelectOp sel_op;
+
+ /* runtime */
+ int pass;
+ bool is_done;
+ bool is_changed;
} LassoSelectUserData;
-static void view3d_userdata_lassoselect_init(
- LassoSelectUserData *r_data,
- ViewContext *vc, const rcti *rect, const int (*mcords)[2],
- const int moves, const eSelectOp sel_op)
+static void view3d_userdata_lassoselect_init(LassoSelectUserData *r_data,
+ ViewContext *vc,
+ const rcti *rect,
+ const int (*mcords)[2],
+ const int moves,
+ const eSelectOp sel_op)
{
- r_data->vc = vc;
+ r_data->vc = vc;
- r_data->rect = rect;
- r_data->rect_fl = &r_data->_rect_fl;
- BLI_rctf_rcti_copy(&r_data->_rect_fl, rect);
+ r_data->rect = rect;
+ r_data->rect_fl = &r_data->_rect_fl;
+ BLI_rctf_rcti_copy(&r_data->_rect_fl, rect);
- r_data->mcords = mcords;
- r_data->moves = moves;
- r_data->sel_op = sel_op;
+ r_data->mcords = mcords;
+ r_data->moves = moves;
+ r_data->sel_op = sel_op;
- /* runtime */
- r_data->pass = 0;
- r_data->is_done = false;
- r_data->is_changed = false;
+ /* runtime */
+ r_data->pass = 0;
+ r_data->is_done = false;
+ r_data->is_changed = false;
}
static bool view3d_selectable_data(bContext *C)
{
- Object *ob = CTX_data_active_object(C);
+ Object *ob = CTX_data_active_object(C);
- if (!ED_operator_region_view3d_active(C)) {
- return 0;
- }
+ if (!ED_operator_region_view3d_active(C)) {
+ return 0;
+ }
- if (ob) {
- if (ob->mode & OB_MODE_EDIT) {
- if (ob->type == OB_FONT) {
- return 0;
- }
- }
- else {
- if ((ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) &&
- !BKE_paint_select_elem_test(ob))
- {
- return 0;
- }
- }
- }
+ if (ob) {
+ if (ob->mode & OB_MODE_EDIT) {
+ if (ob->type == OB_FONT) {
+ return 0;
+ }
+ }
+ else {
+ if ((ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) &&
+ !BKE_paint_select_elem_test(ob)) {
+ return 0;
+ }
+ }
+ }
- return 1;
+ return 1;
}
-
/* helper also for box_select */
static bool edge_fully_inside_rect(const rctf *rect, const float v1[2], const float v2[2])
{
- return BLI_rctf_isect_pt_v(rect, v1) && BLI_rctf_isect_pt_v(rect, v2);
+ return BLI_rctf_isect_pt_v(rect, v1) && BLI_rctf_isect_pt_v(rect, v2);
}
static bool edge_inside_rect(const rctf *rect, const float v1[2], const float v2[2])
{
- int d1, d2, d3, d4;
-
- /* check points in rect */
- if (edge_fully_inside_rect(rect, v1, v2)) {
- return 1;
- }
-
- /* check points completely out rect */
- if (v1[0] < rect->xmin && v2[0] < rect->xmin) {
- return 0;
- }
- if (v1[0] > rect->xmax && v2[0] > rect->xmax) {
- return 0;
- }
- if (v1[1] < rect->ymin && v2[1] < rect->ymin) {
- return 0;
- }
- if (v1[1] > rect->ymax && v2[1] > rect->ymax) {
- return 0;
- }
-
- /* simple check lines intersecting. */
- d1 = (v1[1] - v2[1]) * (v1[0] - rect->xmin) + (v2[0] - v1[0]) * (v1[1] - rect->ymin);
- d2 = (v1[1] - v2[1]) * (v1[0] - rect->xmin) + (v2[0] - v1[0]) * (v1[1] - rect->ymax);
- d3 = (v1[1] - v2[1]) * (v1[0] - rect->xmax) + (v2[0] - v1[0]) * (v1[1] - rect->ymax);
- d4 = (v1[1] - v2[1]) * (v1[0] - rect->xmax) + (v2[0] - v1[0]) * (v1[1] - rect->ymin);
-
- if (d1 < 0 && d2 < 0 && d3 < 0 && d4 < 0) {
- return 0;
- }
- if (d1 > 0 && d2 > 0 && d3 > 0 && d4 > 0) {
- return 0;
- }
-
- return 1;
-}
-
-static void do_lasso_select_pose__do_tag(
- void *userData, struct bPoseChannel *pchan, const float screen_co_a[2], const float screen_co_b[2])
-{
- LassoSelectUserData *data = userData;
- bArmature *arm = data->vc->obact->data;
-
- if (PBONE_SELECTABLE(arm, pchan->bone)) {
- bool is_point_done = false;
- int points_proj_tot = 0;
-
- /* project head location to screenspace */
- if (screen_co_a[0] != IS_CLIPPED) {
- points_proj_tot++;
- if (BLI_rcti_isect_pt(data->rect, UNPACK2(screen_co_a)) &&
- BLI_lasso_is_point_inside(data->mcords, data->moves, UNPACK2(screen_co_a), INT_MAX))
- {
- is_point_done = true;
- }
- }
-
- /* project tail location to screenspace */
- if (screen_co_b[0] != IS_CLIPPED) {
- points_proj_tot++;
- if (BLI_rcti_isect_pt(data->rect, UNPACK2(screen_co_b)) &&
- BLI_lasso_is_point_inside(data->mcords, data->moves, UNPACK2(screen_co_b), INT_MAX))
- {
- is_point_done = true;
- }
- }
-
- /* if one of points selected, we skip the bone itself */
- if ((is_point_done == true) ||
- ((is_point_done == false) && (points_proj_tot == 2) &&
- BLI_lasso_is_edge_inside(data->mcords, data->moves, UNPACK2(screen_co_a), UNPACK2(screen_co_b), INT_MAX)))
- {
- pchan->bone->flag |= BONE_DONE;
- }
- data->is_changed |= is_point_done;
- }
+ int d1, d2, d3, d4;
+
+ /* check points in rect */
+ if (edge_fully_inside_rect(rect, v1, v2)) {
+ return 1;
+ }
+
+ /* check points completely out rect */
+ if (v1[0] < rect->xmin && v2[0] < rect->xmin) {
+ return 0;
+ }
+ if (v1[0] > rect->xmax && v2[0] > rect->xmax) {
+ return 0;
+ }
+ if (v1[1] < rect->ymin && v2[1] < rect->ymin) {
+ return 0;
+ }
+ if (v1[1] > rect->ymax && v2[1] > rect->ymax) {
+ return 0;
+ }
+
+ /* simple check lines intersecting. */
+ d1 = (v1[1] - v2[1]) * (v1[0] - rect->xmin) + (v2[0] - v1[0]) * (v1[1] - rect->ymin);
+ d2 = (v1[1] - v2[1]) * (v1[0] - rect->xmin) + (v2[0] - v1[0]) * (v1[1] - rect->ymax);
+ d3 = (v1[1] - v2[1]) * (v1[0] - rect->xmax) + (v2[0] - v1[0]) * (v1[1] - rect->ymax);
+ d4 = (v1[1] - v2[1]) * (v1[0] - rect->xmax) + (v2[0] - v1[0]) * (v1[1] - rect->ymin);
+
+ if (d1 < 0 && d2 < 0 && d3 < 0 && d4 < 0) {
+ return 0;
+ }
+ if (d1 > 0 && d2 > 0 && d3 > 0 && d4 > 0) {
+ return 0;
+ }
+
+ return 1;
+}
+
+static void do_lasso_select_pose__do_tag(void *userData,
+ struct bPoseChannel *pchan,
+ const float screen_co_a[2],
+ const float screen_co_b[2])
+{
+ LassoSelectUserData *data = userData;
+ bArmature *arm = data->vc->obact->data;
+
+ if (PBONE_SELECTABLE(arm, pchan->bone)) {
+ bool is_point_done = false;
+ int points_proj_tot = 0;
+
+ /* project head location to screenspace */
+ if (screen_co_a[0] != IS_CLIPPED) {
+ points_proj_tot++;
+ if (BLI_rcti_isect_pt(data->rect, UNPACK2(screen_co_a)) &&
+ BLI_lasso_is_point_inside(data->mcords, data->moves, UNPACK2(screen_co_a), INT_MAX)) {
+ is_point_done = true;
+ }
+ }
+
+ /* project tail location to screenspace */
+ if (screen_co_b[0] != IS_CLIPPED) {
+ points_proj_tot++;
+ if (BLI_rcti_isect_pt(data->rect, UNPACK2(screen_co_b)) &&
+ BLI_lasso_is_point_inside(data->mcords, data->moves, UNPACK2(screen_co_b), INT_MAX)) {
+ is_point_done = true;
+ }
+ }
+
+ /* if one of points selected, we skip the bone itself */
+ if ((is_point_done == true) ||
+ ((is_point_done == false) && (points_proj_tot == 2) &&
+ BLI_lasso_is_edge_inside(
+ data->mcords, data->moves, UNPACK2(screen_co_a), UNPACK2(screen_co_b), INT_MAX))) {
+ pchan->bone->flag |= BONE_DONE;
+ }
+ data->is_changed |= is_point_done;
+ }
}
static void do_lasso_tag_pose(ViewContext *vc, Object *ob, const int mcords[][2], short moves)
{
- ViewContext vc_tmp;
- LassoSelectUserData data;
- rcti rect;
+ ViewContext vc_tmp;
+ LassoSelectUserData data;
+ rcti rect;
- if ((ob->type != OB_ARMATURE) || (ob->pose == NULL)) {
- return;
- }
+ if ((ob->type != OB_ARMATURE) || (ob->pose == NULL)) {
+ return;
+ }
- vc_tmp = *vc;
- vc_tmp.obact = ob;
+ vc_tmp = *vc;
+ vc_tmp.obact = ob;
- BLI_lasso_boundbox(&rect, mcords, moves);
+ BLI_lasso_boundbox(&rect, mcords, moves);
- view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, 0);
+ view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, 0);
- ED_view3d_init_mats_rv3d(vc_tmp.obact, vc->rv3d);
+ ED_view3d_init_mats_rv3d(vc_tmp.obact, vc->rv3d);
- pose_foreachScreenBone(&vc_tmp, do_lasso_select_pose__do_tag, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ pose_foreachScreenBone(&vc_tmp, do_lasso_select_pose__do_tag, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
-static bool do_lasso_select_objects(
- ViewContext *vc, const int mcords[][2], const short moves,
- const eSelectOp sel_op)
+static bool do_lasso_select_objects(ViewContext *vc,
+ const int mcords[][2],
+ const short moves,
+ const eSelectOp sel_op)
{
- View3D *v3d = vc->v3d;
- Base *base;
+ View3D *v3d = vc->v3d;
+ Base *base;
- bool changed = false;
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- changed |= object_deselect_all_visible(vc->view_layer, vc->v3d);
- }
+ bool changed = false;
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ changed |= object_deselect_all_visible(vc->view_layer, vc->v3d);
+ }
- for (base = vc->view_layer->object_bases.first; base; base = base->next) {
- if (BASE_SELECTABLE(v3d, base)) { /* use this to avoid un-needed lasso lookups */
- const bool is_select = base->flag & BASE_SELECTED;
- const bool is_inside = (
- (ED_view3d_project_base(vc->ar, base) == V3D_PROJ_RET_OK) &&
- BLI_lasso_is_point_inside(mcords, moves, base->sx, base->sy, IS_CLIPPED));
- const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- ED_object_base_select(base, sel_op_result ? BA_SELECT : BA_DESELECT);
- changed = true;
- }
- }
- }
+ for (base = vc->view_layer->object_bases.first; base; base = base->next) {
+ if (BASE_SELECTABLE(v3d, base)) { /* use this to avoid un-needed lasso lookups */
+ const bool is_select = base->flag & BASE_SELECTED;
+ const bool is_inside = ((ED_view3d_project_base(vc->ar, base) == V3D_PROJ_RET_OK) &&
+ BLI_lasso_is_point_inside(
+ mcords, moves, base->sx, base->sy, IS_CLIPPED));
+ const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
+ if (sel_op_result != -1) {
+ ED_object_base_select(base, sel_op_result ? BA_SELECT : BA_DESELECT);
+ changed = true;
+ }
+ }
+ }
- if (changed) {
- DEG_id_tag_update(&vc->scene->id, ID_RECALC_SELECT);
- WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, vc->scene);
- }
- return changed;
+ if (changed) {
+ DEG_id_tag_update(&vc->scene->id, ID_RECALC_SELECT);
+ WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, vc->scene);
+ }
+ return changed;
}
-
/**
* Use for lasso & box select.
*/
static Base **do_pose_tag_select_op_prepare(ViewContext *vc, uint *r_bases_len)
{
- Base **bases = NULL;
- BLI_array_declare(bases);
- FOREACH_BASE_IN_MODE_BEGIN (vc->view_layer, vc->v3d, OB_ARMATURE, OB_MODE_POSE, base_iter) {
- Object *ob_iter = base_iter->object;
- bArmature *arm = ob_iter->data;
- for (bPoseChannel *pchan = ob_iter->pose->chanbase.first; pchan; pchan = pchan->next) {
- Bone *bone = pchan->bone;
- bone->flag &= ~BONE_DONE;
- }
- arm->id.tag |= LIB_TAG_DOIT;
- ob_iter->id.tag &= ~LIB_TAG_DOIT;
- BLI_array_append(bases, base_iter);
- }
- FOREACH_BASE_IN_MODE_END;
- *r_bases_len = BLI_array_len(bases);
- return bases;
+ Base **bases = NULL;
+ BLI_array_declare(bases);
+ FOREACH_BASE_IN_MODE_BEGIN (vc->view_layer, vc->v3d, OB_ARMATURE, OB_MODE_POSE, base_iter) {
+ Object *ob_iter = base_iter->object;
+ bArmature *arm = ob_iter->data;
+ for (bPoseChannel *pchan = ob_iter->pose->chanbase.first; pchan; pchan = pchan->next) {
+ Bone *bone = pchan->bone;
+ bone->flag &= ~BONE_DONE;
+ }
+ arm->id.tag |= LIB_TAG_DOIT;
+ ob_iter->id.tag &= ~LIB_TAG_DOIT;
+ BLI_array_append(bases, base_iter);
+ }
+ FOREACH_BASE_IN_MODE_END;
+ *r_bases_len = BLI_array_len(bases);
+ return bases;
}
static bool do_pose_tag_select_op_exec(Base **bases, const uint bases_len, const eSelectOp sel_op)
{
- bool changed_multi = false;
-
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- for (int i = 0; i < bases_len; i++) {
- Base *base_iter = bases[i];
- Object *ob_iter = base_iter->object;
- if (ED_pose_deselect_all(ob_iter, SEL_DESELECT, false)) {
- ED_pose_bone_select_tag_update(ob_iter);
- changed_multi = true;
- }
- }
- }
-
- for (int i = 0; i < bases_len; i++) {
- Base *base_iter = bases[i];
- Object *ob_iter = base_iter->object;
- bArmature *arm = ob_iter->data;
-
- /* Don't handle twice. */
- if (arm->id.tag & LIB_TAG_DOIT) {
- arm->id.tag &= ~LIB_TAG_DOIT;
- }
- else {
- continue;
- }
-
- bool changed = true;
- for (bPoseChannel *pchan = ob_iter->pose->chanbase.first; pchan; pchan = pchan->next) {
- Bone *bone = pchan->bone;
- if ((bone->flag & BONE_UNSELECTABLE) == 0) {
- const bool is_select = bone->flag & BONE_SELECTED;
- const bool is_inside = bone->flag & BONE_DONE;
- const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- SET_FLAG_FROM_TEST(bone->flag, sel_op_result, BONE_SELECTED);
- if (sel_op_result == 0) {
- if (arm->act_bone == bone) {
- arm->act_bone = NULL;
- }
- }
- changed = true;
- }
- }
- }
- if (changed) {
- ED_pose_bone_select_tag_update(ob_iter);
- changed_multi = true;
- }
- }
- return changed_multi;
-}
-
-static bool do_lasso_select_pose(
- ViewContext *vc, const int mcords[][2], const short moves,
- const eSelectOp sel_op)
-{
- uint bases_len;
- Base **bases = do_pose_tag_select_op_prepare(vc, &bases_len);
-
- for (int i = 0; i < bases_len; i++) {
- Base *base_iter = bases[i];
- Object *ob_iter = base_iter->object;
- do_lasso_tag_pose(vc, ob_iter, mcords, moves);
- }
-
- const bool changed_multi = do_pose_tag_select_op_exec(bases, bases_len, sel_op);
- if (changed_multi) {
- DEG_id_tag_update(&vc->scene->id, ID_RECALC_SELECT);
- WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, vc->scene);
- }
-
- MEM_freeN(bases);
- return changed_multi;
-}
-
-static void do_lasso_select_mesh__doSelectVert(void *userData, BMVert *eve, const float screen_co[2], int UNUSED(index))
-{
- LassoSelectUserData *data = userData;
- const bool is_select = BM_elem_flag_test(eve, BM_ELEM_SELECT);
- const bool is_inside = (
- BLI_rctf_isect_pt_v(data->rect_fl, screen_co) &&
- BLI_lasso_is_point_inside(data->mcords, data->moves, screen_co[0], screen_co[1], IS_CLIPPED));
- const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- BM_vert_select_set(data->vc->em->bm, eve, sel_op_result);
- data->is_changed = true;
- }
+ bool changed_multi = false;
+
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ for (int i = 0; i < bases_len; i++) {
+ Base *base_iter = bases[i];
+ Object *ob_iter = base_iter->object;
+ if (ED_pose_deselect_all(ob_iter, SEL_DESELECT, false)) {
+ ED_pose_bone_select_tag_update(ob_iter);
+ changed_multi = true;
+ }
+ }
+ }
+
+ for (int i = 0; i < bases_len; i++) {
+ Base *base_iter = bases[i];
+ Object *ob_iter = base_iter->object;
+ bArmature *arm = ob_iter->data;
+
+ /* Don't handle twice. */
+ if (arm->id.tag & LIB_TAG_DOIT) {
+ arm->id.tag &= ~LIB_TAG_DOIT;
+ }
+ else {
+ continue;
+ }
+
+ bool changed = true;
+ for (bPoseChannel *pchan = ob_iter->pose->chanbase.first; pchan; pchan = pchan->next) {
+ Bone *bone = pchan->bone;
+ if ((bone->flag & BONE_UNSELECTABLE) == 0) {
+ const bool is_select = bone->flag & BONE_SELECTED;
+ const bool is_inside = bone->flag & BONE_DONE;
+ const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
+ if (sel_op_result != -1) {
+ SET_FLAG_FROM_TEST(bone->flag, sel_op_result, BONE_SELECTED);
+ if (sel_op_result == 0) {
+ if (arm->act_bone == bone) {
+ arm->act_bone = NULL;
+ }
+ }
+ changed = true;
+ }
+ }
+ }
+ if (changed) {
+ ED_pose_bone_select_tag_update(ob_iter);
+ changed_multi = true;
+ }
+ }
+ return changed_multi;
+}
+
+static bool do_lasso_select_pose(ViewContext *vc,
+ const int mcords[][2],
+ const short moves,
+ const eSelectOp sel_op)
+{
+ uint bases_len;
+ Base **bases = do_pose_tag_select_op_prepare(vc, &bases_len);
+
+ for (int i = 0; i < bases_len; i++) {
+ Base *base_iter = bases[i];
+ Object *ob_iter = base_iter->object;
+ do_lasso_tag_pose(vc, ob_iter, mcords, moves);
+ }
+
+ const bool changed_multi = do_pose_tag_select_op_exec(bases, bases_len, sel_op);
+ if (changed_multi) {
+ DEG_id_tag_update(&vc->scene->id, ID_RECALC_SELECT);
+ WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, vc->scene);
+ }
+
+ MEM_freeN(bases);
+ return changed_multi;
+}
+
+static void do_lasso_select_mesh__doSelectVert(void *userData,
+ BMVert *eve,
+ const float screen_co[2],
+ int UNUSED(index))
+{
+ LassoSelectUserData *data = userData;
+ const bool is_select = BM_elem_flag_test(eve, BM_ELEM_SELECT);
+ const bool is_inside = (BLI_rctf_isect_pt_v(data->rect_fl, screen_co) &&
+ BLI_lasso_is_point_inside(
+ data->mcords, data->moves, screen_co[0], screen_co[1], IS_CLIPPED));
+ const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
+ if (sel_op_result != -1) {
+ BM_vert_select_set(data->vc->em->bm, eve, sel_op_result);
+ data->is_changed = true;
+ }
}
static void do_lasso_select_mesh__doSelectEdge_pass0(
- void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index)
-{
- LassoSelectUserData *data = userData;
- const bool is_select = BM_elem_flag_test(eed, BM_ELEM_SELECT);
- const bool is_inside = (
- EDBM_backbuf_check(bm_solidoffs + index) &&
- edge_fully_inside_rect(data->rect_fl, screen_co_a, screen_co_b) &&
- BLI_lasso_is_point_inside(data->mcords, data->moves, UNPACK2(screen_co_a), IS_CLIPPED) &&
- BLI_lasso_is_point_inside(data->mcords, data->moves, UNPACK2(screen_co_b), IS_CLIPPED));
- const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- BM_edge_select_set(data->vc->em->bm, eed, sel_op_result);
- data->is_done = true;
- data->is_changed = true;
- }
+ void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index)
+{
+ LassoSelectUserData *data = userData;
+ const bool is_select = BM_elem_flag_test(eed, BM_ELEM_SELECT);
+ const bool is_inside =
+ (EDBM_backbuf_check(bm_solidoffs + index) &&
+ edge_fully_inside_rect(data->rect_fl, screen_co_a, screen_co_b) &&
+ BLI_lasso_is_point_inside(data->mcords, data->moves, UNPACK2(screen_co_a), IS_CLIPPED) &&
+ BLI_lasso_is_point_inside(data->mcords, data->moves, UNPACK2(screen_co_b), IS_CLIPPED));
+ const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
+ if (sel_op_result != -1) {
+ BM_edge_select_set(data->vc->em->bm, eed, sel_op_result);
+ data->is_done = true;
+ data->is_changed = true;
+ }
}
static void do_lasso_select_mesh__doSelectEdge_pass1(
- void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index)
-{
- LassoSelectUserData *data = userData;
- const bool is_select = BM_elem_flag_test(eed, BM_ELEM_SELECT);
- const bool is_inside = (
- EDBM_backbuf_check(bm_solidoffs + index) &&
- BLI_lasso_is_edge_inside(
- data->mcords, data->moves, UNPACK2(screen_co_a), UNPACK2(screen_co_b), IS_CLIPPED));
- const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- BM_edge_select_set(data->vc->em->bm, eed, sel_op_result);
- data->is_changed = true;
- }
-}
-
-static void do_lasso_select_mesh__doSelectFace(void *userData, BMFace *efa, const float screen_co[2], int UNUSED(index))
-{
- LassoSelectUserData *data = userData;
- const bool is_select = BM_elem_flag_test(efa, BM_ELEM_SELECT);
- const bool is_inside = (
- BLI_rctf_isect_pt_v(data->rect_fl, screen_co) &&
- BLI_lasso_is_point_inside(
- data->mcords, data->moves, screen_co[0], screen_co[1], IS_CLIPPED));
- const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- BM_face_select_set(data->vc->em->bm, efa, sel_op_result);
- data->is_changed = true;
- }
-}
-
-static bool do_lasso_select_mesh(
- ViewContext *vc,
- const int mcords[][2], short moves, const eSelectOp sel_op)
-{
- LassoSelectUserData data;
- ToolSettings *ts = vc->scene->toolsettings;
- rcti rect;
- int bbsel;
-
- /* set editmesh */
- vc->em = BKE_editmesh_from_object(vc->obedit);
-
- BLI_lasso_boundbox(&rect, mcords, moves);
-
- view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, sel_op);
-
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- if (vc->em->bm->totvertsel) {
- EDBM_flag_disable_all(vc->em, BM_ELEM_SELECT);
- data.is_changed = true;
- }
- }
-
- /* for non zbuf projections, don't change the GL state */
- ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
-
- GPU_matrix_set(vc->rv3d->viewmat);
- bbsel = EDBM_backbuf_border_mask_init(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
-
- if (ts->selectmode & SCE_SELECT_VERTEX) {
- if (bbsel) {
- data.is_changed |= edbm_backbuf_check_and_select_verts(vc->em, sel_op);
- }
- else {
- mesh_foreachScreenVert(vc, do_lasso_select_mesh__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
- }
- }
- if (ts->selectmode & SCE_SELECT_EDGE) {
- /* Does both bbsel and non-bbsel versions (need screen cos for both) */
- mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge_pass0, &data, V3D_PROJ_TEST_CLIP_NEAR);
- if (data.is_done == false) {
- mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge_pass1, &data, V3D_PROJ_TEST_CLIP_NEAR);
- }
- }
-
- if (ts->selectmode & SCE_SELECT_FACE) {
- if (bbsel) {
- data.is_changed |= edbm_backbuf_check_and_select_faces(vc->em, sel_op);
- }
- else {
- mesh_foreachScreenFace(vc, do_lasso_select_mesh__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
- }
- }
-
- EDBM_backbuf_free();
-
- if (data.is_changed) {
- EDBM_selectmode_flush(vc->em);
- }
- return data.is_changed;
-}
-
-static void do_lasso_select_curve__doSelect(
- void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co[2])
-{
- LassoSelectUserData *data = userData;
-
- const bool is_inside = BLI_lasso_is_point_inside(data->mcords, data->moves, screen_co[0], screen_co[1], IS_CLIPPED);
- if (bp) {
- const bool is_select = bp->f1 & SELECT;
- const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- SET_FLAG_FROM_TEST(bp->f1, sel_op_result, SELECT);
- data->is_changed = true;
- }
- }
- else {
- if ((data->vc->v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_CU_HANDLES) == 0) {
- /* can only be (beztindex == 0) here since handles are hidden */
- const bool is_select = bezt->f2 & SELECT;
- const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- SET_FLAG_FROM_TEST(bezt->f2, sel_op_result, SELECT);
- }
- bezt->f1 = bezt->f3 = bezt->f2;
- data->is_changed = true;
- }
- else {
- char *flag_p = (&bezt->f1) + beztindex;
- const bool is_select = *flag_p & SELECT;
- const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- SET_FLAG_FROM_TEST(*flag_p, sel_op_result, SELECT);
- data->is_changed = true;
- }
- }
- }
-}
-
-static bool do_lasso_select_curve(ViewContext *vc, const int mcords[][2], short moves, const eSelectOp sel_op)
-{
- LassoSelectUserData data;
- rcti rect;
-
- BLI_lasso_boundbox(&rect, mcords, moves);
-
- view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, sel_op);
-
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- Curve *curve = (Curve *) vc->obedit->data;
- data.is_changed |= ED_curve_deselect_all(curve->editnurb);
- }
-
- ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
- nurbs_foreachScreenVert(vc, do_lasso_select_curve__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
- if (data.is_changed) {
- BKE_curve_nurb_vert_active_validate(vc->obedit->data);
- }
- return data.is_changed;
+ void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index)
+{
+ LassoSelectUserData *data = userData;
+ const bool is_select = BM_elem_flag_test(eed, BM_ELEM_SELECT);
+ const bool is_inside =
+ (EDBM_backbuf_check(bm_solidoffs + index) &&
+ BLI_lasso_is_edge_inside(
+ data->mcords, data->moves, UNPACK2(screen_co_a), UNPACK2(screen_co_b), IS_CLIPPED));
+ const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
+ if (sel_op_result != -1) {
+ BM_edge_select_set(data->vc->em->bm, eed, sel_op_result);
+ data->is_changed = true;
+ }
+}
+
+static void do_lasso_select_mesh__doSelectFace(void *userData,
+ BMFace *efa,
+ const float screen_co[2],
+ int UNUSED(index))
+{
+ LassoSelectUserData *data = userData;
+ const bool is_select = BM_elem_flag_test(efa, BM_ELEM_SELECT);
+ const bool is_inside = (BLI_rctf_isect_pt_v(data->rect_fl, screen_co) &&
+ BLI_lasso_is_point_inside(
+ data->mcords, data->moves, screen_co[0], screen_co[1], IS_CLIPPED));
+ const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
+ if (sel_op_result != -1) {
+ BM_face_select_set(data->vc->em->bm, efa, sel_op_result);
+ data->is_changed = true;
+ }
+}
+
+static bool do_lasso_select_mesh(ViewContext *vc,
+ const int mcords[][2],
+ short moves,
+ const eSelectOp sel_op)
+{
+ LassoSelectUserData data;
+ ToolSettings *ts = vc->scene->toolsettings;
+ rcti rect;
+ int bbsel;
+
+ /* set editmesh */
+ vc->em = BKE_editmesh_from_object(vc->obedit);
+
+ BLI_lasso_boundbox(&rect, mcords, moves);
+
+ view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, sel_op);
+
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ if (vc->em->bm->totvertsel) {
+ EDBM_flag_disable_all(vc->em, BM_ELEM_SELECT);
+ data.is_changed = true;
+ }
+ }
+
+ /* for non zbuf projections, don't change the GL state */
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
+
+ GPU_matrix_set(vc->rv3d->viewmat);
+ bbsel = EDBM_backbuf_border_mask_init(
+ vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
+
+ if (ts->selectmode & SCE_SELECT_VERTEX) {
+ if (bbsel) {
+ data.is_changed |= edbm_backbuf_check_and_select_verts(vc->em, sel_op);
+ }
+ else {
+ mesh_foreachScreenVert(
+ vc, do_lasso_select_mesh__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ }
+ }
+ if (ts->selectmode & SCE_SELECT_EDGE) {
+ /* Does both bbsel and non-bbsel versions (need screen cos for both) */
+ mesh_foreachScreenEdge(
+ vc, do_lasso_select_mesh__doSelectEdge_pass0, &data, V3D_PROJ_TEST_CLIP_NEAR);
+ if (data.is_done == false) {
+ mesh_foreachScreenEdge(
+ vc, do_lasso_select_mesh__doSelectEdge_pass1, &data, V3D_PROJ_TEST_CLIP_NEAR);
+ }
+ }
+
+ if (ts->selectmode & SCE_SELECT_FACE) {
+ if (bbsel) {
+ data.is_changed |= edbm_backbuf_check_and_select_faces(vc->em, sel_op);
+ }
+ else {
+ mesh_foreachScreenFace(
+ vc, do_lasso_select_mesh__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ }
+ }
+
+ EDBM_backbuf_free();
+
+ if (data.is_changed) {
+ EDBM_selectmode_flush(vc->em);
+ }
+ return data.is_changed;
+}
+
+static void do_lasso_select_curve__doSelect(void *userData,
+ Nurb *UNUSED(nu),
+ BPoint *bp,
+ BezTriple *bezt,
+ int beztindex,
+ const float screen_co[2])
+{
+ LassoSelectUserData *data = userData;
+
+ const bool is_inside = BLI_lasso_is_point_inside(
+ data->mcords, data->moves, screen_co[0], screen_co[1], IS_CLIPPED);
+ if (bp) {
+ const bool is_select = bp->f1 & SELECT;
+ const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
+ if (sel_op_result != -1) {
+ SET_FLAG_FROM_TEST(bp->f1, sel_op_result, SELECT);
+ data->is_changed = true;
+ }
+ }
+ else {
+ if ((data->vc->v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_CU_HANDLES) == 0) {
+ /* can only be (beztindex == 0) here since handles are hidden */
+ const bool is_select = bezt->f2 & SELECT;
+ const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
+ if (sel_op_result != -1) {
+ SET_FLAG_FROM_TEST(bezt->f2, sel_op_result, SELECT);
+ }
+ bezt->f1 = bezt->f3 = bezt->f2;
+ data->is_changed = true;
+ }
+ else {
+ char *flag_p = (&bezt->f1) + beztindex;
+ const bool is_select = *flag_p & SELECT;
+ const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
+ if (sel_op_result != -1) {
+ SET_FLAG_FROM_TEST(*flag_p, sel_op_result, SELECT);
+ data->is_changed = true;
+ }
+ }
+ }
+}
+
+static bool do_lasso_select_curve(ViewContext *vc,
+ const int mcords[][2],
+ short moves,
+ const eSelectOp sel_op)
+{
+ LassoSelectUserData data;
+ rcti rect;
+
+ BLI_lasso_boundbox(&rect, mcords, moves);
+
+ view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, sel_op);
+
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ Curve *curve = (Curve *)vc->obedit->data;
+ data.is_changed |= ED_curve_deselect_all(curve->editnurb);
+ }
+
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
+ nurbs_foreachScreenVert(vc, do_lasso_select_curve__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ if (data.is_changed) {
+ BKE_curve_nurb_vert_active_validate(vc->obedit->data);
+ }
+ return data.is_changed;
}
static void do_lasso_select_lattice__doSelect(void *userData, BPoint *bp, const float screen_co[2])
{
- LassoSelectUserData *data = userData;
- const bool is_select = bp->f1 & SELECT;
- const bool is_inside = (
- BLI_rctf_isect_pt_v(data->rect_fl, screen_co) &&
- BLI_lasso_is_point_inside(data->mcords, data->moves, screen_co[0], screen_co[1], IS_CLIPPED));
- const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- SET_FLAG_FROM_TEST(bp->f1, sel_op_result, SELECT);
- data->is_changed = true;
- }
+ LassoSelectUserData *data = userData;
+ const bool is_select = bp->f1 & SELECT;
+ const bool is_inside = (BLI_rctf_isect_pt_v(data->rect_fl, screen_co) &&
+ BLI_lasso_is_point_inside(
+ data->mcords, data->moves, screen_co[0], screen_co[1], IS_CLIPPED));
+ const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
+ if (sel_op_result != -1) {
+ SET_FLAG_FROM_TEST(bp->f1, sel_op_result, SELECT);
+ data->is_changed = true;
+ }
}
-static bool do_lasso_select_lattice(ViewContext *vc, const int mcords[][2], short moves, const eSelectOp sel_op)
+static bool do_lasso_select_lattice(ViewContext *vc,
+ const int mcords[][2],
+ short moves,
+ const eSelectOp sel_op)
{
- LassoSelectUserData data;
- rcti rect;
-
- BLI_lasso_boundbox(&rect, mcords, moves);
-
- view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, sel_op);
-
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- data.is_changed |= ED_lattice_flags_set(vc->obedit, 0);
- }
-
- ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
- lattice_foreachScreenVert(vc, do_lasso_select_lattice__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
- return data.is_changed;
+ LassoSelectUserData data;
+ rcti rect;
+
+ BLI_lasso_boundbox(&rect, mcords, moves);
+
+ view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, sel_op);
+
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ data.is_changed |= ED_lattice_flags_set(vc->obedit, 0);
+ }
+
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
+ lattice_foreachScreenVert(
+ vc, do_lasso_select_lattice__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ return data.is_changed;
}
-static void do_lasso_select_armature__doSelectBone(
- void *userData, EditBone *ebone, const float screen_co_a[2], const float screen_co_b[2])
+static void do_lasso_select_armature__doSelectBone(void *userData,
+ EditBone *ebone,
+ const float screen_co_a[2],
+ const float screen_co_b[2])
{
- LassoSelectUserData *data = userData;
- bArmature *arm = data->vc->obedit->data;
- if (EBONE_VISIBLE(arm, ebone)) {
- int is_ignore_flag = 0;
- int is_inside_flag = 0;
-
- if (screen_co_a[0] != IS_CLIPPED) {
- if (BLI_rcti_isect_pt(data->rect, UNPACK2(screen_co_a)) &&
- BLI_lasso_is_point_inside(data->mcords, data->moves, UNPACK2(screen_co_a), INT_MAX))
- {
- is_inside_flag |= BONESEL_ROOT;
- }
- }
- else {
- is_ignore_flag |= BONESEL_ROOT;
- }
+ LassoSelectUserData *data = userData;
+ bArmature *arm = data->vc->obedit->data;
+ if (EBONE_VISIBLE(arm, ebone)) {
+ int is_ignore_flag = 0;
+ int is_inside_flag = 0;
- if (screen_co_b[0] != IS_CLIPPED) {
- if (BLI_rcti_isect_pt(data->rect, UNPACK2(screen_co_b)) &&
- BLI_lasso_is_point_inside(data->mcords, data->moves, UNPACK2(screen_co_b), INT_MAX))
- {
- is_inside_flag |= BONESEL_TIP;
- }
- }
- else {
- is_ignore_flag |= BONESEL_TIP;
- }
+ if (screen_co_a[0] != IS_CLIPPED) {
+ if (BLI_rcti_isect_pt(data->rect, UNPACK2(screen_co_a)) &&
+ BLI_lasso_is_point_inside(data->mcords, data->moves, UNPACK2(screen_co_a), INT_MAX)) {
+ is_inside_flag |= BONESEL_ROOT;
+ }
+ }
+ else {
+ is_ignore_flag |= BONESEL_ROOT;
+ }
- if (is_inside_flag == (BONE_ROOTSEL | BONE_TIPSEL) ||
- BLI_lasso_is_edge_inside(
- data->mcords, data->moves, UNPACK2(screen_co_a), UNPACK2(screen_co_b), INT_MAX))
- {
- is_inside_flag |= BONESEL_BONE;
- }
+ if (screen_co_b[0] != IS_CLIPPED) {
+ if (BLI_rcti_isect_pt(data->rect, UNPACK2(screen_co_b)) &&
+ BLI_lasso_is_point_inside(data->mcords, data->moves, UNPACK2(screen_co_b), INT_MAX)) {
+ is_inside_flag |= BONESEL_TIP;
+ }
+ }
+ else {
+ is_ignore_flag |= BONESEL_TIP;
+ }
+ if (is_inside_flag == (BONE_ROOTSEL | BONE_TIPSEL) ||
+ BLI_lasso_is_edge_inside(
+ data->mcords, data->moves, UNPACK2(screen_co_a), UNPACK2(screen_co_b), INT_MAX)) {
+ is_inside_flag |= BONESEL_BONE;
+ }
- ebone->temp.i = is_inside_flag | (is_ignore_flag >> 16);
- }
+ ebone->temp.i = is_inside_flag | (is_ignore_flag >> 16);
+ }
}
-static bool do_lasso_select_armature(ViewContext *vc, const int mcords[][2], short moves, const eSelectOp sel_op)
+static bool do_lasso_select_armature(ViewContext *vc,
+ const int mcords[][2],
+ short moves,
+ const eSelectOp sel_op)
{
- LassoSelectUserData data;
- rcti rect;
+ LassoSelectUserData data;
+ rcti rect;
- BLI_lasso_boundbox(&rect, mcords, moves);
+ BLI_lasso_boundbox(&rect, mcords, moves);
- view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, sel_op);
+ view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, sel_op);
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- data.is_changed |= ED_armature_edit_deselect_all_visible(vc->obedit);
- }
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ data.is_changed |= ED_armature_edit_deselect_all_visible(vc->obedit);
+ }
- bArmature *arm = vc->obedit->data;
+ bArmature *arm = vc->obedit->data;
- ED_armature_ebone_listbase_temp_clear(arm->edbo);
+ ED_armature_ebone_listbase_temp_clear(arm->edbo);
- ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- armature_foreachScreenBone(vc, do_lasso_select_armature__doSelectBone, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ armature_foreachScreenBone(
+ vc, do_lasso_select_armature__doSelectBone, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
- data.is_changed |= ED_armature_edit_select_op_from_tagged(vc->obedit->data, sel_op);
+ data.is_changed |= ED_armature_edit_select_op_from_tagged(vc->obedit->data, sel_op);
- if (data.is_changed) {
- WM_main_add_notifier(NC_OBJECT | ND_BONE_SELECT, vc->obedit);
- }
- return data.is_changed;
+ if (data.is_changed) {
+ WM_main_add_notifier(NC_OBJECT | ND_BONE_SELECT, vc->obedit);
+ }
+ return data.is_changed;
}
-static void do_lasso_select_mball__doSelectElem(void *userData, struct MetaElem *ml, const float screen_co[2])
+static void do_lasso_select_mball__doSelectElem(void *userData,
+ struct MetaElem *ml,
+ const float screen_co[2])
{
- LassoSelectUserData *data = userData;
- const bool is_select = ml->flag & SELECT;
- const bool is_inside = (
- BLI_rctf_isect_pt_v(data->rect_fl, screen_co) &&
- BLI_lasso_is_point_inside(data->mcords, data->moves, screen_co[0], screen_co[1], INT_MAX));
- const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- SET_FLAG_FROM_TEST(ml->flag, sel_op_result, SELECT);
- data->is_changed = true;
- }
+ LassoSelectUserData *data = userData;
+ const bool is_select = ml->flag & SELECT;
+ const bool is_inside = (BLI_rctf_isect_pt_v(data->rect_fl, screen_co) &&
+ BLI_lasso_is_point_inside(
+ data->mcords, data->moves, screen_co[0], screen_co[1], INT_MAX));
+ const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
+ if (sel_op_result != -1) {
+ SET_FLAG_FROM_TEST(ml->flag, sel_op_result, SELECT);
+ data->is_changed = true;
+ }
}
-static bool do_lasso_select_meta(ViewContext *vc, const int mcords[][2], short moves, const eSelectOp sel_op)
+static bool do_lasso_select_meta(ViewContext *vc,
+ const int mcords[][2],
+ short moves,
+ const eSelectOp sel_op)
{
- LassoSelectUserData data;
- rcti rect;
+ LassoSelectUserData data;
+ rcti rect;
- MetaBall *mb = (MetaBall *)vc->obedit->data;
+ MetaBall *mb = (MetaBall *)vc->obedit->data;
- BLI_lasso_boundbox(&rect, mcords, moves);
+ BLI_lasso_boundbox(&rect, mcords, moves);
- view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, sel_op);
+ view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, sel_op);
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- data.is_changed |= BKE_mball_deselect_all(mb);
- }
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ data.is_changed |= BKE_mball_deselect_all(mb);
+ }
- ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- mball_foreachScreenElem(vc, do_lasso_select_mball__doSelectElem, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ mball_foreachScreenElem(
+ vc, do_lasso_select_mball__doSelectElem, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
- return data.is_changed;
+ return data.is_changed;
}
-static void do_lasso_select_meshobject__doSelectVert(void *userData, MVert *mv, const float screen_co[2], int UNUSED(index))
+static void do_lasso_select_meshobject__doSelectVert(void *userData,
+ MVert *mv,
+ const float screen_co[2],
+ int UNUSED(index))
{
- LassoSelectUserData *data = userData;
- const bool is_select = mv->flag & SELECT;
- const bool is_inside = (
- BLI_rctf_isect_pt_v(data->rect_fl, screen_co) &&
- BLI_lasso_is_point_inside(data->mcords, data->moves, screen_co[0], screen_co[1], IS_CLIPPED));
- const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- SET_FLAG_FROM_TEST(mv->flag, sel_op_result, SELECT);
- data->is_changed = true;
- }
+ LassoSelectUserData *data = userData;
+ const bool is_select = mv->flag & SELECT;
+ const bool is_inside = (BLI_rctf_isect_pt_v(data->rect_fl, screen_co) &&
+ BLI_lasso_is_point_inside(
+ data->mcords, data->moves, screen_co[0], screen_co[1], IS_CLIPPED));
+ const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
+ if (sel_op_result != -1) {
+ SET_FLAG_FROM_TEST(mv->flag, sel_op_result, SELECT);
+ data->is_changed = true;
+ }
}
-static bool do_lasso_select_paintvert(ViewContext *vc, const int mcords[][2], short moves, const eSelectOp sel_op)
+static bool do_lasso_select_paintvert(ViewContext *vc,
+ const int mcords[][2],
+ short moves,
+ const eSelectOp sel_op)
{
- const bool use_zbuf = !XRAY_ENABLED(vc->v3d);
- Object *ob = vc->obact;
- Mesh *me = ob->data;
- rcti rect;
+ const bool use_zbuf = !XRAY_ENABLED(vc->v3d);
+ Object *ob = vc->obact;
+ Mesh *me = ob->data;
+ rcti rect;
- if (me == NULL || me->totvert == 0) {
- return false;
- }
+ if (me == NULL || me->totvert == 0) {
+ return false;
+ }
- bool changed = false;
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- /* flush selection at the end */
- changed |= paintvert_deselect_all_visible(ob, SEL_DESELECT, false);
- }
+ bool changed = false;
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ /* flush selection at the end */
+ changed |= paintvert_deselect_all_visible(ob, SEL_DESELECT, false);
+ }
- BLI_lasso_boundbox(&rect, mcords, moves);
+ BLI_lasso_boundbox(&rect, mcords, moves);
- if (use_zbuf) {
- bm_vertoffs = me->totvert + 1; /* max index array */
+ if (use_zbuf) {
+ bm_vertoffs = me->totvert + 1; /* max index array */
- EDBM_backbuf_border_mask_init(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
+ EDBM_backbuf_border_mask_init(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
- changed |= edbm_backbuf_check_and_select_verts_obmode(me, sel_op);
+ changed |= edbm_backbuf_check_and_select_verts_obmode(me, sel_op);
- EDBM_backbuf_free();
- }
- else {
- LassoSelectUserData data;
+ EDBM_backbuf_free();
+ }
+ else {
+ LassoSelectUserData data;
- view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, sel_op);
+ view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, sel_op);
- ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d);
+ ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d);
- meshobject_foreachScreenVert(vc, do_lasso_select_meshobject__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ meshobject_foreachScreenVert(
+ vc, do_lasso_select_meshobject__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
- changed |= data.is_changed;
- }
+ changed |= data.is_changed;
+ }
- if (changed) {
- if (SEL_OP_CAN_DESELECT(sel_op)) {
- BKE_mesh_mselect_validate(me);
- }
- paintvert_flush_flags(ob);
- paintvert_tag_select_update(vc->C, ob);
- }
- return changed;
+ if (changed) {
+ if (SEL_OP_CAN_DESELECT(sel_op)) {
+ BKE_mesh_mselect_validate(me);
+ }
+ paintvert_flush_flags(ob);
+ paintvert_tag_select_update(vc->C, ob);
+ }
+ return changed;
}
-static bool do_lasso_select_paintface(ViewContext *vc, const int mcords[][2], short moves, const eSelectOp sel_op)
+static bool do_lasso_select_paintface(ViewContext *vc,
+ const int mcords[][2],
+ short moves,
+ const eSelectOp sel_op)
{
- Object *ob = vc->obact;
- Mesh *me = ob->data;
- rcti rect;
+ Object *ob = vc->obact;
+ Mesh *me = ob->data;
+ rcti rect;
- if (me == NULL || me->totpoly == 0) {
- return false;
- }
+ if (me == NULL || me->totpoly == 0) {
+ return false;
+ }
- bm_vertoffs = me->totpoly + 1; /* max index array */
+ bm_vertoffs = me->totpoly + 1; /* max index array */
- BLI_lasso_boundbox(&rect, mcords, moves);
- EDBM_backbuf_border_mask_init(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
+ BLI_lasso_boundbox(&rect, mcords, moves);
+ EDBM_backbuf_border_mask_init(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
- bool changed = false;
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- /* flush selection at the end */
- changed |= paintface_deselect_all_visible(vc->C, ob, SEL_DESELECT, false);
- }
- changed |= edbm_backbuf_check_and_select_tfaces(me, sel_op);
+ bool changed = false;
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ /* flush selection at the end */
+ changed |= paintface_deselect_all_visible(vc->C, ob, SEL_DESELECT, false);
+ }
+ changed |= edbm_backbuf_check_and_select_tfaces(me, sel_op);
- EDBM_backbuf_free();
+ EDBM_backbuf_free();
- if (changed) {
- paintface_flush_flags(vc->C, ob, SELECT);
- }
- return changed;
+ if (changed) {
+ paintface_flush_flags(vc->C, ob, SELECT);
+ }
+ return changed;
}
#if 0
static void do_lasso_select_node(int mcords[][2], short moves, const eSelectOp sel_op)
{
- SpaceNode *snode = sa->spacedata.first;
-
- bNode *node;
- rcti rect;
- int node_cent[2];
- float node_centf[2];
- bool changed = false;
-
- BLI_lasso_boundbox(&rect, mcords, moves);
-
- /* store selection in temp test flag */
- for (node = snode->edittree->nodes.first; node; node = node->next) {
- node_centf[0] = BLI_RCT_CENTER_X(&node->totr);
- node_centf[1] = BLI_RCT_CENTER_Y(&node->totr);
-
- ipoco_to_areaco_noclip(G.v2d, node_centf, node_cent);
- const bool is_select = node->flag & SELECT;
- const bool is_inside = (
- BLI_rcti_isect_pt_v(&rect, node_cent) &&
- BLI_lasso_is_point_inside(mcords, moves, node_cent[0], node_cent[1]));
- const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- SET_FLAG_FROM_TEST(node->flag, sel_op_result, SELECT);
- changed = true;
- }
- }
- if (changed) {
- BIF_undo_push("Lasso select nodes");
- }
+ SpaceNode *snode = sa->spacedata.first;
+
+ bNode *node;
+ rcti rect;
+ int node_cent[2];
+ float node_centf[2];
+ bool changed = false;
+
+ BLI_lasso_boundbox(&rect, mcords, moves);
+
+ /* store selection in temp test flag */
+ for (node = snode->edittree->nodes.first; node; node = node->next) {
+ node_centf[0] = BLI_RCT_CENTER_X(&node->totr);
+ node_centf[1] = BLI_RCT_CENTER_Y(&node->totr);
+
+ ipoco_to_areaco_noclip(G.v2d, node_centf, node_cent);
+ const bool is_select = node->flag & SELECT;
+ const bool is_inside = (
+ BLI_rcti_isect_pt_v(&rect, node_cent) &&
+ BLI_lasso_is_point_inside(mcords, moves, node_cent[0], node_cent[1]));
+ const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
+ if (sel_op_result != -1) {
+ SET_FLAG_FROM_TEST(node->flag, sel_op_result, SELECT);
+ changed = true;
+ }
+ }
+ if (changed) {
+ BIF_undo_push("Lasso select nodes");
+ }
}
#endif
static bool view3d_lasso_select(
- bContext *C, ViewContext *vc,
- const int mcords[][2], short moves,
- const eSelectOp sel_op)
-{
- Object *ob = CTX_data_active_object(C);
- bool changed_multi = false;
-
- if (vc->obedit == NULL) { /* Object Mode */
- if (BKE_paint_select_face_test(ob)) {
- changed_multi |= do_lasso_select_paintface(vc, mcords, moves, sel_op);
- }
- else if (BKE_paint_select_vert_test(ob)) {
- changed_multi |= do_lasso_select_paintvert(vc, mcords, moves, sel_op);
- }
- else if (ob && (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))) {
- /* pass */
- }
- else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT)) {
- changed_multi |= PE_lasso_select(C, mcords, moves, sel_op);
- }
- else if (ob && (ob->mode & OB_MODE_POSE)) {
- changed_multi |= do_lasso_select_pose(vc, mcords, moves, sel_op);
- }
- else {
- changed_multi |= do_lasso_select_objects(vc, mcords, moves, sel_op);
- }
- }
- else { /* Edit Mode */
-
- FOREACH_OBJECT_IN_MODE_BEGIN (vc->view_layer, vc->v3d, ob->type, ob->mode, ob_iter) {
- ED_view3d_viewcontext_init_object(vc, ob_iter);
- bool changed = false;
-
- switch (vc->obedit->type) {
- case OB_MESH:
- changed = do_lasso_select_mesh(vc, mcords, moves, sel_op);
- break;
- case OB_CURVE:
- case OB_SURF:
- changed = do_lasso_select_curve(vc, mcords, moves, sel_op);
- break;
- case OB_LATTICE:
- changed = do_lasso_select_lattice(vc, mcords, moves, sel_op);
- break;
- case OB_ARMATURE:
- changed = do_lasso_select_armature(vc, mcords, moves, sel_op);
- break;
- case OB_MBALL:
- changed = do_lasso_select_meta(vc, mcords, moves, sel_op);
- break;
- default:
- assert(!"lasso select on incorrect object type");
- break;
- }
-
- if (changed) {
- DEG_id_tag_update(vc->obedit->data, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc->obedit->data);
- changed_multi = true;
- }
- }
- FOREACH_OBJECT_IN_MODE_END;
- }
- return changed_multi;
+ bContext *C, ViewContext *vc, const int mcords[][2], short moves, const eSelectOp sel_op)
+{
+ Object *ob = CTX_data_active_object(C);
+ bool changed_multi = false;
+
+ if (vc->obedit == NULL) { /* Object Mode */
+ if (BKE_paint_select_face_test(ob)) {
+ changed_multi |= do_lasso_select_paintface(vc, mcords, moves, sel_op);
+ }
+ else if (BKE_paint_select_vert_test(ob)) {
+ changed_multi |= do_lasso_select_paintvert(vc, mcords, moves, sel_op);
+ }
+ else if (ob &&
+ (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))) {
+ /* pass */
+ }
+ else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT)) {
+ changed_multi |= PE_lasso_select(C, mcords, moves, sel_op);
+ }
+ else if (ob && (ob->mode & OB_MODE_POSE)) {
+ changed_multi |= do_lasso_select_pose(vc, mcords, moves, sel_op);
+ }
+ else {
+ changed_multi |= do_lasso_select_objects(vc, mcords, moves, sel_op);
+ }
+ }
+ else { /* Edit Mode */
+
+ FOREACH_OBJECT_IN_MODE_BEGIN (vc->view_layer, vc->v3d, ob->type, ob->mode, ob_iter) {
+ ED_view3d_viewcontext_init_object(vc, ob_iter);
+ bool changed = false;
+
+ switch (vc->obedit->type) {
+ case OB_MESH:
+ changed = do_lasso_select_mesh(vc, mcords, moves, sel_op);
+ break;
+ case OB_CURVE:
+ case OB_SURF:
+ changed = do_lasso_select_curve(vc, mcords, moves, sel_op);
+ break;
+ case OB_LATTICE:
+ changed = do_lasso_select_lattice(vc, mcords, moves, sel_op);
+ break;
+ case OB_ARMATURE:
+ changed = do_lasso_select_armature(vc, mcords, moves, sel_op);
+ break;
+ case OB_MBALL:
+ changed = do_lasso_select_meta(vc, mcords, moves, sel_op);
+ break;
+ default:
+ assert(!"lasso select on incorrect object type");
+ break;
+ }
+
+ if (changed) {
+ DEG_id_tag_update(vc->obedit->data, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc->obedit->data);
+ changed_multi = true;
+ }
+ }
+ FOREACH_OBJECT_IN_MODE_END;
+ }
+ return changed_multi;
}
-
/* lasso operator gives properties, but since old code works
* with short array we convert */
static int view3d_lasso_select_exec(bContext *C, wmOperator *op)
{
- ViewContext vc;
- int mcords_tot;
- const int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot);
+ ViewContext vc;
+ int mcords_tot;
+ const int(*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot);
- if (mcords) {
- view3d_operator_needs_opengl(C);
+ if (mcords) {
+ view3d_operator_needs_opengl(C);
- /* setup view context for argument to callbacks */
- ED_view3d_viewcontext_init(C, &vc);
+ /* setup view context for argument to callbacks */
+ ED_view3d_viewcontext_init(C, &vc);
- eSelectOp sel_op = RNA_enum_get(op->ptr, "mode");
- bool changed_multi = view3d_lasso_select(C, &vc, mcords, mcords_tot, sel_op);
+ eSelectOp sel_op = RNA_enum_get(op->ptr, "mode");
+ bool changed_multi = view3d_lasso_select(C, &vc, mcords, mcords_tot, sel_op);
- MEM_freeN((void *)mcords);
+ MEM_freeN((void *)mcords);
- if (changed_multi) {
- return OPERATOR_FINISHED;
- }
- else {
- return OPERATOR_CANCELLED;
- }
- }
- return OPERATOR_PASS_THROUGH;
+ if (changed_multi) {
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
+ }
+ return OPERATOR_PASS_THROUGH;
}
void VIEW3D_OT_select_lasso(wmOperatorType *ot)
{
- ot->name = "Lasso Select";
- ot->description = "Select items using lasso selection";
- ot->idname = "VIEW3D_OT_select_lasso";
+ ot->name = "Lasso Select";
+ ot->description = "Select items using lasso selection";
+ ot->idname = "VIEW3D_OT_select_lasso";
- ot->invoke = WM_gesture_lasso_invoke;
- ot->modal = WM_gesture_lasso_modal;
- ot->exec = view3d_lasso_select_exec;
- ot->poll = view3d_selectable_data;
- ot->cancel = WM_gesture_lasso_cancel;
+ ot->invoke = WM_gesture_lasso_invoke;
+ ot->modal = WM_gesture_lasso_modal;
+ ot->exec = view3d_lasso_select_exec;
+ ot->poll = view3d_selectable_data;
+ ot->cancel = WM_gesture_lasso_cancel;
- /* flags */
- ot->flag = OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
- /* properties */
- WM_operator_properties_gesture_lasso(ot);
- WM_operator_properties_select_operation(ot);
+ /* properties */
+ WM_operator_properties_gesture_lasso(ot);
+ WM_operator_properties_select_operation(ot);
}
/** \} */
@@ -1180,1015 +1218,1068 @@ void VIEW3D_OT_select_lasso(wmOperatorType *ot)
/* The max number of menu items in an object select menu */
typedef struct SelMenuItemF {
- char idname[MAX_ID_NAME - 2];
- int icon;
+ char idname[MAX_ID_NAME - 2];
+ int icon;
} SelMenuItemF;
-#define SEL_MENU_SIZE 22
+#define SEL_MENU_SIZE 22
static SelMenuItemF object_mouse_select_menu_data[SEL_MENU_SIZE];
/* special (crappy) operator only for menu select */
-static const EnumPropertyItem *object_select_menu_enum_itemf(
- bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
+static const EnumPropertyItem *object_select_menu_enum_itemf(bContext *C,
+ PointerRNA *UNUSED(ptr),
+ PropertyRNA *UNUSED(prop),
+ bool *r_free)
{
- EnumPropertyItem *item = NULL, item_tmp = {0};
- int totitem = 0;
- int i = 0;
+ EnumPropertyItem *item = NULL, item_tmp = {0};
+ int totitem = 0;
+ int i = 0;
- /* don't need context but avoid docgen using this */
- if (C == NULL || object_mouse_select_menu_data[i].idname[0] == '\0') {
- return DummyRNA_NULL_items;
- }
+ /* don't need context but avoid docgen using this */
+ if (C == NULL || object_mouse_select_menu_data[i].idname[0] == '\0') {
+ return DummyRNA_NULL_items;
+ }
- for (; i < SEL_MENU_SIZE && object_mouse_select_menu_data[i].idname[0] != '\0'; i++) {
- item_tmp.name = object_mouse_select_menu_data[i].idname;
- item_tmp.identifier = object_mouse_select_menu_data[i].idname;
- item_tmp.value = i;
- item_tmp.icon = object_mouse_select_menu_data[i].icon;
- RNA_enum_item_add(&item, &totitem, &item_tmp);
- }
+ for (; i < SEL_MENU_SIZE && object_mouse_select_menu_data[i].idname[0] != '\0'; i++) {
+ item_tmp.name = object_mouse_select_menu_data[i].idname;
+ item_tmp.identifier = object_mouse_select_menu_data[i].idname;
+ item_tmp.value = i;
+ item_tmp.icon = object_mouse_select_menu_data[i].icon;
+ RNA_enum_item_add(&item, &totitem, &item_tmp);
+ }
- RNA_enum_item_end(&item, &totitem);
- *r_free = true;
+ RNA_enum_item_end(&item, &totitem);
+ *r_free = true;
- return item;
+ return item;
}
static int object_select_menu_exec(bContext *C, wmOperator *op)
{
- const int name_index = RNA_enum_get(op->ptr, "name");
- const bool toggle = RNA_boolean_get(op->ptr, "toggle");
- bool changed = false;
- const char *name = object_mouse_select_menu_data[name_index].idname;
-
- if (!toggle) {
- CTX_DATA_BEGIN (C, Base *, base, selectable_bases)
- {
- if ((base->flag & BASE_SELECTED) != 0) {
- ED_object_base_select(base, BA_DESELECT);
- changed = true;
- }
- }
- CTX_DATA_END;
- }
-
- CTX_DATA_BEGIN (C, Base *, base, selectable_bases)
- {
- /* This is a bit dodgy, there should only be ONE object with this name,
- * but library objects can mess this up. */
- if (STREQ(name, base->object->id.name + 2)) {
- ED_object_base_activate(C, base);
- ED_object_base_select(base, BA_SELECT);
- changed = true;
- }
- }
- CTX_DATA_END;
-
- /* weak but ensures we activate menu again before using the enum */
- memset(object_mouse_select_menu_data, 0, sizeof(object_mouse_select_menu_data));
-
- /* undo? */
- if (changed) {
- Scene *scene = CTX_data_scene(C);
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- return OPERATOR_FINISHED;
- }
- else {
- return OPERATOR_CANCELLED;
- }
+ const int name_index = RNA_enum_get(op->ptr, "name");
+ const bool toggle = RNA_boolean_get(op->ptr, "toggle");
+ bool changed = false;
+ const char *name = object_mouse_select_menu_data[name_index].idname;
+
+ if (!toggle) {
+ CTX_DATA_BEGIN (C, Base *, base, selectable_bases) {
+ if ((base->flag & BASE_SELECTED) != 0) {
+ ED_object_base_select(base, BA_DESELECT);
+ changed = true;
+ }
+ }
+ CTX_DATA_END;
+ }
+
+ CTX_DATA_BEGIN (C, Base *, base, selectable_bases) {
+ /* This is a bit dodgy, there should only be ONE object with this name,
+ * but library objects can mess this up. */
+ if (STREQ(name, base->object->id.name + 2)) {
+ ED_object_base_activate(C, base);
+ ED_object_base_select(base, BA_SELECT);
+ changed = true;
+ }
+ }
+ CTX_DATA_END;
+
+ /* weak but ensures we activate menu again before using the enum */
+ memset(object_mouse_select_menu_data, 0, sizeof(object_mouse_select_menu_data));
+
+ /* undo? */
+ if (changed) {
+ Scene *scene = CTX_data_scene(C);
+ DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
void VIEW3D_OT_select_menu(wmOperatorType *ot)
{
- PropertyRNA *prop;
+ PropertyRNA *prop;
- /* identifiers */
- ot->name = "Select Menu";
- ot->description = "Menu object selection";
- ot->idname = "VIEW3D_OT_select_menu";
+ /* identifiers */
+ ot->name = "Select Menu";
+ ot->description = "Menu object selection";
+ ot->idname = "VIEW3D_OT_select_menu";
- /* api callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = object_select_menu_exec;
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = object_select_menu_exec;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* keyingset to use (dynamic enum) */
- prop = RNA_def_enum(ot->srna, "name", DummyRNA_NULL_items, 0, "Object Name", "");
- RNA_def_enum_funcs(prop, object_select_menu_enum_itemf);
- RNA_def_property_flag(prop, PROP_HIDDEN | PROP_ENUM_NO_TRANSLATE);
- ot->prop = prop;
+ /* keyingset to use (dynamic enum) */
+ prop = RNA_def_enum(ot->srna, "name", DummyRNA_NULL_items, 0, "Object Name", "");
+ RNA_def_enum_funcs(prop, object_select_menu_enum_itemf);
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_ENUM_NO_TRANSLATE);
+ ot->prop = prop;
- RNA_def_boolean(ot->srna, "toggle", 0, "Toggle", "Toggle selection instead of deselecting everything first");
+ RNA_def_boolean(
+ ot->srna, "toggle", 0, "Toggle", "Toggle selection instead of deselecting everything first");
}
static Base *object_mouse_select_menu(
- bContext *C, ViewContext *vc, uint *buffer, int hits,
- const int mval[2], bool toggle)
-{
- short baseCount = 0;
- bool ok;
- LinkNode *linklist = NULL;
-
- /* handle base->object->select_id */
- CTX_DATA_BEGIN (C, Base *, base, selectable_bases)
- {
- ok = false;
-
- /* two selection methods, the CTRL select uses max dist of 15 */
- if (buffer) {
- for (int a = 0; a < hits; a++) {
- /* index was converted */
- if (base->object->select_id == (buffer[(4 * a) + 3] & ~0xFFFF0000)) {
- ok = true;
- break;
- }
- }
- }
- else {
- const int dist = 15 * U.pixelsize;
- if (ED_view3d_project_base(vc->ar, base) == V3D_PROJ_RET_OK) {
- const int delta_px[2] = {base->sx - mval[0], base->sy - mval[1]};
- if (len_manhattan_v2_int(delta_px) < dist) {
- ok = true;
- }
- }
- }
-
- if (ok) {
- baseCount++;
- BLI_linklist_prepend(&linklist, base);
-
- if (baseCount == SEL_MENU_SIZE) {
- break;
- }
- }
- }
- CTX_DATA_END;
-
- if (baseCount == 0) {
- return NULL;
- }
- if (baseCount == 1) {
- Base *base = (Base *)linklist->link;
- BLI_linklist_free(linklist, NULL);
- return base;
- }
- else {
- /* UI, full in static array values that we later use in an enum function */
- LinkNode *node;
- int i;
-
- memset(object_mouse_select_menu_data, 0, sizeof(object_mouse_select_menu_data));
-
- for (node = linklist, i = 0; node; node = node->next, i++) {
- Base *base = node->link;
- Object *ob = base->object;
- const char *name = ob->id.name + 2;
-
- BLI_strncpy(object_mouse_select_menu_data[i].idname, name, MAX_ID_NAME - 2);
- object_mouse_select_menu_data[i].icon = UI_icon_from_id(&ob->id);
- }
-
- {
- wmOperatorType *ot = WM_operatortype_find("VIEW3D_OT_select_menu", false);
- PointerRNA ptr;
-
- WM_operator_properties_create_ptr(&ptr, ot);
- RNA_boolean_set(&ptr, "toggle", toggle);
- WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr);
- WM_operator_properties_free(&ptr);
- }
-
- BLI_linklist_free(linklist, NULL);
- return NULL;
- }
+ bContext *C, ViewContext *vc, uint *buffer, int hits, const int mval[2], bool toggle)
+{
+ short baseCount = 0;
+ bool ok;
+ LinkNode *linklist = NULL;
+
+ /* handle base->object->select_id */
+ CTX_DATA_BEGIN (C, Base *, base, selectable_bases) {
+ ok = false;
+
+ /* two selection methods, the CTRL select uses max dist of 15 */
+ if (buffer) {
+ for (int a = 0; a < hits; a++) {
+ /* index was converted */
+ if (base->object->select_id == (buffer[(4 * a) + 3] & ~0xFFFF0000)) {
+ ok = true;
+ break;
+ }
+ }
+ }
+ else {
+ const int dist = 15 * U.pixelsize;
+ if (ED_view3d_project_base(vc->ar, base) == V3D_PROJ_RET_OK) {
+ const int delta_px[2] = {base->sx - mval[0], base->sy - mval[1]};
+ if (len_manhattan_v2_int(delta_px) < dist) {
+ ok = true;
+ }
+ }
+ }
+
+ if (ok) {
+ baseCount++;
+ BLI_linklist_prepend(&linklist, base);
+
+ if (baseCount == SEL_MENU_SIZE) {
+ break;
+ }
+ }
+ }
+ CTX_DATA_END;
+
+ if (baseCount == 0) {
+ return NULL;
+ }
+ if (baseCount == 1) {
+ Base *base = (Base *)linklist->link;
+ BLI_linklist_free(linklist, NULL);
+ return base;
+ }
+ else {
+ /* UI, full in static array values that we later use in an enum function */
+ LinkNode *node;
+ int i;
+
+ memset(object_mouse_select_menu_data, 0, sizeof(object_mouse_select_menu_data));
+
+ for (node = linklist, i = 0; node; node = node->next, i++) {
+ Base *base = node->link;
+ Object *ob = base->object;
+ const char *name = ob->id.name + 2;
+
+ BLI_strncpy(object_mouse_select_menu_data[i].idname, name, MAX_ID_NAME - 2);
+ object_mouse_select_menu_data[i].icon = UI_icon_from_id(&ob->id);
+ }
+
+ {
+ wmOperatorType *ot = WM_operatortype_find("VIEW3D_OT_select_menu", false);
+ PointerRNA ptr;
+
+ WM_operator_properties_create_ptr(&ptr, ot);
+ RNA_boolean_set(&ptr, "toggle", toggle);
+ WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr);
+ WM_operator_properties_free(&ptr);
+ }
+
+ BLI_linklist_free(linklist, NULL);
+ return NULL;
+ }
}
static bool selectbuffer_has_bones(const uint *buffer, const uint hits)
{
- uint i;
- for (i = 0; i < hits; i++) {
- if (buffer[(4 * i) + 3] & 0xFFFF0000) {
- return true;
- }
- }
- return false;
+ uint i;
+ for (i = 0; i < hits; i++) {
+ if (buffer[(4 * i) + 3] & 0xFFFF0000) {
+ return true;
+ }
+ }
+ return false;
}
/* utility function for mixed_bones_object_selectbuffer */
static int selectbuffer_ret_hits_15(uint *UNUSED(buffer), const int hits15)
{
- return hits15;
+ return hits15;
}
static int selectbuffer_ret_hits_9(uint *buffer, const int hits15, const int hits9)
{
- const int offs = 4 * hits15;
- memcpy(buffer, buffer + offs, 4 * hits9 * sizeof(uint));
- return hits9;
+ const int offs = 4 * hits15;
+ memcpy(buffer, buffer + offs, 4 * hits9 * sizeof(uint));
+ return hits9;
}
-static int selectbuffer_ret_hits_5(uint *buffer, const int hits15, const int hits9, const int hits5)
+static int selectbuffer_ret_hits_5(uint *buffer,
+ const int hits15,
+ const int hits9,
+ const int hits5)
{
- const int offs = 4 * hits15 + 4 * hits9;
- memcpy(buffer, buffer + offs, 4 * hits5 * sizeof(uint));
- return hits5;
+ const int offs = 4 * hits15 + 4 * hits9;
+ memcpy(buffer, buffer + offs, 4 * hits5 * sizeof(uint));
+ return hits5;
}
/**
* Populate a select buffer with objects and bones, if there are any.
* Checks three selection levels and compare.
*/
-static int mixed_bones_object_selectbuffer(
- ViewContext *vc, uint *buffer, const int mval[2], eV3DSelectObjectFilter select_filter,
- bool do_nearest)
-{
- rcti rect;
- int hits15, hits9 = 0, hits5 = 0;
- bool has_bones15 = false, has_bones9 = false, has_bones5 = false;
-
- const int select_mode = (do_nearest ? VIEW3D_SELECT_PICK_NEAREST : VIEW3D_SELECT_PICK_ALL);
- int hits = 0;
-
- /* we _must_ end cache before return, use 'goto finally' */
- view3d_opengl_select_cache_begin();
-
- BLI_rcti_init_pt_radius(&rect, mval, 14);
- hits15 = view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect, select_mode, select_filter);
- if (hits15 == 1) {
- hits = selectbuffer_ret_hits_15(buffer, hits15);
- goto finally;
- }
- else if (hits15 > 0) {
- int offs;
- has_bones15 = selectbuffer_has_bones(buffer, hits15);
-
- offs = 4 * hits15;
- BLI_rcti_init_pt_radius(&rect, mval, 9);
- hits9 = view3d_opengl_select(vc, buffer + offs, MAXPICKBUF - offs, &rect, select_mode, select_filter);
- if (hits9 == 1) {
- hits = selectbuffer_ret_hits_9(buffer, hits15, hits9);
- goto finally;
- }
- else if (hits9 > 0) {
- has_bones9 = selectbuffer_has_bones(buffer + offs, hits9);
-
- offs += 4 * hits9;
- BLI_rcti_init_pt_radius(&rect, mval, 5);
- hits5 = view3d_opengl_select(vc, buffer + offs, MAXPICKBUF - offs, &rect, select_mode, select_filter);
- if (hits5 == 1) {
- hits = selectbuffer_ret_hits_5(buffer, hits15, hits9, hits5);
- goto finally;
- }
- else if (hits5 > 0) {
- has_bones5 = selectbuffer_has_bones(buffer + offs, hits5);
- }
- }
-
- if (has_bones5) { hits = selectbuffer_ret_hits_5(buffer, hits15, hits9, hits5); goto finally; }
- else if (has_bones9) { hits = selectbuffer_ret_hits_9(buffer, hits15, hits9); goto finally; }
- else if (has_bones15) { hits = selectbuffer_ret_hits_15(buffer, hits15); goto finally; }
-
- if (hits5 > 0) { hits = selectbuffer_ret_hits_5(buffer, hits15, hits9, hits5); goto finally; }
- else if (hits9 > 0) { hits = selectbuffer_ret_hits_9(buffer, hits15, hits9); goto finally; }
- else { hits = selectbuffer_ret_hits_15(buffer, hits15); goto finally; }
- }
+static int mixed_bones_object_selectbuffer(ViewContext *vc,
+ uint *buffer,
+ const int mval[2],
+ eV3DSelectObjectFilter select_filter,
+ bool do_nearest)
+{
+ rcti rect;
+ int hits15, hits9 = 0, hits5 = 0;
+ bool has_bones15 = false, has_bones9 = false, has_bones5 = false;
+
+ const int select_mode = (do_nearest ? VIEW3D_SELECT_PICK_NEAREST : VIEW3D_SELECT_PICK_ALL);
+ int hits = 0;
+
+ /* we _must_ end cache before return, use 'goto finally' */
+ view3d_opengl_select_cache_begin();
+
+ BLI_rcti_init_pt_radius(&rect, mval, 14);
+ hits15 = view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect, select_mode, select_filter);
+ if (hits15 == 1) {
+ hits = selectbuffer_ret_hits_15(buffer, hits15);
+ goto finally;
+ }
+ else if (hits15 > 0) {
+ int offs;
+ has_bones15 = selectbuffer_has_bones(buffer, hits15);
+
+ offs = 4 * hits15;
+ BLI_rcti_init_pt_radius(&rect, mval, 9);
+ hits9 = view3d_opengl_select(
+ vc, buffer + offs, MAXPICKBUF - offs, &rect, select_mode, select_filter);
+ if (hits9 == 1) {
+ hits = selectbuffer_ret_hits_9(buffer, hits15, hits9);
+ goto finally;
+ }
+ else if (hits9 > 0) {
+ has_bones9 = selectbuffer_has_bones(buffer + offs, hits9);
+
+ offs += 4 * hits9;
+ BLI_rcti_init_pt_radius(&rect, mval, 5);
+ hits5 = view3d_opengl_select(
+ vc, buffer + offs, MAXPICKBUF - offs, &rect, select_mode, select_filter);
+ if (hits5 == 1) {
+ hits = selectbuffer_ret_hits_5(buffer, hits15, hits9, hits5);
+ goto finally;
+ }
+ else if (hits5 > 0) {
+ has_bones5 = selectbuffer_has_bones(buffer + offs, hits5);
+ }
+ }
+
+ if (has_bones5) {
+ hits = selectbuffer_ret_hits_5(buffer, hits15, hits9, hits5);
+ goto finally;
+ }
+ else if (has_bones9) {
+ hits = selectbuffer_ret_hits_9(buffer, hits15, hits9);
+ goto finally;
+ }
+ else if (has_bones15) {
+ hits = selectbuffer_ret_hits_15(buffer, hits15);
+ goto finally;
+ }
+
+ if (hits5 > 0) {
+ hits = selectbuffer_ret_hits_5(buffer, hits15, hits9, hits5);
+ goto finally;
+ }
+ else if (hits9 > 0) {
+ hits = selectbuffer_ret_hits_9(buffer, hits15, hits9);
+ goto finally;
+ }
+ else {
+ hits = selectbuffer_ret_hits_15(buffer, hits15);
+ goto finally;
+ }
+ }
finally:
- view3d_opengl_select_cache_end();
- return hits;
-}
-
-static int mixed_bones_object_selectbuffer_extended(
- ViewContext *vc, uint *buffer, const int mval[2], eV3DSelectObjectFilter select_filter,
- bool use_cycle, bool enumerate, bool *r_do_nearest)
-{
- static int last_mval[2] = {-100, -100};
- bool do_nearest = false;
- View3D *v3d = vc->v3d;
-
- /* define if we use solid nearest select or not */
- if (use_cycle) {
- if (!XRAY_ACTIVE(v3d)) {
- do_nearest = true;
- if (len_manhattan_v2v2_int(mval, last_mval) <= WM_EVENT_CURSOR_MOTION_THRESHOLD) {
- do_nearest = false;
- }
- }
- copy_v2_v2_int(last_mval, mval);
- }
- else {
- if (!XRAY_ACTIVE(v3d)) {
- do_nearest = true;
- }
- }
-
- if (r_do_nearest) {
- *r_do_nearest = do_nearest;
- }
-
- do_nearest = do_nearest && !enumerate;
-
- int hits = mixed_bones_object_selectbuffer(vc, buffer, mval, select_filter, do_nearest);
-
- if (vc->scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK) {
- const bool is_pose_mode = (
- (vc->obact && vc->obact->mode & OB_MODE_POSE) ||
- (select_filter == VIEW3D_SELECT_FILTER_WPAINT_POSE_MODE_LOCK));
- struct {
- uint data[4];
- } *buffer4 = (void *)buffer;
- uint j = 0;
- for (uint i = 0; i < hits; i++) {
- if (((buffer4[i].data[3] & 0xFFFF0000) != 0) == is_pose_mode) {
- if (i != j) {
- buffer4[j] = buffer4[i];
- }
- j++;
- }
- }
- hits = j;
- }
-
- return hits;
+ view3d_opengl_select_cache_end();
+ return hits;
+}
+
+static int mixed_bones_object_selectbuffer_extended(ViewContext *vc,
+ uint *buffer,
+ const int mval[2],
+ eV3DSelectObjectFilter select_filter,
+ bool use_cycle,
+ bool enumerate,
+ bool *r_do_nearest)
+{
+ static int last_mval[2] = {-100, -100};
+ bool do_nearest = false;
+ View3D *v3d = vc->v3d;
+
+ /* define if we use solid nearest select or not */
+ if (use_cycle) {
+ if (!XRAY_ACTIVE(v3d)) {
+ do_nearest = true;
+ if (len_manhattan_v2v2_int(mval, last_mval) <= WM_EVENT_CURSOR_MOTION_THRESHOLD) {
+ do_nearest = false;
+ }
+ }
+ copy_v2_v2_int(last_mval, mval);
+ }
+ else {
+ if (!XRAY_ACTIVE(v3d)) {
+ do_nearest = true;
+ }
+ }
+
+ if (r_do_nearest) {
+ *r_do_nearest = do_nearest;
+ }
+
+ do_nearest = do_nearest && !enumerate;
+
+ int hits = mixed_bones_object_selectbuffer(vc, buffer, mval, select_filter, do_nearest);
+
+ if (vc->scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK) {
+ const bool is_pose_mode = ((vc->obact && vc->obact->mode & OB_MODE_POSE) ||
+ (select_filter == VIEW3D_SELECT_FILTER_WPAINT_POSE_MODE_LOCK));
+ struct {
+ uint data[4];
+ } *buffer4 = (void *)buffer;
+ uint j = 0;
+ for (uint i = 0; i < hits; i++) {
+ if (((buffer4[i].data[3] & 0xFFFF0000) != 0) == is_pose_mode) {
+ if (i != j) {
+ buffer4[j] = buffer4[i];
+ }
+ j++;
+ }
+ }
+ hits = j;
+ }
+
+ return hits;
}
/* returns basact */
-static Base *mouse_select_eval_buffer(
- ViewContext *vc, const uint *buffer, int hits,
- Base *startbase, bool has_bones, bool do_nearest)
-{
- ViewLayer *view_layer = vc->view_layer;
- View3D *v3d = vc->v3d;
- Base *base, *basact = NULL;
- int a;
-
- if (do_nearest) {
- uint min = 0xFFFFFFFF;
- int selcol = 0, notcol = 0;
-
-
- if (has_bones) {
- /* we skip non-bone hits */
- for (a = 0; a < hits; a++) {
- if (min > buffer[4 * a + 1] && (buffer[4 * a + 3] & 0xFFFF0000) ) {
- min = buffer[4 * a + 1];
- selcol = buffer[4 * a + 3] & 0xFFFF;
- }
- }
- }
- else {
- /* only exclude active object when it is selected... */
- if (BASACT(view_layer) && (BASACT(view_layer)->flag & BASE_SELECTED) && hits > 1) {
- notcol = BASACT(view_layer)->object->select_id;
- }
-
- for (a = 0; a < hits; a++) {
- if (min > buffer[4 * a + 1] && notcol != (buffer[4 * a + 3] & 0xFFFF)) {
- min = buffer[4 * a + 1];
- selcol = buffer[4 * a + 3] & 0xFFFF;
- }
- }
- }
-
- base = FIRSTBASE(view_layer);
- while (base) {
- if (BASE_SELECTABLE(v3d, base)) {
- if (base->object->select_id == selcol) {
- break;
- }
- }
- base = base->next;
- }
- if (base) {
- basact = base;
- }
- }
- else {
-
- base = startbase;
- while (base) {
- /* skip objects with select restriction, to prevent prematurely ending this loop
- * with an un-selectable choice */
- if ((base->flag & BASE_SELECTABLE) == 0) {
- base = base->next;
- if (base == NULL) {
- base = FIRSTBASE(view_layer);
- }
- if (base == startbase) {
- break;
- }
- }
-
- if (BASE_SELECTABLE(v3d, base)) {
- for (a = 0; a < hits; a++) {
- if (has_bones) {
- /* skip non-bone objects */
- if ((buffer[4 * a + 3] & 0xFFFF0000)) {
- if (base->object->select_id == (buffer[(4 * a) + 3] & 0xFFFF)) {
- basact = base;
- }
- }
- }
- else {
- if (base->object->select_id == (buffer[(4 * a) + 3] & 0xFFFF)) {
- basact = base;
- }
- }
- }
- }
-
- if (basact) {
- break;
- }
-
- base = base->next;
- if (base == NULL) {
- base = FIRSTBASE(view_layer);
- }
- if (base == startbase) {
- break;
- }
- }
- }
-
- return basact;
+static Base *mouse_select_eval_buffer(ViewContext *vc,
+ const uint *buffer,
+ int hits,
+ Base *startbase,
+ bool has_bones,
+ bool do_nearest)
+{
+ ViewLayer *view_layer = vc->view_layer;
+ View3D *v3d = vc->v3d;
+ Base *base, *basact = NULL;
+ int a;
+
+ if (do_nearest) {
+ uint min = 0xFFFFFFFF;
+ int selcol = 0, notcol = 0;
+
+ if (has_bones) {
+ /* we skip non-bone hits */
+ for (a = 0; a < hits; a++) {
+ if (min > buffer[4 * a + 1] && (buffer[4 * a + 3] & 0xFFFF0000)) {
+ min = buffer[4 * a + 1];
+ selcol = buffer[4 * a + 3] & 0xFFFF;
+ }
+ }
+ }
+ else {
+ /* only exclude active object when it is selected... */
+ if (BASACT(view_layer) && (BASACT(view_layer)->flag & BASE_SELECTED) && hits > 1) {
+ notcol = BASACT(view_layer)->object->select_id;
+ }
+
+ for (a = 0; a < hits; a++) {
+ if (min > buffer[4 * a + 1] && notcol != (buffer[4 * a + 3] & 0xFFFF)) {
+ min = buffer[4 * a + 1];
+ selcol = buffer[4 * a + 3] & 0xFFFF;
+ }
+ }
+ }
+
+ base = FIRSTBASE(view_layer);
+ while (base) {
+ if (BASE_SELECTABLE(v3d, base)) {
+ if (base->object->select_id == selcol) {
+ break;
+ }
+ }
+ base = base->next;
+ }
+ if (base) {
+ basact = base;
+ }
+ }
+ else {
+
+ base = startbase;
+ while (base) {
+ /* skip objects with select restriction, to prevent prematurely ending this loop
+ * with an un-selectable choice */
+ if ((base->flag & BASE_SELECTABLE) == 0) {
+ base = base->next;
+ if (base == NULL) {
+ base = FIRSTBASE(view_layer);
+ }
+ if (base == startbase) {
+ break;
+ }
+ }
+
+ if (BASE_SELECTABLE(v3d, base)) {
+ for (a = 0; a < hits; a++) {
+ if (has_bones) {
+ /* skip non-bone objects */
+ if ((buffer[4 * a + 3] & 0xFFFF0000)) {
+ if (base->object->select_id == (buffer[(4 * a) + 3] & 0xFFFF)) {
+ basact = base;
+ }
+ }
+ }
+ else {
+ if (base->object->select_id == (buffer[(4 * a) + 3] & 0xFFFF)) {
+ basact = base;
+ }
+ }
+ }
+ }
+
+ if (basact) {
+ break;
+ }
+
+ base = base->next;
+ if (base == NULL) {
+ base = FIRSTBASE(view_layer);
+ }
+ if (base == startbase) {
+ break;
+ }
+ }
+ }
+
+ return basact;
}
/* mval comes from event->mval, only use within region handlers */
Base *ED_view3d_give_base_under_cursor(bContext *C, const int mval[2])
{
- ViewContext vc;
- Base *basact = NULL;
- uint buffer[MAXPICKBUF];
+ ViewContext vc;
+ Base *basact = NULL;
+ uint buffer[MAXPICKBUF];
- /* setup view context for argument to callbacks */
- view3d_operator_needs_opengl(C);
+ /* setup view context for argument to callbacks */
+ view3d_operator_needs_opengl(C);
- ED_view3d_viewcontext_init(C, &vc);
+ ED_view3d_viewcontext_init(C, &vc);
- const bool do_nearest = !XRAY_ACTIVE(vc.v3d);
- const int hits = mixed_bones_object_selectbuffer(
- &vc, buffer, mval, VIEW3D_SELECT_FILTER_NOP, do_nearest);
+ const bool do_nearest = !XRAY_ACTIVE(vc.v3d);
+ const int hits = mixed_bones_object_selectbuffer(
+ &vc, buffer, mval, VIEW3D_SELECT_FILTER_NOP, do_nearest);
- if (hits > 0) {
- const bool has_bones = selectbuffer_has_bones(buffer, hits);
- basact = mouse_select_eval_buffer(&vc, buffer, hits, vc.view_layer->object_bases.first, has_bones, do_nearest);
- }
+ if (hits > 0) {
+ const bool has_bones = selectbuffer_has_bones(buffer, hits);
+ basact = mouse_select_eval_buffer(
+ &vc, buffer, hits, vc.view_layer->object_bases.first, has_bones, do_nearest);
+ }
- return basact;
+ return basact;
}
Object *ED_view3d_give_object_under_cursor(bContext *C, const int mval[2])
{
- Base *base = ED_view3d_give_base_under_cursor(C, mval);
- if (base) {
- return base->object;
- }
- return NULL;
+ Base *base = ED_view3d_give_base_under_cursor(C, mval);
+ if (base) {
+ return base->object;
+ }
+ return NULL;
}
bool ED_view3d_is_object_under_cursor(bContext *C, const int mval[2])
{
- return ED_view3d_give_object_under_cursor(C, mval) != NULL;
+ return ED_view3d_give_object_under_cursor(C, mval) != NULL;
}
static void deselect_all_tracks(MovieTracking *tracking)
{
- MovieTrackingObject *object;
+ MovieTrackingObject *object;
- object = tracking->objects.first;
- while (object) {
- ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
- MovieTrackingTrack *track = tracksbase->first;
+ object = tracking->objects.first;
+ while (object) {
+ ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
+ MovieTrackingTrack *track = tracksbase->first;
- while (track) {
- BKE_tracking_track_deselect(track, TRACK_AREA_ALL);
+ while (track) {
+ BKE_tracking_track_deselect(track, TRACK_AREA_ALL);
- track = track->next;
- }
+ track = track->next;
+ }
- object = object->next;
- }
+ object = object->next;
+ }
}
/* mval is region coords */
-static bool ed_object_select_pick(
- bContext *C, const int mval[2],
- bool extend, bool deselect, bool toggle, bool obcenter, bool enumerate, bool object)
-{
- ViewContext vc;
- /* setup view context for argument to callbacks */
- ED_view3d_viewcontext_init(C, &vc);
-
- ARegion *ar = CTX_wm_region(C);
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- View3D *v3d = CTX_wm_view3d(C);
- /* Don't set when the context has no active object (hidden), see: T60807. */
- const Base *oldbasact = vc.obact ? BASACT(view_layer) : NULL;
- Base *base, *startbase = NULL, *basact = NULL;
- const eObjectMode object_mode = oldbasact ? oldbasact->object->mode : OB_MODE_OBJECT;
- bool is_obedit;
- float dist = ED_view3d_select_dist_px() * 1.3333f;
- bool retval = false;
- int hits;
- const float mval_fl[2] = {(float)mval[0], (float)mval[1]};
-
-
- is_obedit = (vc.obedit != NULL);
- if (object) {
- /* signal for view3d_opengl_select to skip editmode objects */
- vc.obedit = NULL;
- }
-
- /* In pose mode we don't want to mess with object selection. */
- const bool is_pose_mode = (vc.obact && vc.obact->mode & OB_MODE_POSE);
-
- /* always start list from basact in wire mode */
- startbase = FIRSTBASE(view_layer);
- if (oldbasact && oldbasact->next) {
- startbase = oldbasact->next;
- }
-
- /* This block uses the control key to make the object selected
- * by its center point rather than its contents */
-
- /* in editmode do not activate */
- if (obcenter) {
-
- /* note; shift+alt goes to group-flush-selecting */
- if (enumerate) {
- basact = object_mouse_select_menu(C, &vc, NULL, 0, mval, toggle);
- }
- else {
- base = startbase;
- while (base) {
- if (BASE_SELECTABLE(v3d, base)) {
- float screen_co[2];
- if (ED_view3d_project_float_global(
- ar, base->object->obmat[3], screen_co,
- V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK)
- {
- float dist_temp = len_manhattan_v2v2(mval_fl, screen_co);
- if (base == oldbasact) {
- dist_temp += 10.0f;
- }
- if (dist_temp < dist) {
- dist = dist_temp;
- basact = base;
- }
- }
- }
- base = base->next;
-
- if (base == NULL) {
- base = FIRSTBASE(view_layer);
- }
- if (base == startbase) {
- break;
- }
- }
- }
- if (scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK) {
- if (is_obedit == false) {
- if (basact && !BKE_object_is_mode_compat(basact->object, object_mode)) {
- if (object_mode == OB_MODE_OBJECT) {
- struct Main *bmain = CTX_data_main(C);
- ED_object_mode_generic_exit(bmain, vc.depsgraph, scene, basact->object);
- }
- if (!BKE_object_is_mode_compat(basact->object, object_mode)) {
- basact = NULL;
- }
- }
- }
- }
- }
- else {
- uint buffer[MAXPICKBUF];
- bool do_nearest;
-
- // TIMEIT_START(select_time);
-
- /* if objects have posemode set, the bones are in the same selection buffer */
- const eV3DSelectObjectFilter select_filter = (
- (object == false) ? ED_view3d_select_filter_from_mode(scene, vc.obact) : VIEW3D_SELECT_FILTER_NOP);
- hits = mixed_bones_object_selectbuffer_extended(
- &vc, buffer, mval, select_filter,
- true, enumerate,
- &do_nearest);
-
- // TIMEIT_END(select_time);
-
- if (hits > 0) {
- /* note: bundles are handling in the same way as bones */
- const bool has_bones = selectbuffer_has_bones(buffer, hits);
-
- /* note; shift+alt goes to group-flush-selecting */
- if (enumerate) {
- basact = object_mouse_select_menu(C, &vc, buffer, hits, mval, toggle);
- }
- else {
- basact = mouse_select_eval_buffer(&vc, buffer, hits, startbase, has_bones, do_nearest);
- }
-
- if (has_bones && basact) {
- if (basact->object->type == OB_CAMERA) {
- if (oldbasact == basact) {
- int i, hitresult;
- bool changed = false;
-
- for (i = 0; i < hits; i++) {
- hitresult = buffer[3 + (i * 4)];
-
- /* if there's bundles in buffer select bundles first,
- * so non-camera elements should be ignored in buffer */
- if (basact->object->select_id != (hitresult & 0xFFFF)) {
- continue;
- }
-
- /* index of bundle is 1<<16-based. if there's no "bone" index
- * in height word, this buffer value belongs to camera. not to bundle
- */
- if (buffer[4 * i + 3] & 0xFFFF0000) {
- MovieClip *clip = BKE_object_movieclip_get(scene, basact->object, false);
- MovieTracking *tracking = &clip->tracking;
- ListBase *tracksbase;
- MovieTrackingTrack *track;
-
- track = BKE_tracking_track_get_indexed(&clip->tracking, hitresult >> 16, &tracksbase);
-
- if (TRACK_SELECTED(track) && extend) {
- changed = false;
- BKE_tracking_track_deselect(track, TRACK_AREA_ALL);
- }
- else {
- int oldsel = TRACK_SELECTED(track) ? 1 : 0;
- if (!extend) {
- deselect_all_tracks(tracking);
- }
-
- BKE_tracking_track_select(tracksbase, track, TRACK_AREA_ALL, extend);
-
- if (oldsel != (TRACK_SELECTED(track) ? 1 : 0)) {
- changed = true;
- }
- }
-
- basact->flag |= BASE_SELECTED;
- BKE_scene_object_base_flag_sync_from_base(basact);
-
- retval = true;
-
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
- DEG_id_tag_update(&clip->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_MOVIECLIP | ND_SELECT, track);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
-
- break;
- }
- }
-
- if (!changed) {
- /* fallback to regular object selection if no new bundles were selected,
- * allows to select object parented to reconstruction object */
- basact = mouse_select_eval_buffer(&vc, buffer, hits, startbase, 0, do_nearest);
- }
- }
- }
- else if (ED_armature_pose_select_pick_with_buffer(
- view_layer, v3d, basact, buffer, hits, extend, deselect, toggle, do_nearest))
- {
- /* then bone is found */
-
- /* we make the armature selected:
- * not-selected active object in posemode won't work well for tools */
- basact->flag |= BASE_SELECTED;
- BKE_scene_object_base_flag_sync_from_base(basact);
-
- retval = true;
- WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, basact->object);
- WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, basact->object);
-
- /* in weightpaint, we use selected bone to select vertexgroup,
- * so no switch to new active object */
- if (oldbasact && (oldbasact->object->mode & OB_MODE_WEIGHT_PAINT)) {
- /* prevent activating */
- basact = NULL;
- }
-
- }
- /* prevent bone selecting to pass on to object selecting */
- if (basact == oldbasact) {
- basact = NULL;
- }
- }
-
- if (scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK) {
- if (is_obedit == false) {
- if (basact && !BKE_object_is_mode_compat(basact->object, object_mode)) {
- if (object_mode == OB_MODE_OBJECT) {
- struct Main *bmain = CTX_data_main(C);
- ED_object_mode_generic_exit(bmain, vc.depsgraph, scene, basact->object);
- }
- if (!BKE_object_is_mode_compat(basact->object, object_mode)) {
- basact = NULL;
- }
- }
- }
- }
- }
- }
-
- if (scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK) {
- /* Disallow switching modes,
- * special exception for edit-mode - vertex-parent operator. */
- if (is_obedit == false) {
- if (oldbasact && basact) {
- if ((oldbasact->object->mode != basact->object->mode) &&
- (oldbasact->object->mode & basact->object->mode) == 0)
- {
- basact = NULL;
- }
- }
- }
- }
-
- /* Ensure code above doesn't change the active base. */
- BLI_assert(oldbasact == (vc.obact ? BASACT(view_layer) : NULL));
-
- /* so, do we have something selected? */
- if (basact) {
- retval = true;
-
- if (vc.obedit) {
- /* only do select */
- object_deselect_all_except(view_layer, basact);
- ED_object_base_select(basact, BA_SELECT);
- }
- /* also prevent making it active on mouse selection */
- else if (BASE_SELECTABLE(v3d, basact)) {
- if (extend) {
- ED_object_base_select(basact, BA_SELECT);
- }
- else if (deselect) {
- ED_object_base_select(basact, BA_DESELECT);
- }
- else if (toggle) {
- if (basact->flag & BASE_SELECTED) {
- if (basact == oldbasact) {
- ED_object_base_select(basact, BA_DESELECT);
- }
- }
- else {
- ED_object_base_select(basact, BA_SELECT);
- }
- }
- else {
- /* When enabled, this puts other objects out of multi pose-mode. */
- if (is_pose_mode == false) {
- object_deselect_all_except(view_layer, basact);
- ED_object_base_select(basact, BA_SELECT);
- }
- }
-
- if ((oldbasact != basact) && (is_obedit == false)) {
- ED_object_base_activate(C, basact); /* adds notifier */
- }
-
- /* Set special modes for grease pencil
- The grease pencil modes are not real modes, but a hack to make the interface
- consistent, so need some tricks to keep UI synchronized */
- // XXX: This stuff needs reviewing (Aligorith)
- if (false &&
- (((oldbasact) && oldbasact->object->type == OB_GPENCIL) ||
- (basact->object->type == OB_GPENCIL)))
- {
- /* set cursor */
- if (ELEM(basact->object->mode,
- OB_MODE_PAINT_GPENCIL,
- OB_MODE_SCULPT_GPENCIL,
- OB_MODE_WEIGHT_GPENCIL))
- {
- ED_gpencil_toggle_brush_cursor(C, true, NULL);
- }
- else {
- /* TODO: maybe is better use restore */
- ED_gpencil_toggle_brush_cursor(C, false, NULL);
- }
- }
- }
-
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- }
-
- return retval;
+static bool ed_object_select_pick(bContext *C,
+ const int mval[2],
+ bool extend,
+ bool deselect,
+ bool toggle,
+ bool obcenter,
+ bool enumerate,
+ bool object)
+{
+ ViewContext vc;
+ /* setup view context for argument to callbacks */
+ ED_view3d_viewcontext_init(C, &vc);
+
+ ARegion *ar = CTX_wm_region(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ /* Don't set when the context has no active object (hidden), see: T60807. */
+ const Base *oldbasact = vc.obact ? BASACT(view_layer) : NULL;
+ Base *base, *startbase = NULL, *basact = NULL;
+ const eObjectMode object_mode = oldbasact ? oldbasact->object->mode : OB_MODE_OBJECT;
+ bool is_obedit;
+ float dist = ED_view3d_select_dist_px() * 1.3333f;
+ bool retval = false;
+ int hits;
+ const float mval_fl[2] = {(float)mval[0], (float)mval[1]};
+
+ is_obedit = (vc.obedit != NULL);
+ if (object) {
+ /* signal for view3d_opengl_select to skip editmode objects */
+ vc.obedit = NULL;
+ }
+
+ /* In pose mode we don't want to mess with object selection. */
+ const bool is_pose_mode = (vc.obact && vc.obact->mode & OB_MODE_POSE);
+
+ /* always start list from basact in wire mode */
+ startbase = FIRSTBASE(view_layer);
+ if (oldbasact && oldbasact->next) {
+ startbase = oldbasact->next;
+ }
+
+ /* This block uses the control key to make the object selected
+ * by its center point rather than its contents */
+
+ /* in editmode do not activate */
+ if (obcenter) {
+
+ /* note; shift+alt goes to group-flush-selecting */
+ if (enumerate) {
+ basact = object_mouse_select_menu(C, &vc, NULL, 0, mval, toggle);
+ }
+ else {
+ base = startbase;
+ while (base) {
+ if (BASE_SELECTABLE(v3d, base)) {
+ float screen_co[2];
+ if (ED_view3d_project_float_global(ar,
+ base->object->obmat[3],
+ screen_co,
+ V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN |
+ V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK) {
+ float dist_temp = len_manhattan_v2v2(mval_fl, screen_co);
+ if (base == oldbasact) {
+ dist_temp += 10.0f;
+ }
+ if (dist_temp < dist) {
+ dist = dist_temp;
+ basact = base;
+ }
+ }
+ }
+ base = base->next;
+
+ if (base == NULL) {
+ base = FIRSTBASE(view_layer);
+ }
+ if (base == startbase) {
+ break;
+ }
+ }
+ }
+ if (scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK) {
+ if (is_obedit == false) {
+ if (basact && !BKE_object_is_mode_compat(basact->object, object_mode)) {
+ if (object_mode == OB_MODE_OBJECT) {
+ struct Main *bmain = CTX_data_main(C);
+ ED_object_mode_generic_exit(bmain, vc.depsgraph, scene, basact->object);
+ }
+ if (!BKE_object_is_mode_compat(basact->object, object_mode)) {
+ basact = NULL;
+ }
+ }
+ }
+ }
+ }
+ else {
+ uint buffer[MAXPICKBUF];
+ bool do_nearest;
+
+ // TIMEIT_START(select_time);
+
+ /* if objects have posemode set, the bones are in the same selection buffer */
+ const eV3DSelectObjectFilter select_filter = ((object == false) ?
+ ED_view3d_select_filter_from_mode(scene,
+ vc.obact) :
+ VIEW3D_SELECT_FILTER_NOP);
+ hits = mixed_bones_object_selectbuffer_extended(
+ &vc, buffer, mval, select_filter, true, enumerate, &do_nearest);
+
+ // TIMEIT_END(select_time);
+
+ if (hits > 0) {
+ /* note: bundles are handling in the same way as bones */
+ const bool has_bones = selectbuffer_has_bones(buffer, hits);
+
+ /* note; shift+alt goes to group-flush-selecting */
+ if (enumerate) {
+ basact = object_mouse_select_menu(C, &vc, buffer, hits, mval, toggle);
+ }
+ else {
+ basact = mouse_select_eval_buffer(&vc, buffer, hits, startbase, has_bones, do_nearest);
+ }
+
+ if (has_bones && basact) {
+ if (basact->object->type == OB_CAMERA) {
+ if (oldbasact == basact) {
+ int i, hitresult;
+ bool changed = false;
+
+ for (i = 0; i < hits; i++) {
+ hitresult = buffer[3 + (i * 4)];
+
+ /* if there's bundles in buffer select bundles first,
+ * so non-camera elements should be ignored in buffer */
+ if (basact->object->select_id != (hitresult & 0xFFFF)) {
+ continue;
+ }
+
+ /* index of bundle is 1<<16-based. if there's no "bone" index
+ * in height word, this buffer value belongs to camera. not to bundle
+ */
+ if (buffer[4 * i + 3] & 0xFFFF0000) {
+ MovieClip *clip = BKE_object_movieclip_get(scene, basact->object, false);
+ MovieTracking *tracking = &clip->tracking;
+ ListBase *tracksbase;
+ MovieTrackingTrack *track;
+
+ track = BKE_tracking_track_get_indexed(
+ &clip->tracking, hitresult >> 16, &tracksbase);
+
+ if (TRACK_SELECTED(track) && extend) {
+ changed = false;
+ BKE_tracking_track_deselect(track, TRACK_AREA_ALL);
+ }
+ else {
+ int oldsel = TRACK_SELECTED(track) ? 1 : 0;
+ if (!extend) {
+ deselect_all_tracks(tracking);
+ }
+
+ BKE_tracking_track_select(tracksbase, track, TRACK_AREA_ALL, extend);
+
+ if (oldsel != (TRACK_SELECTED(track) ? 1 : 0)) {
+ changed = true;
+ }
+ }
+
+ basact->flag |= BASE_SELECTED;
+ BKE_scene_object_base_flag_sync_from_base(basact);
+
+ retval = true;
+
+ DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
+ DEG_id_tag_update(&clip->id, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_MOVIECLIP | ND_SELECT, track);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+
+ break;
+ }
+ }
+
+ if (!changed) {
+ /* fallback to regular object selection if no new bundles were selected,
+ * allows to select object parented to reconstruction object */
+ basact = mouse_select_eval_buffer(&vc, buffer, hits, startbase, 0, do_nearest);
+ }
+ }
+ }
+ else if (ED_armature_pose_select_pick_with_buffer(view_layer,
+ v3d,
+ basact,
+ buffer,
+ hits,
+ extend,
+ deselect,
+ toggle,
+ do_nearest)) {
+ /* then bone is found */
+
+ /* we make the armature selected:
+ * not-selected active object in posemode won't work well for tools */
+ basact->flag |= BASE_SELECTED;
+ BKE_scene_object_base_flag_sync_from_base(basact);
+
+ retval = true;
+ WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, basact->object);
+ WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, basact->object);
+
+ /* in weightpaint, we use selected bone to select vertexgroup,
+ * so no switch to new active object */
+ if (oldbasact && (oldbasact->object->mode & OB_MODE_WEIGHT_PAINT)) {
+ /* prevent activating */
+ basact = NULL;
+ }
+ }
+ /* prevent bone selecting to pass on to object selecting */
+ if (basact == oldbasact) {
+ basact = NULL;
+ }
+ }
+
+ if (scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK) {
+ if (is_obedit == false) {
+ if (basact && !BKE_object_is_mode_compat(basact->object, object_mode)) {
+ if (object_mode == OB_MODE_OBJECT) {
+ struct Main *bmain = CTX_data_main(C);
+ ED_object_mode_generic_exit(bmain, vc.depsgraph, scene, basact->object);
+ }
+ if (!BKE_object_is_mode_compat(basact->object, object_mode)) {
+ basact = NULL;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK) {
+ /* Disallow switching modes,
+ * special exception for edit-mode - vertex-parent operator. */
+ if (is_obedit == false) {
+ if (oldbasact && basact) {
+ if ((oldbasact->object->mode != basact->object->mode) &&
+ (oldbasact->object->mode & basact->object->mode) == 0) {
+ basact = NULL;
+ }
+ }
+ }
+ }
+
+ /* Ensure code above doesn't change the active base. */
+ BLI_assert(oldbasact == (vc.obact ? BASACT(view_layer) : NULL));
+
+ /* so, do we have something selected? */
+ if (basact) {
+ retval = true;
+
+ if (vc.obedit) {
+ /* only do select */
+ object_deselect_all_except(view_layer, basact);
+ ED_object_base_select(basact, BA_SELECT);
+ }
+ /* also prevent making it active on mouse selection */
+ else if (BASE_SELECTABLE(v3d, basact)) {
+ if (extend) {
+ ED_object_base_select(basact, BA_SELECT);
+ }
+ else if (deselect) {
+ ED_object_base_select(basact, BA_DESELECT);
+ }
+ else if (toggle) {
+ if (basact->flag & BASE_SELECTED) {
+ if (basact == oldbasact) {
+ ED_object_base_select(basact, BA_DESELECT);
+ }
+ }
+ else {
+ ED_object_base_select(basact, BA_SELECT);
+ }
+ }
+ else {
+ /* When enabled, this puts other objects out of multi pose-mode. */
+ if (is_pose_mode == false) {
+ object_deselect_all_except(view_layer, basact);
+ ED_object_base_select(basact, BA_SELECT);
+ }
+ }
+
+ if ((oldbasact != basact) && (is_obedit == false)) {
+ ED_object_base_activate(C, basact); /* adds notifier */
+ }
+
+ /* Set special modes for grease pencil
+ The grease pencil modes are not real modes, but a hack to make the interface
+ consistent, so need some tricks to keep UI synchronized */
+ // XXX: This stuff needs reviewing (Aligorith)
+ if (false && (((oldbasact) && oldbasact->object->type == OB_GPENCIL) ||
+ (basact->object->type == OB_GPENCIL))) {
+ /* set cursor */
+ if (ELEM(basact->object->mode,
+ OB_MODE_PAINT_GPENCIL,
+ OB_MODE_SCULPT_GPENCIL,
+ OB_MODE_WEIGHT_GPENCIL)) {
+ ED_gpencil_toggle_brush_cursor(C, true, NULL);
+ }
+ else {
+ /* TODO: maybe is better use restore */
+ ED_gpencil_toggle_brush_cursor(C, false, NULL);
+ }
+ }
+ }
+
+ DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ }
+
+ return retval;
}
/* mouse selection in weight paint */
/* gets called via generic mouse select operator */
static bool ed_wpaint_vertex_select_pick(
- bContext *C, const int mval[2],
- bool extend, bool deselect, bool toggle, Object *obact)
-{
- View3D *v3d = CTX_wm_view3d(C);
- const bool use_zbuf = !XRAY_ENABLED(v3d);
-
- Mesh *me = obact->data; /* already checked for NULL */
- uint index = 0;
- MVert *mv;
-
- if (ED_mesh_pick_vert(C, obact, mval, ED_MESH_PICK_DEFAULT_VERT_DIST, use_zbuf, &index)) {
- mv = &me->mvert[index];
- if (extend) {
- mv->flag |= SELECT;
- }
- else if (deselect) {
- mv->flag &= ~SELECT;
- }
- else if (toggle) {
- mv->flag ^= SELECT;
- }
- else {
- paintvert_deselect_all_visible(obact, SEL_DESELECT, false);
- mv->flag |= SELECT;
- }
-
- /* update mselect */
- if (mv->flag & SELECT) {
- BKE_mesh_mselect_active_set(me, index, ME_VSEL);
- }
- else {
- BKE_mesh_mselect_validate(me);
- }
-
- paintvert_flush_flags(obact);
- paintvert_tag_select_update(C, obact);
- return true;
- }
- return false;
+ bContext *C, const int mval[2], bool extend, bool deselect, bool toggle, Object *obact)
+{
+ View3D *v3d = CTX_wm_view3d(C);
+ const bool use_zbuf = !XRAY_ENABLED(v3d);
+
+ Mesh *me = obact->data; /* already checked for NULL */
+ uint index = 0;
+ MVert *mv;
+
+ if (ED_mesh_pick_vert(C, obact, mval, ED_MESH_PICK_DEFAULT_VERT_DIST, use_zbuf, &index)) {
+ mv = &me->mvert[index];
+ if (extend) {
+ mv->flag |= SELECT;
+ }
+ else if (deselect) {
+ mv->flag &= ~SELECT;
+ }
+ else if (toggle) {
+ mv->flag ^= SELECT;
+ }
+ else {
+ paintvert_deselect_all_visible(obact, SEL_DESELECT, false);
+ mv->flag |= SELECT;
+ }
+
+ /* update mselect */
+ if (mv->flag & SELECT) {
+ BKE_mesh_mselect_active_set(me, index, ME_VSEL);
+ }
+ else {
+ BKE_mesh_mselect_validate(me);
+ }
+
+ paintvert_flush_flags(obact);
+ paintvert_tag_select_update(C, obact);
+ return true;
+ }
+ return false;
}
static int view3d_select_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
- Object *obedit = CTX_data_edit_object(C);
- Object *obact = CTX_data_active_object(C);
- bool extend = RNA_boolean_get(op->ptr, "extend");
- bool deselect = RNA_boolean_get(op->ptr, "deselect");
- bool deselect_all = RNA_boolean_get(op->ptr, "deselect_all");
- bool toggle = RNA_boolean_get(op->ptr, "toggle");
- bool center = RNA_boolean_get(op->ptr, "center");
- bool enumerate = RNA_boolean_get(op->ptr, "enumerate");
- /* only force object select for editmode to support vertex parenting,
- * or paint-select to allow pose bone select with vert/face select */
- bool object = (RNA_boolean_get(op->ptr, "object") &&
- (obedit ||
- BKE_paint_select_elem_test(obact) ||
- /* so its possible to select bones in weightpaint mode (LMB select) */
- (obact && (obact->mode & OB_MODE_WEIGHT_PAINT) && BKE_object_pose_armature_get(obact))));
-
- bool retval = false;
- int location[2];
-
- RNA_int_get_array(op->ptr, "location", location);
-
- view3d_operator_needs_opengl(C);
-
- if (object) {
- obedit = NULL;
- obact = NULL;
-
- /* ack, this is incorrect but to do this correctly we would need an
- * alternative editmode/objectmode keymap, this copies the functionality
- * from 2.4x where Ctrl+Select in editmode does object select only */
- center = false;
- }
-
- if (obedit && object == false) {
- if (obedit->type == OB_MESH) {
- retval = EDBM_select_pick(C, location, extend, deselect, toggle);
- if (!retval && deselect_all) {
- retval = EDBM_mesh_deselect_all_multi(C);
- }
- }
- else if (obedit->type == OB_ARMATURE) {
- retval = ED_armature_edit_select_pick(C, location, extend, deselect, toggle);
- if (!retval && deselect_all) {
- retval = ED_armature_edit_deselect_all_visible_multi(C);
- }
- }
- else if (obedit->type == OB_LATTICE) {
- retval = ED_lattice_select_pick(C, location, extend, deselect, toggle);
- if (!retval && deselect_all) {
- retval = ED_lattice_deselect_all_multi(C);
- }
- }
- else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
- retval = ED_curve_editnurb_select_pick(C, location, extend, deselect, toggle);
- if (!retval && deselect_all) {
- retval = ED_curve_deselect_all_multi(C);
- }
- }
- else if (obedit->type == OB_MBALL) {
- retval = ED_mball_select_pick(C, location, extend, deselect, toggle);
- if (!retval && deselect_all) {
- retval = ED_mball_deselect_all_multi(C);
- }
- }
- else if (obedit->type == OB_FONT) {
- retval = ED_curve_editfont_select_pick(C, location, extend, deselect, toggle);
- if (!retval && deselect_all) {
- /* pass */
- }
- }
-
- }
- else if (obact && obact->mode & OB_MODE_PARTICLE_EDIT) {
- retval = PE_mouse_particles(C, location, extend, deselect, toggle);
- if (!retval && deselect_all) {
- retval = PE_deselect_all_visible(C);
- }
- }
- else if (obact && BKE_paint_select_face_test(obact)) {
- retval = paintface_mouse_select(C, obact, location, extend, deselect, toggle);
- if (!retval && deselect_all) {
- retval = paintface_deselect_all_visible(C, CTX_data_active_object(C), SEL_DESELECT, false);
- }
- }
- else if (BKE_paint_select_vert_test(obact)) {
- retval = ed_wpaint_vertex_select_pick(C, location, extend, deselect, toggle, obact);
- if (!retval && deselect_all) {
- retval = paintvert_deselect_all_visible(obact, SEL_DESELECT, false);
- }
- }
- else {
- retval = ed_object_select_pick(C, location, extend, deselect, toggle, center, enumerate, object);
- if (!retval && deselect_all) {
- if (ED_pose_object_from_context(C)) {
- retval = ED_pose_deselect_all_multi(C, SEL_DESELECT, false);
- }
- else {
- retval = ED_object_base_deselect_all(CTX_data_view_layer(C), CTX_wm_view3d(C), SEL_DESELECT);
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
- }
- }
- }
-
- /* passthrough allows tweaks
- * FINISHED to signal one operator worked
- * */
- if (retval) {
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- return OPERATOR_PASS_THROUGH | OPERATOR_FINISHED;
- }
- else {
- return OPERATOR_PASS_THROUGH; /* nothing selected, just passthrough */
- }
+ Scene *scene = CTX_data_scene(C);
+ Object *obedit = CTX_data_edit_object(C);
+ Object *obact = CTX_data_active_object(C);
+ bool extend = RNA_boolean_get(op->ptr, "extend");
+ bool deselect = RNA_boolean_get(op->ptr, "deselect");
+ bool deselect_all = RNA_boolean_get(op->ptr, "deselect_all");
+ bool toggle = RNA_boolean_get(op->ptr, "toggle");
+ bool center = RNA_boolean_get(op->ptr, "center");
+ bool enumerate = RNA_boolean_get(op->ptr, "enumerate");
+ /* only force object select for editmode to support vertex parenting,
+ * or paint-select to allow pose bone select with vert/face select */
+ bool object = (RNA_boolean_get(op->ptr, "object") &&
+ (obedit || BKE_paint_select_elem_test(obact) ||
+ /* so its possible to select bones in weightpaint mode (LMB select) */
+ (obact && (obact->mode & OB_MODE_WEIGHT_PAINT) &&
+ BKE_object_pose_armature_get(obact))));
+
+ bool retval = false;
+ int location[2];
+
+ RNA_int_get_array(op->ptr, "location", location);
+
+ view3d_operator_needs_opengl(C);
+
+ if (object) {
+ obedit = NULL;
+ obact = NULL;
+
+ /* ack, this is incorrect but to do this correctly we would need an
+ * alternative editmode/objectmode keymap, this copies the functionality
+ * from 2.4x where Ctrl+Select in editmode does object select only */
+ center = false;
+ }
+
+ if (obedit && object == false) {
+ if (obedit->type == OB_MESH) {
+ retval = EDBM_select_pick(C, location, extend, deselect, toggle);
+ if (!retval && deselect_all) {
+ retval = EDBM_mesh_deselect_all_multi(C);
+ }
+ }
+ else if (obedit->type == OB_ARMATURE) {
+ retval = ED_armature_edit_select_pick(C, location, extend, deselect, toggle);
+ if (!retval && deselect_all) {
+ retval = ED_armature_edit_deselect_all_visible_multi(C);
+ }
+ }
+ else if (obedit->type == OB_LATTICE) {
+ retval = ED_lattice_select_pick(C, location, extend, deselect, toggle);
+ if (!retval && deselect_all) {
+ retval = ED_lattice_deselect_all_multi(C);
+ }
+ }
+ else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
+ retval = ED_curve_editnurb_select_pick(C, location, extend, deselect, toggle);
+ if (!retval && deselect_all) {
+ retval = ED_curve_deselect_all_multi(C);
+ }
+ }
+ else if (obedit->type == OB_MBALL) {
+ retval = ED_mball_select_pick(C, location, extend, deselect, toggle);
+ if (!retval && deselect_all) {
+ retval = ED_mball_deselect_all_multi(C);
+ }
+ }
+ else if (obedit->type == OB_FONT) {
+ retval = ED_curve_editfont_select_pick(C, location, extend, deselect, toggle);
+ if (!retval && deselect_all) {
+ /* pass */
+ }
+ }
+ }
+ else if (obact && obact->mode & OB_MODE_PARTICLE_EDIT) {
+ retval = PE_mouse_particles(C, location, extend, deselect, toggle);
+ if (!retval && deselect_all) {
+ retval = PE_deselect_all_visible(C);
+ }
+ }
+ else if (obact && BKE_paint_select_face_test(obact)) {
+ retval = paintface_mouse_select(C, obact, location, extend, deselect, toggle);
+ if (!retval && deselect_all) {
+ retval = paintface_deselect_all_visible(C, CTX_data_active_object(C), SEL_DESELECT, false);
+ }
+ }
+ else if (BKE_paint_select_vert_test(obact)) {
+ retval = ed_wpaint_vertex_select_pick(C, location, extend, deselect, toggle, obact);
+ if (!retval && deselect_all) {
+ retval = paintvert_deselect_all_visible(obact, SEL_DESELECT, false);
+ }
+ }
+ else {
+ retval = ed_object_select_pick(
+ C, location, extend, deselect, toggle, center, enumerate, object);
+ if (!retval && deselect_all) {
+ if (ED_pose_object_from_context(C)) {
+ retval = ED_pose_deselect_all_multi(C, SEL_DESELECT, false);
+ }
+ else {
+ retval = ED_object_base_deselect_all(
+ CTX_data_view_layer(C), CTX_wm_view3d(C), SEL_DESELECT);
+ DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
+ }
+ }
+ }
+
+ /* passthrough allows tweaks
+ * FINISHED to signal one operator worked
+ * */
+ if (retval) {
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ return OPERATOR_PASS_THROUGH | OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_PASS_THROUGH; /* nothing selected, just passthrough */
+ }
}
static int view3d_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- RNA_int_set_array(op->ptr, "location", event->mval);
+ RNA_int_set_array(op->ptr, "location", event->mval);
- return view3d_select_exec(C, op);
+ return view3d_select_exec(C, op);
}
void VIEW3D_OT_select(wmOperatorType *ot)
{
- PropertyRNA *prop;
-
- /* identifiers */
- ot->name = "Select";
- ot->description = "Select and activate item(s)";
- ot->idname = "VIEW3D_OT_select";
-
- /* api callbacks */
- ot->invoke = view3d_select_invoke;
- ot->exec = view3d_select_exec;
- ot->poll = ED_operator_view3d_active;
-
- /* flags */
- ot->flag = OPTYPE_UNDO;
-
- /* properties */
- WM_operator_properties_mouse_select(ot);
- prop = RNA_def_boolean(ot->srna, "deselect_all", 0, "Deselect", "Deselect all when nothing under the cursor");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
-
- prop = RNA_def_boolean(ot->srna, "center", 0, "Center", "Use the object center when selecting, in editmode used to extend object selection");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "enumerate", 0, "Enumerate", "List objects under the mouse (object mode only)");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "object", 0, "Object", "Use object selection (editmode only)");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
-
- prop = RNA_def_int_vector(ot->srna, "location", 2, NULL, INT_MIN, INT_MAX, "Location", "Mouse location", INT_MIN, INT_MAX);
- RNA_def_property_flag(prop, PROP_HIDDEN);
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Select";
+ ot->description = "Select and activate item(s)";
+ ot->idname = "VIEW3D_OT_select";
+
+ /* api callbacks */
+ ot->invoke = view3d_select_invoke;
+ ot->exec = view3d_select_exec;
+ ot->poll = ED_operator_view3d_active;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
+
+ /* properties */
+ WM_operator_properties_mouse_select(ot);
+ prop = RNA_def_boolean(
+ ot->srna, "deselect_all", 0, "Deselect", "Deselect all when nothing under the cursor");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
+ prop = RNA_def_boolean(
+ ot->srna,
+ "center",
+ 0,
+ "Center",
+ "Use the object center when selecting, in editmode used to extend object selection");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_boolean(
+ ot->srna, "enumerate", 0, "Enumerate", "List objects under the mouse (object mode only)");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_boolean(ot->srna, "object", 0, "Object", "Use object selection (editmode only)");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
+ prop = RNA_def_int_vector(ot->srna,
+ "location",
+ 2,
+ NULL,
+ INT_MIN,
+ INT_MAX,
+ "Location",
+ "Mouse location",
+ INT_MIN,
+ INT_MAX);
+ RNA_def_property_flag(prop, PROP_HIDDEN);
}
/** \} */
@@ -2198,453 +2289,468 @@ void VIEW3D_OT_select(wmOperatorType *ot)
* \{ */
typedef struct BoxSelectUserData {
- ViewContext *vc;
- const rcti *rect;
- const rctf *rect_fl;
- rctf _rect_fl;
- eSelectOp sel_op;
-
- /* runtime */
- bool is_done;
- bool is_changed;
+ ViewContext *vc;
+ const rcti *rect;
+ const rctf *rect_fl;
+ rctf _rect_fl;
+ eSelectOp sel_op;
+
+ /* runtime */
+ bool is_done;
+ bool is_changed;
} BoxSelectUserData;
-static void view3d_userdata_boxselect_init(
- BoxSelectUserData *r_data,
- ViewContext *vc, const rcti *rect, const eSelectOp sel_op)
-{
- r_data->vc = vc;
-
- r_data->rect = rect;
- r_data->rect_fl = &r_data->_rect_fl;
- BLI_rctf_rcti_copy(&r_data->_rect_fl, rect);
-
- r_data->sel_op = sel_op;
-
- /* runtime */
- r_data->is_done = false;
- r_data->is_changed = false;
-}
-
-bool edge_inside_circle(const float cent[2], float radius, const float screen_co_a[2], const float screen_co_b[2])
-{
- const float radius_squared = radius * radius;
- return (dist_squared_to_line_segment_v2(cent, screen_co_a, screen_co_b) < radius_squared);
-}
-
-static void do_paintvert_box_select__doSelectVert(void *userData, MVert *mv, const float screen_co[2], int UNUSED(index))
-{
- BoxSelectUserData *data = userData;
- const bool is_select = mv->flag & SELECT;
- const bool is_inside = BLI_rctf_isect_pt_v(data->rect_fl, screen_co);
- const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- SET_FLAG_FROM_TEST(mv->flag, sel_op_result, SELECT);
- data->is_changed = true;
- }
-}
-static bool do_paintvert_box_select(
- ViewContext *vc, const rcti *rect, const eSelectOp sel_op)
-{
- const bool use_zbuf = !XRAY_ENABLED(vc->v3d);
- Mesh *me;
-
- me = vc->obact->data;
- if ((me == NULL) || (me->totvert == 0)) {
- return OPERATOR_CANCELLED;
- }
-
- bool changed = false;
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- changed |= paintvert_deselect_all_visible(vc->obact, SEL_DESELECT, false);
- }
-
- if (BLI_rcti_is_empty(rect)) {
- /* pass */
- }
- else if (use_zbuf) {
- MVert *mvert;
- unsigned int *rt;
- int a, index;
- char *selar;
-
- selar = MEM_callocN(me->totvert + 1, "selar");
-
- uint buf_len;
- uint *buf = ED_view3d_select_id_read_rect(vc, rect, &buf_len);
-
- rt = buf;
-
- a = buf_len;
- while (a--) {
- if (*rt) {
- index = *rt;
- if (index <= me->totvert) {
- selar[index] = 1;
- }
- }
- rt++;
- }
-
- mvert = me->mvert;
- for (a = 1; a <= me->totvert; a++, mvert++) {
- if ((mvert->flag & ME_HIDE) == 0) {
- const bool is_select = mvert->flag & SELECT;
- const bool is_inside = (selar[a] != 0);
- const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- SET_FLAG_FROM_TEST(mvert->flag, sel_op_result, SELECT);
- changed = true;
- }
- }
- }
-
- MEM_freeN(buf);
- MEM_freeN(selar);
+static void view3d_userdata_boxselect_init(BoxSelectUserData *r_data,
+ ViewContext *vc,
+ const rcti *rect,
+ const eSelectOp sel_op)
+{
+ r_data->vc = vc;
+
+ r_data->rect = rect;
+ r_data->rect_fl = &r_data->_rect_fl;
+ BLI_rctf_rcti_copy(&r_data->_rect_fl, rect);
+
+ r_data->sel_op = sel_op;
+
+ /* runtime */
+ r_data->is_done = false;
+ r_data->is_changed = false;
+}
+
+bool edge_inside_circle(const float cent[2],
+ float radius,
+ const float screen_co_a[2],
+ const float screen_co_b[2])
+{
+ const float radius_squared = radius * radius;
+ return (dist_squared_to_line_segment_v2(cent, screen_co_a, screen_co_b) < radius_squared);
+}
+
+static void do_paintvert_box_select__doSelectVert(void *userData,
+ MVert *mv,
+ const float screen_co[2],
+ int UNUSED(index))
+{
+ BoxSelectUserData *data = userData;
+ const bool is_select = mv->flag & SELECT;
+ const bool is_inside = BLI_rctf_isect_pt_v(data->rect_fl, screen_co);
+ const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
+ if (sel_op_result != -1) {
+ SET_FLAG_FROM_TEST(mv->flag, sel_op_result, SELECT);
+ data->is_changed = true;
+ }
+}
+static bool do_paintvert_box_select(ViewContext *vc, const rcti *rect, const eSelectOp sel_op)
+{
+ const bool use_zbuf = !XRAY_ENABLED(vc->v3d);
+ Mesh *me;
+
+ me = vc->obact->data;
+ if ((me == NULL) || (me->totvert == 0)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ bool changed = false;
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ changed |= paintvert_deselect_all_visible(vc->obact, SEL_DESELECT, false);
+ }
+
+ if (BLI_rcti_is_empty(rect)) {
+ /* pass */
+ }
+ else if (use_zbuf) {
+ MVert *mvert;
+ unsigned int *rt;
+ int a, index;
+ char *selar;
+
+ selar = MEM_callocN(me->totvert + 1, "selar");
+
+ uint buf_len;
+ uint *buf = ED_view3d_select_id_read_rect(vc, rect, &buf_len);
+
+ rt = buf;
+
+ a = buf_len;
+ while (a--) {
+ if (*rt) {
+ index = *rt;
+ if (index <= me->totvert) {
+ selar[index] = 1;
+ }
+ }
+ rt++;
+ }
+
+ mvert = me->mvert;
+ for (a = 1; a <= me->totvert; a++, mvert++) {
+ if ((mvert->flag & ME_HIDE) == 0) {
+ const bool is_select = mvert->flag & SELECT;
+ const bool is_inside = (selar[a] != 0);
+ const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
+ if (sel_op_result != -1) {
+ SET_FLAG_FROM_TEST(mvert->flag, sel_op_result, SELECT);
+ changed = true;
+ }
+ }
+ }
+
+ MEM_freeN(buf);
+ MEM_freeN(selar);
#ifdef __APPLE__
- glReadBuffer(GL_BACK);
+ glReadBuffer(GL_BACK);
#endif
- }
- else {
- BoxSelectUserData data;
-
- view3d_userdata_boxselect_init(&data, vc, rect, sel_op);
-
- ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d);
-
- meshobject_foreachScreenVert(vc, do_paintvert_box_select__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
- changed |= data.is_changed;
- }
-
- if (changed) {
- if (SEL_OP_CAN_DESELECT(sel_op)) {
- BKE_mesh_mselect_validate(me);
- }
- paintvert_flush_flags(vc->obact);
- paintvert_tag_select_update(vc->C, vc->obact);
- }
- return changed;
-}
-
-static void do_nurbs_box_select__doSelect(
- void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co[2])
-{
- BoxSelectUserData *data = userData;
-
- const bool is_inside = BLI_rctf_isect_pt_v(data->rect_fl, screen_co);
- if (bp) {
- const bool is_select = bp->f1 & SELECT;
- const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- SET_FLAG_FROM_TEST(bp->f1, sel_op_result, SELECT);
- data->is_changed = true;
- }
- }
- else {
- if ((data->vc->v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_CU_HANDLES) == 0) {
- /* can only be (beztindex == 0) here since handles are hidden */
- const bool is_select = bezt->f2 & SELECT;
- const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- SET_FLAG_FROM_TEST(bezt->f2, sel_op_result, SELECT);
- data->is_changed = true;
- }
- bezt->f1 = bezt->f3 = bezt->f2;
- }
- else {
- char *flag_p = (&bezt->f1) + beztindex;
- const bool is_select = *flag_p & SELECT;
- const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- SET_FLAG_FROM_TEST(*flag_p, sel_op_result, SELECT);
- data->is_changed = true;
- }
- }
- }
+ }
+ else {
+ BoxSelectUserData data;
+
+ view3d_userdata_boxselect_init(&data, vc, rect, sel_op);
+
+ ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d);
+
+ meshobject_foreachScreenVert(
+ vc, do_paintvert_box_select__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ changed |= data.is_changed;
+ }
+
+ if (changed) {
+ if (SEL_OP_CAN_DESELECT(sel_op)) {
+ BKE_mesh_mselect_validate(me);
+ }
+ paintvert_flush_flags(vc->obact);
+ paintvert_tag_select_update(vc->C, vc->obact);
+ }
+ return changed;
+}
+
+static void do_nurbs_box_select__doSelect(void *userData,
+ Nurb *UNUSED(nu),
+ BPoint *bp,
+ BezTriple *bezt,
+ int beztindex,
+ const float screen_co[2])
+{
+ BoxSelectUserData *data = userData;
+
+ const bool is_inside = BLI_rctf_isect_pt_v(data->rect_fl, screen_co);
+ if (bp) {
+ const bool is_select = bp->f1 & SELECT;
+ const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
+ if (sel_op_result != -1) {
+ SET_FLAG_FROM_TEST(bp->f1, sel_op_result, SELECT);
+ data->is_changed = true;
+ }
+ }
+ else {
+ if ((data->vc->v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_CU_HANDLES) == 0) {
+ /* can only be (beztindex == 0) here since handles are hidden */
+ const bool is_select = bezt->f2 & SELECT;
+ const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
+ if (sel_op_result != -1) {
+ SET_FLAG_FROM_TEST(bezt->f2, sel_op_result, SELECT);
+ data->is_changed = true;
+ }
+ bezt->f1 = bezt->f3 = bezt->f2;
+ }
+ else {
+ char *flag_p = (&bezt->f1) + beztindex;
+ const bool is_select = *flag_p & SELECT;
+ const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
+ if (sel_op_result != -1) {
+ SET_FLAG_FROM_TEST(*flag_p, sel_op_result, SELECT);
+ data->is_changed = true;
+ }
+ }
+ }
}
static bool do_nurbs_box_select(ViewContext *vc, rcti *rect, const eSelectOp sel_op)
{
- BoxSelectUserData data;
+ BoxSelectUserData data;
- view3d_userdata_boxselect_init(&data, vc, rect, sel_op);
+ view3d_userdata_boxselect_init(&data, vc, rect, sel_op);
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- Curve *curve = (Curve *) vc->obedit->data;
- data.is_changed |= ED_curve_deselect_all(curve->editnurb);
- }
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ Curve *curve = (Curve *)vc->obedit->data;
+ data.is_changed |= ED_curve_deselect_all(curve->editnurb);
+ }
- ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
- nurbs_foreachScreenVert(vc, do_nurbs_box_select__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
- BKE_curve_nurb_vert_active_validate(vc->obedit->data);
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
+ nurbs_foreachScreenVert(vc, do_nurbs_box_select__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ BKE_curve_nurb_vert_active_validate(vc->obedit->data);
- return data.is_changed;
+ return data.is_changed;
}
static void do_lattice_box_select__doSelect(void *userData, BPoint *bp, const float screen_co[2])
{
- BoxSelectUserData *data = userData;
- const bool is_select = bp->f1 & SELECT;
- const bool is_inside = BLI_rctf_isect_pt_v(data->rect_fl, screen_co);
- const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- SET_FLAG_FROM_TEST(bp->f1, sel_op_result, SELECT);
- data->is_changed = true;
- }
+ BoxSelectUserData *data = userData;
+ const bool is_select = bp->f1 & SELECT;
+ const bool is_inside = BLI_rctf_isect_pt_v(data->rect_fl, screen_co);
+ const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
+ if (sel_op_result != -1) {
+ SET_FLAG_FROM_TEST(bp->f1, sel_op_result, SELECT);
+ data->is_changed = true;
+ }
}
static bool do_lattice_box_select(ViewContext *vc, rcti *rect, const eSelectOp sel_op)
{
- BoxSelectUserData data;
+ BoxSelectUserData data;
- view3d_userdata_boxselect_init(&data, vc, rect, sel_op);
+ view3d_userdata_boxselect_init(&data, vc, rect, sel_op);
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- data.is_changed |= ED_lattice_flags_set(vc->obedit, 0);
- }
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ data.is_changed |= ED_lattice_flags_set(vc->obedit, 0);
+ }
- ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
- lattice_foreachScreenVert(vc, do_lattice_box_select__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
+ lattice_foreachScreenVert(
+ vc, do_lattice_box_select__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
- return data.is_changed;
+ return data.is_changed;
}
-static void do_mesh_box_select__doSelectVert(void *userData, BMVert *eve, const float screen_co[2], int UNUSED(index))
+static void do_mesh_box_select__doSelectVert(void *userData,
+ BMVert *eve,
+ const float screen_co[2],
+ int UNUSED(index))
{
- BoxSelectUserData *data = userData;
- const bool is_select = BM_elem_flag_test(eve, BM_ELEM_SELECT);
- const bool is_inside = BLI_rctf_isect_pt_v(data->rect_fl, screen_co);
- const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- BM_vert_select_set(data->vc->em->bm, eve, sel_op_result);
- data->is_changed = true;
- }
+ BoxSelectUserData *data = userData;
+ const bool is_select = BM_elem_flag_test(eve, BM_ELEM_SELECT);
+ const bool is_inside = BLI_rctf_isect_pt_v(data->rect_fl, screen_co);
+ const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
+ if (sel_op_result != -1) {
+ BM_vert_select_set(data->vc->em->bm, eve, sel_op_result);
+ data->is_changed = true;
+ }
}
static void do_mesh_box_select__doSelectEdge_pass0(
- void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index)
-{
- BoxSelectUserData *data = userData;
- const bool is_select = BM_elem_flag_test(eed, BM_ELEM_SELECT);
- const bool is_inside = (
- EDBM_backbuf_check(bm_solidoffs + index) &&
- edge_fully_inside_rect(data->rect_fl, screen_co_a, screen_co_b));
- const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- BM_edge_select_set(data->vc->em->bm, eed, sel_op_result);
- data->is_done = true;
- data->is_changed = true;
- }
+ void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index)
+{
+ BoxSelectUserData *data = userData;
+ const bool is_select = BM_elem_flag_test(eed, BM_ELEM_SELECT);
+ const bool is_inside = (EDBM_backbuf_check(bm_solidoffs + index) &&
+ edge_fully_inside_rect(data->rect_fl, screen_co_a, screen_co_b));
+ const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
+ if (sel_op_result != -1) {
+ BM_edge_select_set(data->vc->em->bm, eed, sel_op_result);
+ data->is_done = true;
+ data->is_changed = true;
+ }
}
static void do_mesh_box_select__doSelectEdge_pass1(
- void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index)
-{
- BoxSelectUserData *data = userData;
- const bool is_select = BM_elem_flag_test(eed, BM_ELEM_SELECT);
- const bool is_inside = (
- EDBM_backbuf_check(bm_solidoffs + index) &&
- edge_inside_rect(data->rect_fl, screen_co_a, screen_co_b));
- const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- BM_edge_select_set(data->vc->em->bm, eed, sel_op_result);
- data->is_changed = true;
- }
-}
-static void do_mesh_box_select__doSelectFace(void *userData, BMFace *efa, const float screen_co[2], int UNUSED(index))
-{
- BoxSelectUserData *data = userData;
- const bool is_select = BM_elem_flag_test(efa, BM_ELEM_SELECT);
- const bool is_inside = BLI_rctf_isect_pt_v(data->rect_fl, screen_co);
- const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- BM_face_select_set(data->vc->em->bm, efa, sel_op_result);
- data->is_changed = true;
- }
-}
-static bool do_mesh_box_select(
- ViewContext *vc, rcti *rect, const eSelectOp sel_op)
-{
- BoxSelectUserData data;
- ToolSettings *ts = vc->scene->toolsettings;
- int bbsel;
-
- view3d_userdata_boxselect_init(&data, vc, rect, sel_op);
-
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- if (vc->em->bm->totvertsel) {
- EDBM_flag_disable_all(vc->em, BM_ELEM_SELECT);
- data.is_changed = true;
- }
- }
-
- /* for non zbuf projections, don't change the GL state */
- ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
-
- GPU_matrix_set(vc->rv3d->viewmat);
- bbsel = EDBM_backbuf_border_init(vc, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
-
- if (ts->selectmode & SCE_SELECT_VERTEX) {
- if (bbsel) {
- data.is_changed |= edbm_backbuf_check_and_select_verts(vc->em, sel_op);
- }
- else {
- mesh_foreachScreenVert(vc, do_mesh_box_select__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
- }
- }
- if (ts->selectmode & SCE_SELECT_EDGE) {
- /* Does both bbsel and non-bbsel versions (need screen cos for both) */
- mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge_pass0, &data, V3D_PROJ_TEST_CLIP_NEAR);
- if (data.is_done == false) {
- mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge_pass1, &data, V3D_PROJ_TEST_CLIP_NEAR);
- }
- }
-
- if (ts->selectmode & SCE_SELECT_FACE) {
- if (bbsel) {
- data.is_changed |= edbm_backbuf_check_and_select_faces(vc->em, sel_op);
- }
- else {
- mesh_foreachScreenFace(vc, do_mesh_box_select__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
- }
- }
-
- EDBM_backbuf_free();
-
- if (data.is_changed) {
- EDBM_selectmode_flush(vc->em);
- }
- return data.is_changed;
-}
-
-static bool do_meta_box_select(
- ViewContext *vc,
- const rcti *rect, const eSelectOp sel_op)
-{
- Object *ob = vc->obedit;
- MetaBall *mb = (MetaBall *)ob->data;
- MetaElem *ml;
- int a;
- bool changed = false;
-
- uint buffer[MAXPICKBUF];
- int hits;
-
- hits = view3d_opengl_select(
- vc, buffer, MAXPICKBUF, rect,
- VIEW3D_SELECT_ALL, VIEW3D_SELECT_FILTER_NOP);
-
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- changed |= BKE_mball_deselect_all(mb);
- }
-
- int metaelem_id = 0;
- for (ml = mb->editelems->first; ml; ml = ml->next, metaelem_id += 0x10000) {
- bool is_inside_radius = false;
- bool is_inside_stiff = false;
-
- for (a = 0; a < hits; a++) {
- int hitresult = buffer[(4 * a) + 3];
-
- if (hitresult == -1) {
- continue;
- }
- else if (hitresult & MBALL_NOSEL) {
- continue;
- }
-
- const uint hit_object = hitresult & 0xFFFF;
- if (vc->obedit->select_id != hit_object) {
- continue;
- }
-
- if (metaelem_id != (hitresult & 0xFFFF0000 & ~(MBALLSEL_ANY))) {
- continue;
- }
-
- if (hitresult & MBALLSEL_RADIUS) {
- is_inside_radius = true;
- break;
- }
-
- if (hitresult & MBALLSEL_STIFF) {
- is_inside_stiff = true;
- break;
- }
- }
- const int flag_prev = ml->flag;
- if (is_inside_radius) {
- ml->flag |= MB_SCALE_RAD;
- }
- if (is_inside_stiff) {
- ml->flag &= ~MB_SCALE_RAD;
- }
-
- const bool is_select = (ml->flag & SELECT);
- const bool is_inside = is_inside_radius || is_inside_stiff;
-
- const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- SET_FLAG_FROM_TEST(ml->flag, sel_op_result, SELECT);
- }
- changed |= (flag_prev != ml->flag);
- }
-
- return changed;
-}
-
-static bool do_armature_box_select(
- ViewContext *vc,
- const rcti *rect, const eSelectOp sel_op)
-{
- bool changed = false;
- int a;
-
- uint buffer[MAXPICKBUF];
- int hits;
-
- hits = view3d_opengl_select(
- vc, buffer, MAXPICKBUF, rect,
- VIEW3D_SELECT_ALL, VIEW3D_SELECT_FILTER_NOP);
-
- uint bases_len = 0;
- Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(vc->view_layer, vc->v3d, &bases_len);
-
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- changed |= ED_armature_edit_deselect_all_visible_multi_ex(bases, bases_len);
- }
-
- for (uint base_index = 0; base_index < bases_len; base_index++) {
- Object *obedit = bases[base_index]->object;
- obedit->id.tag &= ~LIB_TAG_DOIT;
-
- bArmature *arm = obedit->data;
- ED_armature_ebone_listbase_temp_clear(arm->edbo);
- }
-
- /* first we only check points inside the border */
- for (a = 0; a < hits; a++) {
- int select_id = buffer[(4 * a) + 3];
- if (select_id != -1) {
- if ((select_id & 0xFFFF0000) == 0) {
- continue;
- }
-
- EditBone *ebone;
- Base *base_edit = ED_armature_base_and_ebone_from_select_buffer(bases, bases_len, select_id, &ebone);
- ebone->temp.i |= select_id & BONESEL_ANY;
- base_edit->object->id.tag |= LIB_TAG_DOIT;
- }
- }
-
- for (uint base_index = 0; base_index < bases_len; base_index++) {
- Object *obedit = bases[base_index]->object;
- if (obedit->id.tag & LIB_TAG_DOIT) {
- obedit->id.tag &= ~LIB_TAG_DOIT;
- changed |= ED_armature_edit_select_op_from_tagged(obedit->data, sel_op);
- }
- }
-
- MEM_freeN(bases);
-
- return changed;
+ void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index)
+{
+ BoxSelectUserData *data = userData;
+ const bool is_select = BM_elem_flag_test(eed, BM_ELEM_SELECT);
+ const bool is_inside = (EDBM_backbuf_check(bm_solidoffs + index) &&
+ edge_inside_rect(data->rect_fl, screen_co_a, screen_co_b));
+ const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
+ if (sel_op_result != -1) {
+ BM_edge_select_set(data->vc->em->bm, eed, sel_op_result);
+ data->is_changed = true;
+ }
+}
+static void do_mesh_box_select__doSelectFace(void *userData,
+ BMFace *efa,
+ const float screen_co[2],
+ int UNUSED(index))
+{
+ BoxSelectUserData *data = userData;
+ const bool is_select = BM_elem_flag_test(efa, BM_ELEM_SELECT);
+ const bool is_inside = BLI_rctf_isect_pt_v(data->rect_fl, screen_co);
+ const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
+ if (sel_op_result != -1) {
+ BM_face_select_set(data->vc->em->bm, efa, sel_op_result);
+ data->is_changed = true;
+ }
+}
+static bool do_mesh_box_select(ViewContext *vc, rcti *rect, const eSelectOp sel_op)
+{
+ BoxSelectUserData data;
+ ToolSettings *ts = vc->scene->toolsettings;
+ int bbsel;
+
+ view3d_userdata_boxselect_init(&data, vc, rect, sel_op);
+
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ if (vc->em->bm->totvertsel) {
+ EDBM_flag_disable_all(vc->em, BM_ELEM_SELECT);
+ data.is_changed = true;
+ }
+ }
+
+ /* for non zbuf projections, don't change the GL state */
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
+
+ GPU_matrix_set(vc->rv3d->viewmat);
+ bbsel = EDBM_backbuf_border_init(vc, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
+
+ if (ts->selectmode & SCE_SELECT_VERTEX) {
+ if (bbsel) {
+ data.is_changed |= edbm_backbuf_check_and_select_verts(vc->em, sel_op);
+ }
+ else {
+ mesh_foreachScreenVert(
+ vc, do_mesh_box_select__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ }
+ }
+ if (ts->selectmode & SCE_SELECT_EDGE) {
+ /* Does both bbsel and non-bbsel versions (need screen cos for both) */
+ mesh_foreachScreenEdge(
+ vc, do_mesh_box_select__doSelectEdge_pass0, &data, V3D_PROJ_TEST_CLIP_NEAR);
+ if (data.is_done == false) {
+ mesh_foreachScreenEdge(
+ vc, do_mesh_box_select__doSelectEdge_pass1, &data, V3D_PROJ_TEST_CLIP_NEAR);
+ }
+ }
+
+ if (ts->selectmode & SCE_SELECT_FACE) {
+ if (bbsel) {
+ data.is_changed |= edbm_backbuf_check_and_select_faces(vc->em, sel_op);
+ }
+ else {
+ mesh_foreachScreenFace(
+ vc, do_mesh_box_select__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ }
+ }
+
+ EDBM_backbuf_free();
+
+ if (data.is_changed) {
+ EDBM_selectmode_flush(vc->em);
+ }
+ return data.is_changed;
+}
+
+static bool do_meta_box_select(ViewContext *vc, const rcti *rect, const eSelectOp sel_op)
+{
+ Object *ob = vc->obedit;
+ MetaBall *mb = (MetaBall *)ob->data;
+ MetaElem *ml;
+ int a;
+ bool changed = false;
+
+ uint buffer[MAXPICKBUF];
+ int hits;
+
+ hits = view3d_opengl_select(
+ vc, buffer, MAXPICKBUF, rect, VIEW3D_SELECT_ALL, VIEW3D_SELECT_FILTER_NOP);
+
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ changed |= BKE_mball_deselect_all(mb);
+ }
+
+ int metaelem_id = 0;
+ for (ml = mb->editelems->first; ml; ml = ml->next, metaelem_id += 0x10000) {
+ bool is_inside_radius = false;
+ bool is_inside_stiff = false;
+
+ for (a = 0; a < hits; a++) {
+ int hitresult = buffer[(4 * a) + 3];
+
+ if (hitresult == -1) {
+ continue;
+ }
+ else if (hitresult & MBALL_NOSEL) {
+ continue;
+ }
+
+ const uint hit_object = hitresult & 0xFFFF;
+ if (vc->obedit->select_id != hit_object) {
+ continue;
+ }
+
+ if (metaelem_id != (hitresult & 0xFFFF0000 & ~(MBALLSEL_ANY))) {
+ continue;
+ }
+
+ if (hitresult & MBALLSEL_RADIUS) {
+ is_inside_radius = true;
+ break;
+ }
+
+ if (hitresult & MBALLSEL_STIFF) {
+ is_inside_stiff = true;
+ break;
+ }
+ }
+ const int flag_prev = ml->flag;
+ if (is_inside_radius) {
+ ml->flag |= MB_SCALE_RAD;
+ }
+ if (is_inside_stiff) {
+ ml->flag &= ~MB_SCALE_RAD;
+ }
+
+ const bool is_select = (ml->flag & SELECT);
+ const bool is_inside = is_inside_radius || is_inside_stiff;
+
+ const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
+ if (sel_op_result != -1) {
+ SET_FLAG_FROM_TEST(ml->flag, sel_op_result, SELECT);
+ }
+ changed |= (flag_prev != ml->flag);
+ }
+
+ return changed;
+}
+
+static bool do_armature_box_select(ViewContext *vc, const rcti *rect, const eSelectOp sel_op)
+{
+ bool changed = false;
+ int a;
+
+ uint buffer[MAXPICKBUF];
+ int hits;
+
+ hits = view3d_opengl_select(
+ vc, buffer, MAXPICKBUF, rect, VIEW3D_SELECT_ALL, VIEW3D_SELECT_FILTER_NOP);
+
+ uint bases_len = 0;
+ Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
+ vc->view_layer, vc->v3d, &bases_len);
+
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ changed |= ED_armature_edit_deselect_all_visible_multi_ex(bases, bases_len);
+ }
+
+ for (uint base_index = 0; base_index < bases_len; base_index++) {
+ Object *obedit = bases[base_index]->object;
+ obedit->id.tag &= ~LIB_TAG_DOIT;
+
+ bArmature *arm = obedit->data;
+ ED_armature_ebone_listbase_temp_clear(arm->edbo);
+ }
+
+ /* first we only check points inside the border */
+ for (a = 0; a < hits; a++) {
+ int select_id = buffer[(4 * a) + 3];
+ if (select_id != -1) {
+ if ((select_id & 0xFFFF0000) == 0) {
+ continue;
+ }
+
+ EditBone *ebone;
+ Base *base_edit = ED_armature_base_and_ebone_from_select_buffer(
+ bases, bases_len, select_id, &ebone);
+ ebone->temp.i |= select_id & BONESEL_ANY;
+ base_edit->object->id.tag |= LIB_TAG_DOIT;
+ }
+ }
+
+ for (uint base_index = 0; base_index < bases_len; base_index++) {
+ Object *obedit = bases[base_index]->object;
+ if (obedit->id.tag & LIB_TAG_DOIT) {
+ obedit->id.tag &= ~LIB_TAG_DOIT;
+ changed |= ED_armature_edit_select_op_from_tagged(obedit->data, sel_op);
+ }
+ }
+
+ MEM_freeN(bases);
+
+ return changed;
}
/**
@@ -2653,291 +2759,294 @@ static bool do_armature_box_select(
*/
static int opengl_bone_select_buffer_cmp(const void *sel_a_p, const void *sel_b_p)
{
- /* 4th element is select id */
- uint sel_a = ((uint *)sel_a_p)[3];
- uint sel_b = ((uint *)sel_b_p)[3];
+ /* 4th element is select id */
+ uint sel_a = ((uint *)sel_a_p)[3];
+ uint sel_b = ((uint *)sel_b_p)[3];
#ifdef __BIG_ENDIAN__
- BLI_endian_switch_uint32(&sel_a);
- BLI_endian_switch_uint32(&sel_b);
+ BLI_endian_switch_uint32(&sel_a);
+ BLI_endian_switch_uint32(&sel_b);
#endif
- if (sel_a < sel_b) {
- return -1;
- }
- else if (sel_a > sel_b) {
- return 1;
- }
- else {
- return 0;
- }
+ if (sel_a < sel_b) {
+ return -1;
+ }
+ else if (sel_a > sel_b) {
+ return 1;
+ }
+ else {
+ return 0;
+ }
}
static bool do_object_box_select(bContext *C, ViewContext *vc, rcti *rect, const eSelectOp sel_op)
{
- View3D *v3d = vc->v3d;
- int totobj = MAXPICKBUF; /* XXX solve later */
-
- /* selection buffer now has bones potentially too, so we add MAXPICKBUF */
- uint *vbuffer = MEM_mallocN(4 * (totobj + MAXPICKELEMS) * sizeof(uint[4]), "selection buffer");
- const eV3DSelectObjectFilter select_filter = ED_view3d_select_filter_from_mode(vc->scene, vc->obact);
- const int hits = view3d_opengl_select(
- vc, vbuffer, 4 * (totobj + MAXPICKELEMS), rect,
- VIEW3D_SELECT_ALL, select_filter);
-
- for (Base *base = vc->view_layer->object_bases.first; base; base = base->next) {
- base->object->id.tag &= ~LIB_TAG_DOIT;
- }
-
- Base **bases = NULL;
- BLI_array_declare(bases);
-
- bool changed = false;
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- changed |= object_deselect_all_visible(vc->view_layer, vc->v3d);
- }
-
- if ((hits == -1) && !SEL_OP_USE_OUTSIDE(sel_op)) {
- goto finally;
- }
-
- for (Base *base = vc->view_layer->object_bases.first; base; base = base->next) {
- if (BASE_SELECTABLE(v3d, base)) {
- if ((base->object->select_id & 0x0000FFFF) != 0) {
- BLI_array_append(bases, base);
- }
- }
- }
-
- /* The draw order doesn't always match the order we populate the engine, see: T51695. */
- qsort(vbuffer, hits, sizeof(uint[4]), opengl_bone_select_buffer_cmp);
-
- for (const uint *col = vbuffer + 3, *col_end = col + (hits * 4); col < col_end; col += 4) {
- Bone *bone;
- Base *base = ED_armature_base_and_bone_from_select_buffer(bases, BLI_array_len(bases), *col, &bone);
- if (base != NULL) {
- base->object->id.tag |= LIB_TAG_DOIT;
- }
- }
-
- for (Base *base = vc->view_layer->object_bases.first; base && hits; base = base->next) {
- if (BASE_SELECTABLE(v3d, base)) {
- const bool is_select = base->flag & BASE_SELECTED;
- const bool is_inside = base->object->id.tag & LIB_TAG_DOIT;
- const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- ED_object_base_select(base, sel_op_result ? BA_SELECT : BA_DESELECT);
- changed = true;
- }
- }
- }
+ View3D *v3d = vc->v3d;
+ int totobj = MAXPICKBUF; /* XXX solve later */
+
+ /* selection buffer now has bones potentially too, so we add MAXPICKBUF */
+ uint *vbuffer = MEM_mallocN(4 * (totobj + MAXPICKELEMS) * sizeof(uint[4]), "selection buffer");
+ const eV3DSelectObjectFilter select_filter = ED_view3d_select_filter_from_mode(vc->scene,
+ vc->obact);
+ const int hits = view3d_opengl_select(
+ vc, vbuffer, 4 * (totobj + MAXPICKELEMS), rect, VIEW3D_SELECT_ALL, select_filter);
+
+ for (Base *base = vc->view_layer->object_bases.first; base; base = base->next) {
+ base->object->id.tag &= ~LIB_TAG_DOIT;
+ }
+
+ Base **bases = NULL;
+ BLI_array_declare(bases);
+
+ bool changed = false;
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ changed |= object_deselect_all_visible(vc->view_layer, vc->v3d);
+ }
+
+ if ((hits == -1) && !SEL_OP_USE_OUTSIDE(sel_op)) {
+ goto finally;
+ }
+
+ for (Base *base = vc->view_layer->object_bases.first; base; base = base->next) {
+ if (BASE_SELECTABLE(v3d, base)) {
+ if ((base->object->select_id & 0x0000FFFF) != 0) {
+ BLI_array_append(bases, base);
+ }
+ }
+ }
+
+ /* The draw order doesn't always match the order we populate the engine, see: T51695. */
+ qsort(vbuffer, hits, sizeof(uint[4]), opengl_bone_select_buffer_cmp);
+
+ for (const uint *col = vbuffer + 3, *col_end = col + (hits * 4); col < col_end; col += 4) {
+ Bone *bone;
+ Base *base = ED_armature_base_and_bone_from_select_buffer(
+ bases, BLI_array_len(bases), *col, &bone);
+ if (base != NULL) {
+ base->object->id.tag |= LIB_TAG_DOIT;
+ }
+ }
+
+ for (Base *base = vc->view_layer->object_bases.first; base && hits; base = base->next) {
+ if (BASE_SELECTABLE(v3d, base)) {
+ const bool is_select = base->flag & BASE_SELECTED;
+ const bool is_inside = base->object->id.tag & LIB_TAG_DOIT;
+ const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
+ if (sel_op_result != -1) {
+ ED_object_base_select(base, sel_op_result ? BA_SELECT : BA_DESELECT);
+ changed = true;
+ }
+ }
+ }
finally:
- if (bases != NULL) {
- MEM_freeN(bases);
- }
+ if (bases != NULL) {
+ MEM_freeN(bases);
+ }
- MEM_freeN(vbuffer);
+ MEM_freeN(vbuffer);
- if (changed) {
- DEG_id_tag_update(&vc->scene->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, vc->scene);
- }
- return changed;
+ if (changed) {
+ DEG_id_tag_update(&vc->scene->id, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, vc->scene);
+ }
+ return changed;
}
static bool do_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, const eSelectOp sel_op)
{
- uint bases_len;
- Base **bases = do_pose_tag_select_op_prepare(vc, &bases_len);
-
- int totobj = MAXPICKBUF; /* XXX solve later */
-
- /* selection buffer now has bones potentially too, so we add MAXPICKBUF */
- uint *vbuffer = MEM_mallocN((totobj + MAXPICKELEMS) * sizeof(uint[4]), "selection buffer");
- const eV3DSelectObjectFilter select_filter = ED_view3d_select_filter_from_mode(vc->scene, vc->obact);
- const int hits = view3d_opengl_select(
- vc, vbuffer, 4 * (totobj + MAXPICKELEMS), rect,
- VIEW3D_SELECT_ALL, select_filter);
- /*
- * LOGIC NOTES (theeth):
- * The buffer and ListBase have the same relative order, which makes the selection
- * very simple. Loop through both data sets at the same time, if the color
- * is the same as the object, we have a hit and can move to the next color
- * and object pair, if not, just move to the next object,
- * keeping the same color until we have a hit.
- */
-
- if (hits > 0) {
- /* no need to loop if there's no hit */
-
- /* The draw order doesn't always match the order we populate the engine, see: T51695. */
- qsort(vbuffer, hits, sizeof(uint[4]), opengl_bone_select_buffer_cmp);
-
- for (const uint *col = vbuffer + 3, *col_end = col + (hits * 4); col < col_end; col += 4) {
- Bone *bone;
- Base *base = ED_armature_base_and_bone_from_select_buffer(bases, bases_len, *col, &bone);
-
- if (base == NULL) {
- continue;
- }
-
- /* Loop over contiguous bone hits for 'base'. */
- for (; col != col_end; col += 4) {
- /* should never fail */
- if (bone != NULL) {
- base->object->id.tag |= LIB_TAG_DOIT;
- bone->flag |= BONE_DONE;
- }
-
- /* Select the next bone if we're not switching bases. */
- if (col + 4 != col_end) {
- if ((base->object->select_id & 0x0000FFFF) != (col[4] & 0x0000FFFF)) {
- break;
- }
- if (base->object->pose != NULL) {
- const uint hit_bone = (col[4] & ~BONESEL_ANY) >> 16;
- bPoseChannel *pchan = BLI_findlink(&base->object->pose->chanbase, hit_bone);
- bone = pchan ? pchan->bone : NULL;
- }
- else {
- bone = NULL;
- }
- }
- }
- }
- }
-
- const bool changed_multi = do_pose_tag_select_op_exec(bases, bases_len, sel_op);
- if (changed_multi) {
- DEG_id_tag_update(&vc->scene->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, vc->scene);
- }
-
- if (bases != NULL) {
- MEM_freeN(bases);
- }
- MEM_freeN(vbuffer);
-
- return changed_multi;
+ uint bases_len;
+ Base **bases = do_pose_tag_select_op_prepare(vc, &bases_len);
+
+ int totobj = MAXPICKBUF; /* XXX solve later */
+
+ /* selection buffer now has bones potentially too, so we add MAXPICKBUF */
+ uint *vbuffer = MEM_mallocN((totobj + MAXPICKELEMS) * sizeof(uint[4]), "selection buffer");
+ const eV3DSelectObjectFilter select_filter = ED_view3d_select_filter_from_mode(vc->scene,
+ vc->obact);
+ const int hits = view3d_opengl_select(
+ vc, vbuffer, 4 * (totobj + MAXPICKELEMS), rect, VIEW3D_SELECT_ALL, select_filter);
+ /*
+ * LOGIC NOTES (theeth):
+ * The buffer and ListBase have the same relative order, which makes the selection
+ * very simple. Loop through both data sets at the same time, if the color
+ * is the same as the object, we have a hit and can move to the next color
+ * and object pair, if not, just move to the next object,
+ * keeping the same color until we have a hit.
+ */
+
+ if (hits > 0) {
+ /* no need to loop if there's no hit */
+
+ /* The draw order doesn't always match the order we populate the engine, see: T51695. */
+ qsort(vbuffer, hits, sizeof(uint[4]), opengl_bone_select_buffer_cmp);
+
+ for (const uint *col = vbuffer + 3, *col_end = col + (hits * 4); col < col_end; col += 4) {
+ Bone *bone;
+ Base *base = ED_armature_base_and_bone_from_select_buffer(bases, bases_len, *col, &bone);
+
+ if (base == NULL) {
+ continue;
+ }
+
+ /* Loop over contiguous bone hits for 'base'. */
+ for (; col != col_end; col += 4) {
+ /* should never fail */
+ if (bone != NULL) {
+ base->object->id.tag |= LIB_TAG_DOIT;
+ bone->flag |= BONE_DONE;
+ }
+
+ /* Select the next bone if we're not switching bases. */
+ if (col + 4 != col_end) {
+ if ((base->object->select_id & 0x0000FFFF) != (col[4] & 0x0000FFFF)) {
+ break;
+ }
+ if (base->object->pose != NULL) {
+ const uint hit_bone = (col[4] & ~BONESEL_ANY) >> 16;
+ bPoseChannel *pchan = BLI_findlink(&base->object->pose->chanbase, hit_bone);
+ bone = pchan ? pchan->bone : NULL;
+ }
+ else {
+ bone = NULL;
+ }
+ }
+ }
+ }
+ }
+
+ const bool changed_multi = do_pose_tag_select_op_exec(bases, bases_len, sel_op);
+ if (changed_multi) {
+ DEG_id_tag_update(&vc->scene->id, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, vc->scene);
+ }
+
+ if (bases != NULL) {
+ MEM_freeN(bases);
+ }
+ MEM_freeN(vbuffer);
+
+ return changed_multi;
}
static int view3d_box_select_exec(bContext *C, wmOperator *op)
{
- ViewContext vc;
- rcti rect;
- bool changed_multi = false;
-
- view3d_operator_needs_opengl(C);
-
- /* setup view context for argument to callbacks */
- ED_view3d_viewcontext_init(C, &vc);
-
- eSelectOp sel_op = RNA_enum_get(op->ptr, "mode");
- WM_operator_properties_border_to_rcti(op, &rect);
-
- if (vc.obedit) {
-
- FOREACH_OBJECT_IN_MODE_BEGIN (vc.view_layer, vc.v3d, vc.obedit->type, vc.obedit->mode, ob_iter) {
- ED_view3d_viewcontext_init_object(&vc, ob_iter);
- bool changed = false;
-
- switch (vc.obedit->type) {
- case OB_MESH:
- vc.em = BKE_editmesh_from_object(vc.obedit);
- changed = do_mesh_box_select(&vc, &rect, sel_op);
- if (changed) {
- DEG_id_tag_update(vc.obedit->data, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
- }
- break;
- case OB_CURVE:
- case OB_SURF:
- changed = do_nurbs_box_select(&vc, &rect, sel_op);
- if (changed) {
- DEG_id_tag_update(vc.obedit->data, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
- }
- break;
- case OB_MBALL:
- changed = do_meta_box_select(&vc, &rect, sel_op);
- if (changed) {
- DEG_id_tag_update(vc.obedit->data, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
- }
- break;
- case OB_ARMATURE:
- changed = do_armature_box_select(&vc, &rect, sel_op);
- if (changed) {
- DEG_id_tag_update(&vc.obedit->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, vc.obedit);
- }
- break;
- case OB_LATTICE:
- changed = do_lattice_box_select(&vc, &rect, sel_op);
- if (changed) {
- DEG_id_tag_update(vc.obedit->data, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
- }
- break;
- default:
- assert(!"box select on incorrect object type");
- break;
- }
- changed_multi |= changed;
- }
- FOREACH_OBJECT_IN_MODE_END;
- }
- else { /* no editmode, unified for bones and objects */
- if (vc.obact && vc.obact->mode & OB_MODE_SCULPT) {
- /* XXX, this is not selection, could be it's own operator. */
- changed_multi = ED_sculpt_mask_box_select(C, &vc, &rect, sel_op == SEL_OP_ADD ? true : false);
- }
- else if (vc.obact && BKE_paint_select_face_test(vc.obact)) {
- changed_multi = do_paintface_box_select(&vc, &rect, sel_op);
- }
- else if (vc.obact && BKE_paint_select_vert_test(vc.obact)) {
- changed_multi = do_paintvert_box_select(&vc, &rect, sel_op);
- }
- else if (vc.obact && vc.obact->mode & OB_MODE_PARTICLE_EDIT) {
- changed_multi = PE_box_select(C, &rect, sel_op);
- }
- else if (vc.obact && vc.obact->mode & OB_MODE_POSE) {
- changed_multi = do_pose_box_select(C, &vc, &rect, sel_op);
- }
- else { /* object mode with none active */
- changed_multi = do_object_box_select(C, &vc, &rect, sel_op);
- }
- }
-
- if (changed_multi) {
- return OPERATOR_FINISHED;
- }
- else {
- return OPERATOR_CANCELLED;
- }
+ ViewContext vc;
+ rcti rect;
+ bool changed_multi = false;
+
+ view3d_operator_needs_opengl(C);
+
+ /* setup view context for argument to callbacks */
+ ED_view3d_viewcontext_init(C, &vc);
+
+ eSelectOp sel_op = RNA_enum_get(op->ptr, "mode");
+ WM_operator_properties_border_to_rcti(op, &rect);
+
+ if (vc.obedit) {
+
+ FOREACH_OBJECT_IN_MODE_BEGIN (
+ vc.view_layer, vc.v3d, vc.obedit->type, vc.obedit->mode, ob_iter) {
+ ED_view3d_viewcontext_init_object(&vc, ob_iter);
+ bool changed = false;
+
+ switch (vc.obedit->type) {
+ case OB_MESH:
+ vc.em = BKE_editmesh_from_object(vc.obedit);
+ changed = do_mesh_box_select(&vc, &rect, sel_op);
+ if (changed) {
+ DEG_id_tag_update(vc.obedit->data, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
+ }
+ break;
+ case OB_CURVE:
+ case OB_SURF:
+ changed = do_nurbs_box_select(&vc, &rect, sel_op);
+ if (changed) {
+ DEG_id_tag_update(vc.obedit->data, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
+ }
+ break;
+ case OB_MBALL:
+ changed = do_meta_box_select(&vc, &rect, sel_op);
+ if (changed) {
+ DEG_id_tag_update(vc.obedit->data, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
+ }
+ break;
+ case OB_ARMATURE:
+ changed = do_armature_box_select(&vc, &rect, sel_op);
+ if (changed) {
+ DEG_id_tag_update(&vc.obedit->id, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, vc.obedit);
+ }
+ break;
+ case OB_LATTICE:
+ changed = do_lattice_box_select(&vc, &rect, sel_op);
+ if (changed) {
+ DEG_id_tag_update(vc.obedit->data, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
+ }
+ break;
+ default:
+ assert(!"box select on incorrect object type");
+ break;
+ }
+ changed_multi |= changed;
+ }
+ FOREACH_OBJECT_IN_MODE_END;
+ }
+ else { /* no editmode, unified for bones and objects */
+ if (vc.obact && vc.obact->mode & OB_MODE_SCULPT) {
+ /* XXX, this is not selection, could be it's own operator. */
+ changed_multi = ED_sculpt_mask_box_select(
+ C, &vc, &rect, sel_op == SEL_OP_ADD ? true : false);
+ }
+ else if (vc.obact && BKE_paint_select_face_test(vc.obact)) {
+ changed_multi = do_paintface_box_select(&vc, &rect, sel_op);
+ }
+ else if (vc.obact && BKE_paint_select_vert_test(vc.obact)) {
+ changed_multi = do_paintvert_box_select(&vc, &rect, sel_op);
+ }
+ else if (vc.obact && vc.obact->mode & OB_MODE_PARTICLE_EDIT) {
+ changed_multi = PE_box_select(C, &rect, sel_op);
+ }
+ else if (vc.obact && vc.obact->mode & OB_MODE_POSE) {
+ changed_multi = do_pose_box_select(C, &vc, &rect, sel_op);
+ }
+ else { /* object mode with none active */
+ changed_multi = do_object_box_select(C, &vc, &rect, sel_op);
+ }
+ }
+
+ if (changed_multi) {
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
void VIEW3D_OT_select_box(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Box Select";
- ot->description = "Select items using box selection";
- ot->idname = "VIEW3D_OT_select_box";
+ /* identifiers */
+ ot->name = "Box Select";
+ ot->description = "Select items using box selection";
+ ot->idname = "VIEW3D_OT_select_box";
- /* api callbacks */
- ot->invoke = WM_gesture_box_invoke;
- ot->exec = view3d_box_select_exec;
- ot->modal = WM_gesture_box_modal;
- ot->poll = view3d_selectable_data;
- ot->cancel = WM_gesture_box_cancel;
+ /* api callbacks */
+ ot->invoke = WM_gesture_box_invoke;
+ ot->exec = view3d_box_select_exec;
+ ot->modal = WM_gesture_box_modal;
+ ot->poll = view3d_selectable_data;
+ ot->cancel = WM_gesture_box_cancel;
- /* flags */
- ot->flag = OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
- /* rna */
- WM_operator_properties_gesture_box(ot);
- WM_operator_properties_select_operation(ot);
+ /* rna */
+ WM_operator_properties_gesture_box(ot);
+ WM_operator_properties_select_operation(ot);
}
/** \} */
@@ -2947,638 +3056,691 @@ void VIEW3D_OT_select_box(wmOperatorType *ot)
* \{ */
typedef struct CircleSelectUserData {
- ViewContext *vc;
- bool select;
- int mval[2];
- float mval_fl[2];
- float radius;
- float radius_squared;
-
- /* runtime */
- bool is_changed;
+ ViewContext *vc;
+ bool select;
+ int mval[2];
+ float mval_fl[2];
+ float radius;
+ float radius_squared;
+
+ /* runtime */
+ bool is_changed;
} CircleSelectUserData;
-static void view3d_userdata_circleselect_init(
- CircleSelectUserData *r_data,
- ViewContext *vc, const bool select, const int mval[2], const float rad)
+static void view3d_userdata_circleselect_init(CircleSelectUserData *r_data,
+ ViewContext *vc,
+ const bool select,
+ const int mval[2],
+ const float rad)
{
- r_data->vc = vc;
- r_data->select = select;
- copy_v2_v2_int(r_data->mval, mval);
- r_data->mval_fl[0] = mval[0];
- r_data->mval_fl[1] = mval[1];
+ r_data->vc = vc;
+ r_data->select = select;
+ copy_v2_v2_int(r_data->mval, mval);
+ r_data->mval_fl[0] = mval[0];
+ r_data->mval_fl[1] = mval[1];
- r_data->radius = rad;
- r_data->radius_squared = rad * rad;
+ r_data->radius = rad;
+ r_data->radius_squared = rad * rad;
- /* runtime */
- r_data->is_changed = false;
+ /* runtime */
+ r_data->is_changed = false;
}
-static void mesh_circle_doSelectVert(void *userData, BMVert *eve, const float screen_co[2], int UNUSED(index))
+static void mesh_circle_doSelectVert(void *userData,
+ BMVert *eve,
+ const float screen_co[2],
+ int UNUSED(index))
{
- CircleSelectUserData *data = userData;
+ CircleSelectUserData *data = userData;
- if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
- BM_vert_select_set(data->vc->em->bm, eve, data->select);
- data->is_changed = true;
- }
+ if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
+ BM_vert_select_set(data->vc->em->bm, eve, data->select);
+ data->is_changed = true;
+ }
}
-static void mesh_circle_doSelectEdge(
- void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int UNUSED(index))
+static void mesh_circle_doSelectEdge(void *userData,
+ BMEdge *eed,
+ const float screen_co_a[2],
+ const float screen_co_b[2],
+ int UNUSED(index))
{
- CircleSelectUserData *data = userData;
+ CircleSelectUserData *data = userData;
- if (edge_inside_circle(data->mval_fl, data->radius, screen_co_a, screen_co_b)) {
- BM_edge_select_set(data->vc->em->bm, eed, data->select);
- data->is_changed = true;
- }
+ if (edge_inside_circle(data->mval_fl, data->radius, screen_co_a, screen_co_b)) {
+ BM_edge_select_set(data->vc->em->bm, eed, data->select);
+ data->is_changed = true;
+ }
}
-static void mesh_circle_doSelectFace(void *userData, BMFace *efa, const float screen_co[2], int UNUSED(index))
+static void mesh_circle_doSelectFace(void *userData,
+ BMFace *efa,
+ const float screen_co[2],
+ int UNUSED(index))
{
- CircleSelectUserData *data = userData;
+ CircleSelectUserData *data = userData;
- if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
- BM_face_select_set(data->vc->em->bm, efa, data->select);
- data->is_changed = true;
- }
+ if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
+ BM_face_select_set(data->vc->em->bm, efa, data->select);
+ data->is_changed = true;
+ }
}
static bool mesh_circle_select(ViewContext *vc, eSelectOp sel_op, const int mval[2], float rad)
{
- ToolSettings *ts = vc->scene->toolsettings;
- int bbsel;
- CircleSelectUserData data;
- vc->em = BKE_editmesh_from_object(vc->obedit);
-
- bool changed = false;
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- if (vc->em->bm->totvertsel) {
- EDBM_flag_disable_all(vc->em, BM_ELEM_SELECT);
- changed = true;
- }
- }
- const bool select = (sel_op != SEL_OP_SUB);
-
- bbsel = EDBM_backbuf_circle_init(vc, mval[0], mval[1], (short)(rad + 1.0f));
- ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
-
- view3d_userdata_circleselect_init(&data, vc, select, mval, rad);
-
- if (ts->selectmode & SCE_SELECT_VERTEX) {
- if (bbsel) {
- changed |= edbm_backbuf_check_and_select_verts(vc->em, select ? SEL_OP_ADD : SEL_OP_SUB);
- }
- else {
- mesh_foreachScreenVert(vc, mesh_circle_doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
- }
- }
-
- if (ts->selectmode & SCE_SELECT_EDGE) {
- if (bbsel) {
- changed |= edbm_backbuf_check_and_select_edges(vc->em, select ? SEL_OP_ADD : SEL_OP_SUB);
- }
- else {
- mesh_foreachScreenEdge(vc, mesh_circle_doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
- }
- }
-
- if (ts->selectmode & SCE_SELECT_FACE) {
- if (bbsel) {
- changed |= edbm_backbuf_check_and_select_faces(vc->em, select ? SEL_OP_ADD : SEL_OP_SUB);
- }
- else {
- mesh_foreachScreenFace(vc, mesh_circle_doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
- }
- }
-
- changed |= data.is_changed;
-
- EDBM_backbuf_free();
-
- if (changed) {
- EDBM_selectmode_flush(vc->em);
- }
- return changed;
-}
-
-static bool paint_facesel_circle_select(ViewContext *vc, const eSelectOp sel_op, const int mval[2], float rad)
-{
- BLI_assert(ELEM(sel_op, SEL_OP_SET, SEL_OP_ADD, SEL_OP_SUB));
- Object *ob = vc->obact;
- Mesh *me = ob->data;
- bool bbsel;
-
- bool changed = false;
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- /* flush selection at the end */
- changed |= paintface_deselect_all_visible(vc->C, ob, SEL_DESELECT, false);
- }
-
- bm_vertoffs = me->totpoly + 1; /* max index array */
-
- bbsel = EDBM_backbuf_circle_init(vc, mval[0], mval[1], (short)(rad + 1.0f));
- if (bbsel) {
- changed |= edbm_backbuf_check_and_select_tfaces(me, sel_op);
- EDBM_backbuf_free();
- }
- if (changed) {
- paintface_flush_flags(vc->C, ob, SELECT);
- }
- return changed;
-}
-
-static void paint_vertsel_circle_select_doSelectVert(void *userData, MVert *mv, const float screen_co[2], int UNUSED(index))
-{
- CircleSelectUserData *data = userData;
-
- if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
- SET_FLAG_FROM_TEST(mv->flag, data->select, SELECT);
- data->is_changed = true;
- }
-}
-static bool paint_vertsel_circle_select(ViewContext *vc, const eSelectOp sel_op, const int mval[2], float rad)
-{
- BLI_assert(ELEM(sel_op, SEL_OP_SET, SEL_OP_ADD, SEL_OP_SUB));
- const bool use_zbuf = !XRAY_ENABLED(vc->v3d);
- Object *ob = vc->obact;
- Mesh *me = ob->data;
- bool bbsel;
- /* CircleSelectUserData data = {NULL}; */ /* UNUSED */
-
- bool changed = false;
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- changed |= paintvert_deselect_all_visible(ob, SEL_DESELECT, false); /* flush selection at the end */
- }
-
- const bool select = (sel_op != SEL_OP_SUB);
-
- if (use_zbuf) {
- bm_vertoffs = me->totvert + 1; /* max index array */
-
- bbsel = EDBM_backbuf_circle_init(vc, mval[0], mval[1], (short)(rad + 1.0f));
- if (bbsel) {
- changed |= edbm_backbuf_check_and_select_verts_obmode(me, sel_op);
- EDBM_backbuf_free();
- }
- }
- else {
- CircleSelectUserData data;
-
- ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); /* for foreach's screen/vert projection */
-
- view3d_userdata_circleselect_init(&data, vc, select, mval, rad);
- meshobject_foreachScreenVert(vc, paint_vertsel_circle_select_doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
- changed |= data.is_changed;
- }
-
- if (changed) {
- if (sel_op == SEL_OP_SUB) {
- BKE_mesh_mselect_validate(me);
- }
- paintvert_flush_flags(ob);
- paintvert_tag_select_update(vc->C, ob);
- }
- return changed;
-}
-
-
-static void nurbscurve_circle_doSelect(
- void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co[2])
-{
- CircleSelectUserData *data = userData;
-
- if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
- if (bp) {
- bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT);
- }
- else {
- if ((data->vc->v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_CU_HANDLES) == 0) {
- /* can only be (beztindex == 0) here since handles are hidden */
- bezt->f1 = bezt->f2 = bezt->f3 = data->select ? (bezt->f2 | SELECT) : (bezt->f2 & ~SELECT);
- }
- else {
- if (beztindex == 0) {
- bezt->f1 = data->select ? (bezt->f1 | SELECT) : (bezt->f1 & ~SELECT);
- }
- else if (beztindex == 1) {
- bezt->f2 = data->select ? (bezt->f2 | SELECT) : (bezt->f2 & ~SELECT);
- }
- else {
- bezt->f3 = data->select ? (bezt->f3 | SELECT) : (bezt->f3 & ~SELECT);
- }
- }
- }
- data->is_changed = true;
- }
-}
-static bool nurbscurve_circle_select(ViewContext *vc, const eSelectOp sel_op, const int mval[2], float rad)
-{
- CircleSelectUserData data;
- bool changed = false;
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- Curve *curve = vc->obedit->data;
- changed |= ED_curve_deselect_all(curve->editnurb);
- }
- const bool select = (sel_op != SEL_OP_SUB);
-
- view3d_userdata_circleselect_init(&data, vc, select, mval, rad);
-
- ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
- nurbs_foreachScreenVert(vc, nurbscurve_circle_doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
- BKE_curve_nurb_vert_active_validate(vc->obedit->data);
-
- return changed || data.is_changed;
+ ToolSettings *ts = vc->scene->toolsettings;
+ int bbsel;
+ CircleSelectUserData data;
+ vc->em = BKE_editmesh_from_object(vc->obedit);
+
+ bool changed = false;
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ if (vc->em->bm->totvertsel) {
+ EDBM_flag_disable_all(vc->em, BM_ELEM_SELECT);
+ changed = true;
+ }
+ }
+ const bool select = (sel_op != SEL_OP_SUB);
+
+ bbsel = EDBM_backbuf_circle_init(vc, mval[0], mval[1], (short)(rad + 1.0f));
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
+
+ view3d_userdata_circleselect_init(&data, vc, select, mval, rad);
+
+ if (ts->selectmode & SCE_SELECT_VERTEX) {
+ if (bbsel) {
+ changed |= edbm_backbuf_check_and_select_verts(vc->em, select ? SEL_OP_ADD : SEL_OP_SUB);
+ }
+ else {
+ mesh_foreachScreenVert(vc, mesh_circle_doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ }
+ }
+
+ if (ts->selectmode & SCE_SELECT_EDGE) {
+ if (bbsel) {
+ changed |= edbm_backbuf_check_and_select_edges(vc->em, select ? SEL_OP_ADD : SEL_OP_SUB);
+ }
+ else {
+ mesh_foreachScreenEdge(vc, mesh_circle_doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
+ }
+ }
+
+ if (ts->selectmode & SCE_SELECT_FACE) {
+ if (bbsel) {
+ changed |= edbm_backbuf_check_and_select_faces(vc->em, select ? SEL_OP_ADD : SEL_OP_SUB);
+ }
+ else {
+ mesh_foreachScreenFace(vc, mesh_circle_doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ }
+ }
+
+ changed |= data.is_changed;
+
+ EDBM_backbuf_free();
+
+ if (changed) {
+ EDBM_selectmode_flush(vc->em);
+ }
+ return changed;
+}
+
+static bool paint_facesel_circle_select(ViewContext *vc,
+ const eSelectOp sel_op,
+ const int mval[2],
+ float rad)
+{
+ BLI_assert(ELEM(sel_op, SEL_OP_SET, SEL_OP_ADD, SEL_OP_SUB));
+ Object *ob = vc->obact;
+ Mesh *me = ob->data;
+ bool bbsel;
+
+ bool changed = false;
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ /* flush selection at the end */
+ changed |= paintface_deselect_all_visible(vc->C, ob, SEL_DESELECT, false);
+ }
+
+ bm_vertoffs = me->totpoly + 1; /* max index array */
+
+ bbsel = EDBM_backbuf_circle_init(vc, mval[0], mval[1], (short)(rad + 1.0f));
+ if (bbsel) {
+ changed |= edbm_backbuf_check_and_select_tfaces(me, sel_op);
+ EDBM_backbuf_free();
+ }
+ if (changed) {
+ paintface_flush_flags(vc->C, ob, SELECT);
+ }
+ return changed;
+}
+
+static void paint_vertsel_circle_select_doSelectVert(void *userData,
+ MVert *mv,
+ const float screen_co[2],
+ int UNUSED(index))
+{
+ CircleSelectUserData *data = userData;
+
+ if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
+ SET_FLAG_FROM_TEST(mv->flag, data->select, SELECT);
+ data->is_changed = true;
+ }
+}
+static bool paint_vertsel_circle_select(ViewContext *vc,
+ const eSelectOp sel_op,
+ const int mval[2],
+ float rad)
+{
+ BLI_assert(ELEM(sel_op, SEL_OP_SET, SEL_OP_ADD, SEL_OP_SUB));
+ const bool use_zbuf = !XRAY_ENABLED(vc->v3d);
+ Object *ob = vc->obact;
+ Mesh *me = ob->data;
+ bool bbsel;
+ /* CircleSelectUserData data = {NULL}; */ /* UNUSED */
+
+ bool changed = false;
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ changed |= paintvert_deselect_all_visible(
+ ob, SEL_DESELECT, false); /* flush selection at the end */
+ }
+
+ const bool select = (sel_op != SEL_OP_SUB);
+
+ if (use_zbuf) {
+ bm_vertoffs = me->totvert + 1; /* max index array */
+
+ bbsel = EDBM_backbuf_circle_init(vc, mval[0], mval[1], (short)(rad + 1.0f));
+ if (bbsel) {
+ changed |= edbm_backbuf_check_and_select_verts_obmode(me, sel_op);
+ EDBM_backbuf_free();
+ }
+ }
+ else {
+ CircleSelectUserData data;
+
+ ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); /* for foreach's screen/vert projection */
+
+ view3d_userdata_circleselect_init(&data, vc, select, mval, rad);
+ meshobject_foreachScreenVert(
+ vc, paint_vertsel_circle_select_doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ changed |= data.is_changed;
+ }
+
+ if (changed) {
+ if (sel_op == SEL_OP_SUB) {
+ BKE_mesh_mselect_validate(me);
+ }
+ paintvert_flush_flags(ob);
+ paintvert_tag_select_update(vc->C, ob);
+ }
+ return changed;
+}
+
+static void nurbscurve_circle_doSelect(void *userData,
+ Nurb *UNUSED(nu),
+ BPoint *bp,
+ BezTriple *bezt,
+ int beztindex,
+ const float screen_co[2])
+{
+ CircleSelectUserData *data = userData;
+
+ if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
+ if (bp) {
+ bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT);
+ }
+ else {
+ if ((data->vc->v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_CU_HANDLES) == 0) {
+ /* can only be (beztindex == 0) here since handles are hidden */
+ bezt->f1 = bezt->f2 = bezt->f3 = data->select ? (bezt->f2 | SELECT) : (bezt->f2 & ~SELECT);
+ }
+ else {
+ if (beztindex == 0) {
+ bezt->f1 = data->select ? (bezt->f1 | SELECT) : (bezt->f1 & ~SELECT);
+ }
+ else if (beztindex == 1) {
+ bezt->f2 = data->select ? (bezt->f2 | SELECT) : (bezt->f2 & ~SELECT);
+ }
+ else {
+ bezt->f3 = data->select ? (bezt->f3 | SELECT) : (bezt->f3 & ~SELECT);
+ }
+ }
+ }
+ data->is_changed = true;
+ }
+}
+static bool nurbscurve_circle_select(ViewContext *vc,
+ const eSelectOp sel_op,
+ const int mval[2],
+ float rad)
+{
+ CircleSelectUserData data;
+ bool changed = false;
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ Curve *curve = vc->obedit->data;
+ changed |= ED_curve_deselect_all(curve->editnurb);
+ }
+ const bool select = (sel_op != SEL_OP_SUB);
+
+ view3d_userdata_circleselect_init(&data, vc, select, mval, rad);
+
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
+ nurbs_foreachScreenVert(vc, nurbscurve_circle_doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ BKE_curve_nurb_vert_active_validate(vc->obedit->data);
+
+ return changed || data.is_changed;
}
-
static void latticecurve_circle_doSelect(void *userData, BPoint *bp, const float screen_co[2])
{
- CircleSelectUserData *data = userData;
+ CircleSelectUserData *data = userData;
- if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
- bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT);
- data->is_changed = true;
- }
+ if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
+ bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT);
+ data->is_changed = true;
+ }
}
-static bool lattice_circle_select(ViewContext *vc, const eSelectOp sel_op, const int mval[2], float rad)
+static bool lattice_circle_select(ViewContext *vc,
+ const eSelectOp sel_op,
+ const int mval[2],
+ float rad)
{
- CircleSelectUserData data;
- const bool select = (sel_op != SEL_OP_SUB);
+ CircleSelectUserData data;
+ const bool select = (sel_op != SEL_OP_SUB);
- view3d_userdata_circleselect_init(&data, vc, select, mval, rad);
+ view3d_userdata_circleselect_init(&data, vc, select, mval, rad);
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- data.is_changed |= ED_lattice_flags_set(vc->obedit, 0);
- }
- ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ data.is_changed |= ED_lattice_flags_set(vc->obedit, 0);
+ }
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
- lattice_foreachScreenVert(vc, latticecurve_circle_doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ lattice_foreachScreenVert(vc, latticecurve_circle_doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
- return data.is_changed;
+ return data.is_changed;
}
-
/* NOTE: pose-bone case is copied from editbone case... */
-static bool pchan_circle_doSelectJoint(void *userData, bPoseChannel *pchan, const float screen_co[2])
-{
- CircleSelectUserData *data = userData;
-
- if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
- if (data->select) {
- pchan->bone->flag |= BONE_SELECTED;
- }
- else {
- pchan->bone->flag &= ~BONE_SELECTED;
- }
- return 1;
- }
- return 0;
-}
-static void do_circle_select_pose__doSelectBone(
- void *userData, struct bPoseChannel *pchan, const float screen_co_a[2], const float screen_co_b[2])
-{
- CircleSelectUserData *data = userData;
- bArmature *arm = data->vc->obact->data;
-
- if (PBONE_SELECTABLE(arm, pchan->bone)) {
- bool is_point_done = false;
- int points_proj_tot = 0;
-
- /* project head location to screenspace */
- if (screen_co_a[0] != IS_CLIPPED) {
- points_proj_tot++;
- if (pchan_circle_doSelectJoint(data, pchan, screen_co_a)) {
- is_point_done = true;
- }
- }
-
- /* project tail location to screenspace */
- if (screen_co_b[0] != IS_CLIPPED) {
- points_proj_tot++;
- if (pchan_circle_doSelectJoint(data, pchan, screen_co_b)) {
- is_point_done = true;
- }
- }
-
- /* check if the head and/or tail is in the circle
- * - the call to check also does the selection already
- */
-
- /* only if the endpoints didn't get selected, deal with the middle of the bone too
- * It works nicer to only do this if the head or tail are not in the circle,
- * otherwise there is no way to circle select joints alone */
- if ((is_point_done == false) && (points_proj_tot == 2) &&
- edge_inside_circle(data->mval_fl, data->radius, screen_co_a, screen_co_b))
- {
- if (data->select) {
- pchan->bone->flag |= BONE_SELECTED;
- }
- else {
- pchan->bone->flag &= ~BONE_SELECTED;
- }
- data->is_changed = true;
- }
-
- data->is_changed |= is_point_done;
- }
-}
-static bool pose_circle_select(ViewContext *vc, const eSelectOp sel_op, const int mval[2], float rad)
-{
- BLI_assert(ELEM(sel_op, SEL_OP_SET, SEL_OP_ADD, SEL_OP_SUB));
- CircleSelectUserData data;
- const bool select = (sel_op != SEL_OP_SUB);
-
- view3d_userdata_circleselect_init(&data, vc, select, mval, rad);
-
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- data.is_changed |= ED_pose_deselect_all(vc->obact, SEL_DESELECT, false);
- }
-
- ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); /* for foreach's screen/vert projection */
-
- pose_foreachScreenBone(vc, do_circle_select_pose__doSelectBone, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
-
- if (data.is_changed) {
- ED_pose_bone_select_tag_update(vc->obact);
- }
- return data.is_changed;
-}
-
-static bool armature_circle_doSelectJoint(void *userData, EditBone *ebone, const float screen_co[2], bool head)
-{
- CircleSelectUserData *data = userData;
-
- if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
- if (head) {
- if (data->select) {
- ebone->flag |= BONE_ROOTSEL;
- }
- else {
- ebone->flag &= ~BONE_ROOTSEL;
- }
- }
- else {
- if (data->select) {
- ebone->flag |= BONE_TIPSEL;
- }
- else {
- ebone->flag &= ~BONE_TIPSEL;
- }
- }
- return 1;
- }
- return 0;
-}
-static void do_circle_select_armature__doSelectBone(
- void *userData, struct EditBone *ebone, const float screen_co_a[2], const float screen_co_b[2])
-{
- CircleSelectUserData *data = userData;
- bArmature *arm = data->vc->obedit->data;
-
- if (data->select ? EBONE_SELECTABLE(arm, ebone) : EBONE_VISIBLE(arm, ebone)) {
- bool is_point_done = false;
- int points_proj_tot = 0;
-
- /* project head location to screenspace */
- if (screen_co_a[0] != IS_CLIPPED) {
- points_proj_tot++;
- if (armature_circle_doSelectJoint(data, ebone, screen_co_a, true)) {
- is_point_done = true;
- }
- }
-
- /* project tail location to screenspace */
- if (screen_co_b[0] != IS_CLIPPED) {
- points_proj_tot++;
- if (armature_circle_doSelectJoint(data, ebone, screen_co_b, false)) {
- is_point_done = true;
- }
- }
-
- /* check if the head and/or tail is in the circle
- * - the call to check also does the selection already
- */
-
- /* only if the endpoints didn't get selected, deal with the middle of the bone too
- * It works nicer to only do this if the head or tail are not in the circle,
- * otherwise there is no way to circle select joints alone */
- if ((is_point_done == false) && (points_proj_tot == 2) &&
- edge_inside_circle(data->mval_fl, data->radius, screen_co_a, screen_co_b))
- {
- if (data->select) {
- ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
- }
- else {
- ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
- }
- data->is_changed = true;
- }
-
- data->is_changed |= is_point_done;
- }
-}
-static bool armature_circle_select(ViewContext *vc, const eSelectOp sel_op, const int mval[2], float rad)
+static bool pchan_circle_doSelectJoint(void *userData,
+ bPoseChannel *pchan,
+ const float screen_co[2])
+{
+ CircleSelectUserData *data = userData;
+
+ if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
+ if (data->select) {
+ pchan->bone->flag |= BONE_SELECTED;
+ }
+ else {
+ pchan->bone->flag &= ~BONE_SELECTED;
+ }
+ return 1;
+ }
+ return 0;
+}
+static void do_circle_select_pose__doSelectBone(void *userData,
+ struct bPoseChannel *pchan,
+ const float screen_co_a[2],
+ const float screen_co_b[2])
+{
+ CircleSelectUserData *data = userData;
+ bArmature *arm = data->vc->obact->data;
+
+ if (PBONE_SELECTABLE(arm, pchan->bone)) {
+ bool is_point_done = false;
+ int points_proj_tot = 0;
+
+ /* project head location to screenspace */
+ if (screen_co_a[0] != IS_CLIPPED) {
+ points_proj_tot++;
+ if (pchan_circle_doSelectJoint(data, pchan, screen_co_a)) {
+ is_point_done = true;
+ }
+ }
+
+ /* project tail location to screenspace */
+ if (screen_co_b[0] != IS_CLIPPED) {
+ points_proj_tot++;
+ if (pchan_circle_doSelectJoint(data, pchan, screen_co_b)) {
+ is_point_done = true;
+ }
+ }
+
+ /* check if the head and/or tail is in the circle
+ * - the call to check also does the selection already
+ */
+
+ /* only if the endpoints didn't get selected, deal with the middle of the bone too
+ * It works nicer to only do this if the head or tail are not in the circle,
+ * otherwise there is no way to circle select joints alone */
+ if ((is_point_done == false) && (points_proj_tot == 2) &&
+ edge_inside_circle(data->mval_fl, data->radius, screen_co_a, screen_co_b)) {
+ if (data->select) {
+ pchan->bone->flag |= BONE_SELECTED;
+ }
+ else {
+ pchan->bone->flag &= ~BONE_SELECTED;
+ }
+ data->is_changed = true;
+ }
+
+ data->is_changed |= is_point_done;
+ }
+}
+static bool pose_circle_select(ViewContext *vc,
+ const eSelectOp sel_op,
+ const int mval[2],
+ float rad)
+{
+ BLI_assert(ELEM(sel_op, SEL_OP_SET, SEL_OP_ADD, SEL_OP_SUB));
+ CircleSelectUserData data;
+ const bool select = (sel_op != SEL_OP_SUB);
+
+ view3d_userdata_circleselect_init(&data, vc, select, mval, rad);
+
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ data.is_changed |= ED_pose_deselect_all(vc->obact, SEL_DESELECT, false);
+ }
+
+ ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); /* for foreach's screen/vert projection */
+
+ pose_foreachScreenBone(
+ vc, do_circle_select_pose__doSelectBone, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+
+ if (data.is_changed) {
+ ED_pose_bone_select_tag_update(vc->obact);
+ }
+ return data.is_changed;
+}
+
+static bool armature_circle_doSelectJoint(void *userData,
+ EditBone *ebone,
+ const float screen_co[2],
+ bool head)
+{
+ CircleSelectUserData *data = userData;
+
+ if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
+ if (head) {
+ if (data->select) {
+ ebone->flag |= BONE_ROOTSEL;
+ }
+ else {
+ ebone->flag &= ~BONE_ROOTSEL;
+ }
+ }
+ else {
+ if (data->select) {
+ ebone->flag |= BONE_TIPSEL;
+ }
+ else {
+ ebone->flag &= ~BONE_TIPSEL;
+ }
+ }
+ return 1;
+ }
+ return 0;
+}
+static void do_circle_select_armature__doSelectBone(void *userData,
+ struct EditBone *ebone,
+ const float screen_co_a[2],
+ const float screen_co_b[2])
+{
+ CircleSelectUserData *data = userData;
+ bArmature *arm = data->vc->obedit->data;
+
+ if (data->select ? EBONE_SELECTABLE(arm, ebone) : EBONE_VISIBLE(arm, ebone)) {
+ bool is_point_done = false;
+ int points_proj_tot = 0;
+
+ /* project head location to screenspace */
+ if (screen_co_a[0] != IS_CLIPPED) {
+ points_proj_tot++;
+ if (armature_circle_doSelectJoint(data, ebone, screen_co_a, true)) {
+ is_point_done = true;
+ }
+ }
+
+ /* project tail location to screenspace */
+ if (screen_co_b[0] != IS_CLIPPED) {
+ points_proj_tot++;
+ if (armature_circle_doSelectJoint(data, ebone, screen_co_b, false)) {
+ is_point_done = true;
+ }
+ }
+
+ /* check if the head and/or tail is in the circle
+ * - the call to check also does the selection already
+ */
+
+ /* only if the endpoints didn't get selected, deal with the middle of the bone too
+ * It works nicer to only do this if the head or tail are not in the circle,
+ * otherwise there is no way to circle select joints alone */
+ if ((is_point_done == false) && (points_proj_tot == 2) &&
+ edge_inside_circle(data->mval_fl, data->radius, screen_co_a, screen_co_b)) {
+ if (data->select) {
+ ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
+ }
+ else {
+ ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
+ }
+ data->is_changed = true;
+ }
+
+ data->is_changed |= is_point_done;
+ }
+}
+static bool armature_circle_select(ViewContext *vc,
+ const eSelectOp sel_op,
+ const int mval[2],
+ float rad)
+{
+ CircleSelectUserData data;
+ bArmature *arm = vc->obedit->data;
+
+ const bool select = (sel_op != SEL_OP_SUB);
+
+ view3d_userdata_circleselect_init(&data, vc, select, mval, rad);
+
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ data.is_changed |= ED_armature_edit_deselect_all_visible(vc->obedit);
+ }
+
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
+
+ armature_foreachScreenBone(
+ vc, do_circle_select_armature__doSelectBone, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+
+ if (data.is_changed) {
+ ED_armature_edit_sync_selection(arm->edbo);
+ ED_armature_edit_validate_active(arm);
+ WM_main_add_notifier(NC_OBJECT | ND_BONE_SELECT, vc->obedit);
+ }
+ return data.is_changed;
+}
+
+static void do_circle_select_mball__doSelectElem(void *userData,
+ struct MetaElem *ml,
+ const float screen_co[2])
+{
+ CircleSelectUserData *data = userData;
+
+ if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
+ if (data->select) {
+ ml->flag |= SELECT;
+ }
+ else {
+ ml->flag &= ~SELECT;
+ }
+ data->is_changed = true;
+ }
+}
+static bool mball_circle_select(ViewContext *vc,
+ const eSelectOp sel_op,
+ const int mval[2],
+ float rad)
{
- CircleSelectUserData data;
- bArmature *arm = vc->obedit->data;
-
- const bool select = (sel_op != SEL_OP_SUB);
-
- view3d_userdata_circleselect_init(&data, vc, select, mval, rad);
-
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- data.is_changed |= ED_armature_edit_deselect_all_visible(vc->obedit);
- }
-
- ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
-
- armature_foreachScreenBone(vc, do_circle_select_armature__doSelectBone, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
-
- if (data.is_changed) {
- ED_armature_edit_sync_selection(arm->edbo);
- ED_armature_edit_validate_active(arm);
- WM_main_add_notifier(NC_OBJECT | ND_BONE_SELECT, vc->obedit);
- }
- return data.is_changed;
-}
-
-static void do_circle_select_mball__doSelectElem(void *userData, struct MetaElem *ml, const float screen_co[2])
-{
- CircleSelectUserData *data = userData;
-
- if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
- if (data->select) {
- ml->flag |= SELECT;
- }
- else {
- ml->flag &= ~SELECT;
- }
- data->is_changed = true;
- }
-}
-static bool mball_circle_select(ViewContext *vc, const eSelectOp sel_op, const int mval[2], float rad)
-{
- CircleSelectUserData data;
-
- const bool select = (sel_op != SEL_OP_SUB);
-
- view3d_userdata_circleselect_init(&data, vc, select, mval, rad);
+ CircleSelectUserData data;
+
+ const bool select = (sel_op != SEL_OP_SUB);
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- data.is_changed |= BKE_mball_deselect_all(vc->obedit->data);
- }
+ view3d_userdata_circleselect_init(&data, vc, select, mval, rad);
- ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ data.is_changed |= BKE_mball_deselect_all(vc->obedit->data);
+ }
+
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- mball_foreachScreenElem(vc, do_circle_select_mball__doSelectElem, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
- return data.is_changed;
+ mball_foreachScreenElem(
+ vc, do_circle_select_mball__doSelectElem, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ return data.is_changed;
}
/** Callbacks for circle selection in Editmode */
-static bool obedit_circle_select(
- ViewContext *vc, const eSelectOp sel_op, const int mval[2], float rad)
-{
- BLI_assert(ELEM(sel_op, SEL_OP_SET, SEL_OP_ADD, SEL_OP_SUB));
- switch (vc->obedit->type) {
- case OB_MESH:
- return mesh_circle_select(vc, sel_op, mval, rad);
- case OB_CURVE:
- case OB_SURF:
- return nurbscurve_circle_select(vc, sel_op, mval, rad);
- case OB_LATTICE:
- return lattice_circle_select(vc, sel_op, mval, rad);
- case OB_ARMATURE:
- return armature_circle_select(vc, sel_op, mval, rad);
- case OB_MBALL:
- return mball_circle_select(vc, sel_op, mval, rad);
- default:
- BLI_assert(0);
- return false;
- }
-}
-
-static bool object_circle_select(ViewContext *vc, const eSelectOp sel_op, const int mval[2], float rad)
-{
- BLI_assert(ELEM(sel_op, SEL_OP_SET, SEL_OP_ADD, SEL_OP_SUB));
- ViewLayer *view_layer = vc->view_layer;
- View3D *v3d = vc->v3d;
-
- const float radius_squared = rad * rad;
- const float mval_fl[2] = {mval[0], mval[1]};
-
- bool changed = false;
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- changed |= object_deselect_all_visible(vc->view_layer, vc->v3d);
- }
- const bool select = (sel_op != SEL_OP_SUB);
- const int select_flag = select ? BASE_SELECTED : 0;
-
- Base *base;
- for (base = FIRSTBASE(view_layer); base; base = base->next) {
- if (BASE_SELECTABLE(v3d, base) && ((base->flag & BASE_SELECTED) != select_flag)) {
- float screen_co[2];
- if (ED_view3d_project_float_global(
- vc->ar, base->object->obmat[3], screen_co,
- V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK)
- {
- if (len_squared_v2v2(mval_fl, screen_co) <= radius_squared) {
- ED_object_base_select(base, select ? BA_SELECT : BA_DESELECT);
- changed = true;
- }
- }
- }
- }
-
- return changed;
+static bool obedit_circle_select(ViewContext *vc,
+ const eSelectOp sel_op,
+ const int mval[2],
+ float rad)
+{
+ BLI_assert(ELEM(sel_op, SEL_OP_SET, SEL_OP_ADD, SEL_OP_SUB));
+ switch (vc->obedit->type) {
+ case OB_MESH:
+ return mesh_circle_select(vc, sel_op, mval, rad);
+ case OB_CURVE:
+ case OB_SURF:
+ return nurbscurve_circle_select(vc, sel_op, mval, rad);
+ case OB_LATTICE:
+ return lattice_circle_select(vc, sel_op, mval, rad);
+ case OB_ARMATURE:
+ return armature_circle_select(vc, sel_op, mval, rad);
+ case OB_MBALL:
+ return mball_circle_select(vc, sel_op, mval, rad);
+ default:
+ BLI_assert(0);
+ return false;
+ }
+}
+
+static bool object_circle_select(ViewContext *vc,
+ const eSelectOp sel_op,
+ const int mval[2],
+ float rad)
+{
+ BLI_assert(ELEM(sel_op, SEL_OP_SET, SEL_OP_ADD, SEL_OP_SUB));
+ ViewLayer *view_layer = vc->view_layer;
+ View3D *v3d = vc->v3d;
+
+ const float radius_squared = rad * rad;
+ const float mval_fl[2] = {mval[0], mval[1]};
+
+ bool changed = false;
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ changed |= object_deselect_all_visible(vc->view_layer, vc->v3d);
+ }
+ const bool select = (sel_op != SEL_OP_SUB);
+ const int select_flag = select ? BASE_SELECTED : 0;
+
+ Base *base;
+ for (base = FIRSTBASE(view_layer); base; base = base->next) {
+ if (BASE_SELECTABLE(v3d, base) && ((base->flag & BASE_SELECTED) != select_flag)) {
+ float screen_co[2];
+ if (ED_view3d_project_float_global(vc->ar,
+ base->object->obmat[3],
+ screen_co,
+ V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN |
+ V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK) {
+ if (len_squared_v2v2(mval_fl, screen_co) <= radius_squared) {
+ ED_object_base_select(base, select ? BA_SELECT : BA_DESELECT);
+ changed = true;
+ }
+ }
+ }
+ }
+
+ return changed;
}
/* not a real operator, only for circle test */
static int view3d_circle_select_exec(bContext *C, wmOperator *op)
{
- ViewContext vc;
- const int radius = RNA_int_get(op->ptr, "radius");
- const int mval[2] = {RNA_int_get(op->ptr, "x"),
- RNA_int_get(op->ptr, "y")};
-
- const eSelectOp sel_op = ED_select_op_modal(
- RNA_enum_get(op->ptr, "mode"), WM_gesture_is_modal_first(op->customdata));
-
- ED_view3d_viewcontext_init(C, &vc);
-
- Object *obact = vc.obact;
- Object *obedit = vc.obedit;
-
- if (obedit || BKE_paint_select_elem_test(obact) ||
- (obact && (obact->mode & OB_MODE_POSE)))
- {
- view3d_operator_needs_opengl(C);
-
- FOREACH_OBJECT_IN_MODE_BEGIN (vc.view_layer, vc.v3d, obact->type, obact->mode, ob_iter) {
- ED_view3d_viewcontext_init_object(&vc, ob_iter);
-
- obact = vc.obact;
- obedit = vc.obedit;
-
- if (obedit) {
- if (obedit_circle_select(&vc, sel_op, mval, (float)radius)) {
- DEG_id_tag_update(obact->data, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data);
- }
- }
- else if (BKE_paint_select_face_test(obact)) {
- paint_facesel_circle_select(&vc, sel_op, mval, (float)radius);
- }
- else if (BKE_paint_select_vert_test(obact)) {
- paint_vertsel_circle_select(&vc, sel_op, mval, (float)radius);
- }
- else if (obact->mode & OB_MODE_POSE) {
- pose_circle_select(&vc, sel_op, mval, (float)radius);
- }
- else {
- BLI_assert(0);
- }
- }
- FOREACH_OBJECT_IN_MODE_END;
- }
- else if (obact && (obact->mode & OB_MODE_PARTICLE_EDIT)) {
- if (PE_circle_select(C, sel_op, mval, (float)radius)) {
- return OPERATOR_FINISHED;
- }
- return OPERATOR_CANCELLED;
- }
- else if (obact && obact->mode & OB_MODE_SCULPT) {
- return OPERATOR_CANCELLED;
- }
- else {
- if (object_circle_select(&vc, sel_op, mval, (float)radius)) {
- DEG_id_tag_update(&vc.scene->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, vc.scene);
- }
- }
-
- return OPERATOR_FINISHED;
+ ViewContext vc;
+ const int radius = RNA_int_get(op->ptr, "radius");
+ const int mval[2] = {RNA_int_get(op->ptr, "x"), RNA_int_get(op->ptr, "y")};
+
+ const eSelectOp sel_op = ED_select_op_modal(RNA_enum_get(op->ptr, "mode"),
+ WM_gesture_is_modal_first(op->customdata));
+
+ ED_view3d_viewcontext_init(C, &vc);
+
+ Object *obact = vc.obact;
+ Object *obedit = vc.obedit;
+
+ if (obedit || BKE_paint_select_elem_test(obact) || (obact && (obact->mode & OB_MODE_POSE))) {
+ view3d_operator_needs_opengl(C);
+
+ FOREACH_OBJECT_IN_MODE_BEGIN (vc.view_layer, vc.v3d, obact->type, obact->mode, ob_iter) {
+ ED_view3d_viewcontext_init_object(&vc, ob_iter);
+
+ obact = vc.obact;
+ obedit = vc.obedit;
+
+ if (obedit) {
+ if (obedit_circle_select(&vc, sel_op, mval, (float)radius)) {
+ DEG_id_tag_update(obact->data, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data);
+ }
+ }
+ else if (BKE_paint_select_face_test(obact)) {
+ paint_facesel_circle_select(&vc, sel_op, mval, (float)radius);
+ }
+ else if (BKE_paint_select_vert_test(obact)) {
+ paint_vertsel_circle_select(&vc, sel_op, mval, (float)radius);
+ }
+ else if (obact->mode & OB_MODE_POSE) {
+ pose_circle_select(&vc, sel_op, mval, (float)radius);
+ }
+ else {
+ BLI_assert(0);
+ }
+ }
+ FOREACH_OBJECT_IN_MODE_END;
+ }
+ else if (obact && (obact->mode & OB_MODE_PARTICLE_EDIT)) {
+ if (PE_circle_select(C, sel_op, mval, (float)radius)) {
+ return OPERATOR_FINISHED;
+ }
+ return OPERATOR_CANCELLED;
+ }
+ else if (obact && obact->mode & OB_MODE_SCULPT) {
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ if (object_circle_select(&vc, sel_op, mval, (float)radius)) {
+ DEG_id_tag_update(&vc.scene->id, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, vc.scene);
+ }
+ }
+
+ return OPERATOR_FINISHED;
}
void VIEW3D_OT_select_circle(wmOperatorType *ot)
{
- ot->name = "Circle Select";
- ot->description = "Select items using circle selection";
- ot->idname = "VIEW3D_OT_select_circle";
+ ot->name = "Circle Select";
+ ot->description = "Select items using circle selection";
+ ot->idname = "VIEW3D_OT_select_circle";
- ot->invoke = WM_gesture_circle_invoke;
- ot->modal = WM_gesture_circle_modal;
- ot->exec = view3d_circle_select_exec;
- ot->poll = view3d_selectable_data;
- ot->cancel = WM_gesture_circle_cancel;
+ ot->invoke = WM_gesture_circle_invoke;
+ ot->modal = WM_gesture_circle_modal;
+ ot->exec = view3d_circle_select_exec;
+ ot->poll = view3d_selectable_data;
+ ot->cancel = WM_gesture_circle_cancel;
- /* flags */
- ot->flag = OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
- /* properties */
- WM_operator_properties_gesture_circle(ot);
- WM_operator_properties_select_operation_simple(ot);
+ /* properties */
+ WM_operator_properties_gesture_circle(ot);
+ WM_operator_properties_select_operation_simple(ot);
}
/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c
index 711e084f2ac..5aa19cc8a51 100644
--- a/source/blender/editors/space_view3d/view3d_snap.c
+++ b/source/blender/editors/space_view3d/view3d_snap.c
@@ -21,7 +21,6 @@
* \ingroup spview3d
*/
-
#include "MEM_guardedalloc.h"
#include "DNA_armature_types.h"
@@ -62,172 +61,172 @@
static bool snap_curs_to_sel_ex(bContext *C, float cursor[3]);
static bool snap_calc_active_center(bContext *C, const bool select_only, float r_center[3]);
-
/* *********************** operators ******************** */
/** Snaps every individual object center to its nearest point on the grid. */
static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op))
{
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- ViewLayer *view_layer_eval = DEG_get_evaluated_view_layer(depsgraph);
- Object *obedit = CTX_data_edit_object(C);
- Scene *scene = CTX_data_scene(C);
- RegionView3D *rv3d = CTX_wm_region_data(C);
- View3D *v3d = CTX_wm_view3d(C);
- TransVertStore tvs = {NULL};
- TransVert *tv;
- float gridf, imat[3][3], bmat[3][3], vec[3];
- int a;
-
- gridf = ED_view3d_grid_view_scale(scene, v3d, rv3d, NULL);
-
- if (obedit) {
- ViewLayer *view_layer = CTX_data_view_layer(C);
- uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- obedit = objects[ob_index];
-
- if (obedit->type == OB_MESH) {
- BMEditMesh *em = BKE_editmesh_from_object(obedit);
-
- if (em->bm->totvertsel == 0) {
- continue;
- }
- }
-
- if (ED_transverts_check_obedit(obedit)) {
- ED_transverts_create_from_obedit(&tvs, obedit, 0);
- }
-
- if (tvs.transverts_tot != 0) {
- copy_m3_m4(bmat, obedit->obmat);
- invert_m3_m3(imat, bmat);
-
- tv = tvs.transverts;
- for (a = 0; a < tvs.transverts_tot; a++, tv++) {
- copy_v3_v3(vec, tv->loc);
- mul_m3_v3(bmat, vec);
- add_v3_v3(vec, obedit->obmat[3]);
- vec[0] = gridf * floorf(0.5f + vec[0] / gridf);
- vec[1] = gridf * floorf(0.5f + vec[1] / gridf);
- vec[2] = gridf * floorf(0.5f + vec[2] / gridf);
- sub_v3_v3(vec, obedit->obmat[3]);
-
- mul_m3_v3(imat, vec);
- copy_v3_v3(tv->loc, vec);
- }
- ED_transverts_update_obedit(&tvs, obedit);
- }
- ED_transverts_free(&tvs);
- }
- MEM_freeN(objects);
- }
- else {
- struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID);
-
- FOREACH_SELECTED_EDITABLE_OBJECT_BEGIN(view_layer_eval, v3d, ob_eval)
- {
- Object *ob = DEG_get_original_object(ob_eval);
- if (ob->mode & OB_MODE_POSE) {
- bPoseChannel *pchan_eval;
- bArmature *arm_eval = ob_eval->data;
-
- invert_m4_m4(ob_eval->imat, ob_eval->obmat);
-
- for (pchan_eval = ob_eval->pose->chanbase.first; pchan_eval; pchan_eval = pchan_eval->next) {
- if (pchan_eval->bone->flag & BONE_SELECTED) {
- if (pchan_eval->bone->layer & arm_eval->layer) {
- if ((pchan_eval->bone->flag & BONE_CONNECTED) == 0) {
- float nLoc[3];
-
- /* get nearest grid point to snap to */
- copy_v3_v3(nLoc, pchan_eval->pose_mat[3]);
- /* We must operate in world space! */
- mul_m4_v3(ob_eval->obmat, nLoc);
- vec[0] = gridf * floorf(0.5f + nLoc[0] / gridf);
- vec[1] = gridf * floorf(0.5f + nLoc[1] / gridf);
- vec[2] = gridf * floorf(0.5f + nLoc[2] / gridf);
- /* Back in object space... */
- mul_m4_v3(ob_eval->imat, vec);
-
- /* Get location of grid point in pose space. */
- BKE_armature_loc_pose_to_bone(pchan_eval, vec, vec);
-
- /* adjust location on the original pchan*/
- bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, pchan_eval->name);
- if ((pchan->protectflag & OB_LOCK_LOCX) == 0) {
- pchan->loc[0] = vec[0];
- }
- if ((pchan->protectflag & OB_LOCK_LOCY) == 0) {
- pchan->loc[1] = vec[1];
- }
- if ((pchan->protectflag & OB_LOCK_LOCZ) == 0) {
- pchan->loc[2] = vec[2];
- }
-
- /* auto-keyframing */
- ED_autokeyframe_pchan(C, scene, ob, pchan, ks);
- }
- /* if the bone has a parent and is connected to the parent,
- * don't do anything - will break chain unless we do auto-ik.
- */
- }
- }
- }
- ob->pose->flag |= (POSE_LOCKED | POSE_DO_UNLOCK);
-
- DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
- }
- else {
- vec[0] = -ob_eval->obmat[3][0] + gridf * floorf(0.5f + ob_eval->obmat[3][0] / gridf);
- vec[1] = -ob_eval->obmat[3][1] + gridf * floorf(0.5f + ob_eval->obmat[3][1] / gridf);
- vec[2] = -ob_eval->obmat[3][2] + gridf * floorf(0.5f + ob_eval->obmat[3][2] / gridf);
-
- if (ob->parent) {
- float originmat[3][3];
- BKE_object_where_is_calc_ex(depsgraph, scene, NULL, ob, originmat);
-
- invert_m3_m3(imat, originmat);
- mul_m3_v3(imat, vec);
- }
- if ((ob->protectflag & OB_LOCK_LOCX) == 0) {
- ob->loc[0] = ob_eval->loc[0] + vec[0];
- }
- if ((ob->protectflag & OB_LOCK_LOCY) == 0) {
- ob->loc[1] = ob_eval->loc[1] + vec[1];
- }
- if ((ob->protectflag & OB_LOCK_LOCZ) == 0) {
- ob->loc[2] = ob_eval->loc[2] + vec[2];
- }
-
- /* auto-keyframing */
- ED_autokeyframe_object(C, scene, ob, ks);
-
- DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
- }
- }
- FOREACH_SELECTED_EDITABLE_OBJECT_END;
- }
-
- WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
-
- return OPERATOR_FINISHED;
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ ViewLayer *view_layer_eval = DEG_get_evaluated_view_layer(depsgraph);
+ Object *obedit = CTX_data_edit_object(C);
+ Scene *scene = CTX_data_scene(C);
+ RegionView3D *rv3d = CTX_wm_region_data(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ TransVertStore tvs = {NULL};
+ TransVert *tv;
+ float gridf, imat[3][3], bmat[3][3], vec[3];
+ int a;
+
+ gridf = ED_view3d_grid_view_scale(scene, v3d, rv3d, NULL);
+
+ if (obedit) {
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ obedit = objects[ob_index];
+
+ if (obedit->type == OB_MESH) {
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+
+ if (em->bm->totvertsel == 0) {
+ continue;
+ }
+ }
+
+ if (ED_transverts_check_obedit(obedit)) {
+ ED_transverts_create_from_obedit(&tvs, obedit, 0);
+ }
+
+ if (tvs.transverts_tot != 0) {
+ copy_m3_m4(bmat, obedit->obmat);
+ invert_m3_m3(imat, bmat);
+
+ tv = tvs.transverts;
+ for (a = 0; a < tvs.transverts_tot; a++, tv++) {
+ copy_v3_v3(vec, tv->loc);
+ mul_m3_v3(bmat, vec);
+ add_v3_v3(vec, obedit->obmat[3]);
+ vec[0] = gridf * floorf(0.5f + vec[0] / gridf);
+ vec[1] = gridf * floorf(0.5f + vec[1] / gridf);
+ vec[2] = gridf * floorf(0.5f + vec[2] / gridf);
+ sub_v3_v3(vec, obedit->obmat[3]);
+
+ mul_m3_v3(imat, vec);
+ copy_v3_v3(tv->loc, vec);
+ }
+ ED_transverts_update_obedit(&tvs, obedit);
+ }
+ ED_transverts_free(&tvs);
+ }
+ MEM_freeN(objects);
+ }
+ else {
+ struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID);
+
+ FOREACH_SELECTED_EDITABLE_OBJECT_BEGIN (view_layer_eval, v3d, ob_eval) {
+ Object *ob = DEG_get_original_object(ob_eval);
+ if (ob->mode & OB_MODE_POSE) {
+ bPoseChannel *pchan_eval;
+ bArmature *arm_eval = ob_eval->data;
+
+ invert_m4_m4(ob_eval->imat, ob_eval->obmat);
+
+ for (pchan_eval = ob_eval->pose->chanbase.first; pchan_eval;
+ pchan_eval = pchan_eval->next) {
+ if (pchan_eval->bone->flag & BONE_SELECTED) {
+ if (pchan_eval->bone->layer & arm_eval->layer) {
+ if ((pchan_eval->bone->flag & BONE_CONNECTED) == 0) {
+ float nLoc[3];
+
+ /* get nearest grid point to snap to */
+ copy_v3_v3(nLoc, pchan_eval->pose_mat[3]);
+ /* We must operate in world space! */
+ mul_m4_v3(ob_eval->obmat, nLoc);
+ vec[0] = gridf * floorf(0.5f + nLoc[0] / gridf);
+ vec[1] = gridf * floorf(0.5f + nLoc[1] / gridf);
+ vec[2] = gridf * floorf(0.5f + nLoc[2] / gridf);
+ /* Back in object space... */
+ mul_m4_v3(ob_eval->imat, vec);
+
+ /* Get location of grid point in pose space. */
+ BKE_armature_loc_pose_to_bone(pchan_eval, vec, vec);
+
+ /* adjust location on the original pchan*/
+ bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, pchan_eval->name);
+ if ((pchan->protectflag & OB_LOCK_LOCX) == 0) {
+ pchan->loc[0] = vec[0];
+ }
+ if ((pchan->protectflag & OB_LOCK_LOCY) == 0) {
+ pchan->loc[1] = vec[1];
+ }
+ if ((pchan->protectflag & OB_LOCK_LOCZ) == 0) {
+ pchan->loc[2] = vec[2];
+ }
+
+ /* auto-keyframing */
+ ED_autokeyframe_pchan(C, scene, ob, pchan, ks);
+ }
+ /* if the bone has a parent and is connected to the parent,
+ * don't do anything - will break chain unless we do auto-ik.
+ */
+ }
+ }
+ }
+ ob->pose->flag |= (POSE_LOCKED | POSE_DO_UNLOCK);
+
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ }
+ else {
+ vec[0] = -ob_eval->obmat[3][0] + gridf * floorf(0.5f + ob_eval->obmat[3][0] / gridf);
+ vec[1] = -ob_eval->obmat[3][1] + gridf * floorf(0.5f + ob_eval->obmat[3][1] / gridf);
+ vec[2] = -ob_eval->obmat[3][2] + gridf * floorf(0.5f + ob_eval->obmat[3][2] / gridf);
+
+ if (ob->parent) {
+ float originmat[3][3];
+ BKE_object_where_is_calc_ex(depsgraph, scene, NULL, ob, originmat);
+
+ invert_m3_m3(imat, originmat);
+ mul_m3_v3(imat, vec);
+ }
+ if ((ob->protectflag & OB_LOCK_LOCX) == 0) {
+ ob->loc[0] = ob_eval->loc[0] + vec[0];
+ }
+ if ((ob->protectflag & OB_LOCK_LOCY) == 0) {
+ ob->loc[1] = ob_eval->loc[1] + vec[1];
+ }
+ if ((ob->protectflag & OB_LOCK_LOCZ) == 0) {
+ ob->loc[2] = ob_eval->loc[2] + vec[2];
+ }
+
+ /* auto-keyframing */
+ ED_autokeyframe_object(C, scene, ob, ks);
+
+ DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
+ }
+ }
+ FOREACH_SELECTED_EDITABLE_OBJECT_END;
+ }
+
+ WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
+
+ return OPERATOR_FINISHED;
}
void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Snap Selection to Grid";
- ot->description = "Snap selected item(s) to their nearest grid division";
- ot->idname = "VIEW3D_OT_snap_selected_to_grid";
+ /* identifiers */
+ ot->name = "Snap Selection to Grid";
+ ot->description = "Snap selected item(s) to their nearest grid division";
+ ot->idname = "VIEW3D_OT_snap_selected_to_grid";
- /* api callbacks */
- ot->exec = snap_sel_to_grid_exec;
- ot->poll = ED_operator_region_view3d_active;
+ /* api callbacks */
+ ot->exec = snap_sel_to_grid_exec;
+ ot->poll = ED_operator_region_view3d_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA;
}
/* *************************************************** */
@@ -238,256 +237,257 @@ void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot)
* \param use_offset: if the selected objects should maintain their relative offsets and be snapped by the selection
* pivot point (median, active), or if every object origin should be snapped to the given location.
*/
-static int snap_selected_to_location(bContext *C, const float snap_target_global[3], const bool use_offset)
+static int snap_selected_to_location(bContext *C,
+ const float snap_target_global[3],
+ const bool use_offset)
{
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- Scene *scene = CTX_data_scene(C);
- Object *obedit = CTX_data_edit_object(C);
- Object *obact = CTX_data_active_object(C);
- View3D *v3d = CTX_wm_view3d(C);
- TransVertStore tvs = {NULL};
- TransVert *tv;
- float imat[3][3], bmat[3][3];
- float center_global[3];
- float offset_global[3];
- int a;
-
- if (use_offset) {
- if ((v3d && scene->toolsettings->transform_pivot_point == V3D_AROUND_ACTIVE) &&
- snap_calc_active_center(C, true, center_global))
- {
- /* pass */
- }
- else {
- snap_curs_to_sel_ex(C, center_global);
- }
- sub_v3_v3v3(offset_global, snap_target_global, center_global);
- }
-
- if (obedit) {
- float snap_target_local[3];
- ViewLayer *view_layer = CTX_data_view_layer(C);
- uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- obedit = objects[ob_index];
-
- if (obedit->type == OB_MESH) {
- BMEditMesh *em = BKE_editmesh_from_object(obedit);
-
- if (em->bm->totvertsel == 0) {
- continue;
- }
- }
-
- if (ED_transverts_check_obedit(obedit)) {
- ED_transverts_create_from_obedit(&tvs, obedit, 0);
- }
-
- if (tvs.transverts_tot != 0) {
- copy_m3_m4(bmat, obedit->obmat);
- invert_m3_m3(imat, bmat);
-
- /* get the cursor in object space */
- sub_v3_v3v3(snap_target_local, snap_target_global, obedit->obmat[3]);
- mul_m3_v3(imat, snap_target_local);
-
- if (use_offset) {
- float offset_local[3];
-
- mul_v3_m3v3(offset_local, imat, offset_global);
-
- tv = tvs.transverts;
- for (a = 0; a < tvs.transverts_tot; a++, tv++) {
- add_v3_v3(tv->loc, offset_local);
- }
- }
- else {
- tv = tvs.transverts;
- for (a = 0; a < tvs.transverts_tot; a++, tv++) {
- copy_v3_v3(tv->loc, snap_target_local);
- }
- }
- ED_transverts_update_obedit(&tvs, obedit);
- }
- ED_transverts_free(&tvs);
- }
- MEM_freeN(objects);
- }
- else if (obact && (obact->mode & OB_MODE_POSE)) {
- struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_mode_unique_data(view_layer, CTX_wm_view3d(C),
- &objects_len, OB_MODE_POSE);
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *ob = objects[ob_index];
- bPoseChannel *pchan;
- bArmature *arm = ob->data;
- float snap_target_local[3];
-
- invert_m4_m4(ob->imat, ob->obmat);
- mul_v3_m4v3(snap_target_local, ob->imat, snap_target_global);
-
- for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
- if ((pchan->bone->flag & BONE_SELECTED) &&
- (PBONE_VISIBLE(arm, pchan->bone)) &&
- /* if the bone has a parent and is connected to the parent,
- * don't do anything - will break chain unless we do auto-ik.
- */
- (pchan->bone->flag & BONE_CONNECTED) == 0)
- {
- pchan->bone->flag |= BONE_TRANSFORM;
- }
- else {
- pchan->bone->flag &= ~BONE_TRANSFORM;
- }
- }
-
- for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
- if ((pchan->bone->flag & BONE_TRANSFORM) &&
- /* check that our parents not transformed (if we have one) */
- ((pchan->bone->parent &&
- BKE_armature_bone_flag_test_recursive(pchan->bone->parent, BONE_TRANSFORM)) == 0))
- {
- /* Get position in pchan (pose) space. */
- float cursor_pose[3];
-
- if (use_offset) {
- mul_v3_m4v3(cursor_pose, ob->obmat, pchan->pose_mat[3]);
- add_v3_v3(cursor_pose, offset_global);
-
- mul_m4_v3(ob->imat, cursor_pose);
- BKE_armature_loc_pose_to_bone(pchan, cursor_pose, cursor_pose);
- }
- else {
- BKE_armature_loc_pose_to_bone(pchan, snap_target_local, cursor_pose);
- }
-
- /* copy new position */
- if ((pchan->protectflag & OB_LOCK_LOCX) == 0) {
- pchan->loc[0] = cursor_pose[0];
- }
- if ((pchan->protectflag & OB_LOCK_LOCY) == 0) {
- pchan->loc[1] = cursor_pose[1];
- }
- if ((pchan->protectflag & OB_LOCK_LOCZ) == 0) {
- pchan->loc[2] = cursor_pose[2];
- }
-
- /* auto-keyframing */
- ED_autokeyframe_pchan(C, scene, ob, pchan, ks);
- }
- }
-
- for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
- pchan->bone->flag &= ~BONE_TRANSFORM;
- }
-
- ob->pose->flag |= (POSE_LOCKED | POSE_DO_UNLOCK);
-
- DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
- }
- MEM_freeN(objects);
- }
- else {
- struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID);
- Main *bmain = CTX_data_main(C);
-
- ListBase ctx_data_list;
- CollectionPointerLink *ctx_ob;
- Object *ob;
-
- CTX_data_selected_editable_objects(C, &ctx_data_list);
-
- /* reset flags */
- for (ob = bmain->objects.first; ob; ob = ob->id.next) {
- ob->flag &= ~OB_DONE;
- }
-
- /* tag objects we're transforming */
- for (ctx_ob = ctx_data_list.first; ctx_ob; ctx_ob = ctx_ob->next) {
- ob = ctx_ob->ptr.data;
- ob->flag |= OB_DONE;
- }
-
- for (ctx_ob = ctx_data_list.first; ctx_ob; ctx_ob = ctx_ob->next) {
- ob = ctx_ob->ptr.data;
-
- if ((ob->parent && BKE_object_flag_test_recursive(ob->parent, OB_DONE)) == 0) {
-
- float cursor_parent[3]; /* parent-relative */
-
- if (use_offset) {
- add_v3_v3v3(cursor_parent, ob->obmat[3], offset_global);
- }
- else {
- copy_v3_v3(cursor_parent, snap_target_global);
- }
-
- sub_v3_v3(cursor_parent, ob->obmat[3]);
-
- if (ob->parent) {
- float originmat[3][3];
- BKE_object_where_is_calc_ex(depsgraph, scene, NULL, ob, originmat);
-
- invert_m3_m3(imat, originmat);
- mul_m3_v3(imat, cursor_parent);
- }
- if ((ob->protectflag & OB_LOCK_LOCX) == 0) {
- ob->loc[0] += cursor_parent[0];
- }
- if ((ob->protectflag & OB_LOCK_LOCY) == 0) {
- ob->loc[1] += cursor_parent[1];
- }
- if ((ob->protectflag & OB_LOCK_LOCZ) == 0) {
- ob->loc[2] += cursor_parent[2];
- }
-
- /* auto-keyframing */
- ED_autokeyframe_object(C, scene, ob, ks);
-
- DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
- }
- }
-
- BLI_freelistN(&ctx_data_list);
- }
-
- WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
-
- return OPERATOR_FINISHED;
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ Scene *scene = CTX_data_scene(C);
+ Object *obedit = CTX_data_edit_object(C);
+ Object *obact = CTX_data_active_object(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ TransVertStore tvs = {NULL};
+ TransVert *tv;
+ float imat[3][3], bmat[3][3];
+ float center_global[3];
+ float offset_global[3];
+ int a;
+
+ if (use_offset) {
+ if ((v3d && scene->toolsettings->transform_pivot_point == V3D_AROUND_ACTIVE) &&
+ snap_calc_active_center(C, true, center_global)) {
+ /* pass */
+ }
+ else {
+ snap_curs_to_sel_ex(C, center_global);
+ }
+ sub_v3_v3v3(offset_global, snap_target_global, center_global);
+ }
+
+ if (obedit) {
+ float snap_target_local[3];
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ obedit = objects[ob_index];
+
+ if (obedit->type == OB_MESH) {
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+
+ if (em->bm->totvertsel == 0) {
+ continue;
+ }
+ }
+
+ if (ED_transverts_check_obedit(obedit)) {
+ ED_transverts_create_from_obedit(&tvs, obedit, 0);
+ }
+
+ if (tvs.transverts_tot != 0) {
+ copy_m3_m4(bmat, obedit->obmat);
+ invert_m3_m3(imat, bmat);
+
+ /* get the cursor in object space */
+ sub_v3_v3v3(snap_target_local, snap_target_global, obedit->obmat[3]);
+ mul_m3_v3(imat, snap_target_local);
+
+ if (use_offset) {
+ float offset_local[3];
+
+ mul_v3_m3v3(offset_local, imat, offset_global);
+
+ tv = tvs.transverts;
+ for (a = 0; a < tvs.transverts_tot; a++, tv++) {
+ add_v3_v3(tv->loc, offset_local);
+ }
+ }
+ else {
+ tv = tvs.transverts;
+ for (a = 0; a < tvs.transverts_tot; a++, tv++) {
+ copy_v3_v3(tv->loc, snap_target_local);
+ }
+ }
+ ED_transverts_update_obedit(&tvs, obedit);
+ }
+ ED_transverts_free(&tvs);
+ }
+ MEM_freeN(objects);
+ }
+ else if (obact && (obact->mode & OB_MODE_POSE)) {
+ struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len, OB_MODE_POSE);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *ob = objects[ob_index];
+ bPoseChannel *pchan;
+ bArmature *arm = ob->data;
+ float snap_target_local[3];
+
+ invert_m4_m4(ob->imat, ob->obmat);
+ mul_v3_m4v3(snap_target_local, ob->imat, snap_target_global);
+
+ for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
+ if ((pchan->bone->flag & BONE_SELECTED) && (PBONE_VISIBLE(arm, pchan->bone)) &&
+ /* if the bone has a parent and is connected to the parent,
+ * don't do anything - will break chain unless we do auto-ik.
+ */
+ (pchan->bone->flag & BONE_CONNECTED) == 0) {
+ pchan->bone->flag |= BONE_TRANSFORM;
+ }
+ else {
+ pchan->bone->flag &= ~BONE_TRANSFORM;
+ }
+ }
+
+ for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
+ if ((pchan->bone->flag & BONE_TRANSFORM) &&
+ /* check that our parents not transformed (if we have one) */
+ ((pchan->bone->parent &&
+ BKE_armature_bone_flag_test_recursive(pchan->bone->parent, BONE_TRANSFORM)) == 0)) {
+ /* Get position in pchan (pose) space. */
+ float cursor_pose[3];
+
+ if (use_offset) {
+ mul_v3_m4v3(cursor_pose, ob->obmat, pchan->pose_mat[3]);
+ add_v3_v3(cursor_pose, offset_global);
+
+ mul_m4_v3(ob->imat, cursor_pose);
+ BKE_armature_loc_pose_to_bone(pchan, cursor_pose, cursor_pose);
+ }
+ else {
+ BKE_armature_loc_pose_to_bone(pchan, snap_target_local, cursor_pose);
+ }
+
+ /* copy new position */
+ if ((pchan->protectflag & OB_LOCK_LOCX) == 0) {
+ pchan->loc[0] = cursor_pose[0];
+ }
+ if ((pchan->protectflag & OB_LOCK_LOCY) == 0) {
+ pchan->loc[1] = cursor_pose[1];
+ }
+ if ((pchan->protectflag & OB_LOCK_LOCZ) == 0) {
+ pchan->loc[2] = cursor_pose[2];
+ }
+
+ /* auto-keyframing */
+ ED_autokeyframe_pchan(C, scene, ob, pchan, ks);
+ }
+ }
+
+ for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
+ pchan->bone->flag &= ~BONE_TRANSFORM;
+ }
+
+ ob->pose->flag |= (POSE_LOCKED | POSE_DO_UNLOCK);
+
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ }
+ MEM_freeN(objects);
+ }
+ else {
+ struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID);
+ Main *bmain = CTX_data_main(C);
+
+ ListBase ctx_data_list;
+ CollectionPointerLink *ctx_ob;
+ Object *ob;
+
+ CTX_data_selected_editable_objects(C, &ctx_data_list);
+
+ /* reset flags */
+ for (ob = bmain->objects.first; ob; ob = ob->id.next) {
+ ob->flag &= ~OB_DONE;
+ }
+
+ /* tag objects we're transforming */
+ for (ctx_ob = ctx_data_list.first; ctx_ob; ctx_ob = ctx_ob->next) {
+ ob = ctx_ob->ptr.data;
+ ob->flag |= OB_DONE;
+ }
+
+ for (ctx_ob = ctx_data_list.first; ctx_ob; ctx_ob = ctx_ob->next) {
+ ob = ctx_ob->ptr.data;
+
+ if ((ob->parent && BKE_object_flag_test_recursive(ob->parent, OB_DONE)) == 0) {
+
+ float cursor_parent[3]; /* parent-relative */
+
+ if (use_offset) {
+ add_v3_v3v3(cursor_parent, ob->obmat[3], offset_global);
+ }
+ else {
+ copy_v3_v3(cursor_parent, snap_target_global);
+ }
+
+ sub_v3_v3(cursor_parent, ob->obmat[3]);
+
+ if (ob->parent) {
+ float originmat[3][3];
+ BKE_object_where_is_calc_ex(depsgraph, scene, NULL, ob, originmat);
+
+ invert_m3_m3(imat, originmat);
+ mul_m3_v3(imat, cursor_parent);
+ }
+ if ((ob->protectflag & OB_LOCK_LOCX) == 0) {
+ ob->loc[0] += cursor_parent[0];
+ }
+ if ((ob->protectflag & OB_LOCK_LOCY) == 0) {
+ ob->loc[1] += cursor_parent[1];
+ }
+ if ((ob->protectflag & OB_LOCK_LOCZ) == 0) {
+ ob->loc[2] += cursor_parent[2];
+ }
+
+ /* auto-keyframing */
+ ED_autokeyframe_object(C, scene, ob, ks);
+
+ DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
+ }
+ }
+
+ BLI_freelistN(&ctx_data_list);
+ }
+
+ WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
+
+ return OPERATOR_FINISHED;
}
static int snap_selected_to_cursor_exec(bContext *C, wmOperator *op)
{
- const bool use_offset = RNA_boolean_get(op->ptr, "use_offset");
+ const bool use_offset = RNA_boolean_get(op->ptr, "use_offset");
- Scene *scene = CTX_data_scene(C);
+ Scene *scene = CTX_data_scene(C);
- const float *snap_target_global = scene->cursor.location;
+ const float *snap_target_global = scene->cursor.location;
- return snap_selected_to_location(C, snap_target_global, use_offset);
+ return snap_selected_to_location(C, snap_target_global, use_offset);
}
void VIEW3D_OT_snap_selected_to_cursor(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Snap Selection to Cursor";
- ot->description = "Snap selected item(s) to the 3D cursor";
- ot->idname = "VIEW3D_OT_snap_selected_to_cursor";
-
- /* api callbacks */
- ot->exec = snap_selected_to_cursor_exec;
- ot->poll = ED_operator_view3d_active;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA;
-
- /* rna */
- RNA_def_boolean(
- ot->srna, "use_offset", 1, "Offset",
- "If the selection should be snapped as a whole or by each object center");
+ /* identifiers */
+ ot->name = "Snap Selection to Cursor";
+ ot->description = "Snap selected item(s) to the 3D cursor";
+ ot->idname = "VIEW3D_OT_snap_selected_to_cursor";
+
+ /* api callbacks */
+ ot->exec = snap_selected_to_cursor_exec;
+ ot->poll = ED_operator_view3d_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA;
+
+ /* rna */
+ RNA_def_boolean(ot->srna,
+ "use_offset",
+ 1,
+ "Offset",
+ "If the selection should be snapped as a whole or by each object center");
}
/* *************************************************** */
@@ -495,68 +495,67 @@ void VIEW3D_OT_snap_selected_to_cursor(wmOperatorType *ot)
/** Snaps each selected object to the location of the active selected object. */
static int snap_selected_to_active_exec(bContext *C, wmOperator *op)
{
- float snap_target_global[3];
+ float snap_target_global[3];
- if (snap_calc_active_center(C, false, snap_target_global) == false) {
- BKE_report(op->reports, RPT_ERROR, "No active element found!");
- return OPERATOR_CANCELLED;
- }
+ if (snap_calc_active_center(C, false, snap_target_global) == false) {
+ BKE_report(op->reports, RPT_ERROR, "No active element found!");
+ return OPERATOR_CANCELLED;
+ }
- return snap_selected_to_location(C, snap_target_global, false);
+ return snap_selected_to_location(C, snap_target_global, false);
}
void VIEW3D_OT_snap_selected_to_active(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Snap Selection to Active";
- ot->description = "Snap selected item(s) to the active item";
- ot->idname = "VIEW3D_OT_snap_selected_to_active";
+ /* identifiers */
+ ot->name = "Snap Selection to Active";
+ ot->description = "Snap selected item(s) to the active item";
+ ot->idname = "VIEW3D_OT_snap_selected_to_active";
- /* api callbacks */
- ot->exec = snap_selected_to_active_exec;
- ot->poll = ED_operator_view3d_active;
+ /* api callbacks */
+ ot->exec = snap_selected_to_active_exec;
+ ot->poll = ED_operator_view3d_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA;
}
-
/* *************************************************** */
/** Snaps the 3D cursor location to its nearest point on the grid. */
static int snap_curs_to_grid_exec(bContext *C, wmOperator *UNUSED(op))
{
- Scene *scene = CTX_data_scene(C);
- RegionView3D *rv3d = CTX_wm_region_data(C);
- View3D *v3d = CTX_wm_view3d(C);
- float gridf, *curs;
+ Scene *scene = CTX_data_scene(C);
+ RegionView3D *rv3d = CTX_wm_region_data(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ float gridf, *curs;
- gridf = ED_view3d_grid_view_scale(scene, v3d, rv3d, NULL);
- curs = scene->cursor.location;
+ gridf = ED_view3d_grid_view_scale(scene, v3d, rv3d, NULL);
+ curs = scene->cursor.location;
- curs[0] = gridf * floorf(0.5f + curs[0] / gridf);
- curs[1] = gridf * floorf(0.5f + curs[1] / gridf);
- curs[2] = gridf * floorf(0.5f + curs[2] / gridf);
+ curs[0] = gridf * floorf(0.5f + curs[0] / gridf);
+ curs[1] = gridf * floorf(0.5f + curs[1] / gridf);
+ curs[2] = gridf * floorf(0.5f + curs[2] / gridf);
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d); /* hrm */
- DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d); /* hrm */
+ DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void VIEW3D_OT_snap_cursor_to_grid(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Snap Cursor to Grid";
- ot->description = "Snap 3D cursor to the nearest grid division";
- ot->idname = "VIEW3D_OT_snap_cursor_to_grid";
+ /* identifiers */
+ ot->name = "Snap Cursor to Grid";
+ ot->description = "Snap 3D cursor to the nearest grid division";
+ ot->idname = "VIEW3D_OT_snap_cursor_to_grid";
- /* api callbacks */
- ot->exec = snap_curs_to_grid_exec;
- ot->poll = ED_operator_region_view3d_active;
+ /* api callbacks */
+ ot->exec = snap_curs_to_grid_exec;
+ ot->poll = ED_operator_region_view3d_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* **************************************************** */
@@ -567,202 +566,202 @@ void VIEW3D_OT_snap_cursor_to_grid(wmOperatorType *ot)
*/
static void bundle_midpoint(Scene *scene, Object *ob, float r_vec[3])
{
- MovieClip *clip = BKE_object_movieclip_get(scene, ob, false);
- MovieTracking *tracking;
- MovieTrackingObject *object;
- bool ok = false;
- float min[3], max[3], mat[4][4], pos[3], cammat[4][4];
+ MovieClip *clip = BKE_object_movieclip_get(scene, ob, false);
+ MovieTracking *tracking;
+ MovieTrackingObject *object;
+ bool ok = false;
+ float min[3], max[3], mat[4][4], pos[3], cammat[4][4];
- if (!clip) {
- return;
- }
+ if (!clip) {
+ return;
+ }
- tracking = &clip->tracking;
+ tracking = &clip->tracking;
- copy_m4_m4(cammat, ob->obmat);
+ copy_m4_m4(cammat, ob->obmat);
- BKE_tracking_get_camera_object_matrix(scene, ob, mat);
+ BKE_tracking_get_camera_object_matrix(scene, ob, mat);
- INIT_MINMAX(min, max);
+ INIT_MINMAX(min, max);
- for (object = tracking->objects.first; object; object = object->next) {
- ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
- MovieTrackingTrack *track = tracksbase->first;
- float obmat[4][4];
+ for (object = tracking->objects.first; object; object = object->next) {
+ ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
+ MovieTrackingTrack *track = tracksbase->first;
+ float obmat[4][4];
- if (object->flag & TRACKING_OBJECT_CAMERA) {
- copy_m4_m4(obmat, mat);
- }
- else {
- float imat[4][4];
+ if (object->flag & TRACKING_OBJECT_CAMERA) {
+ copy_m4_m4(obmat, mat);
+ }
+ else {
+ float imat[4][4];
- BKE_tracking_camera_get_reconstructed_interpolate(tracking, object, scene->r.cfra, imat);
- invert_m4(imat);
+ BKE_tracking_camera_get_reconstructed_interpolate(tracking, object, scene->r.cfra, imat);
+ invert_m4(imat);
- mul_m4_m4m4(obmat, cammat, imat);
- }
+ mul_m4_m4m4(obmat, cammat, imat);
+ }
- while (track) {
- if ((track->flag & TRACK_HAS_BUNDLE) && TRACK_SELECTED(track)) {
- ok = 1;
- mul_v3_m4v3(pos, obmat, track->bundle_pos);
- minmax_v3v3_v3(min, max, pos);
- }
+ while (track) {
+ if ((track->flag & TRACK_HAS_BUNDLE) && TRACK_SELECTED(track)) {
+ ok = 1;
+ mul_v3_m4v3(pos, obmat, track->bundle_pos);
+ minmax_v3v3_v3(min, max, pos);
+ }
- track = track->next;
- }
- }
+ track = track->next;
+ }
+ }
- if (ok) {
- mid_v3_v3v3(r_vec, min, max);
- }
+ if (ok) {
+ mid_v3_v3v3(r_vec, min, max);
+ }
}
/** Snaps the 3D cursor location to the median point of the selection. */
static bool snap_curs_to_sel_ex(bContext *C, float cursor[3])
{
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- ViewLayer *view_layer_eval = DEG_get_evaluated_view_layer(depsgraph);
- Object *obedit = CTX_data_edit_object(C);
- Scene *scene = CTX_data_scene(C);
- View3D *v3d = CTX_wm_view3d(C);
- TransVertStore tvs = {NULL};
- TransVert *tv;
- float bmat[3][3], vec[3], min[3], max[3], centroid[3];
- int count, a;
-
- count = 0;
- INIT_MINMAX(min, max);
- zero_v3(centroid);
-
- if (obedit) {
- int global_transverts_tot = 0;
- ViewLayer *view_layer = CTX_data_view_layer(C);
- uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- obedit = objects[ob_index];
-
- /* We can do that quick check for meshes only... */
- if (obedit->type == OB_MESH) {
- BMEditMesh *em = BKE_editmesh_from_object(obedit);
-
- if (em->bm->totvertsel == 0) {
- continue;
- }
- }
-
- if (ED_transverts_check_obedit(obedit)) {
- ED_transverts_create_from_obedit(&tvs, obedit, TM_ALL_JOINTS | TM_SKIP_HANDLES);
- }
-
- global_transverts_tot += tvs.transverts_tot;
- if (tvs.transverts_tot != 0) {
- Object *obedit_eval = DEG_get_evaluated_object(depsgraph, obedit);
- copy_m3_m4(bmat, obedit_eval->obmat);
-
- tv = tvs.transverts;
- for (a = 0; a < tvs.transverts_tot; a++, tv++) {
- copy_v3_v3(vec, tv->loc);
- mul_m3_v3(bmat, vec);
- add_v3_v3(vec, obedit_eval->obmat[3]);
- add_v3_v3(centroid, vec);
- minmax_v3v3_v3(min, max, vec);
- }
- }
- ED_transverts_free(&tvs);
- }
- MEM_freeN(objects);
-
- if (scene->toolsettings->transform_pivot_point == V3D_AROUND_CENTER_MEDIAN) {
- mul_v3_fl(centroid, 1.0f / (float)global_transverts_tot);
- copy_v3_v3(cursor, centroid);
- }
- else {
- mid_v3_v3v3(cursor, min, max);
- }
- }
- else {
- Object *obact = CTX_data_active_object(C);
-
- if (obact && (obact->mode & OB_MODE_POSE)) {
- Object *obact_eval = DEG_get_evaluated_object(depsgraph, obact);
- bArmature *arm = obact_eval->data;
- bPoseChannel *pchan;
- for (pchan = obact_eval->pose->chanbase.first; pchan; pchan = pchan->next) {
- if (arm->layer & pchan->bone->layer) {
- if (pchan->bone->flag & BONE_SELECTED) {
- copy_v3_v3(vec, pchan->pose_head);
- mul_m4_v3(obact_eval->obmat, vec);
- add_v3_v3(centroid, vec);
- minmax_v3v3_v3(min, max, vec);
- count++;
- }
- }
- }
- }
- else {
- FOREACH_SELECTED_OBJECT_BEGIN(view_layer_eval, v3d, ob_eval)
- {
- copy_v3_v3(vec, ob_eval->obmat[3]);
-
- /* special case for camera -- snap to bundles */
- if (ob_eval->type == OB_CAMERA) {
- /* snap to bundles should happen only when bundles are visible */
- if (v3d->flag2 & V3D_SHOW_RECONSTRUCTION) {
- bundle_midpoint(scene, DEG_get_original_object(ob_eval), vec);
- }
- }
-
- add_v3_v3(centroid, vec);
- minmax_v3v3_v3(min, max, vec);
- count++;
- }
- FOREACH_SELECTED_OBJECT_END;
- }
-
- if (count == 0) {
- return false;
- }
-
- if (scene->toolsettings->transform_pivot_point == V3D_AROUND_CENTER_MEDIAN) {
- mul_v3_fl(centroid, 1.0f / (float)count);
- copy_v3_v3(cursor, centroid);
- }
- else {
- mid_v3_v3v3(cursor, min, max);
- }
- }
- return true;
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ ViewLayer *view_layer_eval = DEG_get_evaluated_view_layer(depsgraph);
+ Object *obedit = CTX_data_edit_object(C);
+ Scene *scene = CTX_data_scene(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ TransVertStore tvs = {NULL};
+ TransVert *tv;
+ float bmat[3][3], vec[3], min[3], max[3], centroid[3];
+ int count, a;
+
+ count = 0;
+ INIT_MINMAX(min, max);
+ zero_v3(centroid);
+
+ if (obedit) {
+ int global_transverts_tot = 0;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ obedit = objects[ob_index];
+
+ /* We can do that quick check for meshes only... */
+ if (obedit->type == OB_MESH) {
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+
+ if (em->bm->totvertsel == 0) {
+ continue;
+ }
+ }
+
+ if (ED_transverts_check_obedit(obedit)) {
+ ED_transverts_create_from_obedit(&tvs, obedit, TM_ALL_JOINTS | TM_SKIP_HANDLES);
+ }
+
+ global_transverts_tot += tvs.transverts_tot;
+ if (tvs.transverts_tot != 0) {
+ Object *obedit_eval = DEG_get_evaluated_object(depsgraph, obedit);
+ copy_m3_m4(bmat, obedit_eval->obmat);
+
+ tv = tvs.transverts;
+ for (a = 0; a < tvs.transverts_tot; a++, tv++) {
+ copy_v3_v3(vec, tv->loc);
+ mul_m3_v3(bmat, vec);
+ add_v3_v3(vec, obedit_eval->obmat[3]);
+ add_v3_v3(centroid, vec);
+ minmax_v3v3_v3(min, max, vec);
+ }
+ }
+ ED_transverts_free(&tvs);
+ }
+ MEM_freeN(objects);
+
+ if (scene->toolsettings->transform_pivot_point == V3D_AROUND_CENTER_MEDIAN) {
+ mul_v3_fl(centroid, 1.0f / (float)global_transverts_tot);
+ copy_v3_v3(cursor, centroid);
+ }
+ else {
+ mid_v3_v3v3(cursor, min, max);
+ }
+ }
+ else {
+ Object *obact = CTX_data_active_object(C);
+
+ if (obact && (obact->mode & OB_MODE_POSE)) {
+ Object *obact_eval = DEG_get_evaluated_object(depsgraph, obact);
+ bArmature *arm = obact_eval->data;
+ bPoseChannel *pchan;
+ for (pchan = obact_eval->pose->chanbase.first; pchan; pchan = pchan->next) {
+ if (arm->layer & pchan->bone->layer) {
+ if (pchan->bone->flag & BONE_SELECTED) {
+ copy_v3_v3(vec, pchan->pose_head);
+ mul_m4_v3(obact_eval->obmat, vec);
+ add_v3_v3(centroid, vec);
+ minmax_v3v3_v3(min, max, vec);
+ count++;
+ }
+ }
+ }
+ }
+ else {
+ FOREACH_SELECTED_OBJECT_BEGIN (view_layer_eval, v3d, ob_eval) {
+ copy_v3_v3(vec, ob_eval->obmat[3]);
+
+ /* special case for camera -- snap to bundles */
+ if (ob_eval->type == OB_CAMERA) {
+ /* snap to bundles should happen only when bundles are visible */
+ if (v3d->flag2 & V3D_SHOW_RECONSTRUCTION) {
+ bundle_midpoint(scene, DEG_get_original_object(ob_eval), vec);
+ }
+ }
+
+ add_v3_v3(centroid, vec);
+ minmax_v3v3_v3(min, max, vec);
+ count++;
+ }
+ FOREACH_SELECTED_OBJECT_END;
+ }
+
+ if (count == 0) {
+ return false;
+ }
+
+ if (scene->toolsettings->transform_pivot_point == V3D_AROUND_CENTER_MEDIAN) {
+ mul_v3_fl(centroid, 1.0f / (float)count);
+ copy_v3_v3(cursor, centroid);
+ }
+ else {
+ mid_v3_v3v3(cursor, min, max);
+ }
+ }
+ return true;
}
static int snap_curs_to_sel_exec(bContext *C, wmOperator *UNUSED(op))
{
- Scene *scene = CTX_data_scene(C);
- if (snap_curs_to_sel_ex(C, scene->cursor.location)) {
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
- DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
-
- return OPERATOR_FINISHED;
- }
- else {
- return OPERATOR_CANCELLED;
- }
+ Scene *scene = CTX_data_scene(C);
+ if (snap_curs_to_sel_ex(C, scene->cursor.location)) {
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+ DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
+
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Snap Cursor to Selected";
- ot->description = "Snap 3D cursor to the middle of the selected item(s)";
- ot->idname = "VIEW3D_OT_snap_cursor_to_selected";
+ /* identifiers */
+ ot->name = "Snap Cursor to Selected";
+ ot->description = "Snap 3D cursor to the middle of the selected item(s)";
+ ot->idname = "VIEW3D_OT_snap_cursor_to_selected";
- /* api callbacks */
- ot->exec = snap_curs_to_sel_exec;
- ot->poll = ED_operator_view3d_active;
+ /* api callbacks */
+ ot->exec = snap_curs_to_sel_exec;
+ ot->poll = ED_operator_view3d_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA;
}
/* ********************************************** */
@@ -774,42 +773,42 @@ void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot)
*/
static bool snap_calc_active_center(bContext *C, const bool select_only, float r_center[3])
{
- Object *ob = CTX_data_active_object(C);
- if (ob == NULL) {
- return false;
- }
- return ED_object_calc_active_center(ob, select_only, r_center);
+ Object *ob = CTX_data_active_object(C);
+ if (ob == NULL) {
+ return false;
+ }
+ return ED_object_calc_active_center(ob, select_only, r_center);
}
static int snap_curs_to_active_exec(bContext *C, wmOperator *UNUSED(op))
{
- Scene *scene = CTX_data_scene(C);
- View3D *v3d = CTX_wm_view3d(C);
-
- if (snap_calc_active_center(C, false, scene->cursor.location)) {
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
- DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
-
- return OPERATOR_FINISHED;
- }
- else {
- return OPERATOR_CANCELLED;
- }
+ Scene *scene = CTX_data_scene(C);
+ View3D *v3d = CTX_wm_view3d(C);
+
+ if (snap_calc_active_center(C, false, scene->cursor.location)) {
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
+ DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
+
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
void VIEW3D_OT_snap_cursor_to_active(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Snap Cursor to Active";
- ot->description = "Snap 3D cursor to the active item";
- ot->idname = "VIEW3D_OT_snap_cursor_to_active";
+ /* identifiers */
+ ot->name = "Snap Cursor to Active";
+ ot->description = "Snap 3D cursor to the active item";
+ ot->idname = "VIEW3D_OT_snap_cursor_to_active";
- /* api callbacks */
- ot->exec = snap_curs_to_active_exec;
- ot->poll = ED_operator_view3d_active;
+ /* api callbacks */
+ ot->exec = snap_curs_to_active_exec;
+ ot->poll = ED_operator_view3d_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA;
}
/* **************************************************** */
@@ -817,32 +816,32 @@ void VIEW3D_OT_snap_cursor_to_active(wmOperatorType *ot)
/** Snaps the 3D cursor location to the origin and clears cursor rotation. */
static int snap_curs_to_center_exec(bContext *C, wmOperator *UNUSED(op))
{
- Scene *scene = CTX_data_scene(C);
- float mat3[3][3];
- unit_m3(mat3);
+ Scene *scene = CTX_data_scene(C);
+ float mat3[3][3];
+ unit_m3(mat3);
- zero_v3(scene->cursor.location);
- BKE_scene_cursor_mat3_to_rot(&scene->cursor, mat3, false);
+ zero_v3(scene->cursor.location);
+ BKE_scene_cursor_mat3_to_rot(&scene->cursor, mat3, false);
- DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
+ DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
- return OPERATOR_FINISHED;
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+ return OPERATOR_FINISHED;
}
void VIEW3D_OT_snap_cursor_to_center(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Snap Cursor to World Origin";
- ot->description = "Snap 3D cursor to the world origin";
- ot->idname = "VIEW3D_OT_snap_cursor_to_center";
+ /* identifiers */
+ ot->name = "Snap Cursor to World Origin";
+ ot->description = "Snap 3D cursor to the world origin";
+ ot->idname = "VIEW3D_OT_snap_cursor_to_center";
- /* api callbacks */
- ot->exec = snap_curs_to_center_exec;
- ot->poll = ED_operator_view3d_active;
+ /* api callbacks */
+ ot->exec = snap_curs_to_center_exec;
+ ot->poll = ED_operator_view3d_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* **************************************************** */
@@ -853,43 +852,43 @@ void VIEW3D_OT_snap_cursor_to_center(wmOperatorType *ot)
*/
bool ED_view3d_minmax_verts(Object *obedit, float r_min[3], float r_max[3])
{
- TransVertStore tvs = {NULL};
- TransVert *tv;
- float centroid[3], vec[3], bmat[3][3];
-
- /* Metaballs are an exception. */
- if (obedit->type == OB_MBALL) {
- float ob_min[3], ob_max[3];
- bool changed;
-
- changed = BKE_mball_minmax_ex(obedit->data, ob_min, ob_max, obedit->obmat, SELECT);
- if (changed) {
- minmax_v3v3_v3(r_min, r_max, ob_min);
- minmax_v3v3_v3(r_min, r_max, ob_max);
- }
- return changed;
- }
-
- if (ED_transverts_check_obedit(obedit)) {
- ED_transverts_create_from_obedit(&tvs, obedit, TM_ALL_JOINTS);
- }
-
- if (tvs.transverts_tot == 0) {
- return false;
- }
-
- copy_m3_m4(bmat, obedit->obmat);
-
- tv = tvs.transverts;
- for (int a = 0; a < tvs.transverts_tot; a++, tv++) {
- copy_v3_v3(vec, (tv->flag & TX_VERT_USE_MAPLOC) ? tv->maploc : tv->loc);
- mul_m3_v3(bmat, vec);
- add_v3_v3(vec, obedit->obmat[3]);
- add_v3_v3(centroid, vec);
- minmax_v3v3_v3(r_min, r_max, vec);
- }
-
- ED_transverts_free(&tvs);
-
- return true;
+ TransVertStore tvs = {NULL};
+ TransVert *tv;
+ float centroid[3], vec[3], bmat[3][3];
+
+ /* Metaballs are an exception. */
+ if (obedit->type == OB_MBALL) {
+ float ob_min[3], ob_max[3];
+ bool changed;
+
+ changed = BKE_mball_minmax_ex(obedit->data, ob_min, ob_max, obedit->obmat, SELECT);
+ if (changed) {
+ minmax_v3v3_v3(r_min, r_max, ob_min);
+ minmax_v3v3_v3(r_min, r_max, ob_max);
+ }
+ return changed;
+ }
+
+ if (ED_transverts_check_obedit(obedit)) {
+ ED_transverts_create_from_obedit(&tvs, obedit, TM_ALL_JOINTS);
+ }
+
+ if (tvs.transverts_tot == 0) {
+ return false;
+ }
+
+ copy_m3_m4(bmat, obedit->obmat);
+
+ tv = tvs.transverts;
+ for (int a = 0; a < tvs.transverts_tot; a++, tv++) {
+ copy_v3_v3(vec, (tv->flag & TX_VERT_USE_MAPLOC) ? tv->maploc : tv->loc);
+ mul_m3_v3(bmat, vec);
+ add_v3_v3(vec, obedit->obmat[3]);
+ add_v3_v3(centroid, vec);
+ minmax_v3v3_v3(r_min, r_max, vec);
+ }
+
+ ED_transverts_free(&tvs);
+
+ return true;
}
diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c
index c96e524ec2b..9357d3e05ee 100644
--- a/source/blender/editors/space_view3d/view3d_toolbar.c
+++ b/source/blender/editors/space_view3d/view3d_toolbar.c
@@ -37,31 +37,31 @@
#include "ED_screen.h"
-#include "view3d_intern.h" /* own include */
+#include "view3d_intern.h" /* own include */
/* ********** operator to open/close toolshelf region */
static int view3d_toolshelf_toggle_exec(bContext *C, wmOperator *UNUSED(op))
{
- ScrArea *sa = CTX_wm_area(C);
- ARegion *ar = view3d_has_tools_region(sa);
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = view3d_has_tools_region(sa);
- if (ar) {
- ED_region_toggle_hidden(C, ar);
- }
+ if (ar) {
+ ED_region_toggle_hidden(C, ar);
+ }
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void VIEW3D_OT_toolshelf(wmOperatorType *ot)
{
- ot->name = "Toggle Toolbar";
- ot->description = "Toggles tool shelf display";
- ot->idname = "VIEW3D_OT_toolshelf";
+ ot->name = "Toggle Toolbar";
+ ot->description = "Toggles tool shelf display";
+ ot->idname = "VIEW3D_OT_toolshelf";
- ot->exec = view3d_toolshelf_toggle_exec;
- ot->poll = ED_operator_view3d_active;
+ ot->exec = view3d_toolshelf_toggle_exec;
+ ot->poll = ED_operator_view3d_active;
- /* flags */
- ot->flag = 0;
+ /* flags */
+ ot->flag = 0;
}
diff --git a/source/blender/editors/space_view3d/view3d_utils.c b/source/blender/editors/space_view3d/view3d_utils.c
index 0639bdaa71c..3f078e35046 100644
--- a/source/blender/editors/space_view3d/view3d_utils.c
+++ b/source/blender/editors/space_view3d/view3d_utils.c
@@ -63,7 +63,7 @@
#include "UI_resources.h"
-#include "view3d_intern.h" /* own include */
+#include "view3d_intern.h" /* own include */
/* -------------------------------------------------------------------- */
/** \name View Data Access Utilities
@@ -72,115 +72,118 @@
void ED_view3d_background_color_get(const Scene *scene, const View3D *v3d, float r_color[3])
{
- if (v3d->shading.background_type == V3D_SHADING_BACKGROUND_WORLD) {
- if (scene->world) {
- copy_v3_v3(r_color, &scene->world->horr);
- return;
- }
- }
- else if (v3d->shading.background_type == V3D_SHADING_BACKGROUND_VIEWPORT) {
- copy_v3_v3(r_color, v3d->shading.background_color);
- return;
- }
-
- UI_GetThemeColor3fv(TH_BACK, r_color);
+ if (v3d->shading.background_type == V3D_SHADING_BACKGROUND_WORLD) {
+ if (scene->world) {
+ copy_v3_v3(r_color, &scene->world->horr);
+ return;
+ }
+ }
+ else if (v3d->shading.background_type == V3D_SHADING_BACKGROUND_VIEWPORT) {
+ copy_v3_v3(r_color, v3d->shading.background_color);
+ return;
+ }
+
+ UI_GetThemeColor3fv(TH_BACK, r_color);
}
void ED_view3d_cursor3d_calc_mat3(const Scene *scene, float mat[3][3])
{
- const View3DCursor *cursor = &scene->cursor;
- BKE_scene_cursor_rot_to_mat3(cursor, mat);
+ const View3DCursor *cursor = &scene->cursor;
+ BKE_scene_cursor_rot_to_mat3(cursor, mat);
}
void ED_view3d_cursor3d_calc_mat4(const Scene *scene, float mat[4][4])
{
- const View3DCursor *cursor = &scene->cursor;
- float mat3[3][3];
- BKE_scene_cursor_rot_to_mat3(cursor, mat3);
- copy_m4_m3(mat, mat3);
- copy_v3_v3(mat[3], cursor->location);
+ const View3DCursor *cursor = &scene->cursor;
+ float mat3[3][3];
+ BKE_scene_cursor_rot_to_mat3(cursor, mat3);
+ copy_m4_m3(mat, mat3);
+ copy_v3_v3(mat[3], cursor->location);
}
Camera *ED_view3d_camera_data_get(View3D *v3d, RegionView3D *rv3d)
{
- /* establish the camera object,
- * so we can default to view mapping if anything is wrong with it */
- if ((rv3d->persp == RV3D_CAMOB) && v3d->camera && (v3d->camera->type == OB_CAMERA)) {
- return v3d->camera->data;
- }
- else {
- return NULL;
- }
+ /* establish the camera object,
+ * so we can default to view mapping if anything is wrong with it */
+ if ((rv3d->persp == RV3D_CAMOB) && v3d->camera && (v3d->camera->type == OB_CAMERA)) {
+ return v3d->camera->data;
+ }
+ else {
+ return NULL;
+ }
}
-void ED_view3d_dist_range_get(
- const View3D *v3d,
- float r_dist_range[2])
+void ED_view3d_dist_range_get(const View3D *v3d, float r_dist_range[2])
{
- r_dist_range[0] = v3d->grid * 0.001f;
- r_dist_range[1] = v3d->clip_end * 10.0f;
+ r_dist_range[0] = v3d->grid * 0.001f;
+ r_dist_range[1] = v3d->clip_end * 10.0f;
}
/**
* \note copies logic of #ED_view3d_viewplane_get(), keep in sync.
*/
-bool ED_view3d_clip_range_get(
- Depsgraph *depsgraph,
- const View3D *v3d, const RegionView3D *rv3d,
- float *r_clipsta, float *r_clipend,
- const bool use_ortho_factor)
+bool ED_view3d_clip_range_get(Depsgraph *depsgraph,
+ const View3D *v3d,
+ const RegionView3D *rv3d,
+ float *r_clipsta,
+ float *r_clipend,
+ const bool use_ortho_factor)
{
- CameraParams params;
+ CameraParams params;
- BKE_camera_params_init(&params);
- BKE_camera_params_from_view3d(&params, depsgraph, v3d, rv3d);
+ BKE_camera_params_init(&params);
+ BKE_camera_params_from_view3d(&params, depsgraph, v3d, rv3d);
- if (use_ortho_factor && params.is_ortho) {
- const float fac = 2.0f / (params.clip_end - params.clip_start);
- params.clip_start *= fac;
- params.clip_end *= fac;
- }
+ if (use_ortho_factor && params.is_ortho) {
+ const float fac = 2.0f / (params.clip_end - params.clip_start);
+ params.clip_start *= fac;
+ params.clip_end *= fac;
+ }
- if (r_clipsta) {
- *r_clipsta = params.clip_start;
- }
- if (r_clipend) {
- *r_clipend = params.clip_end;
- }
+ if (r_clipsta) {
+ *r_clipsta = params.clip_start;
+ }
+ if (r_clipend) {
+ *r_clipend = params.clip_end;
+ }
- return params.is_ortho;
+ return params.is_ortho;
}
-bool ED_view3d_viewplane_get(
- Depsgraph *depsgraph,
- const View3D *v3d, const RegionView3D *rv3d, int winx, int winy,
- rctf *r_viewplane, float *r_clip_start, float *r_clip_end, float *r_pixsize)
+bool ED_view3d_viewplane_get(Depsgraph *depsgraph,
+ const View3D *v3d,
+ const RegionView3D *rv3d,
+ int winx,
+ int winy,
+ rctf *r_viewplane,
+ float *r_clip_start,
+ float *r_clip_end,
+ float *r_pixsize)
{
- CameraParams params;
-
- BKE_camera_params_init(&params);
- BKE_camera_params_from_view3d(&params, depsgraph, v3d, rv3d);
- BKE_camera_params_compute_viewplane(&params, winx, winy, 1.0f, 1.0f);
-
- if (r_viewplane) {
- *r_viewplane = params.viewplane;
- }
- if (r_clip_start) {
- *r_clip_start = params.clip_start;
- }
- if (r_clip_end) {
- *r_clip_end = params.clip_end;
- }
- if (r_pixsize) {
- *r_pixsize = params.viewdx;
- }
-
- return params.is_ortho;
+ CameraParams params;
+
+ BKE_camera_params_init(&params);
+ BKE_camera_params_from_view3d(&params, depsgraph, v3d, rv3d);
+ BKE_camera_params_compute_viewplane(&params, winx, winy, 1.0f, 1.0f);
+
+ if (r_viewplane) {
+ *r_viewplane = params.viewplane;
+ }
+ if (r_clip_start) {
+ *r_clip_start = params.clip_start;
+ }
+ if (r_clip_end) {
+ *r_clip_end = params.clip_end;
+ }
+ if (r_pixsize) {
+ *r_pixsize = params.viewdx;
+ }
+
+ return params.is_ortho;
}
/** \} */
-
/* -------------------------------------------------------------------- */
/** \name View State/Context Utilities
*
@@ -192,25 +195,25 @@ bool ED_view3d_viewplane_get(
*/
void view3d_operator_needs_opengl(const bContext *C)
{
- wmWindow *win = CTX_wm_window(C);
- ARegion *ar = CTX_wm_region(C);
+ wmWindow *win = CTX_wm_window(C);
+ ARegion *ar = CTX_wm_region(C);
- view3d_region_operator_needs_opengl(win, ar);
+ view3d_region_operator_needs_opengl(win, ar);
}
void view3d_region_operator_needs_opengl(wmWindow *UNUSED(win), ARegion *ar)
{
- /* for debugging purpose, context should always be OK */
- if ((ar == NULL) || (ar->regiontype != RGN_TYPE_WINDOW)) {
- printf("view3d_region_operator_needs_opengl error, wrong region\n");
- }
- else {
- RegionView3D *rv3d = ar->regiondata;
-
- wmViewport(&ar->winrct); // TODO: bad
- GPU_matrix_projection_set(rv3d->winmat);
- GPU_matrix_set(rv3d->viewmat);
- }
+ /* for debugging purpose, context should always be OK */
+ if ((ar == NULL) || (ar->regiontype != RGN_TYPE_WINDOW)) {
+ printf("view3d_region_operator_needs_opengl error, wrong region\n");
+ }
+ else {
+ RegionView3D *rv3d = ar->regiondata;
+
+ wmViewport(&ar->winrct); // TODO: bad
+ GPU_matrix_projection_set(rv3d->winmat);
+ GPU_matrix_set(rv3d->viewmat);
+ }
}
/**
@@ -218,51 +221,51 @@ void view3d_region_operator_needs_opengl(wmWindow *UNUSED(win), ARegion *ar)
*/
void ED_view3d_polygon_offset(const RegionView3D *rv3d, const float dist)
{
- float viewdist;
+ float viewdist;
- if (rv3d->rflag & RV3D_ZOFFSET_DISABLED) {
- return;
- }
+ if (rv3d->rflag & RV3D_ZOFFSET_DISABLED) {
+ return;
+ }
- viewdist = rv3d->dist;
+ viewdist = rv3d->dist;
- /* special exception for ortho camera (viewdist isnt used for perspective cameras) */
- if (dist != 0.0f) {
- if (rv3d->persp == RV3D_CAMOB) {
- if (rv3d->is_persp == false) {
- viewdist = 1.0f / max_ff(fabsf(rv3d->winmat[0][0]), fabsf(rv3d->winmat[1][1]));
- }
- }
- }
+ /* special exception for ortho camera (viewdist isnt used for perspective cameras) */
+ if (dist != 0.0f) {
+ if (rv3d->persp == RV3D_CAMOB) {
+ if (rv3d->is_persp == false) {
+ viewdist = 1.0f / max_ff(fabsf(rv3d->winmat[0][0]), fabsf(rv3d->winmat[1][1]));
+ }
+ }
+ }
- bglPolygonOffset(viewdist, dist);
+ bglPolygonOffset(viewdist, dist);
}
bool ED_view3d_context_activate(bContext *C)
{
- bScreen *sc = CTX_wm_screen(C);
- ScrArea *sa = CTX_wm_area(C);
- ARegion *ar;
+ bScreen *sc = CTX_wm_screen(C);
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar;
- /* sa can be NULL when called from python */
- if (sa == NULL || sa->spacetype != SPACE_VIEW3D) {
- sa = BKE_screen_find_big_area(sc, SPACE_VIEW3D, 0);
- }
+ /* sa can be NULL when called from python */
+ if (sa == NULL || sa->spacetype != SPACE_VIEW3D) {
+ sa = BKE_screen_find_big_area(sc, SPACE_VIEW3D, 0);
+ }
- if (sa == NULL) {
- return false;
- }
+ if (sa == NULL) {
+ return false;
+ }
- ar = BKE_area_find_region_active_win(sa);
- if (ar == NULL) {
- return false;
- }
+ ar = BKE_area_find_region_active_win(sa);
+ if (ar == NULL) {
+ return false;
+ }
- /* bad context switch .. */
- CTX_wm_area_set(C, sa);
- CTX_wm_region_set(C, ar);
+ /* bad context switch .. */
+ CTX_wm_area_set(C, sa);
+ CTX_wm_region_set(C, ar);
- return true;
+ return true;
}
/** \} */
@@ -272,51 +275,54 @@ bool ED_view3d_context_activate(bContext *C)
*
* \{ */
-void ED_view3d_clipping_calc_from_boundbox(float clip[4][4], const BoundBox *bb, const bool is_flip)
+void ED_view3d_clipping_calc_from_boundbox(float clip[4][4],
+ const BoundBox *bb,
+ const bool is_flip)
{
- int val;
+ int val;
- for (val = 0; val < 4; val++) {
- normal_tri_v3(clip[val], bb->vec[val], bb->vec[val == 3 ? 0 : val + 1], bb->vec[val + 4]);
- if (UNLIKELY(is_flip)) {
- negate_v3(clip[val]);
- }
+ for (val = 0; val < 4; val++) {
+ normal_tri_v3(clip[val], bb->vec[val], bb->vec[val == 3 ? 0 : val + 1], bb->vec[val + 4]);
+ if (UNLIKELY(is_flip)) {
+ negate_v3(clip[val]);
+ }
- clip[val][3] = -dot_v3v3(clip[val], bb->vec[val]);
- }
+ clip[val][3] = -dot_v3v3(clip[val], bb->vec[val]);
+ }
}
-void ED_view3d_clipping_calc(BoundBox *bb, float planes[4][4], const ARegion *ar, const Object *ob, const rcti *rect)
+void ED_view3d_clipping_calc(
+ BoundBox *bb, float planes[4][4], const ARegion *ar, const Object *ob, const rcti *rect)
{
- /* init in case unproject fails */
- memset(bb->vec, 0, sizeof(bb->vec));
-
- /* four clipping planes and bounding volume */
- /* first do the bounding volume */
- for (int val = 0; val < 4; val++) {
- float xs = (val == 0 || val == 3) ? rect->xmin : rect->xmax;
- float ys = (val == 0 || val == 1) ? rect->ymin : rect->ymax;
-
- ED_view3d_unproject(ar, xs, ys, 0.0, bb->vec[val]);
- ED_view3d_unproject(ar, xs, ys, 1.0, bb->vec[4 + val]);
- }
-
- /* optionally transform to object space */
- if (ob) {
- float imat[4][4];
- invert_m4_m4(imat, ob->obmat);
-
- for (int val = 0; val < 8; val++) {
- mul_m4_v3(imat, bb->vec[val]);
- }
- }
-
- /* verify if we have negative scale. doing the transform before cross
- * product flips the sign of the vector compared to doing cross product
- * before transform then, so we correct for that. */
- int flip_sign = (ob) ? is_negative_m4(ob->obmat) : false;
-
- ED_view3d_clipping_calc_from_boundbox(planes, bb, flip_sign);
+ /* init in case unproject fails */
+ memset(bb->vec, 0, sizeof(bb->vec));
+
+ /* four clipping planes and bounding volume */
+ /* first do the bounding volume */
+ for (int val = 0; val < 4; val++) {
+ float xs = (val == 0 || val == 3) ? rect->xmin : rect->xmax;
+ float ys = (val == 0 || val == 1) ? rect->ymin : rect->ymax;
+
+ ED_view3d_unproject(ar, xs, ys, 0.0, bb->vec[val]);
+ ED_view3d_unproject(ar, xs, ys, 1.0, bb->vec[4 + val]);
+ }
+
+ /* optionally transform to object space */
+ if (ob) {
+ float imat[4][4];
+ invert_m4_m4(imat, ob->obmat);
+
+ for (int val = 0; val < 8; val++) {
+ mul_m4_v3(imat, bb->vec[val]);
+ }
+ }
+
+ /* verify if we have negative scale. doing the transform before cross
+ * product flips the sign of the vector compared to doing cross product
+ * before transform then, so we correct for that. */
+ int flip_sign = (ob) ? is_negative_m4(ob->obmat) : false;
+
+ ED_view3d_clipping_calc_from_boundbox(planes, bb, flip_sign);
}
/** \} */
@@ -328,73 +334,73 @@ void ED_view3d_clipping_calc(BoundBox *bb, float planes[4][4], const ARegion *ar
static bool view3d_boundbox_clip_m4(const BoundBox *bb, float persmatob[4][4])
{
- int a, flag = -1, fl;
-
- for (a = 0; a < 8; a++) {
- float vec[4], min, max;
- copy_v3_v3(vec, bb->vec[a]);
- vec[3] = 1.0;
- mul_m4_v4(persmatob, vec);
- max = vec[3];
- min = -vec[3];
-
- fl = 0;
- if (vec[0] < min) {
- fl += 1;
- }
- if (vec[0] > max) {
- fl += 2;
- }
- if (vec[1] < min) {
- fl += 4;
- }
- if (vec[1] > max) {
- fl += 8;
- }
- if (vec[2] < min) {
- fl += 16;
- }
- if (vec[2] > max) {
- fl += 32;
- }
-
- flag &= fl;
- if (flag == 0) {
- return true;
- }
- }
-
- return false;
+ int a, flag = -1, fl;
+
+ for (a = 0; a < 8; a++) {
+ float vec[4], min, max;
+ copy_v3_v3(vec, bb->vec[a]);
+ vec[3] = 1.0;
+ mul_m4_v4(persmatob, vec);
+ max = vec[3];
+ min = -vec[3];
+
+ fl = 0;
+ if (vec[0] < min) {
+ fl += 1;
+ }
+ if (vec[0] > max) {
+ fl += 2;
+ }
+ if (vec[1] < min) {
+ fl += 4;
+ }
+ if (vec[1] > max) {
+ fl += 8;
+ }
+ if (vec[2] < min) {
+ fl += 16;
+ }
+ if (vec[2] > max) {
+ fl += 32;
+ }
+
+ flag &= fl;
+ if (flag == 0) {
+ return true;
+ }
+ }
+
+ return false;
}
bool ED_view3d_boundbox_clip_ex(const RegionView3D *rv3d, const BoundBox *bb, float obmat[4][4])
{
- /* return 1: draw */
+ /* return 1: draw */
- float persmatob[4][4];
+ float persmatob[4][4];
- if (bb == NULL) {
- return true;
- }
- if (bb->flag & BOUNDBOX_DISABLED) {
- return true;
- }
+ if (bb == NULL) {
+ return true;
+ }
+ if (bb->flag & BOUNDBOX_DISABLED) {
+ return true;
+ }
- mul_m4_m4m4(persmatob, (float(*)[4])rv3d->persmat, obmat);
+ mul_m4_m4m4(persmatob, (float(*)[4])rv3d->persmat, obmat);
- return view3d_boundbox_clip_m4(bb, persmatob);
+ return view3d_boundbox_clip_m4(bb, persmatob);
}
bool ED_view3d_boundbox_clip(RegionView3D *rv3d, const BoundBox *bb)
{
- if (bb == NULL) {
- return true;
- }
- if (bb->flag & BOUNDBOX_DISABLED) {
- return true;
- }
-
- return view3d_boundbox_clip_m4(bb, rv3d->persmatob);
+ if (bb == NULL) {
+ return true;
+ }
+ if (bb->flag & BOUNDBOX_DISABLED) {
+ return true;
+ }
+
+ return view3d_boundbox_clip_m4(bb, rv3d->persmatob);
}
/** \} */
@@ -405,9 +411,9 @@ bool ED_view3d_boundbox_clip(RegionView3D *rv3d, const BoundBox *bb)
* Misc view utility functions.
* \{ */
-bool ED_view3d_offset_lock_check(const View3D *v3d, const RegionView3D *rv3d)
+bool ED_view3d_offset_lock_check(const View3D *v3d, const RegionView3D *rv3d)
{
- return (rv3d->persp != RV3D_CAMOB) && (v3d->ob_centre_cursor || v3d->ob_centre);
+ return (rv3d->persp != RV3D_CAMOB) && (v3d->ob_centre_cursor || v3d->ob_centre);
}
/**
@@ -415,19 +421,19 @@ bool ED_view3d_offset_lock_check(const View3D *v3d, const RegionView3D *rv3d)
*/
void ED_view3d_lastview_store(RegionView3D *rv3d)
{
- copy_qt_qt(rv3d->lviewquat, rv3d->viewquat);
- rv3d->lview = rv3d->view;
- if (rv3d->persp != RV3D_CAMOB) {
- rv3d->lpersp = rv3d->persp;
- }
+ copy_qt_qt(rv3d->lviewquat, rv3d->viewquat);
+ rv3d->lview = rv3d->view;
+ if (rv3d->persp != RV3D_CAMOB) {
+ rv3d->lpersp = rv3d->persp;
+ }
}
void ED_view3d_lock_clear(View3D *v3d)
{
- v3d->ob_centre = NULL;
- v3d->ob_centre_bone[0] = '\0';
- v3d->ob_centre_cursor = false;
- v3d->flag2 &= ~V3D_LOCK_CAMERA;
+ v3d->ob_centre = NULL;
+ v3d->ob_centre_bone[0] = '\0';
+ v3d->ob_centre_cursor = false;
+ v3d->flag2 &= ~V3D_LOCK_CAMERA;
}
/**
@@ -437,20 +443,23 @@ void ED_view3d_lock_clear(View3D *v3d)
* sets the ``ofs`` and ``dist`` values of the viewport so it matches the camera,
* otherwise switching out of camera view may jump to a different part of the scene.
*/
-void ED_view3d_persp_switch_from_camera(const Depsgraph *depsgraph, View3D *v3d, RegionView3D *rv3d, const char persp)
+void ED_view3d_persp_switch_from_camera(const Depsgraph *depsgraph,
+ View3D *v3d,
+ RegionView3D *rv3d,
+ const char persp)
{
- BLI_assert(rv3d->persp == RV3D_CAMOB);
- BLI_assert(persp != RV3D_CAMOB);
-
- if (v3d->camera) {
- Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera);
- rv3d->dist = ED_view3d_offset_distance(ob_camera_eval->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK);
- ED_view3d_from_object(ob_camera_eval, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL);
- }
-
- if (!ED_view3d_camera_lock_check(v3d, rv3d)) {
- rv3d->persp = persp;
- }
+ BLI_assert(rv3d->persp == RV3D_CAMOB);
+ BLI_assert(persp != RV3D_CAMOB);
+
+ if (v3d->camera) {
+ Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera);
+ rv3d->dist = ED_view3d_offset_distance(ob_camera_eval->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK);
+ ED_view3d_from_object(ob_camera_eval, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL);
+ }
+
+ if (!ED_view3d_camera_lock_check(v3d, rv3d)) {
+ rv3d->persp = persp;
+ }
}
/**
* Action to take when rotating the view,
@@ -460,29 +469,29 @@ void ED_view3d_persp_switch_from_camera(const Depsgraph *depsgraph, View3D *v3d,
*/
bool ED_view3d_persp_ensure(const Depsgraph *depsgraph, View3D *v3d, ARegion *ar)
{
- RegionView3D *rv3d = ar->regiondata;
- const bool autopersp = (U.uiflag & USER_AUTOPERSP) != 0;
-
- BLI_assert((rv3d->viewlock & RV3D_LOCKED) == 0);
-
- if (ED_view3d_camera_lock_check(v3d, rv3d)) {
- return false;
- }
-
- if (rv3d->persp != RV3D_PERSP) {
- if (rv3d->persp == RV3D_CAMOB) {
- /* If autopersp and previous view was an axis one,
- * switch back to PERSP mode, else reuse previous mode. */
- char persp = (autopersp && RV3D_VIEW_IS_AXIS(rv3d->lview)) ? RV3D_PERSP : rv3d->lpersp;
- ED_view3d_persp_switch_from_camera(depsgraph, v3d, rv3d, persp);
- }
- else if (autopersp && RV3D_VIEW_IS_AXIS(rv3d->view)) {
- rv3d->persp = RV3D_PERSP;
- }
- return true;
- }
-
- return false;
+ RegionView3D *rv3d = ar->regiondata;
+ const bool autopersp = (U.uiflag & USER_AUTOPERSP) != 0;
+
+ BLI_assert((rv3d->viewlock & RV3D_LOCKED) == 0);
+
+ if (ED_view3d_camera_lock_check(v3d, rv3d)) {
+ return false;
+ }
+
+ if (rv3d->persp != RV3D_PERSP) {
+ if (rv3d->persp == RV3D_CAMOB) {
+ /* If autopersp and previous view was an axis one,
+ * switch back to PERSP mode, else reuse previous mode. */
+ char persp = (autopersp && RV3D_VIEW_IS_AXIS(rv3d->lview)) ? RV3D_PERSP : rv3d->lpersp;
+ ED_view3d_persp_switch_from_camera(depsgraph, v3d, rv3d, persp);
+ }
+ else if (autopersp && RV3D_VIEW_IS_AXIS(rv3d->view)) {
+ rv3d->persp = RV3D_PERSP;
+ }
+ return true;
+ }
+
+ return false;
}
/** \} */
@@ -498,31 +507,33 @@ bool ED_view3d_persp_ensure(const Depsgraph *depsgraph, View3D *v3d, ARegion *ar
*/
bool ED_view3d_camera_lock_check(const View3D *v3d, const RegionView3D *rv3d)
{
- return ((v3d->camera) &&
- (!ID_IS_LINKED(v3d->camera)) &&
- (v3d->flag2 & V3D_LOCK_CAMERA) &&
- (rv3d->persp == RV3D_CAMOB));
+ return ((v3d->camera) && (!ID_IS_LINKED(v3d->camera)) && (v3d->flag2 & V3D_LOCK_CAMERA) &&
+ (rv3d->persp == RV3D_CAMOB));
}
/**
* Apply the camera object transformation to the view-port.
* (needed so we can use regular view-port manipulation operators, that sync back to the camera).
*/
-void ED_view3d_camera_lock_init_ex(const Depsgraph *depsgraph, View3D *v3d, RegionView3D *rv3d, const bool calc_dist)
+void ED_view3d_camera_lock_init_ex(const Depsgraph *depsgraph,
+ View3D *v3d,
+ RegionView3D *rv3d,
+ const bool calc_dist)
{
- if (ED_view3d_camera_lock_check(v3d, rv3d)) {
- Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera);
- if (calc_dist) {
- /* using a fallback dist is OK here since ED_view3d_from_object() compensates for it */
- rv3d->dist = ED_view3d_offset_distance(ob_camera_eval->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK);
- }
- ED_view3d_from_object(ob_camera_eval, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL);
- }
+ if (ED_view3d_camera_lock_check(v3d, rv3d)) {
+ Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera);
+ if (calc_dist) {
+ /* using a fallback dist is OK here since ED_view3d_from_object() compensates for it */
+ rv3d->dist = ED_view3d_offset_distance(
+ ob_camera_eval->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK);
+ }
+ ED_view3d_from_object(ob_camera_eval, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL);
+ }
}
void ED_view3d_camera_lock_init(const Depsgraph *depsgraph, View3D *v3d, RegionView3D *rv3d)
{
- ED_view3d_camera_lock_init_ex(depsgraph, v3d, rv3d, true);
+ ED_view3d_camera_lock_init_ex(depsgraph, v3d, rv3d, true);
}
/**
@@ -532,95 +543,95 @@ void ED_view3d_camera_lock_init(const Depsgraph *depsgraph, View3D *v3d, RegionV
*/
bool ED_view3d_camera_lock_sync(const Depsgraph *depsgraph, View3D *v3d, RegionView3D *rv3d)
{
- if (ED_view3d_camera_lock_check(v3d, rv3d)) {
- ObjectTfmProtectedChannels obtfm;
- Object *root_parent;
-
- if ((U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0 && (root_parent = v3d->camera->parent)) {
- Object *ob_update;
- float tmat[4][4];
- float imat[4][4];
- float view_mat[4][4];
- float diff_mat[4][4];
- float parent_mat[4][4];
-
- while (root_parent->parent) {
- root_parent = root_parent->parent;
- }
- Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera);
- Object *root_parent_eval = DEG_get_evaluated_object(depsgraph, root_parent);
-
- ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist);
-
- normalize_m4_m4(tmat, ob_camera_eval->obmat);
-
- invert_m4_m4(imat, tmat);
- mul_m4_m4m4(diff_mat, view_mat, imat);
-
- mul_m4_m4m4(parent_mat, diff_mat, root_parent_eval->obmat);
-
- BKE_object_tfm_protected_backup(root_parent, &obtfm);
- BKE_object_apply_mat4(root_parent, parent_mat, true, false);
- BKE_object_tfm_protected_restore(root_parent, &obtfm, root_parent->protectflag);
-
- ob_update = v3d->camera;
- while (ob_update) {
- DEG_id_tag_update(&ob_update->id, ID_RECALC_TRANSFORM);
- WM_main_add_notifier(NC_OBJECT | ND_TRANSFORM, ob_update);
- ob_update = ob_update->parent;
- }
- }
- else {
- /* always maintain the same scale */
- const short protect_scale_all = (OB_LOCK_SCALEX | OB_LOCK_SCALEY | OB_LOCK_SCALEZ);
- BKE_object_tfm_protected_backup(v3d->camera, &obtfm);
- ED_view3d_to_object(depsgraph, v3d->camera, rv3d->ofs, rv3d->viewquat, rv3d->dist);
- BKE_object_tfm_protected_restore(v3d->camera, &obtfm, v3d->camera->protectflag | protect_scale_all);
-
- DEG_id_tag_update(&v3d->camera->id, ID_RECALC_TRANSFORM);
- WM_main_add_notifier(NC_OBJECT | ND_TRANSFORM, v3d->camera);
- }
-
- return true;
- }
- else {
- return false;
- }
+ if (ED_view3d_camera_lock_check(v3d, rv3d)) {
+ ObjectTfmProtectedChannels obtfm;
+ Object *root_parent;
+
+ if ((U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0 && (root_parent = v3d->camera->parent)) {
+ Object *ob_update;
+ float tmat[4][4];
+ float imat[4][4];
+ float view_mat[4][4];
+ float diff_mat[4][4];
+ float parent_mat[4][4];
+
+ while (root_parent->parent) {
+ root_parent = root_parent->parent;
+ }
+ Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera);
+ Object *root_parent_eval = DEG_get_evaluated_object(depsgraph, root_parent);
+
+ ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist);
+
+ normalize_m4_m4(tmat, ob_camera_eval->obmat);
+
+ invert_m4_m4(imat, tmat);
+ mul_m4_m4m4(diff_mat, view_mat, imat);
+
+ mul_m4_m4m4(parent_mat, diff_mat, root_parent_eval->obmat);
+
+ BKE_object_tfm_protected_backup(root_parent, &obtfm);
+ BKE_object_apply_mat4(root_parent, parent_mat, true, false);
+ BKE_object_tfm_protected_restore(root_parent, &obtfm, root_parent->protectflag);
+
+ ob_update = v3d->camera;
+ while (ob_update) {
+ DEG_id_tag_update(&ob_update->id, ID_RECALC_TRANSFORM);
+ WM_main_add_notifier(NC_OBJECT | ND_TRANSFORM, ob_update);
+ ob_update = ob_update->parent;
+ }
+ }
+ else {
+ /* always maintain the same scale */
+ const short protect_scale_all = (OB_LOCK_SCALEX | OB_LOCK_SCALEY | OB_LOCK_SCALEZ);
+ BKE_object_tfm_protected_backup(v3d->camera, &obtfm);
+ ED_view3d_to_object(depsgraph, v3d->camera, rv3d->ofs, rv3d->viewquat, rv3d->dist);
+ BKE_object_tfm_protected_restore(
+ v3d->camera, &obtfm, v3d->camera->protectflag | protect_scale_all);
+
+ DEG_id_tag_update(&v3d->camera->id, ID_RECALC_TRANSFORM);
+ WM_main_add_notifier(NC_OBJECT | ND_TRANSFORM, v3d->camera);
+ }
+
+ return true;
+ }
+ else {
+ return false;
+ }
}
bool ED_view3d_camera_autokey(
- Scene *scene, ID *id_key,
- struct bContext *C, const bool do_rotate, const bool do_translate)
+ Scene *scene, ID *id_key, struct bContext *C, const bool do_rotate, const bool do_translate)
{
- if (autokeyframe_cfra_can_key(scene, id_key)) {
- const float cfra = (float)CFRA;
- ListBase dsources = {NULL, NULL};
-
- /* add data-source override for the camera object */
- ANIM_relative_keyingset_add_source(&dsources, id_key, NULL, NULL);
-
- /* insert keyframes
- * 1) on the first frame
- * 2) on each subsequent frame
- * TODO: need to check in future that frame changed before doing this
- */
- if (do_rotate) {
- struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_ROTATION_ID);
- ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
- }
- if (do_translate) {
- struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID);
- ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
- }
-
- /* free temp data */
- BLI_freelistN(&dsources);
-
- return true;
- }
- else {
- return false;
- }
+ if (autokeyframe_cfra_can_key(scene, id_key)) {
+ const float cfra = (float)CFRA;
+ ListBase dsources = {NULL, NULL};
+
+ /* add data-source override for the camera object */
+ ANIM_relative_keyingset_add_source(&dsources, id_key, NULL, NULL);
+
+ /* insert keyframes
+ * 1) on the first frame
+ * 2) on each subsequent frame
+ * TODO: need to check in future that frame changed before doing this
+ */
+ if (do_rotate) {
+ struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_ROTATION_ID);
+ ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ }
+ if (do_translate) {
+ struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID);
+ ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ }
+
+ /* free temp data */
+ BLI_freelistN(&dsources);
+
+ return true;
+ }
+ else {
+ return false;
+ }
}
/**
@@ -629,36 +640,36 @@ bool ED_view3d_camera_autokey(
* \note Not every view edit currently auto-keys (numpad for eg),
* this is complicated because of smoothview.
*/
-bool ED_view3d_camera_lock_autokey(
- View3D *v3d, RegionView3D *rv3d,
- struct bContext *C, const bool do_rotate, const bool do_translate)
+bool ED_view3d_camera_lock_autokey(View3D *v3d,
+ RegionView3D *rv3d,
+ struct bContext *C,
+ const bool do_rotate,
+ const bool do_translate)
{
- /* similar to ED_view3d_cameracontrol_update */
- if (ED_view3d_camera_lock_check(v3d, rv3d)) {
- Scene *scene = CTX_data_scene(C);
- ID *id_key;
- Object *root_parent;
- if ((U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0 && (root_parent = v3d->camera->parent)) {
- while (root_parent->parent) {
- root_parent = root_parent->parent;
- }
- id_key = &root_parent->id;
- }
- else {
- id_key = &v3d->camera->id;
- }
-
- return ED_view3d_camera_autokey(scene, id_key, C, do_rotate, do_translate);
- }
- else {
- return false;
- }
+ /* similar to ED_view3d_cameracontrol_update */
+ if (ED_view3d_camera_lock_check(v3d, rv3d)) {
+ Scene *scene = CTX_data_scene(C);
+ ID *id_key;
+ Object *root_parent;
+ if ((U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0 && (root_parent = v3d->camera->parent)) {
+ while (root_parent->parent) {
+ root_parent = root_parent->parent;
+ }
+ id_key = &root_parent->id;
+ }
+ else {
+ id_key = &v3d->camera->id;
+ }
+
+ return ED_view3d_camera_autokey(scene, id_key, C, do_rotate, do_translate);
+ }
+ else {
+ return false;
+ }
}
/** \} */
-
-
/* -------------------------------------------------------------------- */
/** \name Box View Support
*
@@ -667,100 +678,100 @@ bool ED_view3d_camera_lock_autokey(
static void view3d_boxview_clip(ScrArea *sa)
{
- ARegion *ar;
- BoundBox *bb = MEM_callocN(sizeof(BoundBox), "clipbb");
- float clip[6][4];
- float x1 = 0.0f, y1 = 0.0f, z1 = 0.0f, ofs[3] = {0.0f, 0.0f, 0.0f};
- int val;
-
- /* create bounding box */
- for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->regiontype == RGN_TYPE_WINDOW) {
- RegionView3D *rv3d = ar->regiondata;
-
- if (rv3d->viewlock & RV3D_BOXCLIP) {
- if (ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM)) {
- if (ar->winx > ar->winy) {
- x1 = rv3d->dist;
- }
- else {
- x1 = ar->winx * rv3d->dist / ar->winy;
- }
-
- if (ar->winx > ar->winy) {
- y1 = ar->winy * rv3d->dist / ar->winx;
- }
- else {
- y1 = rv3d->dist;
- }
- copy_v2_v2(ofs, rv3d->ofs);
- }
- else if (ELEM(rv3d->view, RV3D_VIEW_FRONT, RV3D_VIEW_BACK)) {
- ofs[2] = rv3d->ofs[2];
-
- if (ar->winx > ar->winy) {
- z1 = ar->winy * rv3d->dist / ar->winx;
- }
- else {
- z1 = rv3d->dist;
- }
- }
- }
- }
- }
-
- for (val = 0; val < 8; val++) {
- if (ELEM(val, 0, 3, 4, 7)) {
- bb->vec[val][0] = -x1 - ofs[0];
- }
- else {
- bb->vec[val][0] = x1 - ofs[0];
- }
-
- if (ELEM(val, 0, 1, 4, 5)) {
- bb->vec[val][1] = -y1 - ofs[1];
- }
- else {
- bb->vec[val][1] = y1 - ofs[1];
- }
-
- if (val > 3) {
- bb->vec[val][2] = -z1 - ofs[2];
- }
- else {
- bb->vec[val][2] = z1 - ofs[2];
- }
- }
-
- /* normals for plane equations */
- normal_tri_v3(clip[0], bb->vec[0], bb->vec[1], bb->vec[4]);
- normal_tri_v3(clip[1], bb->vec[1], bb->vec[2], bb->vec[5]);
- normal_tri_v3(clip[2], bb->vec[2], bb->vec[3], bb->vec[6]);
- normal_tri_v3(clip[3], bb->vec[3], bb->vec[0], bb->vec[7]);
- normal_tri_v3(clip[4], bb->vec[4], bb->vec[5], bb->vec[6]);
- normal_tri_v3(clip[5], bb->vec[0], bb->vec[2], bb->vec[1]);
-
- /* then plane equations */
- for (val = 0; val < 6; val++) {
- clip[val][3] = -dot_v3v3(clip[val], bb->vec[val % 5]);
- }
-
- /* create bounding box */
- for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->regiontype == RGN_TYPE_WINDOW) {
- RegionView3D *rv3d = ar->regiondata;
-
- if (rv3d->viewlock & RV3D_BOXCLIP) {
- rv3d->rflag |= RV3D_CLIPPING;
- memcpy(rv3d->clip, clip, sizeof(clip));
- if (rv3d->clipbb) {
- MEM_freeN(rv3d->clipbb);
- }
- rv3d->clipbb = MEM_dupallocN(bb);
- }
- }
- }
- MEM_freeN(bb);
+ ARegion *ar;
+ BoundBox *bb = MEM_callocN(sizeof(BoundBox), "clipbb");
+ float clip[6][4];
+ float x1 = 0.0f, y1 = 0.0f, z1 = 0.0f, ofs[3] = {0.0f, 0.0f, 0.0f};
+ int val;
+
+ /* create bounding box */
+ for (ar = sa->regionbase.first; ar; ar = ar->next) {
+ if (ar->regiontype == RGN_TYPE_WINDOW) {
+ RegionView3D *rv3d = ar->regiondata;
+
+ if (rv3d->viewlock & RV3D_BOXCLIP) {
+ if (ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM)) {
+ if (ar->winx > ar->winy) {
+ x1 = rv3d->dist;
+ }
+ else {
+ x1 = ar->winx * rv3d->dist / ar->winy;
+ }
+
+ if (ar->winx > ar->winy) {
+ y1 = ar->winy * rv3d->dist / ar->winx;
+ }
+ else {
+ y1 = rv3d->dist;
+ }
+ copy_v2_v2(ofs, rv3d->ofs);
+ }
+ else if (ELEM(rv3d->view, RV3D_VIEW_FRONT, RV3D_VIEW_BACK)) {
+ ofs[2] = rv3d->ofs[2];
+
+ if (ar->winx > ar->winy) {
+ z1 = ar->winy * rv3d->dist / ar->winx;
+ }
+ else {
+ z1 = rv3d->dist;
+ }
+ }
+ }
+ }
+ }
+
+ for (val = 0; val < 8; val++) {
+ if (ELEM(val, 0, 3, 4, 7)) {
+ bb->vec[val][0] = -x1 - ofs[0];
+ }
+ else {
+ bb->vec[val][0] = x1 - ofs[0];
+ }
+
+ if (ELEM(val, 0, 1, 4, 5)) {
+ bb->vec[val][1] = -y1 - ofs[1];
+ }
+ else {
+ bb->vec[val][1] = y1 - ofs[1];
+ }
+
+ if (val > 3) {
+ bb->vec[val][2] = -z1 - ofs[2];
+ }
+ else {
+ bb->vec[val][2] = z1 - ofs[2];
+ }
+ }
+
+ /* normals for plane equations */
+ normal_tri_v3(clip[0], bb->vec[0], bb->vec[1], bb->vec[4]);
+ normal_tri_v3(clip[1], bb->vec[1], bb->vec[2], bb->vec[5]);
+ normal_tri_v3(clip[2], bb->vec[2], bb->vec[3], bb->vec[6]);
+ normal_tri_v3(clip[3], bb->vec[3], bb->vec[0], bb->vec[7]);
+ normal_tri_v3(clip[4], bb->vec[4], bb->vec[5], bb->vec[6]);
+ normal_tri_v3(clip[5], bb->vec[0], bb->vec[2], bb->vec[1]);
+
+ /* then plane equations */
+ for (val = 0; val < 6; val++) {
+ clip[val][3] = -dot_v3v3(clip[val], bb->vec[val % 5]);
+ }
+
+ /* create bounding box */
+ for (ar = sa->regionbase.first; ar; ar = ar->next) {
+ if (ar->regiontype == RGN_TYPE_WINDOW) {
+ RegionView3D *rv3d = ar->regiondata;
+
+ if (rv3d->viewlock & RV3D_BOXCLIP) {
+ rv3d->rflag |= RV3D_CLIPPING;
+ memcpy(rv3d->clip, clip, sizeof(clip));
+ if (rv3d->clipbb) {
+ MEM_freeN(rv3d->clipbb);
+ }
+ rv3d->clipbb = MEM_dupallocN(bb);
+ }
+ }
+ }
+ MEM_freeN(bb);
}
/**
@@ -769,161 +780,156 @@ static void view3d_boxview_clip(ScrArea *sa)
*/
static void view3d_boxview_sync_axis(RegionView3D *rv3d_dst, RegionView3D *rv3d_src)
{
- /* absolute axis values above this are considered to be set (will be ~1.0f) */
- const float axis_eps = 0.5f;
- float viewinv[4];
-
- /* use the view rotation to identify which axis to sync on */
- float view_axis_all[4][3] = {
- {1.0f, 0.0f, 0.0f},
- {0.0f, 1.0f, 0.0f},
- {1.0f, 0.0f, 0.0f},
- {0.0f, 1.0f, 0.0f}};
-
- float *view_src_x = &view_axis_all[0][0];
- float *view_src_y = &view_axis_all[1][0];
-
- float *view_dst_x = &view_axis_all[2][0];
- float *view_dst_y = &view_axis_all[3][0];
- int i;
-
-
- /* we could use rv3d->viewinv, but better not depend on view matrix being updated */
- if (UNLIKELY(ED_view3d_quat_from_axis_view(rv3d_src->view, viewinv) == false)) {
- return;
- }
- invert_qt_normalized(viewinv);
- mul_qt_v3(viewinv, view_src_x);
- mul_qt_v3(viewinv, view_src_y);
-
- if (UNLIKELY(ED_view3d_quat_from_axis_view(rv3d_dst->view, viewinv) == false)) {
- return;
- }
- invert_qt_normalized(viewinv);
- mul_qt_v3(viewinv, view_dst_x);
- mul_qt_v3(viewinv, view_dst_y);
-
- /* check source and dest have a matching axis */
- for (i = 0; i < 3; i++) {
- if (((fabsf(view_src_x[i]) > axis_eps) || (fabsf(view_src_y[i]) > axis_eps)) &&
- ((fabsf(view_dst_x[i]) > axis_eps) || (fabsf(view_dst_y[i]) > axis_eps)))
- {
- rv3d_dst->ofs[i] = rv3d_src->ofs[i];
- }
- }
+ /* absolute axis values above this are considered to be set (will be ~1.0f) */
+ const float axis_eps = 0.5f;
+ float viewinv[4];
+
+ /* use the view rotation to identify which axis to sync on */
+ float view_axis_all[4][3] = {
+ {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}};
+
+ float *view_src_x = &view_axis_all[0][0];
+ float *view_src_y = &view_axis_all[1][0];
+
+ float *view_dst_x = &view_axis_all[2][0];
+ float *view_dst_y = &view_axis_all[3][0];
+ int i;
+
+ /* we could use rv3d->viewinv, but better not depend on view matrix being updated */
+ if (UNLIKELY(ED_view3d_quat_from_axis_view(rv3d_src->view, viewinv) == false)) {
+ return;
+ }
+ invert_qt_normalized(viewinv);
+ mul_qt_v3(viewinv, view_src_x);
+ mul_qt_v3(viewinv, view_src_y);
+
+ if (UNLIKELY(ED_view3d_quat_from_axis_view(rv3d_dst->view, viewinv) == false)) {
+ return;
+ }
+ invert_qt_normalized(viewinv);
+ mul_qt_v3(viewinv, view_dst_x);
+ mul_qt_v3(viewinv, view_dst_y);
+
+ /* check source and dest have a matching axis */
+ for (i = 0; i < 3; i++) {
+ if (((fabsf(view_src_x[i]) > axis_eps) || (fabsf(view_src_y[i]) > axis_eps)) &&
+ ((fabsf(view_dst_x[i]) > axis_eps) || (fabsf(view_dst_y[i]) > axis_eps))) {
+ rv3d_dst->ofs[i] = rv3d_src->ofs[i];
+ }
+ }
}
/* sync center/zoom view of region to others, for view transforms */
void view3d_boxview_sync(ScrArea *sa, ARegion *ar)
{
- ARegion *artest;
- RegionView3D *rv3d = ar->regiondata;
- short clip = 0;
-
- for (artest = sa->regionbase.first; artest; artest = artest->next) {
- if (artest != ar && artest->regiontype == RGN_TYPE_WINDOW) {
- RegionView3D *rv3dtest = artest->regiondata;
-
- if (rv3dtest->viewlock & RV3D_LOCKED) {
- rv3dtest->dist = rv3d->dist;
- view3d_boxview_sync_axis(rv3dtest, rv3d);
- clip |= rv3dtest->viewlock & RV3D_BOXCLIP;
-
- ED_region_tag_redraw(artest);
- }
- }
- }
-
- if (clip) {
- view3d_boxview_clip(sa);
- }
+ ARegion *artest;
+ RegionView3D *rv3d = ar->regiondata;
+ short clip = 0;
+
+ for (artest = sa->regionbase.first; artest; artest = artest->next) {
+ if (artest != ar && artest->regiontype == RGN_TYPE_WINDOW) {
+ RegionView3D *rv3dtest = artest->regiondata;
+
+ if (rv3dtest->viewlock & RV3D_LOCKED) {
+ rv3dtest->dist = rv3d->dist;
+ view3d_boxview_sync_axis(rv3dtest, rv3d);
+ clip |= rv3dtest->viewlock & RV3D_BOXCLIP;
+
+ ED_region_tag_redraw(artest);
+ }
+ }
+ }
+
+ if (clip) {
+ view3d_boxview_clip(sa);
+ }
}
/* for home, center etc */
void view3d_boxview_copy(ScrArea *sa, ARegion *ar)
{
- ARegion *artest;
- RegionView3D *rv3d = ar->regiondata;
- bool clip = false;
-
- for (artest = sa->regionbase.first; artest; artest = artest->next) {
- if (artest != ar && artest->regiontype == RGN_TYPE_WINDOW) {
- RegionView3D *rv3dtest = artest->regiondata;
-
- if (rv3dtest->viewlock) {
- rv3dtest->dist = rv3d->dist;
- copy_v3_v3(rv3dtest->ofs, rv3d->ofs);
- ED_region_tag_redraw(artest);
-
- clip |= ((rv3dtest->viewlock & RV3D_BOXCLIP) != 0);
- }
- }
- }
-
- if (clip) {
- view3d_boxview_clip(sa);
- }
+ ARegion *artest;
+ RegionView3D *rv3d = ar->regiondata;
+ bool clip = false;
+
+ for (artest = sa->regionbase.first; artest; artest = artest->next) {
+ if (artest != ar && artest->regiontype == RGN_TYPE_WINDOW) {
+ RegionView3D *rv3dtest = artest->regiondata;
+
+ if (rv3dtest->viewlock) {
+ rv3dtest->dist = rv3d->dist;
+ copy_v3_v3(rv3dtest->ofs, rv3d->ofs);
+ ED_region_tag_redraw(artest);
+
+ clip |= ((rv3dtest->viewlock & RV3D_BOXCLIP) != 0);
+ }
+ }
+ }
+
+ if (clip) {
+ view3d_boxview_clip(sa);
+ }
}
/* 'clip' is used to know if our clip setting has changed */
void ED_view3d_quadview_update(ScrArea *sa, ARegion *ar, bool do_clip)
{
- ARegion *ar_sync = NULL;
- RegionView3D *rv3d = ar->regiondata;
- short viewlock;
- /* this function copies flags from the first of the 3 other quadview
- * regions to the 2 other, so it assumes this is the region whose
- * properties are always being edited, weak */
- viewlock = rv3d->viewlock;
-
- if ((viewlock & RV3D_LOCKED) == 0) {
- do_clip = (viewlock & RV3D_BOXCLIP) != 0;
- viewlock = 0;
- }
- else if ((viewlock & RV3D_BOXVIEW) == 0 && (viewlock & RV3D_BOXCLIP) != 0) {
- do_clip = true;
- viewlock &= ~RV3D_BOXCLIP;
- }
-
- for (; ar; ar = ar->prev) {
- if (ar->alignment == RGN_ALIGN_QSPLIT) {
- rv3d = ar->regiondata;
- rv3d->viewlock = viewlock;
-
- if (do_clip && (viewlock & RV3D_BOXCLIP) == 0) {
- rv3d->rflag &= ~RV3D_BOXCLIP;
- }
-
- /* use ar_sync so we sync with one of the aligned views below
- * else the view jumps on changing view settings like 'clip'
- * since it copies from the perspective view */
- ar_sync = ar;
- }
- }
-
- if (rv3d->viewlock & RV3D_BOXVIEW) {
- view3d_boxview_sync(sa, ar_sync ? ar_sync : sa->regionbase.last);
- }
-
- /* ensure locked regions have an axis, locked user views don't make much sense */
- if (viewlock & RV3D_LOCKED) {
- int index_qsplit = 0;
- for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->alignment == RGN_ALIGN_QSPLIT) {
- rv3d = ar->regiondata;
- if (rv3d->viewlock) {
- if (!RV3D_VIEW_IS_AXIS(rv3d->view)) {
- rv3d->view = ED_view3d_lock_view_from_index(index_qsplit);
- rv3d->persp = RV3D_ORTHO;
- ED_view3d_lock(rv3d);
- }
- }
- index_qsplit++;
- }
- }
- }
-
- ED_area_tag_redraw(sa);
+ ARegion *ar_sync = NULL;
+ RegionView3D *rv3d = ar->regiondata;
+ short viewlock;
+ /* this function copies flags from the first of the 3 other quadview
+ * regions to the 2 other, so it assumes this is the region whose
+ * properties are always being edited, weak */
+ viewlock = rv3d->viewlock;
+
+ if ((viewlock & RV3D_LOCKED) == 0) {
+ do_clip = (viewlock & RV3D_BOXCLIP) != 0;
+ viewlock = 0;
+ }
+ else if ((viewlock & RV3D_BOXVIEW) == 0 && (viewlock & RV3D_BOXCLIP) != 0) {
+ do_clip = true;
+ viewlock &= ~RV3D_BOXCLIP;
+ }
+
+ for (; ar; ar = ar->prev) {
+ if (ar->alignment == RGN_ALIGN_QSPLIT) {
+ rv3d = ar->regiondata;
+ rv3d->viewlock = viewlock;
+
+ if (do_clip && (viewlock & RV3D_BOXCLIP) == 0) {
+ rv3d->rflag &= ~RV3D_BOXCLIP;
+ }
+
+ /* use ar_sync so we sync with one of the aligned views below
+ * else the view jumps on changing view settings like 'clip'
+ * since it copies from the perspective view */
+ ar_sync = ar;
+ }
+ }
+
+ if (rv3d->viewlock & RV3D_BOXVIEW) {
+ view3d_boxview_sync(sa, ar_sync ? ar_sync : sa->regionbase.last);
+ }
+
+ /* ensure locked regions have an axis, locked user views don't make much sense */
+ if (viewlock & RV3D_LOCKED) {
+ int index_qsplit = 0;
+ for (ar = sa->regionbase.first; ar; ar = ar->next) {
+ if (ar->alignment == RGN_ALIGN_QSPLIT) {
+ rv3d = ar->regiondata;
+ if (rv3d->viewlock) {
+ if (!RV3D_VIEW_IS_AXIS(rv3d->view)) {
+ rv3d->view = ED_view3d_lock_view_from_index(index_qsplit);
+ rv3d->persp = RV3D_ORTHO;
+ ED_view3d_lock(rv3d);
+ }
+ }
+ index_qsplit++;
+ }
+ }
+ }
+
+ ED_area_tag_redraw(sa);
}
/** \} */
@@ -934,25 +940,25 @@ void ED_view3d_quadview_update(ScrArea *sa, ARegion *ar, bool do_clip)
static float view_autodist_depth_margin(ARegion *ar, const int mval[2], int margin)
{
- ViewDepths depth_temp = {0};
- rcti rect;
- float depth_close;
-
- if (margin == 0) {
- /* Get Z Depths, needed for perspective, nice for ortho */
- rect.xmin = mval[0];
- rect.ymin = mval[1];
- rect.xmax = mval[0] + 1;
- rect.ymax = mval[1] + 1;
- }
- else {
- BLI_rcti_init_pt_radius(&rect, mval, margin);
- }
-
- view3d_update_depths_rect(ar, &depth_temp, &rect);
- depth_close = view3d_depth_near(&depth_temp);
- MEM_SAFE_FREE(depth_temp.depths);
- return depth_close;
+ ViewDepths depth_temp = {0};
+ rcti rect;
+ float depth_close;
+
+ if (margin == 0) {
+ /* Get Z Depths, needed for perspective, nice for ortho */
+ rect.xmin = mval[0];
+ rect.ymin = mval[1];
+ rect.xmax = mval[0] + 1;
+ rect.ymax = mval[1] + 1;
+ }
+ else {
+ BLI_rcti_init_pt_radius(&rect, mval, margin);
+ }
+
+ view3d_update_depths_rect(ar, &depth_temp, &rect);
+ depth_close = view3d_depth_near(&depth_temp);
+ MEM_SAFE_FREE(depth_temp.depths);
+ return depth_close;
}
/**
@@ -962,131 +968,139 @@ static float view_autodist_depth_margin(ARegion *ar, const int mval[2], int marg
* \param mouse_worldloc: Output world-space location.
* \param fallback_depth_pt: Use this points depth when no depth can be found.
*/
-bool ED_view3d_autodist(
- Depsgraph *depsgraph, ARegion *ar, View3D *v3d,
- const int mval[2], float mouse_worldloc[3],
- const bool alphaoverride, const float fallback_depth_pt[3])
+bool ED_view3d_autodist(Depsgraph *depsgraph,
+ ARegion *ar,
+ View3D *v3d,
+ const int mval[2],
+ float mouse_worldloc[3],
+ const bool alphaoverride,
+ const float fallback_depth_pt[3])
{
- float depth_close;
- int margin_arr[] = {0, 2, 4};
- int i;
- bool depth_ok = false;
-
- /* Get Z Depths, needed for perspective, nice for ortho */
- ED_view3d_draw_depth(depsgraph, ar, v3d, alphaoverride);
-
- /* Attempt with low margin's first */
- i = 0;
- do {
- depth_close = view_autodist_depth_margin(ar, mval, margin_arr[i++] * U.pixelsize);
- depth_ok = (depth_close != FLT_MAX);
- } while ((depth_ok == false) && (i < ARRAY_SIZE(margin_arr)));
-
- if (depth_ok) {
- float centx = (float)mval[0] + 0.5f;
- float centy = (float)mval[1] + 0.5f;
-
- if (ED_view3d_unproject(ar, centx, centy, depth_close, mouse_worldloc)) {
- return true;
- }
- }
-
- if (fallback_depth_pt) {
- ED_view3d_win_to_3d_int(v3d, ar, fallback_depth_pt, mval, mouse_worldloc);
- return true;
- }
- else {
- return false;
- }
+ float depth_close;
+ int margin_arr[] = {0, 2, 4};
+ int i;
+ bool depth_ok = false;
+
+ /* Get Z Depths, needed for perspective, nice for ortho */
+ ED_view3d_draw_depth(depsgraph, ar, v3d, alphaoverride);
+
+ /* Attempt with low margin's first */
+ i = 0;
+ do {
+ depth_close = view_autodist_depth_margin(ar, mval, margin_arr[i++] * U.pixelsize);
+ depth_ok = (depth_close != FLT_MAX);
+ } while ((depth_ok == false) && (i < ARRAY_SIZE(margin_arr)));
+
+ if (depth_ok) {
+ float centx = (float)mval[0] + 0.5f;
+ float centy = (float)mval[1] + 0.5f;
+
+ if (ED_view3d_unproject(ar, centx, centy, depth_close, mouse_worldloc)) {
+ return true;
+ }
+ }
+
+ if (fallback_depth_pt) {
+ ED_view3d_win_to_3d_int(v3d, ar, fallback_depth_pt, mval, mouse_worldloc);
+ return true;
+ }
+ else {
+ return false;
+ }
}
-void ED_view3d_autodist_init(Depsgraph *depsgraph,
- ARegion *ar, View3D *v3d, int mode)
+void ED_view3d_autodist_init(Depsgraph *depsgraph, ARegion *ar, View3D *v3d, int mode)
{
- /* Get Z Depths, needed for perspective, nice for ortho */
- switch (mode) {
- case 0:
- ED_view3d_draw_depth(depsgraph, ar, v3d, true);
- break;
- case 1:
- {
- Scene *scene = DEG_get_evaluated_scene(depsgraph);
- ED_view3d_draw_depth_gpencil(depsgraph, scene, ar, v3d);
- break;
- }
- }
+ /* Get Z Depths, needed for perspective, nice for ortho */
+ switch (mode) {
+ case 0:
+ ED_view3d_draw_depth(depsgraph, ar, v3d, true);
+ break;
+ case 1: {
+ Scene *scene = DEG_get_evaluated_scene(depsgraph);
+ ED_view3d_draw_depth_gpencil(depsgraph, scene, ar, v3d);
+ break;
+ }
+ }
}
/* no 4x4 sampling, run #ED_view3d_autodist_init first */
-bool ED_view3d_autodist_simple(ARegion *ar, const int mval[2], float mouse_worldloc[3],
- int margin, float *force_depth)
+bool ED_view3d_autodist_simple(
+ ARegion *ar, const int mval[2], float mouse_worldloc[3], int margin, float *force_depth)
{
- float depth;
-
- /* Get Z Depths, needed for perspective, nice for ortho */
- if (force_depth) {
- depth = *force_depth;
- }
- else {
- depth = view_autodist_depth_margin(ar, mval, margin);
- }
-
- if (depth == FLT_MAX) {
- return false;
- }
-
- float centx = (float)mval[0] + 0.5f;
- float centy = (float)mval[1] + 0.5f;
- return ED_view3d_unproject(ar, centx, centy, depth, mouse_worldloc);
+ float depth;
+
+ /* Get Z Depths, needed for perspective, nice for ortho */
+ if (force_depth) {
+ depth = *force_depth;
+ }
+ else {
+ depth = view_autodist_depth_margin(ar, mval, margin);
+ }
+
+ if (depth == FLT_MAX) {
+ return false;
+ }
+
+ float centx = (float)mval[0] + 0.5f;
+ float centy = (float)mval[1] + 0.5f;
+ return ED_view3d_unproject(ar, centx, centy, depth, mouse_worldloc);
}
bool ED_view3d_autodist_depth(ARegion *ar, const int mval[2], int margin, float *depth)
{
- *depth = view_autodist_depth_margin(ar, mval, margin);
+ *depth = view_autodist_depth_margin(ar, mval, margin);
- return (*depth != FLT_MAX);
+ return (*depth != FLT_MAX);
}
static bool depth_segment_cb(int x, int y, void *userData)
{
- struct { ARegion *ar; int margin; float depth; } *data = userData;
- int mval[2];
- float depth;
-
- mval[0] = x;
- mval[1] = y;
-
- depth = view_autodist_depth_margin(data->ar, mval, data->margin);
-
- if (depth != FLT_MAX) {
- data->depth = depth;
- return 0;
- }
- else {
- return 1;
- }
+ struct {
+ ARegion *ar;
+ int margin;
+ float depth;
+ } *data = userData;
+ int mval[2];
+ float depth;
+
+ mval[0] = x;
+ mval[1] = y;
+
+ depth = view_autodist_depth_margin(data->ar, mval, data->margin);
+
+ if (depth != FLT_MAX) {
+ data->depth = depth;
+ return 0;
+ }
+ else {
+ return 1;
+ }
}
bool ED_view3d_autodist_depth_seg(
- ARegion *ar, const int mval_sta[2], const int mval_end[2],
- int margin, float *depth)
+ ARegion *ar, const int mval_sta[2], const int mval_end[2], int margin, float *depth)
{
- struct { ARegion *ar; int margin; float depth; } data = {NULL};
- int p1[2];
- int p2[2];
+ struct {
+ ARegion *ar;
+ int margin;
+ float depth;
+ } data = {NULL};
+ int p1[2];
+ int p2[2];
- data.ar = ar;
- data.margin = margin;
- data.depth = FLT_MAX;
+ data.ar = ar;
+ data.margin = margin;
+ data.depth = FLT_MAX;
- copy_v2_v2_int(p1, mval_sta);
- copy_v2_v2_int(p2, mval_end);
+ copy_v2_v2_int(p1, mval_sta);
+ copy_v2_v2_int(p2, mval_end);
- BLI_bitmap_draw_2d_line_v2v2i(p1, p2, depth_segment_cb, &data);
+ BLI_bitmap_draw_2d_line_v2v2i(p1, p2, depth_segment_cb, &data);
- *depth = data.depth;
+ *depth = data.depth;
- return (*depth != FLT_MAX);
+ return (*depth != FLT_MAX);
}
/** \} */
@@ -1099,12 +1113,12 @@ bool ED_view3d_autodist_depth_seg(
float ED_view3d_radius_to_dist_persp(const float angle, const float radius)
{
- return radius * (1.0f / tanf(angle / 2.0f));
+ return radius * (1.0f / tanf(angle / 2.0f));
}
float ED_view3d_radius_to_dist_ortho(const float lens, const float radius)
{
- return radius / (DEFAULT_SENSOR_WIDTH / lens);
+ return radius / (DEFAULT_SENSOR_WIDTH / lens);
}
/**
@@ -1131,78 +1145,79 @@ float ED_view3d_radius_to_dist_ortho(const float lens, const float radius)
* \param use_aspect: Increase the distance to account for non 1:1 view aspect.
* \param radius: The radius will be fitted exactly, typically pre-scaled by a margin (#VIEW3D_MARGIN).
*/
-float ED_view3d_radius_to_dist(
- const View3D *v3d, const ARegion *ar,
- const struct Depsgraph *depsgraph,
- const char persp, const bool use_aspect,
- const float radius)
+float ED_view3d_radius_to_dist(const View3D *v3d,
+ const ARegion *ar,
+ const struct Depsgraph *depsgraph,
+ const char persp,
+ const bool use_aspect,
+ const float radius)
{
- float dist;
-
- BLI_assert(ELEM(persp, RV3D_ORTHO, RV3D_PERSP, RV3D_CAMOB));
- BLI_assert((persp != RV3D_CAMOB) || v3d->camera);
-
- if (persp == RV3D_ORTHO) {
- dist = ED_view3d_radius_to_dist_ortho(v3d->lens, radius);
- }
- else {
- float lens, sensor_size, zoom;
- float angle;
-
- if (persp == RV3D_CAMOB) {
- CameraParams params;
- BKE_camera_params_init(&params);
- params.clip_start = v3d->clip_start;
- params.clip_end = v3d->clip_end;
- Object *camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera);
- BKE_camera_params_from_object(&params, camera_eval);
-
- lens = params.lens;
- sensor_size = BKE_camera_sensor_size(params.sensor_fit, params.sensor_x, params.sensor_y);
-
- /* ignore 'rv3d->camzoom' because we want to fit to the cameras frame */
- zoom = CAMERA_PARAM_ZOOM_INIT_CAMOB;
- }
- else {
- lens = v3d->lens;
- sensor_size = DEFAULT_SENSOR_WIDTH;
- zoom = CAMERA_PARAM_ZOOM_INIT_PERSP;
- }
-
- angle = focallength_to_fov(lens, sensor_size);
-
- /* zoom influences lens, correct this by scaling the angle as a distance
- * (by the zoom-level) */
- angle = atanf(tanf(angle / 2.0f) * zoom) * 2.0f;
-
- dist = ED_view3d_radius_to_dist_persp(angle, radius);
- }
-
- if (use_aspect) {
- const RegionView3D *rv3d = ar->regiondata;
-
- float winx, winy;
-
- if (persp == RV3D_CAMOB) {
- /* camera frame x/y in pixels */
- winx = ar->winx / rv3d->viewcamtexcofac[0];
- winy = ar->winy / rv3d->viewcamtexcofac[1];
- }
- else {
- winx = ar->winx;
- winy = ar->winy;
- }
-
- if (winx && winy) {
- float aspect = winx / winy;
- if (aspect < 1.0f) {
- aspect = 1.0f / aspect;
- }
- dist *= aspect;
- }
- }
-
- return dist;
+ float dist;
+
+ BLI_assert(ELEM(persp, RV3D_ORTHO, RV3D_PERSP, RV3D_CAMOB));
+ BLI_assert((persp != RV3D_CAMOB) || v3d->camera);
+
+ if (persp == RV3D_ORTHO) {
+ dist = ED_view3d_radius_to_dist_ortho(v3d->lens, radius);
+ }
+ else {
+ float lens, sensor_size, zoom;
+ float angle;
+
+ if (persp == RV3D_CAMOB) {
+ CameraParams params;
+ BKE_camera_params_init(&params);
+ params.clip_start = v3d->clip_start;
+ params.clip_end = v3d->clip_end;
+ Object *camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera);
+ BKE_camera_params_from_object(&params, camera_eval);
+
+ lens = params.lens;
+ sensor_size = BKE_camera_sensor_size(params.sensor_fit, params.sensor_x, params.sensor_y);
+
+ /* ignore 'rv3d->camzoom' because we want to fit to the cameras frame */
+ zoom = CAMERA_PARAM_ZOOM_INIT_CAMOB;
+ }
+ else {
+ lens = v3d->lens;
+ sensor_size = DEFAULT_SENSOR_WIDTH;
+ zoom = CAMERA_PARAM_ZOOM_INIT_PERSP;
+ }
+
+ angle = focallength_to_fov(lens, sensor_size);
+
+ /* zoom influences lens, correct this by scaling the angle as a distance
+ * (by the zoom-level) */
+ angle = atanf(tanf(angle / 2.0f) * zoom) * 2.0f;
+
+ dist = ED_view3d_radius_to_dist_persp(angle, radius);
+ }
+
+ if (use_aspect) {
+ const RegionView3D *rv3d = ar->regiondata;
+
+ float winx, winy;
+
+ if (persp == RV3D_CAMOB) {
+ /* camera frame x/y in pixels */
+ winx = ar->winx / rv3d->viewcamtexcofac[0];
+ winy = ar->winy / rv3d->viewcamtexcofac[1];
+ }
+ else {
+ winx = ar->winx;
+ winy = ar->winy;
+ }
+
+ if (winx && winy) {
+ float aspect = winx / winy;
+ if (aspect < 1.0f) {
+ aspect = 1.0f / aspect;
+ }
+ dist *= aspect;
+ }
+ }
+
+ return dist;
}
/** \} */
@@ -1217,22 +1232,22 @@ float ED_view3d_radius_to_dist(
*/
float ED_view3d_offset_distance(float mat[4][4], const float ofs[3], const float fallback_dist)
{
- float pos[4] = {0.0f, 0.0f, 0.0f, 1.0f};
- float dir[4] = {0.0f, 0.0f, 1.0f, 0.0f};
- float dist;
+ float pos[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+ float dir[4] = {0.0f, 0.0f, 1.0f, 0.0f};
+ float dist;
- mul_m4_v4(mat, pos);
- add_v3_v3(pos, ofs);
- mul_m4_v4(mat, dir);
- normalize_v3(dir);
+ mul_m4_v4(mat, pos);
+ add_v3_v3(pos, ofs);
+ mul_m4_v4(mat, dir);
+ normalize_v3(dir);
- dist = dot_v3v3(pos, dir);
+ dist = dot_v3v3(pos, dir);
- if ((dist < FLT_EPSILON) && (fallback_dist != 0.0f)) {
- dist = fallback_dist;
- }
+ if ((dist < FLT_EPSILON) && (fallback_dist != 0.0f)) {
+ dist = fallback_dist;
+ }
- return dist;
+ return dist;
}
/**
@@ -1242,22 +1257,22 @@ float ED_view3d_offset_distance(float mat[4][4], const float ofs[3], const float
*/
void ED_view3d_distance_set(RegionView3D *rv3d, const float dist)
{
- float viewinv[4];
- float tvec[3];
+ float viewinv[4];
+ float tvec[3];
- BLI_assert(dist >= 0.0f);
+ BLI_assert(dist >= 0.0f);
- copy_v3_fl3(tvec, 0.0f, 0.0f, rv3d->dist - dist);
- /* rv3d->viewinv isn't always valid */
+ copy_v3_fl3(tvec, 0.0f, 0.0f, rv3d->dist - dist);
+ /* rv3d->viewinv isn't always valid */
#if 0
- mul_mat3_m4_v3(rv3d->viewinv, tvec);
+ mul_mat3_m4_v3(rv3d->viewinv, tvec);
#else
- invert_qt_qt_normalized(viewinv, rv3d->viewquat);
- mul_qt_v3(viewinv, tvec);
+ invert_qt_qt_normalized(viewinv, rv3d->viewquat);
+ mul_qt_v3(viewinv, tvec);
#endif
- sub_v3_v3(rv3d->ofs, tvec);
+ sub_v3_v3(rv3d->ofs, tvec);
- rv3d->dist = dist;
+ rv3d->dist = dist;
}
/** \} */
@@ -1266,70 +1281,77 @@ void ED_view3d_distance_set(RegionView3D *rv3d, const float dist)
/** \name View Axis Utilities
* \{ */
static float view3d_quat_axis[6][4] = {
- {M_SQRT1_2, -M_SQRT1_2, 0.0f, 0.0f}, /* RV3D_VIEW_FRONT */
- {0.0f, 0.0f, -M_SQRT1_2, -M_SQRT1_2}, /* RV3D_VIEW_BACK */
- {0.5f, -0.5f, 0.5f, 0.5f}, /* RV3D_VIEW_LEFT */
- {0.5f, -0.5f, -0.5f, -0.5f}, /* RV3D_VIEW_RIGHT */
- {1.0f, 0.0f, 0.0f, 0.0f}, /* RV3D_VIEW_TOP */
- {0.0f, -1.0f, 0.0f, 0.0f}, /* RV3D_VIEW_BOTTOM */
+ {M_SQRT1_2, -M_SQRT1_2, 0.0f, 0.0f}, /* RV3D_VIEW_FRONT */
+ {0.0f, 0.0f, -M_SQRT1_2, -M_SQRT1_2}, /* RV3D_VIEW_BACK */
+ {0.5f, -0.5f, 0.5f, 0.5f}, /* RV3D_VIEW_LEFT */
+ {0.5f, -0.5f, -0.5f, -0.5f}, /* RV3D_VIEW_RIGHT */
+ {1.0f, 0.0f, 0.0f, 0.0f}, /* RV3D_VIEW_TOP */
+ {0.0f, -1.0f, 0.0f, 0.0f}, /* RV3D_VIEW_BOTTOM */
};
-
bool ED_view3d_quat_from_axis_view(const char view, float quat[4])
{
- if (RV3D_VIEW_IS_AXIS(view)) {
- copy_qt_qt(quat, view3d_quat_axis[view - RV3D_VIEW_FRONT]);
- return true;
- }
- else {
- return false;
- }
+ if (RV3D_VIEW_IS_AXIS(view)) {
+ copy_qt_qt(quat, view3d_quat_axis[view - RV3D_VIEW_FRONT]);
+ return true;
+ }
+ else {
+ return false;
+ }
}
char ED_view3d_quat_to_axis_view(const float quat[4], const float epsilon)
{
- /* quat values are all unit length */
+ /* quat values are all unit length */
- char view;
+ char view;
- for (view = RV3D_VIEW_FRONT; view <= RV3D_VIEW_BOTTOM; view++) {
- if (fabsf(angle_signed_qtqt(quat, view3d_quat_axis[view - RV3D_VIEW_FRONT])) < epsilon) {
- return view;
- }
- }
+ for (view = RV3D_VIEW_FRONT; view <= RV3D_VIEW_BOTTOM; view++) {
+ if (fabsf(angle_signed_qtqt(quat, view3d_quat_axis[view - RV3D_VIEW_FRONT])) < epsilon) {
+ return view;
+ }
+ }
- return RV3D_VIEW_USER;
+ return RV3D_VIEW_USER;
}
char ED_view3d_lock_view_from_index(int index)
{
- switch (index) {
- case 0: return RV3D_VIEW_FRONT;
- case 1: return RV3D_VIEW_TOP;
- case 2: return RV3D_VIEW_RIGHT;
- default: return RV3D_VIEW_USER;
- }
-
+ switch (index) {
+ case 0:
+ return RV3D_VIEW_FRONT;
+ case 1:
+ return RV3D_VIEW_TOP;
+ case 2:
+ return RV3D_VIEW_RIGHT;
+ default:
+ return RV3D_VIEW_USER;
+ }
}
char ED_view3d_axis_view_opposite(char view)
{
- switch (view) {
- case RV3D_VIEW_FRONT: return RV3D_VIEW_BACK;
- case RV3D_VIEW_BACK: return RV3D_VIEW_FRONT;
- case RV3D_VIEW_LEFT: return RV3D_VIEW_RIGHT;
- case RV3D_VIEW_RIGHT: return RV3D_VIEW_LEFT;
- case RV3D_VIEW_TOP: return RV3D_VIEW_BOTTOM;
- case RV3D_VIEW_BOTTOM: return RV3D_VIEW_TOP;
- }
-
- return RV3D_VIEW_USER;
+ switch (view) {
+ case RV3D_VIEW_FRONT:
+ return RV3D_VIEW_BACK;
+ case RV3D_VIEW_BACK:
+ return RV3D_VIEW_FRONT;
+ case RV3D_VIEW_LEFT:
+ return RV3D_VIEW_RIGHT;
+ case RV3D_VIEW_RIGHT:
+ return RV3D_VIEW_LEFT;
+ case RV3D_VIEW_TOP:
+ return RV3D_VIEW_BOTTOM;
+ case RV3D_VIEW_BOTTOM:
+ return RV3D_VIEW_TOP;
+ }
+
+ return RV3D_VIEW_USER;
}
-
bool ED_view3d_lock(RegionView3D *rv3d)
{
- return ED_view3d_quat_from_axis_view(rv3d->view, rv3d->viewquat);
+ return ED_view3d_quat_from_axis_view(rv3d->view, rv3d->viewquat);
}
/** \} */
@@ -1348,28 +1370,28 @@ bool ED_view3d_lock(RegionView3D *rv3d)
*/
void ED_view3d_from_m4(const float mat[4][4], float ofs[3], float quat[4], float *dist)
{
- float nmat[3][3];
+ float nmat[3][3];
- /* dist depends on offset */
- BLI_assert(dist == NULL || ofs != NULL);
+ /* dist depends on offset */
+ BLI_assert(dist == NULL || ofs != NULL);
- copy_m3_m4(nmat, mat);
- normalize_m3(nmat);
+ copy_m3_m4(nmat, mat);
+ normalize_m3(nmat);
- /* Offset */
- if (ofs) {
- negate_v3_v3(ofs, mat[3]);
- }
+ /* Offset */
+ if (ofs) {
+ negate_v3_v3(ofs, mat[3]);
+ }
- /* Quat */
- if (quat) {
- mat3_normalized_to_quat(quat, nmat);
- invert_qt_normalized(quat);
- }
+ /* Quat */
+ if (quat) {
+ mat3_normalized_to_quat(quat, nmat);
+ invert_qt_normalized(quat);
+ }
- if (ofs && dist) {
- madd_v3_v3fl(ofs, nmat[2], *dist);
- }
+ if (ofs && dist) {
+ madd_v3_v3fl(ofs, nmat[2], *dist);
+ }
}
/**
@@ -1382,12 +1404,12 @@ void ED_view3d_from_m4(const float mat[4][4], float ofs[3], float quat[4], float
*/
void ED_view3d_to_m4(float mat[4][4], const float ofs[3], const float quat[4], const float dist)
{
- float iviewquat[4] = {-quat[0], quat[1], quat[2], quat[3]};
- float dvec[3] = {0.0f, 0.0f, dist};
+ float iviewquat[4] = {-quat[0], quat[1], quat[2], quat[3]};
+ float dvec[3] = {0.0f, 0.0f, dist};
- quat_to_mat4(mat, iviewquat);
- mul_mat3_m4_v3(mat, dvec);
- sub_v3_v3v3(mat[3], dvec, ofs);
+ quat_to_mat4(mat, iviewquat);
+ mul_mat3_m4_v3(mat, dvec);
+ sub_v3_v3v3(mat[3], dvec, ofs);
}
/**
@@ -1400,15 +1422,15 @@ void ED_view3d_to_m4(float mat[4][4], const float ofs[3], const float quat[4], c
*/
void ED_view3d_from_object(const Object *ob, float ofs[3], float quat[4], float *dist, float *lens)
{
- ED_view3d_from_m4(ob->obmat, ofs, quat, dist);
+ ED_view3d_from_m4(ob->obmat, ofs, quat, dist);
- if (lens) {
- CameraParams params;
+ if (lens) {
+ CameraParams params;
- BKE_camera_params_init(&params);
- BKE_camera_params_from_object(&params, ob);
- *lens = params.lens;
- }
+ BKE_camera_params_init(&params);
+ BKE_camera_params_from_object(&params, ob);
+ *lens = params.lens;
+ }
}
/**
@@ -1419,13 +1441,17 @@ void ED_view3d_from_object(const Object *ob, float ofs[3], float quat[4], float
* \param quat: The view rotation, quaternion normally from RegionView3D.viewquat.
* \param dist: The view distance from ofs, normally from RegionView3D.dist.
*/
-void ED_view3d_to_object(const Depsgraph *depsgraph, Object *ob, const float ofs[3], const float quat[4], const float dist)
+void ED_view3d_to_object(const Depsgraph *depsgraph,
+ Object *ob,
+ const float ofs[3],
+ const float quat[4],
+ const float dist)
{
- float mat[4][4];
- ED_view3d_to_m4(mat, ofs, quat, dist);
+ float mat[4][4];
+ ED_view3d_to_m4(mat, ofs, quat, dist);
- Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
- BKE_object_apply_mat4_ex(ob, mat, ob_eval->parent, ob_eval->parentinv, true);
+ Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
+ BKE_object_apply_mat4_ex(ob, mat, ob_eval->parent, ob_eval->parentinv, true);
}
/** \} */
@@ -1436,96 +1462,92 @@ void ED_view3d_to_object(const Depsgraph *depsgraph, Object *ob, const float ofs
float ED_view3d_depth_read_cached(const ViewContext *vc, const int mval[2])
{
- ViewDepths *vd = vc->rv3d->depths;
-
- int x = mval[0];
- int y = mval[1];
-
- if (vd && vd->depths && x > 0 && y > 0 && x < vd->w && y < vd->h) {
- return vd->depths[y * vd->w + x];
- }
- else {
- BLI_assert(1.0 <= vd->depth_range[1]);
- return 1.0f;
- }
+ ViewDepths *vd = vc->rv3d->depths;
+
+ int x = mval[0];
+ int y = mval[1];
+
+ if (vd && vd->depths && x > 0 && y > 0 && x < vd->w && y < vd->h) {
+ return vd->depths[y * vd->w + x];
+ }
+ else {
+ BLI_assert(1.0 <= vd->depth_range[1]);
+ return 1.0f;
+ }
}
-bool ED_view3d_depth_read_cached_normal(
- const ViewContext *vc, const int mval[2],
- float r_normal[3])
+bool ED_view3d_depth_read_cached_normal(const ViewContext *vc,
+ const int mval[2],
+ float r_normal[3])
{
- /* Note: we could support passing in a radius.
- * For now just read 9 pixels. */
-
- /* pixels surrounding */
- bool depths_valid[9] = {false};
- float coords[9][3] = {{0}};
-
- ARegion *ar = vc->ar;
- const ViewDepths *depths = vc->rv3d->depths;
-
- for (int x = 0, i = 0; x < 2; x++) {
- for (int y = 0; y < 2; y++) {
- const int mval_ofs[2] = {mval[0] + (x - 1), mval[1] + (y - 1)};
-
- const double depth = (double)ED_view3d_depth_read_cached(vc, mval_ofs);
- if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) {
- if (ED_view3d_depth_unproject(ar, mval_ofs, depth, coords[i])) {
- depths_valid[i] = true;
- }
- }
- i++;
- }
- }
-
- const int edges[2][6][2] = {
- /* x edges */
- {{0, 1}, {1, 2},
- {3, 4}, {4, 5},
- {6, 7}, {7, 8}},
- /* y edges */
- {{0, 3}, {3, 6},
- {1, 4}, {4, 7},
- {2, 5}, {5, 8}},
- };
-
- float cross[2][3] = {{0.0f}};
-
- for (int i = 0; i < 6; i++) {
- for (int axis = 0; axis < 2; axis++) {
- if (depths_valid[edges[axis][i][0]] && depths_valid[edges[axis][i][1]]) {
- float delta[3];
- sub_v3_v3v3(delta, coords[edges[axis][i][0]], coords[edges[axis][i][1]]);
- add_v3_v3(cross[axis], delta);
- }
- }
- }
-
- cross_v3_v3v3(r_normal, cross[0], cross[1]);
-
- if (normalize_v3(r_normal) != 0.0f) {
- return true;
- }
- else {
- return false;
- }
+ /* Note: we could support passing in a radius.
+ * For now just read 9 pixels. */
+
+ /* pixels surrounding */
+ bool depths_valid[9] = {false};
+ float coords[9][3] = {{0}};
+
+ ARegion *ar = vc->ar;
+ const ViewDepths *depths = vc->rv3d->depths;
+
+ for (int x = 0, i = 0; x < 2; x++) {
+ for (int y = 0; y < 2; y++) {
+ const int mval_ofs[2] = {mval[0] + (x - 1), mval[1] + (y - 1)};
+
+ const double depth = (double)ED_view3d_depth_read_cached(vc, mval_ofs);
+ if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) {
+ if (ED_view3d_depth_unproject(ar, mval_ofs, depth, coords[i])) {
+ depths_valid[i] = true;
+ }
+ }
+ i++;
+ }
+ }
+
+ const int edges[2][6][2] = {
+ /* x edges */
+ {{0, 1}, {1, 2}, {3, 4}, {4, 5}, {6, 7}, {7, 8}},
+ /* y edges */
+ {{0, 3}, {3, 6}, {1, 4}, {4, 7}, {2, 5}, {5, 8}},
+ };
+
+ float cross[2][3] = {{0.0f}};
+
+ for (int i = 0; i < 6; i++) {
+ for (int axis = 0; axis < 2; axis++) {
+ if (depths_valid[edges[axis][i][0]] && depths_valid[edges[axis][i][1]]) {
+ float delta[3];
+ sub_v3_v3v3(delta, coords[edges[axis][i][0]], coords[edges[axis][i][1]]);
+ add_v3_v3(cross[axis], delta);
+ }
+ }
+ }
+
+ cross_v3_v3v3(r_normal, cross[0], cross[1]);
+
+ if (normalize_v3(r_normal) != 0.0f) {
+ return true;
+ }
+ else {
+ return false;
+ }
}
-bool ED_view3d_depth_unproject(
- const ARegion *ar,
- const int mval[2], const double depth,
- float r_location_world[3])
+bool ED_view3d_depth_unproject(const ARegion *ar,
+ const int mval[2],
+ const double depth,
+ float r_location_world[3])
{
- float centx = (float)mval[0] + 0.5f;
- float centy = (float)mval[1] + 0.5f;
- return ED_view3d_unproject(ar, centx, centy, depth, r_location_world);
+ float centx = (float)mval[0] + 0.5f;
+ float centy = (float)mval[1] + 0.5f;
+ return ED_view3d_unproject(ar, centx, centy, depth, r_location_world);
}
void ED_view3d_depth_tag_update(RegionView3D *rv3d)
{
- if (rv3d->depths) {
- rv3d->depths->damaged = true;
- }
+ if (rv3d->depths) {
+ rv3d->depths->damaged = true;
+ }
}
/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 4e5dddf4742..e313ed39c49 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -62,7 +62,7 @@
#include "RNA_access.h"
#include "RNA_define.h"
-#include "view3d_intern.h" /* own include */
+#include "view3d_intern.h" /* own include */
/* -------------------------------------------------------------------- */
/** \name Smooth View Operator & Utilities
@@ -73,371 +73,378 @@
/* This operator is one of the 'timer refresh' ones like animation playback */
struct SmoothView3DState {
- float dist;
- float lens;
- float quat[4];
- float ofs[3];
+ float dist;
+ float lens;
+ float quat[4];
+ float ofs[3];
};
struct SmoothView3DStore {
- /* source*/
- struct SmoothView3DState src; /* source */
- struct SmoothView3DState dst; /* destination */
- struct SmoothView3DState org; /* original */
+ /* source*/
+ struct SmoothView3DState src; /* source */
+ struct SmoothView3DState dst; /* destination */
+ struct SmoothView3DState org; /* original */
- bool to_camera;
+ bool to_camera;
- bool use_dyn_ofs;
- float dyn_ofs[3];
+ bool use_dyn_ofs;
+ float dyn_ofs[3];
- /* When smooth-view is enabled, store the 'rv3d->view' here,
- * assign back when the view motion is completed. */
- char org_view;
+ /* When smooth-view is enabled, store the 'rv3d->view' here,
+ * assign back when the view motion is completed. */
+ char org_view;
- double time_allowed;
+ double time_allowed;
};
static void view3d_smooth_view_state_backup(struct SmoothView3DState *sms_state,
- const View3D *v3d, const RegionView3D *rv3d)
+ const View3D *v3d,
+ const RegionView3D *rv3d)
{
- copy_v3_v3(sms_state->ofs, rv3d->ofs);
- copy_qt_qt(sms_state->quat, rv3d->viewquat);
- sms_state->dist = rv3d->dist;
- sms_state->lens = v3d->lens;
+ copy_v3_v3(sms_state->ofs, rv3d->ofs);
+ copy_qt_qt(sms_state->quat, rv3d->viewquat);
+ sms_state->dist = rv3d->dist;
+ sms_state->lens = v3d->lens;
}
static void view3d_smooth_view_state_restore(const struct SmoothView3DState *sms_state,
- View3D *v3d, RegionView3D *rv3d)
+ View3D *v3d,
+ RegionView3D *rv3d)
{
- copy_v3_v3(rv3d->ofs, sms_state->ofs);
- copy_qt_qt(rv3d->viewquat, sms_state->quat);
- rv3d->dist = sms_state->dist;
- v3d->lens = sms_state->lens;
+ copy_v3_v3(rv3d->ofs, sms_state->ofs);
+ copy_qt_qt(rv3d->viewquat, sms_state->quat);
+ rv3d->dist = sms_state->dist;
+ v3d->lens = sms_state->lens;
}
/* will start timer if appropriate */
/* the arguments are the desired situation */
void ED_view3d_smooth_view_ex(
- /* avoid passing in the context */
- const Depsgraph *depsgraph, wmWindowManager *wm, wmWindow *win, ScrArea *sa,
- View3D *v3d, ARegion *ar, const int smooth_viewtx,
- const V3D_SmoothParams *sview)
+ /* avoid passing in the context */
+ const Depsgraph *depsgraph,
+ wmWindowManager *wm,
+ wmWindow *win,
+ ScrArea *sa,
+ View3D *v3d,
+ ARegion *ar,
+ const int smooth_viewtx,
+ const V3D_SmoothParams *sview)
{
- RegionView3D *rv3d = ar->regiondata;
- struct SmoothView3DStore sms = {{0}};
- bool ok = false;
-
- /* initialize sms */
- view3d_smooth_view_state_backup(&sms.dst, v3d, rv3d);
- view3d_smooth_view_state_backup(&sms.src, v3d, rv3d);
- /* if smoothview runs multiple times... */
- if (rv3d->sms == NULL) {
- view3d_smooth_view_state_backup(&sms.org, v3d, rv3d);
- }
- else {
- sms.org = rv3d->sms->org;
- }
- sms.org_view = rv3d->view;
-
- /* sms.to_camera = false; */ /* initizlized to zero anyway */
-
- /* note on camera locking, this is a little confusing but works ok.
- * we may be changing the view 'as if' there is no active camera, but in fact
- * there is an active camera which is locked to the view.
- *
- * In the case where smooth view is moving _to_ a camera we don't want that
- * camera to be moved or changed, so only when the camera is not being set should
- * we allow camera option locking to initialize the view settings from the camera.
- */
- if (sview->camera == NULL && sview->camera_old == NULL) {
- ED_view3d_camera_lock_init(depsgraph, v3d, rv3d);
- }
-
- /* store the options we want to end with */
- if (sview->ofs) {
- copy_v3_v3(sms.dst.ofs, sview->ofs);
- }
- if (sview->quat) {
- copy_qt_qt(sms.dst.quat, sview->quat);
- }
- if (sview->dist) {
- sms.dst.dist = *sview->dist;
- }
- if (sview->lens) {
- sms.dst.lens = *sview->lens;
- }
-
- if (sview->dyn_ofs) {
- BLI_assert(sview->ofs == NULL);
- BLI_assert(sview->quat != NULL);
-
- copy_v3_v3(sms.dyn_ofs, sview->dyn_ofs);
- sms.use_dyn_ofs = true;
-
- /* calculate the final destination offset */
- view3d_orbit_apply_dyn_ofs(sms.dst.ofs, sms.src.ofs, sms.src.quat, sms.dst.quat, sms.dyn_ofs);
- }
-
- if (sview->camera) {
- Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, sview->camera);
- sms.dst.dist = ED_view3d_offset_distance(ob_camera_eval->obmat, sview->ofs, VIEW3D_DIST_FALLBACK);
- ED_view3d_from_object(ob_camera_eval, sms.dst.ofs, sms.dst.quat, &sms.dst.dist, &sms.dst.lens);
- sms.to_camera = true; /* restore view3d values in end */
- }
-
- /* skip smooth viewing for render engine draw */
- if (smooth_viewtx && v3d->shading.type != OB_RENDER) {
- bool changed = false; /* zero means no difference */
-
- if (sview->camera_old != sview->camera) {
- changed = true;
- }
- else if (sms.dst.dist != rv3d->dist) {
- changed = true;
- }
- else if (sms.dst.lens != v3d->lens) {
- changed = true;
- }
- else if (!equals_v3v3(sms.dst.ofs, rv3d->ofs)) {
- changed = true;
- }
- else if (!equals_v4v4(sms.dst.quat, rv3d->viewquat)) {
- changed = true;
- }
-
- /* The new view is different from the old one
- * so animate the view */
- if (changed) {
- /* original values */
- if (sview->camera_old) {
- Object *ob_camera_old_eval = DEG_get_evaluated_object(depsgraph, sview->camera_old);
- sms.src.dist = ED_view3d_offset_distance(ob_camera_old_eval->obmat, rv3d->ofs, 0.0f);
- /* this */
- ED_view3d_from_object(ob_camera_old_eval, sms.src.ofs, sms.src.quat, &sms.src.dist, &sms.src.lens);
- }
- /* grid draw as floor */
- if ((rv3d->viewlock & RV3D_LOCKED) == 0) {
- /* use existing if exists, means multiple calls to smooth view
- * wont loose the original 'view' setting */
- rv3d->view = RV3D_VIEW_USER;
- }
-
- sms.time_allowed = (double)smooth_viewtx / 1000.0;
-
- /* if this is view rotation only
- * we can decrease the time allowed by
- * the angle between quats
- * this means small rotations wont lag */
- if (sview->quat && !sview->ofs && !sview->dist) {
- /* scale the time allowed by the rotation */
- /* 180deg == 1.0 */
- sms.time_allowed *= (double)fabsf(angle_signed_normalized_qtqt(sms.dst.quat, sms.src.quat)) / M_PI;
- }
-
- /* ensure it shows correct */
- if (sms.to_camera) {
- /* use ortho if we move from an ortho view to an ortho camera */
- Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, sview->camera);
- rv3d->persp = (((rv3d->is_persp == false) &&
- (ob_camera_eval->type == OB_CAMERA) &&
- (((Camera *)ob_camera_eval->data)->type == CAM_ORTHO)) ?
- RV3D_ORTHO : RV3D_PERSP);
- }
-
- rv3d->rflag |= RV3D_NAVIGATING;
-
- /* not essential but in some cases the caller will tag the area for redraw, and in that
- * case we can get a flicker of the 'org' user view but we want to see 'src' */
- view3d_smooth_view_state_restore(&sms.src, v3d, rv3d);
-
- /* keep track of running timer! */
- if (rv3d->sms == NULL) {
- rv3d->sms = MEM_mallocN(sizeof(struct SmoothView3DStore), "smoothview v3d");
- }
- *rv3d->sms = sms;
- if (rv3d->smooth_timer) {
- WM_event_remove_timer(wm, win, rv3d->smooth_timer);
- }
- /* TIMER1 is hardcoded in keymap */
- /* max 30 frs/sec */
- rv3d->smooth_timer = WM_event_add_timer(wm, win, TIMER1, 1.0 / 100.0);
-
- ok = true;
- }
- }
-
- /* if we get here nothing happens */
- if (ok == false) {
- if (sms.to_camera == false) {
- copy_v3_v3(rv3d->ofs, sms.dst.ofs);
- copy_qt_qt(rv3d->viewquat, sms.dst.quat);
- rv3d->dist = sms.dst.dist;
- v3d->lens = sms.dst.lens;
-
- ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
- }
-
- if (rv3d->viewlock & RV3D_BOXVIEW) {
- view3d_boxview_copy(sa, ar);
- }
-
- ED_region_tag_redraw(ar);
- }
+ RegionView3D *rv3d = ar->regiondata;
+ struct SmoothView3DStore sms = {{0}};
+ bool ok = false;
+
+ /* initialize sms */
+ view3d_smooth_view_state_backup(&sms.dst, v3d, rv3d);
+ view3d_smooth_view_state_backup(&sms.src, v3d, rv3d);
+ /* if smoothview runs multiple times... */
+ if (rv3d->sms == NULL) {
+ view3d_smooth_view_state_backup(&sms.org, v3d, rv3d);
+ }
+ else {
+ sms.org = rv3d->sms->org;
+ }
+ sms.org_view = rv3d->view;
+
+ /* sms.to_camera = false; */ /* initizlized to zero anyway */
+
+ /* note on camera locking, this is a little confusing but works ok.
+ * we may be changing the view 'as if' there is no active camera, but in fact
+ * there is an active camera which is locked to the view.
+ *
+ * In the case where smooth view is moving _to_ a camera we don't want that
+ * camera to be moved or changed, so only when the camera is not being set should
+ * we allow camera option locking to initialize the view settings from the camera.
+ */
+ if (sview->camera == NULL && sview->camera_old == NULL) {
+ ED_view3d_camera_lock_init(depsgraph, v3d, rv3d);
+ }
+
+ /* store the options we want to end with */
+ if (sview->ofs) {
+ copy_v3_v3(sms.dst.ofs, sview->ofs);
+ }
+ if (sview->quat) {
+ copy_qt_qt(sms.dst.quat, sview->quat);
+ }
+ if (sview->dist) {
+ sms.dst.dist = *sview->dist;
+ }
+ if (sview->lens) {
+ sms.dst.lens = *sview->lens;
+ }
+
+ if (sview->dyn_ofs) {
+ BLI_assert(sview->ofs == NULL);
+ BLI_assert(sview->quat != NULL);
+
+ copy_v3_v3(sms.dyn_ofs, sview->dyn_ofs);
+ sms.use_dyn_ofs = true;
+
+ /* calculate the final destination offset */
+ view3d_orbit_apply_dyn_ofs(sms.dst.ofs, sms.src.ofs, sms.src.quat, sms.dst.quat, sms.dyn_ofs);
+ }
+
+ if (sview->camera) {
+ Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, sview->camera);
+ sms.dst.dist = ED_view3d_offset_distance(
+ ob_camera_eval->obmat, sview->ofs, VIEW3D_DIST_FALLBACK);
+ ED_view3d_from_object(ob_camera_eval, sms.dst.ofs, sms.dst.quat, &sms.dst.dist, &sms.dst.lens);
+ sms.to_camera = true; /* restore view3d values in end */
+ }
+
+ /* skip smooth viewing for render engine draw */
+ if (smooth_viewtx && v3d->shading.type != OB_RENDER) {
+ bool changed = false; /* zero means no difference */
+
+ if (sview->camera_old != sview->camera) {
+ changed = true;
+ }
+ else if (sms.dst.dist != rv3d->dist) {
+ changed = true;
+ }
+ else if (sms.dst.lens != v3d->lens) {
+ changed = true;
+ }
+ else if (!equals_v3v3(sms.dst.ofs, rv3d->ofs)) {
+ changed = true;
+ }
+ else if (!equals_v4v4(sms.dst.quat, rv3d->viewquat)) {
+ changed = true;
+ }
+
+ /* The new view is different from the old one
+ * so animate the view */
+ if (changed) {
+ /* original values */
+ if (sview->camera_old) {
+ Object *ob_camera_old_eval = DEG_get_evaluated_object(depsgraph, sview->camera_old);
+ sms.src.dist = ED_view3d_offset_distance(ob_camera_old_eval->obmat, rv3d->ofs, 0.0f);
+ /* this */
+ ED_view3d_from_object(
+ ob_camera_old_eval, sms.src.ofs, sms.src.quat, &sms.src.dist, &sms.src.lens);
+ }
+ /* grid draw as floor */
+ if ((rv3d->viewlock & RV3D_LOCKED) == 0) {
+ /* use existing if exists, means multiple calls to smooth view
+ * wont loose the original 'view' setting */
+ rv3d->view = RV3D_VIEW_USER;
+ }
+
+ sms.time_allowed = (double)smooth_viewtx / 1000.0;
+
+ /* if this is view rotation only
+ * we can decrease the time allowed by
+ * the angle between quats
+ * this means small rotations wont lag */
+ if (sview->quat && !sview->ofs && !sview->dist) {
+ /* scale the time allowed by the rotation */
+ /* 180deg == 1.0 */
+ sms.time_allowed *= (double)fabsf(
+ angle_signed_normalized_qtqt(sms.dst.quat, sms.src.quat)) /
+ M_PI;
+ }
+
+ /* ensure it shows correct */
+ if (sms.to_camera) {
+ /* use ortho if we move from an ortho view to an ortho camera */
+ Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, sview->camera);
+ rv3d->persp = (((rv3d->is_persp == false) && (ob_camera_eval->type == OB_CAMERA) &&
+ (((Camera *)ob_camera_eval->data)->type == CAM_ORTHO)) ?
+ RV3D_ORTHO :
+ RV3D_PERSP);
+ }
+
+ rv3d->rflag |= RV3D_NAVIGATING;
+
+ /* not essential but in some cases the caller will tag the area for redraw, and in that
+ * case we can get a flicker of the 'org' user view but we want to see 'src' */
+ view3d_smooth_view_state_restore(&sms.src, v3d, rv3d);
+
+ /* keep track of running timer! */
+ if (rv3d->sms == NULL) {
+ rv3d->sms = MEM_mallocN(sizeof(struct SmoothView3DStore), "smoothview v3d");
+ }
+ *rv3d->sms = sms;
+ if (rv3d->smooth_timer) {
+ WM_event_remove_timer(wm, win, rv3d->smooth_timer);
+ }
+ /* TIMER1 is hardcoded in keymap */
+ /* max 30 frs/sec */
+ rv3d->smooth_timer = WM_event_add_timer(wm, win, TIMER1, 1.0 / 100.0);
+
+ ok = true;
+ }
+ }
+
+ /* if we get here nothing happens */
+ if (ok == false) {
+ if (sms.to_camera == false) {
+ copy_v3_v3(rv3d->ofs, sms.dst.ofs);
+ copy_qt_qt(rv3d->viewquat, sms.dst.quat);
+ rv3d->dist = sms.dst.dist;
+ v3d->lens = sms.dst.lens;
+
+ ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
+ }
+
+ if (rv3d->viewlock & RV3D_BOXVIEW) {
+ view3d_boxview_copy(sa, ar);
+ }
+
+ ED_region_tag_redraw(ar);
+ }
}
-void ED_view3d_smooth_view(
- bContext *C,
- View3D *v3d, ARegion *ar, const int smooth_viewtx,
- const struct V3D_SmoothParams *sview)
+void ED_view3d_smooth_view(bContext *C,
+ View3D *v3d,
+ ARegion *ar,
+ const int smooth_viewtx,
+ const struct V3D_SmoothParams *sview)
{
- const Depsgraph *depsgraph = CTX_data_depsgraph(C);
- wmWindowManager *wm = CTX_wm_manager(C);
- wmWindow *win = CTX_wm_window(C);
- ScrArea *sa = CTX_wm_area(C);
-
- ED_view3d_smooth_view_ex(
- depsgraph,
- wm, win, sa,
- v3d, ar, smooth_viewtx,
- sview);
+ const Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ wmWindowManager *wm = CTX_wm_manager(C);
+ wmWindow *win = CTX_wm_window(C);
+ ScrArea *sa = CTX_wm_area(C);
+
+ ED_view3d_smooth_view_ex(depsgraph, wm, win, sa, v3d, ar, smooth_viewtx, sview);
}
/* only meant for timer usage */
static void view3d_smoothview_apply(bContext *C, View3D *v3d, ARegion *ar, bool sync_boxview)
{
- const Depsgraph *depsgraph = CTX_data_depsgraph(C);
- RegionView3D *rv3d = ar->regiondata;
- struct SmoothView3DStore *sms = rv3d->sms;
- float step, step_inv;
-
- if (sms->time_allowed != 0.0) {
- step = (float)((rv3d->smooth_timer->duration) / sms->time_allowed);
- }
- else {
- step = 1.0f;
- }
-
- /* end timer */
- if (step >= 1.0f) {
-
- /* if we went to camera, store the original */
- if (sms->to_camera) {
- rv3d->persp = RV3D_CAMOB;
- view3d_smooth_view_state_restore(&sms->org, v3d, rv3d);
- }
- else {
- view3d_smooth_view_state_restore(&sms->dst, v3d, rv3d);
-
- ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
- ED_view3d_camera_lock_autokey(v3d, rv3d, C, true, true);
- }
-
- if ((rv3d->viewlock & RV3D_LOCKED) == 0) {
- rv3d->view = sms->org_view;
- }
-
- MEM_freeN(rv3d->sms);
- rv3d->sms = NULL;
-
- WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), rv3d->smooth_timer);
- rv3d->smooth_timer = NULL;
- rv3d->rflag &= ~RV3D_NAVIGATING;
- }
- else {
- /* ease in/out */
- step = (3.0f * step * step - 2.0f * step * step * step);
-
- step_inv = 1.0f - step;
-
- interp_qt_qtqt(rv3d->viewquat, sms->src.quat, sms->dst.quat, step);
-
- if (sms->use_dyn_ofs) {
- view3d_orbit_apply_dyn_ofs(rv3d->ofs, sms->src.ofs, sms->src.quat, rv3d->viewquat, sms->dyn_ofs);
- }
- else {
- interp_v3_v3v3(rv3d->ofs, sms->src.ofs, sms->dst.ofs, step);
- }
-
- rv3d->dist = sms->dst.dist * step + sms->src.dist * step_inv;
- v3d->lens = sms->dst.lens * step + sms->src.lens * step_inv;
-
- ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
- if (ED_screen_animation_playing(CTX_wm_manager(C))) {
- ED_view3d_camera_lock_autokey(v3d, rv3d, C, true, true);
- }
-
- /* Event handling won't know if a UI item has been moved under the pointer. */
- WM_event_add_mousemove(C);
- }
-
- if (sync_boxview && (rv3d->viewlock & RV3D_BOXVIEW)) {
- view3d_boxview_copy(CTX_wm_area(C), ar);
- }
-
- /* note: this doesn't work right because the v3d->lens is now used in ortho mode r51636,
- * when switching camera in quad-view the other ortho views would zoom & reset.
- *
- * For now only redraw all regions when smoothview finishes.
- */
- if (step >= 1.0f) {
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
- }
- else {
- ED_region_tag_redraw(ar);
- }
+ const Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ RegionView3D *rv3d = ar->regiondata;
+ struct SmoothView3DStore *sms = rv3d->sms;
+ float step, step_inv;
+
+ if (sms->time_allowed != 0.0) {
+ step = (float)((rv3d->smooth_timer->duration) / sms->time_allowed);
+ }
+ else {
+ step = 1.0f;
+ }
+
+ /* end timer */
+ if (step >= 1.0f) {
+
+ /* if we went to camera, store the original */
+ if (sms->to_camera) {
+ rv3d->persp = RV3D_CAMOB;
+ view3d_smooth_view_state_restore(&sms->org, v3d, rv3d);
+ }
+ else {
+ view3d_smooth_view_state_restore(&sms->dst, v3d, rv3d);
+
+ ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
+ ED_view3d_camera_lock_autokey(v3d, rv3d, C, true, true);
+ }
+
+ if ((rv3d->viewlock & RV3D_LOCKED) == 0) {
+ rv3d->view = sms->org_view;
+ }
+
+ MEM_freeN(rv3d->sms);
+ rv3d->sms = NULL;
+
+ WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), rv3d->smooth_timer);
+ rv3d->smooth_timer = NULL;
+ rv3d->rflag &= ~RV3D_NAVIGATING;
+ }
+ else {
+ /* ease in/out */
+ step = (3.0f * step * step - 2.0f * step * step * step);
+
+ step_inv = 1.0f - step;
+
+ interp_qt_qtqt(rv3d->viewquat, sms->src.quat, sms->dst.quat, step);
+
+ if (sms->use_dyn_ofs) {
+ view3d_orbit_apply_dyn_ofs(
+ rv3d->ofs, sms->src.ofs, sms->src.quat, rv3d->viewquat, sms->dyn_ofs);
+ }
+ else {
+ interp_v3_v3v3(rv3d->ofs, sms->src.ofs, sms->dst.ofs, step);
+ }
+
+ rv3d->dist = sms->dst.dist * step + sms->src.dist * step_inv;
+ v3d->lens = sms->dst.lens * step + sms->src.lens * step_inv;
+
+ ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
+ if (ED_screen_animation_playing(CTX_wm_manager(C))) {
+ ED_view3d_camera_lock_autokey(v3d, rv3d, C, true, true);
+ }
+
+ /* Event handling won't know if a UI item has been moved under the pointer. */
+ WM_event_add_mousemove(C);
+ }
+
+ if (sync_boxview && (rv3d->viewlock & RV3D_BOXVIEW)) {
+ view3d_boxview_copy(CTX_wm_area(C), ar);
+ }
+
+ /* note: this doesn't work right because the v3d->lens is now used in ortho mode r51636,
+ * when switching camera in quad-view the other ortho views would zoom & reset.
+ *
+ * For now only redraw all regions when smoothview finishes.
+ */
+ if (step >= 1.0f) {
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
+ }
+ else {
+ ED_region_tag_redraw(ar);
+ }
}
static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
- View3D *v3d = CTX_wm_view3d(C);
- ARegion *ar = CTX_wm_region(C);
- RegionView3D *rv3d = ar->regiondata;
+ View3D *v3d = CTX_wm_view3d(C);
+ ARegion *ar = CTX_wm_region(C);
+ RegionView3D *rv3d = ar->regiondata;
- /* escape if not our timer */
- if (rv3d->smooth_timer == NULL || rv3d->smooth_timer != event->customdata) {
- return OPERATOR_PASS_THROUGH;
- }
+ /* escape if not our timer */
+ if (rv3d->smooth_timer == NULL || rv3d->smooth_timer != event->customdata) {
+ return OPERATOR_PASS_THROUGH;
+ }
- view3d_smoothview_apply(C, v3d, ar, true);
+ view3d_smoothview_apply(C, v3d, ar, true);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
/**
* Apply the smoothview immediately, use when we need to start a new view operation.
* (so we don't end up half-applying a view operation when pressing keys quickly).
*/
-void ED_view3d_smooth_view_force_finish(
- bContext *C,
- View3D *v3d, ARegion *ar)
+void ED_view3d_smooth_view_force_finish(bContext *C, View3D *v3d, ARegion *ar)
{
- RegionView3D *rv3d = ar->regiondata;
-
- if (rv3d && rv3d->sms) {
- rv3d->sms->time_allowed = 0.0; /* force finishing */
- view3d_smoothview_apply(C, v3d, ar, false);
-
- /* force update of view matrix so tools that run immediately after
- * can use them without redrawing first */
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- Scene *scene = CTX_data_scene(C);
- ED_view3d_update_viewmat(depsgraph, scene, v3d, ar, NULL, NULL, NULL);
- }
+ RegionView3D *rv3d = ar->regiondata;
+
+ if (rv3d && rv3d->sms) {
+ rv3d->sms->time_allowed = 0.0; /* force finishing */
+ view3d_smoothview_apply(C, v3d, ar, false);
+
+ /* force update of view matrix so tools that run immediately after
+ * can use them without redrawing first */
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ Scene *scene = CTX_data_scene(C);
+ ED_view3d_update_viewmat(depsgraph, scene, v3d, ar, NULL, NULL, NULL);
+ }
}
void VIEW3D_OT_smoothview(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Smooth View";
- ot->idname = "VIEW3D_OT_smoothview";
+ /* identifiers */
+ ot->name = "Smooth View";
+ ot->idname = "VIEW3D_OT_smoothview";
- /* api callbacks */
- ot->invoke = view3d_smoothview_invoke;
+ /* api callbacks */
+ ot->invoke = view3d_smoothview_invoke;
- /* flags */
- ot->flag = OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_INTERNAL;
- ot->poll = ED_operator_view3d_active;
+ ot->poll = ED_operator_view3d_active;
}
/** \} */
@@ -448,65 +455,64 @@ void VIEW3D_OT_smoothview(wmOperatorType *ot)
static int view3d_camera_to_view_exec(bContext *C, wmOperator *UNUSED(op))
{
- const Depsgraph *depsgraph = CTX_data_depsgraph(C);
- View3D *v3d;
- ARegion *ar;
- RegionView3D *rv3d;
-
- ObjectTfmProtectedChannels obtfm;
+ const Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ View3D *v3d;
+ ARegion *ar;
+ RegionView3D *rv3d;
- ED_view3d_context_user_region(C, &v3d, &ar);
- rv3d = ar->regiondata;
+ ObjectTfmProtectedChannels obtfm;
- ED_view3d_lastview_store(rv3d);
+ ED_view3d_context_user_region(C, &v3d, &ar);
+ rv3d = ar->regiondata;
- BKE_object_tfm_protected_backup(v3d->camera, &obtfm);
+ ED_view3d_lastview_store(rv3d);
- ED_view3d_to_object(depsgraph, v3d->camera, rv3d->ofs, rv3d->viewquat, rv3d->dist);
+ BKE_object_tfm_protected_backup(v3d->camera, &obtfm);
- BKE_object_tfm_protected_restore(v3d->camera, &obtfm, v3d->camera->protectflag);
+ ED_view3d_to_object(depsgraph, v3d->camera, rv3d->ofs, rv3d->viewquat, rv3d->dist);
- DEG_id_tag_update(&v3d->camera->id, ID_RECALC_TRANSFORM);
- rv3d->persp = RV3D_CAMOB;
+ BKE_object_tfm_protected_restore(v3d->camera, &obtfm, v3d->camera->protectflag);
- WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, v3d->camera);
+ DEG_id_tag_update(&v3d->camera->id, ID_RECALC_TRANSFORM);
+ rv3d->persp = RV3D_CAMOB;
- return OPERATOR_FINISHED;
+ WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, v3d->camera);
+ return OPERATOR_FINISHED;
}
static bool view3d_camera_to_view_poll(bContext *C)
{
- View3D *v3d;
- ARegion *ar;
-
- if (ED_view3d_context_user_region(C, &v3d, &ar)) {
- RegionView3D *rv3d = ar->regiondata;
- if (v3d && v3d->camera && !ID_IS_LINKED(v3d->camera)) {
- if (rv3d && (rv3d->viewlock & RV3D_LOCKED) == 0) {
- if (rv3d->persp != RV3D_CAMOB) {
- return 1;
- }
- }
- }
- }
-
- return 0;
+ View3D *v3d;
+ ARegion *ar;
+
+ if (ED_view3d_context_user_region(C, &v3d, &ar)) {
+ RegionView3D *rv3d = ar->regiondata;
+ if (v3d && v3d->camera && !ID_IS_LINKED(v3d->camera)) {
+ if (rv3d && (rv3d->viewlock & RV3D_LOCKED) == 0) {
+ if (rv3d->persp != RV3D_CAMOB) {
+ return 1;
+ }
+ }
+ }
+ }
+
+ return 0;
}
void VIEW3D_OT_camera_to_view(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Align Camera To View";
- ot->description = "Set camera view to active view";
- ot->idname = "VIEW3D_OT_camera_to_view";
+ /* identifiers */
+ ot->name = "Align Camera To View";
+ ot->description = "Set camera view to active view";
+ ot->idname = "VIEW3D_OT_camera_to_view";
- /* api callbacks */
- ot->exec = view3d_camera_to_view_exec;
- ot->poll = view3d_camera_to_view_poll;
+ /* api callbacks */
+ ot->exec = view3d_camera_to_view_exec;
+ ot->poll = view3d_camera_to_view_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/** \} */
@@ -519,60 +525,61 @@ void VIEW3D_OT_camera_to_view(wmOperatorType *ot)
* meant to take into account vertex/bone selection for eg. */
static int view3d_camera_to_view_selected_exec(bContext *C, wmOperator *op)
{
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- Scene *scene = CTX_data_scene(C);
- View3D *v3d = CTX_wm_view3d(C); /* can be NULL */
- Object *camera_ob = v3d ? v3d->camera : scene->camera;
- Object *camera_ob_eval = DEG_get_evaluated_object(depsgraph, camera_ob);
-
- float r_co[3]; /* the new location to apply */
- float r_scale; /* only for ortho cameras */
-
- if (camera_ob_eval == NULL) {
- BKE_report(op->reports, RPT_ERROR, "No active camera");
- return OPERATOR_CANCELLED;
- }
-
- /* this function does all the important stuff */
- if (BKE_camera_view_frame_fit_to_scene(depsgraph, scene, camera_ob_eval, r_co, &r_scale)) {
- ObjectTfmProtectedChannels obtfm;
- float obmat_new[4][4];
-
- if ((camera_ob_eval->type == OB_CAMERA) && (((Camera *)camera_ob_eval->data)->type == CAM_ORTHO)) {
- ((Camera *)camera_ob->data)->ortho_scale = r_scale;
- }
-
- copy_m4_m4(obmat_new, camera_ob_eval->obmat);
- copy_v3_v3(obmat_new[3], r_co);
-
- /* only touch location */
- BKE_object_tfm_protected_backup(camera_ob, &obtfm);
- BKE_object_apply_mat4(camera_ob, obmat_new, true, true);
- BKE_object_tfm_protected_restore(camera_ob, &obtfm, OB_LOCK_SCALE | OB_LOCK_ROT4D);
-
- /* notifiers */
- DEG_id_tag_update(&camera_ob->id, ID_RECALC_TRANSFORM);
- WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, camera_ob);
- return OPERATOR_FINISHED;
- }
- else {
- return OPERATOR_CANCELLED;
- }
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ Scene *scene = CTX_data_scene(C);
+ View3D *v3d = CTX_wm_view3d(C); /* can be NULL */
+ Object *camera_ob = v3d ? v3d->camera : scene->camera;
+ Object *camera_ob_eval = DEG_get_evaluated_object(depsgraph, camera_ob);
+
+ float r_co[3]; /* the new location to apply */
+ float r_scale; /* only for ortho cameras */
+
+ if (camera_ob_eval == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "No active camera");
+ return OPERATOR_CANCELLED;
+ }
+
+ /* this function does all the important stuff */
+ if (BKE_camera_view_frame_fit_to_scene(depsgraph, scene, camera_ob_eval, r_co, &r_scale)) {
+ ObjectTfmProtectedChannels obtfm;
+ float obmat_new[4][4];
+
+ if ((camera_ob_eval->type == OB_CAMERA) &&
+ (((Camera *)camera_ob_eval->data)->type == CAM_ORTHO)) {
+ ((Camera *)camera_ob->data)->ortho_scale = r_scale;
+ }
+
+ copy_m4_m4(obmat_new, camera_ob_eval->obmat);
+ copy_v3_v3(obmat_new[3], r_co);
+
+ /* only touch location */
+ BKE_object_tfm_protected_backup(camera_ob, &obtfm);
+ BKE_object_apply_mat4(camera_ob, obmat_new, true, true);
+ BKE_object_tfm_protected_restore(camera_ob, &obtfm, OB_LOCK_SCALE | OB_LOCK_ROT4D);
+
+ /* notifiers */
+ DEG_id_tag_update(&camera_ob->id, ID_RECALC_TRANSFORM);
+ WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, camera_ob);
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
void VIEW3D_OT_camera_to_view_selected(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Camera Fit Frame to Selected";
- ot->description = "Move the camera so selected objects are framed";
- ot->idname = "VIEW3D_OT_camera_to_view_selected";
+ /* identifiers */
+ ot->name = "Camera Fit Frame to Selected";
+ ot->description = "Move the camera so selected objects are framed";
+ ot->idname = "VIEW3D_OT_camera_to_view_selected";
- /* api callbacks */
- ot->exec = view3d_camera_to_view_selected_exec;
- ot->poll = ED_operator_scene_editable;
+ /* api callbacks */
+ ot->exec = view3d_camera_to_view_selected_exec;
+ ot->poll = ED_operator_scene_editable;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/** \} */
@@ -581,124 +588,134 @@ void VIEW3D_OT_camera_to_view_selected(wmOperatorType *ot)
/** \name Object as Camera Operator
* \{ */
-static void sync_viewport_camera_smoothview(bContext *C, View3D *v3d, Object *ob, const int smooth_viewtx)
+static void sync_viewport_camera_smoothview(bContext *C,
+ View3D *v3d,
+ Object *ob,
+ const int smooth_viewtx)
{
- Main *bmain = CTX_data_main(C);
- for (bScreen *screen = bmain->screens.first; screen != NULL; screen = screen->id.next) {
- for (ScrArea *area = screen->areabase.first; area != NULL; area = area->next) {
- for (SpaceLink *space_link = area->spacedata.first; space_link != NULL; space_link = space_link->next) {
- if (space_link->spacetype == SPACE_VIEW3D) {
- View3D *other_v3d = (View3D *)space_link;
- if (other_v3d == v3d) {
- continue;
- }
- if (other_v3d->camera == ob) {
- continue;
- }
- if (v3d->scenelock) {
- ListBase *lb = (space_link == area->spacedata.first)
- ? &area->regionbase
- : &space_link->regionbase;
- for (ARegion *other_ar = lb->first; other_ar != NULL; other_ar = other_ar->next) {
- if (other_ar->regiontype == RGN_TYPE_WINDOW) {
- if (other_ar->regiondata) {
- RegionView3D *other_rv3d = other_ar->regiondata;
- if (other_rv3d->persp == RV3D_CAMOB) {
- Object *other_camera_old = other_v3d->camera;
- other_v3d->camera = ob;
- ED_view3d_lastview_store(other_rv3d);
- ED_view3d_smooth_view(
- C, other_v3d, other_ar, smooth_viewtx,
- &(const V3D_SmoothParams) {
- .camera_old = other_camera_old,
- .camera = other_v3d->camera,
- .ofs = other_rv3d->ofs,
- .quat = other_rv3d->viewquat,
- .dist = &other_rv3d->dist,
- .lens = &other_v3d->lens,
- });
- }
- else {
- other_v3d->camera = ob;
- }
- }
- }
- }
- }
- }
- }
- }
- }
+ Main *bmain = CTX_data_main(C);
+ for (bScreen *screen = bmain->screens.first; screen != NULL; screen = screen->id.next) {
+ for (ScrArea *area = screen->areabase.first; area != NULL; area = area->next) {
+ for (SpaceLink *space_link = area->spacedata.first; space_link != NULL;
+ space_link = space_link->next) {
+ if (space_link->spacetype == SPACE_VIEW3D) {
+ View3D *other_v3d = (View3D *)space_link;
+ if (other_v3d == v3d) {
+ continue;
+ }
+ if (other_v3d->camera == ob) {
+ continue;
+ }
+ if (v3d->scenelock) {
+ ListBase *lb = (space_link == area->spacedata.first) ? &area->regionbase :
+ &space_link->regionbase;
+ for (ARegion *other_ar = lb->first; other_ar != NULL; other_ar = other_ar->next) {
+ if (other_ar->regiontype == RGN_TYPE_WINDOW) {
+ if (other_ar->regiondata) {
+ RegionView3D *other_rv3d = other_ar->regiondata;
+ if (other_rv3d->persp == RV3D_CAMOB) {
+ Object *other_camera_old = other_v3d->camera;
+ other_v3d->camera = ob;
+ ED_view3d_lastview_store(other_rv3d);
+ ED_view3d_smooth_view(C,
+ other_v3d,
+ other_ar,
+ smooth_viewtx,
+ &(const V3D_SmoothParams){
+ .camera_old = other_camera_old,
+ .camera = other_v3d->camera,
+ .ofs = other_rv3d->ofs,
+ .quat = other_rv3d->viewquat,
+ .dist = &other_rv3d->dist,
+ .lens = &other_v3d->lens,
+ });
+ }
+ else {
+ other_v3d->camera = ob;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
}
static int view3d_setobjectascamera_exec(bContext *C, wmOperator *op)
{
- View3D *v3d;
- ARegion *ar;
- RegionView3D *rv3d;
-
- Scene *scene = CTX_data_scene(C);
- Object *ob = CTX_data_active_object(C);
-
- const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
-
- /* no NULL check is needed, poll checks */
- ED_view3d_context_user_region(C, &v3d, &ar);
- rv3d = ar->regiondata;
-
- if (ob) {
- Object *camera_old = (rv3d->persp == RV3D_CAMOB) ? V3D_CAMERA_SCENE(scene, v3d) : NULL;
- rv3d->persp = RV3D_CAMOB;
- v3d->camera = ob;
- if (v3d->scenelock && scene->camera != ob) {
- scene->camera = ob;
- DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
- }
-
- /* unlikely but looks like a glitch when set to the same */
- if (camera_old != ob) {
- ED_view3d_lastview_store(rv3d);
-
- ED_view3d_smooth_view(
- C, v3d, ar, smooth_viewtx,
- &(const V3D_SmoothParams) {
- .camera_old = camera_old, .camera = v3d->camera,
- .ofs = rv3d->ofs, .quat = rv3d->viewquat,
- .dist = &rv3d->dist, .lens = &v3d->lens,
- });
- }
-
- if (v3d->scenelock) {
- sync_viewport_camera_smoothview(C, v3d, ob, smooth_viewtx);
- WM_event_add_notifier(C, NC_SCENE, scene);
- }
- WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, scene);
- }
-
- return OPERATOR_FINISHED;
+ View3D *v3d;
+ ARegion *ar;
+ RegionView3D *rv3d;
+
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = CTX_data_active_object(C);
+
+ const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
+
+ /* no NULL check is needed, poll checks */
+ ED_view3d_context_user_region(C, &v3d, &ar);
+ rv3d = ar->regiondata;
+
+ if (ob) {
+ Object *camera_old = (rv3d->persp == RV3D_CAMOB) ? V3D_CAMERA_SCENE(scene, v3d) : NULL;
+ rv3d->persp = RV3D_CAMOB;
+ v3d->camera = ob;
+ if (v3d->scenelock && scene->camera != ob) {
+ scene->camera = ob;
+ DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
+ }
+
+ /* unlikely but looks like a glitch when set to the same */
+ if (camera_old != ob) {
+ ED_view3d_lastview_store(rv3d);
+
+ ED_view3d_smooth_view(C,
+ v3d,
+ ar,
+ smooth_viewtx,
+ &(const V3D_SmoothParams){
+ .camera_old = camera_old,
+ .camera = v3d->camera,
+ .ofs = rv3d->ofs,
+ .quat = rv3d->viewquat,
+ .dist = &rv3d->dist,
+ .lens = &v3d->lens,
+ });
+ }
+
+ if (v3d->scenelock) {
+ sync_viewport_camera_smoothview(C, v3d, ob, smooth_viewtx);
+ WM_event_add_notifier(C, NC_SCENE, scene);
+ }
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, scene);
+ }
+
+ return OPERATOR_FINISHED;
}
bool ED_operator_rv3d_user_region_poll(bContext *C)
{
- View3D *v3d_dummy;
- ARegion *ar_dummy;
+ View3D *v3d_dummy;
+ ARegion *ar_dummy;
- return ED_view3d_context_user_region(C, &v3d_dummy, &ar_dummy);
+ return ED_view3d_context_user_region(C, &v3d_dummy, &ar_dummy);
}
void VIEW3D_OT_object_as_camera(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Set Active Object as Camera";
- ot->description = "Set the active object as the active camera for this view or scene";
- ot->idname = "VIEW3D_OT_object_as_camera";
+ /* identifiers */
+ ot->name = "Set Active Object as Camera";
+ ot->description = "Set the active object as the active camera for this view or scene";
+ ot->idname = "VIEW3D_OT_object_as_camera";
- /* api callbacks */
- ot->exec = view3d_setobjectascamera_exec;
- ot->poll = ED_operator_rv3d_user_region_poll;
+ /* api callbacks */
+ ot->exec = view3d_setobjectascamera_exec;
+ ot->poll = ED_operator_rv3d_user_region_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/** \} */
@@ -712,51 +729,54 @@ void VIEW3D_OT_object_as_camera(wmOperatorType *ot)
*/
void view3d_winmatrix_set(Depsgraph *depsgraph, ARegion *ar, const View3D *v3d, const rcti *rect)
{
- RegionView3D *rv3d = ar->regiondata;
- rctf viewplane;
- float clipsta, clipend;
- bool is_ortho;
+ RegionView3D *rv3d = ar->regiondata;
+ rctf viewplane;
+ float clipsta, clipend;
+ bool is_ortho;
- is_ortho = ED_view3d_viewplane_get(depsgraph, v3d, rv3d, ar->winx, ar->winy, &viewplane, &clipsta, &clipend, NULL);
- rv3d->is_persp = !is_ortho;
+ is_ortho = ED_view3d_viewplane_get(
+ depsgraph, v3d, rv3d, ar->winx, ar->winy, &viewplane, &clipsta, &clipend, NULL);
+ rv3d->is_persp = !is_ortho;
#if 0
- printf("%s: %d %d %f %f %f %f %f %f\n", __func__, winx, winy,
- viewplane.xmin, viewplane.ymin, viewplane.xmax, viewplane.ymax,
- clipsta, clipend);
+ printf("%s: %d %d %f %f %f %f %f %f\n", __func__, winx, winy,
+ viewplane.xmin, viewplane.ymin, viewplane.xmax, viewplane.ymax,
+ clipsta, clipend);
#endif
- if (rect) { /* picking */
- rctf r;
- r.xmin = viewplane.xmin + (BLI_rctf_size_x(&viewplane) * (rect->xmin / (float)ar->winx));
- r.ymin = viewplane.ymin + (BLI_rctf_size_y(&viewplane) * (rect->ymin / (float)ar->winy));
- r.xmax = viewplane.xmin + (BLI_rctf_size_x(&viewplane) * (rect->xmax / (float)ar->winx));
- r.ymax = viewplane.ymin + (BLI_rctf_size_y(&viewplane) * (rect->ymax / (float)ar->winy));
- viewplane = r;
- }
-
- if (is_ortho) {
- GPU_matrix_ortho_set(viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend);
- }
- else {
- GPU_matrix_frustum_set(viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend);
- }
-
- /* update matrix in 3d view region */
- GPU_matrix_projection_get(rv3d->winmat);
+ if (rect) { /* picking */
+ rctf r;
+ r.xmin = viewplane.xmin + (BLI_rctf_size_x(&viewplane) * (rect->xmin / (float)ar->winx));
+ r.ymin = viewplane.ymin + (BLI_rctf_size_y(&viewplane) * (rect->ymin / (float)ar->winy));
+ r.xmax = viewplane.xmin + (BLI_rctf_size_x(&viewplane) * (rect->xmax / (float)ar->winx));
+ r.ymax = viewplane.ymin + (BLI_rctf_size_y(&viewplane) * (rect->ymax / (float)ar->winy));
+ viewplane = r;
+ }
+
+ if (is_ortho) {
+ GPU_matrix_ortho_set(
+ viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend);
+ }
+ else {
+ GPU_matrix_frustum_set(
+ viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend);
+ }
+
+ /* update matrix in 3d view region */
+ GPU_matrix_projection_get(rv3d->winmat);
}
static void obmat_to_viewmat(RegionView3D *rv3d, Object *ob)
{
- float bmat[4][4];
+ float bmat[4][4];
- rv3d->view = RV3D_VIEW_USER; /* don't show the grid */
+ rv3d->view = RV3D_VIEW_USER; /* don't show the grid */
- normalize_m4_m4(bmat, ob->obmat);
- invert_m4_m4(rv3d->viewmat, bmat);
+ normalize_m4_m4(bmat, ob->obmat);
+ invert_m4_m4(rv3d->viewmat, bmat);
- /* view quat calculation, needed for add object */
- mat4_normalized_to_quat(rv3d->viewquat, rv3d->viewmat);
+ /* view quat calculation, needed for add object */
+ mat4_normalized_to_quat(rv3d->viewquat, rv3d->viewmat);
}
/**
@@ -771,86 +791,87 @@ static void obmat_to_viewmat(RegionView3D *rv3d, Object *ob)
*
* \note don't set windows active in here, is used by renderwin too.
*/
-void view3d_viewmatrix_set(
- Depsgraph *depsgraph, Scene *scene,
- const View3D *v3d, RegionView3D *rv3d, const float rect_scale[2])
+void view3d_viewmatrix_set(Depsgraph *depsgraph,
+ Scene *scene,
+ const View3D *v3d,
+ RegionView3D *rv3d,
+ const float rect_scale[2])
{
- if (rv3d->persp == RV3D_CAMOB) { /* obs/camera */
- if (v3d->camera) {
- Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera);
- obmat_to_viewmat(rv3d, ob_camera_eval);
- }
- else {
- quat_to_mat4(rv3d->viewmat, rv3d->viewquat);
- rv3d->viewmat[3][2] -= rv3d->dist;
- }
- }
- else {
- bool use_lock_ofs = false;
-
-
- /* should be moved to better initialize later on XXX */
- if (rv3d->viewlock & RV3D_LOCKED) {
- ED_view3d_lock(rv3d);
- }
-
- quat_to_mat4(rv3d->viewmat, rv3d->viewquat);
- if (rv3d->persp == RV3D_PERSP) {
- rv3d->viewmat[3][2] -= rv3d->dist;
- }
- if (v3d->ob_centre) {
- Object *ob_eval = DEG_get_evaluated_object(depsgraph, v3d->ob_centre);
- float vec[3];
-
- copy_v3_v3(vec, ob_eval->obmat[3]);
- if (ob_eval->type == OB_ARMATURE && v3d->ob_centre_bone[0]) {
- bPoseChannel *pchan = BKE_pose_channel_find_name(ob_eval->pose, v3d->ob_centre_bone);
- if (pchan) {
- copy_v3_v3(vec, pchan->pose_mat[3]);
- mul_m4_v3(ob_eval->obmat, vec);
- }
- }
- translate_m4(rv3d->viewmat, -vec[0], -vec[1], -vec[2]);
- use_lock_ofs = true;
- }
- else if (v3d->ob_centre_cursor) {
- float vec[3];
- copy_v3_v3(vec, scene->cursor.location);
- translate_m4(rv3d->viewmat, -vec[0], -vec[1], -vec[2]);
- use_lock_ofs = true;
- }
- else {
- translate_m4(rv3d->viewmat, rv3d->ofs[0], rv3d->ofs[1], rv3d->ofs[2]);
- }
-
- /* lock offset */
- if (use_lock_ofs) {
- float persmat[4][4], persinv[4][4];
- float vec[3];
-
- /* we could calculate the real persmat/persinv here
- * but it would be unreliable so better to later */
- mul_m4_m4m4(persmat, rv3d->winmat, rv3d->viewmat);
- invert_m4_m4(persinv, persmat);
-
- mul_v2_v2fl(vec, rv3d->ofs_lock, rv3d->is_persp ? rv3d->dist : 1.0f);
- vec[2] = 0.0f;
-
- if (rect_scale) {
- /* Since 'RegionView3D.winmat' has been calculated and this function doesn't take the 'ARegion'
- * we don't know about the region size.
- * Use 'rect_scale' when drawing a sub-region to apply 2D offset,
- * scaled by the difference between the sub-region and the region size.
- */
- vec[0] /= rect_scale[0];
- vec[1] /= rect_scale[1];
- }
-
- mul_mat3_m4_v3(persinv, vec);
- translate_m4(rv3d->viewmat, vec[0], vec[1], vec[2]);
- }
- /* end lock offset */
- }
+ if (rv3d->persp == RV3D_CAMOB) { /* obs/camera */
+ if (v3d->camera) {
+ Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera);
+ obmat_to_viewmat(rv3d, ob_camera_eval);
+ }
+ else {
+ quat_to_mat4(rv3d->viewmat, rv3d->viewquat);
+ rv3d->viewmat[3][2] -= rv3d->dist;
+ }
+ }
+ else {
+ bool use_lock_ofs = false;
+
+ /* should be moved to better initialize later on XXX */
+ if (rv3d->viewlock & RV3D_LOCKED) {
+ ED_view3d_lock(rv3d);
+ }
+
+ quat_to_mat4(rv3d->viewmat, rv3d->viewquat);
+ if (rv3d->persp == RV3D_PERSP) {
+ rv3d->viewmat[3][2] -= rv3d->dist;
+ }
+ if (v3d->ob_centre) {
+ Object *ob_eval = DEG_get_evaluated_object(depsgraph, v3d->ob_centre);
+ float vec[3];
+
+ copy_v3_v3(vec, ob_eval->obmat[3]);
+ if (ob_eval->type == OB_ARMATURE && v3d->ob_centre_bone[0]) {
+ bPoseChannel *pchan = BKE_pose_channel_find_name(ob_eval->pose, v3d->ob_centre_bone);
+ if (pchan) {
+ copy_v3_v3(vec, pchan->pose_mat[3]);
+ mul_m4_v3(ob_eval->obmat, vec);
+ }
+ }
+ translate_m4(rv3d->viewmat, -vec[0], -vec[1], -vec[2]);
+ use_lock_ofs = true;
+ }
+ else if (v3d->ob_centre_cursor) {
+ float vec[3];
+ copy_v3_v3(vec, scene->cursor.location);
+ translate_m4(rv3d->viewmat, -vec[0], -vec[1], -vec[2]);
+ use_lock_ofs = true;
+ }
+ else {
+ translate_m4(rv3d->viewmat, rv3d->ofs[0], rv3d->ofs[1], rv3d->ofs[2]);
+ }
+
+ /* lock offset */
+ if (use_lock_ofs) {
+ float persmat[4][4], persinv[4][4];
+ float vec[3];
+
+ /* we could calculate the real persmat/persinv here
+ * but it would be unreliable so better to later */
+ mul_m4_m4m4(persmat, rv3d->winmat, rv3d->viewmat);
+ invert_m4_m4(persinv, persmat);
+
+ mul_v2_v2fl(vec, rv3d->ofs_lock, rv3d->is_persp ? rv3d->dist : 1.0f);
+ vec[2] = 0.0f;
+
+ if (rect_scale) {
+ /* Since 'RegionView3D.winmat' has been calculated and this function doesn't take the 'ARegion'
+ * we don't know about the region size.
+ * Use 'rect_scale' when drawing a sub-region to apply 2D offset,
+ * scaled by the difference between the sub-region and the region size.
+ */
+ vec[0] /= rect_scale[0];
+ vec[1] /= rect_scale[1];
+ }
+
+ mul_mat3_m4_v3(persinv, vec);
+ translate_m4(rv3d->viewmat, vec[0], vec[1], vec[2]);
+ }
+ /* end lock offset */
+ }
}
/** \} */
@@ -866,77 +887,76 @@ void view3d_viewmatrix_set(
*/
void view3d_opengl_select_cache_begin(void)
{
- GPU_select_cache_begin();
+ GPU_select_cache_begin();
}
void view3d_opengl_select_cache_end(void)
{
- GPU_select_cache_end();
+ GPU_select_cache_end();
}
struct DrawSelectLoopUserData {
- uint pass;
- uint hits;
- uint *buffer;
- uint buffer_len;
- const rcti *rect;
- char gpu_select_mode;
+ uint pass;
+ uint hits;
+ uint *buffer;
+ uint buffer_len;
+ const rcti *rect;
+ char gpu_select_mode;
};
static bool drw_select_loop_pass(eDRWSelectStage stage, void *user_data)
{
- bool continue_pass = false;
- struct DrawSelectLoopUserData *data = user_data;
- if (stage == DRW_SELECT_PASS_PRE) {
- GPU_select_begin(data->buffer, data->buffer_len, data->rect, data->gpu_select_mode, data->hits);
- /* always run POST after PRE. */
- continue_pass = true;
- }
- else if (stage == DRW_SELECT_PASS_POST) {
- int hits = GPU_select_end();
- if (data->pass == 0) {
- /* quirk of GPU_select_end, only take hits value from first call. */
- data->hits = hits;
- }
- if (data->gpu_select_mode == GPU_SELECT_NEAREST_FIRST_PASS) {
- data->gpu_select_mode = GPU_SELECT_NEAREST_SECOND_PASS;
- continue_pass = (hits > 0);
- }
- data->pass += 1;
- }
- else {
- BLI_assert(0);
- }
- return continue_pass;
-
+ bool continue_pass = false;
+ struct DrawSelectLoopUserData *data = user_data;
+ if (stage == DRW_SELECT_PASS_PRE) {
+ GPU_select_begin(
+ data->buffer, data->buffer_len, data->rect, data->gpu_select_mode, data->hits);
+ /* always run POST after PRE. */
+ continue_pass = true;
+ }
+ else if (stage == DRW_SELECT_PASS_POST) {
+ int hits = GPU_select_end();
+ if (data->pass == 0) {
+ /* quirk of GPU_select_end, only take hits value from first call. */
+ data->hits = hits;
+ }
+ if (data->gpu_select_mode == GPU_SELECT_NEAREST_FIRST_PASS) {
+ data->gpu_select_mode = GPU_SELECT_NEAREST_SECOND_PASS;
+ continue_pass = (hits > 0);
+ }
+ data->pass += 1;
+ }
+ else {
+ BLI_assert(0);
+ }
+ return continue_pass;
}
eV3DSelectObjectFilter ED_view3d_select_filter_from_mode(const Scene *scene, const Object *obact)
{
- if (scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK) {
- if (obact && (obact->mode & OB_MODE_WEIGHT_PAINT) &&
- BKE_object_pose_armature_get((Object *)obact))
- {
- return VIEW3D_SELECT_FILTER_WPAINT_POSE_MODE_LOCK;
- }
- return VIEW3D_SELECT_FILTER_OBJECT_MODE_LOCK;
- }
- return VIEW3D_SELECT_FILTER_NOP;
+ if (scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK) {
+ if (obact && (obact->mode & OB_MODE_WEIGHT_PAINT) &&
+ BKE_object_pose_armature_get((Object *)obact)) {
+ return VIEW3D_SELECT_FILTER_WPAINT_POSE_MODE_LOCK;
+ }
+ return VIEW3D_SELECT_FILTER_OBJECT_MODE_LOCK;
+ }
+ return VIEW3D_SELECT_FILTER_NOP;
}
/** Implement #VIEW3D_SELECT_FILTER_OBJECT_MODE_LOCK. */
static bool drw_select_filter_object_mode_lock(Object *ob, void *user_data)
{
- const Object *obact = user_data;
- return BKE_object_is_mode_compat(ob, obact->mode);
+ const Object *obact = user_data;
+ return BKE_object_is_mode_compat(ob, obact->mode);
}
/** Implement #VIEW3D_SELECT_FILTER_WPAINT_POSE_MODE_LOCK for special case when
* we want to select pose bones (this doesn't switch modes). */
static bool drw_select_filter_object_mode_lock_for_weight_paint(Object *ob, void *user_data)
{
- const Object *ob_pose = user_data;
- return (DEG_get_original_object(ob) == ob_pose);
+ const Object *ob_pose = user_data;
+ return (DEG_get_original_object(ob) == ob_pose);
}
/**
@@ -946,184 +966,196 @@ static bool drw_select_filter_object_mode_lock_for_weight_paint(Object *ob, void
*
* \note (vc->obedit == NULL) can be set to explicitly skip edit-object selection.
*/
-int view3d_opengl_select(
- ViewContext *vc, uint *buffer, uint bufsize, const rcti *input,
- eV3DSelectMode select_mode, eV3DSelectObjectFilter select_filter)
+int view3d_opengl_select(ViewContext *vc,
+ uint *buffer,
+ uint bufsize,
+ const rcti *input,
+ eV3DSelectMode select_mode,
+ eV3DSelectObjectFilter select_filter)
{
- struct bThemeState theme_state;
- Depsgraph *depsgraph = vc->depsgraph;
- Scene *scene = vc->scene;
- View3D *v3d = vc->v3d;
- ARegion *ar = vc->ar;
- rcti rect;
- int hits = 0;
- const bool use_obedit_skip = (OBEDIT_FROM_VIEW_LAYER(vc->view_layer) != NULL) && (vc->obedit == NULL);
- const bool is_pick_select = (U.gpu_flag & USER_GPU_FLAG_NO_DEPT_PICK) == 0;
- const bool do_passes = (
- (is_pick_select == false) &&
- (select_mode == VIEW3D_SELECT_PICK_NEAREST));
- const bool use_nearest = (is_pick_select && select_mode == VIEW3D_SELECT_PICK_NEAREST);
- bool draw_surface = true;
-
- char gpu_select_mode;
-
- /* case not a box select */
- if (input->xmin == input->xmax) {
- /* seems to be default value for bones only now */
- BLI_rcti_init_pt_radius(&rect, (const int[2]){input->xmin, input->ymin}, 12);
- }
- else {
- rect = *input;
- }
-
- if (is_pick_select) {
- if (is_pick_select && select_mode == VIEW3D_SELECT_PICK_NEAREST) {
- gpu_select_mode = GPU_SELECT_PICK_NEAREST;
- }
- else if (is_pick_select && select_mode == VIEW3D_SELECT_PICK_ALL) {
- gpu_select_mode = GPU_SELECT_PICK_ALL;
- }
- else {
- gpu_select_mode = GPU_SELECT_ALL;
- }
- }
- else {
- if (do_passes) {
- gpu_select_mode = GPU_SELECT_NEAREST_FIRST_PASS;
- }
- else {
- gpu_select_mode = GPU_SELECT_ALL;
- }
- }
-
- /* Important to use 'vc->obact', not 'OBACT(vc->view_layer)' below,
- * so it will be NULL when hidden. */
- struct {
- DRW_ObjectFilterFn fn;
- void *user_data;
- } object_filter = {NULL, NULL};
- switch (select_filter) {
- case VIEW3D_SELECT_FILTER_OBJECT_MODE_LOCK:
- {
- Object *obact = vc->obact;
- if (obact && obact->mode != OB_MODE_OBJECT) {
- object_filter.fn = drw_select_filter_object_mode_lock;
- object_filter.user_data = obact;
- }
- break;
- }
- case VIEW3D_SELECT_FILTER_WPAINT_POSE_MODE_LOCK:
- {
- Object *obact = vc->obact;
- BLI_assert(obact && (obact->mode & OB_MODE_WEIGHT_PAINT));
- Object *ob_pose = BKE_object_pose_armature_get(obact);
-
- object_filter.fn = drw_select_filter_object_mode_lock_for_weight_paint;
- object_filter.user_data = ob_pose;
- break;
- }
- case VIEW3D_SELECT_FILTER_NOP:
- break;
-
- }
-
- /* Tools may request depth outside of regular drawing code. */
- UI_Theme_Store(&theme_state);
- UI_SetTheme(SPACE_VIEW3D, RGN_TYPE_WINDOW);
-
- /* Re-use cache (rect must be smaller then the cached)
- * other context is assumed to be unchanged */
- if (GPU_select_is_cached()) {
- GPU_select_begin(buffer, bufsize, &rect, gpu_select_mode, 0);
- GPU_select_cache_load_id();
- hits = GPU_select_end();
- goto finally;
- }
-
- /* All of the queries need to be perform on the drawing context. */
- DRW_opengl_context_enable();
-
- G.f |= G_FLAG_PICKSEL;
-
- /* Important we use the 'viewmat' and don't re-calculate since
- * the object & bone view locking takes 'rect' into account, see: T51629. */
- ED_view3d_draw_setup_view(vc->win, depsgraph, scene, ar, v3d, vc->rv3d->viewmat, NULL, &rect);
-
- if (!XRAY_ACTIVE(v3d)) {
- GPU_depth_test(true);
- }
-
- if (vc->rv3d->rflag & RV3D_CLIPPING) {
- ED_view3d_clipping_set(vc->rv3d);
- }
-
- /* If in xray mode, we select the wires in priority. */
- if (XRAY_ACTIVE(v3d) && use_nearest) {
- /* We need to call "GPU_select_*" API's inside DRW_draw_select_loop
- * because the OpenGL context created & destroyed inside this function. */
- struct DrawSelectLoopUserData drw_select_loop_user_data = {
- .pass = 0,
- .hits = 0,
- .buffer = buffer,
- .buffer_len = bufsize,
- .rect = &rect,
- .gpu_select_mode = gpu_select_mode,
- };
- draw_surface = false;
- DRW_draw_select_loop(
- depsgraph, ar, v3d,
- use_obedit_skip, draw_surface, use_nearest, &rect,
- drw_select_loop_pass, &drw_select_loop_user_data,
- object_filter.fn, object_filter.user_data);
- hits = drw_select_loop_user_data.hits;
- /* FIX: This cleanup the state before doing another selection pass.
- * (see T56695) */
- GPU_select_cache_end();
- }
-
- if (hits == 0) {
- /* We need to call "GPU_select_*" API's inside DRW_draw_select_loop
- * because the OpenGL context created & destroyed inside this function. */
- struct DrawSelectLoopUserData drw_select_loop_user_data = {
- .pass = 0,
- .hits = 0,
- .buffer = buffer,
- .buffer_len = bufsize,
- .rect = &rect,
- .gpu_select_mode = gpu_select_mode,
- };
- /* If are not in wireframe mode, we need to use the mesh surfaces to check for hits */
- draw_surface = (v3d->shading.type > OB_WIRE) || !XRAY_ENABLED(v3d);
- DRW_draw_select_loop(
- depsgraph, ar, v3d,
- use_obedit_skip, draw_surface, use_nearest, &rect,
- drw_select_loop_pass, &drw_select_loop_user_data,
- object_filter.fn, object_filter.user_data);
- hits = drw_select_loop_user_data.hits;
- }
-
- G.f &= ~G_FLAG_PICKSEL;
- ED_view3d_draw_setup_view(vc->win, depsgraph, scene, ar, v3d, vc->rv3d->viewmat, NULL, NULL);
-
- if (!XRAY_ACTIVE(v3d)) {
- GPU_depth_test(false);
- }
-
- if (vc->rv3d->rflag & RV3D_CLIPPING) {
- ED_view3d_clipping_disable();
- }
-
- DRW_opengl_context_disable();
+ struct bThemeState theme_state;
+ Depsgraph *depsgraph = vc->depsgraph;
+ Scene *scene = vc->scene;
+ View3D *v3d = vc->v3d;
+ ARegion *ar = vc->ar;
+ rcti rect;
+ int hits = 0;
+ const bool use_obedit_skip = (OBEDIT_FROM_VIEW_LAYER(vc->view_layer) != NULL) &&
+ (vc->obedit == NULL);
+ const bool is_pick_select = (U.gpu_flag & USER_GPU_FLAG_NO_DEPT_PICK) == 0;
+ const bool do_passes = ((is_pick_select == false) &&
+ (select_mode == VIEW3D_SELECT_PICK_NEAREST));
+ const bool use_nearest = (is_pick_select && select_mode == VIEW3D_SELECT_PICK_NEAREST);
+ bool draw_surface = true;
+
+ char gpu_select_mode;
+
+ /* case not a box select */
+ if (input->xmin == input->xmax) {
+ /* seems to be default value for bones only now */
+ BLI_rcti_init_pt_radius(&rect, (const int[2]){input->xmin, input->ymin}, 12);
+ }
+ else {
+ rect = *input;
+ }
+
+ if (is_pick_select) {
+ if (is_pick_select && select_mode == VIEW3D_SELECT_PICK_NEAREST) {
+ gpu_select_mode = GPU_SELECT_PICK_NEAREST;
+ }
+ else if (is_pick_select && select_mode == VIEW3D_SELECT_PICK_ALL) {
+ gpu_select_mode = GPU_SELECT_PICK_ALL;
+ }
+ else {
+ gpu_select_mode = GPU_SELECT_ALL;
+ }
+ }
+ else {
+ if (do_passes) {
+ gpu_select_mode = GPU_SELECT_NEAREST_FIRST_PASS;
+ }
+ else {
+ gpu_select_mode = GPU_SELECT_ALL;
+ }
+ }
+
+ /* Important to use 'vc->obact', not 'OBACT(vc->view_layer)' below,
+ * so it will be NULL when hidden. */
+ struct {
+ DRW_ObjectFilterFn fn;
+ void *user_data;
+ } object_filter = {NULL, NULL};
+ switch (select_filter) {
+ case VIEW3D_SELECT_FILTER_OBJECT_MODE_LOCK: {
+ Object *obact = vc->obact;
+ if (obact && obact->mode != OB_MODE_OBJECT) {
+ object_filter.fn = drw_select_filter_object_mode_lock;
+ object_filter.user_data = obact;
+ }
+ break;
+ }
+ case VIEW3D_SELECT_FILTER_WPAINT_POSE_MODE_LOCK: {
+ Object *obact = vc->obact;
+ BLI_assert(obact && (obact->mode & OB_MODE_WEIGHT_PAINT));
+ Object *ob_pose = BKE_object_pose_armature_get(obact);
+
+ object_filter.fn = drw_select_filter_object_mode_lock_for_weight_paint;
+ object_filter.user_data = ob_pose;
+ break;
+ }
+ case VIEW3D_SELECT_FILTER_NOP:
+ break;
+ }
+
+ /* Tools may request depth outside of regular drawing code. */
+ UI_Theme_Store(&theme_state);
+ UI_SetTheme(SPACE_VIEW3D, RGN_TYPE_WINDOW);
+
+ /* Re-use cache (rect must be smaller then the cached)
+ * other context is assumed to be unchanged */
+ if (GPU_select_is_cached()) {
+ GPU_select_begin(buffer, bufsize, &rect, gpu_select_mode, 0);
+ GPU_select_cache_load_id();
+ hits = GPU_select_end();
+ goto finally;
+ }
+
+ /* All of the queries need to be perform on the drawing context. */
+ DRW_opengl_context_enable();
+
+ G.f |= G_FLAG_PICKSEL;
+
+ /* Important we use the 'viewmat' and don't re-calculate since
+ * the object & bone view locking takes 'rect' into account, see: T51629. */
+ ED_view3d_draw_setup_view(vc->win, depsgraph, scene, ar, v3d, vc->rv3d->viewmat, NULL, &rect);
+
+ if (!XRAY_ACTIVE(v3d)) {
+ GPU_depth_test(true);
+ }
+
+ if (vc->rv3d->rflag & RV3D_CLIPPING) {
+ ED_view3d_clipping_set(vc->rv3d);
+ }
+
+ /* If in xray mode, we select the wires in priority. */
+ if (XRAY_ACTIVE(v3d) && use_nearest) {
+ /* We need to call "GPU_select_*" API's inside DRW_draw_select_loop
+ * because the OpenGL context created & destroyed inside this function. */
+ struct DrawSelectLoopUserData drw_select_loop_user_data = {
+ .pass = 0,
+ .hits = 0,
+ .buffer = buffer,
+ .buffer_len = bufsize,
+ .rect = &rect,
+ .gpu_select_mode = gpu_select_mode,
+ };
+ draw_surface = false;
+ DRW_draw_select_loop(depsgraph,
+ ar,
+ v3d,
+ use_obedit_skip,
+ draw_surface,
+ use_nearest,
+ &rect,
+ drw_select_loop_pass,
+ &drw_select_loop_user_data,
+ object_filter.fn,
+ object_filter.user_data);
+ hits = drw_select_loop_user_data.hits;
+ /* FIX: This cleanup the state before doing another selection pass.
+ * (see T56695) */
+ GPU_select_cache_end();
+ }
+
+ if (hits == 0) {
+ /* We need to call "GPU_select_*" API's inside DRW_draw_select_loop
+ * because the OpenGL context created & destroyed inside this function. */
+ struct DrawSelectLoopUserData drw_select_loop_user_data = {
+ .pass = 0,
+ .hits = 0,
+ .buffer = buffer,
+ .buffer_len = bufsize,
+ .rect = &rect,
+ .gpu_select_mode = gpu_select_mode,
+ };
+ /* If are not in wireframe mode, we need to use the mesh surfaces to check for hits */
+ draw_surface = (v3d->shading.type > OB_WIRE) || !XRAY_ENABLED(v3d);
+ DRW_draw_select_loop(depsgraph,
+ ar,
+ v3d,
+ use_obedit_skip,
+ draw_surface,
+ use_nearest,
+ &rect,
+ drw_select_loop_pass,
+ &drw_select_loop_user_data,
+ object_filter.fn,
+ object_filter.user_data);
+ hits = drw_select_loop_user_data.hits;
+ }
+
+ G.f &= ~G_FLAG_PICKSEL;
+ ED_view3d_draw_setup_view(vc->win, depsgraph, scene, ar, v3d, vc->rv3d->viewmat, NULL, NULL);
+
+ if (!XRAY_ACTIVE(v3d)) {
+ GPU_depth_test(false);
+ }
+
+ if (vc->rv3d->rflag & RV3D_CLIPPING) {
+ ED_view3d_clipping_disable();
+ }
+
+ DRW_opengl_context_disable();
finally:
- if (hits < 0) {
- printf("Too many objects in select buffer\n"); /* XXX make error message */
- }
+ if (hits < 0) {
+ printf("Too many objects in select buffer\n"); /* XXX make error message */
+ }
- UI_Theme_Restore(&theme_state);
+ UI_Theme_Restore(&theme_state);
- return hits;
+ return hits;
}
/** \} */
@@ -1134,332 +1166,348 @@ finally:
static uint free_localbit(Main *bmain)
{
- ScrArea *sa;
- bScreen *sc;
-
- ushort local_view_bits = 0;
-
- /* sometimes we loose a localview: when an area is closed */
- /* check all areas: which localviews are in use? */
- for (sc = bmain->screens.first; sc; sc = sc->id.next) {
- for (sa = sc->areabase.first; sa; sa = sa->next) {
- SpaceLink *sl = sa->spacedata.first;
- for (; sl; sl = sl->next) {
- if (sl->spacetype == SPACE_VIEW3D) {
- View3D *v3d = (View3D *) sl;
- if (v3d->localvd) {
- local_view_bits |= v3d->local_view_uuid;
- }
- }
- }
- }
- }
-
- for (int i = 0; i < 16; i++) {
- if ((local_view_bits & (1 << i)) == 0) {
- return (1 << i);
- }
- }
-
- return 0;
+ ScrArea *sa;
+ bScreen *sc;
+
+ ushort local_view_bits = 0;
+
+ /* sometimes we loose a localview: when an area is closed */
+ /* check all areas: which localviews are in use? */
+ for (sc = bmain->screens.first; sc; sc = sc->id.next) {
+ for (sa = sc->areabase.first; sa; sa = sa->next) {
+ SpaceLink *sl = sa->spacedata.first;
+ for (; sl; sl = sl->next) {
+ if (sl->spacetype == SPACE_VIEW3D) {
+ View3D *v3d = (View3D *)sl;
+ if (v3d->localvd) {
+ local_view_bits |= v3d->local_view_uuid;
+ }
+ }
+ }
+ }
+ }
+
+ for (int i = 0; i < 16; i++) {
+ if ((local_view_bits & (1 << i)) == 0) {
+ return (1 << i);
+ }
+ }
+
+ return 0;
}
-static bool view3d_localview_init(
- const Depsgraph *depsgraph,
- wmWindowManager *wm,
- wmWindow *win,
- Main *bmain,
- ViewLayer *view_layer,
- ScrArea *sa,
- const bool frame_selected,
- const int smooth_viewtx,
- ReportList *reports)
+static bool view3d_localview_init(const Depsgraph *depsgraph,
+ wmWindowManager *wm,
+ wmWindow *win,
+ Main *bmain,
+ ViewLayer *view_layer,
+ ScrArea *sa,
+ const bool frame_selected,
+ const int smooth_viewtx,
+ ReportList *reports)
{
- View3D *v3d = sa->spacedata.first;
- Base *base;
- float min[3], max[3], box[3];
- float size = 0.0f;
- uint local_view_bit;
- bool ok = false;
-
- if (v3d->localvd) {
- return ok;
- }
-
- INIT_MINMAX(min, max);
-
- local_view_bit = free_localbit(bmain);
-
- if (local_view_bit == 0) {
- /* TODO(dfelinto): We can kick one of the other 3D views out of local view
- specially if it is not being used. */
- BKE_report(reports, RPT_ERROR, "No more than 16 local views");
- ok = false;
- }
- else {
- Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer);
- if (obedit) {
- FOREACH_BASE_IN_EDIT_MODE_BEGIN(view_layer, v3d, base_iter) {
- BKE_object_minmax(base_iter->object, min, max, false);
- base_iter->local_view_bits |= local_view_bit;
- ok = true;
- } FOREACH_BASE_IN_EDIT_MODE_END;
- }
- else {
- for (base = FIRSTBASE(view_layer); base; base = base->next) {
- if (BASE_SELECTED(v3d, base)) {
- BKE_object_minmax(base->object, min, max, false);
- base->local_view_bits |= local_view_bit;
- ok = true;
- }
- }
- }
-
- sub_v3_v3v3(box, max, min);
- size = max_fff(box[0], box[1], box[2]);
- }
-
- if (ok == false) {
- return false;
- }
-
- ARegion *ar;
-
- v3d->localvd = MEM_mallocN(sizeof(View3D), "localview");
-
- memcpy(v3d->localvd, v3d, sizeof(View3D));
- v3d->local_view_uuid = local_view_bit;
-
- for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->regiontype == RGN_TYPE_WINDOW) {
- RegionView3D *rv3d = ar->regiondata;
- bool ok_dist = true;
-
- /* New view values. */
- Object *camera_old = NULL;
- float dist_new, ofs_new[3];
-
- rv3d->localvd = MEM_mallocN(sizeof(RegionView3D), "localview region");
- memcpy(rv3d->localvd, rv3d, sizeof(RegionView3D));
-
- if (frame_selected) {
- float mid[3];
- mid_v3_v3v3(mid, min, max);
- negate_v3_v3(ofs_new, mid);
-
- if (rv3d->persp == RV3D_CAMOB) {
- rv3d->persp = RV3D_PERSP;
- camera_old = v3d->camera;
- }
-
- if (rv3d->persp == RV3D_ORTHO) {
- if (size < 0.0001f) {
- ok_dist = false;
- }
- }
-
- if (ok_dist) {
- dist_new = ED_view3d_radius_to_dist(v3d, ar, depsgraph, rv3d->persp, true, (size / 2) * VIEW3D_MARGIN);
-
- if (rv3d->persp == RV3D_PERSP) {
- /* Don't zoom closer than the near clipping plane. */
- dist_new = max_ff(dist_new, v3d->clip_start * 1.5f);
- }
- }
-
- ED_view3d_smooth_view_ex(
- depsgraph,
- wm, win, sa, v3d, ar, smooth_viewtx,
- &(const V3D_SmoothParams) {
- .camera_old = camera_old,
- .ofs = ofs_new, .quat = rv3d->viewquat,
- .dist = ok_dist ? &dist_new : NULL, .lens = &v3d->lens,
- });
- }
- }
- }
-
- return ok;
+ View3D *v3d = sa->spacedata.first;
+ Base *base;
+ float min[3], max[3], box[3];
+ float size = 0.0f;
+ uint local_view_bit;
+ bool ok = false;
+
+ if (v3d->localvd) {
+ return ok;
+ }
+
+ INIT_MINMAX(min, max);
+
+ local_view_bit = free_localbit(bmain);
+
+ if (local_view_bit == 0) {
+ /* TODO(dfelinto): We can kick one of the other 3D views out of local view
+ specially if it is not being used. */
+ BKE_report(reports, RPT_ERROR, "No more than 16 local views");
+ ok = false;
+ }
+ else {
+ Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer);
+ if (obedit) {
+ FOREACH_BASE_IN_EDIT_MODE_BEGIN (view_layer, v3d, base_iter) {
+ BKE_object_minmax(base_iter->object, min, max, false);
+ base_iter->local_view_bits |= local_view_bit;
+ ok = true;
+ }
+ FOREACH_BASE_IN_EDIT_MODE_END;
+ }
+ else {
+ for (base = FIRSTBASE(view_layer); base; base = base->next) {
+ if (BASE_SELECTED(v3d, base)) {
+ BKE_object_minmax(base->object, min, max, false);
+ base->local_view_bits |= local_view_bit;
+ ok = true;
+ }
+ }
+ }
+
+ sub_v3_v3v3(box, max, min);
+ size = max_fff(box[0], box[1], box[2]);
+ }
+
+ if (ok == false) {
+ return false;
+ }
+
+ ARegion *ar;
+
+ v3d->localvd = MEM_mallocN(sizeof(View3D), "localview");
+
+ memcpy(v3d->localvd, v3d, sizeof(View3D));
+ v3d->local_view_uuid = local_view_bit;
+
+ for (ar = sa->regionbase.first; ar; ar = ar->next) {
+ if (ar->regiontype == RGN_TYPE_WINDOW) {
+ RegionView3D *rv3d = ar->regiondata;
+ bool ok_dist = true;
+
+ /* New view values. */
+ Object *camera_old = NULL;
+ float dist_new, ofs_new[3];
+
+ rv3d->localvd = MEM_mallocN(sizeof(RegionView3D), "localview region");
+ memcpy(rv3d->localvd, rv3d, sizeof(RegionView3D));
+
+ if (frame_selected) {
+ float mid[3];
+ mid_v3_v3v3(mid, min, max);
+ negate_v3_v3(ofs_new, mid);
+
+ if (rv3d->persp == RV3D_CAMOB) {
+ rv3d->persp = RV3D_PERSP;
+ camera_old = v3d->camera;
+ }
+
+ if (rv3d->persp == RV3D_ORTHO) {
+ if (size < 0.0001f) {
+ ok_dist = false;
+ }
+ }
+
+ if (ok_dist) {
+ dist_new = ED_view3d_radius_to_dist(
+ v3d, ar, depsgraph, rv3d->persp, true, (size / 2) * VIEW3D_MARGIN);
+
+ if (rv3d->persp == RV3D_PERSP) {
+ /* Don't zoom closer than the near clipping plane. */
+ dist_new = max_ff(dist_new, v3d->clip_start * 1.5f);
+ }
+ }
+
+ ED_view3d_smooth_view_ex(depsgraph,
+ wm,
+ win,
+ sa,
+ v3d,
+ ar,
+ smooth_viewtx,
+ &(const V3D_SmoothParams){
+ .camera_old = camera_old,
+ .ofs = ofs_new,
+ .quat = rv3d->viewquat,
+ .dist = ok_dist ? &dist_new : NULL,
+ .lens = &v3d->lens,
+ });
+ }
+ }
+ }
+
+ return ok;
}
-static void view3d_localview_exit(
- const Depsgraph *depsgraph,
- wmWindowManager *wm,
- wmWindow *win,
- ViewLayer *view_layer,
- ScrArea *sa,
- const bool frame_selected,
- const int smooth_viewtx)
+static void view3d_localview_exit(const Depsgraph *depsgraph,
+ wmWindowManager *wm,
+ wmWindow *win,
+ ViewLayer *view_layer,
+ ScrArea *sa,
+ const bool frame_selected,
+ const int smooth_viewtx)
{
- View3D *v3d = sa->spacedata.first;
-
- if (v3d->localvd == NULL) {
- return;
- }
-
- for (Base *base = FIRSTBASE(view_layer); base; base = base->next) {
- if (base->local_view_bits & v3d->local_view_uuid) {
- base->local_view_bits &= ~v3d->local_view_uuid;
- }
- }
-
- Object *camera_old = v3d->camera;
- Object *camera_new = v3d->localvd->camera;
-
- v3d->local_view_uuid = 0;
- v3d->camera = v3d->localvd->camera;
-
- MEM_freeN(v3d->localvd);
- v3d->localvd = NULL;
-
- for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->regiontype == RGN_TYPE_WINDOW) {
- RegionView3D *rv3d = ar->regiondata;
-
- if (rv3d->localvd == NULL) {
- continue;
- }
-
- if (frame_selected) {
- Object *camera_old_rv3d, *camera_new_rv3d;
-
- camera_old_rv3d = (rv3d->persp == RV3D_CAMOB) ? camera_old : NULL;
- camera_new_rv3d = (rv3d->localvd->persp == RV3D_CAMOB) ? camera_new : NULL;
-
- rv3d->view = rv3d->localvd->view;
- rv3d->persp = rv3d->localvd->persp;
- rv3d->camzoom = rv3d->localvd->camzoom;
-
- ED_view3d_smooth_view_ex(
- depsgraph,
- wm, win, sa,
- v3d, ar, smooth_viewtx,
- &(const V3D_SmoothParams) {
- .camera_old = camera_old_rv3d, .camera = camera_new_rv3d,
- .ofs = rv3d->localvd->ofs, .quat = rv3d->localvd->viewquat,
- .dist = &rv3d->localvd->dist,
- });
- }
-
- MEM_freeN(rv3d->localvd);
- rv3d->localvd = NULL;
- }
- }
+ View3D *v3d = sa->spacedata.first;
+
+ if (v3d->localvd == NULL) {
+ return;
+ }
+
+ for (Base *base = FIRSTBASE(view_layer); base; base = base->next) {
+ if (base->local_view_bits & v3d->local_view_uuid) {
+ base->local_view_bits &= ~v3d->local_view_uuid;
+ }
+ }
+
+ Object *camera_old = v3d->camera;
+ Object *camera_new = v3d->localvd->camera;
+
+ v3d->local_view_uuid = 0;
+ v3d->camera = v3d->localvd->camera;
+
+ MEM_freeN(v3d->localvd);
+ v3d->localvd = NULL;
+
+ for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) {
+ if (ar->regiontype == RGN_TYPE_WINDOW) {
+ RegionView3D *rv3d = ar->regiondata;
+
+ if (rv3d->localvd == NULL) {
+ continue;
+ }
+
+ if (frame_selected) {
+ Object *camera_old_rv3d, *camera_new_rv3d;
+
+ camera_old_rv3d = (rv3d->persp == RV3D_CAMOB) ? camera_old : NULL;
+ camera_new_rv3d = (rv3d->localvd->persp == RV3D_CAMOB) ? camera_new : NULL;
+
+ rv3d->view = rv3d->localvd->view;
+ rv3d->persp = rv3d->localvd->persp;
+ rv3d->camzoom = rv3d->localvd->camzoom;
+
+ ED_view3d_smooth_view_ex(depsgraph,
+ wm,
+ win,
+ sa,
+ v3d,
+ ar,
+ smooth_viewtx,
+ &(const V3D_SmoothParams){
+ .camera_old = camera_old_rv3d,
+ .camera = camera_new_rv3d,
+ .ofs = rv3d->localvd->ofs,
+ .quat = rv3d->localvd->viewquat,
+ .dist = &rv3d->localvd->dist,
+ });
+ }
+
+ MEM_freeN(rv3d->localvd);
+ rv3d->localvd = NULL;
+ }
+ }
}
static int localview_exec(bContext *C, wmOperator *op)
{
- const Depsgraph *depsgraph = CTX_data_depsgraph(C);
- const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
- wmWindowManager *wm = CTX_wm_manager(C);
- wmWindow *win = CTX_wm_window(C);
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- ScrArea *sa = CTX_wm_area(C);
- View3D *v3d = CTX_wm_view3d(C);
- bool frame_selected = RNA_boolean_get(op->ptr, "frame_selected");
- bool changed;
-
- if (v3d->localvd) {
- view3d_localview_exit(depsgraph, wm, win, view_layer, sa, frame_selected, smooth_viewtx);
- changed = true;
- }
- else {
- changed = view3d_localview_init(depsgraph, wm, win, bmain, view_layer, sa, frame_selected, smooth_viewtx, op->reports);
- }
-
- if (changed) {
- DEG_id_type_tag(bmain, ID_OB);
- ED_area_tag_redraw(sa);
-
- /* Unselected objects become selected when exiting. */
- if (v3d->localvd == NULL) {
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- }
- else {
- DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
- }
-
- return OPERATOR_FINISHED;
- }
- else {
- return OPERATOR_CANCELLED;
- }
+ const Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
+ wmWindowManager *wm = CTX_wm_manager(C);
+ wmWindow *win = CTX_wm_window(C);
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ ScrArea *sa = CTX_wm_area(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ bool frame_selected = RNA_boolean_get(op->ptr, "frame_selected");
+ bool changed;
+
+ if (v3d->localvd) {
+ view3d_localview_exit(depsgraph, wm, win, view_layer, sa, frame_selected, smooth_viewtx);
+ changed = true;
+ }
+ else {
+ changed = view3d_localview_init(
+ depsgraph, wm, win, bmain, view_layer, sa, frame_selected, smooth_viewtx, op->reports);
+ }
+
+ if (changed) {
+ DEG_id_type_tag(bmain, ID_OB);
+ ED_area_tag_redraw(sa);
+
+ /* Unselected objects become selected when exiting. */
+ if (v3d->localvd == NULL) {
+ DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ }
+ else {
+ DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
+ }
+
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
void VIEW3D_OT_localview(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Local View";
- ot->description = "Toggle display of selected object(s) separately and centered in view";
- ot->idname = "VIEW3D_OT_localview";
-
- /* api callbacks */
- ot->exec = localview_exec;
- ot->flag = OPTYPE_UNDO; /* localview changes object layer bitflags */
-
- ot->poll = ED_operator_view3d_active;
-
- RNA_def_boolean(ot->srna, "frame_selected", true, "Frame Selected", "Move the view to frame the selected objects");
+ /* identifiers */
+ ot->name = "Local View";
+ ot->description = "Toggle display of selected object(s) separately and centered in view";
+ ot->idname = "VIEW3D_OT_localview";
+
+ /* api callbacks */
+ ot->exec = localview_exec;
+ ot->flag = OPTYPE_UNDO; /* localview changes object layer bitflags */
+
+ ot->poll = ED_operator_view3d_active;
+
+ RNA_def_boolean(ot->srna,
+ "frame_selected",
+ true,
+ "Frame Selected",
+ "Move the view to frame the selected objects");
}
static int localview_remove_from_exec(bContext *C, wmOperator *op)
{
- View3D *v3d = CTX_wm_view3d(C);
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- bool changed = false;
-
- for (Base *base = FIRSTBASE(view_layer); base; base = base->next) {
- if (BASE_SELECTED(v3d, base)) {
- base->local_view_bits &= ~v3d->local_view_uuid;
- ED_object_base_select(base, BA_DESELECT);
-
- if (base == BASACT(view_layer)) {
- view_layer->basact = NULL;
- }
- changed = true;
- }
- }
-
- if (changed) {
- DEG_on_visible_update(bmain, false);
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
- return OPERATOR_FINISHED;
- }
- else {
- BKE_report(op->reports, RPT_ERROR, "No object selected");
- return OPERATOR_CANCELLED;
- }
+ View3D *v3d = CTX_wm_view3d(C);
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ bool changed = false;
+
+ for (Base *base = FIRSTBASE(view_layer); base; base = base->next) {
+ if (BASE_SELECTED(v3d, base)) {
+ base->local_view_bits &= ~v3d->local_view_uuid;
+ ED_object_base_select(base, BA_DESELECT);
+
+ if (base == BASACT(view_layer)) {
+ view_layer->basact = NULL;
+ }
+ changed = true;
+ }
+ }
+
+ if (changed) {
+ DEG_on_visible_update(bmain, false);
+ DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
+ return OPERATOR_FINISHED;
+ }
+ else {
+ BKE_report(op->reports, RPT_ERROR, "No object selected");
+ return OPERATOR_CANCELLED;
+ }
}
static bool localview_remove_from_poll(bContext *C)
{
- if (CTX_data_edit_object(C) != NULL) {
- return false;
- }
+ if (CTX_data_edit_object(C) != NULL) {
+ return false;
+ }
- View3D *v3d = CTX_wm_view3d(C);
- return v3d && v3d->localvd;
+ View3D *v3d = CTX_wm_view3d(C);
+ return v3d && v3d->localvd;
}
void VIEW3D_OT_localview_remove_from(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Remove from Local View";
- ot->description = "Move selected objects out of local view";
- ot->idname = "VIEW3D_OT_localview_remove_from";
-
- /* api callbacks */
- ot->exec = localview_remove_from_exec;
- ot->invoke = WM_operator_confirm;
- ot->poll = localview_remove_from_poll;
- ot->flag = OPTYPE_UNDO;
+ /* identifiers */
+ ot->name = "Remove from Local View";
+ ot->description = "Move selected objects out of local view";
+ ot->idname = "VIEW3D_OT_localview_remove_from";
+
+ /* api callbacks */
+ ot->exec = localview_remove_from_exec;
+ ot->invoke = WM_operator_confirm;
+ ot->poll = localview_remove_from_poll;
+ ot->flag = OPTYPE_UNDO;
}
/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c
index a015b7f9945..a0613d3b76f 100644
--- a/source/blender/editors/space_view3d/view3d_walk.c
+++ b/source/blender/editors/space_view3d/view3d_walk.c
@@ -52,7 +52,7 @@
#include "DEG_depsgraph.h"
-#include "view3d_intern.h" /* own include */
+#include "view3d_intern.h" /* own include */
#ifdef WITH_INPUT_NDOF
//# define NDOF_WALK_DEBUG
@@ -71,330 +71,344 @@ static float getVelocityZeroTime(const float gravity, const float velocity);
/* NOTE: these defines are saved in keymap files,
* do not change values but just add new ones */
enum {
- WALK_MODAL_CANCEL = 1,
- WALK_MODAL_CONFIRM,
- WALK_MODAL_DIR_FORWARD,
- WALK_MODAL_DIR_FORWARD_STOP,
- WALK_MODAL_DIR_BACKWARD,
- WALK_MODAL_DIR_BACKWARD_STOP,
- WALK_MODAL_DIR_LEFT,
- WALK_MODAL_DIR_LEFT_STOP,
- WALK_MODAL_DIR_RIGHT,
- WALK_MODAL_DIR_RIGHT_STOP,
- WALK_MODAL_DIR_UP,
- WALK_MODAL_DIR_UP_STOP,
- WALK_MODAL_DIR_DOWN,
- WALK_MODAL_DIR_DOWN_STOP,
- WALK_MODAL_FAST_ENABLE,
- WALK_MODAL_FAST_DISABLE,
- WALK_MODAL_SLOW_ENABLE,
- WALK_MODAL_SLOW_DISABLE,
- WALK_MODAL_JUMP,
- WALK_MODAL_JUMP_STOP,
- WALK_MODAL_TELEPORT,
- WALK_MODAL_TOGGLE,
- WALK_MODAL_ACCELERATE,
- WALK_MODAL_DECELERATE,
+ WALK_MODAL_CANCEL = 1,
+ WALK_MODAL_CONFIRM,
+ WALK_MODAL_DIR_FORWARD,
+ WALK_MODAL_DIR_FORWARD_STOP,
+ WALK_MODAL_DIR_BACKWARD,
+ WALK_MODAL_DIR_BACKWARD_STOP,
+ WALK_MODAL_DIR_LEFT,
+ WALK_MODAL_DIR_LEFT_STOP,
+ WALK_MODAL_DIR_RIGHT,
+ WALK_MODAL_DIR_RIGHT_STOP,
+ WALK_MODAL_DIR_UP,
+ WALK_MODAL_DIR_UP_STOP,
+ WALK_MODAL_DIR_DOWN,
+ WALK_MODAL_DIR_DOWN_STOP,
+ WALK_MODAL_FAST_ENABLE,
+ WALK_MODAL_FAST_DISABLE,
+ WALK_MODAL_SLOW_ENABLE,
+ WALK_MODAL_SLOW_DISABLE,
+ WALK_MODAL_JUMP,
+ WALK_MODAL_JUMP_STOP,
+ WALK_MODAL_TELEPORT,
+ WALK_MODAL_TOGGLE,
+ WALK_MODAL_ACCELERATE,
+ WALK_MODAL_DECELERATE,
};
enum {
- WALK_BIT_FORWARD = 1 << 0,
- WALK_BIT_BACKWARD = 1 << 1,
- WALK_BIT_LEFT = 1 << 2,
- WALK_BIT_RIGHT = 1 << 3,
- WALK_BIT_UP = 1 << 4,
- WALK_BIT_DOWN = 1 << 5,
+ WALK_BIT_FORWARD = 1 << 0,
+ WALK_BIT_BACKWARD = 1 << 1,
+ WALK_BIT_LEFT = 1 << 2,
+ WALK_BIT_RIGHT = 1 << 3,
+ WALK_BIT_UP = 1 << 4,
+ WALK_BIT_DOWN = 1 << 5,
};
typedef enum eWalkTeleportState {
- WALK_TELEPORT_STATE_OFF = 0,
- WALK_TELEPORT_STATE_ON,
+ WALK_TELEPORT_STATE_OFF = 0,
+ WALK_TELEPORT_STATE_ON,
} eWalkTeleportState;
typedef enum eWalkMethod {
- WALK_MODE_FREE = 0,
- WALK_MODE_GRAVITY,
+ WALK_MODE_FREE = 0,
+ WALK_MODE_GRAVITY,
} eWalkMethod;
typedef enum eWalkGravityState {
- WALK_GRAVITY_STATE_OFF = 0,
- WALK_GRAVITY_STATE_JUMP,
- WALK_GRAVITY_STATE_START,
- WALK_GRAVITY_STATE_ON,
+ WALK_GRAVITY_STATE_OFF = 0,
+ WALK_GRAVITY_STATE_JUMP,
+ WALK_GRAVITY_STATE_START,
+ WALK_GRAVITY_STATE_ON,
} eWalkGravityState;
/* called in transform_ops.c, on each regeneration of keymaps */
void walk_modal_keymap(wmKeyConfig *keyconf)
{
- static const EnumPropertyItem modal_items[] = {
- {WALK_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
- {WALK_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
+ static const EnumPropertyItem modal_items[] = {
+ {WALK_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
+ {WALK_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
- {WALK_MODAL_DIR_FORWARD, "FORWARD", 0, "Forward", ""},
- {WALK_MODAL_DIR_BACKWARD, "BACKWARD", 0, "Backward", ""},
- {WALK_MODAL_DIR_LEFT, "LEFT", 0, "Left (Strafe)", ""},
- {WALK_MODAL_DIR_RIGHT, "RIGHT", 0, "Right (Strafe)", ""},
- {WALK_MODAL_DIR_UP, "UP", 0, "Up", ""},
- {WALK_MODAL_DIR_DOWN, "DOWN", 0, "Down", ""},
+ {WALK_MODAL_DIR_FORWARD, "FORWARD", 0, "Forward", ""},
+ {WALK_MODAL_DIR_BACKWARD, "BACKWARD", 0, "Backward", ""},
+ {WALK_MODAL_DIR_LEFT, "LEFT", 0, "Left (Strafe)", ""},
+ {WALK_MODAL_DIR_RIGHT, "RIGHT", 0, "Right (Strafe)", ""},
+ {WALK_MODAL_DIR_UP, "UP", 0, "Up", ""},
+ {WALK_MODAL_DIR_DOWN, "DOWN", 0, "Down", ""},
- {WALK_MODAL_DIR_FORWARD_STOP, "FORWARD_STOP", 0, "Stop Move Forward", ""},
- {WALK_MODAL_DIR_BACKWARD_STOP, "BACKWARD_STOP", 0, "Stop Mode Backward", ""},
- {WALK_MODAL_DIR_LEFT_STOP, "LEFT_STOP", 0, "Stop Move Left", ""},
- {WALK_MODAL_DIR_RIGHT_STOP, "RIGHT_STOP", 0, "Stop Mode Right", ""},
- {WALK_MODAL_DIR_UP_STOP, "UP_STOP", 0, "Stop Move Up", ""},
- {WALK_MODAL_DIR_DOWN_STOP, "DOWN_STOP", 0, "Stop Mode Down", ""},
+ {WALK_MODAL_DIR_FORWARD_STOP, "FORWARD_STOP", 0, "Stop Move Forward", ""},
+ {WALK_MODAL_DIR_BACKWARD_STOP, "BACKWARD_STOP", 0, "Stop Mode Backward", ""},
+ {WALK_MODAL_DIR_LEFT_STOP, "LEFT_STOP", 0, "Stop Move Left", ""},
+ {WALK_MODAL_DIR_RIGHT_STOP, "RIGHT_STOP", 0, "Stop Mode Right", ""},
+ {WALK_MODAL_DIR_UP_STOP, "UP_STOP", 0, "Stop Move Up", ""},
+ {WALK_MODAL_DIR_DOWN_STOP, "DOWN_STOP", 0, "Stop Mode Down", ""},
- {WALK_MODAL_TELEPORT, "TELEPORT", 0, "Teleport", "Move forward a few units at once"},
+ {WALK_MODAL_TELEPORT, "TELEPORT", 0, "Teleport", "Move forward a few units at once"},
- {WALK_MODAL_ACCELERATE, "ACCELERATE", 0, "Accelerate", ""},
- {WALK_MODAL_DECELERATE, "DECELERATE", 0, "Decelerate", ""},
+ {WALK_MODAL_ACCELERATE, "ACCELERATE", 0, "Accelerate", ""},
+ {WALK_MODAL_DECELERATE, "DECELERATE", 0, "Decelerate", ""},
- {WALK_MODAL_FAST_ENABLE, "FAST_ENABLE", 0, "Fast", "Move faster (walk or fly)"},
- {WALK_MODAL_FAST_DISABLE, "FAST_DISABLE", 0, "Fast (Off)", "Resume regular speed"},
+ {WALK_MODAL_FAST_ENABLE, "FAST_ENABLE", 0, "Fast", "Move faster (walk or fly)"},
+ {WALK_MODAL_FAST_DISABLE, "FAST_DISABLE", 0, "Fast (Off)", "Resume regular speed"},
- {WALK_MODAL_SLOW_ENABLE, "SLOW_ENABLE", 0, "Slow", "Move slower (walk or fly)"},
- {WALK_MODAL_SLOW_DISABLE, "SLOW_DISABLE", 0, "Slow (Off)", "Resume regular speed"},
+ {WALK_MODAL_SLOW_ENABLE, "SLOW_ENABLE", 0, "Slow", "Move slower (walk or fly)"},
+ {WALK_MODAL_SLOW_DISABLE, "SLOW_DISABLE", 0, "Slow (Off)", "Resume regular speed"},
- {WALK_MODAL_JUMP, "JUMP", 0, "Jump", "Jump when in walk mode"},
- {WALK_MODAL_JUMP_STOP, "JUMP_STOP", 0, "Jump (Off)", "Stop pushing jump"},
+ {WALK_MODAL_JUMP, "JUMP", 0, "Jump", "Jump when in walk mode"},
+ {WALK_MODAL_JUMP_STOP, "JUMP_STOP", 0, "Jump (Off)", "Stop pushing jump"},
- {WALK_MODAL_TOGGLE, "GRAVITY_TOGGLE", 0, "Toggle Gravity", "Toggle gravity effect"},
+ {WALK_MODAL_TOGGLE, "GRAVITY_TOGGLE", 0, "Toggle Gravity", "Toggle gravity effect"},
- {0, NULL, 0, NULL, NULL},
- };
+ {0, NULL, 0, NULL, NULL},
+ };
- wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Walk Modal");
+ wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Walk Modal");
- /* this function is called for each spacetype, only needs to add map once */
- if (keymap && keymap->modal_items) {
- return;
- }
+ /* this function is called for each spacetype, only needs to add map once */
+ if (keymap && keymap->modal_items) {
+ return;
+ }
- keymap = WM_modalkeymap_add(keyconf, "View3D Walk Modal", modal_items);
+ keymap = WM_modalkeymap_add(keyconf, "View3D Walk Modal", modal_items);
- /* assign map to operators */
- WM_modalkeymap_assign(keymap, "VIEW3D_OT_walk");
+ /* assign map to operators */
+ WM_modalkeymap_assign(keymap, "VIEW3D_OT_walk");
}
-
typedef struct WalkTeleport {
- eWalkTeleportState state;
- float duration; /* from user preferences */
- float origin[3];
- float direction[3];
- double initial_time;
- eWalkMethod navigation_mode; /* teleport always set FREE mode on */
+ eWalkTeleportState state;
+ float duration; /* from user preferences */
+ float origin[3];
+ float direction[3];
+ double initial_time;
+ eWalkMethod navigation_mode; /* teleport always set FREE mode on */
} WalkTeleport;
typedef struct WalkInfo {
- /* context stuff */
- RegionView3D *rv3d;
- View3D *v3d;
- ARegion *ar;
- struct Depsgraph *depsgraph;
- Scene *scene;
+ /* context stuff */
+ RegionView3D *rv3d;
+ View3D *v3d;
+ ARegion *ar;
+ struct Depsgraph *depsgraph;
+ Scene *scene;
- wmTimer *timer; /* needed for redraws */
+ wmTimer *timer; /* needed for redraws */
- short state;
- bool redraw;
+ short state;
+ bool redraw;
- int prev_mval[2]; /* previous 2D mouse values */
- int center_mval[2]; /* center mouse values */
- int moffset[2];
+ int prev_mval[2]; /* previous 2D mouse values */
+ int center_mval[2]; /* center mouse values */
+ int moffset[2];
#ifdef WITH_INPUT_NDOF
- wmNDOFMotionData *ndof; /* latest 3D mouse values */
+ wmNDOFMotionData *ndof; /* latest 3D mouse values */
#endif
- /* walk state state */
- float base_speed; /* the base speed without run/slow down modifications */
- float speed; /* the speed the view is moving per redraw */
- float grid; /* world scale 1.0 default */
+ /* walk state state */
+ float base_speed; /* the base speed without run/slow down modifications */
+ float speed; /* the speed the view is moving per redraw */
+ float grid; /* world scale 1.0 default */
- /* compare between last state */
- double time_lastdraw; /* time between draws */
+ /* compare between last state */
+ double time_lastdraw; /* time between draws */
- void *draw_handle_pixel;
+ void *draw_handle_pixel;
- /* use for some lag */
- float dvec_prev[3]; /* old for some lag */
+ /* use for some lag */
+ float dvec_prev[3]; /* old for some lag */
- /* walk/fly */
- eWalkMethod navigation_mode;
+ /* walk/fly */
+ eWalkMethod navigation_mode;
- /* teleport */
- WalkTeleport teleport;
+ /* teleport */
+ WalkTeleport teleport;
- /* look speed factor - user preferences */
- float mouse_speed;
+ /* look speed factor - user preferences */
+ float mouse_speed;
- /* speed adjustments */
- bool is_fast;
- bool is_slow;
+ /* speed adjustments */
+ bool is_fast;
+ bool is_slow;
- /* mouse reverse */
- bool is_reversed;
+ /* mouse reverse */
+ bool is_reversed;
#ifdef USE_TABLET_SUPPORT
- /* check if we had a cursor event before */
- bool is_cursor_first;
+ /* check if we had a cursor event before */
+ bool is_cursor_first;
- /* tablet devices (we can't relocate the cursor) */
- bool is_cursor_absolute;
+ /* tablet devices (we can't relocate the cursor) */
+ bool is_cursor_absolute;
#endif
- /* gravity system */
- eWalkGravityState gravity_state;
- float gravity;
+ /* gravity system */
+ eWalkGravityState gravity_state;
+ float gravity;
- /* height to use in walk mode */
- float view_height;
+ /* height to use in walk mode */
+ float view_height;
- /* counting system to allow movement to continue if a direction (WASD) key is still pressed */
- int active_directions;
+ /* counting system to allow movement to continue if a direction (WASD) key is still pressed */
+ int active_directions;
- float speed_jump;
- float jump_height; /* maximum jump height */
- float speed_factor; /* to use for fast/slow speeds */
+ float speed_jump;
+ float jump_height; /* maximum jump height */
+ float speed_factor; /* to use for fast/slow speeds */
- struct SnapObjectContext *snap_context;
+ struct SnapObjectContext *snap_context;
- struct View3DCameraControl *v3d_camera_control;
+ struct View3DCameraControl *v3d_camera_control;
} WalkInfo;
static void drawWalkPixel(const struct bContext *UNUSED(C), ARegion *ar, void *arg)
{
- /* draws an aim/cross in the center */
- WalkInfo *walk = arg;
+ /* draws an aim/cross in the center */
+ WalkInfo *walk = arg;
- const int outter_length = 24;
- const int inner_length = 14;
- int xoff, yoff;
- rctf viewborder;
+ const int outter_length = 24;
+ const int inner_length = 14;
+ int xoff, yoff;
+ rctf viewborder;
- if (ED_view3d_cameracontrol_object_get(walk->v3d_camera_control)) {
- ED_view3d_calc_camera_border(walk->scene, walk->depsgraph, ar, walk->v3d, walk->rv3d, &viewborder, false);
- xoff = viewborder.xmin + BLI_rctf_size_x(&viewborder) * 0.5f;
- yoff = viewborder.ymin + BLI_rctf_size_y(&viewborder) * 0.5f;
- }
- else {
- xoff = walk->ar->winx / 2;
- yoff = walk->ar->winy / 2;
- }
+ if (ED_view3d_cameracontrol_object_get(walk->v3d_camera_control)) {
+ ED_view3d_calc_camera_border(
+ walk->scene, walk->depsgraph, ar, walk->v3d, walk->rv3d, &viewborder, false);
+ xoff = viewborder.xmin + BLI_rctf_size_x(&viewborder) * 0.5f;
+ yoff = viewborder.ymin + BLI_rctf_size_y(&viewborder) * 0.5f;
+ }
+ else {
+ xoff = walk->ar->winx / 2;
+ yoff = walk->ar->winy / 2;
+ }
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformThemeColor(TH_VIEW_OVERLAY);
+ immUniformThemeColor(TH_VIEW_OVERLAY);
- immBegin(GPU_PRIM_LINES, 8);
+ immBegin(GPU_PRIM_LINES, 8);
- /* North */
- immVertex2i(pos, xoff, yoff + inner_length);
- immVertex2i(pos, xoff, yoff + outter_length);
+ /* North */
+ immVertex2i(pos, xoff, yoff + inner_length);
+ immVertex2i(pos, xoff, yoff + outter_length);
- /* East */
- immVertex2i(pos, xoff + inner_length, yoff);
- immVertex2i(pos, xoff + outter_length, yoff);
+ /* East */
+ immVertex2i(pos, xoff + inner_length, yoff);
+ immVertex2i(pos, xoff + outter_length, yoff);
- /* South */
- immVertex2i(pos, xoff, yoff - inner_length);
- immVertex2i(pos, xoff, yoff - outter_length);
+ /* South */
+ immVertex2i(pos, xoff, yoff - inner_length);
+ immVertex2i(pos, xoff, yoff - outter_length);
- /* West */
- immVertex2i(pos, xoff - inner_length, yoff);
- immVertex2i(pos, xoff - outter_length, yoff);
+ /* West */
+ immVertex2i(pos, xoff - inner_length, yoff);
+ immVertex2i(pos, xoff - outter_length, yoff);
- immEnd();
- immUnbindProgram();
+ immEnd();
+ immUnbindProgram();
}
static void walk_update_header(bContext *C, wmOperator *op, WalkInfo *walk)
{
- const bool gravity = (walk->navigation_mode == WALK_MODE_GRAVITY) ||
- ((walk->teleport.state == WALK_TELEPORT_STATE_ON) &&
- (walk->teleport.navigation_mode == WALK_MODE_GRAVITY));
- char header[UI_MAX_DRAW_STR];
- char buf[UI_MAX_DRAW_STR];
+ const bool gravity = (walk->navigation_mode == WALK_MODE_GRAVITY) ||
+ ((walk->teleport.state == WALK_TELEPORT_STATE_ON) &&
+ (walk->teleport.navigation_mode == WALK_MODE_GRAVITY));
+ char header[UI_MAX_DRAW_STR];
+ char buf[UI_MAX_DRAW_STR];
- char *p = buf;
- int available_len = sizeof(buf);
+ char *p = buf;
+ int available_len = sizeof(buf);
#define WM_MODALKEY(_id) \
- WM_modalkeymap_operator_items_to_string_buf(op->type, (_id), true, UI_MAX_SHORTCUT_STR, &available_len, &p)
-
- BLI_snprintf(header, sizeof(header), IFACE_("%s: confirm, %s: cancel, "
- "%s: gravity (%s), "
- "%s|%s|%s|%s: move around, "
- "%s: fast, %s: slow, "
- "%s|%s: up and down, "
- "%s: teleport, %s: jump, "
- "%s: increase speed, %s: decrease speed"),
- WM_MODALKEY(WALK_MODAL_CONFIRM), WM_MODALKEY(WALK_MODAL_CANCEL),
- WM_MODALKEY(WALK_MODAL_TOGGLE), WM_bool_as_string(gravity),
- WM_MODALKEY(WALK_MODAL_DIR_FORWARD), WM_MODALKEY(WALK_MODAL_DIR_LEFT),
- WM_MODALKEY(WALK_MODAL_DIR_BACKWARD), WM_MODALKEY(WALK_MODAL_DIR_RIGHT),
- WM_MODALKEY(WALK_MODAL_FAST_ENABLE), WM_MODALKEY(WALK_MODAL_SLOW_ENABLE),
- WM_MODALKEY(WALK_MODAL_DIR_UP), WM_MODALKEY(WALK_MODAL_DIR_DOWN),
- WM_MODALKEY(WALK_MODAL_TELEPORT), WM_MODALKEY(WALK_MODAL_JUMP),
- WM_MODALKEY(WALK_MODAL_ACCELERATE), WM_MODALKEY(WALK_MODAL_DECELERATE));
+ WM_modalkeymap_operator_items_to_string_buf( \
+ op->type, (_id), true, UI_MAX_SHORTCUT_STR, &available_len, &p)
+
+ BLI_snprintf(header,
+ sizeof(header),
+ IFACE_("%s: confirm, %s: cancel, "
+ "%s: gravity (%s), "
+ "%s|%s|%s|%s: move around, "
+ "%s: fast, %s: slow, "
+ "%s|%s: up and down, "
+ "%s: teleport, %s: jump, "
+ "%s: increase speed, %s: decrease speed"),
+ WM_MODALKEY(WALK_MODAL_CONFIRM),
+ WM_MODALKEY(WALK_MODAL_CANCEL),
+ WM_MODALKEY(WALK_MODAL_TOGGLE),
+ WM_bool_as_string(gravity),
+ WM_MODALKEY(WALK_MODAL_DIR_FORWARD),
+ WM_MODALKEY(WALK_MODAL_DIR_LEFT),
+ WM_MODALKEY(WALK_MODAL_DIR_BACKWARD),
+ WM_MODALKEY(WALK_MODAL_DIR_RIGHT),
+ WM_MODALKEY(WALK_MODAL_FAST_ENABLE),
+ WM_MODALKEY(WALK_MODAL_SLOW_ENABLE),
+ WM_MODALKEY(WALK_MODAL_DIR_UP),
+ WM_MODALKEY(WALK_MODAL_DIR_DOWN),
+ WM_MODALKEY(WALK_MODAL_TELEPORT),
+ WM_MODALKEY(WALK_MODAL_JUMP),
+ WM_MODALKEY(WALK_MODAL_ACCELERATE),
+ WM_MODALKEY(WALK_MODAL_DECELERATE));
#undef WM_MODALKEY
- ED_workspace_status_text(C, header);
+ ED_workspace_status_text(C, header);
}
static void walk_navigation_mode_set(bContext *C, wmOperator *op, WalkInfo *walk, eWalkMethod mode)
{
- if (mode == WALK_MODE_FREE) {
- walk->navigation_mode = WALK_MODE_FREE;
- walk->gravity_state = WALK_GRAVITY_STATE_OFF;
- }
- else { /* WALK_MODE_GRAVITY */
- walk->navigation_mode = WALK_MODE_GRAVITY;
- walk->gravity_state = WALK_GRAVITY_STATE_START;
- }
-
- walk_update_header(C, op, walk);
+ if (mode == WALK_MODE_FREE) {
+ walk->navigation_mode = WALK_MODE_FREE;
+ walk->gravity_state = WALK_GRAVITY_STATE_OFF;
+ }
+ else { /* WALK_MODE_GRAVITY */
+ walk->navigation_mode = WALK_MODE_GRAVITY;
+ walk->gravity_state = WALK_GRAVITY_STATE_START;
+ }
+
+ walk_update_header(C, op, walk);
}
/**
* \param r_distance: Distance to the hit point
*/
-static bool walk_floor_distance_get(
- RegionView3D *rv3d, WalkInfo *walk, const float dvec[3],
- float *r_distance)
+static bool walk_floor_distance_get(RegionView3D *rv3d,
+ WalkInfo *walk,
+ const float dvec[3],
+ float *r_distance)
{
- float ray_normal[3] = {0, 0, -1}; /* down */
- float ray_start[3];
- float r_location[3];
- float r_normal_dummy[3];
- float dvec_tmp[3];
- bool ret;
-
- *r_distance = BVH_RAYCAST_DIST_MAX;
-
- copy_v3_v3(ray_start, rv3d->viewinv[3]);
-
- mul_v3_v3fl(dvec_tmp, dvec, walk->grid);
- add_v3_v3(ray_start, dvec_tmp);
-
- ret = ED_transform_snap_object_project_ray(
- walk->snap_context,
- &(const struct SnapObjectParams){
- .snap_select = SNAP_ALL,
- },
- ray_start, ray_normal, r_distance,
- r_location, r_normal_dummy);
-
- /* artificially scale the distance to the scene size */
- *r_distance /= walk->grid;
- return ret;
+ float ray_normal[3] = {0, 0, -1}; /* down */
+ float ray_start[3];
+ float r_location[3];
+ float r_normal_dummy[3];
+ float dvec_tmp[3];
+ bool ret;
+
+ *r_distance = BVH_RAYCAST_DIST_MAX;
+
+ copy_v3_v3(ray_start, rv3d->viewinv[3]);
+
+ mul_v3_v3fl(dvec_tmp, dvec, walk->grid);
+ add_v3_v3(ray_start, dvec_tmp);
+
+ ret = ED_transform_snap_object_project_ray(walk->snap_context,
+ &(const struct SnapObjectParams){
+ .snap_select = SNAP_ALL,
+ },
+ ray_start,
+ ray_normal,
+ r_distance,
+ r_location,
+ r_normal_dummy);
+
+ /* artificially scale the distance to the scene size */
+ *r_distance /= walk->grid;
+ return ret;
}
/**
@@ -402,46 +416,50 @@ static bool walk_floor_distance_get(
* \param r_location: Location of the hit point
* \param r_normal: Normal of the hit surface, transformed to always face the camera
*/
-static bool walk_ray_cast(
- RegionView3D *rv3d, WalkInfo *walk,
- float r_location[3], float r_normal[3], float *ray_distance)
+static bool walk_ray_cast(RegionView3D *rv3d,
+ WalkInfo *walk,
+ float r_location[3],
+ float r_normal[3],
+ float *ray_distance)
{
- float ray_normal[3] = {0, 0, -1}; /* forward */
- float ray_start[3];
- bool ret;
+ float ray_normal[3] = {0, 0, -1}; /* forward */
+ float ray_start[3];
+ bool ret;
- *ray_distance = BVH_RAYCAST_DIST_MAX;
+ *ray_distance = BVH_RAYCAST_DIST_MAX;
- copy_v3_v3(ray_start, rv3d->viewinv[3]);
+ copy_v3_v3(ray_start, rv3d->viewinv[3]);
- mul_mat3_m4_v3(rv3d->viewinv, ray_normal);
+ mul_mat3_m4_v3(rv3d->viewinv, ray_normal);
- normalize_v3(ray_normal);
+ normalize_v3(ray_normal);
- ret = ED_transform_snap_object_project_ray(
- walk->snap_context,
- &(const struct SnapObjectParams){
- .snap_select = SNAP_ALL,
- },
- ray_start, ray_normal, NULL,
- r_location, r_normal);
+ ret = ED_transform_snap_object_project_ray(walk->snap_context,
+ &(const struct SnapObjectParams){
+ .snap_select = SNAP_ALL,
+ },
+ ray_start,
+ ray_normal,
+ NULL,
+ r_location,
+ r_normal);
- /* dot is positive if both rays are facing the same direction */
- if (dot_v3v3(ray_normal, r_normal) > 0) {
- negate_v3(r_normal);
- }
+ /* dot is positive if both rays are facing the same direction */
+ if (dot_v3v3(ray_normal, r_normal) > 0) {
+ negate_v3(r_normal);
+ }
- /* artificially scale the distance to the scene size */
- *ray_distance /= walk->grid;
+ /* artificially scale the distance to the scene size */
+ *ray_distance /= walk->grid;
- return ret;
+ return ret;
}
/* WalkInfo->state */
enum {
- WALK_RUNNING = 0,
- WALK_CANCEL = 1,
- WALK_CONFIRM = 2,
+ WALK_RUNNING = 0,
+ WALK_CANCEL = 1,
+ WALK_CONFIRM = 2,
};
/* keep the previous speed until user changes userpreferences */
@@ -450,484 +468,484 @@ static float userdef_speed = -1.f;
static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
- wmWindow *win = CTX_wm_window(C);
+ Main *bmain = CTX_data_main(C);
+ wmWindow *win = CTX_wm_window(C);
- walk->rv3d = CTX_wm_region_view3d(C);
- walk->v3d = CTX_wm_view3d(C);
- walk->ar = CTX_wm_region(C);
- walk->depsgraph = CTX_data_depsgraph(C);
- walk->scene = CTX_data_scene(C);
+ walk->rv3d = CTX_wm_region_view3d(C);
+ walk->v3d = CTX_wm_view3d(C);
+ walk->ar = CTX_wm_region(C);
+ walk->depsgraph = CTX_data_depsgraph(C);
+ walk->scene = CTX_data_scene(C);
#ifdef NDOF_WALK_DEBUG
- puts("\n-- walk begin --");
+ puts("\n-- walk begin --");
#endif
- /* sanity check: for rare but possible case (if lib-linking the camera fails) */
- if ((walk->rv3d->persp == RV3D_CAMOB) && (walk->v3d->camera == NULL)) {
- walk->rv3d->persp = RV3D_PERSP;
- }
-
- if (walk->rv3d->persp == RV3D_CAMOB && ID_IS_LINKED(walk->v3d->camera)) {
- BKE_report(op->reports, RPT_ERROR, "Cannot navigate a camera from an external library");
- return false;
- }
-
- if (ED_view3d_offset_lock_check(walk->v3d, walk->rv3d)) {
- BKE_report(op->reports, RPT_ERROR, "Cannot navigate when the view offset is locked");
- return false;
- }
-
- if (walk->rv3d->persp == RV3D_CAMOB && walk->v3d->camera->constraints.first) {
- BKE_report(op->reports, RPT_ERROR, "Cannot navigate an object with constraints");
- return false;
- }
-
- walk->state = WALK_RUNNING;
-
- if (fabsf(U.walk_navigation.walk_speed - userdef_speed) > 0.1f) {
- base_speed = U.walk_navigation.walk_speed;
- userdef_speed = U.walk_navigation.walk_speed;
- }
-
- walk->speed = 0.0f;
- walk->is_fast = false;
- walk->is_slow = false;
- walk->grid = (walk->scene->unit.system == USER_UNIT_NONE) ? 1.f : 1.f / walk->scene->unit.scale_length;
-
- /* user preference settings */
- walk->teleport.duration = U.walk_navigation.teleport_time;
- walk->mouse_speed = U.walk_navigation.mouse_speed;
-
- if ((U.walk_navigation.flag & USER_WALK_GRAVITY)) {
- walk_navigation_mode_set(C, op, walk, WALK_MODE_GRAVITY);
- }
- else {
- walk_navigation_mode_set(C, op, walk, WALK_MODE_FREE);
- }
-
- walk->view_height = U.walk_navigation.view_height;
- walk->jump_height = U.walk_navigation.jump_height;
- walk->speed = U.walk_navigation.walk_speed;
- walk->speed_factor = U.walk_navigation.walk_speed_factor;
-
- walk->gravity_state = WALK_GRAVITY_STATE_OFF;
-
- if ((walk->scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY)) {
- walk->gravity = fabsf(walk->scene->physics_settings.gravity[2]);
- }
- else {
- walk->gravity = 9.80668f; /* m/s2 */
- }
-
- walk->is_reversed = ((U.walk_navigation.flag & USER_WALK_MOUSE_REVERSE) != 0);
+ /* sanity check: for rare but possible case (if lib-linking the camera fails) */
+ if ((walk->rv3d->persp == RV3D_CAMOB) && (walk->v3d->camera == NULL)) {
+ walk->rv3d->persp = RV3D_PERSP;
+ }
+
+ if (walk->rv3d->persp == RV3D_CAMOB && ID_IS_LINKED(walk->v3d->camera)) {
+ BKE_report(op->reports, RPT_ERROR, "Cannot navigate a camera from an external library");
+ return false;
+ }
+
+ if (ED_view3d_offset_lock_check(walk->v3d, walk->rv3d)) {
+ BKE_report(op->reports, RPT_ERROR, "Cannot navigate when the view offset is locked");
+ return false;
+ }
+
+ if (walk->rv3d->persp == RV3D_CAMOB && walk->v3d->camera->constraints.first) {
+ BKE_report(op->reports, RPT_ERROR, "Cannot navigate an object with constraints");
+ return false;
+ }
+
+ walk->state = WALK_RUNNING;
+
+ if (fabsf(U.walk_navigation.walk_speed - userdef_speed) > 0.1f) {
+ base_speed = U.walk_navigation.walk_speed;
+ userdef_speed = U.walk_navigation.walk_speed;
+ }
+
+ walk->speed = 0.0f;
+ walk->is_fast = false;
+ walk->is_slow = false;
+ walk->grid = (walk->scene->unit.system == USER_UNIT_NONE) ? 1.f :
+ 1.f / walk->scene->unit.scale_length;
+
+ /* user preference settings */
+ walk->teleport.duration = U.walk_navigation.teleport_time;
+ walk->mouse_speed = U.walk_navigation.mouse_speed;
+
+ if ((U.walk_navigation.flag & USER_WALK_GRAVITY)) {
+ walk_navigation_mode_set(C, op, walk, WALK_MODE_GRAVITY);
+ }
+ else {
+ walk_navigation_mode_set(C, op, walk, WALK_MODE_FREE);
+ }
+
+ walk->view_height = U.walk_navigation.view_height;
+ walk->jump_height = U.walk_navigation.jump_height;
+ walk->speed = U.walk_navigation.walk_speed;
+ walk->speed_factor = U.walk_navigation.walk_speed_factor;
+
+ walk->gravity_state = WALK_GRAVITY_STATE_OFF;
+
+ if ((walk->scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY)) {
+ walk->gravity = fabsf(walk->scene->physics_settings.gravity[2]);
+ }
+ else {
+ walk->gravity = 9.80668f; /* m/s2 */
+ }
+
+ walk->is_reversed = ((U.walk_navigation.flag & USER_WALK_MOUSE_REVERSE) != 0);
#ifdef USE_TABLET_SUPPORT
- walk->is_cursor_first = true;
+ walk->is_cursor_first = true;
- walk->is_cursor_absolute = false;
+ walk->is_cursor_absolute = false;
#endif
- walk->active_directions = 0;
+ walk->active_directions = 0;
#ifdef NDOF_WALK_DRAW_TOOMUCH
- walk->redraw = 1;
+ walk->redraw = 1;
#endif
- zero_v3(walk->dvec_prev);
+ zero_v3(walk->dvec_prev);
- walk->timer = WM_event_add_timer(CTX_wm_manager(C), win, TIMER, 0.01f);
+ walk->timer = WM_event_add_timer(CTX_wm_manager(C), win, TIMER, 0.01f);
#ifdef WITH_INPUT_NDOF
- walk->ndof = NULL;
+ walk->ndof = NULL;
#endif
- walk->time_lastdraw = PIL_check_seconds_timer();
+ walk->time_lastdraw = PIL_check_seconds_timer();
- walk->draw_handle_pixel = ED_region_draw_cb_activate(walk->ar->type, drawWalkPixel, walk, REGION_DRAW_POST_PIXEL);
+ walk->draw_handle_pixel = ED_region_draw_cb_activate(
+ walk->ar->type, drawWalkPixel, walk, REGION_DRAW_POST_PIXEL);
- walk->rv3d->rflag |= RV3D_NAVIGATING;
+ walk->rv3d->rflag |= RV3D_NAVIGATING;
- walk->snap_context = ED_transform_snap_object_context_create_view3d(
- bmain, walk->scene, CTX_data_depsgraph(C), 0,
- walk->ar, walk->v3d);
+ walk->snap_context = ED_transform_snap_object_context_create_view3d(
+ bmain, walk->scene, CTX_data_depsgraph(C), 0, walk->ar, walk->v3d);
- walk->v3d_camera_control = ED_view3d_cameracontrol_acquire(
- walk->depsgraph, walk->scene, walk->v3d, walk->rv3d,
- (U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0);
+ walk->v3d_camera_control = ED_view3d_cameracontrol_acquire(
+ walk->depsgraph,
+ walk->scene,
+ walk->v3d,
+ walk->rv3d,
+ (U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0);
- /* center the mouse */
- walk->center_mval[0] = walk->ar->winx * 0.5f;
- walk->center_mval[1] = walk->ar->winy * 0.5f;
+ /* center the mouse */
+ walk->center_mval[0] = walk->ar->winx * 0.5f;
+ walk->center_mval[1] = walk->ar->winy * 0.5f;
#ifdef USE_PIXELSIZE_NATIVE_SUPPORT
- walk->center_mval[0] += walk->ar->winrct.xmin;
- walk->center_mval[1] += walk->ar->winrct.ymin;
+ walk->center_mval[0] += walk->ar->winrct.xmin;
+ walk->center_mval[1] += walk->ar->winrct.ymin;
- WM_cursor_compatible_xy(win, &walk->center_mval[0], &walk->center_mval[1]);
+ WM_cursor_compatible_xy(win, &walk->center_mval[0], &walk->center_mval[1]);
- walk->center_mval[0] -= walk->ar->winrct.xmin;
- walk->center_mval[1] -= walk->ar->winrct.ymin;
+ walk->center_mval[0] -= walk->ar->winrct.xmin;
+ walk->center_mval[1] -= walk->ar->winrct.ymin;
#endif
- copy_v2_v2_int(walk->prev_mval, walk->center_mval);
+ copy_v2_v2_int(walk->prev_mval, walk->center_mval);
- WM_cursor_warp(win,
- walk->ar->winrct.xmin + walk->center_mval[0],
- walk->ar->winrct.ymin + walk->center_mval[1]);
+ WM_cursor_warp(win,
+ walk->ar->winrct.xmin + walk->center_mval[0],
+ walk->ar->winrct.ymin + walk->center_mval[1]);
- /* remove the mouse cursor temporarily */
- WM_cursor_modal_set(win, CURSOR_NONE);
+ /* remove the mouse cursor temporarily */
+ WM_cursor_modal_set(win, CURSOR_NONE);
- return 1;
+ return 1;
}
static int walkEnd(bContext *C, WalkInfo *walk)
{
- wmWindow *win;
- RegionView3D *rv3d;
+ wmWindow *win;
+ RegionView3D *rv3d;
- if (walk->state == WALK_RUNNING) {
- return OPERATOR_RUNNING_MODAL;
- }
+ if (walk->state == WALK_RUNNING) {
+ return OPERATOR_RUNNING_MODAL;
+ }
#ifdef NDOF_WALK_DEBUG
- puts("\n-- walk end --");
+ puts("\n-- walk end --");
#endif
- win = CTX_wm_window(C);
- rv3d = walk->rv3d;
+ win = CTX_wm_window(C);
+ rv3d = walk->rv3d;
- WM_event_remove_timer(CTX_wm_manager(C), win, walk->timer);
+ WM_event_remove_timer(CTX_wm_manager(C), win, walk->timer);
- ED_region_draw_cb_exit(walk->ar->type, walk->draw_handle_pixel);
+ ED_region_draw_cb_exit(walk->ar->type, walk->draw_handle_pixel);
- ED_transform_snap_object_context_destroy(walk->snap_context);
+ ED_transform_snap_object_context_destroy(walk->snap_context);
- ED_view3d_cameracontrol_release(walk->v3d_camera_control, walk->state == WALK_CANCEL);
+ ED_view3d_cameracontrol_release(walk->v3d_camera_control, walk->state == WALK_CANCEL);
- rv3d->rflag &= ~RV3D_NAVIGATING;
+ rv3d->rflag &= ~RV3D_NAVIGATING;
#ifdef WITH_INPUT_NDOF
- if (walk->ndof) {
- MEM_freeN(walk->ndof);
- }
+ if (walk->ndof) {
+ MEM_freeN(walk->ndof);
+ }
#endif
- /* restore the cursor */
- WM_cursor_modal_restore(win);
+ /* restore the cursor */
+ WM_cursor_modal_restore(win);
#ifdef USE_TABLET_SUPPORT
- if (walk->is_cursor_absolute == false)
+ if (walk->is_cursor_absolute == false)
#endif
- {
- /* center the mouse */
- WM_cursor_warp(
- win,
- walk->ar->winrct.xmin + walk->center_mval[0],
- walk->ar->winrct.ymin + walk->center_mval[1]);
- }
-
- if (walk->state == WALK_CONFIRM) {
- MEM_freeN(walk);
- return OPERATOR_FINISHED;
- }
-
- MEM_freeN(walk);
- return OPERATOR_CANCELLED;
+ {
+ /* center the mouse */
+ WM_cursor_warp(win,
+ walk->ar->winrct.xmin + walk->center_mval[0],
+ walk->ar->winrct.ymin + walk->center_mval[1]);
+ }
+
+ if (walk->state == WALK_CONFIRM) {
+ MEM_freeN(walk);
+ return OPERATOR_FINISHED;
+ }
+
+ MEM_freeN(walk);
+ return OPERATOR_CANCELLED;
}
static void walkEvent(bContext *C, wmOperator *op, WalkInfo *walk, const wmEvent *event)
{
- if (event->type == TIMER && event->customdata == walk->timer) {
- walk->redraw = true;
- }
- else if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
+ if (event->type == TIMER && event->customdata == walk->timer) {
+ walk->redraw = true;
+ }
+ else if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
#ifdef USE_TABLET_SUPPORT
- if (walk->is_cursor_first) {
- /* wait until we get the 'warp' event */
- if ((walk->center_mval[0] == event->mval[0]) &&
- (walk->center_mval[1] == event->mval[1]))
- {
- walk->is_cursor_first = false;
- }
- else {
- /* note, its possible the system isn't giving us the warp event
- * ideally we shouldn't have to worry about this, see: T45361 */
- wmWindow *win = CTX_wm_window(C);
- WM_cursor_warp(win,
- walk->ar->winrct.xmin + walk->center_mval[0],
- walk->ar->winrct.ymin + walk->center_mval[1]);
- }
- return;
- }
-
- if ((walk->is_cursor_absolute == false) && event->is_motion_absolute) {
- walk->is_cursor_absolute = true;
- copy_v2_v2_int(walk->prev_mval, event->mval);
- copy_v2_v2_int(walk->center_mval, event->mval);
- /* without this we can't turn 180d */
- CLAMP_MIN(walk->mouse_speed, 4.0f);
- }
-#endif /* USE_TABLET_SUPPORT */
-
-
- walk->moffset[0] += event->mval[0] - walk->prev_mval[0];
- walk->moffset[1] += event->mval[1] - walk->prev_mval[1];
-
- copy_v2_v2_int(walk->prev_mval, event->mval);
-
- if ((walk->center_mval[0] != event->mval[0]) ||
- (walk->center_mval[1] != event->mval[1]))
- {
- walk->redraw = true;
+ if (walk->is_cursor_first) {
+ /* wait until we get the 'warp' event */
+ if ((walk->center_mval[0] == event->mval[0]) && (walk->center_mval[1] == event->mval[1])) {
+ walk->is_cursor_first = false;
+ }
+ else {
+ /* note, its possible the system isn't giving us the warp event
+ * ideally we shouldn't have to worry about this, see: T45361 */
+ wmWindow *win = CTX_wm_window(C);
+ WM_cursor_warp(win,
+ walk->ar->winrct.xmin + walk->center_mval[0],
+ walk->ar->winrct.ymin + walk->center_mval[1]);
+ }
+ return;
+ }
+
+ if ((walk->is_cursor_absolute == false) && event->is_motion_absolute) {
+ walk->is_cursor_absolute = true;
+ copy_v2_v2_int(walk->prev_mval, event->mval);
+ copy_v2_v2_int(walk->center_mval, event->mval);
+ /* without this we can't turn 180d */
+ CLAMP_MIN(walk->mouse_speed, 4.0f);
+ }
+#endif /* USE_TABLET_SUPPORT */
+
+ walk->moffset[0] += event->mval[0] - walk->prev_mval[0];
+ walk->moffset[1] += event->mval[1] - walk->prev_mval[1];
+
+ copy_v2_v2_int(walk->prev_mval, event->mval);
+
+ if ((walk->center_mval[0] != event->mval[0]) || (walk->center_mval[1] != event->mval[1])) {
+ walk->redraw = true;
#ifdef USE_TABLET_SUPPORT
- if (walk->is_cursor_absolute) {
- /* pass */
- }
- else
+ if (walk->is_cursor_absolute) {
+ /* pass */
+ }
+ else
#endif
- if (WM_event_is_last_mousemove(event)) {
- wmWindow *win = CTX_wm_window(C);
+ if (WM_event_is_last_mousemove(event)) {
+ wmWindow *win = CTX_wm_window(C);
#ifdef __APPLE__
- if ((abs(walk->prev_mval[0] - walk->center_mval[0]) > walk->center_mval[0] / 2) ||
- (abs(walk->prev_mval[1] - walk->center_mval[1]) > walk->center_mval[1] / 2))
+ if ((abs(walk->prev_mval[0] - walk->center_mval[0]) > walk->center_mval[0] / 2) ||
+ (abs(walk->prev_mval[1] - walk->center_mval[1]) > walk->center_mval[1] / 2))
#endif
- {
- WM_cursor_warp(win,
- walk->ar->winrct.xmin + walk->center_mval[0],
- walk->ar->winrct.ymin + walk->center_mval[1]);
- copy_v2_v2_int(walk->prev_mval, walk->center_mval);
- }
- }
- }
- }
+ {
+ WM_cursor_warp(win,
+ walk->ar->winrct.xmin + walk->center_mval[0],
+ walk->ar->winrct.ymin + walk->center_mval[1]);
+ copy_v2_v2_int(walk->prev_mval, walk->center_mval);
+ }
+ }
+ }
+ }
#ifdef WITH_INPUT_NDOF
- else if (event->type == NDOF_MOTION) {
- /* do these automagically get delivered? yes. */
- // puts("ndof motion detected in walk mode!");
- // static const char *tag_name = "3D mouse position";
-
- const wmNDOFMotionData *incoming_ndof = event->customdata;
- switch (incoming_ndof->progress) {
- case P_STARTING:
- /* start keeping track of 3D mouse position */
+ else if (event->type == NDOF_MOTION) {
+ /* do these automagically get delivered? yes. */
+ // puts("ndof motion detected in walk mode!");
+ // static const char *tag_name = "3D mouse position";
+
+ const wmNDOFMotionData *incoming_ndof = event->customdata;
+ switch (incoming_ndof->progress) {
+ case P_STARTING:
+ /* start keeping track of 3D mouse position */
# ifdef NDOF_WALK_DEBUG
- puts("start keeping track of 3D mouse position");
+ puts("start keeping track of 3D mouse position");
# endif
- /* fall-through */
- case P_IN_PROGRESS:
- /* update 3D mouse position */
+ /* fall-through */
+ case P_IN_PROGRESS:
+ /* update 3D mouse position */
# ifdef NDOF_WALK_DEBUG
- putchar('.'); fflush(stdout);
+ putchar('.');
+ fflush(stdout);
# endif
- if (walk->ndof == NULL) {
- // walk->ndof = MEM_mallocN(sizeof(wmNDOFMotionData), tag_name);
- walk->ndof = MEM_dupallocN(incoming_ndof);
- // walk->ndof = malloc(sizeof(wmNDOFMotionData));
- }
- else {
- memcpy(walk->ndof, incoming_ndof, sizeof(wmNDOFMotionData));
- }
- break;
- case P_FINISHING:
- /* stop keeping track of 3D mouse position */
+ if (walk->ndof == NULL) {
+ // walk->ndof = MEM_mallocN(sizeof(wmNDOFMotionData), tag_name);
+ walk->ndof = MEM_dupallocN(incoming_ndof);
+ // walk->ndof = malloc(sizeof(wmNDOFMotionData));
+ }
+ else {
+ memcpy(walk->ndof, incoming_ndof, sizeof(wmNDOFMotionData));
+ }
+ break;
+ case P_FINISHING:
+ /* stop keeping track of 3D mouse position */
# ifdef NDOF_WALK_DEBUG
- puts("stop keeping track of 3D mouse position");
+ puts("stop keeping track of 3D mouse position");
# endif
- if (walk->ndof) {
- MEM_freeN(walk->ndof);
- // free(walk->ndof);
- walk->ndof = NULL;
- }
-
- /* update the time else the view will jump when 2D mouse/timer resume */
- walk->time_lastdraw = PIL_check_seconds_timer();
-
- break;
- default:
- break; /* should always be one of the above 3 */
- }
- }
+ if (walk->ndof) {
+ MEM_freeN(walk->ndof);
+ // free(walk->ndof);
+ walk->ndof = NULL;
+ }
+
+ /* update the time else the view will jump when 2D mouse/timer resume */
+ walk->time_lastdraw = PIL_check_seconds_timer();
+
+ break;
+ default:
+ break; /* should always be one of the above 3 */
+ }
+ }
#endif /* WITH_INPUT_NDOF */
- /* handle modal keymap first */
- else if (event->type == EVT_MODAL_MAP) {
- switch (event->val) {
- case WALK_MODAL_CANCEL:
- walk->state = WALK_CANCEL;
- break;
- case WALK_MODAL_CONFIRM:
- walk->state = WALK_CONFIRM;
- break;
-
- case WALK_MODAL_ACCELERATE:
- base_speed *= 1.0f + (walk->is_slow ? 0.01f : 0.1f);
- break;
- case WALK_MODAL_DECELERATE:
- base_speed /= 1.0f + (walk->is_slow ? 0.01f : 0.1f);
- break;
-
- /* implement WASD keys */
- case WALK_MODAL_DIR_FORWARD:
- walk->active_directions |= WALK_BIT_FORWARD;
- break;
- case WALK_MODAL_DIR_BACKWARD:
- walk->active_directions |= WALK_BIT_BACKWARD;
- break;
- case WALK_MODAL_DIR_LEFT:
- walk->active_directions |= WALK_BIT_LEFT;
- break;
- case WALK_MODAL_DIR_RIGHT:
- walk->active_directions |= WALK_BIT_RIGHT;
- break;
- case WALK_MODAL_DIR_UP:
- walk->active_directions |= WALK_BIT_UP;
- break;
- case WALK_MODAL_DIR_DOWN:
- walk->active_directions |= WALK_BIT_DOWN;
- break;
-
- case WALK_MODAL_DIR_FORWARD_STOP:
- walk->active_directions &= ~WALK_BIT_FORWARD;
- break;
- case WALK_MODAL_DIR_BACKWARD_STOP:
- walk->active_directions &= ~WALK_BIT_BACKWARD;
- break;
- case WALK_MODAL_DIR_LEFT_STOP:
- walk->active_directions &= ~WALK_BIT_LEFT;
- break;
- case WALK_MODAL_DIR_RIGHT_STOP:
- walk->active_directions &= ~WALK_BIT_RIGHT;
- break;
- case WALK_MODAL_DIR_UP_STOP:
- walk->active_directions &= ~WALK_BIT_UP;
- break;
- case WALK_MODAL_DIR_DOWN_STOP:
- walk->active_directions &= ~WALK_BIT_DOWN;
- break;
-
- case WALK_MODAL_FAST_ENABLE:
- walk->is_fast = true;
- break;
- case WALK_MODAL_FAST_DISABLE:
- walk->is_fast = false;
- break;
- case WALK_MODAL_SLOW_ENABLE:
- walk->is_slow = true;
- break;
- case WALK_MODAL_SLOW_DISABLE:
- walk->is_slow = false;
- break;
+ /* handle modal keymap first */
+ else if (event->type == EVT_MODAL_MAP) {
+ switch (event->val) {
+ case WALK_MODAL_CANCEL:
+ walk->state = WALK_CANCEL;
+ break;
+ case WALK_MODAL_CONFIRM:
+ walk->state = WALK_CONFIRM;
+ break;
+
+ case WALK_MODAL_ACCELERATE:
+ base_speed *= 1.0f + (walk->is_slow ? 0.01f : 0.1f);
+ break;
+ case WALK_MODAL_DECELERATE:
+ base_speed /= 1.0f + (walk->is_slow ? 0.01f : 0.1f);
+ break;
+
+ /* implement WASD keys */
+ case WALK_MODAL_DIR_FORWARD:
+ walk->active_directions |= WALK_BIT_FORWARD;
+ break;
+ case WALK_MODAL_DIR_BACKWARD:
+ walk->active_directions |= WALK_BIT_BACKWARD;
+ break;
+ case WALK_MODAL_DIR_LEFT:
+ walk->active_directions |= WALK_BIT_LEFT;
+ break;
+ case WALK_MODAL_DIR_RIGHT:
+ walk->active_directions |= WALK_BIT_RIGHT;
+ break;
+ case WALK_MODAL_DIR_UP:
+ walk->active_directions |= WALK_BIT_UP;
+ break;
+ case WALK_MODAL_DIR_DOWN:
+ walk->active_directions |= WALK_BIT_DOWN;
+ break;
+
+ case WALK_MODAL_DIR_FORWARD_STOP:
+ walk->active_directions &= ~WALK_BIT_FORWARD;
+ break;
+ case WALK_MODAL_DIR_BACKWARD_STOP:
+ walk->active_directions &= ~WALK_BIT_BACKWARD;
+ break;
+ case WALK_MODAL_DIR_LEFT_STOP:
+ walk->active_directions &= ~WALK_BIT_LEFT;
+ break;
+ case WALK_MODAL_DIR_RIGHT_STOP:
+ walk->active_directions &= ~WALK_BIT_RIGHT;
+ break;
+ case WALK_MODAL_DIR_UP_STOP:
+ walk->active_directions &= ~WALK_BIT_UP;
+ break;
+ case WALK_MODAL_DIR_DOWN_STOP:
+ walk->active_directions &= ~WALK_BIT_DOWN;
+ break;
+
+ case WALK_MODAL_FAST_ENABLE:
+ walk->is_fast = true;
+ break;
+ case WALK_MODAL_FAST_DISABLE:
+ walk->is_fast = false;
+ break;
+ case WALK_MODAL_SLOW_ENABLE:
+ walk->is_slow = true;
+ break;
+ case WALK_MODAL_SLOW_DISABLE:
+ walk->is_slow = false;
+ break;
#define JUMP_SPEED_MIN 1.0f
#define JUMP_TIME_MAX 0.2f /* s */
#define JUMP_SPEED_MAX sqrtf(2.0f * walk->gravity * walk->jump_height)
- case WALK_MODAL_JUMP_STOP:
- if (walk->gravity_state == WALK_GRAVITY_STATE_JUMP) {
- float t;
-
- /* delta time */
- t = (float)(PIL_check_seconds_timer() - walk->teleport.initial_time);
-
- /* reduce the veolocity, if JUMP wasn't hold for long enough */
- t = min_ff(t, JUMP_TIME_MAX);
- walk->speed_jump = JUMP_SPEED_MIN + t * (JUMP_SPEED_MAX - JUMP_SPEED_MIN) / JUMP_TIME_MAX;
-
- /* when jumping, duration is how long it takes before we start going down */
- walk->teleport.duration = getVelocityZeroTime(walk->gravity, walk->speed_jump);
-
- /* no more increase of jump speed */
- walk->gravity_state = WALK_GRAVITY_STATE_ON;
- }
- break;
- case WALK_MODAL_JUMP:
- if ((walk->navigation_mode == WALK_MODE_GRAVITY) &&
- (walk->gravity_state == WALK_GRAVITY_STATE_OFF) &&
- (walk->teleport.state == WALK_TELEPORT_STATE_OFF))
- {
- /* no need to check for ground,
- * walk->gravity wouldn't be off
- * if we were over a hole */
- walk->gravity_state = WALK_GRAVITY_STATE_JUMP;
- walk->speed_jump = JUMP_SPEED_MAX;
-
- walk->teleport.initial_time = PIL_check_seconds_timer();
- copy_v3_v3(walk->teleport.origin, walk->rv3d->viewinv[3]);
-
- /* using previous vec because WASD keys are not called when SPACE is */
- copy_v2_v2(walk->teleport.direction, walk->dvec_prev);
-
- /* when jumping, duration is how long it takes before we start going down */
- walk->teleport.duration = getVelocityZeroTime(walk->gravity, walk->speed_jump);
- }
-
- break;
-
- case WALK_MODAL_TELEPORT:
- {
- float loc[3], nor[3];
- float distance;
- bool ret = walk_ray_cast(walk->rv3d, walk, loc, nor, &distance);
-
- /* in case we are teleporting middle way from a jump */
- walk->speed_jump = 0.0f;
-
- if (ret) {
- WalkTeleport *teleport = &walk->teleport;
- teleport->state = WALK_TELEPORT_STATE_ON;
- teleport->initial_time = PIL_check_seconds_timer();
- teleport->duration = U.walk_navigation.teleport_time;
-
- teleport->navigation_mode = walk->navigation_mode;
- walk_navigation_mode_set(C, op, walk, WALK_MODE_FREE);
-
- copy_v3_v3(teleport->origin, walk->rv3d->viewinv[3]);
-
- /* stop the camera from a distance (camera height) */
- normalize_v3_length(nor, walk->view_height);
- add_v3_v3(loc, nor);
-
- sub_v3_v3v3(teleport->direction, loc, teleport->origin);
- }
- else {
- walk->teleport.state = WALK_TELEPORT_STATE_OFF;
- }
- break;
- }
+ case WALK_MODAL_JUMP_STOP:
+ if (walk->gravity_state == WALK_GRAVITY_STATE_JUMP) {
+ float t;
+
+ /* delta time */
+ t = (float)(PIL_check_seconds_timer() - walk->teleport.initial_time);
+
+ /* reduce the veolocity, if JUMP wasn't hold for long enough */
+ t = min_ff(t, JUMP_TIME_MAX);
+ walk->speed_jump = JUMP_SPEED_MIN +
+ t * (JUMP_SPEED_MAX - JUMP_SPEED_MIN) / JUMP_TIME_MAX;
+
+ /* when jumping, duration is how long it takes before we start going down */
+ walk->teleport.duration = getVelocityZeroTime(walk->gravity, walk->speed_jump);
+
+ /* no more increase of jump speed */
+ walk->gravity_state = WALK_GRAVITY_STATE_ON;
+ }
+ break;
+ case WALK_MODAL_JUMP:
+ if ((walk->navigation_mode == WALK_MODE_GRAVITY) &&
+ (walk->gravity_state == WALK_GRAVITY_STATE_OFF) &&
+ (walk->teleport.state == WALK_TELEPORT_STATE_OFF)) {
+ /* no need to check for ground,
+ * walk->gravity wouldn't be off
+ * if we were over a hole */
+ walk->gravity_state = WALK_GRAVITY_STATE_JUMP;
+ walk->speed_jump = JUMP_SPEED_MAX;
+
+ walk->teleport.initial_time = PIL_check_seconds_timer();
+ copy_v3_v3(walk->teleport.origin, walk->rv3d->viewinv[3]);
+
+ /* using previous vec because WASD keys are not called when SPACE is */
+ copy_v2_v2(walk->teleport.direction, walk->dvec_prev);
+
+ /* when jumping, duration is how long it takes before we start going down */
+ walk->teleport.duration = getVelocityZeroTime(walk->gravity, walk->speed_jump);
+ }
+
+ break;
+
+ case WALK_MODAL_TELEPORT: {
+ float loc[3], nor[3];
+ float distance;
+ bool ret = walk_ray_cast(walk->rv3d, walk, loc, nor, &distance);
+
+ /* in case we are teleporting middle way from a jump */
+ walk->speed_jump = 0.0f;
+
+ if (ret) {
+ WalkTeleport *teleport = &walk->teleport;
+ teleport->state = WALK_TELEPORT_STATE_ON;
+ teleport->initial_time = PIL_check_seconds_timer();
+ teleport->duration = U.walk_navigation.teleport_time;
+
+ teleport->navigation_mode = walk->navigation_mode;
+ walk_navigation_mode_set(C, op, walk, WALK_MODE_FREE);
+
+ copy_v3_v3(teleport->origin, walk->rv3d->viewinv[3]);
+
+ /* stop the camera from a distance (camera height) */
+ normalize_v3_length(nor, walk->view_height);
+ add_v3_v3(loc, nor);
+
+ sub_v3_v3v3(teleport->direction, loc, teleport->origin);
+ }
+ else {
+ walk->teleport.state = WALK_TELEPORT_STATE_OFF;
+ }
+ break;
+ }
#undef JUMP_SPEED_MAX
#undef JUMP_TIME_MAX
#undef JUMP_SPEED_MIN
- case WALK_MODAL_TOGGLE:
- if (walk->navigation_mode == WALK_MODE_GRAVITY) {
- walk_navigation_mode_set(C, op, walk, WALK_MODE_FREE);
- }
- else { /* WALK_MODE_FREE */
- walk_navigation_mode_set(C, op, walk, WALK_MODE_GRAVITY);
- }
- break;
- }
- }
+ case WALK_MODAL_TOGGLE:
+ if (walk->navigation_mode == WALK_MODE_GRAVITY) {
+ walk_navigation_mode_set(C, op, walk, WALK_MODE_FREE);
+ }
+ else { /* WALK_MODE_FREE */
+ walk_navigation_mode_set(C, op, walk, WALK_MODE_GRAVITY);
+ }
+ break;
+ }
+ }
}
-static void walkMoveCamera(bContext *C, WalkInfo *walk,
- const bool do_rotate, const bool do_translate)
+static void walkMoveCamera(bContext *C,
+ WalkInfo *walk,
+ const bool do_rotate,
+ const bool do_translate)
{
- ED_view3d_cameracontrol_update(walk->v3d_camera_control, true, C, do_rotate, do_translate);
+ ED_view3d_cameracontrol_update(walk->v3d_camera_control, true, C, do_rotate, do_translate);
}
static float getFreeFallDistance(const float gravity, const float time)
{
- return gravity * (time * time) * 0.5f;
+ return gravity * (time * time) * 0.5f;
}
static float getVelocityZeroTime(const float gravity, const float velocity)
{
- return velocity / gravity;
+ return velocity / gravity;
}
static int walkApply(bContext *C, wmOperator *op, WalkInfo *walk)
@@ -938,361 +956,347 @@ static int walkApply(bContext *C, wmOperator *op, WalkInfo *walk)
#define WALK_MOVE_SPEED base_speed
#define WALK_BOOST_FACTOR ((void)0, walk->speed_factor)
- /* walk mode - Ctrl+Shift+F
- * a walk loop where the user can move move the view as if they are in a walk game
- */
- RegionView3D *rv3d = walk->rv3d;
- ARegion *ar = walk->ar;
+ /* walk mode - Ctrl+Shift+F
+ * a walk loop where the user can move move the view as if they are in a walk game
+ */
+ RegionView3D *rv3d = walk->rv3d;
+ ARegion *ar = walk->ar;
- /* 3x3 copy of the view matrix so we can move along the view axis */
- float mat[3][3];
- /* this is the direction that's added to the view offset per redraw */
- float dvec[3] = {0.0f, 0.0f, 0.0f};
+ /* 3x3 copy of the view matrix so we can move along the view axis */
+ float mat[3][3];
+ /* this is the direction that's added to the view offset per redraw */
+ float dvec[3] = {0.0f, 0.0f, 0.0f};
- int moffset[2]; /* mouse offset from the views center */
- float tmp_quat[4]; /* used for rotating the view */
+ int moffset[2]; /* mouse offset from the views center */
+ float tmp_quat[4]; /* used for rotating the view */
#ifdef NDOF_WALK_DEBUG
- {
- static uint iteration = 1;
- printf("walk timer %d\n", iteration++);
- }
+ {
+ static uint iteration = 1;
+ printf("walk timer %d\n", iteration++);
+ }
#endif
- {
- /* mouse offset from the center */
- copy_v2_v2_int(moffset, walk->moffset);
-
- /* apply moffset so we can re-accumulate */
- walk->moffset[0] = 0;
- walk->moffset[1] = 0;
-
- /* revert mouse */
- if (walk->is_reversed) {
- moffset[1] = -moffset[1];
- }
-
- /* Should we redraw? */
- if ((walk->active_directions) ||
- moffset[0] || moffset[1] ||
- walk->teleport.state == WALK_TELEPORT_STATE_ON ||
- walk->gravity_state != WALK_GRAVITY_STATE_OFF)
- {
- float dvec_tmp[3];
-
- /* time how fast it takes for us to redraw,
- * this is so simple scenes don't walk too fast */
- double time_current;
- float time_redraw;
+ {
+ /* mouse offset from the center */
+ copy_v2_v2_int(moffset, walk->moffset);
+
+ /* apply moffset so we can re-accumulate */
+ walk->moffset[0] = 0;
+ walk->moffset[1] = 0;
+
+ /* revert mouse */
+ if (walk->is_reversed) {
+ moffset[1] = -moffset[1];
+ }
+
+ /* Should we redraw? */
+ if ((walk->active_directions) || moffset[0] || moffset[1] ||
+ walk->teleport.state == WALK_TELEPORT_STATE_ON ||
+ walk->gravity_state != WALK_GRAVITY_STATE_OFF) {
+ float dvec_tmp[3];
+
+ /* time how fast it takes for us to redraw,
+ * this is so simple scenes don't walk too fast */
+ double time_current;
+ float time_redraw;
#ifdef NDOF_WALK_DRAW_TOOMUCH
- walk->redraw = 1;
+ walk->redraw = 1;
#endif
- time_current = PIL_check_seconds_timer();
- time_redraw = (float)(time_current - walk->time_lastdraw);
-
- walk->time_lastdraw = time_current;
-
- /* base speed in m/s */
- walk->speed = WALK_MOVE_SPEED;
-
- if (walk->is_fast) {
- walk->speed *= WALK_BOOST_FACTOR;
- }
- else if (walk->is_slow) {
- walk->speed *= 1.0f / WALK_BOOST_FACTOR;
- }
-
- copy_m3_m4(mat, rv3d->viewinv);
+ time_current = PIL_check_seconds_timer();
+ time_redraw = (float)(time_current - walk->time_lastdraw);
- {
- /* rotate about the X axis- look up/down */
- if (moffset[1]) {
- float upvec[3];
- float angle;
- float y;
+ walk->time_lastdraw = time_current;
- /* relative offset */
- y = (float) moffset[1] / ar->winy;
+ /* base speed in m/s */
+ walk->speed = WALK_MOVE_SPEED;
- /* speed factor */
- y *= WALK_ROTATE_FAC;
+ if (walk->is_fast) {
+ walk->speed *= WALK_BOOST_FACTOR;
+ }
+ else if (walk->is_slow) {
+ walk->speed *= 1.0f / WALK_BOOST_FACTOR;
+ }
- /* user adjustment factor */
- y *= walk->mouse_speed;
+ copy_m3_m4(mat, rv3d->viewinv);
- /* clamp the angle limits */
- /* it ranges from 90.0f to -90.0f */
- angle = -asinf(rv3d->viewmat[2][2]);
+ {
+ /* rotate about the X axis- look up/down */
+ if (moffset[1]) {
+ float upvec[3];
+ float angle;
+ float y;
- if (angle > WALK_TOP_LIMIT && y > 0.0f) {
- y = 0.0f;
- }
- else if (angle < WALK_BOTTOM_LIMIT && y < 0.0f) {
- y = 0.0f;
- }
+ /* relative offset */
+ y = (float)moffset[1] / ar->winy;
- copy_v3_fl3(upvec, 1.0f, 0.0f, 0.0f);
- mul_m3_v3(mat, upvec);
- /* Rotate about the relative up vec */
- axis_angle_to_quat(tmp_quat, upvec, -y);
- mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
- }
+ /* speed factor */
+ y *= WALK_ROTATE_FAC;
- /* rotate about the Y axis- look left/right */
- if (moffset[0]) {
- float upvec[3];
- float x;
+ /* user adjustment factor */
+ y *= walk->mouse_speed;
- /* if we're upside down invert the moffset */
- copy_v3_fl3(upvec, 0.0f, 1.0f, 0.0f);
- mul_m3_v3(mat, upvec);
+ /* clamp the angle limits */
+ /* it ranges from 90.0f to -90.0f */
+ angle = -asinf(rv3d->viewmat[2][2]);
- if (upvec[2] < 0.0f) {
- moffset[0] = -moffset[0];
- }
+ if (angle > WALK_TOP_LIMIT && y > 0.0f) {
+ y = 0.0f;
+ }
+ else if (angle < WALK_BOTTOM_LIMIT && y < 0.0f) {
+ y = 0.0f;
+ }
- /* relative offset */
- x = (float) moffset[0] / ar->winx;
+ copy_v3_fl3(upvec, 1.0f, 0.0f, 0.0f);
+ mul_m3_v3(mat, upvec);
+ /* Rotate about the relative up vec */
+ axis_angle_to_quat(tmp_quat, upvec, -y);
+ mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
+ }
- /* speed factor */
- x *= WALK_ROTATE_FAC;
+ /* rotate about the Y axis- look left/right */
+ if (moffset[0]) {
+ float upvec[3];
+ float x;
- /* user adjustment factor */
- x *= walk->mouse_speed;
+ /* if we're upside down invert the moffset */
+ copy_v3_fl3(upvec, 0.0f, 1.0f, 0.0f);
+ mul_m3_v3(mat, upvec);
- /* Rotate about the relative up vec */
- axis_angle_to_quat_single(tmp_quat, 'Z', x);
- mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
- }
- }
+ if (upvec[2] < 0.0f) {
+ moffset[0] = -moffset[0];
+ }
- /* WASD - 'move' translation code */
- if ((walk->active_directions) &&
- (walk->gravity_state == WALK_GRAVITY_STATE_OFF))
- {
+ /* relative offset */
+ x = (float)moffset[0] / ar->winx;
- short direction;
- zero_v3(dvec);
+ /* speed factor */
+ x *= WALK_ROTATE_FAC;
- if ((walk->active_directions & WALK_BIT_FORWARD) ||
- (walk->active_directions & WALK_BIT_BACKWARD))
- {
+ /* user adjustment factor */
+ x *= walk->mouse_speed;
- direction = 0;
+ /* Rotate about the relative up vec */
+ axis_angle_to_quat_single(tmp_quat, 'Z', x);
+ mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
+ }
+ }
- if ((walk->active_directions & WALK_BIT_FORWARD)) {
- direction += 1;
- }
+ /* WASD - 'move' translation code */
+ if ((walk->active_directions) && (walk->gravity_state == WALK_GRAVITY_STATE_OFF)) {
- if ((walk->active_directions & WALK_BIT_BACKWARD)) {
- direction -= 1;
- }
+ short direction;
+ zero_v3(dvec);
- copy_v3_fl3(dvec_tmp, 0.0f, 0.0f, direction);
- mul_m3_v3(mat, dvec_tmp);
+ if ((walk->active_directions & WALK_BIT_FORWARD) ||
+ (walk->active_directions & WALK_BIT_BACKWARD)) {
- if (walk->navigation_mode == WALK_MODE_GRAVITY) {
- dvec_tmp[2] = 0.0f;
- }
+ direction = 0;
- normalize_v3(dvec_tmp);
- add_v3_v3(dvec, dvec_tmp);
+ if ((walk->active_directions & WALK_BIT_FORWARD)) {
+ direction += 1;
+ }
- }
+ if ((walk->active_directions & WALK_BIT_BACKWARD)) {
+ direction -= 1;
+ }
- if ((walk->active_directions & WALK_BIT_LEFT) ||
- (walk->active_directions & WALK_BIT_RIGHT))
- {
+ copy_v3_fl3(dvec_tmp, 0.0f, 0.0f, direction);
+ mul_m3_v3(mat, dvec_tmp);
- direction = 0;
+ if (walk->navigation_mode == WALK_MODE_GRAVITY) {
+ dvec_tmp[2] = 0.0f;
+ }
- if ((walk->active_directions & WALK_BIT_LEFT)) {
- direction += 1;
- }
+ normalize_v3(dvec_tmp);
+ add_v3_v3(dvec, dvec_tmp);
+ }
- if ((walk->active_directions & WALK_BIT_RIGHT)) {
- direction -= 1;
- }
+ if ((walk->active_directions & WALK_BIT_LEFT) ||
+ (walk->active_directions & WALK_BIT_RIGHT)) {
- dvec_tmp[0] = direction * rv3d->viewinv[0][0];
- dvec_tmp[1] = direction * rv3d->viewinv[0][1];
- dvec_tmp[2] = 0.0f;
+ direction = 0;
- normalize_v3(dvec_tmp);
- add_v3_v3(dvec, dvec_tmp);
+ if ((walk->active_directions & WALK_BIT_LEFT)) {
+ direction += 1;
+ }
- }
+ if ((walk->active_directions & WALK_BIT_RIGHT)) {
+ direction -= 1;
+ }
- if ((walk->active_directions & WALK_BIT_UP) ||
- (walk->active_directions & WALK_BIT_DOWN))
- {
+ dvec_tmp[0] = direction * rv3d->viewinv[0][0];
+ dvec_tmp[1] = direction * rv3d->viewinv[0][1];
+ dvec_tmp[2] = 0.0f;
- if (walk->navigation_mode == WALK_MODE_FREE) {
+ normalize_v3(dvec_tmp);
+ add_v3_v3(dvec, dvec_tmp);
+ }
- direction = 0;
-
- if ((walk->active_directions & WALK_BIT_UP)) {
- direction -= 1;
- }
-
- if ((walk->active_directions & WALK_BIT_DOWN)) {
- direction = 1;
- }
-
- copy_v3_fl3(dvec_tmp, 0.0f, 0.0f, direction);
- add_v3_v3(dvec, dvec_tmp);
- }
- }
-
- /* apply movement */
- mul_v3_fl(dvec, walk->speed * time_redraw);
- }
-
- /* stick to the floor */
- if (walk->navigation_mode == WALK_MODE_GRAVITY &&
- ELEM(walk->gravity_state,
- WALK_GRAVITY_STATE_OFF,
- WALK_GRAVITY_STATE_START))
- {
-
- bool ret;
- float ray_distance;
- float difference = -100.0f;
- float fall_distance;
-
- ret = walk_floor_distance_get(rv3d, walk, dvec, &ray_distance);
-
- if (ret) {
- difference = walk->view_height - ray_distance;
- }
-
- /* the distance we would fall naturally smoothly enough that we
- * can manually drop the object without activating gravity */
- fall_distance = time_redraw * walk->speed * WALK_BOOST_FACTOR;
-
- if (fabsf(difference) < fall_distance) {
- /* slope/stairs */
- dvec[2] -= difference;
-
- /* in case we switched from FREE to GRAVITY too close to the ground */
- if (walk->gravity_state == WALK_GRAVITY_STATE_START) {
- walk->gravity_state = WALK_GRAVITY_STATE_OFF;
- }
- }
- else {
- /* hijack the teleport variables */
- walk->teleport.initial_time = PIL_check_seconds_timer();
- walk->gravity_state = WALK_GRAVITY_STATE_ON;
- walk->teleport.duration = 0.0f;
-
- copy_v3_v3(walk->teleport.origin, walk->rv3d->viewinv[3]);
- copy_v2_v2(walk->teleport.direction, dvec);
-
- }
- }
-
- /* Falling or jumping) */
- if (ELEM(walk->gravity_state, WALK_GRAVITY_STATE_ON, WALK_GRAVITY_STATE_JUMP)) {
- float t;
- float z_cur, z_new;
- bool ret;
- float ray_distance, difference = -100.0f;
-
- /* delta time */
- t = (float)(PIL_check_seconds_timer() - walk->teleport.initial_time);
-
- /* keep moving if we were moving */
- copy_v2_v2(dvec, walk->teleport.direction);
-
- z_cur = walk->rv3d->viewinv[3][2];
- z_new = walk->teleport.origin[2] - getFreeFallDistance(walk->gravity, t) * walk->grid;
-
- /* jump */
- z_new += t * walk->speed_jump * walk->grid;
-
- /* duration is the jump duration */
- if (t > walk->teleport.duration) {
-
- /* check to see if we are landing */
- ret = walk_floor_distance_get(rv3d, walk, dvec, &ray_distance);
-
- if (ret) {
- difference = walk->view_height - ray_distance;
- }
-
- if (difference > 0.0f) {
- /* quit falling, lands at "view_height" from the floor */
- dvec[2] -= difference;
- walk->gravity_state = WALK_GRAVITY_STATE_OFF;
- walk->speed_jump = 0.0f;
- }
- else {
- /* keep falling */
- dvec[2] = z_cur - z_new;
- }
- }
- else {
- /* keep going up (jump) */
- dvec[2] = z_cur - z_new;
- }
- }
-
- /* Teleport */
- else if (walk->teleport.state == WALK_TELEPORT_STATE_ON) {
- float t; /* factor */
- float new_loc[3];
- float cur_loc[3];
-
- /* linear interpolation */
- t = (float)(PIL_check_seconds_timer() - walk->teleport.initial_time);
- t /= walk->teleport.duration;
-
- /* clamp so we don't go past our limit */
- if (t >= 1.0f) {
- t = 1.0f;
- walk->teleport.state = WALK_TELEPORT_STATE_OFF;
- walk_navigation_mode_set(C, op, walk, walk->teleport.navigation_mode);
- }
-
- mul_v3_v3fl(new_loc, walk->teleport.direction, t);
- add_v3_v3(new_loc, walk->teleport.origin);
-
- copy_v3_v3(cur_loc, walk->rv3d->viewinv[3]);
- sub_v3_v3v3(dvec, cur_loc, new_loc);
- }
-
- if (rv3d->persp == RV3D_CAMOB) {
- Object *lock_ob = ED_view3d_cameracontrol_object_get(walk->v3d_camera_control);
- if (lock_ob->protectflag & OB_LOCK_LOCX) {
- dvec[0] = 0.0f;
- }
- if (lock_ob->protectflag & OB_LOCK_LOCY) {
- dvec[1] = 0.0f;
- }
- if (lock_ob->protectflag & OB_LOCK_LOCZ) {
- dvec[2] = 0.0f;
- }
- }
-
- /* scale the movement to the scene size */
- mul_v3_v3fl(dvec_tmp, dvec, walk->grid);
- add_v3_v3(rv3d->ofs, dvec_tmp);
-
- if (rv3d->persp == RV3D_CAMOB) {
- const bool do_rotate = (moffset[0] || moffset[1]);
- const bool do_translate = (walk->speed != 0.0f);
- walkMoveCamera(C, walk, do_rotate, do_translate);
- }
- }
- else {
- /* we're not redrawing but we need to update the time else the view will jump */
- walk->time_lastdraw = PIL_check_seconds_timer();
- }
- /* end drawing */
- copy_v3_v3(walk->dvec_prev, dvec);
- }
-
- return OPERATOR_FINISHED;
+ if ((walk->active_directions & WALK_BIT_UP) || (walk->active_directions & WALK_BIT_DOWN)) {
+
+ if (walk->navigation_mode == WALK_MODE_FREE) {
+
+ direction = 0;
+
+ if ((walk->active_directions & WALK_BIT_UP)) {
+ direction -= 1;
+ }
+
+ if ((walk->active_directions & WALK_BIT_DOWN)) {
+ direction = 1;
+ }
+
+ copy_v3_fl3(dvec_tmp, 0.0f, 0.0f, direction);
+ add_v3_v3(dvec, dvec_tmp);
+ }
+ }
+
+ /* apply movement */
+ mul_v3_fl(dvec, walk->speed * time_redraw);
+ }
+
+ /* stick to the floor */
+ if (walk->navigation_mode == WALK_MODE_GRAVITY &&
+ ELEM(walk->gravity_state, WALK_GRAVITY_STATE_OFF, WALK_GRAVITY_STATE_START)) {
+
+ bool ret;
+ float ray_distance;
+ float difference = -100.0f;
+ float fall_distance;
+
+ ret = walk_floor_distance_get(rv3d, walk, dvec, &ray_distance);
+
+ if (ret) {
+ difference = walk->view_height - ray_distance;
+ }
+
+ /* the distance we would fall naturally smoothly enough that we
+ * can manually drop the object without activating gravity */
+ fall_distance = time_redraw * walk->speed * WALK_BOOST_FACTOR;
+
+ if (fabsf(difference) < fall_distance) {
+ /* slope/stairs */
+ dvec[2] -= difference;
+
+ /* in case we switched from FREE to GRAVITY too close to the ground */
+ if (walk->gravity_state == WALK_GRAVITY_STATE_START) {
+ walk->gravity_state = WALK_GRAVITY_STATE_OFF;
+ }
+ }
+ else {
+ /* hijack the teleport variables */
+ walk->teleport.initial_time = PIL_check_seconds_timer();
+ walk->gravity_state = WALK_GRAVITY_STATE_ON;
+ walk->teleport.duration = 0.0f;
+
+ copy_v3_v3(walk->teleport.origin, walk->rv3d->viewinv[3]);
+ copy_v2_v2(walk->teleport.direction, dvec);
+ }
+ }
+
+ /* Falling or jumping) */
+ if (ELEM(walk->gravity_state, WALK_GRAVITY_STATE_ON, WALK_GRAVITY_STATE_JUMP)) {
+ float t;
+ float z_cur, z_new;
+ bool ret;
+ float ray_distance, difference = -100.0f;
+
+ /* delta time */
+ t = (float)(PIL_check_seconds_timer() - walk->teleport.initial_time);
+
+ /* keep moving if we were moving */
+ copy_v2_v2(dvec, walk->teleport.direction);
+
+ z_cur = walk->rv3d->viewinv[3][2];
+ z_new = walk->teleport.origin[2] - getFreeFallDistance(walk->gravity, t) * walk->grid;
+
+ /* jump */
+ z_new += t * walk->speed_jump * walk->grid;
+
+ /* duration is the jump duration */
+ if (t > walk->teleport.duration) {
+
+ /* check to see if we are landing */
+ ret = walk_floor_distance_get(rv3d, walk, dvec, &ray_distance);
+
+ if (ret) {
+ difference = walk->view_height - ray_distance;
+ }
+
+ if (difference > 0.0f) {
+ /* quit falling, lands at "view_height" from the floor */
+ dvec[2] -= difference;
+ walk->gravity_state = WALK_GRAVITY_STATE_OFF;
+ walk->speed_jump = 0.0f;
+ }
+ else {
+ /* keep falling */
+ dvec[2] = z_cur - z_new;
+ }
+ }
+ else {
+ /* keep going up (jump) */
+ dvec[2] = z_cur - z_new;
+ }
+ }
+
+ /* Teleport */
+ else if (walk->teleport.state == WALK_TELEPORT_STATE_ON) {
+ float t; /* factor */
+ float new_loc[3];
+ float cur_loc[3];
+
+ /* linear interpolation */
+ t = (float)(PIL_check_seconds_timer() - walk->teleport.initial_time);
+ t /= walk->teleport.duration;
+
+ /* clamp so we don't go past our limit */
+ if (t >= 1.0f) {
+ t = 1.0f;
+ walk->teleport.state = WALK_TELEPORT_STATE_OFF;
+ walk_navigation_mode_set(C, op, walk, walk->teleport.navigation_mode);
+ }
+
+ mul_v3_v3fl(new_loc, walk->teleport.direction, t);
+ add_v3_v3(new_loc, walk->teleport.origin);
+
+ copy_v3_v3(cur_loc, walk->rv3d->viewinv[3]);
+ sub_v3_v3v3(dvec, cur_loc, new_loc);
+ }
+
+ if (rv3d->persp == RV3D_CAMOB) {
+ Object *lock_ob = ED_view3d_cameracontrol_object_get(walk->v3d_camera_control);
+ if (lock_ob->protectflag & OB_LOCK_LOCX) {
+ dvec[0] = 0.0f;
+ }
+ if (lock_ob->protectflag & OB_LOCK_LOCY) {
+ dvec[1] = 0.0f;
+ }
+ if (lock_ob->protectflag & OB_LOCK_LOCZ) {
+ dvec[2] = 0.0f;
+ }
+ }
+
+ /* scale the movement to the scene size */
+ mul_v3_v3fl(dvec_tmp, dvec, walk->grid);
+ add_v3_v3(rv3d->ofs, dvec_tmp);
+
+ if (rv3d->persp == RV3D_CAMOB) {
+ const bool do_rotate = (moffset[0] || moffset[1]);
+ const bool do_translate = (walk->speed != 0.0f);
+ walkMoveCamera(C, walk, do_rotate, do_translate);
+ }
+ }
+ else {
+ /* we're not redrawing but we need to update the time else the view will jump */
+ walk->time_lastdraw = PIL_check_seconds_timer();
+ }
+ /* end drawing */
+ copy_v3_v3(walk->dvec_prev, dvec);
+ }
+
+ return OPERATOR_FINISHED;
#undef WALK_ROTATE_FAC
#undef WALK_ZUP_CORRECT_FAC
#undef WALK_ZUP_CORRECT_ACCEL
@@ -1306,121 +1310,124 @@ static int walkApply(bContext *C, wmOperator *op, WalkInfo *walk)
#ifdef WITH_INPUT_NDOF
static void walkApply_ndof(bContext *C, WalkInfo *walk)
{
- Object *lock_ob = ED_view3d_cameracontrol_object_get(walk->v3d_camera_control);
- bool has_translate, has_rotate;
-
- view3d_ndof_fly(walk->ndof,
- walk->v3d, walk->rv3d,
- walk->is_slow, lock_ob ? lock_ob->protectflag : 0,
- &has_translate, &has_rotate);
-
- if (has_translate || has_rotate) {
- walk->redraw = true;
-
- if (walk->rv3d->persp == RV3D_CAMOB) {
- walkMoveCamera(C, walk, has_rotate, has_translate);
- }
- }
+ Object *lock_ob = ED_view3d_cameracontrol_object_get(walk->v3d_camera_control);
+ bool has_translate, has_rotate;
+
+ view3d_ndof_fly(walk->ndof,
+ walk->v3d,
+ walk->rv3d,
+ walk->is_slow,
+ lock_ob ? lock_ob->protectflag : 0,
+ &has_translate,
+ &has_rotate);
+
+ if (has_translate || has_rotate) {
+ walk->redraw = true;
+
+ if (walk->rv3d->persp == RV3D_CAMOB) {
+ walkMoveCamera(C, walk, has_rotate, has_translate);
+ }
+ }
}
#endif /* WITH_INPUT_NDOF */
/****** walk operator ******/
static int walk_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
- WalkInfo *walk;
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ WalkInfo *walk;
- if (rv3d->viewlock & RV3D_LOCKED) {
- return OPERATOR_CANCELLED;
- }
+ if (rv3d->viewlock & RV3D_LOCKED) {
+ return OPERATOR_CANCELLED;
+ }
- walk = MEM_callocN(sizeof(WalkInfo), "NavigationWalkOperation");
+ walk = MEM_callocN(sizeof(WalkInfo), "NavigationWalkOperation");
- op->customdata = walk;
+ op->customdata = walk;
- if (initWalkInfo(C, walk, op) == false) {
- MEM_freeN(op->customdata);
- return OPERATOR_CANCELLED;
- }
+ if (initWalkInfo(C, walk, op) == false) {
+ MEM_freeN(op->customdata);
+ return OPERATOR_CANCELLED;
+ }
- walkEvent(C, op, walk, event);
+ walkEvent(C, op, walk, event);
- WM_event_add_modal_handler(C, op);
+ WM_event_add_modal_handler(C, op);
- return OPERATOR_RUNNING_MODAL;
+ return OPERATOR_RUNNING_MODAL;
}
static void walk_cancel(bContext *C, wmOperator *op)
{
- WalkInfo *walk = op->customdata;
+ WalkInfo *walk = op->customdata;
- walk->state = WALK_CANCEL;
- walkEnd(C, walk);
- op->customdata = NULL;
+ walk->state = WALK_CANCEL;
+ walkEnd(C, walk);
+ op->customdata = NULL;
}
static int walk_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
- int exit_code;
- bool do_draw = false;
- WalkInfo *walk = op->customdata;
- RegionView3D *rv3d = walk->rv3d;
- Object *walk_object = ED_view3d_cameracontrol_object_get(walk->v3d_camera_control);
+ int exit_code;
+ bool do_draw = false;
+ WalkInfo *walk = op->customdata;
+ RegionView3D *rv3d = walk->rv3d;
+ Object *walk_object = ED_view3d_cameracontrol_object_get(walk->v3d_camera_control);
- walk->redraw = false;
+ walk->redraw = false;
- walkEvent(C, op, walk, event);
+ walkEvent(C, op, walk, event);
#ifdef WITH_INPUT_NDOF
- if (walk->ndof) { /* 3D mouse overrules [2D mouse + timer] */
- if (event->type == NDOF_MOTION) {
- walkApply_ndof(C, walk);
- }
- }
- else
+ if (walk->ndof) { /* 3D mouse overrules [2D mouse + timer] */
+ if (event->type == NDOF_MOTION) {
+ walkApply_ndof(C, walk);
+ }
+ }
+ else
#endif /* WITH_INPUT_NDOF */
- if (event->type == TIMER && event->customdata == walk->timer) {
- walkApply(C, op, walk);
- }
+ if (event->type == TIMER && event->customdata == walk->timer) {
+ walkApply(C, op, walk);
+ }
- do_draw |= walk->redraw;
+ do_draw |= walk->redraw;
- exit_code = walkEnd(C, walk);
+ exit_code = walkEnd(C, walk);
- if (exit_code != OPERATOR_RUNNING_MODAL) {
- do_draw = true;
- }
+ if (exit_code != OPERATOR_RUNNING_MODAL) {
+ do_draw = true;
+ }
- if (do_draw) {
- if (rv3d->persp == RV3D_CAMOB) {
- WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, walk_object);
- }
+ if (do_draw) {
+ if (rv3d->persp == RV3D_CAMOB) {
+ WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, walk_object);
+ }
- // too frequent, commented with NDOF_WALK_DRAW_TOOMUCH for now
- // puts("redraw!");
- ED_region_tag_redraw(CTX_wm_region(C));
- }
+ // too frequent, commented with NDOF_WALK_DRAW_TOOMUCH for now
+ // puts("redraw!");
+ ED_region_tag_redraw(CTX_wm_region(C));
+ }
- if (ELEM(exit_code, OPERATOR_FINISHED, OPERATOR_CANCELLED)) {
- ED_workspace_status_text(C, NULL);
- }
+ if (ELEM(exit_code, OPERATOR_FINISHED, OPERATOR_CANCELLED)) {
+ ED_workspace_status_text(C, NULL);
+ }
- return exit_code;
+ return exit_code;
}
void VIEW3D_OT_walk(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Walk Navigation";
- ot->description = "Interactively walk around the scene";
- ot->idname = "VIEW3D_OT_walk";
-
- /* api callbacks */
- ot->invoke = walk_invoke;
- ot->cancel = walk_cancel;
- ot->modal = walk_modal;
- ot->poll = ED_operator_region_view3d_active;
-
- /* flags */
- ot->flag = OPTYPE_BLOCKING;
+ /* identifiers */
+ ot->name = "Walk Navigation";
+ ot->description = "Interactively walk around the scene";
+ ot->idname = "VIEW3D_OT_walk";
+
+ /* api callbacks */
+ ot->invoke = walk_invoke;
+ ot->cancel = walk_cancel;
+ ot->modal = walk_modal;
+ ot->poll = ED_operator_region_view3d_active;
+
+ /* flags */
+ ot->flag = OPTYPE_BLOCKING;
}