I hoped we could skip a floor() in the new zbuffer code, but no...
[blender.git] / source / blender / blenkernel / intern / modifier.c
1 #include "string.h"
2 #include "stdarg.h"
3 #include "math.h"
4
5 #include "BLI_blenlib.h"
6 #include "BLI_rand.h"
7 #include "BLI_arithb.h"
8
9 #include "MEM_guardedalloc.h"
10
11 #include "DNA_armature_types.h"
12 #include "DNA_effect_types.h"
13 #include "DNA_mesh_types.h"
14 #include "DNA_meshdata_types.h"
15 #include "DNA_modifier_types.h"
16 #include "DNA_object_types.h"
17 #include "DNA_object_force.h"
18 #include "DNA_scene_types.h"
19
20 #include "BLI_editVert.h"
21
22 #include "BKE_bad_level_calls.h"
23 #include "BKE_global.h"
24 #include "BKE_utildefines.h"
25 #include "BKE_DerivedMesh.h"
26 #include "BKE_booleanops.h"
27 #include "BKE_displist.h"
28 #include "BKE_modifier.h"
29 #include "BKE_lattice.h"
30 #include "BKE_subsurf.h"
31 #include "BKE_object.h"
32 #include "BKE_mesh.h"
33 #include "BKE_softbody.h"
34 #include "depsgraph_private.h"
35
36 #include "LOD_DependKludge.h"
37 #include "LOD_decimation.h"
38
39 #include "CCGSubSurf.h"
40
41 /***/
42
43 static int noneModifier_isDisabled(ModifierData *md)
44 {
45         return 1;
46 }
47
48 /* Curve */
49
50 static void curveModifier_copyData(ModifierData *md, ModifierData *target)
51 {
52         CurveModifierData *cmd = (CurveModifierData*) md;
53         CurveModifierData *tcmd = (CurveModifierData*) target;
54
55         tcmd->object = cmd->object;
56 }
57
58 static int curveModifier_isDisabled(ModifierData *md)
59 {
60         CurveModifierData *cmd = (CurveModifierData*) md;
61
62         return !cmd->object;
63 }
64
65 static void curveModifier_foreachObjectLink(ModifierData *md, Object *ob, void (*walk)(void *userData, Object *ob, Object **obpoin), void *userData)
66 {
67         CurveModifierData *cmd = (CurveModifierData*) md;
68
69         walk(userData, ob, &cmd->object);
70 }
71
72 static void curveModifier_updateDepgraph(ModifierData *md, DagForest *forest, Object *ob, DagNode *obNode)
73 {
74         CurveModifierData *cmd = (CurveModifierData*) md;
75
76         if (cmd->object) {
77                 DagNode *curNode = dag_get_node(forest, cmd->object);
78
79                 dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
80         }
81 }
82
83 static void curveModifier_deformVerts(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int numVerts)
84 {
85         CurveModifierData *cmd = (CurveModifierData*) md;
86
87         curve_deform_verts(cmd->object, ob, vertexCos, numVerts, cmd->name);
88 }
89
90 static void curveModifier_deformVertsEM(ModifierData *md, Object *ob, void *editData, void *derivedData, float (*vertexCos)[3], int numVerts)
91 {
92         curveModifier_deformVerts(md, ob, NULL, vertexCos, numVerts);
93 }
94
95 /* Lattice */
96
97 static void latticeModifier_copyData(ModifierData *md, ModifierData *target)
98 {
99         LatticeModifierData *lmd = (LatticeModifierData*) md;
100         LatticeModifierData *tlmd = (LatticeModifierData*) target;
101
102         tlmd->object = lmd->object;
103 }
104
105 static int latticeModifier_isDisabled(ModifierData *md)
106 {
107         LatticeModifierData *lmd = (LatticeModifierData*) md;
108
109         return !lmd->object;
110 }
111
112 static void latticeModifier_foreachObjectLink(ModifierData *md, Object *ob, void (*walk)(void *userData, Object *ob, Object **obpoin), void *userData)
113 {
114         LatticeModifierData *lmd = (LatticeModifierData*) md;
115
116         walk(userData, ob, &lmd->object);
117 }
118
119 static void latticeModifier_updateDepgraph(ModifierData *md, DagForest *forest, Object *ob, DagNode *obNode)
120 {
121         LatticeModifierData *lmd = (LatticeModifierData*) md;
122
123         if (lmd->object) {
124                 DagNode *latNode = dag_get_node(forest, lmd->object);
125
126                 dag_add_relation(forest, latNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
127         }
128 }
129
130 static void latticeModifier_deformVerts(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int numVerts)
131 {
132         LatticeModifierData *lmd = (LatticeModifierData*) md;
133
134         lattice_deform_verts(lmd->object, ob, vertexCos, numVerts, lmd->name);
135 }
136
137 static void latticeModifier_deformVertsEM(ModifierData *md, Object *ob, void *editData, void *derivedData, float (*vertexCos)[3], int numVerts)
138 {
139         latticeModifier_deformVerts(md, ob, NULL, vertexCos, numVerts);
140 }
141
142 /* Subsurf */
143
144 static void subsurfModifier_initData(ModifierData *md)
145 {
146         SubsurfModifierData *smd = (SubsurfModifierData*) md;
147         
148         smd->levels = 1;
149         smd->renderLevels = 2;
150 }
151
152 static void subsurfModifier_copyData(ModifierData *md, ModifierData *target)
153 {
154         SubsurfModifierData *smd = (SubsurfModifierData*) md;
155         SubsurfModifierData *tsmd = (SubsurfModifierData*) target;
156
157         tsmd->flags = smd->flags;
158         tsmd->levels = smd->levels;
159         tsmd->renderLevels = smd->renderLevels;
160         tsmd->subdivType = smd->subdivType;
161 }
162
163 static void subsurfModifier_freeData(ModifierData *md)
164 {
165         SubsurfModifierData *smd = (SubsurfModifierData*) md;
166
167         if (smd->mCache) {
168                 ccgSubSurf_free(smd->mCache);
169         }
170         if (smd->emCache) {
171                 ccgSubSurf_free(smd->emCache);
172         }
173 }       
174
175 static void *subsurfModifier_applyModifier(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams, int isFinalCalc)
176 {
177         DerivedMesh *dm = derivedData;
178         SubsurfModifierData *smd = (SubsurfModifierData*) md;
179         Mesh *me = ob->data;
180
181         if (dm) {
182                 DispListMesh *dlm = dm->convertToDispListMesh(dm, 0);
183                 int i;
184
185                 if (vertexCos) {
186                         int numVerts = dm->getNumVerts(dm);
187
188                         for (i=0; i<numVerts; i++) {
189                                 VECCOPY(dlm->mvert[i].co, vertexCos[i]);
190                         }
191                 }
192
193                 dm = subsurf_make_derived_from_mesh(me, dlm, smd, useRenderParams, NULL, isFinalCalc);
194
195                 return dm;
196         } else {
197                 return subsurf_make_derived_from_mesh(me, NULL, smd, useRenderParams, vertexCos, isFinalCalc);
198         }
199 }
200
201 static void *subsurfModifier_applyModifierEM(ModifierData *md, Object *ob, void *editData, void *derivedData, float (*vertexCos)[3])
202 {
203         EditMesh *em = editData;
204         DerivedMesh *dm = derivedData;
205         SubsurfModifierData *smd = (SubsurfModifierData*) md;
206
207         if (dm) {
208                 DispListMesh *dlm = dm->convertToDispListMesh(dm, 0);
209
210                 dm = subsurf_make_derived_from_dlm_em(dlm, smd, vertexCos);
211
212                 return dm;
213         } else {
214                 return subsurf_make_derived_from_editmesh(em, smd, vertexCos);
215         }
216 }
217
218 /* Build */
219
220 static void buildModifier_initData(ModifierData *md)
221 {
222         BuildModifierData *bmd = (BuildModifierData*) md;
223
224         bmd->start = 1.0;
225         bmd->length = 100.0;
226 }
227
228 static void buildModifier_copyData(ModifierData *md, ModifierData *target)
229 {
230         BuildModifierData *bmd = (BuildModifierData*) md;
231         BuildModifierData *tbmd = (BuildModifierData*) target;
232
233         tbmd->start = bmd->start;
234         tbmd->length = bmd->length;
235         tbmd->randomize = bmd->randomize;
236         tbmd->seed = bmd->seed;
237 }
238
239 static int buildModifier_dependsOnTime(ModifierData *md)
240 {
241         return 1;
242 }
243
244 static void *buildModifier_applyModifier(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams, int isFinalCalc)
245 {
246         DerivedMesh *dm = derivedData;
247         BuildModifierData *bmd = (BuildModifierData*) md;
248         DispListMesh *dlm=NULL, *ndlm = MEM_callocN(sizeof(*ndlm), "build_dlm");
249         MVert *mvert;
250         MEdge *medge;
251         MFace *mface;
252         MCol *mcol;
253         TFace *tface;
254         int totvert, totedge, totface;
255         int i,j;
256         float frac;
257
258         if (dm) {
259                 dlm = dm->convertToDispListMesh(dm, 1);
260                 mvert = dlm->mvert;
261                 medge = dlm->medge;
262                 mface = dlm->mface;
263                 mcol = dlm->mcol;
264                 tface = dlm->tface;
265                 totvert = dlm->totvert;
266                 totedge = dlm->totedge;
267                 totface = dlm->totface;
268         } else {
269                 Mesh *me = ob->data;
270                 mvert = me->mvert;
271                 medge = me->medge;
272                 mface = me->mface;
273                 mcol = me->mcol;
274                 tface = me->tface;
275                 totvert = me->totvert;
276                 totedge = me->totedge;
277                 totface = me->totface;
278         }
279
280         if (ob) {
281                 frac = bsystem_time(ob, 0, (float)G.scene->r.cfra, bmd->start-1.0f)/bmd->length;
282         } else {
283                 frac = G.scene->r.cfra - bmd->start/bmd->length;
284         }
285         CLAMP(frac, 0.0, 1.0);
286
287         ndlm->totface = totface*frac;
288         ndlm->totedge = totedge*frac;
289         if (ndlm->totface) {
290                 ndlm->mvert = MEM_mallocN(sizeof(*ndlm->mvert)*totvert, "build_mvert");
291                 memcpy(ndlm->mvert, mvert, sizeof(*mvert)*totvert);
292                 for (i=0; i<totvert; i++) {
293                         if (vertexCos)
294                                 VECCOPY(ndlm->mvert[i].co, vertexCos[i]);
295                         ndlm->mvert[i].flag = 0;
296                 }
297
298                 if (bmd->randomize) {
299                         ndlm->mface = MEM_dupallocN(mface);
300                         BLI_array_randomize(ndlm->mface, sizeof(*mface), totface, bmd->seed);
301
302                         if (tface) {
303                                 ndlm->tface = MEM_dupallocN(tface);
304                                 BLI_array_randomize(ndlm->tface, sizeof(*tface), totface, bmd->seed);
305                         } else if (mcol) {
306                                 ndlm->mcol = MEM_dupallocN(mcol);
307                                 BLI_array_randomize(ndlm->mcol, sizeof(*mcol)*4, totface, bmd->seed);
308                         }
309                 } else {
310                         ndlm->mface = MEM_mallocN(sizeof(*ndlm->mface)*ndlm->totface, "build_mf");
311                         memcpy(ndlm->mface, mface, sizeof(*mface)*ndlm->totface);
312
313                         if (tface) {
314                                 ndlm->tface = MEM_mallocN(sizeof(*ndlm->tface)*ndlm->totface, "build_tf");
315                                 memcpy(ndlm->tface, tface, sizeof(*tface)*ndlm->totface);
316                         } else if (mcol) {
317                                 ndlm->mcol = MEM_mallocN(sizeof(*ndlm->mcol)*4*ndlm->totface, "build_mcol");
318                                 memcpy(ndlm->mcol, mcol, sizeof(*mcol)*4*ndlm->totface);
319                         }
320                 }
321
322                 for (i=0; i<ndlm->totface; i++) {
323                         MFace *mf = &ndlm->mface[i];
324
325                         ndlm->mvert[mf->v1].flag = 1;
326                         ndlm->mvert[mf->v2].flag = 1;
327                         ndlm->mvert[mf->v3].flag = 1;
328                         if (mf->v4) ndlm->mvert[mf->v4].flag = 1;
329                 }
330
331                         /* Store remapped indices in *((int*) mv->no) */
332                 ndlm->totvert = 0;
333                 for (i=0; i<totvert; i++) {
334                         MVert *mv = &ndlm->mvert[i];
335
336                         if (mv->flag) 
337                                 *((int*) mv->no) = ndlm->totvert++;
338                 }
339
340                         /* Remap face vertex indices */
341                 for (i=0; i<ndlm->totface; i++) {
342                         MFace *mf = &ndlm->mface[i];
343
344                         mf->v1 = *((int*) ndlm->mvert[mf->v1].no);
345                         mf->v2 = *((int*) ndlm->mvert[mf->v2].no);
346                         mf->v3 = *((int*) ndlm->mvert[mf->v3].no);
347                         if (mf->v4) mf->v4 = *((int*) ndlm->mvert[mf->v4].no);
348                 }
349                         /* Copy in all edges that have both vertices (remap in process) */
350                 if (totedge) {
351                         ndlm->totedge = 0;
352                         ndlm->medge = MEM_mallocN(sizeof(*ndlm->medge)*totedge, "build_med");
353
354                         for (i=0; i<totedge; i++) {
355                                 MEdge *med = &medge[i];
356
357                                 if (ndlm->mvert[med->v1].flag && ndlm->mvert[med->v2].flag) {
358                                         MEdge *nmed = &ndlm->medge[ndlm->totedge++];
359
360                                         memcpy(nmed, med, sizeof(*med));
361
362                                         nmed->v1 = *((int*) ndlm->mvert[nmed->v1].no);
363                                         nmed->v2 = *((int*) ndlm->mvert[nmed->v2].no);
364                                 }
365                         }
366                 }
367
368                         /* Collapse vertex array to remove unused verts */
369                 for(i=j=0; i<totvert; i++) {
370                         MVert *mv = &ndlm->mvert[i];
371
372                         if (mv->flag) {
373                                 if (j!=i) 
374                                         memcpy(&ndlm->mvert[j], mv, sizeof(*mv));
375                                 j++;
376                         }
377                 }
378         } else if (ndlm->totedge) {
379                 ndlm->mvert = MEM_mallocN(sizeof(*ndlm->mvert)*totvert, "build_mvert");
380                 memcpy(ndlm->mvert, mvert, sizeof(*mvert)*totvert);
381                 for (i=0; i<totvert; i++) {
382                         if (vertexCos)
383                                 VECCOPY(ndlm->mvert[i].co, vertexCos[i]);
384                         ndlm->mvert[i].flag = 0;
385                 }
386
387                 if (bmd->randomize) {
388                         ndlm->medge = MEM_dupallocN(medge);
389                         BLI_array_randomize(ndlm->medge, sizeof(*medge), totedge, bmd->seed);
390                 } else {
391                         ndlm->medge = MEM_mallocN(sizeof(*ndlm->medge)*ndlm->totedge, "build_mf");
392                         memcpy(ndlm->medge, medge, sizeof(*medge)*ndlm->totedge);
393                 }
394
395                 for (i=0; i<ndlm->totedge; i++) {
396                         MEdge *med = &ndlm->medge[i];
397
398                         ndlm->mvert[med->v1].flag = 1;
399                         ndlm->mvert[med->v2].flag = 1;
400                 }
401
402                         /* Store remapped indices in *((int*) mv->no) */
403                 ndlm->totvert = 0;
404                 for (i=0; i<totvert; i++) {
405                         MVert *mv = &ndlm->mvert[i];
406
407                         if (mv->flag) 
408                                 *((int*) mv->no) = ndlm->totvert++;
409                 }
410
411                         /* Remap edge vertex indices */
412                 for (i=0; i<ndlm->totedge; i++) {
413                         MEdge *med = &ndlm->medge[i];
414
415                         med->v1 = *((int*) ndlm->mvert[med->v1].no);
416                         med->v2 = *((int*) ndlm->mvert[med->v2].no);
417                 }
418
419                         /* Collapse vertex array to remove unused verts */
420                 for(i=j=0; i<totvert; i++) {
421                         MVert *mv = &ndlm->mvert[i];
422
423                         if (mv->flag) {
424                                 if (j!=i) 
425                                         memcpy(&ndlm->mvert[j], mv, sizeof(*mv));
426                                 j++;
427                         }
428                 }
429         } else {
430                 ndlm->totvert = totvert*frac;
431
432                 if (bmd->randomize) {
433                         ndlm->mvert = MEM_dupallocN(mvert);
434                         BLI_array_randomize(ndlm->mvert, sizeof(*mvert), totvert, bmd->seed);
435                 } else {
436                         ndlm->mvert = MEM_mallocN(sizeof(*ndlm->mvert)*ndlm->totvert, "build_mvert");
437                         memcpy(ndlm->mvert, mvert, sizeof(*mvert)*ndlm->totvert);
438                 }
439
440                 if (vertexCos) {
441                         for (i=0; i<ndlm->totvert; i++) {
442                                 VECCOPY(ndlm->mvert[i].co, vertexCos[i]);
443                         }
444                 }
445         }
446
447         if (dlm) displistmesh_free(dlm);
448
449         mesh_calc_normals(ndlm->mvert, ndlm->totvert, ndlm->mface, ndlm->totface, &ndlm->nors);
450         
451         return derivedmesh_from_displistmesh(ndlm, NULL);
452 }
453
454 /* Mirror */
455
456 static void mirrorModifier_initData(ModifierData *md)
457 {
458         MirrorModifierData *mmd = (MirrorModifierData*) md;
459
460         mmd->tolerance = 0.001;
461 }
462
463 static void mirrorModifier_copyData(ModifierData *md, ModifierData *target)
464 {
465         MirrorModifierData *mmd = (MirrorModifierData*) md;
466         MirrorModifierData *tmmd = (MirrorModifierData*) target;
467
468         tmmd->axis = mmd->axis;
469         tmmd->tolerance = mmd->tolerance;
470 }
471
472 static DispListMesh *mirrorModifier__doMirror(MirrorModifierData *mmd, DispListMesh *inDLM, float (*vertexCos)[3], int initFlags)
473 {
474         int i, axis = mmd->axis;
475         float tolerance = mmd->tolerance;
476         DispListMesh *dlm = MEM_callocN(sizeof(*dlm), "mirror_dlm");
477         int (*indexMap)[2];
478
479         dlm->totvert = dlm->totedge = dlm->totface = 0;
480         indexMap = MEM_mallocN(sizeof(*indexMap)*inDLM->totvert, "indexmap");
481         dlm->mvert = MEM_callocN(sizeof(*dlm->mvert)*inDLM->totvert*2, "dlm_mvert");
482         dlm->mface = MEM_callocN(sizeof(*dlm->mface)*inDLM->totface*2, "dlm_mface");
483
484         if (inDLM->medge) dlm->medge = MEM_callocN(sizeof(*dlm->medge)*inDLM->totedge*2, "dlm_medge");
485         if (inDLM->tface) dlm->tface = MEM_callocN(sizeof(*dlm->tface)*inDLM->totface*2, "dlm_tface");
486         if (inDLM->mcol) dlm->mcol = MEM_callocN(sizeof(*dlm->mcol)*inDLM->totface*4*2, "dlm_mcol");
487
488         for (i=0; i<inDLM->totvert; i++) {
489                 MVert *inMV = &inDLM->mvert[i];
490                 MVert *mv = &dlm->mvert[dlm->totvert++];
491                 int isShared = ABS(inMV->co[axis])<=tolerance;
492
493                                 /* Because the topology result (# of vertices) must be the same
494                                  * if the mesh data is overridden by vertex cos, have to calc sharedness
495                                  * based on original coordinates. This is why we test before copy.
496                                  */
497                 *mv = *inMV;
498                 if (vertexCos) {
499                         VECCOPY(mv->co, vertexCos[i]);
500                 }
501                 if (initFlags) mv->flag |= ME_VERT_STEPINDEX;
502
503                 indexMap[i][0] = dlm->totvert-1;
504                 indexMap[i][1] = !isShared;
505
506                 if (isShared) {
507                         mv->co[axis] = 0;
508                 } else {
509                         MVert *mv2 = &dlm->mvert[dlm->totvert++];
510
511                         *mv2 = *mv;
512                         mv2->co[axis] = -mv2->co[axis];
513                         mv2->flag &= ~ME_VERT_STEPINDEX;
514                 }
515         }
516
517         for (i=0; i<inDLM->totedge; i++) {
518                 MEdge *inMED = &inDLM->medge[i];
519                 MEdge *med = &dlm->medge[dlm->totedge++];
520
521                 *med = *inMED;
522                 med->v1 = indexMap[inMED->v1][0];
523                 med->v2 = indexMap[inMED->v2][0];
524                 if (initFlags) med->flag |= ME_EDGEDRAW|ME_EDGERENDER|ME_EDGE_STEPINDEX;
525
526                 if (indexMap[inMED->v1][1] || indexMap[inMED->v2][1]) {
527                         MEdge *med2 = &dlm->medge[dlm->totedge++];
528
529                         *med2 = *med;
530                         med2->v1 += indexMap[inMED->v1][1];
531                         med2->v2 += indexMap[inMED->v2][1];
532                         med2->flag &= ~ME_EDGE_STEPINDEX;
533                 }
534         }
535
536         for (i=0; i<inDLM->totface; i++) {
537                 MFace *inMF = &inDLM->mface[i];
538                 MFace *mf = &dlm->mface[dlm->totface++];
539
540                 *mf = *inMF;
541                 mf->v1 = indexMap[inMF->v1][0];
542                 mf->v2 = indexMap[inMF->v2][0];
543                 mf->v3 = indexMap[inMF->v3][0];
544                 mf->v4 = indexMap[inMF->v4][0];
545                 if (initFlags) mf->flag |= ME_FACE_STEPINDEX;
546
547                 if (inDLM->tface) {
548                         TFace *inTF = &inDLM->tface[i];
549                         TFace *tf = &dlm->tface[dlm->totface-1];
550
551                         *tf = *inTF;
552                 } else if (inDLM->mcol) {
553                         MCol *inMC = &inDLM->mcol[i*4];
554                         MCol *mc = &dlm->mcol[(dlm->totface-1)*4];
555
556                         mc[0] = inMC[0];
557                         mc[1] = inMC[1];
558                         mc[2] = inMC[2];
559                         mc[3] = inMC[3];
560                 }
561                 
562                 if (indexMap[inMF->v1][1] || indexMap[inMF->v2][1] || indexMap[inMF->v3][1] || (mf->v4 && indexMap[inMF->v4][1])) {
563                         MFace *mf2 = &dlm->mface[dlm->totface++];
564                         TFace *tf = NULL;
565                         MCol *mc = NULL;
566
567                         *mf2 = *mf;
568                         mf2->v1 += indexMap[inMF->v1][1];
569                         mf2->v2 += indexMap[inMF->v2][1];
570                         mf2->v3 += indexMap[inMF->v3][1];
571                         if (inMF->v4) mf2->v4 += indexMap[inMF->v4][1];
572                         mf2->flag &= ~ME_FACE_STEPINDEX;
573
574                         if (inDLM->tface) {
575                                 TFace *inTF = &inDLM->tface[i];
576                                 tf = &dlm->tface[dlm->totface-1];
577
578                                 *tf = *inTF;
579                         } else if (inDLM->mcol) {
580                                 MCol *inMC = &inDLM->mcol[i*4];
581                                 mc = &dlm->mcol[(dlm->totface-1)*4];
582
583                                 mc[0] = inMC[0];
584                                 mc[1] = inMC[1];
585                                 mc[2] = inMC[2];
586                                 mc[3] = inMC[3];
587                         }
588
589                                 /* Flip face normal */
590                         SWAP(int, mf2->v1, mf2->v3);
591                         if (tf) {
592                                 SWAP(unsigned int, tf->col[0], tf->col[2]);
593                                 SWAP(float, tf->uv[0][0], tf->uv[2][0]);
594                                 SWAP(float, tf->uv[0][1], tf->uv[2][1]);
595                         } else if (mc) {
596                                 SWAP(MCol, mc[0], mc[2]);
597                         }
598
599                         test_index_face(mf2, mc, tf, inMF->v4?4:3);
600                 }
601         }
602
603         MEM_freeN(indexMap);
604
605         return dlm;
606 }
607
608 static void *mirrorModifier_applyModifier__internal(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams, int isFinalCalc)
609 {
610         DerivedMesh *dm = derivedData;
611         MirrorModifierData *mmd = (MirrorModifierData*) md;
612         DispListMesh *outDLM, *inDLM;
613
614         if (dm) {
615                 inDLM = dm->convertToDispListMesh(dm, 1);
616         } else {
617                 Mesh *me = ob->data;
618
619                 inDLM = MEM_callocN(sizeof(*inDLM), "inDLM");
620                 inDLM->dontFreeVerts = inDLM->dontFreeOther = 1;
621                 inDLM->mvert = me->mvert;
622                 inDLM->medge = me->medge;
623                 inDLM->mface = me->mface;
624                 inDLM->tface = me->tface;
625                 inDLM->mcol = me->mcol;
626                 inDLM->totvert = me->totvert;
627                 inDLM->totedge = me->totedge;
628                 inDLM->totface = me->totface;
629         }
630
631         outDLM = mirrorModifier__doMirror(mmd, inDLM, vertexCos, dm?0:1);
632
633         displistmesh_free(inDLM);
634         
635         mesh_calc_normals(outDLM->mvert, outDLM->totvert, outDLM->mface, outDLM->totface, &outDLM->nors);
636         
637         return derivedmesh_from_displistmesh(outDLM, NULL);
638 }
639
640 static void *mirrorModifier_applyModifier(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams, int isFinalCalc)
641 {
642         return mirrorModifier_applyModifier__internal(md, ob, derivedData, vertexCos, 0, 1);
643 }
644
645 static void *mirrorModifier_applyModifierEM(ModifierData *md, Object *ob, void *editData, void *derivedData, float (*vertexCos)[3])
646 {
647         if (derivedData) {
648                 return mirrorModifier_applyModifier__internal(md, ob, derivedData, vertexCos, 0, 1);
649         } else {
650                 MirrorModifierData *mmd = (MirrorModifierData*) md;
651                 DispListMesh *outDLM, *inDLM = MEM_callocN(sizeof(*inDLM), "mm_dlm");
652                 EditMesh *em = editData;
653                 EditVert *eve, *preveve;
654                 EditEdge *eed;
655                 EditFace *efa;
656                 int i;
657
658                 for (i=0,eve=em->verts.first; eve; eve= eve->next)
659                         eve->prev = (EditVert*) i++;
660
661                 inDLM->totvert = BLI_countlist(&em->verts);
662                 inDLM->totedge = BLI_countlist(&em->edges);
663                 inDLM->totface = BLI_countlist(&em->faces);
664
665                 inDLM->mvert = MEM_mallocN(sizeof(*inDLM->mvert)*inDLM->totvert*2, "mm_mv");
666                 inDLM->medge = MEM_mallocN(sizeof(*inDLM->medge)*inDLM->totedge*2, "mm_med");
667                 inDLM->mface = MEM_mallocN(sizeof(*inDLM->mface)*inDLM->totface*2, "mm_mf");
668
669                         /* Need to be able to mark loose edges */
670                 for (eed=em->edges.first; eed; eed=eed->next) {
671                         eed->f2 = 0;
672                 }
673                 for (efa=em->faces.first; efa; efa=efa->next) {
674                         efa->e1->f2 = 1;
675                         efa->e2->f2 = 1;
676                         efa->e3->f2 = 1;
677                         if (efa->e4) efa->e4->f2 = 1;
678                 }
679
680                 for (i=0,eve=em->verts.first; i<inDLM->totvert; i++,eve=eve->next) {
681                         MVert *mv = &inDLM->mvert[i];
682
683                         VECCOPY(mv->co, eve->co);
684                         mv->mat_nr = 0;
685                         mv->flag = ME_VERT_STEPINDEX;
686                 }
687                 for (i=0,eed=em->edges.first; i<inDLM->totedge; i++,eed=eed->next) {
688                         MEdge *med = &inDLM->medge[i];
689
690                         med->v1 = (int) eed->v1->prev;
691                         med->v2 = (int) eed->v2->prev;
692                         med->crease = (unsigned char) (eed->crease*255.0f);
693                         med->flag = ME_EDGEDRAW|ME_EDGERENDER|ME_EDGE_STEPINDEX;
694                         
695                         if (eed->seam) med->flag |= ME_SEAM;
696                         if (!eed->f2) med->flag |= ME_LOOSEEDGE;
697                 }
698                 for (i=0,efa=em->faces.first; i<inDLM->totface; i++,efa=efa->next) {
699                         MFace *mf = &inDLM->mface[i];
700                         mf->v1 = (int) efa->v1->prev;
701                         mf->v2 = (int) efa->v2->prev;
702                         mf->v3 = (int) efa->v3->prev;
703                         mf->v4 = efa->v4?(int) efa->v4->prev:0;
704                         mf->mat_nr = efa->mat_nr;
705                         mf->flag = efa->flag|ME_FACE_STEPINDEX;
706                         test_index_face(mf, NULL, NULL, efa->v4?4:3);
707                 }
708
709                 outDLM = mirrorModifier__doMirror(mmd, inDLM, vertexCos, 0);
710
711                 displistmesh_free(inDLM);
712
713                 for (preveve=NULL, eve=em->verts.first; eve; preveve=eve, eve= eve->next)
714                         eve->prev = preveve;
715
716                 mesh_calc_normals(outDLM->mvert, outDLM->totvert, outDLM->mface, outDLM->totface, &outDLM->nors);
717
718                 return derivedmesh_from_displistmesh(outDLM, NULL);
719         }
720 }
721
722 /* Decimate */
723
724 static void decimateModifier_initData(ModifierData *md)
725 {
726         DecimateModifierData *dmd = (DecimateModifierData*) md;
727
728         dmd->percent = 1.0;
729 }
730
731 static void decimateModifier_copyData(ModifierData *md, ModifierData *target)
732 {
733         DecimateModifierData *dmd = (DecimateModifierData*) md;
734         DecimateModifierData *tdmd = (DecimateModifierData*) target;
735
736         tdmd->percent = dmd->percent;
737 }
738
739 static void *decimateModifier_applyModifier(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams, int isFinalCalc)
740 {
741         DecimateModifierData *dmd = (DecimateModifierData*) md;
742         DerivedMesh *dm = derivedData;
743         Mesh *me = ob->data;
744         MVert *mvert;
745         MFace *mface;
746         DispListMesh *ndlm=NULL, *dlm=NULL;
747         LOD_Decimation_Info lod;
748         int totvert, totface;
749         int a, numTris;
750
751         if (dm) {
752                 dlm = dm->convertToDispListMesh(dm, 1);
753                 mvert = dlm->mvert;
754                 mface = dlm->mface;
755                 totvert = dlm->totvert;
756                 totface = dlm->totface;
757         } else {
758                 mvert = me->mvert;
759                 mface = me->mface;
760                 totvert = me->totvert;
761                 totface = me->totface;
762         }
763
764         numTris = 0;
765         for (a=0; a<totface; a++) {
766                 MFace *mf = &mface[a];
767                 numTris++;
768                 if (mf->v4) numTris++;
769         }
770
771         if(numTris<3) {
772                 modifier_setError(md, "There must be more than 3 input faces (triangles).");
773                 goto exit;
774         }
775
776         lod.vertex_buffer= MEM_mallocN(3*sizeof(float)*totvert, "vertices");
777         lod.vertex_normal_buffer= MEM_mallocN(3*sizeof(float)*totvert, "normals");
778         lod.triangle_index_buffer= MEM_mallocN(3*sizeof(int)*numTris, "trias");
779         lod.vertex_num= totvert;
780         lod.face_num= numTris;
781
782         for(a=0; a<totvert; a++) {
783                 MVert *mv = &mvert[a];
784                 float *vbCo = &lod.vertex_buffer[a*3];
785                 float *vbNo = &lod.vertex_normal_buffer[a*3];
786
787                 if (vertexCos) {
788                         VECCOPY(vbCo, vertexCos[a]);
789                 } else {
790                         VECCOPY(vbCo, mv->co);
791                 }
792
793                 vbNo[0] = mv->no[0]/32767.0f;
794                 vbNo[1] = mv->no[1]/32767.0f;
795                 vbNo[2] = mv->no[2]/32767.0f;
796         }
797
798         numTris = 0;
799         for(a=0; a<totface; a++) {
800                 MFace *mf = &mface[a];
801                 int *tri = &lod.triangle_index_buffer[3*numTris++];
802                 tri[0]= mf->v1;
803                 tri[1]= mf->v2;
804                 tri[2]= mf->v3;
805
806                 if(mf->v4) {
807                         tri = &lod.triangle_index_buffer[3*numTris++];
808                         tri[0]= mf->v1;
809                         tri[1]= mf->v3;
810                         tri[2]= mf->v4;
811                 }
812         }
813
814         dmd->faceCount = 0;
815         if(LOD_LoadMesh(&lod) ) {
816                 if( LOD_PreprocessMesh(&lod) ) {
817                         /* we assume the decim_faces tells how much to reduce */
818
819                         while(lod.face_num > numTris*dmd->percent) {
820                                 if( LOD_CollapseEdge(&lod)==0) break;
821                         }
822
823                         ndlm= MEM_callocN(sizeof(DispListMesh), "dispmesh");
824                         ndlm->mvert= MEM_callocN(lod.vertex_num*sizeof(MVert), "mvert");
825                         ndlm->totvert= lod.vertex_num;
826                         if(lod.vertex_num>2) {
827                                 ndlm->mface= MEM_callocN(lod.face_num*sizeof(MFace), "mface");
828                                 ndlm->totface= dmd->faceCount = lod.face_num;
829                         }
830                         for(a=0; a<lod.vertex_num; a++) {
831                                 MVert *mv = &ndlm->mvert[a];
832                                 float *vbCo = &lod.vertex_buffer[a*3];
833                                 
834                                 VECCOPY(mv->co, vbCo);
835                         }
836
837                         if(lod.vertex_num>2) {
838                                 for(a=0; a<lod.face_num; a++) {
839                                         MFace *mf = &ndlm->mface[a];
840                                         int *tri = &lod.triangle_index_buffer[a*3];
841                                         mf->v1 = tri[0];
842                                         mf->v2 = tri[1];
843                                         mf->v3 = tri[2];
844                                         test_index_face(mface, NULL, NULL, 3);
845                                 }
846                                 displistmesh_add_edges(ndlm);
847                         }
848                 }
849                 else {
850                         modifier_setError(md, "Out of memory.");
851                 }
852
853                 LOD_FreeDecimationData(&lod);
854         }
855         else {
856                 modifier_setError(md, "Non-manifold mesh as input.");
857         }
858
859         MEM_freeN(lod.vertex_buffer);
860         MEM_freeN(lod.vertex_normal_buffer);
861         MEM_freeN(lod.triangle_index_buffer);
862
863 exit:
864         if (dlm) displistmesh_free(dlm);
865
866         if (ndlm) {
867                 mesh_calc_normals(ndlm->mvert, ndlm->totvert, ndlm->mface, ndlm->totface, &ndlm->nors);
868
869                 return derivedmesh_from_displistmesh(ndlm, NULL);
870         } else {
871                 return NULL;
872         }
873 }
874
875 /* Wave */
876
877 static void waveModifier_initData(ModifierData *md) 
878 {
879         WaveModifierData *wmd = (WaveModifierData*) md; // whadya know, moved here from Iraq
880                 
881         wmd->flag |= (WAV_X+WAV_Y+WAV_CYCL);
882         
883         wmd->height= 0.5f;
884         wmd->width= 1.5f;
885         wmd->speed= 0.5f;
886         wmd->narrow= 1.5f;
887         wmd->lifetime= 0.0f;
888         wmd->damp= 10.0f;
889 }
890
891 static void waveModifier_copyData(ModifierData *md, ModifierData *target)
892 {
893         WaveModifierData *wmd = (WaveModifierData*) md;
894         WaveModifierData *twmd = (WaveModifierData*) target;
895
896         twmd->damp = wmd->damp;
897         twmd->flag = wmd->flag;
898         twmd->height = wmd->height;
899         twmd->lifetime = wmd->lifetime;
900         twmd->narrow = wmd->narrow;
901         twmd->speed = wmd->speed;
902         twmd->startx = wmd->startx;
903         twmd->starty = wmd->starty;
904         twmd->timeoffs = wmd->timeoffs;
905         twmd->width = wmd->width;
906 }
907
908 static int waveModifier_dependsOnTime(ModifierData *md)
909 {
910         return 1;
911 }
912
913 static void waveModifier_deformVerts(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int numVerts)
914 {
915         WaveModifierData *wmd = (WaveModifierData*) md;
916         float ctime = bsystem_time(ob, 0, (float)G.scene->r.cfra, 0.0);
917         float minfac = (float)(1.0/exp(wmd->width*wmd->narrow*wmd->width*wmd->narrow));
918         float lifefac = wmd->height;
919
920         if(wmd->damp==0) wmd->damp= 10.0f;
921
922         if(wmd->lifetime!=0.0) {
923                 float x= ctime - wmd->timeoffs;
924
925                 if(x>wmd->lifetime) {
926                         lifefac= x-wmd->lifetime;
927                         
928                         if(lifefac > wmd->damp) lifefac= 0.0;
929                         else lifefac= (float)(wmd->height*(1.0 - sqrt(lifefac/wmd->damp)));
930                 }
931         }
932
933         if(lifefac!=0.0) {
934                 int i;
935
936                 for (i=0; i<numVerts; i++) {
937                         float *co = vertexCos[i];
938                         float x= co[0]-wmd->startx;
939                         float y= co[1]-wmd->starty;
940                         float amplit;
941
942                         if(wmd->flag & WAV_X) {
943                                 if(wmd->flag & WAV_Y) amplit= (float)sqrt( (x*x + y*y));
944                                 else amplit= x;
945                         }
946                         else amplit= y;
947                         
948                         /* this way it makes nice circles */
949                         amplit-= (ctime-wmd->timeoffs)*wmd->speed;
950
951                         if(wmd->flag & WAV_CYCL) {
952                                 amplit = (float)fmod(amplit-wmd->width, 2.0*wmd->width) + wmd->width;
953                         }
954
955                                 /* GAUSSIAN */
956                         if(amplit> -wmd->width && amplit<wmd->width) {
957                                 amplit = amplit*wmd->narrow;
958                                 amplit= (float)(1.0/exp(amplit*amplit) - minfac);
959
960                                 co[2]+= lifefac*amplit;
961                         }
962                 }
963         }
964 }
965
966 static void waveModifier_deformVertsEM(ModifierData *md, Object *ob, void *editData, void *derivedData, float (*vertexCos)[3], int numVerts)
967 {
968         waveModifier_deformVerts(md, ob, NULL, vertexCos, numVerts);
969 }
970
971 /* Armature */
972
973 static void armatureModifier_initData(ModifierData *md)
974 {
975         ArmatureModifierData *amd = (ArmatureModifierData*) md;
976         
977         amd->deformflag = ARM_DEF_ENVELOPE|ARM_DEF_VGROUP;
978 }
979
980 static void armatureModifier_copyData(ModifierData *md, ModifierData *target)
981 {
982         ArmatureModifierData *amd = (ArmatureModifierData*) md;
983         ArmatureModifierData *tamd = (ArmatureModifierData*) target;
984
985         tamd->object = amd->object;
986         tamd->deformflag = amd->deformflag;
987 }
988
989 static int armatureModifier_isDisabled(ModifierData *md)
990 {
991         ArmatureModifierData *amd = (ArmatureModifierData*) md;
992
993         return !amd->object;
994 }
995
996 static void armatureModifier_foreachObjectLink(ModifierData *md, Object *ob, void (*walk)(void *userData, Object *ob, Object **obpoin), void *userData)
997 {
998         ArmatureModifierData *amd = (ArmatureModifierData*) md;
999
1000         walk(userData, ob, &amd->object);
1001 }
1002
1003 static void armatureModifier_updateDepgraph(ModifierData *md, DagForest *forest, Object *ob, DagNode *obNode)
1004 {
1005         ArmatureModifierData *amd = (ArmatureModifierData*) md;
1006
1007         if (amd->object) {
1008                 DagNode *curNode = dag_get_node(forest, amd->object);
1009
1010                 dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
1011         }
1012 }
1013
1014 static void armatureModifier_deformVerts(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int numVerts)
1015 {
1016         ArmatureModifierData *amd = (ArmatureModifierData*) md;
1017
1018         armature_deform_verts(amd->object, ob, vertexCos, numVerts, amd->deformflag);
1019 }
1020
1021 static void armatureModifier_deformVertsEM(ModifierData *md, Object *ob, void *editData, void *derivedData, float (*vertexCos)[3], int numVerts)
1022 {
1023         ArmatureModifierData *amd = (ArmatureModifierData*) md;
1024
1025         armature_deform_verts(amd->object, ob, vertexCos, numVerts, amd->deformflag);
1026 }
1027
1028 /* Hook */
1029
1030 static void hookModifier_initData(ModifierData *md) 
1031 {
1032         HookModifierData *hmd = (HookModifierData*) md;
1033
1034         hmd->force= 1.0;
1035 }
1036
1037 static void hookModifier_copyData(ModifierData *md, ModifierData *target)
1038 {
1039         HookModifierData *hmd = (HookModifierData*) md;
1040         HookModifierData *thmd = (HookModifierData*) target;
1041
1042         VECCOPY(thmd->cent, hmd->cent);
1043         thmd->falloff = hmd->falloff;
1044         thmd->force = hmd->force;
1045         thmd->object = hmd->object;
1046         thmd->totindex = hmd->totindex;
1047         thmd->indexar = MEM_dupallocN(hmd->indexar);
1048         memcpy(thmd->parentinv, hmd->parentinv, sizeof(hmd->parentinv));
1049 }
1050
1051 static void hookModifier_freeData(ModifierData *md)
1052 {
1053         HookModifierData *hmd = (HookModifierData*) md;
1054
1055         if (hmd->indexar) MEM_freeN(hmd->indexar);
1056 }
1057
1058 static int hookModifier_isDisabled(ModifierData *md)
1059 {
1060         HookModifierData *hmd = (HookModifierData*) md;
1061
1062         return !hmd->object;
1063 }
1064
1065 static void hookModifier_foreachObjectLink(ModifierData *md, Object *ob, void (*walk)(void *userData, Object *ob, Object **obpoin), void *userData)
1066 {
1067         HookModifierData *hmd = (HookModifierData*) md;
1068
1069         walk(userData, ob, &hmd->object);
1070 }
1071
1072 static void hookModifier_updateDepgraph(ModifierData *md, DagForest *forest, Object *ob, DagNode *obNode)
1073 {
1074         HookModifierData *hmd = (HookModifierData*) md;
1075
1076         if (hmd->object) {
1077                 DagNode *curNode = dag_get_node(forest, hmd->object);
1078
1079                 dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA);
1080         }
1081 }
1082
1083 static void hookModifier_deformVerts(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int numVerts)
1084 {
1085         HookModifierData *hmd = (HookModifierData*) md;
1086         float vec[3], mat[4][4];
1087         int i;
1088
1089         Mat4Invert(ob->imat, ob->obmat);
1090         Mat4MulSerie(mat, ob->imat, hmd->object->obmat, hmd->parentinv, NULL, NULL, NULL, NULL, NULL);
1091
1092         /* vertex indices? */
1093         if(hmd->indexar) {
1094                 for (i=0; i<hmd->totindex; i++) {
1095                         int index = hmd->indexar[i];
1096
1097                                 /* This should always be true and I don't generally like 
1098                                  * "paranoid" style code like this, but old files can have
1099                                  * indices that are out of range because old blender did
1100                                  * not correct them on exit editmode. - zr
1101                                  */
1102                         if (index<numVerts) {
1103                                 float *co = vertexCos[index];
1104                                 float fac = hmd->force;
1105
1106                                 if(hmd->falloff!=0.0) {
1107                                         float len= VecLenf(co, hmd->cent);
1108                                         if(len > hmd->falloff) fac = 0.0;
1109                                         else if(len>0.0) fac *= sqrt(1.0 - len/hmd->falloff);
1110                                 }
1111
1112                                 if(fac!=0.0) {
1113                                         VecMat4MulVecfl(vec, mat, co);
1114                                         VecLerpf(co, co, vec, fac);
1115                                 }
1116                         }
1117                 }
1118         }
1119         else {  /* vertex group hook */
1120                 bDeformGroup *curdef;
1121                 Mesh *me= ob->data;
1122                 int index=0;
1123                 
1124                 /* find the group (weak loop-in-loop) */
1125                 for (curdef = ob->defbase.first; curdef; curdef=curdef->next, index++)
1126                         if (!strcmp(curdef->name, hmd->name))
1127                                 break;
1128                 
1129                 if(curdef && me->dvert) {
1130                         MDeformVert *dvert= me->dvert;
1131                         int i, j;
1132                         
1133                         for (i=0; i < me->totvert; i++, dvert++) {
1134                                 for(j=0; j<dvert->totweight; j++) {
1135                                         if (dvert->dw[j].def_nr == index) {
1136                                                 float fac = hmd->force*dvert->dw[j].weight;
1137                                                 float *co = vertexCos[i];
1138                                                 
1139                                                 if(hmd->falloff!=0.0) {
1140                                                         float len= VecLenf(co, hmd->cent);
1141                                                         if(len > hmd->falloff) fac = 0.0;
1142                                                         else if(len>0.0) fac *= sqrt(1.0 - len/hmd->falloff);
1143                                                 }
1144                                                 
1145                                                 VecMat4MulVecfl(vec, mat, co);
1146                                                 VecLerpf(co, co, vec, fac);
1147
1148                                         }
1149                                 }
1150                         }
1151                 }
1152
1153         }
1154 }
1155
1156 static void hookModifier_deformVertsEM(ModifierData *md, Object *ob, void *editData, void *derivedData, float (*vertexCos)[3], int numVerts)
1157 {
1158         hookModifier_deformVerts(md, ob, derivedData, vertexCos, numVerts);
1159 }
1160
1161 /* Softbody */
1162
1163 static void softbodyModifier_deformVerts(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int numVerts)
1164 {
1165         sbObjectStep(ob, (float)G.scene->r.cfra, vertexCos, numVerts);
1166 }
1167
1168 /* Boolean */
1169
1170 static void booleanModifier_copyData(ModifierData *md, ModifierData *target)
1171 {
1172         BooleanModifierData *bmd = (BooleanModifierData*) md;
1173         BooleanModifierData *tbmd = (BooleanModifierData*) target;
1174
1175         tbmd->object = bmd->object;
1176 }
1177
1178 static int booleanModifier_isDisabled(ModifierData *md)
1179 {
1180         BooleanModifierData *bmd = (BooleanModifierData*) md;
1181
1182         return !bmd->object;
1183 }
1184
1185 static void booleanModifier_foreachObjectLink(ModifierData *md, Object *ob, void (*walk)(void *userData, Object *ob, Object **obpoin), void *userData)
1186 {
1187         BooleanModifierData *bmd = (BooleanModifierData*) md;
1188
1189         walk(userData, ob, &bmd->object);
1190 }
1191
1192 static void booleanModifier_updateDepgraph(ModifierData *md, DagForest *forest, Object *ob, DagNode *obNode)
1193 {
1194         BooleanModifierData *bmd = (BooleanModifierData*) md;
1195
1196         if (bmd->object) {
1197                 DagNode *curNode = dag_get_node(forest, bmd->object);
1198
1199                 dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
1200         }
1201 }
1202
1203 static void *booleanModifier_applyModifier(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams, int isFinalCalc)
1204 {       
1205                 // XXX doesn't handle derived data
1206         BooleanModifierData *bmd = (BooleanModifierData*) md;
1207         DispListMesh *dlm = NewBooleanMeshDLM(bmd->object, ob, 1+bmd->operation);
1208
1209         return derivedmesh_from_displistmesh(dlm, NULL);
1210 }
1211
1212 /***/
1213
1214 static ModifierTypeInfo typeArr[NUM_MODIFIER_TYPES];
1215 static int typeArrInit = 1;
1216
1217 ModifierTypeInfo *modifierType_getInfo(ModifierType type)
1218 {
1219         if (typeArrInit) {
1220                 ModifierTypeInfo *mti;
1221
1222                 memset(typeArr, 0, sizeof(typeArr));
1223
1224                 /* Initialize and return the appropriate type info structure,
1225                  * assumes that modifier has:
1226                  *  name == typeName, 
1227                  *  structName == typeName + 'ModifierData'
1228                  */
1229 #define INIT_TYPE(typeName) \
1230         (       strcpy(typeArr[eModifierType_##typeName].name, #typeName), \
1231                 strcpy(typeArr[eModifierType_##typeName].structName, #typeName "ModifierData"), \
1232                 typeArr[eModifierType_##typeName].structSize = sizeof(typeName##ModifierData), \
1233                 &typeArr[eModifierType_##typeName])
1234
1235                 mti = &typeArr[eModifierType_None];
1236                 strcpy(mti->name, "None");
1237                 strcpy(mti->structName, "ModifierData");
1238                 mti->structSize = sizeof(ModifierData);
1239                 mti->type = eModifierType_None;
1240                 mti->flags = eModifierTypeFlag_AcceptsMesh|eModifierTypeFlag_AcceptsCVs;
1241                 mti->isDisabled = noneModifier_isDisabled;
1242
1243                 mti = INIT_TYPE(Curve);
1244                 mti->type = eModifierTypeType_OnlyDeform;
1245                 mti->flags = eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_RequiresOriginalData;
1246                 mti->copyData = curveModifier_copyData;
1247                 mti->isDisabled = curveModifier_isDisabled;
1248                 mti->foreachObjectLink = curveModifier_foreachObjectLink;
1249                 mti->updateDepgraph = curveModifier_updateDepgraph;
1250                 mti->deformVerts = curveModifier_deformVerts;
1251                 mti->deformVertsEM = curveModifier_deformVertsEM;
1252
1253                 mti = INIT_TYPE(Lattice);
1254                 mti->type = eModifierTypeType_OnlyDeform;
1255                 mti->flags = eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_RequiresOriginalData;
1256                 mti->copyData = latticeModifier_copyData;
1257                 mti->isDisabled = latticeModifier_isDisabled;
1258                 mti->foreachObjectLink = latticeModifier_foreachObjectLink;
1259                 mti->updateDepgraph = latticeModifier_updateDepgraph;
1260                 mti->deformVerts = latticeModifier_deformVerts;
1261                 mti->deformVertsEM = latticeModifier_deformVertsEM;
1262
1263                 mti = INIT_TYPE(Subsurf);
1264                 mti->type = eModifierTypeType_Constructive;
1265                 mti->flags = eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode;
1266                 mti->initData = subsurfModifier_initData;
1267                 mti->copyData = subsurfModifier_copyData;
1268                 mti->freeData = subsurfModifier_freeData;
1269                 mti->applyModifier = subsurfModifier_applyModifier;
1270                 mti->applyModifierEM = subsurfModifier_applyModifierEM;
1271
1272                 mti = INIT_TYPE(Build);
1273                 mti->type = eModifierTypeType_Nonconstructive;
1274                 mti->flags = eModifierTypeFlag_AcceptsMesh;
1275                 mti->initData = buildModifier_initData;
1276                 mti->copyData = buildModifier_copyData;
1277                 mti->dependsOnTime = buildModifier_dependsOnTime;
1278                 mti->applyModifier = buildModifier_applyModifier;
1279
1280                 mti = INIT_TYPE(Mirror);
1281                 mti->type = eModifierTypeType_Constructive;
1282                 mti->flags = eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode;
1283                 mti->initData = mirrorModifier_initData;
1284                 mti->copyData = mirrorModifier_copyData;
1285                 mti->applyModifier = mirrorModifier_applyModifier;
1286                 mti->applyModifierEM = mirrorModifier_applyModifierEM;
1287
1288                 mti = INIT_TYPE(Decimate);
1289                 mti->type = eModifierTypeType_Nonconstructive;
1290                 mti->flags = eModifierTypeFlag_AcceptsMesh;
1291                 mti->initData = decimateModifier_initData;
1292                 mti->copyData = decimateModifier_copyData;
1293                 mti->applyModifier = decimateModifier_applyModifier;
1294
1295                 mti = INIT_TYPE(Wave);
1296                 mti->type = eModifierTypeType_OnlyDeform;
1297                 mti->flags = eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_SupportsEditmode;
1298                 mti->initData = waveModifier_initData;
1299                 mti->copyData = waveModifier_copyData;
1300                 mti->dependsOnTime = waveModifier_dependsOnTime;
1301                 mti->deformVerts = waveModifier_deformVerts;
1302                 mti->deformVertsEM = waveModifier_deformVertsEM;
1303
1304                 mti = INIT_TYPE(Armature);
1305                 mti->type = eModifierTypeType_OnlyDeform;
1306                 mti->flags = eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_RequiresOriginalData;
1307                 mti->initData = armatureModifier_initData;
1308                 mti->copyData = armatureModifier_copyData;
1309                 mti->isDisabled = armatureModifier_isDisabled;
1310                 mti->foreachObjectLink = armatureModifier_foreachObjectLink;
1311                 mti->updateDepgraph = armatureModifier_updateDepgraph;
1312                 mti->deformVerts = armatureModifier_deformVerts;
1313                 mti->deformVertsEM = armatureModifier_deformVertsEM;
1314
1315                 mti = INIT_TYPE(Hook);
1316                 mti->type = eModifierTypeType_OnlyDeform;
1317                 mti->flags = eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_RequiresOriginalData;
1318                 mti->initData = hookModifier_initData;
1319                 mti->copyData = hookModifier_copyData;
1320                 mti->freeData = hookModifier_freeData;
1321                 mti->isDisabled = hookModifier_isDisabled;
1322                 mti->foreachObjectLink = hookModifier_foreachObjectLink;
1323                 mti->updateDepgraph = hookModifier_updateDepgraph;
1324                 mti->deformVerts = hookModifier_deformVerts;
1325                 mti->deformVertsEM = hookModifier_deformVertsEM;
1326
1327                 mti = INIT_TYPE(Softbody);
1328                 mti->type = eModifierTypeType_OnlyDeform;
1329                 mti->flags = eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_RequiresOriginalData;
1330                 mti->deformVerts = softbodyModifier_deformVerts;
1331
1332                 mti = INIT_TYPE(Boolean);
1333                 mti->type = eModifierTypeType_Nonconstructive;
1334                 mti->flags = eModifierTypeFlag_AcceptsMesh;
1335                 mti->copyData = booleanModifier_copyData;
1336                 mti->isDisabled = booleanModifier_isDisabled;
1337                 mti->applyModifier = booleanModifier_applyModifier;
1338                 mti->foreachObjectLink = booleanModifier_foreachObjectLink;
1339                 mti->updateDepgraph = booleanModifier_updateDepgraph;
1340
1341                 typeArrInit = 0;
1342 #undef INIT_TYPE
1343         }
1344
1345         if (type>=0 && type<NUM_MODIFIER_TYPES && typeArr[type].name[0]!='\0') {
1346                 return &typeArr[type];
1347         } else {
1348                 return NULL;
1349         }
1350 }
1351
1352 /***/
1353
1354 ModifierData *modifier_new(int type)
1355 {
1356         ModifierTypeInfo *mti = modifierType_getInfo(type);
1357         ModifierData *md = MEM_callocN(mti->structSize, mti->structName);
1358
1359         strcpy(md->name, mti->name);
1360
1361         md->type = type;
1362         md->mode = eModifierMode_Realtime|eModifierMode_Render|eModifierMode_Expanded;
1363
1364         if (mti->flags&eModifierTypeFlag_EnableInEditmode)
1365                 md->mode |= eModifierMode_Editmode;
1366
1367         if (mti->initData) mti->initData(md);
1368
1369         return md;
1370 }
1371
1372 void modifier_free(ModifierData *md) 
1373 {
1374         ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1375
1376         if (mti->freeData) mti->freeData(md);
1377         if (md->error) MEM_freeN(md->error);
1378
1379         MEM_freeN(md);
1380 }
1381
1382 int modifier_dependsOnTime(ModifierData *md) 
1383 {
1384         ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1385
1386         return mti->dependsOnTime && mti->dependsOnTime(md);
1387 }
1388
1389 int modifier_supportsMapping(ModifierData *md)
1390 {
1391         ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1392
1393         return (        (mti->flags&eModifierTypeFlag_SupportsEditmode) &&
1394                                 (       (mti->type==eModifierTypeType_OnlyDeform ||
1395                                         (mti->flags&eModifierTypeFlag_SupportsMapping))) );
1396 }
1397
1398 ModifierData *modifiers_findByType(Object *ob, ModifierType type)
1399 {
1400         ModifierData *md = ob->modifiers.first;
1401
1402         for (; md; md=md->next)
1403                 if (md->type==type)
1404                         break;
1405
1406         return md;
1407 }
1408
1409 void modifiers_clearErrors(Object *ob)
1410 {
1411         ModifierData *md = ob->modifiers.first;
1412         int qRedraw = 0;
1413
1414         for (; md; md=md->next) {
1415                 if (md->error) {
1416                         MEM_freeN(md->error);
1417                         md->error = NULL;
1418
1419                         qRedraw = 1;
1420                 }
1421         }
1422
1423         if (qRedraw) allqueue(REDRAWBUTSEDIT, 0);
1424 }
1425
1426 void modifiers_foreachObjectLink(Object *ob, void (*walk)(void *userData, Object *ob, Object **obpoin), void *userData)
1427 {
1428         ModifierData *md = ob->modifiers.first;
1429
1430         for (; md; md=md->next) {
1431                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1432
1433                 if (mti->foreachObjectLink) mti->foreachObjectLink(md, ob, walk, userData);
1434         }
1435 }
1436
1437 void modifier_copyData(ModifierData *md, ModifierData *target)
1438 {
1439         ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1440
1441         target->mode = md->mode;
1442
1443         if (mti->copyData)
1444                 mti->copyData(md, target);
1445 }
1446
1447 int modifier_couldBeCage(ModifierData *md)
1448 {
1449         ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1450
1451         return (        (md->mode&eModifierMode_Realtime) &&
1452                                 (md->mode&eModifierMode_Editmode) &&
1453                                 (!mti->isDisabled || !mti->isDisabled(md)) &&
1454                                 modifier_supportsMapping(md));  
1455 }
1456
1457 void modifier_setError(ModifierData *md, char *format, ...)
1458 {
1459         char buffer[2048];
1460         va_list ap;
1461
1462         va_start(ap, format);
1463         vsprintf(buffer, format, ap);
1464         va_end(ap);
1465
1466         if (md->error)
1467                 MEM_freeN(md->error);
1468
1469         md->error = BLI_strdup(buffer);
1470
1471         allqueue(REDRAWBUTSEDIT, 0);
1472 }
1473
1474 /* used for buttons, to find out if the 'draw deformed in editmode' option is there */
1475 /* also used in transform_conversion.c, to detect CrazySpace [tm] (2nd arg then is NULL) */
1476 int modifiers_getCageIndex(Object *ob, int *lastPossibleCageIndex_r)
1477 {
1478         ModifierData *md = ob->modifiers.first;
1479         int i, cageIndex = -1;
1480
1481                 /* Find the last modifier acting on the cage. */
1482         for (i=0; md; i++,md=md->next) {
1483                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1484
1485                 if (!(md->mode&eModifierMode_Realtime)) continue;
1486                 if (!(md->mode&eModifierMode_Editmode)) continue;
1487                 if (mti->isDisabled && mti->isDisabled(md)) continue;
1488                 if (!(mti->flags&eModifierTypeFlag_SupportsEditmode)) continue;
1489
1490                 if (!modifier_supportsMapping(md))
1491                         break;
1492
1493                 if (lastPossibleCageIndex_r) *lastPossibleCageIndex_r = i;
1494                 if (md->mode&eModifierMode_OnCage)
1495                         cageIndex = i;
1496         }
1497
1498         return cageIndex;
1499 }
1500
1501
1502 int modifiers_isSoftbodyEnabled(Object *ob)
1503 {
1504         ModifierData *md = modifiers_findByType(ob, eModifierType_Softbody);
1505
1506                 /* Softbody not allowed in this situation, enforce! */
1507         /* if (md && ob->pd && ob->pd->deflect) {       */
1508         /* no reason for that any more BM */
1509         if (0) {
1510                 md->mode &= ~(eModifierMode_Realtime|eModifierMode_Render|eModifierMode_Editmode);
1511                 md = NULL;
1512         }
1513
1514         return (md && md->mode&(eModifierMode_Realtime|eModifierMode_Render));
1515 }
1516
1517 ModifierData *modifiers_getVirtualModifierList(Object *ob)
1518 {
1519                 /* Kinda hacky, but should be fine since we are never
1520                  * reentrant and avoid free hassles.
1521                  */
1522         static ArmatureModifierData amd;
1523         static CurveModifierData cmd;
1524         static LatticeModifierData lmd;
1525         static int init = 1;
1526
1527         if (init) {
1528                 ModifierData *md;
1529
1530                 md = modifier_new(eModifierType_Armature);
1531                 amd = *((ArmatureModifierData*) md);
1532                 modifier_free(md);
1533
1534                 md = modifier_new(eModifierType_Curve);
1535                 cmd = *((CurveModifierData*) md);
1536                 modifier_free(md);
1537
1538                 md = modifier_new(eModifierType_Lattice);
1539                 lmd = *((LatticeModifierData*) md);
1540                 modifier_free(md);
1541
1542                 amd.modifier.mode |= eModifierMode_Virtual;
1543                 cmd.modifier.mode |= eModifierMode_Virtual;
1544                 lmd.modifier.mode |= eModifierMode_Virtual;
1545
1546                 init = 0;
1547         }
1548
1549         if (ob->parent) {
1550                 if(ob->parent->type==OB_ARMATURE && ob->partype==PARSKEL) {
1551                         amd.object = ob->parent;
1552                         amd.modifier.next = ob->modifiers.first;
1553                         amd.deformflag= ((bArmature *)(ob->parent->data))->deformflag;
1554                         return &amd.modifier;
1555                 } else if(ob->parent->type==OB_CURVE && ob->partype==PARSKEL) {
1556                         cmd.object = ob->parent;
1557                         cmd.modifier.next = ob->modifiers.first;
1558                         return &cmd.modifier;
1559                 } else if(ob->parent->type==OB_LATTICE && ob->partype==PARSKEL) {
1560                         lmd.object = ob->parent;
1561                         lmd.modifier.next = ob->modifiers.first;
1562                         return &lmd.modifier;
1563                 }
1564         }
1565
1566         return ob->modifiers.first;
1567 }
1568
1569 Object *modifiers_isDeformedByArmature(Object *ob)
1570 {
1571         ModifierData *md = modifiers_getVirtualModifierList(ob);
1572
1573         for (; md; md=md->next) {
1574                 if (md->type==eModifierType_Armature) {
1575                         ArmatureModifierData *amd = (ArmatureModifierData*) md;
1576                         return amd->object;
1577                 }
1578         }
1579
1580         return NULL;
1581 }
1582
1583 int modifiers_isDeformed(Object *ob)
1584 {
1585         ModifierData *md = modifiers_getVirtualModifierList(ob);
1586         
1587         for (; md; md=md->next) {
1588                 if (md->type==eModifierType_Armature)
1589                         return 1;
1590                 if (md->type==eModifierType_Curve)
1591                         return 1;
1592                 if (md->type==eModifierType_Lattice)
1593                         return 1;
1594         }
1595         return 0;
1596 }