[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [43669] trunk/blender/source/blender/ blenkernel/intern/dynamicpaint.c: Dynamic Paint:

Miika Hamalainen miika.hamalainen at kolumbus.fi
Tue Jan 24 18:29:04 CET 2012


Revision: 43669
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=43669
Author:   miikah
Date:     2012-01-24 17:28:50 +0000 (Tue, 24 Jan 2012)
Log Message:
-----------
Dynamic Paint:
* Fix: Substep update failed if brush was parented to a canvas vertex. Now substeps are ignored in such case.
* Fix: Wave "open borders" option didn't work for image sequence format.
* Fixed a possible crash after changing surface format to image sequence.
* Some code cleanup.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/dynamicpaint.c

Modified: trunk/blender/source/blender/blenkernel/intern/dynamicpaint.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/dynamicpaint.c	2012-01-24 16:54:21 UTC (rev 43668)
+++ trunk/blender/source/blender/blenkernel/intern/dynamicpaint.c	2012-01-24 17:28:50 UTC (rev 43669)
@@ -97,6 +97,10 @@
 /* brush mesh raycast status */
 #define HIT_VOLUME 1
 #define HIT_PROXIMITY 2
+/* dynamicPaint_findNeighbourPixel() return codes */
+#define NOT_FOUND -1
+#define ON_MESH_EDGE -2
+#define OUT_OF_TEXTURE -3
 /* paint effect default movement per frame in global units */
 #define EFF_MOVEMENT_PER_FRAME 0.05f
 /* initial wave time factor */
@@ -134,10 +138,10 @@
 	float v[3];
 } Vec3f;
 
-typedef struct BakeNeighPoint {
+typedef struct BakeAdjPoint {
 	float dir[3];	/* vector pointing towards this neighbour */
 	float dist;		/* distance to */
-} BakeNeighPoint;
+} BakeAdjPoint;
 
 /* Surface data used while processing a frame	*/
 typedef struct PaintBakeNormal {
@@ -156,7 +160,7 @@
 	Bounds3D mesh_bounds;
 
 	/* adjacency info */
-	BakeNeighPoint *bNeighs; /* current global neighbour distances and directions, if required */
+	BakeAdjPoint *bNeighs; /* current global neighbour distances and directions, if required */
 	double average_dist;
 	/* space partitioning */
 	VolumeGrid *grid;		/* space partitioning grid to optimize brush checks */
@@ -188,13 +192,6 @@
 	Vec3f *barycentricWeights;		/* b-weights for all pixel samples */
 } ImgSeqFormatData;
 
-#if 0 /* UNUSED */
-typedef struct EffVelPoint {
-	float previous_pos[3];
-	float previous_vel[3];
-} EffVelPoint;
-#endif
-
 /* adjacency data flags */
 #define ADJ_ON_MESH_EDGE (1<<0)
 
@@ -470,20 +467,26 @@
 	BLI_freelistN(&pidlist);
 }
 
-static void subframe_updateObject(Scene *scene, Object *ob, int flags, float frame)
+static int subframe_updateObject(Scene *scene, Object *ob, int flags, float frame)
 {
 	DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)modifiers_findByType(ob, eModifierType_DynamicPaint);
 	bConstraint *con;
 
 	/* if other is dynamic paint canvas, dont update */
 	if (pmd && pmd->canvas)
-		return;
+		return 1;
 
 	/* if object has parents, update them too */
 	if (flags & UPDATE_PARENTS) {
-		if (ob->parent) subframe_updateObject(scene, ob->parent, 0, frame);
-		if (ob->track) subframe_updateObject(scene, ob->track, 0, frame);
+		int is_canvas = 0;
+		if (ob->parent) is_canvas += subframe_updateObject(scene, ob->parent, 0, frame);
+		if (ob->track) is_canvas += subframe_updateObject(scene, ob->track, 0, frame);
 
+		/* skip subframe if object is parented
+		*  to vertex of a dynamic paint canvas */
+		if (is_canvas && (ob->partype == PARVERT1 || ob->partype == PARVERT3))
+			return 0;
+
 		/* also update constraint targets */
 		for (con = ob->constraints.first; con; con=con->next) {
 			bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
@@ -519,6 +522,8 @@
 	}
 	else
 		where_is_object_time(scene, ob, frame);
+
+	return 0;
 }
 
 static void scene_setSubframe(Scene *scene, float subframe)
