[Bf-blender-cvs] [4e1c31ca7bf] fracture_modifier: crash fix for external constraints

Martin Felke noreply at git.blender.org
Sat Feb 17 13:42:53 CET 2018


Commit: 4e1c31ca7bf4f34a435fcafac59f9066d321b34d
Author: Martin Felke
Date:   Sat Feb 17 13:42:26 2018 +0100
Branches: fracture_modifier
https://developer.blender.org/rB4e1c31ca7bf4f34a435fcafac59f9066d321b34d

crash fix for external constraints

ensure refresh of "parent" FM object on every refresh of connected objects, also ensure evaluation order in rigidbody.c / bullet (parent always after children)

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

M	source/blender/blenkernel/intern/fracture.c
M	source/blender/blenkernel/intern/rigidbody.c
M	source/blender/modifiers/intern/MOD_fracture.c

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

diff --git a/source/blender/blenkernel/intern/fracture.c b/source/blender/blenkernel/intern/fracture.c
index fd8ef26a6bb..a07c1fd8771 100644
--- a/source/blender/blenkernel/intern/fracture.c
+++ b/source/blender/blenkernel/intern/fracture.c
@@ -2643,21 +2643,17 @@ void BKE_free_constraints(FractureModifierData *fmd)
 		}
 	}
 
