[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [55614] trunk/blender/source/blender/bmesh /intern: api cleanup: split part of BM_face_create_ngon_vcloud() into a new function BM_face_create_ngon_verts(),

Campbell Barton ideasman42 at gmail.com
Wed Mar 27 06:52:29 CET 2013


Revision: 55614
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=55614
Author:   campbellbarton
Date:     2013-03-27 05:52:28 +0000 (Wed, 27 Mar 2013)
Log Message:
-----------
api cleanup: split part of BM_face_create_ngon_vcloud() into a new function BM_face_create_ngon_verts(),
a function to create a bmesh face from an ordered vertex array, optionally creating edges and calculating winding.

Modified Paths:
--------------
    trunk/blender/source/blender/bmesh/intern/bmesh_construct.c
    trunk/blender/source/blender/bmesh/intern/bmesh_construct.h
    trunk/blender/source/blender/bmesh/intern/bmesh_core.c

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_construct.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_construct.c	2013-03-27 04:41:20 UTC (rev 55613)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_construct.c	2013-03-27 05:52:28 UTC (rev 55614)
@@ -171,7 +171,7 @@
  * #BM_face_create should be considered over this function as it
  * avoids some unnecessary work.
  */
-BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, int len, const int create_flag)
+BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, const int len, const int create_flag)
 {
 	BMEdge **edges_sort = BLI_array_alloca(edges_sort, len);
 	BMVert **verts_sort = BLI_array_alloca(verts_sort, len + 1);
@@ -308,6 +308,72 @@
 	return NULL;
 }
 