@@ -1222,7 +1227,7 @@
 static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface, int force_init)
 {
 	PaintSurfaceData *sData = surface->data;
-	PaintAdjData *ed;
+	PaintAdjData *ad;
 	int *temp_data;
 	int neigh_points = 0;
 
@@ -1238,17 +1243,17 @@
 	if (!neigh_points) return;
 
 	/* allocate memory */
-	ed = sData->adj_data = MEM_callocN(sizeof(PaintAdjData), "Surface Adj Data");
-	if (!ed) return;
-	ed->n_index = MEM_callocN(sizeof(int)*sData->total_points, "Surface Adj Index");
-	ed->n_num = MEM_callocN(sizeof(int)*sData->total_points, "Surface Adj Counts");
+	ad = sData->adj_data = MEM_callocN(sizeof(PaintAdjData), "Surface Adj Data");
+	if (!ad) return;
+	ad->n_index = MEM_callocN(sizeof(int)*sData->total_points, "Surface Adj Index");
+	ad->n_num = MEM_callocN(sizeof(int)*sData->total_points, "Surface Adj Counts");
 	temp_data = MEM_callocN(sizeof(int)*sData->total_points, "Temp Adj Data");
-	ed->n_target = MEM_callocN(sizeof(int)*neigh_points, "Surface Adj Targets");
-	ed->flags = MEM_callocN(sizeof(int)*sData->total_points, "Surface Adj Flags");
-	ed->total_targets = neigh_points;
+	ad->n_target = MEM_callocN(sizeof(int)*neigh_points, "Surface Adj Targets");
+	ad->flags = MEM_callocN(sizeof(int)*sData->total_points, "Surface Adj Flags");
+	ad->total_targets = neigh_points;
 
 	/* in case of allocation error, free memory */
-	if (!ed->n_index || !ed->n_num || !ed->n_target || !temp_data) {
+	if (!ad->n_index || !ad->n_num || !ad->n_target || !temp_data) {
 		dynamicPaint_freeAdjData(sData);
 		if (temp_data) MEM_freeN(temp_data);
 		setError(surface->canvas, "Not enough free memory.");
@@ -1267,14 +1272,15 @@
 
 		/* count number of edges per vertex */
 		for (i=0; i<numOfEdges; i++) {
-			ed->n_num[edge[i].v1]++;
-			ed->n_num[edge[i].v2]++;
+			ad->n_num[edge[i].v1]++;
+			ad->n_num[edge[i].v2]++;
 
 			temp_data[edge[i].v1]++;
 			temp_data[edge[i].v2]++;
 		}
 
-		/* to locate points on "mesh edge" */
+		/* also add number of vertices to temp_data
+		*  to locate points on "mesh edge" */
 		for (i=0; i<numOfFaces; i++) {
 			temp_data[face[i].v1]++;
 			temp_data[face[i].v2]++;
@@ -1288,7 +1294,7 @@
 		for (i=0; i<sData->total_points; i++) {
 			if ((temp_data[i]%2) ||
 				temp_data[i] < 4)
-				ed->flags[i] |= ADJ_ON_MESH_EDGE;
+				ad->flags[i] |= ADJ_ON_MESH_EDGE;
 				
 			/* reset temp data */ 
 			temp_data[i] = 0;
@@ -1297,22 +1303,22 @@
 		/* order n_index array */
 		n_pos = 0;
 		for (i=0; i<sData->total_points; i++) {
-			ed->n_index[i] = n_pos;
-			n_pos += ed->n_num[i];
+			ad->n_index[i] = n_pos;
+			n_pos += ad->n_num[i];
 		}
 
 		/* and now add neighbour data using that info */
 		for (i=0; i<numOfEdges; i++) {
 			/* first vertex */
 			int index = edge[i].v1;
-			n_pos = ed->n_index[index]+temp_data[index];
-			ed->n_target[n_pos] = edge[i].v2;
+			n_pos = ad->n_index[index]+temp_data[index];
+			ad->n_target[n_pos] = edge[i].v2;
 			temp_data[index]++;
 
 			/* second vertex */
 			index = edge[i].v2;
-			n_pos = ed->n_index[index]+temp_data[index];
-			ed->n_target[n_pos] = edge[i].v1;
+			n_pos = ad->n_index[index]+temp_data[index];
+			ad->n_target[n_pos] = edge[i].v1;
 			temp_data[index]++;
 		}
 	}
@@ -1500,10 +1506,11 @@
 int dynamicPaint_resetSurface(DynamicPaintSurface *surface)
 {
 	int numOfPoints = dynamicPaint_surfaceNumOfPoints(surface);
-	/* dont touch image sequence types. they get handled only on bake */
+	/* free existing data */
+	if (surface->data) dynamicPaint_freeSurfaceData(surface);
+
+	/* dont reallocate for image sequence types. they get handled only on bake */
 	if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) return 1;
-
-	if (surface->data) dynamicPaint_freeSurfaceData(surface);
 	if (numOfPoints < 1) return 0;
 
 	/* allocate memory */
@@ -1899,8 +1906,8 @@
 	x = px + neighX[n_index];
 	y = py + neighY[n_index];
 
-	if (x<0 || x>=w) return -1;
-	if (y<0 || y>=h) return -1;
+	if (x<0 || x>=w) return OUT_OF_TEXTURE;
+	if (y<0 || y>=h) return OUT_OF_TEXTURE;
 
 	tPoint = &tempPoints[x+w*y];		/* UV neighbour */
 	cPoint = &tempPoints[px+w*py];		/* Origin point */
@@ -2013,8 +2020,8 @@
 				}
 			}
 
-			/* If none found return -1	*/
-			if (target_face == -1) return -1;
+			/* If none found pixel is on mesh edge	*/
+			if (target_face == -1) return ON_MESH_EDGE;
 
 			/*
 			*	If target face is connected in UV space as well, just use original index
@@ -2052,15 +2059,15 @@
 			final_pixel[1] = (int)floor(pixel[1]);
 
 			/* If current pixel uv is outside of texture	*/
-			if (final_pixel[0] < 0 || final_pixel[0] >= w) return -1;
-			if (final_pixel[1] < 0 || final_pixel[1] >= h) return -1;
+			if (final_pixel[0] < 0 || final_pixel[0] >= w) return OUT_OF_TEXTURE;
+			if (final_pixel[1] < 0 || final_pixel[1] >= h) return OUT_OF_TEXTURE;
 
 			final_index = final_pixel[0] + w * final_pixel[1];
 
 			/* If we ended up to our origin point ( mesh has smaller than pixel sized faces)	*/
-			if (final_index == (px+w*py)) return -1;
+			if (final_index == (px+w*py)) return NOT_FOUND;
 			/* If found pixel still lies on wrong face ( mesh has smaller than pixel sized faces)	*/
-			if (tempPoints[final_index].face_index != target_face) return -1;
+			if (tempPoints[final_index].face_index != target_face) return NOT_FOUND;
 
 			/*
 			*	If final point is an "edge pixel", use it's "real" neighbour instead
@@ -2442,11 +2449,14 @@
 								*  If not found, -1 is returned */
 								int n_target = dynamicPaint_findNeighbourPixel(tempPoints, dm, uvname, w, h, tx, ty, i);
 
-								if (n_target != -1) {
+								if (n_target >= 0) {
 									ed->n_target[n_pos] = final_index[n_target];
 									ed->n_num[final_index[index]]++;
 									n_pos++;
 								}
+								else if (n_target == ON_MESH_EDGE || n_target == OUT_OF_TEXTURE) {
+									ed->flags[final_index[index]] |= ADJ_ON_MESH_EDGE;
+								}
 							}
 						}
 					}
