[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [55878] trunk/blender/source/blender: Mesh Tool,

Campbell Barton ideasman42 at gmail.com
Sun Apr 7 13:41:38 CEST 2013


Revision: 55878
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=55878
Author:   campbellbarton
Date:     2013-04-07 11:41:37 +0000 (Sun, 07 Apr 2013)
Log Message:
-----------
Mesh Tool,
inset interpolation now works for 'inset_region', enabled by default.

Example:
http://www.graphicall.org/ftp/ideasman42/inset_interpolation_new.png

Modified Paths:
--------------
    trunk/blender/source/blender/bmesh/intern/bmesh_interp.c
    trunk/blender/source/blender/bmesh/intern/bmesh_interp.h
    trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c
    trunk/blender/source/blender/bmesh/operators/bmo_inset.c
    trunk/blender/source/blender/editors/mesh/editmesh_inset.c

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_interp.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_interp.c	2013-04-07 11:22:54 UTC (rev 55877)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_interp.c	2013-04-07 11:41:37 UTC (rev 55878)
@@ -167,6 +167,29 @@
  *
  * \note Only handles loop customdata. multires is handled.
  */
+void BM_face_interp_from_face_ex(BMesh *bm, BMFace *target, BMFace *source,
+                                 void **blocks, float (*cos_2d)[2], float axis_mat[3][3])
+{
+	BMLoop *l_iter;
+	BMLoop *l_first;
+
+	float *w = BLI_array_alloca(w, source->len);
+	float co[2];
+	int i;
+
+	if (source != target)
+		BM_elem_attrs_copy(bm, bm, source, target);
+
+	/* interpolate */
+	i = 0;
+	l_iter = l_first = BM_FACE_FIRST_LOOP(target);
+	do {
+		mul_v2_m3v3(co, axis_mat, l_iter->v->co);
+		interp_weights_poly_v2(w, cos_2d, source->len, co);
+		CustomData_bmesh_interp(&bm->ldata, blocks, w, NULL, source->len, l_iter->head.data);
+	} while (i++, (l_iter = l_iter->next) != l_first);
+}
+
 void BM_face_interp_from_face(BMesh *bm, BMFace *target, BMFace *source)
 {
 	BMLoop *l_iter;
@@ -176,14 +199,11 @@
 	float (*cos_2d)[2] = BLI_array_alloca(cos_2d, source->len);
 	float *w        = BLI_array_alloca(w,      source->len);
 	float axis_mat[3][3];  /* use normal to transform into 2d xy coords */
-	float co[2];
 	int i;
 
 	/* convert the 3d coords into 2d for projection */
 	axis_dominant_v3_to_m3(axis_mat, source->no);
 
-	BM_elem_attrs_copy(bm, bm, source, target);
-
 	i = 0;
 	l_iter = l_first = BM_FACE_FIRST_LOOP(source);
 	do {
@@ -191,14 +211,8 @@
 		blocks[i] = l_iter->head.data;
 	} while (i++, (l_iter = l_iter->next) != l_first);
 
-	/* interpolate */
-	i = 0;
-	l_iter = l_first = BM_FACE_FIRST_LOOP(target);
-	do {
-		mul_v2_m3v3(co, axis_mat, l_iter->v->co);
-		interp_weights_poly_v2(w, cos_2d, source->len, co);
-		CustomData_bmesh_interp(&bm->ldata, blocks, w, NULL, source->len, l_iter->head.data);
-	} while (i++, (l_iter = l_iter->next) != l_first);
+	BM_face_interp_from_face_ex(bm, target, source,
+	                            blocks, cos_2d, axis_mat);
 }
 
 /**

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_interp.h
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_interp.h	2013-04-07 11:22:54 UTC (rev 55877)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_interp.h	2013-04-07 11:41:37 UTC (rev 55878)
@@ -42,6 +42,8 @@
 float BM_elem_float_data_get(CustomData *cd, void *element, int type);
 void  BM_elem_float_data_set(CustomData *cd, void *element, int type, const float val);
 
+void BM_face_interp_from_face_ex(BMesh *bm, BMFace *target, BMFace *source,
+                                 void **blocks, float (*cos_2d)[2], float axis_mat[3][3]);
 void  BM_face_interp_from_face(BMesh *bm, BMFace *target, BMFace *source);
 void  BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source,
                               const bool do_vertex, const bool do_multires);

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c	2013-04-07 11:22:54 UTC (rev 55877)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c	2013-04-07 11:41:37 UTC (rev 55878)
@@ -1533,6 +1533,7 @@
 	{{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
 	 {"use_boundary", BMO_OP_SLOT_BOOL},
 	 {"use_even_offset", BMO_OP_SLOT_BOOL},
+	 {"use_interpolate", BMO_OP_SLOT_BOOL},
 	 {"use_relative_offset", BMO_OP_SLOT_BOOL},
 	 {"thickness", BMO_OP_SLOT_FLT},
 	 {"depth", BMO_OP_SLOT_FLT},

Modified: trunk/blender/source/blender/bmesh/operators/bmo_inset.c
===================================================================
--- trunk/blender/source/blender/bmesh/operators/bmo_inset.c	2013-04-07 11:22:54 UTC (rev 55877)
+++ trunk/blender/source/blender/bmesh/operators/bmo_inset.c	2013-04-07 11:41:37 UTC (rev 55878)
@@ -32,6 +32,8 @@
 
 #include "BLI_math.h"
 #include "BLI_array.h"
+#include "BLI_memarena.h"
+#include "BKE_customdata.h"
 
 #include "bmesh.h"
 
@@ -243,7 +245,60 @@
 	BMLoop *l;
 } SplitEdgeInfo;
 
+
 /**
+ * Interpolation, this is more complex for regions since we're not creating new faces
+ * and throwing away old ones, so instead, store face data needed for interpolation.
+ *
+ * \note This uses CustomData functions in quite a low-level way which should be
+ * avoided, but in this case its hard to do without storing a duplicate mesh. */
+
+/* just enough of a face to store interpolation data we can use once the inset is done */
+typedef struct InterpFace {
+	BMFace *f;
+	void **blocks;
+	float (*cos_2d)[2];
+	float axis_mat[3][3];
+} InterpFace;
+
+/* basically a clone of #BM_vert_interp_from_face */
+static void bm_interp_face_store(InterpFace *iface, BMesh *bm, BMFace *f, MemArena *interp_arena)
+{
+	BMLoop *l_iter, *l_first;
+	void **blocks      = iface->blocks = BLI_memarena_alloc(interp_arena, sizeof(*iface->blocks) * f->len);
+	float (*cos_2d)[2] = iface->cos_2d = BLI_memarena_alloc(interp_arena, sizeof(*iface->cos_2d) * f->len);
+	void *axis_mat     = iface->axis_mat;
+	int i;
+
+	axis_dominant_v3_to_m3(axis_mat, f->no);
+
+	iface->f = f;
+
+	i = 0;
+	l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+	do {
+		mul_v2_m3v3(cos_2d[i], axis_mat, l_iter->v->co);
+		blocks[i] = NULL;
+		CustomData_bmesh_copy_data(&bm->ldata, &bm->ldata, l_iter->head.data, &blocks[i]);
+		/* if we were not modifying the loops later we would do... */
+		// blocks[i] = l_iter->head.data;
+
+		/* use later for index lookups */
+		BM_elem_index_set(l_iter, i); /* set_ok */
+	} while (i++, (l_iter = l_iter->next) != l_first);
+}
+static void bm_interp_face_free(InterpFace *iface, BMesh *bm)
+{
+	void **blocks = iface->blocks;
+	int i;
+
+	for (i = 0; i < iface->f->len; i++) {
+		CustomData_bmesh_free_block(&bm->ldata, &blocks[i]);
+	}
+}
+
+
+/**
  * return the tag loop where there is...
  * - only 1 tagged face attached to this edge.
  * - 1 or more untagged faces.
@@ -298,6 +353,7 @@
 	const bool use_even_offset     = BMO_slot_bool_get(op->slots_in, "use_even_offset");
 	const bool use_even_boundry    = use_even_offset; /* could make own option */
 	const bool use_relative_offset = BMO_slot_bool_get(op->slots_in, "use_relative_offset");
+	const bool use_interpolate     = BMO_slot_bool_get(op->slots_in, "use_interpolate");
 	const float thickness          = BMO_slot_float_get(op->slots_in, "thickness");
 	const float depth              = BMO_slot_float_get(op->slots_in, "depth");
 
@@ -307,11 +363,24 @@
 	SplitEdgeInfo *edge_info;
 	SplitEdgeInfo *es;
 
+	/* Interpolation Vars */
+	/* an array alligned with faces but only fill items which are used. */
+	InterpFace **iface_array = NULL;
+	int          iface_array_len;
+	MemArena *interp_arena = NULL;
+
 	BMVert *v;
 	BMEdge *e;
 	BMFace *f;
 	int i, j, k;
 
+	if (use_interpolate) {
+		interp_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
+		/* warning, we could be more clever here and not over alloc */
+		iface_array = MEM_callocN(sizeof(*iface_array) * bm->totface, __func__);
+		iface_array_len = bm->totface;
+	}
+
 	if (use_outset == false) {
 		BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, false);
 		BMO_slot_buffer_hflag_enable(bm, op->slots_in, "faces", BM_FACE, BM_ELEM_TAG, false);
@@ -392,9 +461,22 @@
 		/* important to tag again here */
 		BM_elem_flag_enable(es->e_new->v1, BM_ELEM_TAG);
 		BM_elem_flag_enable(es->e_new->v2, BM_ELEM_TAG);
+
+
+		/* initialize interpolation vars */
+		/* this could go in its own loop,
+		 * only use the 'es->l->f' so we don't store loops for faces which have no mixed selection */
+		if (use_interpolate) {
+			const int j = BM_elem_index_get((f = es->l->f));
+			if (iface_array[j] == NULL) {
+				InterpFace *iface = BLI_memarena_alloc(interp_arena, sizeof(*iface));
+				bm_interp_face_store(iface, bm, f, interp_arena);
+				iface_array[j] = iface;
+			}
+		}
+		/* done interpolation */
 	}
 
