[Bf-blender-cvs] [25397ea] fracture_modifier: fix: some speed improvement for converting to objects or to keyframed objects and proper renaming of shards and constraints being created

Martin Felke noreply at git.blender.org
Sun Mar 22 10:14:05 CET 2015


Commit: 25397ea3556e7f2e21d6c037fed8e0bbc57b9302
Author: Martin Felke
Date:   Sun Mar 22 10:13:39 2015 +0100
Branches: fracture_modifier
https://developer.blender.org/rB25397ea3556e7f2e21d6c037fed8e0bbc57b9302

fix: some speed improvement for converting to objects or to keyframed objects and proper renaming of shards and constraints being created

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

M	source/blender/blenkernel/BKE_object.h
M	source/blender/blenkernel/intern/object.c
M	source/blender/editors/object/object_modifier.c
M	source/blender/modifiers/intern/MOD_fracture.c

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

diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 9a0b1e1..c875bd2 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -87,7 +87,7 @@ bool BKE_object_is_in_wpaint_select_vert(struct Object *ob);
 
 struct Object *BKE_object_add_only_object(struct Main *bmain, int type, const char *name);
 struct Object *BKE_object_add(struct Main *bmain, struct Scene *scene, int type);
-struct Object *BKE_object_add_named(struct Main *bmain, struct Scene *scene, int type, const char *custname);
+struct Object *BKE_object_add_named(struct Main *bmain, struct Scene *scene, int type, char *custname);
 void *BKE_object_obdata_add_from_type(struct Main *bmain, int type);
 
 void BKE_object_lod_add(struct Object *ob);
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index f6d300e..ab26294 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -1023,7 +1023,7 @@ Object *BKE_object_add_only_object(Main *bmain, int type, const char *name)
 
 /* general add: to scene, with layer from area and default name */
 /* creates minimum required data, but without vertices etc. */
