Wow! A new feature!
[blender.git] / source / blender / blenkernel / intern / modifier.c
1 #include "string.h"
2
3 #include "BLI_rand.h"
4
5 #include "MEM_guardedalloc.h"
6
7 #include "DNA_mesh_types.h"
8 #include "DNA_meshdata_types.h"
9 #include "DNA_modifier_types.h"
10 #include "DNA_object_types.h"
11 #include "DNA_scene_types.h"
12
13 #include "BKE_global.h"
14 #include "BKE_utildefines.h"
15 #include "BKE_DerivedMesh.h"
16 #include "BKE_displist.h"
17 #include "BKE_modifier.h"
18 #include "BKE_lattice.h"
19 #include "BKE_subsurf.h"
20 #include "BKE_object.h"
21 #include "BKE_mesh.h"
22 #include "depsgraph_private.h"
23
24 /***/
25
26 static void *allocModifierData(int type, int size)
27 {
28         ModifierData *md = MEM_callocN(size, "md");
29         md->type = type;
30         md->mode = eModifierMode_RealtimeAndRender;
31
32         return md;
33 }
34
35 static ModifierData *noneModifier_allocData(void)
36 {
37         return allocModifierData(eModifierType_None, sizeof(ModifierData));
38 }
39
40 static int noneModifier_isDisabled(ModifierData *md)
41 {
42         return 1;
43 }
44
45 /* Curve */
46
47 static ModifierData *curveModifier_allocData(void)
48 {
49         return allocModifierData(eModifierType_Curve, sizeof(CurveModifierData));
50 }
51
52 static int curveModifier_isDisabled(ModifierData *md)
53 {
54         CurveModifierData *cmd = (CurveModifierData*) md;
55
56         return !cmd->object;
57 }
58
59 static void curveModifier_updateDepgraph(ModifierData *md, DagForest *forest, Object *ob, DagNode *obNode)
60 {
61         CurveModifierData *cmd = (CurveModifierData*) md;
62
63         if (cmd->object) {
64                 DagNode *curNode = dag_get_node(forest, cmd->object);
65
66                 dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
67         }
68 }
69
70 static void curveModifier_deformVerts(ModifierData *md, Object *ob, float (*vertexCos)[3], int numVerts)
71 {
72         CurveModifierData *cmd = (CurveModifierData*) md;
73
74         curve_deform_verts(cmd->object, ob, vertexCos, numVerts);
75 }
76
77 /* Lattice */
78
79 static ModifierData *latticeModifier_allocData(void)
80 {
81         return allocModifierData(eModifierType_Lattice, sizeof(LatticeModifierData));
82 }
83
84 static int latticeModifier_isDisabled(ModifierData *md)
85 {
86         LatticeModifierData *lmd = (LatticeModifierData*) md;
87
88         return !lmd->object;
89 }
90
91 static void latticeModifier_updateDepgraph(ModifierData *md, DagForest *forest, Object *ob, DagNode *obNode)
92 {
93         LatticeModifierData *lmd = (LatticeModifierData*) md;
94
95         if (lmd->object) {
96                 DagNode *latNode = dag_get_node(forest, lmd->object);
97
98                 dag_add_relation(forest, latNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
99         }
100 }
101
102 static void latticeModifier_deformVerts(ModifierData *md, Object *ob, float (*vertexCos)[3], int numVerts)
103 {
104         LatticeModifierData *lmd = (LatticeModifierData*) md;
105
106         lattice_deform_verts(lmd->object, ob, vertexCos, numVerts);
107 }
108
109 /* Subsurf */
110
111 static ModifierData *subsurfModifier_allocData(void)
112 {
113         SubsurfModifierData *smd = allocModifierData(eModifierType_Subsurf, sizeof(SubsurfModifierData));
114
115         smd->levels = 1;
116         smd->renderLevels = 2;
117
118         return (ModifierData*) smd;
119 }
120
121 static void *subsurfModifier_applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int useRenderParams)
122 {
123         SubsurfModifierData *smd = (SubsurfModifierData*) md;
124         int levels = useRenderParams?smd->renderLevels:smd->levels;
125         Mesh *me = ob->data;
126
127         if (dm) {
128                 DispListMesh *dlm = dm->convertToDispListMesh(dm); // XXX what if verts were shared
129                 int i;
130
131                 if (vertexCos) {
132                         int numVerts = dm->getNumVerts(dm);
133
134                         for (i=0; i<numVerts; i++) {
135                                 VECCOPY(dlm->mvert[i].co, vertexCos[i]);
136                         }
137                 }
138                 dm->release(dm);
139
140                 dm = subsurf_make_derived_from_dlm(dlm, smd->subdivType, levels);
141                 displistmesh_free(dlm);
142
143                 return dm;
144         } else {
145                 return subsurf_make_derived_from_mesh(me, smd->subdivType, levels, vertexCos);
146         }
147 }
148
149 /* Build */
150
151 static ModifierData *buildModifier_allocData(void)
152 {
153         BuildModifierData *bmd = allocModifierData(eModifierType_Build, sizeof(BuildModifierData));
154
155         bmd->start = 1.0;
156         bmd->length = 100.0;
157
158         return (ModifierData*) bmd;
159 }
160
161 static int buildModifier_dependsOnTime(ModifierData *md)
162 {
163         return 1;
164 }
165
166 static void *buildModifier_applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int useRenderParams)
167 {
168         BuildModifierData *bmd = (BuildModifierData*) md;
169         DispListMesh *dlm=NULL, *ndlm = MEM_callocN(sizeof(*ndlm), "build_dlm");
170         MVert *mvert;
171         MEdge *medge;
172         MFace *mface;
173         MCol *mcol;
174         TFace *tface;
175         int totvert, totedge, totface;
176         int i,j;
177         float frac;
178
179         if (dm) {
180                 dlm = dm->convertToDispListMesh(dm);
181                 mvert = dlm->mvert;
182                 medge = dlm->medge;
183                 mface = dlm->mface;
184                 mcol = dlm->mcol;
185                 tface = dlm->tface;
186                 totvert = dlm->totvert;
187                 totedge = dlm->totedge;
188                 totface = dlm->totface;
189         } else {
190                 Mesh *me = ob->data;
191                 mvert = me->mvert;
192                 medge = me->medge;
193                 mface = me->mface;
194                 mcol = me->mcol;
195                 tface = me->tface;
196                 totvert = me->totvert;
197                 totedge = me->totedge;
198                 totface = me->totface;
199         }
200
201         if (ob) {
202                 frac = bsystem_time(ob, 0, (float)G.scene->r.cfra, bmd->start-1.0f)/bmd->length;
203         } else {
204                 frac = G.scene->r.cfra - bmd->start/bmd->length;
205         }
206         CLAMP(frac, 0.0, 1.0);
207
208         ndlm->totface = totface*frac;
209         ndlm->totedge = totedge*frac;
210         if (ndlm->totface) {
211                 ndlm->mvert = MEM_mallocN(sizeof(*ndlm->mvert)*totvert, "build_mvert");
212                 memcpy(ndlm->mvert, mvert, sizeof(*mvert)*totvert);
213                 for (i=0; i<totvert; i++) {
214                         if (vertexCos)
215                                 VECCOPY(ndlm->mvert[i].co, vertexCos[i]);
216                         ndlm->mvert[i].flag = 0;
217                 }
218
219                 if (bmd->randomize) {
220                         ndlm->mface = MEM_dupallocN(mface);
221                         BLI_array_randomize(ndlm->mface, sizeof(*mface), totface, bmd->seed);
222
223                         if (tface) {
224                                 ndlm->tface = MEM_dupallocN(tface);
225                                 BLI_array_randomize(ndlm->tface, sizeof(*tface), totface, bmd->seed);
226                         } else if (mcol) {
227                                 ndlm->mcol = MEM_dupallocN(mcol);
228                                 BLI_array_randomize(ndlm->mcol, sizeof(*mcol)*4, totface, bmd->seed);
229                         }
230                 } else {
231                         ndlm->mface = MEM_mallocN(sizeof(*ndlm->mface)*ndlm->totface, "build_mf");
232                         memcpy(ndlm->mface, mface, sizeof(*mface)*ndlm->totface);
233
234                         if (tface) {
235                                 ndlm->tface = MEM_mallocN(sizeof(*ndlm->tface)*ndlm->totface, "build_tf");
236                                 memcpy(ndlm->tface, tface, sizeof(*tface)*ndlm->totface);
237                         } else if (mcol) {
238                                 ndlm->mcol = MEM_mallocN(sizeof(*ndlm->mcol)*4*ndlm->totface, "build_mcol");
239                                 memcpy(ndlm->mcol, mcol, sizeof(*mcol)*4*ndlm->totface);
240                         }
241                 }
242
243                 for (i=0; i<ndlm->totface; i++) {
244                         MFace *mf = &ndlm->mface[i];
245
246                         ndlm->mvert[mf->v1].flag = 1;
247                         ndlm->mvert[mf->v2].flag = 1;
248                         if (mf->v3) {
249                                 ndlm->mvert[mf->v3].flag = 1;
250                                 if (mf->v4) ndlm->mvert[mf->v4].flag = 1;
251                         }
252                 }
253
254                         /* Store remapped indices in *((int*) mv->no) */
255                 ndlm->totvert = 0;
256                 for (i=0; i<totvert; i++) {
257                         MVert *mv = &ndlm->mvert[i];
258
259                         if (mv->flag) 
260                                 *((int*) mv->no) = ndlm->totvert++;
261                 }
262
263                         /* Remap face vertex indices */
264                 for (i=0; i<ndlm->totface; i++) {
265                         MFace *mf = &ndlm->mface[i];
266
267                         mf->v1 = *((int*) ndlm->mvert[mf->v1].no);
268                         mf->v2 = *((int*) ndlm->mvert[mf->v2].no);
269                         if (mf->v3) {
270                                 mf->v3 = *((int*) ndlm->mvert[mf->v3].no);
271                                 if (mf->v4) mf->v4 = *((int*) ndlm->mvert[mf->v4].no);
272                         }
273                 }
274                         /* Copy in all edges that have both vertices (remap in process) */
275                 if (totedge) {
276                         ndlm->totedge = 0;
277                         ndlm->medge = MEM_mallocN(sizeof(*ndlm->medge)*totedge, "build_med");
278
279                         for (i=0; i<totedge; i++) {
280                                 MEdge *med = &medge[i];
281
282                                 if (ndlm->mvert[med->v1].flag && ndlm->mvert[med->v2].flag) {
283                                         MEdge *nmed = &ndlm->medge[ndlm->totedge++];
284
285                                         memcpy(nmed, med, sizeof(*med));
286
287                                         nmed->v1 = *((int*) ndlm->mvert[nmed->v1].no);
288                                         nmed->v2 = *((int*) ndlm->mvert[nmed->v2].no);
289                                 }
290                         }
291                 }
292
293                         /* Collapse vertex array to remove unused verts */
294                 for(i=j=0; i<totvert; i++) {
295                         MVert *mv = &ndlm->mvert[i];
296
297                         if (mv->flag) {
298                                 if (j!=i) 
299                                         memcpy(&ndlm->mvert[j], mv, sizeof(*mv));
300                                 j++;
301                         }
302                 }
303         } else if (ndlm->totedge) {
304                 ndlm->mvert = MEM_mallocN(sizeof(*ndlm->mvert)*totvert, "build_mvert");
305                 memcpy(ndlm->mvert, mvert, sizeof(*mvert)*totvert);
306                 for (i=0; i<totvert; i++) {
307                         if (vertexCos)
308                                 VECCOPY(ndlm->mvert[i].co, vertexCos[i]);
309                         ndlm->mvert[i].flag = 0;
310                 }
311
312                 if (bmd->randomize) {
313                         ndlm->medge = MEM_dupallocN(medge);
314                         BLI_array_randomize(ndlm->medge, sizeof(*medge), totedge, bmd->seed);
315                 } else {
316                         ndlm->medge = MEM_mallocN(sizeof(*ndlm->medge)*ndlm->totedge, "build_mf");
317                         memcpy(ndlm->medge, medge, sizeof(*medge)*ndlm->totedge);
318                 }
319
320                 for (i=0; i<ndlm->totedge; i++) {
321                         MEdge *med = &ndlm->medge[i];
322
323                         ndlm->mvert[med->v1].flag = 1;
324                         ndlm->mvert[med->v2].flag = 1;
325                 }
326
327                         /* Store remapped indices in *((int*) mv->no) */
328                 ndlm->totvert = 0;
329                 for (i=0; i<totvert; i++) {
330                         MVert *mv = &ndlm->mvert[i];
331
332                         if (mv->flag) 
333                                 *((int*) mv->no) = ndlm->totvert++;
334                 }
335
336                         /* Remap edge vertex indices */
337                 for (i=0; i<ndlm->totedge; i++) {
338                         MEdge *med = &ndlm->medge[i];
339
340                         med->v1 = *((int*) ndlm->mvert[med->v1].no);
341                         med->v2 = *((int*) ndlm->mvert[med->v2].no);
342                 }
343
344                         /* Collapse vertex array to remove unused verts */
345                 for(i=j=0; i<totvert; i++) {
346                         MVert *mv = &ndlm->mvert[i];
347
348                         if (mv->flag) {
349                                 if (j!=i) 
350                                         memcpy(&ndlm->mvert[j], mv, sizeof(*mv));
351                                 j++;
352                         }
353                 }
354         } else {
355                 ndlm->totvert = totvert*frac;
356
357                 ndlm->mvert = MEM_mallocN(sizeof(*ndlm->mvert)*ndlm->totvert, "build_mvert");
358                 memcpy(ndlm->mvert, mvert, sizeof(*mvert)*ndlm->totvert);
359                 if (vertexCos) {
360                         for (i=0; i<ndlm->totvert; i++) {
361                                 VECCOPY(ndlm->mvert[i].co, vertexCos[i]);
362                         }
363                 }
364         }
365
366         if (dm) dm->release(dm);
367         if (dlm) displistmesh_free(dlm);
368
369         mesh_calc_normals(ndlm->mvert, ndlm->totvert, ndlm->mface, ndlm->totface, &ndlm->nors);
370         
371         return derivedmesh_from_displistmesh(ndlm);
372 }
373
374 /* Mirror */
375
376 static ModifierData *mirrorModifier_allocData(void)
377 {
378         MirrorModifierData *mmd = allocModifierData(eModifierType_Mirror, sizeof(MirrorModifierData));
379
380         mmd->axis = 0;
381         mmd->tolerance = 0.001;
382
383         return (ModifierData*) mmd;
384 }
385
386 static void *mirrorModifier_applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int useRenderParams)
387 {
388         MirrorModifierData *mmd = (MirrorModifierData*) md;
389         DispListMesh *dlm=NULL, *ndlm = MEM_callocN(sizeof(*dlm), "mm_dlm");
390         MVert *mvert;
391         MEdge *medge;
392         MFace *mface;
393         TFace *tface;
394         MCol *mcol;
395         int i, j, totvert, totedge, totface;
396         int axis = mmd->axis;
397         float tolerance = mmd->tolerance;
398
399         if (dm) {
400                 dlm = dm->convertToDispListMesh(dm);
401
402                 mvert = dlm->mvert;
403                 medge = dlm->medge;
404                 mface = dlm->mface;
405                 tface = dlm->tface;
406                 mcol = dlm->mcol;
407                 totvert = dlm->totvert;
408                 totedge = dlm->totedge;
409                 totface = dlm->totface;
410         } else {
411                 Mesh *me = ob->data;
412
413                 mvert = me->mvert;
414                 medge = me->medge;
415                 mface = me->mface;
416                 tface = me->tface;
417                 mcol = me->mcol;
418                 totvert = me->totvert;
419                 totedge = me->totedge;
420                 totface = me->totface;
421         }
422
423         ndlm->mvert = MEM_mallocN(sizeof(*mvert)*totvert*2, "mm_mv");
424         for (i=0,j=totvert; i<totvert; i++) {
425                 MVert *mv = &mvert[i];
426                 MVert *nmv = &ndlm->mvert[i];
427
428                 memcpy(nmv, mv, sizeof(*mv));
429
430                 if (ABS(nmv->co[axis])<=tolerance) {
431                         nmv->co[axis] = 0;
432                         *((int*) nmv->no) = i;
433                 } else {
434                         MVert *nmvMirror = &ndlm->mvert[j];
435
436                                 /* Because the topology result (# of vertices) must stuff the same
437                                  * if the mesh data is overridden by vertex cos, have to calc sharedness
438                                  * based on original coordinates. Only write new cos for non-shared
439                                  * vertices.
440                                  */
441                         if (vertexCos) {
442                                 VECCOPY(nmv->co, vertexCos[i]);
443                         }
444
445                         memcpy(nmvMirror, nmv, sizeof(*mv));
446                         nmvMirror->co[axis] = -nmvMirror->co[axis];
447
448                         *((int*) nmv->no) = j++;
449                 }
450         }
451         ndlm->totvert = j;
452
453         if (medge) {
454                 ndlm->medge = MEM_mallocN(sizeof(*medge)*totedge*2, "mm_med");
455                 memcpy(ndlm->medge, medge, sizeof(*medge)*totedge);
456                 ndlm->totedge = totedge;
457
458                 for (i=0; i<totedge; i++) {
459                         MEdge *med = &ndlm->medge[i];
460                         MEdge *nmed = &ndlm->medge[ndlm->totedge];
461
462                         memcpy(nmed, med, sizeof(*med));
463
464                         nmed->v1 = *((int*) ndlm->mvert[nmed->v1].no);
465                         nmed->v2 = *((int*) ndlm->mvert[nmed->v2].no);
466
467                         if (nmed->v1!=med->v1 || nmed->v2!=med->v2) {
468                                 ndlm->totedge++;
469                         }
470                 }
471         }
472
473         ndlm->mface = MEM_mallocN(sizeof(*mface)*totface*2, "mm_mf");
474         memcpy(ndlm->mface, mface, sizeof(*mface)*totface);
475
476         if (tface) {
477                 ndlm->tface = MEM_mallocN(sizeof(*tface)*totface*2, "mm_tf");
478                 memcpy(ndlm->tface, tface, sizeof(*tface)*totface);
479         } else if (mcol) {
480                 ndlm->mcol = MEM_mallocN(sizeof(*mcol)*4*totface*2, "mm_mcol");
481                 memcpy(ndlm->mcol, mcol, sizeof(*mcol)*4*totface);
482         }
483
484         ndlm->totface = totface;
485         for (i=0; i<totface; i++) {
486                 MFace *mf = &ndlm->mface[i];
487                 MFace *nmf = &ndlm->mface[ndlm->totface];
488                 TFace *tf, *ntf;
489                 MCol *mc, *nmc;
490
491                 memcpy(nmf, mf, sizeof(*mf));
492                 if (tface) {
493                         ntf = &ndlm->tface[ndlm->totface];
494                         tf = &ndlm->tface[i];
495                         memcpy(ntf, tf, sizeof(*tface));
496                 } else if (mcol) {
497                         nmc = &ndlm->mcol[ndlm->totface*4];
498                         mc = &ndlm->mcol[i*4];
499                         memcpy(nmc, mc, sizeof(*mcol)*4);
500                 }
501
502                         /* Map vertices to shared */
503
504                 nmf->v1 = *((int*) ndlm->mvert[nmf->v1].no);
505                 nmf->v2 = *((int*) ndlm->mvert[nmf->v2].no);
506                 if (nmf->v3) {
507                         nmf->v3 = *((int*) ndlm->mvert[nmf->v3].no);
508                         if (nmf->v4) nmf->v4 = *((int*) ndlm->mvert[nmf->v4].no);
509                 }
510
511                         /* If all vertices shared don't duplicate face */
512                 if (nmf->v1==mf->v1 && nmf->v2==mf->v2 && nmf->v3==mf->v3 && nmf->v4==mf->v4)
513                         continue;
514
515                 if (nmf->v3) {
516                         if (nmf->v4) {
517                                 int copyIdx;
518
519                                         /* If three in order vertices are shared then duplicating the face 
520                                         * will be strange (don't want two quads sharing three vertices in a
521                                         * mesh. Instead modify the original quad to leave out the middle vertice
522                                         * and span the gap. Vertice will remain in mesh and still have edges
523                                         * to it but will not interfere with normals.
524                                         */
525                                 if (nmf->v4==mf->v4 && nmf->v1==mf->v1 && nmf->v2==mf->v2) {
526                                         mf->v1 = nmf->v3;
527                                         copyIdx = 0;
528                                 } else if (nmf->v1==mf->v1 && nmf->v2==mf->v2 && nmf->v3==mf->v3) {
529                                         mf->v2 = nmf->v4;
530                                         copyIdx = 1;
531                                 }  else if (nmf->v2==mf->v2 && nmf->v3==mf->v3 && nmf->v4==mf->v4) {
532                                         mf->v3 = nmf->v1;
533                                         copyIdx = 2;
534                                 } else if (nmf->v3==mf->v3 && nmf->v4==mf->v4 && nmf->v1==mf->v1) {
535                                         mf->v4 = nmf->v2;
536                                         copyIdx = 3;
537                                 } else {
538                                         copyIdx = -1;
539                                 }
540
541                                 if (copyIdx!=-1) {
542                                         int fromIdx = (copyIdx+2)%4;
543
544                                         if (tface) {
545                                                 tf->col[copyIdx] = ntf->col[fromIdx];
546                                                 tf->uv[copyIdx][0] = ntf->uv[fromIdx][0];
547                                                 tf->uv[copyIdx][1] = ntf->uv[fromIdx][1];
548                                         } else if (mcol) {
549                                                 mc[copyIdx] = nmc[fromIdx];
550                                         }
551
552                                         continue;
553                                 }
554                         }
555
556                                 /* Need to flip face normal, pick which verts to flip
557                                  * in order to prevent nmf->v3==0 or nmf->v4==0
558                                  */
559                         if (nmf->v1) {
560                                 SWAP(int, nmf->v1, nmf->v3);
561
562                                 if (tface) {
563                                         SWAP(unsigned int, ntf->col[0], ntf->col[2]);
564                                         SWAP(float, ntf->uv[0][0], ntf->uv[2][0]);
565                                         SWAP(float, ntf->uv[0][1], ntf->uv[2][1]);
566                                 } else if (mcol) {
567                                         SWAP(MCol, nmc[0], nmc[2]);
568                                 }
569                         } else {
570                                 SWAP(int, nmf->v2, nmf->v4);
571
572                                 if (tface) {
573                                         SWAP(unsigned int, ntf->col[1], ntf->col[3]);
574                                         SWAP(float, ntf->uv[1][0], ntf->uv[3][0]);
575                                         SWAP(float, ntf->uv[1][1], ntf->uv[3][1]);
576                                 } else if (mcol) {
577                                         SWAP(MCol, nmc[1], nmc[3]);
578                                 }
579                         }
580                 }
581
582                 ndlm->totface++;
583         }
584
585         if (dlm) displistmesh_free(dlm);
586         if (dm) dm->release(dm);
587
588         mesh_calc_normals(ndlm->mvert, ndlm->totvert, ndlm->mface, ndlm->totface, &ndlm->nors);
589         
590         return derivedmesh_from_displistmesh(ndlm);
591 }
592
593 /***/
594
595 static ModifierTypeInfo typeArr[NUM_MODIFIER_TYPES];
596 static int typeArrInit = 1;
597
598 ModifierTypeInfo *modifierType_get_info(ModifierType type)
599 {
600         if (typeArrInit) {
601                 ModifierTypeInfo *mti;
602
603                 memset(typeArr, 0, sizeof(typeArr));
604
605                 mti = &typeArr[eModifierType_None];
606                 strcpy(mti->name, "None");
607                 strcpy(mti->structName, "ModifierData");
608                 mti->type = eModifierType_None;
609                 mti->flags = eModifierTypeFlag_AcceptsMesh|eModifierTypeFlag_AcceptsCVs;
610                 mti->allocData = noneModifier_allocData;
611                 mti->isDisabled = noneModifier_isDisabled;
612
613                 mti = &typeArr[eModifierType_Curve];
614                 strcpy(mti->name, "Curve");
615                 strcpy(mti->structName, "CurveModifierData");
616                 mti->type = eModifierTypeType_OnlyDeform;
617                 mti->flags = eModifierTypeFlag_AcceptsCVs;
618                 mti->allocData = curveModifier_allocData;
619                 mti->isDisabled = curveModifier_isDisabled;
620                 mti->updateDepgraph = curveModifier_updateDepgraph;
621                 mti->deformVerts = curveModifier_deformVerts;
622
623                 mti = &typeArr[eModifierType_Lattice];
624                 strcpy(mti->name, "Lattice");
625                 strcpy(mti->structName, "LatticeModifierData");
626                 mti->type = eModifierTypeType_OnlyDeform;
627                 mti->flags = eModifierTypeFlag_AcceptsCVs;
628                 mti->allocData = latticeModifier_allocData;
629                 mti->isDisabled = latticeModifier_isDisabled;
630                 mti->updateDepgraph = latticeModifier_updateDepgraph;
631                 mti->deformVerts = latticeModifier_deformVerts;
632
633                 mti = &typeArr[eModifierType_Subsurf];
634                 strcpy(mti->name, "Subsurf");
635                 strcpy(mti->structName, "SubsurfModifierData");
636                 mti->type = eModifierTypeType_Constructive;
637                 mti->flags = eModifierTypeFlag_AcceptsMesh|eModifierTypeFlag_SupportsMapping;
638                 mti->allocData = subsurfModifier_allocData;
639                 mti->applyModifier = subsurfModifier_applyModifier;
640
641                 mti = &typeArr[eModifierType_Build];
642                 strcpy(mti->name, "Build");
643                 strcpy(mti->structName, "BuildModifierData");
644                 mti->type = eModifierTypeType_Nonconstructive;
645                 mti->flags = eModifierTypeFlag_AcceptsMesh;
646                 mti->allocData = buildModifier_allocData;
647                 mti->dependsOnTime = buildModifier_dependsOnTime;
648                 mti->applyModifier = buildModifier_applyModifier;
649
650                 mti = &typeArr[eModifierType_Mirror];
651                 strcpy(mti->name, "Mirror");
652                 strcpy(mti->structName, "MirrorModifierData");
653                 mti->type = eModifierTypeType_Constructive;
654                 mti->flags = eModifierTypeFlag_AcceptsMesh;
655                 mti->allocData = mirrorModifier_allocData;
656                 mti->applyModifier = mirrorModifier_applyModifier;
657
658                 typeArrInit = 0;
659         }
660
661         if (type>=0 && type<NUM_MODIFIER_TYPES && typeArr[type].name[0]!='\0') {
662                 return &typeArr[type];
663         } else {
664                 return NULL;
665         }
666 }
667
668 int modifier_dependsOnTime(ModifierData *md) 
669 {
670         ModifierTypeInfo *mti = modifierType_get_info(md->type);
671
672         return mti->dependsOnTime && mti->dependsOnTime(md);
673 }