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. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to