Bugfixes:
[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_action_types.h"
35 #include "DNA_curve_types.h"
36 #include "DNA_key_types.h"
37 #include "DNA_mesh_types.h"
38 #include "DNA_meshdata_types.h"
39 #include "DNA_modifier_types.h"
40 #include "DNA_object_types.h"
41 #include "DNA_object_force.h"
42 #include "DNA_scene_types.h"
43
44 #include "BLI_math.h"
45 #include "BLI_listbase.h"
46
47 #include "BKE_action.h"
48 #include "BKE_curve.h"
49 #include "BKE_context.h"
50 #include "BKE_depsgraph.h"
51 #include "BKE_displist.h"
52 #include "BKE_DerivedMesh.h"
53 #include "BKE_effect.h"
54 #include "BKE_global.h"
55 #include "BKE_key.h"
56 #include "BKE_lattice.h"
57 #include "BKE_mesh.h"
58 #include "BKE_modifier.h"
59 #include "BKE_multires.h"
60 #include "BKE_report.h"
61 #include "BKE_object.h"
62 #include "BKE_particle.h"
63 #include "BKE_softbody.h"
64 #include "BKE_utildefines.h"
65
66 #include "RNA_access.h"
67 #include "RNA_define.h"
68 #include "RNA_enum_types.h"
69
70 #include "ED_armature.h"
71 #include "ED_object.h"
72 #include "ED_screen.h"
73
74 #include "WM_api.h"
75 #include "WM_types.h"
76
77 #include "object_intern.h"
78
79 /******************************** API ****************************/
80
81 ModifierData *ED_object_modifier_add(ReportList *reports, Scene *scene, Object *ob, int type)
82 {
83         ModifierData *md=NULL, *new_md=NULL;
84         ModifierTypeInfo *mti = modifierType_getInfo(type);
85
86         if(mti->flags&eModifierTypeFlag_Single) {
87                 if(modifiers_findByType(ob, type)) {
88                         BKE_report(reports, RPT_WARNING, "Only one modifier of this type allowed.");
89                         return NULL;
90                 }
91         }
92
93         if(type == eModifierType_ParticleSystem) {
94                 /* don't need to worry about the new modifier's name, since that is set to the number
95                  * of particle systems which shouldn't have too many duplicates 
96                  */
97                 object_add_particle_system(scene, ob);
98         }
99         else {
100                 /* get new modifier data to add */
101                 new_md= modifier_new(type);
102                 
103                 if(mti->flags&eModifierTypeFlag_RequiresOriginalData) {
104                         md = ob->modifiers.first;
105                         
106                         while(md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform)
107                                 md = md->next;
108                         
109                         BLI_insertlinkbefore(&ob->modifiers, md, new_md);
110                 }
111                 else
112                         BLI_addtail(&ob->modifiers, new_md);
113                 
114                 /* make sure modifier data has unique name */
115                 modifier_unique_name(&ob->modifiers, new_md);
116                 
117                 /* special cases */
118                 if(type == eModifierType_Softbody) {
119                         if(!ob->soft) {
120                                 ob->soft= sbNew(scene);
121                                 ob->softflag |= OB_SB_GOAL|OB_SB_EDGES;
122                         }
123                 }
124                 else if(type == eModifierType_Collision) {
125                         if(!ob->pd)
126                                 ob->pd= object_add_collision_fields(0);
127                         
128                         ob->pd->deflect= 1;
129                         DAG_scene_sort(scene);
130                 }
131                 else if(type == eModifierType_Surface)
132                         DAG_scene_sort(scene);
133         }
134
135         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
136
137         return new_md;
138 }
139
140 int ED_object_modifier_remove(ReportList *reports, Scene *scene, Object *ob, ModifierData *md)
141 {
142         ModifierData *obmd;
143
144         /* It seems on rapid delete it is possible to
145          * get called twice on same modifier, so make
146          * sure it is in list. */
147         for(obmd=ob->modifiers.first; obmd; obmd=obmd->next)
148                 if(obmd==md)
149                         break;
150         
151         if(!obmd)
152                 return 0;
153
154         /* special cases */
155         if(md->type == eModifierType_ParticleSystem) {
156                 ParticleSystemModifierData *psmd=(ParticleSystemModifierData*)md;
157
158                 BLI_remlink(&ob->particlesystem, psmd->psys);
159                 psys_free(ob, psmd->psys);
160         }
161         else if(md->type == eModifierType_Softbody) {
162                 if(ob->soft) {
163                         sbFree(ob->soft);
164                         ob->soft= NULL;
165                         ob->softflag= 0;
166                 }
167         }
168         else if(md->type == eModifierType_Collision) {
169                 if(ob->pd)
170                         ob->pd->deflect= 0;
171
172         DAG_scene_sort(scene);
173         }
174         else if(md->type == eModifierType_Surface) {
175                 if(ob->pd && ob->pd->shape == PFIELD_SHAPE_SURFACE)
176                         ob->pd->shape = PFIELD_SHAPE_PLANE;
177
178         DAG_scene_sort(scene);
179         }
180         else if(md->type == eModifierType_Smoke) {
181                 ob->dt = OB_SHADED;
182         }
183
184         BLI_remlink(&ob->modifiers, md);
185         modifier_free(md);
186
187         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
188
189         return 1;
190 }
191
192 int ED_object_modifier_move_up(ReportList *reports, Object *ob, ModifierData *md)
193 {
194         if(md->prev) {
195                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
196
197                 if(mti->type!=eModifierTypeType_OnlyDeform) {
198                         ModifierTypeInfo *nmti = modifierType_getInfo(md->prev->type);
199
200                         if(nmti->flags&eModifierTypeFlag_RequiresOriginalData) {
201                                 BKE_report(reports, RPT_WARNING, "Cannot move above a modifier requiring original data.");
202                                 return 0;
203                         }
204                 }
205
206                 BLI_remlink(&ob->modifiers, md);
207                 BLI_insertlink(&ob->modifiers, md->prev->prev, md);
208         }
209
210         return 1;
211 }
212
213 int ED_object_modifier_move_down(ReportList *reports, Object *ob, ModifierData *md)
214 {
215         if(md->next) {
216                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
217
218                 if(mti->flags&eModifierTypeFlag_RequiresOriginalData) {
219                         ModifierTypeInfo *nmti = modifierType_getInfo(md->next->type);
220
221                         if(nmti->type!=eModifierTypeType_OnlyDeform) {
222                                 BKE_report(reports, RPT_WARNING, "Cannot move beyond a non-deforming modifier.");
223                                 return 0;
224                         }
225                 }
226
227                 BLI_remlink(&ob->modifiers, md);
228                 BLI_insertlink(&ob->modifiers, md->next, md);
229         }
230
231         return 1;
232 }
233
234 int ED_object_modifier_convert(ReportList *reports, Scene *scene, Object *ob, ModifierData *md)
235 {
236         Object *obn;
237         ParticleSystem *psys;
238         ParticleCacheKey *key, **cache;
239         ParticleSettings *part;
240         Mesh *me;
241         MVert *mvert;
242         MEdge *medge;
243         int a, k, kmax;
244         int totvert=0, totedge=0, cvert=0;
245         int totpart=0, totchild=0;
246
247         if(md->type != eModifierType_ParticleSystem) return 0;
248         if(ob && ob->mode & OB_MODE_PARTICLE_EDIT) return 0;
249
250         psys=((ParticleSystemModifierData *)md)->psys;
251         part= psys->part;
252
253         if(part->ren_as == PART_DRAW_GR || part->ren_as == PART_DRAW_OB) {
254                 ; // XXX make_object_duplilist_real(NULL);
255         }
256         else {
257                 if(part->ren_as != PART_DRAW_PATH || psys->pathcache == 0)
258                         return 0;
259
260                 totpart= psys->totcached;
261                 totchild= psys->totchildcache;
262
263                 if(totchild && (part->draw&PART_DRAW_PARENT)==0)
264                         totpart= 0;
265
266                 /* count */
267                 cache= psys->pathcache;
268                 for(a=0; a<totpart; a++) {
269                         key= cache[a];
270                         totvert+= key->steps+1;
271                         totedge+= key->steps;
272                 }
273
274                 cache= psys->childcache;
275                 for(a=0; a<totchild; a++) {
276                         key= cache[a];
277                         totvert+= key->steps+1;
278                         totedge+= key->steps;
279                 }
280
281                 if(totvert==0) return 0;
282
283                 /* add new mesh */
284                 obn= add_object(scene, OB_MESH);
285                 me= obn->data;
286                 
287                 me->totvert= totvert;
288                 me->totedge= totedge;
289                 
290                 me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
291                 me->medge= CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
292                 me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, 0);
293                 
294                 mvert= me->mvert;
295                 medge= me->medge;
296
297                 /* copy coordinates */
298                 cache= psys->pathcache;
299                 for(a=0; a<totpart; a++) {
300                         key= cache[a];
301                         kmax= key->steps;
302                         for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
303                                 VECCOPY(mvert->co,key->co);
304                                 if(k) {
305                                         medge->v1= cvert-1;
306                                         medge->v2= cvert;
307                                         medge->flag= ME_EDGEDRAW|ME_EDGERENDER|ME_LOOSEEDGE;
308                                         medge++;
309                                 }
310                         }
311                 }
312
313                 cache=psys->childcache;
314                 for(a=0; a<totchild; a++) {
315                         key=cache[a];
316                         kmax=key->steps;
317                         for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
318                                 VECCOPY(mvert->co,key->co);
319                                 if(k) {
320                                         medge->v1=cvert-1;
321                                         medge->v2=cvert;
322                                         medge->flag= ME_EDGEDRAW|ME_EDGERENDER|ME_LOOSEEDGE;
323                                         medge++;
324                                 }
325                         }
326                 }
327         }
328
329         DAG_scene_sort(scene);
330
331         return 1;
332 }
333
334 int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, ModifierData *md, int mode)
335 {
336         DerivedMesh *dm;
337         Mesh *me = ob->data;
338         int converted = 0;
339
340         if (scene->obedit) {
341                 BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied in editmode");
342                 return 0;
343         } else if (((ID*) ob->data)->us>1) {
344                 BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied to multi-user data");
345                 return 0;
346         }
347
348         if (md!=ob->modifiers.first)
349                 BKE_report(reports, RPT_INFO, "Applied modifier was not first, result may not be as expected.");
350
351         if (ob->type==OB_MESH) {
352                 if (mode == MODIFIER_APPLY_SHAPE) {
353                         Key *key=me->key;
354                         KeyBlock *kb;
355                         int newkey=0;
356                         
357                         if(!modifier_sameTopology(md)) {
358                                 BKE_report(reports, RPT_ERROR, "Only deforming modifiers can be applied to Shapes");
359                                 return 0;
360                         }
361                         mesh_pmv_off(ob, me);
362                         
363                         dm = mesh_create_derived_for_modifier(scene, ob, md);
364                         if (!dm) {
365                                 BKE_report(reports, RPT_ERROR, "Modifier is disabled or returned error, skipping apply");
366                                 return 0;
367                         }
368                         
369                         if(key == NULL) {
370                                 key= me->key= add_key((ID *)me);
371                                 key->type= KEY_RELATIVE;
372                                 newkey= 1;
373                         }
374                         kb= add_keyblock(scene, key);
375                         
376                         if (newkey) {
377                                 /* if that was the first key block added, then it was the basis.
378                                  * Initialise it with the mesh, and add another for the modifier */
379                                 mesh_to_key(me, kb);
380                                 kb= add_keyblock(scene, key);
381                         }
382                         DM_to_meshkey(dm, me, kb);
383                         converted = 1;
384                         
385                         dm->release(dm);
386                 }
387                 else {  /* MODIFIER_APPLY_DATA */
388                         if( me->key) {
389                                 BKE_report(reports, RPT_ERROR, "Modifier cannot be applied to Mesh with Shape Keys");
390                                 return 0;
391                         }
392                         
393                         mesh_pmv_off(ob, me);
394
395                         /* Multires: ensure that recent sculpting is applied */
396                         if(md->type == eModifierType_Multires)
397                                    multires_force_update(ob);
398
399                         dm = mesh_create_derived_for_modifier(scene, ob, md);
400                         if (!dm) {
401                                 BKE_report(reports, RPT_ERROR, "Modifier is disabled or returned error, skipping apply");
402                                 return 0;
403                         }
404
405                         DM_to_mesh(dm, me);
406                         converted = 1;
407
408                         dm->release(dm);
409                 }
410         } 
411         else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
412                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
413                 Curve *cu = ob->data;
414                 int numVerts;
415                 float (*vertexCos)[3];
416
417                 BKE_report(reports, RPT_INFO, "Applied modifier only changed CV points, not tesselated/bevel vertices");
418
419                 if (!(md->mode&eModifierMode_Realtime) || (mti->isDisabled && mti->isDisabled(md))) {
420                         BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
421                         return 0;
422                 }
423
424                 vertexCos = curve_getVertexCos(cu, &cu->nurb, &numVerts);
425                 mti->deformVerts(md, ob, NULL, vertexCos, numVerts, 0, 0);
426                 curve_applyVertexCos(cu, &cu->nurb, vertexCos);
427
428                 converted = 1;
429
430                 MEM_freeN(vertexCos);
431
432                 DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
433         }
434         else {
435                 BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type");
436                 return 0;
437         }
438
439         if (converted) {
440                 BLI_remlink(&ob->modifiers, md);
441                 modifier_free(md);
442
443                 return 1;
444         }
445
446         return 0;
447 }
448
449 int ED_object_modifier_copy(ReportList *reports, Object *ob, ModifierData *md)
450 {
451         ModifierData *nmd;
452         
453         nmd = modifier_new(md->type);
454         modifier_copyData(md, nmd);
455         BLI_insertlink(&ob->modifiers, md, nmd);
456         modifier_unique_name(&ob->modifiers, nmd);
457
458         return 1;
459 }
460
461 /***************************** OPERATORS ****************************/
462
463 static int modifier_poll(bContext *C)
464 {
465         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
466         return (ptr.data != NULL && !((ID*)ptr.id.data)->lib);
467 }
468
469 /************************ add modifier operator *********************/
470
471 static int modifier_add_exec(bContext *C, wmOperator *op)
472 {
473         Scene *scene= CTX_data_scene(C);
474     Object *ob = CTX_data_active_object(C);
475         int type= RNA_enum_get(op->ptr, "type");
476
477         if(!ED_object_modifier_add(op->reports, scene, ob, type))
478                 return OPERATOR_CANCELLED;
479
480         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
481         
482         return OPERATOR_FINISHED;
483 }
484
485 static EnumPropertyItem *modifier_add_itemf(bContext *C, PointerRNA *ptr, int *free)
486 {       
487         Object *ob= CTX_data_active_object(C);
488         EnumPropertyItem *item= NULL, *md_item;
489         ModifierTypeInfo *mti;
490         int totitem= 0, a;
491         
492         if(!ob)
493                 return modifier_type_items;
494
495         for(a=0; modifier_type_items[a].identifier; a++) {
496                 md_item= &modifier_type_items[a];
497
498                 if(md_item->identifier[0]) {
499                         mti= modifierType_getInfo(md_item->value);
500
501                         if(mti->flags & eModifierTypeFlag_NoUserAdd)
502                                 continue;
503
504                         if(!((mti->flags & eModifierTypeFlag_AcceptsCVs) ||
505                            (ob->type==OB_MESH && (mti->flags & eModifierTypeFlag_AcceptsMesh))))
506                                 continue;
507                 }
508
509                 RNA_enum_item_add(&item, &totitem, md_item);
510         }
511
512         RNA_enum_item_end(&item, &totitem);
513         *free= 1;
514
515         return item;
516 }
517
518 void OBJECT_OT_modifier_add(wmOperatorType *ot)
519 {
520         PropertyRNA *prop;
521
522         /* identifiers */
523         ot->name= "Add Modifier";
524         ot->description = "Add a modifier to the active object.";
525         ot->idname= "OBJECT_OT_modifier_add";
526         
527         /* api callbacks */
528         ot->invoke= WM_menu_invoke;
529         ot->exec= modifier_add_exec;
530         ot->poll= ED_operator_object_active;
531         
532         /* flags */
533         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
534         
535         /* properties */
536         prop= RNA_def_enum(ot->srna, "type", modifier_type_items, eModifierType_Subsurf, "Type", "");
537         RNA_def_enum_funcs(prop, modifier_add_itemf);
538 }
539
540 /************************ remove modifier operator *********************/
541
542 static int modifier_remove_exec(bContext *C, wmOperator *op)
543 {
544         Scene *scene= CTX_data_scene(C);
545         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
546         Object *ob= ptr.id.data;
547         ModifierData *md= ptr.data;
548
549         if(!ED_object_modifier_remove(op->reports, scene, ob, md))
550                 return OPERATOR_CANCELLED;
551
552         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
553         
554         return OPERATOR_FINISHED;
555 }
556
557 void OBJECT_OT_modifier_remove(wmOperatorType *ot)
558 {
559         ot->name= "Remove Modifier";
560         ot->description= "Remove a modifier from the active object.";
561         ot->idname= "OBJECT_OT_modifier_remove";
562         ot->poll= ED_operator_object_active;
563
564         ot->exec= modifier_remove_exec;
565         ot->poll= modifier_poll;
566         
567         /* flags */
568         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
569 }
570
571 /************************ move up modifier operator *********************/
572
573 static int modifier_move_up_exec(bContext *C, wmOperator *op)
574 {
575         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
576         Object *ob= ptr.id.data;
577         ModifierData *md= ptr.data;
578
579         if(!ED_object_modifier_move_up(op->reports, ob, md))
580                 return OPERATOR_CANCELLED;
581
582         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
583         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
584         
585         return OPERATOR_FINISHED;
586 }
587
588 void OBJECT_OT_modifier_move_up(wmOperatorType *ot)
589 {
590         ot->name= "Move Up Modifier";
591         ot->description= "Move modifier up in the stack.";
592         ot->idname= "OBJECT_OT_modifier_move_up";
593         ot->poll= ED_operator_object_active;
594
595         ot->exec= modifier_move_up_exec;
596         ot->poll= modifier_poll;
597         
598         /* flags */
599         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
600 }
601
602 /************************ move down modifier operator *********************/
603
604 static int modifier_move_down_exec(bContext *C, wmOperator *op)
605 {
606         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
607         Object *ob= ptr.id.data;
608         ModifierData *md= ptr.data;
609
610         if(!ob || !md || !ED_object_modifier_move_down(op->reports, ob, md))
611                 return OPERATOR_CANCELLED;
612
613         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
614         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
615         
616         return OPERATOR_FINISHED;
617 }
618
619 void OBJECT_OT_modifier_move_down(wmOperatorType *ot)
620 {
621         ot->name= "Move Down Modifier";
622         ot->description= "Move modifier down in the stack.";
623         ot->idname= "OBJECT_OT_modifier_move_down";
624         ot->poll= ED_operator_object_active;
625
626         ot->exec= modifier_move_down_exec;
627         ot->poll= modifier_poll;
628         
629         /* flags */
630         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
631 }
632
633 /************************ apply modifier operator *********************/
634
635 static int modifier_apply_exec(bContext *C, wmOperator *op)
636 {
637         Scene *scene= CTX_data_scene(C);
638         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
639         Object *ob= ptr.id.data;
640         ModifierData *md= ptr.data;
641         int apply_as= RNA_enum_get(op->ptr, "apply_as");
642
643         if(!ob || !md || !ED_object_modifier_apply(op->reports, scene, ob, md, apply_as))
644                 return OPERATOR_CANCELLED;
645
646         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
647         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
648         
649         return OPERATOR_FINISHED;
650 }
651
652 static EnumPropertyItem modifier_apply_as_items[] = {
653         {MODIFIER_APPLY_DATA, "DATA", 0, "Object Data", "Apply modifier to the object's data"},
654         {MODIFIER_APPLY_SHAPE, "SHAPE", 0, "New Shape", "Apply deform-only modifier to a new shape on this object"},
655         {0, NULL, 0, NULL, NULL}};
656
657 void OBJECT_OT_modifier_apply(wmOperatorType *ot)
658 {
659         ot->name= "Apply Modifier";
660         ot->description= "Apply modifier and remove from the stack.";
661         ot->idname= "OBJECT_OT_modifier_apply";
662         ot->poll= ED_operator_object_active;
663
664         //ot->invoke= WM_menu_invoke;
665         ot->exec= modifier_apply_exec;
666         ot->poll= modifier_poll;
667         
668         /* flags */
669         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
670         
671         RNA_def_enum(ot->srna, "apply_as", modifier_apply_as_items, MODIFIER_APPLY_DATA, "Apply as", "How to apply the modifier to the geometry");
672 }
673
674 /************************ convert modifier operator *********************/
675
676 static int modifier_convert_exec(bContext *C, wmOperator *op)
677 {
678         Scene *scene= CTX_data_scene(C);
679         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
680         Object *ob= ptr.id.data;
681         ModifierData *md= ptr.data;
682
683         if(!ob || !md || !ED_object_modifier_convert(op->reports, scene, ob, md))
684                 return OPERATOR_CANCELLED;
685
686         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
687         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
688         
689         return OPERATOR_FINISHED;
690 }
691
692 void OBJECT_OT_modifier_convert(wmOperatorType *ot)
693 {
694         ot->name= "Convert Modifier";
695         ot->description= "Convert particles to a mesh object.";
696         ot->idname= "OBJECT_OT_modifier_convert";
697         ot->poll= ED_operator_object_active;
698
699         ot->exec= modifier_convert_exec;
700         ot->poll= modifier_poll;
701         
702         /* flags */
703         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
704 }
705
706 /************************ copy modifier operator *********************/
707
708 static int modifier_copy_exec(bContext *C, wmOperator *op)
709 {
710         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
711         Object *ob= ptr.id.data;
712         ModifierData *md= ptr.data;
713
714         if(!ob || !md || !ED_object_modifier_copy(op->reports, ob, md))
715                 return OPERATOR_CANCELLED;
716
717         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
718         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
719         
720         return OPERATOR_FINISHED;
721 }
722
723 void OBJECT_OT_modifier_copy(wmOperatorType *ot)
724 {
725         ot->name= "Copy Modifier";
726         ot->description= "Duplicate modifier at the same position in the stack.";
727         ot->idname= "OBJECT_OT_modifier_copy";
728         ot->poll= ED_operator_object_active;
729
730         ot->exec= modifier_copy_exec;
731         ot->poll= modifier_poll;
732         
733         /* flags */
734         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
735 }
736
737 /************* multires delete higher levels operator ****************/
738
739 static int multires_higher_levels_delete_exec(bContext *C, wmOperator *op)
740 {
741         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_MultiresModifier);
742         Object *ob= ptr.id.data;
743         MultiresModifierData *mmd= ptr.data;
744
745         if(mmd) {
746                 multiresModifier_del_levels(mmd, ob, 1);
747                 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
748         }
749         
750         return OPERATOR_FINISHED;
751 }
752
753 void OBJECT_OT_multires_higher_levels_delete(wmOperatorType *ot)
754 {
755         ot->name= "Delete Higher Levels";
756         ot->idname= "OBJECT_OT_multires_higher_levels_delete";
757         ot->poll= ED_operator_object_active;
758
759         ot->exec= multires_higher_levels_delete_exec;
760         
761         /* flags */
762         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
763 }
764
765 /****************** multires subdivide operator *********************/
766
767 static int multires_subdivide_exec(bContext *C, wmOperator *op)
768 {
769         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_MultiresModifier);
770         Object *ob= ptr.id.data;
771         MultiresModifierData *mmd= ptr.data;
772
773         multiresModifier_subdivide(mmd, ob, 1, 0, mmd->simple);
774         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
775         
776         return OPERATOR_FINISHED;
777 }
778
779 static int multires_subdivide_poll(bContext *C)
780 {
781         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_MultiresModifier);
782         ID *id= ptr.id.data;
783         return (ptr.data && id && !id->lib);
784 }
785
786 void OBJECT_OT_multires_subdivide(wmOperatorType *ot)
787 {
788         ot->name= "Multires Subdivide";
789         ot->description= "Add a new level of subdivision.";
790         ot->idname= "OBJECT_OT_multires_subdivide";
791
792         ot->exec= multires_subdivide_exec;
793         ot->poll= multires_subdivide_poll;
794         
795         /* flags */
796         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
797 }
798
799 /************************ mdef bind operator *********************/
800
801 static int meshdeform_poll(bContext *C)
802 {
803         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_MeshDeformModifier);
804         ID *id= ptr.id.data;
805         return (ptr.data && id && !id->lib);
806 }
807
808 static int meshdeform_bind_exec(bContext *C, wmOperator *op)
809 {
810         Scene *scene= CTX_data_scene(C);
811         PointerRNA ptr= CTX_data_pointer_get(C, "modifier");
812         Object *ob= ptr.id.data;
813         MeshDeformModifierData *mmd= ptr.data;
814
815         if(mmd->bindcos) {
816                 if(mmd->bindweights) MEM_freeN(mmd->bindweights);
817                 if(mmd->bindcos) MEM_freeN(mmd->bindcos);
818                 if(mmd->dyngrid) MEM_freeN(mmd->dyngrid);
819                 if(mmd->dyninfluences) MEM_freeN(mmd->dyninfluences);
820                 if(mmd->dynverts) MEM_freeN(mmd->dynverts);
821                 mmd->bindweights= NULL;
822                 mmd->bindcos= NULL;
823                 mmd->dyngrid= NULL;
824                 mmd->dyninfluences= NULL;
825                 mmd->dynverts= NULL;
826                 mmd->totvert= 0;
827                 mmd->totcagevert= 0;
828                 mmd->totinfluence= 0;
829         }
830         else {
831                 DerivedMesh *dm;
832                 int mode= mmd->modifier.mode;
833
834                 /* force modifier to run, it will call binding routine */
835                 mmd->bindfunc= harmonic_coordinates_bind;
836                 mmd->modifier.mode |= eModifierMode_Realtime;
837
838                 if(ob->type == OB_MESH) {
839                         dm= mesh_create_derived_view(scene, ob, 0);
840                         dm->release(dm);
841                 }
842                 else if(ob->type == OB_LATTICE) {
843                         lattice_calc_modifiers(scene, ob);
844                 }
845                 else if(ob->type==OB_MBALL) {
846                         makeDispListMBall(scene, ob);
847                 }
848                 else if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
849                         makeDispListCurveTypes(scene, ob, 0);
850                 }
851
852                 mmd->bindfunc= NULL;
853                 mmd->modifier.mode= mode;
854         }
855         
856         return OPERATOR_FINISHED;
857 }
858
859 void OBJECT_OT_meshdeform_bind(wmOperatorType *ot)
860 {
861         /* identifiers */
862         ot->name= "Mesh Deform Bind";
863         ot->description = "Bind mesh to cage in mesh deform modifier.";
864         ot->idname= "OBJECT_OT_meshdeform_bind";
865         
866         /* api callbacks */
867         ot->poll= meshdeform_poll;
868         ot->exec= meshdeform_bind_exec;
869         
870         /* flags */
871         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
872 }
873
874 /****************** explode refresh operator *********************/
875
876 static int explode_refresh_poll(bContext *C)
877 {
878         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_ExplodeModifier);
879         ID *id= ptr.id.data;
880         return (ptr.data && id && !id->lib);
881 }
882
883 static int explode_refresh_exec(bContext *C, wmOperator *op)
884 {
885         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_ExplodeModifier);
886         Object *ob= ptr.id.data;
887         ExplodeModifierData *emd= ptr.data;
888
889         emd->flag |= eExplodeFlag_CalcFaces;
890
891         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
892         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
893         
894         return OPERATOR_FINISHED;
895 }
896
897 void OBJECT_OT_explode_refresh(wmOperatorType *ot)
898 {
899         ot->name= "Explode Refresh";
900         ot->description= "Refresh data in the Explode modifier.";
901         ot->idname= "OBJECT_OT_explode_refresh";
902
903         ot->exec= explode_refresh_exec;
904         ot->poll= explode_refresh_poll;
905         
906         /* flags */
907         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
908 }
909