Bugfix #20382
[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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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_key_types.h"
36 #include "DNA_mesh_types.h"
37 #include "DNA_meshdata_types.h"
38 #include "DNA_object_force.h"
39 #include "DNA_scene_types.h"
40
41 #include "BLI_math.h"
42 #include "BLI_listbase.h"
43 #include "BLI_string.h"
44 #include "BLI_path_util.h"
45
46 #include "BKE_curve.h"
47 #include "BKE_context.h"
48 #include "BKE_depsgraph.h"
49 #include "BKE_displist.h"
50 #include "BKE_DerivedMesh.h"
51 #include "BKE_effect.h"
52 #include "BKE_global.h"
53 #include "BKE_key.h"
54 #include "BKE_lattice.h"
55 #include "BKE_main.h"
56 #include "BKE_mesh.h"
57 #include "BKE_modifier.h"
58 #include "BKE_multires.h"
59 #include "BKE_report.h"
60 #include "BKE_object.h"
61 #include "BKE_particle.h"
62 #include "BKE_softbody.h"
63
64 #include "RNA_access.h"
65 #include "RNA_define.h"
66 #include "RNA_enum_types.h"
67
68 #include "ED_armature.h"
69 #include "ED_object.h"
70 #include "ED_screen.h"
71
72 #include "WM_api.h"
73 #include "WM_types.h"
74
75 #include "object_intern.h"
76
77 /******************************** API ****************************/
78
79 ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *scene, Object *ob, char *name, int type)
80 {
81         ModifierData *md=NULL, *new_md=NULL;
82         ModifierTypeInfo *mti = modifierType_getInfo(type);
83
84         if(mti->flags&eModifierTypeFlag_Single) {
85                 if(modifiers_findByType(ob, type)) {
86                         BKE_report(reports, RPT_WARNING, "Only one modifier of this type allowed.");
87                         return NULL;
88                 }
89         }
90
91         if(type == eModifierType_ParticleSystem) {
92                 /* don't need to worry about the new modifier's name, since that is set to the number
93                  * of particle systems which shouldn't have too many duplicates 
94                  */
95                 new_md = object_add_particle_system(scene, ob, name);
96         }
97         else {
98                 /* get new modifier data to add */
99                 new_md= modifier_new(type);
100                 
101                 if(mti->flags&eModifierTypeFlag_RequiresOriginalData) {
102                         md = ob->modifiers.first;
103                         
104                         while(md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform)
105                                 md = md->next;
106                         
107                         BLI_insertlinkbefore(&ob->modifiers, md, new_md);
108                 }
109                 else
110                         BLI_addtail(&ob->modifiers, new_md);
111
112                 if(name)
113                         BLI_strncpy(new_md->name, name, sizeof(new_md->name));
114
115                 /* make sure modifier data has unique name */
116
117                 modifier_unique_name(&ob->modifiers, new_md);
118                 
119                 /* special cases */
120                 if(type == eModifierType_Softbody) {
121                         if(!ob->soft) {
122                                 ob->soft= sbNew(scene);
123                                 ob->softflag |= OB_SB_GOAL|OB_SB_EDGES;
124                         }
125                 }
126                 else if(type == eModifierType_Collision) {
127                         if(!ob->pd)
128                                 ob->pd= object_add_collision_fields(0);
129                         
130                         ob->pd->deflect= 1;
131                         DAG_scene_sort(bmain, scene);
132                 }
133                 else if(type == eModifierType_Surface)
134                         DAG_scene_sort(bmain, scene);
135                 else if(type == eModifierType_Multires)
136                         /* set totlvl from existing MDISPS layer if object already had it */
137                         multiresModifier_set_levels_from_disps((MultiresModifierData *)new_md, ob);
138         }
139
140         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
141
142         return new_md;
143 }
144
145 int ED_object_modifier_remove(ReportList *reports, Main *bmain, Scene *scene, Object *ob, ModifierData *md)
146 {
147         ModifierData *obmd;
148         int sort_depsgraph = 0;
149
150         /* It seems on rapid delete it is possible to
151          * get called twice on same modifier, so make
152          * sure it is in list. */
153         for(obmd=ob->modifiers.first; obmd; obmd=obmd->next)
154                 if(obmd==md)
155                         break;
156         
157         if(!obmd) {
158                 BKE_reportf(reports, RPT_ERROR, "Modifier '%s' not in object '%s'.", ob->id.name, md->name);
159                 return 0;
160         }
161
162         /* special cases */
163         if(md->type == eModifierType_ParticleSystem) {
164                 ParticleSystemModifierData *psmd=(ParticleSystemModifierData*)md;
165
166                 BLI_remlink(&ob->particlesystem, psmd->psys);
167                 psys_free(ob, psmd->psys);
168                 psmd->psys= NULL;
169         }
170         else if(md->type == eModifierType_Softbody) {
171                 if(ob->soft) {
172                         sbFree(ob->soft);
173                         ob->soft= NULL;
174                         ob->softflag= 0;
175                 }
176         }
177         else if(md->type == eModifierType_Collision) {
178                 if(ob->pd)
179                         ob->pd->deflect= 0;
180
181                 sort_depsgraph = 1;
182         }
183         else if(md->type == eModifierType_Surface) {
184                 if(ob->pd && ob->pd->shape == PFIELD_SHAPE_SURFACE)
185                         ob->pd->shape = PFIELD_SHAPE_PLANE;
186
187                 sort_depsgraph = 1;
188         }
189         else if(md->type == eModifierType_Smoke) {
190                 ob->dt = OB_TEXTURE;
191         }
192         else if(md->type == eModifierType_Multires) {
193                 Mesh *me= ob->data;
194
195                 CustomData_external_remove(&me->fdata, &me->id, CD_MDISPS, me->totface);
196                 CustomData_free_layer_active(&me->fdata, CD_MDISPS, me->totface);
197         }
198
199         if(ELEM(md->type, eModifierType_Softbody, eModifierType_Cloth) &&
200                 ob->particlesystem.first == NULL) {
201                 ob->mode &= ~OB_MODE_PARTICLE_EDIT;
202         }
203
204         BLI_remlink(&ob->modifiers, md);
205         modifier_free(md);
206
207         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
208
209         /* sorting has to be done after the update so that dynamic systems can react properly */
210         if(sort_depsgraph)
211                 DAG_scene_sort(bmain, scene);
212
213         return 1;
214 }
215
216 int ED_object_modifier_move_up(ReportList *reports, Object *ob, ModifierData *md)
217 {
218         if(md->prev) {
219                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
220
221                 if(mti->type!=eModifierTypeType_OnlyDeform) {
222                         ModifierTypeInfo *nmti = modifierType_getInfo(md->prev->type);
223
224                         if(nmti->flags&eModifierTypeFlag_RequiresOriginalData) {
225                                 BKE_report(reports, RPT_WARNING, "Cannot move above a modifier requiring original data.");
226                                 return 0;
227                         }
228                 }
229
230                 BLI_remlink(&ob->modifiers, md);
231                 BLI_insertlink(&ob->modifiers, md->prev->prev, md);
232         }
233
234         return 1;
235 }
236
237 int ED_object_modifier_move_down(ReportList *reports, Object *ob, ModifierData *md)
238 {
239         if(md->next) {
240                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
241
242                 if(mti->flags&eModifierTypeFlag_RequiresOriginalData) {
243                         ModifierTypeInfo *nmti = modifierType_getInfo(md->next->type);
244
245                         if(nmti->type!=eModifierTypeType_OnlyDeform) {
246                                 BKE_report(reports, RPT_WARNING, "Cannot move beyond a non-deforming modifier.");
247                                 return 0;
248                         }
249                 }
250
251                 BLI_remlink(&ob->modifiers, md);
252                 BLI_insertlink(&ob->modifiers, md->next, md);
253         }
254
255         return 1;
256 }
257
258 int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene *scene, Object *ob, ModifierData *md)
259 {
260         Object *obn;
261         ParticleSystem *psys;
262         ParticleCacheKey *key, **cache;
263         ParticleSettings *part;
264         Mesh *me;
265         MVert *mvert;
266         MEdge *medge;
267         int a, k, kmax;
268         int totvert=0, totedge=0, cvert=0;
269         int totpart=0, totchild=0;
270
271         if(md->type != eModifierType_ParticleSystem) return 0;
272         if(ob && ob->mode & OB_MODE_PARTICLE_EDIT) return 0;
273
274         psys=((ParticleSystemModifierData *)md)->psys;
275         part= psys->part;
276
277         if(part->ren_as != PART_DRAW_PATH || psys->pathcache == 0)
278                 return 0;
279
280         totpart= psys->totcached;
281         totchild= psys->totchildcache;
282
283         if(totchild && (part->draw&PART_DRAW_PARENT)==0)
284                 totpart= 0;
285
286         /* count */
287         cache= psys->pathcache;
288         for(a=0; a<totpart; a++) {
289                 key= cache[a];
290                 totvert+= key->steps+1;
291                 totedge+= key->steps;
292         }
293
294         cache= psys->childcache;
295         for(a=0; a<totchild; a++) {
296                 key= cache[a];
297                 totvert+= key->steps+1;
298                 totedge+= key->steps;
299         }
300
301         if(totvert==0) return 0;
302
303         /* add new mesh */
304         obn= add_object(scene, OB_MESH);
305         me= obn->data;
306         
307         me->totvert= totvert;
308         me->totedge= totedge;
309         
310         me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
311         me->medge= CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
312         me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, 0);
313         
314         mvert= me->mvert;
315         medge= me->medge;
316
317         /* copy coordinates */
318         cache= psys->pathcache;
319         for(a=0; a<totpart; a++) {
320                 key= cache[a];
321                 kmax= key->steps;
322                 for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
323                         VECCOPY(mvert->co,key->co);
324                         if(k) {
325                                 medge->v1= cvert-1;
326                                 medge->v2= cvert;
327                                 medge->flag= ME_EDGEDRAW|ME_EDGERENDER|ME_LOOSEEDGE;
328                                 medge++;
329                         }
330                         else {
331                                 /* cheap trick to select the roots */
332                                 mvert->flag |= SELECT;
333                         }
334                 }
335         }
336
337         cache=psys->childcache;
338         for(a=0; a<totchild; a++) {
339                 key=cache[a];
340                 kmax=key->steps;
341                 for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
342                         VECCOPY(mvert->co,key->co);
343                         if(k) {
344                                 medge->v1=cvert-1;
345                                 medge->v2=cvert;
346                                 medge->flag= ME_EDGEDRAW|ME_EDGERENDER|ME_LOOSEEDGE;
347                                 medge++;
348                         }
349                         else {
350                                 /* cheap trick to select the roots */
351                                 mvert->flag |= SELECT;
352                         }
353                 }
354         }
355
356         DAG_scene_sort(bmain, scene);
357
358         return 1;
359 }
360
361 static int modifier_apply_shape(ReportList *reports, Scene *scene, Object *ob, ModifierData *md)
362 {
363         if (ob->type==OB_MESH) {
364                 DerivedMesh *dm;
365                 Mesh *me= ob->data;
366                 Key *key=me->key;
367                 KeyBlock *kb;
368                 
369                 if(!modifier_sameTopology(md)) {
370                         BKE_report(reports, RPT_ERROR, "Only deforming modifiers can be applied to Shapes");
371                         return 0;
372                 }
373                 mesh_pmv_off(me);
374                 
375                 dm = mesh_create_derived_for_modifier(scene, ob, md);
376                 if (!dm) {
377                         BKE_report(reports, RPT_ERROR, "Modifier is disabled or returned error, skipping apply");
378                         return 0;
379                 }
380                 
381                 if(key == NULL) {
382                         key= me->key= add_key((ID *)me);
383                         key->type= KEY_RELATIVE;
384                         /* if that was the first key block added, then it was the basis.
385                          * Initialise it with the mesh, and add another for the modifier */
386                         kb= add_keyblock(key, NULL);
387                         mesh_to_key(me, kb);
388                 }
389
390                 kb= add_keyblock(key, md->name);
391                 DM_to_meshkey(dm, me, kb);
392                 
393                 dm->release(dm);
394         }
395         else {
396                 BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type");
397                 return 0;
398         }
399         return 1;
400 }
401
402 static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob, ModifierData *md)
403 {
404         ModifierTypeInfo *mti= modifierType_getInfo(md->type);
405
406         if (!(md->mode&eModifierMode_Realtime) || (mti->isDisabled && mti->isDisabled(md, 0))) {
407                 BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
408                 return 0;
409         }
410
411         if (ob->type==OB_MESH) {
412                 DerivedMesh *dm;
413                 Mesh *me = ob->data;
414                 MultiresModifierData *mmd= find_multires_modifier_before(scene, md);
415
416                 if( me->key) {
417                         BKE_report(reports, RPT_ERROR, "Modifier cannot be applied to Mesh with Shape Keys");
418                         return 0;
419                 }
420
421                 mesh_pmv_off(me);
422
423                 /* Multires: ensure that recent sculpting is applied */
424                 if(md->type == eModifierType_Multires)
425                         multires_force_update(ob);
426
427                 if (mmd && mmd->totlvl && mti->type==eModifierTypeType_OnlyDeform) {
428                         if(!multiresModifier_reshapeFromDeformMod (scene, mmd, ob, md)) {
429                                 BKE_report(reports, RPT_ERROR, "Multires modifier returned error, skipping apply");
430                                 return 0;
431                         }
432                 } else {
433                         dm = mesh_create_derived_for_modifier(scene, ob, md);
434                         if (!dm) {
435                                 BKE_report(reports, RPT_ERROR, "Modifier returned error, skipping apply");
436                                 return 0;
437                         }
438
439                         DM_to_mesh(dm, me);
440
441                         dm->release(dm);
442
443                         if(md->type == eModifierType_Multires) {
444                                 CustomData_external_remove(&me->fdata, &me->id, CD_MDISPS, me->totface);
445                                 CustomData_free_layer_active(&me->fdata, CD_MDISPS, me->totface);
446                         }
447                 }
448         } 
449         else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
450                 Curve *cu;
451                 int numVerts;
452                 float (*vertexCos)[3];
453
454                 if (mti->type==eModifierTypeType_Constructive) {
455                         BKE_report(reports, RPT_ERROR, "Cannot apply constructive modifiers on curve");
456                         return 0;
457                 }
458
459                 cu = ob->data;
460                 BKE_report(reports, RPT_INFO, "Applied modifier only changed CV points, not tesselated/bevel vertices");
461
462                 vertexCos = curve_getVertexCos(cu, &cu->nurb, &numVerts);
463                 mti->deformVerts(md, ob, NULL, vertexCos, numVerts, 0, 0);
464                 curve_applyVertexCos(cu, &cu->nurb, vertexCos);
465
466                 MEM_freeN(vertexCos);
467
468                 DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
469         }
470         else {
471                 BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type");
472                 return 0;
473         }
474
475         /* lattice modifier can be applied to particle system too */
476         if(ob->particlesystem.first) {
477
478                 ParticleSystem *psys = ob->particlesystem.first;
479
480                 for(; psys; psys=psys->next) {
481                         
482                         if(psys->part->type != PART_HAIR)
483                                 continue;
484
485                         psys_apply_hair_lattice(scene, ob, psys);
486                 }
487         }
488
489         return 1;
490 }
491
492 int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, ModifierData *md, int mode)
493 {
494         if (scene->obedit) {
495                 BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied in editmode");
496                 return 0;
497         } else if (((ID*) ob->data)->us>1) {
498                 BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied to multi-user data");
499                 return 0;
500         }
501
502         if (md!=ob->modifiers.first)
503                 BKE_report(reports, RPT_INFO, "Applied modifier was not first, result may not be as expected.");
504
505         if (mode == MODIFIER_APPLY_SHAPE) {
506                 if (!modifier_apply_shape(reports, scene, ob, md))
507                         return 0;
508         } else {
509                 if (!modifier_apply_obdata(reports, scene, ob, md))
510                         return 0;
511         }
512
513         BLI_remlink(&ob->modifiers, md);
514         modifier_free(md);
515
516         return 1;
517 }
518
519 int ED_object_modifier_copy(ReportList *UNUSED(reports), Object *ob, ModifierData *md)
520 {
521         ModifierData *nmd;
522         
523         nmd = modifier_new(md->type);
524         modifier_copyData(md, nmd);
525         BLI_insertlink(&ob->modifiers, md, nmd);
526         modifier_unique_name(&ob->modifiers, nmd);
527
528         return 1;
529 }
530
531 /************************ add modifier operator *********************/
532
533 static int modifier_add_exec(bContext *C, wmOperator *op)
534 {
535         Main *bmain= CTX_data_main(C);
536         Scene *scene= CTX_data_scene(C);
537         Object *ob = ED_object_active_context(C);
538         int type= RNA_enum_get(op->ptr, "type");
539
540         if(!ED_object_modifier_add(op->reports, bmain, scene, ob, NULL, type))
541                 return OPERATOR_CANCELLED;
542
543         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
544         
545         return OPERATOR_FINISHED;
546 }
547
548 static EnumPropertyItem *modifier_add_itemf(bContext *C, PointerRNA *UNUSED(ptr), int *free)
549 {       
550         Object *ob= ED_object_active_context(C);
551         EnumPropertyItem *item= NULL, *md_item;
552         ModifierTypeInfo *mti;
553         int totitem= 0, a;
554         
555         if(!ob)
556                 return modifier_type_items;
557
558         for(a=0; modifier_type_items[a].identifier; a++) {
559                 md_item= &modifier_type_items[a];
560
561                 if(md_item->identifier[0]) {
562                         mti= modifierType_getInfo(md_item->value);
563
564                         if(mti->flags & eModifierTypeFlag_NoUserAdd)
565                                 continue;
566
567                         if(!((mti->flags & eModifierTypeFlag_AcceptsCVs) ||
568                            (ob->type==OB_MESH && (mti->flags & eModifierTypeFlag_AcceptsMesh))))
569                                 continue;
570                 }
571
572                 RNA_enum_item_add(&item, &totitem, md_item);
573         }
574
575         RNA_enum_item_end(&item, &totitem);
576         *free= 1;
577
578         return item;
579 }
580
581 void OBJECT_OT_modifier_add(wmOperatorType *ot)
582 {
583         PropertyRNA *prop;
584
585         /* identifiers */
586         ot->name= "Add Modifier";
587         ot->description = "Add a modifier to the active object";
588         ot->idname= "OBJECT_OT_modifier_add";
589         
590         /* api callbacks */
591         ot->invoke= WM_menu_invoke;
592         ot->exec= modifier_add_exec;
593         ot->poll= ED_operator_object_active_editable;
594         
595         /* flags */
596         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
597         
598         /* properties */
599         prop= RNA_def_enum(ot->srna, "type", modifier_type_items, eModifierType_Subsurf, "Type", "");
600         RNA_def_enum_funcs(prop, modifier_add_itemf);
601         ot->prop= prop;
602 }
603
604 /************************ generic functions for operators using mod names and data context *********************/
605
606 static int edit_modifier_poll_generic(bContext *C, StructRNA *rna_type, int obtype_flag)
607 {
608         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", rna_type);
609         Object *ob= (ptr.id.data)?ptr.id.data:ED_object_active_context(C);
610         
611         if (!ob || ob->id.lib) return 0;
612         if (obtype_flag && ((1<<ob->type) & obtype_flag)==0) return 0;
613         if (ptr.data && ((ID*)ptr.id.data)->lib) return 0;
614         
615         return 1;
616 }
617
618 static int edit_modifier_poll(bContext *C)
619 {
620         return edit_modifier_poll_generic(C, &RNA_Modifier, 0);
621 }
622
623 static void edit_modifier_properties(wmOperatorType *ot)
624 {
625         RNA_def_string(ot->srna, "modifier", "", 32, "Modifier", "Name of the modifier to edit");
626 }
627
628 static int edit_modifier_invoke_properties(bContext *C, wmOperator *op)
629 {
630         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
631         ModifierData *md;
632         
633         if (RNA_property_is_set(op->ptr, "modifier"))
634                 return 1;
635         
636         if (ptr.data) {
637                 md = ptr.data;
638                 RNA_string_set(op->ptr, "modifier", md->name);
639                 return 1;
640         }
641         
642         return 0;
643 }
644
645 static ModifierData *edit_modifier_property_get(wmOperator *op, Object *ob, int type)
646 {
647         char modifier_name[32];
648         ModifierData *md;
649         RNA_string_get(op->ptr, "modifier", modifier_name);
650         
651         md = modifiers_findByName(ob, modifier_name);
652         
653         if (md && type != 0 && md->type != type)
654                 md = NULL;
655
656         return md;
657 }
658
659 /************************ remove modifier operator *********************/
660
661 static int modifier_remove_exec(bContext *C, wmOperator *op)
662 {
663         Main *bmain= CTX_data_main(C);
664         Scene *scene= CTX_data_scene(C);
665         Object *ob = ED_object_active_context(C);
666         ModifierData *md = edit_modifier_property_get(op, ob, 0);
667         int mode_orig = ob->mode;
668         
669         if(!ob || !md || !ED_object_modifier_remove(op->reports, bmain, scene, ob, md))
670                 return OPERATOR_CANCELLED;
671
672         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
673
674         /* if cloth/softbody was removed, particle mode could be cleared */
675         if(mode_orig & OB_MODE_PARTICLE_EDIT)
676                 if((ob->mode & OB_MODE_PARTICLE_EDIT)==0)
677                         if(scene->basact && scene->basact->object==ob)
678                                 WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, NULL);
679         
680         return OPERATOR_FINISHED;
681 }
682
683 static int modifier_remove_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
684 {
685         if (edit_modifier_invoke_properties(C, op))
686                 return modifier_remove_exec(C, op);
687         else
688                 return OPERATOR_CANCELLED;
689 }
690
691 void OBJECT_OT_modifier_remove(wmOperatorType *ot)
692 {
693         ot->name= "Remove Modifier";
694         ot->description= "Remove a modifier from the active object";
695         ot->idname= "OBJECT_OT_modifier_remove";
696
697         ot->invoke= modifier_remove_invoke;
698         ot->exec= modifier_remove_exec;
699         ot->poll= edit_modifier_poll;
700         
701         /* flags */
702         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
703         edit_modifier_properties(ot);
704 }
705
706 /************************ move up modifier operator *********************/
707
708 static int modifier_move_up_exec(bContext *C, wmOperator *op)
709 {
710         Object *ob = ED_object_active_context(C);
711         ModifierData *md = edit_modifier_property_get(op, ob, 0);
712
713         if(!ob || !md || !ED_object_modifier_move_up(op->reports, ob, md))
714                 return OPERATOR_CANCELLED;
715
716         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
717         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
718         
719         return OPERATOR_FINISHED;
720 }
721
722 static int modifier_move_up_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
723 {
724         if (edit_modifier_invoke_properties(C, op))
725                 return modifier_move_up_exec(C, op);
726         else
727                 return OPERATOR_CANCELLED;
728 }
729
730 void OBJECT_OT_modifier_move_up(wmOperatorType *ot)
731 {
732         ot->name= "Move Up Modifier";
733         ot->description= "Move modifier up in the stack";
734         ot->idname= "OBJECT_OT_modifier_move_up";
735
736         ot->invoke= modifier_move_up_invoke;
737         ot->exec= modifier_move_up_exec;
738         ot->poll= edit_modifier_poll;
739         
740         /* flags */
741         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
742         edit_modifier_properties(ot);
743 }
744
745 /************************ move down modifier operator *********************/
746
747 static int modifier_move_down_exec(bContext *C, wmOperator *op)
748 {
749         Object *ob = ED_object_active_context(C);
750         ModifierData *md = edit_modifier_property_get(op, ob, 0);
751
752         if(!ob || !md || !ED_object_modifier_move_down(op->reports, ob, md))
753                 return OPERATOR_CANCELLED;
754
755         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
756         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
757         
758         return OPERATOR_FINISHED;
759 }
760
761 static int modifier_move_down_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
762 {
763         if (edit_modifier_invoke_properties(C, op))
764                 return modifier_move_down_exec(C, op);
765         else
766                 return OPERATOR_CANCELLED;
767 }
768
769 void OBJECT_OT_modifier_move_down(wmOperatorType *ot)
770 {
771         ot->name= "Move Down Modifier";
772         ot->description= "Move modifier down in the stack";
773         ot->idname= "OBJECT_OT_modifier_move_down";
774
775         ot->invoke= modifier_move_down_invoke;
776         ot->exec= modifier_move_down_exec;
777         ot->poll= edit_modifier_poll;
778         
779         /* flags */
780         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
781         edit_modifier_properties(ot);
782 }
783
784 /************************ apply modifier operator *********************/
785
786 static int modifier_apply_exec(bContext *C, wmOperator *op)
787 {
788         Scene *scene= CTX_data_scene(C);
789         Object *ob = ED_object_active_context(C);
790         ModifierData *md = edit_modifier_property_get(op, ob, 0);
791         int apply_as= RNA_enum_get(op->ptr, "apply_as");
792         
793         if(!ob || !md || !ED_object_modifier_apply(op->reports, scene, ob, md, apply_as)) {
794                 return OPERATOR_CANCELLED;
795         }
796
797         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
798         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
799         
800         return OPERATOR_FINISHED;
801 }
802
803 static int modifier_apply_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
804 {
805         if (edit_modifier_invoke_properties(C, op))
806                 return modifier_apply_exec(C, op);
807         else
808                 return OPERATOR_CANCELLED;
809 }
810
811 static EnumPropertyItem modifier_apply_as_items[] = {
812         {MODIFIER_APPLY_DATA, "DATA", 0, "Object Data", "Apply modifier to the object's data"},
813         {MODIFIER_APPLY_SHAPE, "SHAPE", 0, "New Shape", "Apply deform-only modifier to a new shape on this object"},
814         {0, NULL, 0, NULL, NULL}};
815
816 void OBJECT_OT_modifier_apply(wmOperatorType *ot)
817 {
818         ot->name= "Apply Modifier";
819         ot->description= "Apply modifier and remove from the stack";
820         ot->idname= "OBJECT_OT_modifier_apply";
821
822         ot->invoke= modifier_apply_invoke;
823         ot->exec= modifier_apply_exec;
824         ot->poll= edit_modifier_poll;
825         
826         /* flags */
827         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
828         
829         RNA_def_enum(ot->srna, "apply_as", modifier_apply_as_items, MODIFIER_APPLY_DATA, "Apply as", "How to apply the modifier to the geometry");
830         edit_modifier_properties(ot);
831 }
832
833 /************************ convert modifier operator *********************/
834
835 static int modifier_convert_exec(bContext *C, wmOperator *op)
836 {
837         Main *bmain= CTX_data_main(C);
838         Scene *scene= CTX_data_scene(C);
839         Object *ob = ED_object_active_context(C);
840         ModifierData *md = edit_modifier_property_get(op, ob, 0);
841         
842         if(!ob || !md || !ED_object_modifier_convert(op->reports, bmain, scene, ob, md))
843                 return OPERATOR_CANCELLED;
844
845         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
846         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
847         
848         return OPERATOR_FINISHED;
849 }
850
851 static int modifier_convert_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
852 {
853         if (edit_modifier_invoke_properties(C, op))
854                 return modifier_convert_exec(C, op);
855         else
856                 return OPERATOR_CANCELLED;
857 }
858
859 void OBJECT_OT_modifier_convert(wmOperatorType *ot)
860 {
861         ot->name= "Convert Modifier";
862         ot->description= "Convert particles to a mesh object";
863         ot->idname= "OBJECT_OT_modifier_convert";
864
865         ot->invoke= modifier_convert_invoke;
866         ot->exec= modifier_convert_exec;
867         ot->poll= edit_modifier_poll;
868         
869         /* flags */
870         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
871         edit_modifier_properties(ot);
872 }
873
874 /************************ copy modifier operator *********************/
875
876 static int modifier_copy_exec(bContext *C, wmOperator *op)
877 {
878         Object *ob = ED_object_active_context(C);
879         ModifierData *md = edit_modifier_property_get(op, ob, 0);
880
881         if(!ob || !md || !ED_object_modifier_copy(op->reports, ob, md))
882                 return OPERATOR_CANCELLED;
883
884         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
885         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
886         
887         return OPERATOR_FINISHED;
888 }
889
890 static int modifier_copy_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
891 {
892         if (edit_modifier_invoke_properties(C, op))
893                 return modifier_copy_exec(C, op);
894         else
895                 return OPERATOR_CANCELLED;
896 }
897
898 void OBJECT_OT_modifier_copy(wmOperatorType *ot)
899 {
900         ot->name= "Copy Modifier";
901         ot->description= "Duplicate modifier at the same position in the stack";
902         ot->idname= "OBJECT_OT_modifier_copy";
903
904         ot->invoke= modifier_copy_invoke;
905         ot->exec= modifier_copy_exec;
906         ot->poll= edit_modifier_poll;
907         
908         /* flags */
909         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
910         edit_modifier_properties(ot);
911 }
912
913 /************* multires delete higher levels operator ****************/
914
915 static int multires_poll(bContext *C)
916 {
917         return edit_modifier_poll_generic(C, &RNA_MultiresModifier, (1<<OB_MESH));
918 }
919
920 static int multires_higher_levels_delete_exec(bContext *C, wmOperator *op)
921 {
922         Object *ob = ED_object_active_context(C);
923         MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
924         
925         if (!mmd)
926                 return OPERATOR_CANCELLED;
927         
928         multiresModifier_del_levels(mmd, ob, 1);
929         
930         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
931         
932         return OPERATOR_FINISHED;
933 }
934
935 static int multires_higher_levels_delete_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
936 {
937         if (edit_modifier_invoke_properties(C, op))
938                 return multires_higher_levels_delete_exec(C, op);
939         else
940                 return OPERATOR_CANCELLED;
941 }
942
943 void OBJECT_OT_multires_higher_levels_delete(wmOperatorType *ot)
944 {
945         ot->name= "Delete Higher Levels";
946         ot->idname= "OBJECT_OT_multires_higher_levels_delete";
947
948         ot->poll= multires_poll;
949         ot->invoke= multires_higher_levels_delete_invoke;
950         ot->exec= multires_higher_levels_delete_exec;
951         
952         /* flags */
953         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
954         edit_modifier_properties(ot);
955 }
956
957 /****************** multires subdivide operator *********************/
958
959 static int multires_subdivide_exec(bContext *C, wmOperator *op)
960 {
961         Object *ob = ED_object_active_context(C);
962         MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
963         
964         if (!mmd)
965                 return OPERATOR_CANCELLED;
966         
967         multiresModifier_subdivide(mmd, ob, 0, mmd->simple);
968
969         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
970         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
971         
972         return OPERATOR_FINISHED;
973 }
974
975 static int multires_subdivide_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
976 {
977         if (edit_modifier_invoke_properties(C, op))
978                 return multires_subdivide_exec(C, op);
979         else
980                 return OPERATOR_CANCELLED;
981 }
982
983 void OBJECT_OT_multires_subdivide(wmOperatorType *ot)
984 {
985         ot->name= "Multires Subdivide";
986         ot->description= "Add a new level of subdivision";
987         ot->idname= "OBJECT_OT_multires_subdivide";
988
989         ot->poll= multires_poll;
990         ot->invoke= multires_subdivide_invoke;
991         ot->exec= multires_subdivide_exec;
992         
993         /* flags */
994         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
995         edit_modifier_properties(ot);
996 }
997
998 /****************** multires reshape operator *********************/
999
1000 static int multires_reshape_exec(bContext *C, wmOperator *op)
1001 {
1002         Object *ob= ED_object_active_context(C), *secondob= NULL;
1003         Scene *scene= CTX_data_scene(C);
1004         MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
1005
1006         if (!mmd)
1007                 return OPERATOR_CANCELLED;
1008         
1009         CTX_DATA_BEGIN(C, Object*, selob, selected_editable_objects) {
1010                 if(selob->type == OB_MESH && selob != ob) {
1011                         secondob= selob;
1012                         break;
1013                 }
1014         }
1015         CTX_DATA_END;
1016
1017         if(!secondob) {
1018                 BKE_report(op->reports, RPT_ERROR, "Second selected mesh object require to copy shape from.");
1019                 return OPERATOR_CANCELLED;
1020         }
1021
1022         if(!multiresModifier_reshape(scene, mmd, ob, secondob)) {
1023                 BKE_report(op->reports, RPT_ERROR, "Objects do not have the same number of vertices.");
1024                 return OPERATOR_CANCELLED;
1025         }
1026
1027         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
1028         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1029
1030         return OPERATOR_FINISHED;
1031 }
1032
1033 static int multires_reshape_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1034 {
1035         if (edit_modifier_invoke_properties(C, op))
1036                 return multires_reshape_exec(C, op);
1037         else
1038                 return OPERATOR_CANCELLED;
1039 }
1040
1041 void OBJECT_OT_multires_reshape(wmOperatorType *ot)
1042 {
1043         ot->name= "Multires Reshape";
1044         ot->description= "Copy vertex coordinates from other object";
1045         ot->idname= "OBJECT_OT_multires_reshape";
1046
1047         ot->poll= multires_poll;
1048         ot->invoke= multires_reshape_invoke;
1049         ot->exec= multires_reshape_exec;
1050         
1051         /* flags */
1052         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1053         edit_modifier_properties(ot);
1054 }
1055
1056 /****************** multires save external operator *********************/
1057
1058 static int multires_external_save_exec(bContext *C, wmOperator *op)
1059 {
1060         Object *ob = ED_object_active_context(C);
1061         Mesh *me= (ob)? ob->data: op->customdata;
1062         char path[FILE_MAX];
1063         int relative= RNA_boolean_get(op->ptr, "relative_path");
1064
1065         if(!me)
1066                 return OPERATOR_CANCELLED;
1067
1068         if(CustomData_external_test(&me->fdata, CD_MDISPS))
1069                 return OPERATOR_CANCELLED;
1070         
1071         RNA_string_get(op->ptr, "filepath", path);
1072
1073         if(relative)
1074                 BLI_path_rel(path, G.main->name);
1075
1076         CustomData_external_add(&me->fdata, &me->id, CD_MDISPS, me->totface, path);
1077         CustomData_external_write(&me->fdata, &me->id, CD_MASK_MESH, me->totface, 0);
1078         
1079         return OPERATOR_FINISHED;
1080 }
1081
1082 static int multires_external_save_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1083 {
1084         Object *ob = ED_object_active_context(C);
1085         MultiresModifierData *mmd;
1086         Mesh *me= ob->data;
1087         char path[FILE_MAX];
1088
1089         if (!edit_modifier_invoke_properties(C, op))
1090                 return OPERATOR_CANCELLED;
1091         
1092         mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
1093         
1094         if (!mmd)
1095                 return OPERATOR_CANCELLED;
1096         
1097         if(CustomData_external_test(&me->fdata, CD_MDISPS))
1098                 return OPERATOR_CANCELLED;
1099
1100         if(!RNA_property_is_set(op->ptr, "relative_path"))
1101                 RNA_boolean_set(op->ptr, "relative_path", U.flag & USER_RELPATHS);
1102
1103         if(RNA_property_is_set(op->ptr, "filepath"))
1104                 return multires_external_save_exec(C, op);
1105         
1106         op->customdata= me;
1107
1108         BLI_snprintf(path, sizeof(path), "//%s.btx", me->id.name+2);
1109         RNA_string_set(op->ptr, "filepath", path);
1110         
1111         WM_event_add_fileselect(C, op);
1112
1113         return OPERATOR_RUNNING_MODAL;
1114 }
1115
1116 void OBJECT_OT_multires_external_save(wmOperatorType *ot)
1117 {
1118         ot->name= "Multires Save External";
1119         ot->description= "Save displacements to an external file";
1120         ot->idname= "OBJECT_OT_multires_external_save";
1121
1122         // XXX modifier no longer in context after file browser .. ot->poll= multires_poll;
1123         ot->exec= multires_external_save_exec;
1124         ot->invoke= multires_external_save_invoke;
1125         ot->poll= multires_poll;
1126         
1127         /* flags */
1128         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1129
1130         WM_operator_properties_filesel(ot, FOLDERFILE|BTXFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH);
1131         edit_modifier_properties(ot);
1132 }
1133
1134 /****************** multires pack operator *********************/
1135
1136 static int multires_external_pack_exec(bContext *C, wmOperator *UNUSED(op))
1137 {
1138         Object *ob = ED_object_active_context(C);
1139         Mesh *me= ob->data;
1140
1141         if(!CustomData_external_test(&me->fdata, CD_MDISPS))
1142                 return OPERATOR_CANCELLED;
1143
1144         // XXX don't remove..
1145         CustomData_external_remove(&me->fdata, &me->id, CD_MDISPS, me->totface);
1146         
1147         return OPERATOR_FINISHED;
1148 }
1149
1150 void OBJECT_OT_multires_external_pack(wmOperatorType *ot)
1151 {
1152         ot->name= "Multires Pack External";
1153         ot->description= "Pack displacements from an external file";
1154         ot->idname= "OBJECT_OT_multires_external_pack";
1155
1156         ot->poll= multires_poll;
1157         ot->exec= multires_external_pack_exec;
1158         
1159         /* flags */
1160         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1161 }
1162
1163 /************************ mdef bind operator *********************/
1164
1165 static int meshdeform_poll(bContext *C)
1166 {
1167         return edit_modifier_poll_generic(C, &RNA_MeshDeformModifier, (1<<OB_MESH));
1168 }
1169
1170 static int meshdeform_bind_exec(bContext *C, wmOperator *op)
1171 {
1172         Scene *scene= CTX_data_scene(C);
1173         Object *ob = ED_object_active_context(C);
1174         MeshDeformModifierData *mmd = (MeshDeformModifierData *)edit_modifier_property_get(op, ob, eModifierType_MeshDeform);
1175         
1176         if (!mmd)
1177                 return OPERATOR_CANCELLED;
1178
1179         if(mmd->bindcagecos) {
1180                 if(mmd->bindweights) MEM_freeN(mmd->bindweights);
1181                 if(mmd->bindcagecos) MEM_freeN(mmd->bindcagecos);
1182                 if(mmd->dyngrid) MEM_freeN(mmd->dyngrid);
1183                 if(mmd->dyninfluences) MEM_freeN(mmd->dyninfluences);
1184                 if(mmd->dynverts) MEM_freeN(mmd->dynverts);
1185                 mmd->bindweights= NULL;
1186                 mmd->bindcagecos= NULL;
1187                 mmd->dyngrid= NULL;
1188                 mmd->dyninfluences= NULL;
1189                 mmd->dynverts= NULL;
1190                 mmd->totvert= 0;
1191                 mmd->totcagevert= 0;
1192                 mmd->totinfluence= 0;
1193                 
1194                 DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
1195                 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1196         }
1197         else {
1198                 DerivedMesh *dm;
1199                 int mode= mmd->modifier.mode;
1200
1201                 /* force modifier to run, it will call binding routine */
1202                 mmd->bindfunc= mesh_deform_bind;
1203                 mmd->modifier.mode |= eModifierMode_Realtime;
1204
1205                 if(ob->type == OB_MESH) {
1206                         dm= mesh_create_derived_view(scene, ob, 0);
1207                         dm->release(dm);
1208                 }
1209                 else if(ob->type == OB_LATTICE) {
1210                         lattice_calc_modifiers(scene, ob);
1211                 }
1212                 else if(ob->type==OB_MBALL) {
1213                         makeDispListMBall(scene, ob);
1214                 }
1215                 else if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
1216                         makeDispListCurveTypes(scene, ob, 0);
1217                 }
1218
1219                 mmd->bindfunc= NULL;
1220                 mmd->modifier.mode= mode;
1221         }
1222         
1223         return OPERATOR_FINISHED;
1224 }
1225
1226 static int meshdeform_bind_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1227 {
1228         if (edit_modifier_invoke_properties(C, op))
1229                 return meshdeform_bind_exec(C, op);
1230         else 
1231                 return OPERATOR_CANCELLED;
1232 }
1233
1234 void OBJECT_OT_meshdeform_bind(wmOperatorType *ot)
1235 {
1236         /* identifiers */
1237         ot->name= "Mesh Deform Bind";
1238         ot->description = "Bind mesh to cage in mesh deform modifier";
1239         ot->idname= "OBJECT_OT_meshdeform_bind";
1240         
1241         /* api callbacks */
1242         ot->poll= meshdeform_poll;
1243         ot->invoke= meshdeform_bind_invoke;
1244         ot->exec= meshdeform_bind_exec;
1245         
1246         /* flags */
1247         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1248         edit_modifier_properties(ot);
1249 }
1250
1251 /****************** explode refresh operator *********************/
1252
1253 static int explode_poll(bContext *C)
1254 {
1255         return edit_modifier_poll_generic(C, &RNA_ExplodeModifier, 0);
1256 }
1257
1258 static int explode_refresh_exec(bContext *C, wmOperator *op)
1259 {
1260         Object *ob = ED_object_active_context(C);
1261         ExplodeModifierData *emd = (ExplodeModifierData *)edit_modifier_property_get(op, ob, eModifierType_Explode);
1262         
1263         if (!emd)
1264                 return OPERATOR_CANCELLED;
1265
1266         emd->flag |= eExplodeFlag_CalcFaces;
1267
1268         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
1269         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1270         
1271         return OPERATOR_FINISHED;
1272 }
1273
1274 static int explode_refresh_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1275 {
1276         if (edit_modifier_invoke_properties(C, op))
1277                 return explode_refresh_exec(C, op);
1278         else
1279                 return OPERATOR_CANCELLED;
1280 }
1281
1282
1283 void OBJECT_OT_explode_refresh(wmOperatorType *ot)
1284 {
1285         ot->name= "Explode Refresh";
1286         ot->description= "Refresh data in the Explode modifier";
1287         ot->idname= "OBJECT_OT_explode_refresh";
1288
1289         ot->poll= explode_poll;
1290         ot->invoke= explode_refresh_invoke;
1291         ot->exec= explode_refresh_exec;
1292         
1293         /* flags */
1294         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1295         edit_modifier_properties(ot);
1296 }
1297