Dynamic Paint:
authorMiika Hamalainen <blender@miikah.org>
Sat, 18 Jun 2011 18:41:20 +0000 (18:41 +0000)
committerMiika Hamalainen <blender@miikah.org>
Sat, 18 Jun 2011 18:41:20 +0000 (18:41 +0000)
* Added vertex weight painting.
* Added dissolve/fade setting for every surface type.
* Restored image format and displace type selection for image sequences.
* Fixed a possible crash when OpenMP enabled.
* Attempt to fix surface rna paths.
* Fixed compile warnings.

release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py
source/blender/blenkernel/intern/dynamicpaint.c
source/blender/blenkernel/intern/pointcache.c
source/blender/makesrna/intern/rna_dynamicpaint.c
source/blender/modifiers/intern/MOD_dynamicpaint.c
source/blender/render/intern/source/render_texture.c

index 46edc6e..9f3f590 100644 (file)
@@ -49,9 +49,9 @@ class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, bpy.types.Panel):
 
             if md.dynamicpaint_type == 'CANVAS':
                 canvas = md.canvas_settings
-                surface = canvas.active_surface
+                surface = canvas.canvas_surfaces.active
                 row = layout.row()
-                row.template_list(canvas, "canvas_surfaces", canvas, "active_index", rows=2)
+                row.template_list(canvas, "canvas_surfaces", canvas.canvas_surfaces, "active_index", rows=2)
 
                 col = row.column(align=True)
                 col.operator("dpaint.surface_slot_add", icon='ZOOMIN', text="")
@@ -113,31 +113,35 @@ class PHYSICS_PT_dp_advanced_canvas(PhysicButtonsPanel, bpy.types.Panel):
     @classmethod
     def poll(cls, context):
         md = context.dynamic_paint
-        return md and (md.dynamicpaint_type == 'CANVAS') and (context.dynamic_paint.canvas_settings.active_surface)
+        return md and (md.dynamicpaint_type == 'CANVAS') and (context.dynamic_paint.canvas_settings.canvas_surfaces.active)
 
     def draw(self, context):
         layout = self.layout
 
         canvas = context.dynamic_paint.canvas_settings
-        surface = canvas.active_surface
+        surface = canvas.canvas_surfaces.active
         ob = context.object
 
         layout.prop(surface, "surface_type", expand=False)
 
         if (surface.surface_type == "PAINT"):
             layout.prop(surface, "initial_color", expand=False)
-            col = layout.split(percentage=0.33)
-            col.prop(surface, "use_dissolve", text="Dissolve:")
-            sub = col.column()
-            sub.active = surface.use_dissolve
-            sub.prop(surface, "dissolve_speed", text="Time")
-
-        if (surface.surface_type == "DISPLACE"):
-            col = layout.split(percentage=0.33)
-            col.prop(surface, "use_dissolve", text="Flatten:")
-            sub = col.column()
+            split = layout.split(percentage=0.8)
+            split.prop(surface, "dry_speed", text="Dry Time")
+            split.prop(surface, "use_dry_log", text="Slow")
+            
+        if (surface.surface_type != "IWAVE"):
+            if (surface.surface_type == "DISPLACE"):
+                layout.prop(surface, "use_dissolve", text="Dissolve:")
+            elif (surface.surface_type == "WEIGHT"):
+                layout.prop(surface, "use_dissolve", text="Fade:")
+            else:
+                layout.prop(surface, "use_dissolve", text="Dissolve:")
+            sub = layout.column()
             sub.active = surface.use_dissolve
-            sub.prop(surface, "dissolve_speed", text="Time")
+            split = sub.split(percentage=0.8)
+            split.prop(surface, "dissolve_speed", text="Time")
+            split.prop(surface, "use_dissolve_log", text="Slow")
             
         layout.label(text="Brush Group:")
         layout.prop(surface, "brush_group", text="")
@@ -152,14 +156,14 @@ class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, bpy.types.Panel):
         md = context.dynamic_paint
         if ((not md) or (md.dynamicpaint_type != 'CANVAS')):
             return 0
-        surface = context.dynamic_paint.canvas_settings.active_surface
+        surface = context.dynamic_paint.canvas_settings.canvas_surfaces.active
         return (surface and (not (surface.surface_format=="VERTEX" and surface.surface_type=="DISPLACE") ))
 
     def draw(self, context):
         layout = self.layout
 
         canvas = context.dynamic_paint.canvas_settings
