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