2 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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.
18 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19 * All rights reserved.
21 * Contributor(s): Blender Foundation, 2009
23 * ***** END GPL LICENSE BLOCK *****
26 /** \file blender/editors/object/object_modifier.c
35 #include "MEM_guardedalloc.h"
37 #include "DNA_anim_types.h"
38 #include "DNA_armature_types.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"
46 #include "BLI_bitmap.h"
48 #include "BLI_listbase.h"
49 #include "BLI_string.h"
50 #include "BLI_string_utf8.h"
51 #include "BLI_path_util.h"
52 #include "BLI_utildefines.h"
54 #include "BKE_animsys.h"
55 #include "BKE_curve.h"
56 #include "BKE_context.h"
57 #include "BKE_depsgraph.h"
58 #include "BKE_displist.h"
59 #include "BKE_DerivedMesh.h"
60 #include "BKE_effect.h"
61 #include "BKE_global.h"
63 #include "BKE_lattice.h"
66 #include "BKE_mesh_mapping.h"
67 #include "BKE_modifier.h"
68 #include "BKE_multires.h"
69 #include "BKE_report.h"
70 #include "BKE_object.h"
71 #include "BKE_object_deform.h"
72 #include "BKE_ocean.h"
73 #include "BKE_paint.h"
74 #include "BKE_particle.h"
75 #include "BKE_softbody.h"
76 #include "BKE_editmesh.h"
78 #include "RNA_access.h"
79 #include "RNA_define.h"
80 #include "RNA_enum_types.h"
82 #include "ED_armature.h"
83 #include "ED_object.h"
84 #include "ED_screen.h"
90 #include "object_intern.h"
92 static void modifier_skin_customdata_delete(struct Object *ob);
94 /******************************** API ****************************/
96 ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *scene, Object *ob, const char *name, int type)
98 ModifierData *md = NULL, *new_md = NULL;
99 const ModifierTypeInfo *mti = modifierType_getInfo(type);
101 /* only geometry objects should be able to get modifiers [#25291] */
102 if (!ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) {
103 BKE_reportf(reports, RPT_WARNING, "Modifiers cannot be added to object '%s'", ob->id.name + 2);
107 if (mti->flags & eModifierTypeFlag_Single) {
108 if (modifiers_findByType(ob, type)) {
109 BKE_report(reports, RPT_WARNING, "Only one modifier of this type is allowed");
114 if (type == eModifierType_ParticleSystem) {
115 /* don't need to worry about the new modifier's name, since that is set to the number
116 * of particle systems which shouldn't have too many duplicates
118 new_md = object_add_particle_system(scene, ob, name);
121 /* get new modifier data to add */
122 new_md = modifier_new(type);
124 if (mti->flags & eModifierTypeFlag_RequiresOriginalData) {
125 md = ob->modifiers.first;
127 while (md && modifierType_getInfo(md->type)->type == eModifierTypeType_OnlyDeform)
130 BLI_insertlinkbefore(&ob->modifiers, md, new_md);
133 BLI_addtail(&ob->modifiers, new_md);
136 BLI_strncpy_utf8(new_md->name, name, sizeof(new_md->name));
139 /* make sure modifier data has unique name */
141 modifier_unique_name(&ob->modifiers, new_md);
144 if (type == eModifierType_Softbody) {
146 ob->soft = sbNew(scene);
147 ob->softflag |= OB_SB_GOAL | OB_SB_EDGES;
150 else if (type == eModifierType_Collision) {
152 ob->pd = object_add_collision_fields(0);
155 DAG_relations_tag_update(bmain);
157 else if (type == eModifierType_Surface)
158 DAG_relations_tag_update(bmain);
159 else if (type == eModifierType_Multires) {
160 /* set totlvl from existing MDISPS layer if object already had it */
161 multiresModifier_set_levels_from_disps((MultiresModifierData *)new_md, ob);
163 if (ob->mode & OB_MODE_SCULPT) {
164 /* ensure that grid paint mask layer is created */
165 BKE_sculpt_mask_layers_ensure(ob, (MultiresModifierData *)new_md);
168 else if (type == eModifierType_Skin) {
169 /* ensure skin-node customdata exists */
170 BKE_mesh_ensure_skin_customdata(ob->data);
174 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
179 /* Return true if the object has a modifier of type 'type' other than
180 * the modifier pointed to be 'exclude', otherwise returns false. */
181 static bool object_has_modifier(const Object *ob, const ModifierData *exclude,
186 for (md = ob->modifiers.first; md; md = md->next) {
187 if ((md != exclude) && (md->type == type))
194 /* If the object data of 'orig_ob' has other users, run 'callback' on
197 * If include_orig is true, the callback will run on 'orig_ob' too.
199 * If the callback ever returns true, iteration will stop and the
200 * function value will be true. Otherwise the function returns false.
202 bool ED_object_iter_other(Main *bmain, Object *orig_ob, const bool include_orig,
203 bool (*callback)(Object *ob, void *callback_data),
206 ID *ob_data_id = orig_ob->data;
207 int users = ob_data_id->us;
209 if (ob_data_id->flag & LIB_FAKEUSER)
212 /* First check that the object's data has multiple users */
215 int totfound = include_orig ? 0 : 1;
217 for (ob = bmain->object.first; ob && totfound < users;
220 if (((ob != orig_ob) || include_orig) &&
221 (ob->data == orig_ob->data))
223 if (callback(ob, callback_data))
230 else if (include_orig) {
231 return callback(orig_ob, callback_data);
237 static bool object_has_modifier_cb(Object *ob, void *data)
239 ModifierType type = *((ModifierType *)data);
241 return object_has_modifier(ob, NULL, type);
244 /* Use with ED_object_iter_other(). Sets the total number of levels
245 * for any multires modifiers on the object to the int pointed to by
247 bool ED_object_multires_update_totlevels_cb(Object *ob, void *totlevel_v)
250 int totlevel = *((int *)totlevel_v);
252 for (md = ob->modifiers.first; md; md = md->next) {
253 if (md->type == eModifierType_Multires) {
254 multires_set_tot_level(ob, (MultiresModifierData *)md, totlevel);
255 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
261 /* Return true if no modifier of type 'type' other than 'exclude' */
262 static bool object_modifier_safe_to_delete(Main *bmain, Object *ob,
263 ModifierData *exclude,
266 return (!object_has_modifier(ob, exclude, type) &&
267 !ED_object_iter_other(bmain, ob, false,
268 object_has_modifier_cb, &type));
271 static bool object_modifier_remove(Main *bmain, Object *ob, ModifierData *md,
272 bool *r_sort_depsgraph)
274 /* It seems on rapid delete it is possible to
275 * get called twice on same modifier, so make
276 * sure it is in list. */
277 if (BLI_findindex(&ob->modifiers, md) == -1) {
282 if (md->type == eModifierType_ParticleSystem) {
283 ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md;
285 BLI_remlink(&ob->particlesystem, psmd->psys);
286 psys_free(ob, psmd->psys);
289 else if (md->type == eModifierType_Softbody) {
296 else if (md->type == eModifierType_Collision) {
300 *r_sort_depsgraph = true;
302 else if (md->type == eModifierType_Surface) {
303 *r_sort_depsgraph = true;
305 else if (md->type == eModifierType_Multires) {
306 /* Delete MDisps layer if not used by another multires modifier */
307 if (object_modifier_safe_to_delete(bmain, ob, md, eModifierType_Multires))
308 multires_customdata_delete(ob->data);
310 else if (md->type == eModifierType_Skin) {
311 /* Delete MVertSkin layer if not used by another skin modifier */
312 if (object_modifier_safe_to_delete(bmain, ob, md, eModifierType_Skin))
313 modifier_skin_customdata_delete(ob);
316 if (ELEM(md->type, eModifierType_Softbody, eModifierType_Cloth) &&
317 BLI_listbase_is_empty(&ob->particlesystem))
319 ob->mode &= ~OB_MODE_PARTICLE_EDIT;
322 BLI_remlink(&ob->modifiers, md);
328 bool ED_object_modifier_remove(ReportList *reports, Main *bmain, Object *ob, ModifierData *md)
330 bool sort_depsgraph = false;
333 ok = object_modifier_remove(bmain, ob, md, &sort_depsgraph);
336 BKE_reportf(reports, RPT_ERROR, "Modifier '%s' not in object '%s'", md->name, ob->id.name);
340 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
341 DAG_relations_tag_update(bmain);
346 void ED_object_modifier_clear(Main *bmain, Object *ob)
348 ModifierData *md = ob->modifiers.first;
349 bool sort_depsgraph = false;
355 ModifierData *next_md;
359 object_modifier_remove(bmain, ob, md, &sort_depsgraph);
364 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
365 DAG_relations_tag_update(bmain);
368 int ED_object_modifier_move_up(ReportList *reports, Object *ob, ModifierData *md)
371 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
373 if (mti->type != eModifierTypeType_OnlyDeform) {
374 const ModifierTypeInfo *nmti = modifierType_getInfo(md->prev->type);
376 if (nmti->flags & eModifierTypeFlag_RequiresOriginalData) {
377 BKE_report(reports, RPT_WARNING, "Cannot move above a modifier requiring original data");
382 BLI_remlink(&ob->modifiers, md);
383 BLI_insertlinkbefore(&ob->modifiers, md->prev, md);
389 int ED_object_modifier_move_down(ReportList *reports, Object *ob, ModifierData *md)
392 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
394 if (mti->flags & eModifierTypeFlag_RequiresOriginalData) {
395 const ModifierTypeInfo *nmti = modifierType_getInfo(md->next->type);
397 if (nmti->type != eModifierTypeType_OnlyDeform) {
398 BKE_report(reports, RPT_WARNING, "Cannot move beyond a non-deforming modifier");
403 BLI_remlink(&ob->modifiers, md);
404 BLI_insertlinkafter(&ob->modifiers, md->next, md);
410 int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene *scene, Object *ob, ModifierData *md)
413 ParticleSystem *psys;
414 ParticleCacheKey *key, **cache;
415 ParticleSettings *part;
420 int totvert = 0, totedge = 0, cvert = 0;
421 int totpart = 0, totchild = 0;
423 if (md->type != eModifierType_ParticleSystem) return 0;
424 if (ob && ob->mode & OB_MODE_PARTICLE_EDIT) return 0;
426 psys = ((ParticleSystemModifierData *)md)->psys;
429 if (part->ren_as != PART_DRAW_PATH || psys->pathcache == NULL)
432 totpart = psys->totcached;
433 totchild = psys->totchildcache;
435 if (totchild && (part->draw & PART_DRAW_PARENT) == 0)
439 cache = psys->pathcache;
440 for (a = 0; a < totpart; a++) {
443 if (key->segments > 0) {
444 totvert += key->segments + 1;
445 totedge += key->segments;
449 cache = psys->childcache;
450 for (a = 0; a < totchild; a++) {
453 if (key->segments > 0) {
454 totvert += key->segments + 1;
455 totedge += key->segments;
459 if (totvert == 0) return 0;
462 obn = BKE_object_add(bmain, scene, OB_MESH);
465 me->totvert = totvert;
466 me->totedge = totedge;
468 me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
469 me->medge = CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
470 me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, 0);
475 /* copy coordinates */
476 cache = psys->pathcache;
477 for (a = 0; a < totpart; a++) {
479 kmax = key->segments;
480 for (k = 0; k <= kmax; k++, key++, cvert++, mvert++) {
481 copy_v3_v3(mvert->co, key->co);
483 medge->v1 = cvert - 1;
485 medge->flag = ME_EDGEDRAW | ME_EDGERENDER | ME_LOOSEEDGE;
489 /* cheap trick to select the roots */
490 mvert->flag |= SELECT;
495 cache = psys->childcache;
496 for (a = 0; a < totchild; a++) {
498 kmax = key->segments;
499 for (k = 0; k <= kmax; k++, key++, cvert++, mvert++) {
500 copy_v3_v3(mvert->co, key->co);
502 medge->v1 = cvert - 1;
504 medge->flag = ME_EDGEDRAW | ME_EDGERENDER | ME_LOOSEEDGE;
508 /* cheap trick to select the roots */
509 mvert->flag |= SELECT;
514 DAG_relations_tag_update(bmain);
519 static int modifier_apply_shape(ReportList *reports, Scene *scene, Object *ob, ModifierData *md)
521 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
525 if (mti->isDisabled && mti->isDisabled(md, 0)) {
526 BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
531 * It should be ridiculously easy to extract the original verts that we want
532 * and form the shape data. We can probably use the CD KEYINDEX layer (or
533 * whatever I ended up calling it, too tired to check now), though this would
534 * by necessity have to make some potentially ugly assumptions about the order
535 * of the mesh data :-/ you can probably assume in 99% of cases that the first
536 * element of a given index is the original, and any subsequent duplicates are
537 * copies/interpolates, but that's an assumption that would need to be tested
538 * and then predominantly stated in comments in a half dozen headers.
541 if (ob->type == OB_MESH) {
547 if (!modifier_isSameTopology(md) || mti->type == eModifierTypeType_NonGeometrical) {
548 BKE_report(reports, RPT_ERROR, "Only deforming modifiers can be applied to shapes");
552 dm = mesh_create_derived_for_modifier(scene, ob, md, 0);
554 BKE_report(reports, RPT_ERROR, "Modifier is disabled or returned error, skipping apply");
559 key = me->key = BKE_key_add((ID *)me);
560 key->type = KEY_RELATIVE;
561 /* if that was the first key block added, then it was the basis.
562 * Initialize it with the mesh, and add another for the modifier */
563 kb = BKE_keyblock_add(key, NULL);
564 BKE_keyblock_convert_from_mesh(me, kb);
567 kb = BKE_keyblock_add(key, md->name);
568 DM_to_meshkey(dm, me, kb);
573 BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type");
579 static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob, ModifierData *md)
581 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
585 if (mti->isDisabled && mti->isDisabled(md, 0)) {
586 BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
590 if (ob->type == OB_MESH) {
593 MultiresModifierData *mmd = find_multires_modifier_before(scene, md);
595 if (me->key && mti->type != eModifierTypeType_NonGeometrical) {
596 BKE_report(reports, RPT_ERROR, "Modifier cannot be applied to a mesh with shape keys");
600 /* Multires: ensure that recent sculpting is applied */
601 if (md->type == eModifierType_Multires)
602 multires_force_update(ob);
604 if (mmd && mmd->totlvl && mti->type == eModifierTypeType_OnlyDeform) {
605 if (!multiresModifier_reshapeFromDeformMod(scene, mmd, ob, md)) {
606 BKE_report(reports, RPT_ERROR, "Multires modifier returned error, skipping apply");
611 dm = mesh_create_derived_for_modifier(scene, ob, md, 1);
613 BKE_report(reports, RPT_ERROR, "Modifier returned error, skipping apply");
617 DM_to_mesh(dm, me, ob, CD_MASK_MESH, true);
619 if (md->type == eModifierType_Multires)
620 multires_customdata_delete(me);
623 else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
626 float (*vertexCos)[3];
628 if (ELEM(mti->type, eModifierTypeType_Constructive, eModifierTypeType_Nonconstructive)) {
629 BKE_report(reports, RPT_ERROR, "Cannot apply constructive modifiers on curve");
634 BKE_report(reports, RPT_INFO, "Applied modifier only changed CV points, not tessellated/bevel vertices");
636 vertexCos = BKE_curve_nurbs_vertexCos_get(&cu->nurb, &numVerts);
637 mti->deformVerts(md, ob, NULL, vertexCos, numVerts, 0);
638 BK_curve_nurbs_vertexCos_apply(&cu->nurb, vertexCos);
640 MEM_freeN(vertexCos);
642 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
645 BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type");
649 /* lattice modifier can be applied to particle system too */
650 if (ob->particlesystem.first) {
652 ParticleSystem *psys = ob->particlesystem.first;
654 for (; psys; psys = psys->next) {
656 if (psys->part->type != PART_HAIR)
659 psys_apply_hair_lattice(scene, ob, psys);
666 int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, ModifierData *md, int mode)
671 BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied in edit mode");
674 else if (((ID *) ob->data)->us > 1) {
675 BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied to multi-user data");
678 else if ((ob->mode & OB_MODE_SCULPT) &&
679 (find_multires_modifier_before(scene, md)) &&
680 (modifier_isSameTopology(md) == false))
682 BKE_report(reports, RPT_ERROR, "Constructive modifier cannot be applied to multi-res data in sculpt mode");
686 if (md != ob->modifiers.first)
687 BKE_report(reports, RPT_INFO, "Applied modifier was not first, result may not be as expected");
689 /* allow apply of a not-realtime modifier, by first re-enabling realtime. */
690 prev_mode = md->mode;
691 md->mode |= eModifierMode_Realtime;
693 if (mode == MODIFIER_APPLY_SHAPE) {
694 if (!modifier_apply_shape(reports, scene, ob, md)) {
695 md->mode = prev_mode;
700 if (!modifier_apply_obdata(reports, scene, ob, md)) {
701 md->mode = prev_mode;
706 BLI_remlink(&ob->modifiers, md);
712 int ED_object_modifier_copy(ReportList *UNUSED(reports), Object *ob, ModifierData *md)
716 nmd = modifier_new(md->type);
717 modifier_copyData(md, nmd);
718 BLI_insertlinkafter(&ob->modifiers, md, nmd);
719 modifier_unique_name(&ob->modifiers, nmd);
724 /************************ add modifier operator *********************/
726 static int modifier_add_exec(bContext *C, wmOperator *op)
728 Main *bmain = CTX_data_main(C);
729 Scene *scene = CTX_data_scene(C);
730 Object *ob = ED_object_active_context(C);
731 int type = RNA_enum_get(op->ptr, "type");
733 if (!ED_object_modifier_add(op->reports, bmain, scene, ob, NULL, type))
734 return OPERATOR_CANCELLED;
736 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
738 return OPERATOR_FINISHED;
741 static EnumPropertyItem *modifier_add_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
743 Object *ob = ED_object_active_context(C);
744 EnumPropertyItem *item = NULL, *md_item, *group_item = NULL;
745 const ModifierTypeInfo *mti;
749 return modifier_type_items;
751 for (a = 0; modifier_type_items[a].identifier; a++) {
752 md_item = &modifier_type_items[a];
754 if (md_item->identifier[0]) {
755 mti = modifierType_getInfo(md_item->value);
757 if (mti->flags & eModifierTypeFlag_NoUserAdd)
760 if (!BKE_object_support_modifier_type_check(ob, md_item->value))
764 group_item = md_item;
771 RNA_enum_item_add(&item, &totitem, group_item);
775 RNA_enum_item_add(&item, &totitem, md_item);
778 RNA_enum_item_end(&item, &totitem);
784 void OBJECT_OT_modifier_add(wmOperatorType *ot)
789 ot->name = "Add Modifier";
790 ot->description = "Add a modifier to the active object";
791 ot->idname = "OBJECT_OT_modifier_add";
794 ot->invoke = WM_menu_invoke;
795 ot->exec = modifier_add_exec;
796 ot->poll = ED_operator_object_active_editable;
799 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
802 prop = RNA_def_enum(ot->srna, "type", modifier_type_items, eModifierType_Subsurf, "Type", "");
803 RNA_def_enum_funcs(prop, modifier_add_itemf);
807 /************************ generic functions for operators using mod names and data context *********************/
809 int edit_modifier_poll_generic(bContext *C, StructRNA *rna_type, int obtype_flag)
811 PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", rna_type);
812 Object *ob = (ptr.id.data) ? ptr.id.data : ED_object_active_context(C);
814 if (!ob || ob->id.lib) return 0;
815 if (obtype_flag && ((1 << ob->type) & obtype_flag) == 0) return 0;
816 if (ptr.id.data && ((ID *)ptr.id.data)->lib) return 0;
821 int edit_modifier_poll(bContext *C)
823 return edit_modifier_poll_generic(C, &RNA_Modifier, 0);
826 void edit_modifier_properties(wmOperatorType *ot)
828 RNA_def_string(ot->srna, "modifier", NULL, MAX_NAME, "Modifier", "Name of the modifier to edit");
831 int edit_modifier_invoke_properties(bContext *C, wmOperator *op)
835 if (RNA_struct_property_is_set(op->ptr, "modifier")) {
839 PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
842 RNA_string_set(op->ptr, "modifier", md->name);
850 ModifierData *edit_modifier_property_get(wmOperator *op, Object *ob, int type)
852 char modifier_name[MAX_NAME];
854 RNA_string_get(op->ptr, "modifier", modifier_name);
856 md = modifiers_findByName(ob, modifier_name);
858 if (md && type != 0 && md->type != type)
864 /************************ remove modifier operator *********************/
866 static int modifier_remove_exec(bContext *C, wmOperator *op)
868 Main *bmain = CTX_data_main(C);
869 Scene *scene = CTX_data_scene(C);
870 Object *ob = ED_object_active_context(C);
871 ModifierData *md = edit_modifier_property_get(op, ob, 0);
872 int mode_orig = ob->mode;
874 if (!md || !ED_object_modifier_remove(op->reports, bmain, ob, md))
875 return OPERATOR_CANCELLED;
877 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
879 /* if cloth/softbody was removed, particle mode could be cleared */
880 if (mode_orig & OB_MODE_PARTICLE_EDIT)
881 if ((ob->mode & OB_MODE_PARTICLE_EDIT) == 0)
882 if (scene->basact && scene->basact->object == ob)
883 WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, NULL);
885 return OPERATOR_FINISHED;
888 static int modifier_remove_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
890 if (edit_modifier_invoke_properties(C, op))
891 return modifier_remove_exec(C, op);
893 return OPERATOR_CANCELLED;
896 void OBJECT_OT_modifier_remove(wmOperatorType *ot)
898 ot->name = "Remove Modifier";
899 ot->description = "Remove a modifier from the active object";
900 ot->idname = "OBJECT_OT_modifier_remove";
902 ot->invoke = modifier_remove_invoke;
903 ot->exec = modifier_remove_exec;
904 ot->poll = edit_modifier_poll;
907 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
908 edit_modifier_properties(ot);
911 /************************ move up modifier operator *********************/
913 static int modifier_move_up_exec(bContext *C, wmOperator *op)
915 Object *ob = ED_object_active_context(C);
916 ModifierData *md = edit_modifier_property_get(op, ob, 0);
918 if (!md || !ED_object_modifier_move_up(op->reports, ob, md))
919 return OPERATOR_CANCELLED;
921 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
922 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
924 return OPERATOR_FINISHED;
927 static int modifier_move_up_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
929 if (edit_modifier_invoke_properties(C, op))
930 return modifier_move_up_exec(C, op);
932 return OPERATOR_CANCELLED;
935 void OBJECT_OT_modifier_move_up(wmOperatorType *ot)
937 ot->name = "Move Up Modifier";
938 ot->description = "Move modifier up in the stack";
939 ot->idname = "OBJECT_OT_modifier_move_up";
941 ot->invoke = modifier_move_up_invoke;
942 ot->exec = modifier_move_up_exec;
943 ot->poll = edit_modifier_poll;
946 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
947 edit_modifier_properties(ot);
950 /************************ move down modifier operator *********************/
952 static int modifier_move_down_exec(bContext *C, wmOperator *op)
954 Object *ob = ED_object_active_context(C);
955 ModifierData *md = edit_modifier_property_get(op, ob, 0);
957 if (!md || !ED_object_modifier_move_down(op->reports, ob, md))
958 return OPERATOR_CANCELLED;
960 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
961 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
963 return OPERATOR_FINISHED;
966 static int modifier_move_down_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
968 if (edit_modifier_invoke_properties(C, op))
969 return modifier_move_down_exec(C, op);
971 return OPERATOR_CANCELLED;
974 void OBJECT_OT_modifier_move_down(wmOperatorType *ot)
976 ot->name = "Move Down Modifier";
977 ot->description = "Move modifier down in the stack";
978 ot->idname = "OBJECT_OT_modifier_move_down";
980 ot->invoke = modifier_move_down_invoke;
981 ot->exec = modifier_move_down_exec;
982 ot->poll = edit_modifier_poll;
985 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
986 edit_modifier_properties(ot);
989 /************************ apply modifier operator *********************/
991 static int modifier_apply_exec(bContext *C, wmOperator *op)
993 Scene *scene = CTX_data_scene(C);
994 Object *ob = ED_object_active_context(C);
995 ModifierData *md = edit_modifier_property_get(op, ob, 0);
996 int apply_as = RNA_enum_get(op->ptr, "apply_as");
998 if (!md || !ED_object_modifier_apply(op->reports, scene, ob, md, apply_as)) {
999 return OPERATOR_CANCELLED;
1002 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1003 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
1005 return OPERATOR_FINISHED;
1008 static int modifier_apply_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
1010 if (edit_modifier_invoke_properties(C, op))
1011 return modifier_apply_exec(C, op);
1013 return OPERATOR_CANCELLED;
1016 static EnumPropertyItem modifier_apply_as_items[] = {
1017 {MODIFIER_APPLY_DATA, "DATA", 0, "Object Data", "Apply modifier to the object's data"},
1018 {MODIFIER_APPLY_SHAPE, "SHAPE", 0, "New Shape", "Apply deform-only modifier to a new shape on this object"},
1019 {0, NULL, 0, NULL, NULL}
1022 void OBJECT_OT_modifier_apply(wmOperatorType *ot)
1024 ot->name = "Apply Modifier";
1025 ot->description = "Apply modifier and remove from the stack";
1026 ot->idname = "OBJECT_OT_modifier_apply";
1028 ot->invoke = modifier_apply_invoke;
1029 ot->exec = modifier_apply_exec;
1030 ot->poll = edit_modifier_poll;
1033 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1035 RNA_def_enum(ot->srna, "apply_as", modifier_apply_as_items, MODIFIER_APPLY_DATA, "Apply as", "How to apply the modifier to the geometry");
1036 edit_modifier_properties(ot);
1039 /************************ convert modifier operator *********************/
1041 static int modifier_convert_exec(bContext *C, wmOperator *op)
1043 Main *bmain = CTX_data_main(C);
1044 Scene *scene = CTX_data_scene(C);
1045 Object *ob = ED_object_active_context(C);
1046 ModifierData *md = edit_modifier_property_get(op, ob, 0);
1048 if (!md || !ED_object_modifier_convert(op->reports, bmain, scene, ob, md))
1049 return OPERATOR_CANCELLED;
1051 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1052 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
1054 return OPERATOR_FINISHED;
1057 static int modifier_convert_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
1059 if (edit_modifier_invoke_properties(C, op))
1060 return modifier_convert_exec(C, op);
1062 return OPERATOR_CANCELLED;
1065 void OBJECT_OT_modifier_convert(wmOperatorType *ot)
1067 ot->name = "Convert Modifier";
1068 ot->description = "Convert particles to a mesh object";
1069 ot->idname = "OBJECT_OT_modifier_convert";
1071 ot->invoke = modifier_convert_invoke;
1072 ot->exec = modifier_convert_exec;
1073 ot->poll = edit_modifier_poll;
1076 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1077 edit_modifier_properties(ot);
1080 /************************ copy modifier operator *********************/
1082 static int modifier_copy_exec(bContext *C, wmOperator *op)
1084 Object *ob = ED_object_active_context(C);
1085 ModifierData *md = edit_modifier_property_get(op, ob, 0);
1087 if (!md || !ED_object_modifier_copy(op->reports, ob, md))
1088 return OPERATOR_CANCELLED;
1090 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1091 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
1093 return OPERATOR_FINISHED;
1096 static int modifier_copy_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
1098 if (edit_modifier_invoke_properties(C, op))
1099 return modifier_copy_exec(C, op);
1101 return OPERATOR_CANCELLED;
1104 void OBJECT_OT_modifier_copy(wmOperatorType *ot)
1106 ot->name = "Copy Modifier";
1107 ot->description = "Duplicate modifier at the same position in the stack";
1108 ot->idname = "OBJECT_OT_modifier_copy";
1110 ot->invoke = modifier_copy_invoke;
1111 ot->exec = modifier_copy_exec;
1112 ot->poll = edit_modifier_poll;
1115 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1116 edit_modifier_properties(ot);
1119 /************* multires delete higher levels operator ****************/
1121 static int multires_poll(bContext *C)
1123 return edit_modifier_poll_generic(C, &RNA_MultiresModifier, (1 << OB_MESH));
1126 static int multires_higher_levels_delete_exec(bContext *C, wmOperator *op)
1128 Object *ob = ED_object_active_context(C);
1129 MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
1132 return OPERATOR_CANCELLED;
1134 multiresModifier_del_levels(mmd, ob, 1);
1136 ED_object_iter_other(CTX_data_main(C), ob, true,
1137 ED_object_multires_update_totlevels_cb,
1140 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
1142 return OPERATOR_FINISHED;
1145 static int multires_higher_levels_delete_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
1147 if (edit_modifier_invoke_properties(C, op))
1148 return multires_higher_levels_delete_exec(C, op);
1150 return OPERATOR_CANCELLED;
1153 void OBJECT_OT_multires_higher_levels_delete(wmOperatorType *ot)
1155 ot->name = "Delete Higher Levels";
1156 ot->description = "Deletes the higher resolution mesh, potential loss of detail";
1157 ot->idname = "OBJECT_OT_multires_higher_levels_delete";
1159 ot->poll = multires_poll;
1160 ot->invoke = multires_higher_levels_delete_invoke;
1161 ot->exec = multires_higher_levels_delete_exec;
1164 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1165 edit_modifier_properties(ot);
1168 /****************** multires subdivide operator *********************/
1170 static int multires_subdivide_exec(bContext *C, wmOperator *op)
1172 Object *ob = ED_object_active_context(C);
1173 MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
1176 return OPERATOR_CANCELLED;
1178 multiresModifier_subdivide(mmd, ob, 0, mmd->simple);
1180 ED_object_iter_other(CTX_data_main(C), ob, true,
1181 ED_object_multires_update_totlevels_cb,
1184 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1185 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
1187 if (ob->mode & OB_MODE_SCULPT) {
1188 /* ensure that grid paint mask layer is created */
1189 BKE_sculpt_mask_layers_ensure(ob, mmd);
1192 return OPERATOR_FINISHED;
1195 static int multires_subdivide_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
1197 if (edit_modifier_invoke_properties(C, op))
1198 return multires_subdivide_exec(C, op);
1200 return OPERATOR_CANCELLED;
1203 void OBJECT_OT_multires_subdivide(wmOperatorType *ot)
1205 ot->name = "Multires Subdivide";
1206 ot->description = "Add a new level of subdivision";
1207 ot->idname = "OBJECT_OT_multires_subdivide";
1209 ot->poll = multires_poll;
1210 ot->invoke = multires_subdivide_invoke;
1211 ot->exec = multires_subdivide_exec;
1214 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1215 edit_modifier_properties(ot);
1218 /****************** multires reshape operator *********************/
1220 static int multires_reshape_exec(bContext *C, wmOperator *op)
1222 Object *ob = ED_object_active_context(C), *secondob = NULL;
1223 Scene *scene = CTX_data_scene(C);
1224 MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
1227 return OPERATOR_CANCELLED;
1229 if (mmd->lvl == 0) {
1230 BKE_report(op->reports, RPT_ERROR, "Reshape can work only with higher levels of subdivisions");
1231 return OPERATOR_CANCELLED;
1234 CTX_DATA_BEGIN(C, Object *, selob, selected_editable_objects)
1236 if (selob->type == OB_MESH && selob != ob) {
1244 BKE_report(op->reports, RPT_ERROR, "Second selected mesh object required to copy shape from");
1245 return OPERATOR_CANCELLED;
1248 if (!multiresModifier_reshape(scene, mmd, ob, secondob)) {
1249 BKE_report(op->reports, RPT_ERROR, "Objects do not have the same number of vertices");
1250 return OPERATOR_CANCELLED;
1253 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1254 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
1256 return OPERATOR_FINISHED;
1259 static int multires_reshape_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
1261 if (edit_modifier_invoke_properties(C, op))
1262 return multires_reshape_exec(C, op);
1264 return OPERATOR_CANCELLED;
1267 void OBJECT_OT_multires_reshape(wmOperatorType *ot)
1269 ot->name = "Multires Reshape";
1270 ot->description = "Copy vertex coordinates from other object";
1271 ot->idname = "OBJECT_OT_multires_reshape";
1273 ot->poll = multires_poll;
1274 ot->invoke = multires_reshape_invoke;
1275 ot->exec = multires_reshape_exec;
1278 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1279 edit_modifier_properties(ot);
1284 /****************** multires save external operator *********************/
1286 static int multires_external_save_exec(bContext *C, wmOperator *op)
1288 Object *ob = ED_object_active_context(C);
1289 Mesh *me = (ob) ? ob->data : op->customdata;
1290 char path[FILE_MAX];
1291 const bool relative = RNA_boolean_get(op->ptr, "relative_path");
1294 return OPERATOR_CANCELLED;
1296 if (CustomData_external_test(&me->ldata, CD_MDISPS))
1297 return OPERATOR_CANCELLED;
1299 RNA_string_get(op->ptr, "filepath", path);
1302 BLI_path_rel(path, G.main->name);
1304 CustomData_external_add(&me->ldata, &me->id, CD_MDISPS, me->totloop, path);
1305 CustomData_external_write(&me->ldata, &me->id, CD_MASK_MESH, me->totloop, 0);
1307 return OPERATOR_FINISHED;
1310 static int multires_external_save_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
1312 Object *ob = ED_object_active_context(C);
1313 MultiresModifierData *mmd;
1314 Mesh *me = ob->data;
1315 char path[FILE_MAX];
1317 if (!edit_modifier_invoke_properties(C, op))
1318 return OPERATOR_CANCELLED;
1320 mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
1323 return OPERATOR_CANCELLED;
1325 if (CustomData_external_test(&me->ldata, CD_MDISPS))
1326 return OPERATOR_CANCELLED;
1328 if (RNA_struct_property_is_set(op->ptr, "filepath"))
1329 return multires_external_save_exec(C, op);
1331 op->customdata = me;
1333 BLI_snprintf(path, sizeof(path), "//%s.btx", me->id.name + 2);
1334 RNA_string_set(op->ptr, "filepath", path);
1336 WM_event_add_fileselect(C, op);
1338 return OPERATOR_RUNNING_MODAL;
1341 void OBJECT_OT_multires_external_save(wmOperatorType *ot)
1343 ot->name = "Multires Save External";
1344 ot->description = "Save displacements to an external file";
1345 ot->idname = "OBJECT_OT_multires_external_save";
1347 /* XXX modifier no longer in context after file browser .. ot->poll = multires_poll; */
1348 ot->exec = multires_external_save_exec;
1349 ot->invoke = multires_external_save_invoke;
1350 ot->poll = multires_poll;
1353 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1355 WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_BTX, FILE_SPECIAL, FILE_SAVE,
1356 WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY);
1357 edit_modifier_properties(ot);
1360 /****************** multires pack operator *********************/
1362 static int multires_external_pack_exec(bContext *C, wmOperator *UNUSED(op))
1364 Object *ob = ED_object_active_context(C);
1365 Mesh *me = ob->data;
1367 if (!CustomData_external_test(&me->ldata, CD_MDISPS))
1368 return OPERATOR_CANCELLED;
1370 /* XXX don't remove.. */
1371 CustomData_external_remove(&me->ldata, &me->id, CD_MDISPS, me->totloop);
1373 return OPERATOR_FINISHED;
1376 void OBJECT_OT_multires_external_pack(wmOperatorType *ot)
1378 ot->name = "Multires Pack External";
1379 ot->description = "Pack displacements from an external file";
1380 ot->idname = "OBJECT_OT_multires_external_pack";
1382 ot->poll = multires_poll;
1383 ot->exec = multires_external_pack_exec;
1386 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1389 /********************* multires apply base ***********************/
1390 static int multires_base_apply_exec(bContext *C, wmOperator *op)
1392 Object *ob = ED_object_active_context(C);
1393 MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
1396 return OPERATOR_CANCELLED;
1398 multiresModifier_base_apply(mmd, ob);
1400 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1401 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
1403 return OPERATOR_FINISHED;
1406 static int multires_base_apply_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
1408 if (edit_modifier_invoke_properties(C, op))
1409 return multires_base_apply_exec(C, op);
1411 return OPERATOR_CANCELLED;
1415 void OBJECT_OT_multires_base_apply(wmOperatorType *ot)
1417 ot->name = "Multires Apply Base";
1418 ot->description = "Modify the base mesh to conform to the displaced mesh";
1419 ot->idname = "OBJECT_OT_multires_base_apply";
1421 ot->poll = multires_poll;
1422 ot->invoke = multires_base_apply_invoke;
1423 ot->exec = multires_base_apply_exec;
1426 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1427 edit_modifier_properties(ot);
1431 /************************** skin modifier ***********************/
1433 static void modifier_skin_customdata_delete(Object *ob)
1435 Mesh *me = ob->data;
1436 BMEditMesh *em = me->edit_btmesh;
1439 BM_data_layer_free(em->bm, &em->bm->vdata, CD_MVERT_SKIN);
1441 CustomData_free_layer_active(&me->vdata, CD_MVERT_SKIN, me->totvert);
1444 static int skin_poll(bContext *C)
1446 return (!CTX_data_edit_object(C) &&
1447 edit_modifier_poll_generic(C, &RNA_SkinModifier, (1 << OB_MESH)));
1450 static int skin_edit_poll(bContext *C)
1452 return (CTX_data_edit_object(C) &&
1453 edit_modifier_poll_generic(C, &RNA_SkinModifier, (1 << OB_MESH)));
1456 static void skin_root_clear(BMesh *bm, BMVert *bm_vert, GSet *visited)
1461 BM_ITER_ELEM (bm_edge, &bm_iter, bm_vert, BM_EDGES_OF_VERT) {
1462 BMVert *v2 = BM_edge_other_vert(bm_edge, bm_vert);
1464 if (!BLI_gset_haskey(visited, v2)) {
1465 MVertSkin *vs = CustomData_bmesh_get(&bm->vdata,
1469 /* clear vertex root flag and add to visited set */
1470 vs->flag &= ~MVERT_SKIN_ROOT;
1471 BLI_gset_insert(visited, v2);
1473 skin_root_clear(bm, v2, visited);
1478 static int skin_root_mark_exec(bContext *C, wmOperator *UNUSED(op))
1480 Object *ob = CTX_data_edit_object(C);
1481 BMEditMesh *em = BKE_editmesh_from_object(ob);
1487 visited = BLI_gset_ptr_new(__func__);
1489 BKE_mesh_ensure_skin_customdata(ob->data);
1491 BM_ITER_MESH (bm_vert, &bm_iter, bm, BM_VERTS_OF_MESH) {
1492 if (!BLI_gset_haskey(visited, bm_vert) &&
1493 BM_elem_flag_test(bm_vert, BM_ELEM_SELECT))
1495 MVertSkin *vs = CustomData_bmesh_get(&bm->vdata,
1499 /* mark vertex as root and add to visited set */
1500 vs->flag |= MVERT_SKIN_ROOT;
1501 BLI_gset_insert(visited, bm_vert);
1503 /* clear root flag from all connected vertices (recursively) */
1504 skin_root_clear(bm, bm_vert, visited);
1508 BLI_gset_free(visited, NULL);
1510 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1511 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
1513 return OPERATOR_FINISHED;
1516 void OBJECT_OT_skin_root_mark(wmOperatorType *ot)
1518 ot->name = "Skin Root Mark";
1519 ot->description = "Mark selected vertices as roots";
1520 ot->idname = "OBJECT_OT_skin_root_mark";
1522 ot->poll = skin_edit_poll;
1523 ot->exec = skin_root_mark_exec;
1526 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1534 static int skin_loose_mark_clear_exec(bContext *C, wmOperator *op)
1536 Object *ob = CTX_data_edit_object(C);
1537 BMEditMesh *em = BKE_editmesh_from_object(ob);
1541 SkinLooseAction action = RNA_enum_get(op->ptr, "action");
1543 if (!CustomData_has_layer(&bm->vdata, CD_MVERT_SKIN)) {
1544 return OPERATOR_CANCELLED;
1547 BM_ITER_MESH (bm_vert, &bm_iter, bm, BM_VERTS_OF_MESH) {
1548 if (BM_elem_flag_test(bm_vert, BM_ELEM_SELECT)) {
1549 MVertSkin *vs = CustomData_bmesh_get(&bm->vdata,
1555 case SKIN_LOOSE_MARK:
1556 vs->flag |= MVERT_SKIN_LOOSE;
1558 case SKIN_LOOSE_CLEAR:
1559 vs->flag &= ~MVERT_SKIN_LOOSE;
1565 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1566 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
1568 return OPERATOR_FINISHED;
1571 void OBJECT_OT_skin_loose_mark_clear(wmOperatorType *ot)
1573 static EnumPropertyItem action_items[] = {
1574 {SKIN_LOOSE_MARK, "MARK", 0, "Mark", "Mark selected vertices as loose"},
1575 {SKIN_LOOSE_CLEAR, "CLEAR", 0, "Clear", "Set selected vertices as not loose"},
1576 {0, NULL, 0, NULL, NULL}
1579 ot->name = "Skin Mark/Clear Loose";
1580 ot->description = "Mark/clear selected vertices as loose";
1581 ot->idname = "OBJECT_OT_skin_loose_mark_clear";
1583 ot->poll = skin_edit_poll;
1584 ot->exec = skin_loose_mark_clear_exec;
1587 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1589 RNA_def_enum(ot->srna, "action", action_items, SKIN_LOOSE_MARK, "Action", NULL);
1592 static int skin_radii_equalize_exec(bContext *C, wmOperator *UNUSED(op))
1594 Object *ob = CTX_data_edit_object(C);
1595 BMEditMesh *em = BKE_editmesh_from_object(ob);
1600 if (!CustomData_has_layer(&bm->vdata, CD_MVERT_SKIN)) {
1601 return OPERATOR_CANCELLED;
1604 BM_ITER_MESH (bm_vert, &bm_iter, bm, BM_VERTS_OF_MESH) {
1605 if (BM_elem_flag_test(bm_vert, BM_ELEM_SELECT)) {
1606 MVertSkin *vs = CustomData_bmesh_get(&bm->vdata,
1609 float avg = (vs->radius[0] + vs->radius[1]) * 0.5f;
1611 vs->radius[0] = vs->radius[1] = avg;
1615 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1616 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
1618 return OPERATOR_FINISHED;
1621 void OBJECT_OT_skin_radii_equalize(wmOperatorType *ot)
1623 ot->name = "Skin Radii Equalize";
1624 ot->description = "Make skin radii of selected vertices equal on each axis";
1625 ot->idname = "OBJECT_OT_skin_radii_equalize";
1627 ot->poll = skin_edit_poll;
1628 ot->exec = skin_radii_equalize_exec;
1631 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1634 static void skin_armature_bone_create(Object *skin_ob,
1635 MVert *mvert, MEdge *medge,
1637 BLI_bitmap *edges_visited,
1638 const MeshElemMap *emap,
1639 EditBone *parent_bone,
1644 for (i = 0; i < emap[parent_v].count; i++) {
1645 int endx = emap[parent_v].indices[i];
1646 const MEdge *e = &medge[endx];
1651 /* ignore edge if already visited */
1652 if (BLI_BITMAP_TEST(edges_visited, endx))
1654 BLI_BITMAP_ENABLE(edges_visited, endx);
1656 v = (e->v1 == parent_v ? e->v2 : e->v1);
1658 bone = ED_armature_edit_bone_add(arm, "Bone");
1660 bone->parent = parent_bone;
1661 bone->flag |= BONE_CONNECTED;
1663 copy_v3_v3(bone->head, mvert[parent_v].co);
1664 copy_v3_v3(bone->tail, mvert[v].co);
1665 bone->rad_head = bone->rad_tail = 0.25;
1666 BLI_snprintf(bone->name, sizeof(bone->name), "Bone.%.2d", endx);
1668 /* add bDeformGroup */
1669 if ((dg = BKE_object_defgroup_add_name(skin_ob, bone->name))) {
1670 ED_vgroup_vert_add(skin_ob, dg, parent_v, 1, WEIGHT_REPLACE);
1671 ED_vgroup_vert_add(skin_ob, dg, v, 1, WEIGHT_REPLACE);
1674 skin_armature_bone_create(skin_ob,
1684 static Object *modifier_skin_armature_create(Main *bmain, Scene *scene, Object *skin_ob)
1686 BLI_bitmap *edges_visited;
1687 DerivedMesh *deform_dm;
1689 Mesh *me = skin_ob->data;
1692 MVertSkin *mvert_skin;
1697 deform_dm = mesh_get_derived_deform(scene, skin_ob, CD_MASK_BAREMESH);
1698 mvert = deform_dm->getVertArray(deform_dm);
1700 /* add vertex weights to original mesh */
1701 CustomData_add_layer(&me->vdata,
1707 arm_ob = BKE_object_add(bmain, scene, OB_ARMATURE);
1708 BKE_object_transform_copy(arm_ob, skin_ob);
1711 arm_ob->dtx |= OB_DRAWXRAY;
1712 arm->drawtype = ARM_LINE;
1713 arm->edbo = MEM_callocN(sizeof(ListBase), "edbo armature");
1715 mvert_skin = CustomData_get_layer(&me->vdata, CD_MVERT_SKIN);
1716 BKE_mesh_vert_edge_map_create(&emap, &emap_mem,
1717 me->medge, me->totvert, me->totedge);
1719 edges_visited = BLI_BITMAP_NEW(me->totedge, "edge_visited");
1721 /* note: we use EditBones here, easier to set them up and use
1722 * edit-armature functions to convert back to regular bones */
1723 for (v = 0; v < me->totvert; v++) {
1724 if (mvert_skin[v].flag & MVERT_SKIN_ROOT) {
1725 EditBone *bone = NULL;
1727 /* Unless the skin root has just one adjacent edge, create
1728 * a fake root bone (have it going off in the Y direction
1730 if (emap[v].count > 1) {
1731 bone = ED_armature_edit_bone_add(arm, "Bone");
1733 copy_v3_v3(bone->head, me->mvert[v].co);
1734 copy_v3_v3(bone->tail, me->mvert[v].co);
1736 bone->head[1] = 1.0f;
1737 bone->rad_head = bone->rad_tail = 0.25;
1740 if (emap[v].count >= 1) {
1741 skin_armature_bone_create(skin_ob,
1752 MEM_freeN(edges_visited);
1754 MEM_freeN(emap_mem);
1756 ED_armature_from_edit(arm);
1757 ED_armature_edit_free(arm);
1762 static int skin_armature_create_exec(bContext *C, wmOperator *op)
1764 Main *bmain = CTX_data_main(C);
1765 Scene *scene = CTX_data_scene(C);
1766 Object *ob = CTX_data_active_object(C), *arm_ob;
1767 Mesh *me = ob->data;
1768 ModifierData *skin_md;
1769 ArmatureModifierData *arm_md;
1771 if (!CustomData_has_layer(&me->vdata, CD_MVERT_SKIN)) {
1772 BKE_reportf(op->reports, RPT_WARNING, "Mesh '%s' has no skin vertex data", me->id.name + 2);
1773 return OPERATOR_CANCELLED;
1776 /* create new armature */
1777 arm_ob = modifier_skin_armature_create(bmain, scene, ob);
1779 /* add a modifier to connect the new armature to the mesh */
1780 arm_md = (ArmatureModifierData *)modifier_new(eModifierType_Armature);
1782 skin_md = edit_modifier_property_get(op, ob, eModifierType_Skin);
1783 BLI_insertlinkafter(&ob->modifiers, skin_md, arm_md);
1785 arm_md->object = arm_ob;
1786 arm_md->deformflag = ARM_DEF_VGROUP | ARM_DEF_QUATERNION;
1787 DAG_relations_tag_update(bmain);
1788 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1791 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
1793 return OPERATOR_FINISHED;
1796 static int skin_armature_create_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
1798 if (edit_modifier_invoke_properties(C, op))
1799 return skin_armature_create_exec(C, op);
1801 return OPERATOR_CANCELLED;
1804 void OBJECT_OT_skin_armature_create(wmOperatorType *ot)
1806 ot->name = "Skin Armature Create";
1807 ot->description = "Create an armature that parallels the skin layout";
1808 ot->idname = "OBJECT_OT_skin_armature_create";
1810 ot->poll = skin_poll;
1811 ot->invoke = skin_armature_create_invoke;
1812 ot->exec = skin_armature_create_exec;
1815 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1816 edit_modifier_properties(ot);
1819 /************************ mdef bind operator *********************/
1821 static int meshdeform_poll(bContext *C)
1823 return edit_modifier_poll_generic(C, &RNA_MeshDeformModifier, 0);
1826 static int meshdeform_bind_exec(bContext *C, wmOperator *op)
1828 Scene *scene = CTX_data_scene(C);
1829 Object *ob = ED_object_active_context(C);
1830 MeshDeformModifierData *mmd = (MeshDeformModifierData *)edit_modifier_property_get(op, ob, eModifierType_MeshDeform);
1833 return OPERATOR_CANCELLED;
1835 if (mmd->bindcagecos) {
1836 MEM_freeN(mmd->bindcagecos);
1837 if (mmd->dyngrid) MEM_freeN(mmd->dyngrid);
1838 if (mmd->dyninfluences) MEM_freeN(mmd->dyninfluences);
1839 if (mmd->bindinfluences) MEM_freeN(mmd->bindinfluences);
1840 if (mmd->bindoffsets) MEM_freeN(mmd->bindoffsets);
1841 if (mmd->dynverts) MEM_freeN(mmd->dynverts);
1842 if (mmd->bindweights) MEM_freeN(mmd->bindweights); /* deprecated */
1843 if (mmd->bindcos) MEM_freeN(mmd->bindcos); /* deprecated */
1845 mmd->bindcagecos = NULL;
1846 mmd->dyngrid = NULL;
1847 mmd->dyninfluences = NULL;
1848 mmd->bindinfluences = NULL;
1849 mmd->bindoffsets = NULL;
1850 mmd->dynverts = NULL;
1851 mmd->bindweights = NULL; /* deprecated */
1852 mmd->bindcos = NULL; /* deprecated */
1854 mmd->totcagevert = 0;
1855 mmd->totinfluence = 0;
1857 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1858 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
1862 int mode = mmd->modifier.mode;
1864 /* force modifier to run, it will call binding routine */
1865 mmd->bindfunc = mesh_deform_bind;
1866 mmd->modifier.mode |= eModifierMode_Realtime;
1868 if (ob->type == OB_MESH) {
1869 dm = mesh_create_derived_view(scene, ob, 0);
1872 else if (ob->type == OB_LATTICE) {
1873 BKE_lattice_modifiers_calc(scene, ob);
1875 else if (ob->type == OB_MBALL) {
1876 BKE_displist_make_mball(CTX_data_main(C)->eval_ctx, scene, ob);
1878 else if (ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
1879 BKE_displist_make_curveTypes(scene, ob, 0);
1882 mmd->bindfunc = NULL;
1883 mmd->modifier.mode = mode;
1886 return OPERATOR_FINISHED;
1889 static int meshdeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
1891 if (edit_modifier_invoke_properties(C, op))
1892 return meshdeform_bind_exec(C, op);
1894 return OPERATOR_CANCELLED;
1897 void OBJECT_OT_meshdeform_bind(wmOperatorType *ot)
1900 ot->name = "Mesh Deform Bind";
1901 ot->description = "Bind mesh to cage in mesh deform modifier";
1902 ot->idname = "OBJECT_OT_meshdeform_bind";
1905 ot->poll = meshdeform_poll;
1906 ot->invoke = meshdeform_bind_invoke;
1907 ot->exec = meshdeform_bind_exec;
1910 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1911 edit_modifier_properties(ot);
1914 /****************** explode refresh operator *********************/
1916 static int explode_poll(bContext *C)
1918 return edit_modifier_poll_generic(C, &RNA_ExplodeModifier, 0);
1921 static int explode_refresh_exec(bContext *C, wmOperator *op)
1923 Object *ob = ED_object_active_context(C);
1924 ExplodeModifierData *emd = (ExplodeModifierData *)edit_modifier_property_get(op, ob, eModifierType_Explode);
1927 return OPERATOR_CANCELLED;
1929 emd->flag |= eExplodeFlag_CalcFaces;
1931 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1932 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
1934 return OPERATOR_FINISHED;
1937 static int explode_refresh_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
1939 if (edit_modifier_invoke_properties(C, op))
1940 return explode_refresh_exec(C, op);
1942 return OPERATOR_CANCELLED;
1946 void OBJECT_OT_explode_refresh(wmOperatorType *ot)
1948 ot->name = "Explode Refresh";
1949 ot->description = "Refresh data in the Explode modifier";
1950 ot->idname = "OBJECT_OT_explode_refresh";
1952 ot->poll = explode_poll;
1953 ot->invoke = explode_refresh_invoke;
1954 ot->exec = explode_refresh_exec;
1957 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1958 edit_modifier_properties(ot);
1962 /****************** ocean bake operator *********************/
1964 static int ocean_bake_poll(bContext *C)
1966 return edit_modifier_poll_generic(C, &RNA_OceanModifier, 0);
1969 /* copied from init_ocean_modifier, MOD_ocean.c */
1970 static void init_ocean_modifier_bake(struct Ocean *oc, struct OceanModifierData *omd)
1972 int do_heightfield, do_chop, do_normals, do_jacobian;
1974 if (!omd || !oc) return;
1976 do_heightfield = true;
1977 do_chop = (omd->chop_amount > 0);
1978 do_normals = (omd->flag & MOD_OCEAN_GENERATE_NORMALS);
1979 do_jacobian = (omd->flag & MOD_OCEAN_GENERATE_FOAM);
1981 BKE_init_ocean(oc, omd->resolution * omd->resolution, omd->resolution * omd->resolution, omd->spatial_size, omd->spatial_size,
1982 omd->wind_velocity, omd->smallest_wave, 1.0, omd->wave_direction, omd->damp, omd->wave_alignment,
1983 omd->depth, omd->time,
1984 do_heightfield, do_chop, do_normals, do_jacobian,
1988 typedef struct OceanBakeJob {
1991 short *stop, *do_update;
1994 struct OceanCache *och;
1995 struct Ocean *ocean;
1996 struct OceanModifierData *omd;
1999 static void oceanbake_free(void *customdata)
2001 OceanBakeJob *oj = customdata;
2005 /* called by oceanbake, only to check job 'stop' value */
2006 static int oceanbake_breakjob(void *UNUSED(customdata))
2008 //OceanBakeJob *ob = (OceanBakeJob *)customdata;
2009 //return *(ob->stop);
2011 /* this is not nice yet, need to make the jobs list template better
2012 * for identifying/acting upon various different jobs */
2013 /* but for now we'll reuse the render break... */
2014 return (G.is_break);
2017 /* called by oceanbake, wmJob sends notifier */
2018 static void oceanbake_update(void *customdata, float progress, int *cancel)
2020 OceanBakeJob *oj = customdata;
2022 if (oceanbake_breakjob(oj))
2025 *(oj->do_update) = true;
2026 *(oj->progress) = progress;
2029 static void oceanbake_startjob(void *customdata, short *stop, short *do_update, float *progress)
2031 OceanBakeJob *oj = customdata;
2034 oj->do_update = do_update;
2035 oj->progress = progress;
2037 G.is_break = false; /* XXX shared with render - replace with job 'stop' switch */
2039 BKE_bake_ocean(oj->ocean, oj->och, oceanbake_update, (void *)oj);
2045 static void oceanbake_endjob(void *customdata)
2047 OceanBakeJob *oj = customdata;
2050 BKE_free_ocean(oj->ocean);
2054 oj->omd->oceancache = oj->och;
2055 oj->omd->cached = true;
2058 static int ocean_bake_exec(bContext *C, wmOperator *op)
2060 Object *ob = ED_object_active_context(C);
2061 OceanModifierData *omd = (OceanModifierData *)edit_modifier_property_get(op, ob, eModifierType_Ocean);
2062 Scene *scene = CTX_data_scene(C);
2064 struct Ocean *ocean;
2066 const bool free = RNA_boolean_get(op->ptr, "free");
2072 return OPERATOR_CANCELLED;
2075 omd->refresh |= MOD_OCEAN_REFRESH_CLEAR_CACHE;
2076 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
2077 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
2078 return OPERATOR_FINISHED;
2081 och = BKE_init_ocean_cache(omd->cachepath, modifier_path_relbase(ob),
2082 omd->bakestart, omd->bakeend, omd->wave_scale,
2083 omd->chop_amount, omd->foam_coverage, omd->foam_fade, omd->resolution);
2085 och->time = MEM_mallocN(och->duration * sizeof(float), "foam bake time");
2087 cfra = scene->r.cfra;
2089 /* precalculate time variable before baking */
2090 for (f = omd->bakestart; f <= omd->bakeend; f++) {
2091 /* from physics_fluid.c:
2093 * XXX: This can't be used due to an anim sys optimization that ignores recalc object animation,
2094 * leaving it for the depgraph (this ignores object animation such as modifier properties though... :/ )
2095 * --> BKE_animsys_evaluate_all_animation(G.main, eval_time);
2096 * This doesn't work with drivers:
2097 * --> BKE_animsys_evaluate_animdata(&fsDomain->id, fsDomain->adt, eval_time, ADT_RECALC_ALL);
2100 /* Modifying the global scene isn't nice, but we can do it in
2101 * this part of the process before a threaded job is created */
2103 //scene->r.cfra = f;
2104 //ED_update_for_newframe(CTX_data_main(C), scene, 1);
2106 /* ok, this doesn't work with drivers, but is way faster.
2107 * let's use this for now and hope nobody wants to drive the time value... */
2108 BKE_animsys_evaluate_animdata(scene, (ID *)ob, ob->adt, f, ADT_RECALC_ANIM);
2110 och->time[i] = omd->time;
2114 /* make a copy of ocean to use for baking - threadsafety */
2115 ocean = BKE_add_ocean();
2116 init_ocean_modifier_bake(ocean, omd);
2119 BKE_bake_ocean(ocean, och);
2121 omd->oceancache = och;
2124 scene->r.cfra = cfra;
2126 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
2127 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
2132 scene->r.cfra = cfra;
2135 wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Ocean Simulation",
2136 WM_JOB_PROGRESS, WM_JOB_TYPE_OBJECT_SIM_OCEAN);
2137 oj = MEM_callocN(sizeof(OceanBakeJob), "ocean bake job");
2142 WM_jobs_customdata_set(wm_job, oj, oceanbake_free);
2143 WM_jobs_timer(wm_job, 0.1, NC_OBJECT | ND_MODIFIER, NC_OBJECT | ND_MODIFIER);
2144 WM_jobs_callbacks(wm_job, oceanbake_startjob, NULL, NULL, oceanbake_endjob);
2146 WM_jobs_start(CTX_wm_manager(C), wm_job);
2150 return OPERATOR_FINISHED;
2153 static int ocean_bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
2155 if (edit_modifier_invoke_properties(C, op))
2156 return ocean_bake_exec(C, op);
2158 return OPERATOR_CANCELLED;
2162 void OBJECT_OT_ocean_bake(wmOperatorType *ot)
2164 ot->name = "Bake Ocean";
2165 ot->description = "Bake an image sequence of ocean data";
2166 ot->idname = "OBJECT_OT_ocean_bake";
2168 ot->poll = ocean_bake_poll;
2169 ot->invoke = ocean_bake_invoke;
2170 ot->exec = ocean_bake_exec;
2173 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
2174 edit_modifier_properties(ot);
2176 RNA_def_boolean(ot->srna, "free", false, "Free", "Free the bake, rather than generating it");
2179 /************************ LaplacianDeform bind operator *********************/
2181 static int laplaciandeform_poll(bContext *C)
2183 return edit_modifier_poll_generic(C, &RNA_LaplacianDeformModifier, 0);
2186 static int laplaciandeform_bind_exec(bContext *C, wmOperator *op)
2188 Object *ob = ED_object_active_context(C);
2189 LaplacianDeformModifierData *lmd = (LaplacianDeformModifierData *)edit_modifier_property_get(op, ob, eModifierType_LaplacianDeform);
2192 return OPERATOR_CANCELLED;
2193 if (lmd->flag & MOD_LAPLACIANDEFORM_BIND) {
2194 lmd->flag &= ~MOD_LAPLACIANDEFORM_BIND;
2197 lmd->flag |= MOD_LAPLACIANDEFORM_BIND;
2199 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
2200 WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
2201 return OPERATOR_FINISHED;
2204 static int laplaciandeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
2206 if (edit_modifier_invoke_properties(C, op))
2207 return laplaciandeform_bind_exec(C, op);
2209 return OPERATOR_CANCELLED;
2212 void OBJECT_OT_laplaciandeform_bind(wmOperatorType *ot)
2215 ot->name = "Laplacian Deform Bind";
2216 ot->description = "Bind mesh to system in laplacian deform modifier";
2217 ot->idname = "OBJECT_OT_laplaciandeform_bind";
2220 ot->poll = laplaciandeform_poll;
2221 ot->invoke = laplaciandeform_bind_invoke;
2222 ot->exec = laplaciandeform_bind_exec;
2225 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
2226 edit_modifier_properties(ot);