Spelling Cleanup
[blender.git] / source / blender / editors / object / object_modifier.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * Contributor(s): Blender Foundation, 2009
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26 /** \file blender/editors/object/object_modifier.c
27  *  \ingroup edobj
28  */
29
30
31 #include <math.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34
35 #include "MEM_guardedalloc.h"
36
37 #include "DNA_anim_types.h"
38 #include "DNA_curve_types.h"
39 #include "DNA_key_types.h"
40 #include "DNA_mesh_types.h"
41 #include "DNA_meshdata_types.h"
42 #include "DNA_object_force.h"
43 #include "DNA_scene_types.h"
44
45 #include "BLI_math.h"
46 #include "BLI_listbase.h"
47 #include "BLI_string.h"
48 #include "BLI_path_util.h"
49 #include "BLI_utildefines.h"
50
51 #include "BKE_animsys.h"
52 #include "BKE_curve.h"
53 #include "BKE_context.h"
54 #include "BKE_depsgraph.h"
55 #include "BKE_displist.h"
56 #include "BKE_DerivedMesh.h"
57 #include "BKE_effect.h"
58 #include "BKE_global.h"
59 #include "BKE_key.h"
60 #include "BKE_lattice.h"
61 #include "BKE_main.h"
62 #include "BKE_mesh.h"
63 #include "BKE_modifier.h"
64 #include "BKE_multires.h"
65 #include "BKE_report.h"
66 #include "BKE_object.h"
67 #include "BKE_ocean.h"
68 #include "BKE_particle.h"
69 #include "BKE_softbody.h"
70 #include "BKE_tessmesh.h"
71
72 #include "RNA_access.h"
73 #include "RNA_define.h"
74 #include "RNA_enum_types.h"
75
76 #include "ED_armature.h"
77 #include "ED_object.h"
78 #include "ED_screen.h"
79 #include "ED_mesh.h"
80
81 #include "WM_api.h"
82 #include "WM_types.h"
83
84 #include "object_intern.h"
85
86 /******************************** API ****************************/
87
88 ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *scene, Object *ob, const char *name, int type)
89 {
90         ModifierData *md=NULL, *new_md=NULL;
91         ModifierTypeInfo *mti = modifierType_getInfo(type);
92         
93         /* only geometry objects should be able to get modifiers [#25291] */
94         if(!ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) {
95                 BKE_reportf(reports, RPT_WARNING, "Modifiers cannot be added to Object '%s'", ob->id.name+2);
96                 return NULL;
97         }
98         
99         if(mti->flags&eModifierTypeFlag_Single) {
100                 if(modifiers_findByType(ob, type)) {
101                         BKE_report(reports, RPT_WARNING, "Only one modifier of this type allowed");
102                         return NULL;
103                 }
104         }
105         
106         if(type == eModifierType_ParticleSystem) {
107                 /* don't need to worry about the new modifier's name, since that is set to the number
108                  * of particle systems which shouldn't have too many duplicates 
109                  */
110                 new_md = object_add_particle_system(scene, ob, name);
111         }
112         else {
113                 /* get new modifier data to add */
114                 new_md= modifier_new(type);
115                 
116                 if(mti->flags&eModifierTypeFlag_RequiresOriginalData) {
117                         md = ob->modifiers.first;
118                         
119                         while(md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform)
120                                 md = md->next;
121                         
122                         BLI_insertlinkbefore(&ob->modifiers, md, new_md);
123                 }
124                 else
125                         BLI_addtail(&ob->modifiers, new_md);
126
127                 if(name)
128                         BLI_strncpy(new_md->name, name, sizeof(new_md->name));
129
130                 /* make sure modifier data has unique name */
131
132                 modifier_unique_name(&ob->modifiers, new_md);
133                 
134                 /* special cases */
135                 if(type == eModifierType_Softbody) {
136                         if(!ob->soft) {
137                                 ob->soft= sbNew(scene);
138                                 ob->softflag |= OB_SB_GOAL|OB_SB_EDGES;
139                         }
140                 }
141                 else if(type == eModifierType_Collision) {
142                         if(!ob->pd)
143                                 ob->pd= object_add_collision_fields(0);
144                         
145                         ob->pd->deflect= 1;
146                         DAG_scene_sort(bmain, scene);
147                 }
148                 else if(type == eModifierType_Surface)
149                         DAG_scene_sort(bmain, scene);
150                 else if(type == eModifierType_Multires)
151                         /* set totlvl from existing MDISPS layer if object already had it */
152                         multiresModifier_set_levels_from_disps((MultiresModifierData *)new_md, ob);
153         }
154
155         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
156
157         return new_md;
158 }
159
160 static int object_modifier_remove(Object *ob, ModifierData *md, int *sort_depsgraph)
161 {
162         ModifierData *obmd;
163
164         /* It seems on rapid delete it is possible to
165          * get called twice on same modifier, so make
166          * sure it is in list. */
167         for(obmd=ob->modifiers.first; obmd; obmd=obmd->next)
168                 if(obmd==md)
169                         break;
170
171         if(!obmd)
172                 return 0;
173
174         /* special cases */
175         if(md->type == eModifierType_ParticleSystem) {
176                 ParticleSystemModifierData *psmd=(ParticleSystemModifierData*)md;
177
178                 BLI_remlink(&ob->particlesystem, psmd->psys);
179                 psys_free(ob, psmd->psys);
180                 psmd->psys= NULL;
181         }
182         else if(md->type == eModifierType_Softbody) {
183                 if(ob->soft) {
184                         sbFree(ob->soft);
185                         ob->soft= NULL;
186                         ob->softflag= 0;
187                 }
188         }
189         else if(md->type == eModifierType_Collision) {
190                 if(ob->pd)
191                         ob->pd->deflect= 0;
192
193                 *sort_depsgraph = 1;
194         }
195         else if(md->type == eModifierType_Surface) {
196                 if(ob->pd && ob->pd->shape == PFIELD_SHAPE_SURFACE)
197                         ob->pd->shape = PFIELD_SHAPE_PLANE;
198
199                 *sort_depsgraph = 1;
200         }
201         else if(md->type == eModifierType_Smoke) {
202                 ob->dt = OB_TEXTURE;
203         }
204         else if(md->type == eModifierType_Multires) {
205                 int ok= 1;
206                 Mesh *me= ob->data;
207                 ModifierData *tmpmd;
208
209                 /* ensure MDISPS CustomData layer is't used by another multires modifiers */
210                 for(tmpmd= ob->modifiers.first; tmpmd; tmpmd= tmpmd->next)
211                         if(tmpmd!=md && tmpmd->type == eModifierType_Multires) {
212                                 ok= 0;
213                                 break;
214                         }
215
216                 if(ok) {
217                         if(me->edit_btmesh) {
218                                 BMEditMesh *em= me->edit_btmesh;
219                                 /* CustomData_external_remove is used here only to mark layer as non-external
220                                    for further free-ing, so zero element count looks safer than em->totface */
221                                 CustomData_external_remove(&em->bm->ldata, &me->id, CD_MDISPS, 0);
222                                 BM_data_layer_free(em->bm, &em->bm->ldata, CD_MDISPS);
223                         } else {
224                                 CustomData_external_remove(&me->ldata, &me->id, CD_MDISPS, me->totloop);
225                                 CustomData_free_layer_active(&me->ldata, CD_MDISPS, me->totloop);
226                         }
227                 }
228         }
229
230         if(ELEM(md->type, eModifierType_Softbody, eModifierType_Cloth) &&
231                 ob->particlesystem.first == NULL) {
232                 ob->mode &= ~OB_MODE_PARTICLE_EDIT;
233         }
234
235         BLI_remlink(&ob->modifiers, md);
236         modifier_free(md);
237
238         return 1;
239 }
240
241 int ED_object_modifier_remove(ReportList *reports, Main *bmain, Scene *scene, Object *ob, ModifierData *md)
242 {
243         int sort_depsgraph = 0;
244         int ok;
245
246         ok= object_modifier_remove(ob, md, &sort_depsgraph);
247
248         if(!ok) {
249                 BKE_reportf(reports, RPT_ERROR, "Modifier '%s' not in object '%s'", ob->id.name, md->name);
250                 return 0;
251         }
252
253         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
254
255         /* sorting has to be done after the update so that dynamic systems can react properly */
256         if(sort_depsgraph)
257                 DAG_scene_sort(bmain, scene);
258
259         return 1;
260 }
261
262 void ED_object_modifier_clear(Main *bmain, Scene *scene, Object *ob)
263 {
264         ModifierData *md = ob->modifiers.first;
265         int sort_depsgraph = 0;
266
267         if(!md)
268                 return;
269
270         while(md) {
271                 ModifierData *next_md;
272
273                 next_md= md->next;
274
275                 object_modifier_remove(ob, md, &sort_depsgraph);
276
277                 md= next_md;
278         }
279
280         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
281
282         /* sorting has to be done after the update so that dynamic systems can react properly */
283         if(sort_depsgraph)
284                 DAG_scene_sort(bmain, scene);
285 }
286
287 int ED_object_modifier_move_up(ReportList *reports, Object *ob, ModifierData *md)
288 {
289         if(md->prev) {
290                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
291
292                 if(mti->type!=eModifierTypeType_OnlyDeform) {
293                         ModifierTypeInfo *nmti = modifierType_getInfo(md->prev->type);
294
295                         if(nmti->flags&eModifierTypeFlag_RequiresOriginalData) {
296                                 BKE_report(reports, RPT_WARNING, "Cannot move above a modifier requiring original data");
297                                 return 0;
298                         }
299                 }
300
301                 BLI_remlink(&ob->modifiers, md);
302                 BLI_insertlink(&ob->modifiers, md->prev->prev, md);
303         }
304
305         return 1;
306 }
307
308 int ED_object_modifier_move_down(ReportList *reports, Object *ob, ModifierData *md)
309 {
310         if(md->next) {
311                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
312
313                 if(mti->flags&eModifierTypeFlag_RequiresOriginalData) {
314                         ModifierTypeInfo *nmti = modifierType_getInfo(md->next->type);
315
316                         if(nmti->type!=eModifierTypeType_OnlyDeform) {
317                                 BKE_report(reports, RPT_WARNING, "Cannot move beyond a non-deforming modifier");
318                                 return 0;
319                         }
320                 }
321
322                 BLI_remlink(&ob->modifiers, md);
323                 BLI_insertlink(&ob->modifiers, md->next, md);
324         }
325
326         return 1;
327 }
328
329 int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene *scene, Object *ob, ModifierData *md)
330 {
331         Object *obn;
332         ParticleSystem *psys;
333         ParticleCacheKey *key, **cache;
334         ParticleSettings *part;
335         Mesh *me;
336         MVert *mvert;
337         MEdge *medge;
338         int a, k, kmax;
339         int totvert=0, totedge=0, cvert=0;
340         int totpart=0, totchild=0;
341
342         if(md->type != eModifierType_ParticleSystem) return 0;
343         if(ob && ob->mode & OB_MODE_PARTICLE_EDIT) return 0;
344
345         psys=((ParticleSystemModifierData *)md)->psys;
346         part= psys->part;
347
348         if(part->ren_as != PART_DRAW_PATH || psys->pathcache == NULL)
349                 return 0;
350
351         totpart= psys->totcached;
352         totchild= psys->totchildcache;
353
354         if(totchild && (part->draw&PART_DRAW_PARENT)==0)
355                 totpart= 0;
356
357         /* count */
358         cache= psys->pathcache;
359         for(a=0; a<totpart; a++) {
360                 key= cache[a];
361
362                 if(key->steps > 0) {
363                         totvert+= key->steps+1;
364                         totedge+= key->steps;
365                 }
366         }
367
368         cache= psys->childcache;
369         for(a=0; a<totchild; a++) {
370                 key= cache[a];
371
372                 if(key->steps > 0) {
373                         totvert+= key->steps+1;
374                         totedge+= key->steps;
375                 }
376         }
377
378         if(totvert==0) return 0;
379
380         /* add new mesh */
381         obn= add_object(scene, OB_MESH);
382         me= obn->data;
383         
384         me->totvert= totvert;
385         me->totedge= totedge;
386         
387         me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
388         me->medge= CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
389         me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, 0);
390         
391         mvert= me->mvert;
392         medge= me->medge;
393
394         /* copy coordinates */
395         cache= psys->pathcache;
396         for(a=0; a<totpart; a++) {
397                 key= cache[a];
398                 kmax= key->steps;
399                 for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
400                         copy_v3_v3(mvert->co,key->co);
401                         if(k) {
402                                 medge->v1= cvert-1;
403                                 medge->v2= cvert;
404                                 medge->flag= ME_EDGEDRAW|ME_EDGERENDER|ME_LOOSEEDGE;
405                                 medge++;
406                         }
407                         else {
408                                 /* cheap trick to select the roots */
409                                 mvert->flag |= SELECT;
410                         }
411                 }
412         }
413
414         cache=psys->childcache;
415         for(a=0; a<totchild; a++) {
416                 key=cache[a];
417                 kmax=key->steps;
418                 for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
419                         copy_v3_v3(mvert->co,key->co);
420                         if(k) {
421                                 medge->v1=cvert-1;
422                                 medge->v2=cvert;
423                                 medge->flag= ME_EDGEDRAW|ME_EDGERENDER|ME_LOOSEEDGE;
424                                 medge++;
425                         }
426                         else {
427                                 /* cheap trick to select the roots */
428                                 mvert->flag |= SELECT;
429                         }
430                 }
431         }
432
433         DAG_scene_sort(bmain, scene);
434
435         return 1;
436 }
437
438 static int modifier_apply_shape(ReportList *reports, Scene *scene, Object *ob, ModifierData *md)
439 {
440         ModifierTypeInfo *mti= modifierType_getInfo(md->type);
441
442         md->scene= scene;
443
444         if (mti->isDisabled && mti->isDisabled(md, 0)) {
445                 BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
446                 return 0;
447         }
448
449         /*
450           It should be ridiculously easy to extract the original verts that we want
451           and form the shape data.  We can probably use the CD KEYINDEX layer (or
452           whatever I ended up calling it, too tired to check now), though this would
453           by necassity have to make some potentially ugly assumptions about the order
454           of the mesh data :-/  you can probably assume in 99% of cases that the first
455           element of a given index is the original, and any subsequent duplicates are
456           copies/interpolates, but that's an assumption that would need to be tested
457           and then predominantly stated in comments in a half dozen headers.
458         */
459
460         if (ob->type==OB_MESH) {
461                 DerivedMesh *dm;
462                 Mesh *me= ob->data;
463                 Key *key=me->key;
464                 KeyBlock *kb;
465                 
466                 if(!modifier_sameTopology(md) || mti->type == eModifierTypeType_NonGeometrical) {
467                         BKE_report(reports, RPT_ERROR, "Only deforming modifiers can be applied to Shapes");
468                         return 0;
469                 }
470                 
471                 dm = mesh_create_derived_for_modifier(scene, ob, md, 0);
472                 if (!dm) {
473                         BKE_report(reports, RPT_ERROR, "Modifier is disabled or returned error, skipping apply");
474                         return 0;
475                 }
476                 
477                 if(key == NULL) {
478                         key= me->key= add_key((ID *)me);
479                         key->type= KEY_RELATIVE;
480                         /* if that was the first key block added, then it was the basis.
481                          * Initialize it with the mesh, and add another for the modifier */
482                         kb= add_keyblock(key, NULL);
483                         mesh_to_key(me, kb);
484                 }
485
486                 kb= add_keyblock(key, md->name);
487                 DM_to_meshkey(dm, me, kb);
488                 
489                 dm->release(dm);
490         }
491         else {
492                 BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type");
493                 return 0;
494         }
495         return 1;
496 }
497
498 static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob, ModifierData *md)
499 {
500         ModifierTypeInfo *mti= modifierType_getInfo(md->type);
501
502         md->scene= scene;
503
504         if (mti->isDisabled && mti->isDisabled(md, 0)) {
505                 BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
506                 return 0;
507         }
508
509         if (ob->type==OB_MESH) {
510                 DerivedMesh *dm;
511                 Mesh *me = ob->data;
512                 MultiresModifierData *mmd= find_multires_modifier_before(scene, md);
513
514                 if(me->key && mti->type != eModifierTypeType_NonGeometrical) {
515                         BKE_report(reports, RPT_ERROR, "Modifier cannot be applied to Mesh with Shape Keys");
516                         return 0;
517                 }
518
519                 /* Multires: ensure that recent sculpting is applied */
520                 if(md->type == eModifierType_Multires)
521                         multires_force_update(ob);
522
523                 if (mmd && mmd->totlvl && mti->type==eModifierTypeType_OnlyDeform) {
524                         if(!multiresModifier_reshapeFromDeformMod (scene, mmd, ob, md)) {
525                                 BKE_report(reports, RPT_ERROR, "Multires modifier returned error, skipping apply");
526                                 return 0;
527                         }
528                 } else {
529                         dm = mesh_create_derived_for_modifier(scene, ob, md, 1);
530                         if (!dm) {
531                                 BKE_report(reports, RPT_ERROR, "Modifier returned error, skipping apply");
532                                 return 0;
533                         }
534
535                         DM_to_mesh(dm, me, ob);
536
537                         dm->release(dm);
538
539                         if(md->type == eModifierType_Multires) {
540                                 CustomData_external_remove(&me->ldata, &me->id, CD_MDISPS, me->totloop);
541                                 CustomData_free_layer_active(&me->ldata, CD_MDISPS, me->totloop);
542                         }
543                 }
544         }
545         else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
546                 Curve *cu;
547                 int numVerts;
548                 float (*vertexCos)[3];
549
550                 if (ELEM(mti->type, eModifierTypeType_Constructive, eModifierTypeType_Nonconstructive)) {
551                         BKE_report(reports, RPT_ERROR, "Cannot apply constructive modifiers on curve");
552                         return 0;
553                 }
554
555                 cu = ob->data;
556                 BKE_report(reports, RPT_INFO, "Applied modifier only changed CV points, not tesselated/bevel vertices");
557
558                 vertexCos = curve_getVertexCos(cu, &cu->nurb, &numVerts);
559                 mti->deformVerts(md, ob, NULL, vertexCos, numVerts, 0, 0);
560                 curve_applyVertexCos(cu, &cu->nurb, vertexCos);
561
562                 MEM_freeN(vertexCos);
563
564                 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
565         }
566         else {
567                 BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type");
568                 return 0;
569         }
570
571         /* lattice modifier can be applied to particle system too */
572         if(ob->particlesystem.first) {
573
574                 ParticleSystem *psys = ob->particlesystem.first;
575
576                 for(; psys; psys=psys->next) {
577                         
578                         if(psys->part->type != PART_HAIR)
579                                 continue;
580
581                         psys_apply_hair_lattice(scene, ob, psys);
582                 }
583         }
584
585         return 1;
586 }
587
588 int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, ModifierData *md, int mode)
589 {
590         int prev_mode;
591
592         if (scene->obedit) {
593                 BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied in editmode");
594                 return 0;
595         } else if (((ID*) ob->data)->us>1) {
596                 BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied to multi-user data");
597                 return 0;
598         }
599
600         if (md!=ob->modifiers.first)
601                 BKE_report(reports, RPT_INFO, "Applied modifier was not first, result may not be as expected");
602
603         /* allow apply of a not-realtime modifier, by first re-enabling realtime. */
604         prev_mode= md->mode;
605         md->mode |= eModifierMode_Realtime;
606
607         if (mode == MODIFIER_APPLY_SHAPE) {
608                 if (!modifier_apply_shape(reports, scene, ob, md)) {
609                         md->mode= prev_mode;
610                         return 0;
611                 }
612         } else {
613                 if (!modifier_apply_obdata(reports, scene, ob, md)) {
614                         md->mode= prev_mode;
615                         return 0;
616                 }
617         }
618
619         BLI_remlink(&ob->modifiers, md);
620         modifier_free(md);
621
622         return 1;
623 }
624
625 int ED_object_modifier_copy(ReportList *UNUSED(reports), Object *ob, ModifierData *md)
626 {
627         ModifierData *nmd;
628         
629         nmd = modifier_new(md->type);
630         modifier_copyData(md, nmd);
631         BLI_insertlink(&ob->modifiers, md, nmd);
632         modifier_unique_name(&ob->modifiers, nmd);
633
634         return 1;
635 }
636
637 /************************ add modifier operator *********************/
638
639 static int modifier_add_exec(bContext *C, wmOperator *op)
640 {
641         Main *bmain= CTX_data_main(C);
642         Scene *scene= CTX_data_scene(C);
643         Object *ob = ED_object_active_context(C);
644         int type= RNA_enum_get(op->ptr, "type");
645
646         if(!ED_object_modifier_add(op->reports, bmain, scene, ob, NULL, type))
647                 return OPERATOR_CANCELLED;
648
649         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
650         
651         return OPERATOR_FINISHED;
652 }
653
654 static EnumPropertyItem *modifier_add_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free)
655 {       
656         Object *ob= ED_object_active_context(C);
657         EnumPropertyItem *item= NULL, *md_item, *group_item= NULL;
658         ModifierTypeInfo *mti;
659         int totitem= 0, a;
660         
661         if(!ob)
662                 return modifier_type_items;
663
664         for(a=0; modifier_type_items[a].identifier; a++) {
665                 md_item= &modifier_type_items[a];
666
667                 if(md_item->identifier[0]) {
668                         mti= modifierType_getInfo(md_item->value);
669
670                         if(mti->flags & eModifierTypeFlag_NoUserAdd)
671                                 continue;
672
673                         if(!((mti->flags & eModifierTypeFlag_AcceptsCVs) ||
674                            (ob->type==OB_MESH && (mti->flags & eModifierTypeFlag_AcceptsMesh))))
675                                 continue;
676                 }
677                 else {
678                         group_item= md_item;
679                         md_item= NULL;
680
681                         continue;
682                 }
683
684                 if(group_item) {
685                         RNA_enum_item_add(&item, &totitem, group_item);
686                         group_item= NULL;
687                 }
688
689                 RNA_enum_item_add(&item, &totitem, md_item);
690         }
691
692         RNA_enum_item_end(&item, &totitem);
693         *free= 1;
694
695         return item;
696 }
697
698 void OBJECT_OT_modifier_add(wmOperatorType *ot)
699 {
700         PropertyRNA *prop;
701
702         /* identifiers */
703         ot->name= "Add Modifier";
704         ot->description = "Add a modifier to the active object";
705         ot->idname= "OBJECT_OT_modifier_add";
706         
707         /* api callbacks */
708         ot->invoke= WM_menu_invoke;
709         ot->exec= modifier_add_exec;
710         ot->poll= ED_operator_object_active_editable;
711         
712         /* flags */
713         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
714         
715         /* properties */
716         prop= RNA_def_enum(ot->srna, "type", modifier_type_items, eModifierType_Subsurf, "Type", "");
717         RNA_def_enum_funcs(prop, modifier_add_itemf);
718         ot->prop= prop;
719 }
720
721 /************************ generic functions for operators using mod names and data context *********************/
722
723 static int edit_modifier_poll_generic(bContext *C, StructRNA *rna_type, int obtype_flag)
724 {
725         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", rna_type);
726         Object *ob= (ptr.id.data)?ptr.id.data:ED_object_active_context(C);
727         
728         if (!ob || ob->id.lib) return 0;
729         if (obtype_flag && ((1<<ob->type) & obtype_flag)==0) return 0;
730         if (ptr.id.data && ((ID*)ptr.id.data)->lib) return 0;
731         
732         return 1;
733 }
734
735 static int edit_modifier_poll(bContext *C)
736 {
737         return edit_modifier_poll_generic(C, &RNA_Modifier, 0);
738 }
739
740 static void edit_modifier_properties(wmOperatorType *ot)
741 {
742         RNA_def_string(ot->srna, "modifier", "", MAX_NAME, "Modifier", "Name of the modifier to edit");
743 }
744
745 static int edit_modifier_invoke_properties(bContext *C, wmOperator *op)
746 {
747         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
748         ModifierData *md;
749         
750         if (RNA_struct_property_is_set(op->ptr, "modifier"))
751                 return 1;
752         
753         if (ptr.data) {
754                 md = ptr.data;
755                 RNA_string_set(op->ptr, "modifier", md->name);
756                 return 1;
757         }
758         
759         return 0;
760 }
761
762 static ModifierData *edit_modifier_property_get(wmOperator *op, Object *ob, int type)
763 {
764         char modifier_name[MAX_NAME];
765         ModifierData *md;
766         RNA_string_get(op->ptr, "modifier", modifier_name);
767         
768         md = modifiers_findByName(ob, modifier_name);
769         
770         if (md && type != 0 && md->type != type)
771                 md = NULL;
772
773         return md;
774 }
775
776 /************************ remove modifier operator *********************/
777
778 static int modifier_remove_exec(bContext *C, wmOperator *op)
779 {
780         Main *bmain= CTX_data_main(C);
781         Scene *scene= CTX_data_scene(C);
782         Object *ob = ED_object_active_context(C);
783         ModifierData *md = edit_modifier_property_get(op, ob, 0);
784         int mode_orig = ob ? ob->mode : 0;
785         
786         if(!ob || !md || !ED_object_modifier_remove(op->reports, bmain, scene, ob, md))
787                 return OPERATOR_CANCELLED;
788
789         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
790
791         /* if cloth/softbody was removed, particle mode could be cleared */
792         if(mode_orig & OB_MODE_PARTICLE_EDIT)
793                 if((ob->mode & OB_MODE_PARTICLE_EDIT)==0)
794                         if(scene->basact && scene->basact->object==ob)
795                                 WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, NULL);
796         
797         return OPERATOR_FINISHED;
798 }
799
800 static int modifier_remove_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
801 {
802         if (edit_modifier_invoke_properties(C, op))
803                 return modifier_remove_exec(C, op);
804         else
805                 return OPERATOR_CANCELLED;
806 }
807
808 void OBJECT_OT_modifier_remove(wmOperatorType *ot)
809 {
810         ot->name= "Remove Modifier";
811         ot->description= "Remove a modifier from the active object";
812         ot->idname= "OBJECT_OT_modifier_remove";
813
814         ot->invoke= modifier_remove_invoke;
815         ot->exec= modifier_remove_exec;
816         ot->poll= edit_modifier_poll;
817         
818         /* flags */
819         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
820         edit_modifier_properties(ot);
821 }
822
823 /************************ move up modifier operator *********************/
824
825 static int modifier_move_up_exec(bContext *C, wmOperator *op)
826 {
827         Object *ob = ED_object_active_context(C);
828         ModifierData *md = edit_modifier_property_get(op, ob, 0);
829
830         if(!ob || !md || !ED_object_modifier_move_up(op->reports, ob, md))
831                 return OPERATOR_CANCELLED;
832
833         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
834         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
835         
836         return OPERATOR_FINISHED;
837 }
838
839 static int modifier_move_up_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
840 {
841         if (edit_modifier_invoke_properties(C, op))
842                 return modifier_move_up_exec(C, op);
843         else
844                 return OPERATOR_CANCELLED;
845 }
846
847 void OBJECT_OT_modifier_move_up(wmOperatorType *ot)
848 {
849         ot->name= "Move Up Modifier";
850         ot->description= "Move modifier up in the stack";
851         ot->idname= "OBJECT_OT_modifier_move_up";
852
853         ot->invoke= modifier_move_up_invoke;
854         ot->exec= modifier_move_up_exec;
855         ot->poll= edit_modifier_poll;
856         
857         /* flags */
858         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
859         edit_modifier_properties(ot);
860 }
861
862 /************************ move down modifier operator *********************/
863
864 static int modifier_move_down_exec(bContext *C, wmOperator *op)
865 {
866         Object *ob = ED_object_active_context(C);
867         ModifierData *md = edit_modifier_property_get(op, ob, 0);
868
869         if(!ob || !md || !ED_object_modifier_move_down(op->reports, ob, md))
870                 return OPERATOR_CANCELLED;
871
872         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
873         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
874         
875         return OPERATOR_FINISHED;
876 }
877
878 static int modifier_move_down_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
879 {
880         if (edit_modifier_invoke_properties(C, op))
881                 return modifier_move_down_exec(C, op);
882         else
883                 return OPERATOR_CANCELLED;
884 }
885
886 void OBJECT_OT_modifier_move_down(wmOperatorType *ot)
887 {
888         ot->name= "Move Down Modifier";
889         ot->description= "Move modifier down in the stack";
890         ot->idname= "OBJECT_OT_modifier_move_down";
891
892         ot->invoke= modifier_move_down_invoke;
893         ot->exec= modifier_move_down_exec;
894         ot->poll= edit_modifier_poll;
895         
896         /* flags */
897         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
898         edit_modifier_properties(ot);
899 }
900
901 /************************ apply modifier operator *********************/
902
903 static int modifier_apply_exec(bContext *C, wmOperator *op)
904 {
905         Scene *scene= CTX_data_scene(C);
906         Object *ob = ED_object_active_context(C);
907         ModifierData *md = edit_modifier_property_get(op, ob, 0);
908         int apply_as= RNA_enum_get(op->ptr, "apply_as");
909         
910         if(!ob || !md || !ED_object_modifier_apply(op->reports, scene, ob, md, apply_as)) {
911                 return OPERATOR_CANCELLED;
912         }
913
914         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
915         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
916         
917         return OPERATOR_FINISHED;
918 }
919
920 static int modifier_apply_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
921 {
922         if (edit_modifier_invoke_properties(C, op))
923                 return modifier_apply_exec(C, op);
924         else
925                 return OPERATOR_CANCELLED;
926 }
927
928 static EnumPropertyItem modifier_apply_as_items[] = {
929         {MODIFIER_APPLY_DATA, "DATA", 0, "Object Data", "Apply modifier to the object's data"},
930         {MODIFIER_APPLY_SHAPE, "SHAPE", 0, "New Shape", "Apply deform-only modifier to a new shape on this object"},
931         {0, NULL, 0, NULL, NULL}};
932
933 void OBJECT_OT_modifier_apply(wmOperatorType *ot)
934 {
935         ot->name= "Apply Modifier";
936         ot->description= "Apply modifier and remove from the stack";
937         ot->idname= "OBJECT_OT_modifier_apply";
938
939         ot->invoke= modifier_apply_invoke;
940         ot->exec= modifier_apply_exec;
941         ot->poll= edit_modifier_poll;
942         
943         /* flags */
944         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
945         
946         RNA_def_enum(ot->srna, "apply_as", modifier_apply_as_items, MODIFIER_APPLY_DATA, "Apply as", "How to apply the modifier to the geometry");
947         edit_modifier_properties(ot);
948 }
949
950 /************************ convert modifier operator *********************/
951
952 static int modifier_convert_exec(bContext *C, wmOperator *op)
953 {
954         Main *bmain= CTX_data_main(C);
955         Scene *scene= CTX_data_scene(C);
956         Object *ob = ED_object_active_context(C);
957         ModifierData *md = edit_modifier_property_get(op, ob, 0);
958         
959         if(!ob || !md || !ED_object_modifier_convert(op->reports, bmain, scene, ob, md))
960                 return OPERATOR_CANCELLED;
961
962         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
963         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
964         
965         return OPERATOR_FINISHED;
966 }
967
968 static int modifier_convert_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
969 {
970         if (edit_modifier_invoke_properties(C, op))
971                 return modifier_convert_exec(C, op);
972         else
973                 return OPERATOR_CANCELLED;
974 }
975
976 void OBJECT_OT_modifier_convert(wmOperatorType *ot)
977 {
978         ot->name= "Convert Modifier";
979         ot->description= "Convert particles to a mesh object";
980         ot->idname= "OBJECT_OT_modifier_convert";
981
982         ot->invoke= modifier_convert_invoke;
983         ot->exec= modifier_convert_exec;
984         ot->poll= edit_modifier_poll;
985         
986         /* flags */
987         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
988         edit_modifier_properties(ot);
989 }
990
991 /************************ copy modifier operator *********************/
992
993 static int modifier_copy_exec(bContext *C, wmOperator *op)
994 {
995         Object *ob = ED_object_active_context(C);
996         ModifierData *md = edit_modifier_property_get(op, ob, 0);
997
998         if(!ob || !md || !ED_object_modifier_copy(op->reports, ob, md))
999                 return OPERATOR_CANCELLED;
1000
1001         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1002         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1003         
1004         return OPERATOR_FINISHED;
1005 }
1006
1007 static int modifier_copy_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1008 {
1009         if (edit_modifier_invoke_properties(C, op))
1010                 return modifier_copy_exec(C, op);
1011         else
1012                 return OPERATOR_CANCELLED;
1013 }
1014
1015 void OBJECT_OT_modifier_copy(wmOperatorType *ot)
1016 {
1017         ot->name= "Copy Modifier";
1018         ot->description= "Duplicate modifier at the same position in the stack";
1019         ot->idname= "OBJECT_OT_modifier_copy";
1020
1021         ot->invoke= modifier_copy_invoke;
1022         ot->exec= modifier_copy_exec;
1023         ot->poll= edit_modifier_poll;
1024         
1025         /* flags */
1026         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1027         edit_modifier_properties(ot);
1028 }
1029
1030 /************* multires delete higher levels operator ****************/
1031
1032 static int multires_poll(bContext *C)
1033 {
1034         return edit_modifier_poll_generic(C, &RNA_MultiresModifier, (1<<OB_MESH));
1035 }
1036
1037 static int multires_higher_levels_delete_exec(bContext *C, wmOperator *op)
1038 {
1039         Object *ob = ED_object_active_context(C);
1040         MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
1041         
1042         if (!mmd)
1043                 return OPERATOR_CANCELLED;
1044         
1045         multiresModifier_del_levels(mmd, ob, 1);
1046         
1047         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1048         
1049         return OPERATOR_FINISHED;
1050 }
1051
1052 static int multires_higher_levels_delete_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1053 {
1054         if (edit_modifier_invoke_properties(C, op))
1055                 return multires_higher_levels_delete_exec(C, op);
1056         else
1057                 return OPERATOR_CANCELLED;
1058 }
1059
1060 void OBJECT_OT_multires_higher_levels_delete(wmOperatorType *ot)
1061 {
1062         ot->name= "Delete Higher Levels";
1063         ot->description= "Deletes the higher resolution mesh, potential loss of detail";
1064         ot->idname= "OBJECT_OT_multires_higher_levels_delete";
1065
1066         ot->poll= multires_poll;
1067         ot->invoke= multires_higher_levels_delete_invoke;
1068         ot->exec= multires_higher_levels_delete_exec;
1069         
1070         /* flags */
1071         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1072         edit_modifier_properties(ot);
1073 }
1074
1075 /****************** multires subdivide operator *********************/
1076
1077 static int multires_subdivide_exec(bContext *C, wmOperator *op)
1078 {
1079         Object *ob = ED_object_active_context(C);
1080         MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
1081         
1082         if (!mmd)
1083                 return OPERATOR_CANCELLED;
1084         
1085         multiresModifier_subdivide(mmd, ob, 0, mmd->simple);
1086
1087         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1088         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1089         
1090         return OPERATOR_FINISHED;
1091 }
1092
1093 static int multires_subdivide_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1094 {
1095         if (edit_modifier_invoke_properties(C, op))
1096                 return multires_subdivide_exec(C, op);
1097         else
1098                 return OPERATOR_CANCELLED;
1099 }
1100
1101 void OBJECT_OT_multires_subdivide(wmOperatorType *ot)
1102 {
1103         ot->name= "Multires Subdivide";
1104         ot->description= "Add a new level of subdivision";
1105         ot->idname= "OBJECT_OT_multires_subdivide";
1106
1107         ot->poll= multires_poll;
1108         ot->invoke= multires_subdivide_invoke;
1109         ot->exec= multires_subdivide_exec;
1110         
1111         /* flags */
1112         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1113         edit_modifier_properties(ot);
1114 }
1115
1116 /****************** multires reshape operator *********************/
1117
1118 static int multires_reshape_exec(bContext *C, wmOperator *op)
1119 {
1120         Object *ob= ED_object_active_context(C), *secondob= NULL;
1121         Scene *scene= CTX_data_scene(C);
1122         MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
1123
1124         if (!mmd)
1125                 return OPERATOR_CANCELLED;
1126
1127         if(mmd->lvl==0) {
1128                 BKE_report(op->reports, RPT_ERROR, "Reshape can work only with higher levels of subdivisions");
1129                 return OPERATOR_CANCELLED;
1130         }
1131
1132         CTX_DATA_BEGIN(C, Object*, selob, selected_editable_objects) {
1133                 if(selob->type == OB_MESH && selob != ob) {
1134                         secondob= selob;
1135                         break;
1136                 }
1137         }
1138         CTX_DATA_END;
1139
1140         if(!secondob) {
1141                 BKE_report(op->reports, RPT_ERROR, "Second selected mesh object require to copy shape from");
1142                 return OPERATOR_CANCELLED;
1143         }
1144
1145         if(!multiresModifier_reshape(scene, mmd, ob, secondob)) {
1146                 BKE_report(op->reports, RPT_ERROR, "Objects do not have the same number of vertices");
1147                 return OPERATOR_CANCELLED;
1148         }
1149
1150         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1151         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1152
1153         return OPERATOR_FINISHED;
1154 }
1155
1156 static int multires_reshape_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1157 {
1158         if (edit_modifier_invoke_properties(C, op))
1159                 return multires_reshape_exec(C, op);
1160         else
1161                 return OPERATOR_CANCELLED;
1162 }
1163
1164 void OBJECT_OT_multires_reshape(wmOperatorType *ot)
1165 {
1166         ot->name= "Multires Reshape";
1167         ot->description= "Copy vertex coordinates from other object";
1168         ot->idname= "OBJECT_OT_multires_reshape";
1169
1170         ot->poll= multires_poll;
1171         ot->invoke= multires_reshape_invoke;
1172         ot->exec= multires_reshape_exec;
1173         
1174         /* flags */
1175         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1176         edit_modifier_properties(ot);
1177 }
1178
1179 static int multires_test_exec(bContext *C, wmOperator *op)
1180 {
1181         Object *ob= ED_object_active_context(C);
1182         Mesh *me = ob->data;
1183         MPoly *mp;
1184         MDisps *mdisps;
1185         int i, x = RNA_int_get(op->ptr, "x"), y = RNA_int_get(op->ptr, "y");
1186         
1187         if (ob->type != OB_MESH || !me)
1188                 return OPERATOR_CANCELLED;
1189         
1190         mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
1191         if (!mdisps)
1192                 return OPERATOR_CANCELLED;
1193         
1194         mp = me->mpoly;
1195         for (i=0; i<me->totpoly; i++, mp++) {
1196                 MLoop *ml;
1197                 int j;
1198                 
1199                 ml = me->mloop + mp->loopstart;
1200                 for (j=0; j<mp->totloop; j++, ml++) {
1201                         MLoop *ml_prev = ME_POLY_LOOP_PREV(me->mloop, mp, j);
1202                         MLoop *ml_next = ME_POLY_LOOP_NEXT(me->mloop, mp, j);
1203                         
1204                         if ((me->mvert[ml->v].flag&SELECT) && (me->mvert[ml_prev->v].flag&SELECT) && (me->mvert[ml_next->v].flag&SELECT)) {
1205                                 MDisps *md = mdisps + mp->loopstart + j;
1206                                 int res = sqrt(md->totdisp);
1207                                 
1208                                 if (x >= res) x = res-1;
1209                                 if (y >= res) y = res-1;
1210                                 
1211                                 md->disps[y*res + x][2] += 1.0;
1212                         }
1213                 }
1214         }
1215                 
1216         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1217         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1218
1219         return OPERATOR_FINISHED;
1220 }
1221
1222 void OBJECT_OT_test_multires(wmOperatorType *ot)
1223 {
1224         ot->name= "Multires Object Mode Test";
1225         ot->description= "";
1226         ot->idname= "OBJECT_OT_test_multires";
1227
1228         ot->poll= multires_poll;
1229         ot->exec= multires_test_exec;
1230         
1231         /* flags */
1232         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1233         RNA_def_int(ot->srna, "x", 0, 0, 100, "x", "x", 0, 100);
1234         RNA_def_int(ot->srna, "y", 0, 0, 100, "y", "y", 0, 100);
1235 }
1236
1237
1238                 
1239 /****************** multires save external operator *********************/
1240
1241 static int multires_external_save_exec(bContext *C, wmOperator *op)
1242 {
1243         Object *ob = ED_object_active_context(C);
1244         Mesh *me= (ob)? ob->data: op->customdata;
1245         char path[FILE_MAX];
1246         int relative= RNA_boolean_get(op->ptr, "relative_path");
1247
1248         if(!me)
1249                 return OPERATOR_CANCELLED;
1250
1251         if(CustomData_external_test(&me->ldata, CD_MDISPS))
1252                 return OPERATOR_CANCELLED;
1253         
1254         RNA_string_get(op->ptr, "filepath", path);
1255
1256         if(relative)
1257                 BLI_path_rel(path, G.main->name);
1258
1259         CustomData_external_add(&me->ldata, &me->id, CD_MDISPS, me->totloop, path);
1260         CustomData_external_write(&me->ldata, &me->id, CD_MASK_MESH, me->totloop, 0);
1261         
1262         return OPERATOR_FINISHED;
1263 }
1264
1265 static int multires_external_save_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1266 {
1267         Object *ob = ED_object_active_context(C);
1268         MultiresModifierData *mmd;
1269         Mesh *me= ob->data;
1270         char path[FILE_MAX];
1271
1272         if (!edit_modifier_invoke_properties(C, op))
1273                 return OPERATOR_CANCELLED;
1274         
1275         mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
1276         
1277         if (!mmd)
1278                 return OPERATOR_CANCELLED;
1279         
1280         if(CustomData_external_test(&me->ldata, CD_MDISPS))
1281                 return OPERATOR_CANCELLED;
1282
1283         if(RNA_struct_property_is_set(op->ptr, "filepath"))
1284                 return multires_external_save_exec(C, op);
1285         
1286         op->customdata= me;
1287
1288         BLI_snprintf(path, sizeof(path), "//%s.btx", me->id.name+2);
1289         RNA_string_set(op->ptr, "filepath", path);
1290         
1291         WM_event_add_fileselect(C, op);
1292
1293         return OPERATOR_RUNNING_MODAL;
1294 }
1295
1296 void OBJECT_OT_multires_external_save(wmOperatorType *ot)
1297 {
1298         ot->name= "Multires Save External";
1299         ot->description= "Save displacements to an external file";
1300         ot->idname= "OBJECT_OT_multires_external_save";
1301
1302         // XXX modifier no longer in context after file browser .. ot->poll= multires_poll;
1303         ot->exec= multires_external_save_exec;
1304         ot->invoke= multires_external_save_invoke;
1305         ot->poll= multires_poll;
1306         
1307         /* flags */
1308         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1309
1310         WM_operator_properties_filesel(ot, FOLDERFILE|BTXFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY);
1311         edit_modifier_properties(ot);
1312 }
1313
1314 /****************** multires pack operator *********************/
1315
1316 static int multires_external_pack_exec(bContext *C, wmOperator *UNUSED(op))
1317 {
1318         Object *ob = ED_object_active_context(C);
1319         Mesh *me= ob->data;
1320
1321         if(!CustomData_external_test(&me->ldata, CD_MDISPS))
1322                 return OPERATOR_CANCELLED;
1323
1324         // XXX don't remove..
1325         CustomData_external_remove(&me->ldata, &me->id, CD_MDISPS, me->totloop);
1326         
1327         return OPERATOR_FINISHED;
1328 }
1329
1330 void OBJECT_OT_multires_external_pack(wmOperatorType *ot)
1331 {
1332         ot->name= "Multires Pack External";
1333         ot->description= "Pack displacements from an external file";
1334         ot->idname= "OBJECT_OT_multires_external_pack";
1335
1336         ot->poll= multires_poll;
1337         ot->exec= multires_external_pack_exec;
1338         
1339         /* flags */
1340         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1341 }
1342
1343 /********************* multires apply base ***********************/
1344 static int multires_base_apply_exec(bContext *C, wmOperator *op)
1345 {
1346         Object *ob = ED_object_active_context(C);
1347         MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
1348         
1349         if (!mmd)
1350                 return OPERATOR_CANCELLED;
1351         
1352         multiresModifier_base_apply(mmd, ob);
1353
1354         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1355         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1356         
1357         return OPERATOR_FINISHED;
1358 }
1359
1360 static int multires_base_apply_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1361 {
1362         if (edit_modifier_invoke_properties(C, op))
1363                 return multires_base_apply_exec(C, op);
1364         else
1365                 return OPERATOR_CANCELLED;
1366 }
1367
1368
1369 void OBJECT_OT_multires_base_apply(wmOperatorType *ot)
1370 {
1371         ot->name= "Multires Apply Base";
1372         ot->description= "Modify the base mesh to conform to the displaced mesh";
1373         ot->idname= "OBJECT_OT_multires_base_apply";
1374
1375         ot->poll= multires_poll;
1376         ot->invoke= multires_base_apply_invoke;
1377         ot->exec= multires_base_apply_exec;
1378         
1379         /* flags */
1380         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1381         edit_modifier_properties(ot);
1382 }
1383
1384
1385 /************************ mdef bind operator *********************/
1386
1387 static int meshdeform_poll(bContext *C)
1388 {
1389         return edit_modifier_poll_generic(C, &RNA_MeshDeformModifier, (1<<OB_MESH));
1390 }
1391
1392 static int meshdeform_bind_exec(bContext *C, wmOperator *op)
1393 {
1394         Scene *scene= CTX_data_scene(C);
1395         Object *ob = ED_object_active_context(C);
1396         MeshDeformModifierData *mmd = (MeshDeformModifierData *)edit_modifier_property_get(op, ob, eModifierType_MeshDeform);
1397         
1398         if (!mmd)
1399                 return OPERATOR_CANCELLED;
1400
1401         if(mmd->bindcagecos) {
1402                 MEM_freeN(mmd->bindcagecos);
1403                 if(mmd->dyngrid) MEM_freeN(mmd->dyngrid);
1404                 if(mmd->dyninfluences) MEM_freeN(mmd->dyninfluences);
1405                 if(mmd->bindinfluences) MEM_freeN(mmd->bindinfluences);
1406                 if(mmd->bindoffsets) MEM_freeN(mmd->bindoffsets);
1407                 if(mmd->dynverts) MEM_freeN(mmd->dynverts);
1408                 if(mmd->bindweights) MEM_freeN(mmd->bindweights); /* deprecated */
1409                 if(mmd->bindcos) MEM_freeN(mmd->bindcos); /* deprecated */
1410
1411                 mmd->bindcagecos= NULL;
1412                 mmd->dyngrid= NULL;
1413                 mmd->dyninfluences= NULL;
1414                 mmd->bindoffsets= NULL;
1415                 mmd->dynverts= NULL;
1416                 mmd->bindweights= NULL; /* deprecated */
1417                 mmd->bindcos= NULL; /* deprecated */
1418                 mmd->totvert= 0;
1419                 mmd->totcagevert= 0;
1420                 mmd->totinfluence= 0;
1421                 
1422                 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1423                 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1424         }
1425         else {
1426                 DerivedMesh *dm;
1427                 int mode= mmd->modifier.mode;
1428
1429                 /* force modifier to run, it will call binding routine */
1430                 mmd->bindfunc= mesh_deform_bind;
1431                 mmd->modifier.mode |= eModifierMode_Realtime;
1432
1433                 if(ob->type == OB_MESH) {
1434                         dm= mesh_create_derived_view(scene, ob, 0);
1435                         dm->release(dm);
1436                 }
1437                 else if(ob->type == OB_LATTICE) {
1438                         lattice_calc_modifiers(scene, ob);
1439                 }
1440                 else if(ob->type==OB_MBALL) {
1441                         makeDispListMBall(scene, ob);
1442                 }
1443                 else if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
1444                         makeDispListCurveTypes(scene, ob, 0);
1445                 }
1446
1447                 mmd->bindfunc= NULL;
1448                 mmd->modifier.mode= mode;
1449         }
1450         
1451         return OPERATOR_FINISHED;
1452 }
1453
1454 static int meshdeform_bind_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1455 {
1456         if (edit_modifier_invoke_properties(C, op))
1457                 return meshdeform_bind_exec(C, op);
1458         else 
1459                 return OPERATOR_CANCELLED;
1460 }
1461
1462 void OBJECT_OT_meshdeform_bind(wmOperatorType *ot)
1463 {
1464         /* identifiers */
1465         ot->name= "Mesh Deform Bind";
1466         ot->description = "Bind mesh to cage in mesh deform modifier";
1467         ot->idname= "OBJECT_OT_meshdeform_bind";
1468         
1469         /* api callbacks */
1470         ot->poll= meshdeform_poll;
1471         ot->invoke= meshdeform_bind_invoke;
1472         ot->exec= meshdeform_bind_exec;
1473         
1474         /* flags */
1475         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1476         edit_modifier_properties(ot);
1477 }
1478
1479 /****************** explode refresh operator *********************/
1480
1481 static int explode_poll(bContext *C)
1482 {
1483         return edit_modifier_poll_generic(C, &RNA_ExplodeModifier, 0);
1484 }
1485
1486 static int explode_refresh_exec(bContext *C, wmOperator *op)
1487 {
1488         Object *ob = ED_object_active_context(C);
1489         ExplodeModifierData *emd = (ExplodeModifierData *)edit_modifier_property_get(op, ob, eModifierType_Explode);
1490         
1491         if (!emd)
1492                 return OPERATOR_CANCELLED;
1493
1494         emd->flag |= eExplodeFlag_CalcFaces;
1495
1496         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1497         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1498         
1499         return OPERATOR_FINISHED;
1500 }
1501
1502 static int explode_refresh_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1503 {
1504         if (edit_modifier_invoke_properties(C, op))
1505                 return explode_refresh_exec(C, op);
1506         else
1507                 return OPERATOR_CANCELLED;
1508 }
1509
1510
1511 void OBJECT_OT_explode_refresh(wmOperatorType *ot)
1512 {
1513         ot->name= "Explode Refresh";
1514         ot->description= "Refresh data in the Explode modifier";
1515         ot->idname= "OBJECT_OT_explode_refresh";
1516
1517         ot->poll= explode_poll;
1518         ot->invoke= explode_refresh_invoke;
1519         ot->exec= explode_refresh_exec;
1520         
1521         /* flags */
1522         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1523         edit_modifier_properties(ot);
1524 }
1525
1526
1527 /****************** ocean bake operator *********************/
1528
1529 static int ocean_bake_poll(bContext *C)
1530 {
1531         return edit_modifier_poll_generic(C, &RNA_OceanModifier, 0);
1532 }
1533
1534 /* copied from init_ocean_modifier, MOD_ocean.c */
1535 static void init_ocean_modifier_bake(struct Ocean *oc, struct OceanModifierData *omd)
1536 {
1537         int do_heightfield, do_chop, do_normals, do_jacobian;
1538         
1539         if (!omd || !oc) return; 
1540         
1541         do_heightfield = TRUE;
1542         do_chop = (omd->chop_amount > 0);
1543         do_normals = (omd->flag & MOD_OCEAN_GENERATE_NORMALS);
1544         do_jacobian = (omd->flag & MOD_OCEAN_GENERATE_FOAM);
1545         
1546         BKE_init_ocean(oc, omd->resolution*omd->resolution, omd->resolution*omd->resolution, omd->spatial_size, omd->spatial_size, 
1547                                    omd->wind_velocity, omd->smallest_wave, 1.0, omd->wave_direction, omd->damp, omd->wave_alignment, 
1548                                    omd->depth, omd->time,
1549                                    do_heightfield, do_chop, do_normals, do_jacobian,
1550                                    omd->seed);
1551 }
1552
1553 typedef struct OceanBakeJob {
1554         /* from wmJob */
1555         void *owner;
1556         short *stop, *do_update;
1557         float *progress;
1558         int current_frame;
1559         struct OceanCache *och;
1560         struct Ocean *ocean;
1561         struct OceanModifierData *omd;
1562 } OceanBakeJob;
1563
1564 static void oceanbake_free(void *customdata)
1565 {
1566         OceanBakeJob *oj= customdata;
1567         MEM_freeN(oj);
1568 }
1569
1570 /* called by oceanbake, only to check job 'stop' value */
1571 static int oceanbake_breakjob(void *UNUSED(customdata))
1572 {
1573         //OceanBakeJob *ob= (OceanBakeJob *)customdata;
1574         //return *(ob->stop);
1575         
1576         /* this is not nice yet, need to make the jobs list template better 
1577          * for identifying/acting upon various different jobs */
1578         /* but for now we'll reuse the render break... */
1579         return (G.afbreek);
1580 }
1581
1582 /* called by oceanbake, wmJob sends notifier */
1583 static void oceanbake_update(void *customdata, float progress, int *cancel)
1584 {
1585         OceanBakeJob *oj= customdata;
1586         
1587         if (oceanbake_breakjob(oj))
1588                 *cancel = 1;
1589         
1590         *(oj->do_update)= 1;
1591         *(oj->progress)= progress;
1592 }
1593
1594 static void oceanbake_startjob(void *customdata, short *stop, short *do_update, float *progress)
1595 {
1596         OceanBakeJob *oj= customdata;
1597         
1598         oj->stop= stop;
1599         oj->do_update = do_update;
1600         oj->progress = progress;
1601         
1602         G.afbreek= 0;   /* XXX shared with render - replace with job 'stop' switch */
1603         
1604         BKE_bake_ocean(oj->ocean, oj->och, oceanbake_update, (void *)oj);
1605         
1606         *do_update= 1;
1607         *stop = 0;
1608 }
1609
1610 static void oceanbake_endjob(void *customdata)
1611 {
1612         OceanBakeJob *oj= customdata;
1613         
1614         if (oj->ocean) {
1615                 BKE_free_ocean(oj->ocean);
1616                 oj->ocean = NULL;
1617         }
1618         
1619         oj->omd->oceancache = oj->och;
1620         oj->omd->cached = TRUE;
1621 }
1622
1623 static int ocean_bake_exec(bContext *C, wmOperator *op)
1624 {
1625         Object *ob = ED_object_active_context(C);
1626         OceanModifierData *omd = (OceanModifierData *)edit_modifier_property_get(op, ob, eModifierType_Ocean);
1627         Scene *scene = CTX_data_scene(C);
1628         OceanCache *och;
1629         struct Ocean *ocean;
1630         int f, cfra, i=0;
1631         int free= RNA_boolean_get(op->ptr, "free");
1632         
1633         wmJob *steve;
1634         OceanBakeJob *oj;
1635         
1636         if (!omd)
1637                 return OPERATOR_CANCELLED;
1638         
1639         if (free) {
1640                 omd->refresh |= MOD_OCEAN_REFRESH_CLEAR_CACHE;
1641                 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1642                 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1643                 return OPERATOR_FINISHED;
1644         }
1645
1646         och = BKE_init_ocean_cache(omd->cachepath, modifier_path_relbase(ob),
1647                                    omd->bakestart, omd->bakeend, omd->wave_scale,
1648                                    omd->chop_amount, omd->foam_coverage, omd->foam_fade, omd->resolution);
1649         
1650         och->time = MEM_mallocN(och->duration*sizeof(float), "foam bake time");
1651         
1652         cfra = scene->r.cfra;
1653         
1654         /* precalculate time variable before baking */
1655         for (f=omd->bakestart; f<=omd->bakeend; f++) {
1656                 /* from physics_fluid.c:
1657                  
1658                  * XXX: This can't be used due to an anim sys optimisation that ignores recalc object animation,
1659                  * leaving it for the depgraph (this ignores object animation such as modifier properties though... :/ )
1660                  * --> BKE_animsys_evaluate_all_animation(G.main, eval_time);
1661                  * This doesn't work with drivers:
1662                  * --> BKE_animsys_evaluate_animdata(&fsDomain->id, fsDomain->adt, eval_time, ADT_RECALC_ALL);
1663                  */
1664                 
1665                 /* Modifying the global scene isn't nice, but we can do it in 
1666                  * this part of the process before a threaded job is created */
1667                 
1668                 //scene->r.cfra = f;
1669                 //ED_update_for_newframe(CTX_data_main(C), scene, CTX_wm_screen(C), 1);
1670                 
1671                 /* ok, this doesn't work with drivers, but is way faster. 
1672                  * let's use this for now and hope nobody wants to drive the time value... */
1673                 BKE_animsys_evaluate_animdata(scene, (ID *)ob, ob->adt, f, ADT_RECALC_ANIM);
1674                 
1675                 och->time[i] = omd->time;
1676                 i++;
1677         }
1678         
1679         /* make a copy of ocean to use for baking - threadsafety */
1680         ocean = BKE_add_ocean();
1681         init_ocean_modifier_bake(ocean, omd);
1682         
1683         /*
1684          BKE_bake_ocean(ocean, och);
1685         
1686         omd->oceancache = och;
1687         omd->cached = TRUE;
1688         
1689         scene->r.cfra = cfra;
1690         
1691         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1692         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1693         */
1694         
1695         /* job stuff */
1696         
1697         scene->r.cfra = cfra;
1698         
1699         /* setup job */
1700         steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Ocean Simulation", WM_JOB_PROGRESS);
1701         oj= MEM_callocN(sizeof(OceanBakeJob), "ocean bake job");
1702         oj->ocean = ocean;
1703         oj->och = och;
1704         oj->omd = omd;
1705         
1706         WM_jobs_customdata(steve, oj, oceanbake_free);
1707         WM_jobs_timer(steve, 0.1, NC_OBJECT|ND_MODIFIER, NC_OBJECT|ND_MODIFIER);
1708         WM_jobs_callbacks(steve, oceanbake_startjob, NULL, NULL, oceanbake_endjob);
1709         
1710         WM_jobs_start(CTX_wm_manager(C), steve);
1711         
1712         
1713         
1714         return OPERATOR_FINISHED;
1715 }
1716
1717 static int ocean_bake_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1718 {
1719         if (edit_modifier_invoke_properties(C, op))
1720                 return ocean_bake_exec(C, op);
1721         else
1722                 return OPERATOR_CANCELLED;
1723 }
1724
1725
1726 void OBJECT_OT_ocean_bake(wmOperatorType *ot)
1727 {
1728         ot->name= "Bake Ocean";
1729         ot->description= "Bake an image sequence of ocean data";
1730         ot->idname= "OBJECT_OT_ocean_bake";
1731         
1732         ot->poll= ocean_bake_poll;
1733         ot->invoke= ocean_bake_invoke;
1734         ot->exec= ocean_bake_exec;
1735         
1736         /* flags */
1737         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1738         edit_modifier_properties(ot);
1739         
1740         RNA_def_boolean(ot->srna, "free", FALSE, "Free", "Free the bake, rather than generating it");
1741 }
1742