[Bf-blender-cvs] [b6f0f8a5b5a] blender2.8: Cloth: Implement angular bending springs

Luca Rood noreply at git.blender.org
Fri Aug 31 16:41:24 CEST 2018


Commit: b6f0f8a5b5a4871603755d4413e47f054ecd5b68
Author: Luca Rood
Date:   Mon Dec 5 21:39:29 2016 -0200
Branches: blender2.8
https://developer.blender.org/rBb6f0f8a5b5a4871603755d4413e47f054ecd5b68

Cloth: Implement angular bending springs

This implements angular bending springs for cloth simulation. This also
adds shearing springs for n-gons.

This angular spring implementation does not include Jacobian matrices,
as the springs can exist between polygons of different vertex counts,
rendering their relationships asymmetrical, and thus impossible to solve
with the current implementation. This means that the bending component
is solved explicitly. However, this is usually not a big problem, as
bending springs contribute less to instability than structural springs.

The the old linear bending model can still be used, and is the default for
existing files, to keep compatibility. However, the new angular bending
model is the default for any new simulation.

This commit makes small breaking changes, in that shearing springs are
now created on n-gons (also in linear bending mode), while n-gons were
previously ignored.

Reviewed By: brecht

Differential Revision: http://developer.blender.org/D3662

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

M	release/scripts/addons
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/release/scripts/addons b/release/scripts/addons
index 371960484a3..6c3a46dc113 160000
--- a/release/scripts/addons
+++ b/release/scripts/addons
@@ -1 +1 @@
-Subproject commit 371960484a38fc64e0a2635170a41a0d8ab2f6bd
+Subproject commit 6c3a46dc113de870a03191e4c0685238b0823acd
diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h
index a099ae46d78..baf60397504 100644
--- a/source/blender/blenkernel/BKE_cloth.h
+++ b/source/blender/blenkernel/BKE_cloth.h
@@ -133,11 +133,17 @@ 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;
-	float	restlen;	/* The original length of the spring.	*/
-	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 */
+	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 lin_stiffness;	/* Linear stiffness factor from the vertex groups. */
+	float ang_stiffness;	/* Angular stiffness factor from the vertex groups. */
 	float editrestlen;
 
 	/* angular bending spring target and derivatives */
