[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [51093] trunk/blender/source/blender/ editors/space_view3d: add armature_foreachScreenBone(), use for lasso and circle select.
Campbell Barton
ideasman42 at gmail.com
Fri Oct 5 19:07:02 CEST 2012
Revision: 51093
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=51093
Author: campbellbarton
Date: 2012-10-05 17:07:02 +0000 (Fri, 05 Oct 2012)
Log Message:
-----------
add armature_foreachScreenBone(), use for lasso and circle select.
also add boundbox checking for lasso select.
Modified Paths:
--------------
trunk/blender/source/blender/editors/space_view3d/drawobject.c
trunk/blender/source/blender/editors/space_view3d/view3d_select.c
Modified: trunk/blender/source/blender/editors/space_view3d/drawobject.c
===================================================================
--- trunk/blender/source/blender/editors/space_view3d/drawobject.c 2012-10-05 15:48:39 UTC (rev 51092)
+++ trunk/blender/source/blender/editors/space_view3d/drawobject.c 2012-10-05 17:07:02 UTC (rev 51093)
@@ -101,6 +101,7 @@
#include "ED_sculpt.h"
#include "ED_types.h"
#include "ED_curve.h" /* for curve_editnurbs */
+#include "ED_armature.h"
#include "UI_resources.h"
@@ -2219,6 +2220,51 @@
}
}
+/* ED_view3d_init_mats_rv3d must be called first */
+void armature_foreachScreenBone(
+ struct ViewContext *vc,
+ void (*func)(void *userData, struct EditBone *ebone, int x0, int y0, int x1, int y1),
+ void *userData)
+{
+ bArmature *arm = vc->obedit->data;
+ EditBone *ebone;
+
+ for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
+ if (EBONE_VISIBLE(arm, ebone)) {
+ int screen_co_a[2], screen_co_b[2];
+ int points_proj_tot = 0;
+
+ /* project head location to screenspace */
+ if (ED_view3d_project_int_object(vc->ar, ebone->head, screen_co_a,
+ V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS)
+ {
+ 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_int_object(vc->ar, ebone->tail, screen_co_b,
+ V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS)
+ {
+ 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[0], screen_co_a[1],
+ screen_co_b[0], screen_co_b[1]);
+ }
+ }
+ }
+}
+
/* ************** DRAW MESH ****************** */
/* First section is all the "simple" draw routines,
Modified: trunk/blender/source/blender/editors/space_view3d/view3d_select.c
===================================================================
--- trunk/blender/source/blender/editors/space_view3d/view3d_select.c 2012-10-05 15:48:39 UTC (rev 51092)
+++ trunk/blender/source/blender/editors/space_view3d/view3d_select.c 2012-10-05 17:07:02 UTC (rev 51093)
@@ -600,65 +600,70 @@
lattice_foreachScreenVert(vc, do_lasso_select_lattice__doSelect, &data);
}
-static void do_lasso_select_armature(ViewContext *vc, const int mcords[][2], short moves, short extend, short select)
+static void do_lasso_select_armature__doSelectBone(void *userData, struct EditBone *ebone, int x0, int y0, int x1, int y1)
{
- bArmature *arm = vc->obedit->data;
- EditBone *ebone;
- int change = FALSE;
+ LassoSelectUserData *data = userData;
+ bArmature *arm = data->vc->obedit->data;
- if (extend == 0 && select)
- ED_armature_deselect_all_visible(vc->obedit);
+ if (EBONE_SELECTABLE(arm, ebone)) {
+ int is_point_done = FALSE;
+ int points_proj_tot = 0;
- ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
-
- /* set editdata in vc */
-
- for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
- if (EBONE_SELECTABLE(arm, ebone)) {
- int screen_co_a[2], screen_co_b[2];
- int is_point_done = FALSE;
- int points_proj_tot = 0;
-
- /* project head location to screenspace */
- if (ED_view3d_project_int_object(vc->ar, ebone->head, screen_co_a,
- V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS)
+ /* project head location to screenspace */
+ if (x0 != IS_CLIPPED) {
+ points_proj_tot++;
+ if (BLI_rcti_isect_pt(data->rect, x0, y0) &&
+ BLI_lasso_is_point_inside(data->mcords, data->moves, x0, y0, INT_MAX))
{
- points_proj_tot++;
- if (BLI_lasso_is_point_inside(mcords, moves, screen_co_a[0], screen_co_a[1], INT_MAX)) {
- is_point_done = TRUE;
- if (select) ebone->flag |= BONE_ROOTSEL;
- else ebone->flag &= ~BONE_ROOTSEL;
- }
+ is_point_done = TRUE;
+ if (data->select) ebone->flag |= BONE_ROOTSEL;
+ else ebone->flag &= ~BONE_ROOTSEL;
}
+ }
- /* project tail location to screenspace */
- if (ED_view3d_project_int_object(vc->ar, ebone->tail, screen_co_b,
- V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS)
+ /* project tail location to screenspace */
+ if (x1 != IS_CLIPPED) {
+ points_proj_tot++;
+ if (BLI_rcti_isect_pt(data->rect, x1, y1) &&
+ BLI_lasso_is_point_inside(data->mcords, data->moves, x1, y1, INT_MAX))
{
- points_proj_tot++;
- if (BLI_lasso_is_point_inside(mcords, moves, screen_co_b[0], screen_co_b[1], INT_MAX)) {
- is_point_done = TRUE;
- if (select) ebone->flag |= BONE_TIPSEL;
- else ebone->flag &= ~BONE_TIPSEL;
- }
+ is_point_done = TRUE;
+ if (data->select) ebone->flag |= BONE_TIPSEL;
+ else ebone->flag &= ~BONE_TIPSEL;
}
+ }
- /* if one of points selected, we skip the bone itself */
- if ((is_point_done == FALSE) && (points_proj_tot == 2) &&
- BLI_lasso_is_edge_inside(mcords, moves,
- screen_co_a[0], screen_co_a[1],
- screen_co_b[0], screen_co_b[1], INT_MAX))
- {
- if (select) ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
- else ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
- change = TRUE;
- }
-
- change |= is_point_done;
+ /* if one of points selected, we skip the bone itself */
+ if ((is_point_done == FALSE) && (points_proj_tot == 2) &&
+ BLI_lasso_is_edge_inside(data->mcords, data->moves, x0, y0, x1, y1, INT_MAX))
+ {
+ if (data->select) ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
+ else ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
+ data->is_change = TRUE;
}
+
+ data->is_change |= is_point_done;
}
-
- if (change) {
+}
+
+static void do_lasso_select_armature(ViewContext *vc, const int mcords[][2], short moves, short extend, short select)
+{
+ LassoSelectUserData data;
+ rcti rect;
+
+ view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select);
+
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
+
+ BLI_lasso_boundbox(&rect, mcords, moves);
+
+ if (extend == 0 && select)
+ ED_armature_deselect_all_visible(vc->obedit);
+
+ armature_foreachScreenBone(vc, do_lasso_select_armature__doSelectBone, &data);
+
+ if (data.is_change) {
+ bArmature *arm = vc->obedit->data;
ED_armature_sync_selection(arm->edbo);
ED_armature_validate_active(arm);
WM_main_add_notifier(NC_OBJECT | ND_BONE_SELECT, vc->obedit);
@@ -2508,66 +2513,60 @@
}
return 0;
}
-static void armature_circle_select(ViewContext *vc, int select, const int mval[2], float rad)
+static void do_circle_select_armature__doSelectBone(void *userData, struct EditBone *ebone, int x0, int y0, int x1, int y1)
{
- CircleSelectUserData data;
- bArmature *arm = vc->obedit->data;
- EditBone *ebone;
+ CircleSelectUserData *data = userData;
+ bArmature *arm = data->vc->obedit->data;
- view3d_userdata_circleselect_init(&data, vc, select, mval, rad);
+ if (EBONE_SELECTABLE(arm, ebone)) {
+ int is_point_done = FALSE;
+ int points_proj_tot = 0;
- ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
-
- /* check each EditBone... */
- for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
- if (EBONE_SELECTABLE(arm, ebone)) {
- int screen_co_a[2], screen_co_b[2];
- int is_point_done = FALSE;
- int points_proj_tot = 0;
-
- /* project head location to screenspace */
- if (ED_view3d_project_int_object(vc->ar, ebone->head, screen_co_a,
- V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS)
- {
- points_proj_tot++;
- if (armature_circle_doSelectJoint(&data, ebone, screen_co_a[0], screen_co_a[1], TRUE)) {
- is_point_done = TRUE;
- }
+ /* project head location to screenspace */
+ if (x0 != IS_CLIPPED) {
+ points_proj_tot++;
+ if (armature_circle_doSelectJoint(data, ebone, x0, y0, TRUE)) {
+ is_point_done = TRUE;
}
+ }
- /* project tail location to screenspace */
- if (ED_view3d_project_int_object(vc->ar, ebone->tail, screen_co_b,
- V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS)
- {
- points_proj_tot++;
- if (armature_circle_doSelectJoint(&data, ebone, screen_co_b[0], screen_co_b[1], FALSE)) {
- is_point_done = TRUE;
- }
+ /* project tail location to screenspace */
+ if (x1 != IS_CLIPPED) {
+ points_proj_tot++;
+ if (armature_circle_doSelectJoint(data, ebone, x1, y1, 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
- */
+ /* 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(mval[0], mval[1], rad,
- screen_co_a[0], screen_co_a[1],
- screen_co_b[0], screen_co_b[1]))
- {
- if (select)
- ebone->flag |= BONE_TIPSEL | BONE_ROOTSEL | BONE_SELECTED;
- else
- ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
- data.is_change = TRUE;
- }
-
- data.is_change |= is_point_done;
+ /* 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[0], data->mval[1], data->radius, x0, y0, x1, y1))
+ {
+ if (data->select) ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list