[Bf-blender-cvs] [fa11639] fracture_modifier: added a new vertex coordinate based constraint build method, as alternative to meshisland centroid based constraint building

Martin Felke noreply at git.blender.org
Thu Mar 19 18:06:38 CET 2015


Commit: fa116391dfc846966158538b6a91185fe28172e9
Author: Martin Felke
Date:   Thu Mar 19 18:06:15 2015 +0100
Branches: fracture_modifier
https://developer.blender.org/rBfa116391dfc846966158538b6a91185fe28172e9

added a new vertex coordinate based constraint build method, as alternative to meshisland centroid based constraint building

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

M	release/scripts/startup/bl_ui/properties_physics_fracture.py
M	source/blender/blenloader/intern/readfile.c
M	source/blender/makesdna/DNA_modifier_types.h
M	source/blender/makesrna/intern/rna_modifier.c
M	source/blender/modifiers/intern/MOD_fracture.c

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

diff --git a/release/scripts/startup/bl_ui/properties_physics_fracture.py b/release/scripts/startup/bl_ui/properties_physics_fracture.py
index ca1c8c0..f8e44b8 100644
--- a/release/scripts/startup/bl_ui/properties_physics_fracture.py
+++ b/release/scripts/startup/bl_ui/properties_physics_fracture.py
@@ -135,6 +135,7 @@ class PHYSICS_PT_fracture_simulation(PhysicButtonsPanel, Panel):
         row = layout.row()
         row.prop(md, "use_constraints")
         row.prop(md, "use_breaking")
+        layout.prop(md, "constraint_target")
         col = layout.column(align=True)
         col.prop(md, "constraint_limit", text="Constraint limit, per MeshIsland")
         col.prop(md, "contact_dist")
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 01d1e85..c40de3a 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -4760,6 +4760,7 @@ static void load_fracture_modifier(FileData* fd, FractureModifierData *fmd)
 	fmd->nor_tree = NULL;
 	fmd->face_pairs = NULL;
 	fmd->vert_index_map = NULL;
