[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [45266] trunk/blender/source/blender/ modifiers/intern/MOD_array.c: Fix "First Last" merge option in array modifier (partial fix for bug 30195)

Nicholas Bishop nicholasbishop at gmail.com
Thu Mar 29 22:58:37 CEST 2012


Revision: 45266
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=45266
Author:   nicholasbishop
Date:     2012-03-29 20:58:25 +0000 (Thu, 29 Mar 2012)
Log Message:
-----------
Fix "First Last" merge option in array modifier (partial fix for bug 30195)

Modified Paths:
--------------
    trunk/blender/source/blender/modifiers/intern/MOD_array.c

Modified: trunk/blender/source/blender/modifiers/intern/MOD_array.c
===================================================================
--- trunk/blender/source/blender/modifiers/intern/MOD_array.c	2012-03-29 17:17:39 UTC (rev 45265)
+++ trunk/blender/source/blender/modifiers/intern/MOD_array.c	2012-03-29 20:58:25 UTC (rev 45266)
@@ -239,6 +239,7 @@
 	DerivedMesh *result;
 	BMEditMesh *em = DM_to_editbmesh(dm, NULL, FALSE);
 	BMOperator dupe_op, old_dupe_op, weld_op;
+	BMVert **first_geom = NULL;
 	int i, j, indexLen;
 	/* offset matrix */
 	float offset[4][4];
@@ -342,8 +343,8 @@
 	
 	for (j=0; j < count - 1; j++) {
 		BMVert *v, *v2, *v3;
-		BMOpSlot *s1;
-		BMOpSlot *s2;
+		BMOpSlot *geom_slot;
+		BMOpSlot *newout_slot;
 
 		if (j == 0)
 			BMO_op_initf(em->bm, &dupe_op, "dupe geom=%avef");
@@ -351,9 +352,18 @@
 			BMO_op_initf(em->bm, &dupe_op, "dupe geom=%s", &old_dupe_op, "newout");
 		BMO_op_exec(em->bm, &dupe_op);
 
-		s1 = BMO_slot_get(&dupe_op, "geom");
-		s2 = BMO_slot_get(&dupe_op, "newout");
+		geom_slot = BMO_slot_get(&dupe_op, "geom");
+		newout_slot = BMO_slot_get(&dupe_op, "newout");
 
+		if ((amd->flags & MOD_ARR_MERGEFINAL) && j == 0) {
+			int first_geom_bytes = sizeof(BMVert*) * geom_slot->len;
+				
+			/* make a copy of the initial geometry ordering so the
+			   last duplicate can be merged into it */
+			first_geom = MEM_mallocN(first_geom_bytes, "first_geom");
+			memcpy(first_geom, geom_slot->data.buf, first_geom_bytes);
+		}
+
 		BMO_op_callf(em->bm, "transform mat=%m4 verts=%s", offset, &dupe_op, "newout");
 
 		if (amd->flags & MOD_ARR_MERGE) {
@@ -366,13 +376,17 @@
 			#define _E(s, i) ((BMVert **)(s)->data.buf)[i]
 			/* generate merge mapping using index map.  we do this by using the
 			 * operator slots as lookup arrays.*/
-			#define E(i) (i) < s1->len ? _E(s1, i) : _E(s2, (i)-s1->len)
+			#define E(i) \
+				((i) < geom_slot->len ? \
+				 _E(geom_slot, i) :		\
+				 _E(newout_slot, (i)-geom_slot->len))
 
 			for (i=0; i<indexLen; i++) {
 				if (!indexMap[i]) continue;
 
-				v = E(i);
-				v2 = E(indexMap[i]-1);
+				/* merge v (from 'newout') into v2 (from old 'geom') */
+				v = _E(newout_slot, i - geom_slot->len);
+				v2 = _E(geom_slot, indexMap[i]-1);
 
 				/* check in case the target vertex (v2) is already marked
 				   for merging */
@@ -382,6 +396,24 @@
 				BMO_slot_map_ptr_insert(em->bm, &weld_op, "targetmap", v, v2);
 			}
 
+			if ((amd->flags & MOD_ARR_MERGEFINAL) && j == count - 2) {
+				/* special case for merging first and last */
+				for (i=0; i < indexLen; i++) {
+					if (!indexMap[i]) continue;
+
+					/* merge v (from 'newout') into v2 (from XXX) */
+					v = _E(newout_slot, indexMap[i]-1);
+					v2 = first_geom[i - geom_slot->len];
+
+					/* check in case the target vertex (v2) is already marked
+					   for merging */
+					while((v3 = BMO_slot_map_ptr_get(em->bm, &weld_op, "targetmap", v2)))
+						v2 = v3;
+
+					BMO_slot_map_ptr_insert(em->bm, &weld_op, "targetmap", v, v2);
+				}
+			}
+
 			#undef E
 			#undef _E
 		}
@@ -444,6 +476,8 @@
 	MEM_freeN(em);
 	if (indexMap)
 		MEM_freeN(indexMap);
+	if (first_geom)
+		MEM_freeN(first_geom);
 
 	return result;
 }




More information about the Bf-blender-cvs mailing list