Merge with trunk r41625
[blender.git] / source / blender / modifiers / intern / MOD_dynamicpaint.c
1 /*
2 * ***** BEGIN GPL LICENSE BLOCK *****
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * Contributor(s): Miika Hämäläinen
10 *
11 * ***** END GPL LICENSE BLOCK *****
12 *
13 */
14
15 #include <stddef.h>
16
17 #include "DNA_dynamicpaint_types.h"
18 #include "DNA_meshdata_types.h"
19 #include "DNA_object_types.h"
20 #include "DNA_scene_types.h"
21
22 #include "MEM_guardedalloc.h"
23
24 #include "BKE_cdderivedmesh.h"
25 #include "BKE_dynamicpaint.h"
26 #include "BKE_modifier.h"
27
28 #include "depsgraph_private.h"
29
30 #include "MOD_util.h"
31
32
33 static void initData(ModifierData *md) 
34 {
35         DynamicPaintModifierData *pmd = (DynamicPaintModifierData*) md;
36         
37         pmd->canvas = NULL;
38         pmd->brush = NULL;
39         pmd->type = MOD_DYNAMICPAINT_TYPE_CANVAS;
40 }
41
42 static void copyData(ModifierData *md, ModifierData *target)
43 {
44         DynamicPaintModifierData *pmd  = (DynamicPaintModifierData*)md;
45         DynamicPaintModifierData *tpmd = (DynamicPaintModifierData*)target;
46         
47         dynamicPaint_Modifier_copy(pmd, tpmd);
48 }
49
50 static void freeData(ModifierData *md)
51 {
52         DynamicPaintModifierData *pmd = (DynamicPaintModifierData*) md;
53         dynamicPaint_Modifier_free(pmd);
54 }
55
56 static CustomDataMask requiredDataMask(Object *ob, ModifierData *md)
57 {
58         DynamicPaintModifierData *pmd = (DynamicPaintModifierData*)md;
59         CustomDataMask dataMask = 0;
60
61         if (pmd->canvas) {
62                 DynamicPaintSurface *surface = pmd->canvas->surfaces.first;
63                 for(; surface; surface=surface->next) {
64                         /* tface */
65                         if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ || 
66                                 surface->init_color_type == MOD_DPAINT_INITIAL_TEXTURE) {
67                                 dataMask |= (1 << CD_MTFACE);
68                         }
69                         /* mcol */
70                         if (surface->type == MOD_DPAINT_SURFACE_T_PAINT ||
71                                 surface->init_color_type == MOD_DPAINT_INITIAL_VERTEXCOLOR) {
72                                 dataMask |= (1 << CD_MCOL);
73                         }
74                         /* CD_MDEFORMVERT */
75                         if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) {
76                                 dataMask |= (1 << CD_MDEFORMVERT);
77                         }
78                 }
79         }
80
81         if (pmd->brush) {
82                 if (pmd->brush->flags & MOD_DPAINT_USE_MATERIAL) {
83                         dataMask |= (1 << CD_MTFACE);
84                 }
85         }
86         return dataMask;
87 }
88
89 static DerivedMesh *applyModifier(ModifierData *md, Object *ob, 
90                                                 DerivedMesh *dm,
91                                                 int useRenderParams,
92                                                 int isFinalCalc)
93 {
94         DynamicPaintModifierData *pmd = (DynamicPaintModifierData*) md;
95
96         return dynamicPaint_Modifier_do(pmd, md->scene, ob, dm);
97 }
98
99 static void updateDepgraph(ModifierData *md, DagForest *forest,
100                                                 struct Scene *scene,
101                                                 Object *ob,
102                                                 DagNode *obNode)
103 {
104         DynamicPaintModifierData *pmd = (DynamicPaintModifierData*) md;
105
106         /* add relation from canvases to all brush objects */
107         if(pmd && pmd->canvas)
108         {
109                 Base *base = scene->base.first;
110
111                 for(; base; base = base->next) {
112                         DynamicPaintModifierData *pmd2 = (DynamicPaintModifierData *)modifiers_findByType(base->object, eModifierType_DynamicPaint);
113
114                         if(pmd2 && pmd2->brush && ob!=base->object)
115                         {
116                                 DagNode *brushNode = dag_get_node(forest, base->object);
117                                 dag_add_relation(forest, brushNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA, "Dynamic Paint Brush");
118                         }
119                 }
120         }
121 }
122
123 static int dependsOnTime(ModifierData *md)
124 {
125         return 1;
126 }
127
128 static void foreachIDLink(ModifierData *md, Object *ob,
129                                            IDWalkFunc walk, void *userData)
130 {
131         DynamicPaintModifierData *pmd = (DynamicPaintModifierData*) md;
132
133         if(pmd->canvas) {
134                 DynamicPaintSurface *surface = pmd->canvas->surfaces.first;
135
136                 for(; surface; surface=surface->next) {
137                         walk(userData, ob, (ID **)&surface->brush_group);
138                         walk(userData, ob, (ID **)&surface->init_texture);
139                 }
140         }
141         if (pmd->brush) {
142                 walk(userData, ob, (ID **)&pmd->brush->mat);
143         }
144 }
145
146 static void foreachTexLink(ModifierData *md, Object *ob,
147                                            TexWalkFunc walk, void *userData)
148 {
149         walk(userData, ob, md, ""); /* property name isn't used */
150 }
151
152 ModifierTypeInfo modifierType_DynamicPaint = {
153         /* name */              "Dynamic Paint",
154         /* structName */        "DynamicPaintModifierData",
155         /* structSize */        sizeof(DynamicPaintModifierData),
156         /* type */              eModifierTypeType_Constructive,
157         /* flags */             eModifierTypeFlag_AcceptsMesh
158                                                         | eModifierTypeFlag_UsesPointCache
159                                                         | eModifierTypeFlag_Single,
160
161         /* copyData */          copyData,
162         /* deformVerts */       0,
163         /* deformMatrices */    0,
164         /* deformVertsEM */     0,
165         /* deformMatricesEM */  0,
166         /* applyModifier */     applyModifier,
167         /* applyModifierEM */   0,
168         /* initData */          initData,
169         /* requiredDataMask */  requiredDataMask,
170         /* freeData */          freeData,
171         /* isDisabled */        0,
172         /* updateDepgraph */    updateDepgraph,
173         /* dependsOnTime */     dependsOnTime,
174         /* dependsOnNormals */  0,
175         /* foreachObjectLink */ 0,
176         /* foreachIDLink */     foreachIDLink,
177         /* foreachTexLink */    foreachTexLink,
178 };