forked from bartvdbraak/blender
Dynamic Paint:
* Added option to preview surface wetmap instead of paint. * Changed default paint color to blue for better visibility. * Fix: Random sized particles didn't work anymore. * Fix: Particle initial velocity issues when using canvas substeps and a particle brush.
This commit is contained in:
parent
c5106fd097
commit
0bb7ddad97
@ -222,6 +222,9 @@ class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, bpy.types.Panel):
|
|||||||
# vertex format outputs
|
# vertex format outputs
|
||||||
if (surface.surface_format == "VERTEX"):
|
if (surface.surface_format == "VERTEX"):
|
||||||
if (surface.surface_type == "PAINT"):
|
if (surface.surface_type == "PAINT"):
|
||||||
|
# toggle active preview
|
||||||
|
layout.prop(surface, "preview_id")
|
||||||
|
|
||||||
# paintmap output
|
# paintmap output
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
row.prop_search(surface, "output_name", ob.data, "vertex_colors", text="Paintmap layer: ")
|
row.prop_search(surface, "output_name", ob.data, "vertex_colors", text="Paintmap layer: ")
|
||||||
|
@ -410,6 +410,25 @@ static void mixColors(float *t_color, float t_alpha, float *s_color, float s_alp
|
|||||||
t_color[2] = t_color[2]*invFact + s_color[2]*factor;
|
t_color[2] = t_color[2]*invFact + s_color[2]*factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* set "ignore cache" flag for all caches on this object */
|
||||||
|
static void object_cacheIgnoreClear(Object *ob, int state)
|
||||||
|
{
|
||||||
|
ListBase pidlist;
|
||||||
|
PTCacheID *pid;
|
||||||
|
BKE_ptcache_ids_from_object(&pidlist, ob, NULL, 0);
|
||||||
|
|
||||||
|
for(pid=pidlist.first; pid; pid=pid->next) {
|
||||||
|
if(pid->cache) {
|
||||||
|
if (state)
|
||||||
|
pid->cache->flag |= PTCACHE_IGNORE_CLEAR;
|
||||||
|
else
|
||||||
|
pid->cache->flag &= ~PTCACHE_IGNORE_CLEAR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BLI_freelistN(&pidlist);
|
||||||
|
}
|
||||||
|
|
||||||
#define UPDATE_PARENTS (1<<0)
|
#define UPDATE_PARENTS (1<<0)
|
||||||
#define UPDATE_MESH (1<<1)
|
#define UPDATE_MESH (1<<1)
|
||||||
#define UPDATE_EVERYTHING (UPDATE_PARENTS|UPDATE_MESH)
|
#define UPDATE_EVERYTHING (UPDATE_PARENTS|UPDATE_MESH)
|
||||||
@ -439,8 +458,13 @@ static void subframe_updateObject(Scene *scene, Object *ob, int flags, float fra
|
|||||||
ob->recalc |= OB_RECALC_ALL;
|
ob->recalc |= OB_RECALC_ALL;
|
||||||
ob->recalc |= OB_RECALC_DATA;
|
ob->recalc |= OB_RECALC_DATA;
|
||||||
BKE_animsys_evaluate_animdata(&ob->id, ob->adt, frame, ADT_RECALC_ANIM);
|
BKE_animsys_evaluate_animdata(&ob->id, ob->adt, frame, ADT_RECALC_ANIM);
|
||||||
if (flags & UPDATE_MESH)
|
if (flags & UPDATE_MESH) {
|
||||||
|
/* ignore cache clear during subframe updates
|
||||||
|
* to not mess up cache validity */
|
||||||
|
object_cacheIgnoreClear(ob, 1);
|
||||||
object_handle_update(scene, ob);
|
object_handle_update(scene, ob);
|
||||||
|
object_cacheIgnoreClear(ob, 0);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
where_is_object_time(scene, ob, frame);
|
where_is_object_time(scene, ob, frame);
|
||||||
|
|
||||||
@ -988,8 +1012,8 @@ int dynamicPaint_createType(struct DynamicPaintModifierData *pmd, int type, stru
|
|||||||
pmd->brush->collision = MOD_DPAINT_COL_VOLUME;
|
pmd->brush->collision = MOD_DPAINT_COL_VOLUME;
|
||||||
|
|
||||||
pmd->brush->mat = NULL;
|
pmd->brush->mat = NULL;
|
||||||
pmd->brush->r = 1.0f;
|
pmd->brush->r = 0.0f;
|
||||||
pmd->brush->g = 1.0f;
|
pmd->brush->g = 0.0f;
|
||||||
pmd->brush->b = 1.0f;
|
pmd->brush->b = 1.0f;
|
||||||
pmd->brush->alpha = 1.0f;
|
pmd->brush->alpha = 1.0f;
|
||||||
pmd->brush->wetness = 1.0f;
|
pmd->brush->wetness = 1.0f;
|
||||||
@ -1373,6 +1397,8 @@ static struct DerivedMesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData
|
|||||||
|
|
||||||
for (; j<((mface[i].v4)?4:3); j++) {
|
for (; j<((mface[i].v4)?4:3); j++) {
|
||||||
int index = (j==0)?mface[i].v1: (j==1)?mface[i].v2: (j==2)?mface[i].v3: mface[i].v4;
|
int index = (j==0)?mface[i].v1: (j==1)?mface[i].v2: (j==2)?mface[i].v3: mface[i].v4;
|
||||||
|
|
||||||
|
if (surface->preview_id == MOD_DPAINT_SURFACE_PREV_PAINT) {
|
||||||
index *= 4;
|
index *= 4;
|
||||||
invAlpha = 1.0f - fcolor[index+3];
|
invAlpha = 1.0f - fcolor[index+3];
|
||||||
|
|
||||||
@ -1394,6 +1420,13 @@ static struct DerivedMesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData
|
|||||||
col[i*4+j].g = (char)(((float)col[i*4+j].g)*invAlpha + (fcolor[index+1]*255*fcolor[index+3]));
|
col[i*4+j].g = (char)(((float)col[i*4+j].g)*invAlpha + (fcolor[index+1]*255*fcolor[index+3]));
|
||||||
col[i*4+j].b = (char)(((float)col[i*4+j].b)*invAlpha + (fcolor[index]*255*fcolor[index+3]));
|
col[i*4+j].b = (char)(((float)col[i*4+j].b)*invAlpha + (fcolor[index]*255*fcolor[index+3]));
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
col[i*4+j].a = 255;
|
||||||
|
col[i*4+j].r = (char)(pPoint[index].wetness*255);
|
||||||
|
col[i*4+j].g = (char)(pPoint[index].wetness*255);
|
||||||
|
col[i*4+j].b = (char)(pPoint[index].wetness*255);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pmd->canvas->flags |= MOD_DPAINT_PREVIEW_READY;
|
pmd->canvas->flags |= MOD_DPAINT_PREVIEW_READY;
|
||||||
}
|
}
|
||||||
@ -3800,16 +3833,23 @@ static int dynamicPaint_paintParticles(DynamicPaintSurface *surface, ParticleSys
|
|||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
KDTreeNearest nearest;
|
KDTreeNearest nearest;
|
||||||
float smooth_range;
|
float smooth_range, part_solidradius;
|
||||||
radius = solidradius + smooth;
|
|
||||||
|
|
||||||
/* Find nearest particle and get distance to it */
|
/* Find nearest particle and get distance to it */
|
||||||
BLI_kdtree_find_nearest(tree, bData->realCoord[bData->s_pos[index]].v, NULL, &nearest);
|
BLI_kdtree_find_nearest(tree, bData->realCoord[bData->s_pos[index]].v, NULL, &nearest);
|
||||||
if (nearest.dist > radius) continue;
|
if (brush->flags & MOD_DPAINT_PART_RAD) {
|
||||||
|
/* use particles individual size */
|
||||||
/* distances inside solid radius have maximum influence -> dist = 0 */
|
ParticleData *pa = psys->particles + nearest.index;
|
||||||
smooth_range = (nearest.dist - solidradius);
|
part_solidradius = pa->size;
|
||||||
if (smooth_range<0) smooth_range=0.0f;
|
}
|
||||||
|
else {
|
||||||
|
part_solidradius = solidradius;
|
||||||
|
}
|
||||||
|
radius = part_solidradius + smooth;
|
||||||
|
if (nearest.dist < radius) {
|
||||||
|
/* distances inside solid radius has maximum influence -> dist = 0 */
|
||||||
|
smooth_range = (nearest.dist - part_solidradius);
|
||||||
|
if (smooth_range<0.0f) smooth_range=0.0f;
|
||||||
/* do smoothness if enabled */
|
/* do smoothness if enabled */
|
||||||
if (smooth) smooth_range/=smooth;
|
if (smooth) smooth_range/=smooth;
|
||||||
|
|
||||||
@ -3817,6 +3857,7 @@ static int dynamicPaint_paintParticles(DynamicPaintSurface *surface, ParticleSys
|
|||||||
disp_intersect = radius - nearest.dist;
|
disp_intersect = radius - nearest.dist;
|
||||||
part_index = nearest.index;
|
part_index = nearest.index;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/* If using random per particle radius and closest particle didn't give max influence */
|
/* If using random per particle radius and closest particle didn't give max influence */
|
||||||
if (brush->flags & MOD_DPAINT_PART_RAD && strength < 1.0f && psys->part->randsize > 0.0f) {
|
if (brush->flags & MOD_DPAINT_PART_RAD && strength < 1.0f && psys->part->randsize > 0.0f) {
|
||||||
/*
|
/*
|
||||||
@ -3829,7 +3870,7 @@ static int dynamicPaint_paintParticles(DynamicPaintSurface *surface, ParticleSys
|
|||||||
KDTreeNearest *nearest = nearest_th[0];
|
KDTreeNearest *nearest = nearest_th[0];
|
||||||
#endif
|
#endif
|
||||||
int n, particles = 0;
|
int n, particles = 0;
|
||||||
float smooth_range = range, dist;
|
float smooth_range = smooth * (1.0f-strength), dist;
|
||||||
/* calculate max range that can have particles with higher influence than the nearest one */
|
/* calculate max range that can have particles with higher influence than the nearest one */
|
||||||
float max_range = smooth - strength*smooth + solidradius;
|
float max_range = smooth - strength*smooth + solidradius;
|
||||||
|
|
||||||
@ -3847,7 +3888,7 @@ static int dynamicPaint_paintParticles(DynamicPaintSurface *surface, ParticleSys
|
|||||||
/* update hit data */
|
/* update hit data */
|
||||||
s_range = nearest[n].dist - pa->size;
|
s_range = nearest[n].dist - pa->size;
|
||||||
|
|
||||||
/* continue if higher influence is already found */
|
/* skip if higher influence is already found */
|
||||||
if (smooth_range < s_range)
|
if (smooth_range < s_range)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -3860,11 +3901,11 @@ static int dynamicPaint_paintParticles(DynamicPaintSurface *surface, ParticleSys
|
|||||||
if (s_range < 0.0f)
|
if (s_range < 0.0f)
|
||||||
if (surface->type != MOD_DPAINT_SURFACE_T_DISPLACE &&
|
if (surface->type != MOD_DPAINT_SURFACE_T_DISPLACE &&
|
||||||
surface->type != MOD_DPAINT_SURFACE_T_WAVE)
|
surface->type != MOD_DPAINT_SURFACE_T_WAVE)
|
||||||
break;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now calculate influence for this particle */
|
/* now calculate influence for this particle */
|
||||||
if (smooth_range != range) {
|
{
|
||||||
float rad = radius + smooth, str;
|
float rad = radius + smooth, str;
|
||||||
|
|
||||||
if ((rad-dist) > disp_intersect) {
|
if ((rad-dist) > disp_intersect) {
|
||||||
@ -3873,6 +3914,7 @@ static int dynamicPaint_paintParticles(DynamicPaintSurface *surface, ParticleSys
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* do smoothness if enabled */
|
/* do smoothness if enabled */
|
||||||
|
if (smooth_range<0.0f) smooth_range=0.0f;
|
||||||
if (smooth) smooth_range/=smooth;
|
if (smooth) smooth_range/=smooth;
|
||||||
str = 1.0f - smooth_range;
|
str = 1.0f - smooth_range;
|
||||||
/* if influence is greater, use this one */
|
/* if influence is greater, use this one */
|
||||||
|
@ -2113,6 +2113,9 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, unsigned int cfra)
|
|||||||
if(!pid || !pid->cache || pid->cache->flag & PTCACHE_BAKED)
|
if(!pid || !pid->cache || pid->cache->flag & PTCACHE_BAKED)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (pid->cache->flag & PTCACHE_IGNORE_CLEAR)
|
||||||
|
return;
|
||||||
|
|
||||||
sta = pid->cache->startframe;
|
sta = pid->cache->startframe;
|
||||||
end = pid->cache->endframe;
|
end = pid->cache->endframe;
|
||||||
|
|
||||||
|
@ -57,6 +57,10 @@ struct PaintSurfaceData;
|
|||||||
#define MOD_DPAINT_EFFECT_DO_DRIP (1<<1) /* do spread effect */
|
#define MOD_DPAINT_EFFECT_DO_DRIP (1<<1) /* do spread effect */
|
||||||
#define MOD_DPAINT_EFFECT_DO_SHRINK (1<<2) /* do spread effect */
|
#define MOD_DPAINT_EFFECT_DO_SHRINK (1<<2) /* do spread effect */
|
||||||
|
|
||||||
|
/* preview_id */
|
||||||
|
#define MOD_DPAINT_SURFACE_PREV_PAINT 0
|
||||||
|
#define MOD_DPAINT_SURFACE_PREV_WETMAP 1
|
||||||
|
|
||||||
typedef struct DynamicPaintSurface {
|
typedef struct DynamicPaintSurface {
|
||||||
|
|
||||||
struct DynamicPaintSurface *next, *prev;
|
struct DynamicPaintSurface *next, *prev;
|
||||||
@ -76,7 +80,7 @@ typedef struct DynamicPaintSurface {
|
|||||||
short format, type;
|
short format, type;
|
||||||
short disp_type, image_fileformat;
|
short disp_type, image_fileformat;
|
||||||
short effect_ui; /* just ui selection box */
|
short effect_ui; /* just ui selection box */
|
||||||
short pad;
|
short preview_id; /* surface output id to preview */
|
||||||
int flags, effect;
|
int flags, effect;
|
||||||
|
|
||||||
int image_resolution, substeps;
|
int image_resolution, substeps;
|
||||||
|
@ -400,6 +400,7 @@ typedef struct SoftBody {
|
|||||||
#define PTCACHE_IGNORE_LIBPATH 2048
|
#define PTCACHE_IGNORE_LIBPATH 2048
|
||||||
/* high resolution cache is saved for smoke for backwards compatibility, so set this flag to know it's a "fake" cache */
|
/* high resolution cache is saved for smoke for backwards compatibility, so set this flag to know it's a "fake" cache */
|
||||||
#define PTCACHE_FAKE_SMOKE (1<<12)
|
#define PTCACHE_FAKE_SMOKE (1<<12)
|
||||||
|
#define PTCACHE_IGNORE_CLEAR (1<<13)
|
||||||
|
|
||||||
/* PTCACHE_OUTDATED + PTCACHE_FRAMES_SKIPPED */
|
/* PTCACHE_OUTDATED + PTCACHE_FRAMES_SKIPPED */
|
||||||
#define PTCACHE_REDO_NEEDED 258
|
#define PTCACHE_REDO_NEEDED 258
|
||||||
|
@ -296,6 +296,12 @@ static void rna_def_canvas_surface(BlenderRNA *brna)
|
|||||||
{MOD_DPAINT_SURFACE_T_PAINT, "PAINT", 0, "Paint", ""},
|
{MOD_DPAINT_SURFACE_T_PAINT, "PAINT", 0, "Paint", ""},
|
||||||
{0, NULL, 0, NULL, NULL}};
|
{0, NULL, 0, NULL, NULL}};
|
||||||
|
|
||||||
|
/* Surface output preview. currently only paint has multiple outputs */
|
||||||
|
static EnumPropertyItem prop_dynamicpaint_surface_preview[] = {
|
||||||
|
{MOD_DPAINT_SURFACE_PREV_PAINT, "PAINT", 0, "Paint", ""},
|
||||||
|
{MOD_DPAINT_SURFACE_PREV_WETMAP, "WETMAP", 0, "Wetmap", ""},
|
||||||
|
{0, NULL, 0, NULL, NULL}};
|
||||||
|
|
||||||
/* Effect type
|
/* Effect type
|
||||||
* Only used by ui to view per effect settings */
|
* Only used by ui to view per effect settings */
|
||||||
static EnumPropertyItem prop_dynamicpaint_effecttype[] = {
|
static EnumPropertyItem prop_dynamicpaint_effecttype[] = {
|
||||||
@ -528,6 +534,13 @@ static void rna_def_canvas_surface(BlenderRNA *brna)
|
|||||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DPAINT_OUT2);
|
RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DPAINT_OUT2);
|
||||||
RNA_def_property_ui_text(prop, "Save layer", "");
|
RNA_def_property_ui_text(prop, "Save layer", "");
|
||||||
|
|
||||||
|
prop= RNA_def_property(srna, "preview_id", PROP_ENUM, PROP_NONE);
|
||||||
|
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||||
|
RNA_def_property_enum_sdna(prop, NULL, "preview_id");
|
||||||
|
RNA_def_property_enum_items(prop, prop_dynamicpaint_surface_preview);
|
||||||
|
RNA_def_property_ui_text(prop, "Preview", "");
|
||||||
|
RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_DynamicPaint_redoModifier");
|
||||||
|
|
||||||
/* to check if output name exists */
|
/* to check if output name exists */
|
||||||
func = RNA_def_function(srna, "output_exists", "rna_DynamicPaint_is_output_exists");
|
func = RNA_def_function(srna, "output_exists", "rna_DynamicPaint_is_output_exists");
|
||||||
RNA_def_function_ui_description(func, "Checks if surface output layer of given name exists");
|
RNA_def_function_ui_description(func, "Checks if surface output layer of given name exists");
|
||||||
|
Loading…
Reference in New Issue
Block a user