Dynamic Paint:

* Fixed memory leak when baking image sequences.
* Fixed sub-steps when brush was controlled by a parent object.
* Added option to select active outputs for paint surfaces.
* Improved color mixing algorithm.
* Improved memory allocation behavior.
* Memory is now freed even in case of errors.
* Removed "initial color" setting, as it's better to adjust color from material.

* "Paint effects" system:
** Converted to use new data structures.
** Works now with any number of surrounding points.
** Re-implemented support for UV-image surfaces.
** Added support for vertex surfaces too.
** Improved color handling.
** Improved movement stability.
** "Drip" effect uses now Blender's force fields instead of just z-directional gravity like before. Now each surface point can have different force influence.
This commit is contained in:
Miika Hamalainen 2011-06-27 07:30:58 +00:00
parent 40d4f34e82
commit cb12648656
8 changed files with 1088 additions and 506 deletions

@ -21,6 +21,7 @@ import bpy
from bl_ui.properties_physics_common import (
point_cache_ui,
effector_weights_ui,
)
class PhysicButtonsPanel():
@ -123,9 +124,9 @@ class PHYSICS_PT_dp_advanced_canvas(PhysicButtonsPanel, bpy.types.Panel):
ob = context.object
layout.prop(surface, "surface_type", expand=False)
layout.separator()
if (surface.surface_type == "PAINT"):
layout.prop(surface, "initial_color", expand=False)
split = layout.split(percentage=0.8)
split.prop(surface, "dry_speed", text="Dry Time")
split.prop(surface, "use_dry_log", text="Slow")
@ -189,16 +190,22 @@ class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, bpy.types.Panel):
col = layout.column()
col.prop(surface, "image_output_path", text="Output directory")
col.prop(surface, "image_fileformat", text="Image Format:")
if (surface.surface_type == "PAINT"):
col.prop(surface, "output_name", text="Paintmap: ")
col.prop(surface, "premultiply", text="Premultiply alpha")
col.prop(surface, "output_name2", text="Wetmap: ")
col.prop(surface, "do_output1", text="Output Paintmaps:")
sub = col.column()
sub.active = surface.do_output1
sub.prop(surface, "output_name", text="Filename: ")
sub.prop(surface, "premultiply", text="Premultiply alpha")
col.prop(surface, "do_output2", text="Output Wetmaps:")
sub = col.column()
sub.active = surface.do_output2
sub.prop(surface, "output_name2", text="Filename: ")
if (surface.surface_type == "DISPLACE"):
col.prop(surface, "output_name", text="Filename: ")
col.prop(surface, "disp_type", text="Displace Type")
col.prop(surface, "image_fileformat", text="Image Format:")
layout.separator()
layout.operator("dpaint.bake", text="Bake Image Sequence", icon='MOD_DYNAMICPAINT')
if len(canvas.ui_info) != 0:
@ -215,7 +222,7 @@ class PHYSICS_PT_dp_effects(PhysicButtonsPanel, bpy.types.Panel):
if ((not md) or (md.dynamicpaint_type != 'CANVAS')):
return False;
surface = context.dynamic_paint.canvas_settings.canvas_surfaces.active
return surface and (surface.surface_format != "VERTEX")
return surface and (surface.surface_format != "PTEX")
def draw(self, context):
layout = self.layout
@ -235,7 +242,7 @@ class PHYSICS_PT_dp_effects(PhysicButtonsPanel, bpy.types.Panel):
layout.prop(surface, "use_drip")
col = layout.column()
col.active = surface.use_drip
col.prop(surface, "drip_speed")
effector_weights_ui(self, context, surface.effector_weights)
elif surface.effect_ui == "SHRINK":
layout.prop(surface, "use_shrink")

@ -16,12 +16,16 @@
#include "DNA_dynamicpaint_types.h"
struct PaintEffectData;
/* Actual surface point */
typedef struct PaintSurfaceData {
/* surface format data */
void *format_data;
/* surface type data */
void *type_data;
/* paint effects data */
struct PaintEffectData *eff_data;
unsigned int total_points;
short samples;

File diff suppressed because it is too large Load Diff

@ -4042,6 +4042,9 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
surface->canvas = pmd->canvas;
surface->data = NULL;
direct_link_pointcache_list(fd, &(surface->ptcaches), &(surface->pointcache), 1);
if(!(surface->effector_weights = newdataadr(fd, surface->effector_weights)))
surface->effector_weights = BKE_add_effector_weights(NULL);
}
}
}