-
 	/* show edge normals for debugging */
 #if 0
 	for (i = 0, es = edge_info; i < edge_info_len; i++, es++) {
@@ -638,6 +720,16 @@
 		}
 	}
 
+	if (use_interpolate) {
+		for (i = 0; i < iface_array_len; i++) {
+			if (iface_array[i]) {
+				InterpFace *iface = iface_array[i];
+				BM_face_interp_from_face_ex(bm, iface->f, iface->f,
+				                            iface->blocks, iface->cos_2d, iface->axis_mat);
+			}
+		}
+	}
+
 	/* create faces */
 	for (i = 0, es = edge_info; i < edge_info_len; i++, es++) {
 		BMVert *varr[4] = {NULL};
@@ -704,10 +796,30 @@
 			l_b = l_a->next;
 
 			/* swap a<->b intentionally */
-			BM_elem_attrs_copy(bm, bm, l_a_other, l_b);
-			BM_elem_attrs_copy(bm, bm, l_b_other, l_a);
+			if (use_interpolate) {
+				InterpFace *iface = iface_array[BM_elem_index_get(es->l->f)];
+				const int i_a = BM_elem_index_get(l_a_other);
+				const int i_b = BM_elem_index_get(l_b_other);
+				CustomData_bmesh_copy_data(&bm->ldata, &bm->ldata, iface->blocks[i_a], &l_b->head.data);
+				CustomData_bmesh_copy_data(&bm->ldata, &bm->ldata, iface->blocks[i_b], &l_a->head.data);
+			}
+			else {
+				BM_elem_attrs_copy(bm, bm, l_a_other, l_b);
+				BM_elem_attrs_copy(bm, bm, l_b_other, l_a);
+			}
 		}