@@ -186,12 +192,12 @@ typedef enum {
 
 /* Spring types as defined in the paper.*/
 typedef enum {
-	CLOTH_SPRING_TYPE_STRUCTURAL  = (1 << 1),
-	CLOTH_SPRING_TYPE_SHEAR       = (1 << 2),
-	CLOTH_SPRING_TYPE_BENDING     = (1 << 3),
-	CLOTH_SPRING_TYPE_GOAL        = (1 << 4),
-	CLOTH_SPRING_TYPE_SEWING      = (1 << 5),
-	CLOTH_SPRING_TYPE_BENDING_ANG = (1 << 6),
+	CLOTH_SPRING_TYPE_STRUCTURAL   = (1 << 1),
+	CLOTH_SPRING_TYPE_SHEAR        = (1 << 2),
+	CLOTH_SPRING_TYPE_BENDING      = (1 << 3),
+	CLOTH_SPRING_TYPE_GOAL         = (1 << 4),
+	CLOTH_SPRING_TYPE_SEWING       = (1 << 5),
+	CLOTH_SPRING_TYPE_BENDING_HAIR = (1 << 6),
 } CLOTH_SPRING_TYPES;
 
 /* SPRING FLAGS */
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index 54236785509..ce723d4a7f2 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -68,6 +68,12 @@ static void cloth_update_spring_lengths( ClothModifierData *clmd, Mesh *mesh );
 static int cloth_build_springs ( ClothModifierData *clmd, Mesh *mesh );
 static void cloth_apply_vgroup ( ClothModifierData *clmd, Mesh *mesh );
 
+typedef struct BendSpringRef {
+	int index;
+	int polys;
+	ClothSpring *spring;
+} BendSpringRef;
+
 /******************************************************************************
  *
  * External interface called by modifier.c clothModifier functions.
@@ -536,6 +542,9 @@ void cloth_free_modifier(ClothModifierData *clmd )
 			while (search) {
 				ClothSpring *spring = search->link;
 
+				MEM_SAFE_FREE(spring->pa);
+				MEM_SAFE_FREE(spring->pb);
+
 				MEM_freeN ( spring );
 				search = search->next;
 			}
@@ -602,6 +611,9 @@ void cloth_free_modifier_extern(ClothModifierData *clmd )
 			while (search) {
 				ClothSpring *spring = search->link;
 
+				MEM_SAFE_FREE(spring->pa);
+				MEM_SAFE_FREE(spring->pb);
+
 				MEM_freeN ( spring );
 				search = search->next;
 			}
@@ -961,13 +973,16 @@ static void cloth_free_edgelist(LinkNodePair *edgelist, unsigned int mvert_num)
 	}
 }
 
-static void cloth_free_errorsprings(Cloth *cloth, LinkNodePair *edgelist)
+static void cloth_free_errorsprings(Cloth *cloth, LinkNodePair *edgelist, BendSpringRef *spring_ref)
 {
 	if ( cloth->springs != NULL ) {
 		LinkNode *search = cloth->springs;
 		while (search) {
 			ClothSpring *spring = search->link;
 
+			MEM_SAFE_FREE(spring->pa);
+			MEM_SAFE_FREE(spring->pb);
+
 			MEM_freeN ( spring );
 			search = search->next;
 		}
@@ -978,12 +993,49 @@ static void cloth_free_errorsprings(Cloth *cloth, LinkNodePair *edgelist)
 
 	cloth_free_edgelist(edgelist, cloth->mvert_num);
 
+	MEM_SAFE_FREE(spring_ref);
+
 	if (cloth->edgeset) {
 		BLI_edgeset_free(cloth->edgeset);
 		cloth->edgeset = NULL;
 	}
 }
 
+BLI_INLINE void cloth_bend_poly_dir(ClothVertex *verts, int i, int j, int *inds, int len, float r_dir[3])
+{
+	float cent[3] = {0};
+	float fact = 1.0f / len;
+
+	for (int x = 0; x < len; x++) {
+		madd_v3_v3fl(cent, verts[inds[x]].xrest, fact);
+	}
+
+	normal_tri_v3(r_dir, verts[i].xrest, verts[j].xrest, cent);
+}
+
+static float cloth_spring_angle(ClothVertex *verts, int i, int j, int *i_a, int *i_b, int len_a, int len_b)
+{
+	float dir_a[3], dir_b[3];
+	float tmp[3], vec_e[3];
+	float sin, cos;
+
+	/* Poly vectors. */
+	cloth_bend_poly_dir(verts, j, i, i_a, len_a, dir_a);
+	cloth_bend_poly_dir(verts, i, j, i_b, len_b, dir_b);
+
+	/* Edge vector. */
+	sub_v3_v3v3(vec_e, verts[i].xrest, verts[j].xrest);
+	normalize_v3(vec_e);
+
+	/* Compute angle. */
+	cos = dot_v3v3(dir_a, dir_b);
+
+	cross_v3_v3v3(tmp, dir_a, dir_b);
+	sin = dot_v3v3(tmp, vec_e);
+
+	return atan2f(sin, cos);
+}
+
 static void cloth_hair_update_bending_targets(ClothModifierData *clmd)
 {
 	Cloth *cloth = clmd->clothObject;
@@ -1008,7 +1060,7 @@ static void cloth_hair_update_bending_targets(ClothModifierData *clmd)
 		ClothHairData *hair_ij, *hair_kl;
 		bool is_root = spring->kl != prev_mn;
 
-		if (spring->type != CLOTH_SPRING_TYPE_BENDING_ANG) {
+		if (spring->type != CLOTH_SPRING_TYPE_BENDING_HAIR) {
 			continue;
 		}
 
@@ -1083,7 +1135,7 @@ static void cloth_hair_update_bending_rest_targets(ClothModifierData *clmd)
 		ClothHairData *hair_ij, *hair_kl;
 		bool is_root = spring->kl != prev_mn;
 
-		if (spring->type != CLOTH_SPRING_TYPE_BENDING_ANG) {
+		if (spring->type != CLOTH_SPRING_TYPE_BENDING_HAIR) {
 			continue;
 		}
 
@@ -1123,18 +1175,24 @@ static void cloth_update_springs( ClothModifierData *clmd )
 	while (search) {
 		ClothSpring *spring = search->link;
 
-		spring->stiffness = 0.0f;
+		spring->lin_stiffness = 0.0f;
+
+		if (clmd->sim_parms->bending_model == CLOTH_BENDING_ANGULAR) {
+			if (spring->type & CLOTH_SPRING_TYPE_BENDING) {
+				spring->ang_stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0f;
+			}
+		}
 
-		if (spring->type == CLOTH_SPRING_TYPE_STRUCTURAL) {
-			spring->stiffness = (cloth->verts[spring->kl].struct_stiff + cloth->verts[spring->ij].struct_stiff) / 2.0f;
+		if (spring->type & CLOTH_SPRING_TYPE_STRUCTURAL) {
+			spring->lin_stiffness = (cloth->verts[spring->kl].struct_stiff + cloth->verts[spring->ij].struct_stiff) / 2.0f;
 		}
-		else if (spring->type == CLOTH_SPRING_TYPE_SHEAR) {
-			spring->stiffness = (cloth->verts[spring->kl].shear_stiff + cloth->verts[spring->ij].shear_stiff) / 2.0f;
+		else if (spring->type & CLOTH_SPRING_TYPE_SHEAR) {
+			spring->lin_stiffness = (cloth->verts[spring->kl].shear_stiff + cloth->verts[spring->ij].shear_stiff) / 2.0f;
 		}
 		else if (spring->type == CLOTH_SPRING_TYPE_BENDING) {
-			spring->stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0f;
+			spring->lin_stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0f;
 		}
-		else if (spring->type == CLOTH_SPRING_TYPE_BENDING_ANG) {
+		else if (spring->type == CLOTH_SPRING_TYPE_BENDING_HAIR) {
 			ClothVertex *v1 = &cloth->verts[spring->ij];
 			ClothVertex *v2 = &cloth->verts[spring->kl];
 			if (clmd->hairdata) {
@@ -1142,7 +1200,7 @@ static void cloth_update_springs( ClothModifierData *clmd )
 				v1->bend_stiff = clmd->hairdata[spring->ij].bending_stiffness;
 				v2->bend_stiff = clmd->hairdata[spring->kl].bending_stiffness;
 			}
-			spring->stiffness = (v1->bend_stiff + v2->bend_stiff) / 2.0f;
+			spring->lin_stiffness = (v1->bend_stiff + v2->bend_stiff) / 2.0f;
 		}
 		else if (spring->type == CLOTH_SPRING_TYPE_GOAL) {
 			/* Warning: Appending NEW goal springs does not work because implicit solver would need reset! */
@@ -1197,16 +1255,23 @@ static void cloth_update_spring_lengths( ClothModifierData *clmd, Mesh *mesh )
 	while (search) {
 		ClothSpring *spring = search->link;
 
-		if ( spring->type != CLOTH_SPRING_TYPE_SEWING ) {
-			if ( spring->type & (CLOTH_SPRING_TYPE_STRUCTURAL | CLOTH_SPRING_TYPE_SHEAR | CLOTH_SPRING_TYPE_BENDING) )
+		if (spring->type != CLOTH_SPRING_TYPE_SEWING) {
+			if (spring->type & (CLOTH_SPRING_TYPE_STRUCTURAL | CLOTH_SPRING_TYPE_SHEAR | CLOTH_SPRING_TYPE_BENDING)) {
 				shrink_factor = cloth_shrink_factor(clmd, cloth->verts, spring->ij, spring->kl);
-			else
+			}
+			else {
 				shrink_factor = 1.0f;
+			}
 
 			spring->restlen = len_v3v3(cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest) * shrink_factor;
+
+			if (spring->type & CLOTH_SPRING_TYPE_BENDING) {
+				spring->restang = cloth_spring_angle(cloth->verts, spring->ij, spring->kl,
+				                                     spring->pa, spring->pb, spring->la, spring->lb);
+			}
 		}
 
-		if ( spring->type == CLOTH_SPRING_TYPE_STRUCTURAL ) {
+		if (spring->type & CLOTH_SPRING_TYPE_STRUCTURAL) {
 			clmd->sim_parms->avg_spring_len += spring->restlen;
 			cloth->verts[spring->ij].avg_spring_len += spring->restlen;
 			cloth->verts[spring->kl].avg_spring_len += spring->restlen;
@@ -1216,12 +1281,14 @@ static void cloth_update_spring_lengths( ClothModifierData *clmd, Mesh *mesh )
 		search = search->next;
 	}
 
-	if (struct_springs > 0)
+	if (struct_springs > 0) {
 		clmd->sim_parms->avg_spring_len /= struct_springs;
+	}
 
 	for (i = 0; i < mvert_num; i++) {
-		if (cloth->verts[i].spring_count > 0)
+		if (cloth->verts[i].spring_count > 0) {
 			cloth->verts[i].avg_spring_len = cloth->verts[i].avg_spring_len * 0.49f / ((float)cloth->verts[i].spring_count);
+		}
 	}
 }
 
@@ -1260,12 +1327,103 @@ void cloth_parallel_transport_hair_frame(float mat[3][3], const float dir_old[3]
 	mul_m3_m3m3(mat,

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list