svn merge ^/trunk/blender -r42080:42095
[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_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)) {
468                         BKE_report(reports, RPT_ERROR, "Only deforming modifiers can be applied to Shapes");
469                         return 0;
470                 }
471                 mesh_pmv_off(me);
472                 
473                 dm = mesh_create_derived_for_modifier(scene, ob, md, 0);
474                 if (!dm) {
475                         BKE_report(reports, RPT_ERROR, "Modifier is disabled or returned error, skipping apply");
476                         return 0;
477                 }
478                 
479                 if(key == NULL) {
480                         key= me->key= add_key((ID *)me);
481                         key->type= KEY_RELATIVE;
482                         /* if that was the first key block added, then it was the basis.
483                          * Initialise it with the mesh, and add another for the modifier */
484                         kb= add_keyblock(key, NULL);
485                         mesh_to_key(me, kb);
486                 }
487
488                 kb= add_keyblock(key, md->name);
489                 DM_to_meshkey(dm, me, kb);
490                 
491                 dm->release(dm);
492         }
493         else {
494                 BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type");
495                 return 0;
496         }
497         return 1;
498 }
499
500 static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob, ModifierData *md)
501 {
502         ModifierTypeInfo *mti= modifierType_getInfo(md->type);
503
504         md->scene= scene;
505
506         if (mti->isDisabled && mti->isDisabled(md, 0)) {
507                 BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
508                 return 0;
509         }
510
511         if (ob->type==OB_MESH) {
512                 DerivedMesh *dm;
513                 Mesh *me = ob->data;
514                 MultiresModifierData *mmd= find_multires_modifier_before(scene, md);
515
516                 if( me->key) {
517                         BKE_report(reports, RPT_ERROR, "Modifier cannot be applied to Mesh with Shape Keys");
518                         return 0;
519                 }
520
521                 mesh_pmv_off(me);
522
523                 /* Multires: ensure that recent sculpting is applied */
524                 if(md->type == eModifierType_Multires)
525                         multires_force_update(ob);
526
527                 if (mmd && mmd->totlvl && mti->type==eModifierTypeType_OnlyDeform) {
528                         if(!multiresModifier_reshapeFromDeformMod (scene, mmd, ob, md)) {
529                                 BKE_report(reports, RPT_ERROR, "Multires modifier returned error, skipping apply");
530                                 return 0;
531                         }
532                 } else {
533                         dm = mesh_create_derived_for_modifier(scene, ob, md, 1);
534                         if (!dm) {
535                                 BKE_report(reports, RPT_ERROR, "Modifier returned error, skipping apply");
536                                 return 0;
537                         }
538
539                         DM_to_mesh(dm, me, ob);
540
541                         dm->release(dm);
542
543                         if(md->type == eModifierType_Multires) {
544                                 CustomData_external_remove(&me->ldata, &me->id, CD_MDISPS, me->totloop);
545                                 CustomData_free_layer_active(&me->ldata, CD_MDISPS, me->totloop);
546                         }
547                 }
548         }
549         else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
550                 Curve *cu;
551                 int numVerts;
552                 float (*vertexCos)[3];
553
554                 if (mti->type==eModifierTypeType_Constructive) {
555                         BKE_report(reports, RPT_ERROR, "Cannot apply constructive modifiers on curve");
556                         return 0;
557                 }
558
559                 cu = ob->data;
560                 BKE_report(reports, RPT_INFO, "Applied modifier only changed CV points, not tesselated/bevel vertices");
561
562                 vertexCos = curve_getVertexCos(cu, &cu->nurb, &numVerts);
563                 mti->deformVerts(md, ob, NULL, vertexCos, numVerts, 0, 0);
564                 curve_applyVertexCos(cu, &cu->nurb, vertexCos);
565
566                 MEM_freeN(vertexCos);
567
568                 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
569         }
570         else {
571                 BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type");
572                 return 0;
573         }
574
575         /* lattice modifier can be applied to particle system too */
576         if(ob->particlesystem.first) {
577
578                 ParticleSystem *psys = ob->particlesystem.first;
579
580                 for(; psys; psys=psys->next) {
581                         
582                         if(psys->part->type != PART_HAIR)
583                                 continue;
584
585                         psys_apply_hair_lattice(scene, ob, psys);
586                 }
587         }
588
589         return 1;
590 }
591
592 int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, ModifierData *md, int mode)
593 {
594         int prev_mode;
595
596         if (scene->obedit) {
597                 BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied in editmode");
598                 return 0;
599         } else if (((ID*) ob->data)->us>1) {
600                 BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied to multi-user data");
601                 return 0;
602         }
603
604         if (md!=ob->modifiers.first)
605                 BKE_report(reports, RPT_INFO, "Applied modifier was not first, result may not be as expected");
606
607         /* allow apply of a not-realtime modifier, by first re-enabling realtime. */
608         prev_mode= md->mode;
609         md->mode |= eModifierMode_Realtime;
610
611         if (mode == MODIFIER_APPLY_SHAPE) {
612                 if (!modifier_apply_shape(reports, scene, ob, md)) {
613                         md->mode= prev_mode;
614                         return 0;
615                 }
616         } else {
617                 if (!modifier_apply_obdata(reports, scene, ob, md)) {
618                         md->mode= prev_mode;
619                         return 0;
620                 }
621         }
622
623         BLI_remlink(&ob->modifiers, md);
624         modifier_free(md);
625
626         return 1;
627 }
628
629 int ED_object_modifier_copy(ReportList *UNUSED(reports), Object *ob, ModifierData *md)
630 {
631         ModifierData *nmd;
632         
633         nmd = modifier_new(md->type);
634         modifier_copyData(md, nmd);
635         BLI_insertlink(&ob->modifiers, md, nmd);
636         modifier_unique_name(&ob->modifiers, nmd);
637
638         return 1;
639 }
640
641 /************************ add modifier operator *********************/
642
643 static int modifier_add_exec(bContext *C, wmOperator *op)
644 {
645         Main *bmain= CTX_data_main(C);
646         Scene *scene= CTX_data_scene(C);
647         Object *ob = ED_object_active_context(C);
648         int type= RNA_enum_get(op->ptr, "type");
649
650         if(!ED_object_modifier_add(op->reports, bmain, scene, ob, NULL, type))
651                 return OPERATOR_CANCELLED;
652
653         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
654         
655         return OPERATOR_FINISHED;
656 }
657
658 static EnumPropertyItem *modifier_add_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free)
659 {       
660         Object *ob= ED_object_active_context(C);
661         EnumPropertyItem *item= NULL, *md_item;
662         ModifierTypeInfo *mti;
663         int totitem= 0, a;
664         
665         if(!ob)
666                 return modifier_type_items;
667
668         for(a=0; modifier_type_items[a].identifier; a++) {
669                 md_item= &modifier_type_items[a];
670
671                 if(md_item->identifier[0]) {
672                         mti= modifierType_getInfo(md_item->value);
673
674                         if(mti->flags & eModifierTypeFlag_NoUserAdd)
675                                 continue;
676
677                         if(!((mti->flags & eModifierTypeFlag_AcceptsCVs) ||
678                            (ob->type==OB_MESH && (mti->flags & eModifierTypeFlag_AcceptsMesh))))
679                                 continue;
680                 }
681
682                 RNA_enum_item_add(&item, &totitem, md_item);
683         }
684
685         RNA_enum_item_end(&item, &totitem);
686         *free= 1;
687
688         return item;
689 }
690
691 void OBJECT_OT_modifier_add(wmOperatorType *ot)
692 {
693         PropertyRNA *prop;
694
695         /* identifiers */
696         ot->name= "Add Modifier";
697         ot->description = "Add a modifier to the active object";
698         ot->idname= "OBJECT_OT_modifier_add";
699         
700         /* api callbacks */
701         ot->invoke= WM_menu_invoke;
702         ot->exec= modifier_add_exec;
703         ot->poll= ED_operator_object_active_editable;
704         
705         /* flags */
706         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
707         
708         /* properties */
709         prop= RNA_def_enum(ot->srna, "type", modifier_type_items, eModifierType_Subsurf, "Type", "");
710         RNA_def_enum_funcs(prop, modifier_add_itemf);
711         ot->prop= prop;
712 }
713
714 /************************ generic functions for operators using mod names and data context *********************/
715
716 static int edit_modifier_poll_generic(bContext *C, StructRNA *rna_type, int obtype_flag)
717 {
718         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", rna_type);
719         Object *ob= (ptr.id.data)?ptr.id.data:ED_object_active_context(C);
720         
721         if (!ob || ob->id.lib) return 0;
722         if (obtype_flag && ((1<<ob->type) & obtype_flag)==0) return 0;
723         if (ptr.id.data && ((ID*)ptr.id.data)->lib) return 0;
724         
725         return 1;
726 }
727
728 static int edit_modifier_poll(bContext *C)
729 {
730         return edit_modifier_poll_generic(C, &RNA_Modifier, 0);
731 }
732
733 static void edit_modifier_properties(wmOperatorType *ot)
734 {
735         RNA_def_string(ot->srna, "modifier", "", 32, "Modifier", "Name of the modifier to edit");
736 }
737
738 static int edit_modifier_invoke_properties(bContext *C, wmOperator *op)
739 {
740         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
741         ModifierData *md;
742         
743         if (RNA_property_is_set(op->ptr, "modifier"))
744                 return 1;
745         
746         if (ptr.data) {
747                 md = ptr.data;
748                 RNA_string_set(op->ptr, "modifier", md->name);
749                 return 1;
750         }
751         
752         return 0;
753 }
754
755 static ModifierData *edit_modifier_property_get(wmOperator *op, Object *ob, int type)
756 {
757         char modifier_name[32];
758         ModifierData *md;
759         RNA_string_get(op->ptr, "modifier", modifier_name);
760         
761         md = modifiers_findByName(ob, modifier_name);
762         
763         if (md && type != 0 && md->type != type)
764                 md = NULL;
765
766         return md;
767 }
768
769 /************************ remove modifier operator *********************/
770
771 static int modifier_remove_exec(bContext *C, wmOperator *op)
772 {
773         Main *bmain= CTX_data_main(C);
774         Scene *scene= CTX_data_scene(C);
775         Object *ob = ED_object_active_context(C);
776         ModifierData *md = edit_modifier_property_get(op, ob, 0);
777         int mode_orig = ob ? ob->mode : 0;
778         
779         if(!ob || !md || !ED_object_modifier_remove(op->reports, bmain, scene, ob, md))
780                 return OPERATOR_CANCELLED;
781
782         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
783
784         /* if cloth/softbody was removed, particle mode could be cleared */
785         if(mode_orig & OB_MODE_PARTICLE_EDIT)
786                 if((ob->mode & OB_MODE_PARTICLE_EDIT)==0)
787                         if(scene->basact && scene->basact->object==ob)
788                                 WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, NULL);
789         
790         return OPERATOR_FINISHED;
791 }
792
793 static int modifier_remove_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
794 {
795         if (edit_modifier_invoke_properties(C, op))
796                 return modifier_remove_exec(C, op);
797         else
798                 return OPERATOR_CANCELLED;
799 }
800
801 void OBJECT_OT_modifier_remove(wmOperatorType *ot)
802 {
803         ot->name= "Remove Modifier";
804         ot->description= "Remove a modifier from the active object";
805         ot->idname= "OBJECT_OT_modifier_remove";
806
807         ot->invoke= modifier_remove_invoke;
808         ot->exec= modifier_remove_exec;
809         ot->poll= edit_modifier_poll;
810         
811         /* flags */
812         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
813         edit_modifier_properties(ot);
814 }
815
816 /************************ move up modifier operator *********************/
817
818 static int modifier_move_up_exec(bContext *C, wmOperator *op)
819 {
820         Object *ob = ED_object_active_context(C);
821         ModifierData *md = edit_modifier_property_get(op, ob, 0);
822
823         if(!ob || !md || !ED_object_modifier_move_up(op->reports, ob, md))
824                 return OPERATOR_CANCELLED;
825
826         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
827         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
828         
829         return OPERATOR_FINISHED;
830 }
831
832 static int modifier_move_up_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
833 {
834         if (edit_modifier_invoke_properties(C, op))
835                 return modifier_move_up_exec(C, op);
836         else
837                 return OPERATOR_CANCELLED;
838 }
839
840 void OBJECT_OT_modifier_move_up(wmOperatorType *ot)
841 {
842         ot->name= "Move Up Modifier";
843         ot->description= "Move modifier up in the stack";
844         ot->idname= "OBJECT_OT_modifier_move_up";
845
846         ot->invoke= modifier_move_up_invoke;
847         ot->exec= modifier_move_up_exec;
848         ot->poll= edit_modifier_poll;
849         
850         /* flags */
851         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
852         edit_modifier_properties(ot);
853 }
854
855 /************************ move down modifier operator *********************/
856
857 static int modifier_move_down_exec(bContext *C, wmOperator *op)
858 {
859         Object *ob = ED_object_active_context(C);
860         ModifierData *md = edit_modifier_property_get(op, ob, 0);
861
862         if(!ob || !md || !ED_object_modifier_move_down(op->reports, ob, md))
863                 return OPERATOR_CANCELLED;
864
865         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
866         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
867         
868         return OPERATOR_FINISHED;
869 }
870
871 static int modifier_move_down_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
872 {
873         if (edit_modifier_invoke_properties(C, op))
874                 return modifier_move_down_exec(C, op);
875         else
876                 return OPERATOR_CANCELLED;
877 }
878
879 void OBJECT_OT_modifier_move_down(wmOperatorType *ot)
880 {
881         ot->name= "Move Down Modifier";
882         ot->description= "Move modifier down in the stack";
883         ot->idname= "OBJECT_OT_modifier_move_down";
884
885         ot->invoke= modifier_move_down_invoke;
886         ot->exec= modifier_move_down_exec;
887         ot->poll= edit_modifier_poll;
888         
889         /* flags */
890         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
891         edit_modifier_properties(ot);
892 }
893
894 /************************ apply modifier operator *********************/
895
896 static int modifier_apply_exec(bContext *C, wmOperator *op)
897 {
898         Scene *scene= CTX_data_scene(C);
899         Object *ob = ED_object_active_context(C);
900         ModifierData *md = edit_modifier_property_get(op, ob, 0);
901         int apply_as= RNA_enum_get(op->ptr, "apply_as");
902         
903         if(!ob || !md || !ED_object_modifier_apply(op->reports, scene, ob, md, apply_as)) {
904                 return OPERATOR_CANCELLED;
905         }
906
907         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
908         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
909         
910         return OPERATOR_FINISHED;
911 }
912
913 static int modifier_apply_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
914 {
915         if (edit_modifier_invoke_properties(C, op))
916                 return modifier_apply_exec(C, op);
917         else
918                 return OPERATOR_CANCELLED;
919 }
920
921 static EnumPropertyItem modifier_apply_as_items[] = {
922         {MODIFIER_APPLY_DATA, "DATA", 0, "Object Data", "Apply modifier to the object's data"},
923         {MODIFIER_APPLY_SHAPE, "SHAPE", 0, "New Shape", "Apply deform-only modifier to a new shape on this object"},
924         {0, NULL, 0, NULL, NULL}};
925
926 void OBJECT_OT_modifier_apply(wmOperatorType *ot)
927 {
928         ot->name= "Apply Modifier";
929         ot->description= "Apply modifier and remove from the stack";
930         ot->idname= "OBJECT_OT_modifier_apply";
931
932         ot->invoke= modifier_apply_invoke;
933         ot->exec= modifier_apply_exec;
934         ot->poll= edit_modifier_poll;
935         
936         /* flags */
937         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
938         
939         RNA_def_enum(ot->srna, "apply_as", modifier_apply_as_items, MODIFIER_APPLY_DATA, "Apply as", "How to apply the modifier to the geometry");
940         edit_modifier_properties(ot);
941 }
942
943 /************************ convert modifier operator *********************/
944
945 static int modifier_convert_exec(bContext *C, wmOperator *op)
946 {
947         Main *bmain= CTX_data_main(C);
948         Scene *scene= CTX_data_scene(C);
949         Object *ob = ED_object_active_context(C);
950         ModifierData *md = edit_modifier_property_get(op, ob, 0);
951         
952         if(!ob || !md || !ED_object_modifier_convert(op->reports, bmain, scene, ob, md))
953                 return OPERATOR_CANCELLED;
954
955         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
956         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
957         
958         return OPERATOR_FINISHED;
959 }
960
961 static int modifier_convert_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
962 {
963         if (edit_modifier_invoke_properties(C, op))
964                 return modifier_convert_exec(C, op);
965         else
966                 return OPERATOR_CANCELLED;
967 }
968
969 void OBJECT_OT_modifier_convert(wmOperatorType *ot)
970 {
971         ot->name= "Convert Modifier";
972         ot->description= "Convert particles to a mesh object";
973         ot->idname= "OBJECT_OT_modifier_convert";
974
975         ot->invoke= modifier_convert_invoke;
976         ot->exec= modifier_convert_exec;
977         ot->poll= edit_modifier_poll;
978         
979         /* flags */
980         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
981         edit_modifier_properties(ot);
982 }
983
984 /************************ copy modifier operator *********************/
985
986 static int modifier_copy_exec(bContext *C, wmOperator *op)
987 {
988         Object *ob = ED_object_active_context(C);
989         ModifierData *md = edit_modifier_property_get(op, ob, 0);
990
991         if(!ob || !md || !ED_object_modifier_copy(op->reports, ob, md))
992                 return OPERATOR_CANCELLED;
993
994         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
995         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
996         
997         return OPERATOR_FINISHED;
998 }
999
1000 static int modifier_copy_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1001 {
1002         if (edit_modifier_invoke_properties(C, op))
1003                 return modifier_copy_exec(C, op);
1004         else
1005                 return OPERATOR_CANCELLED;
1006 }
1007
1008 void OBJECT_OT_modifier_copy(wmOperatorType *ot)
1009 {
1010         ot->name= "Copy Modifier";
1011         ot->description= "Duplicate modifier at the same position in the stack";
1012         ot->idname= "OBJECT_OT_modifier_copy";
1013
1014         ot->invoke= modifier_copy_invoke;
1015         ot->exec= modifier_copy_exec;
1016         ot->poll= edit_modifier_poll;
1017         
1018         /* flags */
1019         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1020         edit_modifier_properties(ot);
1021 }
1022
1023 /************* multires delete higher levels operator ****************/
1024
1025 static int multires_poll(bContext *C)
1026 {
1027         return edit_modifier_poll_generic(C, &RNA_MultiresModifier, (1<<OB_MESH));
1028 }
1029
1030 static int multires_higher_levels_delete_exec(bContext *C, wmOperator *op)
1031 {
1032         Object *ob = ED_object_active_context(C);
1033         MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
1034         
1035         if (!mmd)
1036                 return OPERATOR_CANCELLED;
1037         
1038         multiresModifier_del_levels(mmd, ob, 1);
1039         
1040         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1041         
1042         return OPERATOR_FINISHED;
1043 }
1044
1045 static int multires_higher_levels_delete_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1046 {
1047         if (edit_modifier_invoke_properties(C, op))
1048                 return multires_higher_levels_delete_exec(C, op);
1049         else
1050                 return OPERATOR_CANCELLED;
1051 }
1052
1053 void OBJECT_OT_multires_higher_levels_delete(wmOperatorType *ot)
1054 {
1055         ot->name= "Delete Higher Levels";
1056         ot->description= "Deletes the higher resolution mesh, potential loss of detail";
1057         ot->idname= "OBJECT_OT_multires_higher_levels_delete";
1058
1059         ot->poll= multires_poll;
1060         ot->invoke= multires_higher_levels_delete_invoke;
1061         ot->exec= multires_higher_levels_delete_exec;
1062         
1063         /* flags */
1064         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1065         edit_modifier_properties(ot);
1066 }
1067
1068 /****************** multires subdivide operator *********************/
1069
1070 static int multires_subdivide_exec(bContext *C, wmOperator *op)
1071 {
1072         Object *ob = ED_object_active_context(C);
1073         MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
1074         
1075         if (!mmd)
1076                 return OPERATOR_CANCELLED;
1077         
1078         multiresModifier_subdivide(mmd, ob, 0, mmd->simple);
1079
1080         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1081         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1082         
1083         return OPERATOR_FINISHED;
1084 }
1085
1086 static int multires_subdivide_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1087 {
1088         if (edit_modifier_invoke_properties(C, op))
1089                 return multires_subdivide_exec(C, op);
1090         else
1091                 return OPERATOR_CANCELLED;
1092 }
1093
1094 void OBJECT_OT_multires_subdivide(wmOperatorType *ot)
1095 {
1096         ot->name= "Multires Subdivide";
1097         ot->description= "Add a new level of subdivision";
1098         ot->idname= "OBJECT_OT_multires_subdivide";
1099
1100         ot->poll= multires_poll;
1101         ot->invoke= multires_subdivide_invoke;
1102         ot->exec= multires_subdivide_exec;
1103         
1104         /* flags */
1105         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1106         edit_modifier_properties(ot);
1107 }
1108
1109 /****************** multires reshape operator *********************/
1110
1111 static int multires_reshape_exec(bContext *C, wmOperator *op)
1112 {
1113         Object *ob= ED_object_active_context(C), *secondob= NULL;
1114         Scene *scene= CTX_data_scene(C);
1115         MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
1116
1117         if (!mmd)
1118                 return OPERATOR_CANCELLED;
1119
1120         if(mmd->lvl==0) {
1121                 BKE_report(op->reports, RPT_ERROR, "Reshape can work only with higher levels of subdivisions");
1122                 return OPERATOR_CANCELLED;
1123         }
1124
1125         CTX_DATA_BEGIN(C, Object*, selob, selected_editable_objects) {
1126                 if(selob->type == OB_MESH && selob != ob) {
1127                         secondob= selob;
1128                         break;
1129                 }
1130         }
1131         CTX_DATA_END;
1132
1133         if(!secondob) {
1134                 BKE_report(op->reports, RPT_ERROR, "Second selected mesh object require to copy shape from");
1135                 return OPERATOR_CANCELLED;
1136         }
1137
1138         if(!multiresModifier_reshape(scene, mmd, ob, secondob)) {
1139                 BKE_report(op->reports, RPT_ERROR, "Objects do not have the same number of vertices");
1140                 return OPERATOR_CANCELLED;
1141         }
1142
1143         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1144         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1145
1146         return OPERATOR_FINISHED;
1147 }
1148
1149 static int multires_reshape_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1150 {
1151         if (edit_modifier_invoke_properties(C, op))
1152                 return multires_reshape_exec(C, op);
1153         else
1154                 return OPERATOR_CANCELLED;
1155 }
1156
1157 void OBJECT_OT_multires_reshape(wmOperatorType *ot)
1158 {
1159         ot->name= "Multires Reshape";
1160         ot->description= "Copy vertex coordinates from other object";
1161         ot->idname= "OBJECT_OT_multires_reshape";
1162
1163         ot->poll= multires_poll;
1164         ot->invoke= multires_reshape_invoke;
1165         ot->exec= multires_reshape_exec;
1166         
1167         /* flags */
1168         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1169         edit_modifier_properties(ot);
1170 }
1171
1172 static int multires_test_exec(bContext *C, wmOperator *op)
1173 {
1174         Object *ob= ED_object_active_context(C);
1175         Mesh *me = ob->data;
1176         MPoly *mp;
1177         MDisps *mdisps;
1178         int i, x = RNA_int_get(op->ptr, "x"), y = RNA_int_get(op->ptr, "y");
1179         
1180         if (ob->type != OB_MESH || !me)
1181                 return OPERATOR_CANCELLED;
1182         
1183         mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
1184         if (!mdisps)
1185                 return OPERATOR_CANCELLED;
1186         
1187         mp = me->mpoly;
1188         for (i=0; i<me->totpoly; i++, mp++) {
1189                 MLoop *ml;
1190                 int j;
1191                 
1192                 ml = me->mloop + mp->loopstart;
1193                 for (j=0; j<mp->totloop; j++, ml++) {
1194                         MLoop *ml2 = me->mloop + mp->loopstart + (j+mp->totloop-1)%mp->totloop;
1195                         MLoop *ml3 = me->mloop + mp->loopstart + (j+1)%mp->totloop;
1196                         
1197                         if ((me->mvert[ml->v].flag&SELECT) && (me->mvert[ml2->v].flag&SELECT) && (me->mvert[ml3->v].flag&SELECT)) {
1198                                 MDisps *md = mdisps + mp->loopstart + j;
1199                                 int res = sqrt(md->totdisp);
1200                                 
1201                                 if (x >= res) x = res-1;
1202                                 if (y >= res) y = res-1;
1203                                 
1204                                 md->disps[y*res + x][2] += 1.0;
1205                         }
1206                 }
1207         }
1208                 
1209         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1210         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1211
1212         return OPERATOR_FINISHED;
1213 }
1214
1215 void OBJECT_OT_test_multires(wmOperatorType *ot)
1216 {
1217         ot->name= "Multires Object Mode Test";
1218         ot->description= "";
1219         ot->idname= "OBJECT_OT_test_multires";
1220
1221         ot->poll= multires_poll;
1222         ot->exec= multires_test_exec;
1223         
1224         /* flags */
1225         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1226         RNA_def_int(ot->srna, "x", 0, 0, 100, "x", "x", 0, 100);
1227         RNA_def_int(ot->srna, "y", 0, 0, 100, "y", "y", 0, 100);
1228 }
1229
1230
1231                 
1232 /****************** multires save external operator *********************/
1233
1234 static int multires_external_save_exec(bContext *C, wmOperator *op)
1235 {
1236         Object *ob = ED_object_active_context(C);
1237         Mesh *me= (ob)? ob->data: op->customdata;
1238         char path[FILE_MAX];
1239         int relative= RNA_boolean_get(op->ptr, "relative_path");
1240
1241         if(!me)
1242                 return OPERATOR_CANCELLED;
1243
1244         if(CustomData_external_test(&me->ldata, CD_MDISPS))
1245                 return OPERATOR_CANCELLED;
1246         
1247         RNA_string_get(op->ptr, "filepath", path);
1248
1249         if(relative)
1250                 BLI_path_rel(path, G.main->name);
1251
1252         CustomData_external_add(&me->ldata, &me->id, CD_MDISPS, me->totloop, path);
1253         CustomData_external_write(&me->ldata, &me->id, CD_MASK_MESH, me->totloop, 0);
1254         
1255         return OPERATOR_FINISHED;
1256 }
1257
1258 static int multires_external_save_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1259 {
1260         Object *ob = ED_object_active_context(C);
1261         MultiresModifierData *mmd;
1262         Mesh *me= ob->data;
1263         char path[FILE_MAX];
1264
1265         if (!edit_modifier_invoke_properties(C, op))
1266                 return OPERATOR_CANCELLED;
1267         
1268         mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
1269         
1270         if (!mmd)
1271                 return OPERATOR_CANCELLED;
1272         
1273         if(CustomData_external_test(&me->ldata, CD_MDISPS))
1274                 return OPERATOR_CANCELLED;
1275
1276         if(RNA_property_is_set(op->ptr, "filepath"))
1277                 return multires_external_save_exec(C, op);
1278         
1279         op->customdata= me;
1280
1281         BLI_snprintf(path, sizeof(path), "//%s.btx", me->id.name+2);
1282         RNA_string_set(op->ptr, "filepath", path);
1283         
1284         WM_event_add_fileselect(C, op);
1285
1286         return OPERATOR_RUNNING_MODAL;
1287 }
1288
1289 void OBJECT_OT_multires_external_save(wmOperatorType *ot)
1290 {
1291         ot->name= "Multires Save External";
1292         ot->description= "Save displacements to an external file";
1293         ot->idname= "OBJECT_OT_multires_external_save";
1294
1295         // XXX modifier no longer in context after file browser .. ot->poll= multires_poll;
1296         ot->exec= multires_external_save_exec;
1297         ot->invoke= multires_external_save_invoke;
1298         ot->poll= multires_poll;
1299         
1300         /* flags */
1301         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1302
1303         WM_operator_properties_filesel(ot, FOLDERFILE|BTXFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH);
1304         edit_modifier_properties(ot);
1305 }
1306
1307 /****************** multires pack operator *********************/
1308
1309 static int multires_external_pack_exec(bContext *C, wmOperator *UNUSED(op))
1310 {
1311         Object *ob = ED_object_active_context(C);
1312         Mesh *me= ob->data;
1313
1314         if(!CustomData_external_test(&me->ldata, CD_MDISPS))
1315                 return OPERATOR_CANCELLED;
1316
1317         // XXX don't remove..
1318         CustomData_external_remove(&me->ldata, &me->id, CD_MDISPS, me->totloop);
1319         
1320         return OPERATOR_FINISHED;
1321 }
1322
1323 void OBJECT_OT_multires_external_pack(wmOperatorType *ot)
1324 {
1325         ot->name= "Multires Pack External";
1326         ot->description= "Pack displacements from an external file";
1327         ot->idname= "OBJECT_OT_multires_external_pack";
1328
1329         ot->poll= multires_poll;
1330         ot->exec= multires_external_pack_exec;
1331         
1332         /* flags */
1333         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1334 }
1335
1336 /********************* multires apply base ***********************/
1337 static int multires_base_apply_exec(bContext *C, wmOperator *op)
1338 {
1339         Object *ob = ED_object_active_context(C);
1340         MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
1341         
1342         if (!mmd)
1343                 return OPERATOR_CANCELLED;
1344         
1345         multiresModifier_base_apply(mmd, ob);
1346
1347         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1348         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1349         
1350         return OPERATOR_FINISHED;
1351 }
1352
1353 static int multires_base_apply_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1354 {
1355         if (edit_modifier_invoke_properties(C, op))
1356                 return multires_base_apply_exec(C, op);
1357         else
1358                 return OPERATOR_CANCELLED;
1359 }
1360
1361
1362 void OBJECT_OT_multires_base_apply(wmOperatorType *ot)
1363 {
1364         ot->name= "Multires Apply Base";
1365         ot->description= "Modify the base mesh to conform to the displaced mesh";
1366         ot->idname= "OBJECT_OT_multires_base_apply";
1367
1368         ot->poll= multires_poll;
1369         ot->invoke= multires_base_apply_invoke;
1370         ot->exec= multires_base_apply_exec;
1371         
1372         /* flags */
1373         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1374         edit_modifier_properties(ot);
1375 }
1376
1377
1378 /************************ mdef bind operator *********************/
1379
1380 static int meshdeform_poll(bContext *C)
1381 {
1382         return edit_modifier_poll_generic(C, &RNA_MeshDeformModifier, (1<<OB_MESH));
1383 }
1384
1385 static int meshdeform_bind_exec(bContext *C, wmOperator *op)
1386 {
1387         Scene *scene= CTX_data_scene(C);
1388         Object *ob = ED_object_active_context(C);
1389         MeshDeformModifierData *mmd = (MeshDeformModifierData *)edit_modifier_property_get(op, ob, eModifierType_MeshDeform);
1390         
1391         if (!mmd)
1392                 return OPERATOR_CANCELLED;
1393
1394         if(mmd->bindcagecos) {
1395                 MEM_freeN(mmd->bindcagecos);
1396                 if(mmd->dyngrid) MEM_freeN(mmd->dyngrid);
1397                 if(mmd->dyninfluences) MEM_freeN(mmd->dyninfluences);
1398                 if(mmd->bindinfluences) MEM_freeN(mmd->bindinfluences);
1399                 if(mmd->bindoffsets) MEM_freeN(mmd->bindoffsets);
1400                 if(mmd->dynverts) MEM_freeN(mmd->dynverts);
1401                 if(mmd->bindweights) MEM_freeN(mmd->bindweights); /* deprecated */
1402                 if(mmd->bindcos) MEM_freeN(mmd->bindcos); /* deprecated */
1403
1404                 mmd->bindcagecos= NULL;
1405                 mmd->dyngrid= NULL;
1406                 mmd->dyninfluences= NULL;
1407                 mmd->bindoffsets= NULL;
1408                 mmd->dynverts= NULL;
1409                 mmd->bindweights= NULL; /* deprecated */
1410                 mmd->bindcos= NULL; /* deprecated */
1411                 mmd->totvert= 0;
1412                 mmd->totcagevert= 0;
1413                 mmd->totinfluence= 0;
1414                 
1415                 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1416                 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1417         }
1418         else {
1419                 DerivedMesh *dm;
1420                 int mode= mmd->modifier.mode;
1421
1422                 /* force modifier to run, it will call binding routine */
1423                 mmd->bindfunc= mesh_deform_bind;
1424                 mmd->modifier.mode |= eModifierMode_Realtime;
1425
1426                 if(ob->type == OB_MESH) {
1427                         dm= mesh_create_derived_view(scene, ob, 0);
1428                         dm->release(dm);
1429                 }
1430                 else if(ob->type == OB_LATTICE) {
1431                         lattice_calc_modifiers(scene, ob);
1432                 }
1433                 else if(ob->type==OB_MBALL) {
1434                         makeDispListMBall(scene, ob);
1435                 }
1436                 else if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
1437                         makeDispListCurveTypes(scene, ob, 0);
1438                 }
1439
1440                 mmd->bindfunc= NULL;
1441                 mmd->modifier.mode= mode;
1442         }
1443         
1444         return OPERATOR_FINISHED;
1445 }
1446
1447 static int meshdeform_bind_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1448 {
1449         if (edit_modifier_invoke_properties(C, op))
1450                 return meshdeform_bind_exec(C, op);
1451         else 
1452                 return OPERATOR_CANCELLED;
1453 }
1454
1455 void OBJECT_OT_meshdeform_bind(wmOperatorType *ot)
1456 {
1457         /* identifiers */
1458         ot->name= "Mesh Deform Bind";
1459         ot->description = "Bind mesh to cage in mesh deform modifier";
1460         ot->idname= "OBJECT_OT_meshdeform_bind";
1461         
1462         /* api callbacks */
1463         ot->poll= meshdeform_poll;
1464         ot->invoke= meshdeform_bind_invoke;
1465         ot->exec= meshdeform_bind_exec;
1466         
1467         /* flags */
1468         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1469         edit_modifier_properties(ot);
1470 }
1471
1472 /****************** explode refresh operator *********************/
1473
1474 static int explode_poll(bContext *C)
1475 {
1476         return edit_modifier_poll_generic(C, &RNA_ExplodeModifier, 0);
1477 }
1478
1479 static int explode_refresh_exec(bContext *C, wmOperator *op)
1480 {
1481         Object *ob = ED_object_active_context(C);
1482         ExplodeModifierData *emd = (ExplodeModifierData *)edit_modifier_property_get(op, ob, eModifierType_Explode);
1483         
1484         if (!emd)
1485                 return OPERATOR_CANCELLED;
1486
1487         emd->flag |= eExplodeFlag_CalcFaces;
1488
1489         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1490         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1491         
1492         return OPERATOR_FINISHED;
1493 }
1494
1495 static int explode_refresh_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1496 {
1497         if (edit_modifier_invoke_properties(C, op))
1498                 return explode_refresh_exec(C, op);
1499         else
1500                 return OPERATOR_CANCELLED;
1501 }
1502
1503
1504 void OBJECT_OT_explode_refresh(wmOperatorType *ot)
1505 {
1506         ot->name= "Explode Refresh";
1507         ot->description= "Refresh data in the Explode modifier";
1508         ot->idname= "OBJECT_OT_explode_refresh";
1509
1510         ot->poll= explode_poll;
1511         ot->invoke= explode_refresh_invoke;
1512         ot->exec= explode_refresh_exec;
1513         
1514         /* flags */
1515         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1516         edit_modifier_properties(ot);
1517 }
1518
1519
1520 /****************** ocean bake operator *********************/
1521
1522 static int ocean_bake_poll(bContext *C)
1523 {
1524         return edit_modifier_poll_generic(C, &RNA_OceanModifier, 0);
1525 }
1526
1527 /* copied from init_ocean_modifier, MOD_ocean.c */
1528 static void init_ocean_modifier_bake(struct Ocean *oc, struct OceanModifierData *omd)
1529 {
1530         int do_heightfield, do_chop, do_normals, do_jacobian;
1531         
1532         if (!omd || !oc) return; 
1533         
1534         do_heightfield = TRUE;
1535         do_chop = (omd->chop_amount > 0);
1536         do_normals = (omd->flag & MOD_OCEAN_GENERATE_NORMALS);
1537         do_jacobian = (omd->flag & MOD_OCEAN_GENERATE_FOAM);
1538         
1539         BKE_init_ocean(oc, omd->resolution*omd->resolution, omd->resolution*omd->resolution, omd->spatial_size, omd->spatial_size, 
1540                                    omd->wind_velocity, omd->smallest_wave, 1.0, omd->wave_direction, omd->damp, omd->wave_alignment, 
1541                                    omd->depth, omd->time,
1542                                    do_heightfield, do_chop, do_normals, do_jacobian,
1543                                    omd->seed);
1544 }
1545
1546 typedef struct OceanBakeJob {
1547         /* from wmJob */
1548         void *owner;
1549         short *stop, *do_update;
1550         float *progress;
1551         int current_frame;
1552         struct OceanCache *och;
1553         struct Ocean *ocean;
1554         struct OceanModifierData *omd;
1555 } OceanBakeJob;
1556
1557 static void oceanbake_free(void *customdata)
1558 {
1559         OceanBakeJob *oj= customdata;
1560         MEM_freeN(oj);
1561 }
1562
1563 /* called by oceanbake, only to check job 'stop' value */
1564 static int oceanbake_breakjob(void *UNUSED(customdata))
1565 {
1566         //OceanBakeJob *ob= (OceanBakeJob *)customdata;
1567         //return *(ob->stop);
1568         
1569         /* this is not nice yet, need to make the jobs list template better 
1570          * for identifying/acting upon various different jobs */
1571         /* but for now we'll reuse the render break... */
1572         return (G.afbreek);
1573 }
1574
1575 /* called by oceanbake, wmJob sends notifier */
1576 static void oceanbake_update(void *customdata, float progress, int *cancel)
1577 {
1578         OceanBakeJob *oj= customdata;
1579         
1580         if (oceanbake_breakjob(oj))
1581                 *cancel = 1;
1582         
1583         *(oj->do_update)= 1;
1584         *(oj->progress)= progress;
1585 }
1586
1587 static void oceanbake_startjob(void *customdata, short *stop, short *do_update, float *progress)
1588 {
1589         OceanBakeJob *oj= customdata;
1590         
1591         oj->stop= stop;
1592         oj->do_update = do_update;
1593         oj->progress = progress;
1594         
1595         G.afbreek= 0;   /* XXX shared with render - replace with job 'stop' switch */
1596         
1597         BKE_bake_ocean(oj->ocean, oj->och, oceanbake_update, (void *)oj);
1598         
1599         *do_update= 1;
1600         *stop = 0;
1601 }
1602
1603 static void oceanbake_endjob(void *customdata)
1604 {
1605         OceanBakeJob *oj= customdata;
1606         
1607         if (oj->ocean) {
1608                 BKE_free_ocean(oj->ocean);
1609                 oj->ocean = NULL;
1610         }
1611         
1612         oj->omd->oceancache = oj->och;
1613         oj->omd->cached = TRUE;
1614 }
1615
1616 static int ocean_bake_exec(bContext *C, wmOperator *op)
1617 {
1618         Object *ob = ED_object_active_context(C);
1619         OceanModifierData *omd = (OceanModifierData *)edit_modifier_property_get(op, ob, eModifierType_Ocean);
1620         Scene *scene = CTX_data_scene(C);
1621         OceanCache *och;
1622         struct Ocean *ocean;
1623         int f, cfra, i=0;
1624         int free= RNA_boolean_get(op->ptr, "free");
1625         
1626         wmJob *steve;
1627         OceanBakeJob *oj;
1628         
1629         if (!omd)
1630                 return OPERATOR_CANCELLED;
1631         
1632         if (free) {
1633                 omd->refresh |= MOD_OCEAN_REFRESH_CLEAR_CACHE;
1634                 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1635                 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1636                 return OPERATOR_FINISHED;
1637         }
1638
1639         och = BKE_init_ocean_cache(omd->cachepath, modifier_path_relbase(ob),
1640                                    omd->bakestart, omd->bakeend, omd->wave_scale,
1641                                    omd->chop_amount, omd->foam_coverage, omd->foam_fade, omd->resolution);
1642         
1643         och->time = MEM_mallocN(och->duration*sizeof(float), "foam bake time");
1644         
1645         cfra = scene->r.cfra;
1646         
1647         /* precalculate time variable before baking */
1648         for (f=omd->bakestart; f<=omd->bakeend; f++) {
1649                 /* from physics_fluid.c:
1650                  
1651                  * XXX: This can't be used due to an anim sys optimisation that ignores recalc object animation,
1652                  * leaving it for the depgraph (this ignores object animation such as modifier properties though... :/ )
1653                  * --> BKE_animsys_evaluate_all_animation(G.main, eval_time);
1654                  * This doesn't work with drivers:
1655                  * --> BKE_animsys_evaluate_animdata(&fsDomain->id, fsDomain->adt, eval_time, ADT_RECALC_ALL);
1656                  */
1657                 
1658                 /* Modifying the global scene isn't nice, but we can do it in 
1659                  * this part of the process before a threaded job is created */
1660                 
1661                 //scene->r.cfra = f;
1662                 //ED_update_for_newframe(CTX_data_main(C), scene, CTX_wm_screen(C), 1);
1663                 
1664                 /* ok, this doesn't work with drivers, but is way faster. 
1665                  * let's use this for now and hope nobody wants to drive the time value... */
1666                 BKE_animsys_evaluate_animdata(scene, (ID *)ob, ob->adt, f, ADT_RECALC_ANIM);
1667                 
1668                 och->time[i] = omd->time;
1669                 i++;
1670         }
1671         
1672         /* make a copy of ocean to use for baking - threadsafety */
1673         ocean = BKE_add_ocean();
1674         init_ocean_modifier_bake(ocean, omd);
1675         
1676         /*
1677          BKE_bake_ocean(ocean, och);
1678         
1679         omd->oceancache = och;
1680         omd->cached = TRUE;
1681         
1682         scene->r.cfra = cfra;
1683         
1684         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1685         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1686         */
1687         
1688         /* job stuff */
1689         
1690         scene->r.cfra = cfra;
1691         
1692         /* setup job */
1693         steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Ocean Simulation", WM_JOB_PROGRESS);
1694         oj= MEM_callocN(sizeof(OceanBakeJob), "ocean bake job");
1695         oj->ocean = ocean;
1696         oj->och = och;
1697         oj->omd = omd;
1698         
1699         WM_jobs_customdata(steve, oj, oceanbake_free);
1700         WM_jobs_timer(steve, 0.1, NC_OBJECT|ND_MODIFIER, NC_OBJECT|ND_MODIFIER);
1701         WM_jobs_callbacks(steve, oceanbake_startjob, NULL, NULL, oceanbake_endjob);
1702         
1703         WM_jobs_start(CTX_wm_manager(C), steve);
1704         
1705         
1706         
1707         return OPERATOR_FINISHED;
1708 }
1709
1710 static int ocean_bake_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1711 {
1712         if (edit_modifier_invoke_properties(C, op))
1713                 return ocean_bake_exec(C, op);
1714         else
1715                 return OPERATOR_CANCELLED;
1716 }
1717
1718
1719 void OBJECT_OT_ocean_bake(wmOperatorType *ot)
1720 {
1721         ot->name= "Bake Ocean";
1722         ot->description= "Bake an image sequence of ocean data";
1723         ot->idname= "OBJECT_OT_ocean_bake";
1724         
1725         ot->poll= ocean_bake_poll;
1726         ot->invoke= ocean_bake_invoke;
1727         ot->exec= ocean_bake_exec;
1728         
1729         /* flags */
1730         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1731         edit_modifier_properties(ot);
1732         
1733         RNA_def_boolean(ot->srna, "free", FALSE, "Free", "Free the bake, rather than generating it");
1734 }
1735