2011-02-23 10:52:22 +00:00
|
|
|
/*
|
2008-12-20 18:43:21 +00:00
|
|
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
2010-02-12 13:34:04 +00:00
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2008-12-20 18:43:21 +00:00
|
|
|
*
|
|
|
|
* The Original Code is Copyright (C) 2008 Blender Foundation.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* Contributor(s): Blender Foundation
|
|
|
|
*
|
|
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
|
|
*/
|
|
|
|
|
2011-02-27 20:29:51 +00:00
|
|
|
/** \file blender/editors/space_view3d/view3d_select.c
|
|
|
|
* \ingroup spview3d
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2008-12-20 18:43:21 +00:00
|
|
|
#include <string.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <math.h>
|
|
|
|
#include <float.h>
|
2010-11-03 01:56:02 +00:00
|
|
|
#include <assert.h>
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
#include "DNA_action_types.h"
|
|
|
|
#include "DNA_armature_types.h"
|
|
|
|
#include "DNA_curve_types.h"
|
|
|
|
#include "DNA_meta_types.h"
|
2012-02-19 22:17:30 +00:00
|
|
|
#include "DNA_mesh_types.h"
|
2008-12-20 18:43:21 +00:00
|
|
|
#include "DNA_meshdata_types.h"
|
|
|
|
#include "DNA_object_types.h"
|
|
|
|
#include "DNA_scene_types.h"
|
2011-11-07 12:55:18 +00:00
|
|
|
#include "DNA_tracking_types.h"
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
2009-11-10 20:43:45 +00:00
|
|
|
#include "BLI_math.h"
|
2008-12-20 18:43:21 +00:00
|
|
|
#include "BLI_blenlib.h"
|
|
|
|
#include "BLI_rand.h"
|
2009-09-16 17:43:09 +00:00
|
|
|
#include "BLI_linklist.h"
|
2011-01-07 18:36:47 +00:00
|
|
|
#include "BLI_utildefines.h"
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2011-09-18 17:10:28 +00:00
|
|
|
/* vertex box select */
|
2011-08-09 16:32:15 +00:00
|
|
|
#include "IMB_imbuf_types.h"
|
|
|
|
#include "IMB_imbuf.h"
|
|
|
|
#include "BKE_global.h"
|
|
|
|
|
2008-12-20 18:43:21 +00:00
|
|
|
#include "BKE_context.h"
|
2009-08-15 19:48:50 +00:00
|
|
|
#include "BKE_paint.h"
|
2010-11-03 01:56:02 +00:00
|
|
|
#include "BKE_armature.h"
|
2009-05-16 16:18:08 +00:00
|
|
|
#include "BKE_tessmesh.h"
|
2011-11-07 12:55:18 +00:00
|
|
|
#include "BKE_movieclip.h"
|
|
|
|
#include "BKE_object.h"
|
|
|
|
#include "BKE_tracking.h"
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2011-12-04 23:13:28 +00:00
|
|
|
|
2008-12-20 18:43:21 +00:00
|
|
|
#include "BIF_gl.h"
|
2011-01-05 15:37:36 +00:00
|
|
|
#include "BIF_glutil.h"
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
#include "WM_api.h"
|
|
|
|
#include "WM_types.h"
|
|
|
|
|
|
|
|
#include "RNA_access.h"
|
|
|
|
#include "RNA_define.h"
|
2012-01-11 03:40:20 +00:00
|
|
|
#include "RNA_enum_types.h"
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2009-01-05 15:19:31 +00:00
|
|
|
#include "ED_armature.h"
|
2009-01-14 12:26:45 +00:00
|
|
|
#include "ED_curve.h"
|
2009-02-20 20:39:27 +00:00
|
|
|
#include "ED_particle.h"
|
2008-12-30 13:16:14 +00:00
|
|
|
#include "ED_mesh.h"
|
2008-12-29 12:15:42 +00:00
|
|
|
#include "ED_object.h"
|
2008-12-20 18:43:21 +00:00
|
|
|
#include "ED_screen.h"
|
2009-07-29 12:35:09 +00:00
|
|
|
#include "ED_mball.h"
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
#include "UI_interface.h"
|
2011-02-27 18:03:19 +00:00
|
|
|
#include "UI_resources.h"
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
#include "view3d_intern.h" // own include
|
|
|
|
|
Cleanup of MotionPaths+Ghosts (AnimViz) - Part 1
This commit sets up some of the groundwork necessary to extend the animation visualisation capabilities, previously only available for bones in PoseMode, to Objects as well. Also, some of the other goals of this refactor is to make future visualisation goodies (i.e. editable paths) more feasible...
(There's really nothing to see here yet. The following log notes are really just for my own reference to keep track of things.)
Currently, the following things have been done:
* New datastructures + settings have been tidied up, ready for usage
* Added these new types into the Object and PoseBone code as necessary, with freeing/adding/copying accounted for
* File IO code for the new data, including version patching to convert the old system to the new one.
* Set up the drawing system for motionpaths based on the old armature path drawing code. Armatures still draw using the old system, since the two systems use different storage systems.
* Started setting up the motionpath 'baking' code, but the core of this still needs to be coded...
Next Steps (after some semi-urgent Durian Driver changes):
* Port the ghosting/onionskinning code over too
* Finish motionpath baking code
* RNA wrapping for the new types
* Hooking up all the new code into the operators, etc.
2010-01-01 12:24:16 +00:00
|
|
|
// TODO: should return whether there is valid context to continue
|
2.5
Vertex Paint back!
Added WM level "paint cursor" system, which manages a custom painting
cursor for tools or modes.
- Activate it with WM_paint_cursor_activate(). That function wants two
callbacks, a poll(C) to check whether there's a cursor in given context
and ARegion, and a draw(C, x, y) which gets called when appropriate.
- While paintcursor is active, the WM handles necessary redrawing events
for all regions, also to nicely clear the cursor on region exit.
- WM_paint_cursor_activate returns a handle, which you have to use to
end the paint cursor. This handle also means you can register as many
custom cursors as you want.
At the moment, vertex paint mode registers only a mousemove handler,
all other events are still normally handled. This is stuff for the
future todo.
2009-01-09 13:55:45 +00:00
|
|
|
void view3d_set_viewcontext(bContext *C, ViewContext *vc)
|
2009-01-02 14:11:18 +00:00
|
|
|
{
|
|
|
|
memset(vc, 0, sizeof(ViewContext));
|
|
|
|
vc->ar= CTX_wm_region(C);
|
|
|
|
vc->scene= CTX_data_scene(C);
|
2009-01-17 18:35:33 +00:00
|
|
|
vc->v3d= CTX_wm_view3d(C);
|
Cleanup of MotionPaths+Ghosts (AnimViz) - Part 1
This commit sets up some of the groundwork necessary to extend the animation visualisation capabilities, previously only available for bones in PoseMode, to Objects as well. Also, some of the other goals of this refactor is to make future visualisation goodies (i.e. editable paths) more feasible...
(There's really nothing to see here yet. The following log notes are really just for my own reference to keep track of things.)
Currently, the following things have been done:
* New datastructures + settings have been tidied up, ready for usage
* Added these new types into the Object and PoseBone code as necessary, with freeing/adding/copying accounted for
* File IO code for the new data, including version patching to convert the old system to the new one.
* Set up the drawing system for motionpaths based on the old armature path drawing code. Armatures still draw using the old system, since the two systems use different storage systems.
* Started setting up the motionpath 'baking' code, but the core of this still needs to be coded...
Next Steps (after some semi-urgent Durian Driver changes):
* Port the ghosting/onionskinning code over too
* Finish motionpath baking code
* RNA wrapping for the new types
* Hooking up all the new code into the operators, etc.
2010-01-01 12:24:16 +00:00
|
|
|
vc->rv3d= CTX_wm_region_view3d(C);
|
2009-01-02 14:11:18 +00:00
|
|
|
vc->obact= CTX_data_active_object(C);
|
|
|
|
vc->obedit= CTX_data_edit_object(C);
|
|
|
|
}
|
|
|
|
|
2011-05-12 16:47:36 +00:00
|
|
|
int view3d_get_view_aligned_coordinate(ViewContext *vc, float fp[3], const int mval[2], const short do_fallback)
|
2009-02-13 17:37:01 +00:00
|
|
|
{
|
|
|
|
float dvec[3];
|
2011-05-12 16:47:36 +00:00
|
|
|
int mval_cpy[2];
|
2011-04-21 17:25:58 +00:00
|
|
|
|
|
|
|
mval_cpy[0]= mval[0];
|
|
|
|
mval_cpy[1]= mval[1];
|
|
|
|
|
2011-05-12 16:47:36 +00:00
|
|
|
project_int_noclip(vc->ar, fp, mval_cpy);
|
2011-04-21 17:25:58 +00:00
|
|
|
|
2009-02-13 17:37:01 +00:00
|
|
|
initgrabz(vc->rv3d, fp[0], fp[1], fp[2]);
|
2011-04-21 17:25:58 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (mval_cpy[0]!=IS_CLIPPED) {
|
2011-05-20 13:50:41 +00:00
|
|
|
float mval_f[2];
|
|
|
|
VECSUB2D(mval_f, mval_cpy, mval);
|
|
|
|
ED_view3d_win_to_delta(vc->ar, mval_f, dvec);
|
2010-04-23 23:57:00 +00:00
|
|
|
sub_v3_v3(fp, dvec);
|
2011-04-21 18:33:30 +00:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* fallback to the view center */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (do_fallback) {
|
2011-04-21 18:33:30 +00:00
|
|
|
negate_v3_v3(fp, vc->rv3d->ofs);
|
|
|
|
return view3d_get_view_aligned_coordinate(vc, fp, mval, FALSE);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return FALSE;
|
|
|
|
}
|
2009-02-13 17:37:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-01-10 20:31:23 +00:00
|
|
|
/*
|
|
|
|
* ob == NULL if you want global matrices
|
|
|
|
* */
|
2011-12-26 20:19:55 +00:00
|
|
|
void view3d_get_transformation(const ARegion *ar, RegionView3D *rv3d, Object *ob, bglMats *mats)
|
2009-02-20 20:39:27 +00:00
|
|
|
{
|
|
|
|
float cpy[4][4];
|
|
|
|
int i, j;
|
|
|
|
|
2010-01-10 20:31:23 +00:00
|
|
|
if (ob) {
|
Math lib: matrix multiplication order fix for two functions that were
inconsistent with similar functions & math notation:
mul_m4_m4m4(R, B, A) => mult_m4_m4m4(R, A, B)
mul_m3_m3m4(R, B, A) => mult_m3_m3m4(R, A, B)
For branch maintainers, it should be relatively simple to fix things manually,
it's also possible run this script after merging to do automatic replacement:
http://www.pasteall.org/27459/python
2011-12-16 19:53:12 +00:00
|
|
|
mult_m4_m4m4(cpy, rv3d->viewmat, ob->obmat);
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
else {
|
2010-01-10 20:31:23 +00:00
|
|
|
copy_m4_m4(cpy, rv3d->viewmat);
|
|
|
|
}
|
2009-02-20 20:39:27 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
for (i = 0; i < 4; ++i) {
|
|
|
|
for (j = 0; j < 4; ++j) {
|
2009-10-27 19:53:34 +00:00
|
|
|
mats->projection[i*4+j] = rv3d->winmat[i][j];
|
2009-02-20 20:39:27 +00:00
|
|
|
mats->modelview[i*4+j] = cpy[i][j];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-10-27 19:53:34 +00:00
|
|
|
mats->viewport[0] = ar->winrct.xmin;
|
|
|
|
mats->viewport[1] = ar->winrct.ymin;
|
|
|
|
mats->viewport[2] = ar->winx;
|
|
|
|
mats->viewport[3] = ar->winy;
|
2009-02-20 20:39:27 +00:00
|
|
|
}
|
|
|
|
|
2008-12-20 18:43:21 +00:00
|
|
|
/* ********************** view3d_select: selection manipulations ********************* */
|
|
|
|
|
|
|
|
/* local prototypes */
|
|
|
|
|
2011-05-11 02:14:43 +00:00
|
|
|
static void EDBM_backbuf_checkAndSelectVerts(BMEditMesh *em, int select)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2009-05-16 16:18:08 +00:00
|
|
|
BMVert *eve;
|
|
|
|
BMIter iter;
|
2009-05-18 10:29:37 +00:00
|
|
|
int index= bm_wireoffs;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2012-02-12 10:51:45 +00:00
|
|
|
eve = BM_iter_new(&iter, em->bm, BM_VERTS_OF_MESH, NULL);
|
|
|
|
for ( ; eve; eve=BM_iter_step(&iter), index++) {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
|
|
|
|
if (EDBM_check_backbuf(index)) {
|
2012-02-12 18:43:59 +00:00
|
|
|
BM_vert_select_set(em->bm, eve, select);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-05-11 02:14:43 +00:00
|
|
|
static void EDBM_backbuf_checkAndSelectEdges(BMEditMesh *em, int select)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2009-05-16 16:18:08 +00:00
|
|
|
BMEdge *eed;
|
|
|
|
BMIter iter;
|
2009-05-18 10:29:37 +00:00
|
|
|
int index= bm_solidoffs;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2012-02-12 10:51:45 +00:00
|
|
|
eed = BM_iter_new(&iter, em->bm, BM_EDGES_OF_MESH, NULL);
|
|
|
|
for ( ; eed; eed=BM_iter_step(&iter), index++) {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
|
|
|
|
if (EDBM_check_backbuf(index)) {
|
2012-02-12 18:43:59 +00:00
|
|
|
BM_edge_select_set(em->bm, eed, select);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-05-11 02:14:43 +00:00
|
|
|
static void EDBM_backbuf_checkAndSelectFaces(BMEditMesh *em, int select)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2009-05-16 16:18:08 +00:00
|
|
|
BMFace *efa;
|
|
|
|
BMIter iter;
|
2008-12-20 18:43:21 +00:00
|
|
|
int index= 1;
|
|
|
|
|
2012-02-12 10:51:45 +00:00
|
|
|
efa = BM_iter_new(&iter, em->bm, BM_FACES_OF_MESH, NULL);
|
|
|
|
for ( ; efa; efa=BM_iter_step(&iter), index++) {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
|
|
|
|
if (EDBM_check_backbuf(index)) {
|
2012-02-12 18:43:59 +00:00
|
|
|
BM_face_select_set(em->bm, efa, select);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-18 17:10:28 +00:00
|
|
|
|
2011-09-18 02:46:03 +00:00
|
|
|
/* object mode, EM_ prefix is confusing here, rename? */
|
2011-09-22 16:09:27 +00:00
|
|
|
static void EDBM_backbuf_checkAndSelectVerts_obmode(Mesh *me, int select)
|
2011-07-05 18:03:31 +00:00
|
|
|
{
|
|
|
|
MVert *mv = me->mvert;
|
|
|
|
int a;
|
|
|
|
|
|
|
|
if (mv) {
|
2012-02-22 16:52:06 +00:00
|
|
|
for (a=1; a<=me->totvert; a++, mv++) {
|
|
|
|
if (EDBM_check_backbuf(a)) {
|
|
|
|
if (!(mv->flag & ME_HIDE)) {
|
2011-07-05 18:03:31 +00:00
|
|
|
mv->flag = select?(mv->flag|SELECT):(mv->flag&~SELECT);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-09-18 02:46:03 +00:00
|
|
|
/* object mode, EM_ prefix is confusing here, rename? */
|
2011-09-22 16:09:27 +00:00
|
|
|
|
2011-05-11 02:14:43 +00:00
|
|
|
static void EDBM_backbuf_checkAndSelectTFaces(Mesh *me, int select)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2011-02-27 06:19:40 +00:00
|
|
|
MPoly *mpoly = me->mpoly;
|
2008-12-20 18:43:21 +00:00
|
|
|
int a;
|
|
|
|
|
2011-02-27 06:19:40 +00:00
|
|
|
if (mpoly) {
|
2012-02-22 16:52:06 +00:00
|
|
|
for (a=1; a<=me->totpoly; a++, mpoly++) {
|
|
|
|
if (EDBM_check_backbuf(a)) {
|
2011-02-27 06:19:40 +00:00
|
|
|
mpoly->flag = select?(mpoly->flag|ME_FACE_SEL):(mpoly->flag&~ME_FACE_SEL);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* *********************** GESTURE AND LASSO ******************* */
|
|
|
|
|
2012-01-26 08:12:12 +00:00
|
|
|
typedef struct LassoSelectUserData {
|
|
|
|
ViewContext *vc;
|
|
|
|
rcti *rect;
|
|
|
|
int (*mcords)[2], moves, select, pass, done;
|
|
|
|
} LassoSelectUserData;
|
|
|
|
|
2010-06-04 06:02:46 +00:00
|
|
|
static int view3d_selectable_data(bContext *C)
|
|
|
|
{
|
|
|
|
Object *ob = CTX_data_active_object(C);
|
2011-01-17 22:37:24 +00:00
|
|
|
|
2010-09-27 10:44:46 +00:00
|
|
|
if (!ED_operator_region_view3d_active(C))
|
2010-06-04 06:02:46 +00:00
|
|
|
return 0;
|
2011-01-17 22:37:24 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ob) {
|
2011-01-18 14:34:59 +00:00
|
|
|
if (ob->mode & OB_MODE_EDIT) {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ob->type == OB_FONT) {
|
2011-01-18 14:34:59 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2011-01-17 22:37:24 +00:00
|
|
|
}
|
2011-01-18 14:34:59 +00:00
|
|
|
else {
|
|
|
|
if (ob->mode & OB_MODE_SCULPT) {
|
|
|
|
return 0;
|
|
|
|
}
|
2012-01-19 16:04:44 +00:00
|
|
|
if ((ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT)) &&
|
|
|
|
!paint_facesel_test(ob) && !paint_vertsel_test(ob))
|
|
|
|
{
|
2011-01-18 14:34:59 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2011-01-17 22:37:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-06-04 06:02:46 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-12-20 18:43:21 +00:00
|
|
|
/* helper also for borderselect */
|
|
|
|
static int edge_fully_inside_rect(rcti *rect, short x1, short y1, short x2, short y2)
|
|
|
|
{
|
|
|
|
return BLI_in_rcti(rect, x1, y1) && BLI_in_rcti(rect, x2, y2);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int edge_inside_rect(rcti *rect, short x1, short y1, short x2, short y2)
|
|
|
|
{
|
|
|
|
int d1, d2, d3, d4;
|
|
|
|
|
|
|
|
/* check points in rect */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (edge_fully_inside_rect(rect, x1, y1, x2, y2)) return 1;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
/* check points completely out rect */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (x1<rect->xmin && x2<rect->xmin) return 0;
|
|
|
|
if (x1>rect->xmax && x2>rect->xmax) return 0;
|
|
|
|
if (y1<rect->ymin && y2<rect->ymin) return 0;
|
|
|
|
if (y1>rect->ymax && y2>rect->ymax) return 0;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
/* simple check lines intersecting. */
|
|
|
|
d1= (y1-y2)*(x1- rect->xmin ) + (x2-x1)*(y1- rect->ymin );
|
|
|
|
d2= (y1-y2)*(x1- rect->xmin ) + (x2-x1)*(y1- rect->ymax );
|
|
|
|
d3= (y1-y2)*(x1- rect->xmax ) + (x2-x1)*(y1- rect->ymax );
|
|
|
|
d4= (y1-y2)*(x1- rect->xmax ) + (x2-x1)*(y1- rect->ymin );
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (d1<0 && d2<0 && d3<0 && d4<0) return 0;
|
|
|
|
if (d1>0 && d2>0 && d3>0 && d4>0) return 0;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#define MOVES_GESTURE 50
|
|
|
|
#define MOVES_LASSO 500
|
|
|
|
|
2011-05-12 16:47:36 +00:00
|
|
|
int lasso_inside(int mcords[][2], short moves, int sx, int sy)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
|
|
|
/* we do the angle rule, define that all added angles should be about zero or 2*PI */
|
|
|
|
float angletot=0.0, len, dot, ang, cross, fp1[2], fp2[2];
|
|
|
|
int a;
|
2011-05-12 16:47:36 +00:00
|
|
|
int *p1, *p2;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (sx==IS_CLIPPED)
|
2008-12-20 18:43:21 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
p1= mcords[moves-1];
|
|
|
|
p2= mcords[0];
|
|
|
|
|
|
|
|
/* first vector */
|
|
|
|
fp1[0]= (float)(p1[0]-sx);
|
|
|
|
fp1[1]= (float)(p1[1]-sy);
|
|
|
|
len= sqrt(fp1[0]*fp1[0] + fp1[1]*fp1[1]);
|
|
|
|
fp1[0]/= len;
|
|
|
|
fp1[1]/= len;
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
for (a=0; a<moves; a++) {
|
2008-12-20 18:43:21 +00:00
|
|
|
/* second vector */
|
|
|
|
fp2[0]= (float)(p2[0]-sx);
|
|
|
|
fp2[1]= (float)(p2[1]-sy);
|
|
|
|
len= sqrt(fp2[0]*fp2[0] + fp2[1]*fp2[1]);
|
|
|
|
fp2[0]/= len;
|
|
|
|
fp2[1]/= len;
|
|
|
|
|
|
|
|
/* dot and angle and cross */
|
|
|
|
dot= fp1[0]*fp2[0] + fp1[1]*fp2[1];
|
|
|
|
ang= fabs(saacos(dot));
|
|
|
|
|
|
|
|
cross= (float)((p1[1]-p2[1])*(p1[0]-sx) + (p2[0]-p1[0])*(p1[1]-sy));
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (cross<0.0f) angletot-= ang;
|
2008-12-20 18:43:21 +00:00
|
|
|
else angletot+= ang;
|
|
|
|
|
|
|
|
/* circulate */
|
|
|
|
fp1[0]= fp2[0]; fp1[1]= fp2[1];
|
|
|
|
p1= p2;
|
|
|
|
p2= mcords[a+1];
|
|
|
|
}
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if ( fabs(angletot) > 4.0 ) return 1;
|
2008-12-20 18:43:21 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* edge version for lasso select. we assume boundbox check was done */
|
2011-05-12 16:47:36 +00:00
|
|
|
int lasso_inside_edge(int mcords[][2], short moves, int x0, int y0, int x1, int y1)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2011-05-12 16:47:36 +00:00
|
|
|
int v1[2], v2[2];
|
2008-12-20 18:43:21 +00:00
|
|
|
int a;
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (x0==IS_CLIPPED || x1==IS_CLIPPED)
|
2008-12-20 18:43:21 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
v1[0] = x0, v1[1] = y0;
|
|
|
|
v2[0] = x1, v2[1] = y1;
|
|
|
|
|
|
|
|
/* check points in lasso */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (lasso_inside(mcords, moves, v1[0], v1[1])) return 1;
|
|
|
|
if (lasso_inside(mcords, moves, v2[0], v2[1])) return 1;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
/* no points in lasso, so we have to intersect with lasso edge */
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if ( isect_line_line_v2_int(mcords[0], mcords[moves-1], v1, v2) > 0) return 1;
|
|
|
|
for (a=0; a<moves-1; a++) {
|
|
|
|
if ( isect_line_line_v2_int(mcords[a], mcords[a+1], v1, v2) > 0) return 1;
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* warning; lasso select with backbuffer-check draws in backbuf with persp(PERSP_WIN)
|
2012-03-03 16:31:46 +00:00
|
|
|
* and returns with persp(PERSP_VIEW). After lasso select backbuf is not OK
|
|
|
|
*/
|
2011-05-12 16:47:36 +00:00
|
|
|
static void do_lasso_select_pose(ViewContext *vc, Object *ob, int mcords[][2], short moves, short select)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
|
|
|
bPoseChannel *pchan;
|
|
|
|
float vec[3];
|
2011-05-12 16:47:36 +00:00
|
|
|
int sco1[2], sco2[2];
|
2010-11-03 01:56:02 +00:00
|
|
|
bArmature *arm= ob->data;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ob->type!=OB_ARMATURE || ob->pose==NULL) return;
|
2010-11-03 01:56:02 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
|
2010-11-03 01:56:02 +00:00
|
|
|
if (PBONE_VISIBLE(arm, pchan->bone) && (pchan->bone->flag & BONE_UNSELECTABLE)==0) {
|
|
|
|
mul_v3_m4v3(vec, ob->obmat, pchan->pose_head);
|
2011-05-12 16:47:36 +00:00
|
|
|
project_int(vc->ar, vec, sco1);
|
2010-11-03 01:56:02 +00:00
|
|
|
mul_v3_m4v3(vec, ob->obmat, pchan->pose_tail);
|
2011-05-12 16:47:36 +00:00
|
|
|
project_int(vc->ar, vec, sco2);
|
2010-11-03 01:56:02 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (lasso_inside_edge(mcords, moves, sco1[0], sco1[1], sco2[0], sco2[1])) {
|
|
|
|
if (select) pchan->bone->flag |= BONE_SELECTED;
|
2010-11-03 01:56:02 +00:00
|
|
|
else pchan->bone->flag &= ~BONE_SELECTED;
|
|
|
|
}
|
2009-11-09 21:03:54 +00:00
|
|
|
}
|
|
|
|
}
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
|
2010-11-03 01:56:02 +00:00
|
|
|
static void object_deselect_all_visible(Scene *scene, View3D *v3d)
|
|
|
|
{
|
|
|
|
Base *base;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
for (base= scene->base.first; base; base= base->next) {
|
|
|
|
if (BASE_SELECTABLE(v3d, base)) {
|
2010-11-03 01:56:02 +00:00
|
|
|
ED_base_object_select(base, BA_DESELECT);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-05-12 16:47:36 +00:00
|
|
|
static void do_lasso_select_objects(ViewContext *vc, int mcords[][2], short moves, short extend, short select)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
|
|
|
Base *base;
|
|
|
|
|
2010-11-03 01:56:02 +00:00
|
|
|
if (extend == 0 && select)
|
|
|
|
object_deselect_all_visible(vc->scene, vc->v3d);
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
for (base= vc->scene->base.first; base; base= base->next) {
|
|
|
|
if (BASE_SELECTABLE(vc->v3d, base)) { /* use this to avoid un-needed lasso lookups */
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
project_short(vc->ar, base->object->obmat[3], &base->sx);
|
2012-02-22 16:52:06 +00:00
|
|
|
if (lasso_inside(mcords, moves, base->sx, base->sy)) {
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (select) ED_base_object_select(base, BA_SELECT);
|
2008-12-29 12:15:42 +00:00
|
|
|
else ED_base_object_select(base, BA_DESELECT);
|
2008-12-20 18:43:21 +00:00
|
|
|
base->object->flag= base->flag;
|
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
if (base->object->mode & OB_MODE_POSE) {
|
2010-01-19 16:38:48 +00:00
|
|
|
do_lasso_select_pose(vc, base->object, mcords, moves, select);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-05-12 16:47:36 +00:00
|
|
|
static void lasso_select_boundbox(rcti *rect, int mcords[][2], short moves)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
|
|
|
short a;
|
|
|
|
|
|
|
|
rect->xmin= rect->xmax= mcords[0][0];
|
|
|
|
rect->ymin= rect->ymax= mcords[0][1];
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
for (a=1; a<moves; a++) {
|
|
|
|
if (mcords[a][0]<rect->xmin) rect->xmin= mcords[a][0];
|
|
|
|
else if (mcords[a][0]>rect->xmax) rect->xmax= mcords[a][0];
|
|
|
|
if (mcords[a][1]<rect->ymin) rect->ymin= mcords[a][1];
|
|
|
|
else if (mcords[a][1]>rect->ymax) rect->ymax= mcords[a][1];
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-02-27 06:19:40 +00:00
|
|
|
static void do_lasso_select_mesh__doSelectVert(void *userData, BMVert *eve, int x, int y, int UNUSED(index))
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2012-01-26 08:12:12 +00:00
|
|
|
LassoSelectUserData *data = userData;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
if (BLI_in_rcti(data->rect, x, y) && lasso_inside(data->mcords, data->moves, x, y)) {
|
2012-02-12 10:51:45 +00:00
|
|
|
BM_elem_select_set(data->vc->em->bm, eve, data->select);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
2009-05-16 16:18:08 +00:00
|
|
|
static void do_lasso_select_mesh__doSelectEdge(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int index)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2012-01-26 08:12:12 +00:00
|
|
|
LassoSelectUserData *data = userData;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2010-01-28 00:45:30 +00:00
|
|
|
if (EDBM_check_backbuf(bm_solidoffs+index)) {
|
2008-12-20 18:43:21 +00:00
|
|
|
if (data->pass==0) {
|
|
|
|
if ( edge_fully_inside_rect(data->rect, x0, y0, x1, y1) &&
|
|
|
|
lasso_inside(data->mcords, data->moves, x0, y0) &&
|
|
|
|
lasso_inside(data->mcords, data->moves, x1, y1)) {
|
2012-02-12 10:51:45 +00:00
|
|
|
BM_elem_select_set(data->vc->em->bm, eed, data->select);
|
2008-12-20 18:43:21 +00:00
|
|
|
data->done = 1;
|
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
else {
|
2008-12-20 18:43:21 +00:00
|
|
|
if (lasso_inside_edge(data->mcords, data->moves, x0, y0, x1, y1)) {
|
2012-02-12 10:51:45 +00:00
|
|
|
BM_elem_select_set(data->vc->em->bm, eed, data->select);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-02-27 06:19:40 +00:00
|
|
|
static void do_lasso_select_mesh__doSelectFace(void *userData, BMFace *efa, int x, int y, int UNUSED(index))
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2012-01-26 08:12:12 +00:00
|
|
|
LassoSelectUserData *data = userData;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
if (BLI_in_rcti(data->rect, x, y) && lasso_inside(data->mcords, data->moves, x, y)) {
|
2012-02-12 10:51:45 +00:00
|
|
|
BM_elem_select_set(data->vc->em->bm, efa, data->select);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-05-12 16:47:36 +00:00
|
|
|
static void do_lasso_select_mesh(ViewContext *vc, int mcords[][2], short moves, short extend, short select)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2012-01-26 08:12:12 +00:00
|
|
|
LassoSelectUserData data;
|
2009-06-23 00:41:55 +00:00
|
|
|
ToolSettings *ts= vc->scene->toolsettings;
|
2008-12-20 18:43:21 +00:00
|
|
|
rcti rect;
|
|
|
|
int bbsel;
|
|
|
|
|
|
|
|
lasso_select_boundbox(&rect, mcords, moves);
|
|
|
|
|
2009-01-02 14:11:18 +00:00
|
|
|
/* set editmesh */
|
2012-03-02 12:09:49 +00:00
|
|
|
vc->em = BMEdit_FromObject(vc->obedit);
|
2009-01-02 14:11:18 +00:00
|
|
|
|
2012-01-26 08:12:12 +00:00
|
|
|
data.vc= vc;
|
2008-12-20 18:43:21 +00:00
|
|
|
data.rect = ▭
|
|
|
|
data.mcords = mcords;
|
|
|
|
data.moves = moves;
|
|
|
|
data.select = select;
|
|
|
|
data.done = 0;
|
|
|
|
data.pass = 0;
|
|
|
|
|
2010-11-03 01:56:02 +00:00
|
|
|
if (extend == 0 && select)
|
2012-02-12 18:43:59 +00:00
|
|
|
EDBM_flag_disable_all(vc->em, BM_ELEM_SELECT);
|
2010-11-03 01:56:02 +00:00
|
|
|
|
2011-06-09 03:56:32 +00:00
|
|
|
/* for non zbuf projections, dont change the GL state */
|
|
|
|
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
|
2010-02-08 10:12:02 +00:00
|
|
|
|
|
|
|
glLoadMatrixf(vc->rv3d->viewmat);
|
2010-01-28 00:45:30 +00:00
|
|
|
bbsel= EDBM_mask_init_backbuf_border(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ts->selectmode & SCE_SELECT_VERTEX) {
|
2008-12-20 18:43:21 +00:00
|
|
|
if (bbsel) {
|
2010-01-05 22:33:41 +00:00
|
|
|
EDBM_backbuf_checkAndSelectVerts(vc->em, select);
|
2011-06-09 03:56:32 +00:00
|
|
|
}
|
|
|
|
else {
|
2011-11-28 16:44:17 +00:00
|
|
|
mesh_foreachScreenVert(vc, do_lasso_select_mesh__doSelectVert, &data, V3D_CLIP_TEST_RV3D_CLIPPING);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ts->selectmode & SCE_SELECT_EDGE) {
|
2011-06-09 03:56:32 +00:00
|
|
|
/* Does both bbsel and non-bbsel versions (need screen cos for both) */
|
2008-12-20 18:43:21 +00:00
|
|
|
data.pass = 0;
|
2011-11-28 16:44:17 +00:00
|
|
|
mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_CLIP_TEST_OFF);
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
if (data.done==0) {
|
|
|
|
data.pass = 1;
|
2011-11-28 16:44:17 +00:00
|
|
|
mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_CLIP_TEST_OFF);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ts->selectmode & SCE_SELECT_FACE) {
|
2008-12-20 18:43:21 +00:00
|
|
|
if (bbsel) {
|
2010-01-28 00:45:30 +00:00
|
|
|
EDBM_backbuf_checkAndSelectFaces(vc->em, select);
|
2011-06-09 03:56:32 +00:00
|
|
|
}
|
|
|
|
else {
|
2008-12-30 16:03:29 +00:00
|
|
|
mesh_foreachScreenFace(vc, do_lasso_select_mesh__doSelectFace, &data);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-01-28 00:45:30 +00:00
|
|
|
EDBM_free_backbuf();
|
2012-02-10 06:16:21 +00:00
|
|
|
EDBM_selectmode_flush(vc->em);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
|
2012-02-27 13:47:53 +00:00
|
|
|
/* BMESH_TODO */
|
2008-12-20 18:43:21 +00:00
|
|
|
#if 0
|
|
|
|
/* this is an exception in that its the only lasso that dosnt use the 3d view (uses space image view) */
|
2011-05-12 16:47:36 +00:00
|
|
|
static void do_lasso_select_mesh_uv(int mcords[][2], short moves, short select)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
|
|
|
EditFace *efa;
|
|
|
|
MTFace *tf;
|
|
|
|
int screenUV[2], nverts, i, ok = 1;
|
|
|
|
rcti rect;
|
|
|
|
|
|
|
|
lasso_select_boundbox(&rect, mcords, moves);
|
|
|
|
|
|
|
|
if (draw_uvs_face_check()) { /* Face Center Sel */
|
|
|
|
float cent[2];
|
|
|
|
ok = 0;
|
|
|
|
for (efa= em->faces.first; efa; efa= efa->next) {
|
|
|
|
/* assume not touched */
|
|
|
|
efa->tmp.l = 0;
|
|
|
|
tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
|
|
|
|
if ((select) != (simaFaceSel_Check(efa, tf))) {
|
|
|
|
uv_center(tf->uv, cent, (void *)efa->v4);
|
|
|
|
uvco_to_areaco_noclip(cent, screenUV);
|
|
|
|
if (BLI_in_rcti(&rect, screenUV[0], screenUV[1]) && lasso_inside(mcords, moves, screenUV[0], screenUV[1])) {
|
|
|
|
efa->tmp.l = ok = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* (de)selects all tagged faces and deals with sticky modes */
|
|
|
|
if (ok)
|
|
|
|
uvface_setsel__internal(select);
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
else { /* Vert Sel*/
|
2008-12-20 18:43:21 +00:00
|
|
|
for (efa= em->faces.first; efa; efa= efa->next) {
|
|
|
|
tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
|
2010-04-24 10:08:07 +00:00
|
|
|
if (uvedit_face_visible(scene, ima, efa, tf)) {
|
2008-12-20 18:43:21 +00:00
|
|
|
nverts= efa->v4? 4: 3;
|
2012-02-22 16:52:06 +00:00
|
|
|
for (i=0; i<nverts; i++) {
|
2008-12-20 18:43:21 +00:00
|
|
|
if ((select) != (simaUVSel_Check(efa, tf, i))) {
|
|
|
|
uvco_to_areaco_noclip(tf->uv[i], screenUV);
|
|
|
|
if (BLI_in_rcti(&rect, screenUV[0], screenUV[1]) && lasso_inside(mcords, moves, screenUV[0], screenUV[1])) {
|
|
|
|
if (select) {
|
|
|
|
simaUVSel_Set(efa, tf, i);
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
else {
|
2008-12-20 18:43:21 +00:00
|
|
|
simaUVSel_UnSet(efa, tf, i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (ok && G.sima->flag & SI_SYNC_UVSEL) {
|
2008-12-30 16:03:29 +00:00
|
|
|
if (select) EM_select_flush(vc->em);
|
|
|
|
else EM_deselect_flush(vc->em);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2010-10-15 12:29:02 +00:00
|
|
|
static void do_lasso_select_curve__doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, int x, int y)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2012-01-26 08:12:12 +00:00
|
|
|
LassoSelectUserData *data = userData;
|
2010-04-30 04:48:40 +00:00
|
|
|
Object *obedit= data->vc->obedit;
|
|
|
|
Curve *cu= (Curve*)obedit->data;
|
|
|
|
|
2008-12-20 18:43:21 +00:00
|
|
|
if (lasso_inside(data->mcords, data->moves, x, y)) {
|
|
|
|
if (bp) {
|
|
|
|
bp->f1 = data->select?(bp->f1|SELECT):(bp->f1&~SELECT);
|
2010-04-30 04:48:40 +00:00
|
|
|
if (bp == cu->lastsel && !(bp->f1 & 1)) cu->lastsel = NULL;
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
else {
|
2009-09-16 17:43:09 +00:00
|
|
|
if (cu->drawflag & CU_HIDE_HANDLES) {
|
2008-12-20 18:43:21 +00:00
|
|
|
/* can only be beztindex==0 here since handles are hidden */
|
|
|
|
bezt->f1 = bezt->f2 = bezt->f3 = data->select?(bezt->f2|SELECT):(bezt->f2&~SELECT);
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
else {
|
2008-12-20 18:43:21 +00:00
|
|
|
if (beztindex==0) {
|
|
|
|
bezt->f1 = data->select?(bezt->f1|SELECT):(bezt->f1&~SELECT);
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
else if (beztindex==1) {
|
2008-12-20 18:43:21 +00:00
|
|
|
bezt->f2 = data->select?(bezt->f2|SELECT):(bezt->f2&~SELECT);
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
else {
|
2008-12-20 18:43:21 +00:00
|
|
|
bezt->f3 = data->select?(bezt->f3|SELECT):(bezt->f3&~SELECT);
|
|
|
|
}
|
|
|
|
}
|
2010-04-30 04:48:40 +00:00
|
|
|
|
|
|
|
if (bezt == cu->lastsel && !(bezt->f2 & 1)) cu->lastsel = NULL;
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-05-12 16:47:36 +00:00
|
|
|
static void do_lasso_select_curve(ViewContext *vc, int mcords[][2], short moves, short extend, short select)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2012-01-26 08:12:12 +00:00
|
|
|
LassoSelectUserData data;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2009-01-02 14:11:18 +00:00
|
|
|
/* set vc->editnurb */
|
2010-04-30 04:48:40 +00:00
|
|
|
data.vc = vc;
|
2008-12-20 18:43:21 +00:00
|
|
|
data.mcords = mcords;
|
|
|
|
data.moves = moves;
|
|
|
|
data.select = select;
|
|
|
|
|
2010-11-03 01:56:02 +00:00
|
|
|
if (extend == 0 && select)
|
|
|
|
CU_deselect_all(vc->obedit);
|
|
|
|
|
2009-10-22 23:22:05 +00:00
|
|
|
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
|
2008-12-30 16:03:29 +00:00
|
|
|
nurbs_foreachScreenVert(vc, do_lasso_select_curve__doSelect, &data);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void do_lasso_select_lattice__doSelect(void *userData, BPoint *bp, int x, int y)
|
|
|
|
{
|
2012-01-26 08:12:12 +00:00
|
|
|
LassoSelectUserData *data = userData;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
if (lasso_inside(data->mcords, data->moves, x, y)) {
|
|
|
|
bp->f1 = data->select?(bp->f1|SELECT):(bp->f1&~SELECT);
|
|
|
|
}
|
|
|
|
}
|
2011-05-12 16:47:36 +00:00
|
|
|
static void do_lasso_select_lattice(ViewContext *vc, int mcords[][2], short moves, short extend, short select)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2012-01-26 08:12:12 +00:00
|
|
|
LassoSelectUserData data;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2009-01-02 14:11:18 +00:00
|
|
|
/* set editdata in vc */
|
2008-12-20 18:43:21 +00:00
|
|
|
data.mcords = mcords;
|
|
|
|
data.moves = moves;
|
|
|
|
data.select = select;
|
|
|
|
|
2010-11-03 01:56:02 +00:00
|
|
|
if (extend == 0 && select)
|
|
|
|
ED_setflagsLatt(vc->obedit, 0);
|
|
|
|
|
2009-10-22 23:22:05 +00:00
|
|
|
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
|
2008-12-30 16:03:29 +00:00
|
|
|
lattice_foreachScreenVert(vc, do_lasso_select_lattice__doSelect, &data);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
|
2011-05-12 16:47:36 +00:00
|
|
|
static void do_lasso_select_armature(ViewContext *vc, int mcords[][2], short moves, short extend, short select)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2009-01-04 14:14:06 +00:00
|
|
|
bArmature *arm= vc->obedit->data;
|
2008-12-20 18:43:21 +00:00
|
|
|
EditBone *ebone;
|
|
|
|
float vec[3];
|
|
|
|
short sco1[2], sco2[2], didpoint;
|
2010-09-15 13:22:36 +00:00
|
|
|
int change= FALSE;
|
2010-11-03 01:56:02 +00:00
|
|
|
|
|
|
|
if (extend==0 && select)
|
|
|
|
ED_armature_deselect_all_visible(vc->obedit);
|
|
|
|
|
2009-01-02 14:11:18 +00:00
|
|
|
/* set editdata in vc */
|
|
|
|
|
2009-01-04 14:14:06 +00:00
|
|
|
for (ebone= arm->edbo->first; ebone; ebone=ebone->next) {
|
2010-11-03 01:56:02 +00:00
|
|
|
if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_UNSELECTABLE)==0) {
|
|
|
|
mul_v3_m4v3(vec, vc->obedit->obmat, ebone->head);
|
|
|
|
project_short(vc->ar, vec, sco1);
|
|
|
|
mul_v3_m4v3(vec, vc->obedit->obmat, ebone->tail);
|
|
|
|
project_short(vc->ar, vec, sco2);
|
|
|
|
|
|
|
|
didpoint= 0;
|
2012-02-22 16:52:06 +00:00
|
|
|
if (lasso_inside(mcords, moves, sco1[0], sco1[1])) {
|
|
|
|
if (select) ebone->flag |= BONE_ROOTSEL;
|
2010-11-03 01:56:02 +00:00
|
|
|
else ebone->flag &= ~BONE_ROOTSEL;
|
|
|
|
didpoint= 1;
|
|
|
|
change= TRUE;
|
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
if (lasso_inside(mcords, moves, sco2[0], sco2[1])) {
|
|
|
|
if (select) ebone->flag |= BONE_TIPSEL;
|
2011-05-11 09:31:00 +00:00
|
|
|
else ebone->flag &= ~BONE_TIPSEL;
|
|
|
|
didpoint= 1;
|
|
|
|
change= TRUE;
|
2010-11-03 01:56:02 +00:00
|
|
|
}
|
|
|
|
/* if one of points selected, we skip the bone itself */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (didpoint==0 && lasso_inside_edge(mcords, moves, sco1[0], sco1[1], sco2[0], sco2[1])) {
|
|
|
|
if (select) ebone->flag |= BONE_TIPSEL|BONE_ROOTSEL|BONE_SELECTED;
|
2010-11-03 01:56:02 +00:00
|
|
|
else ebone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
|
|
|
|
change= TRUE;
|
|
|
|
}
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
2010-09-15 13:22:36 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (change) {
|
2010-09-15 13:22:36 +00:00
|
|
|
ED_armature_sync_selection(arm->edbo);
|
|
|
|
ED_armature_validate_active(arm);
|
|
|
|
WM_main_add_notifier(NC_OBJECT|ND_BONE_SELECT, vc->obedit);
|
|
|
|
}
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
|
2010-11-03 02:28:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2011-05-12 16:47:36 +00:00
|
|
|
static void do_lasso_select_meta(ViewContext *vc, int mcords[][2], short moves, short extend, short select)
|
2010-11-03 02:28:11 +00:00
|
|
|
{
|
|
|
|
MetaBall *mb = (MetaBall*)vc->obedit->data;
|
|
|
|
MetaElem *ml;
|
|
|
|
float vec[3];
|
|
|
|
short sco[2];
|
|
|
|
|
|
|
|
if (extend == 0 && select) {
|
2012-02-22 16:52:06 +00:00
|
|
|
for (ml= mb->editelems->first; ml; ml= ml->next) {
|
2010-11-03 02:28:11 +00:00
|
|
|
ml->flag &= ~SELECT;
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
2010-11-03 02:28:11 +00:00
|
|
|
}
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
for (ml= mb->editelems->first; ml; ml= ml->next) {
|
2010-11-03 02:28:11 +00:00
|
|
|
|
|
|
|
mul_v3_m4v3(vec, vc->obedit->obmat, &ml->x);
|
|
|
|
project_short(vc->ar, vec, sco);
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (lasso_inside(mcords, moves, sco[0], sco[1])) {
|
|
|
|
if (select) ml->flag |= SELECT;
|
2010-11-03 02:28:11 +00:00
|
|
|
else ml->flag &= ~SELECT;
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-07-14 18:04:48 +00:00
|
|
|
int do_paintvert_box_select(ViewContext *vc, rcti *rect, int select, int extend)
|
2011-07-13 20:45:09 +00:00
|
|
|
{
|
2011-08-09 16:32:15 +00:00
|
|
|
Mesh *me;
|
|
|
|
MVert *mvert;
|
|
|
|
struct ImBuf *ibuf;
|
|
|
|
unsigned int *rt;
|
|
|
|
int a, index;
|
|
|
|
char *selar;
|
2011-07-14 18:04:48 +00:00
|
|
|
int sx= rect->xmax-rect->xmin+1;
|
|
|
|
int sy= rect->ymax-rect->ymin+1;
|
2011-07-15 17:09:43 +00:00
|
|
|
|
2011-08-09 16:32:15 +00:00
|
|
|
me= vc->obact->data;
|
2011-07-13 20:45:09 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (me==NULL || me->totvert==0 || sx*sy <= 0)
|
2011-07-14 18:04:48 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2011-07-13 20:45:09 +00:00
|
|
|
|
2011-08-09 16:32:15 +00:00
|
|
|
selar= MEM_callocN(me->totvert+1, "selar");
|
2010-11-03 02:28:11 +00:00
|
|
|
|
2011-08-09 16:32:15 +00:00
|
|
|
if (extend == 0 && select)
|
|
|
|
paintvert_deselect_all_visible(vc->obact, SEL_DESELECT, FALSE);
|
2011-07-13 20:45:09 +00:00
|
|
|
|
2011-08-09 16:32:15 +00:00
|
|
|
view3d_validate_backbuf(vc);
|
2011-07-13 20:45:09 +00:00
|
|
|
|
2011-08-09 16:32:15 +00:00
|
|
|
ibuf = IMB_allocImBuf(sx,sy,32,IB_rect);
|
|
|
|
rt = ibuf->rect;
|
|
|
|
glReadPixels(rect->xmin+vc->ar->winrct.xmin, rect->ymin+vc->ar->winrct.ymin, sx, sy, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ENDIAN_ORDER==B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf);
|
2011-08-09 16:32:15 +00:00
|
|
|
|
|
|
|
a= sx*sy;
|
2012-02-22 16:52:06 +00:00
|
|
|
while (a--) {
|
|
|
|
if (*rt) {
|
2011-08-09 16:32:15 +00:00
|
|
|
index= WM_framebuffer_to_index(*rt);
|
2012-02-22 16:52:06 +00:00
|
|
|
if (index<=me->totvert) selar[index]= 1;
|
2011-08-09 16:32:15 +00:00
|
|
|
}
|
|
|
|
rt++;
|
|
|
|
}
|
|
|
|
|
|
|
|
mvert= me->mvert;
|
2012-03-10 22:00:55 +00:00
|
|
|
for (a = 1; a <= me->totvert; a++, mvert++) {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (selar[a]) {
|
2012-03-10 22:00:55 +00:00
|
|
|
if ((mvert->flag & ME_HIDE) == 0) {
|
|
|
|
if (select) mvert->flag |= SELECT;
|
|
|
|
else mvert->flag &= ~SELECT;
|
2011-08-09 16:32:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
IMB_freeImBuf(ibuf);
|
|
|
|
MEM_freeN(selar);
|
|
|
|
|
|
|
|
#ifdef __APPLE__
|
|
|
|
glReadBuffer(GL_BACK);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
paintvert_flush_flags(vc->obact);
|
2011-07-13 20:45:09 +00:00
|
|
|
|
2011-07-14 18:04:48 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
2011-09-18 17:10:28 +00:00
|
|
|
|
2011-07-14 18:04:48 +00:00
|
|
|
static void do_lasso_select_paintvert(ViewContext *vc, int mcords[][2], short moves, short extend, short select)
|
|
|
|
{
|
|
|
|
Object *ob= vc->obact;
|
|
|
|
Mesh *me= ob?ob->data:NULL;
|
2011-08-09 16:32:15 +00:00
|
|
|
rcti rect;
|
2011-07-14 18:04:48 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (me==NULL || me->totvert==0)
|
2011-07-14 18:04:48 +00:00
|
|
|
return;
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (extend==0 && select)
|
2011-07-14 18:04:48 +00:00
|
|
|
paintvert_deselect_all_visible(ob, SEL_DESELECT, FALSE); /* flush selection at the end */
|
2011-09-22 16:09:27 +00:00
|
|
|
bm_vertoffs= me->totvert+1; /* max index array */
|
2011-08-09 16:32:15 +00:00
|
|
|
|
|
|
|
lasso_select_boundbox(&rect, mcords, moves);
|
2011-09-22 16:09:27 +00:00
|
|
|
EDBM_mask_init_backbuf_border(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
|
2011-08-09 16:32:15 +00:00
|
|
|
|
2011-09-22 16:09:27 +00:00
|
|
|
EDBM_backbuf_checkAndSelectVerts_obmode(me, select);
|
2011-08-09 16:32:15 +00:00
|
|
|
|
2011-09-22 16:09:27 +00:00
|
|
|
EDBM_free_backbuf();
|
2011-07-14 18:04:48 +00:00
|
|
|
|
|
|
|
paintvert_flush_flags(ob);
|
2011-07-13 20:45:09 +00:00
|
|
|
}
|
2011-05-12 16:47:36 +00:00
|
|
|
static void do_lasso_select_paintface(ViewContext *vc, int mcords[][2], short moves, short extend, short select)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2008-12-30 16:03:29 +00:00
|
|
|
Object *ob= vc->obact;
|
2008-12-20 18:43:21 +00:00
|
|
|
Mesh *me= ob?ob->data:NULL;
|
|
|
|
rcti rect;
|
2010-11-03 02:50:05 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (me==NULL || me->totpoly==0)
|
2010-11-03 01:56:02 +00:00
|
|
|
return;
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (extend==0 && select)
|
2010-11-03 01:56:02 +00:00
|
|
|
paintface_deselect_all_visible(ob, SEL_DESELECT, FALSE); /* flush selection at the end */
|
|
|
|
|
2011-02-27 06:19:40 +00:00
|
|
|
bm_vertoffs= me->totpoly+1; /* max index array */
|
2010-11-03 01:56:02 +00:00
|
|
|
|
2008-12-20 18:43:21 +00:00
|
|
|
lasso_select_boundbox(&rect, mcords, moves);
|
2010-01-28 00:45:30 +00:00
|
|
|
EDBM_mask_init_backbuf_border(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2010-01-28 00:45:30 +00:00
|
|
|
EDBM_backbuf_checkAndSelectTFaces(me, select);
|
2010-11-03 01:56:02 +00:00
|
|
|
|
2010-01-28 00:45:30 +00:00
|
|
|
EDBM_free_backbuf();
|
2010-11-03 01:56:02 +00:00
|
|
|
|
|
|
|
paintface_flush_flags(ob);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
2011-05-12 16:47:36 +00:00
|
|
|
static void do_lasso_select_node(int mcords[][2], short moves, short select)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
|
|
|
SpaceNode *snode = sa->spacedata.first;
|
|
|
|
|
|
|
|
bNode *node;
|
|
|
|
rcti rect;
|
|
|
|
short node_cent[2];
|
|
|
|
float node_centf[2];
|
|
|
|
|
|
|
|
lasso_select_boundbox(&rect, mcords, moves);
|
|
|
|
|
|
|
|
/* store selection in temp test flag */
|
2012-02-22 16:52:06 +00:00
|
|
|
for (node= snode->edittree->nodes.first; node; node= node->next) {
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
node_centf[0] = (node->totr.xmin+node->totr.xmax)/2;
|
|
|
|
node_centf[1] = (node->totr.ymin+node->totr.ymax)/2;
|
|
|
|
|
|
|
|
ipoco_to_areaco_noclip(G.v2d, node_centf, node_cent);
|
|
|
|
if (BLI_in_rcti(&rect, node_cent[0], node_cent[1]) && lasso_inside(mcords, moves, node_cent[0], node_cent[1])) {
|
|
|
|
if (select) {
|
|
|
|
node->flag |= SELECT;
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
else {
|
2008-12-20 18:43:21 +00:00
|
|
|
node->flag &= ~SELECT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
BIF_undo_push("Lasso select nodes");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2011-05-12 16:47:36 +00:00
|
|
|
static void view3d_lasso_select(bContext *C, ViewContext *vc, int mcords[][2], short moves, short extend, short select)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2009-08-15 20:36:15 +00:00
|
|
|
Object *ob = CTX_data_active_object(C);
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (vc->obedit==NULL) { /* Object Mode */
|
|
|
|
if (paint_facesel_test(ob))
|
2010-11-03 01:56:02 +00:00
|
|
|
do_lasso_select_paintface(vc, mcords, moves, extend, select);
|
2012-02-22 16:52:06 +00:00
|
|
|
else if (paint_vertsel_test(ob))
|
2011-07-13 20:45:09 +00:00
|
|
|
do_lasso_select_paintvert(vc, mcords, moves, extend, select);
|
2012-02-22 16:52:06 +00:00
|
|
|
else if (ob && ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT))
|
2008-12-20 18:43:21 +00:00
|
|
|
;
|
2012-02-22 16:52:06 +00:00
|
|
|
else if (ob && ob->mode & OB_MODE_PARTICLE_EDIT)
|
2010-11-03 01:56:02 +00:00
|
|
|
PE_lasso_select(C, mcords, moves, extend, select);
|
2010-08-25 00:58:15 +00:00
|
|
|
else {
|
2010-11-03 01:56:02 +00:00
|
|
|
do_lasso_select_objects(vc, mcords, moves, extend, select);
|
2010-08-25 00:58:15 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, vc->scene);
|
|
|
|
}
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
2009-10-26 09:35:33 +00:00
|
|
|
else { /* Edit Mode */
|
2010-11-03 02:28:11 +00:00
|
|
|
switch(vc->obedit->type) {
|
|
|
|
case OB_MESH:
|
2010-11-03 01:56:02 +00:00
|
|
|
do_lasso_select_mesh(vc, mcords, moves, extend, select);
|
2010-11-03 02:28:11 +00:00
|
|
|
break;
|
|
|
|
case OB_CURVE:
|
|
|
|
case OB_SURF:
|
2010-11-03 01:56:02 +00:00
|
|
|
do_lasso_select_curve(vc, mcords, moves, extend, select);
|
2010-11-03 02:28:11 +00:00
|
|
|
break;
|
|
|
|
case OB_LATTICE:
|
2010-11-03 01:56:02 +00:00
|
|
|
do_lasso_select_lattice(vc, mcords, moves, extend, select);
|
2010-11-03 02:28:11 +00:00
|
|
|
break;
|
|
|
|
case OB_ARMATURE:
|
2010-11-03 01:56:02 +00:00
|
|
|
do_lasso_select_armature(vc, mcords, moves, extend, select);
|
2010-11-03 02:28:11 +00:00
|
|
|
break;
|
|
|
|
case OB_MBALL:
|
|
|
|
do_lasso_select_meta(vc, mcords, moves, extend, select);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
assert(!"lasso select on incorrect object type");
|
|
|
|
}
|
|
|
|
|
2009-10-26 09:35:33 +00:00
|
|
|
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, vc->obedit->data);
|
|
|
|
}
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
|
2009-01-02 14:11:18 +00:00
|
|
|
|
|
|
|
/* lasso operator gives properties, but since old code works
|
2012-03-03 16:31:46 +00:00
|
|
|
* with short array we convert */
|
2009-01-02 14:11:18 +00:00
|
|
|
static int view3d_lasso_select_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
ViewContext vc;
|
2010-11-03 01:56:02 +00:00
|
|
|
int i= 0;
|
2011-05-12 16:47:36 +00:00
|
|
|
int mcords[1024][2];
|
2009-01-02 14:11:18 +00:00
|
|
|
|
|
|
|
RNA_BEGIN(op->ptr, itemptr, "path") {
|
|
|
|
float loc[2];
|
|
|
|
|
|
|
|
RNA_float_get_array(&itemptr, "loc", loc);
|
2011-05-12 16:47:36 +00:00
|
|
|
mcords[i][0]= (int)loc[0];
|
|
|
|
mcords[i][1]= (int)loc[1];
|
2009-01-02 14:11:18 +00:00
|
|
|
i++;
|
2012-02-22 16:52:06 +00:00
|
|
|
if (i>=1024) break;
|
2009-01-02 14:11:18 +00:00
|
|
|
}
|
|
|
|
RNA_END;
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (i>1) {
|
2010-11-03 01:56:02 +00:00
|
|
|
short extend, select;
|
2.5
Sanitized the 'tweak' event.
Original idea was to have WM event system generating it
automatically. However, I first tested it via a handler
and operator, to check what kind of configurations would
be useful. It appeared to not work nice, also because
that inserting a tweak operator in a keymap is confusing.
Now 'tweaks' are generated automatically, and can be
catched by keymaps as any event. The current definition
of tweak is:
- if Left/Middle/Rightmouse pressed
if event wasn't handled by window queue (modal handlers)
start checking mousepositions
- while mousepositions are checked
- escape on any event other than mouse
- on mouse events:
- add tweak event if mousemove > 10 pixels
- stop checking for tweak if mousebutton released
- Tweak events have a define indicating mousebutton used
EVT_TWEAK_L, EVT_TWEAK_M, EVT_TWEAK_R
- In keymap definitions you can use _S or _A to map to
action or select mouse userdef.
- Event value in keymap should be KM_ANY for all tweaks,
or use one of the eight directions:
EVT_GESTURE_E, _SE, _S, _SW, _W, _NW, _N, _NE
- And of course you can add modifier checks in keymaps for it.
- Because tweaks are a result of mouse events, the handlers get
both to evaluate. That means that RMB-select + tweak will work
correctly.
In case you don't want both to be handled, for example the
CTRL+LMB 'extrude' and CTRL+LMB-tweak 'lasso select', you will
need to set the first acting on a EVT_RELEASE, this event only
gets passed on when tweak fails.
The current system allows all options, configurable, we had in 2.48,
and many more! A diagram of what's possible is on the todo. :)
Also in this commit: lasso select editmesh failed with 'zbuffer
occluded select'. Also circle-select failed.
2009-02-02 14:13:14 +00:00
|
|
|
view3d_operator_needs_opengl(C);
|
|
|
|
|
2.5
- Edit mesh: Add ctrl+click add vertex or extrude.
I've made it not move the 3d cursor in that case.
Also found out tweak events conflicted with existing
keymap definitions; on tweak failure (= no mousemove)
it now passes on the mouse event as 'mouse down' for
the remaining keymaps to check.
These then actually respond to mouse-up instead of down...
The location in the keymaps where tweaks get generated
remains important. Examples:
1 - 'select' mouse-handler, operator return pass-through
2 - tweak handler checks, and makes tweak event
3 - grabber responds to tweak event
1 - ctrl+mouse tweak handler checks, makes tweak event,
or passes event on
2 - if tweak event, it runs lasso
3 - else when passed on, ctrl+click extrude happens
In the first case, select works on mouse-down, immediate.
In the second case, extrude happens on mouse-release, even
though the keymap defined mouse-press.
This will make designing nice balanced keymaps still not
simple; especially because you can't tell operators to
pass on the key... although we can add the convention that
select-mouse operators always pass on to enable tweaks.
Still a good reason to wait with custom keymaps
when this is fully settled!
2009-01-30 18:18:41 +00:00
|
|
|
/* setup view context for argument to callbacks */
|
|
|
|
view3d_set_viewcontext(C, &vc);
|
|
|
|
|
2010-11-03 01:56:02 +00:00
|
|
|
extend= RNA_boolean_get(op->ptr, "extend");
|
RNA
* Enums can now be dynamically created in the _itemf callback,
using RNA_enum_item(s)_add, RNA_enum_item_end. All places asking
for enum items now need to potentially free the items.
* This callback now also gets context, this was added specifically
for operators. This doesn't fit design well at all, needed to do
some ugly hacks, but can't find a good solution at the moment.
* All enums must have a default list of items too, even with an
_itemf callback, for docs and fallback in case there is no context.
* Used by MESH_OT_merge, MESH_OT_select_similar, TFM_OT_select_orientation.
* Also changes some operator properties that were enums to booleas
(unselected, deselect), to make them consistent with other ops.
2009-07-10 19:56:13 +00:00
|
|
|
select= !RNA_boolean_get(op->ptr, "deselect");
|
2010-11-03 01:56:02 +00:00
|
|
|
view3d_lasso_select(C, &vc, mcords, i, extend, select);
|
2.5
- Edit mesh: Add ctrl+click add vertex or extrude.
I've made it not move the 3d cursor in that case.
Also found out tweak events conflicted with existing
keymap definitions; on tweak failure (= no mousemove)
it now passes on the mouse event as 'mouse down' for
the remaining keymaps to check.
These then actually respond to mouse-up instead of down...
The location in the keymaps where tweaks get generated
remains important. Examples:
1 - 'select' mouse-handler, operator return pass-through
2 - tweak handler checks, and makes tweak event
3 - grabber responds to tweak event
1 - ctrl+mouse tweak handler checks, makes tweak event,
or passes event on
2 - if tweak event, it runs lasso
3 - else when passed on, ctrl+click extrude happens
In the first case, select works on mouse-down, immediate.
In the second case, extrude happens on mouse-release, even
though the keymap defined mouse-press.
This will make designing nice balanced keymaps still not
simple; especially because you can't tell operators to
pass on the key... although we can add the convention that
select-mouse operators always pass on to enable tweaks.
Still a good reason to wait with custom keymaps
when this is fully settled!
2009-01-30 18:18:41 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
return OPERATOR_PASS_THROUGH;
|
2009-01-02 14:11:18 +00:00
|
|
|
}
|
|
|
|
|
2009-03-29 02:15:13 +00:00
|
|
|
void VIEW3D_OT_select_lasso(wmOperatorType *ot)
|
2009-01-02 14:11:18 +00:00
|
|
|
{
|
|
|
|
ot->name= "Lasso Select";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description= "Select items using lasso selection";
|
2009-03-29 02:15:13 +00:00
|
|
|
ot->idname= "VIEW3D_OT_select_lasso";
|
2009-01-02 14:11:18 +00:00
|
|
|
|
|
|
|
ot->invoke= WM_gesture_lasso_invoke;
|
|
|
|
ot->modal= WM_gesture_lasso_modal;
|
|
|
|
ot->exec= view3d_lasso_select_exec;
|
2010-06-04 06:02:46 +00:00
|
|
|
ot->poll= view3d_selectable_data;
|
2011-06-06 11:04:54 +00:00
|
|
|
ot->cancel= WM_gesture_lasso_cancel;
|
2009-01-02 14:11:18 +00:00
|
|
|
|
2009-01-31 19:40:40 +00:00
|
|
|
/* flags */
|
2009-05-23 03:24:15 +00:00
|
|
|
ot->flag= OPTYPE_UNDO;
|
2009-01-31 19:40:40 +00:00
|
|
|
|
2009-01-16 23:53:11 +00:00
|
|
|
RNA_def_collection_runtime(ot->srna, "path", &RNA_OperatorMousePath, "Path", "");
|
2011-09-19 12:26:20 +00:00
|
|
|
RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Deselect rather than select items");
|
|
|
|
RNA_def_boolean(ot->srna, "extend", 1, "Extend", "Extend selection instead of deselecting everything first");
|
2009-01-02 14:11:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ************************************************* */
|
|
|
|
|
2008-12-20 18:43:21 +00:00
|
|
|
#if 0
|
|
|
|
/* smart function to sample a rect spiralling outside, nice for backbuf selection */
|
|
|
|
static unsigned int samplerect(unsigned int *buf, int size, unsigned int dontdo)
|
|
|
|
{
|
|
|
|
Base *base;
|
|
|
|
unsigned int *bufmin,*bufmax;
|
2011-08-01 02:58:44 +00:00
|
|
|
int a,b,rc,tel,len,dirvec[4][2],maxob;
|
2008-12-20 18:43:21 +00:00
|
|
|
unsigned int retval=0;
|
|
|
|
|
|
|
|
base= LASTBASE;
|
2012-02-22 16:52:06 +00:00
|
|
|
if (base==0) return 0;
|
2008-12-20 18:43:21 +00:00
|
|
|
maxob= base->selcol;
|
|
|
|
|
2011-08-01 02:58:44 +00:00
|
|
|
len= (size-1)/2;
|
2008-12-20 18:43:21 +00:00
|
|
|
rc= 0;
|
|
|
|
|
|
|
|
dirvec[0][0]= 1;
|
|
|
|
dirvec[0][1]= 0;
|
|
|
|
dirvec[1][0]= 0;
|
|
|
|
dirvec[1][1]= -size;
|
|
|
|
dirvec[2][0]= -1;
|
|
|
|
dirvec[2][1]= 0;
|
|
|
|
dirvec[3][0]= 0;
|
|
|
|
dirvec[3][1]= size;
|
|
|
|
|
|
|
|
bufmin= buf;
|
|
|
|
bufmax= buf+ size*size;
|
2011-08-01 02:58:44 +00:00
|
|
|
buf+= len*size+ len;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
for (tel=1;tel<=size;tel++) {
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
for (a=0;a<2;a++) {
|
|
|
|
for (b=0;b<tel;b++) {
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (*buf && *buf<=maxob && *buf!=dontdo) return *buf;
|
|
|
|
if ( *buf==dontdo ) retval= dontdo; /* if only color dontdo is available, still return dontdo */
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
buf+= (dirvec[rc][0]+dirvec[rc][1]);
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (buf<bufmin || buf>=bufmax) return retval;
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
rc++;
|
|
|
|
rc &= 3;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* ************************** mouse select ************************* */
|
|
|
|
|
|
|
|
|
|
|
|
/* The max number of menu items in an object select menu */
|
2012-01-11 03:40:20 +00:00
|
|
|
typedef struct SelMenuItemF {
|
|
|
|
char idname[MAX_ID_NAME-2];
|
|
|
|
int icon;
|
|
|
|
} SelMenuItemF;
|
|
|
|
|
2008-12-20 18:43:21 +00:00
|
|
|
#define SEL_MENU_SIZE 22
|
2012-01-11 03:40:20 +00:00
|
|
|
static SelMenuItemF object_mouse_select_menu_data[SEL_MENU_SIZE];
|
|
|
|
|
|
|
|
/* special (crappy) operator only for menu select */
|
|
|
|
static EnumPropertyItem *object_select_menu_enum_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free)
|
|
|
|
{
|
|
|
|
EnumPropertyItem *item= NULL, item_tmp= {0};
|
|
|
|
int totitem= 0;
|
|
|
|
int i= 0;
|
|
|
|
|
|
|
|
/* dont 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);
|
|
|
|
}
|
|
|
|
|
|
|
|
RNA_enum_item_end(&item, &totitem);
|
|
|
|
*free= 1;
|
|
|
|
|
|
|
|
return item;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int object_select_menu_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
int name_index= RNA_enum_get(op->ptr, "name");
|
|
|
|
short extend= RNA_boolean_get(op->ptr, "extend");
|
|
|
|
short changed = 0;
|
|
|
|
const char *name= object_mouse_select_menu_data[name_index].idname;
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (!extend) {
|
2012-01-11 03:40:20 +00:00
|
|
|
CTX_DATA_BEGIN(C, Base*, base, selectable_bases) {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (base->flag & SELECT) {
|
2012-01-11 03:40:20 +00:00
|
|
|
ED_base_object_select(base, BA_DESELECT);
|
|
|
|
changed= 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CTX_DATA_END;
|
|
|
|
}
|
|
|
|
|
|
|
|
CTX_DATA_BEGIN(C, Base*, base, selectable_bases) {
|
|
|
|
/* this is a bit dodjy, there should only be ONE object with this name, but library objects can mess this up */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (strcmp(name, base->object->id.name+2)==0) {
|
2012-01-11 03:40:20 +00:00
|
|
|
ED_base_object_activate(C, base);
|
|
|
|
ED_base_object_select(base, BA_SELECT);
|
|
|
|
changed= 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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? */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (changed) {
|
2012-01-11 03:40:20 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C));
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void VIEW3D_OT_select_menu(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
PropertyRNA *prop;
|
|
|
|
|
|
|
|
/* 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;
|
|
|
|
|
|
|
|
/* 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);
|
|
|
|
ot->prop= prop;
|
|
|
|
|
|
|
|
RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend selection instead of deselecting everything first");
|
|
|
|
}
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
static void deselectall_except(Scene *scene, Base *b) /* deselect all except b */
|
|
|
|
{
|
|
|
|
Base *base;
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
for (base= FIRSTBASE; base; base= base->next) {
|
2008-12-20 18:43:21 +00:00
|
|
|
if (base->flag & SELECT) {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (b!=base) {
|
2008-12-29 12:15:42 +00:00
|
|
|
ED_base_object_select(base, BA_DESELECT);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-11 03:40:20 +00:00
|
|
|
static Base *object_mouse_select_menu(bContext *C, ViewContext *vc, unsigned int *buffer, int hits, const int mval[2], short extend)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
|
|
|
short baseCount = 0;
|
2009-09-16 17:43:09 +00:00
|
|
|
short ok;
|
|
|
|
LinkNode *linklist= NULL;
|
|
|
|
|
|
|
|
CTX_DATA_BEGIN(C, Base*, base, selectable_bases) {
|
|
|
|
ok= FALSE;
|
|
|
|
|
|
|
|
/* two selection methods, the CTRL select uses max dist of 15 */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (buffer) {
|
2009-09-16 17:43:09 +00:00
|
|
|
int a;
|
2012-02-22 16:52:06 +00:00
|
|
|
for (a=0; a<hits; a++) {
|
2009-09-16 17:43:09 +00:00
|
|
|
/* index was converted */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (base->selcol==buffer[ (4 * a) + 3 ])
|
2009-09-16 17:43:09 +00:00
|
|
|
ok= TRUE;
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
2009-09-16 17:43:09 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
int temp, dist=15;
|
|
|
|
|
|
|
|
project_short(vc->ar, base->object->obmat[3], &base->sx);
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2009-09-16 17:43:09 +00:00
|
|
|
temp= abs(base->sx -mval[0]) + abs(base->sy -mval[1]);
|
2012-02-22 16:52:06 +00:00
|
|
|
if (temp < dist)
|
2009-09-16 17:43:09 +00:00
|
|
|
ok= TRUE;
|
|
|
|
}
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ok) {
|
2009-09-16 17:43:09 +00:00
|
|
|
baseCount++;
|
|
|
|
BLI_linklist_prepend(&linklist, base);
|
|
|
|
|
|
|
|
if (baseCount==SEL_MENU_SIZE)
|
|
|
|
break;
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
2009-09-16 17:43:09 +00:00
|
|
|
CTX_DATA_END;
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (baseCount==0) {
|
2009-09-16 17:43:09 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
if (baseCount == 1) {
|
2009-09-16 17:43:09 +00:00
|
|
|
Base *base= (Base *)linklist->link;
|
|
|
|
BLI_linklist_free(linklist, NULL);
|
|
|
|
return base;
|
|
|
|
}
|
2008-12-20 18:43:21 +00:00
|
|
|
else {
|
2012-01-11 03:40:20 +00:00
|
|
|
/* UI, full in static array values that we later use in an enum function */
|
2009-09-16 17:43:09 +00:00
|
|
|
LinkNode *node;
|
2012-01-11 03:40:20 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
memset(object_mouse_select_menu_data, 0, sizeof(object_mouse_select_menu_data));
|
2009-09-16 17:43:09 +00:00
|
|
|
|
2012-01-11 03:40:20 +00:00
|
|
|
for (node = linklist, i = 0; node; node= node->next, i++) {
|
2009-09-16 17:43:09 +00:00
|
|
|
Base *base=node->link;
|
|
|
|
Object *ob= base->object;
|
|
|
|
char *name= ob->id.name+2;
|
|
|
|
|
2012-01-11 03:40:20 +00:00
|
|
|
BLI_strncpy(object_mouse_select_menu_data[i].idname, name, MAX_ID_NAME-2);
|
|
|
|
object_mouse_select_menu_data[i].icon = uiIconFromID(&ob->id);
|
|
|
|
}
|
2009-09-16 17:43:09 +00:00
|
|
|
|
2012-01-11 03:40:20 +00:00
|
|
|
{
|
|
|
|
PointerRNA ptr;
|
2009-09-16 17:43:09 +00:00
|
|
|
|
2012-01-11 03:40:20 +00:00
|
|
|
WM_operator_properties_create(&ptr, "VIEW3D_OT_select_menu");
|
|
|
|
RNA_boolean_set(&ptr, "extend", extend);
|
|
|
|
WM_operator_name_call(C, "VIEW3D_OT_select_menu", WM_OP_INVOKE_DEFAULT, &ptr);
|
|
|
|
WM_operator_properties_free(&ptr);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
2009-09-16 17:43:09 +00:00
|
|
|
|
|
|
|
BLI_linklist_free(linklist, NULL);
|
|
|
|
return NULL;
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* we want a select buffer with bones, if there are... */
|
|
|
|
/* so check three selection levels and compare */
|
2011-05-12 16:47:36 +00:00
|
|
|
static short mixed_bones_object_selectbuffer(ViewContext *vc, unsigned int *buffer, const int mval[2])
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
|
|
|
rcti rect;
|
|
|
|
int offs;
|
|
|
|
short a, hits15, hits9=0, hits5=0;
|
|
|
|
short has_bones15=0, has_bones9=0, has_bones5=0;
|
|
|
|
|
|
|
|
BLI_init_rcti(&rect, mval[0]-14, mval[0]+14, mval[1]-14, mval[1]+14);
|
2008-12-30 16:03:29 +00:00
|
|
|
hits15= view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect);
|
2012-02-22 16:52:06 +00:00
|
|
|
if (hits15>0) {
|
|
|
|
for (a=0; a<hits15; a++) if (buffer[4*a+3] & 0xFFFF0000) has_bones15= 1;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
offs= 4*hits15;
|
|
|
|
BLI_init_rcti(&rect, mval[0]-9, mval[0]+9, mval[1]-9, mval[1]+9);
|
2008-12-30 16:03:29 +00:00
|
|
|
hits9= view3d_opengl_select(vc, buffer+offs, MAXPICKBUF-offs, &rect);
|
2012-02-22 16:52:06 +00:00
|
|
|
if (hits9>0) {
|
|
|
|
for (a=0; a<hits9; a++) if (buffer[offs+4*a+3] & 0xFFFF0000) has_bones9= 1;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
offs+= 4*hits9;
|
|
|
|
BLI_init_rcti(&rect, mval[0]-5, mval[0]+5, mval[1]-5, mval[1]+5);
|
2008-12-30 16:03:29 +00:00
|
|
|
hits5= view3d_opengl_select(vc, buffer+offs, MAXPICKBUF-offs, &rect);
|
2012-02-22 16:52:06 +00:00
|
|
|
if (hits5>0) {
|
|
|
|
for (a=0; a<hits5; a++) if (buffer[offs+4*a+3] & 0xFFFF0000) has_bones5= 1;
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (has_bones5) {
|
2008-12-20 18:43:21 +00:00
|
|
|
offs= 4*hits15 + 4*hits9;
|
|
|
|
memcpy(buffer, buffer+offs, 4*offs);
|
|
|
|
return hits5;
|
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
if (has_bones9) {
|
2008-12-20 18:43:21 +00:00
|
|
|
offs= 4*hits15;
|
|
|
|
memcpy(buffer, buffer+offs, 4*offs);
|
|
|
|
return hits9;
|
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
if (has_bones15) {
|
2008-12-20 18:43:21 +00:00
|
|
|
return hits15;
|
|
|
|
}
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (hits5>0) {
|
2008-12-20 18:43:21 +00:00
|
|
|
offs= 4*hits15 + 4*hits9;
|
|
|
|
memcpy(buffer, buffer+offs, 4*offs);
|
|
|
|
return hits5;
|
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
if (hits9>0) {
|
2008-12-20 18:43:21 +00:00
|
|
|
offs= 4*hits15;
|
|
|
|
memcpy(buffer, buffer+offs, 4*offs);
|
|
|
|
return hits9;
|
|
|
|
}
|
|
|
|
return hits15;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
Drag and drop 2.5 integration! Finally, slashdot regulars can use
Blender too now! :)
** Drag works as follows:
- drag-able items are defined by the standard interface ui toolkit
- each button can get this feature, via uiButSetDragXXX(but, ...).
There are calls to define drag-able images, ID blocks, RNA paths,
file paths, and so on. By default you drag an icon, exceptionally
an ImBuf
- Drag items are registered centrally in the WM, it allows more drag
items simultaneous too, but not implemented
** Drop works as follows:
- On mouse release, and if drag items exist in the WM, it converts
the mouse event to an EVT_DROP type. This event then gets the full
drag info as customdata
- drop regions are defined with WM_dropbox_add(), similar to keymaps
you can make a "drop map" this way, which become 'drop map handlers'
in the queues.
- next to that the UI kit handles some common button types (like
accepting ID or names) to be catching a drop event too.
- Every "drop box" has two callbacks:
- poll() = check if the event drag data is relevant for this box
- copy() = fill in custom properties in the dropbox to initialize
an operator
- The dropbox handler then calls its standard Operator with its
dropbox properties.
** Currently implemented
Drag items:
- ID icons in browse buttons
- ID icons in context menu of properties region
- ID icons in outliner and rna viewer
- FileBrowser icons
- FileBrowser preview images
Drag-able icons are subtly visualized by making them brighter a bit
on mouse-over. In case the icon is a button or UI element too (most
cases), the drag-able feature will make the item react to
mouse-release instead of mouse-press.
Drop options:
- UI buttons: ID and text buttons (paste name)
- View3d: Object ID drop copies object
- View3d: Material ID drop assigns to object under cursor
- View3d: Image ID drop assigns to object UV texture under cursor
- Sequencer: Path drop will add either Image or Movie strip
- Image window: Path drop will open image
** Drag and drop Notes:
- Dropping into another Blender window (from same application) works
too. I've added code that passes on mousemoves and clicks to other
windows, without activating them though. This does make using multi-window
Blender a bit friendler.
- Dropping a file path to an image, is not the same as dropping an
Image ID... keep this in mind. Sequencer for example wants paths to
be dropped, textures in 3d window wants an Image ID.
- Although drop boxes could be defined via Python, I suggest they're
part of the UI and editor design (= how we want an editor to work), and
not default offered configurable like keymaps.
- At the moment only one item can be dragged at a time. This is for
several reasons.... For one, Blender doesn't have a well defined
uniform way to define "what is selected" (files, outliner items, etc).
Secondly there's potential conflicts on what todo when you drop mixed
drag sets on spots. All undefined stuff... nice for later.
- Example to bypass the above: a collection of images that form a strip,
should be represented in filewindow as a single sequence anyway.
This then will fit well and gets handled neatly by design.
- Another option to check is to allow multiple options per drop... it
could show the operator as a sort of menu, allowing arrow or scrollwheel
to choose. For time being I'd prefer to try to design a singular drop
though, just offer only one drop action per data type on given spots.
- What does work already, but a tad slow, is to use a function that
detects an object (type) under cursor, so a drag item's option can be
further refined (like drop object on object = parent). (disabled)
** More notes
- Added saving for Region layouts (like split points for toolbar)
- Label buttons now handle mouse over
- File list: added full path entry for drop feature.
- Filesel bugfix: wm_operator_exec() got called there and fully handled,
while WM event code tried same. Added new OPERATOR_HANDLED flag for this.
Maybe python needs it too?
- Cocoa: added window move event, so multi-win setups work OK (didnt save).
- Interface_handlers.c: removed win->active
- Severe area copy bug: area handlers were not set to NULL
- Filesel bugfix: next/prev folder list was not copied on area copies
** Leftover todos
- Cocoa windows seem to hang on cases still... needs check
- Cocoa 'draw overlap' swap doesn't work
- Cocoa window loses focus permanently on using Spotlight
(for these reasons, makefile building has Carbon as default atm)
- ListView templates in UI cannot become dragged yet, needs review...
it consists of two overlapping UI elements, preventing handling icon clicks.
- There's already Ghost library code to handle dropping from OS
into Blender window. I've noticed this code is unfinished for Macs, but
seems to be complete for Windows. Needs test... currently, an external
drop event will print in console when succesfully delivered to Blender's WM.
2010-01-26 18:18:21 +00:00
|
|
|
/* returns basact */
|
2011-05-12 16:47:36 +00:00
|
|
|
static Base *mouse_select_eval_buffer(ViewContext *vc, unsigned int *buffer, int hits, const int mval[2], Base *startbase, int has_bones)
|
Drag and drop 2.5 integration! Finally, slashdot regulars can use
Blender too now! :)
** Drag works as follows:
- drag-able items are defined by the standard interface ui toolkit
- each button can get this feature, via uiButSetDragXXX(but, ...).
There are calls to define drag-able images, ID blocks, RNA paths,
file paths, and so on. By default you drag an icon, exceptionally
an ImBuf
- Drag items are registered centrally in the WM, it allows more drag
items simultaneous too, but not implemented
** Drop works as follows:
- On mouse release, and if drag items exist in the WM, it converts
the mouse event to an EVT_DROP type. This event then gets the full
drag info as customdata
- drop regions are defined with WM_dropbox_add(), similar to keymaps
you can make a "drop map" this way, which become 'drop map handlers'
in the queues.
- next to that the UI kit handles some common button types (like
accepting ID or names) to be catching a drop event too.
- Every "drop box" has two callbacks:
- poll() = check if the event drag data is relevant for this box
- copy() = fill in custom properties in the dropbox to initialize
an operator
- The dropbox handler then calls its standard Operator with its
dropbox properties.
** Currently implemented
Drag items:
- ID icons in browse buttons
- ID icons in context menu of properties region
- ID icons in outliner and rna viewer
- FileBrowser icons
- FileBrowser preview images
Drag-able icons are subtly visualized by making them brighter a bit
on mouse-over. In case the icon is a button or UI element too (most
cases), the drag-able feature will make the item react to
mouse-release instead of mouse-press.
Drop options:
- UI buttons: ID and text buttons (paste name)
- View3d: Object ID drop copies object
- View3d: Material ID drop assigns to object under cursor
- View3d: Image ID drop assigns to object UV texture under cursor
- Sequencer: Path drop will add either Image or Movie strip
- Image window: Path drop will open image
** Drag and drop Notes:
- Dropping into another Blender window (from same application) works
too. I've added code that passes on mousemoves and clicks to other
windows, without activating them though. This does make using multi-window
Blender a bit friendler.
- Dropping a file path to an image, is not the same as dropping an
Image ID... keep this in mind. Sequencer for example wants paths to
be dropped, textures in 3d window wants an Image ID.
- Although drop boxes could be defined via Python, I suggest they're
part of the UI and editor design (= how we want an editor to work), and
not default offered configurable like keymaps.
- At the moment only one item can be dragged at a time. This is for
several reasons.... For one, Blender doesn't have a well defined
uniform way to define "what is selected" (files, outliner items, etc).
Secondly there's potential conflicts on what todo when you drop mixed
drag sets on spots. All undefined stuff... nice for later.
- Example to bypass the above: a collection of images that form a strip,
should be represented in filewindow as a single sequence anyway.
This then will fit well and gets handled neatly by design.
- Another option to check is to allow multiple options per drop... it
could show the operator as a sort of menu, allowing arrow or scrollwheel
to choose. For time being I'd prefer to try to design a singular drop
though, just offer only one drop action per data type on given spots.
- What does work already, but a tad slow, is to use a function that
detects an object (type) under cursor, so a drag item's option can be
further refined (like drop object on object = parent). (disabled)
** More notes
- Added saving for Region layouts (like split points for toolbar)
- Label buttons now handle mouse over
- File list: added full path entry for drop feature.
- Filesel bugfix: wm_operator_exec() got called there and fully handled,
while WM event code tried same. Added new OPERATOR_HANDLED flag for this.
Maybe python needs it too?
- Cocoa: added window move event, so multi-win setups work OK (didnt save).
- Interface_handlers.c: removed win->active
- Severe area copy bug: area handlers were not set to NULL
- Filesel bugfix: next/prev folder list was not copied on area copies
** Leftover todos
- Cocoa windows seem to hang on cases still... needs check
- Cocoa 'draw overlap' swap doesn't work
- Cocoa window loses focus permanently on using Spotlight
(for these reasons, makefile building has Carbon as default atm)
- ListView templates in UI cannot become dragged yet, needs review...
it consists of two overlapping UI elements, preventing handling icon clicks.
- There's already Ghost library code to handle dropping from OS
into Blender window. I've noticed this code is unfinished for Macs, but
seems to be complete for Windows. Needs test... currently, an external
drop event will print in console when succesfully delivered to Blender's WM.
2010-01-26 18:18:21 +00:00
|
|
|
{
|
|
|
|
Scene *scene= vc->scene;
|
|
|
|
View3D *v3d= vc->v3d;
|
|
|
|
Base *base, *basact= NULL;
|
2011-05-12 16:47:36 +00:00
|
|
|
static int lastmval[2]={-100, -100};
|
Drag and drop 2.5 integration! Finally, slashdot regulars can use
Blender too now! :)
** Drag works as follows:
- drag-able items are defined by the standard interface ui toolkit
- each button can get this feature, via uiButSetDragXXX(but, ...).
There are calls to define drag-able images, ID blocks, RNA paths,
file paths, and so on. By default you drag an icon, exceptionally
an ImBuf
- Drag items are registered centrally in the WM, it allows more drag
items simultaneous too, but not implemented
** Drop works as follows:
- On mouse release, and if drag items exist in the WM, it converts
the mouse event to an EVT_DROP type. This event then gets the full
drag info as customdata
- drop regions are defined with WM_dropbox_add(), similar to keymaps
you can make a "drop map" this way, which become 'drop map handlers'
in the queues.
- next to that the UI kit handles some common button types (like
accepting ID or names) to be catching a drop event too.
- Every "drop box" has two callbacks:
- poll() = check if the event drag data is relevant for this box
- copy() = fill in custom properties in the dropbox to initialize
an operator
- The dropbox handler then calls its standard Operator with its
dropbox properties.
** Currently implemented
Drag items:
- ID icons in browse buttons
- ID icons in context menu of properties region
- ID icons in outliner and rna viewer
- FileBrowser icons
- FileBrowser preview images
Drag-able icons are subtly visualized by making them brighter a bit
on mouse-over. In case the icon is a button or UI element too (most
cases), the drag-able feature will make the item react to
mouse-release instead of mouse-press.
Drop options:
- UI buttons: ID and text buttons (paste name)
- View3d: Object ID drop copies object
- View3d: Material ID drop assigns to object under cursor
- View3d: Image ID drop assigns to object UV texture under cursor
- Sequencer: Path drop will add either Image or Movie strip
- Image window: Path drop will open image
** Drag and drop Notes:
- Dropping into another Blender window (from same application) works
too. I've added code that passes on mousemoves and clicks to other
windows, without activating them though. This does make using multi-window
Blender a bit friendler.
- Dropping a file path to an image, is not the same as dropping an
Image ID... keep this in mind. Sequencer for example wants paths to
be dropped, textures in 3d window wants an Image ID.
- Although drop boxes could be defined via Python, I suggest they're
part of the UI and editor design (= how we want an editor to work), and
not default offered configurable like keymaps.
- At the moment only one item can be dragged at a time. This is for
several reasons.... For one, Blender doesn't have a well defined
uniform way to define "what is selected" (files, outliner items, etc).
Secondly there's potential conflicts on what todo when you drop mixed
drag sets on spots. All undefined stuff... nice for later.
- Example to bypass the above: a collection of images that form a strip,
should be represented in filewindow as a single sequence anyway.
This then will fit well and gets handled neatly by design.
- Another option to check is to allow multiple options per drop... it
could show the operator as a sort of menu, allowing arrow or scrollwheel
to choose. For time being I'd prefer to try to design a singular drop
though, just offer only one drop action per data type on given spots.
- What does work already, but a tad slow, is to use a function that
detects an object (type) under cursor, so a drag item's option can be
further refined (like drop object on object = parent). (disabled)
** More notes
- Added saving for Region layouts (like split points for toolbar)
- Label buttons now handle mouse over
- File list: added full path entry for drop feature.
- Filesel bugfix: wm_operator_exec() got called there and fully handled,
while WM event code tried same. Added new OPERATOR_HANDLED flag for this.
Maybe python needs it too?
- Cocoa: added window move event, so multi-win setups work OK (didnt save).
- Interface_handlers.c: removed win->active
- Severe area copy bug: area handlers were not set to NULL
- Filesel bugfix: next/prev folder list was not copied on area copies
** Leftover todos
- Cocoa windows seem to hang on cases still... needs check
- Cocoa 'draw overlap' swap doesn't work
- Cocoa window loses focus permanently on using Spotlight
(for these reasons, makefile building has Carbon as default atm)
- ListView templates in UI cannot become dragged yet, needs review...
it consists of two overlapping UI elements, preventing handling icon clicks.
- There's already Ghost library code to handle dropping from OS
into Blender window. I've noticed this code is unfinished for Macs, but
seems to be complete for Windows. Needs test... currently, an external
drop event will print in console when succesfully delivered to Blender's WM.
2010-01-26 18:18:21 +00:00
|
|
|
int a, donearest= 0;
|
|
|
|
|
|
|
|
/* define if we use solid nearest select or not */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (v3d->drawtype>OB_WIRE) {
|
Drag and drop 2.5 integration! Finally, slashdot regulars can use
Blender too now! :)
** Drag works as follows:
- drag-able items are defined by the standard interface ui toolkit
- each button can get this feature, via uiButSetDragXXX(but, ...).
There are calls to define drag-able images, ID blocks, RNA paths,
file paths, and so on. By default you drag an icon, exceptionally
an ImBuf
- Drag items are registered centrally in the WM, it allows more drag
items simultaneous too, but not implemented
** Drop works as follows:
- On mouse release, and if drag items exist in the WM, it converts
the mouse event to an EVT_DROP type. This event then gets the full
drag info as customdata
- drop regions are defined with WM_dropbox_add(), similar to keymaps
you can make a "drop map" this way, which become 'drop map handlers'
in the queues.
- next to that the UI kit handles some common button types (like
accepting ID or names) to be catching a drop event too.
- Every "drop box" has two callbacks:
- poll() = check if the event drag data is relevant for this box
- copy() = fill in custom properties in the dropbox to initialize
an operator
- The dropbox handler then calls its standard Operator with its
dropbox properties.
** Currently implemented
Drag items:
- ID icons in browse buttons
- ID icons in context menu of properties region
- ID icons in outliner and rna viewer
- FileBrowser icons
- FileBrowser preview images
Drag-able icons are subtly visualized by making them brighter a bit
on mouse-over. In case the icon is a button or UI element too (most
cases), the drag-able feature will make the item react to
mouse-release instead of mouse-press.
Drop options:
- UI buttons: ID and text buttons (paste name)
- View3d: Object ID drop copies object
- View3d: Material ID drop assigns to object under cursor
- View3d: Image ID drop assigns to object UV texture under cursor
- Sequencer: Path drop will add either Image or Movie strip
- Image window: Path drop will open image
** Drag and drop Notes:
- Dropping into another Blender window (from same application) works
too. I've added code that passes on mousemoves and clicks to other
windows, without activating them though. This does make using multi-window
Blender a bit friendler.
- Dropping a file path to an image, is not the same as dropping an
Image ID... keep this in mind. Sequencer for example wants paths to
be dropped, textures in 3d window wants an Image ID.
- Although drop boxes could be defined via Python, I suggest they're
part of the UI and editor design (= how we want an editor to work), and
not default offered configurable like keymaps.
- At the moment only one item can be dragged at a time. This is for
several reasons.... For one, Blender doesn't have a well defined
uniform way to define "what is selected" (files, outliner items, etc).
Secondly there's potential conflicts on what todo when you drop mixed
drag sets on spots. All undefined stuff... nice for later.
- Example to bypass the above: a collection of images that form a strip,
should be represented in filewindow as a single sequence anyway.
This then will fit well and gets handled neatly by design.
- Another option to check is to allow multiple options per drop... it
could show the operator as a sort of menu, allowing arrow or scrollwheel
to choose. For time being I'd prefer to try to design a singular drop
though, just offer only one drop action per data type on given spots.
- What does work already, but a tad slow, is to use a function that
detects an object (type) under cursor, so a drag item's option can be
further refined (like drop object on object = parent). (disabled)
** More notes
- Added saving for Region layouts (like split points for toolbar)
- Label buttons now handle mouse over
- File list: added full path entry for drop feature.
- Filesel bugfix: wm_operator_exec() got called there and fully handled,
while WM event code tried same. Added new OPERATOR_HANDLED flag for this.
Maybe python needs it too?
- Cocoa: added window move event, so multi-win setups work OK (didnt save).
- Interface_handlers.c: removed win->active
- Severe area copy bug: area handlers were not set to NULL
- Filesel bugfix: next/prev folder list was not copied on area copies
** Leftover todos
- Cocoa windows seem to hang on cases still... needs check
- Cocoa 'draw overlap' swap doesn't work
- Cocoa window loses focus permanently on using Spotlight
(for these reasons, makefile building has Carbon as default atm)
- ListView templates in UI cannot become dragged yet, needs review...
it consists of two overlapping UI elements, preventing handling icon clicks.
- There's already Ghost library code to handle dropping from OS
into Blender window. I've noticed this code is unfinished for Macs, but
seems to be complete for Windows. Needs test... currently, an external
drop event will print in console when succesfully delivered to Blender's WM.
2010-01-26 18:18:21 +00:00
|
|
|
donearest= 1;
|
2012-02-22 16:52:06 +00:00
|
|
|
if ( ABS(mval[0]-lastmval[0])<3 && ABS(mval[1]-lastmval[1])<3) {
|
|
|
|
if (!has_bones) /* hrms, if theres bones we always do nearest */
|
Drag and drop 2.5 integration! Finally, slashdot regulars can use
Blender too now! :)
** Drag works as follows:
- drag-able items are defined by the standard interface ui toolkit
- each button can get this feature, via uiButSetDragXXX(but, ...).
There are calls to define drag-able images, ID blocks, RNA paths,
file paths, and so on. By default you drag an icon, exceptionally
an ImBuf
- Drag items are registered centrally in the WM, it allows more drag
items simultaneous too, but not implemented
** Drop works as follows:
- On mouse release, and if drag items exist in the WM, it converts
the mouse event to an EVT_DROP type. This event then gets the full
drag info as customdata
- drop regions are defined with WM_dropbox_add(), similar to keymaps
you can make a "drop map" this way, which become 'drop map handlers'
in the queues.
- next to that the UI kit handles some common button types (like
accepting ID or names) to be catching a drop event too.
- Every "drop box" has two callbacks:
- poll() = check if the event drag data is relevant for this box
- copy() = fill in custom properties in the dropbox to initialize
an operator
- The dropbox handler then calls its standard Operator with its
dropbox properties.
** Currently implemented
Drag items:
- ID icons in browse buttons
- ID icons in context menu of properties region
- ID icons in outliner and rna viewer
- FileBrowser icons
- FileBrowser preview images
Drag-able icons are subtly visualized by making them brighter a bit
on mouse-over. In case the icon is a button or UI element too (most
cases), the drag-able feature will make the item react to
mouse-release instead of mouse-press.
Drop options:
- UI buttons: ID and text buttons (paste name)
- View3d: Object ID drop copies object
- View3d: Material ID drop assigns to object under cursor
- View3d: Image ID drop assigns to object UV texture under cursor
- Sequencer: Path drop will add either Image or Movie strip
- Image window: Path drop will open image
** Drag and drop Notes:
- Dropping into another Blender window (from same application) works
too. I've added code that passes on mousemoves and clicks to other
windows, without activating them though. This does make using multi-window
Blender a bit friendler.
- Dropping a file path to an image, is not the same as dropping an
Image ID... keep this in mind. Sequencer for example wants paths to
be dropped, textures in 3d window wants an Image ID.
- Although drop boxes could be defined via Python, I suggest they're
part of the UI and editor design (= how we want an editor to work), and
not default offered configurable like keymaps.
- At the moment only one item can be dragged at a time. This is for
several reasons.... For one, Blender doesn't have a well defined
uniform way to define "what is selected" (files, outliner items, etc).
Secondly there's potential conflicts on what todo when you drop mixed
drag sets on spots. All undefined stuff... nice for later.
- Example to bypass the above: a collection of images that form a strip,
should be represented in filewindow as a single sequence anyway.
This then will fit well and gets handled neatly by design.
- Another option to check is to allow multiple options per drop... it
could show the operator as a sort of menu, allowing arrow or scrollwheel
to choose. For time being I'd prefer to try to design a singular drop
though, just offer only one drop action per data type on given spots.
- What does work already, but a tad slow, is to use a function that
detects an object (type) under cursor, so a drag item's option can be
further refined (like drop object on object = parent). (disabled)
** More notes
- Added saving for Region layouts (like split points for toolbar)
- Label buttons now handle mouse over
- File list: added full path entry for drop feature.
- Filesel bugfix: wm_operator_exec() got called there and fully handled,
while WM event code tried same. Added new OPERATOR_HANDLED flag for this.
Maybe python needs it too?
- Cocoa: added window move event, so multi-win setups work OK (didnt save).
- Interface_handlers.c: removed win->active
- Severe area copy bug: area handlers were not set to NULL
- Filesel bugfix: next/prev folder list was not copied on area copies
** Leftover todos
- Cocoa windows seem to hang on cases still... needs check
- Cocoa 'draw overlap' swap doesn't work
- Cocoa window loses focus permanently on using Spotlight
(for these reasons, makefile building has Carbon as default atm)
- ListView templates in UI cannot become dragged yet, needs review...
it consists of two overlapping UI elements, preventing handling icon clicks.
- There's already Ghost library code to handle dropping from OS
into Blender window. I've noticed this code is unfinished for Macs, but
seems to be complete for Windows. Needs test... currently, an external
drop event will print in console when succesfully delivered to Blender's WM.
2010-01-26 18:18:21 +00:00
|
|
|
donearest= 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
lastmval[0]= mval[0]; lastmval[1]= mval[1];
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (donearest) {
|
Drag and drop 2.5 integration! Finally, slashdot regulars can use
Blender too now! :)
** Drag works as follows:
- drag-able items are defined by the standard interface ui toolkit
- each button can get this feature, via uiButSetDragXXX(but, ...).
There are calls to define drag-able images, ID blocks, RNA paths,
file paths, and so on. By default you drag an icon, exceptionally
an ImBuf
- Drag items are registered centrally in the WM, it allows more drag
items simultaneous too, but not implemented
** Drop works as follows:
- On mouse release, and if drag items exist in the WM, it converts
the mouse event to an EVT_DROP type. This event then gets the full
drag info as customdata
- drop regions are defined with WM_dropbox_add(), similar to keymaps
you can make a "drop map" this way, which become 'drop map handlers'
in the queues.
- next to that the UI kit handles some common button types (like
accepting ID or names) to be catching a drop event too.
- Every "drop box" has two callbacks:
- poll() = check if the event drag data is relevant for this box
- copy() = fill in custom properties in the dropbox to initialize
an operator
- The dropbox handler then calls its standard Operator with its
dropbox properties.
** Currently implemented
Drag items:
- ID icons in browse buttons
- ID icons in context menu of properties region
- ID icons in outliner and rna viewer
- FileBrowser icons
- FileBrowser preview images
Drag-able icons are subtly visualized by making them brighter a bit
on mouse-over. In case the icon is a button or UI element too (most
cases), the drag-able feature will make the item react to
mouse-release instead of mouse-press.
Drop options:
- UI buttons: ID and text buttons (paste name)
- View3d: Object ID drop copies object
- View3d: Material ID drop assigns to object under cursor
- View3d: Image ID drop assigns to object UV texture under cursor
- Sequencer: Path drop will add either Image or Movie strip
- Image window: Path drop will open image
** Drag and drop Notes:
- Dropping into another Blender window (from same application) works
too. I've added code that passes on mousemoves and clicks to other
windows, without activating them though. This does make using multi-window
Blender a bit friendler.
- Dropping a file path to an image, is not the same as dropping an
Image ID... keep this in mind. Sequencer for example wants paths to
be dropped, textures in 3d window wants an Image ID.
- Although drop boxes could be defined via Python, I suggest they're
part of the UI and editor design (= how we want an editor to work), and
not default offered configurable like keymaps.
- At the moment only one item can be dragged at a time. This is for
several reasons.... For one, Blender doesn't have a well defined
uniform way to define "what is selected" (files, outliner items, etc).
Secondly there's potential conflicts on what todo when you drop mixed
drag sets on spots. All undefined stuff... nice for later.
- Example to bypass the above: a collection of images that form a strip,
should be represented in filewindow as a single sequence anyway.
This then will fit well and gets handled neatly by design.
- Another option to check is to allow multiple options per drop... it
could show the operator as a sort of menu, allowing arrow or scrollwheel
to choose. For time being I'd prefer to try to design a singular drop
though, just offer only one drop action per data type on given spots.
- What does work already, but a tad slow, is to use a function that
detects an object (type) under cursor, so a drag item's option can be
further refined (like drop object on object = parent). (disabled)
** More notes
- Added saving for Region layouts (like split points for toolbar)
- Label buttons now handle mouse over
- File list: added full path entry for drop feature.
- Filesel bugfix: wm_operator_exec() got called there and fully handled,
while WM event code tried same. Added new OPERATOR_HANDLED flag for this.
Maybe python needs it too?
- Cocoa: added window move event, so multi-win setups work OK (didnt save).
- Interface_handlers.c: removed win->active
- Severe area copy bug: area handlers were not set to NULL
- Filesel bugfix: next/prev folder list was not copied on area copies
** Leftover todos
- Cocoa windows seem to hang on cases still... needs check
- Cocoa 'draw overlap' swap doesn't work
- Cocoa window loses focus permanently on using Spotlight
(for these reasons, makefile building has Carbon as default atm)
- ListView templates in UI cannot become dragged yet, needs review...
it consists of two overlapping UI elements, preventing handling icon clicks.
- There's already Ghost library code to handle dropping from OS
into Blender window. I've noticed this code is unfinished for Macs, but
seems to be complete for Windows. Needs test... currently, an external
drop event will print in console when succesfully delivered to Blender's WM.
2010-01-26 18:18:21 +00:00
|
|
|
unsigned int min= 0xFFFFFFFF;
|
|
|
|
int selcol= 0, notcol=0;
|
|
|
|
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (has_bones) {
|
Drag and drop 2.5 integration! Finally, slashdot regulars can use
Blender too now! :)
** Drag works as follows:
- drag-able items are defined by the standard interface ui toolkit
- each button can get this feature, via uiButSetDragXXX(but, ...).
There are calls to define drag-able images, ID blocks, RNA paths,
file paths, and so on. By default you drag an icon, exceptionally
an ImBuf
- Drag items are registered centrally in the WM, it allows more drag
items simultaneous too, but not implemented
** Drop works as follows:
- On mouse release, and if drag items exist in the WM, it converts
the mouse event to an EVT_DROP type. This event then gets the full
drag info as customdata
- drop regions are defined with WM_dropbox_add(), similar to keymaps
you can make a "drop map" this way, which become 'drop map handlers'
in the queues.
- next to that the UI kit handles some common button types (like
accepting ID or names) to be catching a drop event too.
- Every "drop box" has two callbacks:
- poll() = check if the event drag data is relevant for this box
- copy() = fill in custom properties in the dropbox to initialize
an operator
- The dropbox handler then calls its standard Operator with its
dropbox properties.
** Currently implemented
Drag items:
- ID icons in browse buttons
- ID icons in context menu of properties region
- ID icons in outliner and rna viewer
- FileBrowser icons
- FileBrowser preview images
Drag-able icons are subtly visualized by making them brighter a bit
on mouse-over. In case the icon is a button or UI element too (most
cases), the drag-able feature will make the item react to
mouse-release instead of mouse-press.
Drop options:
- UI buttons: ID and text buttons (paste name)
- View3d: Object ID drop copies object
- View3d: Material ID drop assigns to object under cursor
- View3d: Image ID drop assigns to object UV texture under cursor
- Sequencer: Path drop will add either Image or Movie strip
- Image window: Path drop will open image
** Drag and drop Notes:
- Dropping into another Blender window (from same application) works
too. I've added code that passes on mousemoves and clicks to other
windows, without activating them though. This does make using multi-window
Blender a bit friendler.
- Dropping a file path to an image, is not the same as dropping an
Image ID... keep this in mind. Sequencer for example wants paths to
be dropped, textures in 3d window wants an Image ID.
- Although drop boxes could be defined via Python, I suggest they're
part of the UI and editor design (= how we want an editor to work), and
not default offered configurable like keymaps.
- At the moment only one item can be dragged at a time. This is for
several reasons.... For one, Blender doesn't have a well defined
uniform way to define "what is selected" (files, outliner items, etc).
Secondly there's potential conflicts on what todo when you drop mixed
drag sets on spots. All undefined stuff... nice for later.
- Example to bypass the above: a collection of images that form a strip,
should be represented in filewindow as a single sequence anyway.
This then will fit well and gets handled neatly by design.
- Another option to check is to allow multiple options per drop... it
could show the operator as a sort of menu, allowing arrow or scrollwheel
to choose. For time being I'd prefer to try to design a singular drop
though, just offer only one drop action per data type on given spots.
- What does work already, but a tad slow, is to use a function that
detects an object (type) under cursor, so a drag item's option can be
further refined (like drop object on object = parent). (disabled)
** More notes
- Added saving for Region layouts (like split points for toolbar)
- Label buttons now handle mouse over
- File list: added full path entry for drop feature.
- Filesel bugfix: wm_operator_exec() got called there and fully handled,
while WM event code tried same. Added new OPERATOR_HANDLED flag for this.
Maybe python needs it too?
- Cocoa: added window move event, so multi-win setups work OK (didnt save).
- Interface_handlers.c: removed win->active
- Severe area copy bug: area handlers were not set to NULL
- Filesel bugfix: next/prev folder list was not copied on area copies
** Leftover todos
- Cocoa windows seem to hang on cases still... needs check
- Cocoa 'draw overlap' swap doesn't work
- Cocoa window loses focus permanently on using Spotlight
(for these reasons, makefile building has Carbon as default atm)
- ListView templates in UI cannot become dragged yet, needs review...
it consists of two overlapping UI elements, preventing handling icon clicks.
- There's already Ghost library code to handle dropping from OS
into Blender window. I've noticed this code is unfinished for Macs, but
seems to be complete for Windows. Needs test... currently, an external
drop event will print in console when succesfully delivered to Blender's WM.
2010-01-26 18:18:21 +00:00
|
|
|
/* we skip non-bone hits */
|
2012-02-22 16:52:06 +00:00
|
|
|
for (a=0; a<hits; a++) {
|
|
|
|
if ( min > buffer[4*a+1] && (buffer[4*a+3] & 0xFFFF0000) ) {
|
Drag and drop 2.5 integration! Finally, slashdot regulars can use
Blender too now! :)
** Drag works as follows:
- drag-able items are defined by the standard interface ui toolkit
- each button can get this feature, via uiButSetDragXXX(but, ...).
There are calls to define drag-able images, ID blocks, RNA paths,
file paths, and so on. By default you drag an icon, exceptionally
an ImBuf
- Drag items are registered centrally in the WM, it allows more drag
items simultaneous too, but not implemented
** Drop works as follows:
- On mouse release, and if drag items exist in the WM, it converts
the mouse event to an EVT_DROP type. This event then gets the full
drag info as customdata
- drop regions are defined with WM_dropbox_add(), similar to keymaps
you can make a "drop map" this way, which become 'drop map handlers'
in the queues.
- next to that the UI kit handles some common button types (like
accepting ID or names) to be catching a drop event too.
- Every "drop box" has two callbacks:
- poll() = check if the event drag data is relevant for this box
- copy() = fill in custom properties in the dropbox to initialize
an operator
- The dropbox handler then calls its standard Operator with its
dropbox properties.
** Currently implemented
Drag items:
- ID icons in browse buttons
- ID icons in context menu of properties region
- ID icons in outliner and rna viewer
- FileBrowser icons
- FileBrowser preview images
Drag-able icons are subtly visualized by making them brighter a bit
on mouse-over. In case the icon is a button or UI element too (most
cases), the drag-able feature will make the item react to
mouse-release instead of mouse-press.
Drop options:
- UI buttons: ID and text buttons (paste name)
- View3d: Object ID drop copies object
- View3d: Material ID drop assigns to object under cursor
- View3d: Image ID drop assigns to object UV texture under cursor
- Sequencer: Path drop will add either Image or Movie strip
- Image window: Path drop will open image
** Drag and drop Notes:
- Dropping into another Blender window (from same application) works
too. I've added code that passes on mousemoves and clicks to other
windows, without activating them though. This does make using multi-window
Blender a bit friendler.
- Dropping a file path to an image, is not the same as dropping an
Image ID... keep this in mind. Sequencer for example wants paths to
be dropped, textures in 3d window wants an Image ID.
- Although drop boxes could be defined via Python, I suggest they're
part of the UI and editor design (= how we want an editor to work), and
not default offered configurable like keymaps.
- At the moment only one item can be dragged at a time. This is for
several reasons.... For one, Blender doesn't have a well defined
uniform way to define "what is selected" (files, outliner items, etc).
Secondly there's potential conflicts on what todo when you drop mixed
drag sets on spots. All undefined stuff... nice for later.
- Example to bypass the above: a collection of images that form a strip,
should be represented in filewindow as a single sequence anyway.
This then will fit well and gets handled neatly by design.
- Another option to check is to allow multiple options per drop... it
could show the operator as a sort of menu, allowing arrow or scrollwheel
to choose. For time being I'd prefer to try to design a singular drop
though, just offer only one drop action per data type on given spots.
- What does work already, but a tad slow, is to use a function that
detects an object (type) under cursor, so a drag item's option can be
further refined (like drop object on object = parent). (disabled)
** More notes
- Added saving for Region layouts (like split points for toolbar)
- Label buttons now handle mouse over
- File list: added full path entry for drop feature.
- Filesel bugfix: wm_operator_exec() got called there and fully handled,
while WM event code tried same. Added new OPERATOR_HANDLED flag for this.
Maybe python needs it too?
- Cocoa: added window move event, so multi-win setups work OK (didnt save).
- Interface_handlers.c: removed win->active
- Severe area copy bug: area handlers were not set to NULL
- Filesel bugfix: next/prev folder list was not copied on area copies
** Leftover todos
- Cocoa windows seem to hang on cases still... needs check
- Cocoa 'draw overlap' swap doesn't work
- Cocoa window loses focus permanently on using Spotlight
(for these reasons, makefile building has Carbon as default atm)
- ListView templates in UI cannot become dragged yet, needs review...
it consists of two overlapping UI elements, preventing handling icon clicks.
- There's already Ghost library code to handle dropping from OS
into Blender window. I've noticed this code is unfinished for Macs, but
seems to be complete for Windows. Needs test... currently, an external
drop event will print in console when succesfully delivered to Blender's WM.
2010-01-26 18:18:21 +00:00
|
|
|
min= buffer[4*a+1];
|
|
|
|
selcol= buffer[4*a+3] & 0xFFFF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* only exclude active object when it is selected... */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (BASACT && (BASACT->flag & SELECT) && hits>1) notcol= BASACT->selcol;
|
Drag and drop 2.5 integration! Finally, slashdot regulars can use
Blender too now! :)
** Drag works as follows:
- drag-able items are defined by the standard interface ui toolkit
- each button can get this feature, via uiButSetDragXXX(but, ...).
There are calls to define drag-able images, ID blocks, RNA paths,
file paths, and so on. By default you drag an icon, exceptionally
an ImBuf
- Drag items are registered centrally in the WM, it allows more drag
items simultaneous too, but not implemented
** Drop works as follows:
- On mouse release, and if drag items exist in the WM, it converts
the mouse event to an EVT_DROP type. This event then gets the full
drag info as customdata
- drop regions are defined with WM_dropbox_add(), similar to keymaps
you can make a "drop map" this way, which become 'drop map handlers'
in the queues.
- next to that the UI kit handles some common button types (like
accepting ID or names) to be catching a drop event too.
- Every "drop box" has two callbacks:
- poll() = check if the event drag data is relevant for this box
- copy() = fill in custom properties in the dropbox to initialize
an operator
- The dropbox handler then calls its standard Operator with its
dropbox properties.
** Currently implemented
Drag items:
- ID icons in browse buttons
- ID icons in context menu of properties region
- ID icons in outliner and rna viewer
- FileBrowser icons
- FileBrowser preview images
Drag-able icons are subtly visualized by making them brighter a bit
on mouse-over. In case the icon is a button or UI element too (most
cases), the drag-able feature will make the item react to
mouse-release instead of mouse-press.
Drop options:
- UI buttons: ID and text buttons (paste name)
- View3d: Object ID drop copies object
- View3d: Material ID drop assigns to object under cursor
- View3d: Image ID drop assigns to object UV texture under cursor
- Sequencer: Path drop will add either Image or Movie strip
- Image window: Path drop will open image
** Drag and drop Notes:
- Dropping into another Blender window (from same application) works
too. I've added code that passes on mousemoves and clicks to other
windows, without activating them though. This does make using multi-window
Blender a bit friendler.
- Dropping a file path to an image, is not the same as dropping an
Image ID... keep this in mind. Sequencer for example wants paths to
be dropped, textures in 3d window wants an Image ID.
- Although drop boxes could be defined via Python, I suggest they're
part of the UI and editor design (= how we want an editor to work), and
not default offered configurable like keymaps.
- At the moment only one item can be dragged at a time. This is for
several reasons.... For one, Blender doesn't have a well defined
uniform way to define "what is selected" (files, outliner items, etc).
Secondly there's potential conflicts on what todo when you drop mixed
drag sets on spots. All undefined stuff... nice for later.
- Example to bypass the above: a collection of images that form a strip,
should be represented in filewindow as a single sequence anyway.
This then will fit well and gets handled neatly by design.
- Another option to check is to allow multiple options per drop... it
could show the operator as a sort of menu, allowing arrow or scrollwheel
to choose. For time being I'd prefer to try to design a singular drop
though, just offer only one drop action per data type on given spots.
- What does work already, but a tad slow, is to use a function that
detects an object (type) under cursor, so a drag item's option can be
further refined (like drop object on object = parent). (disabled)
** More notes
- Added saving for Region layouts (like split points for toolbar)
- Label buttons now handle mouse over
- File list: added full path entry for drop feature.
- Filesel bugfix: wm_operator_exec() got called there and fully handled,
while WM event code tried same. Added new OPERATOR_HANDLED flag for this.
Maybe python needs it too?
- Cocoa: added window move event, so multi-win setups work OK (didnt save).
- Interface_handlers.c: removed win->active
- Severe area copy bug: area handlers were not set to NULL
- Filesel bugfix: next/prev folder list was not copied on area copies
** Leftover todos
- Cocoa windows seem to hang on cases still... needs check
- Cocoa 'draw overlap' swap doesn't work
- Cocoa window loses focus permanently on using Spotlight
(for these reasons, makefile building has Carbon as default atm)
- ListView templates in UI cannot become dragged yet, needs review...
it consists of two overlapping UI elements, preventing handling icon clicks.
- There's already Ghost library code to handle dropping from OS
into Blender window. I've noticed this code is unfinished for Macs, but
seems to be complete for Windows. Needs test... currently, an external
drop event will print in console when succesfully delivered to Blender's WM.
2010-01-26 18:18:21 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
for (a=0; a<hits; a++) {
|
|
|
|
if ( min > buffer[4*a+1] && notcol!=(buffer[4*a+3] & 0xFFFF)) {
|
Drag and drop 2.5 integration! Finally, slashdot regulars can use
Blender too now! :)
** Drag works as follows:
- drag-able items are defined by the standard interface ui toolkit
- each button can get this feature, via uiButSetDragXXX(but, ...).
There are calls to define drag-able images, ID blocks, RNA paths,
file paths, and so on. By default you drag an icon, exceptionally
an ImBuf
- Drag items are registered centrally in the WM, it allows more drag
items simultaneous too, but not implemented
** Drop works as follows:
- On mouse release, and if drag items exist in the WM, it converts
the mouse event to an EVT_DROP type. This event then gets the full
drag info as customdata
- drop regions are defined with WM_dropbox_add(), similar to keymaps
you can make a "drop map" this way, which become 'drop map handlers'
in the queues.
- next to that the UI kit handles some common button types (like
accepting ID or names) to be catching a drop event too.
- Every "drop box" has two callbacks:
- poll() = check if the event drag data is relevant for this box
- copy() = fill in custom properties in the dropbox to initialize
an operator
- The dropbox handler then calls its standard Operator with its
dropbox properties.
** Currently implemented
Drag items:
- ID icons in browse buttons
- ID icons in context menu of properties region
- ID icons in outliner and rna viewer
- FileBrowser icons
- FileBrowser preview images
Drag-able icons are subtly visualized by making them brighter a bit
on mouse-over. In case the icon is a button or UI element too (most
cases), the drag-able feature will make the item react to
mouse-release instead of mouse-press.
Drop options:
- UI buttons: ID and text buttons (paste name)
- View3d: Object ID drop copies object
- View3d: Material ID drop assigns to object under cursor
- View3d: Image ID drop assigns to object UV texture under cursor
- Sequencer: Path drop will add either Image or Movie strip
- Image window: Path drop will open image
** Drag and drop Notes:
- Dropping into another Blender window (from same application) works
too. I've added code that passes on mousemoves and clicks to other
windows, without activating them though. This does make using multi-window
Blender a bit friendler.
- Dropping a file path to an image, is not the same as dropping an
Image ID... keep this in mind. Sequencer for example wants paths to
be dropped, textures in 3d window wants an Image ID.
- Although drop boxes could be defined via Python, I suggest they're
part of the UI and editor design (= how we want an editor to work), and
not default offered configurable like keymaps.
- At the moment only one item can be dragged at a time. This is for
several reasons.... For one, Blender doesn't have a well defined
uniform way to define "what is selected" (files, outliner items, etc).
Secondly there's potential conflicts on what todo when you drop mixed
drag sets on spots. All undefined stuff... nice for later.
- Example to bypass the above: a collection of images that form a strip,
should be represented in filewindow as a single sequence anyway.
This then will fit well and gets handled neatly by design.
- Another option to check is to allow multiple options per drop... it
could show the operator as a sort of menu, allowing arrow or scrollwheel
to choose. For time being I'd prefer to try to design a singular drop
though, just offer only one drop action per data type on given spots.
- What does work already, but a tad slow, is to use a function that
detects an object (type) under cursor, so a drag item's option can be
further refined (like drop object on object = parent). (disabled)
** More notes
- Added saving for Region layouts (like split points for toolbar)
- Label buttons now handle mouse over
- File list: added full path entry for drop feature.
- Filesel bugfix: wm_operator_exec() got called there and fully handled,
while WM event code tried same. Added new OPERATOR_HANDLED flag for this.
Maybe python needs it too?
- Cocoa: added window move event, so multi-win setups work OK (didnt save).
- Interface_handlers.c: removed win->active
- Severe area copy bug: area handlers were not set to NULL
- Filesel bugfix: next/prev folder list was not copied on area copies
** Leftover todos
- Cocoa windows seem to hang on cases still... needs check
- Cocoa 'draw overlap' swap doesn't work
- Cocoa window loses focus permanently on using Spotlight
(for these reasons, makefile building has Carbon as default atm)
- ListView templates in UI cannot become dragged yet, needs review...
it consists of two overlapping UI elements, preventing handling icon clicks.
- There's already Ghost library code to handle dropping from OS
into Blender window. I've noticed this code is unfinished for Macs, but
seems to be complete for Windows. Needs test... currently, an external
drop event will print in console when succesfully delivered to Blender's WM.
2010-01-26 18:18:21 +00:00
|
|
|
min= buffer[4*a+1];
|
|
|
|
selcol= buffer[4*a+3] & 0xFFFF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
base= FIRSTBASE;
|
2012-02-22 16:52:06 +00:00
|
|
|
while (base) {
|
|
|
|
if (BASE_SELECTABLE(v3d, base)) {
|
|
|
|
if (base->selcol==selcol) break;
|
Drag and drop 2.5 integration! Finally, slashdot regulars can use
Blender too now! :)
** Drag works as follows:
- drag-able items are defined by the standard interface ui toolkit
- each button can get this feature, via uiButSetDragXXX(but, ...).
There are calls to define drag-able images, ID blocks, RNA paths,
file paths, and so on. By default you drag an icon, exceptionally
an ImBuf
- Drag items are registered centrally in the WM, it allows more drag
items simultaneous too, but not implemented
** Drop works as follows:
- On mouse release, and if drag items exist in the WM, it converts
the mouse event to an EVT_DROP type. This event then gets the full
drag info as customdata
- drop regions are defined with WM_dropbox_add(), similar to keymaps
you can make a "drop map" this way, which become 'drop map handlers'
in the queues.
- next to that the UI kit handles some common button types (like
accepting ID or names) to be catching a drop event too.
- Every "drop box" has two callbacks:
- poll() = check if the event drag data is relevant for this box
- copy() = fill in custom properties in the dropbox to initialize
an operator
- The dropbox handler then calls its standard Operator with its
dropbox properties.
** Currently implemented
Drag items:
- ID icons in browse buttons
- ID icons in context menu of properties region
- ID icons in outliner and rna viewer
- FileBrowser icons
- FileBrowser preview images
Drag-able icons are subtly visualized by making them brighter a bit
on mouse-over. In case the icon is a button or UI element too (most
cases), the drag-able feature will make the item react to
mouse-release instead of mouse-press.
Drop options:
- UI buttons: ID and text buttons (paste name)
- View3d: Object ID drop copies object
- View3d: Material ID drop assigns to object under cursor
- View3d: Image ID drop assigns to object UV texture under cursor
- Sequencer: Path drop will add either Image or Movie strip
- Image window: Path drop will open image
** Drag and drop Notes:
- Dropping into another Blender window (from same application) works
too. I've added code that passes on mousemoves and clicks to other
windows, without activating them though. This does make using multi-window
Blender a bit friendler.
- Dropping a file path to an image, is not the same as dropping an
Image ID... keep this in mind. Sequencer for example wants paths to
be dropped, textures in 3d window wants an Image ID.
- Although drop boxes could be defined via Python, I suggest they're
part of the UI and editor design (= how we want an editor to work), and
not default offered configurable like keymaps.
- At the moment only one item can be dragged at a time. This is for
several reasons.... For one, Blender doesn't have a well defined
uniform way to define "what is selected" (files, outliner items, etc).
Secondly there's potential conflicts on what todo when you drop mixed
drag sets on spots. All undefined stuff... nice for later.
- Example to bypass the above: a collection of images that form a strip,
should be represented in filewindow as a single sequence anyway.
This then will fit well and gets handled neatly by design.
- Another option to check is to allow multiple options per drop... it
could show the operator as a sort of menu, allowing arrow or scrollwheel
to choose. For time being I'd prefer to try to design a singular drop
though, just offer only one drop action per data type on given spots.
- What does work already, but a tad slow, is to use a function that
detects an object (type) under cursor, so a drag item's option can be
further refined (like drop object on object = parent). (disabled)
** More notes
- Added saving for Region layouts (like split points for toolbar)
- Label buttons now handle mouse over
- File list: added full path entry for drop feature.
- Filesel bugfix: wm_operator_exec() got called there and fully handled,
while WM event code tried same. Added new OPERATOR_HANDLED flag for this.
Maybe python needs it too?
- Cocoa: added window move event, so multi-win setups work OK (didnt save).
- Interface_handlers.c: removed win->active
- Severe area copy bug: area handlers were not set to NULL
- Filesel bugfix: next/prev folder list was not copied on area copies
** Leftover todos
- Cocoa windows seem to hang on cases still... needs check
- Cocoa 'draw overlap' swap doesn't work
- Cocoa window loses focus permanently on using Spotlight
(for these reasons, makefile building has Carbon as default atm)
- ListView templates in UI cannot become dragged yet, needs review...
it consists of two overlapping UI elements, preventing handling icon clicks.
- There's already Ghost library code to handle dropping from OS
into Blender window. I've noticed this code is unfinished for Macs, but
seems to be complete for Windows. Needs test... currently, an external
drop event will print in console when succesfully delivered to Blender's WM.
2010-01-26 18:18:21 +00:00
|
|
|
}
|
|
|
|
base= base->next;
|
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
if (base) basact= base;
|
Drag and drop 2.5 integration! Finally, slashdot regulars can use
Blender too now! :)
** Drag works as follows:
- drag-able items are defined by the standard interface ui toolkit
- each button can get this feature, via uiButSetDragXXX(but, ...).
There are calls to define drag-able images, ID blocks, RNA paths,
file paths, and so on. By default you drag an icon, exceptionally
an ImBuf
- Drag items are registered centrally in the WM, it allows more drag
items simultaneous too, but not implemented
** Drop works as follows:
- On mouse release, and if drag items exist in the WM, it converts
the mouse event to an EVT_DROP type. This event then gets the full
drag info as customdata
- drop regions are defined with WM_dropbox_add(), similar to keymaps
you can make a "drop map" this way, which become 'drop map handlers'
in the queues.
- next to that the UI kit handles some common button types (like
accepting ID or names) to be catching a drop event too.
- Every "drop box" has two callbacks:
- poll() = check if the event drag data is relevant for this box
- copy() = fill in custom properties in the dropbox to initialize
an operator
- The dropbox handler then calls its standard Operator with its
dropbox properties.
** Currently implemented
Drag items:
- ID icons in browse buttons
- ID icons in context menu of properties region
- ID icons in outliner and rna viewer
- FileBrowser icons
- FileBrowser preview images
Drag-able icons are subtly visualized by making them brighter a bit
on mouse-over. In case the icon is a button or UI element too (most
cases), the drag-able feature will make the item react to
mouse-release instead of mouse-press.
Drop options:
- UI buttons: ID and text buttons (paste name)
- View3d: Object ID drop copies object
- View3d: Material ID drop assigns to object under cursor
- View3d: Image ID drop assigns to object UV texture under cursor
- Sequencer: Path drop will add either Image or Movie strip
- Image window: Path drop will open image
** Drag and drop Notes:
- Dropping into another Blender window (from same application) works
too. I've added code that passes on mousemoves and clicks to other
windows, without activating them though. This does make using multi-window
Blender a bit friendler.
- Dropping a file path to an image, is not the same as dropping an
Image ID... keep this in mind. Sequencer for example wants paths to
be dropped, textures in 3d window wants an Image ID.
- Although drop boxes could be defined via Python, I suggest they're
part of the UI and editor design (= how we want an editor to work), and
not default offered configurable like keymaps.
- At the moment only one item can be dragged at a time. This is for
several reasons.... For one, Blender doesn't have a well defined
uniform way to define "what is selected" (files, outliner items, etc).
Secondly there's potential conflicts on what todo when you drop mixed
drag sets on spots. All undefined stuff... nice for later.
- Example to bypass the above: a collection of images that form a strip,
should be represented in filewindow as a single sequence anyway.
This then will fit well and gets handled neatly by design.
- Another option to check is to allow multiple options per drop... it
could show the operator as a sort of menu, allowing arrow or scrollwheel
to choose. For time being I'd prefer to try to design a singular drop
though, just offer only one drop action per data type on given spots.
- What does work already, but a tad slow, is to use a function that
detects an object (type) under cursor, so a drag item's option can be
further refined (like drop object on object = parent). (disabled)
** More notes
- Added saving for Region layouts (like split points for toolbar)
- Label buttons now handle mouse over
- File list: added full path entry for drop feature.
- Filesel bugfix: wm_operator_exec() got called there and fully handled,
while WM event code tried same. Added new OPERATOR_HANDLED flag for this.
Maybe python needs it too?
- Cocoa: added window move event, so multi-win setups work OK (didnt save).
- Interface_handlers.c: removed win->active
- Severe area copy bug: area handlers were not set to NULL
- Filesel bugfix: next/prev folder list was not copied on area copies
** Leftover todos
- Cocoa windows seem to hang on cases still... needs check
- Cocoa 'draw overlap' swap doesn't work
- Cocoa window loses focus permanently on using Spotlight
(for these reasons, makefile building has Carbon as default atm)
- ListView templates in UI cannot become dragged yet, needs review...
it consists of two overlapping UI elements, preventing handling icon clicks.
- There's already Ghost library code to handle dropping from OS
into Blender window. I've noticed this code is unfinished for Macs, but
seems to be complete for Windows. Needs test... currently, an external
drop event will print in console when succesfully delivered to Blender's WM.
2010-01-26 18:18:21 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
|
|
|
|
base= startbase;
|
2012-02-22 16:52:06 +00:00
|
|
|
while (base) {
|
Drag and drop 2.5 integration! Finally, slashdot regulars can use
Blender too now! :)
** Drag works as follows:
- drag-able items are defined by the standard interface ui toolkit
- each button can get this feature, via uiButSetDragXXX(but, ...).
There are calls to define drag-able images, ID blocks, RNA paths,
file paths, and so on. By default you drag an icon, exceptionally
an ImBuf
- Drag items are registered centrally in the WM, it allows more drag
items simultaneous too, but not implemented
** Drop works as follows:
- On mouse release, and if drag items exist in the WM, it converts
the mouse event to an EVT_DROP type. This event then gets the full
drag info as customdata
- drop regions are defined with WM_dropbox_add(), similar to keymaps
you can make a "drop map" this way, which become 'drop map handlers'
in the queues.
- next to that the UI kit handles some common button types (like
accepting ID or names) to be catching a drop event too.
- Every "drop box" has two callbacks:
- poll() = check if the event drag data is relevant for this box
- copy() = fill in custom properties in the dropbox to initialize
an operator
- The dropbox handler then calls its standard Operator with its
dropbox properties.
** Currently implemented
Drag items:
- ID icons in browse buttons
- ID icons in context menu of properties region
- ID icons in outliner and rna viewer
- FileBrowser icons
- FileBrowser preview images
Drag-able icons are subtly visualized by making them brighter a bit
on mouse-over. In case the icon is a button or UI element too (most
cases), the drag-able feature will make the item react to
mouse-release instead of mouse-press.
Drop options:
- UI buttons: ID and text buttons (paste name)
- View3d: Object ID drop copies object
- View3d: Material ID drop assigns to object under cursor
- View3d: Image ID drop assigns to object UV texture under cursor
- Sequencer: Path drop will add either Image or Movie strip
- Image window: Path drop will open image
** Drag and drop Notes:
- Dropping into another Blender window (from same application) works
too. I've added code that passes on mousemoves and clicks to other
windows, without activating them though. This does make using multi-window
Blender a bit friendler.
- Dropping a file path to an image, is not the same as dropping an
Image ID... keep this in mind. Sequencer for example wants paths to
be dropped, textures in 3d window wants an Image ID.
- Although drop boxes could be defined via Python, I suggest they're
part of the UI and editor design (= how we want an editor to work), and
not default offered configurable like keymaps.
- At the moment only one item can be dragged at a time. This is for
several reasons.... For one, Blender doesn't have a well defined
uniform way to define "what is selected" (files, outliner items, etc).
Secondly there's potential conflicts on what todo when you drop mixed
drag sets on spots. All undefined stuff... nice for later.
- Example to bypass the above: a collection of images that form a strip,
should be represented in filewindow as a single sequence anyway.
This then will fit well and gets handled neatly by design.
- Another option to check is to allow multiple options per drop... it
could show the operator as a sort of menu, allowing arrow or scrollwheel
to choose. For time being I'd prefer to try to design a singular drop
though, just offer only one drop action per data type on given spots.
- What does work already, but a tad slow, is to use a function that
detects an object (type) under cursor, so a drag item's option can be
further refined (like drop object on object = parent). (disabled)
** More notes
- Added saving for Region layouts (like split points for toolbar)
- Label buttons now handle mouse over
- File list: added full path entry for drop feature.
- Filesel bugfix: wm_operator_exec() got called there and fully handled,
while WM event code tried same. Added new OPERATOR_HANDLED flag for this.
Maybe python needs it too?
- Cocoa: added window move event, so multi-win setups work OK (didnt save).
- Interface_handlers.c: removed win->active
- Severe area copy bug: area handlers were not set to NULL
- Filesel bugfix: next/prev folder list was not copied on area copies
** Leftover todos
- Cocoa windows seem to hang on cases still... needs check
- Cocoa 'draw overlap' swap doesn't work
- Cocoa window loses focus permanently on using Spotlight
(for these reasons, makefile building has Carbon as default atm)
- ListView templates in UI cannot become dragged yet, needs review...
it consists of two overlapping UI elements, preventing handling icon clicks.
- There's already Ghost library code to handle dropping from OS
into Blender window. I've noticed this code is unfinished for Macs, but
seems to be complete for Windows. Needs test... currently, an external
drop event will print in console when succesfully delivered to Blender's WM.
2010-01-26 18:18:21 +00:00
|
|
|
/* skip objects with select restriction, to prevent prematurely ending this loop
|
2012-03-03 16:31:46 +00:00
|
|
|
* with an un-selectable choice */
|
Drag and drop 2.5 integration! Finally, slashdot regulars can use
Blender too now! :)
** Drag works as follows:
- drag-able items are defined by the standard interface ui toolkit
- each button can get this feature, via uiButSetDragXXX(but, ...).
There are calls to define drag-able images, ID blocks, RNA paths,
file paths, and so on. By default you drag an icon, exceptionally
an ImBuf
- Drag items are registered centrally in the WM, it allows more drag
items simultaneous too, but not implemented
** Drop works as follows:
- On mouse release, and if drag items exist in the WM, it converts
the mouse event to an EVT_DROP type. This event then gets the full
drag info as customdata
- drop regions are defined with WM_dropbox_add(), similar to keymaps
you can make a "drop map" this way, which become 'drop map handlers'
in the queues.
- next to that the UI kit handles some common button types (like
accepting ID or names) to be catching a drop event too.
- Every "drop box" has two callbacks:
- poll() = check if the event drag data is relevant for this box
- copy() = fill in custom properties in the dropbox to initialize
an operator
- The dropbox handler then calls its standard Operator with its
dropbox properties.
** Currently implemented
Drag items:
- ID icons in browse buttons
- ID icons in context menu of properties region
- ID icons in outliner and rna viewer
- FileBrowser icons
- FileBrowser preview images
Drag-able icons are subtly visualized by making them brighter a bit
on mouse-over. In case the icon is a button or UI element too (most
cases), the drag-able feature will make the item react to
mouse-release instead of mouse-press.
Drop options:
- UI buttons: ID and text buttons (paste name)
- View3d: Object ID drop copies object
- View3d: Material ID drop assigns to object under cursor
- View3d: Image ID drop assigns to object UV texture under cursor
- Sequencer: Path drop will add either Image or Movie strip
- Image window: Path drop will open image
** Drag and drop Notes:
- Dropping into another Blender window (from same application) works
too. I've added code that passes on mousemoves and clicks to other
windows, without activating them though. This does make using multi-window
Blender a bit friendler.
- Dropping a file path to an image, is not the same as dropping an
Image ID... keep this in mind. Sequencer for example wants paths to
be dropped, textures in 3d window wants an Image ID.
- Although drop boxes could be defined via Python, I suggest they're
part of the UI and editor design (= how we want an editor to work), and
not default offered configurable like keymaps.
- At the moment only one item can be dragged at a time. This is for
several reasons.... For one, Blender doesn't have a well defined
uniform way to define "what is selected" (files, outliner items, etc).
Secondly there's potential conflicts on what todo when you drop mixed
drag sets on spots. All undefined stuff... nice for later.
- Example to bypass the above: a collection of images that form a strip,
should be represented in filewindow as a single sequence anyway.
This then will fit well and gets handled neatly by design.
- Another option to check is to allow multiple options per drop... it
could show the operator as a sort of menu, allowing arrow or scrollwheel
to choose. For time being I'd prefer to try to design a singular drop
though, just offer only one drop action per data type on given spots.
- What does work already, but a tad slow, is to use a function that
detects an object (type) under cursor, so a drag item's option can be
further refined (like drop object on object = parent). (disabled)
** More notes
- Added saving for Region layouts (like split points for toolbar)
- Label buttons now handle mouse over
- File list: added full path entry for drop feature.
- Filesel bugfix: wm_operator_exec() got called there and fully handled,
while WM event code tried same. Added new OPERATOR_HANDLED flag for this.
Maybe python needs it too?
- Cocoa: added window move event, so multi-win setups work OK (didnt save).
- Interface_handlers.c: removed win->active
- Severe area copy bug: area handlers were not set to NULL
- Filesel bugfix: next/prev folder list was not copied on area copies
** Leftover todos
- Cocoa windows seem to hang on cases still... needs check
- Cocoa 'draw overlap' swap doesn't work
- Cocoa window loses focus permanently on using Spotlight
(for these reasons, makefile building has Carbon as default atm)
- ListView templates in UI cannot become dragged yet, needs review...
it consists of two overlapping UI elements, preventing handling icon clicks.
- There's already Ghost library code to handle dropping from OS
into Blender window. I've noticed this code is unfinished for Macs, but
seems to be complete for Windows. Needs test... currently, an external
drop event will print in console when succesfully delivered to Blender's WM.
2010-01-26 18:18:21 +00:00
|
|
|
if (base->object->restrictflag & OB_RESTRICT_SELECT) {
|
|
|
|
base=base->next;
|
2012-02-22 16:52:06 +00:00
|
|
|
if (base==NULL) base= FIRSTBASE;
|
|
|
|
if (base==startbase) break;
|
Drag and drop 2.5 integration! Finally, slashdot regulars can use
Blender too now! :)
** Drag works as follows:
- drag-able items are defined by the standard interface ui toolkit
- each button can get this feature, via uiButSetDragXXX(but, ...).
There are calls to define drag-able images, ID blocks, RNA paths,
file paths, and so on. By default you drag an icon, exceptionally
an ImBuf
- Drag items are registered centrally in the WM, it allows more drag
items simultaneous too, but not implemented
** Drop works as follows:
- On mouse release, and if drag items exist in the WM, it converts
the mouse event to an EVT_DROP type. This event then gets the full
drag info as customdata
- drop regions are defined with WM_dropbox_add(), similar to keymaps
you can make a "drop map" this way, which become 'drop map handlers'
in the queues.
- next to that the UI kit handles some common button types (like
accepting ID or names) to be catching a drop event too.
- Every "drop box" has two callbacks:
- poll() = check if the event drag data is relevant for this box
- copy() = fill in custom properties in the dropbox to initialize
an operator
- The dropbox handler then calls its standard Operator with its
dropbox properties.
** Currently implemented
Drag items:
- ID icons in browse buttons
- ID icons in context menu of properties region
- ID icons in outliner and rna viewer
- FileBrowser icons
- FileBrowser preview images
Drag-able icons are subtly visualized by making them brighter a bit
on mouse-over. In case the icon is a button or UI element too (most
cases), the drag-able feature will make the item react to
mouse-release instead of mouse-press.
Drop options:
- UI buttons: ID and text buttons (paste name)
- View3d: Object ID drop copies object
- View3d: Material ID drop assigns to object under cursor
- View3d: Image ID drop assigns to object UV texture under cursor
- Sequencer: Path drop will add either Image or Movie strip
- Image window: Path drop will open image
** Drag and drop Notes:
- Dropping into another Blender window (from same application) works
too. I've added code that passes on mousemoves and clicks to other
windows, without activating them though. This does make using multi-window
Blender a bit friendler.
- Dropping a file path to an image, is not the same as dropping an
Image ID... keep this in mind. Sequencer for example wants paths to
be dropped, textures in 3d window wants an Image ID.
- Although drop boxes could be defined via Python, I suggest they're
part of the UI and editor design (= how we want an editor to work), and
not default offered configurable like keymaps.
- At the moment only one item can be dragged at a time. This is for
several reasons.... For one, Blender doesn't have a well defined
uniform way to define "what is selected" (files, outliner items, etc).
Secondly there's potential conflicts on what todo when you drop mixed
drag sets on spots. All undefined stuff... nice for later.
- Example to bypass the above: a collection of images that form a strip,
should be represented in filewindow as a single sequence anyway.
This then will fit well and gets handled neatly by design.
- Another option to check is to allow multiple options per drop... it
could show the operator as a sort of menu, allowing arrow or scrollwheel
to choose. For time being I'd prefer to try to design a singular drop
though, just offer only one drop action per data type on given spots.
- What does work already, but a tad slow, is to use a function that
detects an object (type) under cursor, so a drag item's option can be
further refined (like drop object on object = parent). (disabled)
** More notes
- Added saving for Region layouts (like split points for toolbar)
- Label buttons now handle mouse over
- File list: added full path entry for drop feature.
- Filesel bugfix: wm_operator_exec() got called there and fully handled,
while WM event code tried same. Added new OPERATOR_HANDLED flag for this.
Maybe python needs it too?
- Cocoa: added window move event, so multi-win setups work OK (didnt save).
- Interface_handlers.c: removed win->active
- Severe area copy bug: area handlers were not set to NULL
- Filesel bugfix: next/prev folder list was not copied on area copies
** Leftover todos
- Cocoa windows seem to hang on cases still... needs check
- Cocoa 'draw overlap' swap doesn't work
- Cocoa window loses focus permanently on using Spotlight
(for these reasons, makefile building has Carbon as default atm)
- ListView templates in UI cannot become dragged yet, needs review...
it consists of two overlapping UI elements, preventing handling icon clicks.
- There's already Ghost library code to handle dropping from OS
into Blender window. I've noticed this code is unfinished for Macs, but
seems to be complete for Windows. Needs test... currently, an external
drop event will print in console when succesfully delivered to Blender's WM.
2010-01-26 18:18:21 +00:00
|
|
|
}
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (BASE_SELECTABLE(v3d, base)) {
|
|
|
|
for (a=0; a<hits; a++) {
|
|
|
|
if (has_bones) {
|
Drag and drop 2.5 integration! Finally, slashdot regulars can use
Blender too now! :)
** Drag works as follows:
- drag-able items are defined by the standard interface ui toolkit
- each button can get this feature, via uiButSetDragXXX(but, ...).
There are calls to define drag-able images, ID blocks, RNA paths,
file paths, and so on. By default you drag an icon, exceptionally
an ImBuf
- Drag items are registered centrally in the WM, it allows more drag
items simultaneous too, but not implemented
** Drop works as follows:
- On mouse release, and if drag items exist in the WM, it converts
the mouse event to an EVT_DROP type. This event then gets the full
drag info as customdata
- drop regions are defined with WM_dropbox_add(), similar to keymaps
you can make a "drop map" this way, which become 'drop map handlers'
in the queues.
- next to that the UI kit handles some common button types (like
accepting ID or names) to be catching a drop event too.
- Every "drop box" has two callbacks:
- poll() = check if the event drag data is relevant for this box
- copy() = fill in custom properties in the dropbox to initialize
an operator
- The dropbox handler then calls its standard Operator with its
dropbox properties.
** Currently implemented
Drag items:
- ID icons in browse buttons
- ID icons in context menu of properties region
- ID icons in outliner and rna viewer
- FileBrowser icons
- FileBrowser preview images
Drag-able icons are subtly visualized by making them brighter a bit
on mouse-over. In case the icon is a button or UI element too (most
cases), the drag-able feature will make the item react to
mouse-release instead of mouse-press.
Drop options:
- UI buttons: ID and text buttons (paste name)
- View3d: Object ID drop copies object
- View3d: Material ID drop assigns to object under cursor
- View3d: Image ID drop assigns to object UV texture under cursor
- Sequencer: Path drop will add either Image or Movie strip
- Image window: Path drop will open image
** Drag and drop Notes:
- Dropping into another Blender window (from same application) works
too. I've added code that passes on mousemoves and clicks to other
windows, without activating them though. This does make using multi-window
Blender a bit friendler.
- Dropping a file path to an image, is not the same as dropping an
Image ID... keep this in mind. Sequencer for example wants paths to
be dropped, textures in 3d window wants an Image ID.
- Although drop boxes could be defined via Python, I suggest they're
part of the UI and editor design (= how we want an editor to work), and
not default offered configurable like keymaps.
- At the moment only one item can be dragged at a time. This is for
several reasons.... For one, Blender doesn't have a well defined
uniform way to define "what is selected" (files, outliner items, etc).
Secondly there's potential conflicts on what todo when you drop mixed
drag sets on spots. All undefined stuff... nice for later.
- Example to bypass the above: a collection of images that form a strip,
should be represented in filewindow as a single sequence anyway.
This then will fit well and gets handled neatly by design.
- Another option to check is to allow multiple options per drop... it
could show the operator as a sort of menu, allowing arrow or scrollwheel
to choose. For time being I'd prefer to try to design a singular drop
though, just offer only one drop action per data type on given spots.
- What does work already, but a tad slow, is to use a function that
detects an object (type) under cursor, so a drag item's option can be
further refined (like drop object on object = parent). (disabled)
** More notes
- Added saving for Region layouts (like split points for toolbar)
- Label buttons now handle mouse over
- File list: added full path entry for drop feature.
- Filesel bugfix: wm_operator_exec() got called there and fully handled,
while WM event code tried same. Added new OPERATOR_HANDLED flag for this.
Maybe python needs it too?
- Cocoa: added window move event, so multi-win setups work OK (didnt save).
- Interface_handlers.c: removed win->active
- Severe area copy bug: area handlers were not set to NULL
- Filesel bugfix: next/prev folder list was not copied on area copies
** Leftover todos
- Cocoa windows seem to hang on cases still... needs check
- Cocoa 'draw overlap' swap doesn't work
- Cocoa window loses focus permanently on using Spotlight
(for these reasons, makefile building has Carbon as default atm)
- ListView templates in UI cannot become dragged yet, needs review...
it consists of two overlapping UI elements, preventing handling icon clicks.
- There's already Ghost library code to handle dropping from OS
into Blender window. I've noticed this code is unfinished for Macs, but
seems to be complete for Windows. Needs test... currently, an external
drop event will print in console when succesfully delivered to Blender's WM.
2010-01-26 18:18:21 +00:00
|
|
|
/* skip non-bone objects */
|
2012-02-22 16:52:06 +00:00
|
|
|
if ((buffer[4*a+3] & 0xFFFF0000)) {
|
|
|
|
if (base->selcol== (buffer[(4*a)+3] & 0xFFFF))
|
Drag and drop 2.5 integration! Finally, slashdot regulars can use
Blender too now! :)
** Drag works as follows:
- drag-able items are defined by the standard interface ui toolkit
- each button can get this feature, via uiButSetDragXXX(but, ...).
There are calls to define drag-able images, ID blocks, RNA paths,
file paths, and so on. By default you drag an icon, exceptionally
an ImBuf
- Drag items are registered centrally in the WM, it allows more drag
items simultaneous too, but not implemented
** Drop works as follows:
- On mouse release, and if drag items exist in the WM, it converts
the mouse event to an EVT_DROP type. This event then gets the full
drag info as customdata
- drop regions are defined with WM_dropbox_add(), similar to keymaps
you can make a "drop map" this way, which become 'drop map handlers'
in the queues.
- next to that the UI kit handles some common button types (like
accepting ID or names) to be catching a drop event too.
- Every "drop box" has two callbacks:
- poll() = check if the event drag data is relevant for this box
- copy() = fill in custom properties in the dropbox to initialize
an operator
- The dropbox handler then calls its standard Operator with its
dropbox properties.
** Currently implemented
Drag items:
- ID icons in browse buttons
- ID icons in context menu of properties region
- ID icons in outliner and rna viewer
- FileBrowser icons
- FileBrowser preview images
Drag-able icons are subtly visualized by making them brighter a bit
on mouse-over. In case the icon is a button or UI element too (most
cases), the drag-able feature will make the item react to
mouse-release instead of mouse-press.
Drop options:
- UI buttons: ID and text buttons (paste name)
- View3d: Object ID drop copies object
- View3d: Material ID drop assigns to object under cursor
- View3d: Image ID drop assigns to object UV texture under cursor
- Sequencer: Path drop will add either Image or Movie strip
- Image window: Path drop will open image
** Drag and drop Notes:
- Dropping into another Blender window (from same application) works
too. I've added code that passes on mousemoves and clicks to other
windows, without activating them though. This does make using multi-window
Blender a bit friendler.
- Dropping a file path to an image, is not the same as dropping an
Image ID... keep this in mind. Sequencer for example wants paths to
be dropped, textures in 3d window wants an Image ID.
- Although drop boxes could be defined via Python, I suggest they're
part of the UI and editor design (= how we want an editor to work), and
not default offered configurable like keymaps.
- At the moment only one item can be dragged at a time. This is for
several reasons.... For one, Blender doesn't have a well defined
uniform way to define "what is selected" (files, outliner items, etc).
Secondly there's potential conflicts on what todo when you drop mixed
drag sets on spots. All undefined stuff... nice for later.
- Example to bypass the above: a collection of images that form a strip,
should be represented in filewindow as a single sequence anyway.
This then will fit well and gets handled neatly by design.
- Another option to check is to allow multiple options per drop... it
could show the operator as a sort of menu, allowing arrow or scrollwheel
to choose. For time being I'd prefer to try to design a singular drop
though, just offer only one drop action per data type on given spots.
- What does work already, but a tad slow, is to use a function that
detects an object (type) under cursor, so a drag item's option can be
further refined (like drop object on object = parent). (disabled)
** More notes
- Added saving for Region layouts (like split points for toolbar)
- Label buttons now handle mouse over
- File list: added full path entry for drop feature.
- Filesel bugfix: wm_operator_exec() got called there and fully handled,
while WM event code tried same. Added new OPERATOR_HANDLED flag for this.
Maybe python needs it too?
- Cocoa: added window move event, so multi-win setups work OK (didnt save).
- Interface_handlers.c: removed win->active
- Severe area copy bug: area handlers were not set to NULL
- Filesel bugfix: next/prev folder list was not copied on area copies
** Leftover todos
- Cocoa windows seem to hang on cases still... needs check
- Cocoa 'draw overlap' swap doesn't work
- Cocoa window loses focus permanently on using Spotlight
(for these reasons, makefile building has Carbon as default atm)
- ListView templates in UI cannot become dragged yet, needs review...
it consists of two overlapping UI elements, preventing handling icon clicks.
- There's already Ghost library code to handle dropping from OS
into Blender window. I've noticed this code is unfinished for Macs, but
seems to be complete for Windows. Needs test... currently, an external
drop event will print in console when succesfully delivered to Blender's WM.
2010-01-26 18:18:21 +00:00
|
|
|
basact= base;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (base->selcol== (buffer[(4*a)+3] & 0xFFFF))
|
Drag and drop 2.5 integration! Finally, slashdot regulars can use
Blender too now! :)
** Drag works as follows:
- drag-able items are defined by the standard interface ui toolkit
- each button can get this feature, via uiButSetDragXXX(but, ...).
There are calls to define drag-able images, ID blocks, RNA paths,
file paths, and so on. By default you drag an icon, exceptionally
an ImBuf
- Drag items are registered centrally in the WM, it allows more drag
items simultaneous too, but not implemented
** Drop works as follows:
- On mouse release, and if drag items exist in the WM, it converts
the mouse event to an EVT_DROP type. This event then gets the full
drag info as customdata
- drop regions are defined with WM_dropbox_add(), similar to keymaps
you can make a "drop map" this way, which become 'drop map handlers'
in the queues.
- next to that the UI kit handles some common button types (like
accepting ID or names) to be catching a drop event too.
- Every "drop box" has two callbacks:
- poll() = check if the event drag data is relevant for this box
- copy() = fill in custom properties in the dropbox to initialize
an operator
- The dropbox handler then calls its standard Operator with its
dropbox properties.
** Currently implemented
Drag items:
- ID icons in browse buttons
- ID icons in context menu of properties region
- ID icons in outliner and rna viewer
- FileBrowser icons
- FileBrowser preview images
Drag-able icons are subtly visualized by making them brighter a bit
on mouse-over. In case the icon is a button or UI element too (most
cases), the drag-able feature will make the item react to
mouse-release instead of mouse-press.
Drop options:
- UI buttons: ID and text buttons (paste name)
- View3d: Object ID drop copies object
- View3d: Material ID drop assigns to object under cursor
- View3d: Image ID drop assigns to object UV texture under cursor
- Sequencer: Path drop will add either Image or Movie strip
- Image window: Path drop will open image
** Drag and drop Notes:
- Dropping into another Blender window (from same application) works
too. I've added code that passes on mousemoves and clicks to other
windows, without activating them though. This does make using multi-window
Blender a bit friendler.
- Dropping a file path to an image, is not the same as dropping an
Image ID... keep this in mind. Sequencer for example wants paths to
be dropped, textures in 3d window wants an Image ID.
- Although drop boxes could be defined via Python, I suggest they're
part of the UI and editor design (= how we want an editor to work), and
not default offered configurable like keymaps.
- At the moment only one item can be dragged at a time. This is for
several reasons.... For one, Blender doesn't have a well defined
uniform way to define "what is selected" (files, outliner items, etc).
Secondly there's potential conflicts on what todo when you drop mixed
drag sets on spots. All undefined stuff... nice for later.
- Example to bypass the above: a collection of images that form a strip,
should be represented in filewindow as a single sequence anyway.
This then will fit well and gets handled neatly by design.
- Another option to check is to allow multiple options per drop... it
could show the operator as a sort of menu, allowing arrow or scrollwheel
to choose. For time being I'd prefer to try to design a singular drop
though, just offer only one drop action per data type on given spots.
- What does work already, but a tad slow, is to use a function that
detects an object (type) under cursor, so a drag item's option can be
further refined (like drop object on object = parent). (disabled)
** More notes
- Added saving for Region layouts (like split points for toolbar)
- Label buttons now handle mouse over
- File list: added full path entry for drop feature.
- Filesel bugfix: wm_operator_exec() got called there and fully handled,
while WM event code tried same. Added new OPERATOR_HANDLED flag for this.
Maybe python needs it too?
- Cocoa: added window move event, so multi-win setups work OK (didnt save).
- Interface_handlers.c: removed win->active
- Severe area copy bug: area handlers were not set to NULL
- Filesel bugfix: next/prev folder list was not copied on area copies
** Leftover todos
- Cocoa windows seem to hang on cases still... needs check
- Cocoa 'draw overlap' swap doesn't work
- Cocoa window loses focus permanently on using Spotlight
(for these reasons, makefile building has Carbon as default atm)
- ListView templates in UI cannot become dragged yet, needs review...
it consists of two overlapping UI elements, preventing handling icon clicks.
- There's already Ghost library code to handle dropping from OS
into Blender window. I've noticed this code is unfinished for Macs, but
seems to be complete for Windows. Needs test... currently, an external
drop event will print in console when succesfully delivered to Blender's WM.
2010-01-26 18:18:21 +00:00
|
|
|
basact= base;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (basact) break;
|
Drag and drop 2.5 integration! Finally, slashdot regulars can use
Blender too now! :)
** Drag works as follows:
- drag-able items are defined by the standard interface ui toolkit
- each button can get this feature, via uiButSetDragXXX(but, ...).
There are calls to define drag-able images, ID blocks, RNA paths,
file paths, and so on. By default you drag an icon, exceptionally
an ImBuf
- Drag items are registered centrally in the WM, it allows more drag
items simultaneous too, but not implemented
** Drop works as follows:
- On mouse release, and if drag items exist in the WM, it converts
the mouse event to an EVT_DROP type. This event then gets the full
drag info as customdata
- drop regions are defined with WM_dropbox_add(), similar to keymaps
you can make a "drop map" this way, which become 'drop map handlers'
in the queues.
- next to that the UI kit handles some common button types (like
accepting ID or names) to be catching a drop event too.
- Every "drop box" has two callbacks:
- poll() = check if the event drag data is relevant for this box
- copy() = fill in custom properties in the dropbox to initialize
an operator
- The dropbox handler then calls its standard Operator with its
dropbox properties.
** Currently implemented
Drag items:
- ID icons in browse buttons
- ID icons in context menu of properties region
- ID icons in outliner and rna viewer
- FileBrowser icons
- FileBrowser preview images
Drag-able icons are subtly visualized by making them brighter a bit
on mouse-over. In case the icon is a button or UI element too (most
cases), the drag-able feature will make the item react to
mouse-release instead of mouse-press.
Drop options:
- UI buttons: ID and text buttons (paste name)
- View3d: Object ID drop copies object
- View3d: Material ID drop assigns to object under cursor
- View3d: Image ID drop assigns to object UV texture under cursor
- Sequencer: Path drop will add either Image or Movie strip
- Image window: Path drop will open image
** Drag and drop Notes:
- Dropping into another Blender window (from same application) works
too. I've added code that passes on mousemoves and clicks to other
windows, without activating them though. This does make using multi-window
Blender a bit friendler.
- Dropping a file path to an image, is not the same as dropping an
Image ID... keep this in mind. Sequencer for example wants paths to
be dropped, textures in 3d window wants an Image ID.
- Although drop boxes could be defined via Python, I suggest they're
part of the UI and editor design (= how we want an editor to work), and
not default offered configurable like keymaps.
- At the moment only one item can be dragged at a time. This is for
several reasons.... For one, Blender doesn't have a well defined
uniform way to define "what is selected" (files, outliner items, etc).
Secondly there's potential conflicts on what todo when you drop mixed
drag sets on spots. All undefined stuff... nice for later.
- Example to bypass the above: a collection of images that form a strip,
should be represented in filewindow as a single sequence anyway.
This then will fit well and gets handled neatly by design.
- Another option to check is to allow multiple options per drop... it
could show the operator as a sort of menu, allowing arrow or scrollwheel
to choose. For time being I'd prefer to try to design a singular drop
though, just offer only one drop action per data type on given spots.
- What does work already, but a tad slow, is to use a function that
detects an object (type) under cursor, so a drag item's option can be
further refined (like drop object on object = parent). (disabled)
** More notes
- Added saving for Region layouts (like split points for toolbar)
- Label buttons now handle mouse over
- File list: added full path entry for drop feature.
- Filesel bugfix: wm_operator_exec() got called there and fully handled,
while WM event code tried same. Added new OPERATOR_HANDLED flag for this.
Maybe python needs it too?
- Cocoa: added window move event, so multi-win setups work OK (didnt save).
- Interface_handlers.c: removed win->active
- Severe area copy bug: area handlers were not set to NULL
- Filesel bugfix: next/prev folder list was not copied on area copies
** Leftover todos
- Cocoa windows seem to hang on cases still... needs check
- Cocoa 'draw overlap' swap doesn't work
- Cocoa window loses focus permanently on using Spotlight
(for these reasons, makefile building has Carbon as default atm)
- ListView templates in UI cannot become dragged yet, needs review...
it consists of two overlapping UI elements, preventing handling icon clicks.
- There's already Ghost library code to handle dropping from OS
into Blender window. I've noticed this code is unfinished for Macs, but
seems to be complete for Windows. Needs test... currently, an external
drop event will print in console when succesfully delivered to Blender's WM.
2010-01-26 18:18:21 +00:00
|
|
|
|
|
|
|
base= base->next;
|
2012-02-22 16:52:06 +00:00
|
|
|
if (base==NULL) base= FIRSTBASE;
|
|
|
|
if (base==startbase) break;
|
Drag and drop 2.5 integration! Finally, slashdot regulars can use
Blender too now! :)
** Drag works as follows:
- drag-able items are defined by the standard interface ui toolkit
- each button can get this feature, via uiButSetDragXXX(but, ...).
There are calls to define drag-able images, ID blocks, RNA paths,
file paths, and so on. By default you drag an icon, exceptionally
an ImBuf
- Drag items are registered centrally in the WM, it allows more drag
items simultaneous too, but not implemented
** Drop works as follows:
- On mouse release, and if drag items exist in the WM, it converts
the mouse event to an EVT_DROP type. This event then gets the full
drag info as customdata
- drop regions are defined with WM_dropbox_add(), similar to keymaps
you can make a "drop map" this way, which become 'drop map handlers'
in the queues.
- next to that the UI kit handles some common button types (like
accepting ID or names) to be catching a drop event too.
- Every "drop box" has two callbacks:
- poll() = check if the event drag data is relevant for this box
- copy() = fill in custom properties in the dropbox to initialize
an operator
- The dropbox handler then calls its standard Operator with its
dropbox properties.
** Currently implemented
Drag items:
- ID icons in browse buttons
- ID icons in context menu of properties region
- ID icons in outliner and rna viewer
- FileBrowser icons
- FileBrowser preview images
Drag-able icons are subtly visualized by making them brighter a bit
on mouse-over. In case the icon is a button or UI element too (most
cases), the drag-able feature will make the item react to
mouse-release instead of mouse-press.
Drop options:
- UI buttons: ID and text buttons (paste name)
- View3d: Object ID drop copies object
- View3d: Material ID drop assigns to object under cursor
- View3d: Image ID drop assigns to object UV texture under cursor
- Sequencer: Path drop will add either Image or Movie strip
- Image window: Path drop will open image
** Drag and drop Notes:
- Dropping into another Blender window (from same application) works
too. I've added code that passes on mousemoves and clicks to other
windows, without activating them though. This does make using multi-window
Blender a bit friendler.
- Dropping a file path to an image, is not the same as dropping an
Image ID... keep this in mind. Sequencer for example wants paths to
be dropped, textures in 3d window wants an Image ID.
- Although drop boxes could be defined via Python, I suggest they're
part of the UI and editor design (= how we want an editor to work), and
not default offered configurable like keymaps.
- At the moment only one item can be dragged at a time. This is for
several reasons.... For one, Blender doesn't have a well defined
uniform way to define "what is selected" (files, outliner items, etc).
Secondly there's potential conflicts on what todo when you drop mixed
drag sets on spots. All undefined stuff... nice for later.
- Example to bypass the above: a collection of images that form a strip,
should be represented in filewindow as a single sequence anyway.
This then will fit well and gets handled neatly by design.
- Another option to check is to allow multiple options per drop... it
could show the operator as a sort of menu, allowing arrow or scrollwheel
to choose. For time being I'd prefer to try to design a singular drop
though, just offer only one drop action per data type on given spots.
- What does work already, but a tad slow, is to use a function that
detects an object (type) under cursor, so a drag item's option can be
further refined (like drop object on object = parent). (disabled)
** More notes
- Added saving for Region layouts (like split points for toolbar)
- Label buttons now handle mouse over
- File list: added full path entry for drop feature.
- Filesel bugfix: wm_operator_exec() got called there and fully handled,
while WM event code tried same. Added new OPERATOR_HANDLED flag for this.
Maybe python needs it too?
- Cocoa: added window move event, so multi-win setups work OK (didnt save).
- Interface_handlers.c: removed win->active
- Severe area copy bug: area handlers were not set to NULL
- Filesel bugfix: next/prev folder list was not copied on area copies
** Leftover todos
- Cocoa windows seem to hang on cases still... needs check
- Cocoa 'draw overlap' swap doesn't work
- Cocoa window loses focus permanently on using Spotlight
(for these reasons, makefile building has Carbon as default atm)
- ListView templates in UI cannot become dragged yet, needs review...
it consists of two overlapping UI elements, preventing handling icon clicks.
- There's already Ghost library code to handle dropping from OS
into Blender window. I've noticed this code is unfinished for Macs, but
seems to be complete for Windows. Needs test... currently, an external
drop event will print in console when succesfully delivered to Blender's WM.
2010-01-26 18:18:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return basact;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* mval comes from event->mval, only use within region handlers */
|
2011-05-12 16:47:36 +00:00
|
|
|
Base *ED_view3d_give_base_under_cursor(bContext *C, const int mval[2])
|
Drag and drop 2.5 integration! Finally, slashdot regulars can use
Blender too now! :)
** Drag works as follows:
- drag-able items are defined by the standard interface ui toolkit
- each button can get this feature, via uiButSetDragXXX(but, ...).
There are calls to define drag-able images, ID blocks, RNA paths,
file paths, and so on. By default you drag an icon, exceptionally
an ImBuf
- Drag items are registered centrally in the WM, it allows more drag
items simultaneous too, but not implemented
** Drop works as follows:
- On mouse release, and if drag items exist in the WM, it converts
the mouse event to an EVT_DROP type. This event then gets the full
drag info as customdata
- drop regions are defined with WM_dropbox_add(), similar to keymaps
you can make a "drop map" this way, which become 'drop map handlers'
in the queues.
- next to that the UI kit handles some common button types (like
accepting ID or names) to be catching a drop event too.
- Every "drop box" has two callbacks:
- poll() = check if the event drag data is relevant for this box
- copy() = fill in custom properties in the dropbox to initialize
an operator
- The dropbox handler then calls its standard Operator with its
dropbox properties.
** Currently implemented
Drag items:
- ID icons in browse buttons
- ID icons in context menu of properties region
- ID icons in outliner and rna viewer
- FileBrowser icons
- FileBrowser preview images
Drag-able icons are subtly visualized by making them brighter a bit
on mouse-over. In case the icon is a button or UI element too (most
cases), the drag-able feature will make the item react to
mouse-release instead of mouse-press.
Drop options:
- UI buttons: ID and text buttons (paste name)
- View3d: Object ID drop copies object
- View3d: Material ID drop assigns to object under cursor
- View3d: Image ID drop assigns to object UV texture under cursor
- Sequencer: Path drop will add either Image or Movie strip
- Image window: Path drop will open image
** Drag and drop Notes:
- Dropping into another Blender window (from same application) works
too. I've added code that passes on mousemoves and clicks to other
windows, without activating them though. This does make using multi-window
Blender a bit friendler.
- Dropping a file path to an image, is not the same as dropping an
Image ID... keep this in mind. Sequencer for example wants paths to
be dropped, textures in 3d window wants an Image ID.
- Although drop boxes could be defined via Python, I suggest they're
part of the UI and editor design (= how we want an editor to work), and
not default offered configurable like keymaps.
- At the moment only one item can be dragged at a time. This is for
several reasons.... For one, Blender doesn't have a well defined
uniform way to define "what is selected" (files, outliner items, etc).
Secondly there's potential conflicts on what todo when you drop mixed
drag sets on spots. All undefined stuff... nice for later.
- Example to bypass the above: a collection of images that form a strip,
should be represented in filewindow as a single sequence anyway.
This then will fit well and gets handled neatly by design.
- Another option to check is to allow multiple options per drop... it
could show the operator as a sort of menu, allowing arrow or scrollwheel
to choose. For time being I'd prefer to try to design a singular drop
though, just offer only one drop action per data type on given spots.
- What does work already, but a tad slow, is to use a function that
detects an object (type) under cursor, so a drag item's option can be
further refined (like drop object on object = parent). (disabled)
** More notes
- Added saving for Region layouts (like split points for toolbar)
- Label buttons now handle mouse over
- File list: added full path entry for drop feature.
- Filesel bugfix: wm_operator_exec() got called there and fully handled,
while WM event code tried same. Added new OPERATOR_HANDLED flag for this.
Maybe python needs it too?
- Cocoa: added window move event, so multi-win setups work OK (didnt save).
- Interface_handlers.c: removed win->active
- Severe area copy bug: area handlers were not set to NULL
- Filesel bugfix: next/prev folder list was not copied on area copies
** Leftover todos
- Cocoa windows seem to hang on cases still... needs check
- Cocoa 'draw overlap' swap doesn't work
- Cocoa window loses focus permanently on using Spotlight
(for these reasons, makefile building has Carbon as default atm)
- ListView templates in UI cannot become dragged yet, needs review...
it consists of two overlapping UI elements, preventing handling icon clicks.
- There's already Ghost library code to handle dropping from OS
into Blender window. I've noticed this code is unfinished for Macs, but
seems to be complete for Windows. Needs test... currently, an external
drop event will print in console when succesfully delivered to Blender's WM.
2010-01-26 18:18:21 +00:00
|
|
|
{
|
|
|
|
ViewContext vc;
|
|
|
|
Base *basact= NULL;
|
|
|
|
unsigned int buffer[4*MAXPICKBUF];
|
|
|
|
int hits;
|
|
|
|
|
|
|
|
/* setup view context for argument to callbacks */
|
|
|
|
view3d_operator_needs_opengl(C);
|
|
|
|
view3d_set_viewcontext(C, &vc);
|
|
|
|
|
|
|
|
hits= mixed_bones_object_selectbuffer(&vc, buffer, mval);
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (hits>0) {
|
Drag and drop 2.5 integration! Finally, slashdot regulars can use
Blender too now! :)
** Drag works as follows:
- drag-able items are defined by the standard interface ui toolkit
- each button can get this feature, via uiButSetDragXXX(but, ...).
There are calls to define drag-able images, ID blocks, RNA paths,
file paths, and so on. By default you drag an icon, exceptionally
an ImBuf
- Drag items are registered centrally in the WM, it allows more drag
items simultaneous too, but not implemented
** Drop works as follows:
- On mouse release, and if drag items exist in the WM, it converts
the mouse event to an EVT_DROP type. This event then gets the full
drag info as customdata
- drop regions are defined with WM_dropbox_add(), similar to keymaps
you can make a "drop map" this way, which become 'drop map handlers'
in the queues.
- next to that the UI kit handles some common button types (like
accepting ID or names) to be catching a drop event too.
- Every "drop box" has two callbacks:
- poll() = check if the event drag data is relevant for this box
- copy() = fill in custom properties in the dropbox to initialize
an operator
- The dropbox handler then calls its standard Operator with its
dropbox properties.
** Currently implemented
Drag items:
- ID icons in browse buttons
- ID icons in context menu of properties region
- ID icons in outliner and rna viewer
- FileBrowser icons
- FileBrowser preview images
Drag-able icons are subtly visualized by making them brighter a bit
on mouse-over. In case the icon is a button or UI element too (most
cases), the drag-able feature will make the item react to
mouse-release instead of mouse-press.
Drop options:
- UI buttons: ID and text buttons (paste name)
- View3d: Object ID drop copies object
- View3d: Material ID drop assigns to object under cursor
- View3d: Image ID drop assigns to object UV texture under cursor
- Sequencer: Path drop will add either Image or Movie strip
- Image window: Path drop will open image
** Drag and drop Notes:
- Dropping into another Blender window (from same application) works
too. I've added code that passes on mousemoves and clicks to other
windows, without activating them though. This does make using multi-window
Blender a bit friendler.
- Dropping a file path to an image, is not the same as dropping an
Image ID... keep this in mind. Sequencer for example wants paths to
be dropped, textures in 3d window wants an Image ID.
- Although drop boxes could be defined via Python, I suggest they're
part of the UI and editor design (= how we want an editor to work), and
not default offered configurable like keymaps.
- At the moment only one item can be dragged at a time. This is for
several reasons.... For one, Blender doesn't have a well defined
uniform way to define "what is selected" (files, outliner items, etc).
Secondly there's potential conflicts on what todo when you drop mixed
drag sets on spots. All undefined stuff... nice for later.
- Example to bypass the above: a collection of images that form a strip,
should be represented in filewindow as a single sequence anyway.
This then will fit well and gets handled neatly by design.
- Another option to check is to allow multiple options per drop... it
could show the operator as a sort of menu, allowing arrow or scrollwheel
to choose. For time being I'd prefer to try to design a singular drop
though, just offer only one drop action per data type on given spots.
- What does work already, but a tad slow, is to use a function that
detects an object (type) under cursor, so a drag item's option can be
further refined (like drop object on object = parent). (disabled)
** More notes
- Added saving for Region layouts (like split points for toolbar)
- Label buttons now handle mouse over
- File list: added full path entry for drop feature.
- Filesel bugfix: wm_operator_exec() got called there and fully handled,
while WM event code tried same. Added new OPERATOR_HANDLED flag for this.
Maybe python needs it too?
- Cocoa: added window move event, so multi-win setups work OK (didnt save).
- Interface_handlers.c: removed win->active
- Severe area copy bug: area handlers were not set to NULL
- Filesel bugfix: next/prev folder list was not copied on area copies
** Leftover todos
- Cocoa windows seem to hang on cases still... needs check
- Cocoa 'draw overlap' swap doesn't work
- Cocoa window loses focus permanently on using Spotlight
(for these reasons, makefile building has Carbon as default atm)
- ListView templates in UI cannot become dragged yet, needs review...
it consists of two overlapping UI elements, preventing handling icon clicks.
- There's already Ghost library code to handle dropping from OS
into Blender window. I've noticed this code is unfinished for Macs, but
seems to be complete for Windows. Needs test... currently, an external
drop event will print in console when succesfully delivered to Blender's WM.
2010-01-26 18:18:21 +00:00
|
|
|
int a, has_bones= 0;
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
for (a=0; a<hits; a++) if (buffer[4*a+3] & 0xFFFF0000) has_bones= 1;
|
Drag and drop 2.5 integration! Finally, slashdot regulars can use
Blender too now! :)
** Drag works as follows:
- drag-able items are defined by the standard interface ui toolkit
- each button can get this feature, via uiButSetDragXXX(but, ...).
There are calls to define drag-able images, ID blocks, RNA paths,
file paths, and so on. By default you drag an icon, exceptionally
an ImBuf
- Drag items are registered centrally in the WM, it allows more drag
items simultaneous too, but not implemented
** Drop works as follows:
- On mouse release, and if drag items exist in the WM, it converts
the mouse event to an EVT_DROP type. This event then gets the full
drag info as customdata
- drop regions are defined with WM_dropbox_add(), similar to keymaps
you can make a "drop map" this way, which become 'drop map handlers'
in the queues.
- next to that the UI kit handles some common button types (like
accepting ID or names) to be catching a drop event too.
- Every "drop box" has two callbacks:
- poll() = check if the event drag data is relevant for this box
- copy() = fill in custom properties in the dropbox to initialize
an operator
- The dropbox handler then calls its standard Operator with its
dropbox properties.
** Currently implemented
Drag items:
- ID icons in browse buttons
- ID icons in context menu of properties region
- ID icons in outliner and rna viewer
- FileBrowser icons
- FileBrowser preview images
Drag-able icons are subtly visualized by making them brighter a bit
on mouse-over. In case the icon is a button or UI element too (most
cases), the drag-able feature will make the item react to
mouse-release instead of mouse-press.
Drop options:
- UI buttons: ID and text buttons (paste name)
- View3d: Object ID drop copies object
- View3d: Material ID drop assigns to object under cursor
- View3d: Image ID drop assigns to object UV texture under cursor
- Sequencer: Path drop will add either Image or Movie strip
- Image window: Path drop will open image
** Drag and drop Notes:
- Dropping into another Blender window (from same application) works
too. I've added code that passes on mousemoves and clicks to other
windows, without activating them though. This does make using multi-window
Blender a bit friendler.
- Dropping a file path to an image, is not the same as dropping an
Image ID... keep this in mind. Sequencer for example wants paths to
be dropped, textures in 3d window wants an Image ID.
- Although drop boxes could be defined via Python, I suggest they're
part of the UI and editor design (= how we want an editor to work), and
not default offered configurable like keymaps.
- At the moment only one item can be dragged at a time. This is for
several reasons.... For one, Blender doesn't have a well defined
uniform way to define "what is selected" (files, outliner items, etc).
Secondly there's potential conflicts on what todo when you drop mixed
drag sets on spots. All undefined stuff... nice for later.
- Example to bypass the above: a collection of images that form a strip,
should be represented in filewindow as a single sequence anyway.
This then will fit well and gets handled neatly by design.
- Another option to check is to allow multiple options per drop... it
could show the operator as a sort of menu, allowing arrow or scrollwheel
to choose. For time being I'd prefer to try to design a singular drop
though, just offer only one drop action per data type on given spots.
- What does work already, but a tad slow, is to use a function that
detects an object (type) under cursor, so a drag item's option can be
further refined (like drop object on object = parent). (disabled)
** More notes
- Added saving for Region layouts (like split points for toolbar)
- Label buttons now handle mouse over
- File list: added full path entry for drop feature.
- Filesel bugfix: wm_operator_exec() got called there and fully handled,
while WM event code tried same. Added new OPERATOR_HANDLED flag for this.
Maybe python needs it too?
- Cocoa: added window move event, so multi-win setups work OK (didnt save).
- Interface_handlers.c: removed win->active
- Severe area copy bug: area handlers were not set to NULL
- Filesel bugfix: next/prev folder list was not copied on area copies
** Leftover todos
- Cocoa windows seem to hang on cases still... needs check
- Cocoa 'draw overlap' swap doesn't work
- Cocoa window loses focus permanently on using Spotlight
(for these reasons, makefile building has Carbon as default atm)
- ListView templates in UI cannot become dragged yet, needs review...
it consists of two overlapping UI elements, preventing handling icon clicks.
- There's already Ghost library code to handle dropping from OS
into Blender window. I've noticed this code is unfinished for Macs, but
seems to be complete for Windows. Needs test... currently, an external
drop event will print in console when succesfully delivered to Blender's WM.
2010-01-26 18:18:21 +00:00
|
|
|
|
|
|
|
basact= mouse_select_eval_buffer(&vc, buffer, hits, mval, vc.scene->base.first, has_bones);
|
|
|
|
}
|
|
|
|
|
|
|
|
return basact;
|
|
|
|
}
|
2008-12-31 17:50:00 +00:00
|
|
|
|
2011-12-15 16:10:49 +00:00
|
|
|
static void deselect_all_tracks(MovieTracking *tracking)
|
|
|
|
{
|
|
|
|
MovieTrackingObject *object;
|
|
|
|
|
|
|
|
object= tracking->objects.first;
|
2012-02-22 16:52:06 +00:00
|
|
|
while (object) {
|
2011-12-15 16:10:49 +00:00
|
|
|
ListBase *tracksbase= BKE_tracking_object_tracks(tracking, object);
|
|
|
|
MovieTrackingTrack *track= tracksbase->first;
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
while (track) {
|
2011-12-15 16:10:49 +00:00
|
|
|
BKE_tracking_deselect_track(track, TRACK_AREA_ALL);
|
|
|
|
|
|
|
|
track= track->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
object= object->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-12-20 18:43:21 +00:00
|
|
|
/* mval is region coords */
|
2011-05-12 16:47:36 +00:00
|
|
|
static int mouse_select(bContext *C, const int mval[2], short extend, short obcenter, short enumerate)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2008-12-30 16:03:29 +00:00
|
|
|
ViewContext vc;
|
2008-12-29 12:15:42 +00:00
|
|
|
ARegion *ar= CTX_wm_region(C);
|
2009-01-17 18:35:33 +00:00
|
|
|
View3D *v3d= CTX_wm_view3d(C);
|
2008-12-29 12:15:42 +00:00
|
|
|
Scene *scene= CTX_data_scene(C);
|
2008-12-20 18:43:21 +00:00
|
|
|
Base *base, *startbase=NULL, *basact=NULL, *oldbasact=NULL;
|
|
|
|
int temp, a, dist=100;
|
2009-11-24 04:59:52 +00:00
|
|
|
int retval = 0;
|
2008-12-20 18:43:21 +00:00
|
|
|
short hits;
|
|
|
|
|
2008-12-30 16:03:29 +00:00
|
|
|
/* setup view context for argument to callbacks */
|
2009-01-02 14:11:18 +00:00
|
|
|
view3d_set_viewcontext(C, &vc);
|
2008-12-30 16:03:29 +00:00
|
|
|
|
2008-12-20 18:43:21 +00:00
|
|
|
/* always start list from basact in wire mode */
|
|
|
|
startbase= FIRSTBASE;
|
2012-02-22 16:52:06 +00:00
|
|
|
if (BASACT && BASACT->next) startbase= BASACT->next;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2011-05-28 13:11:24 +00:00
|
|
|
/* This block uses the control key to make the object selected by its center point rather than its contents */
|
2011-08-23 09:05:12 +00:00
|
|
|
/* in editmode do not activate */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (obcenter) {
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
/* note; shift+alt goes to group-flush-selecting */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (enumerate) {
|
2012-01-11 03:40:20 +00:00
|
|
|
basact= object_mouse_select_menu(C, &vc, NULL, 0, mval, extend);
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
else {
|
2008-12-20 18:43:21 +00:00
|
|
|
base= startbase;
|
2012-02-22 16:52:06 +00:00
|
|
|
while (base) {
|
2008-12-20 18:43:21 +00:00
|
|
|
if (BASE_SELECTABLE(v3d, base)) {
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
project_short(ar, base->object->obmat[3], &base->sx);
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
temp= abs(base->sx -mval[0]) + abs(base->sy -mval[1]);
|
2012-02-22 16:52:06 +00:00
|
|
|
if (base==BASACT) temp+=10;
|
|
|
|
if (temp<dist ) {
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
dist= temp;
|
|
|
|
basact= base;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
base= base->next;
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (base==NULL) base= FIRSTBASE;
|
|
|
|
if (base==startbase) break;
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2009-09-16 17:43:09 +00:00
|
|
|
unsigned int buffer[4*MAXPICKBUF];
|
|
|
|
|
2008-12-20 18:43:21 +00:00
|
|
|
/* if objects have posemode set, the bones are in the same selection buffer */
|
|
|
|
|
2008-12-30 16:03:29 +00:00
|
|
|
hits= mixed_bones_object_selectbuffer(&vc, buffer, mval);
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (hits>0) {
|
2008-12-20 18:43:21 +00:00
|
|
|
int has_bones= 0;
|
|
|
|
|
2011-11-07 12:55:18 +00:00
|
|
|
/* note: bundles are handling in the same way as bones */
|
2012-02-22 16:52:06 +00:00
|
|
|
for (a=0; a<hits; a++) if (buffer[4*a+3] & 0xFFFF0000) has_bones= 1;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
/* note; shift+alt goes to group-flush-selecting */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (has_bones==0 && enumerate) {
|
2012-01-11 03:40:20 +00:00
|
|
|
basact= object_mouse_select_menu(C, &vc, buffer, hits, mval, extend);
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
else {
|
Drag and drop 2.5 integration! Finally, slashdot regulars can use
Blender too now! :)
** Drag works as follows:
- drag-able items are defined by the standard interface ui toolkit
- each button can get this feature, via uiButSetDragXXX(but, ...).
There are calls to define drag-able images, ID blocks, RNA paths,
file paths, and so on. By default you drag an icon, exceptionally
an ImBuf
- Drag items are registered centrally in the WM, it allows more drag
items simultaneous too, but not implemented
** Drop works as follows:
- On mouse release, and if drag items exist in the WM, it converts
the mouse event to an EVT_DROP type. This event then gets the full
drag info as customdata
- drop regions are defined with WM_dropbox_add(), similar to keymaps
you can make a "drop map" this way, which become 'drop map handlers'
in the queues.
- next to that the UI kit handles some common button types (like
accepting ID or names) to be catching a drop event too.
- Every "drop box" has two callbacks:
- poll() = check if the event drag data is relevant for this box
- copy() = fill in custom properties in the dropbox to initialize
an operator
- The dropbox handler then calls its standard Operator with its
dropbox properties.
** Currently implemented
Drag items:
- ID icons in browse buttons
- ID icons in context menu of properties region
- ID icons in outliner and rna viewer
- FileBrowser icons
- FileBrowser preview images
Drag-able icons are subtly visualized by making them brighter a bit
on mouse-over. In case the icon is a button or UI element too (most
cases), the drag-able feature will make the item react to
mouse-release instead of mouse-press.
Drop options:
- UI buttons: ID and text buttons (paste name)
- View3d: Object ID drop copies object
- View3d: Material ID drop assigns to object under cursor
- View3d: Image ID drop assigns to object UV texture under cursor
- Sequencer: Path drop will add either Image or Movie strip
- Image window: Path drop will open image
** Drag and drop Notes:
- Dropping into another Blender window (from same application) works
too. I've added code that passes on mousemoves and clicks to other
windows, without activating them though. This does make using multi-window
Blender a bit friendler.
- Dropping a file path to an image, is not the same as dropping an
Image ID... keep this in mind. Sequencer for example wants paths to
be dropped, textures in 3d window wants an Image ID.
- Although drop boxes could be defined via Python, I suggest they're
part of the UI and editor design (= how we want an editor to work), and
not default offered configurable like keymaps.
- At the moment only one item can be dragged at a time. This is for
several reasons.... For one, Blender doesn't have a well defined
uniform way to define "what is selected" (files, outliner items, etc).
Secondly there's potential conflicts on what todo when you drop mixed
drag sets on spots. All undefined stuff... nice for later.
- Example to bypass the above: a collection of images that form a strip,
should be represented in filewindow as a single sequence anyway.
This then will fit well and gets handled neatly by design.
- Another option to check is to allow multiple options per drop... it
could show the operator as a sort of menu, allowing arrow or scrollwheel
to choose. For time being I'd prefer to try to design a singular drop
though, just offer only one drop action per data type on given spots.
- What does work already, but a tad slow, is to use a function that
detects an object (type) under cursor, so a drag item's option can be
further refined (like drop object on object = parent). (disabled)
** More notes
- Added saving for Region layouts (like split points for toolbar)
- Label buttons now handle mouse over
- File list: added full path entry for drop feature.
- Filesel bugfix: wm_operator_exec() got called there and fully handled,
while WM event code tried same. Added new OPERATOR_HANDLED flag for this.
Maybe python needs it too?
- Cocoa: added window move event, so multi-win setups work OK (didnt save).
- Interface_handlers.c: removed win->active
- Severe area copy bug: area handlers were not set to NULL
- Filesel bugfix: next/prev folder list was not copied on area copies
** Leftover todos
- Cocoa windows seem to hang on cases still... needs check
- Cocoa 'draw overlap' swap doesn't work
- Cocoa window loses focus permanently on using Spotlight
(for these reasons, makefile building has Carbon as default atm)
- ListView templates in UI cannot become dragged yet, needs review...
it consists of two overlapping UI elements, preventing handling icon clicks.
- There's already Ghost library code to handle dropping from OS
into Blender window. I've noticed this code is unfinished for Macs, but
seems to be complete for Windows. Needs test... currently, an external
drop event will print in console when succesfully delivered to Blender's WM.
2010-01-26 18:18:21 +00:00
|
|
|
basact= mouse_select_eval_buffer(&vc, buffer, hits, mval, startbase, has_bones);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (has_bones && basact) {
|
|
|
|
if (basact->object->type==OB_CAMERA) {
|
|
|
|
if (BASACT==basact) {
|
2011-11-07 12:55:18 +00:00
|
|
|
int i, hitresult;
|
2011-12-15 16:10:49 +00:00
|
|
|
int changed= 0;
|
2011-11-07 12:55:18 +00:00
|
|
|
|
|
|
|
for (i=0; i< hits; i++) {
|
|
|
|
hitresult= buffer[3+(i*4)];
|
|
|
|
|
|
|
|
/* if there's bundles in buffer select bundles first,
|
2012-03-03 16:31:46 +00:00
|
|
|
* so non-camera elements should be ignored in buffer */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (basact->selcol != (hitresult & 0xFFFF)) {
|
2011-11-07 12:55:18 +00:00
|
|
|
continue;
|
2011-12-15 16:10:49 +00:00
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
|
|
|
|
/* index of bundle is 1<<16-based. if there's no "bone" index
|
2012-03-03 16:31:46 +00:00
|
|
|
* in hight word, this buffer value belongs to camera,. not to bundle */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (buffer[4*i+3] & 0xFFFF0000) {
|
2011-11-07 12:55:18 +00:00
|
|
|
MovieClip *clip= object_get_movieclip(scene, basact->object, 0);
|
2011-12-05 18:57:17 +00:00
|
|
|
MovieTracking *tracking= &clip->tracking;
|
2011-12-15 16:10:49 +00:00
|
|
|
ListBase *tracksbase;
|
|
|
|
MovieTrackingTrack *track;
|
2011-12-05 18:57:17 +00:00
|
|
|
|
2011-12-15 16:10:49 +00:00
|
|
|
track= BKE_tracking_indexed_track(&clip->tracking, hitresult >> 16, &tracksbase);
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (TRACK_SELECTED(track) && extend) {
|
2011-12-15 16:10:49 +00:00
|
|
|
changed= 0;
|
2011-12-05 18:57:17 +00:00
|
|
|
BKE_tracking_deselect_track(track, TRACK_AREA_ALL);
|
2011-12-15 16:10:49 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
int oldsel= TRACK_SELECTED(track) ? 1 : 0;
|
2012-02-22 16:52:06 +00:00
|
|
|
if (!extend)
|
2011-12-15 16:10:49 +00:00
|
|
|
deselect_all_tracks(tracking);
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2011-12-15 16:10:49 +00:00
|
|
|
BKE_tracking_select_track(tracksbase, track, TRACK_AREA_ALL, extend);
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (oldsel!=(TRACK_SELECTED(track) ? 1 : 0))
|
2011-12-15 16:10:49 +00:00
|
|
|
changed= 1;
|
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
|
|
|
|
basact->flag|= SELECT;
|
|
|
|
basact->object->flag= basact->flag;
|
|
|
|
|
|
|
|
retval= 1;
|
|
|
|
|
|
|
|
WM_event_add_notifier(C, NC_MOVIECLIP|ND_SELECT, track);
|
|
|
|
WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene);
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2011-12-15 16:10:49 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (!changed) {
|
2011-12-15 16:10:49 +00:00
|
|
|
/* fallback to regular object selection if no new bundles were selected,
|
2012-03-03 16:31:46 +00:00
|
|
|
* allows to select object parented to reconstruction object */
|
2011-12-15 16:10:49 +00:00
|
|
|
basact= mouse_select_eval_buffer(&vc, buffer, hits, mval, startbase, 0);
|
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
else if (ED_do_pose_selectbuffer(scene, basact, buffer, hits, extend) ) { /* then bone is found */
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
/* we make the armature selected:
|
2012-03-03 16:31:46 +00:00
|
|
|
* not-selected active object in posemode won't work well for tools */
|
2008-12-20 18:43:21 +00:00
|
|
|
basact->flag|= SELECT;
|
|
|
|
basact->object->flag= basact->flag;
|
|
|
|
|
2009-11-24 04:59:52 +00:00
|
|
|
retval = 1;
|
2009-01-10 14:19:14 +00:00
|
|
|
WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, basact->object);
|
|
|
|
WM_event_add_notifier(C, NC_OBJECT|ND_BONE_ACTIVE, basact->object);
|
|
|
|
|
2008-12-20 18:43:21 +00:00
|
|
|
/* in weightpaint, we use selected bone to select vertexgroup, so no switch to new active object */
|
2012-03-10 22:00:55 +00:00
|
|
|
if (BASACT && (BASACT->object->mode & OB_MODE_WEIGHT_PAINT)) {
|
2008-12-20 18:43:21 +00:00
|
|
|
/* prevent activating */
|
|
|
|
basact= NULL;
|
|
|
|
}
|
2008-12-29 12:15:42 +00:00
|
|
|
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
/* prevent bone selecting to pass on to object selecting */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (basact==BASACT)
|
2008-12-20 18:43:21 +00:00
|
|
|
basact= NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* so, do we have something selected? */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (basact) {
|
2009-11-24 04:59:52 +00:00
|
|
|
retval = 1;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (vc.obedit) {
|
2008-12-20 18:43:21 +00:00
|
|
|
/* only do select */
|
|
|
|
deselectall_except(scene, basact);
|
2008-12-29 12:15:42 +00:00
|
|
|
ED_base_object_select(basact, BA_SELECT);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
/* also prevent making it active on mouse selection */
|
|
|
|
else if (BASE_SELECTABLE(v3d, basact)) {
|
|
|
|
|
|
|
|
oldbasact= BASACT;
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (!extend) {
|
2008-12-20 18:43:21 +00:00
|
|
|
deselectall_except(scene, basact);
|
2008-12-29 12:15:42 +00:00
|
|
|
ED_base_object_select(basact, BA_SELECT);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
else if (0) {
|
2008-12-20 18:43:21 +00:00
|
|
|
// XXX select_all_from_groups(basact);
|
|
|
|
}
|
|
|
|
else {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (basact->flag & SELECT) {
|
|
|
|
if (basact==oldbasact)
|
2008-12-29 12:15:42 +00:00
|
|
|
ED_base_object_select(basact, BA_DESELECT);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
2008-12-29 12:15:42 +00:00
|
|
|
else ED_base_object_select(basact, BA_SELECT);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (oldbasact != basact) {
|
2008-12-29 12:15:42 +00:00
|
|
|
ED_base_object_activate(C, basact); /* adds notifier */
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
2011-08-16 22:44:12 +00:00
|
|
|
|
|
|
|
WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
2009-11-24 04:59:52 +00:00
|
|
|
|
|
|
|
return retval;
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ******************** border and circle ************************************** */
|
|
|
|
|
2012-01-26 08:12:12 +00:00
|
|
|
typedef struct BoxSelectUserData {
|
|
|
|
ViewContext *vc;
|
|
|
|
rcti *rect;
|
|
|
|
int select, pass, done;
|
|
|
|
} BoxSelectUserData;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
int edge_inside_circle(short centx, short centy, short rad, short x1, short y1, short x2, short y2)
|
|
|
|
{
|
|
|
|
int radsq= rad*rad;
|
|
|
|
float v1[2], v2[2], v3[2];
|
|
|
|
|
|
|
|
/* check points in circle itself */
|
2012-02-22 16:52:06 +00:00
|
|
|
if ( (x1-centx)*(x1-centx) + (y1-centy)*(y1-centy) <= radsq ) return 1;
|
|
|
|
if ( (x2-centx)*(x2-centx) + (y2-centy)*(y2-centy) <= radsq ) return 1;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
/* pointdistline */
|
|
|
|
v3[0]= centx;
|
|
|
|
v3[1]= centy;
|
|
|
|
v1[0]= x1;
|
|
|
|
v1[1]= y1;
|
|
|
|
v2[0]= x2;
|
|
|
|
v2[1]= y2;
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if ( dist_to_line_segment_v2(v3, v1, v2) < (float)rad ) return 1;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-10-15 12:29:02 +00:00
|
|
|
static void do_nurbs_box_select__doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, int x, int y)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2012-01-26 08:12:12 +00:00
|
|
|
BoxSelectUserData *data = userData;
|
2010-04-30 04:48:40 +00:00
|
|
|
Object *obedit= data->vc->obedit;
|
|
|
|
Curve *cu= (Curve*)obedit->data;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
if (BLI_in_rcti(data->rect, x, y)) {
|
|
|
|
if (bp) {
|
|
|
|
bp->f1 = data->select?(bp->f1|SELECT):(bp->f1&~SELECT);
|
2010-04-30 04:48:40 +00:00
|
|
|
if (bp == cu->lastsel && !(bp->f1 & 1)) cu->lastsel = NULL;
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
else {
|
2009-09-16 17:43:09 +00:00
|
|
|
if (cu->drawflag & CU_HIDE_HANDLES) {
|
2008-12-20 18:43:21 +00:00
|
|
|
/* can only be beztindex==0 here since handles are hidden */
|
|
|
|
bezt->f1 = bezt->f2 = bezt->f3 = data->select?(bezt->f2|SELECT):(bezt->f2&~SELECT);
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
else {
|
2008-12-20 18:43:21 +00:00
|
|
|
if (beztindex==0) {
|
|
|
|
bezt->f1 = data->select?(bezt->f1|SELECT):(bezt->f1&~SELECT);
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
else if (beztindex==1) {
|
2008-12-20 18:43:21 +00:00
|
|
|
bezt->f2 = data->select?(bezt->f2|SELECT):(bezt->f2&~SELECT);
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
else {
|
2008-12-20 18:43:21 +00:00
|
|
|
bezt->f3 = data->select?(bezt->f3|SELECT):(bezt->f3&~SELECT);
|
|
|
|
}
|
|
|
|
}
|
2010-04-30 04:48:40 +00:00
|
|
|
|
|
|
|
if (bezt == cu->lastsel && !(bezt->f2 & 1)) cu->lastsel = NULL;
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-11-03 01:56:02 +00:00
|
|
|
static int do_nurbs_box_select(ViewContext *vc, rcti *rect, int select, int extend)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2012-01-26 08:12:12 +00:00
|
|
|
BoxSelectUserData data;
|
2008-12-30 16:03:29 +00:00
|
|
|
|
2010-04-30 04:48:40 +00:00
|
|
|
data.vc = vc;
|
2008-12-20 18:43:21 +00:00
|
|
|
data.rect = rect;
|
|
|
|
data.select = select;
|
|
|
|
|
2010-11-03 01:56:02 +00:00
|
|
|
if (extend == 0 && select)
|
2009-11-29 22:16:29 +00:00
|
|
|
CU_deselect_all(vc->obedit);
|
|
|
|
|
2009-10-22 23:22:05 +00:00
|
|
|
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
|
2008-12-30 16:03:29 +00:00
|
|
|
nurbs_foreachScreenVert(vc, do_nurbs_box_select__doSelect, &data);
|
2010-11-03 01:56:02 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void do_lattice_box_select__doSelect(void *userData, BPoint *bp, int x, int y)
|
|
|
|
{
|
2012-01-26 08:12:12 +00:00
|
|
|
BoxSelectUserData *data = userData;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
if (BLI_in_rcti(data->rect, x, y)) {
|
|
|
|
bp->f1 = data->select?(bp->f1|SELECT):(bp->f1&~SELECT);
|
|
|
|
}
|
|
|
|
}
|
2010-11-03 01:56:02 +00:00
|
|
|
static int do_lattice_box_select(ViewContext *vc, rcti *rect, int select, int extend)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2012-01-26 08:12:12 +00:00
|
|
|
BoxSelectUserData data;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2012-01-26 08:12:12 +00:00
|
|
|
data.vc= vc;
|
2008-12-20 18:43:21 +00:00
|
|
|
data.rect = rect;
|
|
|
|
data.select = select;
|
|
|
|
|
2010-11-03 01:56:02 +00:00
|
|
|
if (extend == 0 && select)
|
2009-11-29 22:16:29 +00:00
|
|
|
ED_setflagsLatt(vc->obedit, 0);
|
|
|
|
|
2009-10-22 23:22:05 +00:00
|
|
|
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
|
2008-12-30 16:03:29 +00:00
|
|
|
lattice_foreachScreenVert(vc, do_lattice_box_select__doSelect, &data);
|
2010-11-03 01:56:02 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
|
2011-02-27 06:19:40 +00:00
|
|
|
static void do_mesh_box_select__doSelectVert(void *userData, BMVert *eve, int x, int y, int UNUSED(index))
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2012-01-26 08:12:12 +00:00
|
|
|
BoxSelectUserData *data = userData;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
if (BLI_in_rcti(data->rect, x, y)) {
|
2012-02-12 10:51:45 +00:00
|
|
|
BM_elem_select_set(data->vc->em->bm, eve, data->select);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
2009-05-16 16:18:08 +00:00
|
|
|
static void do_mesh_box_select__doSelectEdge(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int index)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2012-01-26 08:12:12 +00:00
|
|
|
BoxSelectUserData *data = userData;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (EDBM_check_backbuf(bm_solidoffs+index)) {
|
2008-12-20 18:43:21 +00:00
|
|
|
if (data->pass==0) {
|
|
|
|
if (edge_fully_inside_rect(data->rect, x0, y0, x1, y1)) {
|
2012-02-12 10:51:45 +00:00
|
|
|
BM_elem_select_set(data->vc->em->bm, eed, data->select);
|
2008-12-20 18:43:21 +00:00
|
|
|
data->done = 1;
|
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
else {
|
2008-12-20 18:43:21 +00:00
|
|
|
if (edge_inside_rect(data->rect, x0, y0, x1, y1)) {
|
2012-02-12 10:51:45 +00:00
|
|
|
BM_elem_select_set(data->vc->em->bm, eed, data->select);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-02-27 06:19:40 +00:00
|
|
|
static void do_mesh_box_select__doSelectFace(void *userData, BMFace *efa, int x, int y, int UNUSED(index))
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2012-01-26 08:12:12 +00:00
|
|
|
BoxSelectUserData *data = userData;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
if (BLI_in_rcti(data->rect, x, y)) {
|
2012-02-12 10:51:45 +00:00
|
|
|
BM_elem_select_set(data->vc->em->bm, efa, data->select);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
2010-11-03 01:56:02 +00:00
|
|
|
static int do_mesh_box_select(ViewContext *vc, rcti *rect, int select, int extend)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2012-01-26 08:12:12 +00:00
|
|
|
BoxSelectUserData data;
|
2009-06-23 00:41:55 +00:00
|
|
|
ToolSettings *ts= vc->scene->toolsettings;
|
2008-12-20 18:43:21 +00:00
|
|
|
int bbsel;
|
|
|
|
|
2012-01-26 08:12:12 +00:00
|
|
|
data.vc= vc;
|
2008-12-20 18:43:21 +00:00
|
|
|
data.rect = rect;
|
|
|
|
data.select = select;
|
|
|
|
data.pass = 0;
|
|
|
|
data.done = 0;
|
|
|
|
|
2009-11-29 22:16:29 +00:00
|
|
|
if (extend == 0 && select)
|
2012-02-12 18:43:59 +00:00
|
|
|
EDBM_flag_disable_all(vc->em, BM_ELEM_SELECT);
|
2009-11-29 22:16:29 +00:00
|
|
|
|
2011-06-09 03:56:32 +00:00
|
|
|
/* for non zbuf projections, dont change the GL state */
|
|
|
|
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
|
2010-02-08 10:12:02 +00:00
|
|
|
|
|
|
|
glLoadMatrixf(vc->rv3d->viewmat);
|
2010-01-05 22:33:41 +00:00
|
|
|
bbsel= EDBM_init_backbuf_border(vc, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ts->selectmode & SCE_SELECT_VERTEX) {
|
2008-12-20 18:43:21 +00:00
|
|
|
if (bbsel) {
|
2010-01-05 22:33:41 +00:00
|
|
|
EDBM_backbuf_checkAndSelectVerts(vc->em, select);
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
else {
|
2011-11-28 16:44:17 +00:00
|
|
|
mesh_foreachScreenVert(vc, do_mesh_box_select__doSelectVert, &data, V3D_CLIP_TEST_RV3D_CLIPPING);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ts->selectmode & SCE_SELECT_EDGE) {
|
2008-12-20 18:43:21 +00:00
|
|
|
/* Does both bbsel and non-bbsel versions (need screen cos for both) */
|
|
|
|
|
|
|
|
data.pass = 0;
|
2011-11-28 16:44:17 +00:00
|
|
|
mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_CLIP_TEST_OFF);
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
if (data.done==0) {
|
|
|
|
data.pass = 1;
|
2011-11-28 16:44:17 +00:00
|
|
|
mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_CLIP_TEST_OFF);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ts->selectmode & SCE_SELECT_FACE) {
|
|
|
|
if (bbsel) {
|
2010-01-28 00:45:30 +00:00
|
|
|
EDBM_backbuf_checkAndSelectFaces(vc->em, select);
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
else {
|
2008-12-30 16:03:29 +00:00
|
|
|
mesh_foreachScreenFace(vc, do_mesh_box_select__doSelectFace, &data);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-01-28 00:45:30 +00:00
|
|
|
EDBM_free_backbuf();
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2012-02-10 06:16:21 +00:00
|
|
|
EDBM_selectmode_flush(vc->em);
|
2010-11-03 01:56:02 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
|
2010-11-03 01:56:02 +00:00
|
|
|
static int do_meta_box_select(ViewContext *vc, rcti *rect, int select, int extend)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2010-11-03 01:56:02 +00:00
|
|
|
MetaBall *mb = (MetaBall*)vc->obedit->data;
|
2008-12-20 18:43:21 +00:00
|
|
|
MetaElem *ml;
|
2010-11-03 01:56:02 +00:00
|
|
|
int a;
|
|
|
|
|
2008-12-20 18:43:21 +00:00
|
|
|
unsigned int buffer[4*MAXPICKBUF];
|
2010-11-03 01:56:02 +00:00
|
|
|
short hits;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2010-11-03 01:56:02 +00:00
|
|
|
hits= view3d_opengl_select(vc, buffer, MAXPICKBUF, rect);
|
2010-01-11 19:52:03 +00:00
|
|
|
|
2010-11-03 01:56:02 +00:00
|
|
|
if (extend == 0 && select) {
|
2012-02-22 16:52:06 +00:00
|
|
|
for (ml= mb->editelems->first; ml; ml= ml->next) {
|
2010-11-03 01:56:02 +00:00
|
|
|
ml->flag &= ~SELECT;
|
|
|
|
}
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
for (ml= mb->editelems->first; ml; ml= ml->next) {
|
|
|
|
for (a=0; a<hits; a++) {
|
|
|
|
if (ml->selcol1==buffer[ (4 * a) + 3 ]) {
|
2010-11-03 01:56:02 +00:00
|
|
|
ml->flag |= MB_SCALE_RAD;
|
2012-02-22 16:52:06 +00:00
|
|
|
if (select) ml->flag |= SELECT;
|
2010-11-03 02:28:11 +00:00
|
|
|
else ml->flag &= ~SELECT;
|
2010-11-03 01:56:02 +00:00
|
|
|
break;
|
2009-11-29 22:16:29 +00:00
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ml->selcol2==buffer[ (4 * a) + 3 ]) {
|
2010-11-03 01:56:02 +00:00
|
|
|
ml->flag &= ~MB_SCALE_RAD;
|
2012-02-22 16:52:06 +00:00
|
|
|
if (select) ml->flag |= SELECT;
|
2010-11-03 02:28:11 +00:00
|
|
|
else ml->flag &= ~SELECT;
|
2010-11-03 01:56:02 +00:00
|
|
|
break;
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
2010-11-03 01:56:02 +00:00
|
|
|
}
|
2009-11-29 22:16:29 +00:00
|
|
|
|
2010-11-03 01:56:02 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int do_armature_box_select(ViewContext *vc, rcti *rect, short select, short extend)
|
|
|
|
{
|
|
|
|
bArmature *arm= vc->obedit->data;
|
|
|
|
EditBone *ebone;
|
|
|
|
int a;
|
|
|
|
|
|
|
|
unsigned int buffer[4*MAXPICKBUF];
|
|
|
|
short hits;
|
|
|
|
|
|
|
|
hits= view3d_opengl_select(vc, buffer, MAXPICKBUF, rect);
|
|
|
|
|
|
|
|
/* clear flag we use to detect point was affected */
|
2012-02-22 16:52:06 +00:00
|
|
|
for (ebone= arm->edbo->first; ebone; ebone= ebone->next)
|
2010-11-03 01:56:02 +00:00
|
|
|
ebone->flag &= ~BONE_DONE;
|
|
|
|
|
|
|
|
if (extend==0 && select)
|
|
|
|
ED_armature_deselect_all_visible(vc->obedit);
|
|
|
|
|
|
|
|
/* first we only check points inside the border */
|
2012-02-22 16:52:06 +00:00
|
|
|
for (a=0; a<hits; a++) {
|
2010-11-03 01:56:02 +00:00
|
|
|
int index = buffer[(4*a)+3];
|
|
|
|
if (index!=-1) {
|
|
|
|
ebone = BLI_findlink(arm->edbo, index & ~(BONESEL_ANY));
|
|
|
|
if ((ebone->flag & BONE_UNSELECTABLE)==0) {
|
|
|
|
if (index & BONESEL_TIP) {
|
|
|
|
ebone->flag |= BONE_DONE;
|
|
|
|
if (select) ebone->flag |= BONE_TIPSEL;
|
|
|
|
else ebone->flag &= ~BONE_TIPSEL;
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
2010-11-03 01:56:02 +00:00
|
|
|
|
|
|
|
if (index & BONESEL_ROOT) {
|
|
|
|
ebone->flag |= BONE_DONE;
|
|
|
|
if (select) ebone->flag |= BONE_ROOTSEL;
|
|
|
|
else ebone->flag &= ~BONE_ROOTSEL;
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
2010-11-03 01:56:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* now we have to flush tag from parents... */
|
2012-02-22 16:52:06 +00:00
|
|
|
for (ebone= arm->edbo->first; ebone; ebone= ebone->next) {
|
|
|
|
if (ebone->parent && (ebone->flag & BONE_CONNECTED)) {
|
|
|
|
if (ebone->parent->flag & BONE_DONE)
|
2010-11-03 01:56:02 +00:00
|
|
|
ebone->flag |= BONE_DONE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* only select/deselect entire bones when no points where in the rect */
|
2012-02-22 16:52:06 +00:00
|
|
|
for (a=0; a<hits; a++) {
|
2010-11-03 01:56:02 +00:00
|
|
|
int index = buffer[(4*a)+3];
|
|
|
|
if (index!=-1) {
|
|
|
|
ebone = BLI_findlink(arm->edbo, index & ~(BONESEL_ANY));
|
|
|
|
if (index & BONESEL_BONE) {
|
|
|
|
if ((ebone->flag & BONE_UNSELECTABLE)==0) {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (!(ebone->flag & BONE_DONE)) {
|
2010-11-03 01:56:02 +00:00
|
|
|
if (select)
|
|
|
|
ebone->flag |= (BONE_ROOTSEL|BONE_TIPSEL|BONE_SELECTED);
|
|
|
|
else
|
|
|
|
ebone->flag &= ~(BONE_ROOTSEL|BONE_TIPSEL|BONE_SELECTED);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-11-03 01:56:02 +00:00
|
|
|
|
|
|
|
ED_armature_sync_selection(arm->edbo);
|
|
|
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
}
|
2009-11-29 22:16:29 +00:00
|
|
|
|
2010-11-03 01:56:02 +00:00
|
|
|
static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, int select, int extend)
|
|
|
|
{
|
|
|
|
Bone *bone;
|
|
|
|
Object *ob= vc->obact;
|
|
|
|
unsigned int *vbuffer=NULL; /* selection buffer */
|
|
|
|
unsigned int *col; /* color in buffer */
|
|
|
|
int bone_only;
|
|
|
|
int bone_selected=0;
|
|
|
|
int totobj= MAXPICKBUF; // XXX solve later
|
|
|
|
short hits;
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if ((ob) && (ob->mode & OB_MODE_POSE))
|
2010-11-03 01:56:02 +00:00
|
|
|
bone_only= 1;
|
|
|
|
else
|
|
|
|
bone_only= 0;
|
|
|
|
|
|
|
|
if (extend == 0 && select) {
|
|
|
|
if (bone_only) {
|
|
|
|
CTX_DATA_BEGIN(C, bPoseChannel *, pchan, visible_pose_bones) {
|
|
|
|
if ((pchan->bone->flag & BONE_UNSELECTABLE)==0) {
|
2009-11-29 22:16:29 +00:00
|
|
|
pchan->bone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
|
|
|
|
}
|
|
|
|
}
|
2010-11-03 01:56:02 +00:00
|
|
|
CTX_DATA_END;
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
else {
|
2010-11-03 01:56:02 +00:00
|
|
|
object_deselect_all_visible(vc->scene, vc->v3d);
|
2009-11-29 22:16:29 +00:00
|
|
|
}
|
2010-11-03 01:56:02 +00:00
|
|
|
}
|
2009-11-29 22:16:29 +00:00
|
|
|
|
2010-11-03 01:56:02 +00:00
|
|
|
/* selection buffer now has bones potentially too, so we add MAXPICKBUF */
|
|
|
|
vbuffer = MEM_mallocN(4 * (totobj+MAXPICKBUF) * sizeof(unsigned int), "selection buffer");
|
|
|
|
hits= view3d_opengl_select(vc, vbuffer, 4*(totobj+MAXPICKBUF), rect);
|
|
|
|
/*
|
2012-03-03 16:31:46 +00:00
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* The buffer order is defined by OGL standard, hopefully no stupid GFX card
|
|
|
|
* does it incorrectly.
|
|
|
|
*/
|
2010-11-03 01:56:02 +00:00
|
|
|
|
|
|
|
if (hits>0) { /* no need to loop if there's no hit */
|
|
|
|
Base *base;
|
|
|
|
col = vbuffer + 3;
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
for (base= vc->scene->base.first; base && hits; base= base->next) {
|
|
|
|
if (BASE_SELECTABLE(vc->v3d, base)) {
|
2010-11-03 01:56:02 +00:00
|
|
|
while (base->selcol == (*col & 0xFFFF)) { /* we got an object */
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (*col & 0xFFFF0000) { /* we got a bone */
|
2010-11-03 01:56:02 +00:00
|
|
|
bone = get_indexed_bone(base->object, *col & ~(BONESEL_ANY));
|
2012-02-22 16:52:06 +00:00
|
|
|
if (bone) {
|
|
|
|
if (select) {
|
2010-12-31 03:35:34 +00:00
|
|
|
if ((bone->flag & BONE_UNSELECTABLE)==0) {
|
2008-12-20 18:43:21 +00:00
|
|
|
bone->flag |= BONE_SELECTED;
|
2010-12-31 03:35:34 +00:00
|
|
|
bone_selected=1;
|
2008-12-20 18:43:21 +00:00
|
|
|
// XXX select_actionchannel_by_name(base->object->action, bone->name, 1);
|
|
|
|
}
|
2010-11-03 01:56:02 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
bArmature *arm= base->object->data;
|
|
|
|
bone->flag &= ~BONE_SELECTED;
|
2008-12-20 18:43:21 +00:00
|
|
|
// XXX select_actionchannel_by_name(base->object->action, bone->name, 0);
|
2012-02-22 16:52:06 +00:00
|
|
|
if (arm->act_bone==bone)
|
2010-11-03 01:56:02 +00:00
|
|
|
arm->act_bone= NULL;
|
|
|
|
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
else if (!bone_only) {
|
2010-11-03 01:56:02 +00:00
|
|
|
if (select)
|
|
|
|
ED_base_object_select(base, BA_SELECT);
|
|
|
|
else
|
|
|
|
ED_base_object_select(base, BA_DESELECT);
|
|
|
|
}
|
|
|
|
|
|
|
|
col+=4; /* next color */
|
|
|
|
hits--;
|
2012-02-22 16:52:06 +00:00
|
|
|
if (hits==0) break;
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
2010-11-03 01:56:02 +00:00
|
|
|
|
|
|
|
if (bone_selected) {
|
|
|
|
WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, base->object);
|
|
|
|
}
|
|
|
|
}
|
2008-12-29 12:15:42 +00:00
|
|
|
|
2010-11-03 01:56:02 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, vc->scene);
|
2008-12-29 12:15:42 +00:00
|
|
|
|
2010-11-03 01:56:02 +00:00
|
|
|
}
|
|
|
|
MEM_freeN(vbuffer);
|
|
|
|
|
|
|
|
return hits > 0 ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int view3d_borderselect_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
ViewContext vc;
|
|
|
|
rcti rect;
|
|
|
|
short extend;
|
|
|
|
short select;
|
|
|
|
|
|
|
|
int ret= OPERATOR_CANCELLED;
|
2008-12-29 12:15:42 +00:00
|
|
|
|
2010-11-03 01:56:02 +00:00
|
|
|
view3d_operator_needs_opengl(C);
|
|
|
|
|
|
|
|
/* setup view context for argument to callbacks */
|
|
|
|
view3d_set_viewcontext(C, &vc);
|
|
|
|
|
|
|
|
select= (RNA_int_get(op->ptr, "gesture_mode")==GESTURE_MODAL_SELECT);
|
|
|
|
rect.xmin= RNA_int_get(op->ptr, "xmin");
|
|
|
|
rect.ymin= RNA_int_get(op->ptr, "ymin");
|
|
|
|
rect.xmax= RNA_int_get(op->ptr, "xmax");
|
|
|
|
rect.ymax= RNA_int_get(op->ptr, "ymax");
|
|
|
|
extend = RNA_boolean_get(op->ptr, "extend");
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (vc.obedit) {
|
2010-11-03 01:56:02 +00:00
|
|
|
switch(vc.obedit->type) {
|
|
|
|
case OB_MESH:
|
2012-03-02 12:09:49 +00:00
|
|
|
vc.em = BMEdit_FromObject(vc.obedit);
|
2010-11-03 01:56:02 +00:00
|
|
|
ret= do_mesh_box_select(&vc, &rect, select, extend);
|
|
|
|
// if (EM_texFaceCheck())
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ret & OPERATOR_FINISHED) {
|
2010-11-03 01:56:02 +00:00
|
|
|
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, vc.obedit->data);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case OB_CURVE:
|
|
|
|
case OB_SURF:
|
|
|
|
ret= do_nurbs_box_select(&vc, &rect, select, extend);
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ret & OPERATOR_FINISHED) {
|
2011-08-26 11:35:33 +00:00
|
|
|
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, vc.obedit->data);
|
|
|
|
}
|
2010-11-03 01:56:02 +00:00
|
|
|
break;
|
|
|
|
case OB_MBALL:
|
|
|
|
ret= do_meta_box_select(&vc, &rect, select, extend);
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ret & OPERATOR_FINISHED) {
|
2011-08-26 11:35:33 +00:00
|
|
|
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, vc.obedit->data);
|
|
|
|
}
|
2010-11-03 01:56:02 +00:00
|
|
|
break;
|
|
|
|
case OB_ARMATURE:
|
|
|
|
ret= do_armature_box_select(&vc, &rect, select, extend);
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ret & OPERATOR_FINISHED) {
|
2010-11-03 01:56:02 +00:00
|
|
|
WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, vc.obedit);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case OB_LATTICE:
|
2011-02-22 03:19:58 +00:00
|
|
|
ret= do_lattice_box_select(&vc, &rect, select, extend);
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ret & OPERATOR_FINISHED) {
|
2011-02-22 03:19:58 +00:00
|
|
|
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, vc.obedit->data);
|
|
|
|
}
|
2010-11-03 01:56:02 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
assert(!"border select on incorrect object type");
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
2010-11-03 01:56:02 +00:00
|
|
|
else { /* no editmode, unified for bones and objects */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (vc.obact && vc.obact->mode & OB_MODE_SCULPT) {
|
2010-11-03 01:56:02 +00:00
|
|
|
/* pass */
|
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
else if (vc.obact && paint_facesel_test(vc.obact)) {
|
2010-11-03 01:56:02 +00:00
|
|
|
ret= do_paintface_box_select(&vc, &rect, select, extend);
|
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
else if (vc.obact && paint_vertsel_test(vc.obact)) {
|
2011-07-14 18:04:48 +00:00
|
|
|
ret= do_paintvert_box_select(&vc, &rect, select, extend);
|
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
else if (vc.obact && vc.obact->mode & OB_MODE_PARTICLE_EDIT) {
|
2010-11-03 01:56:02 +00:00
|
|
|
ret= PE_border_select(C, &rect, select, extend);
|
|
|
|
}
|
|
|
|
else { /* object mode with none active */
|
|
|
|
ret= do_object_pose_box_select(C, &vc, &rect, select, extend);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-12-28 01:28:31 +00:00
|
|
|
/* *****************Selection Operators******************* */
|
|
|
|
|
|
|
|
/* ****** Border Select ****** */
|
2009-03-29 02:15:13 +00:00
|
|
|
void VIEW3D_OT_select_border(wmOperatorType *ot)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Border Select";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description= "Select items using border selection";
|
2009-03-29 02:15:13 +00:00
|
|
|
ot->idname= "VIEW3D_OT_select_border";
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->invoke= WM_border_select_invoke;
|
|
|
|
ot->exec= view3d_borderselect_exec;
|
|
|
|
ot->modal= WM_border_select_modal;
|
2010-06-04 06:02:46 +00:00
|
|
|
ot->poll= view3d_selectable_data;
|
2011-06-06 11:04:54 +00:00
|
|
|
ot->cancel= WM_border_select_cancel;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2009-01-31 19:40:40 +00:00
|
|
|
/* flags */
|
2009-05-23 03:24:15 +00:00
|
|
|
ot->flag= OPTYPE_UNDO;
|
2009-01-31 19:40:40 +00:00
|
|
|
|
2008-12-20 18:43:21 +00:00
|
|
|
/* rna */
|
2009-11-06 22:51:08 +00:00
|
|
|
WM_operator_properties_gesture_border(ot, TRUE);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
|
2011-08-09 16:32:15 +00:00
|
|
|
/* much like facesel_face_pick()*/
|
|
|
|
/* returns 0 if not found, otherwise 1 */
|
2011-10-09 08:39:38 +00:00
|
|
|
static int vertsel_vert_pick(struct bContext *C, Mesh *me, const int mval[2], unsigned int *index, int size)
|
2011-07-05 18:03:31 +00:00
|
|
|
{
|
2011-08-09 16:32:15 +00:00
|
|
|
ViewContext vc;
|
|
|
|
view3d_set_viewcontext(C, &vc);
|
2011-07-05 18:03:31 +00:00
|
|
|
|
2011-08-09 16:32:15 +00:00
|
|
|
if (!me || me->totvert==0)
|
|
|
|
return 0;
|
2011-07-05 18:03:31 +00:00
|
|
|
|
2011-10-09 08:39:38 +00:00
|
|
|
if (size > 0) {
|
2011-08-09 16:32:15 +00:00
|
|
|
/* sample rect to increase changes of selecting, so that when clicking
|
2012-03-03 16:31:46 +00:00
|
|
|
* on an face in the backbuf, we can still select a vert */
|
2011-07-05 18:03:31 +00:00
|
|
|
|
2011-08-09 16:32:15 +00:00
|
|
|
int dist;
|
2011-10-09 08:39:38 +00:00
|
|
|
*index = view3d_sample_backbuf_rect(&vc, mval, size, 1, me->totvert+1, &dist,0,NULL, NULL);
|
2011-08-09 16:32:15 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* sample only on the exact position */
|
|
|
|
*index = view3d_sample_backbuf(&vc, mval[0], mval[1]);
|
|
|
|
}
|
2011-07-05 18:03:31 +00:00
|
|
|
|
2011-08-09 16:32:15 +00:00
|
|
|
if ((*index)<=0 || (*index)>(unsigned int)me->totvert)
|
|
|
|
return 0;
|
2011-07-05 18:03:31 +00:00
|
|
|
|
2011-08-09 16:32:15 +00:00
|
|
|
(*index)--;
|
|
|
|
|
|
|
|
return 1;
|
2011-07-05 18:03:31 +00:00
|
|
|
}
|
2011-09-18 17:10:28 +00:00
|
|
|
|
2011-07-05 18:03:31 +00:00
|
|
|
/* mouse selection in weight paint */
|
|
|
|
/* gets called via generic mouse select operator */
|
2011-09-20 04:38:59 +00:00
|
|
|
static int mouse_weight_paint_vertex_select(bContext *C, const int mval[2], short extend, Object *obact)
|
2011-07-05 18:03:31 +00:00
|
|
|
{
|
2011-09-20 04:38:59 +00:00
|
|
|
Mesh* me= obact->data; /* already checked for NULL */
|
2011-08-09 16:32:15 +00:00
|
|
|
unsigned int index = 0;
|
2011-07-05 18:03:31 +00:00
|
|
|
MVert *mv;
|
2011-10-09 08:39:38 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (vertsel_vert_pick(C, me, mval, &index, 50)) {
|
2011-08-09 16:32:15 +00:00
|
|
|
mv = me->mvert+index;
|
2012-02-22 16:52:06 +00:00
|
|
|
if (extend) {
|
2011-09-20 04:38:59 +00:00
|
|
|
mv->flag ^= SELECT;
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
else {
|
2011-07-12 19:06:06 +00:00
|
|
|
paintvert_deselect_all_visible(obact, SEL_DESELECT, FALSE);
|
2011-09-20 04:38:59 +00:00
|
|
|
mv->flag |= SELECT;
|
2011-07-05 18:03:31 +00:00
|
|
|
}
|
2011-07-12 19:06:06 +00:00
|
|
|
paintvert_flush_flags(obact);
|
2011-07-05 18:03:31 +00:00
|
|
|
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obact->data);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2008-12-28 01:28:31 +00:00
|
|
|
/* ****** Mouse Select ****** */
|
2008-12-29 00:45:00 +00:00
|
|
|
|
2008-12-31 17:50:00 +00:00
|
|
|
|
2008-12-28 01:28:31 +00:00
|
|
|
static int view3d_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
|
|
|
{
|
2008-12-31 17:11:42 +00:00
|
|
|
Object *obedit= CTX_data_edit_object(C);
|
2009-08-16 02:35:44 +00:00
|
|
|
Object *obact= CTX_data_active_object(C);
|
RNA
* Enums can now be dynamically created in the _itemf callback,
using RNA_enum_item(s)_add, RNA_enum_item_end. All places asking
for enum items now need to potentially free the items.
* This callback now also gets context, this was added specifically
for operators. This doesn't fit design well at all, needed to do
some ugly hacks, but can't find a good solution at the moment.
* All enums must have a default list of items too, even with an
_itemf callback, for docs and fallback in case there is no context.
* Used by MESH_OT_merge, MESH_OT_select_similar, TFM_OT_select_orientation.
* Also changes some operator properties that were enums to booleas
(unselected, deselect), to make them consistent with other ops.
2009-07-10 19:56:13 +00:00
|
|
|
short extend= RNA_boolean_get(op->ptr, "extend");
|
2009-09-16 17:43:09 +00:00
|
|
|
short center= RNA_boolean_get(op->ptr, "center");
|
|
|
|
short enumerate= RNA_boolean_get(op->ptr, "enumerate");
|
2011-08-23 09:05:12 +00:00
|
|
|
short object= RNA_boolean_get(op->ptr, "object");
|
2009-11-24 04:59:52 +00:00
|
|
|
int retval = 0;
|
2008-12-28 01:28:31 +00:00
|
|
|
|
|
|
|
view3d_operator_needs_opengl(C);
|
2011-08-16 22:44:12 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (object) {
|
2011-08-23 09:05:12 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (obedit && object==FALSE) {
|
|
|
|
if (obedit->type==OB_MESH)
|
2009-11-24 04:59:52 +00:00
|
|
|
retval = mouse_mesh(C, event->mval, extend);
|
2012-02-22 16:52:06 +00:00
|
|
|
else if (obedit->type==OB_ARMATURE)
|
2009-11-24 04:59:52 +00:00
|
|
|
retval = mouse_armature(C, event->mval, extend);
|
2012-02-22 16:52:06 +00:00
|
|
|
else if (obedit->type==OB_LATTICE)
|
2009-11-24 04:59:52 +00:00
|
|
|
retval = mouse_lattice(C, event->mval, extend);
|
2012-02-22 16:52:06 +00:00
|
|
|
else if (ELEM(obedit->type, OB_CURVE, OB_SURF))
|
2009-11-24 04:59:52 +00:00
|
|
|
retval = mouse_nurb(C, event->mval, extend);
|
2012-02-22 16:52:06 +00:00
|
|
|
else if (obedit->type==OB_MBALL)
|
2009-11-24 04:59:52 +00:00
|
|
|
retval = mouse_mball(C, event->mval, extend);
|
2009-01-05 19:32:04 +00:00
|
|
|
|
2008-12-31 17:11:42 +00:00
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
else if (obact && obact->mode & OB_MODE_SCULPT)
|
2010-01-04 17:03:44 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2012-02-22 16:52:06 +00:00
|
|
|
else if (obact && obact->mode & OB_MODE_PARTICLE_EDIT)
|
2009-11-24 04:59:52 +00:00
|
|
|
return PE_mouse_particles(C, event->mval, extend);
|
2012-02-22 16:52:06 +00:00
|
|
|
else if (obact && paint_facesel_test(obact))
|
2010-11-03 01:56:02 +00:00
|
|
|
retval = paintface_mouse_select(C, obact, event->mval, extend);
|
2011-09-20 04:38:59 +00:00
|
|
|
else if (paint_vertsel_test(obact))
|
|
|
|
retval = mouse_weight_paint_vertex_select(C, event->mval, extend, obact);
|
|
|
|
else
|
2009-11-24 04:59:52 +00:00
|
|
|
retval = mouse_select(C, event->mval, extend, center, enumerate);
|
2009-01-31 19:40:40 +00:00
|
|
|
|
2009-11-24 04:59:52 +00:00
|
|
|
/* passthrough allows tweaks
|
|
|
|
* FINISHED to signal one operator worked
|
|
|
|
* */
|
|
|
|
if (retval)
|
|
|
|
return OPERATOR_PASS_THROUGH|OPERATOR_FINISHED;
|
|
|
|
else
|
|
|
|
return OPERATOR_PASS_THROUGH; /* nothing selected, just passthrough */
|
2008-12-28 01:28:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void VIEW3D_OT_select(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Activate/Select";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description= "Activate/select item(s)";
|
2008-12-28 01:28:31 +00:00
|
|
|
ot->idname= "VIEW3D_OT_select";
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->invoke= view3d_select_invoke;
|
|
|
|
ot->poll= ED_operator_view3d_active;
|
2009-01-31 19:40:40 +00:00
|
|
|
|
|
|
|
/* flags */
|
2009-05-23 03:24:15 +00:00
|
|
|
ot->flag= OPTYPE_UNDO;
|
2009-01-31 19:40:40 +00:00
|
|
|
|
2009-01-16 23:53:11 +00:00
|
|
|
/* properties */
|
2011-09-19 12:26:20 +00:00
|
|
|
RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend selection instead of deselecting everything first");
|
|
|
|
RNA_def_boolean(ot->srna, "center", 0, "Center", "Use the object center when selecting, in editmode used to extend object selection");
|
|
|
|
RNA_def_boolean(ot->srna, "enumerate", 0, "Enumerate", "List objects under the mouse (object mode only)");
|
|
|
|
RNA_def_boolean(ot->srna, "object", 0, "Object", "Use object selection (editmode only)");
|
2008-12-28 01:28:31 +00:00
|
|
|
}
|
2008-12-29 00:45:00 +00:00
|
|
|
|
2008-12-28 01:28:31 +00:00
|
|
|
|
2009-01-02 14:11:18 +00:00
|
|
|
/* -------------------- circle select --------------------------------------------- */
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2012-01-26 08:12:12 +00:00
|
|
|
typedef struct CircleSelectUserData {
|
|
|
|
ViewContext *vc;
|
|
|
|
short select;
|
|
|
|
int mval[2];
|
|
|
|
float radius;
|
|
|
|
} CircleSelectUserData;
|
|
|
|
|
2011-02-27 06:19:40 +00:00
|
|
|
static void mesh_circle_doSelectVert(void *userData, BMVert *eve, int x, int y, int UNUSED(index))
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2012-01-26 08:12:12 +00:00
|
|
|
CircleSelectUserData *data = userData;
|
2008-12-20 18:43:21 +00:00
|
|
|
int mx = x - data->mval[0], my = y - data->mval[1];
|
|
|
|
float r = sqrt(mx*mx + my*my);
|
|
|
|
|
|
|
|
if (r<=data->radius) {
|
2012-02-12 10:51:45 +00:00
|
|
|
BM_elem_select_set(data->vc->em->bm, eve, data->select);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
2011-02-27 06:19:40 +00:00
|
|
|
static void mesh_circle_doSelectEdge(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int UNUSED(index))
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2012-01-26 08:12:12 +00:00
|
|
|
CircleSelectUserData *data = userData;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
if (edge_inside_circle(data->mval[0], data->mval[1], (short) data->radius, x0, y0, x1, y1)) {
|
2012-02-12 10:51:45 +00:00
|
|
|
BM_elem_select_set(data->vc->em->bm, eed, data->select);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
2011-02-27 06:19:40 +00:00
|
|
|
static void mesh_circle_doSelectFace(void *userData, BMFace *efa, int x, int y, int UNUSED(index))
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2012-01-26 08:12:12 +00:00
|
|
|
CircleSelectUserData *data = userData;
|
2008-12-20 18:43:21 +00:00
|
|
|
int mx = x - data->mval[0], my = y - data->mval[1];
|
|
|
|
float r = sqrt(mx*mx + my*my);
|
2008-12-30 13:16:14 +00:00
|
|
|
|
2008-12-20 18:43:21 +00:00
|
|
|
if (r<=data->radius) {
|
2012-02-12 10:51:45 +00:00
|
|
|
BM_elem_select_set(data->vc->em->bm, efa, data->select);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-05-12 16:47:36 +00:00
|
|
|
static void mesh_circle_select(ViewContext *vc, int select, const int mval[2], float rad)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2009-06-23 00:41:55 +00:00
|
|
|
ToolSettings *ts= vc->scene->toolsettings;
|
2008-12-20 18:43:21 +00:00
|
|
|
int bbsel;
|
2012-01-26 08:12:12 +00:00
|
|
|
CircleSelectUserData data;
|
2009-01-02 14:11:18 +00:00
|
|
|
|
2011-02-27 06:19:40 +00:00
|
|
|
bbsel= EDBM_init_backbuf_circle(vc, mval[0], mval[1], (short)(rad+1.0));
|
2010-09-23 21:01:12 +00:00
|
|
|
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2012-03-02 12:09:49 +00:00
|
|
|
vc->em = BMEdit_FromObject(vc->obedit);
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2010-09-23 21:01:12 +00:00
|
|
|
data.vc = vc;
|
2010-11-03 01:56:02 +00:00
|
|
|
data.select = select;
|
2010-09-23 21:01:12 +00:00
|
|
|
data.mval[0] = mval[0];
|
|
|
|
data.mval[1] = mval[1];
|
|
|
|
data.radius = rad;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ts->selectmode & SCE_SELECT_VERTEX) {
|
|
|
|
if (bbsel) {
|
2011-02-27 06:19:40 +00:00
|
|
|
EDBM_backbuf_checkAndSelectVerts(vc->em, select==LEFTMOUSE);
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
else {
|
2011-11-28 16:44:17 +00:00
|
|
|
mesh_foreachScreenVert(vc, mesh_circle_doSelectVert, &data, V3D_CLIP_TEST_RV3D_CLIPPING);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ts->selectmode & SCE_SELECT_EDGE) {
|
2010-09-23 21:01:12 +00:00
|
|
|
if (bbsel) {
|
2011-02-27 06:19:40 +00:00
|
|
|
EDBM_backbuf_checkAndSelectEdges(vc->em, select==LEFTMOUSE);
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
else {
|
2011-11-28 16:44:17 +00:00
|
|
|
mesh_foreachScreenEdge(vc, mesh_circle_doSelectEdge, &data, V3D_CLIP_TEST_OFF);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
2010-09-23 21:01:12 +00:00
|
|
|
}
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ts->selectmode & SCE_SELECT_FACE) {
|
|
|
|
if (bbsel) {
|
2011-02-27 06:19:40 +00:00
|
|
|
EDBM_backbuf_checkAndSelectFaces(vc->em, select==LEFTMOUSE);
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
else {
|
2010-09-23 21:01:12 +00:00
|
|
|
mesh_foreachScreenFace(vc, mesh_circle_doSelectFace, &data);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
2010-09-23 21:01:12 +00:00
|
|
|
}
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2011-02-27 06:19:40 +00:00
|
|
|
EDBM_free_backbuf();
|
2012-02-10 06:16:21 +00:00
|
|
|
EDBM_selectmode_flush(vc->em);
|
2010-09-23 21:01:12 +00:00
|
|
|
}
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2011-05-12 16:47:36 +00:00
|
|
|
static void paint_facesel_circle_select(ViewContext *vc, int select, const int mval[2], float rad)
|
2010-09-23 21:01:12 +00:00
|
|
|
{
|
|
|
|
Object *ob= vc->obact;
|
|
|
|
Mesh *me = ob?ob->data:NULL;
|
2011-09-20 08:48:48 +00:00
|
|
|
/* int bbsel; */ /* UNUSED */
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2010-09-23 21:01:12 +00:00
|
|
|
if (me) {
|
2011-04-15 01:19:13 +00:00
|
|
|
bm_vertoffs= me->totpoly+1; /* max index array */
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2011-09-23 07:17:07 +00:00
|
|
|
/* bbsel= */ /* UNUSED */ EDBM_init_backbuf_circle(vc, mval[0], mval[1], (short)(rad+1.0));
|
2011-02-27 06:19:40 +00:00
|
|
|
EDBM_backbuf_checkAndSelectTFaces(me, select==LEFTMOUSE);
|
2009-07-24 11:56:26 +00:00
|
|
|
EDBM_free_backbuf();
|
2009-01-02 14:11:18 +00:00
|
|
|
}
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-07-05 18:03:31 +00:00
|
|
|
static void paint_vertsel_circle_select(ViewContext *vc, int select, const int mval[2], float rad)
|
|
|
|
{
|
|
|
|
Object *ob= vc->obact;
|
|
|
|
Mesh *me = ob?ob->data:NULL;
|
2011-09-20 08:48:48 +00:00
|
|
|
/* int bbsel; */ /* UNUSED */
|
2012-01-26 08:12:12 +00:00
|
|
|
/* CircleSelectUserData data = {NULL}; */ /* UNUSED */
|
2011-07-05 18:03:31 +00:00
|
|
|
if (me) {
|
2011-09-22 16:09:27 +00:00
|
|
|
bm_vertoffs= me->totvert+1; /* max index array */
|
2011-08-09 16:32:15 +00:00
|
|
|
|
2011-09-23 07:17:07 +00:00
|
|
|
/* bbsel= */ /* UNUSED */ EDBM_init_backbuf_circle(vc, mval[0], mval[1], (short)(rad+1.0f));
|
2011-09-22 16:09:27 +00:00
|
|
|
EDBM_backbuf_checkAndSelectVerts_obmode(me, select==LEFTMOUSE);
|
|
|
|
EDBM_free_backbuf();
|
2011-07-12 19:06:06 +00:00
|
|
|
|
|
|
|
paintvert_flush_flags(ob);
|
2011-07-05 18:03:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2010-10-15 12:29:02 +00:00
|
|
|
static void nurbscurve_circle_doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, int x, int y)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2012-01-26 08:12:12 +00:00
|
|
|
CircleSelectUserData *data = userData;
|
2008-12-20 18:43:21 +00:00
|
|
|
int mx = x - data->mval[0], my = y - data->mval[1];
|
|
|
|
float r = sqrt(mx*mx + my*my);
|
2010-04-30 04:48:40 +00:00
|
|
|
Object *obedit= data->vc->obedit;
|
|
|
|
Curve *cu= (Curve*)obedit->data;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
|
|
|
if (r<=data->radius) {
|
|
|
|
if (bp) {
|
|
|
|
bp->f1 = data->select?(bp->f1|SELECT):(bp->f1&~SELECT);
|
2010-04-30 04:48:40 +00:00
|
|
|
|
|
|
|
if (bp == cu->lastsel && !(bp->f1 & 1)) cu->lastsel = NULL;
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
else {
|
2010-04-30 04:48:40 +00:00
|
|
|
if (cu->drawflag & CU_HIDE_HANDLES) {
|
|
|
|
/* can only be beztindex==0 here since handles are hidden */
|
|
|
|
bezt->f1 = bezt->f2 = bezt->f3 = data->select?(bezt->f2|SELECT):(bezt->f2&~SELECT);
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
else {
|
2010-04-30 04:48:40 +00:00
|
|
|
if (beztindex==0) {
|
|
|
|
bezt->f1 = data->select?(bezt->f1|SELECT):(bezt->f1&~SELECT);
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
else if (beztindex==1) {
|
2010-04-30 04:48:40 +00:00
|
|
|
bezt->f2 = data->select?(bezt->f2|SELECT):(bezt->f2&~SELECT);
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
else {
|
2010-04-30 04:48:40 +00:00
|
|
|
bezt->f3 = data->select?(bezt->f3|SELECT):(bezt->f3&~SELECT);
|
|
|
|
}
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
2010-04-30 04:48:40 +00:00
|
|
|
|
|
|
|
if (bezt == cu->lastsel && !(bezt->f2 & 1)) cu->lastsel = NULL;
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-05-12 16:47:36 +00:00
|
|
|
static void nurbscurve_circle_select(ViewContext *vc, int select, const int mval[2], float rad)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2012-01-26 08:12:12 +00:00
|
|
|
CircleSelectUserData data;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2009-01-02 14:11:18 +00:00
|
|
|
/* set vc-> edit data */
|
|
|
|
|
2010-11-03 01:56:02 +00:00
|
|
|
data.select = select;
|
2008-12-20 18:43:21 +00:00
|
|
|
data.mval[0] = mval[0];
|
|
|
|
data.mval[1] = mval[1];
|
|
|
|
data.radius = rad;
|
2010-04-30 04:48:40 +00:00
|
|
|
data.vc = vc;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2009-10-22 23:22:05 +00:00
|
|
|
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
|
2009-01-02 14:11:18 +00:00
|
|
|
nurbs_foreachScreenVert(vc, nurbscurve_circle_doSelect, &data);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-01-02 14:11:18 +00:00
|
|
|
static void latticecurve_circle_doSelect(void *userData, BPoint *bp, int x, int y)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2012-01-26 08:12:12 +00:00
|
|
|
CircleSelectUserData *data = userData;
|
2008-12-20 18:43:21 +00:00
|
|
|
int mx = x - data->mval[0], my = y - data->mval[1];
|
|
|
|
float r = sqrt(mx*mx + my*my);
|
|
|
|
|
|
|
|
if (r<=data->radius) {
|
|
|
|
bp->f1 = data->select?(bp->f1|SELECT):(bp->f1&~SELECT);
|
|
|
|
}
|
|
|
|
}
|
2011-05-12 16:47:36 +00:00
|
|
|
static void lattice_circle_select(ViewContext *vc, int select, const int mval[2], float rad)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2012-01-26 08:12:12 +00:00
|
|
|
CircleSelectUserData data;
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2009-01-02 14:11:18 +00:00
|
|
|
/* set vc-> edit data */
|
|
|
|
|
2010-11-03 01:56:02 +00:00
|
|
|
data.select = select;
|
2008-12-20 18:43:21 +00:00
|
|
|
data.mval[0] = mval[0];
|
|
|
|
data.mval[1] = mval[1];
|
|
|
|
data.radius = rad;
|
|
|
|
|
2009-10-22 23:22:05 +00:00
|
|
|
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
|
2009-01-02 14:11:18 +00:00
|
|
|
lattice_foreachScreenVert(vc, latticecurve_circle_doSelect, &data);
|
2008-12-20 18:43:21 +00:00
|
|
|
}
|
|
|
|
|
2009-11-05 08:54:33 +00:00
|
|
|
|
2010-12-31 03:35:34 +00:00
|
|
|
// NOTE: pose-bone case is copied from editbone case...
|
|
|
|
static short pchan_circle_doSelectJoint(void *userData, bPoseChannel *pchan, int x, int y)
|
|
|
|
{
|
2012-01-26 08:12:12 +00:00
|
|
|
CircleSelectUserData *data = userData;
|
2010-12-31 03:35:34 +00:00
|
|
|
int mx = x - data->mval[0], my = y - data->mval[1];
|
|
|
|
float r = sqrt(mx*mx + my*my);
|
|
|
|
|
|
|
|
if (r <= data->radius) {
|
|
|
|
if (data->select)
|
|
|
|
pchan->bone->flag |= BONE_SELECTED;
|
|
|
|
else
|
|
|
|
pchan->bone->flag &= ~BONE_SELECTED;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2011-05-12 16:47:36 +00:00
|
|
|
static void pose_circle_select(ViewContext *vc, int select, const int mval[2], float rad)
|
2010-12-31 03:35:34 +00:00
|
|
|
{
|
2012-01-26 08:12:12 +00:00
|
|
|
CircleSelectUserData data;
|
2012-01-24 08:43:39 +00:00
|
|
|
bArmature *arm = vc->obact->data;
|
2010-12-31 03:35:34 +00:00
|
|
|
bPose *pose = vc->obact->pose;
|
|
|
|
bPoseChannel *pchan;
|
|
|
|
int change= FALSE;
|
|
|
|
|
|
|
|
/* set vc->edit data */
|
|
|
|
data.select = select;
|
|
|
|
data.mval[0] = mval[0];
|
|
|
|
data.mval[1] = mval[1];
|
|
|
|
data.radius = rad;
|
|
|
|
|
|
|
|
ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); /* for foreach's screen/vert projection */
|
|
|
|
|
|
|
|
/* check each PoseChannel... */
|
2012-03-04 04:35:12 +00:00
|
|
|
// TODO: could be optimized at some point
|
2010-12-31 03:35:34 +00:00
|
|
|
for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
|
|
|
|
short sco1[2], sco2[2], didpoint=0;
|
|
|
|
float vec[3];
|
|
|
|
|
2012-01-24 08:43:39 +00:00
|
|
|
/* skip invisible bones */
|
|
|
|
if (PBONE_VISIBLE(arm, pchan->bone) == 0)
|
|
|
|
continue;
|
|
|
|
|
2010-12-31 03:35:34 +00:00
|
|
|
/* project head location to screenspace */
|
|
|
|
mul_v3_m4v3(vec, vc->obact->obmat, pchan->pose_head);
|
|
|
|
project_short(vc->ar, vec, sco1);
|
|
|
|
|
|
|
|
/* project tail location to screenspace */
|
|
|
|
mul_v3_m4v3(vec, vc->obact->obmat, pchan->pose_tail);
|
|
|
|
project_short(vc->ar, vec, sco2);
|
|
|
|
|
|
|
|
/* check if the head and/or tail is in the circle
|
|
|
|
* - the call to check also does the selection already
|
|
|
|
*/
|
|
|
|
if (pchan_circle_doSelectJoint(&data, pchan, sco1[0], sco1[1]))
|
|
|
|
didpoint= 1;
|
|
|
|
if (pchan_circle_doSelectJoint(&data, pchan, sco2[0], sco2[1]))
|
|
|
|
didpoint= 1;
|
|
|
|
|
|
|
|
change |= didpoint;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (change) {
|
|
|
|
WM_main_add_notifier(NC_OBJECT|ND_BONE_SELECT, vc->obact);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-05 08:54:33 +00:00
|
|
|
static short armature_circle_doSelectJoint(void *userData, EditBone *ebone, int x, int y, short head)
|
|
|
|
{
|
2012-01-26 08:12:12 +00:00
|
|
|
CircleSelectUserData *data = userData;
|
2009-11-05 08:54:33 +00:00
|
|
|
int mx = x - data->mval[0], my = y - data->mval[1];
|
|
|
|
float r = sqrt(mx*mx + my*my);
|
|
|
|
|
|
|
|
if (r <= data->radius) {
|
|
|
|
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;
|
|
|
|
}
|
2011-05-12 16:47:36 +00:00
|
|
|
static void armature_circle_select(ViewContext *vc, int select, const int mval[2], float rad)
|
2009-11-05 08:54:33 +00:00
|
|
|
{
|
2012-01-26 08:12:12 +00:00
|
|
|
CircleSelectUserData data;
|
2009-11-05 08:54:33 +00:00
|
|
|
bArmature *arm= vc->obedit->data;
|
|
|
|
EditBone *ebone;
|
2010-09-15 13:22:36 +00:00
|
|
|
int change= FALSE;
|
2009-11-05 08:54:33 +00:00
|
|
|
|
|
|
|
/* set vc->edit data */
|
2010-11-03 01:56:02 +00:00
|
|
|
data.select = select;
|
2009-11-05 08:54:33 +00:00
|
|
|
data.mval[0] = mval[0];
|
|
|
|
data.mval[1] = mval[1];
|
|
|
|
data.radius = rad;
|
|
|
|
|
|
|
|
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
|
|
|
|
|
|
|
|
/* check each EditBone... */
|
2012-03-04 04:35:12 +00:00
|
|
|
// TODO: could be optimized at some point
|
2009-11-05 08:54:33 +00:00
|
|
|
for (ebone= arm->edbo->first; ebone; ebone=ebone->next) {
|
|
|
|
short sco1[2], sco2[2], didpoint=0;
|
|
|
|
float vec[3];
|
|
|
|
|
|
|
|
/* project head location to screenspace */
|
2010-07-26 06:34:56 +00:00
|
|
|
mul_v3_m4v3(vec, vc->obedit->obmat, ebone->head);
|
2009-11-05 08:54:33 +00:00
|
|
|
project_short(vc->ar, vec, sco1);
|
|
|
|
|
|
|
|
/* project tail location to screenspace */
|
2010-07-26 06:34:56 +00:00
|
|
|
mul_v3_m4v3(vec, vc->obedit->obmat, ebone->tail);
|
2009-11-05 08:54:33 +00:00
|
|
|
project_short(vc->ar, vec, sco2);
|
|
|
|
|
|
|
|
/* check if the head and/or tail is in the circle
|
|
|
|
* - the call to check also does the selection already
|
|
|
|
*/
|
|
|
|
if (armature_circle_doSelectJoint(&data, ebone, sco1[0], sco1[1], 1))
|
|
|
|
didpoint= 1;
|
|
|
|
if (armature_circle_doSelectJoint(&data, ebone, sco2[0], sco2[1], 0))
|
|
|
|
didpoint= 1;
|
|
|
|
|
|
|
|
/* only if the endpoints didn't get selected, deal with the middle of the bone too */
|
|
|
|
// XXX should we just do this always?
|
|
|
|
if ( (didpoint==0) && edge_inside_circle(mval[0], mval[1], rad, sco1[0], sco1[1], sco2[0], sco2[1]) ) {
|
2010-11-03 01:56:02 +00:00
|
|
|
if (select)
|
2009-11-05 08:54:33 +00:00
|
|
|
ebone->flag |= BONE_TIPSEL|BONE_ROOTSEL|BONE_SELECTED;
|
|
|
|
else
|
2009-11-09 21:03:54 +00:00
|
|
|
ebone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
|
2010-09-15 13:22:36 +00:00
|
|
|
change= TRUE;
|
2009-11-05 08:54:33 +00:00
|
|
|
}
|
2010-12-08 18:12:59 +00:00
|
|
|
|
|
|
|
change |= didpoint;
|
2009-11-05 08:54:33 +00:00
|
|
|
}
|
2009-11-09 21:03:54 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (change) {
|
2010-12-08 18:12:59 +00:00
|
|
|
ED_armature_sync_selection(arm->edbo);
|
2010-09-15 13:22:36 +00:00
|
|
|
ED_armature_validate_active(arm);
|
|
|
|
WM_main_add_notifier(NC_OBJECT|ND_BONE_SELECT, vc->obedit);
|
|
|
|
}
|
2009-11-05 08:54:33 +00:00
|
|
|
}
|
|
|
|
|
2009-01-02 14:11:18 +00:00
|
|
|
/** Callbacks for circle selection in Editmode */
|
2008-12-20 18:43:21 +00:00
|
|
|
|
2011-05-12 16:47:36 +00:00
|
|
|
static void obedit_circle_select(ViewContext *vc, short select, const int mval[2], float rad)
|
2008-12-20 18:43:21 +00:00
|
|
|
{
|
2009-01-02 14:11:18 +00:00
|
|
|
switch(vc->obedit->type) {
|
2008-12-20 18:43:21 +00:00
|
|
|
case OB_MESH:
|
2010-11-03 01:56:02 +00:00
|
|
|
mesh_circle_select(vc, select, mval, rad);
|
2008-12-20 18:43:21 +00:00
|
|
|
break;
|
|
|
|
case OB_CURVE:
|
|
|
|
case OB_SURF:
|
2010-11-03 01:56:02 +00:00
|
|
|
nurbscurve_circle_select(vc, select, mval, rad);
|
2008-12-20 18:43:21 +00:00
|
|
|
break;
|
|
|
|
case OB_LATTICE:
|
2010-11-03 01:56:02 +00:00
|
|
|
lattice_circle_select(vc, select, mval, rad);
|
2008-12-20 18:43:21 +00:00
|
|
|
break;
|
2009-11-05 08:54:33 +00:00
|
|
|
case OB_ARMATURE:
|
2010-11-03 01:56:02 +00:00
|
|
|
armature_circle_select(vc, select, mval, rad);
|
2009-11-05 08:54:33 +00:00
|
|
|
break;
|
2008-12-20 18:43:21 +00:00
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-12-29 12:15:42 +00:00
|
|
|
/* not a real operator, only for circle test */
|
2009-01-02 14:11:18 +00:00
|
|
|
static int view3d_circle_select_exec(bContext *C, wmOperator *op)
|
2008-12-21 16:24:19 +00:00
|
|
|
{
|
|
|
|
ScrArea *sa= CTX_wm_area(C);
|
|
|
|
ARegion *ar= CTX_wm_region(C);
|
2008-12-22 09:43:29 +00:00
|
|
|
Scene *scene= CTX_data_scene(C);
|
2009-08-16 02:35:44 +00:00
|
|
|
Object *obact= CTX_data_active_object(C);
|
2008-12-21 16:24:19 +00:00
|
|
|
View3D *v3d= sa->spacedata.first;
|
|
|
|
int x= RNA_int_get(op->ptr, "x");
|
|
|
|
int y= RNA_int_get(op->ptr, "y");
|
|
|
|
int radius= RNA_int_get(op->ptr, "radius");
|
2010-03-22 09:30:00 +00:00
|
|
|
int gesture_mode= RNA_int_get(op->ptr, "gesture_mode");
|
2010-11-03 01:56:02 +00:00
|
|
|
int select;
|
2008-12-21 16:24:19 +00:00
|
|
|
|
2010-11-03 01:56:02 +00:00
|
|
|
select= (gesture_mode==GESTURE_MODAL_SELECT);
|
2011-05-11 09:31:00 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if ( CTX_data_edit_object(C) || paint_facesel_test(obact) || paint_vertsel_test(obact) ||
|
2010-12-31 03:35:34 +00:00
|
|
|
(obact && (obact->mode & (OB_MODE_PARTICLE_EDIT|OB_MODE_POSE))) )
|
|
|
|
{
|
2009-01-02 14:11:18 +00:00
|
|
|
ViewContext vc;
|
2011-05-12 16:47:36 +00:00
|
|
|
int mval[2];
|
2009-01-02 14:11:18 +00:00
|
|
|
|
2.5
Sanitized the 'tweak' event.
Original idea was to have WM event system generating it
automatically. However, I first tested it via a handler
and operator, to check what kind of configurations would
be useful. It appeared to not work nice, also because
that inserting a tweak operator in a keymap is confusing.
Now 'tweaks' are generated automatically, and can be
catched by keymaps as any event. The current definition
of tweak is:
- if Left/Middle/Rightmouse pressed
if event wasn't handled by window queue (modal handlers)
start checking mousepositions
- while mousepositions are checked
- escape on any event other than mouse
- on mouse events:
- add tweak event if mousemove > 10 pixels
- stop checking for tweak if mousebutton released
- Tweak events have a define indicating mousebutton used
EVT_TWEAK_L, EVT_TWEAK_M, EVT_TWEAK_R
- In keymap definitions you can use _S or _A to map to
action or select mouse userdef.
- Event value in keymap should be KM_ANY for all tweaks,
or use one of the eight directions:
EVT_GESTURE_E, _SE, _S, _SW, _W, _NW, _N, _NE
- And of course you can add modifier checks in keymaps for it.
- Because tweaks are a result of mouse events, the handlers get
both to evaluate. That means that RMB-select + tweak will work
correctly.
In case you don't want both to be handled, for example the
CTRL+LMB 'extrude' and CTRL+LMB-tweak 'lasso select', you will
need to set the first acting on a EVT_RELEASE, this event only
gets passed on when tweak fails.
The current system allows all options, configurable, we had in 2.48,
and many more! A diagram of what's possible is on the todo. :)
Also in this commit: lasso select editmesh failed with 'zbuffer
occluded select'. Also circle-select failed.
2009-02-02 14:13:14 +00:00
|
|
|
view3d_operator_needs_opengl(C);
|
|
|
|
|
2009-01-02 14:11:18 +00:00
|
|
|
view3d_set_viewcontext(C, &vc);
|
|
|
|
mval[0]= x;
|
|
|
|
mval[1]= y;
|
2009-02-20 20:39:27 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (CTX_data_edit_object(C)) {
|
2010-11-03 01:56:02 +00:00
|
|
|
obedit_circle_select(&vc, select, mval, (float)radius);
|
2009-09-16 17:43:09 +00:00
|
|
|
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obact->data);
|
2009-08-16 18:25:22 +00:00
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
else if (paint_facesel_test(obact)) {
|
2010-11-03 01:56:02 +00:00
|
|
|
paint_facesel_circle_select(&vc, select, mval, (float)radius);
|
2010-09-23 21:01:12 +00:00
|
|
|
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obact->data);
|
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
else if (paint_vertsel_test(obact)) {
|
2011-07-12 19:06:06 +00:00
|
|
|
paint_vertsel_circle_select(&vc, select, mval, (float)radius);
|
2010-09-23 21:01:12 +00:00
|
|
|
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obact->data);
|
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
else if (obact->mode & OB_MODE_POSE)
|
2010-12-31 03:35:34 +00:00
|
|
|
pose_circle_select(&vc, select, mval, (float)radius);
|
2009-02-20 20:39:27 +00:00
|
|
|
else
|
2010-11-03 01:56:02 +00:00
|
|
|
return PE_circle_select(C, select, mval, (float)radius);
|
2009-01-02 14:11:18 +00:00
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
else if (obact && obact->mode & OB_MODE_SCULPT) {
|
2010-01-04 17:03:44 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
}
|
2009-01-02 14:11:18 +00:00
|
|
|
else {
|
|
|
|
Base *base;
|
2010-11-03 01:56:02 +00:00
|
|
|
select= select?BA_SELECT:BA_DESELECT;
|
2012-02-22 16:52:06 +00:00
|
|
|
for (base= FIRSTBASE; base; base= base->next) {
|
|
|
|
if (BASE_SELECTABLE(v3d, base)) {
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
project_short(ar, base->object->obmat[3], &base->sx);
|
2012-02-22 16:52:06 +00:00
|
|
|
if (base->sx!=IS_CLIPPED) {
|
2009-01-02 14:11:18 +00:00
|
|
|
int dx= base->sx-x;
|
|
|
|
int dy= base->sy-y;
|
2012-02-22 16:52:06 +00:00
|
|
|
if ( dx*dx + dy*dy < radius*radius)
|
2010-11-03 01:56:02 +00:00
|
|
|
ED_base_object_select(base, select);
|
2009-01-02 14:11:18 +00:00
|
|
|
}
|
2008-12-21 16:24:19 +00:00
|
|
|
}
|
|
|
|
}
|
2009-01-02 14:11:18 +00:00
|
|
|
|
|
|
|
WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C));
|
2008-12-21 16:24:19 +00:00
|
|
|
}
|
2009-01-02 14:11:18 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
2008-12-21 16:24:19 +00:00
|
|
|
}
|
|
|
|
|
2009-03-29 02:15:13 +00:00
|
|
|
void VIEW3D_OT_select_circle(wmOperatorType *ot)
|
2008-12-21 16:24:19 +00:00
|
|
|
{
|
|
|
|
ot->name= "Circle Select";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description= "Select items using circle selection";
|
2009-03-29 02:15:13 +00:00
|
|
|
ot->idname= "VIEW3D_OT_select_circle";
|
2008-12-21 16:24:19 +00:00
|
|
|
|
|
|
|
ot->invoke= WM_gesture_circle_invoke;
|
|
|
|
ot->modal= WM_gesture_circle_modal;
|
2009-01-02 14:11:18 +00:00
|
|
|
ot->exec= view3d_circle_select_exec;
|
2010-06-04 06:02:46 +00:00
|
|
|
ot->poll= view3d_selectable_data;
|
2011-06-06 11:04:54 +00:00
|
|
|
ot->cancel= WM_gesture_circle_cancel;
|
2008-12-21 16:24:19 +00:00
|
|
|
|
2009-01-31 19:40:40 +00:00
|
|
|
/* flags */
|
2009-05-23 03:24:15 +00:00
|
|
|
ot->flag= OPTYPE_UNDO;
|
2009-01-31 19:40:40 +00:00
|
|
|
|
2009-01-16 23:53:11 +00:00
|
|
|
RNA_def_int(ot->srna, "x", 0, INT_MIN, INT_MAX, "X", "", INT_MIN, INT_MAX);
|
|
|
|
RNA_def_int(ot->srna, "y", 0, INT_MIN, INT_MAX, "Y", "", INT_MIN, INT_MAX);
|
|
|
|
RNA_def_int(ot->srna, "radius", 0, INT_MIN, INT_MAX, "Radius", "", INT_MIN, INT_MAX);
|
2009-11-05 17:32:06 +00:00
|
|
|
RNA_def_int(ot->srna, "gesture_mode", 0, INT_MIN, INT_MAX, "Event Type", "", INT_MIN, INT_MAX);
|
2008-12-21 16:24:19 +00:00
|
|
|
}
|