4 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21 * All rights reserved.
23 * Contributor(s): Blender Foundation, 2009
25 * ***** END GPL LICENSE BLOCK *****
28 /** \file blender/editors/object/object_modifier.c
37 #include "MEM_guardedalloc.h"
39 #include "DNA_curve_types.h"
40 #include "DNA_key_types.h"
41 #include "DNA_mesh_types.h"
42 #include "DNA_meshdata_types.h"
43 #include "DNA_object_force.h"
44 #include "DNA_scene_types.h"
47 #include "BLI_listbase.h"
48 #include "BLI_string.h"
49 #include "BLI_path_util.h"
50 #include "BLI_editVert.h"
51 #include "BLI_utildefines.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"
61 #include "BKE_lattice.h"
64 #include "BKE_modifier.h"
65 #include "BKE_multires.h"
66 #include "BKE_report.h"
67 #include "BKE_object.h"
68 #include "BKE_particle.h"
69 #include "BKE_softbody.h"
70 #include "BKE_tessmesh.h"
72 #include "RNA_access.h"
73 #include "RNA_define.h"
74 #include "RNA_enum_types.h"
76 #include "ED_armature.h"
77 #include "ED_object.h"
78 #include "ED_screen.h"
84 #include "object_intern.h"
86 /******************************** API ****************************/
88 ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *scene, Object *ob, const char *name, int type)
90 ModifierData *md=NULL, *new_md=NULL;
91 ModifierTypeInfo *mti = modifierType_getInfo(type);
93 /* only geometry objects should be able to get modifiers [#25291] */
94 if(!ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) {
95 BKE_reportf(reports, RPT_WARNING, "Modifiers cannot be added to Object '%s'", ob->id.name+2);
99 if(mti->flags&eModifierTypeFlag_Single) {
100 if(modifiers_findByType(ob, type)) {
101 BKE_report(reports, RPT_WARNING, "Only one modifier of this type allowed.");
106 if(type == eModifierType_ParticleSystem) {
107 /* don't need to worry about the new modifier's name, since that is set to the number
108 * of particle systems which shouldn't have too many duplicates
110 new_md = object_add_particle_system(scene, ob, name);
113 /* get new modifier data to add */
114 new_md= modifier_new(type);
116 if(mti->flags&eModifierTypeFlag_RequiresOriginalData) {
117 md = ob->modifiers.first;
119 while(md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform)
122 BLI_insertlinkbefore(&ob->modifiers, md, new_md);
125 BLI_addtail(&ob->modifiers, new_md);
128 BLI_strncpy(new_md->name, name, sizeof(new_md->name));
130 /* make sure modifier data has unique name */
132 modifier_unique_name(&ob->modifiers, new_md);
135 if(type == eModifierType_Softbody) {
137 ob->soft= sbNew(scene);
138 ob->softflag |= OB_SB_GOAL|OB_SB_EDGES;
141 else if(type == eModifierType_Collision) {
143 ob->pd= object_add_collision_fields(0);
146 DAG_scene_sort(bmain, scene);
148 else if(type == eModifierType_Surface)
149 DAG_scene_sort(bmain, scene);
150 else if(type == eModifierType_Multires)
151 /* set totlvl from existing MDISPS layer if object already had it */
152 multiresModifier_set_levels_from_disps((MultiresModifierData *)new_md, ob);
155 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
160 int ED_object_modifier_remove(ReportList *reports, Main *bmain, Scene *scene, Object *ob, ModifierData *md)
163 int sort_depsgraph = 0;
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)
173 BKE_reportf(reports, RPT_ERROR, "Modifier '%s' not in object '%s'.", ob->id.name, md->name);
178 if(md->type == eModifierType_ParticleSystem) {
179 ParticleSystemModifierData *psmd=(ParticleSystemModifierData*)md;
181 BLI_remlink(&ob->particlesystem, psmd->psys);
182 psys_free(ob, psmd->psys);
185 else if(md->type == eModifierType_Softbody) {
192 else if(md->type == eModifierType_Collision) {
198 else if(md->type == eModifierType_Surface) {
199 if(ob->pd && ob->pd->shape == PFIELD_SHAPE_SURFACE)
200 ob->pd->shape = PFIELD_SHAPE_PLANE;
204 else if(md->type == eModifierType_Smoke) {
207 else if(md->type == eModifierType_Multires) {
212 /* ensure MDISPS CustomData layer is't used by another multires modifiers */
213 for(tmpmd= ob->modifiers.first; tmpmd; tmpmd= tmpmd->next)
214 if(tmpmd!=md && tmpmd->type == eModifierType_Multires) {
220 if(me->edit_btmesh) {
221 BMEditMesh *em= me->edit_btmesh;
222 /* CustomData_external_remove is used here only to mark layer as non-external
223 for further free-ing, so zero element count looks safer than em->totface */
224 CustomData_external_remove(&em->bm->ldata, &me->id, CD_MDISPS, 0);
225 BM_free_data_layer(em->bm, &em->bm->ldata, CD_MDISPS);
227 CustomData_external_remove(&me->ldata, &me->id, CD_MDISPS, me->totloop);
228 CustomData_free_layer_active(&me->ldata, CD_MDISPS, me->totloop);
233 if(ELEM(md->type, eModifierType_Softbody, eModifierType_Cloth) &&
234 ob->particlesystem.first == NULL) {
235 ob->mode &= ~OB_MODE_PARTICLE_EDIT;
238 BLI_remlink(&ob->modifiers, md);
241 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
243 /* sorting has to be done after the update so that dynamic systems can react properly */
245 DAG_scene_sort(bmain, scene);
250 int ED_object_modifier_move_up(ReportList *reports, Object *ob, ModifierData *md)
253 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
255 if(mti->type!=eModifierTypeType_OnlyDeform) {
256 ModifierTypeInfo *nmti = modifierType_getInfo(md->prev->type);
258 if(nmti->flags&eModifierTypeFlag_RequiresOriginalData) {
259 BKE_report(reports, RPT_WARNING, "Cannot move above a modifier requiring original data.");
264 BLI_remlink(&ob->modifiers, md);
265 BLI_insertlink(&ob->modifiers, md->prev->prev, md);
271 int ED_object_modifier_move_down(ReportList *reports, Object *ob, ModifierData *md)
274 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
276 if(mti->flags&eModifierTypeFlag_RequiresOriginalData) {
277 ModifierTypeInfo *nmti = modifierType_getInfo(md->next->type);
279 if(nmti->type!=eModifierTypeType_OnlyDeform) {
280 BKE_report(reports, RPT_WARNING, "Cannot move beyond a non-deforming modifier.");
285 BLI_remlink(&ob->modifiers, md);
286 BLI_insertlink(&ob->modifiers, md->next, md);
292 int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene *scene, Object *ob, ModifierData *md)
295 ParticleSystem *psys;
296 ParticleCacheKey *key, **cache;
297 ParticleSettings *part;
302 int totvert=0, totedge=0, cvert=0;
303 int totpart=0, totchild=0;
305 if(md->type != eModifierType_ParticleSystem) return 0;
306 if(ob && ob->mode & OB_MODE_PARTICLE_EDIT) return 0;
308 psys=((ParticleSystemModifierData *)md)->psys;
311 if(part->ren_as != PART_DRAW_PATH || psys->pathcache == NULL)
314 totpart= psys->totcached;
315 totchild= psys->totchildcache;
317 if(totchild && (part->draw&PART_DRAW_PARENT)==0)
321 cache= psys->pathcache;
322 for(a=0; a<totpart; a++) {
326 totvert+= key->steps+1;
327 totedge+= key->steps;
331 cache= psys->childcache;
332 for(a=0; a<totchild; a++) {
336 totvert+= key->steps+1;
337 totedge+= key->steps;
341 if(totvert==0) return 0;
344 obn= add_object(scene, OB_MESH);
347 me->totvert= totvert;
348 me->totedge= totedge;
350 me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
351 me->medge= CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
352 me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, 0);
357 /* copy coordinates */
358 cache= psys->pathcache;
359 for(a=0; a<totpart; a++) {
362 for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
363 VECCOPY(mvert->co,key->co);
367 medge->flag= ME_EDGEDRAW|ME_EDGERENDER|ME_LOOSEEDGE;
371 /* cheap trick to select the roots */
372 mvert->flag |= SELECT;
377 cache=psys->childcache;
378 for(a=0; a<totchild; a++) {
381 for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
382 VECCOPY(mvert->co,key->co);
386 medge->flag= ME_EDGEDRAW|ME_EDGERENDER|ME_LOOSEEDGE;
390 /* cheap trick to select the roots */
391 mvert->flag |= SELECT;
396 DAG_scene_sort(bmain, scene);
401 static int modifier_apply_shape(ReportList *reports, Scene *scene, Object *ob, ModifierData *md)
403 ModifierTypeInfo *mti= modifierType_getInfo(md->type);
407 if (mti->isDisabled && mti->isDisabled(md, 0)) {
408 BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
413 It should be ridiculously easy to extract the original verts that we want
414 and form the shape data. We can probably use the CD KEYINDEX layer (or
415 whatever I ended up calling it, too tired to check now), though this would
416 by necassity have to make some potentially ugly assumptions about the order
417 of the mesh data :-/ you can probably assume in 99% of cases that the first
418 element of a given index is the original, and any subsequent duplicates are
419 copies/interpolates, but that's an assumption that would need to be tested
420 and then predominantly stated in comments in a half dozen headers.
423 if (ob->type==OB_MESH) {
429 if(!modifier_sameTopology(md)) {
430 BKE_report(reports, RPT_ERROR, "Only deforming modifiers can be applied to Shapes");
435 dm = mesh_create_derived_for_modifier(scene, ob, md, 0);
437 BKE_report(reports, RPT_ERROR, "Modifier is disabled or returned error, skipping apply");
442 key= me->key= add_key((ID *)me);
443 key->type= KEY_RELATIVE;
444 /* if that was the first key block added, then it was the basis.
445 * Initialise it with the mesh, and add another for the modifier */
446 kb= add_keyblock(key, NULL);
450 kb= add_keyblock(key, md->name);
451 DM_to_meshkey(dm, me, kb);
456 BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type");
462 static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob, ModifierData *md)
464 ModifierTypeInfo *mti= modifierType_getInfo(md->type);
468 if (mti->isDisabled && mti->isDisabled(md, 0)) {
469 BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
473 if (ob->type==OB_MESH) {
476 MultiresModifierData *mmd= find_multires_modifier_before(scene, md);
479 BKE_report(reports, RPT_ERROR, "Modifier cannot be applied to Mesh with Shape Keys");
485 /* Multires: ensure that recent sculpting is applied */
486 if(md->type == eModifierType_Multires)
487 multires_force_update(ob);
489 if (mmd && mmd->totlvl && mti->type==eModifierTypeType_OnlyDeform) {
490 if(!multiresModifier_reshapeFromDeformMod (scene, mmd, ob, md)) {
491 BKE_report(reports, RPT_ERROR, "Multires modifier returned error, skipping apply");
495 dm = mesh_create_derived_for_modifier(scene, ob, md, 1);
497 BKE_report(reports, RPT_ERROR, "Modifier returned error, skipping apply");
501 DM_to_mesh(dm, me, ob);
505 if(md->type == eModifierType_Multires) {
506 CustomData_external_remove(&me->ldata, &me->id, CD_MDISPS, me->totloop);
507 CustomData_free_layer_active(&me->ldata, CD_MDISPS, me->totloop);
511 else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
514 float (*vertexCos)[3];
516 if (mti->type==eModifierTypeType_Constructive) {
517 BKE_report(reports, RPT_ERROR, "Cannot apply constructive modifiers on curve");
522 BKE_report(reports, RPT_INFO, "Applied modifier only changed CV points, not tesselated/bevel vertices");
524 vertexCos = curve_getVertexCos(cu, &cu->nurb, &numVerts);
525 mti->deformVerts(md, ob, NULL, vertexCos, numVerts, 0, 0);
526 curve_applyVertexCos(cu, &cu->nurb, vertexCos);
528 MEM_freeN(vertexCos);
530 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
533 BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type");
537 /* lattice modifier can be applied to particle system too */
538 if(ob->particlesystem.first) {
540 ParticleSystem *psys = ob->particlesystem.first;
542 for(; psys; psys=psys->next) {
544 if(psys->part->type != PART_HAIR)
547 psys_apply_hair_lattice(scene, ob, psys);
554 int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, ModifierData *md, int mode)
559 BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied in editmode");
561 } else if (((ID*) ob->data)->us>1) {
562 BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied to multi-user data");
566 if (md!=ob->modifiers.first)
567 BKE_report(reports, RPT_INFO, "Applied modifier was not first, result may not be as expected.");
569 /* allow apply of a not-realtime modifier, by first re-enabling realtime. */
571 md->mode |= eModifierMode_Realtime;
573 if (mode == MODIFIER_APPLY_SHAPE) {
574 if (!modifier_apply_shape(reports, scene, ob, md)) {
579 if (!modifier_apply_obdata(reports, scene, ob, md)) {
585 BLI_remlink(&ob->modifiers, md);
591 int ED_object_modifier_copy(ReportList *UNUSED(reports), Object *ob, ModifierData *md)
595 nmd = modifier_new(md->type);
596 modifier_copyData(md, nmd);
597 BLI_insertlink(&ob->modifiers, md, nmd);
598 modifier_unique_name(&ob->modifiers, nmd);
603 /************************ add modifier operator *********************/
605 static int modifier_add_exec(bContext *C, wmOperator *op)
607 Main *bmain= CTX_data_main(C);
608 Scene *scene= CTX_data_scene(C);
609 Object *ob = ED_object_active_context(C);
610 int type= RNA_enum_get(op->ptr, "type");
612 if(!ED_object_modifier_add(op->reports, bmain, scene, ob, NULL, type))
613 return OPERATOR_CANCELLED;
615 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
617 return OPERATOR_FINISHED;
620 static EnumPropertyItem *modifier_add_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free)
622 Object *ob= ED_object_active_context(C);
623 EnumPropertyItem *item= NULL, *md_item;
624 ModifierTypeInfo *mti;
628 return modifier_type_items;
630 for(a=0; modifier_type_items[a].identifier; a++) {
631 md_item= &modifier_type_items[a];
633 if(md_item->identifier[0]) {
634 mti= modifierType_getInfo(md_item->value);
636 if(mti->flags & eModifierTypeFlag_NoUserAdd)
639 if(!((mti->flags & eModifierTypeFlag_AcceptsCVs) ||
640 (ob->type==OB_MESH && (mti->flags & eModifierTypeFlag_AcceptsMesh))))
644 RNA_enum_item_add(&item, &totitem, md_item);
647 RNA_enum_item_end(&item, &totitem);
653 void OBJECT_OT_modifier_add(wmOperatorType *ot)
658 ot->name= "Add Modifier";
659 ot->description = "Add a modifier to the active object";
660 ot->idname= "OBJECT_OT_modifier_add";
663 ot->invoke= WM_menu_invoke;
664 ot->exec= modifier_add_exec;
665 ot->poll= ED_operator_object_active_editable;
668 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
671 prop= RNA_def_enum(ot->srna, "type", modifier_type_items, eModifierType_Subsurf, "Type", "");
672 RNA_def_enum_funcs(prop, modifier_add_itemf);
676 /************************ generic functions for operators using mod names and data context *********************/
678 static int edit_modifier_poll_generic(bContext *C, StructRNA *rna_type, int obtype_flag)
680 PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", rna_type);
681 Object *ob= (ptr.id.data)?ptr.id.data:ED_object_active_context(C);
683 if (!ob || ob->id.lib) return 0;
684 if (obtype_flag && ((1<<ob->type) & obtype_flag)==0) return 0;
685 if (ptr.id.data && ((ID*)ptr.id.data)->lib) return 0;
690 static int edit_modifier_poll(bContext *C)
692 return edit_modifier_poll_generic(C, &RNA_Modifier, 0);
695 static void edit_modifier_properties(wmOperatorType *ot)
697 RNA_def_string(ot->srna, "modifier", "", 32, "Modifier", "Name of the modifier to edit");
700 static int edit_modifier_invoke_properties(bContext *C, wmOperator *op)
702 PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
705 if (RNA_property_is_set(op->ptr, "modifier"))
710 RNA_string_set(op->ptr, "modifier", md->name);
717 static ModifierData *edit_modifier_property_get(wmOperator *op, Object *ob, int type)
719 char modifier_name[32];
721 RNA_string_get(op->ptr, "modifier", modifier_name);
723 md = modifiers_findByName(ob, modifier_name);
725 if (md && type != 0 && md->type != type)
731 /************************ remove modifier operator *********************/
733 static int modifier_remove_exec(bContext *C, wmOperator *op)
735 Main *bmain= CTX_data_main(C);
736 Scene *scene= CTX_data_scene(C);
737 Object *ob = ED_object_active_context(C);
738 ModifierData *md = edit_modifier_property_get(op, ob, 0);
739 int mode_orig = ob->mode;
741 if(!ob || !md || !ED_object_modifier_remove(op->reports, bmain, scene, ob, md))
742 return OPERATOR_CANCELLED;
744 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
746 /* if cloth/softbody was removed, particle mode could be cleared */
747 if(mode_orig & OB_MODE_PARTICLE_EDIT)
748 if((ob->mode & OB_MODE_PARTICLE_EDIT)==0)
749 if(scene->basact && scene->basact->object==ob)
750 WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, NULL);
752 return OPERATOR_FINISHED;
755 static int modifier_remove_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
757 if (edit_modifier_invoke_properties(C, op))
758 return modifier_remove_exec(C, op);
760 return OPERATOR_CANCELLED;
763 void OBJECT_OT_modifier_remove(wmOperatorType *ot)
765 ot->name= "Remove Modifier";
766 ot->description= "Remove a modifier from the active object";
767 ot->idname= "OBJECT_OT_modifier_remove";
769 ot->invoke= modifier_remove_invoke;
770 ot->exec= modifier_remove_exec;
771 ot->poll= edit_modifier_poll;
774 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
775 edit_modifier_properties(ot);
778 /************************ move up modifier operator *********************/
780 static int modifier_move_up_exec(bContext *C, wmOperator *op)
782 Object *ob = ED_object_active_context(C);
783 ModifierData *md = edit_modifier_property_get(op, ob, 0);
785 if(!ob || !md || !ED_object_modifier_move_up(op->reports, ob, md))
786 return OPERATOR_CANCELLED;
788 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
789 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
791 return OPERATOR_FINISHED;
794 static int modifier_move_up_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
796 if (edit_modifier_invoke_properties(C, op))
797 return modifier_move_up_exec(C, op);
799 return OPERATOR_CANCELLED;
802 void OBJECT_OT_modifier_move_up(wmOperatorType *ot)
804 ot->name= "Move Up Modifier";
805 ot->description= "Move modifier up in the stack";
806 ot->idname= "OBJECT_OT_modifier_move_up";
808 ot->invoke= modifier_move_up_invoke;
809 ot->exec= modifier_move_up_exec;
810 ot->poll= edit_modifier_poll;
813 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
814 edit_modifier_properties(ot);
817 /************************ move down modifier operator *********************/
819 static int modifier_move_down_exec(bContext *C, wmOperator *op)
821 Object *ob = ED_object_active_context(C);
822 ModifierData *md = edit_modifier_property_get(op, ob, 0);
824 if(!ob || !md || !ED_object_modifier_move_down(op->reports, ob, md))
825 return OPERATOR_CANCELLED;
827 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
828 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
830 return OPERATOR_FINISHED;
833 static int modifier_move_down_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
835 if (edit_modifier_invoke_properties(C, op))
836 return modifier_move_down_exec(C, op);
838 return OPERATOR_CANCELLED;
841 void OBJECT_OT_modifier_move_down(wmOperatorType *ot)
843 ot->name= "Move Down Modifier";
844 ot->description= "Move modifier down in the stack";
845 ot->idname= "OBJECT_OT_modifier_move_down";
847 ot->invoke= modifier_move_down_invoke;
848 ot->exec= modifier_move_down_exec;
849 ot->poll= edit_modifier_poll;
852 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
853 edit_modifier_properties(ot);
856 /************************ apply modifier operator *********************/
858 static int modifier_apply_exec(bContext *C, wmOperator *op)
860 Scene *scene= CTX_data_scene(C);
861 Object *ob = ED_object_active_context(C);
862 ModifierData *md = edit_modifier_property_get(op, ob, 0);
863 int apply_as= RNA_enum_get(op->ptr, "apply_as");
865 if(!ob || !md || !ED_object_modifier_apply(op->reports, scene, ob, md, apply_as)) {
866 return OPERATOR_CANCELLED;
869 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
870 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
872 return OPERATOR_FINISHED;
875 static int modifier_apply_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
877 if (edit_modifier_invoke_properties(C, op))
878 return modifier_apply_exec(C, op);
880 return OPERATOR_CANCELLED;
883 static EnumPropertyItem modifier_apply_as_items[] = {
884 {MODIFIER_APPLY_DATA, "DATA", 0, "Object Data", "Apply modifier to the object's data"},
885 {MODIFIER_APPLY_SHAPE, "SHAPE", 0, "New Shape", "Apply deform-only modifier to a new shape on this object"},
886 {0, NULL, 0, NULL, NULL}};
888 void OBJECT_OT_modifier_apply(wmOperatorType *ot)
890 ot->name= "Apply Modifier";
891 ot->description= "Apply modifier and remove from the stack";
892 ot->idname= "OBJECT_OT_modifier_apply";
894 ot->invoke= modifier_apply_invoke;
895 ot->exec= modifier_apply_exec;
896 ot->poll= edit_modifier_poll;
899 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
901 RNA_def_enum(ot->srna, "apply_as", modifier_apply_as_items, MODIFIER_APPLY_DATA, "Apply as", "How to apply the modifier to the geometry");
902 edit_modifier_properties(ot);
905 /************************ convert modifier operator *********************/
907 static int modifier_convert_exec(bContext *C, wmOperator *op)
909 Main *bmain= CTX_data_main(C);
910 Scene *scene= CTX_data_scene(C);
911 Object *ob = ED_object_active_context(C);
912 ModifierData *md = edit_modifier_property_get(op, ob, 0);
914 if(!ob || !md || !ED_object_modifier_convert(op->reports, bmain, scene, ob, md))
915 return OPERATOR_CANCELLED;
917 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
918 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
920 return OPERATOR_FINISHED;
923 static int modifier_convert_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
925 if (edit_modifier_invoke_properties(C, op))
926 return modifier_convert_exec(C, op);
928 return OPERATOR_CANCELLED;
931 void OBJECT_OT_modifier_convert(wmOperatorType *ot)
933 ot->name= "Convert Modifier";
934 ot->description= "Convert particles to a mesh object";
935 ot->idname= "OBJECT_OT_modifier_convert";
937 ot->invoke= modifier_convert_invoke;
938 ot->exec= modifier_convert_exec;
939 ot->poll= edit_modifier_poll;
942 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
943 edit_modifier_properties(ot);
946 /************************ copy modifier operator *********************/
948 static int modifier_copy_exec(bContext *C, wmOperator *op)
950 Object *ob = ED_object_active_context(C);
951 ModifierData *md = edit_modifier_property_get(op, ob, 0);
953 if(!ob || !md || !ED_object_modifier_copy(op->reports, ob, md))
954 return OPERATOR_CANCELLED;
956 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
957 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
959 return OPERATOR_FINISHED;
962 static int modifier_copy_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
964 if (edit_modifier_invoke_properties(C, op))
965 return modifier_copy_exec(C, op);
967 return OPERATOR_CANCELLED;
970 void OBJECT_OT_modifier_copy(wmOperatorType *ot)
972 ot->name= "Copy Modifier";
973 ot->description= "Duplicate modifier at the same position in the stack";
974 ot->idname= "OBJECT_OT_modifier_copy";
976 ot->invoke= modifier_copy_invoke;
977 ot->exec= modifier_copy_exec;
978 ot->poll= edit_modifier_poll;
981 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
982 edit_modifier_properties(ot);
985 /************* multires delete higher levels operator ****************/
987 static int multires_poll(bContext *C)
989 return edit_modifier_poll_generic(C, &RNA_MultiresModifier, (1<<OB_MESH));
992 static int multires_higher_levels_delete_exec(bContext *C, wmOperator *op)
994 Object *ob = ED_object_active_context(C);
995 MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
998 return OPERATOR_CANCELLED;
1000 multiresModifier_del_levels(mmd, ob, 1);
1002 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1004 return OPERATOR_FINISHED;
1007 static int multires_higher_levels_delete_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1009 if (edit_modifier_invoke_properties(C, op))
1010 return multires_higher_levels_delete_exec(C, op);
1012 return OPERATOR_CANCELLED;
1015 void OBJECT_OT_multires_higher_levels_delete(wmOperatorType *ot)
1017 ot->name= "Delete Higher Levels";
1018 ot->description= "Deletes the higher resolution mesh, potential loss of detail";
1019 ot->idname= "OBJECT_OT_multires_higher_levels_delete";
1021 ot->poll= multires_poll;
1022 ot->invoke= multires_higher_levels_delete_invoke;
1023 ot->exec= multires_higher_levels_delete_exec;
1026 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1027 edit_modifier_properties(ot);
1030 /****************** multires subdivide operator *********************/
1032 static int multires_subdivide_exec(bContext *C, wmOperator *op)
1034 Object *ob = ED_object_active_context(C);
1035 MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
1038 return OPERATOR_CANCELLED;
1040 multiresModifier_subdivide(mmd, ob, 0, mmd->simple);
1042 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1043 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1045 return OPERATOR_FINISHED;
1048 static int multires_subdivide_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1050 if (edit_modifier_invoke_properties(C, op))
1051 return multires_subdivide_exec(C, op);
1053 return OPERATOR_CANCELLED;
1056 void OBJECT_OT_multires_subdivide(wmOperatorType *ot)
1058 ot->name= "Multires Subdivide";
1059 ot->description= "Add a new level of subdivision";
1060 ot->idname= "OBJECT_OT_multires_subdivide";
1062 ot->poll= multires_poll;
1063 ot->invoke= multires_subdivide_invoke;
1064 ot->exec= multires_subdivide_exec;
1067 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1068 edit_modifier_properties(ot);
1071 /****************** multires reshape operator *********************/
1073 static int multires_reshape_exec(bContext *C, wmOperator *op)
1075 Object *ob= ED_object_active_context(C), *secondob= NULL;
1076 Scene *scene= CTX_data_scene(C);
1077 MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
1080 return OPERATOR_CANCELLED;
1082 CTX_DATA_BEGIN(C, Object*, selob, selected_editable_objects) {
1083 if(selob->type == OB_MESH && selob != ob) {
1091 BKE_report(op->reports, RPT_ERROR, "Second selected mesh object require to copy shape from.");
1092 return OPERATOR_CANCELLED;
1095 if(!multiresModifier_reshape(scene, mmd, ob, secondob)) {
1096 BKE_report(op->reports, RPT_ERROR, "Objects do not have the same number of vertices.");
1097 return OPERATOR_CANCELLED;
1100 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1101 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1103 return OPERATOR_FINISHED;
1106 static int multires_reshape_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1108 if (edit_modifier_invoke_properties(C, op))
1109 return multires_reshape_exec(C, op);
1111 return OPERATOR_CANCELLED;
1114 void OBJECT_OT_multires_reshape(wmOperatorType *ot)
1116 ot->name= "Multires Reshape";
1117 ot->description= "Copy vertex coordinates from other object";
1118 ot->idname= "OBJECT_OT_multires_reshape";
1120 ot->poll= multires_poll;
1121 ot->invoke= multires_reshape_invoke;
1122 ot->exec= multires_reshape_exec;
1125 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1126 edit_modifier_properties(ot);
1129 static int multires_test_exec(bContext *C, wmOperator *op)
1131 Object *ob= ED_object_active_context(C);
1132 Mesh *me = ob->data;
1135 int i, x = RNA_int_get(op->ptr, "x"), y = RNA_int_get(op->ptr, "y");
1137 if (ob->type != OB_MESH || !me)
1138 return OPERATOR_CANCELLED;
1140 mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
1142 return OPERATOR_CANCELLED;
1145 for (i=0; i<me->totpoly; i++, mp++) {
1149 ml = me->mloop + mp->loopstart;
1150 for (j=0; j<mp->totloop; j++, ml++) {
1151 MLoop *ml2 = me->mloop + mp->loopstart + (j+mp->totloop-1)%mp->totloop;
1152 MLoop *ml3 = me->mloop + mp->loopstart + (j+1)%mp->totloop;
1154 if ((me->mvert[ml->v].flag&SELECT) && (me->mvert[ml2->v].flag&SELECT) && (me->mvert[ml3->v].flag&SELECT)) {
1155 MDisps *md = mdisps + mp->loopstart + j;
1156 int res = sqrt(md->totdisp);
1158 if (x >= res) x = res-1;
1159 if (y >= res) y = res-1;
1161 md->disps[y*res + x][2] += 1.0;
1166 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1167 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1169 return OPERATOR_FINISHED;
1172 void OBJECT_OT_test_multires(wmOperatorType *ot)
1174 ot->name= "Multires Object Mode Test";
1175 ot->description= "";
1176 ot->idname= "OBJECT_OT_test_multires";
1178 ot->poll= multires_poll;
1179 ot->exec= multires_test_exec;
1182 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1183 RNA_def_int(ot->srna, "x", 0, 0, 100, "x", "x", 0, 100);
1184 RNA_def_int(ot->srna, "y", 0, 0, 100, "y", "y", 0, 100);
1189 /****************** multires save external operator *********************/
1191 static int multires_external_save_exec(bContext *C, wmOperator *op)
1193 Object *ob = ED_object_active_context(C);
1194 Mesh *me= (ob)? ob->data: op->customdata;
1195 char path[FILE_MAX];
1196 int relative= RNA_boolean_get(op->ptr, "relative_path");
1199 return OPERATOR_CANCELLED;
1201 if(CustomData_external_test(&me->ldata, CD_MDISPS))
1202 return OPERATOR_CANCELLED;
1204 RNA_string_get(op->ptr, "filepath", path);
1207 BLI_path_rel(path, G.main->name);
1209 CustomData_external_add(&me->ldata, &me->id, CD_MDISPS, me->totloop, path);
1210 CustomData_external_write(&me->ldata, &me->id, CD_MASK_MESH, me->totloop, 0);
1212 return OPERATOR_FINISHED;
1215 static int multires_external_save_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1217 Object *ob = ED_object_active_context(C);
1218 MultiresModifierData *mmd;
1220 char path[FILE_MAX];
1222 if (!edit_modifier_invoke_properties(C, op))
1223 return OPERATOR_CANCELLED;
1225 mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
1228 return OPERATOR_CANCELLED;
1230 if(CustomData_external_test(&me->ldata, CD_MDISPS))
1231 return OPERATOR_CANCELLED;
1233 if(!RNA_property_is_set(op->ptr, "relative_path"))
1234 RNA_boolean_set(op->ptr, "relative_path", U.flag & USER_RELPATHS);
1236 if(RNA_property_is_set(op->ptr, "filepath"))
1237 return multires_external_save_exec(C, op);
1241 BLI_snprintf(path, sizeof(path), "//%s.btx", me->id.name+2);
1242 RNA_string_set(op->ptr, "filepath", path);
1244 WM_event_add_fileselect(C, op);
1246 return OPERATOR_RUNNING_MODAL;
1249 void OBJECT_OT_multires_external_save(wmOperatorType *ot)
1251 ot->name= "Multires Save External";
1252 ot->description= "Save displacements to an external file";
1253 ot->idname= "OBJECT_OT_multires_external_save";
1255 // XXX modifier no longer in context after file browser .. ot->poll= multires_poll;
1256 ot->exec= multires_external_save_exec;
1257 ot->invoke= multires_external_save_invoke;
1258 ot->poll= multires_poll;
1261 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1263 WM_operator_properties_filesel(ot, FOLDERFILE|BTXFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH);
1264 edit_modifier_properties(ot);
1267 /****************** multires pack operator *********************/
1269 static int multires_external_pack_exec(bContext *C, wmOperator *UNUSED(op))
1271 Object *ob = ED_object_active_context(C);
1274 if(!CustomData_external_test(&me->ldata, CD_MDISPS))
1275 return OPERATOR_CANCELLED;
1277 // XXX don't remove..
1278 CustomData_external_remove(&me->ldata, &me->id, CD_MDISPS, me->totloop);
1280 return OPERATOR_FINISHED;
1283 void OBJECT_OT_multires_external_pack(wmOperatorType *ot)
1285 ot->name= "Multires Pack External";
1286 ot->description= "Pack displacements from an external file";
1287 ot->idname= "OBJECT_OT_multires_external_pack";
1289 ot->poll= multires_poll;
1290 ot->exec= multires_external_pack_exec;
1293 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1296 /********************* multires apply base ***********************/
1297 static int multires_base_apply_exec(bContext *C, wmOperator *op)
1299 Object *ob = ED_object_active_context(C);
1300 MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
1303 return OPERATOR_CANCELLED;
1305 multiresModifier_base_apply(mmd, ob);
1307 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1308 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1310 return OPERATOR_FINISHED;
1313 static int multires_base_apply_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1315 if (edit_modifier_invoke_properties(C, op))
1316 return multires_base_apply_exec(C, op);
1318 return OPERATOR_CANCELLED;
1322 void OBJECT_OT_multires_base_apply(wmOperatorType *ot)
1324 ot->name= "Multires Apply Base";
1325 ot->description= "Modify the base mesh to conform to the displaced mesh";
1326 ot->idname= "OBJECT_OT_multires_base_apply";
1328 ot->poll= multires_poll;
1329 ot->invoke= multires_base_apply_invoke;
1330 ot->exec= multires_base_apply_exec;
1333 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1334 edit_modifier_properties(ot);
1338 /************************ mdef bind operator *********************/
1340 static int meshdeform_poll(bContext *C)
1342 return edit_modifier_poll_generic(C, &RNA_MeshDeformModifier, (1<<OB_MESH));
1345 static int meshdeform_bind_exec(bContext *C, wmOperator *op)
1347 Scene *scene= CTX_data_scene(C);
1348 Object *ob = ED_object_active_context(C);
1349 MeshDeformModifierData *mmd = (MeshDeformModifierData *)edit_modifier_property_get(op, ob, eModifierType_MeshDeform);
1352 return OPERATOR_CANCELLED;
1354 if(mmd->bindcagecos) {
1355 if(mmd->bindcagecos) MEM_freeN(mmd->bindcagecos);
1356 if(mmd->dyngrid) MEM_freeN(mmd->dyngrid);
1357 if(mmd->dyninfluences) MEM_freeN(mmd->dyninfluences);
1358 if(mmd->bindinfluences) MEM_freeN(mmd->bindinfluences);
1359 if(mmd->bindoffsets) MEM_freeN(mmd->bindoffsets);
1360 if(mmd->dynverts) MEM_freeN(mmd->dynverts);
1361 if(mmd->bindweights) MEM_freeN(mmd->bindweights); /* deprecated */
1362 if(mmd->bindcos) MEM_freeN(mmd->bindcos); /* deprecated */
1364 mmd->bindcagecos= NULL;
1366 mmd->dyninfluences= NULL;
1367 mmd->bindoffsets= NULL;
1368 mmd->dynverts= NULL;
1369 mmd->bindweights= NULL; /* deprecated */
1370 mmd->bindcos= NULL; /* deprecated */
1372 mmd->totcagevert= 0;
1373 mmd->totinfluence= 0;
1375 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1376 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1380 int mode= mmd->modifier.mode;
1382 /* force modifier to run, it will call binding routine */
1383 mmd->bindfunc= mesh_deform_bind;
1384 mmd->modifier.mode |= eModifierMode_Realtime;
1386 if(ob->type == OB_MESH) {
1387 dm= mesh_create_derived_view(scene, ob, 0);
1390 else if(ob->type == OB_LATTICE) {
1391 lattice_calc_modifiers(scene, ob);
1393 else if(ob->type==OB_MBALL) {
1394 makeDispListMBall(scene, ob);
1396 else if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
1397 makeDispListCurveTypes(scene, ob, 0);
1400 mmd->bindfunc= NULL;
1401 mmd->modifier.mode= mode;
1404 return OPERATOR_FINISHED;
1407 static int meshdeform_bind_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1409 if (edit_modifier_invoke_properties(C, op))
1410 return meshdeform_bind_exec(C, op);
1412 return OPERATOR_CANCELLED;
1415 void OBJECT_OT_meshdeform_bind(wmOperatorType *ot)
1418 ot->name= "Mesh Deform Bind";
1419 ot->description = "Bind mesh to cage in mesh deform modifier";
1420 ot->idname= "OBJECT_OT_meshdeform_bind";
1423 ot->poll= meshdeform_poll;
1424 ot->invoke= meshdeform_bind_invoke;
1425 ot->exec= meshdeform_bind_exec;
1428 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1429 edit_modifier_properties(ot);
1432 /****************** explode refresh operator *********************/
1434 static int explode_poll(bContext *C)
1436 return edit_modifier_poll_generic(C, &RNA_ExplodeModifier, 0);
1439 static int explode_refresh_exec(bContext *C, wmOperator *op)
1441 Object *ob = ED_object_active_context(C);
1442 ExplodeModifierData *emd = (ExplodeModifierData *)edit_modifier_property_get(op, ob, eModifierType_Explode);
1445 return OPERATOR_CANCELLED;
1447 emd->flag |= eExplodeFlag_CalcFaces;
1449 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1450 WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
1452 return OPERATOR_FINISHED;
1455 static int explode_refresh_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1457 if (edit_modifier_invoke_properties(C, op))
1458 return explode_refresh_exec(C, op);
1460 return OPERATOR_CANCELLED;
1464 void OBJECT_OT_explode_refresh(wmOperatorType *ot)
1466 ot->name= "Explode Refresh";
1467 ot->description= "Refresh data in the Explode modifier";
1468 ot->idname= "OBJECT_OT_explode_refresh";
1470 ot->poll= explode_poll;
1471 ot->invoke= explode_refresh_invoke;
1472 ot->exec= explode_refresh_exec;
1475 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1476 edit_modifier_properties(ot);