[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [28978] trunk/blender/source/blender/ blenkernel/intern: Merge back a few cloth solver fixes from the render branch:

Brecht Van Lommel brecht at blender.org
Tue May 25 15:33:59 CEST 2010


Revision: 28978
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=28978
Author:   blendix
Date:     2010-05-25 15:33:59 +0200 (Tue, 25 May 2010)

Log Message:
-----------
Merge back a few cloth solver fixes from the render branch:

* Disable openmp for dot product, this gives different results each
  time due to non-commutative floating point add.
* Disable openmp with few vertices, the extra thread overhead only
  slows things down then.
* Replace the hack that would divide stepsPerFrame and then set it
  back, now it simply uses the timescale in the collision function.
  This was incorrect because stepsPerFrame is an int, but we don't
  want this to be rounded.
* Extra out of bounds check for hair velocity smoothing grid.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/cloth.c
    trunk/blender/source/blender/blenkernel/intern/collision.c
    trunk/blender/source/blender/blenkernel/intern/implicit.c

Modified: trunk/blender/source/blender/blenkernel/intern/cloth.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/cloth.c	2010-05-25 12:40:33 UTC (rev 28977)
+++ trunk/blender/source/blender/blenkernel/intern/cloth.c	2010-05-25 13:33:59 UTC (rev 28978)
@@ -27,17 +27,14 @@
 
 #include "MEM_guardedalloc.h"
 
-#include "BKE_cloth.h"
-
 #include "BKE_cdderivedmesh.h"
+#include "BKE_cloth.h"
 #include "BKE_effect.h"
 #include "BKE_global.h"
 #include "BKE_modifier.h"
+#include "BKE_pointcache.h"
 #include "BKE_utildefines.h"
 
-#include "BKE_pointcache.h"
-
-
 #ifdef _WIN32
 void tstart ( void )
 {}

Modified: trunk/blender/source/blender/blenkernel/intern/collision.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/collision.c	2010-05-25 12:40:33 UTC (rev 28977)
+++ trunk/blender/source/blender/blenkernel/intern/collision.c	2010-05-25 13:33:59 UTC (rev 28978)
@@ -59,7 +59,7 @@
 /* step is limited from 0 (frame start position) to 1 (frame end position) */
 void collision_move_object ( CollisionModifierData *collmd, float step, float prevstep )
 {
-	float tv[3] = {0,0,0};
+	float tv[3] = {0, 0, 0};
 	unsigned int i = 0;
 
 	for ( i = 0; i < collmd->numverts; i++ )
@@ -69,6 +69,7 @@
 		VECADDS ( collmd->current_xnew[i].co, collmd->x[i].co, tv, step );
 		VECSUB ( collmd->current_v[i].co, collmd->current_xnew[i].co, collmd->current_x[i].co );
 	}
+
 	bvhtree_update_from_mvert ( collmd->bvhtree, collmd->mfaces, collmd->numfaces, collmd->current_x, collmd->current_xnew, collmd->numverts, 1 );
 }
 
@@ -527,7 +528,7 @@
 			float magtangent = 0, repulse = 0, d = 0;
 			double impulse = 0.0;
 			float vrel_t_pre[3];
-			float temp[3];
+			float temp[3], spf;
 
 			// calculate tangential velocity
 			VECCOPY ( temp, collpair->normal );
@@ -565,10 +566,12 @@
 
 			// Apply repulse impulse if distance too short
 			// I_r = -min(dt*kd, m(0,1d/dt - v_n))
+			spf = (float)clmd->sim_parms->stepsPerFrame / clmd->sim_parms->timescale;
+
 			d = clmd->coll_parms->epsilon*8.0/9.0 + epsilon2*8.0/9.0 - collpair->distance;
