[Bf-blender-cvs] [7b03eb5] master: Fix T39109: Vertices affected by Hook Modifiers change after "switch Direction" on Curves

Sergey Sharybin noreply at git.blender.org
Wed Mar 12 10:47:11 CET 2014


Commit: 7b03eb56bdc61150681bc6bc29f41160923096a6
Author: Sergey Sharybin
Date:   Wed Mar 12 15:46:24 2014 +0600
https://developer.blender.org/rB7b03eb56bdc61150681bc6bc29f41160923096a6

Fix T39109: Vertices affected by Hook Modifiers change after "switch Direction" on Curves

Remapping hooks and vertex parent wasn't implemented for curves.

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

M	source/blender/editors/curve/editcurve.c

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

diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index e50ba2c..6ea7cbd 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -55,6 +55,7 @@
 #include "BKE_report.h"
 #include "BKE_animsys.h"
 #include "BKE_action.h"
+#include "BKE_modifier.h"
 
 #include "WM_api.h"
 #include "WM_types.h"
@@ -89,8 +90,8 @@ typedef struct {
 /* Definitions needed for shape keys */
 typedef struct {
 	void *orig_cv;
-	int key_index, nu_index, pt_index;
-	int switched;
+	int key_index, nu_index, pt_index, vertex_index;
+	bool switched;
 	Nurb *orig_nu;
 } CVKeyIndex;
 
@@ -254,7 +255,7 @@ void printknots(Object *obedit)
 
 /* ********************* Shape keys *************** */
 
-static CVKeyIndex *init_cvKeyIndex(void *cv, int key_index, int nu_index, int pt_index, Nurb *orig_nu)
+static CVKeyIndex *init_cvKeyIndex(void *cv, int key_index, int nu_index, int pt_index, int vertex_index, Nurb *orig_nu)
 {
 	CVKeyIndex *cvIndex = MEM_callocN(sizeof(CVKeyIndex), "init_cvKeyIndex");
 
@@ -262,7 +263,8 @@ static CVKeyIndex *init_cvKeyIndex(void *cv, int key_index, int nu_index, int pt
 	cvIndex->key_index = key_index;
 	cvIndex->nu_index = nu_index;
 	cvIndex->pt_index = pt_index;
-	cvIndex->switched = 0;
+	cvIndex->vertex_index = vertex_index;
+	cvIndex->switched = false;
 	cvIndex->orig_nu = orig_nu;
 
 	return cvIndex;
@@ -276,7 +278,7 @@ static void init_editNurb_keyIndex(EditNurb *editnurb, ListBase *origBase)
 	BezTriple *bezt, *origbezt;
 	BPoint *bp, *origbp;
 	CVKeyIndex *keyIndex;
-	int a, key_index = 0, nu_index = 0, pt_index = 0;
+	int a, key_index = 0, nu_index = 0, pt_index = 0, vertex_index = 0;
 
 	if (editnurb->keyindex) return;
 
@@ -289,9 +291,10 @@ static void init_editNurb_keyIndex(EditNurb *editnurb, ListBase *origBase)
 			origbezt = orignu->bezt;
 			pt_index = 0;
 			while (a--) {
-				keyIndex = init_cvKeyIndex(origbezt, key_index, nu_index, pt_index, orignu);
+				keyIndex = init_cvKeyIndex(origbezt, key_index, nu_index, pt_index, vertex_index, orignu);
 				BLI_ghash_insert(gh, bezt, keyIndex);
 				key_index += 12;
+				vertex_index += 3;
 				bezt++;
 				origbezt++;
 				pt_index++;
@@ -303,12 +306,13 @@ static void init_editNurb_keyIndex(EditNurb *editnurb, ListBase *origBase)
 			origbp = orignu->bp;
 			pt_index = 0;
 			while (a--) {
-				keyIndex = init_cvKeyIndex(origbp, key_index, nu_index, pt_index, orignu);
+				keyIndex = init_cvKeyIndex(origbp, key_index, nu_index, pt_index, vertex_index, orignu);
 				BLI_ghash_insert(gh, bp, keyIndex);
 				key_index += 4;
 				bp++;
 				origbp++;
 				pt_index++;
+				vertex_index++;
 			}
 		}
 
@@ -1161,6 +1165,144 @@ int ED_curve_updateAnimPaths(Curve *cu)
 
 /* ********************* LOAD and MAKE *************** */
 
+static int *initialize_index_map(Object *obedit, int *old_totvert_r)
+{
+	Curve *curve = (Curve *) obedit->data;
+	EditNurb *editnurb = curve->editnurb;
+	Nurb *nu;
+	CVKeyIndex *keyIndex;
+	int *old_to_new_map;
+	int old_totvert, i;
+	int vertex_index;
+
+	for (nu = curve->nurb.first, old_totvert = 0; nu != NULL; nu = nu->next) {
+		if (nu->bezt) {
+			old_totvert += nu->pntsu * 3;
+		}
+		else {
+			old_totvert += nu->pntsu * nu->pntsv;
+		}
+	}
+
+	old_to_new_map = MEM_mallocN(old_totvert * sizeof(int), "curve old to new index map");
+	for (i = 0; i < old_totvert; i++) {
+		old_to_new_map[i] = -1;
+	}
+
+	for (nu = editnurb->nurbs.first, vertex_index = 0;
+	     nu != NULL;
+	     nu = nu->next, vertex_index++)
+	{
+		if (nu->bezt) {
+			BezTriple *bezt = nu->bezt;
+			int a = nu->pntsu;
+
+			while (a--) {
+				keyIndex = getCVKeyIndex(editnurb, bezt);
+				if (keyIndex) {
+					if (keyIndex->switched) {
+						old_to_new_map[keyIndex->vertex_index] = vertex_index + 2;
+						old_to_new_map[keyIndex->vertex_index + 1] = vertex_index + 1;
+						old_to_new_map[keyIndex->vertex_index + 2] = vertex_index;
+					}
+					else {
+						old_to_new_map[keyIndex->vertex_index] = vertex_index;
+						old_to_new_map[keyIndex->vertex_index + 1] = vertex_index + 1;
+						old_to_new_map[keyIndex->vertex_index + 2] = vertex_index + 2;
+					}
+				}
+				vertex_index += 3;
+				bezt++;
+			}
+		}
+		else {
+			BPoint *bp = nu->bp;
+			int a = nu->pntsu * nu->pntsv;
+
+			while (a--) {
+				keyIndex = getCVKeyIndex(editnurb, bp);
+				if (keyIndex) {
+					old_to_new_map[keyIndex->vertex_index] = vertex_index;
+				}
+				vertex_index++;
+				bp++;
+			}
+		}
+	}
+
+	*old_totvert_r = old_totvert;
+	return old_to_new_map;
+}
+
+static void remap_hooks_and_vertex_parents(Object *obedit)
+{
+	Object *object;
+	Curve *curve = (Curve *) obedit->data;
+	int *old_to_new_map = NULL;
+	int old_totvert;
+
+	for (object = G.main->object.first; object; object = object->id.next) {
+		ModifierData *md;
+		int index;
+		if ((object->parent) &&
+		    (object->parent->data == curve) &&
+		    ELEM(object->partype, PARVERT1, PARVERT3))
+		{
+			if (old_to_new_map == NULL) {
+				old_to_new_map = initialize_index_map(obedit, &old_totvert);
+			}
+
+			if (object->par1 < old_totvert) {
+				index = old_to_new_map[object->par1];
+				if (index != -1) {
+					object->par1 = index;
+				}
+			}
+			if (object->par2 < old_totvert) {
+				index = old_to_new_map[object->par2];
+				if (index != -1) {
+					object->par2 = index;
+				}
+			}
+			if (object->par3 < old_totvert) {
+				index = old_to_new_map[object->par3];
+				if (index != -1) {
+					object->par3 = index;
+				}
+			}
+		}
+		if (object->data == curve) {
+			for (md = object->modifiers.first; md; md = md->next) {
+				if (md->type == eModifierType_Hook) {
+					HookModifierData *hmd = (HookModifierData *) md;
+					int i, j;
+
+					if (old_to_new_map == NULL) {
+						old_to_new_map = initialize_index_map(obedit, &old_totvert);
+					}
+
+					for (i = j = 0; i < hmd->totindex; i++) {
+						if (hmd->indexar[i] < old_totvert) {
+							index = old_to_new_map[hmd->indexar[i]];
+							if (index != -1) {
+								hmd->indexar[j++] = index;
+							}
+						}
+						else {
+							j++;
+						}
+					}
+
+					hmd->totindex = j;
+				}
+			}
+		}
+	}
+	if (old_to_new_map != NULL) {
+		MEM_freeN(old_to_new_map);
+	}
+}
+
 /* load editNurb in object */
 void load_editNurb(Object *obedit)
 {
@@ -1173,6 +1315,8 @@ void load_editNurb(Object *obedit)
 		Nurb *nu, *newnu;
 		ListBase newnurb = {NULL, NULL}, oldnurb = cu->nurb;
 
+		remap_hooks_and_vertex_parents(obedit);
+
 		for (nu = editnurb->first; nu; nu = nu->next) {
 			newnu = BKE_nurb_duplicate(nu);
 			BLI_addtail(&newnurb, newnu);
@@ -1229,7 +1373,7 @@ void make_editNurb(Object *obedit)
 		if (actkey)
 			editnurb->shapenr = obedit->shapenr;
 
-		/* animation could be added in editmode even if there was no animdata i
+		/* animation could be added in editmode even if there was no animdata in
 		 * object mode hence we always need CVs index be created */
 		init_editNurb_keyIndex(editnurb, &cu->nurb);
 	}




More information about the Bf-blender-cvs mailing list