Undo revision 23130 which was a merge with 2.5, a messy one because I did something...
[blender.git] / source / blender / editors / object / object_modifier.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * Contributor(s): Blender Foundation, 2009
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 #include <math.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31
32 #include "MEM_guardedalloc.h"
33
34 #include "DNA_curve_types.h"
35 #include "DNA_mesh_types.h"
36 #include "DNA_meshdata_types.h"
37 #include "DNA_modifier_types.h"
38 #include "DNA_object_types.h"
39 #include "DNA_object_force.h"
40 #include "DNA_scene_types.h"
41
42 #include "BLI_listbase.h"
43
44 #include "BKE_curve.h"
45 #include "BKE_context.h"
46 #include "BKE_depsgraph.h"
47 #include "BKE_displist.h"
48 #include "BKE_DerivedMesh.h"
49 #include "BKE_effect.h"
50 #include "BKE_global.h"
51 #include "BKE_lattice.h"
52 #include "BKE_mesh.h"
53 #include "BKE_modifier.h"
54 #include "BKE_multires.h"
55 #include "BKE_report.h"
56 #include "BKE_object.h"
57 #include "BKE_particle.h"
58 #include "BKE_softbody.h"
59 #include "BKE_utildefines.h"
60
61 #include "RNA_access.h"
62 #include "RNA_define.h"
63 #include "RNA_enum_types.h"
64
65 #include "ED_screen.h"
66
67 #include "WM_api.h"
68 #include "WM_types.h"
69
70 #include "object_intern.h"
71
72 /******************************** API ****************************/
73
74 int ED_object_modifier_add(ReportList *reports, Scene *scene, Object *ob, int type)
75 {
76         ModifierData *md;
77         ModifierTypeInfo *mti = modifierType_getInfo(type);
78
79         if(mti->flags&eModifierTypeFlag_Single) {
80                 if(modifiers_findByType(ob, type)) {
81                         BKE_report(reports, RPT_WARNING, "Only one modifier of this type allowed.");
82                         return 0;
83                 }
84         }
85
86         if(type == eModifierType_ParticleSystem) {
87                 object_add_particle_system(scene, ob);
88         }
89         else {
90                 if(mti->flags&eModifierTypeFlag_RequiresOriginalData) {
91                         md = ob->modifiers.first;
92
93                         while(md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform)
94                                 md = md->next;
95
96                         BLI_insertlinkbefore(&ob->modifiers, md, modifier_new(type));
97                 }
98                 else
99                         BLI_addtail(&ob->modifiers, modifier_new(type));
100                 
101                 /* special cases */
102                 if(type == eModifierType_Softbody) {
103                         if(!ob->soft) {
104                                 ob->soft= sbNew(scene);
105                                 ob->softflag |= OB_SB_GOAL|OB_SB_EDGES;
106                         }
107                 }
108                 else if(type == eModifierType_Collision) {
109                         if(!ob->pd)
110                                 ob->pd= object_add_collision_fields();
111
112                         ob->pd->deflect= 1;
113                         DAG_scene_sort(scene);
114                 }
115                 else if(type == eModifierType_Surface)
116                         DAG_scene_sort(scene);
117         }
118
119         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
120
121         return 1;
122 }
123
124 int ED_object_modifier_remove(ReportList *reports, Scene *scene, Object *ob, ModifierData *md)
125 {
126         ModifierData *obmd;
127
128         /* It seems on rapid delete it is possible to
129          * get called twice on same modifier, so make
130          * sure it is in list. */
131         for(obmd=ob->modifiers.first; obmd; obmd=obmd->next)
132                 if(obmd==md)
133                         break;
134         
135         if(!obmd)
136                 return 0;
137
138         /* special cases */
139         if(md->type == eModifierType_ParticleSystem) {
140                 ParticleSystemModifierData *psmd=(ParticleSystemModifierData*)md;
141
142                 BLI_remlink(&ob->particlesystem, psmd->psys);
143                 psys_free(ob, psmd->psys);
144         }
145         else if(md->type == eModifierType_Softbody) {
146                 if(ob->soft) {
147                         sbFree(ob->soft);
148                         ob->soft= NULL;
149                         ob->softflag= 0;
150                 }
151         }
152         else if(md->type == eModifierType_Collision) {
153                 if(ob->pd)
154                         ob->pd->deflect= 0;
155
156         DAG_scene_sort(scene);
157         }
158         else if(md->type == eModifierType_Surface) {
159                 if(ob->pd)
160                         ob->pd->flag &= ~PFIELD_SURFACE;
161
162         DAG_scene_sort(scene);
163         }
164
165         BLI_remlink(&ob->modifiers, md);
166         modifier_free(md);
167
168         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
169
170         return 1;
171 }
172
173 int ED_object_modifier_move_up(ReportList *reports, Object *ob, ModifierData *md)
174 {
175         if(md->prev) {
176                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
177
178                 if(mti->type!=eModifierTypeType_OnlyDeform) {
179                         ModifierTypeInfo *nmti = modifierType_getInfo(md->prev->type);
180
181                         if(nmti->flags&eModifierTypeFlag_RequiresOriginalData) {
182                                 BKE_report(reports, RPT_WARNING, "Cannot move above a modifier requiring original data.");
183                                 return 0;
184                         }
185                 }
186
187                 BLI_remlink(&ob->modifiers, md);
188                 BLI_insertlink(&ob->modifiers, md->prev->prev, md);
189         }
190
191         return 1;
192 }
193
194 int ED_object_modifier_move_down(ReportList *reports, Object *ob, ModifierData *md)
195 {
196         if(md->next) {
197                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
198
199                 if(mti->flags&eModifierTypeFlag_RequiresOriginalData) {
200                         ModifierTypeInfo *nmti = modifierType_getInfo(md->next->type);
201
202                         if(nmti->type!=eModifierTypeType_OnlyDeform) {
203                                 BKE_report(reports, RPT_WARNING, "Cannot move beyond a non-deforming modifier.");
204                                 return 0;
205                         }
206                 }
207
208                 BLI_remlink(&ob->modifiers, md);
209                 BLI_insertlink(&ob->modifiers, md->next, md);
210         }
211
212         return 1;
213 }
214
215 int ED_object_modifier_convert(ReportList *reports, Scene *scene, Object *ob, ModifierData *md)
216 {
217         Object *obn;
218         ParticleSystem *psys;
219         ParticleCacheKey *key, **cache;
220         ParticleSettings *part;
221         Mesh *me;
222         MVert *mvert;
223         MEdge *medge;
224         int a, k, kmax;
225         int totvert=0, totedge=0, cvert=0;
226         int totpart=0, totchild=0;
227
228         if(md->type != eModifierType_ParticleSystem) return 0;
229         if(ob && ob->mode & OB_MODE_PARTICLE_EDIT) return 0;
230
231         psys=((ParticleSystemModifierData *)md)->psys;
232         part= psys->part;
233
234         if(part->ren_as == PART_DRAW_GR || part->ren_as == PART_DRAW_OB) {
235                 ; // XXX make_object_duplilist_real(NULL);
236         }
237         else {
238                 if(part->ren_as != PART_DRAW_PATH || psys->pathcache == 0)
239                         return 0;
240
241                 totpart= psys->totcached;
242                 totchild= psys->totchildcache;
243
244                 if(totchild && (part->draw&PART_DRAW_PARENT)==0)
245                         totpart= 0;
246
247                 /* count */
248                 cache= psys->pathcache;
249                 for(a=0; a<totpart; a++) {
250                         key= cache[a];
251                         totvert+= key->steps+1;
252                         totedge+= key->steps;
253                 }
254
255                 cache= psys->childcache;
256                 for(a=0; a<totchild; a++) {
257                         key= cache[a];
258                         totvert+= key->steps+1;
259                         totedge+= key->steps;
260                 }
261
262                 if(totvert==0) return 0;
263
264                 /* add new mesh */
265                 obn= add_object(scene, OB_MESH);
266                 me= obn->data;
267                 
268                 me->totvert= totvert;
269                 me->totedge= totedge;
270                 
271                 me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
272                 me->medge= CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
273                 me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, 0);
274                 
275                 mvert= me->mvert;
276                 medge= me->medge;
277
278                 /* copy coordinates */
279                 cache= psys->pathcache;
280                 for(a=0; a<totpart; a++) {
281                         key= cache[a];
282                         kmax= key->steps;
283                         for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
284                                 VECCOPY(mvert->co,key->co);
285                                 if(k) {
286                                         medge->v1= cvert-1;
287                                         medge->v2= cvert;
288                                         medge->flag= ME_EDGEDRAW|ME_EDGERENDER|ME_LOOSEEDGE;
289                                         medge++;
290                                 }
291                         }
292                 }
293
294                 cache=psys->childcache;
295                 for(a=0; a<totchild; a++) {
296                         key=cache[a];
297                         kmax=key->steps;
298                         for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
299                                 VECCOPY(mvert->co,key->co);
300                                 if(k) {
301                                         medge->v1=cvert-1;
302                                         medge->v2=cvert;
303                                         medge->flag= ME_EDGEDRAW|ME_EDGERENDER|ME_LOOSEEDGE;
304                                         medge++;
305                                 }
306                         }
307                 }
308         }
309
310         DAG_scene_sort(scene);
311
312         return 1;
313 }
314
315 int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, ModifierData *md)
316 {
317         DerivedMesh *dm;
318         Mesh *me = ob->data;
319         int converted = 0;
320
321         if (scene->obedit) {
322                 BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied in editmode");
323                 return 0;
324         } else if (((ID*) ob->data)->us>1) {
325                 BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied to multi-user data");
326                 return 0;
327         }
328
329         if (md!=ob->modifiers.first)
330                 BKE_report(reports, RPT_INFO, "Applied modifier was not first, result may not be as expected.");
331
332         if (ob->type==OB_MESH) {
333                 if(me->key) {
334                         BKE_report(reports, RPT_ERROR, "Modifier cannot be applied to Mesh with Shape Keys");
335                         return 0;
336                 }
337         
338                 mesh_pmv_off(ob, me);
339
340                /* Multires: ensure that recent sculpting is applied */
341                if(md->type == eModifierType_Multires)
342                        multires_force_update(ob);
343         
344                 dm = mesh_create_derived_for_modifier(scene, ob, md);
345                 if (!dm) {
346                         BKE_report(reports, RPT_ERROR, "Modifier is disabled or returned error, skipping apply");
347                         return 0;
348                 }
349
350                 DM_to_mesh(dm, me);
351                 converted = 1;
352
353                 dm->release(dm);
354         } 
355         else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
356                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
357                 Curve *cu = ob->data;
358                 int numVerts;
359                 float (*vertexCos)[3];
360
361                 BKE_report(reports, RPT_INFO, "Applied modifier only changed CV points, not tesselated/bevel vertices");
362
363                 if (!(md->mode&eModifierMode_Realtime) || (mti->isDisabled && mti->isDisabled(md))) {
364                         BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
365                         return 0;
366                 }
367
368                 vertexCos = curve_getVertexCos(cu, &cu->nurb, &numVerts);
369                 mti->deformVerts(md, ob, NULL, vertexCos, numVerts, 0, 0);
370                 curve_applyVertexCos(cu, &cu->nurb, vertexCos);
371
372                 converted = 1;
373
374                 MEM_freeN(vertexCos);
375
376                 DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
377         }
378         else {
379                 BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type");
380                 return 0;
381         }
382
383         if (converted) {
384                 BLI_remlink(&ob->modifiers, md);
385                 modifier_free(md);
386
387                 return 1;
388         }
389
390         return 0;
391 }
392
393 int ED_object_modifier_copy(ReportList *reports, Object *ob, ModifierData *md)
394 {
395         ModifierData *nmd;
396         
397         nmd = modifier_new(md->type);
398         modifier_copyData(md, nmd);
399         BLI_insertlink(&ob->modifiers, md, nmd);
400
401         return 1;
402 }
403
404 /***************************** OPERATORS ****************************/
405
406 /************************ add modifier operator *********************/
407
408 static int modifier_add_exec(bContext *C, wmOperator *op)
409 {
410         Scene *scene= CTX_data_scene(C);
411     Object *ob = CTX_data_active_object(C);
412         int type= RNA_enum_get(op->ptr, "type");
413
414         if(!ED_object_modifier_add(op->reports, scene, ob, type))
415                 return OPERATOR_CANCELLED;
416
417         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
418         
419         return OPERATOR_FINISHED;
420 }
421
422 void OBJECT_OT_modifier_add(wmOperatorType *ot)
423 {
424         /* identifiers */
425         ot->name= "Add Modifier";
426         ot->description = "Add a modifier to the active object.";
427         ot->idname= "OBJECT_OT_modifier_add";
428         
429         /* api callbacks */
430         ot->invoke= WM_menu_invoke;
431         ot->exec= modifier_add_exec;
432         
433         ot->poll= ED_operator_object_active;
434         
435         /* flags */
436         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
437         
438         /* XXX only some types should be here */
439         RNA_def_enum(ot->srna, "type", modifier_type_items, 0, "Type", "");
440 }
441
442 /************************ remove modifier operator *********************/
443
444 static int modifier_remove_exec(bContext *C, wmOperator *op)
445 {
446         Scene *scene= CTX_data_scene(C);
447         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
448         Object *ob= ptr.id.data;
449         ModifierData *md= ptr.data;
450
451         if(!ob || !md || !ED_object_modifier_remove(op->reports, scene, ob, md))
452                 return OPERATOR_CANCELLED;
453
454         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
455         
456         return OPERATOR_FINISHED;
457 }
458
459 void OBJECT_OT_modifier_remove(wmOperatorType *ot)
460 {
461         ot->name= "Remove Modifier";
462         ot->description= "Remove a modifier from the active object.";
463         ot->idname= "OBJECT_OT_modifier_remove";
464         ot->poll= ED_operator_object_active;
465
466         ot->exec= modifier_remove_exec;
467         
468         /* flags */
469         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
470 }
471
472 /************************ move up modifier operator *********************/
473
474 static int modifier_move_up_exec(bContext *C, wmOperator *op)
475 {
476         Scene *scene= CTX_data_scene(C);
477         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
478         Object *ob= ptr.id.data;
479         ModifierData *md= ptr.data;
480
481         if(!ob || !md || !ED_object_modifier_move_up(op->reports, ob, md))
482                 return OPERATOR_CANCELLED;
483
484         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
485         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
486         
487         return OPERATOR_FINISHED;
488 }
489
490 void OBJECT_OT_modifier_move_up(wmOperatorType *ot)
491 {
492         ot->name= "Move Up Modifier";
493         ot->description= "Move modifier up in the stack.";
494         ot->idname= "OBJECT_OT_modifier_move_up";
495         ot->poll= ED_operator_object_active;
496
497         ot->exec= modifier_move_up_exec;
498         
499         /* flags */
500         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
501 }
502
503 /************************ move down modifier operator *********************/
504
505 static int modifier_move_down_exec(bContext *C, wmOperator *op)
506 {
507         Scene *scene= CTX_data_scene(C);
508         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
509         Object *ob= ptr.id.data;
510         ModifierData *md= ptr.data;
511
512         if(!ob || !md || !ED_object_modifier_move_down(op->reports, ob, md))
513                 return OPERATOR_CANCELLED;
514
515         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
516         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
517         
518         return OPERATOR_FINISHED;
519 }
520
521 void OBJECT_OT_modifier_move_down(wmOperatorType *ot)
522 {
523         ot->name= "Move Down Modifier";
524         ot->description= "Move modifier down in the stack.";
525         ot->idname= "OBJECT_OT_modifier_move_down";
526         ot->poll= ED_operator_object_active;
527
528         ot->exec= modifier_move_down_exec;
529         
530         /* flags */
531         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
532 }
533
534 /************************ apply modifier operator *********************/
535
536 static int modifier_apply_exec(bContext *C, wmOperator *op)
537 {
538         Scene *scene= CTX_data_scene(C);
539         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
540         Object *ob= ptr.id.data;
541         ModifierData *md= ptr.data;
542
543         if(!ob || !md || !ED_object_modifier_apply(op->reports, scene, ob, md))
544                 return OPERATOR_CANCELLED;
545
546         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
547         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
548         
549         return OPERATOR_FINISHED;
550 }
551
552 void OBJECT_OT_modifier_apply(wmOperatorType *ot)
553 {
554         ot->name= "Apply Modifier";
555         ot->description= "Apply modifier and remove from the stack.";
556         ot->idname= "OBJECT_OT_modifier_apply";
557         ot->poll= ED_operator_object_active;
558
559         ot->exec= modifier_apply_exec;
560         
561         /* flags */
562         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
563 }
564
565 /************************ convert modifier operator *********************/
566
567 static int modifier_convert_exec(bContext *C, wmOperator *op)
568 {
569         Scene *scene= CTX_data_scene(C);
570         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
571         Object *ob= ptr.id.data;
572         ModifierData *md= ptr.data;
573
574         if(!ob || !md || !ED_object_modifier_convert(op->reports, scene, ob, md))
575                 return OPERATOR_CANCELLED;
576
577         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
578         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
579         
580         return OPERATOR_FINISHED;
581 }
582
583 void OBJECT_OT_modifier_convert(wmOperatorType *ot)
584 {
585         ot->name= "Convert Modifier";
586         ot->description= "Convert particles to a mesh object.";
587         ot->idname= "OBJECT_OT_modifier_convert";
588         ot->poll= ED_operator_object_active;
589
590         ot->exec= modifier_convert_exec;
591         
592         /* flags */
593         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
594 }
595
596 /************************ copy modifier operator *********************/
597
598 static int modifier_copy_exec(bContext *C, wmOperator *op)
599 {
600         Scene *scene= CTX_data_scene(C);
601         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
602         Object *ob= ptr.id.data;
603         ModifierData *md= ptr.data;
604
605         if(!ob || !md || !ED_object_modifier_copy(op->reports, ob, md))
606                 return OPERATOR_CANCELLED;
607
608         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
609         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
610         
611         return OPERATOR_FINISHED;
612 }
613
614 void OBJECT_OT_modifier_copy(wmOperatorType *ot)
615 {
616         ot->name= "Copy Modifier";
617         ot->description= "Duplicate modifier at the same position in the stack.";
618         ot->idname= "OBJECT_OT_modifier_copy";
619         ot->poll= ED_operator_object_active;
620
621         ot->exec= modifier_copy_exec;
622         
623         /* flags */
624         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
625 }
626
627 /****************** multires subdivide operator *********************/
628
629 static int multires_subdivide_exec(bContext *C, wmOperator *op)
630 {
631         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_MultiresModifier);
632         Object *ob= ptr.id.data;
633         MultiresModifierData *mmd= ptr.data;
634
635         if(mmd) {
636                 multiresModifier_subdivide(mmd, ob, 1, 0, mmd->simple);
637                 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
638         }
639         
640         return OPERATOR_FINISHED;
641 }
642
643 static int multires_subdivide_poll(bContext *C)
644 {
645         return NULL != CTX_data_active_object(C) && NULL == CTX_data_edit_object(C);
646 }
647
648 void OBJECT_OT_multires_subdivide(wmOperatorType *ot)
649 {
650         ot->name= "Multires Subdivide";
651         ot->description= "Add a new level of subdivision.";
652         ot->idname= "OBJECT_OT_multires_subdivide";
653
654         ot->exec= multires_subdivide_exec;
655         ot->poll= multires_subdivide_poll;
656         
657         /* flags */
658         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
659 }
660
661 /************************ mdef bind operator *********************/
662
663 static int modifier_mdef_bind_poll(bContext *C)
664 {
665         return CTX_data_pointer_get_type(C, "modifier", &RNA_MeshDeformModifier).data != NULL;
666 }
667
668 static int modifier_mdef_bind_exec(bContext *C, wmOperator *op)
669 {
670         Scene *scene= CTX_data_scene(C);
671         PointerRNA ptr= CTX_data_pointer_get(C, "modifier");
672         Object *ob= ptr.id.data;
673         MeshDeformModifierData *mmd= ptr.data;
674
675         if(mmd->bindcos) {
676                 if(mmd->bindweights) MEM_freeN(mmd->bindweights);
677                 if(mmd->bindcos) MEM_freeN(mmd->bindcos);
678                 if(mmd->dyngrid) MEM_freeN(mmd->dyngrid);
679                 if(mmd->dyninfluences) MEM_freeN(mmd->dyninfluences);
680                 if(mmd->dynverts) MEM_freeN(mmd->dynverts);
681                 mmd->bindweights= NULL;
682                 mmd->bindcos= NULL;
683                 mmd->dyngrid= NULL;
684                 mmd->dyninfluences= NULL;
685                 mmd->dynverts= NULL;
686                 mmd->totvert= 0;
687                 mmd->totcagevert= 0;
688                 mmd->totinfluence= 0;
689         }
690         else {
691                 DerivedMesh *dm;
692                 int mode= mmd->modifier.mode;
693
694                 /* force modifier to run, it will call binding routine */
695                 mmd->needbind= 1;
696                 mmd->modifier.mode |= eModifierMode_Realtime;
697
698                 if(ob->type == OB_MESH) {
699                         dm= mesh_create_derived_view(scene, ob, 0);
700                         dm->release(dm);
701                 }
702                 else if(ob->type == OB_LATTICE) {
703                         lattice_calc_modifiers(scene, ob);
704                 }
705                 else if(ob->type==OB_MBALL) {
706                         makeDispListMBall(scene, ob);
707                 }
708                 else if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
709                         makeDispListCurveTypes(scene, ob, 0);
710                 }
711
712                 mmd->needbind= 0;
713                 mmd->modifier.mode= mode;
714         }
715         
716         return OPERATOR_FINISHED;
717 }
718
719 void OBJECT_OT_modifier_mdef_bind(wmOperatorType *ot)
720 {
721         /* identifiers */
722         ot->name= "Mesh Deform Bind";
723         ot->description = "Bind mesh to cage in mesh deform modifier.";
724         ot->idname= "OBJECT_OT_modifier_mdef_bind";
725         
726         /* api callbacks */
727         ot->poll= modifier_mdef_bind_poll;
728         ot->exec= modifier_mdef_bind_exec;
729         
730         /* flags */
731         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
732 }
733
734 #if 0
735 static void modifiers_add(void *ob_v, int type)
736 {
737         Object *ob = ob_v;
738         ModifierTypeInfo *mti = modifierType_getInfo(type);
739         
740         if (mti->flags&eModifierTypeFlag_RequiresOriginalData) {
741                 ModifierData *md = ob->modifiers.first;
742
743                 while (md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform) {
744                         md = md->next;
745                 }
746
747                 BLI_insertlinkbefore(&ob->modifiers, md, modifier_new(type));
748         } else {
749                 BLI_addtail(&ob->modifiers, modifier_new(type));
750         }
751         ED_undo_push("Add modifier");
752 }
753
754 typedef struct MenuEntry {
755         char *name;
756         int ID;
757 } MenuEntry;
758
759 static int menuEntry_compare_names(const void *entry1, const void *entry2)
760 {
761         return strcmp(((MenuEntry *)entry1)->name, ((MenuEntry *)entry2)->name);
762 }
763
764 static uiBlock *modifiers_add_menu(void *ob_v)
765 {
766         Object *ob = ob_v;
767         uiBlock *block;
768         int i, yco=0;
769         int numEntries = 0;
770         MenuEntry entries[NUM_MODIFIER_TYPES];
771         
772         block= uiNewBlock(&curarea->uiblocks, "modifier_add_menu",
773                           UI_EMBOSSP, UI_HELV, curarea->win);
774         uiBlockSetButmFunc(block, modifiers_add, ob);
775
776         for (i=eModifierType_None+1; i<NUM_MODIFIER_TYPES; i++) {
777                 ModifierTypeInfo *mti = modifierType_getInfo(i);
778
779                 /* Only allow adding through appropriate other interfaces */
780                 if(ELEM(i, eModifierType_ParticleSystem, eModifierType_Surface)) continue;
781
782                 if((mti->flags&eModifierTypeFlag_AcceptsCVs) ||
783                    (ob->type==OB_MESH && (mti->flags&eModifierTypeFlag_AcceptsMesh))) {
784                         entries[numEntries].name = mti->name;
785                         entries[numEntries].ID = i;
786
787                         ++numEntries;
788                 }
789         }
790
791         qsort(entries, numEntries, sizeof(*entries), menuEntry_compare_names);
792
793
794         for(i = 0; i < numEntries; ++i)
795                 uiDefBut(block, BUTM, B_MODIFIER_RECALC, entries[i].name,
796                          0, yco -= 20, 160, 19, NULL, 0, 0, 1, entries[i].ID, "");
797
798         uiTextBoundsBlock(block, 50);
799         uiBlockSetDirection(block, UI_DOWN);
800
801         return block;
802 }
803 #endif
804
805 #if 0
806 static void modifiers_clearHookOffset(bContext *C, void *ob_v, void *md_v)
807 {
808         Object *ob = ob_v;
809         ModifierData *md = md_v;
810         HookModifierData *hmd = (HookModifierData*) md;
811         
812         if (hmd->object) {
813                 Mat4Invert(hmd->object->imat, hmd->object->obmat);
814                 Mat4MulSerie(hmd->parentinv, hmd->object->imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL);
815                 ED_undo_push(C, "Clear hook offset");
816         }
817 }
818
819 static void modifiers_cursorHookCenter(bContext *C, void *ob_v, void *md_v)
820 {
821         /* XXX 
822         Object *ob = ob_v;
823         ModifierData *md = md_v;
824         HookModifierData *hmd = (HookModifierData*) md;
825
826         if(G.vd) {
827                 float *curs = give_cursor();
828                 float bmat[3][3], imat[3][3];
829
830                 where_is_object(ob);
831         
832                 Mat3CpyMat4(bmat, ob->obmat);
833                 Mat3Inv(imat, bmat);
834
835                 curs= give_cursor();
836                 hmd->cent[0]= curs[0]-ob->obmat[3][0];
837                 hmd->cent[1]= curs[1]-ob->obmat[3][1];
838                 hmd->cent[2]= curs[2]-ob->obmat[3][2];
839                 Mat3MulVecfl(imat, hmd->cent);
840
841                 ED_undo_push(C, "Hook cursor center");
842         }*/
843 }
844
845 static void modifiers_selectHook(bContext *C, void *ob_v, void *md_v)
846 {
847         /* XXX ModifierData *md = md_v;
848         HookModifierData *hmd = (HookModifierData*) md;
849
850         hook_select(hmd);*/
851 }
852
853 static void modifiers_reassignHook(bContext *C, void *ob_v, void *md_v)
854 {
855         /* XXX ModifierData *md = md_v;
856         HookModifierData *hmd = (HookModifierData*) md;
857         float cent[3];
858         int *indexar, tot, ok;
859         char name[32];
860                 
861         ok= hook_getIndexArray(&tot, &indexar, name, cent);
862
863         if (!ok) {
864                 uiPupMenuError(C, "Requires selected vertices or active Vertex Group");
865         } else {
866                 if (hmd->indexar) {
867                         MEM_freeN(hmd->indexar);
868                 }
869
870                 VECCOPY(hmd->cent, cent);
871                 hmd->indexar = indexar;
872                 hmd->totindex = tot;
873         }*/
874 }
875
876 void modifiers_explodeFacepa(bContext *C, void *arg1, void *arg2)
877 {
878         ExplodeModifierData *emd=arg1;
879
880         emd->flag |= eExplodeFlag_CalcFaces;
881 }
882
883 void modifiers_explodeDelVg(bContext *C, void *arg1, void *arg2)
884 {
885         ExplodeModifierData *emd=arg1;
886         emd->vgroup = 0;
887 }
888 #endif
889
890