[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