[Bf-blender-cvs] [7761311] fracture_modifier: added material handling (so meshislands get correct materials from original objects) and added plastic tolerance values, which are taken into account with special simulation mode only.

Martin Felke noreply at git.blender.org
Thu Jan 21 02:13:08 CET 2016


Commit: 7761311305947521005808624c4cafb3d6648a01
Author: Martin Felke
Date:   Wed Jan 20 23:30:55 2016 +0100
Branches: fracture_modifier
https://developer.blender.org/rB7761311305947521005808624c4cafb3d6648a01

added material handling (so meshislands get correct materials from original objects) and added plastic tolerance values, which are taken into account with special simulation mode only.

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

M	source/blender/blenkernel/BKE_fracture.h
M	source/blender/blenkernel/intern/fracture.c
M	source/blender/blenkernel/intern/rigidbody.c
M	source/blender/makesdna/DNA_modifier_types.h
M	source/blender/makesdna/DNA_rigidbody_types.h
M	source/blender/makesrna/intern/rna_modifier.c
M	source/blender/modifiers/intern/MOD_fracture.c

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

diff --git a/source/blender/blenkernel/BKE_fracture.h b/source/blender/blenkernel/BKE_fracture.h
index ae45fb0..38c544a 100644
--- a/source/blender/blenkernel/BKE_fracture.h
+++ b/source/blender/blenkernel/BKE_fracture.h
@@ -44,6 +44,7 @@ struct Object;
 struct Group;
 struct MeshIsland;
 struct RigidBodyShardCon;
+struct GHash;
 
 struct BoundBox;
 struct MVert;
@@ -115,5 +116,6 @@ void BKE_fracture_mesh_constraint_remove_all(struct FractureModifierData *fmd);
 
 void BKE_fracture_free_mesh_island(struct FractureModifierData *rmd, struct MeshIsland *mi, bool remove_rigidbody);
 int BKE_fracture_update_visual_mesh(struct FractureModifierData *fmd, bool do_custom_data);
+short BKE_fracture_collect_materials(struct Object* o, struct Object* ob, short matstart, struct GHash** mat_index_map);
 
 #endif /* BKE_FRACTURE_H */
diff --git a/source/blender/blenkernel/intern/fracture.c b/source/blender/blenkernel/intern/fracture.c
index a088107..41fc4f7 100644
--- a/source/blender/blenkernel/intern/fracture.c
+++ b/source/blender/blenkernel/intern/fracture.c
@@ -40,6 +40,7 @@
 #include "BKE_fracture.h"
 #include "BKE_fracture_util.h"
 #include "BKE_global.h"
+#include "BKE_material.h"
 #include "BKE_mesh.h"
 #include "BKE_modifier.h"
 #include "BKE_object.h"
@@ -59,6 +60,7 @@
 #include "DNA_fracture_types.h"
 #include "DNA_gpencil_types.h"
 #include "DNA_group_types.h"
+#include "DNA_material_types.h"
 #include "DNA_meshdata_types.h"
 #include "DNA_modifier_types.h"
 #include "DNA_rigidbody_types.h"