+/**
+ * Create an ngon from an array of sorted verts
+ *
+ * Special features this has over other functions.
+ * - Optionally calculate winding based on surrounding edges.
+ * - Optionally create edges between vertices.
+ * - Uses verts so no need to find edges (handy when you only have verts)
+ */
+BMFace *BM_face_create_ngon_verts(BMesh *bm, BMVert **vert_arr, const int len, const int create_flag,
+                                  const bool calc_winding, const bool create_edges)
+{
+	BMEdge **edge_arr = BLI_array_alloca(edge_arr, len);
+	unsigned int winding[2] = {0, 0};
+	int i, i_prev = len - 1;
+
+	BLI_assert(len > 2);
+
+	for (i = 0; i < len; i++) {
+		if (create_edges) {
+			edge_arr[i] = BM_edge_create(bm, vert_arr[i_prev], vert_arr[i], NULL, BM_CREATE_NO_DOUBLE);
+		}
+		else {
+			edge_arr[i] = BM_edge_exists(vert_arr[i_prev], vert_arr[i]);
+			if (edge_arr[i] == NULL) {
+				return NULL;
+			}
+		}
+
+		if (calc_winding) {
+			/* the edge may exist already and be attached to a face
+			 * in this case we can find the best winding to use for the new face */
+			if (edge_arr[i]->l) {
+				BMVert *test_v1, *test_v2;
+				/* we want to use the reverse winding to the existing order */
+				BM_edge_ordered_verts(edge_arr[i], &test_v2, &test_v1);
+				winding[(vert_arr[i_prev] == test_v2)]++;
+			}
+		}
+
+		i_prev = i;
+	}
+
+	/* --- */
+
+	if (calc_winding) {
+		if (winding[0] < winding[1]) {
+			winding[0] = 1;
+			winding[1] = 0;
+		}
+		else {
+			winding[0] = 0;
+			winding[1] = 1;
+		}
+	}
+	else {
+		winding[0] = 0;
+		winding[1] = 1;
+	}
+
+	/* --- */
+
+	/* create the face */
+	return BM_face_create_ngon(bm, vert_arr[winding[0]], vert_arr[winding[1]], edge_arr, len, create_flag);
+}
+
+
 typedef struct AngleIndexPair {
 	float angle;
 	int index;
@@ -337,11 +403,11 @@
  *
  * \note Since this is a vcloud there is no direction.
  */
-BMFace *BM_face_create_ngon_vcloud(BMesh *bm, BMVert **vert_arr, int totv, const int create_flag)
+BMFace *BM_face_create_ngon_vcloud(BMesh *bm, BMVert **vert_arr, int len, const int create_flag)
 {
 	BMFace *f;
 
-	float totv_inv = 1.0f / (float)totv;
+	float totv_inv = 1.0f / (float)len;
 	int i = 0;
 
 	float cent[3], nor[3];
@@ -358,21 +424,17 @@
 	AngleIndexPair *vang;
 
 	BMVert **vert_arr_map;
-	BMEdge **edge_arr;
-	int i_prev;
 
-	unsigned int winding[2] = {0, 0};
-
 	/* get the center point and collect vector array since we loop over these a lot */
 	zero_v3(cent);
-	for (i = 0; i < totv; i++) {
+	for (i = 0; i < len; i++) {
 		madd_v3_v3fl(cent, vert_arr[i]->co, totv_inv);
 	}
 
 
 	/* find the far point from cent */
 	far_best = 0.0f;
-	for (i = 0; i < totv; i++) {
+	for (i = 0; i < len; i++) {
 		far_dist = len_squared_v3v3(vert_arr[i]->co, cent);
 		if (far_dist > far_best || far == NULL) {
 			far = vert_arr[i]->co;
@@ -387,7 +449,7 @@
 
 	/* find a point 90deg about to compare with */
 	far_cross_best = 0.0f;
-	for (i = 0; i < totv; i++) {
+	for (i = 0; i < len; i++) {
 
 		if (far == vert_arr[i]->co) {
 			continue;
@@ -422,9 +484,9 @@
 	/* --- */
 
 	/* now calculate every points angle around the normal (signed) */
-	vang = MEM_mallocN(sizeof(AngleIndexPair) * totv, __func__);
+	vang = MEM_mallocN(sizeof(AngleIndexPair) * len, __func__);
 
-	for (i = 0; i < totv; i++) {
+	for (i = 0; i < len; i++) {
 		float co[3];
 		float proj_vec[3];
 		float angle;
@@ -448,53 +510,20 @@
 	}
 
 	/* sort by angle and magic! - we have our ngon */
-	qsort(vang, totv, sizeof(AngleIndexPair), angle_index_pair_cmp);
+	qsort(vang, len, sizeof(AngleIndexPair), angle_index_pair_cmp);
 
 	/* --- */
 
 	/* create edges and find the winding (if faces are attached to any existing edges) */
-	vert_arr_map = MEM_mallocN(sizeof(BMVert **) * totv, __func__);
-	edge_arr = MEM_mallocN(sizeof(BMEdge **) * totv, __func__);
+	vert_arr_map = MEM_mallocN(sizeof(BMVert **) * len, __func__);
 
-	for (i = 0; i < totv; i++) {
+	for (i = 0; i < len; i++) {
 		vert_arr_map[i] = vert_arr[vang[i].index];
 	}
 	MEM_freeN(vang);
 
-	i_prev = totv - 1;
-	for (i = 0; i < totv; i++) {
-		edge_arr[i] = BM_edge_create(bm, vert_arr_map[i_prev], vert_arr_map[i], NULL, BM_CREATE_NO_DOUBLE);
+	f = BM_face_create_ngon_verts(bm, vert_arr_map, len, create_flag, true, true);
 
-		/* the edge may exist already and be attached to a face
-		 * in this case we can find the best winding to use for the new face */
-		if (edge_arr[i]->l) {
-			BMVert *test_v1, *test_v2;
-			/* we want to use the reverse winding to the existing order */
-			BM_edge_ordered_verts(edge_arr[i], &test_v2, &test_v1);
-			winding[(vert_arr_map[i_prev] == test_v2)]++;
-
-		}
-
-		i_prev = i;
-	}
-
-	/* --- */
-
-	if (winding[0] < winding[1]) {
-		winding[0] = 1;
-		winding[1] = 0;
-	}
-	else {
-		winding[0] = 0;
-		winding[1] = 1;
-	}
-
-	/* --- */
-
-	/* create the face */
-	f = BM_face_create_ngon(bm, vert_arr_map[winding[0]], vert_arr_map[winding[1]], edge_arr, totv, create_flag);
-
-	MEM_freeN(edge_arr);
 	MEM_freeN(vert_arr_map);
 
 	return f;

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_construct.h
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_construct.h	2013-03-27 04:41:20 UTC (rev 55613)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_construct.h	2013-03-27 05:52:28 UTC (rev 55614)
@@ -36,7 +36,9 @@
 
 void BM_face_copy_shared(BMesh *bm, BMFace *f);
 
-BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, int len, const int create_flag);
+BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, const int len, const int create_flag);
+BMFace *BM_face_create_ngon_verts(BMesh *bm, BMVert **vert_arr, const int len, const int create_flag,
+                                  const bool calc_winding, const bool create_edges);
 
 BMFace *BM_face_create_ngon_vcloud(BMesh *bm, BMVert **vert_arr, int len, const int create_flag);
 

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_core.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_core.c	2013-03-27 04:41:20 UTC (rev 55613)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_core.c	2013-03-27 05:52:28 UTC (rev 55614)
@@ -308,7 +308,13 @@
 }
 
 /**
- * \brief Main face creation function
+ * Main face creation function
+ *
+ * \param bm  The mesh
+ * \param verts  A sorted array of verts size of len
+ * \param edges  A sorted array of edges size of len
+ * \param len  Length of the face
+ * \param create_flag  Options for creating the face
  */
 BMFace *BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len, const eBMCreateFlag create_flag)
 {




More information about the Bf-blender-cvs mailing list