Commit: cb4d349803cbe27f51be2a5ccca1c68ea42ba3d9
Author: Luca Rood
Date:   Wed Dec 7 15:57:17 2016 -0200
Branches: cloth-improvements
https://developer.blender.org/rBcb4d349803cbe27f51be2a5ccca1c68ea42ba3d9

Initial implementation of angular bending springs

This implements bending resistant forces between adjacent polygons in
cloth simulation. Note that derivatives are not yet included in the
computations (and might not even be needed, as the simulation is already
quite stable). Angular damping is not yet implemented either.

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

M       source/blender/blenkernel/BKE_cloth.h
M       source/blender/blenkernel/intern/cloth.c
M       source/blender/physics/intern/BPH_mass_spring.cpp
M       source/blender/physics/intern/implicit.h
M       source/blender/physics/intern/implicit_blender.c

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

diff --git a/source/blender/blenkernel/BKE_cloth.h 
b/source/blender/blenkernel/BKE_cloth.h
index 9f8a8e4..5514958 100644
--- a/source/blender/blenkernel/BKE_cloth.h
+++ b/source/blender/blenkernel/BKE_cloth.h
@@ -132,8 +132,13 @@ ClothVertex;
 typedef struct ClothSpring {
        int     ij;             /* Pij from the paper, one end of the spring.   
*/
        int     kl;             /* Pkl from the paper, one end of the spring.   
*/
-       int mn;         /* Something related to angular hair springs. */
-       float   restlen;        /* The original length of the spring.   */
+       int mn;         /* For hair springs: third vertex index; For bending 
springs: edge index */
+       int *pa;        /* array of vert indices for poly a (for bending 
springs) */
+       int *pb;        /* array of vert indices for poly b (for bending 
springs) */
+       int la;         /* length of *pa */
+       int lb;         /* length of *pb */
+       float restlen;  /* The original length of the spring */
+       float restang;  /* The original angle of the bending springs */
        int     type;           /* types defined in BKE_cloth.h ("springType") 
*/
        int     flags;          /* defined in BKE_cloth.h, e.g. deactivated due 
to tearing */
        float   stiffness;      /* stiffness factor from the vertex groups */
diff --git a/source/blender/blenkernel/intern/cloth.c 
b/source/blender/blenkernel/intern/cloth.c
index 8485004..be5747a 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -35,6 +35,7 @@
 #include "DNA_object_types.h"
 #include "DNA_meshdata_types.h"
 
+#include "BLI_alloca.h"
 #include "BLI_utildefines.h"
 #include "BLI_math.h"
 #include "BLI_edgehash.h"
@@ -63,6 +64,12 @@ static void cloth_update_spring_lengths( ClothModifierData 
*clmd, DerivedMesh *d
 static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm );
 static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm );
 