@@ -2217,6 +2219,7 @@ static void fracture_update_shards(FractureModifierData *fmd, Shard *s, int inde
 	{
 		fmd->frac_mesh = BKE_create_fracture_container();
 		fmd->frac_mesh->progress_counter = 0; //XXXX ABUSE this for vertstart now, threading doesnt work anyway yet
+		fmd->matstart = 1; //TODO, is this 1-based ?
 	}
 
 	fm = fmd->frac_mesh;
@@ -2315,8 +2318,10 @@ int BKE_fracture_update_visual_mesh(FractureModifierData *fmd, bool do_custom_da
 {
 	MeshIsland *mi;
 	DerivedMesh *dm = fmd->visible_mesh_cached;
-	int vertstart = 0, totvert = 0;
+	int vertstart = 0, totvert = 0, totpoly = 0, polystart = 0, matstart = 1;
 	MVert *mv = NULL;
+	MPoly *mp = NULL, *mpoly = NULL;
+	int j = 0;
 
 	if (dm)
 	{
@@ -2334,6 +2339,7 @@ int BKE_fracture_update_visual_mesh(FractureModifierData *fmd, bool do_custom_da
 	dm = fmd->visible_mesh_cached;
 	mv = dm->getVertArray(dm);
 	totvert = dm->getNumVerts(dm);
+	mpoly = dm->getPolyArray(dm);
 
 	//update existing island's vert refs, if any...should have used indexes instead :S
 	for (mi = fmd->meshIslands.first; mi; mi = mi->next)
@@ -2368,17 +2374,57 @@ int BKE_fracture_update_visual_mesh(FractureModifierData *fmd, bool do_custom_da
 			mi->vertno[3*i+1] = v->no[1];
 			mi->vertno[3*i+2] = v->no[2];
 		}
+
+		totpoly = mi->physics_mesh->getNumPolys(mi->physics_mesh);
+		for (j = 0, mp = mpoly + polystart; j < totpoly; j++, mp++)
+		{
+			/* material index lookup and correction, avoid having the same material in different slots */
+			int index = GET_INT_FROM_POINTER(BLI_ghash_lookup(fmd->material_index_map,
+			                                 SET_INT_IN_POINTER(mp->mat_nr + matstart)));
+			mp->mat_nr = index-1;
+		}
+
+		/* fortunately we know how many faces "belong" to this meshisland, too */
+		polystart += totpoly;
+		matstart += mi->totcol;
 	}
 
 	return vertstart;
 }
 
+short BKE_fracture_collect_materials(Object* o, Object* ob, short matstart, GHash** mat_index_map)
+{
+	short *totcolp = NULL, k = 0;
+	Material ***matarar = NULL;
+	int j;
+
+	/* append materials to target object, if not existing yet */
+	totcolp = give_totcolp(o);
+	matarar = give_matarar(o);
+
+	for (j = 0; j < *totcolp; j++)
+	{
+		int index = find_material_index(ob, (*matarar)[j]);
+		if (index == 0)
+		{
+			assign_material(ob, (*matarar)[j], matstart + k, BKE_MAT_ASSIGN_USERPREF);
+			index = matstart + k;
+			k++;
+		}
+
+		BLI_ghash_insert(*mat_index_map, SET_INT_IN_POINTER(matstart+j), SET_INT_IN_POINTER(index));
+	}
+
+	return *totcolp;
+}
+
 MeshIsland* BKE_fracture_mesh_island_add(FractureModifierData *fmd, Object* own, Object *target, int index, bool update)
 {
 	MeshIsland *mi;
 	Shard *s;
 	int vertstart = 0;
 	float loc[3], rot[4];
+	short totcol = 0;
 
 	if (fmd->fracture_mode != MOD_FRACTURE_EXTERNAL || own->type != OB_MESH)
 		return NULL;
@@ -2406,6 +2452,21 @@ MeshIsland* BKE_fracture_mesh_island_add(FractureModifierData *fmd, Object* own,
 	if (mi->rigidbody)
 		mi->rigidbody->meshisland_index = mi->id;
 
+	//handle materials
+	if (!fmd->material_index_map)
+	{
+		fmd->material_index_map = BLI_ghash_int_new("mat_index_map");
+		fmd->matstart = 1;
+	}
+
+	totcol = BKE_fracture_collect_materials(target, own, (short)fmd->matstart, &fmd->material_index_map);
+	if (totcol < 0)
+	    totcol = 0;
+	fmd->matstart += totcol;
+	mi->totcol = totcol;
+
+	/*XXXXX TODO deal with material deletion, and reorder (in material code) */
+
 	return mi;
 }
 
@@ -2540,6 +2601,13 @@ void BKE_fracture_mesh_island_remove_all(FractureModifierData *fmd)
 		fmd->visible_mesh_cached->release(fmd->visible_mesh_cached);
 		fmd->visible_mesh_cached = NULL;
 	}
+
+	if (fmd->material_index_map)
+	{
+		BLI_ghash_free(fmd->material_index_map, NULL, NULL);
+		fmd->material_index_map = NULL;
+		fmd->matstart = 1;
+	}
 }
 
 RigidBodyShardCon *BKE_fracture_mesh_islands_connect(FractureModifierData *fmd, MeshIsland *mi1, MeshIsland *mi2, short con_type, int index)
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index 424979d..61c28c3 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -3110,7 +3110,7 @@ static void handle_breaking_distance(FractureModifierData *fmd, Object *ob, Rigi
 	}
 }
 
-static void handle_plastic_breaking_constraint(RigidBodyShardCon *rbsc, RigidBodyShardCon *con)
+static void handle_plastic_breaking_constraint(RigidBodyShardCon *rbsc, RigidBodyShardCon *con, bool broken, bool exceeded_plastic, bool exceeded)
 {
 	bool same = (((con->mi1 == rbsc->mi1 && con->mi2 == rbsc->mi2)) || ((con->mi1 == rbsc->mi2 && con->mi2 == rbsc->mi1)));
 	if (con->physics_constraint && same)
@@ -3125,7 +3125,8 @@ static void handle_plastic_breaking_constraint(RigidBodyShardCon *rbsc, RigidBod
 			else
 			{	/* I am NOT plastic and a spring */
 				/* so the other needs to break */
-				RB_constraint_set_enabled(con->physics_constraint, false);
+				if (broken || exceeded)
+					RB_constraint_set_enabled(con->physics_constraint, false);
 			}
 		}
 		else
@@ -3137,19 +3138,24 @@ static void handle_plastic_breaking_constraint(RigidBodyShardCon *rbsc, RigidBod
 				if (con->flag & RBC_FLAG_PLASTIC_ACTIVE)
 				{
 					/*Other is plastic active, break it*/
-					RB_constraint_set_enabled(con->physics_constraint, false);
+					if (broken || exceeded)
+						RB_constraint_set_enabled(con->physics_constraint, false);
 				}
 				else
 				{
 					/* activate other plastic */
-					con->flag |= RBC_FLAG_PLASTIC_ACTIVE;
-					rigidbody_set_springs_active(con, true);
+					if (broken || exceeded_plastic)
+					{
+						con->flag |= RBC_FLAG_PLASTIC_ACTIVE;
+						rigidbody_set_springs_active(con, true);
+					}
 				}
 			}
 			else
 			{
 				/*other is not plastic, break it */
-				RB_constraint_set_enabled(con->physics_constraint, false);
+				if (broken || exceeded)
+					RB_constraint_set_enabled(con->physics_constraint, false);
 			}
 		}
 	}