-			if ( ( magrelVel < 0.1*d*clmd->sim_parms->stepsPerFrame ) && ( d > ALMOST_ZERO ) )
+			if ( ( magrelVel < 0.1*d*spf ) && ( d > ALMOST_ZERO ) )
 			{
-				repulse = MIN2 ( d*1.0/clmd->sim_parms->stepsPerFrame, 0.1*d*clmd->sim_parms->stepsPerFrame - magrelVel );
+				repulse = MIN2 ( d*1.0/spf, 0.1*d*spf - magrelVel );
 
 				// stay on the safe side and clamp repulse
 				if ( impulse > ALMOST_ZERO )
@@ -1541,20 +1544,15 @@
 			overlap = BLI_bvhtree_overlap ( cloth_bvh, collmd->bvhtree, &result );
 				
 			// go to next object if no overlap is there
-			if(!result || !overlap)
-			{
-				if ( overlap )
-					MEM_freeN ( overlap );
-				continue;
-			}
+			if( result && overlap ) {
+				/* check if collisions really happen (costly near check) */
+				cloth_bvh_objcollisions_nearcheck ( clmd, collmd, &collisions[i], &collisions_index[i], result, overlap);
 			
-			/* check if collisions really happen (costly near check) */
-			cloth_bvh_objcollisions_nearcheck ( clmd, collmd, &collisions[i], &collisions_index[i], result, overlap);
-			
-			// resolve nearby collisions
-			ret += cloth_bvh_objcollisions_resolve ( clmd, collmd, collisions[i],  collisions_index[i]);
-			ret2 += ret;
-			
+				// resolve nearby collisions
+				ret += cloth_bvh_objcollisions_resolve ( clmd, collmd, collisions[i],  collisions_index[i]);
+				ret2 += ret;
+			}
+
 			if ( overlap )
 				MEM_freeN ( overlap );
 		}

Modified: trunk/blender/source/blender/blenkernel/intern/implicit.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/implicit.c	2010-05-25 12:40:33 UTC (rev 28977)
+++ trunk/blender/source/blender/blenkernel/intern/implicit.c	2010-05-25 13:33:59 UTC (rev 28978)
@@ -37,6 +37,10 @@
 #include "BKE_global.h"
 #include "BKE_utildefines.h"
 
+#include "BLI_threads.h"
+
+#define CLOTH_OPENMP_LIMIT 25
+
 #ifdef _WIN32
 #include <windows.h>
 static LARGE_INTEGER _itstart, _itend;
