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

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

Reply via email to