[Bf-blender-cvs] [a575c508fe1] blender2.8: Stretch To: fix initialization of the constraint with copy-on-write.

Alexander Gavrilov noreply at git.blender.org
Thu Nov 15 12:11:56 CET 2018


Commit: a575c508fe191b7cb35956c0e25e058896a3deb6
Author: Alexander Gavrilov
Date:   Thu Nov 15 14:09:13 2018 +0300
Branches: blender2.8
https://developer.blender.org/rBa575c508fe191b7cb35956c0e25e058896a3deb6

Stretch To: fix initialization of the constraint with copy-on-write.

The constraint is supposed to automatically initialize the rest
length when it is first evaluated, so now that evaluation is done
on a separate copy it also has to copy the value to the master
instance - or newly created constraints will be broken.

Since this is supposed to happen once at constraint creation,
implementing as a search for now instead of adding new fields.

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

M	source/blender/blenkernel/intern/constraint.c

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

diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 8dfb50cd159..eb242baccfa 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -109,6 +109,8 @@
 
 static void damptrack_do_transform(float matrix[4][4], const float tarvec[3], int track_axis);
 
+static bConstraint *constraint_find_original(struct Depsgraph *depsgraph, Object *ob, bPoseChannel *pchan, bConstraint *con, Object **r_orig_ob);
+
 /* -------------- Naming -------------- */
 
 /* Find the first available, non-duplicate name for a given constraint */
@@ -2977,9 +2979,24 @@ static void stretchto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
 		dist /= size[1];
 
 		/* data->orglength==0 occurs on first run, and after 'R' button is clicked */
-		if (data->orglength == 0)
+		if (data->orglength == 0) {
 			data->orglength = dist;
 
+			/* Write the computed length back to the master copy if in COW evaluation. */
+			if (DEG_is_active(cob->depsgraph)) {
+				Object *orig_ob = NULL;
+				bConstraint *orig_con = constraint_find_original(cob->depsgraph, cob->ob, cob->pchan, con, &orig_ob);
+
+				if (orig_con != NULL) {
+					bStretchToConstraint *orig_data = orig_con->data;
+
+					orig_data->orglength = data->orglength;
+
+					DEG_id_tag_update(&orig_ob->id, DEG_TAG_COPY_ON_WRITE | DEG_TAG_TRANSFORM);
+				}
+			}
+		}
+
 		scale[1] = dist / data->orglength;
 
 		bulge = powf(data->orglength / dist, data->bulge);
@@ -5087,6 +5104,56 @@ bConstraint *BKE_constraint_find_from_target(Object *ob, bConstraintTarget *tgt,
 	return NULL;
 }
 
+/* Finds the original copy of the constraint based on a COW copy. */
+static bConstraint *constraint_find_original(struct Depsgraph *depsgraph, Object *ob, bPoseChannel *pchan, bConstraint *con, Object **r_orig_ob)
+{
+	Object *orig_ob = (Object*)DEG_get_original_id((ID*)ob);
+
+	if (ELEM(orig_ob, NULL, ob)) {
+		return NULL;
+	}
+
+	/* Find which constraint list to use. */
+	ListBase *constraints, *orig_constraints;
+
+	if (pchan != NULL) {
+		if (orig_ob->type != OB_ARMATURE || orig_ob->pose == NULL) {
+			return NULL;
+		}
+
+		bPoseChannel *orig_pchan = BKE_pose_channel_find_name(orig_ob->pose, pchan->name);
+
+		if (orig_pchan == NULL) {
+			return NULL;
+		}
+
+		constraints = &pchan->constraints;
+		orig_constraints = &orig_pchan->constraints;
+	}
+	else {
+		constraints = &ob->constraints;
+		orig_constraints = &orig_ob->constraints;
+	}
+
+	/* Lookup the original constraint by index. */
+	int index = BLI_findindex(constraints, con);
+
+	if (index >= 0) {
+		bConstraint *orig_con = (bConstraint*)BLI_findlink(orig_constraints, index);
+
+		/* Verify it has correct type and name. */
+		if (orig_con && orig_con->type == con->type && STREQ(orig_con->name, con->name)) {
+			if (r_orig_ob != NULL) {
+				*r_orig_ob = orig_ob;
+			}
+
+			return orig_con;
+		}
+	}
+
+	return NULL;
+}
+
 /* -------- Constraints and Proxies ------- */
 
 /* Rescue all constraints tagged as being CONSTRAINT_PROXY_LOCAL (i.e. added to bone that's proxy-synced in this file) */



More information about the Bf-blender-cvs mailing list