Multires: added back Reshape function, to copy vertex locations
[blender.git] / source / blender / editors / object / object_modifier.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * Contributor(s): Blender Foundation, 2009
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 #include <math.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31
32 #include "MEM_guardedalloc.h"
33
34 #include "DNA_action_types.h"
35 #include "DNA_curve_types.h"
36 #include "DNA_key_types.h"
37 #include "DNA_mesh_types.h"
38 #include "DNA_meshdata_types.h"
39 #include "DNA_modifier_types.h"
40 #include "DNA_object_types.h"
41 #include "DNA_object_force.h"
42 #include "DNA_scene_types.h"
43
44 #include "BLI_math.h"
45 #include "BLI_listbase.h"
46 #include "BLI_string.h"
47 #include "BLI_path_util.h"
48
49 #include "BKE_action.h"
50 #include "BKE_curve.h"
51 #include "BKE_context.h"
52 #include "BKE_depsgraph.h"
53 #include "BKE_displist.h"
54 #include "BKE_DerivedMesh.h"
55 #include "BKE_effect.h"
56 #include "BKE_global.h"
57 #include "BKE_key.h"
58 #include "BKE_lattice.h"
59 #include "BKE_mesh.h"
60 #include "BKE_modifier.h"
61 #include "BKE_multires.h"
62 #include "BKE_report.h"
63 #include "BKE_object.h"
64 #include "BKE_particle.h"
65 #include "BKE_softbody.h"
66 #include "BKE_utildefines.h"
67
68 #include "RNA_access.h"
69 #include "RNA_define.h"
70 #include "RNA_enum_types.h"
71
72 #include "ED_armature.h"
73 #include "ED_object.h"
74 #include "ED_screen.h"
75
76 #include "WM_api.h"
77 #include "WM_types.h"
78
79 #include "object_intern.h"
80
81 /******************************** API ****************************/
82
83 ModifierData *ED_object_modifier_add(ReportList *reports, Scene *scene, Object *ob, char *name, int type)
84 {
85         ModifierData *md=NULL, *new_md=NULL;
86         ModifierTypeInfo *mti = modifierType_getInfo(type);
87
88         if(mti->flags&eModifierTypeFlag_Single) {
89                 if(modifiers_findByType(ob, type)) {
90                         BKE_report(reports, RPT_WARNING, "Only one modifier of this type allowed.");
91                         return NULL;
92                 }
93         }
94
95         if(type == eModifierType_ParticleSystem) {
96                 /* don't need to worry about the new modifier's name, since that is set to the number
97                  * of particle systems which shouldn't have too many duplicates 
98                  */
99                 new_md = object_add_particle_system(scene, ob, name);
100         }
101         else {
102                 /* get new modifier data to add */
103                 new_md= modifier_new(type);
104                 
105                 if(mti->flags&eModifierTypeFlag_RequiresOriginalData) {
106                         md = ob->modifiers.first;
107                         
108                         while(md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform)
109                                 md = md->next;
110                         
111                         BLI_insertlinkbefore(&ob->modifiers, md, new_md);
112                 }
113                 else
114                         BLI_addtail(&ob->modifiers, new_md);
115
116                 if(name)
117                         BLI_strncpy(new_md->name, name, sizeof(new_md->name));
118
119                 /* make sure modifier data has unique name */
120
121                 modifier_unique_name(&ob->modifiers, new_md);
122                 
123                 /* special cases */
124                 if(type == eModifierType_Softbody) {
125                         if(!ob->soft) {
126                                 ob->soft= sbNew(scene);
127                                 ob->softflag |= OB_SB_GOAL|OB_SB_EDGES;
128                         }
129                 }
130                 else if(type == eModifierType_Collision) {
131                         if(!ob->pd)
132                                 ob->pd= object_add_collision_fields(0);
133                         
134                         ob->pd->deflect= 1;
135                         DAG_scene_sort(scene);
136                 }
137                 else if(type == eModifierType_Surface)
138                         DAG_scene_sort(scene);
139         }
140
141         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
142
143         return new_md;
144 }
145
146 int ED_object_modifier_remove(ReportList *reports, Scene *scene, Object *ob, ModifierData *md)
147 {
148         ModifierData *obmd;
149
150         /* It seems on rapid delete it is possible to
151          * get called twice on same modifier, so make
152          * sure it is in list. */
153         for(obmd=ob->modifiers.first; obmd; obmd=obmd->next)
154                 if(obmd==md)
155                         break;
156         
157         if(!obmd) {
158                 BKE_reportf(reports, RPT_ERROR, "Modifier '%s' not in object '%s'.", ob->id.name, md->name);
159                 return 0;
160         }
161
162         /* special cases */
163         if(md->type == eModifierType_ParticleSystem) {
164                 ParticleSystemModifierData *psmd=(ParticleSystemModifierData*)md;
165
166                 BLI_remlink(&ob->particlesystem, psmd->psys);
167                 psys_free(ob, psmd->psys);
168         }
169         else if(md->type == eModifierType_Softbody) {
170                 if(ob->soft) {
171                         sbFree(ob->soft);
172                         ob->soft= NULL;
173                         ob->softflag= 0;
174                 }
175         }
176         else if(md->type == eModifierType_Collision) {
177                 if(ob->pd)
178                         ob->pd->deflect= 0;
179
180         DAG_scene_sort(scene);
181         }
182         else if(md->type == eModifierType_Surface) {
183                 if(ob->pd && ob->pd->shape == PFIELD_SHAPE_SURFACE)
184                         ob->pd->shape = PFIELD_SHAPE_PLANE;
185
186         DAG_scene_sort(scene);
187         }
188         else if(md->type == eModifierType_Smoke) {
189                 ob->dt = OB_TEXTURE;
190         }
191         else if(md->type == eModifierType_Multires) {
192                 Mesh *me= ob->data;
193
194                 CustomData_external_remove(&me->fdata, &me->id, CD_MDISPS, me->totface);
195                 CustomData_free_layer_active(&me->fdata, CD_MDISPS, me->totface);
196         }
197
198         BLI_remlink(&ob->modifiers, md);
199         modifier_free(md);
200
201         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
202
203         return 1;
204 }
205
206 int ED_object_modifier_move_up(ReportList *reports, Object *ob, ModifierData *md)
207 {
208         if(md->prev) {
209                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
210
211                 if(mti->type!=eModifierTypeType_OnlyDeform) {
212                         ModifierTypeInfo *nmti = modifierType_getInfo(md->prev->type);
213
214                         if(nmti->flags&eModifierTypeFlag_RequiresOriginalData) {
215                                 BKE_report(reports, RPT_WARNING, "Cannot move above a modifier requiring original data.");
216                                 return 0;
217                         }
218                 }
219
220                 BLI_remlink(&ob->modifiers, md);
221                 BLI_insertlink(&ob->modifiers, md->prev->prev, md);
222         }
223
224         return 1;
225 }
226
227 int ED_object_modifier_move_down(ReportList *reports, Object *ob, ModifierData *md)
228 {
229         if(md->next) {
230                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
231
232                 if(mti->flags&eModifierTypeFlag_RequiresOriginalData) {
233                         ModifierTypeInfo *nmti = modifierType_getInfo(md->next->type);
234
235                         if(nmti->type!=eModifierTypeType_OnlyDeform) {
236                                 BKE_report(reports, RPT_WARNING, "Cannot move beyond a non-deforming modifier.");
237                                 return 0;
238                         }
239                 }
240
241                 BLI_remlink(&ob->modifiers, md);
242                 BLI_insertlink(&ob->modifiers, md->next, md);
243         }
244
245         return 1;
246 }
247
248 int ED_object_modifier_convert(ReportList *reports, Scene *scene, Object *ob, ModifierData *md)
249 {
250         Object *obn;
251         ParticleSystem *psys;
252         ParticleCacheKey *key, **cache;
253         ParticleSettings *part;
254         Mesh *me;
255         MVert *mvert;
256         MEdge *medge;
257         int a, k, kmax;
258         int totvert=0, totedge=0, cvert=0;
259         int totpart=0, totchild=0;
260
261         if(md->type != eModifierType_ParticleSystem) return 0;
262         if(ob && ob->mode & OB_MODE_PARTICLE_EDIT) return 0;
263
264         psys=((ParticleSystemModifierData *)md)->psys;
265         part= psys->part;
266
267         if(part->ren_as == PART_DRAW_GR || part->ren_as == PART_DRAW_OB) {
268                 ; // XXX make_object_duplilist_real(NULL);
269         }
270         else {
271                 if(part->ren_as != PART_DRAW_PATH || psys->pathcache == 0)
272                         return 0;
273
274                 totpart= psys->totcached;
275                 totchild= psys->totchildcache;
276
277                 if(totchild && (part->draw&PART_DRAW_PARENT)==0)
278                         totpart= 0;
279
280                 /* count */
281                 cache= psys->pathcache;
282                 for(a=0; a<totpart; a++) {
283                         key= cache[a];
284                         totvert+= key->steps+1;
285                         totedge+= key->steps;
286                 }
287
288                 cache= psys->childcache;
289                 for(a=0; a<totchild; a++) {
290                         key= cache[a];
291                         totvert+= key->steps+1;
292                         totedge+= key->steps;
293                 }
294
295                 if(totvert==0) return 0;
296
297                 /* add new mesh */
298                 obn= add_object(scene, OB_MESH);
299                 me= obn->data;
300                 
301                 me->totvert= totvert;
302                 me->totedge= totedge;
303                 
304                 me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
305                 me->medge= CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
306                 me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, 0);
307                 
308                 mvert= me->mvert;
309                 medge= me->medge;
310
311                 /* copy coordinates */
312                 cache= psys->pathcache;
313                 for(a=0; a<totpart; a++) {
314                         key= cache[a];
315                         kmax= key->steps;
316                         for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
317                                 VECCOPY(mvert->co,key->co);
318                                 if(k) {
319                                         medge->v1= cvert-1;
320                                         medge->v2= cvert;
321                                         medge->flag= ME_EDGEDRAW|ME_EDGERENDER|ME_LOOSEEDGE;
322                                         medge++;
323                                 }
324                         }
325                 }
326
327                 cache=psys->childcache;
328                 for(a=0; a<totchild; a++) {
329                         key=cache[a];
330                         kmax=key->steps;
331                         for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
332                                 VECCOPY(mvert->co,key->co);
333                                 if(k) {
334                                         medge->v1=cvert-1;
335                                         medge->v2=cvert;
336                                         medge->flag= ME_EDGEDRAW|ME_EDGERENDER|ME_LOOSEEDGE;
337                                         medge++;
338                                 }
339                         }
340                 }
341         }
342
343         DAG_scene_sort(scene);
344
345         return 1;
346 }
347
348 static int modifier_apply_shape(ReportList *reports, Scene *scene, Object *ob, ModifierData *md)
349 {
350         if (ob->type==OB_MESH) {
351                 DerivedMesh *dm;
352                 Mesh *me= ob->data;
353                 Key *key=me->key;
354                 KeyBlock *kb;
355                 
356                 if(!modifier_sameTopology(md)) {
357                         BKE_report(reports, RPT_ERROR, "Only deforming modifiers can be applied to Shapes");
358                         return 0;
359                 }
360                 mesh_pmv_off(ob, me);
361                 
362                 dm = mesh_create_derived_for_modifier(scene, ob, md);
363                 if (!dm) {
364                         BKE_report(reports, RPT_ERROR, "Modifier is disabled or returned error, skipping apply");
365                         return 0;
366                 }
367                 
368                 if(key == NULL) {
369                         key= me->key= add_key((ID *)me);
370                         key->type= KEY_RELATIVE;
371                         /* if that was the first key block added, then it was the basis.
372                          * Initialise it with the mesh, and add another for the modifier */
373                         kb= add_keyblock(scene, key);
374                         mesh_to_key(me, kb);
375                 }
376
377                 kb= add_keyblock(scene, key);
378                 DM_to_meshkey(dm, me, kb);
379                 
380                 dm->release(dm);
381         }
382         else {
383                 BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type");
384                 return 0;
385         }
386         return 1;
387 }
388
389 static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob, ModifierData *md)
390 {
391         if (ob->type==OB_MESH) {
392                 DerivedMesh *dm;
393                 Mesh *me = ob->data;
394                 if( me->key) {
395                         BKE_report(reports, RPT_ERROR, "Modifier cannot be applied to Mesh with Shape Keys");
396                         return 0;
397                 }
398                 
399                 mesh_pmv_off(ob, me);
400                 
401                 /* Multires: ensure that recent sculpting is applied */
402                 if(md->type == eModifierType_Multires)
403                         multires_force_update(ob);
404                 
405                 dm = mesh_create_derived_for_modifier(scene, ob, md);
406                 if (!dm) {
407                         BKE_report(reports, RPT_ERROR, "Modifier is disabled or returned error, skipping apply");
408                         return 0;
409                 }
410                 
411                 DM_to_mesh(dm, me);
412                 
413                 dm->release(dm);
414         } 
415         else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
416                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
417                 Curve *cu = ob->data;
418                 int numVerts;
419                 float (*vertexCos)[3];
420                 
421                 
422                 BKE_report(reports, RPT_INFO, "Applied modifier only changed CV points, not tesselated/bevel vertices");
423                 
424                 if (!(md->mode&eModifierMode_Realtime) || (mti->isDisabled && mti->isDisabled(md, 0))) {
425                         BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
426                         return 0;
427                 }
428                 
429                 vertexCos = curve_getVertexCos(cu, &cu->nurb, &numVerts);
430                 mti->deformVerts(md, ob, NULL, vertexCos, numVerts, 0, 0);
431                 curve_applyVertexCos(cu, &cu->nurb, vertexCos);
432
433                 MEM_freeN(vertexCos);
434                 
435                 DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
436         }
437         else {
438                 BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type");
439                 return 0;
440         }
441         return 1;
442 }
443
444 int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, ModifierData *md, int mode)
445 {
446         if (scene->obedit) {
447                 BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied in editmode");
448                 return 0;
449         } else if (((ID*) ob->data)->us>1) {
450                 BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied to multi-user data");
451                 return 0;
452         }
453
454         if (md!=ob->modifiers.first)
455                 BKE_report(reports, RPT_INFO, "Applied modifier was not first, result may not be as expected.");
456
457         if (mode == MODIFIER_APPLY_SHAPE) {
458                 if (!modifier_apply_shape(reports, scene, ob, md))
459                         return 0;
460         } else {
461                 if (!modifier_apply_obdata(reports, scene, ob, md))
462                         return 0;
463         }
464
465         BLI_remlink(&ob->modifiers, md);
466         modifier_free(md);
467
468         return 1;
469 }
470
471 int ED_object_modifier_copy(ReportList *reports, Object *ob, ModifierData *md)
472 {
473         ModifierData *nmd;
474         
475         nmd = modifier_new(md->type);
476         modifier_copyData(md, nmd);
477         BLI_insertlink(&ob->modifiers, md, nmd);
478         modifier_unique_name(&ob->modifiers, nmd);
479
480         return 1;
481 }
482
483 /***************************** OPERATORS ****************************/
484
485 static int modifier_poll(bContext *C)
486 {
487         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
488         return (ptr.data != NULL && !((ID*)ptr.id.data)->lib);
489 }
490
491 /************************ add modifier operator *********************/
492
493 static int modifier_add_exec(bContext *C, wmOperator *op)
494 {
495         Scene *scene= CTX_data_scene(C);
496     Object *ob = CTX_data_active_object(C);
497         int type= RNA_enum_get(op->ptr, "type");
498
499         if(!ED_object_modifier_add(op->reports, scene, ob, NULL, type))
500                 return OPERATOR_CANCELLED;
501
502         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
503         
504         return OPERATOR_FINISHED;
505 }
506
507 static EnumPropertyItem *modifier_add_itemf(bContext *C, PointerRNA *ptr, int *free)
508 {       
509         Object *ob= CTX_data_active_object(C);
510         EnumPropertyItem *item= NULL, *md_item;
511         ModifierTypeInfo *mti;
512         int totitem= 0, a;
513         
514         if(!ob)
515                 return modifier_type_items;
516
517         for(a=0; modifier_type_items[a].identifier; a++) {
518                 md_item= &modifier_type_items[a];
519
520                 if(md_item->identifier[0]) {
521                         mti= modifierType_getInfo(md_item->value);
522
523                         if(mti->flags & eModifierTypeFlag_NoUserAdd)
524                                 continue;
525
526                         if(!((mti->flags & eModifierTypeFlag_AcceptsCVs) ||
527                            (ob->type==OB_MESH && (mti->flags & eModifierTypeFlag_AcceptsMesh))))
528                                 continue;
529                 }
530
531                 RNA_enum_item_add(&item, &totitem, md_item);
532         }
533
534         RNA_enum_item_end(&item, &totitem);
535         *free= 1;
536
537         return item;
538 }
539
540 void OBJECT_OT_modifier_add(wmOperatorType *ot)
541 {
542         PropertyRNA *prop;
543
544         /* identifiers */
545         ot->name= "Add Modifier";
546         ot->description = "Add a modifier to the active object.";
547         ot->idname= "OBJECT_OT_modifier_add";
548         
549         /* api callbacks */
550         ot->invoke= WM_menu_invoke;
551         ot->exec= modifier_add_exec;
552         ot->poll= ED_operator_object_active_editable;
553         
554         /* flags */
555         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
556         
557         /* properties */
558         prop= RNA_def_enum(ot->srna, "type", modifier_type_items, eModifierType_Subsurf, "Type", "");
559         RNA_def_enum_funcs(prop, modifier_add_itemf);
560 }
561
562 /************************ remove modifier operator *********************/
563
564 static int modifier_remove_exec(bContext *C, wmOperator *op)
565 {
566         Scene *scene= CTX_data_scene(C);
567         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
568         Object *ob= ptr.id.data;
569         ModifierData *md= ptr.data;
570
571         if(!ED_object_modifier_remove(op->reports, scene, ob, md))
572                 return OPERATOR_CANCELLED;
573
574         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
575         
576         return OPERATOR_FINISHED;
577 }
578
579 void OBJECT_OT_modifier_remove(wmOperatorType *ot)
580 {
581         ot->name= "Remove Modifier";
582         ot->description= "Remove a modifier from the active object.";
583         ot->idname= "OBJECT_OT_modifier_remove";
584
585         ot->exec= modifier_remove_exec;
586         ot->poll= modifier_poll;
587         
588         /* flags */
589         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
590 }
591
592 /************************ move up modifier operator *********************/
593
594 static int modifier_move_up_exec(bContext *C, wmOperator *op)
595 {
596         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
597         Object *ob= ptr.id.data;
598         ModifierData *md= ptr.data;
599
600         if(!ED_object_modifier_move_up(op->reports, ob, md))
601                 return OPERATOR_CANCELLED;
602
603         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
604         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
605         
606         return OPERATOR_FINISHED;
607 }
608
609 void OBJECT_OT_modifier_move_up(wmOperatorType *ot)
610 {
611         ot->name= "Move Up Modifier";
612         ot->description= "Move modifier up in the stack.";
613         ot->idname= "OBJECT_OT_modifier_move_up";
614
615         ot->exec= modifier_move_up_exec;
616         ot->poll= modifier_poll;
617         
618         /* flags */
619         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
620 }
621
622 /************************ move down modifier operator *********************/
623
624 static int modifier_move_down_exec(bContext *C, wmOperator *op)
625 {
626         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
627         Object *ob= ptr.id.data;
628         ModifierData *md= ptr.data;
629
630         if(!ob || !md || !ED_object_modifier_move_down(op->reports, ob, md))
631                 return OPERATOR_CANCELLED;
632
633         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
634         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
635         
636         return OPERATOR_FINISHED;
637 }
638
639 void OBJECT_OT_modifier_move_down(wmOperatorType *ot)
640 {
641         ot->name= "Move Down Modifier";
642         ot->description= "Move modifier down in the stack.";
643         ot->idname= "OBJECT_OT_modifier_move_down";
644
645         ot->exec= modifier_move_down_exec;
646         ot->poll= modifier_poll;
647         
648         /* flags */
649         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
650 }
651
652 /************************ apply modifier operator *********************/
653
654 static int modifier_apply_exec(bContext *C, wmOperator *op)
655 {
656         Scene *scene= CTX_data_scene(C);
657         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
658         Object *ob= ptr.id.data;
659         ModifierData *md= ptr.data;
660         int apply_as= RNA_enum_get(op->ptr, "apply_as");
661
662         if(!ob || !md || !ED_object_modifier_apply(op->reports, scene, ob, md, apply_as))
663                 return OPERATOR_CANCELLED;
664
665         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
666         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
667         
668         return OPERATOR_FINISHED;
669 }
670
671 static EnumPropertyItem modifier_apply_as_items[] = {
672         {MODIFIER_APPLY_DATA, "DATA", 0, "Object Data", "Apply modifier to the object's data"},
673         {MODIFIER_APPLY_SHAPE, "SHAPE", 0, "New Shape", "Apply deform-only modifier to a new shape on this object"},
674         {0, NULL, 0, NULL, NULL}};
675
676 void OBJECT_OT_modifier_apply(wmOperatorType *ot)
677 {
678         ot->name= "Apply Modifier";
679         ot->description= "Apply modifier and remove from the stack.";
680         ot->idname= "OBJECT_OT_modifier_apply";
681
682         //ot->invoke= WM_menu_invoke;
683         ot->exec= modifier_apply_exec;
684         ot->poll= modifier_poll;
685         
686         /* flags */
687         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
688         
689         RNA_def_enum(ot->srna, "apply_as", modifier_apply_as_items, MODIFIER_APPLY_DATA, "Apply as", "How to apply the modifier to the geometry");
690 }
691
692 /************************ convert modifier operator *********************/
693
694 static int modifier_convert_exec(bContext *C, wmOperator *op)
695 {
696         Scene *scene= CTX_data_scene(C);
697         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
698         Object *ob= ptr.id.data;
699         ModifierData *md= ptr.data;
700
701         if(!ob || !md || !ED_object_modifier_convert(op->reports, scene, ob, md))
702                 return OPERATOR_CANCELLED;
703
704         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
705         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
706         
707         return OPERATOR_FINISHED;
708 }
709
710 void OBJECT_OT_modifier_convert(wmOperatorType *ot)
711 {
712         ot->name= "Convert Modifier";
713         ot->description= "Convert particles to a mesh object.";
714         ot->idname= "OBJECT_OT_modifier_convert";
715
716         ot->exec= modifier_convert_exec;
717         ot->poll= modifier_poll;
718         
719         /* flags */
720         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
721 }
722
723 /************************ copy modifier operator *********************/
724
725 static int modifier_copy_exec(bContext *C, wmOperator *op)
726 {
727         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
728         Object *ob= ptr.id.data;
729         ModifierData *md= ptr.data;
730
731         if(!ob || !md || !ED_object_modifier_copy(op->reports, ob, md))
732                 return OPERATOR_CANCELLED;
733
734         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
735         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
736         
737         return OPERATOR_FINISHED;
738 }
739
740 void OBJECT_OT_modifier_copy(wmOperatorType *ot)
741 {
742         ot->name= "Copy Modifier";
743         ot->description= "Duplicate modifier at the same position in the stack.";
744         ot->idname= "OBJECT_OT_modifier_copy";
745
746         ot->exec= modifier_copy_exec;
747         ot->poll= modifier_poll;
748         
749         /* flags */
750         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
751 }
752
753 /************* multires delete higher levels operator ****************/
754
755 static int multires_poll(bContext *C)
756 {
757         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_MultiresModifier);
758         ID *id= ptr.id.data;
759         return (ptr.data && id && !id->lib);
760 }
761
762 static int multires_higher_levels_delete_exec(bContext *C, wmOperator *op)
763 {
764         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_MultiresModifier);
765         Object *ob= ptr.id.data;
766         MultiresModifierData *mmd= ptr.data;
767
768         if(mmd) {
769                 multiresModifier_del_levels(mmd, ob, 1);
770                 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
771         }
772         
773         return OPERATOR_FINISHED;
774 }
775
776 void OBJECT_OT_multires_higher_levels_delete(wmOperatorType *ot)
777 {
778         ot->name= "Delete Higher Levels";
779         ot->idname= "OBJECT_OT_multires_higher_levels_delete";
780
781         ot->poll= multires_poll;
782         ot->exec= multires_higher_levels_delete_exec;
783         
784         /* flags */
785         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
786 }
787
788 /****************** multires subdivide operator *********************/
789
790 static int multires_subdivide_exec(bContext *C, wmOperator *op)
791 {
792         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_MultiresModifier);
793         Object *ob= ptr.id.data;
794         MultiresModifierData *mmd= ptr.data;
795
796         multiresModifier_subdivide(mmd, ob, 0, mmd->simple);
797
798         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
799         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
800         
801         return OPERATOR_FINISHED;
802 }
803
804 void OBJECT_OT_multires_subdivide(wmOperatorType *ot)
805 {
806         ot->name= "Multires Subdivide";
807         ot->description= "Add a new level of subdivision.";
808         ot->idname= "OBJECT_OT_multires_subdivide";
809
810         ot->poll= multires_poll;
811         ot->exec= multires_subdivide_exec;
812         
813         /* flags */
814         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
815 }
816
817 /****************** multires reshape operator *********************/
818
819 static int multires_reshape_exec(bContext *C, wmOperator *op)
820 {
821         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_MultiresModifier);
822         Object *ob= ptr.id.data, *secondob= NULL;
823         MultiresModifierData *mmd= ptr.data;
824
825         CTX_DATA_BEGIN(C, Object*, selob, selected_editable_objects) {
826                 if(selob->type == OB_MESH && selob != ob) {
827                         secondob= selob;
828                         break;
829                 }
830         }
831         CTX_DATA_END;
832
833         if(!secondob) {
834                 BKE_report(op->reports, RPT_ERROR, "Second selected mesh object require to copy shape from.");
835                 return OPERATOR_CANCELLED;
836         }
837         
838         if(!multiresModifier_reshape(mmd, ob, secondob)) {
839                 BKE_report(op->reports, RPT_ERROR, "Objects do not have the same number of vertices.");
840                 return OPERATOR_CANCELLED;
841         }
842
843         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
844         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
845         
846         return OPERATOR_FINISHED;
847 }
848
849 void OBJECT_OT_multires_reshape(wmOperatorType *ot)
850 {
851         ot->name= "Multires Reshape";
852         ot->description= "Copy vertex coordinates from other object.";
853         ot->idname= "OBJECT_OT_multires_reshape";
854
855         ot->poll= multires_poll;
856         ot->exec= multires_reshape_exec;
857         
858         /* flags */
859         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
860 }
861
862 /****************** multires save external operator *********************/
863
864 static int multires_save_external_exec(bContext *C, wmOperator *op)
865 {
866         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_MultiresModifier);
867         Object *ob= ptr.id.data;
868         Mesh *me= (ob)? ob->data: op->customdata;
869         char path[FILE_MAX];
870
871         if(CustomData_external_test(&me->fdata, CD_MDISPS))
872                 return OPERATOR_CANCELLED;
873         
874         RNA_string_get(op->ptr, "path", path);
875         if(G.save_over)
876                 BLI_makestringcode(G.sce, path); /* make relative */
877
878         CustomData_external_add(&me->fdata, &me->id, CD_MDISPS, me->totface, path);
879         CustomData_external_write(&me->fdata, &me->id, CD_MASK_MESH, me->totface, 0);
880         
881         return OPERATOR_FINISHED;
882 }
883
884 static int multires_save_external_invoke(bContext *C, wmOperator *op, wmEvent *event)
885 {
886         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_MultiresModifier);
887         Object *ob= ptr.id.data;
888         Mesh *me= ob->data;
889         char path[FILE_MAX];
890
891         if(CustomData_external_test(&me->fdata, CD_MDISPS))
892                 return OPERATOR_CANCELLED;
893
894         if(RNA_property_is_set(op->ptr, "path"))
895                 return multires_save_external_exec(C, op);
896         
897         op->customdata= me;
898
899         BLI_snprintf(path, sizeof(path), "//%s.btx", me->id.name+2);
900         RNA_string_set(op->ptr, "path", path);
901         
902         WM_event_add_fileselect(C, op);
903
904         return OPERATOR_RUNNING_MODAL;
905 }
906
907 void OBJECT_OT_multires_save_external(wmOperatorType *ot)
908 {
909         ot->name= "Multires Save External";
910         ot->description= "Save displacements to an external file.";
911         ot->idname= "OBJECT_OT_multires_save_external";
912
913         ot->poll= multires_poll;
914         ot->exec= multires_save_external_exec;
915         ot->invoke= multires_save_external_invoke;
916         
917         /* flags */
918         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
919
920         WM_operator_properties_filesel(ot, FOLDERFILE|BTXFILE, FILE_SPECIAL);
921 }
922
923 /****************** multires pack operator *********************/
924
925 static int multires_pack_external_exec(bContext *C, wmOperator *op)
926 {
927         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_MultiresModifier);
928         Object *ob= ptr.id.data;
929         Mesh *me= ob->data;
930
931         if(!CustomData_external_test(&me->fdata, CD_MDISPS))
932                 return OPERATOR_CANCELLED;
933
934         // XXX don't remove..
935         CustomData_external_remove(&me->fdata, &me->id, CD_MDISPS, me->totface);
936         
937         return OPERATOR_FINISHED;
938 }
939
940 void OBJECT_OT_multires_pack_external(wmOperatorType *ot)
941 {
942         ot->name= "Multires Pack External";
943         ot->description= "Pack displacements from an external file.";
944         ot->idname= "OBJECT_OT_multires_pack_external";
945
946         ot->poll= multires_poll;
947         ot->exec= multires_pack_external_exec;
948         
949         /* flags */
950         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
951 }
952
953 /************************ mdef bind operator *********************/
954
955 static int meshdeform_poll(bContext *C)
956 {
957         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_MeshDeformModifier);
958         ID *id= ptr.id.data;
959         return (ptr.data && id && !id->lib);
960 }
961
962 static int meshdeform_bind_exec(bContext *C, wmOperator *op)
963 {
964         Scene *scene= CTX_data_scene(C);
965         PointerRNA ptr= CTX_data_pointer_get(C, "modifier");
966         Object *ob= ptr.id.data;
967         MeshDeformModifierData *mmd= ptr.data;
968
969         if(mmd->bindcos) {
970                 if(mmd->bindweights) MEM_freeN(mmd->bindweights);
971                 if(mmd->bindcos) MEM_freeN(mmd->bindcos);
972                 if(mmd->dyngrid) MEM_freeN(mmd->dyngrid);
973                 if(mmd->dyninfluences) MEM_freeN(mmd->dyninfluences);
974                 if(mmd->dynverts) MEM_freeN(mmd->dynverts);
975                 mmd->bindweights= NULL;
976                 mmd->bindcos= NULL;
977                 mmd->dyngrid= NULL;
978                 mmd->dyninfluences= NULL;
979                 mmd->dynverts= NULL;
980                 mmd->totvert= 0;
981                 mmd->totcagevert= 0;
982                 mmd->totinfluence= 0;
983         }
984         else {
985                 DerivedMesh *dm;
986                 int mode= mmd->modifier.mode;
987
988                 /* force modifier to run, it will call binding routine */
989                 mmd->bindfunc= mesh_deform_bind;
990                 mmd->modifier.mode |= eModifierMode_Realtime;
991
992                 if(ob->type == OB_MESH) {
993                         dm= mesh_create_derived_view(scene, ob, 0);
994                         dm->release(dm);
995                 }
996                 else if(ob->type == OB_LATTICE) {
997                         lattice_calc_modifiers(scene, ob);
998                 }
999                 else if(ob->type==OB_MBALL) {
1000                         makeDispListMBall(scene, ob);
1001                 }
1002                 else if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
1003                         makeDispListCurveTypes(scene, ob, 0);
1004                 }
1005
1006                 mmd->bindfunc= NULL;
1007                 mmd->modifier.mode= mode;
1008         }
1009         
1010         return OPERATOR_FINISHED;
1011 }
1012
1013 void OBJECT_OT_meshdeform_bind(wmOperatorType *ot)
1014 {
1015         /* identifiers */
1016         ot->name= "Mesh Deform Bind";
1017         ot->description = "Bind mesh to cage in mesh deform modifier.";
1018         ot->idname= "OBJECT_OT_meshdeform_bind";
1019         
1020         /* api callbacks */
1021         ot->poll= meshdeform_poll;
1022         ot->exec= meshdeform_bind_exec;
1023         
1024         /* flags */
1025         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1026 }
1027
1028 /****************** explode refresh operator *********************/
1029
1030 static int explode_refresh_poll(bContext *C)
1031 {
1032         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_ExplodeModifier);
1033         ID *id= ptr.id.data;
1034         return (ptr.data && id && !id->lib);
1035 }
1036
1037 static int explode_refresh_exec(bContext *C, wmOperator *op)
1038 {
1039         PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_ExplodeModifier);
1040         Object *ob= ptr.id.data;
1041         ExplodeModifierData *emd= ptr.data;
1042
1043         emd->flag |= eExplodeFlag_CalcFaces;
1044
1045         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
1046         WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1047         
1048         return OPERATOR_FINISHED;
1049 }
1050
1051 void OBJECT_OT_explode_refresh(wmOperatorType *ot)
1052 {
1053         ot->name= "Explode Refresh";
1054         ot->description= "Refresh data in the Explode modifier.";
1055         ot->idname= "OBJECT_OT_explode_refresh";
1056
1057         ot->exec= explode_refresh_exec;
1058         ot->poll= explode_refresh_poll;
1059         
1060         /* flags */
1061         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1062 }
1063