[Bf-blender-cvs] [1b8240f] master: Fix T43154: Extrude edges ignored isolated verts

Campbell Barton noreply at git.blender.org
Thu Jan 8 21:35:01 CET 2015


Commit: 1b8240f5af34310017b9f245021e31e6b02ae3ce
Author: Campbell Barton
Date:   Fri Jan 9 05:23:08 2015 +1100
Branches: master
https://developer.blender.org/rB1b8240f5af34310017b9f245021e31e6b02ae3ce

Fix T43154: Extrude edges ignored isolated verts

Also cleanup extrude code.

- remove normal calculation.
- remove return values for transform type.
- use enums.

Thanks to Psy-fi for finding the initial fix.

===================================================================

M	source/blender/editors/mesh/editmesh_extrude.c

===================================================================

diff --git a/source/blender/editors/mesh/editmesh_extrude.c b/source/blender/editors/mesh/editmesh_extrude.c
index 3e40338..023f776 100644
--- a/source/blender/editors/mesh/editmesh_extrude.c
+++ b/source/blender/editors/mesh/editmesh_extrude.c
@@ -54,18 +54,6 @@
 
 #include "mesh_intern.h"  /* own include */
 
-/* allow accumulated normals to form a new direction but don't
- * accept direct opposite directions else they will cancel each other out */
-static void add_normal_aligned(float nor[3], const float add[3])
-{
-	if (dot_v3v3(nor, add) < -0.9999f) {
-		sub_v3_v3(nor, add);
-	}
-	else {
-		add_v3_v3(nor, add);
-	}
-}
-
 static void edbm_extrude_edge_exclude_mirror(
         Object *obedit, BMEditMesh *em,
         const char hflag,
@@ -137,7 +125,7 @@ static void edbm_extrude_edge_exclude_mirror(
 
 /* individual face extrude */
 /* will use vertex normals for extrusion directions, so *nor is unaffected */
-static short edbm_extrude_discrete_faces(BMEditMesh *em, wmOperator *op, const char hflag, float *UNUSED(nor))
+static bool edbm_extrude_discrete_faces(BMEditMesh *em, wmOperator *op, const char hflag)
 {
 	BMOIter siter;
 	BMIter liter;
@@ -165,14 +153,14 @@ static short edbm_extrude_discrete_faces(BMEditMesh *em, wmOperator *op, const c
 	}
 
 	if (!EDBM_op_finish(em, &bmop, op, true)) {
-		return 0;
+		return false;
 	}
 
-	return 's';  /* s is shrink/fatten */
+	return true;
 }
 
 /* extrudes individual edges */
-static short edbm_extrude_edges_indiv(BMEditMesh *em, wmOperator *op, const char hflag, float *UNUSED(nor))
+static bool edbm_extrude_edges_indiv(BMEditMesh *em, wmOperator *op, const char hflag)
 {
 	BMesh *bm = em->bm;
 	BMOperator bmop;
@@ -191,14 +179,14 @@ static short edbm_extrude_edges_indiv(BMEditMesh *em, wmOperator *op, const char
 	BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_VERT | BM_EDGE, BM_ELEM_SELECT, true);
 
 	if (!EDBM_op_finish(em, &bmop, op, true)) {
-		return 0;
+		return false;
 	}
 
-	return 'n';  /* n is normal grab */
+	return true;
 }
 
 /* extrudes individual vertices */
-static short edbm_extrude_verts_indiv(BMEditMesh *em, wmOperator *op, const char hflag, float *UNUSED(nor))
+static bool edbm_extrude_verts_indiv(BMEditMesh *em, wmOperator *op, const char hflag)
 {
 	BMOperator bmop;
 
@@ -214,27 +202,55 @@ static short edbm_extrude_verts_indiv(BMEditMesh *em, wmOperator *op, const char
 	BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "verts.out", BM_VERT, BM_ELEM_SELECT, true);
 
 	if (!EDBM_op_finish(em, &bmop, op, true)) {
-		return 0;
+		return false;
+	}
+
+	return true;
+}
+
+static char edbm_extrude_htype_from_em_select(BMEditMesh *em)
+{
+	char htype = BM_ALL_NOLOOP;
+
+	if (em->selectmode & SCE_SELECT_VERTEX) {
+		/* pass */
+	}
+	else if (em->selectmode & SCE_SELECT_EDGE) {
+		htype &= ~BM_VERT;
+	}
+	else {
+		htype &= ~(BM_VERT | BM_EDGE);
+	}
+
+	if (em->bm->totedgesel == 0) {
+		htype &= ~(BM_EDGE | BM_FACE);
+	}
+	else if (em->bm->totfacesel == 0) {
+		htype &= ~BM_FACE;
 	}
 
-	return 'g';  /* g is grab */
+	return htype;
 }
 
-static short edbm_extrude_edge_ex(
+static bool edbm_extrude_ex(
         Object *obedit, BMEditMesh *em,
-        const char hflag, float nor[3],
+        char htype, const char hflag,
         const bool use_mirror,
         const bool use_select_history)
 {
 	BMesh *bm = em->bm;
 	BMOIter siter;
 	BMOperator extop;
-	BMFace *f;
 	BMElem *ele;
 	
+	/* needed to remove the faces left behind */
+	if (htype & BM_FACE) {
+		htype |= BM_EDGE;
+	}
+
 	BMO_op_init(bm, &extop, BMO_FLAG_DEFAULTS, "extrude_face_region");
 	BMO_slot_bool_set(extop.slots_in, "use_select_history", use_select_history);
-	BMO_slot_buffer_from_enabled_hflag(bm, &extop, extop.slots_in, "geom", BM_VERT | BM_EDGE | BM_FACE, hflag);
+	BMO_slot_buffer_from_enabled_hflag(bm, &extop, extop.slots_in, "geom", htype, hflag);
 
 	if (use_mirror) {
 		BMOpSlot *slot_edges_exclude;
@@ -248,61 +264,14 @@ static short edbm_extrude_edge_ex(
 	BM_SELECT_HISTORY_RESTORE(bm);
 
 	BMO_op_exec(bm, &extop);
-
-	zero_v3(nor);
 	
-	BMO_ITER (ele, &siter, extop.slots_out, "geom.out", BM_ALL) {
+	BMO_ITER (ele, &siter, extop.slots_out, "geom.out", BM_ALL_NOLOOP) {
 		BM_elem_select_set(bm, ele, true);
-
-		if (ele->head.htype == BM_FACE) {
-			f = (BMFace *)ele;
-			add_normal_aligned(nor, f->no);
-		}
 	}
 
-	normalize_v3(nor);
-
 	BMO_op_finish(bm, &extop);
 
-	/* grab / normal constraint */
-	return is_zero_v3(nor) ? 'g' : 'n';
-}
-
-static short edbm_extrude_edge(
-        Object *obedit, BMEditMesh *em,
-        const char hflag, float nor[3])
-{
-	return edbm_extrude_edge_ex(obedit, em, hflag, nor, true, true);
-}
-
-static short edbm_extrude_vert(Object *obedit, BMEditMesh *em, const char hflag, float nor[3])
-{
-	BMIter iter;
-	BMEdge *eed;
-		
-	/* ensure vert flags are consistent for edge selections */
-	BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
-		if (BM_elem_flag_test(eed, hflag)) {
-			if (hflag & BM_ELEM_SELECT) {
-				BM_vert_select_set(em->bm, eed->v1, true);
-				BM_vert_select_set(em->bm, eed->v2, true);
-			}
-
-			BM_elem_flag_enable(eed->v1, hflag & ~BM_ELEM_SELECT);
-			BM_elem_flag_enable(eed->v2, hflag & ~BM_ELEM_SELECT);
-		}
-		else {
-			if (BM_elem_flag_test(eed->v1, hflag) && BM_elem_flag_test(eed->v2, hflag)) {
-				if (hflag & BM_ELEM_SELECT) {
-					BM_edge_select_set(em->bm, eed, true);
-				}
-
-				BM_elem_flag_enable(eed, hflag & ~BM_ELEM_SELECT);
-			}
-		}
-	}
-
-	return edbm_extrude_edge(obedit, em, hflag, nor);
+	return true;
 }
 
 static int edbm_extrude_repeat_exec(bContext *C, wmOperator *op)
@@ -314,7 +283,7 @@ static int edbm_extrude_repeat_exec(bContext *C, wmOperator *op)
 	const int steps = RNA_int_get(op->ptr, "steps");
 	
 	const float offs = RNA_float_get(op->ptr, "offset");
-	float dvec[3], tmat[3][3], bmat[3][3], nor[3] = {0.0, 0.0, 0.0};
+	float dvec[3], tmat[3][3], bmat[3][3];
 	short a;
 
 	/* dvec */
@@ -327,7 +296,7 @@ static int edbm_extrude_repeat_exec(bContext *C, wmOperator *op)
 	mul_m3_v3(tmat, dvec);
 
 	for (a = 0; a < steps; a++) {
-		edbm_extrude_edge_ex(obedit, em, BM_ELEM_SELECT, nor, false, false);
+		edbm_extrude_ex(obedit, em, BM_ALL_NOLOOP, BM_ELEM_SELECT, false, false);
 
 		BMO_op_callf(
 		        em->bm, BMO_FLAG_DEFAULTS,
@@ -362,87 +331,62 @@ void MESH_OT_extrude_repeat(wmOperatorType *ot)
 }
 
 /* generic extern called extruder */
-static int edbm_extrude_mesh(Scene *scene, Object *obedit, BMEditMesh *em, wmOperator *op, float *norin)
+static bool edbm_extrude_mesh(Object *obedit, BMEditMesh *em, wmOperator *op)
 {
-	short nr, transmode = 0;
-	float stacknor[3] = {0.0f, 0.0f, 0.0f};
-	float *nor = norin ? norin : stacknor;
-
-	zero_v3(nor);
+	bool changed = false;
+	const char htype = edbm_extrude_htype_from_em_select(em);
+	enum {NONE = 0, ELEM_FLAG, VERT_ONLY, EDGE_ONLY, FACE_ONLY} nr;
 
 	if (em->selectmode & SCE_SELECT_VERTEX) {
-		if (em->bm->totvertsel == 0) nr = 0;
-		else if (em->bm->totvertsel == 1) nr = 4;
-		else if (em->bm->totedgesel == 0) nr = 4;
-		else if (em->bm->totfacesel == 0)
-			nr = 3;
-		else if (em->bm->totfacesel == 1)
-			nr = 1;
-		else
-			nr = 1;
+		if      (em->bm->totvertsel == 0) nr = NONE;
+		else if (em->bm->totvertsel == 1) nr = VERT_ONLY;
+		else if (em->bm->totedgesel == 0) nr = VERT_ONLY;
+		else                              nr = ELEM_FLAG;
 	}
 	else if (em->selectmode & SCE_SELECT_EDGE) {
-		if (em->bm->totedgesel == 0) nr = 0;
-		
-		nr = 1;
+		if      (em->bm->totedgesel == 0) nr = NONE;
+		else if (em->bm->totfacesel == 0) nr = EDGE_ONLY;
+		else                              nr = ELEM_FLAG;
 	}
 	else {
-		if (em->bm->totfacesel == 0) nr = 0;
-		else if (em->bm->totfacesel == 1) nr = 1;
-		else
-			nr = 1;
+		if      (em->bm->totfacesel == 0) nr = NONE;
+		else if (em->bm->totfacesel == 1) nr = FACE_ONLY;
+		else                              nr = ELEM_FLAG;
 	}
 
-	if (nr < 1) return 'g';
-
-	if (nr == 1 && (em->selectmode & SCE_SELECT_VERTEX))
-		transmode = edbm_extrude_vert(obedit, em, BM_ELEM_SELECT, nor);
-	else if (nr == 1) transmode = edbm_extrude_edge(obedit, em, BM_ELEM_SELECT, nor);
-	else if (nr == 4) transmode = edbm_extrude_verts_indiv(em, op, BM_ELEM_SELECT, nor);
-	else if (nr == 3) transmode = edbm_extrude_edges_indiv(em, op, BM_ELEM_SELECT, nor);
-	else transmode = edbm_extrude_discrete_faces(em, op, BM_ELEM_SELECT, nor);
+	switch (nr) {
+		case NONE:
+			return false;
+		case ELEM_FLAG:
+			changed = edbm_extrude_ex(obedit, em, htype, BM_ELEM_SELECT, true, true);
+			break;
+		case VERT_ONLY:
+			changed = edbm_extrude_verts_indiv(em, op, BM_ELEM_SELECT);
+			break;
+		case EDGE_ONLY:
+			changed = edbm_extrude_edges_indiv(em, op, BM_ELEM_SELECT);
+			break;
+		case FACE_ONLY:
+			changed = edbm_extrude_discrete_faces(em, op, BM_ELEM_SELECT);
+			break;
+	}
 	
-	if (transmode == 0) {
-		BKE_report(op->reports, RPT_ERROR, "Not a valid selection for extrude");
+	if (changed) {
+		return true;
 	}
 	else {
-		
-		/* We need to force immediate calculation here because
-		 * transform may use derived objects (which are now stale).
-		 *
-		 * This shouldn't be necessary, derived queries should be
-		 * automatically building this data if invalid. Or something.
-		 */
-//		DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-		BKE_object_handle_update(G.main->eval_ctx, scene, obedit);
-
-		/* individual faces? */
-		if (nr == 2) {
-//			initTransform(TFM_SHRINKFATTEN, CTX_NO_PET|CTX_NO_MIRROR);
-//			Transform();
-		}
-		else {
-//			initTransform(TFM_TRANSLATION, CTX_NO_PET|CTX_NO_MIRROR);
-			if (transmode == 'n') {
-				mul_m4_v3(obedit->obmat, nor);
-				sub_v3_v3v3(nor, nor, obedit->obmat[3]);
-//				BIF_setSingleAxisConstraint(nor, "along normal");
-			}
-//			Transform();
-		}
+		BKE_report(op->reports, RPT_ERROR, "Not a valid selection for extrude");
+		return false;
 	}
-	
-	return transmode;
 }
 
 /* extrude without transform */
 static int edbm_extrude_region_exec(bContext *C, wmOperator *op)
 {
-	Scene *scene = CTX_data_scene(C);
 	Object *obedit = CTX_data_edit_object(C);
 	BMEditMesh *em = BKE_editmesh_from_object(obedit);
 	
-	edbm_extrude_mesh(scene, obedit, em, op, NULL);
+	edbm_extrude_mesh(obedit, em, op);
 
 	/

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list