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) 2005 by the Blender Foundation.
19 * All rights reserved.
21 * Contributor(s): Daniel Dunbar
27 * ***** END GPL LICENSE BLOCK *****
29 * Modifier stack implementation.
31 * BKE_modifier.h contains the function prototypes for this file.
35 /** \file blender/blenkernel/intern/modifier.c
46 #include "MEM_guardedalloc.h"
48 #include "DNA_armature_types.h"
49 #include "DNA_mesh_types.h"
50 #include "DNA_object_types.h"
52 #include "BLI_utildefines.h"
53 #include "BLI_listbase.h"
54 #include "BLI_linklist.h"
55 #include "BLI_path_util.h"
56 #include "BLI_string.h"
57 #include "BLI_string_utils.h"
59 #include "BLT_translation.h"
61 #include "BKE_appdir.h"
62 #include "BKE_cdderivedmesh.h"
63 #include "BKE_idcode.h"
65 #include "BKE_library.h"
66 #include "BKE_library_query.h"
68 #include "BKE_multires.h"
69 #include "BKE_DerivedMesh.h"
71 /* may move these, only for modifier_path_relbase */
72 #include "BKE_global.h" /* ugh, G.main->name only */
76 #include "DEG_depsgraph.h"
78 #include "MOD_modifiertypes.h"
80 static ModifierTypeInfo *modifier_types[NUM_MODIFIER_TYPES] = {NULL};
81 static VirtualModifierData virtualModifierCommonData;
83 void BKE_modifier_init(void)
87 /* Initialize modifier types */
88 modifier_type_init(modifier_types); /* MOD_utils.c */
90 /* Initialize global cmmon storage used for virtual modifier list */
91 md = modifier_new(eModifierType_Armature);
92 virtualModifierCommonData.amd = *((ArmatureModifierData *) md);
95 md = modifier_new(eModifierType_Curve);
96 virtualModifierCommonData.cmd = *((CurveModifierData *) md);
99 md = modifier_new(eModifierType_Lattice);
100 virtualModifierCommonData.lmd = *((LatticeModifierData *) md);
103 md = modifier_new(eModifierType_ShapeKey);
104 virtualModifierCommonData.smd = *((ShapeKeyModifierData *) md);
107 virtualModifierCommonData.amd.modifier.mode |= eModifierMode_Virtual;
108 virtualModifierCommonData.cmd.modifier.mode |= eModifierMode_Virtual;
109 virtualModifierCommonData.lmd.modifier.mode |= eModifierMode_Virtual;
110 virtualModifierCommonData.smd.modifier.mode |= eModifierMode_Virtual;
113 const ModifierTypeInfo *modifierType_getInfo(ModifierType type)
115 /* type unsigned, no need to check < 0 */
116 if (type < NUM_MODIFIER_TYPES && modifier_types[type]->name[0] != '\0') {
117 return modifier_types[type];
126 ModifierData *modifier_new(int type)
128 const ModifierTypeInfo *mti = modifierType_getInfo(type);
129 ModifierData *md = MEM_callocN(mti->structSize, mti->structName);
131 /* note, this name must be made unique later */
132 BLI_strncpy(md->name, DATA_(mti->name), sizeof(md->name));
135 md->mode = eModifierMode_Realtime | eModifierMode_Render | eModifierMode_Expanded;
136 md->flag = eModifierFlag_StaticOverride_Local;
138 if (mti->flags & eModifierTypeFlag_EnableInEditmode)
139 md->mode |= eModifierMode_Editmode;
141 if (mti->initData) mti->initData(md);
146 static void modifier_free_data_id_us_cb(void *UNUSED(userData), Object *UNUSED(ob), ID **idpoin, int cb_flag)
149 if (id != NULL && (cb_flag & IDWALK_CB_USER) != 0) {
154 void modifier_free_ex(ModifierData *md, const int flag)
156 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
158 if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
159 if (mti->foreachIDLink) {
160 mti->foreachIDLink(md, NULL, modifier_free_data_id_us_cb, NULL);
162 else if (mti->foreachObjectLink) {
163 mti->foreachObjectLink(md, NULL, (ObjectWalkFunc)modifier_free_data_id_us_cb, NULL);
167 if (mti->freeData) mti->freeData(md);
168 if (md->error) MEM_freeN(md->error);
173 void modifier_free(ModifierData *md)
175 modifier_free_ex(md, 0);
178 bool modifier_unique_name(ListBase *modifiers, ModifierData *md)
180 if (modifiers && md) {
181 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
183 return BLI_uniquename(modifiers, md, DATA_(mti->name), '.', offsetof(ModifierData, name), sizeof(md->name));
188 bool modifier_dependsOnTime(ModifierData *md)
190 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
192 return mti->dependsOnTime && mti->dependsOnTime(md);
195 bool modifier_supportsMapping(ModifierData *md)
197 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
199 return (mti->type == eModifierTypeType_OnlyDeform ||
200 (mti->flags & eModifierTypeFlag_SupportsMapping));
203 bool modifier_isPreview(ModifierData *md)
205 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
207 /* Constructive modifiers are highly likely to also modify data like vgroups or vcol! */
208 if (!((mti->flags & eModifierTypeFlag_UsesPreview) || (mti->type == eModifierTypeType_Constructive))) {
212 if (md->mode & eModifierMode_Realtime) {
219 ModifierData *modifiers_findByType(Object *ob, ModifierType type)
221 ModifierData *md = ob->modifiers.first;
223 for (; md; md = md->next)
224 if (md->type == type)
230 ModifierData *modifiers_findByName(Object *ob, const char *name)
232 return BLI_findstring(&(ob->modifiers), name, offsetof(ModifierData, name));
235 void modifiers_clearErrors(Object *ob)
237 ModifierData *md = ob->modifiers.first;
238 /* int qRedraw = 0; */
240 for (; md; md = md->next) {
242 MEM_freeN(md->error);
250 void modifiers_foreachObjectLink(Object *ob, ObjectWalkFunc walk, void *userData)
252 ModifierData *md = ob->modifiers.first;
254 for (; md; md = md->next) {
255 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
257 if (mti->foreachObjectLink)
258 mti->foreachObjectLink(md, ob, walk, userData);
262 void modifiers_foreachIDLink(Object *ob, IDWalkFunc walk, void *userData)
264 ModifierData *md = ob->modifiers.first;
266 for (; md; md = md->next) {
267 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
269 if (mti->foreachIDLink) mti->foreachIDLink(md, ob, walk, userData);
270 else if (mti->foreachObjectLink) {
271 /* each Object can masquerade as an ID, so this should be OK */
272 ObjectWalkFunc fp = (ObjectWalkFunc)walk;
273 mti->foreachObjectLink(md, ob, fp, userData);
278 void modifiers_foreachTexLink(Object *ob, TexWalkFunc walk, void *userData)
280 ModifierData *md = ob->modifiers.first;
282 for (; md; md = md->next) {
283 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
285 if (mti->foreachTexLink)
286 mti->foreachTexLink(md, ob, walk, userData);
290 /* callback's can use this
291 * to avoid copying every member.
293 void modifier_copyData_generic(const ModifierData *md_src, ModifierData *md_dst)
295 const ModifierTypeInfo *mti = modifierType_getInfo(md_src->type);
296 const size_t data_size = sizeof(ModifierData);
297 const char *md_src_data = ((const char *)md_src) + data_size;
298 char *md_dst_data = ((char *)md_dst) + data_size;
299 BLI_assert(data_size <= (size_t)mti->structSize);
300 memcpy(md_dst_data, md_src_data, (size_t)mti->structSize - data_size);
303 static void modifier_copy_data_id_us_cb(void *UNUSED(userData), Object *UNUSED(ob), ID **idpoin, int cb_flag)
306 if (id != NULL && (cb_flag & IDWALK_CB_USER) != 0) {
311 void modifier_copyData_ex(ModifierData *md, ModifierData *target, const int flag)
313 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
315 target->mode = md->mode;
316 target->flag = md->flag;
319 mti->copyData(md, target);
322 if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
323 if (mti->foreachIDLink) {
324 mti->foreachIDLink(target, NULL, modifier_copy_data_id_us_cb, NULL);
326 else if (mti->foreachObjectLink) {
327 mti->foreachObjectLink(target, NULL, (ObjectWalkFunc)modifier_copy_data_id_us_cb, NULL);
332 void modifier_copyData(ModifierData *md, ModifierData *target)
334 modifier_copyData_ex(md, target, 0);
338 bool modifier_supportsCage(struct Scene *scene, ModifierData *md)
340 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
344 return ((!mti->isDisabled || !mti->isDisabled(md, 0)) &&
345 (mti->flags & eModifierTypeFlag_SupportsEditmode) &&
346 modifier_supportsMapping(md));
349 bool modifier_couldBeCage(struct Scene *scene, ModifierData *md)
351 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
355 return ((md->mode & eModifierMode_Realtime) &&
356 (md->mode & eModifierMode_Editmode) &&
357 (!mti->isDisabled || !mti->isDisabled(md, 0)) &&
358 modifier_supportsMapping(md));
361 bool modifier_isSameTopology(ModifierData *md)
363 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
364 return ELEM(mti->type, eModifierTypeType_OnlyDeform, eModifierTypeType_NonGeometrical);
367 bool modifier_isNonGeometrical(ModifierData *md)
369 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
370 return (mti->type == eModifierTypeType_NonGeometrical);
373 void modifier_setError(ModifierData *md, const char *_format, ...)
377 const char *format = TIP_(_format);
379 va_start(ap, _format);
380 vsnprintf(buffer, sizeof(buffer), format, ap);
382 buffer[sizeof(buffer) - 1] = '\0';
385 MEM_freeN(md->error);
387 md->error = BLI_strdup(buffer);
391 /* used for buttons, to find out if the 'draw deformed in editmode' option is
394 * also used in transform_conversion.c, to detect CrazySpace [tm] (2nd arg
396 * also used for some mesh tools to give warnings
398 int modifiers_getCageIndex(struct Scene *scene, Object *ob, int *r_lastPossibleCageIndex, bool is_virtual)
400 VirtualModifierData virtualModifierData;
401 ModifierData *md = (is_virtual) ? modifiers_getVirtualModifierList(ob, &virtualModifierData) : ob->modifiers.first;
402 int i, cageIndex = -1;
404 if (r_lastPossibleCageIndex) {
405 /* ensure the value is initialized */
406 *r_lastPossibleCageIndex = -1;
409 /* Find the last modifier acting on the cage. */
410 for (i = 0; md; i++, md = md->next) {
411 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
412 bool supports_mapping;
416 if (mti->isDisabled && mti->isDisabled(md, 0)) continue;
417 if (!(mti->flags & eModifierTypeFlag_SupportsEditmode)) continue;
418 if (md->mode & eModifierMode_DisableTemporary) continue;
420 supports_mapping = modifier_supportsMapping(md);
421 if (r_lastPossibleCageIndex && supports_mapping) {
422 *r_lastPossibleCageIndex = i;
425 if (!(md->mode & eModifierMode_Realtime)) continue;
426 if (!(md->mode & eModifierMode_Editmode)) continue;
428 if (!supports_mapping)
431 if (md->mode & eModifierMode_OnCage)
439 bool modifiers_isSoftbodyEnabled(Object *ob)
441 ModifierData *md = modifiers_findByType(ob, eModifierType_Softbody);
443 return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
446 bool modifiers_isClothEnabled(Object *ob)
448 ModifierData *md = modifiers_findByType(ob, eModifierType_Cloth);
450 return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
453 bool modifiers_isModifierEnabled(Object *ob, int modifierType)
455 ModifierData *md = modifiers_findByType(ob, modifierType);
457 return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
460 bool modifiers_isParticleEnabled(Object *ob)
462 ModifierData *md = modifiers_findByType(ob, eModifierType_ParticleSystem);
464 return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
468 * Check whether is enabled.
470 * \param scene Current scene, may be NULL, in which case isDisabled callback of the modifier is never called.
472 bool modifier_isEnabled(struct Scene *scene, ModifierData *md, int required_mode)
474 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
478 if ((md->mode & required_mode) != required_mode) return false;
479 if (scene != NULL && mti->isDisabled && mti->isDisabled(md, required_mode == eModifierMode_Render)) return false;
480 if (md->mode & eModifierMode_DisableTemporary) return false;
481 if ((required_mode & eModifierMode_Editmode) && !(mti->flags & eModifierTypeFlag_SupportsEditmode)) return false;
486 CDMaskLink *modifiers_calcDataMasks(struct Scene *scene, Object *ob, ModifierData *md,
487 CustomDataMask dataMask, int required_mode,
488 ModifierData *previewmd, CustomDataMask previewmask)
490 CDMaskLink *dataMasks = NULL;
491 CDMaskLink *curr, *prev;
493 /* build a list of modifier data requirements in reverse order */
494 for (; md; md = md->next) {
495 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
497 curr = MEM_callocN(sizeof(CDMaskLink), "CDMaskLink");
499 if (modifier_isEnabled(scene, md, required_mode)) {
500 if (mti->requiredDataMask)
501 curr->mask = mti->requiredDataMask(ob, md);
503 if (previewmd == md) {
504 curr->mask |= previewmask;
508 /* prepend new datamask */
509 curr->next = dataMasks;
513 /* build the list of required data masks - each mask in the list must
514 * include all elements of the masks that follow it
516 * note the list is currently in reverse order, so "masks that follow it"
517 * actually means "masks that precede it" at the moment
519 for (curr = dataMasks, prev = NULL; curr; prev = curr, curr = curr->next) {
521 CustomDataMask prev_mask = prev->mask;
522 CustomDataMask curr_mask = curr->mask;
524 curr->mask = curr_mask | prev_mask;
527 CustomDataMask curr_mask = curr->mask;
529 curr->mask = curr_mask | dataMask;
533 /* reverse the list so it's in the correct order */
534 BLI_linklist_reverse((LinkNode **)&dataMasks);
539 ModifierData *modifiers_getLastPreview(struct Scene *scene, ModifierData *md, int required_mode)
541 ModifierData *tmp_md = NULL;
543 if ((required_mode & ~eModifierMode_Editmode) != eModifierMode_Realtime)
546 /* Find the latest modifier in stack generating preview. */
547 for (; md; md = md->next) {
548 if (modifier_isEnabled(scene, md, required_mode) && modifier_isPreview(md))
554 /* NOTE: This is to support old files from before Blender supported modifiers,
555 * in some cases versioning code updates these so for new files this will
556 * return an empty list. */
557 ModifierData *modifiers_getVirtualModifierList(Object *ob, VirtualModifierData *virtualModifierData)
561 md = ob->modifiers.first;
563 *virtualModifierData = virtualModifierCommonData;
566 if (ob->parent->type == OB_ARMATURE && ob->partype == PARSKEL) {
567 virtualModifierData->amd.object = ob->parent;
568 virtualModifierData->amd.modifier.next = md;
569 virtualModifierData->amd.deformflag = ((bArmature *)(ob->parent->data))->deformflag;
570 md = &virtualModifierData->amd.modifier;
572 else if (ob->parent->type == OB_CURVE && ob->partype == PARSKEL) {
573 virtualModifierData->cmd.object = ob->parent;
574 virtualModifierData->cmd.defaxis = ob->trackflag + 1;
575 virtualModifierData->cmd.modifier.next = md;
576 md = &virtualModifierData->cmd.modifier;
578 else if (ob->parent->type == OB_LATTICE && ob->partype == PARSKEL) {
579 virtualModifierData->lmd.object = ob->parent;
580 virtualModifierData->lmd.modifier.next = md;
581 md = &virtualModifierData->lmd.modifier;
585 /* shape key modifier, not yet for curves */
586 if (ELEM(ob->type, OB_MESH, OB_LATTICE) && BKE_key_from_object(ob)) {
587 if (ob->type == OB_MESH && (ob->shapeflag & OB_SHAPE_EDIT_MODE))
588 virtualModifierData->smd.modifier.mode |= eModifierMode_Editmode | eModifierMode_OnCage;
590 virtualModifierData->smd.modifier.mode &= ~eModifierMode_Editmode | eModifierMode_OnCage;
592 virtualModifierData->smd.modifier.next = md;
593 md = &virtualModifierData->smd.modifier;
599 /* Takes an object and returns its first selected armature, else just its armature
600 * This should work for multiple armatures per object
602 Object *modifiers_isDeformedByArmature(Object *ob)
604 VirtualModifierData virtualModifierData;
605 ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
606 ArmatureModifierData *amd = NULL;
608 /* return the first selected armature, this lets us use multiple armatures */
609 for (; md; md = md->next) {
610 if (md->type == eModifierType_Armature) {
611 amd = (ArmatureModifierData *) md;
612 if (amd->object && (amd->object->flag & SELECT))
617 if (amd) /* if were still here then return the last armature */
623 /* Takes an object and returns its first selected lattice, else just its lattice
624 * This should work for multiple lattices per object
626 Object *modifiers_isDeformedByLattice(Object *ob)
628 VirtualModifierData virtualModifierData;
629 ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
630 LatticeModifierData *lmd = NULL;
632 /* return the first selected lattice, this lets us use multiple lattices */
633 for (; md; md = md->next) {
634 if (md->type == eModifierType_Lattice) {
635 lmd = (LatticeModifierData *) md;
636 if (lmd->object && (lmd->object->flag & SELECT))
641 if (lmd) /* if were still here then return the last lattice */
647 /* Takes an object and returns its first selected curve, else just its curve
648 * This should work for multiple curves per object
650 Object *modifiers_isDeformedByCurve(Object *ob)
652 VirtualModifierData virtualModifierData;
653 ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
654 CurveModifierData *cmd = NULL;
656 /* return the first selected curve, this lets us use multiple curves */
657 for (; md; md = md->next) {
658 if (md->type == eModifierType_Curve) {
659 cmd = (CurveModifierData *) md;
660 if (cmd->object && (cmd->object->flag & SELECT))
665 if (cmd) /* if were still here then return the last curve */
671 bool modifiers_usesArmature(Object *ob, bArmature *arm)
673 VirtualModifierData virtualModifierData;
674 ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
676 for (; md; md = md->next) {
677 if (md->type == eModifierType_Armature) {
678 ArmatureModifierData *amd = (ArmatureModifierData *) md;
679 if (amd->object && amd->object->data == arm)
687 bool modifier_isCorrectableDeformed(ModifierData *md)
689 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
690 return (mti->deformMatricesEM != NULL) || (mti->deformMatricesEM_DM != NULL);
693 bool modifiers_isCorrectableDeformed(struct Scene *scene, Object *ob)
695 VirtualModifierData virtualModifierData;
696 ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
697 int required_mode = eModifierMode_Realtime;
699 if (ob->mode == OB_MODE_EDIT) {
700 required_mode |= eModifierMode_Editmode;
702 for (; md; md = md->next) {
703 if (!modifier_isEnabled(scene, md, required_mode)) {
706 else if (modifier_isCorrectableDeformed(md)) {
713 /* Check whether the given object has a modifier in its stack that uses WEIGHT_MCOL CD layer
714 * to preview something... Used by DynamicPaint and WeightVG currently. */
715 bool modifiers_isPreview(Object *ob)
717 ModifierData *md = ob->modifiers.first;
719 for (; md; md = md->next) {
720 if (modifier_isPreview(md))
727 void modifier_freeTemporaryData(ModifierData *md)
729 if (md->type == eModifierType_Armature) {
730 ArmatureModifierData *amd = (ArmatureModifierData *)md;
733 MEM_freeN(amd->prevCos);
739 /* ensure modifier correctness when changing ob->data */
740 void test_object_modifiers(Object *ob)
744 /* just multires checked for now, since only multires
745 * modifies mesh data */
747 if (ob->type != OB_MESH) return;
749 for (md = ob->modifiers.first; md; md = md->next) {
750 if (md->type == eModifierType_Multires) {
751 MultiresModifierData *mmd = (MultiresModifierData *)md;
753 multiresModifier_set_levels_from_disps(mmd, ob);
758 /* where should this go?, it doesnt fit well anywhere :S - campbell */
760 /* elubie: changed this to default to the same dir as the render output
761 * to prevent saving to C:\ on Windows */
763 /* campbell: logic behind this...
765 * - if the ID is from a library, return library path
766 * - else if the file has been saved return the blend file path.
767 * - else if the file isn't saved and the ID isn't from a library, return the temp dir.
769 const char *modifier_path_relbase(Object *ob)
771 if (G.relbase_valid || ID_IS_LINKED(ob)) {
772 return ID_BLEND_PATH(G.main, &ob->id);
775 /* last resort, better then using "" which resolves to the current
776 * working directory */
777 return BKE_tempdir_session();
781 /* initializes the path with either */
782 void modifier_path_init(char *path, int path_maxlen, const char *name)
784 /* elubie: changed this to default to the same dir as the render output
785 * to prevent saving to C:\ on Windows */
786 BLI_join_dirfile(path, path_maxlen,
787 G.relbase_valid ? "//" : BKE_tempdir_session(),
792 /* wrapper around ModifierTypeInfo.applyModifier that ensures valid normals */
794 struct DerivedMesh *modwrap_applyModifier(
795 ModifierData *md, const ModifierEvalContext *ctx,
796 struct DerivedMesh *dm)
798 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
799 BLI_assert(CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);
801 if (mti->dependsOnNormals && mti->dependsOnNormals(md)) {
802 DM_ensure_normals(dm);
804 return modifier_applyModifier_DM_deprecated(md, ctx, dm);
807 struct DerivedMesh *modwrap_applyModifierEM(
808 ModifierData *md, const ModifierEvalContext *ctx,
809 struct BMEditMesh *em, DerivedMesh *dm)
811 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
812 BLI_assert(CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);
814 if (mti->dependsOnNormals && mti->dependsOnNormals(md)) {
815 DM_ensure_normals(dm);
817 return modifier_applyModifierEM_DM_deprecated(md, ctx, em, dm);
820 void modwrap_deformVerts(
821 ModifierData *md, const ModifierEvalContext *ctx,
822 DerivedMesh *dm, float (*vertexCos)[3], int numVerts)
824 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
825 BLI_assert(!dm || CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);
827 if (dm && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
828 DM_ensure_normals(dm);
830 modifier_deformVerts_DM_deprecated(md, ctx, dm, vertexCos, numVerts);
833 void modwrap_deformVertsEM(
834 ModifierData *md, const ModifierEvalContext *ctx,
835 struct BMEditMesh *em, DerivedMesh *dm,
836 float (*vertexCos)[3], int numVerts)
838 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
839 BLI_assert(!dm || CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);
841 if (dm && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
842 DM_ensure_normals(dm);
844 modifier_deformVertsEM_DM_deprecated(md, ctx, em, dm, vertexCos, numVerts);
846 /* end modifier callback wrappers */
849 /* wrappers for modifier callbacks that accept Mesh and select the proper implementation
850 * depending on if the modifier has been ported to Mesh or is still using DerivedMesh
853 void modifier_deformVerts(struct ModifierData *md, const ModifierEvalContext *ctx,
855 float (*vertexCos)[3], int numVerts)
857 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
859 if (mti->deformVerts) {
860 mti->deformVerts(md, ctx, mesh, vertexCos, numVerts);
863 DerivedMesh *dm = NULL;
865 dm = CDDM_from_mesh(mesh);
868 mti->deformVerts_DM(md, ctx, dm, vertexCos, numVerts);
876 void modifier_deformMatrices(struct ModifierData *md, const ModifierEvalContext *ctx,
878 float (*vertexCos)[3], float (*defMats)[3][3], int numVerts)
880 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
882 if (mti->deformMatrices) {
883 mti->deformMatrices(md, ctx, mesh, vertexCos, defMats, numVerts);
886 DerivedMesh *dm = NULL;
888 dm = CDDM_from_mesh(mesh);
891 mti->deformMatrices_DM(md, ctx, dm, vertexCos, defMats, numVerts);
899 void modifier_deformVertsEM(struct ModifierData *md, const ModifierEvalContext *ctx,
900 struct BMEditMesh *editData, struct Mesh *mesh,
901 float (*vertexCos)[3], int numVerts)
903 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
905 if (mti->deformVertsEM) {
906 mti->deformVertsEM(md, ctx, editData, mesh, vertexCos, numVerts);
909 DerivedMesh *dm = NULL;
911 dm = CDDM_from_mesh(mesh);
914 mti->deformVertsEM_DM(md, ctx, editData, dm, vertexCos, numVerts);
922 void modifier_deformMatricesEM(struct ModifierData *md, const ModifierEvalContext *ctx,
923 struct BMEditMesh *editData, struct Mesh *mesh,
924 float (*vertexCos)[3], float (*defMats)[3][3], int numVerts)
926 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
928 if (mti->deformMatricesEM) {
929 mti->deformMatricesEM(md, ctx, editData, mesh, vertexCos, defMats, numVerts);
932 DerivedMesh *dm = NULL;
934 dm = CDDM_from_mesh(mesh);
937 mti->deformMatricesEM_DM(md, ctx, editData, dm, vertexCos, defMats, numVerts);
945 struct Mesh *modifier_applyModifier(struct ModifierData *md, const ModifierEvalContext *ctx,
948 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
950 if (mti->applyModifier) {
951 return mti->applyModifier(md, ctx, mesh);
954 DerivedMesh *dm = CDDM_from_mesh(mesh);
956 DerivedMesh *ndm = mti->applyModifier_DM(md, ctx, dm);
962 DM_to_mesh(ndm, mesh, ctx->object, CD_MASK_EVERYTHING, true);
968 struct Mesh *modifier_applyModifierEM(struct ModifierData *md, const ModifierEvalContext *ctx,
969 struct BMEditMesh *editData,
972 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
974 if (mti->applyModifierEM) {
975 return mti->applyModifierEM(md, ctx, editData, mesh);
978 DerivedMesh *dm = CDDM_from_mesh(mesh);
980 DerivedMesh *ndm = mti->applyModifierEM_DM(md, ctx, editData, dm);
986 DM_to_mesh(ndm, mesh, ctx->object, CD_MASK_EVERYTHING, true);
992 /* depricated variants of above that accept DerivedMesh */
994 void modifier_deformVerts_DM_deprecated(struct ModifierData *md, const ModifierEvalContext *ctx,
995 struct DerivedMesh *dm,
996 float (*vertexCos)[3], int numVerts)
998 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1000 if (mti->deformVerts_DM) {
1001 mti->deformVerts_DM(md, ctx, dm, vertexCos, numVerts);
1004 /* TODO(sybren): deduplicate all the copies of this code in this file. */
1007 mesh = BKE_id_new_nomain(ID_ME, NULL);
1008 DM_to_mesh(dm, mesh, ctx->object, CD_MASK_EVERYTHING, false);
1011 mti->deformVerts(md, ctx, mesh, vertexCos, numVerts);
1014 BKE_id_free(NULL, mesh);
1019 void modifier_deformMatrices_DM_deprecated(struct ModifierData *md, const ModifierEvalContext *ctx,
1020 struct DerivedMesh *dm,
1021 float (*vertexCos)[3], float (*defMats)[3][3], int numVerts)
1024 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1026 if (mti->deformMatrices_DM) {
1027 mti->deformMatrices_DM(md, ctx, dm, vertexCos, defMats, numVerts);
1030 /* TODO(sybren): deduplicate all the copies of this code in this file. */
1033 mesh = BKE_id_new_nomain(ID_ME, NULL);
1034 DM_to_mesh(dm, mesh, ctx->object, CD_MASK_EVERYTHING, false);
1037 mti->deformMatrices(md, ctx, mesh, vertexCos, defMats, numVerts);
1040 BKE_id_free(NULL, mesh);
1045 void modifier_deformVertsEM_DM_deprecated(struct ModifierData *md, const ModifierEvalContext *ctx,
1046 struct BMEditMesh *editData, struct DerivedMesh *dm,
1047 float (*vertexCos)[3], int numVerts)
1049 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1051 if (mti->deformVertsEM_DM) {
1052 mti->deformVertsEM_DM(md, ctx, editData, dm, vertexCos, numVerts);
1055 /* TODO(sybren): deduplicate all the copies of this code in this file. */
1058 mesh = BKE_id_new_nomain(ID_ME, NULL);
1059 DM_to_mesh(dm, mesh, ctx->object, CD_MASK_EVERYTHING, false);
1062 mti->deformVertsEM(md, ctx, editData, mesh, vertexCos, numVerts);
1065 BKE_id_free(NULL, mesh);
1070 void modifier_deformMatricesEM_DM_deprecated(struct ModifierData *md, const ModifierEvalContext *ctx,
1071 struct BMEditMesh *editData, struct DerivedMesh *dm,
1072 float (*vertexCos)[3], float (*defMats)[3][3], int numVerts)
1074 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1076 if (mti->deformMatricesEM_DM) {
1077 mti->deformMatricesEM_DM(md, ctx, editData, dm, vertexCos, defMats, numVerts);
1080 /* TODO(sybren): deduplicate all the copies of this code in this file. */
1083 mesh = BKE_id_new_nomain(ID_ME, NULL);
1084 DM_to_mesh(dm, mesh, ctx->object, CD_MASK_EVERYTHING, false);
1087 mti->deformMatricesEM(md, ctx, editData, mesh, vertexCos, defMats, numVerts);
1090 BKE_id_free(NULL, mesh);
1095 struct DerivedMesh *modifier_applyModifier_DM_deprecated(struct ModifierData *md, const ModifierEvalContext *ctx,
1096 struct DerivedMesh *dm)
1098 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1100 if (mti->applyModifier_DM) {
1101 return mti->applyModifier_DM(md, ctx, dm);
1104 /* TODO(sybren): deduplicate all the copies of this code in this file. */
1107 mesh = BKE_id_new_nomain(ID_ME, NULL);
1108 DM_to_mesh(dm, mesh, ctx->object, CD_MASK_EVERYTHING, false);
1111 struct Mesh *new_mesh = mti->applyModifier(md, ctx, mesh);
1113 /* Make a DM that doesn't reference new_mesh so we can free the latter. */
1114 DerivedMesh *ndm = CDDM_from_mesh_ex(new_mesh, CD_DUPLICATE);
1116 if(new_mesh != mesh) {
1117 BKE_id_free(NULL, new_mesh);
1120 BKE_id_free(NULL, mesh);
1127 struct DerivedMesh *modifier_applyModifierEM_DM_deprecated(struct ModifierData *md, const ModifierEvalContext *ctx,
1128 struct BMEditMesh *editData,
1129 struct DerivedMesh *dm)
1131 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1133 if (mti->applyModifierEM_DM) {
1134 return mti->applyModifierEM_DM(md, ctx, editData, dm);
1137 /* TODO(sybren): deduplicate all the copies of this code in this file. */
1140 mesh = BKE_id_new_nomain(ID_ME, NULL);
1141 DM_to_mesh(dm, mesh, ctx->object, CD_MASK_EVERYTHING, false);
1144 struct Mesh *new_mesh = mti->applyModifierEM(md, ctx, editData, mesh);
1146 /* Make a DM that doesn't reference new_mesh so we can free the latter. */
1147 DerivedMesh *ndm = CDDM_from_mesh_ex(new_mesh, CD_DUPLICATE);
1149 if(new_mesh != mesh) {
1150 BKE_id_free(NULL, new_mesh);
1153 BKE_id_free(NULL, mesh);