Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiika Hamalainen <blender@miikah.org>2011-07-08 15:03:37 +0400
committerMiika Hamalainen <blender@miikah.org>2011-07-08 15:03:37 +0400
commitf8f1cbd17f2b0c624d88ee7f7502e544472b4b6e (patch)
tree498fa319d91816109a7bd08f10ebfe7dc1c2c984 /source/blender/blenkernel
parent901f24716b70e961a28fabc5820ced0983b025e0 (diff)
Dynamic Paint:
* Canvas and brush can be now enabled simultaneously. This way it's possible for two canvases to interact. * Added basic anti-aliasing support for vertex surfaces. * 3D-view color preview now works even when there's subsurf modifier after Dynamic Paint in modifier stack. * Added a new brush option to use proximity from object center. * Default surface frame range now use scene's start and end values. * Improved ray checks for volume brushes. * Added new "non-closed" option for volume brushes. This way it's possible to use planar meshes as "volume" brushes with predefined ray direction. * New carrot branch splash image by CGEffex. * Improved brush affection code. * Lots of smaller improvements. * Fixed: Weight paint didn't work with particles. * Fixed: Point cache didn't work for non-wave surfaces anymore since last commit.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_dynamicpaint.h2
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c7
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c681
-rw-r--r--source/blender/blenkernel/intern/particle.c2
-rw-r--r--source/blender/blenkernel/intern/pointcache.c8
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c6
6 files changed, 445 insertions, 261 deletions
diff --git a/source/blender/blenkernel/BKE_dynamicpaint.h b/source/blender/blenkernel/BKE_dynamicpaint.h
index 5c041cb4a5b..e8e932da97e 100644
--- a/source/blender/blenkernel/BKE_dynamicpaint.h
+++ b/source/blender/blenkernel/BKE_dynamicpaint.h
@@ -28,7 +28,6 @@ typedef struct PaintSurfaceData {
struct PaintAdjData *adj_data;
unsigned int total_points;
- short samples;
} PaintSurfaceData;
@@ -63,7 +62,6 @@ typedef struct PaintWavePoint {
struct DerivedMesh *dynamicPaint_Modifier_do(struct DynamicPaintModifierData *pmd, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm);
void dynamicPaint_Modifier_free (struct DynamicPaintModifierData *pmd);
-void dynamicPaint_Modifier_createType(struct DynamicPaintModifierData *pmd);
void dynamicPaint_Modifier_copy(struct DynamicPaintModifierData *pmd, struct DynamicPaintModifierData *tsmd);
void dynamicPaint_cacheUpdateFrames(struct DynamicPaintSurface *surface);
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index d9c98bc0200..ebf21941706 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -1669,7 +1669,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
Mesh *me = ob->data;
ModifierData *firstmd, *md;
LinkNode *datamasks, *curr;
- CustomDataMask mask, nextmask;
+ CustomDataMask mask, nextmask, append_mask = 0;
float (*deformedVerts)[3] = NULL;
DerivedMesh *dm, *orcodm, *clothorcodm, *finaldm;
int numVerts = me->totvert;
@@ -1883,6 +1883,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
/* set the DerivedMesh to only copy needed data */
mask= (CustomDataMask)GET_INT_FROM_POINTER(curr->link);
+ mask |= append_mask;
DM_set_only_copy(dm, mask);
/* add cloth rest shape key if need */
@@ -1941,6 +1942,10 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
clothorcodm = ndm;
}
}
+
+ /* in case of dynamic paint, make sure preview mask remains for following modifiers */
+ if (md->type == eModifierType_DynamicPaint)
+ append_mask |= CD_MASK_WEIGHT_MCOL;
}
isPrevDeform= (mti->type == eModifierTypeType_OnlyDeform);
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index e36167fb23f..c8a7c76e725 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -58,6 +58,10 @@
#include "DNA_scene_types.h"
#include "DNA_userdef_types.h" /* to get temp file path */
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
/* for bake operator */
#include "ED_screen.h"
#include "WM_types.h"
@@ -82,7 +86,6 @@
#include "DNA_material_types.h"
#include "RE_render_ext.h"
-
#define DPOUTPUT_JPEG 0
#define DPOUTPUT_PNG 1
#define DPOUTPUT_OPENEXR 2
@@ -91,15 +94,6 @@ struct Object;
struct Scene;
struct DerivedMesh;
-/*
-* Init predefined antialias jitter data
-*/
-float jitterDistances[5] = {0.0f,
- 0.447213595f,
- 0.447213595f,
- 0.447213595f,
- 0.5f};
-
/* precalculated gaussian factors for 5x super sampling */
float gaussianFactors[5] = { 0.996849f,
0.596145f,
@@ -140,8 +134,10 @@ typedef struct PaintBakePoint {
typedef struct PaintBakeData {
PaintBakePoint *bPoint;
+ unsigned int *s_index; /* index to start reading point sample realcoords */
+ unsigned int *s_num; /* num of samples for each point */
float *realCoord; /* current pixel center world-space coordinates * numOfSamples
- * ordered as (total_points*sample+index)*3*/
+ * ordered as (s_index+sample_num)*3*/
} PaintBakeData;
/* UV Image sequence format point */
@@ -175,11 +171,11 @@ typedef struct BakeNeighPoint {
#define ADJ_ON_MESH_EDGE (1<<0)
typedef struct PaintAdjData {
- unsigned int *n_index; /* total_points sized index array */
- unsigned int *numOf_n; /* num of neighs for each point */
- unsigned int *n_target; /* array of neighbouring point indexes
- for single sample use n_index+neigh_num */
- unsigned int *flags; /* for each point */
+ unsigned int *n_target; /* array of neighbouring point indexes,
+ for single sample use (n_index+neigh_num) */
+ unsigned int *n_index; /* index to start reading n_target for each point */
+ unsigned int *n_num; /* num of neighs for each point */
+ unsigned int *flags; /* vertex adjacency flags */
unsigned int total_targets; /* size of n_target */
} PaintAdjData;
@@ -273,10 +269,12 @@ void dynamicPaintSurface_updateType(struct DynamicPaintSurface *surface) {
if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) {
surface->output_name[0]='\0';
surface->output_name2[0]='\0';
+ surface->flags |= MOD_DPAINT_ANTIALIAS;
}
else {
sprintf(surface->output_name, "dp_");
strcpy(surface->output_name2,surface->output_name);
+ surface->flags &= ~MOD_DPAINT_ANTIALIAS;
}
if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
@@ -355,14 +353,15 @@ static void dynamicPaint_freeBrush(struct DynamicPaintModifierData *pmd)
}
}
-static void dynamicPaint_freeEffectData(PaintSurfaceData *data)
+static void dynamicPaint_freeAdjData(PaintSurfaceData *data)
{
if (data->adj_data) {
if (data->adj_data->n_index) MEM_freeN(data->adj_data->n_index);
- if (data->adj_data->numOf_n) MEM_freeN(data->adj_data->numOf_n);
+ if (data->adj_data->n_num) MEM_freeN(data->adj_data->n_num);
if (data->adj_data->n_target) MEM_freeN(data->adj_data->n_target);
if (data->adj_data->flags) MEM_freeN(data->adj_data->flags);
MEM_freeN(data->adj_data);
+ data->adj_data = NULL;
}
}
@@ -382,7 +381,7 @@ static void dynamicPaint_freeSurfaceData(DynamicPaintSurface *surface)
MEM_freeN(data->format_data);
}
if (data->type_data) MEM_freeN(data->type_data);
- dynamicPaint_freeEffectData(data);
+ dynamicPaint_freeAdjData(data);
MEM_freeN(surface->data);
surface->data = NULL;
}
@@ -444,7 +443,7 @@ void dynamicPaint_Modifier_free(struct DynamicPaintModifierData *pmd)
* Creates a new surface and adds it to the list
* A pointer to this surface is returned
*/
-static DynamicPaintSurface *dynamicPaint_createNewSurface(DynamicPaintCanvasSettings *canvas)
+static DynamicPaintSurface *dynamicPaint_createNewSurface(DynamicPaintCanvasSettings *canvas, Scene *scene)
{
DynamicPaintSurface *surface= MEM_callocN(sizeof(DynamicPaintSurface), "DynamicPaintSurface");
if (!surface) return NULL;
@@ -471,9 +470,16 @@ static DynamicPaintSurface *dynamicPaint_createNewSurface(DynamicPaintCanvasSett
surface->image_fileformat = MOD_DPAINT_IMGFORMAT_PNG;
surface->image_resolution = 256;
- surface->start_frame = 1;
- surface->end_frame = 250;
- surface->substeps = 0;
+ surface->substeps = 0;
+
+ if (scene) {
+ surface->start_frame = scene->r.sfra;
+ surface->end_frame = scene->r.efra;
+ }
+ else {
+ surface->start_frame = 1;
+ surface->end_frame = 250;
+ }
surface->spread_speed = 1.0f;
surface->shrink_speed = 1.0f;
@@ -498,31 +504,36 @@ static DynamicPaintSurface *dynamicPaint_createNewSurface(DynamicPaintCanvasSett
/*
* Initialize modifier data
*/
-void dynamicPaint_Modifier_createType(struct DynamicPaintModifierData *pmd)
+int dynamicPaint_createType(struct DynamicPaintModifierData *pmd, int type, struct Scene *scene)
{
if(pmd)
{
- if(pmd->type & MOD_DYNAMICPAINT_TYPE_CANVAS)
+ if(type == MOD_DYNAMICPAINT_TYPE_CANVAS)
{
if(pmd->canvas)
dynamicPaint_freeCanvas(pmd);
pmd->canvas = MEM_callocN(sizeof(DynamicPaintCanvasSettings), "DynamicPaint Canvas");
+ if (!pmd->canvas)
+ return 0;
pmd->canvas->pmd = pmd;
pmd->canvas->dm = NULL;
/* Create one surface */
- dynamicPaint_createNewSurface(pmd->canvas);
+ if (!dynamicPaint_createNewSurface(pmd->canvas, scene))
+ return 0;
pmd->canvas->ui_info[0] = '\0';
}
- else if(pmd->type & MOD_DYNAMICPAINT_TYPE_BRUSH)
+ else if(type == MOD_DYNAMICPAINT_TYPE_BRUSH)
{
if(pmd->brush)
dynamicPaint_freeBrush(pmd);
pmd->brush = MEM_callocN(sizeof(DynamicPaintBrushSettings), "DynamicPaint Paint");
+ if (!pmd->brush)
+ return 0;
pmd->brush->pmd = pmd;
pmd->brush->psys = NULL;
@@ -557,6 +568,8 @@ void dynamicPaint_Modifier_createType(struct DynamicPaintModifierData *pmd)
CBData *ramp;
pmd->brush->paint_ramp = add_colorband(0);
+ if (!pmd->brush->paint_ramp)
+ return 0;
ramp = pmd->brush->paint_ramp->data;
/* Add default smooth-falloff ramp. */
ramp[0].r = ramp[0].g = ramp[0].b = ramp[0].a = 1.0f;
@@ -567,13 +580,20 @@ void dynamicPaint_Modifier_createType(struct DynamicPaintModifierData *pmd)
}
}
}
+ else
+ return 0;
+
+ return 1;
}
void dynamicPaint_Modifier_copy(struct DynamicPaintModifierData *pmd, struct DynamicPaintModifierData *tpmd)
{
/* Init modifier */
tpmd->type = pmd->type;
- dynamicPaint_Modifier_createType(tpmd);
+ if (pmd->canvas)
+ dynamicPaint_createType(tpmd, MOD_DYNAMICPAINT_TYPE_CANVAS, NULL);
+ if (pmd->brush)
+ dynamicPaint_createType(tpmd, MOD_DYNAMICPAINT_TYPE_BRUSH, NULL);
/* Copy data */
if (tpmd->canvas) {
@@ -581,33 +601,6 @@ void dynamicPaint_Modifier_copy(struct DynamicPaintModifierData *pmd, struct Dyn
tpmd->canvas->ui_info[0] = '\0';
- /*tpmd->canvas->flags = pmd->canvas->flags;
- tpmd->canvas->output = pmd->canvas->output;
- tpmd->canvas->disp_type = pmd->canvas->disp_type;
- tpmd->canvas->disp_format = pmd->canvas->disp_format;
- tpmd->canvas->effect = pmd->canvas->effect;
- tpmd->canvas->effect_ui = 1;
-
- tpmd->canvas->resolution = pmd->canvas->resolution;
- tpmd->canvas->start_frame = pmd->canvas->start_frame;
- tpmd->canvas->end_frame = pmd->canvas->end_frame;
- tpmd->canvas->substeps = pmd->canvas->substeps;
-
- tpmd->canvas->dry_speed = pmd->canvas->dry_speed;
- tpmd->canvas->diss_speed = pmd->canvas->diss_speed;
- tpmd->canvas->disp_depth = pmd->canvas->disp_depth;
- tpmd->canvas->dflat_speed = pmd->canvas->dflat_speed;
-
- strncpy(tpmd->canvas->paint_output_path, pmd->canvas->paint_output_path, 240);
- strncpy(tpmd->canvas->wet_output_path, pmd->canvas->wet_output_path, 240);
- strncpy(tpmd->canvas->displace_output_path, pmd->canvas->displace_output_path, 240);
-
- tpmd->canvas->spread_speed = pmd->canvas->spread_speed;
- tpmd->canvas->drip_speed = pmd->canvas->drip_speed;
- tpmd->canvas->shrink_speed = pmd->canvas->shrink_speed;
-
- strncpy(tpmd->canvas->uvlayer_name, tpmd->canvas->uvlayer_name, 32);*/
-
} else if (tpmd->brush) {
pmd->brush->pmd = tpmd;
@@ -655,9 +648,13 @@ static void dynamicPaint_allocateSurfaceType(DynamicPaintSurface *surface)
if (sData->type_data == NULL) printError(surface->canvas, "Not enough free memory!");
}
-static int surface_usesNeighData(DynamicPaintSurface *surface) {
- return (surface->type == MOD_DPAINT_SURFACE_T_PAINT ||
- surface->type == MOD_DPAINT_SURFACE_T_WAVE);
+static int surface_usesAdjData(DynamicPaintSurface *surface) {
+ if (surface->type == MOD_DPAINT_SURFACE_T_PAINT && surface->effect) return 1;
+ if (surface->type == MOD_DPAINT_SURFACE_T_WAVE) return 1;
+ if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX &&
+ surface->flags & MOD_DPAINT_ANTIALIAS) return 1;
+
+ return 0;
}
/* initialize surface adjacency data */
@@ -667,7 +664,7 @@ static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface) {
int *temp_data;
int neigh_points = 0;
- if (!surface->effect && !surface_usesNeighData(surface)) return;
+ if (!surface_usesAdjData(surface)) return;
if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
/* For vertex format, neighbours are connected by edges */
@@ -682,15 +679,15 @@ static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface) {
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->numOf_n = MEM_callocN(sizeof(int)*sData->total_points, "Surface Adj Counts");
+ ed->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;
/* in case of error, free allocated memory */
- if (!ed->n_index || !ed->numOf_n || !ed->n_target || !temp_data) {
- dynamicPaint_freeEffectData(sData);
+ if (!ed->n_index || !ed->n_num || !ed->n_target || !temp_data) {
+ dynamicPaint_freeAdjData(sData);
MEM_freeN(temp_data);
printError(surface->canvas, "Not enough free memory.");
return;
@@ -708,8 +705,8 @@ static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface) {
/* count number of edges per vertex */
for (i=0; i<numOfEdges; i++) {
- ed->numOf_n[edge[i].v1]++;
- ed->numOf_n[edge[i].v2]++;
+ ed->n_num[edge[i].v1]++;
+ ed->n_num[edge[i].v2]++;
temp_data[edge[i].v1]++;
temp_data[edge[i].v2]++;
@@ -739,7 +736,7 @@ static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface) {
n_pos = 0;
for (i=0; i<sData->total_points; i++) {
ed->n_index[i] = n_pos;
- n_pos += ed->numOf_n[i];
+ n_pos += ed->n_num[i];
}
/* and now add neighbour data using that info */
@@ -798,7 +795,6 @@ int dynamicPaint_resetSurface(DynamicPaintSurface *surface)
/* allocate data depending on surface type and format */
surface->data->total_points = numOfPoints;
- surface->data->samples = 1;
dynamicPaint_allocateSurfaceType(surface);
dynamicPaint_initAdjacencyData(surface);
@@ -828,9 +824,9 @@ void dynamicPaint_cacheUpdateFrames(DynamicPaintSurface *surface) {
/*
* Updates derived mesh copy and processes dynamic paint step / caches.
*/
-static void dynamicPaint_canvasUpdate(DynamicPaintModifierData *pmd, Scene *scene, Object *ob, DerivedMesh *dm)
+static void dynamicPaint_frameUpdate(DynamicPaintModifierData *pmd, Scene *scene, Object *ob, DerivedMesh *dm)
{
- if((pmd->type & MOD_DYNAMICPAINT_TYPE_CANVAS) && pmd->canvas) {
+ if(pmd->canvas) {
DynamicPaintCanvasSettings *canvas = pmd->canvas;
DynamicPaintSurface *surface = canvas->surfaces.first;
@@ -889,11 +885,6 @@ static void dynamicPaint_canvasUpdate(DynamicPaintModifierData *pmd, Scene *scen
}
}
}
- else if((pmd->type & MOD_DYNAMICPAINT_TYPE_BRUSH) && pmd->brush) {
-
- if (pmd->brush->dm) pmd->brush->dm->release(pmd->brush->dm);
- pmd->brush->dm = CDDM_copy(dm);
- }
}
/*
@@ -903,8 +894,7 @@ struct DerivedMesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, S
{
DerivedMesh *result = CDDM_copy(dm);
- if((pmd->type & MOD_DYNAMICPAINT_TYPE_CANVAS) && pmd->canvas &&
- !(pmd->canvas->flags & MOD_DPAINT_BAKING)) {
+ if(pmd->canvas && !(pmd->canvas->flags & MOD_DPAINT_BAKING)) {
DynamicPaintSurface *surface = pmd->canvas->surfaces.first;
pmd->canvas->flags &= ~MOD_DPAINT_PREVIEW_READY;
@@ -1140,6 +1130,11 @@ struct DerivedMesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, S
}
}
}
+ /* make a copy of dm to use as brush data */
+ if (pmd->brush) {
+ if (pmd->brush->dm) pmd->brush->dm->release(pmd->brush->dm);
+ pmd->brush->dm = CDDM_copy(result);
+ }
return result;
}
@@ -1148,7 +1143,7 @@ struct DerivedMesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, S
struct DerivedMesh *dynamicPaint_Modifier_do(DynamicPaintModifierData *pmd, Scene *scene, Object *ob, DerivedMesh *dm)
{
/* Update derived mesh data to modifier if baking */
- dynamicPaint_canvasUpdate(pmd, scene, ob, dm);
+ dynamicPaint_frameUpdate(pmd, scene, ob, dm);
/* Return output mesh */
return dynamicPaint_Modifier_apply(pmd, scene, ob, dm);
@@ -1381,6 +1376,7 @@ static int dynamicPaint_createUVSurface(DynamicPaintSurface *surface)
MTFace *tface = NULL;
BB2d *faceBB = NULL;
int *final_index;
+ int aa_samples;
if (!dm) return printError(canvas, "Canvas mesh not updated.");
if (surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ) return printError(canvas, "Can't bake non-\"image sequence\" formats.");
@@ -1409,7 +1405,7 @@ static int dynamicPaint_createUVSurface(DynamicPaintSurface *surface)
sData = surface->data = MEM_callocN(sizeof(PaintSurfaceData), "PaintSurfaceData");
if (!surface->data) return printError(canvas, "Not enough free memory.");
- sData->samples = (surface->flags & MOD_DPAINT_ANTIALIAS) ? 5 : 1;
+ aa_samples = (surface->flags & MOD_DPAINT_ANTIALIAS) ? 5 : 1;
tempPoints = (struct PaintUVPoint *) MEM_callocN(w*h*sizeof(struct PaintUVPoint), "Temp PaintUVPoint");
if (!tempPoints) error=1;
@@ -1417,7 +1413,7 @@ static int dynamicPaint_createUVSurface(DynamicPaintSurface *surface)
if (!final_index) error=1;
if (!error) {
- tempWeights = (struct Vec3f *) MEM_mallocN(w*h*sData->samples*sizeof(struct Vec3f), "Temp bWeights");
+ tempWeights = (struct Vec3f *) MEM_mallocN(w*h*aa_samples*sizeof(struct Vec3f), "Temp bWeights");
if (!tempWeights) error=1;
}
@@ -1567,11 +1563,11 @@ static int dynamicPaint_createUVSurface(DynamicPaintSurface *surface)
}
/* Add b-weights per anti-aliasing sample */
- for (j=0; j<sData->samples; j++) {
+ for (j=0; j<aa_samples; j++) {
uv[0] = point[0][0] + jitter5sample[j*2] / w;
uv[1] = point[0][1] + jitter5sample[j*2+1] / h;
- barycentric_weights_v2(uv1co, uv2co, uv3co, uv, tempWeights[index*sData->samples+j].v);
+ barycentric_weights_v2(uv1co, uv2co, uv3co, uv, tempWeights[index*aa_samples+j].v);
}
/* Set surface point face values */
@@ -1647,11 +1643,11 @@ static int dynamicPaint_createUVSurface(DynamicPaintSurface *surface)
}
/* Add b-weights per anti-aliasing sample */
- for (j=0; j<sData->samples; j++) {
+ for (j=0; j<aa_samples; j++) {
uv[0] = point[0] + jitter5sample[j*2] / w;
uv[1] = point[1] + jitter5sample[j*2+1] / h;
- barycentric_weights_v2(uv1co, uv2co, uv3co, uv, tempWeights[index*sData->samples+j].v);
+ barycentric_weights_v2(uv1co, uv2co, uv3co, uv, tempWeights[index*aa_samples+j].v);
}
/* Set values */
@@ -1692,7 +1688,7 @@ static int dynamicPaint_createUVSurface(DynamicPaintSurface *surface)
/* If any effect enabled, create surface effect / wet layer
* neighbour lists. Processes possibly moving data. */
- if (surface_usesNeighData(surface)) {
+ if (surface_usesAdjData(surface)) {
int i, cursor=0;
@@ -1722,7 +1718,7 @@ static int dynamicPaint_createUVSurface(DynamicPaintSurface *surface)
if (tempPoints[index].face_index != -1) {
ed->n_index[final_index[index]] = n_pos;
- ed->numOf_n[final_index[index]] = 0;
+ ed->n_num[final_index[index]] = 0;
for (i=0; i<8; i++) {
@@ -1732,7 +1728,7 @@ static int dynamicPaint_createUVSurface(DynamicPaintSurface *surface)
if (n_target != -1) {
ed->n_target[n_pos] = final_index[n_target];
- ed->numOf_n[final_index[index]]++;
+ ed->n_num[final_index[index]]++;
n_pos++;
}
}
@@ -1747,7 +1743,7 @@ static int dynamicPaint_createUVSurface(DynamicPaintSurface *surface)
ImgSeqFormatData *f_data = MEM_callocN(sizeof(struct ImgSeqFormatData), "ImgSeqFormatData");
if (f_data) {
f_data->uv_p = MEM_callocN(active_points*sizeof(struct PaintUVPoint), "PaintUVPoint");
- f_data->barycentricWeights = MEM_callocN(active_points*sData->samples*sizeof(struct Vec3f), "PaintUVPoint");
+ f_data->barycentricWeights = MEM_callocN(active_points*aa_samples*sizeof(struct Vec3f), "PaintUVPoint");
if (!f_data->uv_p || !f_data->barycentricWeights) error=1;
}
@@ -1771,7 +1767,7 @@ static int dynamicPaint_createUVSurface(DynamicPaintSurface *surface)
for(index = 0; index < (w*h); index++) {
if (tempPoints[index].face_index != -1) {
memcpy(&f_data->uv_p[cursor], &tempPoints[index], sizeof(PaintUVPoint));
- memcpy(&f_data->barycentricWeights[cursor*sData->samples], &tempWeights[index*sData->samples], sizeof(Vec3f)*sData->samples);
+ memcpy(&f_data->barycentricWeights[cursor*aa_samples], &tempWeights[index*aa_samples], sizeof(Vec3f)*aa_samples);
cursor++;
}
}
@@ -2451,8 +2447,7 @@ static void mesh_faces_spherecast_dp(void *userdata, int index, const BVHTreeRay
do
{
- float dist;
- dist = ray_tri_intersection(ray, hit->dist, t0, t1, t2);
+ float dist = ray_tri_intersection(ray, hit->dist, t0, t1, t2);
if(dist >= 0 && dist < hit->dist)
{
@@ -2604,6 +2599,57 @@ static void dynamicPaint_mixWaveHeight(PaintWavePoint *wPoint, DynamicPaintBrush
}
/*
+* add paint results to the surface data depending on surface type
+*/
+static void dynamicPaint_updatePointData(DynamicPaintSurface *surface, unsigned int index, DynamicPaintBrushSettings *brush, float paint[4], float strength, float depth, float timescale)
+{
+ PaintSurfaceData *sData = surface->data;
+
+ /* mix paint surface */
+ if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
+
+ float paintWetness = brush->wetness * strength;
+ float paintAlpha = paint[3] * strength;
+ if (paintAlpha > 1.0f) paintAlpha = 1.0f;
+
+ dynamicPaint_mixPaintColors(surface, index, brush->flags, paint, &paintAlpha, &paintWetness, &timescale);
+
+ }
+ /* displace surface */
+ else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) {
+ float *value = (float*)sData->type_data;
+
+ if (brush->flags & MOD_DPAINT_ERASE) {
+ value[index] *= (1.0f - strength);
+ if (value[index] < 0.0f) value[index] = 0.0f;
+ }
+ else {
+ if (value[index] < depth) value[index] = depth;
+ }
+ }
+ /* vertex weight group surface */
+ else if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) {
+ float *value = (float*)sData->type_data;
+
+ if (brush->flags & MOD_DPAINT_ERASE) {
+ value[index] *= (1.0f - strength);
+ if (value[index] < 0.0f) value[index] = 0.0f;
+ }
+ else {
+ if (value[index] < strength) value[index] = strength;
+ }
+ }
+ /* wave surface */
+ else if (surface->type == MOD_DPAINT_SURFACE_T_WAVE) {
+ dynamicPaint_mixWaveHeight(&((PaintWavePoint*)sData->type_data)[index],
+ brush, 0.0f-depth);
+ }
+}
+
+#define VECADDVAL(v,val) {*(v)+=(val); *(v+1)+=(val); *(v+2)+=(val);}
+#define VECMULVAL(v,val) {*(v)*=(val); *(v+1)*=(val); *(v+2)*=(val);}
+
+/*
* Paint a brush object mesh to the surface
*/
static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, PaintBakeData *bData, DynamicPaintBrushSettings *brush, Object *canvasOb, Object *brushOb, float timescale)
@@ -2644,20 +2690,24 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, PaintBakeData *b
for (index = 0; index < sData->total_points; index++)
{
{
- int ss;
+ int ss, samples = bData->s_num[index];
+ float total_sample = (float)samples;
float brushFactor = 0.0f; /* brush influence factor */
float depth = 0.0f; /* displace depth */
- float paintColor[3] = {0.0f, 0.0f, 0.0f};
+ float paintColor[4] = {0.0f, 0.0f, 0.0f, 0.0f};
int numOfHits = 0;
- float paintAlpha = 0.0f;
+
+ /* for image sequence anti-aliasing, use gaussian factors */
+ if (samples > 1 && surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ)
+ total_sample = gaussianTotal;
/* Supersampling */
- for (ss=0; ss<sData->samples; ss++)
+ for (ss=0; ss<samples; ss++)
{
- float ray_start[3], ray_dir[3];
- float gaus_factor;
+ float ray_start[3], ray_dir[3] = {0.0f};
+ float sample_factor;
BVHTreeRayHit hit;
BVHTreeNearest nearest;
short hit_found = 0;
@@ -2671,16 +2721,21 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, PaintBakeData *b
short hitQuad; /* mid-sample hit quad status */
/* Supersampling factor */
- if (sData->samples > 1) {
- gaus_factor = gaussianFactors[ss];
- }
- else {
- gaus_factor = 1.0f;
- }
+ if (samples > 1 && surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ)
+ sample_factor = gaussianFactors[ss];
+ else
+ sample_factor = 1.0f;
/* Get current sample position in world coordinates */
- VECCOPY(ray_start, &bData->realCoord[(sData->total_points*ss+index)*3]);
- VECCOPY(ray_dir, bData->bPoint[index].invNorm);
+ VECCOPY(ray_start, &bData->realCoord[(bData->s_index[index]+ss)*3]);
+ if (!(brush->flags & MOD_DPAINT_ACCEPT_NONCLOSED) || brush->ray_dir == MOD_DPAINT_RAY_CANVAS) {
+ VECCOPY(ray_dir, bData->bPoint[index].invNorm);
+ }
+ else /* MOD_DPAINT_RAY_ZPLUS */
+ ray_dir[2] = 1.0f;
+
+ /* a simple hack to minimize change of ray leaks at identical ray - edge locations */
+ VECADDVAL(ray_start, 0.001f);
hit.index = -1;
hit.dist = 9999;
@@ -2710,18 +2765,31 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, PaintBakeData *b
*/
if (dot>=0)
{
- /* Add factor on supersample filter */
- brushFactor += gaus_factor;
- depth += hit.dist;
- hit_found = 1;
+ float dist = hit.dist;
+ int f_index = hit.index;
- /*
- * Mark hit info
- */
- if (hitFace == -1) {
+ /* In case of non-closed volumes, also cast a ray in opposite direction
+ * to make sure point is at least between two brush faces*/
+ if (!(brush->flags & MOD_DPAINT_ACCEPT_NONCLOSED)) {
+ VECMULVAL(ray_dir, -1.0f);
+ hit.index = -1;
+ hit.dist = 9999;
+
+ BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_dir, 0.0f, &hit, mesh_faces_spherecast_dp, &treeData);
+ }
+
+ if(hit.index != -1) {
+ /* Add factor on supersample filter */
+ brushFactor += sample_factor;
+ hit_found = 1;
+
+ /*
+ * Mark hit info
+ */
VECADDFAC(hitCoord, ray_start, ray_dir, hit.dist); /* Calculate final hit coordinates */
+ depth += dist*sample_factor;
+ hitFace = f_index;
hitQuad = quad;
- hitFace = hit.index;
}
}
} // end of raycast
@@ -2775,15 +2843,15 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, PaintBakeData *b
/* if using smooth falloff, multiply gaussian factor */
if (brush->proximity_falloff == MOD_DPAINT_PRFALL_SMOOTH) {
- prox_influence = (1.0f - dist_rate) * gaus_factor;
+ prox_influence = (1.0f - dist_rate) * sample_factor;
}
- else prox_influence = gaus_factor;
+ else prox_influence = sample_factor;
if (hitFace == -1) {
distRate = dist_rate;
}
}
- else prox_influence = gaus_factor;
+ else prox_influence = sample_factor;
hit_found = 1;
if (brush->flags & MOD_DPAINT_INVERSE_PROX) {
@@ -2802,9 +2870,9 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, PaintBakeData *b
}
/*
- * Process color and alpha
+ * Process hit color and alpha
*/
- if (hit_found)
+ if (hit_found && surface->type == MOD_DPAINT_SURFACE_T_PAINT)
{
float sampleColor[3];
float sampleAlpha = 1.0f;
@@ -2815,7 +2883,7 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, PaintBakeData *b
sampleColor[2] = brush->b;
/* Get material+textures color on hit point if required */
- if (brush->flags & MOD_DPAINT_USE_MATERIAL) dynamicPaint_getMaterialColor(sampleColor, &sampleAlpha, brushOb, &bData->realCoord[(sData->total_points*ss+index)*3], hitCoord, hitFace, hitQuad, brush->dm, brush->mat);
+ if (brush->flags & MOD_DPAINT_USE_MATERIAL) dynamicPaint_getMaterialColor(sampleColor, &sampleAlpha, brushOb, &bData->realCoord[(bData->s_index[index]+ss)*3], hitCoord, hitFace, hitQuad, brush->dm, brush->mat);
/* Sample colorband if required */
if ((distRate >= 0.0f) && (brush->proximity_falloff == MOD_DPAINT_PRFALL_RAMP) && do_colorband(brush->paint_ramp, distRate, bandres)) {
@@ -2832,7 +2900,7 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, PaintBakeData *b
paintColor[1] += sampleColor[1];
paintColor[2] += sampleColor[2];
- paintAlpha += sampleAlpha;
+ paintColor[3] += sampleAlpha;
numOfHits++;
}
} // end supersampling
@@ -2842,72 +2910,26 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, PaintBakeData *b
if (brushFactor > 0.01f) {
/* apply supersampling results */
- if (sData->samples > 1) {
- brushFactor /= gaussianTotal;
+ if (samples > 1) {
+ brushFactor /= total_sample;
}
CLAMP(brushFactor, 0.0f, 1.0f);
brushFactor *= brush->alpha;
- //cPoint->state = 2;
-
if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
-
- float paintWetness = brush->wetness * brushFactor;
-
/* Get final pixel color and alpha */
paintColor[0] /= numOfHits;
paintColor[1] /= numOfHits;
paintColor[2] /= numOfHits;
- paintAlpha /= numOfHits;
-
- /* Multiply alpha value by the ui multiplier */
- paintAlpha = paintAlpha * brushFactor;
- if (paintAlpha > 1.0f) paintAlpha = 1.0f;
-
- /*
- * Mix paint to the surface
- */
- dynamicPaint_mixPaintColors(surface, index, brush->flags, paintColor, &paintAlpha, &paintWetness, &timescale);
- }
- /* displace */
- else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) {
- float *value = (float*)sData->type_data;
-
- if (brush->flags & MOD_DPAINT_ERASE) {
- value[index] *= (1.0f - brushFactor);
- if (value[index] < 0.0f) value[index] = 0.0f;
- }
- else {
- depth /= bData->bPoint[index].normal_scale;
- /* do displace */
- if (value[index] < depth) value[index] = depth;
- }
- }
- /* vertex weight */
- else if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) {
- float *value = (float*)sData->type_data;
-
- if (brush->flags & MOD_DPAINT_ERASE) {
- value[index] *= (1.0f - brushFactor);
- if (value[index] < 0.0f) value[index] = 0.0f;
- }
- else {
- if (brush->flags & MOD_DPAINT_ABS_ALPHA) {
- if (value[index] < brushFactor) value[index] = brushFactor;
- }
- else {
- value[index] += brushFactor;
- if (value[index] > 1.0f) value[index] = 1.0f;
- }
- }
+ paintColor[3] /= total_sample;
}
- /* wave */
- else if (surface->type == MOD_DPAINT_SURFACE_T_WAVE) {
- depth *= -1.0f/bData->bPoint[index].normal_scale;
-
- dynamicPaint_mixWaveHeight(&((PaintWavePoint*)surface->data->type_data)[index],
- brush, depth);
+ /* get final object space depth */
+ else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE ||
+ surface->type == MOD_DPAINT_SURFACE_T_WAVE) {
+ depth /= bData->bPoint[index].normal_scale * total_sample;
}
+
+ dynamicPaint_updatePointData(surface, index, brush, paintColor, brushFactor, depth, timescale);
}
}
}
@@ -2991,7 +3013,7 @@ static int dynamicPaint_paintParticles(DynamicPaintSurface *surface, PaintBakeDa
int n, particles = 0;
float range = psys->part->size + smooth;
- particles = BLI_kdtree_range_search(tree, range, &bData->realCoord[index*3], NULL, &nearest);
+ particles = BLI_kdtree_range_search(tree, range, &bData->realCoord[(bData->s_index[index])*3], NULL, &nearest);
for(n=0; n<particles; n++) {
/*
@@ -3037,7 +3059,7 @@ static int dynamicPaint_paintParticles(DynamicPaintSurface *surface, PaintBakeDa
radius = solidradius + smooth;
/* Find nearest particle and get distance to it */
- BLI_kdtree_find_nearest(tree, &bData->realCoord[index*3], NULL, &nearest);
+ BLI_kdtree_find_nearest(tree, &bData->realCoord[(bData->s_index[index])*3], NULL, &nearest);
if (nearest.dist > radius) continue;
/* distances inside solid radius have maximum influence -> dist = 0 */
@@ -3050,61 +3072,81 @@ static int dynamicPaint_paintParticles(DynamicPaintSurface *surface, PaintBakeDa
disp_intersect = radius - nearest.dist;
}
- if (strength <= 0.0f) continue;
+ if (strength > 0.001f)
+ {
+ float paintColor[4] = {0.0f};
+ float depth = 0.0f;
- //cPoint->state = 2;
+ if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
+ paintColor[0] = brush->r;
+ paintColor[1] = brush->g;
+ paintColor[2] = brush->b;
+ paintColor[3] = brush->alpha;
+ }
+ else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE ||
+ surface->type == MOD_DPAINT_SURFACE_T_WAVE) {
+ /* get displace depth */
+ disp_intersect = (1.0f - sqrt(disp_intersect / radius)) * radius;
+ depth = (radius - disp_intersect) / bData->bPoint[index].normal_scale;
+ if (depth<0.0f) depth = 0.0f;
+ }
+
+ dynamicPaint_updatePointData(surface, index, brush, paintColor, strength, depth, timescale);
+ }
+ }
+ BLI_kdtree_free(tree);
- if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
+ return 1;
+}
- float paintAlpha = brush->alpha * strength;
- float paintWetness = brush->wetness * strength;
- float paintColor[3];
- paintColor[0] = brush->r;
- paintColor[1] = brush->g;
- paintColor[2] = brush->b;
+static int dynamicPaint_paintSinglePoint(DynamicPaintSurface *surface, PaintBakeData *bData, float *pointCoord, DynamicPaintBrushSettings *brush, Object *canvasOb, float timescale)
+{
+ unsigned int index;
+ PaintSurfaceData *sData = surface->data;
- if (paintAlpha > 1.0f) paintAlpha = 1.0f;
+ /*
+ * Loop through every surface point
+ */
+ #pragma omp parallel for schedule(static)
+ for (index = 0; index < sData->total_points; index++)
+ {
+ float distance = len_v3v3(pointCoord, &bData->realCoord[(bData->s_index[index])*3]);
+ float strength;
- dynamicPaint_mixPaintColors(surface, index, brush->flags, paintColor, &paintAlpha, &paintWetness, &timescale);
+ /* Smooth range or color ramp */
+ if (brush->proximity_falloff == MOD_DPAINT_PRFALL_SMOOTH ||
+ brush->proximity_falloff == MOD_DPAINT_PRFALL_RAMP) {
+ if (brush->proximity_falloff == MOD_DPAINT_PRFALL_SMOOTH) {
+ strength = distance / brush->paint_distance;
+ CLAMP(strength, 0.0f, 1.0f);
+ strength = 1.0f - strength;
+ }
+ else strength = 1.0f;
}
- else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) {
- float sdepth;
- float *value = (float*)sData->type_data;
+ else strength = 1.0f;
- /* change falloff type to inverse square to match real displace depth */
- disp_intersect = (1.0f - sqrt(disp_intersect / radius)) * radius;
- /* get displace depth */
- sdepth = (radius - disp_intersect) / bData->bPoint[index].normal_scale;
+ if (strength >= 0.001f) {
+ float paintColor[4] = {0.0f};
+ float depth = 0.0f;
- if (sdepth<0.0f) sdepth = 0.0f;
- if (value[index] < sdepth) value[index] = sdepth;
- }
- else if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) {
- float *value = (float*)sData->type_data;
-
- if (brush->flags & MOD_DPAINT_ERASE) {
- value[index] *= (1.0f - strength);
- if (value[index] < 0.0f) value[index] = 0.0f;
+ if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
+ paintColor[0] = brush->r;
+ paintColor[1] = brush->g;
+ paintColor[2] = brush->b;
+ paintColor[3] = brush->alpha;
}
- else {
- if (value[index] < strength) value[index] = strength;
+ else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE ||
+ surface->type == MOD_DPAINT_SURFACE_T_WAVE) {
+ /* get displace depth */
+ float disp_intersect = (1.0f - sqrt((brush->paint_distance-distance) / brush->paint_distance)) * brush->paint_distance;
+ depth = (brush->paint_distance - disp_intersect) / bData->bPoint[index].normal_scale;
+ if (depth<0.0f) depth = 0.0f;
}
+ dynamicPaint_updatePointData(surface, index, brush, paintColor, strength, depth, timescale);
}
- /* wave */
- else if (surface->type == MOD_DPAINT_SURFACE_T_WAVE) {
- float sdepth;
-
- /* change falloff type to inverse square to match real displace depth */
- disp_intersect = (1.0f - sqrt(disp_intersect / radius)) * radius;
- /* get displace depth */
- sdepth = -1.0f * (radius - disp_intersect) / bData->bPoint[index].normal_scale;
- dynamicPaint_mixWaveHeight(&((PaintWavePoint*)surface->data->type_data)[index],
- brush, sdepth);
- }
}
- BLI_kdtree_free(tree);
return 1;
}
@@ -3125,7 +3167,7 @@ static void dynamicPaint_prepareNeighbourData(DynamicPaintSurface *surface, Bake
for (index = 0; index < sData->total_points; index++)
{
int i;
- int numOfNeighs = sData->adj_data->numOf_n[index];
+ int numOfNeighs = sData->adj_data->n_num[index];
for (i=0; i<numOfNeighs; i++) {
int n_index = sData->adj_data->n_index[index]+i;
@@ -3201,7 +3243,7 @@ static int dynamicPaint_prepareEffectStep(DynamicPaintSurface *surface, Scene *s
for (index = 0; index < sData->total_points; index++)
{
int i;
- int numOfNeighs = sData->adj_data->numOf_n[index];
+ int numOfNeighs = sData->adj_data->n_num[index];
if (*force)
average_force += (*force)[index*4+3];
@@ -3254,7 +3296,7 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, BakeNeighPoi
for (index = 0; index < sData->total_points; index++)
{
int i;
- int numOfNeighs = sData->adj_data->numOf_n[index];
+ int numOfNeighs = sData->adj_data->n_num[index];
float totalAlpha = 0.0f;
PaintPoint *pPoint = &((PaintPoint*)sData->type_data)[index];
@@ -3312,7 +3354,7 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, BakeNeighPoi
for (index = 0; index < sData->total_points; index++)
{
int i;
- int numOfNeighs = sData->adj_data->numOf_n[index];
+ int numOfNeighs = sData->adj_data->n_num[index];
float totalAlpha = 0.0f;
PaintPoint *pPoint = &((PaintPoint*)sData->type_data)[index];
@@ -3362,7 +3404,7 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, BakeNeighPoi
float eff_scale = EFF_MOVEMENT_PER_FRAME*timescale/10.0f;
for (index = 0; index < sData->total_points; index++) {
int i;
- int numOfNeighs = sData->adj_data->numOf_n[index];
+ int numOfNeighs = sData->adj_data->n_num[index];
PaintPoint *pPoint = &((PaintPoint*)sData->type_data)[index];
/* to make dripping happen with as little spread as possible,
@@ -3479,7 +3521,7 @@ void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, BakeNeighPoint *bNeig
for (index = 0; index < sData->total_points; index++)
{
int i;
- int numOfNeighs = sData->adj_data->numOf_n[index];
+ int numOfNeighs = sData->adj_data->n_num[index];
for (i=0; i<numOfNeighs; i++) {
average_dist += bNeighs[sData->adj_data->n_index[index]+i].dist;
@@ -3505,7 +3547,7 @@ void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, BakeNeighPoint *bNeig
#pragma omp parallel for schedule(static)
for (index = 0; index < sData->total_points; index++) {
PaintWavePoint *wPoint = &((PaintWavePoint*)sData->type_data)[index];
- int numOfNeighs = sData->adj_data->numOf_n[index];
+ int numOfNeighs = sData->adj_data->n_num[index];
float force = 0.0f, avg_dist = 0.0f, avg_height = 0.0f;
int numOfN = 0, numOfRN = 0;
int i;
@@ -3591,7 +3633,6 @@ static int dynamicPaint_prepareSurfaceStep(DynamicPaintSurface *surface, PaintBa
#pragma omp parallel for schedule(static)
for (index=0; index<canvasNumOfVerts; index++) {
-
/* Multiply coordinates by canvas transformation matrix */
VECCOPY(canvas_verts[index].v, mvert[index].co);
mul_m4_v3(ob->obmat, canvas_verts[index].v);
@@ -3678,12 +3719,15 @@ static int dynamicPaint_prepareSurfaceStep(DynamicPaintSurface *surface, PaintBa
PaintUVPoint *tPoint = &((PaintUVPoint*)f_data->uv_p)[index];
int ss;
+ bData->s_num[index] = (surface->flags & MOD_DPAINT_ANTIALIAS) ? 5 : 1;
+ bData->s_index[index] = index * bData->s_num[index];
+
/* per sample coordinates */
- for (ss=0; ss<sData->samples; ss++) {
- interp_v3_v3v3v3( &bData->realCoord[(sData->total_points*ss+index)*3],
- canvas_verts[tPoint->v1].v,
- canvas_verts[tPoint->v2].v,
- canvas_verts[tPoint->v3].v, f_data->barycentricWeights[index*sData->samples+ss].v);
+ for (ss=0; ss<bData->s_num[index]; ss++) {
+ interp_v3_v3v3v3( &bData->realCoord[(bData->s_index[index]+ss)*3],
+ canvas_verts[tPoint->v1].v,
+ canvas_verts[tPoint->v2].v,
+ canvas_verts[tPoint->v3].v, f_data->barycentricWeights[index*bData->s_num[index]+ss].v);
}
/* Calculate current pixel surface normal */
@@ -3693,7 +3737,7 @@ static int dynamicPaint_prepareSurfaceStep(DynamicPaintSurface *surface, PaintBa
normal_short_to_float_v3(n3, mvert[tPoint->v3].no);
interp_v3_v3v3v3( bData->bPoint[index].invNorm,
- n1, n2, n3, f_data->barycentricWeights[index*sData->samples].v);
+ n1, n2, n3, f_data->barycentricWeights[index*bData->s_num[index]].v);
mul_mat3_m4_v3(ob->obmat, bData->bPoint[index].invNorm);
normalize_v3(bData->bPoint[index].invNorm);
negate_v3(bData->bPoint[index].invNorm);
@@ -3705,9 +3749,29 @@ static int dynamicPaint_prepareSurfaceStep(DynamicPaintSurface *surface, PaintBa
}
else if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
/* In case of verted data */
+ int ss;
+
+ if (surface->flags & MOD_DPAINT_ANTIALIAS && sData->adj_data) {
+ bData->s_num[index] = sData->adj_data->n_num[index]+1;
+ bData->s_index[index] = sData->adj_data->n_index[index]+index;
+ }
+ else {
+ bData->s_num[index] = 1;
+ bData->s_index[index] = index;
+ }
+ /* per sample coordinates */
+ for (ss=0; ss<bData->s_num[index]; ss++) {
+ /* first sample is always point center */
+ VECCOPY(&bData->realCoord[(bData->s_index[index]+ss)*3], canvas_verts[index].v);
+ if (ss > 0) {
+ int t_index = sData->adj_data->n_index[index]+(ss-1);
+ /* get vertex position at 1/3 of each neigh edge */
+ mul_v3_fl(&bData->realCoord[(bData->s_index[index]+ss)*3], 2.0f/3.0f);
+ madd_v3_v3fl(&bData->realCoord[(bData->s_index[index]+ss)*3], canvas_verts[sData->adj_data->n_target[t_index]].v, 1.0f/3.0f);
+ }
+ }
/* location, currently vertex format can have only one sample */
- VECCOPY(&bData->realCoord[index*3], canvas_verts[index].v);
/* normal */
normal_short_to_float_v3(bData->bPoint[index].invNorm, mvert[index].no);
@@ -3741,12 +3805,18 @@ static int dynamicPaint_prepareSurfaceStep(DynamicPaintSurface *surface, PaintBa
return 1;
}
-static void scene_updateObject(Scene *scene, Object *ob, float frame) {
+static void subframe_updateObject(Scene *scene, Object *ob, int update_parents, float frame)
+{
int oflags;
+ DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)modifiers_findByType(ob, eModifierType_DynamicPaint);
+
+ /* if other is dynamic paint canvas, dont update */
+ if (pmd && pmd->canvas)
+ return;
/* if object has parent, update it too */
- if (ob->parent) scene_updateObject(scene, ob->parent, frame);
- if (ob->track) scene_updateObject(scene, ob->track, frame);
+ if (update_parents && ob->parent) subframe_updateObject(scene, ob->parent, 0, frame);
+ if (update_parents && ob->track) subframe_updateObject(scene, ob->track, 0, frame);
/* for curve */
if(ob->type==OB_CURVE) {
@@ -3766,12 +3836,54 @@ static void scene_updateObject(Scene *scene, Object *ob, float frame) {
ob->recalc = oflags;
}
-static void scene_setSubframe(Scene *scene, float subframe) {
+static void scene_setSubframe(Scene *scene, float subframe)
+{
/* dynamic paint subframes must be done on previous frame */
scene->r.cfra -= 1;
scene->r.subframe = subframe;
}
+static int surface_totalSamples(DynamicPaintSurface *surface)
+{
+ if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ &&
+ surface->flags & MOD_DPAINT_ANTIALIAS)
+ return (surface->data->total_points*5);
+ if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX &&
+ surface->flags & MOD_DPAINT_ANTIALIAS && surface->data->adj_data)
+ return (surface->data->total_points+surface->data->adj_data->total_targets);
+
+ return surface->data->total_points;
+}
+
+static void free_bDataSamples(DynamicPaintSurface *surface, PaintBakeData *bData)
+{
+ PaintSurfaceData *sData = surface->data;
+ float *old_realCoord = bData->realCoord;
+ if (!old_realCoord) return;
+
+ /* if no anti-aliasing enabled, data is alredy in right order */
+ if (surface->flags & MOD_DPAINT_ANTIALIAS) {
+ bData->realCoord = (float *) MEM_mallocN(3*sData->total_points*sizeof(float), "Dynamic Paint point coords");
+
+ if (bData->realCoord) {
+ int index;
+
+ #pragma omp parallel for schedule(static)
+ for (index=0; index<sData->total_points; index++)
+ {
+ memcpy(&bData->realCoord[index*3], &old_realCoord[(bData->s_index[index])*3], sizeof(float)*3);
+ }
+ }
+ MEM_freeN(old_realCoord);
+ }
+
+ /* also free indexing data */
+ MEM_freeN(bData->s_index);
+ MEM_freeN(bData->s_num);
+ bData->s_index = NULL;
+ bData->s_num = NULL;
+}
+
/*
* Do Dynamic Paint Step. Paints scene brush objects of current state/frame to canvas.
*/
@@ -3786,9 +3898,17 @@ static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *su
/* Init surface current frame position data */
bData.bPoint = (struct PaintBakePoint *) MEM_mallocN(sData->total_points*sizeof(struct PaintBakePoint), "Dynamic Paint step data");
- if (bData.bPoint == NULL) return printError(canvas, "Not enough free memory.");
- bData.realCoord = (float *) MEM_mallocN(sData->total_points*3*sData->samples*sizeof(float), "Dynamic Paint step coords");
- if (bData.realCoord == NULL) return printError(canvas, "Not enough free memory.");
+ bData.s_index = MEM_mallocN(sData->total_points*sizeof(unsigned int), "Dynamic Paint bData s_index");
+ bData.s_num = MEM_mallocN(sData->total_points*sizeof(unsigned int), "Dynamic Paint bData s_num");
+ bData.realCoord = (float *) MEM_mallocN(3*surface_totalSamples(surface)*sizeof(float), "Dynamic Paint point coords");
+ if (!bData.bPoint || !bData.s_index || !bData.s_num || !bData.realCoord) {
+ if (bData.bPoint) MEM_freeN(bData.bPoint);
+ if (bData.s_index) MEM_freeN(bData.s_index);
+ if (bData.s_num) MEM_freeN(bData.s_num);
+ if (bData.realCoord) MEM_freeN(bData.realCoord);
+
+ return printError(canvas, "Not enough free memory.");
+ }
if (!dynamicPaint_prepareSurfaceStep(surface, &bData, ob, canvas->dm, timescale)) {
ret = 0;
@@ -3848,14 +3968,14 @@ static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *su
DynamicPaintModifierData *pmd2 = (DynamicPaintModifierData *)md;
/* Make sure we're dealing with a painter */
- if((pmd2->type & MOD_DYNAMICPAINT_TYPE_BRUSH) && pmd2->brush)
+ if (pmd2->brush)
{
DynamicPaintBrushSettings *brush = pmd2->brush;
/* update object position on this subframe */
if (subframe) {
scene_setSubframe(scene, subframe);
- scene_updateObject(scene, brushObj, BKE_curframe(scene));
+ subframe_updateObject(scene, brushObj, 1, BKE_curframe(scene));
}
/* If using material color, update anim data to current (sub)frame */
@@ -3873,8 +3993,11 @@ static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *su
BKE_animsys_evaluate_animdata(&brush->psys->part->id, brush->psys->part->adt, BKE_curframe(scene), ADT_RECALC_ANIM);
dynamicPaint_paintParticles(surface, &bData, brush->psys, brush, ob, timescale);
}
- }
- else {
+ }
+ else if (brush->collision == MOD_DPAINT_COL_POINT && brushObj != ob) {
+ dynamicPaint_paintSinglePoint(surface, &bData, brushObj->loc, brush, ob, timescale);
+ }
+ else if (brushObj != ob){
/* Paint a mesh */
dynamicPaint_paintMesh(surface, &bData, brush, ob, brushObj, timescale);
}
@@ -3883,7 +4006,7 @@ static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *su
if (subframe) {
scene->r.cfra = scene_frame;
scene->r.subframe = scene_subframe;
- scene_updateObject(scene, brushObj, BKE_curframe(scene));
+ subframe_updateObject(scene, brushObj, 1, BKE_curframe(scene));
dynamicPaint_updateObjectMaterials(brushObj, brush->mat, scene);
}
} /* end of collision check (Is valid paint modifier) */
@@ -3891,7 +4014,8 @@ static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *su
}
}
- MEM_freeN(bData.bPoint);
+ if (bData.bPoint) MEM_freeN(bData.bPoint);
+ bData.bPoint = NULL;
/* neighbour data and surface opretions that use it */
if (sData->adj_data)
@@ -3899,6 +4023,9 @@ static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *su
BakeNeighPoint *bNeighs = MEM_mallocN(sData->adj_data->total_targets*sizeof(struct BakeNeighPoint), "PaintEffectBake");
if (bNeighs) {
+ /* free antialias sample coords, as they're not needed anymore
+ * and re-order data*/
+ free_bDataSamples(surface, &bData);
/* calculate current frame distances and global dirs */
dynamicPaint_prepareNeighbourData(surface, bNeighs, bData.realCoord);
@@ -3914,15 +4041,14 @@ static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *su
PaintPoint *prevPoint;
float *force = NULL;
- /* free antialias sample coords, as theyre not needed anymore */
- if (sData->samples>1) bData.realCoord = MEM_reallocN(bData.realCoord, sData->total_points*3*sizeof(float));
/* Allocate memory for surface previous points to read unchanged values from */
prevPoint = MEM_mallocN(sData->total_points*sizeof(struct PaintPoint), "PaintSurfaceDataCopy");
/* in case of error, free already allocated blocks */
if (!prevPoint || !bData.realCoord) {
- if (!bData.realCoord) MEM_freeN(bData.realCoord);
- if (!prevPoint) MEM_freeN(prevPoint);
+ if (bData.realCoord) MEM_freeN(bData.realCoord);
+ if (prevPoint) MEM_freeN(prevPoint);
+ if (bNeighs) MEM_freeN(bNeighs);
return printError(canvas, "Not enough free memory.");
}
@@ -3947,7 +4073,9 @@ static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *su
}
}
- MEM_freeN(bData.realCoord);
+ if (bData.realCoord) MEM_freeN(bData.realCoord);
+ if (bData.s_index) MEM_freeN(bData.s_index);
+ if (bData.s_num) MEM_freeN(bData.s_num);
return ret;
}
@@ -4217,7 +4345,7 @@ static int surface_slot_add_exec(bContext *C, wmOperator *op)
if (!pmd) return OPERATOR_CANCELLED;
if (!pmd->canvas) return OPERATOR_CANCELLED;
- surface = dynamicPaint_createNewSurface(pmd->canvas);
+ surface = dynamicPaint_createNewSurface(pmd->canvas, CTX_data_scene(C));
if (!surface) return OPERATOR_CANCELLED;
@@ -4294,3 +4422,54 @@ void DPAINT_OT_surface_slot_remove(wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
+static int type_toggle_exec(bContext *C, wmOperator *op) {
+
+ Object *cObject = CTX_data_active_object(C);
+ Scene *scene = CTX_data_scene(C);
+ DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)modifiers_findByType(cObject, eModifierType_DynamicPaint);
+ int type= RNA_enum_get(op->ptr, "type");
+
+ if (!pmd) return OPERATOR_CANCELLED;
+
+ /* if type is already enabled, toggle it off */
+ if (type == MOD_DYNAMICPAINT_TYPE_CANVAS && pmd->canvas) {
+ dynamicPaint_freeCanvas(pmd);
+ }
+ else if (type == MOD_DYNAMICPAINT_TYPE_BRUSH && pmd->brush) {
+ dynamicPaint_freeBrush(pmd);
+ }
+ /* else create a new type */
+ else {
+ if (!dynamicPaint_createType(pmd, type, scene))
+ return OPERATOR_CANCELLED;
+ }
+
+ /* update dependancy */
+ DAG_id_tag_update(&cObject->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, cObject);
+ DAG_scene_sort(CTX_data_main(C), scene);
+
+ return OPERATOR_FINISHED;
+}
+
+void DPAINT_OT_type_toggle(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name= "Toggle Type Active";
+ ot->idname= "DPAINT_OT_type_toggle";
+ ot->description = "Toggles whether given type is active or not";
+
+ /* api callbacks */
+ ot->exec= type_toggle_exec;
+ ot->poll= ED_operator_object_active_editable;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* properties */
+ prop= RNA_def_enum(ot->srna, "type", prop_dynamicpaint_type_items, MOD_DYNAMICPAINT_TYPE_CANVAS, "Type", "");
+ ot->prop= prop;
+}
+
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 5b7442fe5bc..2983923f5a9 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -3459,7 +3459,7 @@ void object_remove_particle_system(Scene *scene, Object *ob)
if((md = modifiers_findByType(ob, eModifierType_DynamicPaint)))
{
DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md;
- if((pmd->type == MOD_DYNAMICPAINT_TYPE_BRUSH) && pmd->brush && pmd->brush->psys)
+ if(pmd->brush && pmd->brush->psys)
if(pmd->brush->psys == psys)
pmd->brush->psys = NULL;
}
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 71aeee9c234..1994783b45c 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -688,7 +688,7 @@ static int ptcache_dynamicpaint_write(PTCacheFile *pf, void *dp_v)
else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE ||
surface->type == MOD_DPAINT_SURFACE_T_WEIGHT)
in_len = sizeof(float)*total_points;
- if (surface->type == MOD_DPAINT_SURFACE_T_WAVE)
+ else if (surface->type == MOD_DPAINT_SURFACE_T_WAVE)
in_len = sizeof(PaintWavePoint)*total_points;
else return 0;
@@ -725,7 +725,7 @@ static int ptcache_dynamicpaint_read(PTCacheFile *pf, void *dp_v)
else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE ||
surface->type == MOD_DPAINT_SURFACE_T_WEIGHT)
data_len = sizeof(float);
- if (surface->type == MOD_DPAINT_SURFACE_T_WAVE)
+ else if (surface->type == MOD_DPAINT_SURFACE_T_WAVE)
data_len = sizeof(PaintWavePoint);
else return 0;
@@ -972,7 +972,7 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int dup
}
else if(md->type == eModifierType_DynamicPaint) {
DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md;
- if(pmd->type & MOD_DYNAMICPAINT_TYPE_CANVAS)
+ if(pmd->canvas)
{
DynamicPaintSurface *surface = pmd->canvas->surfaces.first;
@@ -2474,7 +2474,7 @@ int BKE_ptcache_object_reset(Scene *scene, Object *ob, int mode)
}
if(md->type == eModifierType_DynamicPaint) {
DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md;
- if(pmd->type & MOD_DYNAMICPAINT_TYPE_CANVAS)
+ if(pmd->canvas)
{
DynamicPaintSurface *surface = pmd->canvas->surfaces.first;
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index a66caf8879f..d1a12464d26 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -1820,11 +1820,14 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *u
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple(stipple_quarttone);
}
+
+ /* dont set shading mode to flat because
+ * normals are used to change shading */
+ glShadeModel(GL_SMOOTH);
for (S=0; S<numVerts; S++) {
DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
if (drawSmooth) {
- glShadeModel(GL_SMOOTH);
for (y=0; y<gridFaces; y++) {
DMGridData *a, *b;
glBegin(GL_QUAD_STRIP);
@@ -1859,7 +1862,6 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *u
glEnd();
}
} else {
- glShadeModel(GL_FLAT);
glBegin(GL_QUADS);
for (y=0; y<gridFaces; y++) {
for (x=0; x<gridFaces; x++) {