1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
17 /** \file
18  * \ingroup blenloader
19  */
20 
21 #include "BLI_compiler_attrs.h"
22 #include "BLI_utildefines.h"
23 
24 /* for MinGW32 definition of NULL, could use BLI_blenlib.h instead too */
25 #include <stddef.h>
26 
27 /* allow readfile to use deprecated functionality */
28 #define DNA_DEPRECATED_ALLOW
29 
30 #include "DNA_anim_types.h"
31 #include "DNA_armature_types.h"
32 #include "DNA_brush_types.h"
33 #include "DNA_camera_types.h"
34 #include "DNA_cloth_types.h"
35 #include "DNA_constraint_types.h"
36 #include "DNA_fluid_types.h"
37 #include "DNA_gpencil_types.h"
38 #include "DNA_light_types.h"
39 #include "DNA_linestyle_types.h"
40 #include "DNA_mask_types.h"
41 #include "DNA_mesh_types.h"
42 #include "DNA_modifier_types.h"
43 #include "DNA_object_force_types.h"
44 #include "DNA_object_types.h"
45 #include "DNA_particle_types.h"
46 #include "DNA_pointcache_types.h"
47 #include "DNA_rigidbody_types.h"
48 #include "DNA_screen_types.h"
49 #include "DNA_sdna_types.h"
50 #include "DNA_sequence_types.h"
51 #include "DNA_space_types.h"
52 #include "DNA_view3d_types.h"
53 
54 #include "DNA_genfile.h"
55 
56 #include "BKE_anim_data.h"
57 #include "BKE_animsys.h"
58 #include "BKE_colortools.h"
59 #include "BKE_fcurve_driver.h"
60 #include "BKE_main.h"
61 #include "BKE_mask.h"
62 #include "BKE_modifier.h"
63 #include "BKE_node.h"
64 #include "BKE_scene.h"
65 #include "BKE_screen.h"
66 #include "BKE_sequencer.h"
67 #include "BKE_tracking.h"
68 
69 #include "BLI_listbase.h"
70 #include "BLI_math.h"
71 #include "BLI_string.h"
72 #include "BLI_string_utils.h"
73 
74 #include "BLT_translation.h"
75 
76 #include "BLO_readfile.h"
77 
78 #include "NOD_common.h"
79 #include "NOD_composite.h"
80 #include "NOD_socket.h"
81 
82 #include "readfile.h"
83 
84 #include "MEM_guardedalloc.h"
85 
86 /* Make preferences read-only, use versioning_userdef.c. */
87 #define U (*((const UserDef *)&U))
88 
89 /* ************************************************** */
90 /* GP Palettes API (Deprecated) */
91 
92 /* add a new gp-palette */
BKE_gpencil_palette_addnew(bGPdata * gpd,const char * name)93 static bGPDpalette *BKE_gpencil_palette_addnew(bGPdata *gpd, const char *name)
94 {
95   bGPDpalette *palette;
96 
97   /* check that list is ok */
98   if (gpd == NULL) {
99     return NULL;
100   }
101 
102   /* allocate memory and add to end of list */
103   palette = MEM_callocN(sizeof(bGPDpalette), "bGPDpalette");
104 
105   /* add to datablock */
106   BLI_addtail(&gpd->palettes, palette);
107 
108   /* set basic settings */
109   /* auto-name */
110   BLI_strncpy(palette->info, name, sizeof(palette->info));
111   BLI_uniquename(&gpd->palettes,
112                  palette,
113                  DATA_("GP_Palette"),
114                  '.',
115                  offsetof(bGPDpalette, info),
116                  sizeof(palette->info));
117 
118   /* return palette */
119   return palette;
120 }
121 
122 /* add a new gp-palettecolor */
BKE_gpencil_palettecolor_addnew(bGPDpalette * palette,const char * name)123 static bGPDpalettecolor *BKE_gpencil_palettecolor_addnew(bGPDpalette *palette, const char *name)
124 {
125   bGPDpalettecolor *palcolor;
126 
127   /* check that list is ok */
128   if (palette == NULL) {
129     return NULL;
130   }
131 
132   /* allocate memory and add to end of list */
133   palcolor = MEM_callocN(sizeof(bGPDpalettecolor), "bGPDpalettecolor");
134 
135   /* add to datablock */
136   BLI_addtail(&palette->colors, palcolor);
137 
138   /* set basic settings */
139   copy_v4_v4(palcolor->color, U.gpencil_new_layer_col);
140   ARRAY_SET_ITEMS(palcolor->fill, 1.0f, 1.0f, 1.0f);
141 
142   /* auto-name */
143   BLI_strncpy(palcolor->info, name, sizeof(palcolor->info));
144   BLI_uniquename(&palette->colors,
145                  palcolor,
146                  DATA_("Color"),
147                  '.',
148                  offsetof(bGPDpalettecolor, info),
149                  sizeof(palcolor->info));
150 
151   /* return palette color */
152   return palcolor;
153 }
154 
155 /**
156  * Setup rotation stabilization from ancient single track spec.
157  * Former Version of 2D stabilization used a single tracking marker to determine the rotation
158  * to be compensated. Now several tracks can contribute to rotation detection and this feature
159  * is enabled by the MovieTrackingTrack#flag on a per track base.
160  */
migrate_single_rot_stabilization_track_settings(MovieTrackingStabilization * stab)161 static void migrate_single_rot_stabilization_track_settings(MovieTrackingStabilization *stab)
162 {
163   if (stab->rot_track) {
164     if (!(stab->rot_track->flag & TRACK_USE_2D_STAB_ROT)) {
165       stab->tot_rot_track++;
166       stab->rot_track->flag |= TRACK_USE_2D_STAB_ROT;
167     }
168   }
169   stab->rot_track = NULL; /* this field is now ignored */
170 }
171 
do_version_constraints_radians_degrees_270_1(ListBase * lb)172 static void do_version_constraints_radians_degrees_270_1(ListBase *lb)
173 {
174   bConstraint *con;
175 
176   for (con = lb->first; con; con = con->next) {
177     if (con->type == CONSTRAINT_TYPE_TRANSFORM) {
178       bTransformConstraint *data = (bTransformConstraint *)con->data;
179       const float deg_to_rad_f = DEG2RADF(1.0f);
180 
181       if (data->from == TRANS_ROTATION) {
182         mul_v3_fl(data->from_min, deg_to_rad_f);
183         mul_v3_fl(data->from_max, deg_to_rad_f);
184       }
185 
186       if (data->to == TRANS_ROTATION) {
187         mul_v3_fl(data->to_min, deg_to_rad_f);
188         mul_v3_fl(data->to_max, deg_to_rad_f);
189       }
190     }
191   }
192 }
193 
do_version_constraints_radians_degrees_270_5(ListBase * lb)194 static void do_version_constraints_radians_degrees_270_5(ListBase *lb)
195 {
196   bConstraint *con;
197 
198   for (con = lb->first; con; con = con->next) {
199     if (con->type == CONSTRAINT_TYPE_TRANSFORM) {
200       bTransformConstraint *data = (bTransformConstraint *)con->data;
201 
202       if (data->from == TRANS_ROTATION) {
203         copy_v3_v3(data->from_min_rot, data->from_min);
204         copy_v3_v3(data->from_max_rot, data->from_max);
205       }
206       else if (data->from == TRANS_SCALE) {
207         copy_v3_v3(data->from_min_scale, data->from_min);
208         copy_v3_v3(data->from_max_scale, data->from_max);
209       }
210 
211       if (data->to == TRANS_ROTATION) {
212         copy_v3_v3(data->to_min_rot, data->to_min);
213         copy_v3_v3(data->to_max_rot, data->to_max);
214       }
215       else if (data->to == TRANS_SCALE) {
216         copy_v3_v3(data->to_min_scale, data->to_min);
217         copy_v3_v3(data->to_max_scale, data->to_max);
218       }
219     }
220   }
221 }
222 
do_version_constraints_stretch_to_limits(ListBase * lb)223 static void do_version_constraints_stretch_to_limits(ListBase *lb)
224 {
225   bConstraint *con;
226 
227   for (con = lb->first; con; con = con->next) {
228     if (con->type == CONSTRAINT_TYPE_STRETCHTO) {
229       bStretchToConstraint *data = (bStretchToConstraint *)con->data;
230       data->bulge_min = 1.0f;
231       data->bulge_max = 1.0f;
232     }
233   }
234 }
235 
do_version_action_editor_properties_region(ListBase * regionbase)236 static void do_version_action_editor_properties_region(ListBase *regionbase)
237 {
238   ARegion *region;
239 
240   for (region = regionbase->first; region; region = region->next) {
241     if (region->regiontype == RGN_TYPE_UI) {
242       /* already exists */
243       return;
244     }
245     if (region->regiontype == RGN_TYPE_WINDOW) {
246       /* add new region here */
247       ARegion *arnew = MEM_callocN(sizeof(ARegion), "buttons for action");
248 
249       BLI_insertlinkbefore(regionbase, region, arnew);
250 
251       arnew->regiontype = RGN_TYPE_UI;
252       arnew->alignment = RGN_ALIGN_RIGHT;
253       arnew->flag = RGN_FLAG_HIDDEN;
254 
255       return;
256     }
257   }
258 }
259 
do_version_bones_super_bbone(ListBase * lb)260 static void do_version_bones_super_bbone(ListBase *lb)
261 {
262   LISTBASE_FOREACH (Bone *, bone, lb) {
263     bone->scale_in_x = bone->scale_in_y = 1.0f;
264     bone->scale_out_x = bone->scale_out_y = 1.0f;
265 
266     do_version_bones_super_bbone(&bone->childbase);
267   }
268 }
269 
270 /* TODO(sergey): Consider making it somewhat more generic function in BLI_anim.h. */
anim_change_prop_name(FCurve * fcu,const char * prefix,const char * old_prop_name,const char * new_prop_name)271 static void anim_change_prop_name(FCurve *fcu,
272                                   const char *prefix,
273                                   const char *old_prop_name,
274                                   const char *new_prop_name)
275 {
276   const char *old_path = BLI_sprintfN("%s.%s", prefix, old_prop_name);
277   if (STREQ(fcu->rna_path, old_path)) {
278     MEM_freeN(fcu->rna_path);
279     fcu->rna_path = BLI_sprintfN("%s.%s", prefix, new_prop_name);
280   }
281   MEM_freeN((char *)old_path);
282 }
283 
do_version_hue_sat_node(bNodeTree * ntree,bNode * node)284 static void do_version_hue_sat_node(bNodeTree *ntree, bNode *node)
285 {
286   if (node->storage == NULL) {
287     return;
288   }
289 
290   /* Make sure new sockets are properly created. */
291   node_verify_socket_templates(ntree, node);
292   /* Convert value from old storage to new sockets. */
293   NodeHueSat *nhs = node->storage;
294   bNodeSocket *hue = nodeFindSocket(node, SOCK_IN, "Hue"),
295               *saturation = nodeFindSocket(node, SOCK_IN, "Saturation"),
296               *value = nodeFindSocket(node, SOCK_IN, "Value");
297   ((bNodeSocketValueFloat *)hue->default_value)->value = nhs->hue;
298   ((bNodeSocketValueFloat *)saturation->default_value)->value = nhs->sat;
299   ((bNodeSocketValueFloat *)value->default_value)->value = nhs->val;
300   /* Take care of possible animation. */
301   AnimData *adt = BKE_animdata_from_id(&ntree->id);
302   if (adt != NULL && adt->action != NULL) {
303     const char *prefix = BLI_sprintfN("nodes[\"%s\"]", node->name);
304     for (FCurve *fcu = adt->action->curves.first; fcu != NULL; fcu = fcu->next) {
305       if (STRPREFIX(fcu->rna_path, prefix)) {
306         anim_change_prop_name(fcu, prefix, "color_hue", "inputs[1].default_value");
307         anim_change_prop_name(fcu, prefix, "color_saturation", "inputs[2].default_value");
308         anim_change_prop_name(fcu, prefix, "color_value", "inputs[3].default_value");
309       }
310     }
311     MEM_freeN((char *)prefix);
312   }
313   /* Free storage, it is no longer used. */
314   MEM_freeN(node->storage);
315   node->storage = NULL;
316 }
317 
do_versions_compositor_render_passes_storage(bNode * node)318 static void do_versions_compositor_render_passes_storage(bNode *node)
319 {
320   int pass_index = 0;
321   const char *sockname;
322   for (bNodeSocket *sock = node->outputs.first; sock && pass_index < 31;
323        sock = sock->next, pass_index++) {
324     if (sock->storage == NULL) {
325       NodeImageLayer *sockdata = MEM_callocN(sizeof(NodeImageLayer), "node image layer");
326       sock->storage = sockdata;
327       BLI_strncpy(sockdata->pass_name,
328                   node_cmp_rlayers_sock_to_pass(pass_index),
329                   sizeof(sockdata->pass_name));
330 
331       if (pass_index == 0) {
332         sockname = "Image";
333       }
334       else if (pass_index == 1) {
335         sockname = "Alpha";
336       }
337       else {
338         sockname = node_cmp_rlayers_sock_to_pass(pass_index);
339       }
340       BLI_strncpy(sock->name, sockname, sizeof(sock->name));
341     }
342   }
343 }
344 
do_versions_compositor_render_passes(bNodeTree * ntree)345 static void do_versions_compositor_render_passes(bNodeTree *ntree)
346 {
347   LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
348     if (node->type == CMP_NODE_R_LAYERS) {
349       /* First we make sure existing sockets have proper names.
350        * This is important because otherwise verification will
351        * drop links from sockets which were renamed.
352        */
353       do_versions_compositor_render_passes_storage(node);
354       /* Make sure new sockets are properly created. */
355       node_verify_socket_templates(ntree, node);
356       /* Make sure all possibly created sockets have proper storage. */
357       do_versions_compositor_render_passes_storage(node);
358     }
359   }
360 }
361 
replace_bbone_easing_rnapath(char * old_path)362 static char *replace_bbone_easing_rnapath(char *old_path)
363 {
364   char *new_path = NULL;
365 
366   /* NOTE: This will break paths for any bones/custom-properties
367    * which happen be named after the bbone property id's
368    */
369   if (strstr(old_path, "bbone_in")) {
370     new_path = BLI_str_replaceN(old_path, "bbone_in", "bbone_easein");
371   }
372   else if (strstr(old_path, "bbone_out")) {
373     new_path = BLI_str_replaceN(old_path, "bbone_out", "bbone_easeout");
374   }
375 
376   if (new_path) {
377     MEM_freeN(old_path);
378     return new_path;
379   }
380 
381   return old_path;
382 }
383 
do_version_bbone_easing_fcurve_fix(ID * UNUSED (id),FCurve * fcu,void * UNUSED (user_data))384 static void do_version_bbone_easing_fcurve_fix(ID *UNUSED(id),
385                                                FCurve *fcu,
386                                                void *UNUSED(user_data))
387 {
388   /* F-Curve's path (for bbone_in/out) */
389   if (fcu->rna_path) {
390     fcu->rna_path = replace_bbone_easing_rnapath(fcu->rna_path);
391   }
392 
393   /* Driver -> Driver Vars (for bbone_in/out) */
394   if (fcu->driver) {
395     LISTBASE_FOREACH (DriverVar *, dvar, &fcu->driver->variables) {
396       DRIVER_TARGETS_LOOPER_BEGIN (dvar) {
397         if (dtar->rna_path) {
398           dtar->rna_path = replace_bbone_easing_rnapath(dtar->rna_path);
399         }
400       }
401       DRIVER_TARGETS_LOOPER_END;
402     }
403   }
404 
405   /* FModifiers -> Stepped (for frame_start/end) */
406   if (fcu->modifiers.first) {
407     LISTBASE_FOREACH (FModifier *, fcm, &fcu->modifiers) {
408       if (fcm->type == FMODIFIER_TYPE_STEPPED) {
409         FMod_Stepped *data = fcm->data;
410 
411         /* Modifier doesn't work if the modifier's copy of start/end frame are both 0
412          * as those were only getting written to the fcm->data copy (T52009)
413          */
414         if ((fcm->sfra == fcm->efra) && (fcm->sfra == 0)) {
415           fcm->sfra = data->start_frame;
416           fcm->efra = data->end_frame;
417         }
418       }
419     }
420   }
421 }
422 
423 /* NOLINTNEXTLINE: readability-function-size */
blo_do_versions_270(FileData * fd,Library * UNUSED (lib),Main * bmain)424 void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain)
425 {
426   if (!MAIN_VERSION_ATLEAST(bmain, 270, 0)) {
427 
428     if (!DNA_struct_elem_find(fd->filesdna, "BevelModifierData", "float", "profile")) {
429       Object *ob;
430 
431       for (ob = bmain->objects.first; ob; ob = ob->id.next) {
432         ModifierData *md;
433         for (md = ob->modifiers.first; md; md = md->next) {
434           if (md->type == eModifierType_Bevel) {
435             BevelModifierData *bmd = (BevelModifierData *)md;
436             bmd->profile = 0.5f;
437             bmd->val_flags = MOD_BEVEL_AMT_OFFSET;
438           }
439         }
440       }
441     }
442 
443     /* nodes don't use fixed node->id any more, clean up */
444     FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
445       if (ntree->type == NTREE_COMPOSIT) {
446         bNode *node;
447         for (node = ntree->nodes.first; node; node = node->next) {
448           if (ELEM(node->type, CMP_NODE_COMPOSITE, CMP_NODE_OUTPUT_FILE)) {
449             node->id = NULL;
450           }
451         }
452       }
453     }
454     FOREACH_NODETREE_END;
455 
456     {
457       bScreen *screen;
458 
459       for (screen = bmain->screens.first; screen; screen = screen->id.next) {
460         ScrArea *area;
461         for (area = screen->areabase.first; area; area = area->next) {
462           SpaceLink *space_link;
463           for (space_link = area->spacedata.first; space_link; space_link = space_link->next) {
464             if (space_link->spacetype == SPACE_CLIP) {
465               SpaceClip *space_clip = (SpaceClip *)space_link;
466               if (space_clip->mode != SC_MODE_MASKEDIT) {
467                 space_clip->mode = SC_MODE_TRACKING;
468               }
469             }
470           }
471         }
472       }
473     }
474 
475     if (!DNA_struct_elem_find(fd->filesdna, "MovieTrackingSettings", "float", "default_weight")) {
476       MovieClip *clip;
477       for (clip = bmain->movieclips.first; clip; clip = clip->id.next) {
478         clip->tracking.settings.default_weight = 1.0f;
479       }
480     }
481   }
482 
483   if (!MAIN_VERSION_ATLEAST(bmain, 270, 1)) {
484     Object *ob;
485 
486     /* Update Transform constraint (another deg -> rad stuff). */
487     for (ob = bmain->objects.first; ob; ob = ob->id.next) {
488       do_version_constraints_radians_degrees_270_1(&ob->constraints);
489 
490       if (ob->pose) {
491         /* Bones constraints! */
492         bPoseChannel *pchan;
493         for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
494           do_version_constraints_radians_degrees_270_1(&pchan->constraints);
495         }
496       }
497     }
498   }
499 
500   if (!MAIN_VERSION_ATLEAST(bmain, 270, 2)) {
501     Mesh *me;
502 
503     /* Mesh smoothresh deg->rad. */
504     for (me = bmain->meshes.first; me; me = me->id.next) {
505       me->smoothresh = DEG2RADF(me->smoothresh);
506     }
507   }
508 
509   if (!MAIN_VERSION_ATLEAST(bmain, 270, 3)) {
510     FreestyleLineStyle *linestyle;
511 
512     for (linestyle = bmain->linestyles.first; linestyle; linestyle = linestyle->id.next) {
513       linestyle->flag |= LS_NO_SORTING;
514       linestyle->sort_key = LS_SORT_KEY_DISTANCE_FROM_CAMERA;
515       linestyle->integration_type = LS_INTEGRATION_MEAN;
516     }
517   }
518 
519   if (!MAIN_VERSION_ATLEAST(bmain, 270, 4)) {
520     /* ui_previews were not handled correctly when copying areas,
521      * leading to corrupted files (see T39847).
522      * This will always reset situation to a valid state.
523      */
524     bScreen *screen;
525 
526     for (screen = bmain->screens.first; screen; screen = screen->id.next) {
527       ScrArea *area;
528       for (area = screen->areabase.first; area; area = area->next) {
529         SpaceLink *sl;
530 
531         for (sl = area->spacedata.first; sl; sl = sl->next) {
532           ARegion *region;
533           ListBase *lb = (sl == area->spacedata.first) ? &area->regionbase : &sl->regionbase;
534 
535           for (region = lb->first; region; region = region->next) {
536             BLI_listbase_clear(&region->ui_previews);
537           }
538         }
539       }
540     }
541   }
542 
543   if (!MAIN_VERSION_ATLEAST(bmain, 270, 5)) {
544     Object *ob;
545 
546     /* Update Transform constraint (again :|). */
547     for (ob = bmain->objects.first; ob; ob = ob->id.next) {
548       do_version_constraints_radians_degrees_270_5(&ob->constraints);
549 
550       if (ob->pose) {
551         /* Bones constraints! */
552         bPoseChannel *pchan;
553         for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
554           do_version_constraints_radians_degrees_270_5(&pchan->constraints);
555         }
556       }
557     }
558   }
559 
560   if (!MAIN_VERSION_ATLEAST(bmain, 271, 0)) {
561     if (!DNA_struct_elem_find(fd->filesdna, "RenderData", "BakeData", "bake")) {
562       Scene *sce;
563 
564       for (sce = bmain->scenes.first; sce; sce = sce->id.next) {
565         sce->r.bake.flag = R_BAKE_CLEAR;
566         sce->r.bake.width = 512;
567         sce->r.bake.height = 512;
568         sce->r.bake.margin = 16;
569         sce->r.bake.normal_space = R_BAKE_SPACE_TANGENT;
570         sce->r.bake.normal_swizzle[0] = R_BAKE_POSX;
571         sce->r.bake.normal_swizzle[1] = R_BAKE_POSY;
572         sce->r.bake.normal_swizzle[2] = R_BAKE_POSZ;
573         BLI_strncpy(sce->r.bake.filepath, U.renderdir, sizeof(sce->r.bake.filepath));
574 
575         sce->r.bake.im_format.planes = R_IMF_PLANES_RGBA;
576         sce->r.bake.im_format.imtype = R_IMF_IMTYPE_PNG;
577         sce->r.bake.im_format.depth = R_IMF_CHAN_DEPTH_8;
578         sce->r.bake.im_format.quality = 90;
579         sce->r.bake.im_format.compress = 15;
580       }
581     }
582 
583     if (!DNA_struct_elem_find(fd->filesdna, "FreestyleLineStyle", "float", "texstep")) {
584       FreestyleLineStyle *linestyle;
585 
586       for (linestyle = bmain->linestyles.first; linestyle; linestyle = linestyle->id.next) {
587         linestyle->flag |= LS_TEXTURE;
588         linestyle->texstep = 1.0;
589       }
590     }
591 
592     {
593       Scene *scene;
594       for (scene = bmain->scenes.first; scene; scene = scene->id.next) {
595         int num_layers = BLI_listbase_count(&scene->r.layers);
596         scene->r.actlay = min_ff(scene->r.actlay, num_layers - 1);
597       }
598     }
599   }
600 
601   if (!MAIN_VERSION_ATLEAST(bmain, 271, 1)) {
602     if (!DNA_struct_elem_find(fd->filesdna, "Material", "float", "line_col[4]")) {
603       Material *mat;
604 
605       for (mat = bmain->materials.first; mat; mat = mat->id.next) {
606         mat->line_col[0] = mat->line_col[1] = mat->line_col[2] = 0.0f;
607         mat->line_col[3] = mat->alpha;
608       }
609     }
610 
611     if (!DNA_struct_elem_find(fd->filesdna, "RenderData", "int", "preview_start_resolution")) {
612       Scene *scene;
613       for (scene = bmain->scenes.first; scene; scene = scene->id.next) {
614         scene->r.preview_start_resolution = 64;
615       }
616     }
617   }
618 
619   if (!MAIN_VERSION_ATLEAST(bmain, 271, 3)) {
620     Brush *br;
621 
622     for (br = bmain->brushes.first; br; br = br->id.next) {
623       br->fill_threshold = 0.2f;
624     }
625 
626     if (!DNA_struct_elem_find(fd->filesdna, "BevelModifierData", "int", "mat")) {
627       Object *ob;
628       for (ob = bmain->objects.first; ob; ob = ob->id.next) {
629         ModifierData *md;
630 
631         for (md = ob->modifiers.first; md; md = md->next) {
632           if (md->type == eModifierType_Bevel) {
633             BevelModifierData *bmd = (BevelModifierData *)md;
634             bmd->mat = -1;
635           }
636         }
637       }
638     }
639   }
640 
641   if (!MAIN_VERSION_ATLEAST(bmain, 271, 6)) {
642     Object *ob;
643     for (ob = bmain->objects.first; ob; ob = ob->id.next) {
644       ModifierData *md;
645 
646       for (md = ob->modifiers.first; md; md = md->next) {
647         if (md->type == eModifierType_ParticleSystem) {
648           ParticleSystemModifierData *pmd = (ParticleSystemModifierData *)md;
649           if (pmd->psys && pmd->psys->clmd) {
650             pmd->psys->clmd->sim_parms->vel_damping = 1.0f;
651           }
652         }
653       }
654     }
655   }
656 
657   if (!MAIN_VERSION_ATLEAST(bmain, 272, 0)) {
658     if (!DNA_struct_elem_find(fd->filesdna, "RenderData", "int", "preview_start_resolution")) {
659       Scene *scene;
660       for (scene = bmain->scenes.first; scene; scene = scene->id.next) {
661         scene->r.preview_start_resolution = 64;
662       }
663     }
664   }
665 
666   if (!MAIN_VERSION_ATLEAST(bmain, 272, 1)) {
667     Brush *br;
668     for (br = bmain->brushes.first; br; br = br->id.next) {
669       if ((br->ob_mode & OB_MODE_SCULPT) &&
670           ELEM(br->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_SNAKE_HOOK)) {
671         br->alpha = 1.0f;
672       }
673     }
674   }
675 
676   if (!MAIN_VERSION_ATLEAST(bmain, 272, 2)) {
677     if (!DNA_struct_elem_find(fd->filesdna, "Image", "float", "gen_color")) {
678       Image *image;
679       for (image = bmain->images.first; image != NULL; image = image->id.next) {
680         image->gen_color[3] = 1.0f;
681       }
682     }
683 
684     if (!DNA_struct_elem_find(fd->filesdna, "bStretchToConstraint", "float", "bulge_min")) {
685       Object *ob;
686 
687       /* Update Transform constraint (again :|). */
688       for (ob = bmain->objects.first; ob; ob = ob->id.next) {
689         do_version_constraints_stretch_to_limits(&ob->constraints);
690 
691         if (ob->pose) {
692           /* Bones constraints! */
693           bPoseChannel *pchan;
694           for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
695             do_version_constraints_stretch_to_limits(&pchan->constraints);
696           }
697         }
698       }
699     }
700   }
701 
702   if (!MAIN_VERSION_ATLEAST(bmain, 273, 1)) {
703 #define BRUSH_RAKE (1 << 7)
704 #define BRUSH_RANDOM_ROTATION (1 << 25)
705 
706     Brush *br;
707 
708     for (br = bmain->brushes.first; br; br = br->id.next) {
709       if (br->flag & BRUSH_RAKE) {
710         br->mtex.brush_angle_mode |= MTEX_ANGLE_RAKE;
711         br->mask_mtex.brush_angle_mode |= MTEX_ANGLE_RAKE;
712       }
713       else if (br->flag & BRUSH_RANDOM_ROTATION) {
714         br->mtex.brush_angle_mode |= MTEX_ANGLE_RANDOM;
715         br->mask_mtex.brush_angle_mode |= MTEX_ANGLE_RANDOM;
716       }
717       br->mtex.random_angle = 2.0 * M_PI;
718       br->mask_mtex.random_angle = 2.0 * M_PI;
719     }
720   }
721 
722 #undef BRUSH_RAKE
723 #undef BRUSH_RANDOM_ROTATION
724 
725   /* Customizable Safe Areas */
726   if (!MAIN_VERSION_ATLEAST(bmain, 273, 2)) {
727     if (!DNA_struct_elem_find(fd->filesdna, "Scene", "DisplaySafeAreas", "safe_areas")) {
728       Scene *scene;
729 
730       for (scene = bmain->scenes.first; scene; scene = scene->id.next) {
731         copy_v2_fl2(scene->safe_areas.title, 3.5f / 100.0f, 3.5f / 100.0f);
732         copy_v2_fl2(scene->safe_areas.action, 10.0f / 100.0f, 5.0f / 100.0f);
733         copy_v2_fl2(scene->safe_areas.title_center, 17.5f / 100.0f, 5.0f / 100.0f);
734         copy_v2_fl2(scene->safe_areas.action_center, 15.0f / 100.0f, 5.0f / 100.0f);
735       }
736     }
737   }
738 
739   if (!MAIN_VERSION_ATLEAST(bmain, 273, 3)) {
740     ParticleSettings *part;
741     for (part = bmain->particles.first; part; part = part->id.next) {
742       if (part->clumpcurve) {
743         part->child_flag |= PART_CHILD_USE_CLUMP_CURVE;
744       }
745       if (part->roughcurve) {
746         part->child_flag |= PART_CHILD_USE_ROUGH_CURVE;
747       }
748     }
749   }
750 
751   if (!MAIN_VERSION_ATLEAST(bmain, 273, 6)) {
752     if (!DNA_struct_elem_find(fd->filesdna, "ClothSimSettings", "float", "bending_damping")) {
753       Object *ob;
754       ModifierData *md;
755       for (ob = bmain->objects.first; ob; ob = ob->id.next) {
756         for (md = ob->modifiers.first; md; md = md->next) {
757           if (md->type == eModifierType_Cloth) {
758             ClothModifierData *clmd = (ClothModifierData *)md;
759             clmd->sim_parms->bending_damping = 0.5f;
760           }
761           else if (md->type == eModifierType_ParticleSystem) {
762             ParticleSystemModifierData *pmd = (ParticleSystemModifierData *)md;
763             if (pmd->psys->clmd) {
764               pmd->psys->clmd->sim_parms->bending_damping = 0.5f;
765             }
766           }
767         }
768       }
769     }
770 
771     if (!DNA_struct_elem_find(fd->filesdna, "ParticleSettings", "float", "clump_noise_size")) {
772       ParticleSettings *part;
773       for (part = bmain->particles.first; part; part = part->id.next) {
774         part->clump_noise_size = 1.0f;
775       }
776     }
777 
778     if (!DNA_struct_elem_find(fd->filesdna, "ParticleSettings", "int", "kink_extra_steps")) {
779       ParticleSettings *part;
780       for (part = bmain->particles.first; part; part = part->id.next) {
781         part->kink_extra_steps = 4;
782       }
783     }
784 
785     if (!DNA_struct_elem_find(fd->filesdna, "MTex", "float", "kinkampfac")) {
786       ParticleSettings *part;
787       for (part = bmain->particles.first; part; part = part->id.next) {
788         int a;
789         for (a = 0; a < MAX_MTEX; a++) {
790           MTex *mtex = part->mtex[a];
791           if (mtex) {
792             mtex->kinkampfac = 1.0f;
793           }
794         }
795       }
796     }
797 
798     if (!DNA_struct_elem_find(fd->filesdna, "HookModifierData", "char", "flag")) {
799       Object *ob;
800 
801       for (ob = bmain->objects.first; ob; ob = ob->id.next) {
802         ModifierData *md;
803         for (md = ob->modifiers.first; md; md = md->next) {
804           if (md->type == eModifierType_Hook) {
805             HookModifierData *hmd = (HookModifierData *)md;
806             hmd->falloff_type = eHook_Falloff_InvSquare;
807           }
808         }
809       }
810     }
811 
812     if (!DNA_struct_elem_find(fd->filesdna, "NodePlaneTrackDeformData", "char", "flag")) {
813       FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
814         if (ntree->type == NTREE_COMPOSIT) {
815           bNode *node;
816           for (node = ntree->nodes.first; node; node = node->next) {
817             if (ELEM(node->type, CMP_NODE_PLANETRACKDEFORM)) {
818               NodePlaneTrackDeformData *data = node->storage;
819               data->flag = 0;
820               data->motion_blur_samples = 16;
821               data->motion_blur_shutter = 0.5f;
822             }
823           }
824         }
825       }
826       FOREACH_NODETREE_END;
827     }
828 
829     if (!DNA_struct_elem_find(fd->filesdna, "Camera", "GPUDOFSettings", "gpu_dof")) {
830       Camera *ca;
831       for (ca = bmain->cameras.first; ca; ca = ca->id.next) {
832         ca->gpu_dof.fstop = 128.0f;
833         ca->gpu_dof.focal_length = 1.0f;
834         ca->gpu_dof.focus_distance = 1.0f;
835         ca->gpu_dof.sensor = 1.0f;
836       }
837     }
838   }
839 
840   if (!MAIN_VERSION_ATLEAST(bmain, 273, 8)) {
841     Object *ob;
842     for (ob = bmain->objects.first; ob != NULL; ob = ob->id.next) {
843       ModifierData *md;
844       for (md = ob->modifiers.last; md != NULL; md = md->prev) {
845         if (BKE_modifier_unique_name(&ob->modifiers, md)) {
846           printf(
847               "Warning: Object '%s' had several modifiers with the "
848               "same name, renamed one of them to '%s'.\n",
849               ob->id.name + 2,
850               md->name);
851         }
852       }
853     }
854   }
855 
856   if (!MAIN_VERSION_ATLEAST(bmain, 273, 9)) {
857     bScreen *screen;
858     ScrArea *area;
859     SpaceLink *sl;
860     ARegion *region;
861 
862     /* Make sure sequencer preview area limits zoom */
863     for (screen = bmain->screens.first; screen; screen = screen->id.next) {
864       for (area = screen->areabase.first; area; area = area->next) {
865         for (sl = area->spacedata.first; sl; sl = sl->next) {
866           if (sl->spacetype == SPACE_SEQ) {
867             for (region = sl->regionbase.first; region; region = region->next) {
868               if (region->regiontype == RGN_TYPE_PREVIEW) {
869                 region->v2d.keepzoom |= V2D_LIMITZOOM;
870                 region->v2d.minzoom = 0.001f;
871                 region->v2d.maxzoom = 1000.0f;
872                 break;
873               }
874             }
875           }
876         }
877       }
878     }
879   }
880 
881   if (!MAIN_VERSION_ATLEAST(bmain, 274, 1)) {
882     /* particle systems need to be forced to redistribute for jitter mode fix */
883     {
884       Object *ob;
885       ParticleSystem *psys;
886       for (ob = bmain->objects.first; ob; ob = ob->id.next) {
887         for (psys = ob->particlesystem.first; psys; psys = psys->next) {
888           if ((psys->pointcache->flag & PTCACHE_BAKED) == 0) {
889             psys->recalc |= ID_RECALC_PSYS_RESET;
890           }
891         }
892       }
893     }
894   }
895 
896   if (!MAIN_VERSION_ATLEAST(bmain, 274, 4)) {
897     SceneRenderView *srv;
898     wmWindowManager *wm;
899     bScreen *screen;
900     wmWindow *win;
901     Scene *scene;
902     Camera *cam;
903     Image *ima;
904 
905     for (scene = bmain->scenes.first; scene; scene = scene->id.next) {
906       Sequence *seq;
907 
908       BKE_scene_add_render_view(scene, STEREO_LEFT_NAME);
909       srv = scene->r.views.first;
910       BLI_strncpy(srv->suffix, STEREO_LEFT_SUFFIX, sizeof(srv->suffix));
911 
912       BKE_scene_add_render_view(scene, STEREO_RIGHT_NAME);
913       srv = scene->r.views.last;
914       BLI_strncpy(srv->suffix, STEREO_RIGHT_SUFFIX, sizeof(srv->suffix));
915 
916       SEQ_ALL_BEGIN (scene->ed, seq) {
917         seq->stereo3d_format = MEM_callocN(sizeof(Stereo3dFormat), "Stereo Display 3d Format");
918 
919 #define SEQ_USE_PROXY_CUSTOM_DIR (1 << 19)
920 #define SEQ_USE_PROXY_CUSTOM_FILE (1 << 21)
921         if (seq->strip && seq->strip->proxy && !seq->strip->proxy->storage) {
922           if (seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) {
923             seq->strip->proxy->storage = SEQ_STORAGE_PROXY_CUSTOM_DIR;
924           }
925           if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
926             seq->strip->proxy->storage = SEQ_STORAGE_PROXY_CUSTOM_FILE;
927           }
928         }
929 #undef SEQ_USE_PROXY_CUSTOM_DIR
930 #undef SEQ_USE_PROXY_CUSTOM_FILE
931       }
932       SEQ_ALL_END;
933     }
934 
935     for (screen = bmain->screens.first; screen; screen = screen->id.next) {
936       ScrArea *area;
937       for (area = screen->areabase.first; area; area = area->next) {
938         SpaceLink *sl;
939 
940         for (sl = area->spacedata.first; sl; sl = sl->next) {
941           switch (sl->spacetype) {
942             case SPACE_VIEW3D: {
943               View3D *v3d = (View3D *)sl;
944               v3d->stereo3d_camera = STEREO_3D_ID;
945               v3d->stereo3d_flag |= V3D_S3D_DISPPLANE;
946               v3d->stereo3d_convergence_alpha = 0.15f;
947               v3d->stereo3d_volume_alpha = 0.05f;
948               break;
949             }
950             case SPACE_IMAGE: {
951               SpaceImage *sima = (SpaceImage *)sl;
952               sima->iuser.flag |= IMA_SHOW_STEREO;
953               break;
954             }
955           }
956         }
957       }
958     }
959 
960     for (cam = bmain->cameras.first; cam; cam = cam->id.next) {
961       cam->stereo.interocular_distance = 0.065f;
962       cam->stereo.convergence_distance = 30.0f * 0.065f;
963     }
964 
965     for (ima = bmain->images.first; ima; ima = ima->id.next) {
966       ima->stereo3d_format = MEM_callocN(sizeof(Stereo3dFormat), "Image Stereo 3d Format");
967 
968       if (ima->packedfile) {
969         ImagePackedFile *imapf = MEM_mallocN(sizeof(ImagePackedFile), "Image Packed File");
970         BLI_addtail(&ima->packedfiles, imapf);
971 
972         imapf->packedfile = ima->packedfile;
973         BLI_strncpy(imapf->filepath, ima->filepath, FILE_MAX);
974         ima->packedfile = NULL;
975       }
976     }
977 
978     for (wm = bmain->wm.first; wm; wm = wm->id.next) {
979       for (win = wm->windows.first; win; win = win->next) {
980         win->stereo3d_format = MEM_callocN(sizeof(Stereo3dFormat), "Stereo Display 3d Format");
981       }
982     }
983   }
984 
985   if (!MAIN_VERSION_ATLEAST(bmain, 274, 6)) {
986     bScreen *screen;
987 
988     if (!DNA_struct_elem_find(fd->filesdna, "FileSelectParams", "int", "thumbnail_size")) {
989       for (screen = bmain->screens.first; screen; screen = screen->id.next) {
990         ScrArea *area;
991 
992         for (area = screen->areabase.first; area; area = area->next) {
993           SpaceLink *sl;
994 
995           for (sl = area->spacedata.first; sl; sl = sl->next) {
996             if (sl->spacetype == SPACE_FILE) {
997               SpaceFile *sfile = (SpaceFile *)sl;
998 
999               if (sfile->params) {
1000                 sfile->params->thumbnail_size = 128;
1001               }
1002             }
1003           }
1004         }
1005       }
1006     }
1007 
1008     if (!DNA_struct_elem_find(fd->filesdna, "RenderData", "short", "simplify_subsurf_render")) {
1009       Scene *scene;
1010       for (scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
1011         scene->r.simplify_subsurf_render = scene->r.simplify_subsurf;
1012         scene->r.simplify_particles_render = scene->r.simplify_particles;
1013       }
1014     }
1015 
1016     if (!DNA_struct_elem_find(fd->filesdna, "DecimateModifierData", "float", "defgrp_factor")) {
1017       Object *ob;
1018 
1019       for (ob = bmain->objects.first; ob; ob = ob->id.next) {
1020         ModifierData *md;
1021         for (md = ob->modifiers.first; md; md = md->next) {
1022           if (md->type == eModifierType_Decimate) {
1023             DecimateModifierData *dmd = (DecimateModifierData *)md;
1024             dmd->defgrp_factor = 1.0f;
1025           }
1026         }
1027       }
1028     }
1029   }
1030 
1031   if (!MAIN_VERSION_ATLEAST(bmain, 275, 3)) {
1032     Brush *br;
1033 #define BRUSH_TORUS (1 << 1)
1034     for (br = bmain->brushes.first; br; br = br->id.next) {
1035       br->flag &= ~BRUSH_TORUS;
1036     }
1037 #undef BRUSH_TORUS
1038   }
1039 
1040   if (!MAIN_VERSION_ATLEAST(bmain, 276, 2)) {
1041     if (!DNA_struct_elem_find(fd->filesdna, "bPoseChannel", "float", "custom_scale")) {
1042       Object *ob;
1043 
1044       for (ob = bmain->objects.first; ob; ob = ob->id.next) {
1045         if (ob->pose) {
1046           bPoseChannel *pchan;
1047           for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
1048             pchan->custom_scale = 1.0f;
1049           }
1050         }
1051       }
1052     }
1053 
1054     {
1055       bScreen *screen;
1056 #define RV3D_VIEW_PERSPORTHO 7
1057       for (screen = bmain->screens.first; screen; screen = screen->id.next) {
1058         ScrArea *area;
1059         for (area = screen->areabase.first; area; area = area->next) {
1060           SpaceLink *sl;
1061           for (sl = area->spacedata.first; sl; sl = sl->next) {
1062             if (sl->spacetype == SPACE_VIEW3D) {
1063               ARegion *region;
1064               ListBase *lb = (sl == area->spacedata.first) ? &area->regionbase : &sl->regionbase;
1065               for (region = lb->first; region; region = region->next) {
1066                 if (region->regiontype == RGN_TYPE_WINDOW) {
1067                   if (region->regiondata) {
1068                     RegionView3D *rv3d = region->regiondata;
1069                     if (rv3d->view == RV3D_VIEW_PERSPORTHO) {
1070                       rv3d->view = RV3D_VIEW_USER;
1071                     }
1072                   }
1073                 }
1074               }
1075               break;
1076             }
1077           }
1078         }
1079       }
1080 #undef RV3D_VIEW_PERSPORTHO
1081     }
1082 
1083     {
1084 #define LA_YF_PHOTON 5
1085       for (Light *la = bmain->lights.first; la; la = la->id.next) {
1086         if (la->type == LA_YF_PHOTON) {
1087           la->type = LA_LOCAL;
1088         }
1089       }
1090 #undef LA_YF_PHOTON
1091     }
1092   }
1093 
1094   if (!MAIN_VERSION_ATLEAST(bmain, 276, 3)) {
1095     if (!DNA_struct_elem_find(fd->filesdna, "RenderData", "CurveMapping", "mblur_shutter_curve")) {
1096       Scene *scene;
1097       for (scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
1098         CurveMapping *curve_mapping = &scene->r.mblur_shutter_curve;
1099         BKE_curvemapping_set_defaults(curve_mapping, 1, 0.0f, 0.0f, 1.0f, 1.0f);
1100         BKE_curvemapping_init(curve_mapping);
1101         BKE_curvemap_reset(
1102             curve_mapping->cm, &curve_mapping->clipr, CURVE_PRESET_MAX, CURVEMAP_SLOPE_POS_NEG);
1103       }
1104     }
1105   }
1106 
1107   if (!MAIN_VERSION_ATLEAST(bmain, 276, 4)) {
1108     for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
1109       ToolSettings *ts = scene->toolsettings;
1110       if (!DNA_struct_elem_find(fd->filesdna, "ToolSettings", "char", "gpencil_v3d_align")) {
1111         ts->gpencil_v3d_align = GP_PROJECT_VIEWSPACE;
1112         ts->gpencil_v2d_align = GP_PROJECT_VIEWSPACE;
1113         ts->gpencil_seq_align = GP_PROJECT_VIEWSPACE;
1114         ts->gpencil_ima_align = GP_PROJECT_VIEWSPACE;
1115       }
1116     }
1117 
1118     for (bGPdata *gpd = bmain->gpencils.first; gpd; gpd = gpd->id.next) {
1119       bool enabled = false;
1120 
1121       /* Ensure that the datablock's onion-skinning toggle flag
1122        * stays in sync with the status of the actual layers
1123        */
1124       LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
1125         if (gpl->flag & GP_LAYER_ONIONSKIN) {
1126           enabled = true;
1127         }
1128       }
1129 
1130       if (enabled) {
1131         gpd->flag |= GP_DATA_SHOW_ONIONSKINS;
1132       }
1133       else {
1134         gpd->flag &= ~GP_DATA_SHOW_ONIONSKINS;
1135       }
1136     }
1137   }
1138   if (!MAIN_VERSION_ATLEAST(bmain, 276, 5)) {
1139     ListBase *lbarray[MAX_LIBARRAY];
1140     int a;
1141 
1142     /* Important to clear all non-persistent flags from older versions here,
1143      * otherwise they could collide with any new persistent flag we may add in the future. */
1144     a = set_listbasepointers(bmain, lbarray);
1145     while (a--) {
1146       LISTBASE_FOREACH (ID *, id, lbarray[a]) {
1147         id->flag &= LIB_FAKEUSER;
1148       }
1149     }
1150   }
1151 
1152   if (!MAIN_VERSION_ATLEAST(bmain, 276, 7)) {
1153     Scene *scene;
1154     for (scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
1155       scene->r.bake.pass_filter = R_BAKE_PASS_FILTER_ALL;
1156     }
1157   }
1158 
1159   if (!MAIN_VERSION_ATLEAST(bmain, 277, 1)) {
1160     for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
1161       ParticleEditSettings *pset = &scene->toolsettings->particle;
1162       for (int a = 0; a < ARRAY_SIZE(pset->brush); a++) {
1163         if (pset->brush[a].strength > 1.0f) {
1164           pset->brush[a].strength *= 0.01f;
1165         }
1166       }
1167     }
1168 
1169     for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
1170       LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1171         LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
1172           ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
1173                                                                  &sl->regionbase;
1174           /* Bug: Was possible to add preview region to sequencer view by using AZones. */
1175           if (sl->spacetype == SPACE_SEQ) {
1176             SpaceSeq *sseq = (SpaceSeq *)sl;
1177             if (sseq->view == SEQ_VIEW_SEQUENCE) {
1178               LISTBASE_FOREACH (ARegion *, region, regionbase) {
1179                 /* remove preview region for sequencer-only view! */
1180                 if (region->regiontype == RGN_TYPE_PREVIEW) {
1181                   region->flag |= RGN_FLAG_HIDDEN;
1182                   region->alignment = RGN_ALIGN_NONE;
1183                   break;
1184                 }
1185               }
1186             }
1187           }
1188           /* Remove old deprecated region from filebrowsers */
1189           else if (sl->spacetype == SPACE_FILE) {
1190             LISTBASE_FOREACH (ARegion *, region, regionbase) {
1191               if (region->regiontype == RGN_TYPE_CHANNELS) {
1192                 /* Free old deprecated 'channel' region... */
1193                 BKE_area_region_free(NULL, region);
1194                 BLI_freelinkN(regionbase, region);
1195                 break;
1196               }
1197             }
1198           }
1199         }
1200       }
1201     }
1202 
1203     for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
1204       CurvePaintSettings *cps = &scene->toolsettings->curve_paint_settings;
1205       if (cps->error_threshold == 0) {
1206         cps->curve_type = CU_BEZIER;
1207         cps->flag |= CURVE_PAINT_FLAG_CORNERS_DETECT;
1208         cps->error_threshold = 8;
1209         cps->radius_max = 1.0f;
1210         cps->corner_angle = DEG2RADF(70.0f);
1211       }
1212     }
1213 
1214     for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
1215       Sequence *seq;
1216 
1217       SEQ_ALL_BEGIN (scene->ed, seq) {
1218         if (seq->type != SEQ_TYPE_TEXT) {
1219           continue;
1220         }
1221 
1222         if (seq->effectdata == NULL) {
1223           struct SeqEffectHandle effect_handle = BKE_sequence_get_effect(seq);
1224           effect_handle.init(seq);
1225         }
1226 
1227         TextVars *data = seq->effectdata;
1228         if (data->color[3] == 0.0f) {
1229           copy_v4_fl(data->color, 1.0f);
1230           data->shadow_color[3] = 1.0f;
1231         }
1232       }
1233       SEQ_ALL_END;
1234     }
1235 
1236     /* Adding "Properties" region to DopeSheet */
1237     for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
1238       LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1239         /* handle pushed-back space data first */
1240         LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
1241           if (sl->spacetype == SPACE_ACTION) {
1242             SpaceAction *saction = (SpaceAction *)sl;
1243             do_version_action_editor_properties_region(&saction->regionbase);
1244           }
1245         }
1246 
1247         /* active spacedata info must be handled too... */
1248         if (area->spacetype == SPACE_ACTION) {
1249           do_version_action_editor_properties_region(&area->regionbase);
1250         }
1251       }
1252     }
1253   }
1254 
1255   if (!MAIN_VERSION_ATLEAST(bmain, 277, 2)) {
1256     if (!DNA_struct_elem_find(fd->filesdna, "Bone", "float", "scaleIn")) {
1257       for (bArmature *arm = bmain->armatures.first; arm; arm = arm->id.next) {
1258         do_version_bones_super_bbone(&arm->bonebase);
1259       }
1260     }
1261     if (!DNA_struct_elem_find(fd->filesdna, "bPoseChannel", "float", "scaleIn")) {
1262       for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) {
1263         if (ob->pose) {
1264           LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
1265             /* see do_version_bones_super_bbone()... */
1266             pchan->scale_in_x = pchan->scale_in_y = 1.0f;
1267             pchan->scale_out_x = pchan->scale_out_y = 1.0f;
1268 
1269             /* also make sure some legacy (unused for over a decade) flags are unset,
1270              * so that we can reuse them for stuff that matters now...
1271              * (i.e. POSE_IK_MAT, (unknown/unused x 4), POSE_HAS_IK)
1272              *
1273              * These seem to have been runtime flags used by the IK solver, but that stuff
1274              * should be able to be recalculated automatically anyway, so it should be fine.
1275              */
1276             pchan->flag &= ~((1 << 3) | (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7) | (1 << 8));
1277           }
1278         }
1279       }
1280     }
1281 
1282     for (Camera *camera = bmain->cameras.first; camera != NULL; camera = camera->id.next) {
1283       if (camera->stereo.pole_merge_angle_from == 0.0f &&
1284           camera->stereo.pole_merge_angle_to == 0.0f) {
1285         camera->stereo.pole_merge_angle_from = DEG2RADF(60.0f);
1286         camera->stereo.pole_merge_angle_to = DEG2RADF(75.0f);
1287       }
1288     }
1289 
1290     if (!DNA_struct_elem_find(fd->filesdna, "NormalEditModifierData", "float", "mix_limit")) {
1291       Object *ob;
1292 
1293       for (ob = bmain->objects.first; ob; ob = ob->id.next) {
1294         ModifierData *md;
1295         for (md = ob->modifiers.first; md; md = md->next) {
1296           if (md->type == eModifierType_NormalEdit) {
1297             NormalEditModifierData *nemd = (NormalEditModifierData *)md;
1298             nemd->mix_limit = DEG2RADF(180.0f);
1299           }
1300         }
1301       }
1302     }
1303 
1304     if (!DNA_struct_elem_find(fd->filesdna, "BooleanModifierData", "float", "double_threshold")) {
1305       Object *ob;
1306       for (ob = bmain->objects.first; ob; ob = ob->id.next) {
1307         ModifierData *md;
1308         for (md = ob->modifiers.first; md; md = md->next) {
1309           if (md->type == eModifierType_Boolean) {
1310             BooleanModifierData *bmd = (BooleanModifierData *)md;
1311             bmd->double_threshold = 1e-6f;
1312           }
1313         }
1314       }
1315     }
1316 
1317     for (Brush *br = bmain->brushes.first; br; br = br->id.next) {
1318       if (br->sculpt_tool == SCULPT_TOOL_FLATTEN) {
1319         br->flag |= BRUSH_ACCUMULATE;
1320       }
1321     }
1322 
1323     if (!DNA_struct_elem_find(fd->filesdna, "ClothSimSettings", "float", "time_scale")) {
1324       Object *ob;
1325       ModifierData *md;
1326       for (ob = bmain->objects.first; ob; ob = ob->id.next) {
1327         for (md = ob->modifiers.first; md; md = md->next) {
1328           if (md->type == eModifierType_Cloth) {
1329             ClothModifierData *clmd = (ClothModifierData *)md;
1330             clmd->sim_parms->time_scale = 1.0f;
1331           }
1332           else if (md->type == eModifierType_ParticleSystem) {
1333             ParticleSystemModifierData *pmd = (ParticleSystemModifierData *)md;
1334             if (pmd->psys->clmd) {
1335               pmd->psys->clmd->sim_parms->time_scale = 1.0f;
1336             }
1337           }
1338         }
1339       }
1340     }
1341   }
1342 
1343   if (!MAIN_VERSION_ATLEAST(bmain, 277, 3)) {
1344     /* ------- init of grease pencil initialization --------------- */
1345     if (!DNA_struct_elem_find(fd->filesdna, "bGPDstroke", "bGPDpalettecolor", "*palcolor")) {
1346       /* Convert Grease Pencil to new palettes/brushes
1347        * Loop all strokes and create the palette and all colors
1348        */
1349       for (bGPdata *gpd = bmain->gpencils.first; gpd; gpd = gpd->id.next) {
1350         if (BLI_listbase_is_empty(&gpd->palettes)) {
1351           /* create palette */
1352           bGPDpalette *palette = BKE_gpencil_palette_addnew(gpd, "GP_Palette");
1353           LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
1354             /* create color using layer name */
1355             bGPDpalettecolor *palcolor = BKE_gpencil_palettecolor_addnew(palette, gpl->info);
1356             if (palcolor != NULL) {
1357               /* set color attributes */
1358               copy_v4_v4(palcolor->color, gpl->color);
1359               copy_v4_v4(palcolor->fill, gpl->fill);
1360 
1361               if (gpl->flag & GP_LAYER_HIDE) {
1362                 palcolor->flag |= PC_COLOR_HIDE;
1363               }
1364               if (gpl->flag & GP_LAYER_LOCKED) {
1365                 palcolor->flag |= PC_COLOR_LOCKED;
1366               }
1367               if (gpl->flag & GP_LAYER_ONIONSKIN) {
1368                 palcolor->flag |= PC_COLOR_ONIONSKIN;
1369               }
1370               if (gpl->flag & GP_LAYER_VOLUMETRIC) {
1371                 palcolor->flag |= PC_COLOR_VOLUMETRIC;
1372               }
1373 
1374               /* set layer opacity to 1 */
1375               gpl->opacity = 1.0f;
1376 
1377               /* set tint color */
1378               ARRAY_SET_ITEMS(gpl->tintcolor, 0.0f, 0.0f, 0.0f, 0.0f);
1379 
1380               /* flush relevant layer-settings to strokes */
1381               LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
1382                 LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
1383                   /* set stroke to palette and force recalculation */
1384                   BLI_strncpy(gps->colorname, gpl->info, sizeof(gps->colorname));
1385                   gps->thickness = gpl->thickness;
1386 
1387                   /* set alpha strength to 1 */
1388                   for (int i = 0; i < gps->totpoints; i++) {
1389                     gps->points[i].strength = 1.0f;
1390                   }
1391                 }
1392               }
1393             }
1394           }
1395         }
1396       }
1397     }
1398     /* ------- end of grease pencil initialization --------------- */
1399   }
1400 
1401   if (!MAIN_VERSION_ATLEAST(bmain, 278, 0)) {
1402     if (!DNA_struct_elem_find(fd->filesdna, "MovieTrackingTrack", "float", "weight_stab")) {
1403       MovieClip *clip;
1404       for (clip = bmain->movieclips.first; clip; clip = clip->id.next) {
1405         MovieTracking *tracking = &clip->tracking;
1406         MovieTrackingObject *tracking_object;
1407         for (tracking_object = tracking->objects.first; tracking_object != NULL;
1408              tracking_object = tracking_object->next) {
1409           ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, tracking_object);
1410           MovieTrackingTrack *track;
1411           for (track = tracksbase->first; track != NULL; track = track->next) {
1412             track->weight_stab = track->weight;
1413           }
1414         }
1415       }
1416     }
1417 
1418     if (!DNA_struct_elem_find(
1419             fd->filesdna, "MovieTrackingStabilization", "int", "tot_rot_track")) {
1420       MovieClip *clip;
1421       for (clip = bmain->movieclips.first; clip != NULL; clip = clip->id.next) {
1422         if (clip->tracking.stabilization.rot_track) {
1423           migrate_single_rot_stabilization_track_settings(&clip->tracking.stabilization);
1424         }
1425         if (clip->tracking.stabilization.scale == 0.0f) {
1426           /* ensure init.
1427            * Was previously used for autoscale only,
1428            * now used always (as "target scale") */
1429           clip->tracking.stabilization.scale = 1.0f;
1430         }
1431         /* blender prefers 1-based frame counting;
1432          * thus using frame 1 as reference typically works best */
1433         clip->tracking.stabilization.anchor_frame = 1;
1434         /* by default show the track lists expanded, to improve "discoverability" */
1435         clip->tracking.stabilization.flag |= TRACKING_SHOW_STAB_TRACKS;
1436         /* deprecated, not used anymore */
1437         clip->tracking.stabilization.ok = false;
1438       }
1439     }
1440   }
1441   if (!MAIN_VERSION_ATLEAST(bmain, 278, 2)) {
1442     if (!DNA_struct_elem_find(fd->filesdna, "FFMpegCodecData", "int", "ffmpeg_preset")) {
1443       for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
1444         /* "medium" is the preset FFmpeg uses when no presets are given. */
1445         scene->r.ffcodecdata.ffmpeg_preset = FFM_PRESET_MEDIUM;
1446       }
1447     }
1448     if (!DNA_struct_elem_find(fd->filesdna, "FFMpegCodecData", "int", "constant_rate_factor")) {
1449       for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
1450         /* fall back to behavior from before we introduced CRF for old files */
1451         scene->r.ffcodecdata.constant_rate_factor = FFM_CRF_NONE;
1452       }
1453     }
1454 
1455     if (!DNA_struct_elem_find(fd->filesdna, "FluidModifierData", "float", "slice_per_voxel")) {
1456       Object *ob;
1457       ModifierData *md;
1458 
1459       for (ob = bmain->objects.first; ob; ob = ob->id.next) {
1460         for (md = ob->modifiers.first; md; md = md->next) {
1461           if (md->type == eModifierType_Fluid) {
1462             FluidModifierData *fmd = (FluidModifierData *)md;
1463             if (fmd->domain) {
1464               fmd->domain->slice_per_voxel = 5.0f;
1465               fmd->domain->slice_depth = 0.5f;
1466               fmd->domain->display_thickness = 1.0f;
1467             }
1468           }
1469         }
1470       }
1471     }
1472   }
1473 
1474   if (!MAIN_VERSION_ATLEAST(bmain, 278, 3)) {
1475     for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
1476       if (scene->toolsettings != NULL) {
1477         ToolSettings *ts = scene->toolsettings;
1478         ParticleEditSettings *pset = &ts->particle;
1479         for (int a = 0; a < ARRAY_SIZE(pset->brush); a++) {
1480           if (pset->brush[a].count == 0) {
1481             pset->brush[a].count = 10;
1482           }
1483         }
1484       }
1485     }
1486 
1487     if (!DNA_struct_elem_find(fd->filesdna, "RigidBodyCon", "float", "spring_stiffness_ang_x")) {
1488       Object *ob;
1489       for (ob = bmain->objects.first; ob; ob = ob->id.next) {
1490         RigidBodyCon *rbc = ob->rigidbody_constraint;
1491         if (rbc) {
1492           rbc->spring_stiffness_ang_x = 10.0;
1493           rbc->spring_stiffness_ang_y = 10.0;
1494           rbc->spring_stiffness_ang_z = 10.0;
1495           rbc->spring_damping_ang_x = 0.5;
1496           rbc->spring_damping_ang_y = 0.5;
1497           rbc->spring_damping_ang_z = 0.5;
1498         }
1499       }
1500     }
1501 
1502     /* constant detail for sculpting is now a resolution value instead of
1503      * a percentage, we reuse old DNA struct member but convert it */
1504     for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
1505       if (scene->toolsettings != NULL) {
1506         ToolSettings *ts = scene->toolsettings;
1507         if (ts->sculpt && ts->sculpt->constant_detail != 0.0f) {
1508           ts->sculpt->constant_detail = 100.0f / ts->sculpt->constant_detail;
1509         }
1510       }
1511     }
1512   }
1513 
1514   if (!MAIN_VERSION_ATLEAST(bmain, 278, 4)) {
1515     const float sqrt_3 = (float)M_SQRT3;
1516     for (Brush *br = bmain->brushes.first; br; br = br->id.next) {
1517       br->fill_threshold /= sqrt_3;
1518     }
1519 
1520     /* Custom motion paths */
1521     if (!DNA_struct_elem_find(fd->filesdna, "bMotionPath", "int", "line_thickness")) {
1522       Object *ob;
1523       for (ob = bmain->objects.first; ob; ob = ob->id.next) {
1524         bMotionPath *mpath;
1525         bPoseChannel *pchan;
1526         mpath = ob->mpath;
1527         if (mpath) {
1528           mpath->color[0] = 1.0f;
1529           mpath->color[1] = 0.0f;
1530           mpath->color[2] = 0.0f;
1531           mpath->line_thickness = 1;
1532           mpath->flag |= MOTIONPATH_FLAG_LINES;
1533         }
1534         /* bones motion path */
1535         if (ob->pose) {
1536           for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
1537             mpath = pchan->mpath;
1538             if (mpath) {
1539               mpath->color[0] = 1.0f;
1540               mpath->color[1] = 0.0f;
1541               mpath->color[2] = 0.0f;
1542               mpath->line_thickness = 1;
1543               mpath->flag |= MOTIONPATH_FLAG_LINES;
1544             }
1545           }
1546         }
1547       }
1548     }
1549   }
1550 
1551   if (!MAIN_VERSION_ATLEAST(bmain, 278, 5)) {
1552     /* Mask primitive adding code was not initializing correctly id_type of its points' parent. */
1553     for (Mask *mask = bmain->masks.first; mask; mask = mask->id.next) {
1554       LISTBASE_FOREACH (MaskLayer *, mlayer, &mask->masklayers) {
1555         LISTBASE_FOREACH (MaskSpline *, mspline, &mlayer->splines) {
1556           int i = 0;
1557           for (MaskSplinePoint *mspoint = mspline->points; i < mspline->tot_point;
1558                mspoint++, i++) {
1559             if (mspoint->parent.id_type == 0) {
1560               BKE_mask_parent_init(&mspoint->parent);
1561             }
1562           }
1563         }
1564       }
1565     }
1566 
1567     /* Fix for T50736, Glare comp node using same var for two different things. */
1568     if (!DNA_struct_elem_find(fd->filesdna, "NodeGlare", "char", "star_45")) {
1569       FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1570         if (ntree->type == NTREE_COMPOSIT) {
1571           ntreeSetTypes(NULL, ntree);
1572           LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
1573             if (node->type == CMP_NODE_GLARE) {
1574               NodeGlare *ndg = node->storage;
1575               switch (ndg->type) {
1576                 case 2: /* Grrrr! magic numbers :( */
1577                   ndg->streaks = ndg->angle;
1578                   break;
1579                 case 0:
1580                   ndg->star_45 = ndg->angle != 0;
1581                   break;
1582                 default:
1583                   break;
1584               }
1585             }
1586           }
1587         }
1588       }
1589       FOREACH_NODETREE_END;
1590     }
1591 
1592     if (!DNA_struct_elem_find(fd->filesdna, "SurfaceDeformModifierData", "float", "mat[4][4]")) {
1593       for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) {
1594         LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
1595           if (md->type == eModifierType_SurfaceDeform) {
1596             SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
1597             unit_m4(smd->mat);
1598           }
1599         }
1600       }
1601     }
1602 
1603     FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1604       if (ntree->type == NTREE_COMPOSIT) {
1605         do_versions_compositor_render_passes(ntree);
1606       }
1607     }
1608     FOREACH_NODETREE_END;
1609   }
1610 
1611   if (!MAIN_VERSION_ATLEAST(bmain, 279, 0)) {
1612     for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
1613       if (scene->r.im_format.exr_codec == R_IMF_EXR_CODEC_DWAB) {
1614         scene->r.im_format.exr_codec = R_IMF_EXR_CODEC_DWAA;
1615       }
1616     }
1617 
1618     /* Fix related to VGroup modifiers creating named defgroup CD layers! See T51520. */
1619     for (Mesh *me = bmain->meshes.first; me; me = me->id.next) {
1620       CustomData_set_layer_name(&me->vdata, CD_MDEFORMVERT, 0, "");
1621     }
1622   }
1623 
1624   if (!MAIN_VERSION_ATLEAST(bmain, 279, 3)) {
1625     if (!DNA_struct_elem_find(fd->filesdna, "FluidDomainSettings", "float", "clipping")) {
1626       Object *ob;
1627       ModifierData *md;
1628 
1629       for (ob = bmain->objects.first; ob; ob = ob->id.next) {
1630         for (md = ob->modifiers.first; md; md = md->next) {
1631           if (md->type == eModifierType_Fluid) {
1632             FluidModifierData *fmd = (FluidModifierData *)md;
1633             if (fmd->domain) {
1634               fmd->domain->clipping = 1e-3f;
1635             }
1636           }
1637         }
1638       }
1639     }
1640   }
1641 
1642   if (!MAIN_VERSION_ATLEAST(bmain, 279, 4)) {
1643     /* Fix for invalid state of screen due to bug in older versions. */
1644     for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
1645       LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1646         if (area->full && screen->state == SCREENNORMAL) {
1647           area->full = NULL;
1648         }
1649       }
1650     }
1651 
1652     if (!DNA_struct_elem_find(fd->filesdna, "Brush", "float", "falloff_angle")) {
1653       for (Brush *br = bmain->brushes.first; br; br = br->id.next) {
1654         br->falloff_angle = DEG2RADF(80);
1655         /* These flags are used for new feautres. They are not related to falloff_angle */
1656         br->flag &= ~(BRUSH_INVERT_TO_SCRAPE_FILL | BRUSH_ORIGINAL_PLANE |
1657                       BRUSH_GRAB_ACTIVE_VERTEX | BRUSH_SCENE_SPACING | BRUSH_FRONTFACE_FALLOFF);
1658       }
1659 
1660       for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
1661         ToolSettings *ts = scene->toolsettings;
1662         for (int i = 0; i < 2; i++) {
1663           VPaint *vp = i ? ts->vpaint : ts->wpaint;
1664           if (vp != NULL) {
1665             /* remove all other flags */
1666             vp->flag &= (VP_FLAG_VGROUP_RESTRICT);
1667           }
1668         }
1669       }
1670     }
1671 
1672     /* Simple deform modifier no longer assumes Z axis (X for bend type).
1673      * Must set previous defaults. */
1674     if (!DNA_struct_elem_find(fd->filesdna, "SimpleDeformModifierData", "char", "deform_axis")) {
1675       for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) {
1676         LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
1677           if (md->type == eModifierType_SimpleDeform) {
1678             SimpleDeformModifierData *smd = (SimpleDeformModifierData *)md;
1679             smd->deform_axis = 2;
1680           }
1681         }
1682       }
1683     }
1684 
1685     for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
1686       int preset = scene->r.ffcodecdata.ffmpeg_preset;
1687       if (preset == FFM_PRESET_NONE || preset >= FFM_PRESET_GOOD) {
1688         continue;
1689       }
1690       if (preset <= FFM_PRESET_FAST) {
1691         preset = FFM_PRESET_REALTIME;
1692       }
1693       else if (preset >= FFM_PRESET_SLOW) {
1694         preset = FFM_PRESET_BEST;
1695       }
1696       else {
1697         preset = FFM_PRESET_GOOD;
1698       }
1699       scene->r.ffcodecdata.ffmpeg_preset = preset;
1700     }
1701 
1702     if (!DNA_struct_elem_find(
1703             fd->filesdna, "ParticleInstanceModifierData", "float", "particle_amount")) {
1704       for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) {
1705         LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
1706           if (md->type == eModifierType_ParticleInstance) {
1707             ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md;
1708             pimd->space = eParticleInstanceSpace_World;
1709             pimd->particle_amount = 1.0f;
1710           }
1711         }
1712       }
1713     }
1714   }
1715 }
1716 
do_versions_after_linking_270(Main * bmain)1717 void do_versions_after_linking_270(Main *bmain)
1718 {
1719   /* To be added to next subversion bump! */
1720   if (!MAIN_VERSION_ATLEAST(bmain, 279, 0)) {
1721     FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1722       if (ntree->type == NTREE_COMPOSIT) {
1723         ntreeSetTypes(NULL, ntree);
1724         LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
1725           if (node->type == CMP_NODE_HUE_SAT) {
1726             do_version_hue_sat_node(ntree, node);
1727           }
1728         }
1729       }
1730     }
1731     FOREACH_NODETREE_END;
1732   }
1733 
1734   if (!MAIN_VERSION_ATLEAST(bmain, 279, 2)) {
1735     /* B-Bones (bbone_in/out -> bbone_easein/out) + Stepped FMod Frame Start/End fix */
1736     /* if (!DNA_struct_elem_find(fd->filesdna, "Bone", "float", "bbone_easein")) */
1737     BKE_fcurves_main_cb(bmain, do_version_bbone_easing_fcurve_fix, NULL);
1738   }
1739 }
1740