[Bf-blender-cvs] [f225743] hair_immediate_fixes: First selection operator implementation for hair edit: circle select.

Lukas Tönne noreply at git.blender.org
Sat Dec 27 11:32:36 CET 2014


Commit: f225743744693c9993dbb3034d84f5f178ffa1b8
Author: Lukas Tönne
Date:   Thu Dec 4 17:15:46 2014 +0100
Branches: hair_immediate_fixes
https://developer.blender.org/rBf225743744693c9993dbb3034d84f5f178ffa1b8

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