-        surface = canvas.active_surface
+        surface = canvas.canvas_surfaces.active
         ob = context.object
         
         # vertex format outputs
@@ -174,6 +178,8 @@ class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, bpy.types.Panel):
                 row.prop_search(surface, "output_name2", ob.data, "vertex_colors", text="Wetmap layer: ")
                 #col = row.column(align=True)
                 #col.operator("dpaint.output_add", icon='ZOOMIN', text="")
+            if (surface.surface_type == "WEIGHT"):
+                layout.prop_search(surface, "output_name", ob, "vertex_groups", text="Vertex Group: ")
 
         # image format outputs
         if (surface.surface_format == "IMAGE"):
@@ -189,34 +195,14 @@ class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, bpy.types.Panel):
                 col.prop(surface, "output_name2", text="Wetmap: ")
             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:
                 layout.label(text=canvas.ui_info)
-#            
-#            layout.separator()
-#
-#            col = layout.column()
-#            col.prop(surface, "output_wet")
-#            sub = col.column()
-#            sub.active = surface.output_wet
-#            sub.prop(surface, "wet_output_path", text="")
-#            
-#            layout.separator()
-#
-#            col = layout.column()
-#            col.prop(surface, "output_disp")
-#            sub = col.column()
-#            sub.active = surface.output_disp
-#            sub.prop(surface, "displace_output_path", text="")
-#            sub.prop(surface, "displacement", text="Strength")
-#
-#            split = sub.split()
-#            sub = split.column()
-#            sub.prop(surface, "disp_type", text="Type")
-#            sub = split.column()
-#            sub.prop(surface, "disp_format", text="Format")
                
 
 class PHYSICS_PT_dp_effects(PhysicButtonsPanel, bpy.types.Panel):
@@ -228,14 +214,14 @@ class PHYSICS_PT_dp_effects(PhysicButtonsPanel, bpy.types.Panel):
         md = context.dynamic_paint
         if ((not md) or (md.dynamicpaint_type != 'CANVAS')):
             return False;
-        surface = context.dynamic_paint.canvas_settings.active_surface
+        surface = context.dynamic_paint.canvas_settings.canvas_surfaces.active
         return surface and (surface.surface_format != "VERTEX")
 
     def draw(self, context):
         layout = self.layout
 
         canvas = context.dynamic_paint.canvas_settings
-        surface = canvas.active_surface
+        surface = canvas.canvas_surfaces.active
 
         layout.prop(surface, "effect_ui", expand=True)
 
@@ -266,12 +252,12 @@ class PHYSICS_PT_dp_cache(PhysicButtonsPanel, bpy.types.Panel):
     def poll(cls, context):
         md = context.dynamic_paint
         return md and (md.dynamicpaint_type == 'CANVAS') and \
-        (md.canvas_settings.active_surface) and (md.canvas_settings.active_surface.uses_cache)
+        (md.canvas_settings.canvas_surfaces.active) and (md.canvas_settings.canvas_surfaces.active.uses_cache)
 
     def draw(self, context):
         layout = self.layout
 
-        surface = context.dynamic_paint.canvas_settings.active_surface
+        surface = context.dynamic_paint.canvas_settings.canvas_surfaces.active
         cache = surface.point_cache
         
         point_cache_ui(self, context, cache, (cache.is_baked is False), 'DYNAMIC_PAINT')
index 93a6cec..377967c 100644 (file)
@@ -32,6 +32,7 @@
 #include "BKE_context.h"
 #include "BKE_customdata.h"
 #include "BKE_colortools.h"
+#include "BKE_deform.h"
 #include "BKE_depsgraph.h"
 #include "BKE_DerivedMesh.h"
 #include "BKE_dynamicpaint.h"