@ -1263,9 +1263,12 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
/* write surfaces */
for (surface=pmd->canvas->surfaces.first; surface; surface=surface->next)
writestruct(wd, DATA, "DynamicPaintSurface", 1, surface);
/* write caches */
for (surface=pmd->canvas->surfaces.first; surface; surface=surface->next)
/* write caches and effector weights */
for (surface=pmd->canvas->surfaces.first; surface; surface=surface->next) {
write_pointcaches(wd, &(surface->ptcaches));
writestruct(wd, DATA, "EffectorWeights", 1, surface->effector_weights);
}
}
else if(pmd->type & MOD_DYNAMICPAINT_TYPE_BRUSH && pmd->brush)
{

@ -39,6 +39,10 @@ struct PaintSurfaceData;
#define MOD_DPAINT_PREVIEW (1<<6) /* preview this surface on viewport*/
/* image sequence output */
#define MOD_DPAINT_OUT1 (1<<10) /* output primary surface */
#define MOD_DPAINT_OUT2 (1<<11) /* output secondary surface */
/* canvas flags */
#define MOD_DPAINT_PREVIEW_READY (1<<0) /* if viewport preview is ready */
#define MOD_DPAINT_BAKING (1<<1) /* baking an image sequence */
@ -63,6 +67,7 @@ typedef struct DynamicPaintSurface {
struct PaintSurfaceData *data;
struct Group *brush_group;
struct EffectorWeights *effector_weights;
/* cache */
struct PointCache *pointcache;
@ -76,7 +81,6 @@ typedef struct DynamicPaintSurface {
short effect_ui; /* just ui selection box */
short pad;
int flags, effect;
float intitial_color[4];
int image_resolution, substeps;
int start_frame, end_frame;
@ -84,7 +88,7 @@ typedef struct DynamicPaintSurface {
int dry_speed, diss_speed;
float disp_depth;
float spread_speed, drip_speed, shrink_speed;
float spread_speed, shrink_speed, pad_f;
char uvlayer_name[32];
char image_output_path[240];

@ -353,12 +353,6 @@ static void rna_def_canvas_surface(BlenderRNA *brna)
/*
* Paint, wet and disp
*/
prop= RNA_def_property(srna, "initial_color", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_float_sdna(prop, NULL, "intitial_color");
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Initial Color", "Initial surface color");
RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_DynamicPaintSurface_reset");
prop= RNA_def_property(srna, "use_dissolve", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DPAINT_DISSOLVE);
@ -441,30 +435,29 @@ static void rna_def_canvas_surface(BlenderRNA *brna)
prop= RNA_def_property(srna, "spread_speed", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "spread_speed");
RNA_def_property_range(prop, 0.1, 5.0);
RNA_def_property_ui_range(prop, 0.1, 5.0, 1, 2);
RNA_def_property_range(prop, 0.01, 5.0);
RNA_def_property_ui_range(prop, 0.001, 20.0, 1, 2);
RNA_def_property_ui_text(prop, "Spread Speed", "How fast spread effect moves on the canvas surface.");
prop= RNA_def_property(srna, "use_drip", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "effect", MOD_DPAINT_EFFECT_DO_DRIP);
RNA_def_property_ui_text(prop, "Use Drip", "Processes drip effect. Drips wet paint to gravity direction.");
prop= RNA_def_property(srna, "drip_speed", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "drip_speed");
RNA_def_property_range(prop, 0.1, 5.0);
RNA_def_property_ui_range(prop, 0.1, 5.0, 1, 2);
RNA_def_property_ui_text(prop, "Drip Speed", "How fast drip effect moves on the canvas surface.");
prop= RNA_def_property(srna, "use_shrink", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "effect", MOD_DPAINT_EFFECT_DO_SHRINK);
RNA_def_property_ui_text(prop, "Use Shrink", "Processes shrink effect. Shrinks paint areas.");
prop= RNA_def_property(srna, "shrink_speed", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "shrink_speed");
RNA_def_property_range(prop, 0.1, 5.0);
RNA_def_property_ui_range(prop, 0.1, 5.0, 1, 2);
RNA_def_property_range(prop, 0.01, 5.0);
RNA_def_property_ui_range(prop, 0.01, 20.0, 1, 2);
RNA_def_property_ui_text(prop, "Shrink Speed", "How fast shrink effect moves on the canvas surface.");
prop= RNA_def_property(srna, "effector_weights", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "EffectorWeights");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Effector Weights", "");
/*
* Output settings
*/
@ -482,11 +475,18 @@ static void rna_def_canvas_surface(BlenderRNA *brna)
RNA_def_property_string_sdna(prop, NULL, "output_name");
RNA_def_property_ui_text(prop, "Output name", "");
prop= RNA_def_property(srna, "do_output1", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DPAINT_OUT1);
RNA_def_property_ui_text(prop, "Save layer", "");
/* output for secondary sufrace data */
prop= RNA_def_property(srna, "output_name2", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "output_name2");
RNA_def_property_ui_text(prop, "Output name", "");
//RNA_def_property_string_funcs(prop, NULL, NULL, "rna_DynamicPaint_uvlayer_set");
prop= RNA_def_property(srna, "do_output2", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DPAINT_OUT2);
RNA_def_property_ui_text(prop, "Save layer", "");
prop= RNA_def_property(srna, "displacement", PROP_FLOAT, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);

@ -643,6 +643,22 @@ static char *rna_EffectorWeight_path(PointerRNA *ptr)
if (smd->domain->effector_weights == ew)
return BLI_sprintfN("modifiers[\"%s\"].settings.effector_weights", md->name);
}
/* check dynamic paint modifier */
md = (ModifierData *)modifiers_findByType(ob, eModifierType_DynamicPaint);
if (md) {
DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md;
if (pmd->canvas) {
DynamicPaintSurface *surface = pmd->canvas->surfaces.first;
for(; surface; surface=surface->next) {
if (surface->effector_weights == ew)
return BLI_sprintfN("modifiers[\"%s\"].canvas_settings.canvas_surfaces[\"%s\"].effector_weights",
md->name, surface->name);
}
}
}
}
return NULL;
}