@@ -3158,7 +3164,7 @@ static void handle_plastic_breaking_constraint(RigidBodyShardCon *rbsc, RigidBod
 static void handle_plastic_breaking_participants(FractureModifierData *fmd, RigidBodyShardCon *rbsc)
 {
 	float dist, angle, distdiff, anglediff;
-	bool exceeded = false;
+	bool exceeded = false, exceeded_plastic = false, broken = false;
 	calc_dist_angle(rbsc, &dist, &angle);
 
 	anglediff = fabs(angle - rbsc->start_angle);
@@ -3180,20 +3186,24 @@ static void handle_plastic_breaking_participants(FractureModifierData *fmd, Rigi
 	if (!fmd->use_special_breaking)
 		return;
 
+	exceeded_plastic = (rbsc->plastic_angle > 0.0f && anglediff > rbsc->plastic_angle);
+	exceeded_plastic = exceeded_plastic || (rbsc->plastic_dist > 0.0f && distdiff > rbsc->plastic_dist);
+	broken = rbsc->physics_constraint && !(RB_constraint_is_enabled(rbsc->physics_constraint));
+
 	/* is there a break event on THIS constraint ? */
-	if (rbsc->physics_constraint && (!(RB_constraint_is_enabled(rbsc->physics_constraint))))
+	if (broken || exceeded_plastic || exceeded)
 	{
 		int i;
 		for (i = 0; i < rbsc->mi1->participating_constraint_count; i++)
 		{
 			RigidBodyShardCon *con = rbsc->mi1->participating_constraints[i];
-			handle_plastic_breaking_constraint(rbsc, con);
+			handle_plastic_breaking_constraint(rbsc, con, broken, exceeded_plastic, exceeded);
 		}
 
 		for (i = 0; i < rbsc->mi2->participating_constraint_count; i++)
 		{
 			RigidBodyShardCon *con = rbsc->mi2->participating_constraints[i];
-			handle_plastic_breaking_constraint(rbsc, con);
+			handle_plastic_breaking_constraint(rbsc, con, broken, exceeded_plastic, exceeded);
 		}
 	}
 }
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 9348edb..6bc2ff5 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -1433,7 +1433,8 @@ typedef struct MeshIsland {
 	float thresh_weight, ground_weight;
 	int linear_index;  /* index in rigidbody world */
 	int particle_index;
-	//char pad[2];
+	int totcol; /*store number of used materials here, from the original object*/
+	char pad[4];
 } MeshIsland;
 
 
@@ -1640,6 +1641,7 @@ typedef struct FractureModifierData {
 	struct GHash *face_pairs;
 	struct GHash *vert_index_map; /*used for autoconversion of former objects to clusters, marks object membership of each vert*/
 	struct GHash *vertex_island_map; /* used for constraint building based on vertex proximity, temporary data */
+	struct GHash *material_index_map; /* used to collect materials from objects to be packed, temporary data */
 	ListBase shard_sequence; /* used as mesh cache / history for dynamic fracturing, for shards (necessary for conversion to DM) */
 	ListBase meshIsl

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list