Blender  V3.3
blenkernel/intern/modifier.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2005 Blender Foundation. All rights reserved. */
3 
10 /* Allow using deprecated functionality for .blend file I/O. */
11 #define DNA_DEPRECATED_ALLOW
12 
13 #include <float.h>
14 #include <math.h>
15 #include <stdarg.h>
16 #include <stddef.h>
17 #include <stdlib.h>
18 #include <string.h>
19 
20 #include "MEM_guardedalloc.h"
21 
22 #include "DNA_armature_types.h"
23 #include "DNA_cloth_types.h"
24 #include "DNA_dynamicpaint_types.h"
25 #include "DNA_fluid_types.h"
27 #include "DNA_mesh_types.h"
29 #include "DNA_object_force_types.h"
30 #include "DNA_object_types.h"
31 #include "DNA_scene_types.h"
32 #include "DNA_screen_types.h"
33 
34 #include "BLI_linklist.h"
35 #include "BLI_listbase.h"
36 #include "BLI_path_util.h"
37 #include "BLI_session_uuid.h"
38 #include "BLI_string.h"
39 #include "BLI_string_utils.h"
40 #include "BLI_utildefines.h"
41 
42 #include "BLT_translation.h"
43 
44 #include "BKE_DerivedMesh.h"
45 #include "BKE_appdir.h"
46 #include "BKE_editmesh.h"
47 #include "BKE_editmesh_cache.h"
48 #include "BKE_effect.h"
49 #include "BKE_fluid.h"
50 #include "BKE_global.h"
51 #include "BKE_gpencil_modifier.h"
52 #include "BKE_idtype.h"
53 #include "BKE_key.h"
54 #include "BKE_lib_id.h"
55 #include "BKE_lib_query.h"
56 #include "BKE_mesh.h"
57 #include "BKE_mesh_wrapper.h"
58 #include "BKE_multires.h"
59 #include "BKE_object.h"
60 #include "BKE_pointcache.h"
61 
62 /* may move these, only for BKE_modifier_path_relbase */
63 #include "BKE_main.h"
64 /* end */
65 
66 #include "DEG_depsgraph.h"
67 #include "DEG_depsgraph_query.h"
68 
69 #include "MOD_modifiertypes.h"
70 
71 #include "BLO_read_write.h"
72 
73 #include "CLG_log.h"
74 
75 static CLG_LogRef LOG = {"bke.modifier"};
78 
80 {
81  ModifierData *md;
82 
83  /* Initialize modifier types */
84  modifier_type_init(modifier_types); /* MOD_utils.c */
85 
86  /* Initialize global common storage used for virtual modifier list. */
90 
94 
98 
101  BKE_modifier_free(md);
102 
107 }
108 
110 {
111  /* type unsigned, no need to check < 0 */
112  if (type < NUM_MODIFIER_TYPES && modifier_types[type] && modifier_types[type]->name[0] != '\0') {
113  return modifier_types[type];
114  }
115 
116  return NULL;
117 }
118 
120 {
122 
123  strcpy(r_idname, MODIFIER_TYPE_PANEL_PREFIX);
124  strcat(r_idname, mti->name);
125 }
126 
128 {
130 }
131 
132 /***/
133 
135 {
137  ModifierData *md = MEM_callocN(mti->structSize, mti->structName);
138 
139  /* NOTE: this name must be made unique later. */
140  BLI_strncpy(md->name, DATA_(mti->name), sizeof(md->name));
141 
142  md->type = type;
145  md->ui_expand_flag = 1; /* Only open the main panel at the beginning, not the sub-panels. */
146 
149  }
150 
151  if (mti->initData) {
152  mti->initData(md);
153  }
154 
155  return md;
156 }
157 
159 {
161 
163 
164  return md;
165 }
166 
167 static void modifier_free_data_id_us_cb(void *UNUSED(userData),
168  Object *UNUSED(ob),
169  ID **idpoin,
170  int cb_flag)
171 {
172  ID *id = *idpoin;
173  if (id != NULL && (cb_flag & IDWALK_CB_USER) != 0) {
174  id_us_min(id);
175  }
176 }
177 
178 void BKE_modifier_free_ex(ModifierData *md, const int flag)
179 {
180  const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
181 
182  if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
183  if (mti->foreachIDLink) {
185  }
186  }
187 
188  if (mti->freeData) {
189  mti->freeData(md);
190  }
191  if (md->error) {
192  MEM_freeN(md->error);
193  }
194 
195  MEM_freeN(md);
196 }
197 
199 {
200  BKE_modifier_free_ex(md, 0);
201 }
202 
204 {
205  BLI_assert(BLI_findindex(&ob->modifiers, md) != -1);
206 
207  if (md->flag & eModifierFlag_Active) {
208  /* Prefer the previous modifier but use the next if this modifier is the first in the list. */
209  if (md->next != NULL) {
211  }
212  else if (md->prev != NULL) {
214  }
215  }
216 
217  BLI_remlink(&ob->modifiers, md);
218 }
219 
221 {
223 }
224 
226 {
227  if (modifiers && md) {
228  const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
229 
230  return BLI_uniquename(
231  modifiers, md, DATA_(mti->name), '.', offsetof(ModifierData, name), sizeof(md->name));
232  }
233  return false;
234 }
235 
237 {
238  const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
239 
240  return mti->dependsOnTime && mti->dependsOnTime(scene, md);
241 }
242 
244 {
245  const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
246 
247  return (mti->type == eModifierTypeType_OnlyDeform ||
249 }
250 
252 {
253  const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
254 
255  /* Constructive modifiers are highly likely to also modify data like vgroups or vcol! */
256  if (!((mti->flags & eModifierTypeFlag_UsesPreview) ||
258  return false;
259  }
260 
261  if (md->mode & eModifierMode_Realtime) {
262  return true;
263  }
264 
265  return false;
266 }
267 
269 {
270  LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
271  if (md->type == type) {
272  return md;
273  }
274  }
275  return NULL;
276 }
277 
278 ModifierData *BKE_modifiers_findby_name(const Object *ob, const char *name)
279 {
280  return BLI_findstring(&(ob->modifiers), name, offsetof(ModifierData, name));
281 }
282 
284 {
285  LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
286  if (BLI_session_uuid_is_equal(&md->session_uuid, session_uuid)) {
287  return md;
288  }
289  }
290  return NULL;
291 }
292 
294 {
295  LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
296  if (md->error) {
297  MEM_freeN(md->error);
298  md->error = NULL;
299  }
300  }
301 }
302 
303 void BKE_modifiers_foreach_ID_link(Object *ob, IDWalkFunc walk, void *userData)
304 {
305  LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
306  const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
307 
308  if (mti->foreachIDLink) {
309  mti->foreachIDLink(md, ob, walk, userData);
310  }
311  }
312 }
313 
314 void BKE_modifiers_foreach_tex_link(Object *ob, TexWalkFunc walk, void *userData)
315 {
316  LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
317  const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
318 
319  if (mti->foreachTexLink) {
320  mti->foreachTexLink(md, ob, walk, userData);
321  }
322  }
323 }
324 
326 {
328 
329  BLI_strncpy(md_dst->name, md->name, sizeof(md_dst->name));
330  BKE_modifier_copydata_ex(md, md_dst, flag);
331 
332  return md_dst;
333 }
334 
336  ModifierData *md_dst,
337  const int UNUSED(flag))
338 {
339  const ModifierTypeInfo *mti = BKE_modifier_get_info(md_src->type);
340 
341  /* md_dst may have already be fully initialized with some extra allocated data,
342  * we need to free it now to avoid memleak. */
343  if (mti->freeData) {
344  mti->freeData(md_dst);
345  }
346 
347  const size_t data_size = sizeof(ModifierData);
348  const char *md_src_data = ((const char *)md_src) + data_size;
349  char *md_dst_data = ((char *)md_dst) + data_size;
350  BLI_assert(data_size <= (size_t)mti->structSize);
351  memcpy(md_dst_data, md_src_data, (size_t)mti->structSize - data_size);
352 
353  /* Runtime fields are never to be preserved. */
354  md_dst->runtime = NULL;
355 }
356 
357 static void modifier_copy_data_id_us_cb(void *UNUSED(userData),
358  Object *UNUSED(ob),
359  ID **idpoin,
360  int cb_flag)
361 {
362  ID *id = *idpoin;
363  if (id != NULL && (cb_flag & IDWALK_CB_USER) != 0) {
364  id_us_plus(id);
365  }
366 }
367 
368 void BKE_modifier_copydata_ex(const ModifierData *md, ModifierData *target, const int flag)
369 {
370  const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
371 
372  target->mode = md->mode;
373  target->flag = md->flag;
374  target->ui_expand_flag = md->ui_expand_flag;
375 
376  if (mti->copyData) {
377  mti->copyData(md, target, flag);
378  }
379 
380  if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
381  if (mti->foreachIDLink) {
383  }
384  }
385 
386  if (flag & LIB_ID_CREATE_NO_MAIN) {
387  /* Make sure UUID is the same between the source and the target.
388  * This is needed in the cases when UUID is to be preserved and when there is no copyData
389  * callback, or the copyData does not do full byte copy of the modifier data. */
390  target->session_uuid = md->session_uuid;
391  }
392  else {
393  /* In the case copyData made full byte copy force UUID to be re-generated. */
395  }
396 }
397 
399 {
400  BKE_modifier_copydata_ex(md, target, 0);
401 }
402 
404 {
405  const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
406 
407  return ((!mti->isDisabled || !mti->isDisabled(scene, md, 0)) &&
409 }
410 
412 {
413  const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
414 
415  return ((md->mode & eModifierMode_Realtime) && (md->mode & eModifierMode_Editmode) &&
416  (!mti->isDisabled || !mti->isDisabled(scene, md, 0)) &&
418 }
419 
421 {
422  const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
424 }
425 
427 {
428  const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
429  return (mti->type == eModifierTypeType_NonGeometrical);
430 }
431 
432 void BKE_modifier_set_error(const Object *ob, ModifierData *md, const char *_format, ...)
433 {
434  char buffer[512];
435  va_list ap;
436  const char *format = TIP_(_format);
437 
438  va_start(ap, _format);
439  vsnprintf(buffer, sizeof(buffer), format, ap);
440  va_end(ap);
441  buffer[sizeof(buffer) - 1] = '\0';
442 
443  if (md->error) {
444  MEM_freeN(md->error);
445  }
446 
447  md->error = BLI_strdup(buffer);
448 
449 #ifndef NDEBUG
450  if ((md->mode & eModifierMode_Virtual) == 0) {
451  /* Ensure correct object is passed in. */
453  }
454 #endif
455 
456  CLOG_ERROR(&LOG, "Object: \"%s\", Modifier: \"%s\", %s", ob->id.name + 2, md->name, md->error);
457 }
458 
459 void BKE_modifier_set_warning(const struct Object *ob,
460  struct ModifierData *md,
461  const char *_format,
462  ...)
463 {
464  char buffer[512];
465  va_list ap;
466  const char *format = TIP_(_format);
467 
468  va_start(ap, _format);
469  vsnprintf(buffer, sizeof(buffer), format, ap);
470  va_end(ap);
471  buffer[sizeof(buffer) - 1] = '\0';
472 
473  /* Store the warning in the same field as the error.
474  * It is not expected to have both error and warning and having a single place to store the
475  * message simplifies interface code. */
476 
477  if (md->error) {
478  MEM_freeN(md->error);
479  }
480 
481  md->error = BLI_strdup(buffer);
482 
483 #ifndef NDEBUG
484  if ((md->mode & eModifierMode_Virtual) == 0) {
485  /* Ensure correct object is passed in. */
487  }
488 #endif
489 
490  UNUSED_VARS_NDEBUG(ob);
491 }
492 
494  Object *ob,
495  int *r_lastPossibleCageIndex,
496  bool is_virtual)
497 {
498  VirtualModifierData virtualModifierData;
499  ModifierData *md = (is_virtual) ?
500  BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData) :
501  ob->modifiers.first;
502 
503  if (r_lastPossibleCageIndex) {
504  /* ensure the value is initialized */
505  *r_lastPossibleCageIndex = -1;
506  }
507 
508  /* Find the last modifier acting on the cage. */
509  int cageIndex = -1;
510  for (int i = 0; md; i++, md = md->next) {
511  const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
512  bool supports_mapping;
513 
514  if (mti->isDisabled && mti->isDisabled(scene, md, 0)) {
515  continue;
516  }
518  continue;
519  }
521  continue;
522  }
523 
524  supports_mapping = BKE_modifier_supports_mapping(md);
525  if (r_lastPossibleCageIndex && supports_mapping) {
526  *r_lastPossibleCageIndex = i;
527  }
528 
529  if (!(md->mode & eModifierMode_Realtime)) {
530  continue;
531  }
532  if (!(md->mode & eModifierMode_Editmode)) {
533  continue;
534  }
535 
536  if (!supports_mapping) {
537  break;
538  }
539 
540  if (md->mode & eModifierMode_OnCage) {
541  cageIndex = i;
542  }
543  }
544 
545  return cageIndex;
546 }
547 
549 {
551 
552  return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
553 }
554 
556 {
558 
559  return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
560 }
561 
562 bool BKE_modifiers_is_modifier_enabled(Object *ob, int modifierType)
563 {
564  ModifierData *md = BKE_modifiers_findby_type(ob, modifierType);
565 
566  return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
567 }
568 
570 {
572 
573  return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
574 }
575 
576 bool BKE_modifier_is_enabled(const struct Scene *scene, ModifierData *md, int required_mode)
577 {
578  const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
579 
580  if ((md->mode & required_mode) != required_mode) {
581  return false;
582  }
583  if (scene != NULL && mti->isDisabled &&
584  mti->isDisabled(scene, md, required_mode == eModifierMode_Render)) {
585  return false;
586  }
588  return false;
589  }
590  if ((required_mode & eModifierMode_Editmode) &&
592  return false;
593  }
594 
595  return true;
596 }
597 
599 {
600  return (ID_IS_OVERRIDE_LIBRARY(ob) &&
601  (md == NULL || (md->flag & eModifierFlag_OverrideLibrary_Local) == 0));
602 }
603 
605  Object *ob,
606  ModifierData *md,
607  CustomData_MeshMasks *final_datamask,
608  int required_mode,
609  ModifierData *previewmd,
610  const CustomData_MeshMasks *previewmask)
611 {
612  CDMaskLink *dataMasks = NULL;
613  CDMaskLink *curr, *prev;
614  bool have_deform_modifier = false;
615 
616  /* build a list of modifier data requirements in reverse order */
617  for (; md; md = md->next) {
618  const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
619 
620  curr = MEM_callocN(sizeof(CDMaskLink), "CDMaskLink");
621 
622  if (BKE_modifier_is_enabled(scene, md, required_mode)) {
623  if (mti->type == eModifierTypeType_OnlyDeform) {
624  have_deform_modifier = true;
625  }
626 
627  if (mti->requiredDataMask) {
628  mti->requiredDataMask(ob, md, &curr->mask);
629  }
630 
631  if (previewmd == md && previewmask != NULL) {
632  CustomData_MeshMasks_update(&curr->mask, previewmask);
633  }
634  }
635 
636  if (!have_deform_modifier) {
637  /* Don't create orco layer when there is no deformation, we fall
638  * back to regular vertex coordinates */
639  curr->mask.vmask &= ~CD_MASK_ORCO;
640  }
641 
642  /* prepend new datamask */
643  curr->next = dataMasks;
644  dataMasks = curr;
645  }
646 
647  if (!have_deform_modifier) {
648  final_datamask->vmask &= ~CD_MASK_ORCO;
649  }
650 
651  /* build the list of required data masks - each mask in the list must
652  * include all elements of the masks that follow it
653  *
654  * note the list is currently in reverse order, so "masks that follow it"
655  * actually means "masks that precede it" at the moment
656  */
657  for (curr = dataMasks, prev = NULL; curr; prev = curr, curr = curr->next) {
658  if (prev) {
659  CustomData_MeshMasks_update(&curr->mask, &prev->mask);
660  }
661  else {
662  CustomData_MeshMasks_update(&curr->mask, final_datamask);
663  }
664  }
665 
666  /* reverse the list so it's in the correct order */
667  BLI_linklist_reverse((LinkNode **)&dataMasks);
668 
669  return dataMasks;
670 }
671 
673  ModifierData *md,
674  int required_mode)
675 {
676  ModifierData *tmp_md = NULL;
677 
678  if ((required_mode & ~eModifierMode_Editmode) != eModifierMode_Realtime) {
679  return tmp_md;
680  }
681 
682  /* Find the latest modifier in stack generating preview. */
683  for (; md; md = md->next) {
684  if (BKE_modifier_is_enabled(scene, md, required_mode) && BKE_modifier_is_preview(md)) {
685  tmp_md = md;
686  }
687  }
688  return tmp_md;
689 }
690 
692  VirtualModifierData *virtualModifierData)
693 {
694  ModifierData *md = ob->modifiers.first;
695 
696  *virtualModifierData = virtualModifierCommonData;
697 
698  if (ob->parent) {
699  if (ob->parent->type == OB_ARMATURE && ob->partype == PARSKEL) {
700  virtualModifierData->amd.object = ob->parent;
701  virtualModifierData->amd.modifier.next = md;
702  virtualModifierData->amd.deformflag = ((bArmature *)(ob->parent->data))->deformflag;
703  md = &virtualModifierData->amd.modifier;
704  }
705  else if (ob->parent->type == OB_CURVES_LEGACY && ob->partype == PARSKEL) {
706  virtualModifierData->cmd.object = ob->parent;
707  virtualModifierData->cmd.defaxis = ob->trackflag + 1;
708  virtualModifierData->cmd.modifier.next = md;
709  md = &virtualModifierData->cmd.modifier;
710  }
711  else if (ob->parent->type == OB_LATTICE && ob->partype == PARSKEL) {
712  virtualModifierData->lmd.object = ob->parent;
713  virtualModifierData->lmd.modifier.next = md;
714  md = &virtualModifierData->lmd.modifier;
715  }
716  }
717 
718  /* shape key modifier, not yet for curves */
719  if (ELEM(ob->type, OB_MESH, OB_LATTICE) && BKE_key_from_object((Object *)ob)) {
720  if (ob->type == OB_MESH && (ob->shapeflag & OB_SHAPE_EDIT_MODE)) {
721  virtualModifierData->smd.modifier.mode |= eModifierMode_Editmode | eModifierMode_OnCage;
722  }
723  else {
724  virtualModifierData->smd.modifier.mode &= ~eModifierMode_Editmode | eModifierMode_OnCage;
725  }
726 
727  virtualModifierData->smd.modifier.next = md;
728  md = &virtualModifierData->smd.modifier;
729  }
730 
731  return md;
732 }
733 
735 {
736  if (ob->type == OB_GPENCIL) {
737  GpencilVirtualModifierData gpencilvirtualModifierData;
740  ob, &gpencilvirtualModifierData);
741 
742  /* return the first selected armature, this lets us use multiple armatures */
743  for (; gmd; gmd = gmd->next) {
744  if (gmd->type == eGpencilModifierType_Armature) {
745  agmd = (ArmatureGpencilModifierData *)gmd;
746  if (agmd->object && (agmd->object->base_flag & BASE_SELECTED)) {
747  return agmd->object;
748  }
749  }
750  }
751  /* If we're still here then return the last armature. */
752  if (agmd) {
753  return agmd->object;
754  }
755  }
756  else {
757  VirtualModifierData virtualModifierData;
758  ArmatureModifierData *amd = NULL;
759  ModifierData *md = BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData);
760 
761  /* return the first selected armature, this lets us use multiple armatures */
762  for (; md; md = md->next) {
763  if (md->type == eModifierType_Armature) {
764  amd = (ArmatureModifierData *)md;
765  if (amd->object && (amd->object->base_flag & BASE_SELECTED)) {
766  return amd->object;
767  }
768  }
769  }
770  /* If we're still here then return the last armature. */
771  if (amd) {
772  return amd->object;
773  }
774  }
775 
776  return NULL;
777 }
778 
780 {
781  VirtualModifierData virtualModifierData;
782  ModifierData *md = BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData);
784 
785  /* return the first selected armature, this lets us use multiple armatures */
786  for (; md; md = md->next) {
787  if (md->type == eModifierType_MeshDeform) {
788  mdmd = (MeshDeformModifierData *)md;
789  if (mdmd->object && (mdmd->object->base_flag & BASE_SELECTED)) {
790  return mdmd->object;
791  }
792  }
793  }
794 
795  if (mdmd) { /* if we're still here then return the last armature */
796  return mdmd->object;
797  }
798 
799  return NULL;
800 }
801 
803 {
804  VirtualModifierData virtualModifierData;
805  ModifierData *md = BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData);
806  LatticeModifierData *lmd = NULL;
807 
808  /* return the first selected lattice, this lets us use multiple lattices */
809  for (; md; md = md->next) {
810  if (md->type == eModifierType_Lattice) {
811  lmd = (LatticeModifierData *)md;
812  if (lmd->object && (lmd->object->base_flag & BASE_SELECTED)) {
813  return lmd->object;
814  }
815  }
816  }
817 
818  if (lmd) { /* if we're still here then return the last lattice */
819  return lmd->object;
820  }
821 
822  return NULL;
823 }
824 
826 {
827  VirtualModifierData virtualModifierData;
828  ModifierData *md = BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData);
829  CurveModifierData *cmd = NULL;
830 
831  /* return the first selected curve, this lets us use multiple curves */
832  for (; md; md = md->next) {
833  if (md->type == eModifierType_Curve) {
834  cmd = (CurveModifierData *)md;
835  if (cmd->object && (cmd->object->base_flag & BASE_SELECTED)) {
836  return cmd->object;
837  }
838  }
839  }
840 
841  if (cmd) { /* if we're still here then return the last curve */
842  return cmd->object;
843  }
844 
845  return NULL;
846 }
847 
849 {
850  VirtualModifierData virtualModifierData;
851  ModifierData *md = BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData);
852  MultiresModifierData *mmd = NULL;
853 
854  for (; md; md = md->next) {
855  if (md->type == eModifierType_Multires) {
856  mmd = (MultiresModifierData *)md;
857  if (mmd->totlvl != 0) {
858  return true;
859  }
860  }
861  }
862  return false;
863 }
864 
866 {
867  VirtualModifierData virtualModifierData;
868  ModifierData *md = BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData);
869 
870  for (; md; md = md->next) {
871  if (md->type == eModifierType_Armature) {
873  if (amd->object && amd->object->data == arm) {
874  return true;
875  }
876  }
877  }
878 
879  return false;
880 }
881 
883 {
884  const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
885  return mti->deformMatricesEM != NULL;
886 }
887 
889 {
890  VirtualModifierData virtualModifierData;
891  ModifierData *md = BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData);
892  int required_mode = eModifierMode_Realtime;
893 
894  if (ob->mode == OB_MODE_EDIT) {
895  required_mode |= eModifierMode_Editmode;
896  }
897  for (; md; md = md->next) {
898  if (!BKE_modifier_is_enabled(scene, md, required_mode)) {
899  /* pass */
900  }
902  return true;
903  }
904  }
905  return false;
906 }
907 
909 {
910  if (md->type == eModifierType_Armature) {
912 
914  }
915 }
916 
918 {
919  ModifierData *md;
920 
921  /* just multires checked for now, since only multires
922  * modifies mesh data */
923 
924  if (ob->type != OB_MESH) {
925  return;
926  }
927 
928  for (md = ob->modifiers.first; md; md = md->next) {
929  if (md->type == eModifierType_Multires) {
931 
933  }
934  }
935 }
936 
937 const char *BKE_modifier_path_relbase(Main *bmain, Object *ob)
938 {
939  /* - If the ID is from a library, return library path.
940  * - Else if the file has been saved return the blend file path.
941  * - Else if the file isn't saved and the ID isn't from a library, return the temp dir.
942  */
943  if ((bmain->filepath[0] != '\0') || ID_IS_LINKED(ob)) {
944  return ID_BLEND_PATH(bmain, &ob->id);
945  }
946 
947  /* Last resort, better than using "" which resolves to the current working directory. */
948  return BKE_tempdir_session();
949 }
950 
952 {
953  return BKE_modifier_path_relbase(G_MAIN, ob);
954 }
955 
956 void BKE_modifier_path_init(char *path, int path_maxlen, const char *name)
957 {
958  const char *blendfile_path = BKE_main_blendfile_path_from_global();
959  BLI_join_dirfile(path, path_maxlen, blendfile_path[0] ? "//" : BKE_tempdir_session(), name);
960 }
961 
966 {
967  switch ((eMeshWrapperType)me->runtime.wrapper_type) {
968  case ME_WRAPPER_TYPE_BMESH: {
969  EditMeshData *edit_data = me->runtime.edit_data;
970  if (edit_data->vertexCos) {
971  /* Note that 'ensure' is acceptable here since these values aren't modified in-place.
972  * If that changes we'll need to recalculate. */
974  }
975  else {
977  }
978  break;
979  }
981  /* Not an expected case. */
982  break;
984  /* Normals are calculated lazily. */
985  break;
986  }
987 }
988 
989 /* wrapper around ModifierTypeInfo.modifyMesh that ensures valid normals */
990 
992  const ModifierEvalContext *ctx,
993  struct Mesh *me)
994 {
995  const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
996 
998  if ((mti->flags & eModifierTypeFlag_AcceptsBMesh) == 0) {
1000  }
1001  }
1002 
1003  if (mti->dependsOnNormals && mti->dependsOnNormals(md)) {
1005  }
1006  return mti->modifyMesh(md, ctx, me);
1007 }
1008 
1010  const ModifierEvalContext *ctx,
1011  Mesh *me,
1012  float (*vertexCos)[3],
1013  int numVerts)
1014 {
1015  const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
1016  if (me && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
1018  }
1019  mti->deformVerts(md, ctx, me, vertexCos, numVerts);
1020 }
1021 
1023  const ModifierEvalContext *ctx,
1024  struct BMEditMesh *em,
1025  Mesh *me,
1026  float (*vertexCos)[3],
1027  int numVerts)
1028 {
1029  const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
1030  if (me && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
1032  }
1033  mti->deformVertsEM(md, ctx, em, me, vertexCos, numVerts);
1034 }
1035 
1036 /* end modifier callback wrappers */
1037 
1039 {
1040  Mesh *me = NULL;
1041 
1042  if ((ob_eval->type == OB_MESH) && (ob_eval->mode & OB_MODE_EDIT)) {
1043  /* In EditMode, evaluated mesh is stored in BMEditMesh, not the object... */
1044  BMEditMesh *em = BKE_editmesh_from_object(ob_eval);
1045  /* 'em' might not exist yet in some cases, just after loading a .blend file, see T57878. */
1046  if (em != NULL) {
1047  me = BKE_object_get_editmesh_eval_final(ob_eval);
1048  }
1049  }
1050  if (me == NULL) {
1051  me = BKE_object_get_evaluated_mesh(ob_eval);
1052  }
1053 
1054  return me;
1055 }
1056 
1058 {
1059  const Object *object_orig = DEG_get_original_object((Object *)object);
1060  return BKE_modifiers_findby_session_uuid(object_orig, &md->session_uuid);
1061 }
1062 
1064  Object *object,
1065  ModifierData *md)
1066 {
1067  Object *object_eval = DEG_get_evaluated_object(depsgraph, object);
1068  if (object_eval == object) {
1069  return md;
1070  }
1071  return BKE_modifiers_findby_session_uuid(object_eval, &md->session_uuid);
1072 }
1073 
1075 {
1076  struct GSet *used_uuids = BLI_gset_new(
1078 
1079  LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
1080  const SessionUUID *session_uuid = &md->session_uuid;
1081  if (!BLI_session_uuid_is_generated(session_uuid)) {
1082  printf("Modifier %s -> %s does not have UUID generated.\n", object->id.name + 2, md->name);
1083  continue;
1084  }
1085 
1086  if (BLI_gset_lookup(used_uuids, session_uuid) != NULL) {
1087  printf("Modifier %s -> %s has duplicate UUID generated.\n", object->id.name + 2, md->name);
1088  continue;
1089  }
1090 
1091  BLI_gset_insert(used_uuids, (void *)session_uuid);
1092  }
1093 
1094  BLI_gset_free(used_uuids, NULL);
1095 }
1096 
1097 void BKE_modifier_blend_write(BlendWriter *writer, const ID *id_owner, ListBase *modbase)
1098 {
1099  if (modbase == NULL) {
1100  return;
1101  }
1102 
1103  LISTBASE_FOREACH (ModifierData *, md, modbase) {
1104  const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
1105  if (mti == NULL) {
1106  continue;
1107  }
1108 
1109  /* If the blendWrite callback is defined, it should handle the whole writing process. */
1110  if (mti->blendWrite != NULL) {
1111  mti->blendWrite(writer, id_owner, md);
1112  continue;
1113  }
1114 
1115  BLO_write_struct_by_name(writer, mti->structName, md);
1116 
1117  if (md->type == eModifierType_Cloth) {
1118  ClothModifierData *clmd = (ClothModifierData *)md;
1119 
1123  BKE_ptcache_blend_write(writer, &clmd->ptcaches);
1124  }
1125  else if (md->type == eModifierType_Fluid) {
1126  FluidModifierData *fmd = (FluidModifierData *)md;
1127 
1128  if (fmd->type & MOD_FLUID_TYPE_DOMAIN) {
1130 
1131  if (fmd->domain) {
1132  BKE_ptcache_blend_write(writer, &(fmd->domain->ptcaches[0]));
1133 
1134  /* create fake pointcache so that old blender versions can read it */
1135  fmd->domain->point_cache[1] = BKE_ptcache_add(&fmd->domain->ptcaches[1]);
1137  fmd->domain->point_cache[1]->step = 1;
1138 
1139  BKE_ptcache_blend_write(writer, &(fmd->domain->ptcaches[1]));
1140 
1141  if (fmd->domain->coba) {
1142  BLO_write_struct(writer, ColorBand, fmd->domain->coba);
1143  }
1144 
1145  /* cleanup the fake pointcache */
1147  fmd->domain->point_cache[1] = NULL;
1148 
1150  }
1151  }
1152  else if (fmd->type & MOD_FLUID_TYPE_FLOW) {
1153  BLO_write_struct(writer, FluidFlowSettings, fmd->flow);
1154  }
1155  else if (fmd->type & MOD_FLUID_TYPE_EFFEC) {
1157  }
1158  }
1159  else if (md->type == eModifierType_Fluidsim) {
1160  FluidsimModifierData *fluidmd = (FluidsimModifierData *)md;
1161 
1162  BLO_write_struct(writer, FluidsimSettings, fluidmd->fss);
1163  }
1164  else if (md->type == eModifierType_DynamicPaint) {
1166 
1167  if (pmd->canvas) {
1169 
1170  /* write surfaces */
1173  }
1174  /* write caches and effector weights */
1176  BKE_ptcache_blend_write(writer, &(surface->ptcaches));
1177 
1178  BLO_write_struct(writer, EffectorWeights, surface->effector_weights);
1179  }
1180  }
1181  if (pmd->brush) {
1183  BLO_write_struct(writer, ColorBand, pmd->brush->paint_ramp);
1184  BLO_write_struct(writer, ColorBand, pmd->brush->vel_ramp);
1185  }
1186  }
1187  else if (md->type == eModifierType_Collision) {
1188 
1189 #if 0
1191  /* TODO: CollisionModifier should use pointcache
1192  * + have proper reset events before enabling this. */
1193  writestruct(wd, DATA, MVert, collmd->numverts, collmd->x);
1194  writestruct(wd, DATA, MVert, collmd->numverts, collmd->xnew);
1195  writestruct(wd, DATA, MFace, collmd->numfaces, collmd->mfaces);
1196 #endif
1197  }
1198  }
1199 }
1200 
1201 /* TODO(sergey): Find a better place for this.
1202  *
1203  * Unfortunately, this can not be done as a regular do_versions() since the modifier type is
1204  * set to NONE, so the do_versions code wouldn't know where the modifier came from.
1205  *
1206  * The best approach seems to have the functionality in versioning_280.c but still call the
1207  * function from #BKE_modifier_blend_read_data().
1208  */
1209 
1210 /* Domain, inflow, ... */
1211 static void modifier_ensure_type(FluidModifierData *fluid_modifier_data, int type)
1212 {
1213  fluid_modifier_data->type = type;
1214  BKE_fluid_modifier_free(fluid_modifier_data);
1215  BKE_fluid_modifier_create_type_data(fluid_modifier_data);
1216 }
1217 
1224  Object *object,
1225  ListBase *modifiers,
1226  ModifierData *old_modifier_data)
1227 {
1228  ModifierData *new_modifier_data = BKE_modifier_new(eModifierType_Fluid);
1229  FluidModifierData *fluid_modifier_data = (FluidModifierData *)new_modifier_data;
1230 
1231  if (old_modifier_data->type == eModifierType_Fluidsim) {
1232  FluidsimModifierData *old_fluidsim_modifier_data = (FluidsimModifierData *)old_modifier_data;
1233  FluidsimSettings *old_fluidsim_settings = BLO_read_get_new_data_address(
1234  reader, old_fluidsim_modifier_data->fss);
1235  switch (old_fluidsim_settings->type) {
1236  case OB_FLUIDSIM_ENABLE:
1237  modifier_ensure_type(fluid_modifier_data, 0);
1238  break;
1239  case OB_FLUIDSIM_DOMAIN:
1240  modifier_ensure_type(fluid_modifier_data, MOD_FLUID_TYPE_DOMAIN);
1241  BKE_fluid_domain_type_set(object, fluid_modifier_data->domain, FLUID_DOMAIN_TYPE_LIQUID);
1242  break;
1243  case OB_FLUIDSIM_FLUID:
1244  modifier_ensure_type(fluid_modifier_data, MOD_FLUID_TYPE_FLOW);
1245  BKE_fluid_flow_type_set(object, fluid_modifier_data->flow, FLUID_FLOW_TYPE_LIQUID);
1246  /* No need to emit liquid far away from surface. */
1247  fluid_modifier_data->flow->surface_distance = 0.0f;
1248  break;
1249  case OB_FLUIDSIM_OBSTACLE:
1250  modifier_ensure_type(fluid_modifier_data, MOD_FLUID_TYPE_EFFEC);
1252  object, fluid_modifier_data->effector, FLUID_EFFECTOR_TYPE_COLLISION);
1253  break;
1254  case OB_FLUIDSIM_INFLOW:
1255  modifier_ensure_type(fluid_modifier_data, MOD_FLUID_TYPE_FLOW);
1256  BKE_fluid_flow_type_set(object, fluid_modifier_data->flow, FLUID_FLOW_TYPE_LIQUID);
1257  BKE_fluid_flow_behavior_set(object, fluid_modifier_data->flow, FLUID_FLOW_BEHAVIOR_INFLOW);
1258  /* No need to emit liquid far away from surface. */
1259  fluid_modifier_data->flow->surface_distance = 0.0f;
1260  break;
1261  case OB_FLUIDSIM_OUTFLOW:
1262  modifier_ensure_type(fluid_modifier_data, MOD_FLUID_TYPE_FLOW);
1263  BKE_fluid_flow_type_set(object, fluid_modifier_data->flow, FLUID_FLOW_TYPE_LIQUID);
1265  object, fluid_modifier_data->flow, FLUID_FLOW_BEHAVIOR_OUTFLOW);
1266  break;
1267  case OB_FLUIDSIM_PARTICLE:
1268  /* "Particle" type objects not being used by Mantaflow fluid simulations.
1269  * Skip this object, secondary particles can only be enabled through the domain object. */
1270  break;
1271  case OB_FLUIDSIM_CONTROL:
1272  /* "Control" type objects not being used by Mantaflow fluid simulations.
1273  * Use guiding type instead which is similar. */
1274  modifier_ensure_type(fluid_modifier_data, MOD_FLUID_TYPE_EFFEC);
1276  object, fluid_modifier_data->effector, FLUID_EFFECTOR_TYPE_GUIDE);
1277  break;
1278  }
1279  }
1280  else if (old_modifier_data->type == eModifierType_Smoke) {
1281  SmokeModifierData *old_smoke_modifier_data = (SmokeModifierData *)old_modifier_data;
1282  modifier_ensure_type(fluid_modifier_data, old_smoke_modifier_data->type);
1283  if (fluid_modifier_data->type == MOD_FLUID_TYPE_DOMAIN) {
1284  BKE_fluid_domain_type_set(object, fluid_modifier_data->domain, FLUID_DOMAIN_TYPE_GAS);
1285  }
1286  else if (fluid_modifier_data->type == MOD_FLUID_TYPE_FLOW) {
1287  BKE_fluid_flow_type_set(object, fluid_modifier_data->flow, FLUID_FLOW_TYPE_SMOKE);
1288  }
1289  else if (fluid_modifier_data->type == MOD_FLUID_TYPE_EFFEC) {
1291  object, fluid_modifier_data->effector, FLUID_EFFECTOR_TYPE_COLLISION);
1292  }
1293  }
1294 
1295  /* Replace modifier data in the stack. */
1296  new_modifier_data->next = old_modifier_data->next;
1297  new_modifier_data->prev = old_modifier_data->prev;
1298  if (new_modifier_data->prev != NULL) {
1299  new_modifier_data->prev->next = new_modifier_data;
1300  }
1301  if (new_modifier_data->next != NULL) {
1302  new_modifier_data->next->prev = new_modifier_data;
1303  }
1304  if (modifiers->first == old_modifier_data) {
1305  modifiers->first = new_modifier_data;
1306  }
1307  if (modifiers->last == old_modifier_data) {
1308  modifiers->last = new_modifier_data;
1309  }
1310 
1311  /* Free old modifier data. */
1312  MEM_freeN(old_modifier_data);
1313 
1314  return new_modifier_data;
1315 }
1316 
1318 {
1319  BLO_read_list(reader, lb);
1320 
1321  LISTBASE_FOREACH (ModifierData *, md, lb) {
1323 
1324  md->error = NULL;
1325  md->runtime = NULL;
1326 
1327  /* Modifier data has been allocated as a part of data migration process and
1328  * no reading of nested fields from file is needed. */
1329  bool is_allocated = false;
1330 
1331  if (md->type == eModifierType_Fluidsim) {
1333  BLO_read_data_reports(reader),
1334  RPT_WARNING,
1335  TIP_("Possible data loss when saving this file! %s modifier is deprecated (Object: %s)"),
1336  md->name,
1337  ob->id.name + 2);
1338  md = modifier_replace_with_fluid(reader, ob, lb, md);
1339  is_allocated = true;
1340  }
1341  else if (md->type == eModifierType_Smoke) {
1343  BLO_read_data_reports(reader),
1344  RPT_WARNING,
1345  TIP_("Possible data loss when saving this file! %s modifier is deprecated (Object: %s)"),
1346  md->name,
1347  ob->id.name + 2);
1348  md = modifier_replace_with_fluid(reader, ob, lb, md);
1349  is_allocated = true;
1350  }
1351 
1352  const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
1353 
1354  /* if modifiers disappear, or for upward compatibility */
1355  if (mti == NULL) {
1356  md->type = eModifierType_None;
1357  }
1358 
1359  if (is_allocated) {
1360  /* All the fields has been properly allocated. */
1361  }
1362  else if (md->type == eModifierType_Cloth) {
1363  ClothModifierData *clmd = (ClothModifierData *)md;
1364 
1365  clmd->clothObject = NULL;
1366  clmd->hairdata = NULL;
1367 
1368  BLO_read_data_address(reader, &clmd->sim_parms);
1369  BLO_read_data_address(reader, &clmd->coll_parms);
1370 
1371  BKE_ptcache_blend_read_data(reader, &clmd->ptcaches, &clmd->point_cache, 0);
1372 
1373  if (clmd->sim_parms) {
1374  if (clmd->sim_parms->presets > 10) {
1375  clmd->sim_parms->presets = 0;
1376  }
1377 
1378  clmd->sim_parms->reset = 0;
1379 
1381 
1382  if (!clmd->sim_parms->effector_weights) {
1384  }
1385  }
1386 
1387  clmd->solver_result = NULL;
1388  }
1389  else if (md->type == eModifierType_Fluid) {
1390 
1391  FluidModifierData *fmd = (FluidModifierData *)md;
1392 
1393  if (fmd->type == MOD_FLUID_TYPE_DOMAIN) {
1394  fmd->flow = NULL;
1395  fmd->effector = NULL;
1396  BLO_read_data_address(reader, &fmd->domain);
1397  fmd->domain->fmd = fmd;
1398 
1399  fmd->domain->fluid = NULL;
1401  fmd->domain->tex_density = NULL;
1402  fmd->domain->tex_color = NULL;
1403  fmd->domain->tex_shadow = NULL;
1404  fmd->domain->tex_flame = NULL;
1405  fmd->domain->tex_flame_coba = NULL;
1406  fmd->domain->tex_coba = NULL;
1407  fmd->domain->tex_field = NULL;
1408  fmd->domain->tex_velocity_x = NULL;
1409  fmd->domain->tex_velocity_y = NULL;
1410  fmd->domain->tex_velocity_z = NULL;
1411  fmd->domain->tex_wt = NULL;
1412  BLO_read_data_address(reader, &fmd->domain->coba);
1413 
1415  if (!fmd->domain->effector_weights) {
1417  }
1418 
1420  reader, &(fmd->domain->ptcaches[0]), &(fmd->domain->point_cache[0]), 1);
1421 
1422  /* Manta sim uses only one cache from now on, so store pointer convert */
1423  if (fmd->domain->ptcaches[1].first || fmd->domain->point_cache[1]) {
1424  if (fmd->domain->point_cache[1]) {
1425  PointCache *cache = BLO_read_get_new_data_address(reader, fmd->domain->point_cache[1]);
1426  if (cache->flag & PTCACHE_FAKE_SMOKE) {
1427  /* Manta-sim/smoke was already saved in "new format" and this cache is a fake one. */
1428  }
1429  else {
1430  printf(
1431  "High resolution manta cache not available due to pointcache update. Please "
1432  "reset the simulation.\n");
1433  }
1434  BKE_ptcache_free(cache);
1435  }
1436  BLI_listbase_clear(&fmd->domain->ptcaches[1]);
1437  fmd->domain->point_cache[1] = NULL;
1438  }
1439  }
1440  else if (fmd->type == MOD_FLUID_TYPE_FLOW) {
1441  fmd->domain = NULL;
1442  fmd->effector = NULL;
1443  BLO_read_data_address(reader, &fmd->flow);
1444  fmd->flow->fmd = fmd;
1445  fmd->flow->mesh = NULL;
1446  fmd->flow->verts_old = NULL;
1447  fmd->flow->numverts = 0;
1448  BLO_read_data_address(reader, &fmd->flow->psys);
1449  }
1450  else if (fmd->type == MOD_FLUID_TYPE_EFFEC) {
1451  fmd->flow = NULL;
1452  fmd->domain = NULL;
1453  BLO_read_data_address(reader, &fmd->effector);
1454  if (fmd->effector) {
1455  fmd->effector->fmd = fmd;
1456  fmd->effector->verts_old = NULL;
1457  fmd->effector->numverts = 0;
1458  fmd->effector->mesh = NULL;
1459  }
1460  else {
1461  fmd->type = 0;
1462  fmd->flow = NULL;
1463  fmd->domain = NULL;
1464  fmd->effector = NULL;
1465  }
1466  }
1467  }
1468  else if (md->type == eModifierType_DynamicPaint) {
1470 
1471  if (pmd->canvas) {
1472  BLO_read_data_address(reader, &pmd->canvas);
1473  pmd->canvas->pmd = pmd;
1474  pmd->canvas->flags &= ~MOD_DPAINT_BAKING; /* just in case */
1475 
1476  if (pmd->canvas->surfaces.first) {
1477  BLO_read_list(reader, &pmd->canvas->surfaces);
1478 
1480  surface->canvas = pmd->canvas;
1481  surface->data = NULL;
1482  BKE_ptcache_blend_read_data(reader, &(surface->ptcaches), &(surface->pointcache), 1);
1483 
1484  BLO_read_data_address(reader, &surface->effector_weights);
1485  if (surface->effector_weights == NULL) {
1486  surface->effector_weights = BKE_effector_add_weights(NULL);
1487  }
1488  }
1489  }
1490  }
1491  if (pmd->brush) {
1492  BLO_read_data_address(reader, &pmd->brush);
1493  pmd->brush->pmd = pmd;
1494  BLO_read_data_address(reader, &pmd->brush->psys);
1495  BLO_read_data_address(reader, &pmd->brush->paint_ramp);
1496  BLO_read_data_address(reader, &pmd->brush->vel_ramp);
1497  }
1498  }
1499 
1500  if ((mti != NULL) && (mti->blendRead != NULL)) {
1501  mti->blendRead(reader, md);
1502  }
1503  }
1504 }
1505 
1507 {
1509 
1510  /* If linking from a library, clear 'local' library override flag. */
1511  if (ID_IS_LINKED(ob)) {
1514  }
1515  }
1516 }
void CustomData_MeshMasks_update(CustomData_MeshMasks *mask_dst, const CustomData_MeshMasks *mask_src)
Definition: customdata.cc:77
BMEditMesh * BKE_editmesh_from_object(struct Object *ob)
Return the BMEditMesh for a given object.
Definition: editmesh.c:58
void BKE_editmesh_cache_ensure_vert_normals(struct BMEditMesh *em, struct EditMeshData *emd)
struct EffectorWeights * BKE_effector_add_weights(struct Collection *collection)
Definition: effect.c:58
void BKE_fluid_flow_behavior_set(struct Object *object, struct FluidFlowSettings *settings, int behavior)
void BKE_fluid_effector_type_set(struct Object *object, struct FluidEffectorSettings *settings, int type)
void BKE_fluid_domain_type_set(struct Object *object, struct FluidDomainSettings *settings, int type)
Definition: fluid.c:4595
void BKE_fluid_modifier_create_type_data(struct FluidModifierData *fmd)
Definition: fluid.c:4809
void BKE_fluid_flow_type_set(struct Object *object, struct FluidFlowSettings *settings, int type)
Definition: fluid.c:4627
void BKE_fluid_modifier_free(struct FluidModifierData *fmd)
Definition: fluid.c:4798
#define G_MAIN
Definition: BKE_global.h:267
struct GpencilModifierData * BKE_gpencil_modifiers_get_virtual_modifierlist(const struct Object *ob, struct GpencilVirtualModifierData *data)
struct Key * BKE_key_from_object(struct Object *ob)
Definition: key.c:1803
@ LIB_ID_CREATE_NO_USER_REFCOUNT
Definition: BKE_lib_id.h:126
@ LIB_ID_CREATE_NO_MAIN
Definition: BKE_lib_id.h:122
void id_us_min(struct ID *id)
Definition: lib_id.c:313
void id_us_plus(struct ID *id)
Definition: lib_id.c:305
@ IDWALK_CB_USER
Definition: BKE_lib_query.h:73
const char * BKE_main_blendfile_path_from_global(void)
Definition: main.c:562
void BKE_mesh_wrapper_ensure_mdata(struct Mesh *me)
Definition: mesh_wrapper.cc:94
#define MODIFIER_TYPE_PANEL_PREFIX
Definition: BKE_modifier.h:381
void(* IDWalkFunc)(void *userData, struct Object *ob, struct ID **idpoin, int cb_flag)
Definition: BKE_modifier.h:107
@ eModifierTypeFlag_AcceptsBMesh
Definition: BKE_modifier.h:103
@ eModifierTypeFlag_SupportsMapping
Definition: BKE_modifier.h:68
@ eModifierTypeFlag_UsesPreview
Definition: BKE_modifier.h:99
@ eModifierTypeFlag_EnableInEditmode
Definition: BKE_modifier.h:78
@ eModifierTypeFlag_SupportsEditmode
Definition: BKE_modifier.h:69
void(* TexWalkFunc)(void *userData, struct Object *ob, struct ModifierData *md, const char *propname)
Definition: BKE_modifier.h:108
@ eModifierTypeType_OnlyDeform
Definition: BKE_modifier.h:44
@ eModifierTypeType_NonGeometrical
Definition: BKE_modifier.h:62
@ eModifierTypeType_Constructive
Definition: BKE_modifier.h:47
void multiresModifier_set_levels_from_disps(struct MultiresModifierData *mmd, struct Object *ob)
Definition: multires.c:503
General operations, lookup, etc. for blender objects.
void BKE_object_modifiers_lib_link_common(void *userData, struct Object *ob, struct ID **idpoin, int cb_flag)
Definition: object.cc:5562
struct Mesh * BKE_object_get_editmesh_eval_final(const struct Object *object)
struct Mesh * BKE_object_get_evaluated_mesh(const struct Object *object)
void BKE_object_modifier_set_active(struct Object *ob, struct ModifierData *md)
Definition: object.cc:1367
void BKE_ptcache_blend_read_data(struct BlendDataReader *reader, struct ListBase *ptcaches, struct PointCache **ocache, int force_disk)
Definition: pointcache.c:3896
struct PointCache * BKE_ptcache_add(struct ListBase *ptcaches)
Definition: pointcache.c:3014
void BKE_ptcache_free_list(struct ListBase *ptcaches)
Definition: pointcache.c:3052
void BKE_ptcache_free(struct PointCache *cache)
Definition: pointcache.c:3041
void BKE_ptcache_blend_write(struct BlendWriter *writer, struct ListBase *ptcaches)
Definition: pointcache.c:3820
#define BLI_assert(a)
Definition: BLI_assert.h:46
struct GSet GSet
Definition: BLI_ghash.h:340
GSet * BLI_gset_new(GSetHashFP hashfp, GSetCmpFP cmpfp, const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:947
void * BLI_gset_lookup(const GSet *gs, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:1061
void BLI_gset_insert(GSet *gs, void *key)
Definition: BLI_ghash.c:962
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
Definition: BLI_ghash.c:1037
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:273
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:100
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void * BLI_findstring(const struct ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_join_dirfile(char *__restrict dst, size_t maxlen, const char *__restrict dir, const char *__restrict file) ATTR_NONNULL()
Definition: path_util.c:1531
bool BLI_session_uuid_ghash_compare(const void *lhs_v, const void *rhs_v)
Definition: session_uuid.c:59
SessionUUID BLI_session_uuid_generate(void)
Definition: session_uuid.c:22
uint BLI_session_uuid_ghash_hash(const void *uuid_v)
Definition: session_uuid.c:53
bool BLI_session_uuid_is_equal(const SessionUUID *lhs, const SessionUUID *rhs)
Definition: session_uuid.c:43
bool BLI_session_uuid_is_generated(const SessionUUID *uuid)
Definition: session_uuid.c:38
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC
Definition: string.c:42
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
bool BLI_uniquename(struct ListBase *list, void *vlink, const char *defname, char delim, int name_offset, size_t name_len)
Definition: string_utils.c:309
ThreadRWMutex * BLI_rw_mutex_alloc(void)
Definition: threads.cc:508
#define UNUSED_VARS_NDEBUG(...)
#define UNUSED(x)
#define ELEM(...)
@ DATA
#define BLO_read_data_address(reader, ptr_p)
void BLO_write_struct_by_name(BlendWriter *writer, const char *struct_name, const void *data_ptr)
Definition: writefile.c:1494
#define BLO_write_struct(writer, struct_name, data_ptr)
void BLO_read_list(BlendDataReader *reader, struct ListBase *list)
Definition: readfile.c:5172
void * BLO_read_get_new_data_address(BlendDataReader *reader, const void *old_address)
Definition: readfile.c:5123
struct BlendFileReadReport * BLO_read_data_reports(BlendDataReader *reader)
Definition: readfile.c:5303
void BLO_reportf_wrap(struct BlendFileReadReport *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
#define TIP_(msgid)
#define DATA_(msgid)
#define CLOG_ERROR(clg_ref,...)
Definition: CLG_log.h:190
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
struct Object * DEG_get_original_object(struct Object *object)
struct Object * DEG_get_evaluated_object(const struct Depsgraph *depsgraph, struct Object *object)
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:566
#define ID_BLEND_PATH(_bmain, _id)
Definition: DNA_ID.h:559
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition: DNA_ID.h:588
#define CD_MASK_ORCO
@ MOD_DPAINT_BAKING
@ FLUID_DOMAIN_TYPE_GAS
@ FLUID_DOMAIN_TYPE_LIQUID
@ FLUID_FLOW_TYPE_LIQUID
@ FLUID_FLOW_TYPE_SMOKE
@ FLUID_FLOW_BEHAVIOR_OUTFLOW
@ FLUID_FLOW_BEHAVIOR_INFLOW
@ FLUID_EFFECTOR_TYPE_GUIDE
@ FLUID_EFFECTOR_TYPE_COLLISION
@ eGpencilModifierType_Armature
@ BASE_SELECTED
eMeshWrapperType
@ ME_WRAPPER_TYPE_MDATA
@ ME_WRAPPER_TYPE_SUBD
@ ME_WRAPPER_TYPE_BMESH
@ eModifierFlag_OverrideLibrary_Local
@ eModifierFlag_Active
@ eModifierMode_Virtual
@ eModifierMode_Render
@ eModifierMode_Editmode
@ eModifierMode_DisableTemporary
@ eModifierMode_Realtime
@ eModifierMode_OnCage
struct ModifierData ModifierData
ModifierType
@ eModifierType_ParticleSystem
@ eModifierType_MeshDeform
@ eModifierType_Fluidsim
@ eModifierType_Curve
@ eModifierType_Lattice
@ eModifierType_Cloth
@ eModifierType_Fluid
@ NUM_MODIFIER_TYPES
@ eModifierType_ShapeKey
@ eModifierType_Armature
@ eModifierType_Collision
@ eModifierType_DynamicPaint
@ eModifierType_None
@ eModifierType_Softbody
@ eModifierType_Multires
@ MOD_FLUID_TYPE_EFFEC
@ MOD_FLUID_TYPE_DOMAIN
@ MOD_FLUID_TYPE_FLOW
@ OB_MODE_EDIT
#define OB_FLUIDSIM_OUTFLOW
#define OB_FLUIDSIM_INFLOW
#define OB_FLUIDSIM_PARTICLE
#define OB_FLUIDSIM_ENABLE
#define OB_FLUIDSIM_CONTROL
#define OB_FLUIDSIM_DOMAIN
#define OB_FLUIDSIM_FLUID
#define OB_FLUIDSIM_OBSTACLE
Object is a sort of wrapper for general info.
@ OB_SHAPE_EDIT_MODE
@ OB_LATTICE
@ OB_ARMATURE
@ OB_MESH
@ OB_CURVES_LEGACY
@ OB_GPENCIL
@ PARSKEL
@ PTCACHE_FAKE_SMOKE
@ PTCACHE_DISK_CACHE
@ UI_PANEL_DATA_EXPAND_ROOT
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
void modifier_type_init(ModifierTypeInfo *types[])
Definition: MOD_util.c:274
bool BKE_modifier_depends_ontime(Scene *scene, ModifierData *md)
void BKE_modifier_panel_expand(ModifierData *md)
bool BKE_modifiers_is_modifier_enabled(Object *ob, int modifierType)
Object * BKE_modifiers_is_deformed_by_meshdeform(Object *ob)
bool BKE_modifier_is_non_geometrical(ModifierData *md)
void BKE_modifier_path_init(char *path, int path_maxlen, const char *name)
ModifierData * BKE_modifiers_get_virtual_modifierlist(const Object *ob, VirtualModifierData *virtualModifierData)
static void modifier_ensure_type(FluidModifierData *fluid_modifier_data, int type)
void BKE_modifier_check_uuids_unique_and_report(const Object *object)
const ModifierTypeInfo * BKE_modifier_get_info(ModifierType type)
void BKE_modifiers_clear_errors(Object *ob)
void BKE_modifier_blend_write(BlendWriter *writer, const ID *id_owner, ListBase *modbase)
bool BKE_modifiers_is_cloth_enabled(Object *ob)
ModifierData * BKE_modifier_copy_ex(const ModifierData *md, int flag)
Mesh * BKE_modifier_get_evaluated_mesh_from_evaluated_object(Object *ob_eval)
int BKE_modifiers_get_cage_index(const Scene *scene, Object *ob, int *r_lastPossibleCageIndex, bool is_virtual)
bool BKE_modifiers_is_correctable_deformed(const struct Scene *scene, Object *ob)
void BKE_modifier_copydata_ex(const ModifierData *md, ModifierData *target, const int flag)
ModifierData * BKE_modifiers_findby_name(const Object *ob, const char *name)
bool BKE_modifiers_uses_multires(Object *ob)
ModifierData * BKE_modifier_get_original(const Object *object, ModifierData *md)
static void modwrap_dependsOnNormals(Mesh *me)
static ModifierTypeInfo * modifier_types[NUM_MODIFIER_TYPES]
struct ModifierData * BKE_modifier_get_evaluated(Depsgraph *depsgraph, Object *object, ModifierData *md)
void BKE_modifier_deform_vertsEM(ModifierData *md, const ModifierEvalContext *ctx, struct BMEditMesh *em, Mesh *me, float(*vertexCos)[3], int numVerts)
void BKE_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb, Object *ob)
void BKE_modifier_set_error(const Object *ob, ModifierData *md, const char *_format,...)
bool BKE_modifier_supports_cage(struct Scene *scene, ModifierData *md)
bool BKE_modifiers_uses_armature(Object *ob, bArmature *arm)
void BKE_modifier_deform_verts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *me, float(*vertexCos)[3], int numVerts)
Object * BKE_modifiers_is_deformed_by_armature(Object *ob)
const char * BKE_modifier_path_relbase_from_global(Object *ob)
ModifierData * BKE_modifiers_findby_session_uuid(const Object *ob, const SessionUUID *session_uuid)
bool BKE_modifier_supports_mapping(ModifierData *md)
static void modifier_free_data_id_us_cb(void *UNUSED(userData), Object *UNUSED(ob), ID **idpoin, int cb_flag)
bool BKE_modifier_is_enabled(const struct Scene *scene, ModifierData *md, int required_mode)
static ModifierData * modifier_allocate_and_init(int type)
struct Mesh * BKE_modifier_modify_mesh(ModifierData *md, const ModifierEvalContext *ctx, struct Mesh *me)
void BKE_modifier_free_temporary_data(ModifierData *md)
void BKE_modifier_set_warning(const struct Object *ob, struct ModifierData *md, const char *_format,...)
static void modifier_copy_data_id_us_cb(void *UNUSED(userData), Object *UNUSED(ob), ID **idpoin, int cb_flag)
ModifierData * BKE_modifiers_findby_type(const Object *ob, ModifierType type)
bool BKE_modifier_is_same_topology(ModifierData *md)
ModifierData * BKE_modifier_new(int type)
void BKE_modifier_free(ModifierData *md)
CDMaskLink * BKE_modifier_calc_data_masks(const struct Scene *scene, Object *ob, ModifierData *md, CustomData_MeshMasks *final_datamask, int required_mode, ModifierData *previewmd, const CustomData_MeshMasks *previewmask)
bool BKE_modifier_is_nonlocal_in_liboverride(const Object *ob, const ModifierData *md)
void BKE_modifiers_test_object(Object *ob)
void BKE_modifier_remove_from_list(Object *ob, ModifierData *md)
bool BKE_modifiers_is_softbody_enabled(Object *ob)
Object * BKE_modifiers_is_deformed_by_lattice(Object *ob)
Object * BKE_modifiers_is_deformed_by_curve(Object *ob)
bool BKE_modifier_unique_name(ListBase *modifiers, ModifierData *md)
void BKE_modifiers_foreach_tex_link(Object *ob, TexWalkFunc walk, void *userData)
static CLG_LogRef LOG
static VirtualModifierData virtualModifierCommonData
void BKE_modifier_blend_read_lib(BlendLibReader *reader, Object *ob)
bool BKE_modifier_is_correctable_deformed(ModifierData *md)
bool BKE_modifiers_is_particle_enabled(Object *ob)
ModifierData * BKE_modifier_get_last_preview(const struct Scene *scene, ModifierData *md, int required_mode)
void BKE_modifier_copydata_generic(const ModifierData *md_src, ModifierData *md_dst, const int UNUSED(flag))
void BKE_modifiers_foreach_ID_link(Object *ob, IDWalkFunc walk, void *userData)
void BKE_modifier_free_ex(ModifierData *md, const int flag)
bool BKE_modifier_is_preview(ModifierData *md)
void BKE_modifier_type_panel_id(ModifierType type, char *r_idname)
static ModifierData * modifier_replace_with_fluid(BlendDataReader *reader, Object *object, ListBase *modifiers, ModifierData *old_modifier_data)
void BKE_modifier_copydata(const ModifierData *md, ModifierData *target)
bool BKE_modifier_couldbe_cage(struct Scene *scene, ModifierData *md)
void BKE_modifier_session_uuid_generate(ModifierData *md)
const char * BKE_modifier_path_relbase(Main *bmain, Object *ob)
void BKE_modifier_init(void)
void BM_mesh_normals_update(BMesh *bm)
Scene scene
const Depsgraph * depsgraph
struct @211::@212 surface
void * BKE_tempdir_session
ccl_global float * buffer
format
Definition: logImageCore.h:38
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
SymEdge< T > * prev(const SymEdge< T > *se)
Definition: delaunay_2d.cc:105
struct BMesh * bm
Definition: BKE_editmesh.h:40
struct ListBase ptcaches
struct ClothSolverResult * solver_result
struct ClothHairData * hairdata
struct Cloth * clothObject
struct PointCache * point_cache
struct ClothSimSettings * sim_parms
struct ClothCollSettings * coll_parms
struct EffectorWeights * effector_weights
struct Object * object
struct DynamicPaintModifierData * pmd
struct ParticleSystem * psys
struct DynamicPaintModifierData * pmd
struct DynamicPaintCanvasSettings * canvas
struct DynamicPaintBrushSettings * brush
const float(* vertexCos)[3]
struct ListBase ptcaches[2]
struct FluidModifierData * fmd
struct GPUTexture * tex_density
struct GPUTexture * tex_velocity_x
struct GPUTexture * tex_color
struct GPUTexture * tex_wt
struct GPUTexture * tex_velocity_y
struct GPUTexture * tex_field
struct MANTA * fluid
struct GPUTexture * tex_velocity_z
struct PointCache * point_cache[2]
struct GPUTexture * tex_shadow
struct ColorBand * coba
struct GPUTexture * tex_coba
struct GPUTexture * tex_flame
struct EffectorWeights * effector_weights
struct GPUTexture * tex_flame_coba
struct FluidModifierData * fmd
struct FluidModifierData * fmd
struct ParticleSystem * psys
struct Mesh * mesh
struct FluidDomainSettings * domain
struct FluidEffectorSettings * effector
struct FluidFlowSettings * flow
struct FluidsimSettings * fss
struct GpencilModifierData * next
Definition: DNA_ID.h:368
char name[66]
Definition: DNA_ID.h:378
struct Object * object
void * last
Definition: DNA_listBase.h:31
void * first
Definition: DNA_listBase.h:31
Definition: BKE_main.h:121
char filepath[1024]
Definition: BKE_main.h:124
struct EditMeshData * edit_data
struct BMEditMesh * edit_mesh
Mesh_Runtime runtime
struct ModifierData * next
struct ModifierData * prev
SessionUUID session_uuid
bool(* isDisabled)(const struct Scene *scene, struct ModifierData *md, bool userRenderParams)
Definition: BKE_modifier.h:291
ModifierTypeFlag flags
Definition: BKE_modifier.h:161
void(* deformVertsEM)(struct ModifierData *md, const struct ModifierEvalContext *ctx, struct BMEditMesh *editData, struct Mesh *mesh, float(*vertexCos)[3], int numVerts)
Definition: BKE_modifier.h:202
ModifierTypeType type
Definition: BKE_modifier.h:160
void(* freeData)(struct ModifierData *md)
Definition: BKE_modifier.h:280
struct Mesh *(* modifyMesh)(struct ModifierData *md, const struct ModifierEvalContext *ctx, struct Mesh *mesh)
Definition: BKE_modifier.h:231
void(* blendWrite)(struct BlendWriter *writer, const struct ID *id_owner, const struct ModifierData *md)
Definition: BKE_modifier.h:367
void(* deformVerts)(struct ModifierData *md, const struct ModifierEvalContext *ctx, struct Mesh *mesh, float(*vertexCos)[3], int numVerts)
Definition: BKE_modifier.h:184
void(* foreachTexLink)(struct ModifierData *md, struct Object *ob, TexWalkFunc walk, void *userData)
Definition: BKE_modifier.h:339
void(* blendRead)(struct BlendDataReader *reader, struct ModifierData *md)
Definition: BKE_modifier.h:377
char structName[32]
Definition: BKE_modifier.h:152
void(* requiredDataMask)(struct Object *ob, struct ModifierData *md, struct CustomData_MeshMasks *r_cddata_masks)
Definition: BKE_modifier.h:268
bool(* dependsOnTime)(struct Scene *scene, struct ModifierData *md)
Definition: BKE_modifier.h:306
bool(* dependsOnNormals)(struct ModifierData *md)
Definition: BKE_modifier.h:316
void(* foreachIDLink)(struct ModifierData *md, struct Object *ob, IDWalkFunc walk, void *userData)
Definition: BKE_modifier.h:326
void(* initData)(struct ModifierData *md)
Definition: BKE_modifier.h:252
void(* copyData)(const struct ModifierData *md, struct ModifierData *target, int flag)
Definition: BKE_modifier.h:174
void(* deformMatricesEM)(struct ModifierData *md, const struct ModifierEvalContext *ctx, struct BMEditMesh *editData, struct Mesh *mesh, float(*vertexCos)[3], float(*defMats)[3][3], int numVerts)
Definition: BKE_modifier.h:210
short partype
short base_flag
ListBase modifiers
struct Object * parent
short trackflag
void * data
char shapeflag
ArmatureModifierData amd
Definition: BKE_modifier.h:535
CurveModifierData cmd
Definition: BKE_modifier.h:536
LatticeModifierData lmd
Definition: BKE_modifier.h:537
ShapeKeyModifierData smd
Definition: BKE_modifier.h:538
ccl_device_inline int mod(int x, int m)
Definition: util/math.h:490
#define writestruct(wd, filecode, struct_id, nr, adr)
Definition: writefile.c:756