@@ -399,7 +400,7 @@ static DynamicPaintSurface *dynamicPaint_createNewSurface(DynamicPaintCanvasSett
        surface->pointcache->step = 1;
 
        /* Set initial values */
-       surface->flags = MOD_DPAINT_ANTIALIAS | MOD_DPAINT_MULALPHA | MOD_DPAINT_DRY_LOG | MOD_DPAINT_ACTIVE | MOD_DPAINT_PREVIEW;
+       surface->flags = MOD_DPAINT_ANTIALIAS | MOD_DPAINT_MULALPHA | MOD_DPAINT_DRY_LOG | MOD_DPAINT_DISSOLVE_LOG | MOD_DPAINT_ACTIVE | MOD_DPAINT_PREVIEW;
        surface->effect = 0;
        surface->effect_ui = 1;
 
@@ -471,7 +472,7 @@ void dynamicPaint_Modifier_createType(struct DynamicPaintModifierData *pmd)
                        pmd->brush->wetness = 1.0f;
 
                        pmd->brush->paint_distance = 0.1f;
-                       pmd->brush->proximity_falloff = MOD_DPAINT_PRFALL_SHARP;
+                       pmd->brush->proximity_falloff = MOD_DPAINT_PRFALL_SMOOTH;
 
                        pmd->brush->displace_distance = 0.5f;
                        pmd->brush->prox_displace_strength = 0.5f;
@@ -737,14 +738,16 @@ struct DerivedMesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, S
 
                                                MFace *mface = result->getFaceArray(result);
                                                int numOfFaces = result->getNumFaces(result);
-                                               int i,j;
+                                               int i;
                                                PaintPoint* pPoint = (PaintPoint*)surface->data->type_data;
                                                MCol *col;
 
                                                /* paint is stored on dry and wet layers, so mix final color first */
                                                float *fcolor = MEM_callocN(sizeof(float)*surface->data->total_points*4, "Temp paint color");
+
+                                               #pragma omp parallel for schedule(static)
                                                for (i=0; i<surface->data->total_points; i++) {
-                                                       j=i*4;
+                                                       int j=i*4;
                                                        /* If dry layer already has a color, blend it */
                                                        if (pPoint[i].alpha) {
                                                                float invAlpha = 1.0f - pPoint[i].e_alpha;
@@ -770,6 +773,7 @@ struct DerivedMesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, S
                                                        if (!col) col = CustomData_add_layer(&result->faceData, CD_WEIGHT_MCOL, CD_CALLOC, NULL, numOfFaces);
 
                                                        if (col) {
+                                                               #pragma omp parallel for schedule(static)
                                                                for (i=0; i<numOfFaces; i++) {
                                                                        int j=0;
                                                                        float invAlpha;
@@ -809,6 +813,7 @@ struct DerivedMesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, S
                                                /* paint layer */
                                                col = CustomData_get_layer_named(&dm->faceData, CD_MCOL, surface->output_name);
                                                if (col) {
+                                                       #pragma omp parallel for schedule(static)
                                                        for (i=0; i<numOfFaces; i++) {
                                                                int j=0;
                                                                for (; j<((mface[i].v4)?4:3); j++) {
@@ -827,6 +832,7 @@ struct DerivedMesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, S
                                                /* wet layer */
                                                col = CustomData_get_layer_named(&dm->faceData, CD_MCOL, surface->output_name2);
                                                if (col) {
+                                                       #pragma omp parallel for schedule(static)
                                                        for (i=0; i<numOfFaces; i++) {
                                                                int j=0;
 
@@ -859,8 +865,79 @@ struct DerivedMesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, S
 
                                                CDDM_calc_normals(result);
                                        }
+
                                        /* vertex group paint */
                                        else if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) {
+                                               int defgrp_index = defgroup_name_index(ob, surface->output_name);
+                                               MDeformVert *dvert = result->getVertDataArray(result, CD_MDEFORMVERT);
+                                               float *weight = (float*)surface->data->type_data;
+                                               /* viewport preview */
+                                               if (surface->flags & MOD_DPAINT_PREVIEW) {
+                                                       /* Save preview results to weight layer, to be
+                                                       *   able to share same drawing methods */
+                                                       MFace *mface = result->getFaceArray(result);
+                                                       int numOfFaces = result->getNumFaces(result);
+                                                       int i,j;
+                                                       MCol *col = result->getFaceDataArray(result, CD_WEIGHT_MCOL);
+                                                       if (!col) col = CustomData_add_layer(&result->faceData, CD_WEIGHT_MCOL, CD_CALLOC, NULL, numOfFaces);
+
+                                                       if (col) {
+                                                               #pragma omp parallel for schedule(static)
+                                                               for (i=0; i<numOfFaces; i++) {
+                                                                       float temp_color[3];
+                                                                       int j=0;
+                                                                       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;
+
+                                                                               col[i*4+j].a = 255;
+
+                                                                               weight_to_rgb(weight[index], temp_color, temp_color+1, temp_color+2);
+                                                                               col[i*4+j].r = (char)(temp_color[2]*255);
+                                                                               col[i*4+j].g = (char)(temp_color[1]*255);
+                                                                               col[i*4+j].b = (char)(temp_color[0]*255);
+                                                                       }
+                                                               }
+                                                               pmd->canvas->flags |= MOD_DPAINT_PREVIEW_READY;
+                                                       }
+                                               }
+
+                                               /* apply weights into a vertex group, if doesnt exists add a new layer */
+                                               if (defgrp_index >= 0 && !dvert && strlen(surface->output_name)>0)
+                                                       dvert = CustomData_add_layer_named(&result->vertData, CD_MDEFORMVERT, CD_CALLOC,
+                                                                                                                               NULL, surface->data->total_points, surface->output_name);
+                                               if (defgrp_index >= 0 && dvert) {
+                                                       int i;
+                                                       for(i=0; i<surface->data->total_points; i++) {
+                                                               int j;
+                                                               MDeformVert *dv= &dvert[i];
+                                                               MDeformWeight *def_weight = NULL;
+
+                                                               /* check if this vertex has a weight */
+                                                               for (j=0; j<dv->totweight; j++) {
+                                                                       if (dv->dw[j].def_nr == defgrp_index) {
+                                                                               def_weight = &dv->dw[j];
+                                                                               break;
+                                                                       }
+                                                               }
+
+                                                               /* if not found, add a weight for it */
+                                                               if (!def_weight) {
+                                                                       MDeformWeight *newdw = MEM_callocN(sizeof(MDeformWeight)*(dv->totweight+1), 
+                                                                                                                "deformWeight");
+                                                                       if(dv->dw){
+                                                                               memcpy(newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight);
+                                                                               MEM_freeN(dv->dw);
+                                                                       }
+                                                                       dv->dw=newdw;
+                                                                       dv->dw[dv->totweight].def_nr=defgrp_index;
+                                                                       def_weight = &dv->dw[dv->totweight];
+                                                                       dv->totweight++;
+                                                               }
+
+                                                               /* set weight value */
+                                                               def_weight->weight = weight[i];
+                                                       }
+                                               }
                                        }
                                }
                        }
@@ -1419,8 +1496,6 @@ static int dynamicPaint_createUVSurface(DynamicPaintSurface *surface)
        *       When base loop is over convert found neighbour indexes to real ones
        *       Also count the final number of active surface points
        */
-
-       #pragma omp parallel for schedule(static)
        for (yy = 0; yy < h; yy++)
        {
                int xx;
@@ -2531,6 +2606,7 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, PaintBakeData *b
                                                        brushFactor /= gaussianTotal;
                                                }
                                                CLAMP(brushFactor, 0.0f, 1.0f);
+                                               brushFactor *= brush->alpha;
 
                                                //cPoint->state = 2;
 
@@ -2545,7 +2621,7 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, PaintBakeData *b
                                                        paintAlpha /= numOfHits;
 
                                                        /* Multiply alpha value by the ui multiplier    */
-                                                       paintAlpha = paintAlpha * brushFactor * brush->alpha;
+                                                       paintAlpha = paintAlpha * brushFactor;
                                                        if (paintAlpha > 1.0f) paintAlpha = 1.0f;
 
                                                        /*
@@ -2566,6 +2642,23 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, PaintBakeData *b
                                                                if (value[index] < depth) value[index] = depth;
                                                        }
                                                }
+                                               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;
+                                                               }
+                                                       }
+                                               }
                                        }
                                }
                        }
@@ -2738,6 +2831,17 @@ static int dynamicPaint_paintParticles(DynamicPaintSurface *surface, PaintBakeDa
                        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;
+                       }
+                       else {
+                               if (value[index] < strength) value[index] = strength;
+                       }
+               }
        }
        BLI_kdtree_free(tree);
 
@@ -2748,6 +2852,8 @@ static int dynamicPaint_paintParticles(DynamicPaintSurface *surface, PaintBakeDa
 /***************************** Dynamic Paint Step / Baking ******************************/
 
 
+#define VALUE_DISSOLVE(VALUE, SPEED, SCALE, LOG) (VALUE) = (LOG) ? (VALUE) * 1.0f - 1.0f/((SPEED)/(SCALE)) : (VALUE) - 1.0f/(SPEED)*(SCALE)
+
 /* Prepare for surface step by creating PaintBakePoint data */
 static int dynamicPaint_prepareSurfaceStep(DynamicPaintSurface *surface, PaintBakeData *bData, Object *ob, DerivedMesh *dm, float timescale) {
        PaintSurfaceData *sData = surface->data;
@@ -2815,8 +2921,7 @@ static int dynamicPaint_prepareSurfaceStep(DynamicPaintSurface *surface, PaintBa
                                if (pPoint->e_alpha > pPoint->alpha) pPoint->alpha = pPoint->e_alpha;
 
                                /* now dry it ;o        */
-                               if (surface->flags & MOD_DPAINT_DRY_LOG) pPoint->wetness *= 1.0f - (1.0 / (surface->dry_speed/timescale));
-                               else pPoint->wetness -= 1.0f/surface->dry_speed*timescale;
+                               VALUE_DISSOLVE(pPoint->wetness, surface->dry_speed, timescale, (surface->flags & MOD_DPAINT_DRY_LOG));
                        }
                        /*      If effect layer is completely dry, make sure it's marked empty */
                        if (pPoint->wetness <= 0.0f) {
@@ -2827,18 +2932,22 @@ static int dynamicPaint_prepareSurfaceStep(DynamicPaintSurface *surface, PaintBa
 
                        if (surface->flags & MOD_DPAINT_DISSOLVE) {
 
-                               pPoint->alpha -= 1.0f/surface->diss_speed*timescale;
+                               VALUE_DISSOLVE(pPoint->alpha, surface->diss_speed, timescale, (surface->flags & MOD_DPAINT_DISSOLVE_LOG));
                                if (pPoint->alpha < 0.0f) pPoint->alpha = 0.0f;
 
-                               pPoint->e_alpha -= 1.0f/surface->diss_speed*timescale;
+                               VALUE_DISSOLVE(pPoint->e_alpha, surface->diss_speed, timescale, (surface->flags & MOD_DPAINT_DISSOLVE_LOG));
                                if (pPoint->e_alpha < 0.0f) pPoint->e_alpha = 0.0f;
                        }
                }
-               else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE &&
-                               surface->flags & MOD_DPAINT_DISSOLVE) {
-                       float *point = &((float*)sData->type_data)[index];
+               /* dissolve for float types */
+               else if (surface->flags & MOD_DPAINT_DISSOLVE &&
+                               (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE ||
+                                surface->type == MOD_DPAINT_SURFACE_T_WEIGHT)) {
 
-                       *point *= 1.0f - (1.0 / (surface->diss_speed/timescale));
+                       float *point = &((float*)sData->type_data)[index];
+                       /* log or linear */
+                       VALUE_DISSOLVE(*point, surface->diss_speed, timescale, (surface->flags & MOD_DPAINT_DISSOLVE_LOG));
+                       if (*point < 0.0f) *point = 0.0f;
                }
 
                /*
@@ -3150,7 +3259,7 @@ static int dynamicPaint_bakeImageSequence(bContext *C, DynamicPaintSurface *surf
                        char pad[4];
                        char dir_slash[2];
                                                /* OpenEXR or PNG       */
-                       int format = (surface->image_fileformat & MOD_DPAINT_IMGFORMAT_OPENEXR) ? DPOUTPUT_OPENEXR : DPOUTPUT_PNG;
+                       short format = (surface->image_fileformat & MOD_DPAINT_IMGFORMAT_OPENEXR) ? DPOUTPUT_OPENEXR : DPOUTPUT_PNG;
 
                        /* Add frame number padding     */
                        if (frame<10) sprintf(pad,"000");
index e92ba11..65e16f5 100644 (file)
@@ -687,7 +687,8 @@ static int  ptcache_dynamicpaint_write(PTCacheFile *pf, void *dp_v)
                        in_len = sizeof(PaintPoint)*total_points;
                        out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len), "pointcache_lzo_buffer");
                }
-               else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) {
+               else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE ||
+                                surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) {
                        in_len = sizeof(float)*total_points;
                        out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len), "pointcache_lzo_buffer");
                }
@@ -721,7 +722,8 @@ static int ptcache_dynamicpaint_read(PTCacheFile *pf, void *dp_v)
                /* read surface data */
                if (surface->type == MOD_DPAINT_SURFACE_T_PAINT)
                        data_len = sizeof(PaintPoint);
-               else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE)
+               else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE ||
+                                surface->type == MOD_DPAINT_SURFACE_T_WEIGHT)
                        data_len = sizeof(float);
                else return 0;
 
