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