[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [12085] branches/cloth/blender/source/ blender: arround 50% speedup in calculating spring force using OpenMP
Daniel Genrich
daniel.genrich at gmx.net
Tue Sep 18 16:05:36 CEST 2007
Revision: 12085
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=12085
Author: genscher
Date: 2007-09-18 16:05:36 +0200 (Tue, 18 Sep 2007)
Log Message:
-----------
arround 50% speedup in calculating spring force using OpenMP
Modified Paths:
--------------
branches/cloth/blender/source/blender/blenkernel/BKE_cloth.h
branches/cloth/blender/source/blender/blenkernel/intern/cloth.c
branches/cloth/blender/source/blender/blenkernel/intern/implicit.c
branches/cloth/blender/source/blender/makesdna/DNA_cloth_types.h
Modified: branches/cloth/blender/source/blender/blenkernel/BKE_cloth.h
===================================================================
--- branches/cloth/blender/source/blender/blenkernel/BKE_cloth.h 2007-09-18 14:01:33 UTC (rev 12084)
+++ branches/cloth/blender/source/blender/blenkernel/BKE_cloth.h 2007-09-18 14:05:36 UTC (rev 12085)
@@ -52,7 +52,9 @@
#define DO_INLINE
#endif
+#define CLOTH_MAX_THREAD 2
+
/* goal defines */
#define SOFTGOALSNAP 0.999f
@@ -103,6 +105,7 @@
typedef enum
{
CSPRING_FLAG_DEACTIVATE = (1 << 1),
+ CSPRING_FLAG_NEEDED = (1 << 2), // springs has values to be applied
} CSPRINGS_FLAGS;
// needed for buttons_object.c
Modified: branches/cloth/blender/source/blender/blenkernel/intern/cloth.c
===================================================================
--- branches/cloth/blender/source/blender/blenkernel/intern/cloth.c 2007-09-18 14:01:33 UTC (rev 12084)
+++ branches/cloth/blender/source/blender/blenkernel/intern/cloth.c 2007-09-18 14:05:36 UTC (rev 12085)
@@ -117,10 +117,6 @@
// { "Implicit C++", CM_IMPLICITCPP, implicitcpp_init, implicitcpp_solver, implicitcpp_free },
};
-#define DEBUG_CLOTH_VERBOSE 1000
-static int DEBUG_CLOTH = 0;
-
-
/* ********** cloth engine ******* */
/* Prototypes for internal functions.
*/
@@ -774,7 +770,7 @@
solvers [clmd->sim_parms.solver_type].solver (ob, framenr, clmd, effectors,0,0);
tend();
- printf("Cloth simulation time: %f\n", (float)tval());
+ // printf("Cloth simulation time: %f\n", (float)tval());
cloth_cache_set_frame(clmd, framenr);
Modified: branches/cloth/blender/source/blender/blenkernel/intern/implicit.c
===================================================================
--- branches/cloth/blender/source/blender/blenkernel/intern/implicit.c 2007-09-18 14:01:33 UTC (rev 12084)
+++ branches/cloth/blender/source/blender/blenkernel/intern/implicit.c 2007-09-18 14:05:36 UTC (rev 12085)
@@ -570,7 +570,7 @@
/* STATUS: verified */
DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, float (*fLongVector)[3])
{
- unsigned int i = 0,j=0;
+ unsigned int i = 0;
zero_lfvector(to, from[0].vcount);
/* process diagonal elements */
for(i = 0; i < from[0].vcount; i++)
@@ -579,7 +579,8 @@
}
/* process off-diagonal entries (every off-diagonal entry needs to be symmetric) */
-#pragma parallel for shared(to,from, fLongVector) private(i)
+ // TODO: pragma below is wrong, correct it!
+ // #pragma omp parallel for shared(to,from, fLongVector) private(i)
for(i = from[0].vcount; i < from[0].vcount+from[0].scount; i++)
{
// muladd_fmatrix_fvector(to[from[i].c], from[i].m, fLongVector[from[i].r]);
@@ -804,11 +805,13 @@
return 1;
}
+
DO_INLINE float fb(float length, float L)
{
float x = length/L;
return (-11.541f*pow(x,4)+34.193f*pow(x,3)-39.083f*pow(x,2)+23.116f*x-9.713f);
}
+
DO_INLINE float fbderiv(float length, float L)
{
float x = length/L;
@@ -827,6 +830,7 @@
else
return tempfb;
}
+
DO_INLINE float fbstar_jacobi(float length, float L, float kb, float cb)
{
float tempfb = kb * fb(length, L);
@@ -841,6 +845,7 @@
return kb * fbderiv(length, L);
}
}
+
DO_INLINE void filter(lfVector *V, fmatrix3x3 *S)
{
unsigned int i=0;
@@ -850,6 +855,7 @@
mul_fvector_fmatrix(V[S[i].r], V[S[i].r], S[i].m);
}
}
+
// block diagonalizer
void BuildPPinv(fmatrix3x3 *lA, fmatrix3x3 *P, fmatrix3x3 *Pinv, fmatrix3x3 *S, fmatrix3x3 *bigI)
{
@@ -874,6 +880,7 @@
}
}
+
int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S)
{
// Solves for unknown X in equation AX=B
@@ -1101,17 +1108,20 @@
mul_fmatrix_S(temp, k);
add_fmatrix_fmatrix(to, temp, to);
}
+
DO_INLINE void dfdx_spring_type2(float to[3][3], float dir[3],float length,float L,float k, float cb)
{
// return outerprod(dir,dir)*fbstar_jacobi(length, L, k, cb);
mul_fvectorT_fvectorS(to, dir, dir, fbstar_jacobi(length, L, k, cb));
}
+
DO_INLINE void dfdv_damp(float to[3][3], float dir[3], float damping)
{
// derivative of force wrt velocity.
// return outerprod(dir,dir) * damping;
mul_fvectorT_fvectorS(to, dir, dir, damping);
}
+
DO_INLINE void dfdx_spring(float to[3][3], float dir[3],float length,float L,float k)
{
// dir is unit length direction, rest is spring's restlength, k is spring constant.
@@ -1122,6 +1132,7 @@
sub_fmatrix_fmatrix(to, to, I);
mul_fmatrix_S(to, -k);
}
+
DO_INLINE void dfdx_damp(float to[3][3], float dir[3],float length,const float vel[3],float rest,float damping)
{
// inner spring damping vel is the relative velocity of the endpoints.
@@ -1132,7 +1143,7 @@
}
-DO_INLINE void calc_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVector *lF, lfVector *X, lfVector *V, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX)
+DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVector *lF, lfVector *X, lfVector *V, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX)
{
float extent[3];
float length = 0;
@@ -1142,25 +1153,28 @@
float L = s->restlen;
float cb = clmd->sim_parms.structural;
- float f[3] = {0,0,0};
+ float nullf[3] = {0,0,0};
float stretch_force[3] = {0,0,0};
float bending_force[3] = {0,0,0};
float damping_force[3] = {0,0,0};
- float dfdx[3][3]={ {0,0,0}, {0,0,0}, {0,0,0}};
- float dfdv[3][3];
- int needed = 0;
+ float nulldfdx[3][3]={ {0,0,0}, {0,0,0}, {0,0,0}};
Cloth *cloth = clmd->clothObject;
ClothVertex *verts = cloth->verts;
+
+ VECCOPY(s->f, nullf);
+ cp_fmatrix(s->dfdx, nulldfdx);
+ cp_fmatrix(s->dfdv, nulldfdx);
// calculate elonglation
VECSUB(extent, X[s->kl], X[s->ij]);
VECSUB(vel, V[s->kl], V[s->ij]);
length = sqrt(INPR(extent, extent));
+ s->flags &= ~CSPRING_FLAG_NEEDED;
-
if(length > ABS(ALMOST_ZERO))
{
+ /*
if(length>L)
{
if((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED)
@@ -1170,7 +1184,7 @@
return;
}
}
-
+ */
mul_fvector_S(dir, extent, 1.0f/length);
}
else
@@ -1184,55 +1198,37 @@
{
if(length > L) // only on elonglation
{
- needed++;
+ s->flags |= CSPRING_FLAG_NEEDED;
k = clmd->sim_parms.structural;
mul_fvector_S(stretch_force, dir, (k*(length-L)));
- VECADD(f, f, stretch_force);
+ VECADD(s->f, s->f, stretch_force);
// Ascher & Boxman, p.21: Damping only during elonglation
mul_fvector_S(damping_force, extent, clmd->sim_parms.Cdis * ((INPR(vel,extent)/length)));
- VECADD(f, f, damping_force);
+ VECADD(s->f, s->f, damping_force);
- dfdx_spring_type1(dfdx, dir,length,L,k);
+ dfdx_spring_type1(s->dfdx, dir,length,L,k);
- dfdv_damp(dfdv, dir,clmd->sim_parms.Cdis);
-
- sub_fmatrix_fmatrix(dFdV[s->ij].m, dFdV[s->ij].m, dfdv);
-
- sub_fmatrix_fmatrix(dFdV[s->kl].m, dFdV[s->kl].m, dfdv);
-
- add_fmatrix_fmatrix(dFdV[s->matrix_index].m, dFdV[s->matrix_index].m, dfdv);
-
+ dfdv_damp(s->dfdv, dir,clmd->sim_parms.Cdis);
}
}
else // calculate force of bending springs
{
if(length < L)
{
- k = clmd->sim_parms.bending;
+ s->flags |= CSPRING_FLAG_NEEDED;
+
+ k = clmd->sim_parms.bending;
- needed++;
-
mul_fvector_S(bending_force, dir, fbstar(length, L, k, cb));
- VECADD(f, f, bending_force);
+ VECADD(s->f, s->f, bending_force);
- dfdx_spring_type2(dfdx, dir,length,L,k, cb);
+ dfdx_spring_type2(s->dfdx, dir,length,L,k, cb);
}
}
-
- if(needed)
- {
- VECADD(lF[s->ij], lF[s->ij], f);
- VECSUB(lF[s->kl], lF[s->kl], f);
-
- sub_fmatrix_fmatrix(dFdX[s->ij].m, dFdX[s->ij].m, dfdx);
- sub_fmatrix_fmatrix(dFdX[s->kl].m, dFdX[s->kl].m, dfdx);
-
- add_fmatrix_fmatrix(dFdX[s->matrix_index].m, dFdX[s->matrix_index].m, dfdx);
- }
}
DO_INLINE void calculateTriangleNormal(float to[3], lfVector *X, MFace mface)
@@ -1275,7 +1271,7 @@
}
-void calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVector *lV, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, ListBase *effectors, float time)
+void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVector *lV, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, ListBase *effectors, float time)
{
/* Collect forces and derivatives: F,dFdX,dFdV */
Cloth *cloth = clmd->clothObject;
@@ -1332,9 +1328,10 @@
/* handle external forces like wind */
if(effectors)
{
- float wind[3] = {0,1.0f,0};
+ float wind[3] = {0.0f,1.0f,0.0f};
float force[3]= {0.0f, 0.0f, 0.0f};
-
+
+ #pragma omp parallel for private (i) shared(lF)
for(i = 0; i < cloth->numverts; i++)
{
float vertexnormal[3]={0,0,0};
@@ -1348,17 +1345,55 @@
VECADDS(lF[i], lF[i], wind_normalized, -calculateVertexWindForce(i, wind, vertexnormal));
}
}
-
+
/* calculate and apply spring forces */
+#pragma omp parallel private(i)
+ {
+#pragma omp for nowait
+ for(i = 0; i < cloth->numsprings/2; i++)
+ {
+ // only handle active springs
+ // if(((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED))
+ // {
+ cloth_calc_spring_force(clmd, &springs[i], lF, lX, lV, dFdV, dFdX);
+ // }
+ }
+#pragma omp for nowait
+ for(i = cloth->numsprings/2; i < cloth->numsprings; i++)
+ {
+ // only handle active springs
+ // if(((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED))
+ // {
+ cloth_calc_spring_force(clmd, &springs[i], lF, lX, lV, dFdV, dFdX);
+ // }
+ }
+#pragma omp for nowait
for(i = 0; i < cloth->numsprings; i++)
{
// only handle active springs
- if(((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED))
+ // if(((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED))
{
- calc_spring_force(clmd, &springs[i], lF, lX, lV, dFdV, dFdX);
+ ClothSpring *s = &springs[i];
+ if(s->flags & CSPRING_FLAG_NEEDED)
+ {
+ if(s->type != BENDING)
+ {
+ sub_fmatrix_fmatrix(dFdV[s->ij].m, dFdV[s->ij].m, s->dfdv);
+ sub_fmatrix_fmatrix(dFdV[s->kl].m, dFdV[s->kl].m, s->dfdv);
+ add_fmatrix_fmatrix(dFdV[s->matrix_index].m, dFdV[s->matrix_index].m, s->dfdv);
+ }
+
+ VECADD(lF[s->ij], lF[s->ij], s->f);
+ VECSUB(lF[s->kl], lF[s->kl], s->f);
+
+ sub_fmatrix_fmatrix(dFdX[s->ij].m, dFdX[s->ij].m, s->dfdx);
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list