-Object *BKE_object_add_named(Main *bmain, Scene *scene, int type, const char *custname)
+Object *BKE_object_add_named(Main *bmain, Scene *scene, int type, char *custname)
 {
 	Object *ob;
 	Base *base;
@@ -1031,6 +1031,7 @@ Object *BKE_object_add_named(Main *bmain, Scene *scene, int type, const char *cu
 
 	if (custname) {
 		BLI_strncpy(name, custname, sizeof(name));
+		MEM_freeN(custname);
 	}
 	else {
 		BLI_strncpy(name, get_obdata_defname(type), sizeof(name));
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 611de07..ad72108 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -102,6 +102,8 @@
 
 #include "object_intern.h"
 
+#include "PIL_time.h"
+
 static void modifier_skin_customdata_delete(struct Object *ob);
 
 /******************************** API ****************************/
@@ -2540,103 +2542,284 @@ void OBJECT_OT_rigidbody_constraints_refresh(wmOperatorType *ot)
 	edit_modifier_properties(ot);
 }
 
+static void do_add_group_unchecked(Group* group, Object *ob, Base *bas)
+{
+	GroupObject *go;
+
+	go = MEM_callocN(sizeof(GroupObject), "groupobject");
+	BLI_addtail(&group->gobject, go);
+	go->ob = ob;
+
+	ob->flag |= OB_FROMGROUP;
+	bas->flag |= OB_FROMGROUP;
+}
+
+static bool do_unchecked_constraint_add(Scene *scene, Object *ob, int type, ReportList *reports, Base* base)
+{
+	RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene);
+
+	/* check that object doesn't already have a constraint */
+	if (ob->rigidbody_constraint) {
+		BKE_reportf(reports, RPT_INFO, "Object '%s' already has a Rigid Body Constraint", ob->id.name + 2);
+		return false;
+	}
+	/* create constraint group if it doesn't already exits */
+	if (rbw->constraints == NULL) {
+		rbw->constraints = BKE_group_add(G.main, "RigidBodyConstraints");
+	}
+	/* make rigidbody constraint settings */
+	ob->rigidbody_constraint = BKE_rigidbody_create_constraint(scene, ob, type);
+	ob->rigidbody_constraint->flag |= RBC_FLAG_NEEDS_VALIDATE;
+
+	/* add constraint to rigid body constraint group */
+	//BKE_group_object_add(rbw->constraints, ob, scene, NULL);
+	do_add_group_unchecked(rbw->constraints, ob, base);
+
+	DAG_id_tag_update(&ob->id, OB_RECALC_OB);
+	return true;
+}
+
+static Object* do_convert_meshisland_to_object(MeshIsland *mi, Scene* scene, Group* g, Object* ob,
+                                            RigidBodyWorld *rbw, int i, Object*** objs, KDTree **objtree, Base** base)
+{
+	float cent[3];
+	Mesh* me;
+	ModifierData *md;
+	bool foundFracture = false;
+	Object* ob_new = NULL;
+	char *name = BLI_strdupcat(ob->id.name + 2, "_shard");
+
+	/* create separate objects for meshislands */
+#if 0
+	if (ob->type == OB_MESH) {
+		base_new = ED_object_add_duplicate(G.main, scene, base_old, USER_DUP_MESH);
+		ob_new = base_new->object;
+	}
+	else {
+#endif
+
+	ob_new = BKE_object_add_named(G.main, scene, OB_MESH, name);
+	/*set by BKE_object_add ! */
+	*base = scene->basact;
+
+	copy_m4_m4(ob_new->obmat, ob->obmat);
+	copy_v3_v3(ob_new->rot, ob->rot);
+	copy_qt_qt(ob_new->quat, ob->quat);
+	copy_v3_v3(ob_new->rotAxis, ob->rotAxis);
+	ob_new->rotAngle = ob->rotAngle;
+	copy_v3_v3(ob_new->size, ob->size);
+
+	if (rbw) {
+		rbw->pointcache->flag |= PTCACHE_OUTDATED;
+		/* make rigidbody object settings */
+		if (ob_new->rigidbody_object == NULL) {
+			ob_new->rigidbody_object = BKE_rigidbody_create_object(scene, ob_new, RBO_TYPE_ACTIVE);
+		}
+		ob_new->rigidbody_object->type = RBO_TYPE_ACTIVE;
+		ob_new->rigidbody_object->flag |= RBO_FLAG_NEEDS_VALIDATE;
+
+		/* add object to rigid body group */
+		//BKE_group_object_add(rbw->group, ob_new, scene, NULL);
+		do_add_group_unchecked(rbw->group, ob_new, *base);
+
+		DAG_id_tag_update(&ob_new->id, OB_RECALC_OB);
+	}
+//}
+
+	//BKE_group_object_add(g, ob_new, scene, NULL);
+	do_add_group_unchecked(g, ob_new, *base);
+
+	/* throw away all modifiers before fracture, result is stored inside it */
+	while (ob_new->modifiers.first != NULL) {
+		md = ob_new->modifiers.first;
+		if (md->type == eModifierType_Fracture) {
+			/*remove fracture itself too*/
+			foundFracture = true;
+			BLI_remlink(&ob_new->modifiers, md);
+			modifier_free(md);
+			md = NULL;
+		}
+		else if (!foundFracture) {
+			BLI_remlink(&ob_new->modifiers, md);
+			modifier_free(md);
+			md = NULL;
+		}
+		/* XXX else keep following modifiers, or apply them ? */
+	}
+
+	assign_matarar(ob_new, give_matarar(ob), *give_totcolp(ob));
+
+	me = (Mesh*)ob_new->data;
+	me->edit_btmesh = NULL;
+
+	DM_to_mesh(mi->physics_mesh, me, ob_new, CD_MASK_MESH);
+
+	/*set origin to centroid*/
+	copy_v3_v3(cent, mi->centroid);
+	mul_m4_v3(ob_new->obmat, cent);
+	copy_v3_v3(ob_new->loc, cent);
+
+	/*set mass*/
+	ob_new->rigidbody_object->mass = mi->rigidbody->mass;
+
+	/*store obj indexes in kdtree and objs in array*/
+	BLI_kdtree_insert(*objtree, i, mi->centroid);
+	(*objs)[i] = ob_new;
+	//i++;
+
+	BKE_rigidbody_remove_shard(scene, mi);
+
+	return ob_new;
+}
+
+static void do_relink_scene(Object* obj, Scene* scene, Scene* bgscene, Base ***basarray, int i, int count, int *j, Base ***basarray_old)
+{
+	/* add link to 2nd scene as well */
+	Base *bas = BKE_scene_base_add(bgscene, obj);
+	(*basarray)[i] = bas;
+
+	if (((i > 0) && ((i % 10) == 0)) || i == count-1) {
+		/*only add 10 objects to scene, then delete them in current scene (keep links being set to another scene,
+		 *so the scene is empty again -> way faster */
+		int k = 0;
+		for (k = (*j); k < i+1; k++)
+		{
+			/* keep rigidbody settings ! -> dont use BKE_scene_base_unlink() */
+			Base *b = (*basarray_old)[k];
+			//Base *ba = BKE_scene_base_find(scene, b->object);
+			BLI_remlink(&scene->base, b);
+			MEM_freeN(b);
+			(*basarray_old)[k] = NULL;
+		}
+		(*j) = i+1;
+	}
+}
+
+static void do_restore_scene_link(Scene* scene, int count, Scene **bgscene, Base ***basarray, Base ***basarray_old)
+{
+	int i = 0;
+	/*after conversion link all from second scene back to first one*/
+	for (i = 0; i < count; i++) {
+		Base *bas = (*basarray)[i];
+		Base *b = NULL;
+
+		/* keep rigidbody settings ! -> dont use BKE_scene_base_unlink() */
+		BLI_remlink(&(*bgscene)->base, bas);
+		b = BKE_scene_base_add(scene, bas->object);
+		ED_base_object_select(b, BA_SELECT);
+		scene->basact = b;
+		MEM_freeN(bas);
+		(*basarray)[i] = NULL;
+	}
+
+	/*delete 2nd scene and basarrays*/
+	MEM_freeN(*basarray);
+	*basarray = NULL;
+
+	MEM_freeN(*basarray_old);
+	*basarray_old = NULL;
+
+	BKE_scene_unlink(G.main, *bgscene, scene);
+	*bgscene = NULL;
+}
+
+static Object* do_convert_constraints(FractureModifierData *fmd, RigidBodyShardCon* con, Scene* scene, Object* ob,
+                                   KDTree *objtree, Object **objs, float max_con_mass, ReportList* reports, Base **base)
+{
+	int index1 = BLI_kdtree_find_nearest(objtree, con->mi1->centroid, NULL);
+	int index2 =  BLI_kdtree_find_nearest(objtree, con->mi2->centroid, NULL);
+	Object* ob1 = objs[index1];
+	Object* ob2 = objs[index2];
+	char *name = BLI_strdupcat(ob->id.name + 2, "_con");
+	Object* rbcon = BKE_object_add_named(G.main, scene, OB_EMPTY, name);
+	int iterations;
+
+	*base = scene->basact;
+
+	if (fmd->solver_iterations_override == 0) {
+		iterations = fmd->modifier.scene->rigidbody_world->num_solver_iterations;
+	}
+	else {
+		iterations = fmd->solver_iterations_override;
+	}
+
+	if (iterations > 0) {
+		con->flag |= RBC_FLAG_OVERRIDE_SOLVER_ITERATIONS;
+		con->num_solver_iterations = iterations;
+	}
+
+	if ((fmd->use_mass_dependent_thresholds)) {
+		BKE_rigidbody_calc_threshold(max_con_mass, fmd, con);
+	}
+
+	/*use same settings as in modifier
+	 *XXX Maybe use the CENTER between objects ? Might be correct for Non fixed constraints*/
+	copy_v3_v3(rbcon->loc, ob1->loc);
+
+	/*omit check for existing objects in group, since this seems very slow, and should not be necessary in this internal function*/
+	do_unchecked_constraint_add(scene, rbcon, con->type, reports, *base);
+
+	rbcon->rigidbody_constraint->ob1 = ob1;
+	rbcon->rigidbody_constraint->ob2 = ob2;
+	rbcon->rigidbody_constraint->breaking_threshold = con->breaking_threshold;
+	rbcon->rigidbody_constraint->flag |= RBC_FLAG_USE_BREAKING;
+
+	if (con->flag & RBC_FLAG_OVERRIDE_SOLVER_ITERATIONS) {
+		rbcon->rigidbody_constraint->flag |= RBC_FLAG_OVERRIDE_SOLVER_ITERATIONS;
+		rbcon->rigidbody_constraint->num_solver_iterations = iterations;
+	}
+
+	BKE_rigidbody_remove_shard_con(scene, con);
+
+	return rbcon;
+}
+
 static void convert_modifier_to_objects(ReportList *reports, Scene* scene, Object* ob, FractureModifierData *rmd)
 {
-	Base *base_new, *base_old = BKE_scene_base_find(scene, ob);
-	Object *ob_new = NULL;
+//	Base *base_new, *base_old = BKE_scene_base_find(scene, ob);
 	MeshIsland *mi;
 	RigidBodyShardCon* con;
-	int i = 0;
+	int i = 0, j = 0;
 	RigidBodyWorld *rbw = scene->rigidbody_world;
 
 	const char *name = BLI_strdupcat(ob->id.name, "_conv");
 	Group *g 

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list