[Bf-blender-cvs] [be312b1] strand_editmode: First selection operator implementation for hair edit: circle select.
Lukas Tönne
noreply at git.blender.org
Mon Apr 20 14:23:48 CEST 2015
Commit: be312b139961a9a74d920a0c4fb6e243824e5e6d
Author: Lukas Tönne
Date: Thu Dec 4 17:15:46 2014 +0100
Branches: strand_editmode
https://developer.blender.org/rBbe312b139961a9a74d920a0c4fb6e243824e5e6d
First selection operator implementation for hair edit: circle select.
===================================================================
M source/blender/blenkernel/BKE_edithair.h
M source/blender/editors/hair/CMakeLists.txt
M source/blender/editors/hair/hair_edit.c
M source/blender/editors/hair/hair_intern.h
A source/blender/editors/hair/hair_select.c
M source/blender/editors/hair/hair_stroke.c
M source/blender/editors/include/ED_physics.h
M source/blender/editors/space_view3d/view3d_select.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_edithair.h b/source/blender/blenkernel/BKE_edithair.h
index 57cb6aa..070f8df 100644
--- a/source/blender/blenkernel/BKE_edithair.h
+++ b/source/blender/blenkernel/BKE_edithair.h
@@ -50,9 +50,6 @@ typedef struct BMEditStrands {
struct BMEditStrands *emcopy;
int emcopyusers;
- /*selection mode*/
- short selectmode;
-
/* Object this editmesh came from (if it came from one) */
struct Object *ob;
struct DerivedMesh *root_dm;
diff --git a/source/blender/editors/hair/CMakeLists.txt b/source/blender/editors/hair/CMakeLists.txt
index 3e9e256..570f46c 100644
--- a/source/blender/editors/hair/CMakeLists.txt
+++ b/source/blender/editors/hair/CMakeLists.txt
@@ -41,6 +41,7 @@ set(SRC
hair_cursor.c
hair_edit.c
hair_ops.c
+ hair_select.c
hair_stroke.c
hair_intern.h
diff --git a/source/blender/editors/hair/hair_edit.c b/source/blender/editors/hair/hair_edit.c
index 8602eac..fa7e914 100644
--- a/source/blender/editors/hair/hair_edit.c
+++ b/source/blender/editors/hair/hair_edit.c
@@ -224,28 +224,28 @@ void HAIR_OT_hair_edit_toggle(wmOperatorType *ot)
/* ==== brush stroke ==== */
-static void hair_set_view3d_data(bContext *C, HairToolData *data)
+void hair_init_viewdata(bContext *C, HairViewData *viewdata)
{
View3D *v3d;
bool has_zbuf;
- view3d_set_viewcontext(C, &data->vc);
+ view3d_set_viewcontext(C, &viewdata->vc);
- v3d = data->vc.v3d;
+ v3d = viewdata->vc.v3d;
has_zbuf = (v3d->drawtype > OB_WIRE) && (v3d->flag & V3D_ZBUF_SELECT);
- view3d_get_transformation(data->vc.ar, data->vc.rv3d, NULL, &data->mats);
+ view3d_get_transformation(viewdata->vc.ar, viewdata->vc.rv3d, NULL, &viewdata->mats);
if (has_zbuf) {
if (v3d->flag & V3D_INVALID_BACKBUF) {
/* needed or else the draw matrix can be incorrect */
view3d_operator_needs_opengl(C);
- view3d_validate_backbuf(&data->vc);
+ view3d_validate_backbuf(&viewdata->vc);
/* we may need to force an update here by setting the rv3d as dirty
* for now it seems ok, but take care!:
* rv3d->depths->dirty = 1; */
- ED_view3d_depth_update(data->vc.ar);
+ ED_view3d_depth_update(viewdata->vc.ar);
}
}
}
@@ -332,7 +332,7 @@ static bool hair_stroke_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
totsteps = delta_max / (0.2f * BKE_brush_size_get(scene, settings->brush)) + 1;
mul_v2_fl(mdelta, 1.0f / (float)totsteps);
- hair_set_view3d_data(C, &tool_data);
+ hair_init_viewdata(C, &tool_data.viewdata);
tool_data.scene = scene;
tool_data.ob = ob;
tool_data.edit = edit;
diff --git a/source/blender/editors/hair/hair_intern.h b/source/blender/editors/hair/hair_intern.h
index eb57c8b..7218fa0 100644
--- a/source/blender/editors/hair/hair_intern.h
+++ b/source/blender/editors/hair/hair_intern.h
@@ -49,14 +49,24 @@ void HAIR_OT_stroke(struct wmOperatorType *ot);
/* ==== Hair Brush ==== */
-typedef struct HairToolData {
- /* context */
+typedef struct HairViewData {
ViewContext vc;
bglMats mats;
+} HairViewData;
+
+void hair_init_viewdata(struct bContext *C, struct HairViewData *viewdata);
+
+bool hair_test_depth(struct HairViewData *viewdata, const float co[3], const int screen_co[2]);
+bool hair_test_inside_circle(struct HairViewData *viewdata, const float mval[2], float radsq,
+ struct BMVert *v, float *r_dist);
+
+typedef struct HairToolData {
+ /* context */
struct Scene *scene;
struct Object *ob;
struct BMEditStrands *edit;
struct HairEditSettings *settings;
+ HairViewData viewdata;
/* view space */
float mval[2]; /* mouse coordinates */
diff --git a/source/blender/editors/hair/hair_select.c b/source/blender/editors/hair/hair_select.c
new file mode 100644
index 0000000..1e7c664
--- /dev/null
+++ b/source/blender/editors/hair/hair_select.c
@@ -0,0 +1,142 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Lukas Toenne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/hair/hair_select.c
+ * \ingroup edhair
+ */
+
+#include <stdlib.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_view3d_types.h"
+
+#include "BKE_context.h"
+#include "BKE_depsgraph.h"
+#include "BKE_edithair.h"
+
+#include "bmesh.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_object.h"
+#include "ED_physics.h"
+#include "ED_view3d.h"
+
+#include "hair_intern.h"
+
+typedef bool (*TestVertexCb)(void *userdata, struct BMVert *v);
+
+static int hair_select_verts(BMEditStrands *edit, HairEditSelectMode select_mode, bool select, TestVertexCb cb, void *userdata)
+{
+ BMesh *bm = edit->bm;
+
+ BMVert *v;
+ BMIter iter;
+ int tot = 0;
+
+ bm->selectmode = BM_VERT;
+
+ switch (select_mode) {
+ case HAIR_SELECT_STRAND:
+ break;
+ case HAIR_SELECT_VERTEX:
+ BM_ITER_MESH(v, &iter, edit->bm, BM_VERTS_OF_MESH) {
+ if (BM_elem_flag_test_bool(v, BM_ELEM_SELECT) == select)
+ continue;
+ if (!cb(userdata, v))
+ continue;
+
+ BM_elem_flag_set(v, BM_ELEM_SELECT, select);
+ ++tot;
+ }
+ break;
+ case HAIR_SELECT_TIP:
+ BM_ITER_MESH(v, &iter, edit->bm, BM_VERTS_OF_MESH) {
+ if (BM_elem_flag_test_bool(v, BM_ELEM_SELECT) == select)
+ continue;
+ if (!BM_strands_vert_is_tip(v))
+ continue;
+ if (!cb(userdata, v))
+ continue;
+
+ BM_elem_flag_set(v, BM_ELEM_SELECT, select);
+ ++tot;
+ }
+ break;
+ }
+
+ BM_mesh_select_mode_flush(bm);
+
+ return tot;
+}
+
+/* ------------------------------------------------------------------------- */
+
+typedef struct TestVertexCirleData {
+ HairViewData viewdata;
+ float mval[2];
+ float radsq;
+} TestVertexCirleData;
+
+static bool test_vertex_circle(void *userdata, struct BMVert *v)
+{
+ TestVertexCirleData *data = userdata;
+ float dist;
+
+ return hair_test_inside_circle(&data->viewdata, data->mval, data->radsq, v, &dist);
+}
+
+int ED_hair_circle_select(bContext *C, bool select, const int mval[2], float radius)
+{
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = CTX_data_active_object(C);
+ BMEditStrands *edit = BKE_editstrands_from_object(ob);
+ HairEditSettings *settings = &scene->toolsettings->hair_edit;
+
+ TestVertexCirleData data;
+ int tot;
+
+ if (!edit)
+ return 0;
+
+ hair_init_viewdata(C, &data.viewdata);
+ data.mval[0] = mval[0];
+ data.mval[1] = mval[1];
+ data.radsq = radius * radius;
+
+ tot = hair_select_verts(edit, settings->select_mode, select, test_vertex_circle, &data);
+
+ return tot;
+}
diff --git a/source/blender/editors/hair/hair_stroke.c b/source/blender/editors/hair/hair_stroke.c
index 61cbd18..e7b095e 100644
--- a/source/blender/editors/hair/hair_stroke.c
+++ b/source/blender/editors/hair/hair_stroke.c
@@ -53,10 +53,10 @@
#include "hair_intern.h"
-BLI_INLINE bool test_depth(HairToolData *data, const float co[3], const int screen_co[2])
+bool hair_test_depth(HairViewData *viewdata, const float co[3], const int screen_co[2])
{
- View3D *v3d = data->vc.v3d;
- ViewDepths *vd = data->vc.rv3d->depths;
+ View3D *v3d = viewdata->vc.v3d;
+ ViewDepths *vd = viewdata->vc.rv3d->depths;
const bool has_zbuf = (v3d->drawtype > OB_WIRE) && (v3d->flag & V3D_ZBUF_SELECT);
double ux, uy, uz;
@@ -67,7 +67,7 @@ BLI_INLINE bool test_depth(HairToolData *data, const float co[3], const int scre
return true;
gluProject(co[0], co[1], co[2],
- data->mats.modelview, data->mats.projection, data->mats.viewport,
+ viewdata->mats.modelview, viewdata->mats.projection, viewdata->mats.viewport,
&ux, &uy, &uz);
/* check if screen_co is within bounds because brush_cut uses out of screen coords */
@@ -82,26 +82,27 @@ BLI_INLINE bool test_depth(HairToolData *data, const float co[3], const int scre
return false;
}
-BLI_INLINE bool test_inside_circle(HairToolData *data, BMVert *v, float radsq, float *r_dist)
+bool hair_test_inside_circle(HairViewData *viewdata, const float mval[2], float radsq, BMVert *v, float *r_dist)
{
+ float (*obmat)[4] = viewdata->vc.obact->obmat;
float co_world[3];
float dx, dy, distsq;
int screen_co[2];
- mul_v3_m4v3(co_world, data->ob->obmat, v->co);
+ mul_v3_m4v3(co_world, obmat, v->co);
/* TODO, should this check V3D_PROJ_TEST_CLIP_BB too? */
- if (ED_view3d_project_int_global(data->vc.ar, co_world, screen_co, V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_OK)
+ if (ED_view3d_project_int_global(viewdata->vc.ar, co_world, screen_co, V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_OK)
return false;
- dx = data->mval[0] - (float)screen_co[0];
- dy = data->mval[1] - (float)screen_co[1];
+ dx = mval[0] - (float)screen_co[0];
+ dy = mval[1] - (float)screen_co[1];
distsq = dx * dx + dy * dy;
if (distsq > radsq)
return false;
- if (test_depth(data, v->co, screen_co)) {
+ if (hair_test_depth(viewdata, v->co, screen_co)) {
*r_dist = sqrtf(distsq);
return true;
}
@@ -118,7 +119,7 @@ BLI_INLINE float factor_vertex(HairToolData *data, BMVert *v)
float dist;
- if (!test_inside_circle(data, v, radsq, &dist))
+ if (!hair_test_inside_circle(&data->viewdata, data->mval, radsq, v, &dist))
return 0.0f;
return 1.0f - dist / rad;
diff --git a/source/blender/editors/include/ED_physics.h b/source/blender/ed
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list