Merge branch 'master' into blender2.8
[blender.git] / source / blender / blenkernel / intern / modifier.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software  Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2005 by the Blender Foundation.
19  * All rights reserved.
20  *
21  * Contributor(s): Daniel Dunbar
22  *                 Ton Roosendaal,
23  *                 Ben Batt,
24  *                 Brecht Van Lommel,
25  *                 Campbell Barton
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  *
29  * Modifier stack implementation.
30  *
31  * BKE_modifier.h contains the function prototypes for this file.
32  *
33  */
34
35 /** \file blender/blenkernel/intern/modifier.c
36  *  \ingroup bke
37  */
38
39 #include <stdlib.h>
40 #include <stddef.h>
41 #include <string.h>
42 #include <stdarg.h>
43 #include <math.h>
44 #include <float.h>
45
46 #include "MEM_guardedalloc.h"
47
48 #include "DNA_armature_types.h"
49 #include "DNA_object_types.h"
50
51 #include "BLI_utildefines.h"
52 #include "BLI_listbase.h"
53 #include "BLI_linklist.h"
54 #include "BLI_path_util.h"
55 #include "BLI_string.h"
56 #include "BLI_string_utils.h"
57
58 #include "BLT_translation.h"
59
60 #include "BKE_appdir.h"
61 #include "BKE_key.h"
62 #include "BKE_library.h"
63 #include "BKE_library_query.h"
64 #include "BKE_multires.h"
65 #include "BKE_DerivedMesh.h"
66
67 /* may move these, only for modifier_path_relbase */
68 #include "BKE_global.h" /* ugh, G.main->name only */
69 #include "BKE_main.h"
70 /* end */
71
72 #include "MOD_modifiertypes.h"
73
74 static ModifierTypeInfo *modifier_types[NUM_MODIFIER_TYPES] = {NULL};
75 static VirtualModifierData virtualModifierCommonData;
76
77 void BKE_modifier_init(void)
78 {
79         ModifierData *md;
80
81         /* Initialize modifier types */
82         modifier_type_init(modifier_types); /* MOD_utils.c */
83
84         /* Initialize global cmmon storage used for virtual modifier list */
85         md = modifier_new(eModifierType_Armature);
86         virtualModifierCommonData.amd = *((ArmatureModifierData *) md);
87         modifier_free(md);
88
89         md = modifier_new(eModifierType_Curve);
90         virtualModifierCommonData.cmd = *((CurveModifierData *) md);
91         modifier_free(md);
92
93         md = modifier_new(eModifierType_Lattice);
94         virtualModifierCommonData.lmd = *((LatticeModifierData *) md);
95         modifier_free(md);
96
97         md = modifier_new(eModifierType_ShapeKey);
98         virtualModifierCommonData.smd = *((ShapeKeyModifierData *) md);
99         modifier_free(md);
100
101         virtualModifierCommonData.amd.modifier.mode |= eModifierMode_Virtual;
102         virtualModifierCommonData.cmd.modifier.mode |= eModifierMode_Virtual;
103         virtualModifierCommonData.lmd.modifier.mode |= eModifierMode_Virtual;
104         virtualModifierCommonData.smd.modifier.mode |= eModifierMode_Virtual;
105 }
106
107 const ModifierTypeInfo *modifierType_getInfo(ModifierType type)
108 {
109         /* type unsigned, no need to check < 0 */
110         if (type < NUM_MODIFIER_TYPES && modifier_types[type]->name[0] != '\0') {
111                 return modifier_types[type];
112         }
113         else {
114                 return NULL;
115         }
116 }
117
118 /***/
119
120 ModifierData *modifier_new(int type)
121 {
122         const ModifierTypeInfo *mti = modifierType_getInfo(type);
123         ModifierData *md = MEM_callocN(mti->structSize, mti->structName);
124         
125         /* note, this name must be made unique later */
126         BLI_strncpy(md->name, DATA_(mti->name), sizeof(md->name));
127
128         md->type = type;
129         md->mode = eModifierMode_Realtime | eModifierMode_Render | eModifierMode_Expanded;
130
131         if (mti->flags & eModifierTypeFlag_EnableInEditmode)
132                 md->mode |= eModifierMode_Editmode;
133
134         if (mti->initData) mti->initData(md);
135
136         return md;
137 }
138
139 void modifier_free(ModifierData *md) 
140 {
141         const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
142
143         if (mti->freeData) mti->freeData(md);
144         if (md->error) MEM_freeN(md->error);
145
146         MEM_freeN(md);
147 }
148
149 bool modifier_unique_name(ListBase *modifiers, ModifierData *md)
150 {
151         if (modifiers && md) {
152                 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
153
154                 return BLI_uniquename(modifiers, md, DATA_(mti->name), '.', offsetof(ModifierData, name), sizeof(md->name));
155         }
156         return false;
157 }
158
159 bool modifier_dependsOnTime(ModifierData *md)
160 {
161         const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
162
163         return mti->dependsOnTime && mti->dependsOnTime(md);
164 }
165
166 bool modifier_supportsMapping(ModifierData *md)
167 {
168         const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
169
170         return (mti->type == eModifierTypeType_OnlyDeform ||
171                 (mti->flags & eModifierTypeFlag_SupportsMapping));
172 }
173
174 bool modifier_isPreview(ModifierData *md)
175 {
176         const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
177
178         /* Constructive modifiers are highly likely to also modify data like vgroups or vcol! */
179         if (!((mti->flags & eModifierTypeFlag_UsesPreview) || (mti->type == eModifierTypeType_Constructive))) {
180                 return false;
181         }
182
183         if (md->mode & eModifierMode_Realtime) {
184                 return true;
185         }
186
187         return false;
188 }
189
190 ModifierData *modifiers_findByType(Object *ob, ModifierType type)
191 {
192         ModifierData *md = ob->modifiers.first;
193
194         for (; md; md = md->next)
195                 if (md->type == type)
196                         break;
197
198         return md;
199 }
200
201 ModifierData *modifiers_findByName(Object *ob, const char *name)
202 {
203         return BLI_findstring(&(ob->modifiers), name, offsetof(ModifierData, name));
204 }
205
206 void modifiers_clearErrors(Object *ob)
207 {
208         ModifierData *md = ob->modifiers.first;
209         /* int qRedraw = 0; */
210
211         for (; md; md = md->next) {
212                 if (md->error) {
213                         MEM_freeN(md->error);
214                         md->error = NULL;
215
216                         /* qRedraw = 1; */
217                 }
218         }
219 }
220
221 void modifiers_foreachObjectLink(Object *ob, ObjectWalkFunc walk, void *userData)
222 {
223         ModifierData *md = ob->modifiers.first;
224
225         for (; md; md = md->next) {
226                 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
227
228                 if (mti->foreachObjectLink)
229                         mti->foreachObjectLink(md, ob, walk, userData);
230         }
231 }
232
233 void modifiers_foreachIDLink(Object *ob, IDWalkFunc walk, void *userData)
234 {
235         ModifierData *md = ob->modifiers.first;
236
237         for (; md; md = md->next) {
238                 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
239
240                 if (mti->foreachIDLink) mti->foreachIDLink(md, ob, walk, userData);
241                 else if (mti->foreachObjectLink) {
242                         /* each Object can masquerade as an ID, so this should be OK */
243                         ObjectWalkFunc fp = (ObjectWalkFunc)walk;
244                         mti->foreachObjectLink(md, ob, fp, userData);
245                 }
246         }
247 }
248
249 void modifiers_foreachTexLink(Object *ob, TexWalkFunc walk, void *userData)
250 {
251         ModifierData *md = ob->modifiers.first;
252
253         for (; md; md = md->next) {
254                 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
255
256                 if (mti->foreachTexLink)
257                         mti->foreachTexLink(md, ob, walk, userData);
258         }
259 }
260
261 /* callback's can use this
262  * to avoid copying every member.
263  */
264 void modifier_copyData_generic(const ModifierData *md_src, ModifierData *md_dst)
265 {
266         const ModifierTypeInfo *mti = modifierType_getInfo(md_src->type);
267         const size_t data_size = sizeof(ModifierData);
268         const char *md_src_data = ((const char *)md_src) + data_size;
269         char       *md_dst_data =       ((char *)md_dst) + data_size;
270         BLI_assert(data_size <= (size_t)mti->structSize);
271         memcpy(md_dst_data, md_src_data, (size_t)mti->structSize - data_size);
272 }
273
274 static void modifier_copy_data_id_us_cb(void *UNUSED(userData), Object *UNUSED(ob), ID **idpoin, int cb_flag)
275 {
276         ID *id = *idpoin;
277         if (id != NULL && (cb_flag & IDWALK_CB_USER) != 0) {
278                 id_us_plus(id);
279         }
280 }
281
282 void modifier_copyData_ex(ModifierData *md, ModifierData *target, const int flag)
283 {
284         const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
285
286         target->mode = md->mode;
287
288         if (mti->copyData) {
289                 mti->copyData(md, target);
290         }
291
292         if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
293                 if (mti->foreachIDLink) {
294                         mti->foreachIDLink(target, NULL, modifier_copy_data_id_us_cb, NULL);
295                 }
296                 else if (mti->foreachObjectLink) {
297                         mti->foreachObjectLink(target, NULL, (ObjectWalkFunc)modifier_copy_data_id_us_cb, NULL);
298                 }
299         }
300 }
301
302 void modifier_copyData(ModifierData *md, ModifierData *target)
303 {
304         modifier_copyData_ex(md, target, 0);
305 }
306
307
308 bool modifier_supportsCage(struct Scene *scene, ModifierData *md)
309 {
310         const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
311
312         md->scene = scene;
313
314         return ((!mti->isDisabled || !mti->isDisabled(md, 0)) &&
315                 (mti->flags & eModifierTypeFlag_SupportsEditmode) &&
316                 modifier_supportsMapping(md));
317 }
318
319 bool modifier_couldBeCage(struct Scene *scene, ModifierData *md)
320 {
321         const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
322
323         md->scene = scene;
324
325         return ((md->mode & eModifierMode_Realtime) &&
326                 (md->mode & eModifierMode_Editmode) &&
327                 (!mti->isDisabled || !mti->isDisabled(md, 0)) &&
328                 modifier_supportsMapping(md));
329 }
330
331 bool modifier_isSameTopology(ModifierData *md)
332 {
333         const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
334         return ELEM(mti->type, eModifierTypeType_OnlyDeform, eModifierTypeType_NonGeometrical);
335 }
336
337 bool modifier_isNonGeometrical(ModifierData *md)
338 {
339         const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
340         return (mti->type == eModifierTypeType_NonGeometrical);
341 }
342
343 void modifier_setError(ModifierData *md, const char *_format, ...)
344 {
345         char buffer[512];
346         va_list ap;
347         const char *format = TIP_(_format);
348
349         va_start(ap, _format);
350         vsnprintf(buffer, sizeof(buffer), format, ap);
351         va_end(ap);
352         buffer[sizeof(buffer) - 1] = '\0';
353
354         if (md->error)
355                 MEM_freeN(md->error);
356
357         md->error = BLI_strdup(buffer);
358
359 }
360
361 /* used for buttons, to find out if the 'draw deformed in editmode' option is
362  * there
363  * 
364  * also used in transform_conversion.c, to detect CrazySpace [tm] (2nd arg
365  * then is NULL) 
366  * also used for some mesh tools to give warnings
367  */
368 int modifiers_getCageIndex(struct Scene *scene, Object *ob, int *r_lastPossibleCageIndex, bool is_virtual)
369 {
370         VirtualModifierData virtualModifierData;
371         ModifierData *md = (is_virtual) ? modifiers_getVirtualModifierList(ob, &virtualModifierData) : ob->modifiers.first;
372         int i, cageIndex = -1;
373
374         if (r_lastPossibleCageIndex) {
375                 /* ensure the value is initialized */
376                 *r_lastPossibleCageIndex = -1;
377         }
378
379         /* Find the last modifier acting on the cage. */
380         for (i = 0; md; i++, md = md->next) {
381                 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
382                 bool supports_mapping;
383
384                 md->scene = scene;
385
386                 if (mti->isDisabled && mti->isDisabled(md, 0)) continue;
387                 if (!(mti->flags & eModifierTypeFlag_SupportsEditmode)) continue;
388                 if (md->mode & eModifierMode_DisableTemporary) continue;
389
390                 supports_mapping = modifier_supportsMapping(md);
391                 if (r_lastPossibleCageIndex && supports_mapping) {
392                         *r_lastPossibleCageIndex = i;
393                 }
394
395                 if (!(md->mode & eModifierMode_Realtime)) continue;
396                 if (!(md->mode & eModifierMode_Editmode)) continue;
397
398                 if (!supports_mapping)
399                         break;
400
401                 if (md->mode & eModifierMode_OnCage)
402                         cageIndex = i;
403         }
404
405         return cageIndex;
406 }
407
408
409 bool modifiers_isSoftbodyEnabled(Object *ob)
410 {
411         ModifierData *md = modifiers_findByType(ob, eModifierType_Softbody);
412
413         return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
414 }
415
416 bool modifiers_isClothEnabled(Object *ob)
417 {
418         ModifierData *md = modifiers_findByType(ob, eModifierType_Cloth);
419
420         return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
421 }
422
423 bool modifiers_isModifierEnabled(Object *ob, int modifierType)
424 {
425         ModifierData *md = modifiers_findByType(ob, modifierType);
426
427         return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
428 }
429
430 bool modifiers_isParticleEnabled(Object *ob)
431 {
432         ModifierData *md = modifiers_findByType(ob, eModifierType_ParticleSystem);
433
434         return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
435 }
436
437 bool modifier_isEnabled(struct Scene *scene, ModifierData *md, int required_mode)
438 {
439         const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
440
441         md->scene = scene;
442
443         if ((md->mode & required_mode) != required_mode) return false;
444         if (mti->isDisabled && mti->isDisabled(md, required_mode == eModifierMode_Render)) return false;
445         if (md->mode & eModifierMode_DisableTemporary) return false;
446         if ((required_mode & eModifierMode_Editmode) && !(mti->flags & eModifierTypeFlag_SupportsEditmode)) return false;
447         
448         return true;
449 }
450
451 CDMaskLink *modifiers_calcDataMasks(struct Scene *scene, Object *ob, ModifierData *md,
452                                     CustomDataMask dataMask, int required_mode,
453                                     ModifierData *previewmd, CustomDataMask previewmask)
454 {
455         CDMaskLink *dataMasks = NULL;
456         CDMaskLink *curr, *prev;
457
458         /* build a list of modifier data requirements in reverse order */
459         for (; md; md = md->next) {
460                 const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
461
462                 curr = MEM_callocN(sizeof(CDMaskLink), "CDMaskLink");
463                 
464                 if (modifier_isEnabled(scene, md, required_mode)) {
465                         if (mti->requiredDataMask)
466                                 curr->mask = mti->requiredDataMask(ob, md);
467
468                         if (previewmd == md) {
469                                 curr->mask |= previewmask;
470                         }
471                 }
472
473                 /* prepend new datamask */
474                 curr->next = dataMasks;
475                 dataMasks = curr;
476         }
477
478         /* build the list of required data masks - each mask in the list must
479          * include all elements of the masks that follow it
480          *
481          * note the list is currently in reverse order, so "masks that follow it"
482          * actually means "masks that precede it" at the moment
483          */
484         for (curr = dataMasks, prev = NULL; curr; prev = curr, curr = curr->next) {
485                 if (prev) {
486                         CustomDataMask prev_mask = prev->mask;
487                         CustomDataMask curr_mask = curr->mask;
488
489                         curr->mask = curr_mask | prev_mask;
490                 }
491                 else {
492                         CustomDataMask curr_mask = curr->mask;
493
494                         curr->mask = curr_mask | dataMask;
495                 }
496         }
497
498         /* reverse the list so it's in the correct order */
499         BLI_linklist_reverse((LinkNode **)&dataMasks);
500
501         return dataMasks;
502 }
503
504 ModifierData *modifiers_getLastPreview(struct Scene *scene, ModifierData *md, int required_mode)
505 {
506         ModifierData *tmp_md = NULL;
507
508         if ((required_mode & ~eModifierMode_Editmode) != eModifierMode_Realtime)
509                 return tmp_md;
510
511         /* Find the latest modifier in stack generating preview. */
512         for (; md; md = md->next) {
513                 if (modifier_isEnabled(scene, md, required_mode) && modifier_isPreview(md))
514                         tmp_md = md;
515         }
516         return tmp_md;
517 }
518
519 /* NOTE: This is to support old files from before Blender supported modifiers,
520  * in some cases versioning code updates these so for new files this will
521  * return an empty list. */
522 ModifierData *modifiers_getVirtualModifierList(Object *ob, VirtualModifierData *virtualModifierData)
523 {
524         ModifierData *md;
525
526         md = ob->modifiers.first;
527
528         *virtualModifierData = virtualModifierCommonData;
529
530         if (ob->parent) {
531                 if (ob->parent->type == OB_ARMATURE && ob->partype == PARSKEL) {
532                         virtualModifierData->amd.object = ob->parent;
533                         virtualModifierData->amd.modifier.next = md;
534                         virtualModifierData->amd.deformflag = ((bArmature *)(ob->parent->data))->deformflag;
535                         md = &virtualModifierData->amd.modifier;
536                 }
537                 else if (ob->parent->type == OB_CURVE && ob->partype == PARSKEL) {
538                         virtualModifierData->cmd.object = ob->parent;
539                         virtualModifierData->cmd.defaxis = ob->trackflag + 1;
540                         virtualModifierData->cmd.modifier.next = md;
541                         md = &virtualModifierData->cmd.modifier;
542                 }
543                 else if (ob->parent->type == OB_LATTICE && ob->partype == PARSKEL) {
544                         virtualModifierData->lmd.object = ob->parent;
545                         virtualModifierData->lmd.modifier.next = md;
546                         md = &virtualModifierData->lmd.modifier;
547                 }
548         }
549
550         /* shape key modifier, not yet for curves */
551         if (ELEM(ob->type, OB_MESH, OB_LATTICE) && BKE_key_from_object(ob)) {
552                 if (ob->type == OB_MESH && (ob->shapeflag & OB_SHAPE_EDIT_MODE))
553                         virtualModifierData->smd.modifier.mode |= eModifierMode_Editmode | eModifierMode_OnCage;
554                 else
555                         virtualModifierData->smd.modifier.mode &= ~eModifierMode_Editmode | eModifierMode_OnCage;
556
557                 virtualModifierData->smd.modifier.next = md;
558                 md = &virtualModifierData->smd.modifier;
559         }
560
561         return md;
562 }
563
564 /* Takes an object and returns its first selected armature, else just its armature
565  * This should work for multiple armatures per object
566  */
567 Object *modifiers_isDeformedByArmature(Object *ob)
568 {
569         VirtualModifierData virtualModifierData;
570         ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
571         ArmatureModifierData *amd = NULL;
572         
573         /* return the first selected armature, this lets us use multiple armatures */
574         for (; md; md = md->next) {
575                 if (md->type == eModifierType_Armature) {
576                         amd = (ArmatureModifierData *) md;
577                         if (amd->object && (amd->object->flag & SELECT))
578                                 return amd->object;
579                 }
580         }
581         
582         if (amd) /* if were still here then return the last armature */
583                 return amd->object;
584         
585         return NULL;
586 }
587
588 /* Takes an object and returns its first selected lattice, else just its lattice
589  * This should work for multiple lattices per object
590  */
591 Object *modifiers_isDeformedByLattice(Object *ob)
592 {
593         VirtualModifierData virtualModifierData;
594         ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
595         LatticeModifierData *lmd = NULL;
596         
597         /* return the first selected lattice, this lets us use multiple lattices */
598         for (; md; md = md->next) {
599                 if (md->type == eModifierType_Lattice) {
600                         lmd = (LatticeModifierData *) md;
601                         if (lmd->object && (lmd->object->flag & SELECT))
602                                 return lmd->object;
603                 }
604         }
605         
606         if (lmd) /* if were still here then return the last lattice */
607                 return lmd->object;
608         
609         return NULL;
610 }
611
612 /* Takes an object and returns its first selected curve, else just its curve
613  * This should work for multiple curves per object
614  */
615 Object *modifiers_isDeformedByCurve(Object *ob)
616 {
617         VirtualModifierData virtualModifierData;
618         ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
619         CurveModifierData *cmd = NULL;
620         
621         /* return the first selected curve, this lets us use multiple curves */
622         for (; md; md = md->next) {
623                 if (md->type == eModifierType_Curve) {
624                         cmd = (CurveModifierData *) md;
625                         if (cmd->object && (cmd->object->flag & SELECT))
626                                 return cmd->object;
627                 }
628         }
629         
630         if (cmd) /* if were still here then return the last curve */
631                 return cmd->object;
632         
633         return NULL;
634 }
635
636 bool modifiers_usesArmature(Object *ob, bArmature *arm)
637 {
638         VirtualModifierData virtualModifierData;
639         ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
640
641         for (; md; md = md->next) {
642                 if (md->type == eModifierType_Armature) {
643                         ArmatureModifierData *amd = (ArmatureModifierData *) md;
644                         if (amd->object && amd->object->data == arm)
645                                 return true;
646                 }
647         }
648
649         return false;
650 }
651
652 bool modifier_isCorrectableDeformed(ModifierData *md)
653 {
654         const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
655         return (mti->deformMatricesEM != NULL);
656 }
657
658 bool modifiers_isCorrectableDeformed(struct Scene *scene, Object *ob)
659 {
660         VirtualModifierData virtualModifierData;
661         ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
662         int required_mode = eModifierMode_Realtime;
663
664         if (ob->mode == OB_MODE_EDIT)
665                 required_mode |= eModifierMode_Editmode;
666         
667         for (; md; md = md->next) {
668                 if (!modifier_isEnabled(scene, md, required_mode)) {
669                         /* pass */
670                 }
671                 else if (modifier_isCorrectableDeformed(md)) {
672                         return true;
673                 }
674         }
675         return false;
676 }
677
678 /* Check whether the given object has a modifier in its stack that uses WEIGHT_MCOL CD layer
679  * to preview something... Used by DynamicPaint and WeightVG currently. */
680 bool modifiers_isPreview(Object *ob)
681 {
682         ModifierData *md = ob->modifiers.first;
683
684         for (; md; md = md->next) {
685                 if (modifier_isPreview(md))
686                         return true;
687         }
688
689         return false;
690 }
691
692 void modifier_freeTemporaryData(ModifierData *md)
693 {
694         if (md->type == eModifierType_Armature) {
695                 ArmatureModifierData *amd = (ArmatureModifierData *)md;
696
697                 if (amd->prevCos) {
698                         MEM_freeN(amd->prevCos);
699                         amd->prevCos = NULL;
700                 }
701         }
702 }
703
704 /* ensure modifier correctness when changing ob->data */
705 void test_object_modifiers(Object *ob)
706 {
707         ModifierData *md;
708
709         /* just multires checked for now, since only multires
710          * modifies mesh data */
711
712         if (ob->type != OB_MESH) return;
713
714         for (md = ob->modifiers.first; md; md = md->next) {
715                 if (md->type == eModifierType_Multires) {
716                         MultiresModifierData *mmd = (MultiresModifierData *)md;
717
718                         multiresModifier_set_levels_from_disps(mmd, ob);
719                 }
720         }
721 }
722
723 /* where should this go?, it doesnt fit well anywhere :S - campbell */
724
725 /* elubie: changed this to default to the same dir as the render output
726  * to prevent saving to C:\ on Windows */
727
728 /* campbell: logic behind this...
729  *
730  * - if the ID is from a library, return library path
731  * - else if the file has been saved return the blend file path.
732  * - else if the file isn't saved and the ID isn't from a library, return the temp dir.
733  */
734 const char *modifier_path_relbase(Object *ob)
735 {
736         if (G.relbase_valid || ID_IS_LINKED_DATABLOCK(ob)) {
737                 return ID_BLEND_PATH(G.main, &ob->id);
738         }
739         else {
740                 /* last resort, better then using "" which resolves to the current
741                  * working directory */
742                 return BKE_tempdir_session();
743         }
744 }
745
746 /* initializes the path with either */
747 void modifier_path_init(char *path, int path_maxlen, const char *name)
748 {
749         /* elubie: changed this to default to the same dir as the render output
750          * to prevent saving to C:\ on Windows */
751         BLI_join_dirfile(path, path_maxlen,
752                          G.relbase_valid ? "//" : BKE_tempdir_session(),
753                          name);
754 }
755
756
757 /* wrapper around ModifierTypeInfo.applyModifier that ensures valid normals */
758
759 struct DerivedMesh *modwrap_applyModifier(
760         ModifierData *md, const struct EvaluationContext *eval_ctx,
761         Object *ob, struct DerivedMesh *dm,
762         ModifierApplyFlag flag)
763 {
764         const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
765         BLI_assert(CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);
766
767         if (mti->dependsOnNormals && mti->dependsOnNormals(md)) {
768                 DM_ensure_normals(dm);
769         }
770         return mti->applyModifier(md, eval_ctx, ob, dm, flag);
771 }
772
773 struct DerivedMesh *modwrap_applyModifierEM(
774         ModifierData *md, const struct EvaluationContext *eval_ctx,
775         Object *ob, struct BMEditMesh *em,
776         DerivedMesh *dm,
777         ModifierApplyFlag flag)
778 {
779         const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
780         BLI_assert(CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);
781
782         if (mti->dependsOnNormals && mti->dependsOnNormals(md)) {
783                 DM_ensure_normals(dm);
784         }
785         return mti->applyModifierEM(md, eval_ctx, ob, em, dm, flag);
786 }
787
788 void modwrap_deformVerts(
789         ModifierData *md, const struct EvaluationContext *eval_ctx,
790         Object *ob, DerivedMesh *dm,
791         float (*vertexCos)[3], int numVerts,
792         ModifierApplyFlag flag)
793 {
794         const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
795         BLI_assert(!dm || CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);
796
797         if (dm && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
798                 DM_ensure_normals(dm);
799         }
800         mti->deformVerts(md, eval_ctx, ob, dm, vertexCos, numVerts, flag);
801 }
802
803 void modwrap_deformVertsEM(
804         ModifierData *md, const struct EvaluationContext *eval_ctx, Object *ob,
805         struct BMEditMesh *em, DerivedMesh *dm,
806         float (*vertexCos)[3], int numVerts)
807 {
808         const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
809         BLI_assert(!dm || CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);
810
811         if (dm && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
812                 DM_ensure_normals(dm);
813         }
814         mti->deformVertsEM(md, eval_ctx, ob, em, dm, vertexCos, numVerts);
815 }
816 /* end modifier callback wrappers */