[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