@@ -3147,8 +3157,8 @@
 			mul_m4_v3(brushOb->obmat, mvert[ii].co);
 			boundInsert(&mesh_bb, mvert[ii].co);
 
-			/* for project brush calculate average normal */
-			if (brush->flags & MOD_DPAINT_PROX_PROJECT) {
+			/* for proximity project calculate average normal */
+			if (brush->flags & MOD_DPAINT_PROX_PROJECT && brush->collision != MOD_DPAINT_COL_VOLUME) {
 				float nor[3];
 				normal_short_to_float_v3(nor, mvert[ii].no);
 				mul_mat3_m4_v3(brushOb->obmat, nor);
@@ -3158,7 +3168,7 @@
 			}
 		}
 
-		if (brush->flags & MOD_DPAINT_PROX_PROJECT) {
+		if (brush->flags & MOD_DPAINT_PROX_PROJECT && brush->collision != MOD_DPAINT_COL_VOLUME) {
 			mul_v3_fl(avg_brushNor, 1.0f/(float)numOfVerts);
 			/* instead of null vector use positive z */
 			if (!(MIN3(avg_brushNor[0],avg_brushNor[1],avg_brushNor[2])))
@@ -3855,14 +3865,13 @@
 /***************************** Dynamic Paint Step / Baking ******************************/
 
 /*
-*	Calculate current frame neighbouring point distances
-*	and direction vectors
+*	Calculate current frame distances and directions for adjacency data
 */
-static void dynamicPaint_prepareNeighbourData(DynamicPaintSurface *surface, int force_init)
+static void dynamicPaint_prepareAdjacencyData(DynamicPaintSurface *surface, int force_init)
 {
 	PaintSurfaceData *sData = surface->data;
 	PaintBakeData *bData = sData->bData;
-	BakeNeighPoint *bNeighs;
+	BakeAdjPoint *bNeighs;
 	PaintAdjData *adj_data = sData->adj_data;
 	Vec3f *realCoord = bData->realCoord;
 	int index;
@@ -3870,7 +3879,7 @@

@@ Diff output truncated at 10240 characters. @@


More information about the Bf-blender-cvs mailing list