+	fmd->vertex_island_map = NULL;
 
 	if (fm == NULL || fmd->dm_group) {
 		fmd->dm = NULL;
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 8182352..c86d1d0 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -1431,6 +1431,11 @@ enum {
 	MOD_FRACTURE_CUTTER_Z      = (1 << 2),
 };
 
+enum {
+	MOD_FRACTURE_CENTROID      = (1 << 0),
+	MOD_FRACTURE_VERTEX        = (1 << 1),
+};
+
 typedef struct FractureModifierData {
 	ModifierData modifier;
 	struct FracMesh *frac_mesh; /* store only the current fracmesh here first, later maybe an entire history...*/
@@ -1450,6 +1455,7 @@ typedef struct FractureModifierData {
 	struct Material *inner_material;
 	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 */
 
 	/* values */
 	int frac_algorithm;
@@ -1506,6 +1512,7 @@ typedef struct FractureModifierData {
 	int breaking_distance_weighted;
 	int breaking_angle_weighted;
 	int breaking_percentage_weighted;
+	int constraint_target;
 
 	/* internal flags */
 	int use_experimental;
@@ -1515,7 +1522,7 @@ typedef struct FractureModifierData {
 	/* internal values */
 	float max_vol;
 
-	char pad[4];
+	//char pad[4];
 } FractureModifierData;
 
 #endif  /* __DNA_MODIFIER_TYPES_H__ */
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 317097a..975ca03 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -776,6 +776,13 @@ static void rna_FractureModifier_cluster_constraint_type_set(PointerRNA* ptr, in
 	rmd->refresh_constraints = true;
 }
 
+static void rna_FractureModifier_constraint_target_set(PointerRNA* ptr, int value)
+{
+	FractureModifierData *rmd = (FractureModifierData*)ptr->data;
+	rmd->constraint_target = value;
+	rmd->refresh_constraints = true;
+}
+
 
 /* NOTE: Curve and array modifiers requires curve path to be evaluated,
  * dependency graph will make sure that curve eval would create such a path,
@@ -3910,6 +3917,12 @@ static void rna_def_modifier_fracture(BlenderRNA *brna)
 		{0, NULL, 0, NULL, NULL}
 	};
 
+	static EnumPropertyItem prop_constraint_targets[] = {
+		{MOD_FRACTURE_CENTROID, "CENTROID", 0, "Centroid", "Build constraints based on distances between centroids"},
+		{MOD_FRACTURE_VERTEX, "VERTEX", 0, "Vertex", "Build constraints based on distances between vertices (use lower values here)"},
+		{0, NULL, 0, NULL, NULL}
+	};
+
 	srna = RNA_def_struct(brna, "FractureModifier", "Modifier");
 	RNA_def_struct_ui_text(srna, "Fracture Modifier", "Add a fracture container to this object");
 	RNA_def_struct_sdna(srna, "FractureModifierData");
@@ -4277,6 +4290,14 @@ static void rna_def_modifier_fracture(BlenderRNA *brna)
 	RNA_def_property_ui_text(prop, "Cluster Constraint Type", "Type of Rigid Body Constraint between clusters");
 	RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
 	RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+	prop = RNA_def_property(srna, "constraint_target", PROP_ENUM, PROP_NONE);
+	RNA_def_property_enum_items(prop, prop_constraint_targets);
+	RNA_def_property_enum_funcs(prop, NULL, "rna_FractureModifier_constraint_target_set", NULL);
+	RNA_def_property_enum_default(prop, MOD_FRACTURE_CENTROID);
+	RNA_def_property_ui_text(prop, "Constraint Method", "Method to build constraints");
+	RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+	RNA_def_property_update(prop, 0, "rna_Modifier_update");
 }
 
 void RNA_def_modifier(BlenderRNA *brna)
diff --git a/source/blender/modifiers/intern/MOD_fracture.c b/source/blender/modifiers/intern/MOD_fracture.c
index 4923d88..b0cd635 100644
--- a/source/blender/modifiers/intern/MOD_fracture.c
+++ b/source/blender/modifiers/intern/MOD_fracture.c
@@ -157,6 +157,8 @@ static void initData(ModifierData *md)
 	fmd->cutter_axis = MOD_FRACTURE_CUTTER_Z;
 	fmd->cluster_constraint_type = RBC_TYPE_FIXED;
 	fmd->vert_index_map = NULL;
+	fmd->constraint_target = MOD_FRACTURE_CENTROID;
+	fmd->vertex_island_map = NULL;
 }
 
 static void freeMeshIsland(FractureModifierData *rmd, MeshIsland *mi, bool remove_rigidbody)
@@ -289,6 +291,11 @@ static void free_modifier(FractureModifierData *fmd)
 {
 	free_simulation(fmd);
 
+	if (fmd->vertex_island_map) {
+		BLI_ghash_free(fmd->vertex_island_map, NULL, NULL);
+		fmd->vertex_island_map = NULL;
+	}
+
 	if (fmd->nor_tree != NULL) {
 		BLI_kdtree_free(fmd->nor_tree);
 		fmd->nor_tree = NULL;
@@ -1230,6 +1237,7 @@ static void copyData(ModifierData *md, ModifierData *target)
 	trmd->meshConstraints.last = NULL;
 	trmd->face_pairs = NULL;
 	trmd->vert_index_map = NULL;
+	trmd->vertex_island_map = NULL;
 
 	trmd->breaking_threshold = rmd->breaking_threshold;
 	trmd->use_constraints = rmd->use_constraints;
@@ -1295,6 +1303,7 @@ static void copyData(ModifierData *md, ModifierData *target)
 	trmd->cutter_axis = rmd->cutter_axis;
 
 	trmd->cluster_constraint_type = rmd->cluster_constraint_type;
+	trmd->constraint_target = rmd->constraint_target;
 }
 
 /* mi->bb, its for volume fraction calculation.... */
@@ -2029,7 +2038,7 @@ static void connect_meshislands(FractureModifierData *fmd, MeshIsland *mi1, Mesh
 	}
 }
 
-static void search_centroid_based(FractureModifierData *rmd, MeshIsland *mi, MeshIsland **meshIslands, KDTree **combined_tree)
+static void search_tree_based(FractureModifierData *rmd, MeshIsland *mi, MeshIsland **meshIslands, KDTree **combined_tree, float co[3])
 {
 	int r = 0, limit = 0, i = 0;
 	KDTreeNearest *n3 = NULL;
@@ -2038,13 +2047,26 @@ static void search_centroid_based(FractureModifierData *rmd, MeshIsland *mi, Mes
 	limit = rmd->constraint_limit;
 	dist = rmd->contact_dist;
 
-	mul_v3_m4v3(obj_centr, rmd->origmat, mi->centroid);
+	if (rmd->constraint_target == MOD_FRACTURE_CENTROID) {
+		mul_v3_m4v3(obj_centr, rmd->origmat, mi->centroid);
+	}
+	else if (rmd->constraint_target == MOD_FRACTURE_VERTEX){
+		mul_v3_m4v3(obj_centr, rmd->origmat, co);
+	}
 
 	r = BLI_kdtree_range_search(*combined_tree, obj_centr, &n3, dist);
 
 	/* use centroid dist based approach here, together with limit */
 	for (i = 0; i < r; i++) {
-		MeshIsland *mi2 = meshIslands[(n3 + i)->index];
+		MeshIsland *mi2 = NULL;
+
+		if (rmd->constraint_target == MOD_FRACTURE_CENTROID) {
+			mi2 = meshIslands[(n3 + i)->index];
+		}
+		else if(rmd->constraint_target == MOD_FRACTURE_VERTEX) {
+			int index = (n3 + i)->index;
+			mi2 = BLI_ghash_lookup(rmd->vertex_island_map, SET_INT_IN_POINTER(index));
+		}
 		if ((mi != mi2) && (mi2 != NULL)) {
 			float thresh = rmd->breaking_threshold;
 			int con_type = RBC_TYPE_FIXED;
@@ -2062,34 +2084,53 @@ static void search_centroid_based(FractureModifierData *rmd, MeshIsland *mi, Mes
 		n3 = NULL;
 	}
 }
-
 static int prepareConstraintSearch(FractureModifierData *rmd, MeshIsland ***mesh_islands, KDTree **combined_tree)
 {
 	MeshIsland *mi;
-	int i = 0, islands = 0;
+	int i = 0, ret = 0;
 
-	islands = BLI_listbase_count(&rmd->meshIslands);
+	int islands = BLI_listbase_count(&rmd->meshIslands);
 	*mesh_islands = MEM_reallocN(*mesh_islands, islands * sizeof(MeshIsland *));
 	for (mi = rmd->meshIslands.first; mi; mi = mi->next) {
 		(*mesh_islands)[i] = mi;
 		i++;
 	}
 
-	*combined_tree = BLI_kdtree_new(islands);
-	for (i = 0; i < islands; i++) {
-		float obj_centr[3];
-		mul_v3_m4v3(obj_centr, rmd->origmat, (*mesh_islands)[i]->centroid);
-		BLI_kdtree_insert(*combined_tree, i, obj_centr);
+	if (rmd->constraint_target == MOD_FRACTURE_CENTROID)
+	{
+		*combined_tree = BLI_kdtree_new(islands);
+		for (i = 0; i < islands; i++) {
+			float obj_centr[3];
+			mul_v3_m4v3(obj_centr, rmd->origmat, (*mesh_islands)[i]->centroid);
+			BLI_kdtree_insert(*combined_tree, i, obj_centr);
+		}
+
+		BLI_kdtree_balance(*combined_tree);
+		ret = islands;
 	}
+	else if (rmd->constraint_target == MOD_FRACTURE_VERTEX)
+	{
+		int totvert = rmd->visible_mesh_cached->getNumVerts(rmd->visible_mesh_cached);
+		MVert *mvert = rmd->visible_mesh_cached->getVertArray(rmd->visible_mesh_cached);
+		MVert *mv;
 
-	BLI_kdtree_balance(*combined_tree);
+		*combined_tree = BLI_kdtree_new(totvert);
+		for (i = 0, mv = mvert; i < totvert; i++, mv++) {
+			float co[3];
+			mul_v3_m4v3(co, rmd->origmat, mv->co);
+			BLI_kdtree_insert(*combined_tree, i, co);
+		}
 
-	return islands;
+		BLI_kdtree_balance(*combined_tree);
+		ret = totvert;
+	}
+
+	return ret;
 }
 
 static void create_constraints(FractureModifierData *rmd)
 {
-	KDTree *centroid_tree = NULL;
+	KDTree *coord_tree = NULL;
 	MeshIsland **mesh_islands = MEM_mallocN(sizeof(MeshIsland *), "mesh_islands");
 	int count, i = 0;
 
@@ -2104,15 +2145,25 @@ static void create_constraints(FractureModifierData *rmd)
 		MEM_freeN(bb);
 	}
 
-	count = prepareConstraintSearch(rmd, &mesh_islands, &centroid_tree);
+
+	count = prepareConstraintSearch(rmd, &mesh_islands, &coord_tree);
 
 	for (i = 0; i < coun

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list