+typedef struct BendSpringRef {
+       int set;
+       int index;
+       LinkNode **spring;
+} BendSpringRef;
+
 /******************************************************************************
  *
  * External interface called by modifier.c clothModifier functions.
@@ -531,7 +538,12 @@ void cloth_free_modifier(ClothModifierData *clmd )
                        LinkNode *search = cloth->springs;
                        while (search) {
                                ClothSpring *spring = search->link;
-                                               
+
+                               if (spring->type == CLOTH_SPRING_TYPE_BENDING) {
+                                       MEM_freeN(spring->pa);
+                                       MEM_freeN(spring->pb);
+                               }
+
                                MEM_freeN ( spring );
                                search = search->next;
                        }
@@ -598,6 +610,11 @@ void cloth_free_modifier_extern(ClothModifierData *clmd )
                        while (search) {
                                ClothSpring *spring = search->link;
 
+                               if (spring->type == CLOTH_SPRING_TYPE_BENDING) {
+                                       MEM_freeN(spring->pa);
+                                       MEM_freeN(spring->pb);
+                               }
+
                                MEM_freeN ( spring );
                                search = search->next;
                        }
@@ -959,7 +976,7 @@ int cloth_add_spring(ClothModifierData *clmd, unsigned int 
indexA, unsigned int
        Cloth *cloth = clmd->clothObject;
        ClothSpring *spring = NULL;
        
-       if (cloth) {
+       if (cloth && spring_type != CLOTH_SPRING_TYPE_BENDING) {
                // TODO: look if this spring is already there
                
                spring = (ClothSpring *)MEM_callocN ( sizeof ( ClothSpring ), 
"cloth spring" );
@@ -1001,7 +1018,12 @@ static void cloth_free_errorsprings(Cloth *cloth, 
LinkNodePair *edgelist)
                LinkNode *search = cloth->springs;
                while (search) {
                        ClothSpring *spring = search->link;
-                                               
+
+                       if (spring->type == CLOTH_SPRING_TYPE_BENDING) {
+                               MEM_freeN(spring->pa);
+                               MEM_freeN(spring->pb);
+                       }
+
                        MEM_freeN ( spring );
                        search = search->next;
                }
@@ -1294,6 +1316,58 @@ void cloth_parallel_transport_hair_frame(float 
mat[3][3], const float dir_old[3]
        mul_m3_m3m3(mat, rot, mat);
 }
 
+BLI_INLINE float spring_angle(ClothVertex *verts, int i, int j, int *i_a, int 
*i_b, int len_a, int len_b)
+{
+       float co_i[3], co_j[3], co_a[3], co_b[3];
+       float dir_a[3], dir_b[3];
+       float tmp1[3], tmp2[3], vec_e[3];
+       float sin, cos;
+       float (*array_a)[3] = BLI_array_alloca(array_a, len_a);
+       float (*array_b)[3] = BLI_array_alloca(array_b, len_b);
+       int x;
+
+       /* assign poly vert coords to arrays */
+       for (x = 0; x < len_a; x++) {
+               copy_v3_v3(array_a[x], verts[i_a[x]].xrest);
+       }
+
+       for (x = 0; x < len_b; x++) {
+               copy_v3_v3(array_b[x], verts[i_b[x]].xrest);
+       }
+
+       /* get edge vert coords and poly centroid coords. */
+       copy_v3_v3(co_i, verts[i].xrest);
+       copy_v3_v3(co_j, verts[j].xrest);
+       cent_poly_v3(co_a, array_a, len_a);
+       cent_poly_v3(co_b, array_b, len_b);
+
+       /* find dir for poly a */
+       sub_v3_v3v3(tmp1, co_j, co_a);
+       sub_v3_v3v3(tmp2, co_i, co_a);
+
+       cross_v3_v3v3(dir_a, tmp1, tmp2);
+       normalize_v3(dir_a);
+
+       /* find dir for poly b */
+       sub_v3_v3v3(tmp1, co_i, co_b);
+       sub_v3_v3v3(tmp2, co_j, co_b);
+
+       cross_v3_v3v3(dir_b, tmp1, tmp2);
+       normalize_v3(dir_b);
+
+       /* find parallel and perpendicular directions to edge */
+       sub_v3_v3v3(vec_e, co_i, co_j);
+       normalize_v3(vec_e);
+
+       /* calculate angle between polys */
+       cos = dot_v3v3(dir_a, dir_b);
+
+       cross_v3_v3v3(tmp1, dir_a, dir_b);
+       sin = dot_v3v3(tmp1, vec_e);
+
+       return atan2(sin, cos);
+}
+
 static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
 {
        Cloth *cloth = clmd->clothObject;
@@ -1307,6 +1381,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, 
DerivedMesh *dm )
        const MEdge *medge = dm->getEdgeArray(dm);
        const MPoly *mpoly = dm->getPolyArray(dm);
        const MLoop *mloop = dm->getLoopArray(dm);
+       const MLoop *ml;
        int index2 = 0; // our second vertex index
        LinkNodePair *edgelist;
        EdgeSet *edgeset = NULL;
@@ -1329,7 +1404,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, 
DerivedMesh *dm )
        if (!edgelist)
                return 0;
 
-       // structural springs
+       /* structural springs */
        for ( i = 0; i < numedges; i++ ) {
                spring = (ClothSpring *)MEM_callocN ( sizeof ( ClothSpring ), 
"cloth spring" );
 
@@ -1374,157 +1449,172 @@ static int cloth_build_springs ( ClothModifierData 
*clmd, DerivedMesh *dm )
                        cloth->verts[i].avg_spring_len = 
cloth->verts[i].avg_spring_len * 0.49f / ((float)cloth->verts[i].spring_count);
        }
 