+	}
 #endif
+
+	if (use_interpolate) {
+		for (i = 0; i < iface_array_len; i++) {
+			if (iface_array[i]) {
+				bm_interp_face_free(iface_array[i], bm);
+			}
+		}
+
+		BLI_memarena_free(interp_arena);
+		MEM_freeN(iface_array);
 	}
 
 	/* we could flag new edges/verts too, is it useful? */

Modified: trunk/blender/source/blender/editors/mesh/editmesh_inset.c
===================================================================
--- trunk/blender/source/blender/editors/mesh/editmesh_inset.c	2013-04-07 11:22:54 UTC (rev 55877)
+++ trunk/blender/source/blender/editors/mesh/editmesh_inset.c	2013-04-07 11:41:37 UTC (rev 55878)
@@ -209,9 +209,9 @@
 	}
 	else {
 		EDBM_op_init(em, &bmop, op,
-		             "inset_region faces=%hf use_boundary=%b use_even_offset=%b use_relative_offset=%b "
-		             "thickness=%f depth=%f use_outset=%b",
-		             BM_ELEM_SELECT, use_boundary, use_even_offset, use_relative_offset,
+		             "inset_region faces=%hf use_boundary=%b use_even_offset=%b use_relative_offset=%b"
+		             " use_interpolate=%b thickness=%f depth=%f use_outset=%b",

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list