index 45f9a11..405f083 100644 (file)
@@ -53,6 +53,14 @@ static char *rna_DynamicPaintBrushSettings_path(PointerRNA *ptr)
        return BLI_sprintfN("modifiers[\"%s\"].brush_settings", md->name);
 }
 
+static char *rna_DynamicPaintSurface_path(PointerRNA *ptr)
+{
+       DynamicPaintSurface *surface = (DynamicPaintSurface*)ptr->data;
+       ModifierData *md= (ModifierData *)surface->canvas->pmd;
+
+       return BLI_sprintfN("modifiers[\"%s\"].canvas_settings.canvas_surfaces[\"%s\"]", md->name, surface->name);
+}
+
 
 /*
 *      Surfaces
@@ -205,12 +213,12 @@ static EnumPropertyItem *rna_DynamicPaint_surface_type_itemf(bContext *C, Pointe
        }
 
        /* Weight */
-       /*if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
+       if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
                tmp.value = MOD_DPAINT_SURFACE_T_WEIGHT;
                tmp.identifier = "WEIGHT";
                tmp.name = "Weight";
                RNA_enum_item_add(&item, &totitem, &tmp);
-       }*/
+       }
 
        /* iWave */
        /*if (surface->format == MOD_DPAINT_SURFACE_F_PTEX ||
@@ -229,7 +237,35 @@ static EnumPropertyItem *rna_DynamicPaint_surface_type_itemf(bContext *C, Pointe
 
 #else
 
-static void rna_def_surface(BlenderRNA *brna, PropertyRNA *cprop)
+/* canvas.canvas_surfaces */
+static void rna_def_canvas_surfaces(BlenderRNA *brna, PropertyRNA *cprop)
+{
+       StructRNA *srna;
+       
+       PropertyRNA *prop;
+
+       // FunctionRNA *func;
+       // PropertyRNA *parm;
+
+       RNA_def_property_srna(cprop, "DynamicPaintSurfaces");
+       srna= RNA_def_struct(brna, "DynamicPaintSurfaces", NULL);
+       RNA_def_struct_sdna(srna, "DynamicPaintCanvasSettings");
+       RNA_def_struct_ui_text(srna, "Canvas Surfaces", "Collection of Dynamic Paint Canvas surfaces");
+
+       prop= RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_int_funcs(prop, "rna_Surface_active_point_index_get", "rna_Surface_active_point_index_set", "rna_Surface_active_point_range");
+       RNA_def_property_ui_text(prop, "Active Point Cache Index", "");
+
+       prop= RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
+       RNA_def_property_struct_type(prop, "DynamicPaintSurface");
+       RNA_def_property_pointer_funcs(prop, "rna_PaintSurface_active_get", NULL, NULL, NULL);
+       RNA_def_property_ui_text(prop, "Active Surface", "Active Dynamic Paint surface being displayed");
+       RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL);
+}
+
+
+static void rna_def_canvas_surface(BlenderRNA *brna)
 {
        StructRNA *srna;
        PropertyRNA *prop;
@@ -271,10 +307,10 @@ static void rna_def_surface(BlenderRNA *brna, PropertyRNA *cprop)
 
 
        /* Surface */
-       RNA_def_property_srna(cprop, "DynamicPaintSurface");
        srna= RNA_def_struct(brna, "DynamicPaintSurface", NULL);
        RNA_def_struct_sdna(srna, "DynamicPaintSurface");
        RNA_def_struct_ui_text(srna, "Paint Surface", "A canvas surface layer.");
+       RNA_def_struct_path_func(srna, "rna_DynamicPaintSurface_path");
 
        prop= RNA_def_property(srna, "surface_format", PROP_ENUM, PROP_NONE);
        RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
@@ -318,6 +354,7 @@ static void rna_def_surface(BlenderRNA *brna, PropertyRNA *cprop)
        *   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");
@@ -377,6 +414,7 @@ static void rna_def_surface(BlenderRNA *brna, PropertyRNA *cprop)
        RNA_def_property_ui_text(prop, "Sub-Steps", "Do extra frames between scene frames to ensure smooth motion.");
        
        prop= RNA_def_property(srna, "use_anti_aliasing", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
        RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DPAINT_ANTIALIAS);
        RNA_def_property_ui_text(prop, "Anti-aliasing", "Uses 5x multisampling to smoothen paint edges.");
 
@@ -391,7 +429,11 @@ static void rna_def_surface(BlenderRNA *brna, PropertyRNA *cprop)
        
        prop= RNA_def_property(srna, "use_dry_log", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DPAINT_DRY_LOG);
-       RNA_def_property_ui_text(prop, "Slow", "Use 1/x instead of linear drying.");
+       RNA_def_property_ui_text(prop, "Slow", "Use logarithmic drying. Makes high values to fade faster than low values.");
+
+       prop= RNA_def_property(srna, "use_dissolve_log", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DPAINT_DISSOLVE_LOG);
+       RNA_def_property_ui_text(prop, "Slow", "Use logarithmic dissolve. Makes high values to fade faster than low values.");
        
        prop= RNA_def_property(srna, "use_spread", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "effect", MOD_DPAINT_EFFECT_DO_SPREAD);
@@ -496,17 +538,7 @@ static void rna_def_dynamic_paint_canvas_settings(BlenderRNA *brna)
        RNA_def_property_collection_funcs(prop, "rna_DynamicPaint_surfaces_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0);
        RNA_def_property_struct_type(prop, "DynamicPaintSurface");
        RNA_def_property_ui_text(prop, "Paint Surface List", "Paint surface list");
-       rna_def_surface(brna, prop);
-
-       
-       prop= RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
-       RNA_def_property_int_funcs(prop, "rna_Surface_active_point_index_get", "rna_Surface_active_point_index_set", "rna_Surface_active_point_range");
-       RNA_def_property_ui_text(prop, "Active Point Cache Index", "");
-
-       prop= RNA_def_property(srna, "active_surface", PROP_POINTER, PROP_NONE);
-       RNA_def_property_struct_type(prop, "DynamicPaintSurface");
-       RNA_def_property_pointer_funcs(prop, "rna_PaintSurface_active_get", NULL, NULL, NULL);
-       RNA_def_property_ui_text(prop, "Active Surface", "");
+       rna_def_canvas_surfaces(brna, prop);
 
        prop= RNA_def_property(srna, "ui_info", PROP_STRING, PROP_NONE);
        RNA_def_property_string_sdna(prop, NULL, "ui_info");
@@ -672,6 +704,7 @@ void RNA_def_dynamic_paint(BlenderRNA *brna)
 {
        rna_def_dynamic_paint_canvas_settings(brna);
        rna_def_dynamic_paint_brush_settings(brna);
+       rna_def_canvas_surface(brna);
 }
 
 #endif
index 3b02186..18956a2 100644 (file)
@@ -58,6 +58,7 @@ static CustomDataMask requiredDataMask(Object *ob, ModifierData *md)
 
        dataMask |= (1 << CD_MTFACE);
        dataMask |= (1 << CD_MCOL);
+       dataMask |= (1 << CD_MDEFORMVERT);
 
        return dataMask;
 }
@@ -86,7 +87,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
 
 static void updateDepgraph(ModifierData *md, DagForest *forest,
                                                struct Scene *scene,
-                                               Object *UNUSED(ob),
+                                               Object *ob,
                                                DagNode *obNode)
 {
        DynamicPaintModifierData *pmd = (DynamicPaintModifierData*) md;
@@ -133,6 +134,7 @@ ModifierTypeInfo modifierType_DynamicPaint = {
        /* structSize */        sizeof(DynamicPaintModifierData),
        /* type */              eModifierTypeType_Constructive,
        /* flags */             eModifierTypeFlag_AcceptsMesh
+                                                       | eModifierTypeFlag_UsesPointCache
                                                        | eModifierTypeFlag_Single,
 
        /* copyData */          copyData,
@@ -148,6 +150,7 @@ ModifierTypeInfo modifierType_DynamicPaint = {
        /* isDisabled */        0,
        /* updateDepgraph */    updateDepgraph,
        /* dependsOnTime */     dependsOnTime,
+       /* dependsOnNormals */  0,
        /* foreachObjectLink */ 0,
        /* foreachIDLink */     foreachIDLink,
 };
index 72ed716..408dd33 100644 (file)
@@ -1679,7 +1679,7 @@ void texco_mapping_ext(float *facenor, Tex* tex, MTex* mtex, float* co, float* d
        memset (&dum_shi,0,sizeof(ShadeInput));
 
        // Make sure values used by texco_mapping() are correct
-       dum_shi.osatex = NULL;
+       dum_shi.osatex = 0;
        dum_shi.vlr = NULL;
        VECCOPY(dum_shi.facenor, facenor);