+
+
 	for (mi = fmd->meshIslands.first; mi; mi = mi->next) {
 		if (mi->participating_constraints != NULL && mi->participating_constraint_count > 0) {
-			int i = 0;
-
+			int i;
 			for (i = 0; i < mi->participating_constraint_count; i++)
 			{
 				RigidBodyShardCon *con = mi->participating_constraints[i];
 				if (con) {
-					if (con->mi1 == mi) {
-						con->mi1 = NULL;
-					}
-
-					if (con->mi2 == mi) {
-						con->mi2 = NULL;
-					}
+					con->mi1 = NULL;
+					con->mi2 = NULL;
 				}
 			}
 
@@ -2670,8 +2666,6 @@ void BKE_free_constraints(FractureModifierData *fmd)
 	while (fmd->meshConstraints.first) {
 		rbsc = fmd->meshConstraints.first;
 		BLI_remlink(&fmd->meshConstraints, rbsc);
-		remove_participants(rbsc, rbsc->mi1);
-		remove_participants(rbsc, rbsc->mi2);
 
 		if (fmd->fracture_mode == MOD_FRACTURE_DYNAMIC && fmd->modifier.scene)
 		{
@@ -3422,13 +3416,8 @@ void BKE_fracture_free_mesh_island(FractureModifierData *rmd, MeshIsland *mi, bo
 		{
 			RigidBodyShardCon *con = mi->participating_constraints[i];
 			if (con) {
-				if (con->mi1 == mi) {
-					con->mi1 = NULL;
-				}
-
-				if (con->mi2 == mi) {
-					con->mi2 = NULL;
-				}
+				con->mi1 = NULL;
+				con->mi2 = NULL;
 			}
 		}
 
@@ -3794,22 +3783,27 @@ void BKE_meshisland_constraint_create(FractureModifierData* fmd, MeshIsland *mi1
 
 	BLI_addtail(&fmd->meshConstraints, rbsc);
 
-	/* store constraints per meshisland too, to allow breaking percentage */
-	if (mi1->participating_constraints == NULL) {
-		mi1->participating_constraints = MEM_callocN(sizeof(RigidBodyShardCon *), "part_constraints_mi1");
-		mi1->participating_constraint_count = 0;
-	}
-	mi1->participating_constraints = MEM_reallocN(mi1->participating_constraints, sizeof(RigidBodyShardCon *) * (mi1->participating_constraint_count + 1));
-	mi1->participating_constraints[mi1->participating_constraint_count] = rbsc;
-	mi1->participating_constraint_count++;
+	if ((mi1->object_index == -1) && (mi2->object_index == -1))
+	{
+		/* store constraints per meshisland too, to allow breaking percentage */
+		if (mi1->participating_constraints == NULL) {
+			mi1->participating_constraints = MEM_callocN(sizeof(RigidBodyShardCon *), "part_constraints_mi1");
+			mi1->participating_constraint_count = 0;
+		}
+		mi1->participating_constraints = MEM_reallocN(mi1->participating_constraints,
+		                                              sizeof(RigidBodyShardCon *) * (mi1->participating_constraint_count + 1));
+		mi1->participating_constraints[mi1->participating_constraint_count] = rbsc;
+		mi1->participating_constraint_count++;
 
-	if (mi2->participating_constraints == NULL) {
-		mi2->participating_constraints = MEM_callocN(sizeof(RigidBodyShardCon *), "part_constraints_mi2");
-		mi2->participating_constraint_count = 0;
+		if (mi2->participating_constraints == NULL) {
+			mi2->participating_constraints = MEM_callocN(sizeof(RigidBodyShardCon *), "part_constraints_mi2");
+			mi2->participating_constraint_count = 0;
+		}
+		mi2->participating_constraints = MEM_reallocN(mi2->participating_constraints,
+		                                              sizeof(RigidBodyShardCon *) * (mi2->participating_constraint_count + 1));
+		mi2->participating_constraints[mi2->participating_constraint_count] = rbsc;
+		mi2->participating_constraint_count++;
 	}
-	mi2->participating_constraints = MEM_reallocN(mi2->participating_constraints, sizeof(RigidBodyShardCon *) * (mi2->participating_constraint_count + 1));
-	mi2->participating_constraints[mi2->participating_constraint_count] = rbsc;
-	mi2->participating_constraint_count++;
 }
 
 void BKE_update_acceleration_map(FractureModifierData *fmd, MeshIsland* mi, Object* ob, int ctime, float acc, RigidBodyWorld *rbw)
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index 454f3f74e73..1024158a53e 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -44,6 +44,7 @@
 #include "BLI_math.h"
 #include "BLI_kdtree.h"
 #include "BLI_rand.h"
+#include "BLI_sort.h"
 #include "BLI_threads.h"
 #include "BLI_utildefines.h"
 
@@ -1586,6 +1587,45 @@ static int rigidbody_group_count_items(const ListBase *group, int *r_num_objects
 	return num_gobjects;
 }
 
+static int object_sort_eval(const void *s1, const void *s2, void* context)
+{
+	Object **o1 = (Object**)s1;
+	Object **o2 = (Object**)s2;
+
+	FractureModifierData *fmd1 = (FractureModifierData*)modifiers_findByType(*o1, eModifierType_Fracture);
+	FractureModifierData *fmd2 = (FractureModifierData*)modifiers_findByType(*o2, eModifierType_Fracture);
+
+	if (!fmd1 || !fmd2) {
+		return 0;
+	}
+
+	if ((fmd1 && fmd1->dm_group && fmd1->use_constraint_group) &&
+	   (fmd2 && fmd2->dm_group && fmd2->use_constraint_group))
+	{
+		return 0;
+	}
+
+	if ((fmd1 && !(fmd1->dm_group && fmd1->use_constraint_group)) &&
+	   (fmd2 && !(fmd2->dm_group && fmd2->use_constraint_group)))
+	{
+		return 0;
+	}
+
+	if ((fmd1 && fmd1->dm_group && fmd1->use_constraint_group) &&
+	   (fmd2 && !(fmd2->dm_group && fmd2->use_constraint_group)))
+	{
+		return 1;
+	}
+
+	if ((fmd1 && !(fmd1->dm_group && fmd1->use_constraint_group)) &&
+	   (fmd2 && (fmd2->dm_group && fmd2->use_constraint_group)))
+	{
+		return -1;
+	}
+
+	return 0;
+}
+
 /* ************************************** */
 /* Simulation Interface - Bullet */
 
@@ -1626,15 +1666,25 @@ void BKE_rigidbody_update_ob_array(RigidBodyWorld *rbw, bool do_bake_correction)
 
 	printf("RigidbodyCount changed: %d\n", rbw->numbodies);
 
-	//correct map if baked, it might be shifted
+	//pre-sort rbw->objects... put such with fmd->dm_group and fmd->use_constraint_group after all without,
+	//to enforce proper eval order
+
 	for (go = rbw->group->gobject.first, i = 0; go; go = go->next, i++) {
 
 		if (go->ob->rigidbody_object)
 		{
 			rbw->objects[i] = go->ob;
 		}
+	}
+
+	BLI_qsort_r(rbw->objects, l, sizeof(Object *), object_sort_eval, NULL);
 
-		rmd = (FractureModifierData*)modifiers_findByType(go->ob, eModifierType_Fracture);
+	//correct map if baked, it might be shifted
+	for (i = 0; i < l; i++) {
+		Object *ob = rbw->objects[i];
+		printf("%s\n", ob->id.name + 2);
+
+		rmd = (FractureModifierData*)modifiers_findByType(ob, eModifierType_Fracture);
 		if (rmd) {
 			for (mi = rmd->meshIslands.first, j = 0; mi; mi = mi->next) {
 				//store original position of the object in the object array, to be able to rearrange it later so it matches the baked cache
@@ -1651,11 +1701,11 @@ void BKE_rigidbody_update_ob_array(RigidBodyWorld *rbw, bool do_bake_correction)
 			ismapped = true;
 		}
 
-		if (!ismapped && go->ob->rigidbody_object) {
-			tmp_index[counter] = go->ob->rigidbody_object; /*1 object 1 index here (normal case)*/
+		if (!ismapped && ob->rigidbody_object) {
+			tmp_index[counter] = ob->rigidbody_object; /*1 object 1 index here (normal case)*/
 			tmp_offset[counter] = i;
-			if (go->ob->rigidbody_object && !do_bake_correction)
-				go->ob->rigidbody_object->meshisland_index = counter;
+			if (ob->rigidbody_object && !do_bake_correction)
+				ob->rigidbody_object->meshisland_index = counter;
 			counter++;
 		}
 
@@ -1887,6 +1937,8 @@ static void rigidbody_update_simulation(Scene *scene, RigidBodyWorld *rbw, bool
 	bool did_modifier = false;
 	float centroid[3] = {0, 0, 0};
 	float size[3] = {1.0f, 1.0f, 1.0f};
+	float count = BLI_listbase_count(&rbw->group->gobject);
+	int i = 0;
 
 	/* update world */
 	if (rebuild) {
@@ -1896,8 +1948,8 @@ static void rigidbody_update_simulation(Scene *scene, RigidBodyWorld *rbw, bool
 	rigidbody_update_sim_world(scene, rbw, rebuild);
 
 	/* update objects */
-	for (go = rbw->group->gobject.first; go; go = go->next) {
-		Object *ob = go->ob;
+	for (i = 0; i < count; i++) {
+		Object *ob = rbw->objects[i];
 
 		if (ob && (ob->type == OB_MESH || ob->type == OB_CURVE || ob->type == OB_SURF || ob->type == OB_FONT)) {
 			did_modifier = do_update_modifier(scene, ob, rbw, rebuild);
@@ -3920,7 +3972,7 @@ void BKE_rigidbody_validate_sim_shard_constraint(RigidBodyWorld *rbw, FractureMo
 		return;
 	}
 
-	if (ELEM(NULL, rbc->mi1, rbc->mi1->rigidbody, rbc->mi2, rbc->mi2->rigidbody)) {
+	if (ELEM(NULL, rbc->mi1, rbc->mi2)) {
 		if (rbc->physics_constraint) {
 			RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint);
 			RB_constraint_delete(rbc->physics_constraint);
@@ -3934,6 +3986,10 @@ void BKE_rigidbody_validate_sim_shard_constraint(RigidBodyWorld *rbw, FractureMo
 		return;
 	}
 
+	if (ELEM(NULL, rbc->mi1->rigidbody, rbc->mi2->rigidbody)) {
+		return;
+	}
+
 	if (rbc->physics_constraint) {
 		if (rebuild == false)
 		{
diff --git a/source/blender/modifiers/intern/MOD_fracture.c b/source/blender/modifiers/intern/MOD_fracture.c
index bfbd1745326..5ccd254a9ea 100644
--- a/source/blender/modifiers/intern/MOD_fracture.c
+++ b/source/blender/modifiers/intern/MOD_fracture.c
@@ -2608,8 +2608,8 @@ static void connect_meshislands(FractureModifierData *fmd, MeshIsland *mi1, Mesh
 	bool ok = mi1 && mi1->rigidbody;
 	ok = ok && mi2 && mi2->rigidbody;
 	ok = ok && fmd->use_constraints;
-	ok = ok && (!(fmd->dm_group && fmd->use_constraint_group) ||
-	     (fmd->dm_group && fmd->use_constraint_group && mi1->object_index != mi2->object_index));
+	ok = ok && ((!(fmd->dm_group && fmd->use_constraint_group) && (mi1->object_index == -1) && (mi2->object_index == -1))||
+	     (fmd->dm_group && fmd->use_constraint_group && (mi1->object_index != mi2->object_index)));
 
 	if (ok) {
 		/* search local constraint list instead of global one !!! saves lots of time */
@@ -2771,6 +2771,7 @@ static int prepareConstraintSearch(FractureModifierData *rmd, MeshIsland ***mesh
 				if (fmdi) {
 					for (mi = fmdi->meshIslands.first; mi; mi = mi->next) {
 						mi->object_index = j;
+						sprintf(mi->name, "%d", j);
 						(*mesh_islands)[i] = mi;
 						i++;
 					}
@@ -2783,7 +2784,8 @@ st

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list