-       // shear springs
-       for (i = 0; i < numpolys; i++) {
-               /* triangle faces already have shear springs due to structural 
geometry */
-               if (mpoly[i].totloop == 4) {
-                       int j;
+       /* shear and bend springs */
+       if (numpolys) {
+               BendSpringRef *spring_ref = MEM_callocN(sizeof(*spring_ref) * 
numedges, "temp bend spring reference");
+               BendSpringRef *curr_ref;
+               int j;
 
-                       for (j = 0; j != 2; j++) {
-                               spring = (ClothSpring 
*)MEM_callocN(sizeof(ClothSpring), "cloth spring");
+               if (!spring_ref) {
+                       cloth_free_errorsprings(cloth, edgelist);
+                       return 0;
+               }
 
-                               if (!spring) {
-                                       cloth_free_errorsprings(cloth, 
edgelist);
-                                       return 0;
-                               }
+               for (i = 0; i < numpolys; i++) {
+                       /* shear spring */
+                       /* triangle faces already have shear springs due to 
structural geometry */
+                       /* TODO: Support ngons */
+                       if (mpoly[i].totloop == 4) {
+                               for (j = 0; j != 2; j++) {
+                                       spring = (ClothSpring 
*)MEM_callocN(sizeof(ClothSpring), "cloth spring");
 
-                               spring_verts_ordered_set(
-                                       spring,
-                                       mloop[mpoly[i].loopstart + (j + 0)].v,
-                                       mloop[mpoly[i].loopstart + (j + 2)].v);
+                                       if (!spring) {
+                                               cloth_free_errorsprings(cloth, 
edgelist);
+                                               return 0;
+                                       }
 
-                               shrink_factor = cloth_shrink_factor(clmd, 
cloth->verts, spring->ij, spring->kl);
-                               spring->restlen = 
len_v3v3(cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest) * 
shrink_factor;
-                               spring->type = CLOTH_SPRING_TYPE_SHEAR;
-                               spring->stiffness = 
(cloth->verts[spring->kl].shear_stiff + cloth->verts[spring->ij].shear_stiff) / 
2.0f;
+                                       spring_verts_ordered_set(
+                                                       spring,
+                                                       
mloop[mpoly[i].loopstart + (j + 0)].v,
+                                                       
mloop[mpoly[i].loopstart + (j + 2)].v);
 
-                               BLI_linklist_append(&edgelist[spring->ij], 
spring);
-                               BLI_linklist_append(&edgelist[spring->kl], 
spring);
+                                       shrink_factor = 
cloth_shrink_factor(clmd, cloth->verts, spring->ij, spring->kl);
+                                       spring->restlen = 
len_v3v3(cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest) * 
shrink_factor;
+                                       spring->type = CLOTH_SPRING_TYPE_SHEAR;
+                                       spring->stiffness = 
(cloth->verts[spring->kl].shear_stiff + cloth->verts[spring->ij].shear_stiff) / 
2.0f;
+
+                                       
BLI_linklist_append(&edgelist[spring->ij], spring);
+                                       
BLI_linklist_append(&edgelist[spring->kl], spring);
 
-                               shear_springs++;
+                                       shear_springs++;
 
-                               BLI_linklist_prepend(&cloth->springs, spring);
+                                       BLI_linklist_prepend(&cloth->springs, 
spring);
+                               }
                        }
-               }
-       }
 
-       edgeset = BLI_edgeset_new_ex(__func__, numedges);
-       cloth->edgeset = edgeset;
+                       /* bending spring */
+                       ml = mloop + mpoly[i].loopstart;
 
-       if (numpolys) {
-               // bending springs
-               search2 = cloth->springs;
-               for ( i = struct_springs; i < struct_springs+shear_springs; i++ 
) {
-                       if ( !search2 )
-                               break;
+                       for (j = 0; j < mpoly[i].totloop; j++, ml++) {
+                               curr_ref = &spring_ref[ml->e];
+                               if (curr_ref->set == 1) {
+                                       /* Remove spring, because this is the 
third poly to use this edge */
+                                       if (curr_ref->spring) {
+                                               spring = 
BLI_linklist_pop(curr_ref->spring);
+                                               curr_ref->spring = NULL;
 
-                       tspring2 = search2->link;
-                       search = edgelist[tspring2->kl].list;
-                       while ( search ) {
-                               tspring = search->link;
-                               index2 = ( ( tspring->ij==tspring2->kl ) ? ( 
tspring->kl ) : ( tspring->ij ) );
-
-                               // check for existing spring
-                               // check also if startpoint is equal to endpoint
-                               if ((index2 != tspring2->ij) &&
-                                   !BLI_edgeset_haskey(edgeset, tspring2->ij, 
index2))
-                               {
-                                       spring = (ClothSpring *)MEM_callocN ( 
sizeof ( ClothSpring ), "cloth spring" );
+                                               MEM_freeN(spring->pa);
+                                               MEM_freeN(spring->pb);
+                                               MEM_freeN(spring);
+                                               curr_ref->set = -1;
 
-                                       if (!spring) {
-                                               cloth_free_errorsprings(cloth, 
edgelist);
-                                               return 0;
+                                               bend_springs--;
                                        }
+                                       /* Create spring, because this is the 
second poly to use this edge */
+                                       else {
+                                               int k;
+                                               MLoop *tmp_loop;
 
-                                       spring_verts_ordered_set(spring, 
tspring2->ij, index2);
-                                       shrink_factor = 
cloth_shrink_factor(clmd, cloth->verts, spring->ij, spring->kl);
-                                       spring->restlen = 
len_v3v3(cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest)

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to