2022-02-11 09:07:11 +11:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
2021-04-20 17:08:31 +02:00
|
|
|
|
|
|
|
|
/** \file
|
|
|
|
|
* \ingroup blenloader
|
|
|
|
|
*/
|
|
|
|
|
/* allow readfile to use deprecated functionality */
|
|
|
|
|
#define DNA_DEPRECATED_ALLOW
|
|
|
|
|
|
Refactor IDProperty UI data storage
The storage of IDProperty UI data (min, max, default value, etc) is
quite complicated. For every property, retrieving a single one of these
values involves three string lookups. First for the "_RNA_UI" group
property, then another for a group with the property's name, then for
the data value name. Not only is this inefficient, it's hard to reason
about, unintuitive, and not at all self-explanatory.
This commit replaces that system with a UI data struct directly in the
IDProperty. If it's not used, the only cost is of a NULL pointer. Beyond
storing the description, name, and RNA subtype, derived structs are used
to store type specific UI data like min and max.
Note that this means that addons using (abusing) the `_RNA_UI` custom
property will have to be changed. A few places in the addons repository
will be changed after this commit with D9919.
**Before**
Before, first the _RNA_UI subgroup is retrieved the _RNA_UI group,
then the subgroup for the original property, then specific UI data
is accessed like any other IDProperty.
```
prop = rna_idprop_ui_prop_get(idproperties_owner, "prop_name", create=True)
prop["min"] = 1.0
```
**After**
After, the `id_properties_ui` function for RNA structs returns a python
object specifically for managing an IDProperty's UI data.
```
ui_data = idproperties_owner.id_properties_ui("prop_name")
ui_data.update(min=1.0)
```
In addition to `update`, there are now other functions:
- `as_dict`: Returns a dictionary of the property's UI data.
- `clear`: Removes the property's UI data.
- `update_from`: Copy UI data between properties,
even if they have different owners.
Differential Revision: https://developer.blender.org/D9697
2021-08-27 08:27:24 -05:00
|
|
|
#include <string.h>
|
|
|
|
|
|
2021-11-19 09:33:52 +01:00
|
|
|
#include "CLG_log.h"
|
|
|
|
|
|
Refactor IDProperty UI data storage
The storage of IDProperty UI data (min, max, default value, etc) is
quite complicated. For every property, retrieving a single one of these
values involves three string lookups. First for the "_RNA_UI" group
property, then another for a group with the property's name, then for
the data value name. Not only is this inefficient, it's hard to reason
about, unintuitive, and not at all self-explanatory.
This commit replaces that system with a UI data struct directly in the
IDProperty. If it's not used, the only cost is of a NULL pointer. Beyond
storing the description, name, and RNA subtype, derived structs are used
to store type specific UI data like min and max.
Note that this means that addons using (abusing) the `_RNA_UI` custom
property will have to be changed. A few places in the addons repository
will be changed after this commit with D9919.
**Before**
Before, first the _RNA_UI subgroup is retrieved the _RNA_UI group,
then the subgroup for the original property, then specific UI data
is accessed like any other IDProperty.
```
prop = rna_idprop_ui_prop_get(idproperties_owner, "prop_name", create=True)
prop["min"] = 1.0
```
**After**
After, the `id_properties_ui` function for RNA structs returns a python
object specifically for managing an IDProperty's UI data.
```
ui_data = idproperties_owner.id_properties_ui("prop_name")
ui_data.update(min=1.0)
```
In addition to `update`, there are now other functions:
- `as_dict`: Returns a dictionary of the property's UI data.
- `clear`: Removes the property's UI data.
- `update_from`: Copy UI data between properties,
even if they have different owners.
Differential Revision: https://developer.blender.org/D9697
2021-08-27 08:27:24 -05:00
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
2021-04-22 16:33:37 +10:00
|
|
|
#include "BLI_listbase.h"
|
2021-05-11 11:22:41 +02:00
|
|
|
#include "BLI_math_vector.h"
|
2021-08-13 15:51:08 +10:00
|
|
|
#include "BLI_path_util.h"
|
2021-05-28 12:17:04 -04:00
|
|
|
#include "BLI_string.h"
|
2021-12-17 17:31:15 +01:00
|
|
|
#include "BLI_string_utils.h"
|
2021-04-22 16:33:37 +10:00
|
|
|
#include "BLI_utildefines.h"
|
|
|
|
|
|
Armature: add B-Bone Y scale channel and extra flag fields to DNA.
In addition to the base bone transformation itself, B-Bones have
controls that affect transformation of its segments. For rotation
the features are quite complete, allowing to both reorient the
Bezier handles via properties, and to control them using custom
handle bones. However for scaling there are two deficiencies.
First, there are only X and Y scale factors (actually X and Z),
while lengthwise all segments have the same scaling. The ease
option merely affects the shape of the curve, and does not cause
actual scaling.
Second, scaling can only be controlled via properties, thus
requiring up to 6 drivers per joint between B-Bones to transfer
scaling factors from the handle bone. This is very inefficient.
Finally, the Z channels are confusingly called Y.
This commit adds a B-Bone Y Scale channel and extra B-Bone flag
fields to DNA with appropriate versioning (including for F-Curves
and drivers) in preparation to addressing these limitations.
Functionality is not changed, so the new fields are not used
until the following commits.
Differential Revision: https://developer.blender.org/D9870
2020-12-11 19:17:39 +03:00
|
|
|
#include "DNA_anim_types.h"
|
|
|
|
|
#include "DNA_armature_types.h"
|
2021-05-04 16:38:52 +02:00
|
|
|
#include "DNA_brush_types.h"
|
2021-07-06 17:22:18 +02:00
|
|
|
#include "DNA_collection_types.h"
|
2021-08-05 17:17:15 +02:00
|
|
|
#include "DNA_constraint_types.h"
|
2021-07-01 15:03:14 -03:00
|
|
|
#include "DNA_curve_types.h"
|
2021-04-22 16:33:37 +10:00
|
|
|
#include "DNA_genfile.h"
|
2021-09-15 14:03:18 +08:00
|
|
|
#include "DNA_gpencil_modifier_types.h"
|
|
|
|
|
#include "DNA_lineart_types.h"
|
2021-06-04 11:40:27 +02:00
|
|
|
#include "DNA_listBase.h"
|
2021-07-19 22:58:15 +08:00
|
|
|
#include "DNA_material_types.h"
|
2021-04-22 16:33:37 +10:00
|
|
|
#include "DNA_modifier_types.h"
|
2022-01-06 15:42:45 +03:00
|
|
|
#include "DNA_screen_types.h"
|
|
|
|
|
#include "DNA_space_types.h"
|
2021-05-04 14:46:32 +02:00
|
|
|
#include "DNA_text_types.h"
|
2021-07-08 22:16:50 +02:00
|
|
|
#include "DNA_workspace_types.h"
|
2021-04-22 16:33:37 +10:00
|
|
|
|
2021-07-06 15:36:27 +03:00
|
|
|
#include "BKE_action.h"
|
2021-11-19 09:33:52 +01:00
|
|
|
#include "BKE_anim_data.h"
|
Armature: add B-Bone Y scale channel and extra flag fields to DNA.
In addition to the base bone transformation itself, B-Bones have
controls that affect transformation of its segments. For rotation
the features are quite complete, allowing to both reorient the
Bezier handles via properties, and to control them using custom
handle bones. However for scaling there are two deficiencies.
First, there are only X and Y scale factors (actually X and Z),
while lengthwise all segments have the same scaling. The ease
option merely affects the shape of the curve, and does not cause
actual scaling.
Second, scaling can only be controlled via properties, thus
requiring up to 6 drivers per joint between B-Bones to transfer
scaling factors from the handle bone. This is very inefficient.
Finally, the Z channels are confusingly called Y.
This commit adds a B-Bone Y Scale channel and extra B-Bone flag
fields to DNA with appropriate versioning (including for F-Curves
and drivers) in preparation to addressing these limitations.
Functionality is not changed, so the new fields are not used
until the following commits.
Differential Revision: https://developer.blender.org/D9870
2020-12-11 19:17:39 +03:00
|
|
|
#include "BKE_animsys.h"
|
2020-11-21 21:45:14 +03:00
|
|
|
#include "BKE_armature.h"
|
2021-07-08 22:16:50 +02:00
|
|
|
#include "BKE_asset.h"
|
2021-07-06 17:22:18 +02:00
|
|
|
#include "BKE_collection.h"
|
2022-03-10 18:34:27 -06:00
|
|
|
#include "BKE_curve.h"
|
2021-07-13 12:10:34 -04:00
|
|
|
#include "BKE_deform.h"
|
2021-07-01 15:03:14 -03:00
|
|
|
#include "BKE_fcurve.h"
|
Armature: add B-Bone Y scale channel and extra flag fields to DNA.
In addition to the base bone transformation itself, B-Bones have
controls that affect transformation of its segments. For rotation
the features are quite complete, allowing to both reorient the
Bezier handles via properties, and to control them using custom
handle bones. However for scaling there are two deficiencies.
First, there are only X and Y scale factors (actually X and Z),
while lengthwise all segments have the same scaling. The ease
option merely affects the shape of the curve, and does not cause
actual scaling.
Second, scaling can only be controlled via properties, thus
requiring up to 6 drivers per joint between B-Bones to transfer
scaling factors from the handle bone. This is very inefficient.
Finally, the Z channels are confusingly called Y.
This commit adds a B-Bone Y Scale channel and extra B-Bone flag
fields to DNA with appropriate versioning (including for F-Curves
and drivers) in preparation to addressing these limitations.
Functionality is not changed, so the new fields are not used
until the following commits.
Differential Revision: https://developer.blender.org/D9870
2020-12-11 19:17:39 +03:00
|
|
|
#include "BKE_fcurve_driver.h"
|
Refactor IDProperty UI data storage
The storage of IDProperty UI data (min, max, default value, etc) is
quite complicated. For every property, retrieving a single one of these
values involves three string lookups. First for the "_RNA_UI" group
property, then another for a group with the property's name, then for
the data value name. Not only is this inefficient, it's hard to reason
about, unintuitive, and not at all self-explanatory.
This commit replaces that system with a UI data struct directly in the
IDProperty. If it's not used, the only cost is of a NULL pointer. Beyond
storing the description, name, and RNA subtype, derived structs are used
to store type specific UI data like min and max.
Note that this means that addons using (abusing) the `_RNA_UI` custom
property will have to be changed. A few places in the addons repository
will be changed after this commit with D9919.
**Before**
Before, first the _RNA_UI subgroup is retrieved the _RNA_UI group,
then the subgroup for the original property, then specific UI data
is accessed like any other IDProperty.
```
prop = rna_idprop_ui_prop_get(idproperties_owner, "prop_name", create=True)
prop["min"] = 1.0
```
**After**
After, the `id_properties_ui` function for RNA structs returns a python
object specifically for managing an IDProperty's UI data.
```
ui_data = idproperties_owner.id_properties_ui("prop_name")
ui_data.update(min=1.0)
```
In addition to `update`, there are now other functions:
- `as_dict`: Returns a dictionary of the property's UI data.
- `clear`: Removes the property's UI data.
- `update_from`: Copy UI data between properties,
even if they have different owners.
Differential Revision: https://developer.blender.org/D9697
2021-08-27 08:27:24 -05:00
|
|
|
#include "BKE_idprop.h"
|
UDIM: Support virtual filenames
This implements the design detailed in T92696 to support virtual
filenames for UDIM textures. Currently, the following 2 substitution
tokens are supported:
| Token | Meaning |
| ----- | ---- |
| <UDIM> | 1001 + u-tile + v-tile * 10 |
| <UVTILE> | Equivalent to u<u-tile + 1>_v<v-tile + 1> |
Example for u-tile of 3 and v-tile of 1:
filename.<UDIM>_ver0023.png --> filename.1014_ver0023.png
filename.<UVTILE>_ver0023.png --> filename.u4_v2_ver0023.png
For image loading, the existing workflow is unchanged. A user can select
one or more image files, belonging to one or more UDIM tile sets, and
have Blender load them all as it does today. Now the <UVTILE> format is
"guessed" just as the <UDIM> format was guessed before.
If guessing fails, the user can simply go into the Image Editor and type
the proper substitution in the filename. Once typing is complete,
Blender will reload the files and correctly fill the tiles. This
workflow is new as attempting to fix the guessing in current versions
did not really work, and the user was often stuck with a confusing
situation.
For image saving, the existing workflow is changed slightly. Currently,
when saving, a user has to be sure to type the filename of the first
tile (e.g. filename.1001.png) to save the entire UDIM set. The number
could differ if they start at a different tile etc. This is confusing.
Now, the user should type a filename containing the appropriate
substitution token. By default Blender will fill in a default name using
the <UDIM> token but the user is free to save out images using <UVTILE>
if they wish.
Differential Revision: https://developer.blender.org/D13057
2021-12-30 22:06:23 -08:00
|
|
|
#include "BKE_image.h"
|
2021-05-04 14:46:32 +02:00
|
|
|
#include "BKE_lib_id.h"
|
2021-11-19 09:33:52 +01:00
|
|
|
#include "BKE_lib_override.h"
|
2021-04-20 17:08:31 +02:00
|
|
|
#include "BKE_main.h"
|
2021-10-19 08:39:10 -05:00
|
|
|
#include "BKE_modifier.h"
|
2021-05-14 11:22:02 +02:00
|
|
|
#include "BKE_node.h"
|
2021-04-20 17:08:31 +02:00
|
|
|
|
Refactor IDProperty UI data storage
The storage of IDProperty UI data (min, max, default value, etc) is
quite complicated. For every property, retrieving a single one of these
values involves three string lookups. First for the "_RNA_UI" group
property, then another for a group with the property's name, then for
the data value name. Not only is this inefficient, it's hard to reason
about, unintuitive, and not at all self-explanatory.
This commit replaces that system with a UI data struct directly in the
IDProperty. If it's not used, the only cost is of a NULL pointer. Beyond
storing the description, name, and RNA subtype, derived structs are used
to store type specific UI data like min and max.
Note that this means that addons using (abusing) the `_RNA_UI` custom
property will have to be changed. A few places in the addons repository
will be changed after this commit with D9919.
**Before**
Before, first the _RNA_UI subgroup is retrieved the _RNA_UI group,
then the subgroup for the original property, then specific UI data
is accessed like any other IDProperty.
```
prop = rna_idprop_ui_prop_get(idproperties_owner, "prop_name", create=True)
prop["min"] = 1.0
```
**After**
After, the `id_properties_ui` function for RNA structs returns a python
object specifically for managing an IDProperty's UI data.
```
ui_data = idproperties_owner.id_properties_ui("prop_name")
ui_data.update(min=1.0)
```
In addition to `update`, there are now other functions:
- `as_dict`: Returns a dictionary of the property's UI data.
- `clear`: Removes the property's UI data.
- `update_from`: Copy UI data between properties,
even if they have different owners.
Differential Revision: https://developer.blender.org/D9697
2021-08-27 08:27:24 -05:00
|
|
|
#include "RNA_access.h"
|
|
|
|
|
#include "RNA_enum_types.h"
|
2022-03-14 16:54:46 +01:00
|
|
|
#include "RNA_prototypes.h"
|
Refactor IDProperty UI data storage
The storage of IDProperty UI data (min, max, default value, etc) is
quite complicated. For every property, retrieving a single one of these
values involves three string lookups. First for the "_RNA_UI" group
property, then another for a group with the property's name, then for
the data value name. Not only is this inefficient, it's hard to reason
about, unintuitive, and not at all self-explanatory.
This commit replaces that system with a UI data struct directly in the
IDProperty. If it's not used, the only cost is of a NULL pointer. Beyond
storing the description, name, and RNA subtype, derived structs are used
to store type specific UI data like min and max.
Note that this means that addons using (abusing) the `_RNA_UI` custom
property will have to be changed. A few places in the addons repository
will be changed after this commit with D9919.
**Before**
Before, first the _RNA_UI subgroup is retrieved the _RNA_UI group,
then the subgroup for the original property, then specific UI data
is accessed like any other IDProperty.
```
prop = rna_idprop_ui_prop_get(idproperties_owner, "prop_name", create=True)
prop["min"] = 1.0
```
**After**
After, the `id_properties_ui` function for RNA structs returns a python
object specifically for managing an IDProperty's UI data.
```
ui_data = idproperties_owner.id_properties_ui("prop_name")
ui_data.update(min=1.0)
```
In addition to `update`, there are now other functions:
- `as_dict`: Returns a dictionary of the property's UI data.
- `clear`: Removes the property's UI data.
- `update_from`: Copy UI data between properties,
even if they have different owners.
Differential Revision: https://developer.blender.org/D9697
2021-08-27 08:27:24 -05:00
|
|
|
|
2021-04-20 17:08:31 +02:00
|
|
|
#include "BLO_readfile.h"
|
2021-06-25 07:57:24 +02:00
|
|
|
#include "MEM_guardedalloc.h"
|
2021-04-20 17:08:31 +02:00
|
|
|
#include "readfile.h"
|
|
|
|
|
|
2021-09-21 09:38:30 +02:00
|
|
|
#include "SEQ_iterator.h"
|
2021-06-29 20:12:19 +02:00
|
|
|
#include "SEQ_sequencer.h"
|
2021-11-19 06:10:26 +01:00
|
|
|
#include "SEQ_time.h"
|
2021-06-29 20:12:19 +02:00
|
|
|
|
2021-07-01 15:03:14 -03:00
|
|
|
#include "RNA_access.h"
|
Armature: add B-Bone Y scale channel and extra flag fields to DNA.
In addition to the base bone transformation itself, B-Bones have
controls that affect transformation of its segments. For rotation
the features are quite complete, allowing to both reorient the
Bezier handles via properties, and to control them using custom
handle bones. However for scaling there are two deficiencies.
First, there are only X and Y scale factors (actually X and Z),
while lengthwise all segments have the same scaling. The ease
option merely affects the shape of the curve, and does not cause
actual scaling.
Second, scaling can only be controlled via properties, thus
requiring up to 6 drivers per joint between B-Bones to transfer
scaling factors from the handle bone. This is very inefficient.
Finally, the Z channels are confusingly called Y.
This commit adds a B-Bone Y Scale channel and extra B-Bone flag
fields to DNA with appropriate versioning (including for F-Curves
and drivers) in preparation to addressing these limitations.
Functionality is not changed, so the new fields are not used
until the following commits.
Differential Revision: https://developer.blender.org/D9870
2020-12-11 19:17:39 +03:00
|
|
|
|
2021-06-18 16:33:02 -05:00
|
|
|
#include "versioning_common.h"
|
|
|
|
|
|
2021-11-19 09:33:52 +01:00
|
|
|
static CLG_LogRef LOG = {"blo.readfile.doversion"};
|
|
|
|
|
|
Refactor IDProperty UI data storage
The storage of IDProperty UI data (min, max, default value, etc) is
quite complicated. For every property, retrieving a single one of these
values involves three string lookups. First for the "_RNA_UI" group
property, then another for a group with the property's name, then for
the data value name. Not only is this inefficient, it's hard to reason
about, unintuitive, and not at all self-explanatory.
This commit replaces that system with a UI data struct directly in the
IDProperty. If it's not used, the only cost is of a NULL pointer. Beyond
storing the description, name, and RNA subtype, derived structs are used
to store type specific UI data like min and max.
Note that this means that addons using (abusing) the `_RNA_UI` custom
property will have to be changed. A few places in the addons repository
will be changed after this commit with D9919.
**Before**
Before, first the _RNA_UI subgroup is retrieved the _RNA_UI group,
then the subgroup for the original property, then specific UI data
is accessed like any other IDProperty.
```
prop = rna_idprop_ui_prop_get(idproperties_owner, "prop_name", create=True)
prop["min"] = 1.0
```
**After**
After, the `id_properties_ui` function for RNA structs returns a python
object specifically for managing an IDProperty's UI data.
```
ui_data = idproperties_owner.id_properties_ui("prop_name")
ui_data.update(min=1.0)
```
In addition to `update`, there are now other functions:
- `as_dict`: Returns a dictionary of the property's UI data.
- `clear`: Removes the property's UI data.
- `update_from`: Copy UI data between properties,
even if they have different owners.
Differential Revision: https://developer.blender.org/D9697
2021-08-27 08:27:24 -05:00
|
|
|
static IDProperty *idproperty_find_ui_container(IDProperty *idprop_group)
|
|
|
|
|
{
|
|
|
|
|
LISTBASE_FOREACH (IDProperty *, prop, &idprop_group->data.group) {
|
|
|
|
|
if (prop->type == IDP_GROUP && STREQ(prop->name, "_RNA_UI")) {
|
|
|
|
|
return prop;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void version_idproperty_move_data_int(IDPropertyUIDataInt *ui_data,
|
|
|
|
|
const IDProperty *prop_ui_data)
|
|
|
|
|
{
|
|
|
|
|
IDProperty *min = IDP_GetPropertyFromGroup(prop_ui_data, "min");
|
|
|
|
|
if (min != NULL) {
|
|
|
|
|
ui_data->min = ui_data->soft_min = IDP_coerce_to_int_or_zero(min);
|
|
|
|
|
}
|
|
|
|
|
IDProperty *max = IDP_GetPropertyFromGroup(prop_ui_data, "max");
|
|
|
|
|
if (max != NULL) {
|
|
|
|
|
ui_data->max = ui_data->soft_max = IDP_coerce_to_int_or_zero(max);
|
|
|
|
|
}
|
|
|
|
|
IDProperty *soft_min = IDP_GetPropertyFromGroup(prop_ui_data, "soft_min");
|
|
|
|
|
if (soft_min != NULL) {
|
|
|
|
|
ui_data->soft_min = IDP_coerce_to_int_or_zero(soft_min);
|
|
|
|
|
ui_data->soft_min = MIN2(ui_data->soft_min, ui_data->min);
|
|
|
|
|
}
|
|
|
|
|
IDProperty *soft_max = IDP_GetPropertyFromGroup(prop_ui_data, "soft_max");
|
|
|
|
|
if (soft_max != NULL) {
|
|
|
|
|
ui_data->soft_max = IDP_coerce_to_int_or_zero(soft_max);
|
|
|
|
|
ui_data->soft_max = MAX2(ui_data->soft_max, ui_data->max);
|
|
|
|
|
}
|
|
|
|
|
IDProperty *step = IDP_GetPropertyFromGroup(prop_ui_data, "step");
|
|
|
|
|
if (step != NULL) {
|
|
|
|
|
ui_data->step = IDP_coerce_to_int_or_zero(soft_max);
|
|
|
|
|
}
|
|
|
|
|
IDProperty *default_value = IDP_GetPropertyFromGroup(prop_ui_data, "default");
|
|
|
|
|
if (default_value != NULL) {
|
|
|
|
|
if (default_value->type == IDP_ARRAY) {
|
|
|
|
|
if (default_value->subtype == IDP_INT) {
|
2021-09-21 11:20:34 -05:00
|
|
|
ui_data->default_array = MEM_malloc_arrayN(default_value->len, sizeof(int), __func__);
|
|
|
|
|
memcpy(ui_data->default_array, IDP_Array(default_value), sizeof(int) * default_value->len);
|
Refactor IDProperty UI data storage
The storage of IDProperty UI data (min, max, default value, etc) is
quite complicated. For every property, retrieving a single one of these
values involves three string lookups. First for the "_RNA_UI" group
property, then another for a group with the property's name, then for
the data value name. Not only is this inefficient, it's hard to reason
about, unintuitive, and not at all self-explanatory.
This commit replaces that system with a UI data struct directly in the
IDProperty. If it's not used, the only cost is of a NULL pointer. Beyond
storing the description, name, and RNA subtype, derived structs are used
to store type specific UI data like min and max.
Note that this means that addons using (abusing) the `_RNA_UI` custom
property will have to be changed. A few places in the addons repository
will be changed after this commit with D9919.
**Before**
Before, first the _RNA_UI subgroup is retrieved the _RNA_UI group,
then the subgroup for the original property, then specific UI data
is accessed like any other IDProperty.
```
prop = rna_idprop_ui_prop_get(idproperties_owner, "prop_name", create=True)
prop["min"] = 1.0
```
**After**
After, the `id_properties_ui` function for RNA structs returns a python
object specifically for managing an IDProperty's UI data.
```
ui_data = idproperties_owner.id_properties_ui("prop_name")
ui_data.update(min=1.0)
```
In addition to `update`, there are now other functions:
- `as_dict`: Returns a dictionary of the property's UI data.
- `clear`: Removes the property's UI data.
- `update_from`: Copy UI data between properties,
even if they have different owners.
Differential Revision: https://developer.blender.org/D9697
2021-08-27 08:27:24 -05:00
|
|
|
ui_data->default_array_len = default_value->len;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (default_value->type == IDP_INT) {
|
|
|
|
|
ui_data->default_value = IDP_coerce_to_int_or_zero(default_value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void version_idproperty_move_data_float(IDPropertyUIDataFloat *ui_data,
|
|
|
|
|
const IDProperty *prop_ui_data)
|
|
|
|
|
{
|
|
|
|
|
IDProperty *min = IDP_GetPropertyFromGroup(prop_ui_data, "min");
|
|
|
|
|
if (min != NULL) {
|
|
|
|
|
ui_data->min = ui_data->soft_min = IDP_coerce_to_double_or_zero(min);
|
|
|
|
|
}
|
|
|
|
|
IDProperty *max = IDP_GetPropertyFromGroup(prop_ui_data, "max");
|
|
|
|
|
if (max != NULL) {
|
2021-08-31 12:17:05 -05:00
|
|
|
ui_data->max = ui_data->soft_max = IDP_coerce_to_double_or_zero(max);
|
Refactor IDProperty UI data storage
The storage of IDProperty UI data (min, max, default value, etc) is
quite complicated. For every property, retrieving a single one of these
values involves three string lookups. First for the "_RNA_UI" group
property, then another for a group with the property's name, then for
the data value name. Not only is this inefficient, it's hard to reason
about, unintuitive, and not at all self-explanatory.
This commit replaces that system with a UI data struct directly in the
IDProperty. If it's not used, the only cost is of a NULL pointer. Beyond
storing the description, name, and RNA subtype, derived structs are used
to store type specific UI data like min and max.
Note that this means that addons using (abusing) the `_RNA_UI` custom
property will have to be changed. A few places in the addons repository
will be changed after this commit with D9919.
**Before**
Before, first the _RNA_UI subgroup is retrieved the _RNA_UI group,
then the subgroup for the original property, then specific UI data
is accessed like any other IDProperty.
```
prop = rna_idprop_ui_prop_get(idproperties_owner, "prop_name", create=True)
prop["min"] = 1.0
```
**After**
After, the `id_properties_ui` function for RNA structs returns a python
object specifically for managing an IDProperty's UI data.
```
ui_data = idproperties_owner.id_properties_ui("prop_name")
ui_data.update(min=1.0)
```
In addition to `update`, there are now other functions:
- `as_dict`: Returns a dictionary of the property's UI data.
- `clear`: Removes the property's UI data.
- `update_from`: Copy UI data between properties,
even if they have different owners.
Differential Revision: https://developer.blender.org/D9697
2021-08-27 08:27:24 -05:00
|
|
|
}
|
|
|
|
|
IDProperty *soft_min = IDP_GetPropertyFromGroup(prop_ui_data, "soft_min");
|
|
|
|
|
if (soft_min != NULL) {
|
|
|
|
|
ui_data->soft_min = IDP_coerce_to_double_or_zero(soft_min);
|
|
|
|
|
ui_data->soft_min = MAX2(ui_data->soft_min, ui_data->min);
|
|
|
|
|
}
|
|
|
|
|
IDProperty *soft_max = IDP_GetPropertyFromGroup(prop_ui_data, "soft_max");
|
|
|
|
|
if (soft_max != NULL) {
|
|
|
|
|
ui_data->soft_max = IDP_coerce_to_double_or_zero(soft_max);
|
|
|
|
|
ui_data->soft_max = MIN2(ui_data->soft_max, ui_data->max);
|
|
|
|
|
}
|
|
|
|
|
IDProperty *step = IDP_GetPropertyFromGroup(prop_ui_data, "step");
|
|
|
|
|
if (step != NULL) {
|
|
|
|
|
ui_data->step = IDP_coerce_to_float_or_zero(step);
|
|
|
|
|
}
|
|
|
|
|
IDProperty *precision = IDP_GetPropertyFromGroup(prop_ui_data, "precision");
|
|
|
|
|
if (precision != NULL) {
|
|
|
|
|
ui_data->precision = IDP_coerce_to_int_or_zero(precision);
|
|
|
|
|
}
|
|
|
|
|
IDProperty *default_value = IDP_GetPropertyFromGroup(prop_ui_data, "default");
|
|
|
|
|
if (default_value != NULL) {
|
|
|
|
|
if (default_value->type == IDP_ARRAY) {
|
2021-10-14 10:22:51 +11:00
|
|
|
const int array_len = default_value->len;
|
|
|
|
|
ui_data->default_array_len = array_len;
|
2021-09-21 11:20:34 -05:00
|
|
|
if (default_value->subtype == IDP_FLOAT) {
|
2021-10-14 10:22:51 +11:00
|
|
|
ui_data->default_array = MEM_malloc_arrayN(array_len, sizeof(double), __func__);
|
2021-09-21 11:20:34 -05:00
|
|
|
const float *old_default_array = IDP_Array(default_value);
|
|
|
|
|
for (int i = 0; i < ui_data->default_array_len; i++) {
|
|
|
|
|
ui_data->default_array[i] = (double)old_default_array[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (default_value->subtype == IDP_DOUBLE) {
|
2021-10-14 10:22:51 +11:00
|
|
|
ui_data->default_array = MEM_malloc_arrayN(array_len, sizeof(double), __func__);
|
|
|
|
|
memcpy(ui_data->default_array, IDP_Array(default_value), sizeof(double) * array_len);
|
Refactor IDProperty UI data storage
The storage of IDProperty UI data (min, max, default value, etc) is
quite complicated. For every property, retrieving a single one of these
values involves three string lookups. First for the "_RNA_UI" group
property, then another for a group with the property's name, then for
the data value name. Not only is this inefficient, it's hard to reason
about, unintuitive, and not at all self-explanatory.
This commit replaces that system with a UI data struct directly in the
IDProperty. If it's not used, the only cost is of a NULL pointer. Beyond
storing the description, name, and RNA subtype, derived structs are used
to store type specific UI data like min and max.
Note that this means that addons using (abusing) the `_RNA_UI` custom
property will have to be changed. A few places in the addons repository
will be changed after this commit with D9919.
**Before**
Before, first the _RNA_UI subgroup is retrieved the _RNA_UI group,
then the subgroup for the original property, then specific UI data
is accessed like any other IDProperty.
```
prop = rna_idprop_ui_prop_get(idproperties_owner, "prop_name", create=True)
prop["min"] = 1.0
```
**After**
After, the `id_properties_ui` function for RNA structs returns a python
object specifically for managing an IDProperty's UI data.
```
ui_data = idproperties_owner.id_properties_ui("prop_name")
ui_data.update(min=1.0)
```
In addition to `update`, there are now other functions:
- `as_dict`: Returns a dictionary of the property's UI data.
- `clear`: Removes the property's UI data.
- `update_from`: Copy UI data between properties,
even if they have different owners.
Differential Revision: https://developer.blender.org/D9697
2021-08-27 08:27:24 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (ELEM(default_value->type, IDP_DOUBLE, IDP_FLOAT)) {
|
|
|
|
|
ui_data->default_value = IDP_coerce_to_double_or_zero(default_value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void version_idproperty_move_data_string(IDPropertyUIDataString *ui_data,
|
|
|
|
|
const IDProperty *prop_ui_data)
|
|
|
|
|
{
|
|
|
|
|
IDProperty *default_value = IDP_GetPropertyFromGroup(prop_ui_data, "default");
|
|
|
|
|
if (default_value != NULL && default_value->type == IDP_STRING) {
|
|
|
|
|
ui_data->default_value = BLI_strdup(IDP_String(default_value));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void version_idproperty_ui_data(IDProperty *idprop_group)
|
|
|
|
|
{
|
|
|
|
|
if (idprop_group == NULL) { /* NULL check here to reduce verbosity of calls to this function. */
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IDProperty *ui_container = idproperty_find_ui_container(idprop_group);
|
|
|
|
|
if (ui_container == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LISTBASE_FOREACH (IDProperty *, prop, &idprop_group->data.group) {
|
|
|
|
|
IDProperty *prop_ui_data = IDP_GetPropertyFromGroup(ui_container, prop->name);
|
|
|
|
|
if (prop_ui_data == NULL) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!IDP_ui_data_supported(prop)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IDPropertyUIData *ui_data = IDP_ui_data_ensure(prop);
|
|
|
|
|
|
|
|
|
|
IDProperty *subtype = IDP_GetPropertyFromGroup(prop_ui_data, "subtype");
|
|
|
|
|
if (subtype != NULL && subtype->type == IDP_STRING) {
|
|
|
|
|
const char *subtype_string = IDP_String(subtype);
|
|
|
|
|
int result = PROP_NONE;
|
|
|
|
|
RNA_enum_value_from_id(rna_enum_property_subtype_items, subtype_string, &result);
|
|
|
|
|
ui_data->rna_subtype = result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IDProperty *description = IDP_GetPropertyFromGroup(prop_ui_data, "description");
|
|
|
|
|
if (description != NULL && description->type == IDP_STRING) {
|
|
|
|
|
ui_data->description = BLI_strdup(IDP_String(description));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Type specific data. */
|
|
|
|
|
switch (IDP_ui_data_type(prop)) {
|
|
|
|
|
case IDP_UI_DATA_TYPE_STRING:
|
|
|
|
|
version_idproperty_move_data_string((IDPropertyUIDataString *)ui_data, prop_ui_data);
|
|
|
|
|
break;
|
|
|
|
|
case IDP_UI_DATA_TYPE_ID:
|
|
|
|
|
break;
|
|
|
|
|
case IDP_UI_DATA_TYPE_INT:
|
|
|
|
|
version_idproperty_move_data_int((IDPropertyUIDataInt *)ui_data, prop_ui_data);
|
|
|
|
|
break;
|
|
|
|
|
case IDP_UI_DATA_TYPE_FLOAT:
|
|
|
|
|
version_idproperty_move_data_float((IDPropertyUIDataFloat *)ui_data, prop_ui_data);
|
|
|
|
|
break;
|
|
|
|
|
case IDP_UI_DATA_TYPE_UNSUPPORTED:
|
|
|
|
|
BLI_assert_unreachable();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IDP_FreeFromGroup(ui_container, prop_ui_data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IDP_FreeFromGroup(idprop_group, ui_container);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void do_versions_idproperty_bones_recursive(Bone *bone)
|
|
|
|
|
{
|
|
|
|
|
version_idproperty_ui_data(bone->prop);
|
|
|
|
|
LISTBASE_FOREACH (Bone *, child_bone, &bone->childbase) {
|
|
|
|
|
do_versions_idproperty_bones_recursive(child_bone);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-16 21:45:52 +10:00
|
|
|
static void do_versions_idproperty_seq_recursive(ListBase *seqbase)
|
|
|
|
|
{
|
|
|
|
|
LISTBASE_FOREACH (Sequence *, seq, seqbase) {
|
|
|
|
|
version_idproperty_ui_data(seq->prop);
|
|
|
|
|
if (seq->type == SEQ_TYPE_META) {
|
|
|
|
|
do_versions_idproperty_seq_recursive(&seq->seqbase);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
Refactor IDProperty UI data storage
The storage of IDProperty UI data (min, max, default value, etc) is
quite complicated. For every property, retrieving a single one of these
values involves three string lookups. First for the "_RNA_UI" group
property, then another for a group with the property's name, then for
the data value name. Not only is this inefficient, it's hard to reason
about, unintuitive, and not at all self-explanatory.
This commit replaces that system with a UI data struct directly in the
IDProperty. If it's not used, the only cost is of a NULL pointer. Beyond
storing the description, name, and RNA subtype, derived structs are used
to store type specific UI data like min and max.
Note that this means that addons using (abusing) the `_RNA_UI` custom
property will have to be changed. A few places in the addons repository
will be changed after this commit with D9919.
**Before**
Before, first the _RNA_UI subgroup is retrieved the _RNA_UI group,
then the subgroup for the original property, then specific UI data
is accessed like any other IDProperty.
```
prop = rna_idprop_ui_prop_get(idproperties_owner, "prop_name", create=True)
prop["min"] = 1.0
```
**After**
After, the `id_properties_ui` function for RNA structs returns a python
object specifically for managing an IDProperty's UI data.
```
ui_data = idproperties_owner.id_properties_ui("prop_name")
ui_data.update(min=1.0)
```
In addition to `update`, there are now other functions:
- `as_dict`: Returns a dictionary of the property's UI data.
- `clear`: Removes the property's UI data.
- `update_from`: Copy UI data between properties,
even if they have different owners.
Differential Revision: https://developer.blender.org/D9697
2021-08-27 08:27:24 -05:00
|
|
|
/**
|
|
|
|
|
* For every data block that supports them, initialize the new IDProperty UI data struct based on
|
|
|
|
|
* the old more complicated storage. Assumes only the top level of IDProperties below the parent
|
|
|
|
|
* group had UI data in a "_RNA_UI" group.
|
|
|
|
|
*
|
|
|
|
|
* \note The following IDProperty groups in DNA aren't exposed in the UI or are runtime-only, so
|
|
|
|
|
* they don't have UI data: wmOperator, bAddon, bUserMenuItem_Op, wmKeyMapItem, wmKeyConfigPref,
|
|
|
|
|
* uiList, FFMpegCodecData, View3DShading, bToolRef, TimeMarker, ViewLayer, bPoseChannel.
|
|
|
|
|
*/
|
|
|
|
|
static void do_versions_idproperty_ui_data(Main *bmain)
|
|
|
|
|
{
|
|
|
|
|
/* ID data. */
|
|
|
|
|
ID *id;
|
|
|
|
|
FOREACH_MAIN_ID_BEGIN (bmain, id) {
|
|
|
|
|
IDProperty *idprop_group = IDP_GetProperties(id, false);
|
|
|
|
|
version_idproperty_ui_data(idprop_group);
|
|
|
|
|
}
|
|
|
|
|
FOREACH_MAIN_ID_END;
|
|
|
|
|
|
|
|
|
|
/* Bones. */
|
|
|
|
|
LISTBASE_FOREACH (bArmature *, armature, &bmain->armatures) {
|
|
|
|
|
LISTBASE_FOREACH (Bone *, bone, &armature->bonebase) {
|
|
|
|
|
do_versions_idproperty_bones_recursive(bone);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Nodes and node sockets. */
|
|
|
|
|
LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
|
|
|
|
|
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
|
|
|
|
|
version_idproperty_ui_data(node->prop);
|
|
|
|
|
}
|
|
|
|
|
LISTBASE_FOREACH (bNodeSocket *, socket, &ntree->inputs) {
|
|
|
|
|
version_idproperty_ui_data(socket->prop);
|
|
|
|
|
}
|
|
|
|
|
LISTBASE_FOREACH (bNodeSocket *, socket, &ntree->outputs) {
|
|
|
|
|
version_idproperty_ui_data(socket->prop);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
|
2021-08-31 11:12:07 -05:00
|
|
|
/* The UI data from exposed node modifier properties is just copied from the corresponding node
|
|
|
|
|
* group, but the copying only runs when necessary, so we still need to version data here. */
|
Refactor IDProperty UI data storage
The storage of IDProperty UI data (min, max, default value, etc) is
quite complicated. For every property, retrieving a single one of these
values involves three string lookups. First for the "_RNA_UI" group
property, then another for a group with the property's name, then for
the data value name. Not only is this inefficient, it's hard to reason
about, unintuitive, and not at all self-explanatory.
This commit replaces that system with a UI data struct directly in the
IDProperty. If it's not used, the only cost is of a NULL pointer. Beyond
storing the description, name, and RNA subtype, derived structs are used
to store type specific UI data like min and max.
Note that this means that addons using (abusing) the `_RNA_UI` custom
property will have to be changed. A few places in the addons repository
will be changed after this commit with D9919.
**Before**
Before, first the _RNA_UI subgroup is retrieved the _RNA_UI group,
then the subgroup for the original property, then specific UI data
is accessed like any other IDProperty.
```
prop = rna_idprop_ui_prop_get(idproperties_owner, "prop_name", create=True)
prop["min"] = 1.0
```
**After**
After, the `id_properties_ui` function for RNA structs returns a python
object specifically for managing an IDProperty's UI data.
```
ui_data = idproperties_owner.id_properties_ui("prop_name")
ui_data.update(min=1.0)
```
In addition to `update`, there are now other functions:
- `as_dict`: Returns a dictionary of the property's UI data.
- `clear`: Removes the property's UI data.
- `update_from`: Copy UI data between properties,
even if they have different owners.
Differential Revision: https://developer.blender.org/D9697
2021-08-27 08:27:24 -05:00
|
|
|
LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
|
|
|
|
|
if (md->type == eModifierType_Nodes) {
|
|
|
|
|
NodesModifierData *nmd = (NodesModifierData *)md;
|
|
|
|
|
version_idproperty_ui_data(nmd->settings.properties);
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-08-31 11:12:07 -05:00
|
|
|
|
|
|
|
|
/* Object post bones. */
|
|
|
|
|
if (ob->type == OB_ARMATURE && ob->pose != NULL) {
|
|
|
|
|
LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
|
|
|
|
|
version_idproperty_ui_data(pchan->prop);
|
|
|
|
|
}
|
|
|
|
|
}
|
Refactor IDProperty UI data storage
The storage of IDProperty UI data (min, max, default value, etc) is
quite complicated. For every property, retrieving a single one of these
values involves three string lookups. First for the "_RNA_UI" group
property, then another for a group with the property's name, then for
the data value name. Not only is this inefficient, it's hard to reason
about, unintuitive, and not at all self-explanatory.
This commit replaces that system with a UI data struct directly in the
IDProperty. If it's not used, the only cost is of a NULL pointer. Beyond
storing the description, name, and RNA subtype, derived structs are used
to store type specific UI data like min and max.
Note that this means that addons using (abusing) the `_RNA_UI` custom
property will have to be changed. A few places in the addons repository
will be changed after this commit with D9919.
**Before**
Before, first the _RNA_UI subgroup is retrieved the _RNA_UI group,
then the subgroup for the original property, then specific UI data
is accessed like any other IDProperty.
```
prop = rna_idprop_ui_prop_get(idproperties_owner, "prop_name", create=True)
prop["min"] = 1.0
```
**After**
After, the `id_properties_ui` function for RNA structs returns a python
object specifically for managing an IDProperty's UI data.
```
ui_data = idproperties_owner.id_properties_ui("prop_name")
ui_data.update(min=1.0)
```
In addition to `update`, there are now other functions:
- `as_dict`: Returns a dictionary of the property's UI data.
- `clear`: Removes the property's UI data.
- `update_from`: Copy UI data between properties,
even if they have different owners.
Differential Revision: https://developer.blender.org/D9697
2021-08-27 08:27:24 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Sequences. */
|
|
|
|
|
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
|
|
|
|
if (scene->ed != NULL) {
|
2021-09-16 21:45:52 +10:00
|
|
|
do_versions_idproperty_seq_recursive(&scene->ed->seqbase);
|
Refactor IDProperty UI data storage
The storage of IDProperty UI data (min, max, default value, etc) is
quite complicated. For every property, retrieving a single one of these
values involves three string lookups. First for the "_RNA_UI" group
property, then another for a group with the property's name, then for
the data value name. Not only is this inefficient, it's hard to reason
about, unintuitive, and not at all self-explanatory.
This commit replaces that system with a UI data struct directly in the
IDProperty. If it's not used, the only cost is of a NULL pointer. Beyond
storing the description, name, and RNA subtype, derived structs are used
to store type specific UI data like min and max.
Note that this means that addons using (abusing) the `_RNA_UI` custom
property will have to be changed. A few places in the addons repository
will be changed after this commit with D9919.
**Before**
Before, first the _RNA_UI subgroup is retrieved the _RNA_UI group,
then the subgroup for the original property, then specific UI data
is accessed like any other IDProperty.
```
prop = rna_idprop_ui_prop_get(idproperties_owner, "prop_name", create=True)
prop["min"] = 1.0
```
**After**
After, the `id_properties_ui` function for RNA structs returns a python
object specifically for managing an IDProperty's UI data.
```
ui_data = idproperties_owner.id_properties_ui("prop_name")
ui_data.update(min=1.0)
```
In addition to `update`, there are now other functions:
- `as_dict`: Returns a dictionary of the property's UI data.
- `clear`: Removes the property's UI data.
- `update_from`: Copy UI data between properties,
even if they have different owners.
Differential Revision: https://developer.blender.org/D9697
2021-08-27 08:27:24 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-04 11:40:27 +02:00
|
|
|
static void sort_linked_ids(Main *bmain)
|
|
|
|
|
{
|
|
|
|
|
ListBase *lb;
|
|
|
|
|
FOREACH_MAIN_LISTBASE_BEGIN (bmain, lb) {
|
|
|
|
|
ListBase temp_list;
|
|
|
|
|
BLI_listbase_clear(&temp_list);
|
|
|
|
|
LISTBASE_FOREACH_MUTABLE (ID *, id, lb) {
|
|
|
|
|
if (ID_IS_LINKED(id)) {
|
|
|
|
|
BLI_remlink(lb, id);
|
|
|
|
|
BLI_addtail(&temp_list, id);
|
|
|
|
|
id_sort_by_name(&temp_list, id, NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
BLI_movelisttolist(lb, &temp_list);
|
|
|
|
|
}
|
|
|
|
|
FOREACH_MAIN_LISTBASE_END;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void assert_sorted_ids(Main *bmain)
|
|
|
|
|
{
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
ListBase *lb;
|
|
|
|
|
FOREACH_MAIN_LISTBASE_BEGIN (bmain, lb) {
|
|
|
|
|
ID *id_prev = NULL;
|
|
|
|
|
LISTBASE_FOREACH (ID *, id, lb) {
|
|
|
|
|
if (id_prev == NULL) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
BLI_assert(id_prev->lib != id->lib || BLI_strcasecmp(id_prev->name, id->name) < 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
FOREACH_MAIN_LISTBASE_END;
|
|
|
|
|
#else
|
|
|
|
|
UNUSED_VARS_NDEBUG(bmain);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-13 12:10:34 -04:00
|
|
|
static void move_vertex_group_names_to_object_data(Main *bmain)
|
|
|
|
|
{
|
|
|
|
|
LISTBASE_FOREACH (Object *, object, &bmain->objects) {
|
|
|
|
|
if (ELEM(object->type, OB_MESH, OB_LATTICE, OB_GPENCIL)) {
|
|
|
|
|
ListBase *new_defbase = BKE_object_defgroup_list_mutable(object);
|
|
|
|
|
|
2021-07-18 11:47:59 +03:00
|
|
|
/* Choose the longest vertex group name list among all linked duplicates. */
|
|
|
|
|
if (BLI_listbase_count(&object->defbase) < BLI_listbase_count(new_defbase)) {
|
|
|
|
|
BLI_freelistN(&object->defbase);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* Clear the list in case the it was already assigned from another object. */
|
|
|
|
|
BLI_freelistN(new_defbase);
|
|
|
|
|
*new_defbase = object->defbase;
|
2021-10-01 11:36:10 +02:00
|
|
|
BKE_object_defgroup_active_index_set(object, object->actdef);
|
2021-07-18 11:47:59 +03:00
|
|
|
}
|
2021-07-13 12:10:34 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-01 15:03:14 -03:00
|
|
|
static void do_versions_sequencer_speed_effect_recursive(Scene *scene, const ListBase *seqbase)
|
|
|
|
|
{
|
|
|
|
|
/* Old SpeedControlVars->flags. */
|
|
|
|
|
#define SEQ_SPEED_INTEGRATE (1 << 0)
|
|
|
|
|
#define SEQ_SPEED_COMPRESS_IPO_Y (1 << 2)
|
|
|
|
|
|
|
|
|
|
LISTBASE_FOREACH (Sequence *, seq, seqbase) {
|
|
|
|
|
if (seq->type == SEQ_TYPE_SPEED) {
|
|
|
|
|
SpeedControlVars *v = (SpeedControlVars *)seq->effectdata;
|
|
|
|
|
const char *substr = NULL;
|
|
|
|
|
float globalSpeed = v->globalSpeed;
|
|
|
|
|
if (seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) {
|
|
|
|
|
if (globalSpeed == 1.0f) {
|
|
|
|
|
v->speed_control_type = SEQ_SPEED_STRETCH;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
v->speed_control_type = SEQ_SPEED_MULTIPLY;
|
|
|
|
|
v->speed_fader = globalSpeed *
|
|
|
|
|
((float)seq->seq1->len /
|
|
|
|
|
max_ff((float)(seq->seq1->enddisp - seq->seq1->start), 1.0f));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (v->flags & SEQ_SPEED_INTEGRATE) {
|
|
|
|
|
v->speed_control_type = SEQ_SPEED_MULTIPLY;
|
|
|
|
|
v->speed_fader = seq->speed_fader * globalSpeed;
|
|
|
|
|
}
|
|
|
|
|
else if (v->flags & SEQ_SPEED_COMPRESS_IPO_Y) {
|
|
|
|
|
globalSpeed *= 100.0f;
|
|
|
|
|
v->speed_control_type = SEQ_SPEED_LENGTH;
|
|
|
|
|
v->speed_fader_length = seq->speed_fader * globalSpeed;
|
|
|
|
|
substr = "speed_length";
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
v->speed_control_type = SEQ_SPEED_FRAME_NUMBER;
|
|
|
|
|
v->speed_fader_frame_number = (int)(seq->speed_fader * globalSpeed);
|
|
|
|
|
substr = "speed_frame_number";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
v->flags &= ~(SEQ_SPEED_INTEGRATE | SEQ_SPEED_COMPRESS_IPO_Y);
|
|
|
|
|
|
|
|
|
|
if (substr || globalSpeed != 1.0f) {
|
|
|
|
|
FCurve *fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "speed_factor", 0, NULL);
|
|
|
|
|
if (fcu) {
|
|
|
|
|
if (globalSpeed != 1.0f) {
|
|
|
|
|
for (int i = 0; i < fcu->totvert; i++) {
|
|
|
|
|
BezTriple *bezt = &fcu->bezt[i];
|
|
|
|
|
bezt->vec[0][1] *= globalSpeed;
|
|
|
|
|
bezt->vec[1][1] *= globalSpeed;
|
|
|
|
|
bezt->vec[2][1] *= globalSpeed;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (substr) {
|
|
|
|
|
char *new_path = BLI_str_replaceN(fcu->rna_path, "speed_factor", substr);
|
|
|
|
|
MEM_freeN(fcu->rna_path);
|
|
|
|
|
fcu->rna_path = new_path;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (seq->type == SEQ_TYPE_META) {
|
|
|
|
|
do_versions_sequencer_speed_effect_recursive(scene, &seq->seqbase);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#undef SEQ_SPEED_INTEGRATE
|
|
|
|
|
#undef SEQ_SPEED_COMPRESS_IPO_Y
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-29 14:29:32 +02:00
|
|
|
static bool do_versions_sequencer_color_tags(Sequence *seq, void *UNUSED(user_data))
|
|
|
|
|
{
|
|
|
|
|
seq->color_tag = SEQUENCE_COLOR_NONE;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-15 23:13:31 +02:00
|
|
|
static bool do_versions_sequencer_color_balance_sop(Sequence *seq, void *UNUSED(user_data))
|
|
|
|
|
{
|
|
|
|
|
LISTBASE_FOREACH (SequenceModifierData *, smd, &seq->modifiers) {
|
|
|
|
|
if (smd->type == seqModifierType_ColorBalance) {
|
|
|
|
|
StripColorBalance *cb = &((ColorBalanceModifierData *)smd)->color_balance;
|
|
|
|
|
cb->method = SEQ_COLOR_BALANCE_METHOD_LIFTGAMMAGAIN;
|
|
|
|
|
for (int i = 0; i < 3; i++) {
|
|
|
|
|
copy_v3_fl(cb->slope, 1.0f);
|
|
|
|
|
copy_v3_fl(cb->offset, 1.0f);
|
|
|
|
|
copy_v3_fl(cb->power, 1.0f);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-28 11:36:28 -05:00
|
|
|
static bNodeLink *find_connected_link(bNodeTree *ntree, bNodeSocket *in_socket)
|
|
|
|
|
{
|
|
|
|
|
LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
|
|
|
|
|
if (link->tosock == in_socket) {
|
|
|
|
|
return link;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void add_realize_instances_before_socket(bNodeTree *ntree,
|
|
|
|
|
bNode *node,
|
|
|
|
|
bNodeSocket *geometry_socket)
|
|
|
|
|
{
|
|
|
|
|
BLI_assert(geometry_socket->type == SOCK_GEOMETRY);
|
|
|
|
|
bNodeLink *link = find_connected_link(ntree, geometry_socket);
|
|
|
|
|
if (link == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If the realize instances node is already before this socket, no need to continue. */
|
|
|
|
|
if (link->fromnode->type == GEO_NODE_REALIZE_INSTANCES) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bNode *realize_node = nodeAddStaticNode(NULL, ntree, GEO_NODE_REALIZE_INSTANCES);
|
|
|
|
|
realize_node->parent = node->parent;
|
|
|
|
|
realize_node->locx = node->locx - 100;
|
|
|
|
|
realize_node->locy = node->locy;
|
|
|
|
|
nodeAddLink(ntree, link->fromnode, link->fromsock, realize_node, realize_node->inputs.first);
|
|
|
|
|
link->fromnode = realize_node;
|
|
|
|
|
link->fromsock = realize_node->outputs.first;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* If a node used to realize instances implicitly and will no longer do so in 3.0, add a "Realize
|
|
|
|
|
* Instances" node in front of it to avoid changing behavior. Don't do this if the node will be
|
|
|
|
|
* replaced anyway though.
|
|
|
|
|
*/
|
|
|
|
|
static void version_geometry_nodes_add_realize_instance_nodes(bNodeTree *ntree)
|
|
|
|
|
{
|
|
|
|
|
LISTBASE_FOREACH_MUTABLE (bNode *, node, &ntree->nodes) {
|
|
|
|
|
if (ELEM(node->type,
|
2021-10-14 12:06:42 -05:00
|
|
|
GEO_NODE_CAPTURE_ATTRIBUTE,
|
2021-09-28 11:36:28 -05:00
|
|
|
GEO_NODE_SEPARATE_COMPONENTS,
|
|
|
|
|
GEO_NODE_CONVEX_HULL,
|
|
|
|
|
GEO_NODE_CURVE_LENGTH,
|
2021-10-14 12:06:42 -05:00
|
|
|
GEO_NODE_MESH_BOOLEAN,
|
|
|
|
|
GEO_NODE_FILLET_CURVE,
|
|
|
|
|
GEO_NODE_RESAMPLE_CURVE,
|
2021-09-28 11:36:28 -05:00
|
|
|
GEO_NODE_CURVE_TO_MESH,
|
2021-10-14 12:06:42 -05:00
|
|
|
GEO_NODE_TRIM_CURVE,
|
|
|
|
|
GEO_NODE_REPLACE_MATERIAL,
|
|
|
|
|
GEO_NODE_SUBDIVIDE_MESH,
|
2021-09-28 11:36:28 -05:00
|
|
|
GEO_NODE_TRIANGULATE)) {
|
|
|
|
|
bNodeSocket *geometry_socket = node->inputs.first;
|
|
|
|
|
add_realize_instances_before_socket(ntree, node, geometry_socket);
|
|
|
|
|
}
|
|
|
|
|
/* Also realize instances for the profile input of the curve to mesh node. */
|
|
|
|
|
if (node->type == GEO_NODE_CURVE_TO_MESH) {
|
2021-10-27 10:24:29 -05:00
|
|
|
bNodeSocket *profile_socket = (bNodeSocket *)BLI_findlink(&node->inputs, 1);
|
2021-09-28 11:36:28 -05:00
|
|
|
add_realize_instances_before_socket(ntree, node, profile_socket);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-19 08:39:10 -05:00
|
|
|
/**
|
|
|
|
|
* The geometry nodes modifier used to realize instances for the next modifier implicitly. Now it
|
|
|
|
|
* is done with the realize instances node. It also used to convert meshes to point clouds
|
|
|
|
|
* automatically, which is also now done with a specific node.
|
|
|
|
|
*/
|
|
|
|
|
static bNodeTree *add_realize_node_tree(Main *bmain)
|
|
|
|
|
{
|
|
|
|
|
bNodeTree *node_tree = ntreeAddTree(bmain, "Realize Instances 2.93 Legacy", "GeometryNodeTree");
|
|
|
|
|
|
|
|
|
|
ntreeAddSocketInterface(node_tree, SOCK_IN, "NodeSocketGeometry", "Geometry");
|
|
|
|
|
ntreeAddSocketInterface(node_tree, SOCK_OUT, "NodeSocketGeometry", "Geometry");
|
|
|
|
|
|
|
|
|
|
bNode *group_input = nodeAddStaticNode(NULL, node_tree, NODE_GROUP_INPUT);
|
|
|
|
|
group_input->locx = -400.0f;
|
|
|
|
|
bNode *group_output = nodeAddStaticNode(NULL, node_tree, NODE_GROUP_OUTPUT);
|
|
|
|
|
group_output->locx = 500.0f;
|
|
|
|
|
group_output->flag |= NODE_DO_OUTPUT;
|
|
|
|
|
|
|
|
|
|
bNode *join = nodeAddStaticNode(NULL, node_tree, GEO_NODE_JOIN_GEOMETRY);
|
|
|
|
|
join->locx = group_output->locx - 175.0f;
|
|
|
|
|
join->locy = group_output->locy;
|
|
|
|
|
bNode *conv = nodeAddStaticNode(NULL, node_tree, GEO_NODE_POINTS_TO_VERTICES);
|
|
|
|
|
conv->locx = join->locx - 175.0f;
|
|
|
|
|
conv->locy = join->locy - 70.0;
|
|
|
|
|
bNode *separate = nodeAddStaticNode(NULL, node_tree, GEO_NODE_SEPARATE_COMPONENTS);
|
|
|
|
|
separate->locx = join->locx - 350.0f;
|
|
|
|
|
separate->locy = join->locy + 50.0f;
|
|
|
|
|
bNode *realize = nodeAddStaticNode(NULL, node_tree, GEO_NODE_REALIZE_INSTANCES);
|
|
|
|
|
realize->locx = separate->locx - 200.0f;
|
|
|
|
|
realize->locy = join->locy;
|
|
|
|
|
|
|
|
|
|
nodeAddLink(node_tree, group_input, group_input->outputs.first, realize, realize->inputs.first);
|
|
|
|
|
nodeAddLink(node_tree, realize, realize->outputs.first, separate, separate->inputs.first);
|
|
|
|
|
nodeAddLink(node_tree, conv, conv->outputs.first, join, join->inputs.first);
|
|
|
|
|
nodeAddLink(node_tree, separate, BLI_findlink(&separate->outputs, 3), join, join->inputs.first);
|
|
|
|
|
nodeAddLink(node_tree, separate, BLI_findlink(&separate->outputs, 1), conv, conv->inputs.first);
|
|
|
|
|
nodeAddLink(node_tree, separate, BLI_findlink(&separate->outputs, 2), join, join->inputs.first);
|
|
|
|
|
nodeAddLink(node_tree, separate, separate->outputs.first, join, join->inputs.first);
|
|
|
|
|
nodeAddLink(node_tree, join, join->outputs.first, group_output, group_output->inputs.first);
|
|
|
|
|
|
|
|
|
|
LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
|
|
|
|
|
nodeSetSelected(node, false);
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-21 15:18:56 +01:00
|
|
|
version_socket_update_is_used(node_tree);
|
2021-10-19 08:39:10 -05:00
|
|
|
return node_tree;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-04 14:46:32 +02:00
|
|
|
void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports))
|
2021-04-20 17:08:31 +02:00
|
|
|
{
|
2021-05-04 14:46:32 +02:00
|
|
|
if (MAIN_VERSION_ATLEAST(bmain, 300, 0) && !MAIN_VERSION_ATLEAST(bmain, 300, 1)) {
|
|
|
|
|
/* Set zero user text objects to have a fake user. */
|
|
|
|
|
LISTBASE_FOREACH (Text *, text, &bmain->texts) {
|
|
|
|
|
if (text->id.us == 0) {
|
|
|
|
|
id_fake_user_set(&text->id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-05-14 11:22:02 +02:00
|
|
|
|
2021-06-04 11:40:27 +02:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 3)) {
|
|
|
|
|
sort_linked_ids(bmain);
|
|
|
|
|
assert_sorted_ids(bmain);
|
|
|
|
|
}
|
2021-06-25 07:57:24 +02:00
|
|
|
|
2021-06-04 11:40:27 +02:00
|
|
|
if (MAIN_VERSION_ATLEAST(bmain, 300, 3)) {
|
|
|
|
|
assert_sorted_ids(bmain);
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-13 12:10:34 -04:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 11)) {
|
|
|
|
|
move_vertex_group_names_to_object_data(bmain);
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-01 15:03:14 -03:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 13)) {
|
|
|
|
|
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
|
|
|
|
if (scene->ed != NULL) {
|
|
|
|
|
do_versions_sequencer_speed_effect_recursive(scene, &scene->ed->seqbase);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-10 09:30:36 +01:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 25)) {
|
|
|
|
|
version_node_socket_index_animdata(bmain, NTREE_SHADER, SH_NODE_BSDF_PRINCIPLED, 4, 2, 25);
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-27 11:30:52 +02:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 26)) {
|
2021-09-22 17:19:42 +02:00
|
|
|
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
|
|
|
|
ToolSettings *tool_settings = scene->toolsettings;
|
|
|
|
|
ImagePaintSettings *imapaint = &tool_settings->imapaint;
|
|
|
|
|
if (imapaint->canvas != NULL &&
|
|
|
|
|
ELEM(imapaint->canvas->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE)) {
|
|
|
|
|
imapaint->canvas = NULL;
|
|
|
|
|
}
|
|
|
|
|
if (imapaint->stencil != NULL &&
|
|
|
|
|
ELEM(imapaint->stencil->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE)) {
|
|
|
|
|
imapaint->stencil = NULL;
|
|
|
|
|
}
|
|
|
|
|
if (imapaint->clone != NULL &&
|
|
|
|
|
ELEM(imapaint->clone->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE)) {
|
|
|
|
|
imapaint->clone = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-09-27 11:30:52 +02:00
|
|
|
|
2021-09-22 17:19:42 +02:00
|
|
|
LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
|
2021-09-24 10:45:36 +02:00
|
|
|
if (brush->clone.image != NULL &&
|
|
|
|
|
ELEM(brush->clone.image->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE)) {
|
|
|
|
|
brush->clone.image = NULL;
|
2021-09-22 17:19:42 +02:00
|
|
|
}
|
|
|
|
|
}
|
2021-04-20 17:08:31 +02:00
|
|
|
}
|
2021-09-27 11:30:52 +02:00
|
|
|
|
2021-09-28 11:36:28 -05:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 28)) {
|
|
|
|
|
LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
|
|
|
|
|
if (ntree->type == NTREE_GEOMETRY) {
|
|
|
|
|
version_geometry_nodes_add_realize_instance_nodes(ntree);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-29 09:35:05 +02:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 30)) {
|
|
|
|
|
do_versions_idproperty_ui_data(bmain);
|
|
|
|
|
}
|
|
|
|
|
|
Geometry Nodes: Switch Node Fields Update
This update of the Switch node allows for field compatible types
to be switched through the node. This includes the following:
Float, Int, Bool, String, Vector, and Color
The remaining types are processed with the orginal code:
Geometry, Object, Collection, Texture, and Material
Because the old types require a diffent "switch" socket than the
field types, versioning for old files is included to move links
of those types to a new switch socket. Once fields of other types
are supported, this node can be updated to support them as well.
Differential Revision: https://developer.blender.org/D12642
2021-10-02 17:33:25 -05:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 32)) {
|
|
|
|
|
/* Update Switch Node Non-Fields switch input to Switch_001. */
|
|
|
|
|
LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
|
|
|
|
|
if (ntree->type != NTREE_GEOMETRY) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
|
|
|
|
|
if (link->tonode->type == GEO_NODE_SWITCH) {
|
|
|
|
|
if (STREQ(link->tosock->identifier, "Switch")) {
|
|
|
|
|
bNode *to_node = link->tonode;
|
|
|
|
|
|
|
|
|
|
uint8_t mode = ((NodeSwitch *)to_node->storage)->input_type;
|
|
|
|
|
if (ELEM(mode,
|
|
|
|
|
SOCK_GEOMETRY,
|
|
|
|
|
SOCK_OBJECT,
|
|
|
|
|
SOCK_COLLECTION,
|
|
|
|
|
SOCK_TEXTURE,
|
|
|
|
|
SOCK_MATERIAL)) {
|
|
|
|
|
link->tosock = link->tosock->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-10-08 14:30:08 +02:00
|
|
|
|
|
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 33)) {
|
|
|
|
|
/* This was missing from #move_vertex_group_names_to_object_data. */
|
|
|
|
|
LISTBASE_FOREACH (Object *, object, &bmain->objects) {
|
|
|
|
|
if (ELEM(object->type, OB_MESH, OB_LATTICE, OB_GPENCIL)) {
|
|
|
|
|
/* This uses the fact that the active vertex group index starts counting at 1. */
|
|
|
|
|
if (BKE_object_defgroup_active_index_get(object) == 0) {
|
|
|
|
|
BKE_object_defgroup_active_index_set(object, object->actdef);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-19 08:39:10 -05:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 35)) {
|
|
|
|
|
/* Add a new modifier to realize instances from previous modifiers.
|
|
|
|
|
* Previously that was done automatically by geometry nodes. */
|
|
|
|
|
bNodeTree *realize_instances_node_tree = NULL;
|
|
|
|
|
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
|
|
|
|
|
LISTBASE_FOREACH_MUTABLE (ModifierData *, md, &ob->modifiers) {
|
|
|
|
|
if (md->type != eModifierType_Nodes) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (md->next == NULL) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (md->next->type == eModifierType_Nodes) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
NodesModifierData *nmd = (NodesModifierData *)md;
|
|
|
|
|
if (nmd->node_group == NULL) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NodesModifierData *new_nmd = (NodesModifierData *)BKE_modifier_new(eModifierType_Nodes);
|
|
|
|
|
STRNCPY(new_nmd->modifier.name, "Realize Instances 2.93 Legacy");
|
|
|
|
|
BKE_modifier_unique_name(&ob->modifiers, &new_nmd->modifier);
|
|
|
|
|
BLI_insertlinkafter(&ob->modifiers, md, new_nmd);
|
|
|
|
|
if (realize_instances_node_tree == NULL) {
|
|
|
|
|
realize_instances_node_tree = add_realize_node_tree(bmain);
|
|
|
|
|
}
|
|
|
|
|
new_nmd->node_group = realize_instances_node_tree;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-21 11:51:56 -05:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 37)) {
|
|
|
|
|
LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
|
|
|
|
|
if (ntree->type == NTREE_GEOMETRY) {
|
|
|
|
|
LISTBASE_FOREACH_MUTABLE (bNode *, node, &ntree->nodes) {
|
|
|
|
|
if (node->type == GEO_NODE_BOUNDING_BOX) {
|
|
|
|
|
bNodeSocket *geometry_socket = node->inputs.first;
|
|
|
|
|
add_realize_instances_before_socket(ntree, node, geometry_socket);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-28 11:11:11 +01:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 301, 6)) {
|
2021-12-17 17:31:15 +01:00
|
|
|
{ /* Ensure driver variable names are unique within the driver. */
|
|
|
|
|
ID *id;
|
|
|
|
|
FOREACH_MAIN_ID_BEGIN (bmain, id) {
|
|
|
|
|
AnimData *adt = BKE_animdata_from_id(id);
|
|
|
|
|
if (adt == NULL) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
LISTBASE_FOREACH (FCurve *, fcu, &adt->drivers) {
|
|
|
|
|
ChannelDriver *driver = fcu->driver;
|
|
|
|
|
/* Ensure the uniqueness front to back. Given a list of identically
|
|
|
|
|
* named variables, the last one gets to keep its original name. This
|
|
|
|
|
* matches the evaluation order, and thus shouldn't change the evaluated
|
|
|
|
|
* value of the driver expression. */
|
|
|
|
|
LISTBASE_FOREACH (DriverVar *, dvar, &driver->variables) {
|
|
|
|
|
BLI_uniquename(&driver->variables,
|
|
|
|
|
dvar,
|
|
|
|
|
dvar->name,
|
|
|
|
|
'_',
|
|
|
|
|
offsetof(DriverVar, name),
|
|
|
|
|
sizeof(dvar->name));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
FOREACH_MAIN_ID_END;
|
|
|
|
|
}
|
UDIM: Support virtual filenames
This implements the design detailed in T92696 to support virtual
filenames for UDIM textures. Currently, the following 2 substitution
tokens are supported:
| Token | Meaning |
| ----- | ---- |
| <UDIM> | 1001 + u-tile + v-tile * 10 |
| <UVTILE> | Equivalent to u<u-tile + 1>_v<v-tile + 1> |
Example for u-tile of 3 and v-tile of 1:
filename.<UDIM>_ver0023.png --> filename.1014_ver0023.png
filename.<UVTILE>_ver0023.png --> filename.u4_v2_ver0023.png
For image loading, the existing workflow is unchanged. A user can select
one or more image files, belonging to one or more UDIM tile sets, and
have Blender load them all as it does today. Now the <UVTILE> format is
"guessed" just as the <UDIM> format was guessed before.
If guessing fails, the user can simply go into the Image Editor and type
the proper substitution in the filename. Once typing is complete,
Blender will reload the files and correctly fill the tiles. This
workflow is new as attempting to fix the guessing in current versions
did not really work, and the user was often stuck with a confusing
situation.
For image saving, the existing workflow is changed slightly. Currently,
when saving, a user has to be sure to type the filename of the first
tile (e.g. filename.1001.png) to save the entire UDIM set. The number
could differ if they start at a different tile etc. This is confusing.
Now, the user should type a filename containing the appropriate
substitution token. By default Blender will fill in a default name using
the <UDIM> token but the user is free to save out images using <UVTILE>
if they wish.
Differential Revision: https://developer.blender.org/D13057
2021-12-30 22:06:23 -08:00
|
|
|
|
|
|
|
|
/* Ensure tiled image sources contain a UDIM token. */
|
|
|
|
|
LISTBASE_FOREACH (Image *, ima, &bmain->images) {
|
|
|
|
|
if (ima->source == IMA_SRC_TILED) {
|
2022-01-07 15:13:31 +11:00
|
|
|
char *filename = (char *)BLI_path_basename(ima->filepath);
|
|
|
|
|
BKE_image_ensure_tile_token(filename);
|
UDIM: Support virtual filenames
This implements the design detailed in T92696 to support virtual
filenames for UDIM textures. Currently, the following 2 substitution
tokens are supported:
| Token | Meaning |
| ----- | ---- |
| <UDIM> | 1001 + u-tile + v-tile * 10 |
| <UVTILE> | Equivalent to u<u-tile + 1>_v<v-tile + 1> |
Example for u-tile of 3 and v-tile of 1:
filename.<UDIM>_ver0023.png --> filename.1014_ver0023.png
filename.<UVTILE>_ver0023.png --> filename.u4_v2_ver0023.png
For image loading, the existing workflow is unchanged. A user can select
one or more image files, belonging to one or more UDIM tile sets, and
have Blender load them all as it does today. Now the <UVTILE> format is
"guessed" just as the <UDIM> format was guessed before.
If guessing fails, the user can simply go into the Image Editor and type
the proper substitution in the filename. Once typing is complete,
Blender will reload the files and correctly fill the tiles. This
workflow is new as attempting to fix the guessing in current versions
did not really work, and the user was often stuck with a confusing
situation.
For image saving, the existing workflow is changed slightly. Currently,
when saving, a user has to be sure to type the filename of the first
tile (e.g. filename.1001.png) to save the entire UDIM set. The number
could differ if they start at a different tile etc. This is confusing.
Now, the user should type a filename containing the appropriate
substitution token. By default Blender will fill in a default name using
the <UDIM> token but the user is free to save out images using <UVTILE>
if they wish.
Differential Revision: https://developer.blender.org/D13057
2021-12-30 22:06:23 -08:00
|
|
|
}
|
|
|
|
|
}
|
2021-09-27 11:30:52 +02:00
|
|
|
}
|
2022-01-28 11:11:11 +01:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Versioning code until next subversion bump goes here.
|
|
|
|
|
*
|
|
|
|
|
* \note Be sure to check when bumping the version:
|
|
|
|
|
* - #blo_do_versions_300 in this file.
|
|
|
|
|
* - "versioning_userdef.c", #blo_do_versions_userdef
|
|
|
|
|
* - "versioning_userdef.c", #do_versions_theme
|
|
|
|
|
*
|
|
|
|
|
* \note Keep this message at the bottom of the function.
|
|
|
|
|
*/
|
|
|
|
|
{
|
|
|
|
|
/* Keep this block, even when empty. */
|
|
|
|
|
}
|
2021-04-20 17:08:31 +02:00
|
|
|
}
|
|
|
|
|
|
2021-05-28 12:17:04 -04:00
|
|
|
static void version_switch_node_input_prefix(Main *bmain)
|
|
|
|
|
{
|
|
|
|
|
FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
|
|
|
|
|
if (ntree->type == NTREE_GEOMETRY) {
|
|
|
|
|
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
|
|
|
|
|
if (node->type == GEO_NODE_SWITCH) {
|
|
|
|
|
LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
|
|
|
|
|
/* Skip the "switch" socket. */
|
|
|
|
|
if (socket == node->inputs.first) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
strcpy(socket->name, socket->name[0] == 'A' ? "False" : "True");
|
|
|
|
|
|
|
|
|
|
/* Replace "A" and "B", but keep the unique number suffix at the end. */
|
|
|
|
|
char number_suffix[8];
|
|
|
|
|
BLI_strncpy(number_suffix, socket->identifier + 1, sizeof(number_suffix));
|
|
|
|
|
strcpy(socket->identifier, socket->name);
|
|
|
|
|
strcat(socket->identifier, number_suffix);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
FOREACH_NODETREE_END;
|
|
|
|
|
}
|
|
|
|
|
|
Armature: add B-Bone Y scale channel and extra flag fields to DNA.
In addition to the base bone transformation itself, B-Bones have
controls that affect transformation of its segments. For rotation
the features are quite complete, allowing to both reorient the
Bezier handles via properties, and to control them using custom
handle bones. However for scaling there are two deficiencies.
First, there are only X and Y scale factors (actually X and Z),
while lengthwise all segments have the same scaling. The ease
option merely affects the shape of the curve, and does not cause
actual scaling.
Second, scaling can only be controlled via properties, thus
requiring up to 6 drivers per joint between B-Bones to transfer
scaling factors from the handle bone. This is very inefficient.
Finally, the Z channels are confusingly called Y.
This commit adds a B-Bone Y Scale channel and extra B-Bone flag
fields to DNA with appropriate versioning (including for F-Curves
and drivers) in preparation to addressing these limitations.
Functionality is not changed, so the new fields are not used
until the following commits.
Differential Revision: https://developer.blender.org/D9870
2020-12-11 19:17:39 +03:00
|
|
|
static bool replace_bbone_len_scale_rnapath(char **p_old_path, int *p_index)
|
|
|
|
|
{
|
|
|
|
|
char *old_path = *p_old_path;
|
|
|
|
|
|
|
|
|
|
if (old_path == NULL) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int len = strlen(old_path);
|
|
|
|
|
|
|
|
|
|
if (BLI_str_endswith(old_path, ".bbone_curveiny") ||
|
|
|
|
|
BLI_str_endswith(old_path, ".bbone_curveouty")) {
|
|
|
|
|
old_path[len - 1] = 'z';
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (BLI_str_endswith(old_path, ".bbone_scaleinx") ||
|
|
|
|
|
BLI_str_endswith(old_path, ".bbone_scaleiny") ||
|
|
|
|
|
BLI_str_endswith(old_path, ".bbone_scaleoutx") ||
|
|
|
|
|
BLI_str_endswith(old_path, ".bbone_scaleouty")) {
|
|
|
|
|
int index = (old_path[len - 1] == 'y' ? 2 : 0);
|
|
|
|
|
|
|
|
|
|
old_path[len - 1] = 0;
|
|
|
|
|
|
|
|
|
|
if (p_index) {
|
|
|
|
|
*p_index = index;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
*p_old_path = BLI_sprintfN("%s[%d]", old_path, index);
|
|
|
|
|
MEM_freeN(old_path);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void do_version_bbone_len_scale_fcurve_fix(FCurve *fcu)
|
|
|
|
|
{
|
|
|
|
|
/* Update driver variable paths. */
|
|
|
|
|
if (fcu->driver) {
|
|
|
|
|
LISTBASE_FOREACH (DriverVar *, dvar, &fcu->driver->variables) {
|
|
|
|
|
DRIVER_TARGETS_LOOPER_BEGIN (dvar) {
|
|
|
|
|
replace_bbone_len_scale_rnapath(&dtar->rna_path, NULL);
|
|
|
|
|
}
|
|
|
|
|
DRIVER_TARGETS_LOOPER_END;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Update F-Curve's path. */
|
|
|
|
|
replace_bbone_len_scale_rnapath(&fcu->rna_path, &fcu->array_index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void do_version_bbone_len_scale_animdata_cb(ID *UNUSED(id),
|
|
|
|
|
AnimData *adt,
|
|
|
|
|
void *UNUSED(wrapper_data))
|
|
|
|
|
{
|
|
|
|
|
LISTBASE_FOREACH_MUTABLE (FCurve *, fcu, &adt->drivers) {
|
|
|
|
|
do_version_bbone_len_scale_fcurve_fix(fcu);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void do_version_bones_bbone_len_scale(ListBase *lb)
|
|
|
|
|
{
|
|
|
|
|
LISTBASE_FOREACH (Bone *, bone, lb) {
|
|
|
|
|
if (bone->flag & BONE_ADD_PARENT_END_ROLL) {
|
|
|
|
|
bone->bbone_flag |= BBONE_ADD_PARENT_END_ROLL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
copy_v3_fl3(bone->scale_in, bone->scale_in_x, 1.0f, bone->scale_in_z);
|
|
|
|
|
copy_v3_fl3(bone->scale_out, bone->scale_out_x, 1.0f, bone->scale_out_z);
|
|
|
|
|
|
|
|
|
|
do_version_bones_bbone_len_scale(&bone->childbase);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-05 17:17:15 +02:00
|
|
|
static void do_version_constraints_spline_ik_joint_bindings(ListBase *lb)
|
|
|
|
|
{
|
|
|
|
|
/* Binding array data could be freed without properly resetting its size data. */
|
|
|
|
|
LISTBASE_FOREACH (bConstraint *, con, lb) {
|
|
|
|
|
if (con->type == CONSTRAINT_TYPE_SPLINEIK) {
|
|
|
|
|
bSplineIKConstraint *data = (bSplineIKConstraint *)con->data;
|
|
|
|
|
if (data->points == NULL) {
|
|
|
|
|
data->numpoints = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-29 22:08:57 -05:00
|
|
|
static bNodeSocket *do_version_replace_float_size_with_vector(bNodeTree *ntree,
|
|
|
|
|
bNode *node,
|
|
|
|
|
bNodeSocket *socket)
|
|
|
|
|
{
|
|
|
|
|
const bNodeSocketValueFloat *socket_value = (const bNodeSocketValueFloat *)socket->default_value;
|
|
|
|
|
const float old_value = socket_value->value;
|
|
|
|
|
nodeRemoveSocket(ntree, node, socket);
|
|
|
|
|
bNodeSocket *new_socket = nodeAddSocket(
|
|
|
|
|
ntree, node, SOCK_IN, nodeStaticSocketType(SOCK_VECTOR, PROP_TRANSLATION), "Size", "Size");
|
|
|
|
|
bNodeSocketValueVector *value_vector = (bNodeSocketValueVector *)new_socket->default_value;
|
|
|
|
|
copy_v3_fl(value_vector->value, old_value);
|
|
|
|
|
return new_socket;
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-21 09:38:30 +02:00
|
|
|
static bool seq_transform_origin_set(Sequence *seq, void *UNUSED(user_data))
|
|
|
|
|
{
|
|
|
|
|
StripTransform *transform = seq->strip->transform;
|
|
|
|
|
if (seq->strip->transform != NULL) {
|
|
|
|
|
transform->origin[0] = transform->origin[1] = 0.5f;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2021-09-10 10:34:49 -05:00
|
|
|
|
2022-02-07 10:31:39 +01:00
|
|
|
static bool seq_transform_filter_set(Sequence *seq, void *UNUSED(user_data))
|
|
|
|
|
{
|
|
|
|
|
StripTransform *transform = seq->strip->transform;
|
|
|
|
|
if (seq->strip->transform != NULL) {
|
|
|
|
|
transform->filter = SEQ_TRANSFORM_FILTER_BILINEAR;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
static void do_version_subsurface_methods(bNode *node)
|
|
|
|
|
{
|
|
|
|
|
if (node->type == SH_NODE_SUBSURFACE_SCATTERING) {
|
2021-10-07 17:27:22 +02:00
|
|
|
if (!ELEM(node->custom1, SHD_SUBSURFACE_BURLEY, SHD_SUBSURFACE_RANDOM_WALK)) {
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
node->custom1 = SHD_SUBSURFACE_RANDOM_WALK_FIXED_RADIUS;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (node->type == SH_NODE_BSDF_PRINCIPLED) {
|
2021-10-07 17:27:22 +02:00
|
|
|
if (!ELEM(node->custom2, SHD_SUBSURFACE_BURLEY, SHD_SUBSURFACE_RANDOM_WALK)) {
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
node->custom2 = SHD_SUBSURFACE_RANDOM_WALK_FIXED_RADIUS;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-21 12:42:47 -05:00
|
|
|
static void version_geometry_nodes_add_attribute_input_settings(NodesModifierData *nmd)
|
|
|
|
|
{
|
|
|
|
|
/* Before versioning the properties, make sure it hasn't been done already. */
|
|
|
|
|
LISTBASE_FOREACH (const IDProperty *, property, &nmd->settings.properties->data.group) {
|
|
|
|
|
if (strstr(property->name, "_use_attribute") || strstr(property->name, "_attribute_name")) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LISTBASE_FOREACH_MUTABLE (IDProperty *, property, &nmd->settings.properties->data.group) {
|
|
|
|
|
if (!ELEM(property->type, IDP_FLOAT, IDP_INT, IDP_ARRAY)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (strstr(property->name, "_use_attribute") || strstr(property->name, "_attribute_name")) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char use_attribute_prop_name[MAX_IDPROP_NAME];
|
|
|
|
|
BLI_snprintf(use_attribute_prop_name,
|
|
|
|
|
sizeof(use_attribute_prop_name),
|
|
|
|
|
"%s%s",
|
|
|
|
|
property->name,
|
|
|
|
|
"_use_attribute");
|
|
|
|
|
|
|
|
|
|
IDPropertyTemplate idprop = {0};
|
|
|
|
|
IDProperty *use_attribute_prop = IDP_New(IDP_INT, &idprop, use_attribute_prop_name);
|
|
|
|
|
IDP_AddToGroup(nmd->settings.properties, use_attribute_prop);
|
|
|
|
|
|
|
|
|
|
char attribute_name_prop_name[MAX_IDPROP_NAME];
|
|
|
|
|
BLI_snprintf(attribute_name_prop_name,
|
|
|
|
|
sizeof(attribute_name_prop_name),
|
|
|
|
|
"%s%s",
|
|
|
|
|
property->name,
|
|
|
|
|
"_attribute_name");
|
|
|
|
|
|
|
|
|
|
IDProperty *attribute_prop = IDP_New(IDP_STRING, &idprop, attribute_name_prop_name);
|
|
|
|
|
IDP_AddToGroup(nmd->settings.properties, attribute_prop);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-21 21:45:14 +03:00
|
|
|
/* Copy of the function before the fixes. */
|
|
|
|
|
static void legacy_vec_roll_to_mat3_normalized(const float nor[3],
|
|
|
|
|
const float roll,
|
|
|
|
|
float r_mat[3][3])
|
|
|
|
|
{
|
|
|
|
|
const float SAFE_THRESHOLD = 1.0e-5f; /* theta above this value has good enough precision. */
|
|
|
|
|
const float CRITICAL_THRESHOLD = 1.0e-9f; /* above this is safe under certain conditions. */
|
|
|
|
|
const float THRESHOLD_SQUARED = CRITICAL_THRESHOLD * CRITICAL_THRESHOLD;
|
|
|
|
|
|
|
|
|
|
const float x = nor[0];
|
|
|
|
|
const float y = nor[1];
|
|
|
|
|
const float z = nor[2];
|
|
|
|
|
|
|
|
|
|
const float theta = 1.0f + y; /* remapping Y from [-1,+1] to [0,2]. */
|
2022-01-14 10:47:50 +11:00
|
|
|
const float theta_alt = x * x + z * z; /* Helper value for matrix calculations. */
|
2020-11-21 21:45:14 +03:00
|
|
|
float rMatrix[3][3], bMatrix[3][3];
|
|
|
|
|
|
|
|
|
|
BLI_ASSERT_UNIT_V3(nor);
|
|
|
|
|
|
|
|
|
|
/* When theta is close to zero (nor is aligned close to negative Y Axis),
|
|
|
|
|
* we have to check we do have non-null X/Z components as well.
|
|
|
|
|
* Also, due to float precision errors, nor can be (0.0, -0.99999994, 0.0) which results
|
|
|
|
|
* in theta being close to zero. This will cause problems when theta is used as divisor.
|
|
|
|
|
*/
|
|
|
|
|
if (theta > SAFE_THRESHOLD || (theta > CRITICAL_THRESHOLD && theta_alt > THRESHOLD_SQUARED)) {
|
|
|
|
|
/* nor is *not* aligned to negative Y-axis (0,-1,0). */
|
|
|
|
|
|
|
|
|
|
bMatrix[0][1] = -x;
|
|
|
|
|
bMatrix[1][0] = x;
|
|
|
|
|
bMatrix[1][1] = y;
|
|
|
|
|
bMatrix[1][2] = z;
|
|
|
|
|
bMatrix[2][1] = -z;
|
|
|
|
|
|
|
|
|
|
if (theta > SAFE_THRESHOLD) {
|
|
|
|
|
/* nor differs significantly from negative Y axis (0,-1,0): apply the general case. */
|
|
|
|
|
bMatrix[0][0] = 1 - x * x / theta;
|
|
|
|
|
bMatrix[2][2] = 1 - z * z / theta;
|
|
|
|
|
bMatrix[2][0] = bMatrix[0][2] = -x * z / theta;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* nor is close to negative Y axis (0,-1,0): apply the special case. */
|
|
|
|
|
bMatrix[0][0] = (x + z) * (x - z) / -theta_alt;
|
|
|
|
|
bMatrix[2][2] = -bMatrix[0][0];
|
|
|
|
|
bMatrix[2][0] = bMatrix[0][2] = 2.0f * x * z / theta_alt;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* nor is very close to negative Y axis (0,-1,0): use simple symmetry by Z axis. */
|
|
|
|
|
unit_m3(bMatrix);
|
|
|
|
|
bMatrix[0][0] = bMatrix[1][1] = -1.0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Make Roll matrix */
|
|
|
|
|
axis_angle_normalized_to_mat3(rMatrix, nor, roll);
|
|
|
|
|
|
|
|
|
|
/* Combine and output result */
|
|
|
|
|
mul_m3_m3m3(r_mat, rMatrix, bMatrix);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void correct_bone_roll_value(const float head[3],
|
|
|
|
|
const float tail[3],
|
|
|
|
|
const float check_x_axis[3],
|
|
|
|
|
const float check_y_axis[3],
|
|
|
|
|
float *r_roll)
|
|
|
|
|
{
|
|
|
|
|
const float SAFE_THRESHOLD = 1.0e-5f;
|
|
|
|
|
float vec[3], bone_mat[3][3], vec2[3];
|
|
|
|
|
|
|
|
|
|
/* Compute the Y axis vector. */
|
|
|
|
|
sub_v3_v3v3(vec, tail, head);
|
|
|
|
|
normalize_v3(vec);
|
|
|
|
|
|
|
|
|
|
/* Only correct when in the danger zone. */
|
|
|
|
|
if (1.0f + vec[1] < SAFE_THRESHOLD * 2 && (vec[0] || vec[2])) {
|
|
|
|
|
/* Use the armature matrix to double-check if adjustment is needed.
|
|
|
|
|
* This should minimize issues if the file is bounced back and forth between
|
|
|
|
|
* 2.92 and 2.91, provided Edit Mode isn't entered on the armature in 2.91. */
|
|
|
|
|
vec_roll_to_mat3(vec, *r_roll, bone_mat);
|
|
|
|
|
|
2021-10-21 19:27:30 +03:00
|
|
|
UNUSED_VARS_NDEBUG(check_y_axis);
|
2020-11-21 21:45:14 +03:00
|
|
|
BLI_assert(dot_v3v3(bone_mat[1], check_y_axis) > 0.999f);
|
|
|
|
|
|
|
|
|
|
if (dot_v3v3(bone_mat[0], check_x_axis) < 0.999f) {
|
|
|
|
|
/* Recompute roll using legacy code to interpret the old value. */
|
|
|
|
|
legacy_vec_roll_to_mat3_normalized(vec, *r_roll, bone_mat);
|
|
|
|
|
mat3_to_vec_roll(bone_mat, vec2, r_roll);
|
2021-10-22 17:17:21 +03:00
|
|
|
BLI_assert(compare_v3v3(vec, vec2, 0.001f));
|
2020-11-21 21:45:14 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Update the armature Bone roll fields for bones very close to -Y direction. */
|
|
|
|
|
static void do_version_bones_roll(ListBase *lb)
|
|
|
|
|
{
|
|
|
|
|
LISTBASE_FOREACH (Bone *, bone, lb) {
|
|
|
|
|
/* Parent-relative orientation (used for posing). */
|
|
|
|
|
correct_bone_roll_value(
|
|
|
|
|
bone->head, bone->tail, bone->bone_mat[0], bone->bone_mat[1], &bone->roll);
|
|
|
|
|
|
|
|
|
|
/* Absolute orientation (used for Edit mode). */
|
|
|
|
|
correct_bone_roll_value(
|
|
|
|
|
bone->arm_head, bone->arm_tail, bone->arm_mat[0], bone->arm_mat[1], &bone->arm_roll);
|
|
|
|
|
|
|
|
|
|
do_version_bones_roll(&bone->childbase);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-25 11:37:45 +02:00
|
|
|
static void version_geometry_nodes_set_position_node_offset(bNodeTree *ntree)
|
|
|
|
|
{
|
|
|
|
|
/* Add the new Offset socket. */
|
|
|
|
|
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
|
|
|
|
|
if (node->type != GEO_NODE_SET_POSITION) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2021-10-25 13:29:42 +02:00
|
|
|
if (BLI_listbase_count(&node->inputs) < 4) {
|
|
|
|
|
/* The offset socket didn't exist in the file yet. */
|
|
|
|
|
return;
|
|
|
|
|
}
|
2021-10-25 11:37:45 +02:00
|
|
|
bNodeSocket *old_offset_socket = BLI_findlink(&node->inputs, 3);
|
|
|
|
|
if (old_offset_socket->type == SOCK_VECTOR) {
|
|
|
|
|
/* Versioning happened already. */
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
/* Change identifier of old socket, so that the there is no name collision. */
|
|
|
|
|
STRNCPY(old_offset_socket->identifier, "Offset_old");
|
|
|
|
|
nodeAddStaticSocket(ntree, node, SOCK_IN, SOCK_VECTOR, PROP_TRANSLATION, "Offset", "Offset");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Relink links that were connected to Position while Offset was enabled. */
|
|
|
|
|
LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
|
|
|
|
|
if (link->tonode->type != GEO_NODE_SET_POSITION) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (!STREQ(link->tosock->identifier, "Position")) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
bNodeSocket *old_offset_socket = BLI_findlink(&link->tonode->inputs, 3);
|
|
|
|
|
/* This assumes that the offset is not linked to something else. That seems to be a reasonable
|
|
|
|
|
* assumption, because the node is probably only ever used in one or the other mode. */
|
|
|
|
|
const bool offset_enabled =
|
|
|
|
|
((bNodeSocketValueBoolean *)old_offset_socket->default_value)->value;
|
|
|
|
|
if (offset_enabled) {
|
|
|
|
|
/* Relink to new offset socket. */
|
|
|
|
|
link->tosock = old_offset_socket->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Remove old Offset socket. */
|
|
|
|
|
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
|
|
|
|
|
if (node->type != GEO_NODE_SET_POSITION) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
bNodeSocket *old_offset_socket = BLI_findlink(&node->inputs, 3);
|
|
|
|
|
nodeRemoveSocket(ntree, node, old_offset_socket);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-12 12:22:43 -06:00
|
|
|
static void version_node_tree_socket_id_delim(bNodeTree *ntree)
|
|
|
|
|
{
|
|
|
|
|
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
|
|
|
|
|
LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
|
|
|
|
|
version_node_socket_id_delim(socket);
|
|
|
|
|
}
|
|
|
|
|
LISTBASE_FOREACH (bNodeSocket *, socket, &node->outputs) {
|
|
|
|
|
version_node_socket_id_delim(socket);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-19 06:10:26 +01:00
|
|
|
static bool version_fix_seq_meta_range(Sequence *seq, void *user_data)
|
|
|
|
|
{
|
|
|
|
|
Scene *scene = (Scene *)user_data;
|
|
|
|
|
if (seq->type == SEQ_TYPE_META) {
|
|
|
|
|
SEQ_time_update_meta_strip_range(scene, seq);
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-19 09:33:52 +01:00
|
|
|
/* Those `version_liboverride_rnacollections_*` functions mimic the old, pre-3.0 code to find
|
|
|
|
|
* anchor and source items in the given list of modifiers, constraints etc., using only the
|
|
|
|
|
* `subitem_local` data of the override property operation.
|
|
|
|
|
*
|
|
|
|
|
* Then they convert it into the new, proper `subitem_reference` data for the anchor, and
|
|
|
|
|
* `subitem_local` for the source.
|
|
|
|
|
*
|
|
|
|
|
* NOTE: Here only the stored override ID is available, unlike in the `override_apply` functions.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
static void version_liboverride_rnacollections_insertion_object_constraints(
|
|
|
|
|
ListBase *constraints, IDOverrideLibraryProperty *op)
|
|
|
|
|
{
|
|
|
|
|
LISTBASE_FOREACH_MUTABLE (IDOverrideLibraryPropertyOperation *, opop, &op->operations) {
|
|
|
|
|
if (opop->operation != IDOVERRIDE_LIBRARY_OP_INSERT_AFTER) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
bConstraint *constraint_anchor = BLI_listbase_string_or_index_find(constraints,
|
|
|
|
|
opop->subitem_local_name,
|
|
|
|
|
offsetof(bConstraint, name),
|
|
|
|
|
opop->subitem_local_index);
|
2021-11-23 14:33:26 +01:00
|
|
|
bConstraint *constraint_src = constraint_anchor != NULL ? constraint_anchor->next :
|
|
|
|
|
constraints->first;
|
|
|
|
|
|
|
|
|
|
if (constraint_src == NULL) {
|
2021-11-19 09:33:52 +01:00
|
|
|
/* Invalid case, just remove that override property operation. */
|
2021-11-23 14:33:26 +01:00
|
|
|
CLOG_ERROR(&LOG, "Could not find source constraint in stored override data");
|
2021-11-19 09:33:52 +01:00
|
|
|
BKE_lib_override_library_property_operation_delete(op, opop);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2021-11-23 14:33:26 +01:00
|
|
|
|
2021-11-19 09:33:52 +01:00
|
|
|
opop->subitem_reference_name = opop->subitem_local_name;
|
|
|
|
|
opop->subitem_local_name = BLI_strdup(constraint_src->name);
|
|
|
|
|
opop->subitem_reference_index = opop->subitem_local_index;
|
|
|
|
|
opop->subitem_local_index++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void version_liboverride_rnacollections_insertion_object(Object *object)
|
|
|
|
|
{
|
|
|
|
|
IDOverrideLibrary *liboverride = object->id.override_library;
|
|
|
|
|
IDOverrideLibraryProperty *op;
|
|
|
|
|
|
|
|
|
|
op = BKE_lib_override_library_property_find(liboverride, "modifiers");
|
|
|
|
|
if (op != NULL) {
|
|
|
|
|
LISTBASE_FOREACH_MUTABLE (IDOverrideLibraryPropertyOperation *, opop, &op->operations) {
|
|
|
|
|
if (opop->operation != IDOVERRIDE_LIBRARY_OP_INSERT_AFTER) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
ModifierData *mod_anchor = BLI_listbase_string_or_index_find(&object->modifiers,
|
|
|
|
|
opop->subitem_local_name,
|
|
|
|
|
offsetof(ModifierData, name),
|
|
|
|
|
opop->subitem_local_index);
|
2021-11-23 14:33:26 +01:00
|
|
|
ModifierData *mod_src = mod_anchor != NULL ? mod_anchor->next : object->modifiers.first;
|
|
|
|
|
|
|
|
|
|
if (mod_src == NULL) {
|
2021-11-19 09:33:52 +01:00
|
|
|
/* Invalid case, just remove that override property operation. */
|
2021-11-23 14:33:26 +01:00
|
|
|
CLOG_ERROR(&LOG, "Could not find source modifier in stored override data");
|
2021-11-19 09:33:52 +01:00
|
|
|
BKE_lib_override_library_property_operation_delete(op, opop);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2021-11-23 14:33:26 +01:00
|
|
|
|
2021-11-19 09:33:52 +01:00
|
|
|
opop->subitem_reference_name = opop->subitem_local_name;
|
|
|
|
|
opop->subitem_local_name = BLI_strdup(mod_src->name);
|
|
|
|
|
opop->subitem_reference_index = opop->subitem_local_index;
|
|
|
|
|
opop->subitem_local_index++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
op = BKE_lib_override_library_property_find(liboverride, "grease_pencil_modifiers");
|
|
|
|
|
if (op != NULL) {
|
|
|
|
|
LISTBASE_FOREACH_MUTABLE (IDOverrideLibraryPropertyOperation *, opop, &op->operations) {
|
|
|
|
|
if (opop->operation != IDOVERRIDE_LIBRARY_OP_INSERT_AFTER) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
GpencilModifierData *gp_mod_anchor = BLI_listbase_string_or_index_find(
|
|
|
|
|
&object->greasepencil_modifiers,
|
|
|
|
|
opop->subitem_local_name,
|
|
|
|
|
offsetof(GpencilModifierData, name),
|
|
|
|
|
opop->subitem_local_index);
|
2021-11-23 14:33:26 +01:00
|
|
|
GpencilModifierData *gp_mod_src = gp_mod_anchor != NULL ?
|
|
|
|
|
gp_mod_anchor->next :
|
|
|
|
|
object->greasepencil_modifiers.first;
|
|
|
|
|
|
|
|
|
|
if (gp_mod_src == NULL) {
|
2021-11-19 09:33:52 +01:00
|
|
|
/* Invalid case, just remove that override property operation. */
|
2021-11-23 14:33:26 +01:00
|
|
|
CLOG_ERROR(&LOG, "Could not find source GP modifier in stored override data");
|
2021-11-19 09:33:52 +01:00
|
|
|
BKE_lib_override_library_property_operation_delete(op, opop);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2021-11-23 14:33:26 +01:00
|
|
|
|
2021-11-19 09:33:52 +01:00
|
|
|
opop->subitem_reference_name = opop->subitem_local_name;
|
|
|
|
|
opop->subitem_local_name = BLI_strdup(gp_mod_src->name);
|
|
|
|
|
opop->subitem_reference_index = opop->subitem_local_index;
|
|
|
|
|
opop->subitem_local_index++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
op = BKE_lib_override_library_property_find(liboverride, "constraints");
|
|
|
|
|
if (op != NULL) {
|
|
|
|
|
version_liboverride_rnacollections_insertion_object_constraints(&object->constraints, op);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (object->pose != NULL) {
|
|
|
|
|
LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
|
|
|
|
|
char rna_path[FILE_MAXFILE];
|
|
|
|
|
BLI_snprintf(rna_path, sizeof(rna_path), "pose.bones[\"%s\"].constraints", pchan->name);
|
|
|
|
|
op = BKE_lib_override_library_property_find(liboverride, rna_path);
|
|
|
|
|
if (op != NULL) {
|
|
|
|
|
version_liboverride_rnacollections_insertion_object_constraints(&pchan->constraints, op);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void version_liboverride_rnacollections_insertion_animdata(ID *id)
|
|
|
|
|
{
|
|
|
|
|
AnimData *anim_data = BKE_animdata_from_id(id);
|
|
|
|
|
if (anim_data == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IDOverrideLibrary *liboverride = id->override_library;
|
|
|
|
|
IDOverrideLibraryProperty *op;
|
|
|
|
|
|
|
|
|
|
op = BKE_lib_override_library_property_find(liboverride, "animation_data.nla_tracks");
|
|
|
|
|
if (op != NULL) {
|
|
|
|
|
LISTBASE_FOREACH (IDOverrideLibraryPropertyOperation *, opop, &op->operations) {
|
|
|
|
|
if (opop->operation != IDOVERRIDE_LIBRARY_OP_INSERT_AFTER) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
/* NLA tracks are only referenced by index, which limits possibilities, basically they are
|
|
|
|
|
* always added at the end of the list, see #rna_NLA_tracks_override_apply.
|
|
|
|
|
*
|
|
|
|
|
* This makes things simple here. */
|
|
|
|
|
opop->subitem_reference_name = opop->subitem_local_name;
|
|
|
|
|
opop->subitem_local_name = NULL;
|
|
|
|
|
opop->subitem_reference_index = opop->subitem_local_index;
|
|
|
|
|
opop->subitem_local_index++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-20 17:08:31 +02:00
|
|
|
/* NOLINTNEXTLINE: readability-function-size */
|
2021-04-22 16:33:37 +10:00
|
|
|
void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
2021-04-20 17:08:31 +02:00
|
|
|
{
|
2022-03-10 18:33:04 -03:00
|
|
|
/* The #SCE_SNAP_SEQ flag has been removed in favor of the #SCE_SNAP which can be used for each
|
|
|
|
|
* snap_flag member individually. */
|
2022-03-11 09:27:37 +11:00
|
|
|
enum { SCE_SNAP_SEQ = (1 << 7) };
|
2022-03-10 18:33:04 -03:00
|
|
|
|
2021-05-04 14:46:32 +02:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 1)) {
|
2021-04-22 16:33:37 +10:00
|
|
|
/* Set default value for the new bisect_threshold parameter in the mirror modifier. */
|
|
|
|
|
if (!DNA_struct_elem_find(fd->filesdna, "MirrorModifierData", "float", "bisect_threshold")) {
|
|
|
|
|
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
|
|
|
|
|
LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
|
|
|
|
|
if (md->type == eModifierType_Mirror) {
|
|
|
|
|
MirrorModifierData *mmd = (MirrorModifierData *)md;
|
|
|
|
|
/* This was the previous hard-coded value. */
|
|
|
|
|
mmd->bisect_threshold = 0.001f;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-05-04 16:38:52 +02:00
|
|
|
/* Grease Pencil: Set default value for dilate pixels. */
|
|
|
|
|
if (!DNA_struct_elem_find(fd->filesdna, "BrushGpencilSettings", "int", "dilate_pixels")) {
|
|
|
|
|
LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
|
|
|
|
|
if (brush->gpencil_settings) {
|
|
|
|
|
brush->gpencil_settings->dilate_pixels = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-04-20 17:08:31 +02:00
|
|
|
}
|
2021-05-28 12:17:04 -04:00
|
|
|
|
|
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 2)) {
|
|
|
|
|
version_switch_node_input_prefix(bmain);
|
|
|
|
|
|
|
|
|
|
if (!DNA_struct_elem_find(fd->filesdna, "bPoseChannel", "float", "custom_scale_xyz[3]")) {
|
|
|
|
|
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
|
|
|
|
|
if (ob->pose == NULL) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
|
|
|
|
|
copy_v3_fl(pchan->custom_scale_xyz, pchan->custom_scale);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-18 16:33:02 -05:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 4)) {
|
|
|
|
|
/* Add a properties sidebar to the spreadsheet editor. */
|
|
|
|
|
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
|
|
|
|
|
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
|
|
|
|
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
|
|
|
|
|
if (sl->spacetype == SPACE_SPREADSHEET) {
|
|
|
|
|
ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
|
|
|
|
|
&sl->regionbase;
|
|
|
|
|
ARegion *new_sidebar = do_versions_add_region_if_not_found(
|
|
|
|
|
regionbase, RGN_TYPE_UI, "sidebar for spreadsheet", RGN_TYPE_FOOTER);
|
|
|
|
|
if (new_sidebar != NULL) {
|
|
|
|
|
new_sidebar->alignment = RGN_ALIGN_RIGHT;
|
|
|
|
|
new_sidebar->flag |= RGN_FLAG_HIDDEN;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Enable spreadsheet filtering in old files without row filters. */
|
|
|
|
|
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
|
|
|
|
|
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
|
|
|
|
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
|
|
|
|
|
if (sl->spacetype == SPACE_SPREADSHEET) {
|
|
|
|
|
SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)sl;
|
|
|
|
|
sspreadsheet->filter_flag |= SPREADSHEET_FILTER_ENABLE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-08 11:11:49 -05:00
|
|
|
FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
|
|
|
|
|
if (ntree->type == NTREE_GEOMETRY) {
|
|
|
|
|
version_node_socket_name(ntree, GEO_NODE_BOUNDING_BOX, "Mesh", "Bounding Box");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
FOREACH_NODETREE_END;
|
2021-06-11 16:35:39 +02:00
|
|
|
|
2021-10-15 12:36:09 +02:00
|
|
|
if (!DNA_struct_elem_find(fd->filesdna, "FileAssetSelectParams", "short", "import_type")) {
|
2021-06-11 16:35:39 +02:00
|
|
|
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
|
|
|
|
|
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
|
|
|
|
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
|
|
|
|
|
if (sl->spacetype == SPACE_FILE) {
|
|
|
|
|
SpaceFile *sfile = (SpaceFile *)sl;
|
|
|
|
|
if (sfile->asset_params) {
|
|
|
|
|
sfile->asset_params->import_type = FILE_ASSET_IMPORT_APPEND;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
Armature: add B-Bone Y scale channel and extra flag fields to DNA.
In addition to the base bone transformation itself, B-Bones have
controls that affect transformation of its segments. For rotation
the features are quite complete, allowing to both reorient the
Bezier handles via properties, and to control them using custom
handle bones. However for scaling there are two deficiencies.
First, there are only X and Y scale factors (actually X and Z),
while lengthwise all segments have the same scaling. The ease
option merely affects the shape of the curve, and does not cause
actual scaling.
Second, scaling can only be controlled via properties, thus
requiring up to 6 drivers per joint between B-Bones to transfer
scaling factors from the handle bone. This is very inefficient.
Finally, the Z channels are confusingly called Y.
This commit adds a B-Bone Y Scale channel and extra B-Bone flag
fields to DNA with appropriate versioning (including for F-Curves
and drivers) in preparation to addressing these limitations.
Functionality is not changed, so the new fields are not used
until the following commits.
Differential Revision: https://developer.blender.org/D9870
2020-12-11 19:17:39 +03:00
|
|
|
|
|
|
|
|
/* Initialize length-wise scale B-Bone settings. */
|
|
|
|
|
if (!DNA_struct_elem_find(fd->filesdna, "Bone", "int", "bbone_flag")) {
|
|
|
|
|
/* Update armature data and pose channels. */
|
|
|
|
|
LISTBASE_FOREACH (bArmature *, arm, &bmain->armatures) {
|
|
|
|
|
do_version_bones_bbone_len_scale(&arm->bonebase);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
|
|
|
|
|
if (ob->pose) {
|
|
|
|
|
LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
|
|
|
|
|
copy_v3_fl3(pchan->scale_in, pchan->scale_in_x, 1.0f, pchan->scale_in_z);
|
|
|
|
|
copy_v3_fl3(pchan->scale_out, pchan->scale_out_x, 1.0f, pchan->scale_out_z);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Update action curves and drivers. */
|
|
|
|
|
LISTBASE_FOREACH (bAction *, act, &bmain->actions) {
|
|
|
|
|
LISTBASE_FOREACH_MUTABLE (FCurve *, fcu, &act->curves) {
|
|
|
|
|
do_version_bbone_len_scale_fcurve_fix(fcu);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BKE_animdata_main_cb(bmain, do_version_bbone_len_scale_animdata_cb, NULL);
|
|
|
|
|
}
|
2021-05-04 14:46:32 +02:00
|
|
|
}
|
2021-06-18 16:33:02 -05:00
|
|
|
|
2021-06-25 07:57:24 +02:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 5)) {
|
|
|
|
|
/* Add a dataset sidebar to the spreadsheet editor. */
|
|
|
|
|
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
|
|
|
|
|
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
|
|
|
|
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
|
|
|
|
|
if (sl->spacetype == SPACE_SPREADSHEET) {
|
|
|
|
|
ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
|
2021-06-25 18:42:30 +02:00
|
|
|
&sl->regionbase;
|
2021-06-25 07:57:24 +02:00
|
|
|
ARegion *spreadsheet_dataset_region = do_versions_add_region_if_not_found(
|
|
|
|
|
regionbase, RGN_TYPE_CHANNELS, "spreadsheet dataset region", RGN_TYPE_FOOTER);
|
|
|
|
|
|
|
|
|
|
if (spreadsheet_dataset_region) {
|
|
|
|
|
spreadsheet_dataset_region->alignment = RGN_ALIGN_LEFT;
|
|
|
|
|
spreadsheet_dataset_region->v2d.scroll = (V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-06-25 17:12:10 +02:00
|
|
|
|
|
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 6)) {
|
|
|
|
|
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
|
|
|
|
|
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
|
|
|
|
LISTBASE_FOREACH (SpaceLink *, space, &area->spacedata) {
|
|
|
|
|
/* Disable View Layers filter. */
|
|
|
|
|
if (space->spacetype == SPACE_OUTLINER) {
|
|
|
|
|
SpaceOutliner *space_outliner = (SpaceOutliner *)space;
|
|
|
|
|
space_outliner->filter |= SO_FILTER_NO_VIEW_LAYERS;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-29 20:12:19 +02:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 7)) {
|
|
|
|
|
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
|
|
|
|
ToolSettings *tool_settings = scene->toolsettings;
|
|
|
|
|
tool_settings->snap_flag |= SCE_SNAP_SEQ;
|
|
|
|
|
short snap_mode = tool_settings->snap_mode;
|
|
|
|
|
short snap_node_mode = tool_settings->snap_node_mode;
|
2021-06-30 15:13:10 +02:00
|
|
|
short snap_uv_mode = tool_settings->snap_uv_mode;
|
2021-06-29 20:12:19 +02:00
|
|
|
tool_settings->snap_mode &= ~((1 << 4) | (1 << 5) | (1 << 6));
|
|
|
|
|
tool_settings->snap_node_mode &= ~((1 << 5) | (1 << 6));
|
2021-06-30 10:00:32 -03:00
|
|
|
tool_settings->snap_uv_mode &= ~(1 << 4);
|
2021-06-29 20:12:19 +02:00
|
|
|
if (snap_mode & (1 << 4)) {
|
|
|
|
|
tool_settings->snap_mode |= (1 << 6); /* SCE_SNAP_MODE_INCREMENT */
|
|
|
|
|
}
|
|
|
|
|
if (snap_mode & (1 << 5)) {
|
|
|
|
|
tool_settings->snap_mode |= (1 << 4); /* SCE_SNAP_MODE_EDGE_MIDPOINT */
|
|
|
|
|
}
|
|
|
|
|
if (snap_mode & (1 << 6)) {
|
|
|
|
|
tool_settings->snap_mode |= (1 << 5); /* SCE_SNAP_MODE_EDGE_PERPENDICULAR */
|
|
|
|
|
}
|
|
|
|
|
if (snap_node_mode & (1 << 5)) {
|
|
|
|
|
tool_settings->snap_node_mode |= (1 << 0); /* SCE_SNAP_MODE_NODE_X */
|
|
|
|
|
}
|
|
|
|
|
if (snap_node_mode & (1 << 6)) {
|
|
|
|
|
tool_settings->snap_node_mode |= (1 << 1); /* SCE_SNAP_MODE_NODE_Y */
|
|
|
|
|
}
|
2021-06-30 15:13:10 +02:00
|
|
|
if (snap_uv_mode & (1 << 4)) {
|
|
|
|
|
tool_settings->snap_uv_mode |= (1 << 6); /* SCE_SNAP_MODE_INCREMENT */
|
|
|
|
|
}
|
2021-06-29 20:12:19 +02:00
|
|
|
|
|
|
|
|
SequencerToolSettings *sequencer_tool_settings = SEQ_tool_settings_ensure(scene);
|
2021-07-01 11:02:30 +10:00
|
|
|
sequencer_tool_settings->snap_mode = SEQ_SNAP_TO_STRIPS | SEQ_SNAP_TO_CURRENT_FRAME |
|
2021-06-29 20:12:19 +02:00
|
|
|
SEQ_SNAP_TO_STRIP_HOLD;
|
|
|
|
|
sequencer_tool_settings->snap_distance = 15;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-06 17:22:18 +02:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 8)) {
|
|
|
|
|
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
|
|
|
|
if (scene->master_collection != NULL) {
|
|
|
|
|
BLI_strncpy(scene->master_collection->id.name + 2,
|
|
|
|
|
BKE_SCENE_COLLECTION_NAME,
|
|
|
|
|
sizeof(scene->master_collection->id.name) - 2);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-06 15:36:27 +03:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 9)) {
|
|
|
|
|
/* Fix a bug where reordering FCurves and bActionGroups could cause some corruption. Just
|
|
|
|
|
* reconstruct all the action groups & ensure that the FCurves of a group are continuously
|
|
|
|
|
* stored (i.e. not mixed with other groups) to be sure. See T89435. */
|
|
|
|
|
LISTBASE_FOREACH (bAction *, act, &bmain->actions) {
|
|
|
|
|
BKE_action_groups_reconstruct(act);
|
|
|
|
|
}
|
2021-07-06 23:00:27 -05:00
|
|
|
|
|
|
|
|
FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
|
|
|
|
|
if (ntree->type == NTREE_GEOMETRY) {
|
|
|
|
|
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
|
2021-10-14 12:06:42 -05:00
|
|
|
if (node->type == GEO_NODE_SUBDIVIDE_MESH) {
|
2021-07-06 23:00:27 -05:00
|
|
|
strcpy(node->idname, "GeometryNodeMeshSubdivide");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
FOREACH_NODETREE_END;
|
2021-06-18 16:33:02 -05:00
|
|
|
}
|
2021-07-06 15:36:27 +03:00
|
|
|
|
2021-07-13 12:46:40 +02:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 10)) {
|
|
|
|
|
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
|
|
|
|
ToolSettings *tool_settings = scene->toolsettings;
|
|
|
|
|
if (tool_settings->snap_uv_mode & (1 << 4)) {
|
|
|
|
|
tool_settings->snap_uv_mode |= (1 << 6); /* SCE_SNAP_MODE_INCREMENT */
|
|
|
|
|
tool_settings->snap_uv_mode &= ~(1 << 4);
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-07-31 09:27:30 +08:00
|
|
|
LISTBASE_FOREACH (Material *, mat, &bmain->materials) {
|
|
|
|
|
if (!(mat->lineart.flags & LRT_MATERIAL_CUSTOM_OCCLUSION_EFFECTIVENESS)) {
|
|
|
|
|
mat->lineart.mat_occlusion = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-07-13 12:46:40 +02:00
|
|
|
}
|
|
|
|
|
|
2021-07-22 15:19:58 +02:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 13)) {
|
2021-07-14 22:51:59 +03:00
|
|
|
/* Convert Surface Deform to sparse-capable bind structure. */
|
|
|
|
|
if (!DNA_struct_elem_find(
|
|
|
|
|
fd->filesdna, "SurfaceDeformModifierData", "int", "num_mesh_verts")) {
|
|
|
|
|
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
|
|
|
|
|
LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
|
|
|
|
|
if (md->type == eModifierType_SurfaceDeform) {
|
|
|
|
|
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
|
|
|
|
|
if (smd->num_bind_verts && smd->verts) {
|
|
|
|
|
smd->num_mesh_verts = smd->num_bind_verts;
|
|
|
|
|
|
|
|
|
|
for (unsigned int i = 0; i < smd->num_bind_verts; i++) {
|
|
|
|
|
smd->verts[i].vertex_idx = i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-09-26 19:43:12 +08:00
|
|
|
if (ob->type == OB_GPENCIL) {
|
|
|
|
|
LISTBASE_FOREACH (GpencilModifierData *, md, &ob->greasepencil_modifiers) {
|
|
|
|
|
if (md->type == eGpencilModifierType_Lineart) {
|
|
|
|
|
LineartGpencilModifierData *lmd = (LineartGpencilModifierData *)md;
|
|
|
|
|
lmd->flags |= LRT_GPENCIL_USE_CACHE;
|
|
|
|
|
lmd->chain_smooth_tolerance = 0.2f;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-07-14 22:51:59 +03:00
|
|
|
}
|
|
|
|
|
}
|
2021-07-21 19:02:20 +02:00
|
|
|
|
|
|
|
|
if (!DNA_struct_elem_find(
|
|
|
|
|
fd->filesdna, "WorkSpace", "AssetLibraryReference", "asset_library")) {
|
|
|
|
|
LISTBASE_FOREACH (WorkSpace *, workspace, &bmain->workspaces) {
|
2021-08-06 15:18:18 +02:00
|
|
|
BKE_asset_library_reference_init_default(&workspace->asset_library_ref);
|
2021-07-21 19:02:20 +02:00
|
|
|
}
|
|
|
|
|
}
|
2021-07-21 19:22:44 +02:00
|
|
|
|
|
|
|
|
if (!DNA_struct_elem_find(
|
2021-08-06 15:18:18 +02:00
|
|
|
fd->filesdna, "FileAssetSelectParams", "AssetLibraryReference", "asset_library_ref")) {
|
2021-07-21 19:22:44 +02:00
|
|
|
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
|
|
|
|
|
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
|
|
|
|
LISTBASE_FOREACH (SpaceLink *, space, &area->spacedata) {
|
|
|
|
|
if (space->spacetype == SPACE_FILE) {
|
|
|
|
|
SpaceFile *sfile = (SpaceFile *)space;
|
|
|
|
|
if (sfile->browse_mode != FILE_BROWSE_MODE_ASSETS) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2021-08-06 15:18:18 +02:00
|
|
|
BKE_asset_library_reference_init_default(&sfile->asset_params->asset_library_ref);
|
2021-07-21 19:22:44 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-07-26 18:52:48 -04:00
|
|
|
|
|
|
|
|
/* Set default 2D annotation placement. */
|
|
|
|
|
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
|
|
|
|
ToolSettings *ts = scene->toolsettings;
|
|
|
|
|
ts->gpencil_v2d_align = GP_PROJECT_VIEWSPACE | GP_PROJECT_CURSOR;
|
|
|
|
|
}
|
2021-07-06 15:36:27 +03:00
|
|
|
}
|
2021-07-22 15:19:58 +02:00
|
|
|
|
2021-07-29 10:27:54 +02:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 14)) {
|
|
|
|
|
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
|
|
|
|
ToolSettings *tool_settings = scene->toolsettings;
|
|
|
|
|
tool_settings->snap_flag &= ~SCE_SNAP_SEQ;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-29 11:35:48 +02:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 15)) {
|
|
|
|
|
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
|
|
|
|
|
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
|
|
|
|
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
|
|
|
|
|
if (sl->spacetype == SPACE_SEQ) {
|
|
|
|
|
SpaceSeq *sseq = (SpaceSeq *)sl;
|
2021-09-20 16:21:40 +02:00
|
|
|
sseq->flag |= SEQ_TIMELINE_SHOW_GRID;
|
2021-07-29 11:35:48 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-04 13:13:02 +10:00
|
|
|
/* Font names were copied directly into ID names, see: T90417. */
|
2021-08-04 12:57:20 +10:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 16)) {
|
|
|
|
|
ListBase *lb = which_libbase(bmain, ID_VF);
|
|
|
|
|
BKE_main_id_repair_duplicate_names_listbase(lb);
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-05 17:17:15 +02:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 17)) {
|
2021-08-04 10:52:51 +02:00
|
|
|
if (!DNA_struct_elem_find(
|
|
|
|
|
fd->filesdna, "View3DOverlay", "float", "normals_constant_screen_size")) {
|
|
|
|
|
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
|
|
|
|
|
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
|
|
|
|
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
|
|
|
|
|
if (sl->spacetype == SPACE_VIEW3D) {
|
|
|
|
|
View3D *v3d = (View3D *)sl;
|
|
|
|
|
v3d->overlay.normals_constant_screen_size = 7.0f;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-08-05 17:17:15 +02:00
|
|
|
|
2021-08-31 11:12:07 -05:00
|
|
|
/* Fix SplineIK constraint's inconsistency between binding points array and its stored size.
|
|
|
|
|
*/
|
2021-08-05 17:17:15 +02:00
|
|
|
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
|
|
|
|
|
/* NOTE: Objects should never have SplineIK constraint, so no need to apply this fix on
|
|
|
|
|
* their constraints. */
|
|
|
|
|
if (ob->pose) {
|
|
|
|
|
LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
|
|
|
|
|
do_version_constraints_spline_ik_joint_bindings(&pchan->constraints);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-13 15:51:08 +10:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 18)) {
|
2021-08-06 15:18:18 +02:00
|
|
|
if (!DNA_struct_elem_find(
|
|
|
|
|
fd->filesdna, "WorkSpace", "AssetLibraryReference", "asset_library_ref")) {
|
|
|
|
|
LISTBASE_FOREACH (WorkSpace *, workspace, &bmain->workspaces) {
|
|
|
|
|
BKE_asset_library_reference_init_default(&workspace->asset_library_ref);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!DNA_struct_elem_find(
|
|
|
|
|
fd->filesdna, "FileAssetSelectParams", "AssetLibraryReference", "asset_library_ref")) {
|
|
|
|
|
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
|
|
|
|
|
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
|
|
|
|
LISTBASE_FOREACH (SpaceLink *, space, &area->spacedata) {
|
|
|
|
|
if (space->spacetype != SPACE_FILE) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SpaceFile *sfile = (SpaceFile *)space;
|
|
|
|
|
if (sfile->browse_mode != FILE_BROWSE_MODE_ASSETS) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
BKE_asset_library_reference_init_default(&sfile->asset_params->asset_library_ref);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-08-13 15:51:08 +10:00
|
|
|
|
|
|
|
|
/* Previously, only text ending with `.py` would run, apply this logic
|
|
|
|
|
* to existing files so text that happens to have the "Register" enabled
|
|
|
|
|
* doesn't suddenly start running code on startup that was previously ignored. */
|
|
|
|
|
LISTBASE_FOREACH (Text *, text, &bmain->texts) {
|
|
|
|
|
if ((text->flags & TXT_ISSCRIPT) && !BLI_path_extension_check(text->id.name + 2, ".py")) {
|
|
|
|
|
text->flags &= ~TXT_ISSCRIPT;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-27 12:59:46 +02:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 19)) {
|
2021-08-31 11:12:07 -05:00
|
|
|
/* Disable Fade Inactive Overlay by default as it is redundant after introducing flash on
|
|
|
|
|
* mode transfer. */
|
2021-08-23 18:33:04 +02:00
|
|
|
for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
|
|
|
|
|
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
|
|
|
|
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
|
|
|
|
|
if (sl->spacetype == SPACE_VIEW3D) {
|
|
|
|
|
View3D *v3d = (View3D *)sl;
|
|
|
|
|
v3d->overlay.flag &= ~V3D_OVERLAY_FADE_INACTIVE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-08-27 12:59:46 +02:00
|
|
|
|
|
|
|
|
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
|
|
|
|
SequencerToolSettings *sequencer_tool_settings = SEQ_tool_settings_ensure(scene);
|
|
|
|
|
sequencer_tool_settings->overlap_mode = SEQ_OVERLAP_SHUFFLE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-29 22:08:57 -05:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 20)) {
|
|
|
|
|
/* Use new vector Size socket in Cube Mesh Primitive node. */
|
|
|
|
|
LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
|
|
|
|
|
if (ntree->type != NTREE_GEOMETRY) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree->links) {
|
|
|
|
|
if (link->tonode->type == GEO_NODE_MESH_PRIMITIVE_CUBE) {
|
|
|
|
|
bNode *node = link->tonode;
|
|
|
|
|
if (STREQ(link->tosock->identifier, "Size") && link->tosock->type == SOCK_FLOAT) {
|
|
|
|
|
bNode *link_fromnode = link->fromnode;
|
|
|
|
|
bNodeSocket *link_fromsock = link->fromsock;
|
|
|
|
|
bNodeSocket *socket = link->tosock;
|
|
|
|
|
BLI_assert(socket);
|
|
|
|
|
|
|
|
|
|
bNodeSocket *new_socket = do_version_replace_float_size_with_vector(
|
|
|
|
|
ntree, node, socket);
|
|
|
|
|
nodeAddLink(ntree, link_fromnode, link_fromsock, node, new_socket);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
|
|
|
|
|
if (node->type != GEO_NODE_MESH_PRIMITIVE_CUBE) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
|
|
|
|
|
if (STREQ(socket->identifier, "Size") && (socket->type == SOCK_FLOAT)) {
|
|
|
|
|
do_version_replace_float_size_with_vector(ntree, node, socket);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-10 13:26:46 -05:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 22)) {
|
2021-09-15 14:03:18 +08:00
|
|
|
if (!DNA_struct_elem_find(
|
|
|
|
|
fd->filesdna, "LineartGpencilModifierData", "bool", "use_crease_on_smooth")) {
|
|
|
|
|
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
|
|
|
|
|
if (ob->type == OB_GPENCIL) {
|
|
|
|
|
LISTBASE_FOREACH (GpencilModifierData *, md, &ob->greasepencil_modifiers) {
|
|
|
|
|
if (md->type == eGpencilModifierType_Lineart) {
|
|
|
|
|
LineartGpencilModifierData *lmd = (LineartGpencilModifierData *)md;
|
|
|
|
|
lmd->calculation_flags |= LRT_USE_CREASE_ON_SMOOTH_SURFACES;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-09-10 10:34:49 -05:00
|
|
|
}
|
|
|
|
|
|
2021-09-20 16:21:40 +02:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 23)) {
|
2021-09-16 16:39:51 +02:00
|
|
|
for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
|
|
|
|
|
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
|
|
|
|
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
|
|
|
|
|
if (sl->spacetype == SPACE_FILE) {
|
|
|
|
|
SpaceFile *sfile = (SpaceFile *)sl;
|
|
|
|
|
if (sfile->asset_params) {
|
|
|
|
|
sfile->asset_params->base_params.recursion_level = FILE_SELECT_MAX_RECURSIONS;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-09-20 16:21:40 +02:00
|
|
|
|
|
|
|
|
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
|
|
|
|
|
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
|
|
|
|
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
|
|
|
|
|
if (sl->spacetype == SPACE_SEQ) {
|
|
|
|
|
SpaceSeq *sseq = (SpaceSeq *)sl;
|
|
|
|
|
int seq_show_safe_margins = (sseq->flag & SEQ_PREVIEW_SHOW_SAFE_MARGINS);
|
|
|
|
|
int seq_show_gpencil = (sseq->flag & SEQ_PREVIEW_SHOW_GPENCIL);
|
|
|
|
|
int seq_show_fcurves = (sseq->flag & SEQ_TIMELINE_SHOW_FCURVES);
|
|
|
|
|
int seq_show_safe_center = (sseq->flag & SEQ_PREVIEW_SHOW_SAFE_CENTER);
|
|
|
|
|
int seq_show_metadata = (sseq->flag & SEQ_PREVIEW_SHOW_METADATA);
|
|
|
|
|
int seq_show_strip_name = (sseq->flag & SEQ_TIMELINE_SHOW_STRIP_NAME);
|
|
|
|
|
int seq_show_strip_source = (sseq->flag & SEQ_TIMELINE_SHOW_STRIP_SOURCE);
|
|
|
|
|
int seq_show_strip_duration = (sseq->flag & SEQ_TIMELINE_SHOW_STRIP_DURATION);
|
|
|
|
|
int seq_show_grid = (sseq->flag & SEQ_TIMELINE_SHOW_GRID);
|
|
|
|
|
int show_strip_offset = (sseq->draw_flag & SEQ_TIMELINE_SHOW_STRIP_OFFSETS);
|
|
|
|
|
sseq->preview_overlay.flag = (seq_show_safe_margins | seq_show_gpencil |
|
|
|
|
|
seq_show_safe_center | seq_show_metadata);
|
|
|
|
|
sseq->timeline_overlay.flag = (seq_show_fcurves | seq_show_strip_name |
|
|
|
|
|
seq_show_strip_source | seq_show_strip_duration |
|
|
|
|
|
seq_show_grid | show_strip_offset);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-21 09:38:30 +02:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 24)) {
|
|
|
|
|
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
|
|
|
|
SequencerToolSettings *sequencer_tool_settings = SEQ_tool_settings_ensure(scene);
|
|
|
|
|
sequencer_tool_settings->pivot_point = V3D_AROUND_CENTER_MEDIAN;
|
|
|
|
|
|
|
|
|
|
if (scene->ed != NULL) {
|
|
|
|
|
SEQ_for_each_callback(&scene->ed->seqbase, seq_transform_origin_set, NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
|
|
|
|
|
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
|
|
|
|
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
|
|
|
|
|
if (sl->spacetype == SPACE_SEQ) {
|
|
|
|
|
SpaceSeq *sseq = (SpaceSeq *)sl;
|
|
|
|
|
sseq->preview_overlay.flag |= SEQ_PREVIEW_SHOW_OUTLINE_SELECTED;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-09-21 10:38:15 +02:00
|
|
|
|
|
|
|
|
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
|
|
|
|
|
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
|
|
|
|
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
|
|
|
|
|
if (sl->spacetype == SPACE_SEQ) {
|
|
|
|
|
ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
|
|
|
|
|
&sl->regionbase;
|
|
|
|
|
LISTBASE_FOREACH (ARegion *, region, regionbase) {
|
|
|
|
|
if (region->regiontype == RGN_TYPE_WINDOW) {
|
|
|
|
|
region->v2d.min[1] = 4.0f;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-09-21 09:38:30 +02:00
|
|
|
}
|
|
|
|
|
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 25)) {
|
|
|
|
|
FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
|
|
|
|
|
if (ntree->type == NTREE_SHADER) {
|
|
|
|
|
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
|
|
|
|
|
do_version_subsurface_methods(node);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
FOREACH_NODETREE_END;
|
|
|
|
|
|
|
|
|
|
enum {
|
|
|
|
|
R_EXR_TILE_FILE = (1 << 10),
|
|
|
|
|
R_FULL_SAMPLE = (1 << 15),
|
|
|
|
|
};
|
|
|
|
|
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
|
|
|
|
scene->r.scemode &= ~(R_EXR_TILE_FILE | R_FULL_SAMPLE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-27 11:30:52 +02:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 26)) {
|
2021-09-21 12:42:47 -05:00
|
|
|
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
|
|
|
|
|
LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
|
|
|
|
|
if (md->type == eModifierType_Nodes) {
|
|
|
|
|
version_geometry_nodes_add_attribute_input_settings((NodesModifierData *)md);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-09-23 10:43:31 +02:00
|
|
|
|
|
|
|
|
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
|
|
|
|
|
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
|
|
|
|
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
|
|
|
|
|
switch (sl->spacetype) {
|
|
|
|
|
case SPACE_FILE: {
|
|
|
|
|
SpaceFile *sfile = (SpaceFile *)sl;
|
|
|
|
|
if (sfile->params) {
|
|
|
|
|
sfile->params->flag &= ~(FILE_PARAMS_FLAG_UNUSED_1 | FILE_PARAMS_FLAG_UNUSED_2 |
|
UDIM: Support virtual filenames
This implements the design detailed in T92696 to support virtual
filenames for UDIM textures. Currently, the following 2 substitution
tokens are supported:
| Token | Meaning |
| ----- | ---- |
| <UDIM> | 1001 + u-tile + v-tile * 10 |
| <UVTILE> | Equivalent to u<u-tile + 1>_v<v-tile + 1> |
Example for u-tile of 3 and v-tile of 1:
filename.<UDIM>_ver0023.png --> filename.1014_ver0023.png
filename.<UVTILE>_ver0023.png --> filename.u4_v2_ver0023.png
For image loading, the existing workflow is unchanged. A user can select
one or more image files, belonging to one or more UDIM tile sets, and
have Blender load them all as it does today. Now the <UVTILE> format is
"guessed" just as the <UDIM> format was guessed before.
If guessing fails, the user can simply go into the Image Editor and type
the proper substitution in the filename. Once typing is complete,
Blender will reload the files and correctly fill the tiles. This
workflow is new as attempting to fix the guessing in current versions
did not really work, and the user was often stuck with a confusing
situation.
For image saving, the existing workflow is changed slightly. Currently,
when saving, a user has to be sure to type the filename of the first
tile (e.g. filename.1001.png) to save the entire UDIM set. The number
could differ if they start at a different tile etc. This is confusing.
Now, the user should type a filename containing the appropriate
substitution token. By default Blender will fill in a default name using
the <UDIM> token but the user is free to save out images using <UVTILE>
if they wish.
Differential Revision: https://developer.blender.org/D13057
2021-12-30 22:06:23 -08:00
|
|
|
FILE_PARAMS_FLAG_UNUSED_3 | FILE_PATH_TOKENS_ALLOW);
|
2021-09-23 10:43:31 +02:00
|
|
|
}
|
2021-09-29 15:01:36 +02:00
|
|
|
|
|
|
|
|
/* New default import type: Append with reuse. */
|
|
|
|
|
if (sfile->asset_params) {
|
|
|
|
|
sfile->asset_params->import_type = FILE_ASSET_IMPORT_APPEND_REUSE;
|
|
|
|
|
}
|
2021-09-23 10:43:31 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-07-22 15:19:58 +02:00
|
|
|
}
|
2021-09-27 11:30:52 +02:00
|
|
|
|
2021-09-29 17:47:32 +10:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 29)) {
|
2021-09-28 17:55:21 +02:00
|
|
|
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
|
|
|
|
|
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
|
|
|
|
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
|
2021-09-29 17:47:32 +10:00
|
|
|
switch (sl->spacetype) {
|
|
|
|
|
case SPACE_SEQ: {
|
|
|
|
|
ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
|
|
|
|
|
&sl->regionbase;
|
|
|
|
|
LISTBASE_FOREACH (ARegion *, region, regionbase) {
|
|
|
|
|
if (region->regiontype == RGN_TYPE_WINDOW) {
|
|
|
|
|
region->v2d.max[1] = MAXSEQ;
|
|
|
|
|
}
|
2021-09-28 17:55:21 +02:00
|
|
|
}
|
2021-09-29 17:47:32 +10:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case SPACE_IMAGE: {
|
|
|
|
|
SpaceImage *sima = (SpaceImage *)sl;
|
|
|
|
|
sima->custom_grid_subdiv = 10;
|
|
|
|
|
break;
|
2021-09-28 17:55:21 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-09-27 11:30:52 +02:00
|
|
|
}
|
2021-09-29 17:47:32 +10:00
|
|
|
|
2021-09-29 14:29:32 +02:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 31)) {
|
2021-09-28 14:44:36 +10:00
|
|
|
/* Swap header with the tool header so the regular header is always on the edge. */
|
|
|
|
|
for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
|
|
|
|
|
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
|
|
|
|
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
|
|
|
|
|
ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
|
|
|
|
|
&sl->regionbase;
|
|
|
|
|
ARegion *region_tool = NULL, *region_head = NULL;
|
|
|
|
|
int region_tool_index = -1, region_head_index = -1, i;
|
|
|
|
|
LISTBASE_FOREACH_INDEX (ARegion *, region, regionbase, i) {
|
|
|
|
|
if (region->regiontype == RGN_TYPE_TOOL_HEADER) {
|
|
|
|
|
region_tool = region;
|
|
|
|
|
region_tool_index = i;
|
|
|
|
|
}
|
|
|
|
|
else if (region->regiontype == RGN_TYPE_HEADER) {
|
|
|
|
|
region_head = region;
|
|
|
|
|
region_head_index = i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if ((region_tool && region_head) && (region_head_index > region_tool_index)) {
|
|
|
|
|
BLI_listbase_swaplinks(regionbase, region_tool, region_head);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-09-29 14:29:32 +02:00
|
|
|
|
|
|
|
|
/* Set strip color tags to SEQUENCE_COLOR_NONE. */
|
|
|
|
|
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
|
|
|
|
if (scene->ed != NULL) {
|
|
|
|
|
SEQ_for_each_callback(&scene->ed->seqbase, do_versions_sequencer_color_tags, NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-03 12:06:06 +11:00
|
|
|
/* Show sequencer color tags by default. */
|
2021-09-29 14:29:32 +02:00
|
|
|
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
|
|
|
|
|
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
|
|
|
|
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
|
|
|
|
|
if (sl->spacetype == SPACE_SEQ) {
|
|
|
|
|
SpaceSeq *sseq = (SpaceSeq *)sl;
|
|
|
|
|
sseq->timeline_overlay.flag |= SEQ_TIMELINE_SHOW_STRIP_COLOR_TAG;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-10-15 23:13:31 +02:00
|
|
|
|
|
|
|
|
/* Set defaults for new color balance modifier parameters. */
|
|
|
|
|
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
|
|
|
|
if (scene->ed != NULL) {
|
|
|
|
|
SEQ_for_each_callback(&scene->ed->seqbase, do_versions_sequencer_color_balance_sop, NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-09-29 14:29:32 +02:00
|
|
|
}
|
|
|
|
|
|
2021-10-08 14:30:08 +02:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 33)) {
|
2021-10-08 13:03:39 +11:00
|
|
|
for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
|
|
|
|
|
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
|
|
|
|
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
|
|
|
|
|
switch (sl->spacetype) {
|
|
|
|
|
case SPACE_SEQ: {
|
|
|
|
|
SpaceSeq *sseq = (SpaceSeq *)sl;
|
|
|
|
|
enum { SEQ_DRAW_SEQUENCE = 0 };
|
|
|
|
|
if (sseq->mainb == SEQ_DRAW_SEQUENCE) {
|
|
|
|
|
sseq->mainb = SEQ_DRAW_IMG_IMBUF;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case SPACE_TEXT: {
|
|
|
|
|
SpaceText *st = (SpaceText *)sl;
|
|
|
|
|
st->flags &= ~ST_FLAG_UNUSED_4;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-09-29 17:47:32 +10:00
|
|
|
}
|
2021-10-08 14:30:08 +02:00
|
|
|
|
2020-11-21 21:45:14 +03:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 36)) {
|
2021-10-18 11:16:24 +11:00
|
|
|
/* Update the `idnames` for renamed geometry and function nodes. */
|
2021-10-13 08:39:54 -05:00
|
|
|
LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
|
|
|
|
|
if (ntree->type != NTREE_GEOMETRY) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
Geometry Nodes: Generalized Compare Node
Replace compare floats node with a generalized compare node. The node
allows for the comparison of float, int, string, color, and vector.
The datatypes support the following operators:
Float, Int: <, >, <=, >=, ==, !=
String: ==, !=
Color: ==, !=, lighter, darker
(using rgb_to_grayscale value as the brightness value)
Vector Supports 5 comparison modes for: ==, !=, <, >, <=, >=
Average: The average of the components of the vectors are compared.
Dot Product: The dot product of the vectors are compared.
Direction: The angle between the vectors is compared to an angle
Element-wise: The individual components of the vectors are compared.
Length: The lengths of the vectors are compared.
Differential Revision: https://developer.blender.org/D13228
2021-12-01 09:36:25 -06:00
|
|
|
version_node_id(ntree, FN_NODE_COMPARE, "FunctionNodeCompareFloats");
|
2021-10-14 12:06:42 -05:00
|
|
|
version_node_id(ntree, GEO_NODE_CAPTURE_ATTRIBUTE, "GeometryNodeCaptureAttribute");
|
|
|
|
|
version_node_id(ntree, GEO_NODE_MESH_BOOLEAN, "GeometryNodeMeshBoolean");
|
|
|
|
|
version_node_id(ntree, GEO_NODE_FILL_CURVE, "GeometryNodeFillCurve");
|
|
|
|
|
version_node_id(ntree, GEO_NODE_FILLET_CURVE, "GeometryNodeFilletCurve");
|
|
|
|
|
version_node_id(ntree, GEO_NODE_REVERSE_CURVE, "GeometryNodeReverseCurve");
|
|
|
|
|
version_node_id(ntree, GEO_NODE_SAMPLE_CURVE, "GeometryNodeSampleCurve");
|
|
|
|
|
version_node_id(ntree, GEO_NODE_RESAMPLE_CURVE, "GeometryNodeResampleCurve");
|
|
|
|
|
version_node_id(ntree, GEO_NODE_SUBDIVIDE_CURVE, "GeometryNodeSubdivideCurve");
|
|
|
|
|
version_node_id(ntree, GEO_NODE_TRIM_CURVE, "GeometryNodeTrimCurve");
|
|
|
|
|
version_node_id(ntree, GEO_NODE_REPLACE_MATERIAL, "GeometryNodeReplaceMaterial");
|
|
|
|
|
version_node_id(ntree, GEO_NODE_SUBDIVIDE_MESH, "GeometryNodeSubdivideMesh");
|
|
|
|
|
version_node_id(ntree, GEO_NODE_SET_MATERIAL, "GeometryNodeSetMaterial");
|
|
|
|
|
version_node_id(ntree, GEO_NODE_SPLIT_EDGES, "GeometryNodeSplitEdges");
|
2021-10-13 08:39:54 -05:00
|
|
|
}
|
2020-11-21 21:45:14 +03:00
|
|
|
|
|
|
|
|
/* Update bone roll after a fix to vec_roll_to_mat3_normalized. */
|
|
|
|
|
LISTBASE_FOREACH (bArmature *, arm, &bmain->armatures) {
|
|
|
|
|
do_version_bones_roll(&arm->bonebase);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-21 21:00:17 +02:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 37)) {
|
|
|
|
|
/* Node Editor: toggle overlays on. */
|
|
|
|
|
if (!DNA_struct_find(fd->filesdna, "SpaceNodeOverlay")) {
|
|
|
|
|
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
|
|
|
|
|
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
|
|
|
|
LISTBASE_FOREACH (SpaceLink *, space, &area->spacedata) {
|
|
|
|
|
if (space->spacetype == SPACE_NODE) {
|
|
|
|
|
SpaceNode *snode = (SpaceNode *)space;
|
|
|
|
|
snode->overlay.flag |= SN_OVERLAY_SHOW_OVERLAYS;
|
|
|
|
|
snode->overlay.flag |= SN_OVERLAY_SHOW_WIRE_COLORS;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-22 23:56:05 +02:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 38)) {
|
|
|
|
|
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
|
|
|
|
|
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
|
|
|
|
LISTBASE_FOREACH (SpaceLink *, space, &area->spacedata) {
|
|
|
|
|
if (space->spacetype == SPACE_FILE) {
|
|
|
|
|
SpaceFile *sfile = (SpaceFile *)space;
|
|
|
|
|
FileAssetSelectParams *asset_params = sfile->asset_params;
|
|
|
|
|
if (asset_params) {
|
|
|
|
|
asset_params->base_params.filter_id = FILTER_ID_ALL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-26 13:37:31 +09:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 39)) {
|
|
|
|
|
LISTBASE_FOREACH (wmWindowManager *, wm, &bmain->wm) {
|
|
|
|
|
wm->xr.session_settings.base_scale = 1.0f;
|
|
|
|
|
wm->xr.session_settings.draw_flags |= (V3D_OFSDRAW_SHOW_SELECTION |
|
|
|
|
|
V3D_OFSDRAW_XR_SHOW_CONTROLLERS |
|
|
|
|
|
V3D_OFSDRAW_XR_SHOW_CUSTOM_OVERLAYS);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-27 18:20:40 +02:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 40)) {
|
2021-10-24 11:19:10 +02:00
|
|
|
/* Update the `idnames` for renamed geometry and function nodes. */
|
|
|
|
|
LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
|
|
|
|
|
if (ntree->type != NTREE_GEOMETRY) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
version_node_id(ntree, FN_NODE_SLICE_STRING, "FunctionNodeSliceString");
|
2021-10-25 11:37:45 +02:00
|
|
|
version_geometry_nodes_set_position_node_offset(ntree);
|
2021-10-24 11:19:10 +02:00
|
|
|
}
|
2021-10-26 11:25:32 +02:00
|
|
|
|
|
|
|
|
/* Add storage to viewer node. */
|
|
|
|
|
LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
|
|
|
|
|
if (ntree->type != NTREE_GEOMETRY) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
|
|
|
|
|
if (node->type == GEO_NODE_VIEWER) {
|
|
|
|
|
if (node->storage == NULL) {
|
|
|
|
|
NodeGeometryViewer *data = (NodeGeometryViewer *)MEM_callocN(
|
|
|
|
|
sizeof(NodeGeometryViewer), __func__);
|
|
|
|
|
data->data_type = CD_PROP_FLOAT;
|
|
|
|
|
node->storage = data;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-10-27 08:36:59 -05:00
|
|
|
|
|
|
|
|
LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
|
|
|
|
|
if (ntree->type == NTREE_GEOMETRY) {
|
|
|
|
|
version_node_input_socket_name(
|
|
|
|
|
ntree, GEO_NODE_DISTRIBUTE_POINTS_ON_FACES, "Geometry", "Mesh");
|
|
|
|
|
version_node_input_socket_name(ntree, GEO_NODE_POINTS_TO_VOLUME, "Geometry", "Points");
|
|
|
|
|
version_node_output_socket_name(ntree, GEO_NODE_POINTS_TO_VOLUME, "Geometry", "Volume");
|
|
|
|
|
version_node_socket_name(ntree, GEO_NODE_SUBDIVISION_SURFACE, "Geometry", "Mesh");
|
2021-10-27 09:33:50 -05:00
|
|
|
version_node_socket_name(ntree, GEO_NODE_RESAMPLE_CURVE, "Geometry", "Curve");
|
|
|
|
|
version_node_socket_name(ntree, GEO_NODE_SUBDIVIDE_CURVE, "Geometry", "Curve");
|
|
|
|
|
version_node_socket_name(ntree, GEO_NODE_SET_CURVE_RADIUS, "Geometry", "Curve");
|
|
|
|
|
version_node_socket_name(ntree, GEO_NODE_SET_CURVE_TILT, "Geometry", "Curve");
|
|
|
|
|
version_node_socket_name(ntree, GEO_NODE_SET_CURVE_HANDLES, "Geometry", "Curve");
|
|
|
|
|
version_node_socket_name(ntree, GEO_NODE_TRANSLATE_INSTANCES, "Geometry", "Instances");
|
|
|
|
|
version_node_socket_name(ntree, GEO_NODE_ROTATE_INSTANCES, "Geometry", "Instances");
|
|
|
|
|
version_node_socket_name(ntree, GEO_NODE_SCALE_INSTANCES, "Geometry", "Instances");
|
|
|
|
|
version_node_output_socket_name(ntree, GEO_NODE_MESH_BOOLEAN, "Geometry", "Mesh");
|
|
|
|
|
version_node_input_socket_name(ntree, GEO_NODE_MESH_BOOLEAN, "Geometry 1", "Mesh 1");
|
|
|
|
|
version_node_input_socket_name(ntree, GEO_NODE_MESH_BOOLEAN, "Geometry 2", "Mesh 2");
|
|
|
|
|
version_node_socket_name(ntree, GEO_NODE_SUBDIVIDE_MESH, "Geometry", "Mesh");
|
|
|
|
|
version_node_socket_name(ntree, GEO_NODE_TRIANGULATE, "Geometry", "Mesh");
|
|
|
|
|
version_node_output_socket_name(ntree, GEO_NODE_MESH_PRIMITIVE_CONE, "Geometry", "Mesh");
|
|
|
|
|
version_node_output_socket_name(ntree, GEO_NODE_MESH_PRIMITIVE_CUBE, "Geometry", "Mesh");
|
|
|
|
|
version_node_output_socket_name(
|
|
|
|
|
ntree, GEO_NODE_MESH_PRIMITIVE_CYLINDER, "Geometry", "Mesh");
|
|
|
|
|
version_node_output_socket_name(ntree, GEO_NODE_MESH_PRIMITIVE_GRID, "Geometry", "Mesh");
|
|
|
|
|
version_node_output_socket_name(
|
|
|
|
|
ntree, GEO_NODE_MESH_PRIMITIVE_ICO_SPHERE, "Geometry", "Mesh");
|
|
|
|
|
version_node_output_socket_name(ntree, GEO_NODE_MESH_PRIMITIVE_CIRCLE, "Geometry", "Mesh");
|
|
|
|
|
version_node_output_socket_name(ntree, GEO_NODE_MESH_PRIMITIVE_LINE, "Geometry", "Mesh");
|
|
|
|
|
version_node_output_socket_name(
|
|
|
|
|
ntree, GEO_NODE_MESH_PRIMITIVE_UV_SPHERE, "Geometry", "Mesh");
|
|
|
|
|
version_node_socket_name(ntree, GEO_NODE_SET_POINT_RADIUS, "Geometry", "Points");
|
2021-10-27 08:36:59 -05:00
|
|
|
}
|
|
|
|
|
}
|
2021-10-08 14:30:08 +02:00
|
|
|
}
|
2021-10-27 18:20:40 +02:00
|
|
|
|
2021-11-19 09:33:52 +01:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 42)) {
|
2021-11-15 08:52:58 -06:00
|
|
|
/* Use consistent socket identifiers for the math node.
|
|
|
|
|
* The code to make unique identifiers from the names was inconsistent. */
|
2021-11-12 12:22:43 -06:00
|
|
|
FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
|
|
|
|
|
if (ntree->type != NTREE_CUSTOM) {
|
|
|
|
|
version_node_tree_socket_id_delim(ntree);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
FOREACH_NODETREE_END;
|
2021-11-17 02:44:47 +01:00
|
|
|
|
|
|
|
|
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
|
|
|
|
|
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
|
|
|
|
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
|
|
|
|
|
if (sl->spacetype == SPACE_SEQ) {
|
|
|
|
|
ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
|
|
|
|
|
&sl->regionbase;
|
|
|
|
|
LISTBASE_FOREACH (ARegion *, region, regionbase) {
|
|
|
|
|
if (region->regiontype == RGN_TYPE_WINDOW) {
|
|
|
|
|
region->v2d.min[1] = 1.0f;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-11-17 01:42:42 +01:00
|
|
|
|
|
|
|
|
/* Change minimum zoom to 0.05f in the node editor. */
|
|
|
|
|
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
|
|
|
|
|
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
|
|
|
|
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
|
|
|
|
|
if (sl->spacetype == SPACE_NODE) {
|
|
|
|
|
ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
|
|
|
|
|
&sl->regionbase;
|
|
|
|
|
LISTBASE_FOREACH (ARegion *, region, regionbase) {
|
|
|
|
|
if (region->regiontype == RGN_TYPE_WINDOW) {
|
|
|
|
|
if (region->v2d.minzoom > 0.05f) {
|
|
|
|
|
region->v2d.minzoom = 0.05f;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-11-19 06:22:47 +01:00
|
|
|
|
2021-11-19 06:10:26 +01:00
|
|
|
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
|
|
|
|
Editing *ed = SEQ_editing_get(scene);
|
|
|
|
|
/* Make sure range of meta strips is correct.
|
|
|
|
|
* It was possible to save .blend file with incorrect state of meta strip
|
|
|
|
|
* range. The root cause is expected to be fixed, but need to ensure files
|
|
|
|
|
* with invalid meta strip range are corrected. */
|
2021-11-19 10:05:18 +01:00
|
|
|
if (ed != NULL) {
|
|
|
|
|
SEQ_for_each_callback(&ed->seqbase, version_fix_seq_meta_range, scene);
|
|
|
|
|
}
|
2021-11-19 06:10:26 +01:00
|
|
|
}
|
2021-10-27 18:20:40 +02:00
|
|
|
}
|
2021-11-19 09:33:52 +01:00
|
|
|
|
2021-11-30 09:04:50 +11:00
|
|
|
/* Special case to handle older in-development 3.1 files, before change from 3.0 branch gets
|
|
|
|
|
* merged in master. */
|
2021-11-19 16:10:28 +01:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 300, 42) ||
|
|
|
|
|
(bmain->versionfile == 301 && !MAIN_VERSION_ATLEAST(bmain, 301, 3))) {
|
|
|
|
|
/* Update LibOverride operations regarding insertions in RNA collections (i.e. modifiers,
|
|
|
|
|
* constraints and NLA tracks). */
|
|
|
|
|
ID *id_iter;
|
|
|
|
|
FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
|
|
|
|
|
if (ID_IS_OVERRIDE_LIBRARY_REAL(id_iter)) {
|
|
|
|
|
version_liboverride_rnacollections_insertion_animdata(id_iter);
|
|
|
|
|
if (GS(id_iter->name) == ID_OB) {
|
|
|
|
|
version_liboverride_rnacollections_insertion_object((Object *)id_iter);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
FOREACH_MAIN_ID_END;
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-01 21:45:41 -05:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 301, 4)) {
|
2021-11-30 07:21:14 -06:00
|
|
|
LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
|
|
|
|
|
if (ntree->type != NTREE_GEOMETRY) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
version_node_id(ntree, GEO_NODE_CURVE_SPLINE_PARAMETER, "GeometryNodeSplineParameter");
|
|
|
|
|
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
|
|
|
|
|
if (node->type == GEO_NODE_CURVE_SPLINE_PARAMETER) {
|
|
|
|
|
version_node_add_socket_if_not_exist(
|
|
|
|
|
ntree, node, SOCK_OUT, SOCK_INT, PROP_NONE, "Index", "Index");
|
|
|
|
|
}
|
Geometry Nodes: Generalized Compare Node
Replace compare floats node with a generalized compare node. The node
allows for the comparison of float, int, string, color, and vector.
The datatypes support the following operators:
Float, Int: <, >, <=, >=, ==, !=
String: ==, !=
Color: ==, !=, lighter, darker
(using rgb_to_grayscale value as the brightness value)
Vector Supports 5 comparison modes for: ==, !=, <, >, <=, >=
Average: The average of the components of the vectors are compared.
Dot Product: The dot product of the vectors are compared.
Direction: The angle between the vectors is compared to an angle
Element-wise: The individual components of the vectors are compared.
Length: The lengths of the vectors are compared.
Differential Revision: https://developer.blender.org/D13228
2021-12-01 09:36:25 -06:00
|
|
|
|
|
|
|
|
/* Convert float compare into a more general compare node. */
|
|
|
|
|
if (node->type == FN_NODE_COMPARE) {
|
|
|
|
|
if (node->storage == NULL) {
|
|
|
|
|
NodeFunctionCompare *data = (NodeFunctionCompare *)MEM_callocN(
|
|
|
|
|
sizeof(NodeFunctionCompare), __func__);
|
|
|
|
|
data->data_type = SOCK_FLOAT;
|
|
|
|
|
data->operation = node->custom1;
|
|
|
|
|
strcpy(node->idname, "FunctionNodeCompare");
|
|
|
|
|
node->storage = data;
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-11-30 07:21:14 -06:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-01 21:45:41 -05:00
|
|
|
/* Add a toggle for the breadcrumbs overlay in the node editor. */
|
|
|
|
|
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
|
|
|
|
|
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
|
|
|
|
LISTBASE_FOREACH (SpaceLink *, space, &area->spacedata) {
|
|
|
|
|
if (space->spacetype == SPACE_NODE) {
|
|
|
|
|
SpaceNode *snode = (SpaceNode *)space;
|
|
|
|
|
snode->overlay.flag |= SN_OVERLAY_SHOW_PATH;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
Geometry Nodes: support instance attributes when realizing instances
This patch refactors the instance-realization code and adds new functionality.
* Named and anonymous attributes are propagated from instances to the
realized geometry. If the same attribute exists on the geometry and on an
instance, the attribute on the geometry has precedence.
* The id attribute has special handling to avoid creating the same id on many
output points. This is necessary to make e.g. the Random Value node work
as expected afterwards.
Realizing instance attributes has an effect on existing files, especially due to the
id attribute. To avoid breaking existing files, the Realize Instances node now has
a legacy option that is enabled for all already existing Realize Instances nodes.
Removing this legacy behavior does affect some existing files (although not many).
We can decide whether it's worth to remove the old behavior as a separate step.
This refactor also improves performance when realizing instances. That is mainly
due to multi-threading. See D13446 to get the file used for benchmarking. The
curve code is not as optimized as it could be yet. That's mainly because the storage
for these attributes might change soonish and it wasn't worth optimizing for the
current storage format right now.
```
1,000,000 x mesh vertex: 530 ms -> 130 ms
1,000,000 x simple cube: 1290 ms -> 190 ms
1,000,000 x point: 1000 ms -> 150 ms
1,000,000 x curve spiral: 1740 ms -> 330 ms
1,000,000 x curve line: 1110 ms -> 210 ms
10,000 x subdivided cylinder: 170 ms -> 40 ms
10 x subdivided spiral: 180 ms -> 180 ms
```
Differential Revision: https://developer.blender.org/D13446
2021-12-14 15:57:58 +01:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 301, 5)) {
|
|
|
|
|
LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
|
|
|
|
|
if (ntree->type != NTREE_GEOMETRY) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
|
|
|
|
|
if (node->type != GEO_NODE_REALIZE_INSTANCES) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
node->custom1 |= GEO_NODE_REALIZE_INSTANCES_LEGACY_BEHAVIOR;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-28 11:11:11 +01:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 301, 6)) {
|
2021-12-17 13:49:53 +01:00
|
|
|
/* Add node storage for map range node. */
|
|
|
|
|
FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
|
|
|
|
|
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
|
|
|
|
|
if (node->type == SH_NODE_MAP_RANGE) {
|
|
|
|
|
if (node->storage == NULL) {
|
|
|
|
|
NodeMapRange *data = MEM_callocN(sizeof(NodeMapRange), __func__);
|
|
|
|
|
data->clamp = node->custom1;
|
|
|
|
|
data->data_type = CD_PROP_FLOAT;
|
|
|
|
|
data->interpolation_type = node->custom2;
|
|
|
|
|
node->storage = data;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
FOREACH_NODETREE_END;
|
2022-01-03 12:54:40 -06:00
|
|
|
|
|
|
|
|
/* Update spreadsheet data set region type. */
|
|
|
|
|
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
|
|
|
|
|
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
|
|
|
|
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
|
|
|
|
|
if (sl->spacetype == SPACE_SPREADSHEET) {
|
|
|
|
|
ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
|
|
|
|
|
&sl->regionbase;
|
|
|
|
|
LISTBASE_FOREACH (ARegion *, region, regionbase) {
|
|
|
|
|
if (region->regiontype == RGN_TYPE_CHANNELS) {
|
|
|
|
|
region->regiontype = RGN_TYPE_TOOLS;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-01-06 15:42:45 +03:00
|
|
|
|
|
|
|
|
/* Initialize the bone wireframe opacity setting. */
|
|
|
|
|
if (!DNA_struct_elem_find(fd->filesdna, "View3DOverlay", "float", "bone_wire_alpha")) {
|
|
|
|
|
for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
|
|
|
|
|
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
|
|
|
|
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
|
|
|
|
|
if (sl->spacetype == SPACE_VIEW3D) {
|
|
|
|
|
View3D *v3d = (View3D *)sl;
|
|
|
|
|
v3d->overlay.bone_wire_alpha = 1.0f;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-01-13 19:17:03 +01:00
|
|
|
|
2022-01-18 09:20:31 -06:00
|
|
|
/* Rename sockets on multiple nodes */
|
2022-01-13 19:17:03 +01:00
|
|
|
LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
|
|
|
|
|
if (ntree->type == NTREE_GEOMETRY) {
|
|
|
|
|
version_node_output_socket_name(
|
|
|
|
|
ntree, GEO_NODE_STRING_TO_CURVES, "Curves", "Curve Instances");
|
2022-01-18 09:20:31 -06:00
|
|
|
version_node_output_socket_name(
|
|
|
|
|
ntree, GEO_NODE_INPUT_MESH_EDGE_ANGLE, "Angle", "Unsigned Angle");
|
2022-01-21 09:01:18 -06:00
|
|
|
version_node_output_socket_name(
|
|
|
|
|
ntree, GEO_NODE_INPUT_MESH_ISLAND, "Index", "Island Index");
|
2022-01-14 16:42:04 -06:00
|
|
|
version_node_input_socket_name(ntree, GEO_NODE_TRANSFER_ATTRIBUTE, "Target", "Source");
|
2022-01-13 19:17:03 +01:00
|
|
|
}
|
|
|
|
|
}
|
2021-11-19 09:33:52 +01:00
|
|
|
}
|
2022-01-28 11:11:11 +01:00
|
|
|
|
2022-02-21 18:15:17 +03:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 301, 7) ||
|
|
|
|
|
(bmain->versionfile == 302 && !MAIN_VERSION_ATLEAST(bmain, 302, 4))) {
|
2022-02-21 18:08:53 +03:00
|
|
|
/* Duplicate value for two flags that mistakenly had the same numeric value. */
|
|
|
|
|
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
|
|
|
|
|
LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
|
|
|
|
|
if (md->type == eModifierType_WeightVGProximity) {
|
|
|
|
|
WeightVGProximityModifierData *wpmd = (WeightVGProximityModifierData *)md;
|
|
|
|
|
if (wpmd->proximity_flags & MOD_WVG_PROXIMITY_INVERT_VGROUP_MASK) {
|
|
|
|
|
wpmd->proximity_flags |= MOD_WVG_PROXIMITY_WEIGHTS_NORMALIZE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-07 10:31:39 +01:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 302, 2)) {
|
|
|
|
|
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
|
|
|
|
if (scene->ed != NULL) {
|
|
|
|
|
SEQ_for_each_callback(&scene->ed->seqbase, seq_transform_filter_set, NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-10 18:34:27 -06:00
|
|
|
if (!MAIN_VERSION_ATLEAST(bmain, 302, 6)) {
|
2022-03-09 16:10:19 +11:00
|
|
|
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
|
|
|
|
ToolSettings *ts = scene->toolsettings;
|
|
|
|
|
if (ts->uv_relax_method == 0) {
|
|
|
|
|
ts->uv_relax_method = UV_SCULPT_TOOL_RELAX_LAPLACIAN;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-03-10 18:33:04 -03:00
|
|
|
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
|
|
|
|
ToolSettings *tool_settings = scene->toolsettings;
|
|
|
|
|
tool_settings->snap_flag_seq = tool_settings->snap_flag & ~(SCE_SNAP | SCE_SNAP_SEQ);
|
|
|
|
|
if (tool_settings->snap_flag & SCE_SNAP_SEQ) {
|
|
|
|
|
tool_settings->snap_flag_seq |= SCE_SNAP;
|
|
|
|
|
tool_settings->snap_flag &= ~SCE_SNAP_SEQ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tool_settings->snap_flag_node = tool_settings->snap_flag;
|
|
|
|
|
tool_settings->snap_uv_flag |= tool_settings->snap_flag & SCE_SNAP;
|
|
|
|
|
}
|
2022-03-10 18:34:27 -06:00
|
|
|
|
|
|
|
|
/* Alter NURBS knot mode flags to fit new modes. */
|
|
|
|
|
LISTBASE_FOREACH (Curve *, curve, &bmain->curves) {
|
|
|
|
|
LISTBASE_FOREACH (Nurb *, nurb, &curve->nurb) {
|
|
|
|
|
/* Previously other flags were ignored if CU_NURB_CYCLIC is set. */
|
|
|
|
|
if (nurb->flagu & CU_NURB_CYCLIC) {
|
|
|
|
|
nurb->flagu = CU_NURB_CYCLIC;
|
|
|
|
|
}
|
|
|
|
|
/* CU_NURB_BEZIER and CU_NURB_ENDPOINT were ignored if combined. */
|
|
|
|
|
else if (nurb->flagu & CU_NURB_BEZIER && nurb->flagu & CU_NURB_ENDPOINT) {
|
|
|
|
|
nurb->flagu &= ~(CU_NURB_BEZIER | CU_NURB_ENDPOINT);
|
|
|
|
|
BKE_nurb_knot_calc_u(nurb);
|
|
|
|
|
}
|
|
|
|
|
/* Bezier NURBS of order 3 were clamped to first control point. */
|
|
|
|
|
else if (nurb->orderu == 3 && (nurb->flagu & CU_NURB_BEZIER)) {
|
|
|
|
|
nurb->flagu |= CU_NURB_ENDPOINT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Previously other flags were ignored if CU_NURB_CYCLIC is set. */
|
|
|
|
|
if (nurb->flagv & CU_NURB_CYCLIC) {
|
|
|
|
|
nurb->flagv = CU_NURB_CYCLIC;
|
|
|
|
|
}
|
|
|
|
|
/* CU_NURB_BEZIER and CU_NURB_ENDPOINT were ignored if used together. */
|
|
|
|
|
else if (nurb->flagv & CU_NURB_BEZIER && nurb->flagv & CU_NURB_ENDPOINT) {
|
|
|
|
|
nurb->flagv &= ~(CU_NURB_BEZIER | CU_NURB_ENDPOINT);
|
|
|
|
|
BKE_nurb_knot_calc_v(nurb);
|
|
|
|
|
}
|
|
|
|
|
/* Bezier NURBS of order 3 were clamped to first control point. */
|
|
|
|
|
else if (nurb->orderv == 3 && (nurb->flagv & CU_NURB_BEZIER)) {
|
|
|
|
|
nurb->flagv |= CU_NURB_ENDPOINT;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Versioning code until next subversion bump goes here.
|
|
|
|
|
*
|
|
|
|
|
* \note Be sure to check when bumping the version:
|
|
|
|
|
* - "versioning_userdef.c", #blo_do_versions_userdef
|
|
|
|
|
* - "versioning_userdef.c", #do_versions_theme
|
|
|
|
|
*
|
|
|
|
|
* \note Keep this message at the bottom of the function.
|
|
|
|
|
*/
|
|
|
|
|
{
|
|
|
|
|
/* Keep this block, even when empty. */
|
2022-03-21 18:54:31 +01:00
|
|
|
|
|
|
|
|
/* Initialize brush curves sculpt settings. */
|
|
|
|
|
LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
|
|
|
|
|
if (brush->ob_mode != OB_MODE_SCULPT_CURVES) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (brush->curves_sculpt_settings != NULL) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
brush->curves_sculpt_settings = MEM_callocN(sizeof(BrushCurvesSculptSettings), __func__);
|
|
|
|
|
brush->curves_sculpt_settings->add_amount = 1;
|
|
|
|
|
}
|
|
|
|
|
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
|
|
|
|
if (scene->toolsettings && scene->toolsettings->curves_sculpt &&
|
|
|
|
|
scene->toolsettings->curves_sculpt->curve_length == 0.0f) {
|
|
|
|
|
scene->toolsettings->curves_sculpt->curve_length = 0.3f;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-03-24 17:25:24 +01:00
|
|
|
|
|
|
|
|
for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
|
|
|
|
|
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
|
|
|
|
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
|
|
|
|
|
if (sl->spacetype == SPACE_OUTLINER) {
|
|
|
|
|
SpaceOutliner *space_outliner = (SpaceOutliner *)sl;
|
|
|
|
|
space_outliner->filter &= ~SO_FILTER_CLEARED_1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-01-28 11:11:11 +01:00
|
|
|
}
|
2022-01-06 19:00:35 +11:00
|
|
|
}
|