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