@@ -230,8 +234,11 @@
 {
 	long i = 0;
 	float temp = 0.0;
+// XXX brecht, disabled this for now (first schedule line was already disabled),
+// due to non-commutative nature of floating point ops this makes the sim give
+// different results each time you run it!
 // schedule(guided, 2)
-#pragma omp parallel for reduction(+: temp)
+//#pragma omp parallel for reduction(+: temp) if(verts > CLOTH_OPENMP_LIMIT)
 	for(i = 0; i < (long)verts; i++)
 	{
 		temp += INPR(fLongVectorA[i], fLongVectorB[i]);
@@ -577,11 +584,12 @@
 DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector *fLongVector)
 {
 	unsigned int i = 0;
-	lfVector *temp = create_lfvector(from[0].vcount);
+	unsigned int vcount = from[0].vcount;
+	lfVector *temp = create_lfvector(vcount);
 	
-	zero_lfvector(to, from[0].vcount);
+	zero_lfvector(to, vcount);
 
-#pragma omp parallel sections private(i)
+#pragma omp parallel sections private(i) if(vcount > CLOTH_OPENMP_LIMIT)
 	{
 #pragma omp section
 		{
@@ -962,7 +970,7 @@
 	unsigned int i = 0;
 	
 	// Take only the diagonal blocks of A
-// #pragma omp parallel for private(i)
+// #pragma omp parallel for private(i) if(lA[0].vcount > CLOTH_OPENMP_LIMIT)
 	for(i = 0; i<lA[0].vcount; i++)
 	{
 		// block diagonalizer
@@ -1460,6 +1468,8 @@
 		i = HAIR_GRID_INDEX(lX[v], gmin, gmax, 0);
 		j = HAIR_GRID_INDEX(lX[v], gmin, gmax, 1);
 		k = HAIR_GRID_INDEX(lX[v], gmin, gmax, 2);
+		if (i < 0 || j < 0 || k < 0 || i > 10 || j >= 10 || k >= 10)
+			continue;
 
 		grid[i][j][k].velocity[0] += lV[v][0];
 		grid[i][j][k].velocity[1] += lV[v][1];
@@ -1523,6 +1533,8 @@
 		i = HAIR_GRID_INDEX(lX[v], gmin, gmax, 0);
 		j = HAIR_GRID_INDEX(lX[v], gmin, gmax, 1);
 		k = HAIR_GRID_INDEX(lX[v], gmin, gmax, 2);
+		if (i < 0 || j < 0 || k < 0 || i > 10 || j >= 10 || k >= 10)
+			continue;
 
 		lF[v][0] += smoothfac * (grid[i][j][k].velocity[0] - lV[v][0]);
 		lF[v][1] += smoothfac * (grid[i][j][k].velocity[1] - lV[v][1]);
@@ -1537,6 +1549,7 @@
 
 	free_collider_cache(&colliders);
 }
+
 static void cloth_calc_force(ClothModifierData *clmd, float frame, lfVector *lF, lfVector *lX, lfVector *lV, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, ListBase *effectors, float time, fmatrix3x3 *M)
 {
 	/* Collect forces and derivatives:  F,dFdX,dFdV */
@@ -1731,9 +1744,10 @@
 	ClothVertex *verts = cloth->verts;
 	unsigned int numverts = cloth->numverts;
 	float dt = clmd->sim_parms->timescale / clmd->sim_parms->stepsPerFrame;
+	float spf = (float)clmd->sim_parms->stepsPerFrame / clmd->sim_parms->timescale;
 	Implicit_Data *id = cloth->implicit;
-	int result = 0;
-	
+	int do_extra_solve;
+
 	if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) /* do goal stuff */
 	{
 		for(i = 0; i < numverts; i++)
@@ -1778,60 +1792,50 @@
 
 		if(clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED && clmd->clothObject->bvhtree)
 		{
-			float temp = clmd->sim_parms->stepsPerFrame;
-			/* not too nice hack, but collisions need this correction -jahka */
-			clmd->sim_parms->stepsPerFrame /= clmd->sim_parms->timescale;
-
 			// collisions 
 			// itstart();
 			
 			// update verts to current positions
 			for(i = 0; i < numverts; i++)
-			{	
+			{
 				VECCOPY(verts[i].tx, id->Xnew[i]);
-				
+
 				VECSUB(verts[i].tv, verts[i].tx, verts[i].txold);
 				VECCOPY(verts[i].v, verts[i].tv);
 			}
-			
+
 			// call collision function
 			// TODO: check if "step" or "step+dt" is correct - dg
-			result = cloth_bvh_objcollision(ob, clmd, step/clmd->sim_parms->timescale, dt/clmd->sim_parms->timescale);
+			do_extra_solve = cloth_bvh_objcollision(ob, clmd, step/clmd->sim_parms->timescale, dt/clmd->sim_parms->timescale);
 			
-			// correct velocity again, just to be sure we had to change it due to adaptive collisions
-			for(i = 0; i < numverts; i++)
-			{
-				VECSUB(verts[i].tv, verts[i].tx, id->X[i]);
-			}
-			
 			// copy corrected positions back to simulation
 			for(i = 0; i < numverts; i++)
 			{		
-				if(result)
+				// correct velocity again, just to be sure we had to change it due to adaptive collisions
+				VECSUB(verts[i].tv, verts[i].tx, id->X[i]);
+
+				if(do_extra_solve)
 				{
 					
 					if((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (verts [i].flags & CLOTH_VERT_FLAG_PINNED))
 						continue;
-					
+
 					VECCOPY(id->Xnew[i], verts[i].tx);
 					VECCOPY(id->Vnew[i], verts[i].tv);
-					mul_v3_fl(id->Vnew[i], clmd->sim_parms->stepsPerFrame);
+					mul_v3_fl(id->Vnew[i], spf);
 				}
 			}
 			
-			/* restore original stepsPerFrame */
-			clmd->sim_parms->stepsPerFrame = temp;
-			
 			// X = Xnew;
 			cp_lfvector(id->X, id->Xnew, numverts);
-			
+
 			// if there were collisions, advance the velocity from v_n+1/2 to v_n+1
 			
-			if(result)
+			if(do_extra_solve)
 			{
 				// V = Vnew;
 				cp_lfvector(id->V, id->Vnew, numverts);
-				
+
 				// calculate 
 				cloth_calc_force(clmd, frame, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step+dt, id->M);	
 				
@@ -1851,7 +1855,6 @@
 		cp_lfvector(id->V, id->Vnew, numverts);
 		
 		step += dt;
-		
 	}
 
 	for(i = 0; i < numverts; i++)





More information about the Bf-blender-cvs mailing list