WIP: Brush assets project #106303

Draft
Julian Eisel wants to merge 352 commits from brush-assets-project into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
169 changed files with 1966 additions and 979 deletions
Showing only changes of commit d2e56527e5 - Show all commits

View File

@ -8,7 +8,7 @@ if "%BUILD_WITH_SCCACHE%"=="1" (
)
if "%WITH_CLANG%"=="1" (
set CLANG_CMAKE_ARGS=-T"llvm"
set CLANG_CMAKE_ARGS=-T"ClangCl"
)
if "%WITH_ASAN%"=="1" (

View File

@ -122,11 +122,23 @@ elseif(CMAKE_COMPILER_IS_GNUCC OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
check_cxx_compiler_flag(-mavx2 CXX_HAS_AVX2)
# Assume no signal trapping for better code generation.
set(CYCLES_KERNEL_FLAGS "-fno-trapping-math")
# Avoid overhead of setting errno for NaNs.
string(APPEND CYCLES_KERNEL_FLAGS " -fno-math-errno")
# Let compiler optimize 0.0 - x without worrying about signed zeros.
string(APPEND CYCLES_KERNEL_FLAGS " -fno-signed-zeros")
# We need to omit or modify specific flags to pass through clang-cl to prevent
# unknown flag errors
if (WIN32 AND MSVC)
# Pass clang flags directly to clang otherwise. Clang-cl doesn't recognize
# these flags by default
set(CYCLES_KERNEL_FLAGS " /clang:-fno-trapping-math")
# Avoid overhead of setting errno for NaNs.
string(APPEND CYCLES_KERNEL_FLAGS " /clang:-fno-math-errno")
# Let compiler optimize 0.0 - x without worrying about signed zeros.
string(APPEND CYCLES_KERNEL_FLAGS " /clang:-fno-signed-zeros")
else ()
set(CYCLES_KERNEL_FLAGS " -fno-trapping-math")
# Avoid overhead of setting errno for NaNs.
string(APPEND CYCLES_KERNEL_FLAGS " -fno-math-errno")
# Let compiler optimize 0.0 - x without worrying about signed zeros.
string(APPEND CYCLES_KERNEL_FLAGS " -fno-signed-zeros")
endif()
if(CMAKE_COMPILER_IS_GNUCC)
# Assume no signal trapping for better code generation.

View File

@ -817,7 +817,6 @@ void GeometryManager::device_update(Device *device,
}
/* Update images needed for true displacement. */
bool old_need_object_flags_update = false;
if (true_displacement_used || curve_shadow_transparency_used) {
scoped_callback_timer timer([scene](double time) {
if (scene->update_stats) {
@ -826,7 +825,6 @@ void GeometryManager::device_update(Device *device,
}
});
device_update_displacement_images(device, scene, progress);
old_need_object_flags_update = scene->object_manager->need_flags_update;
scene->object_manager->device_update_flags(device, dscene, scene, progress, false);
}
@ -1011,16 +1009,6 @@ void GeometryManager::device_update(Device *device,
}
}
if (true_displacement_used) {
/* Re-tag flags for update, so they're re-evaluated
* for meshes with correct bounding boxes.
*
* This wouldn't cause wrong results, just true
* displacement might be less optimal to calculate.
*/
scene->object_manager->need_flags_update = old_need_object_flags_update;
}
/* unset flags */
foreach (Geometry *geom, scene->geometry) {

View File

@ -366,6 +366,7 @@ float Object::compute_volume_step_size() const
if (step_size == FLT_MAX) {
/* Fall back to 1/10th of bounds for procedural volumes. */
assert(bounds.valid());
step_size = 0.1f * average(bounds.size());
}
@ -858,8 +859,15 @@ void ObjectManager::device_update_flags(
}
});
update_flags = UPDATE_NONE;
need_flags_update = false;
if (bounds_valid) {
/* Object flags and calculations related to volume depend on proper bounds calculated, which
* might not be available yet when object flags are updated for displacement or hair
* transparency calculation. In this case do not clear the need_flags_update, so that these
* values which depend on bounds are re-calculated when the device_update process comes back
* here from the "Updating Objects Flags" stage. */
update_flags = UPDATE_NONE;
need_flags_update = false;
}
if (scene->objects.size() == 0) {
return;

View File

@ -717,6 +717,10 @@ const bTheme U_theme_default = {
.back = RGBA(0x3d3d3dff),
.sub_back = RGBA(0x0000001f),
},
.asset_shelf = {
.header_back = RGBA(0x1d1d1dff),
.back = RGBA(0x303030ff),
},
.grid = RGBA(0x303030ff),
.wire_edit = RGBA(0xc0c0c0ff),
.vertex_select = RGBA(0xff8500ff),

View File

@ -610,6 +610,7 @@ class NODE_MT_category_utilities_matrix(Menu):
node_add_menu.add_node_type(layout, "FunctionNodeCombineTransform")
node_add_menu.add_node_type(layout, "FunctionNodeInvertMatrix")
node_add_menu.add_node_type(layout, "FunctionNodeMatrixMultiply")
node_add_menu.add_node_type(layout, "FunctionNodeProjectPoint")
node_add_menu.add_node_type(layout, "FunctionNodeSeparateTransform")
node_add_menu.add_node_type(layout, "FunctionNodeTransformDirection")
node_add_menu.add_node_type(layout, "FunctionNodeTransformPoint")

View File

@ -75,6 +75,7 @@ class IMAGE_MT_view(Menu):
layout.prop(sima, "show_region_toolbar")
layout.prop(sima, "show_region_ui")
layout.prop(sima, "show_region_tool_header")
layout.prop(sima, "show_region_asset_shelf")
layout.prop(sima, "show_region_hud")
layout.separator()

View File

@ -2466,6 +2466,9 @@ class SEQUENCER_PT_view(SequencerButtonsPanel_Output, Panel):
if st.display_mode == 'IMAGE':
col.prop(st, "show_overexposed")
if ed:
col.prop(ed, "show_missing_media")
class SEQUENCER_PT_view_cursor(SequencerButtonsPanel_Output, Panel):
bl_category = "View"

View File

@ -29,7 +29,7 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
#define BLENDER_FILE_SUBVERSION 20
#define BLENDER_FILE_SUBVERSION 23
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and cancel loading the file, showing a warning to

View File

@ -101,6 +101,12 @@ Collection *BKE_collection_master_add(Scene *scene);
bool BKE_collection_has_object(Collection *collection, const Object *ob);
bool BKE_collection_has_object_recursive(Collection *collection, Object *ob);
bool BKE_collection_has_object_recursive_instanced(Collection *collection, Object *ob);
/**
* Find whether an evaluated object's original ID is contained or instanced by any object in this
* collection. The collection is expected to be an evaluated data-block too.
*/
bool BKE_collection_has_object_recursive_instanced_orig_id(Collection *collection_eval,
Object *object_eval);
Collection *BKE_collection_object_find(Main *bmain,
Scene *scene,
Collection *collection,

View File

@ -341,11 +341,11 @@ void mesh_hide_vert_flush(Mesh &mesh);
/** Make vertex and edge visibility consistent with faces. */
void mesh_hide_face_flush(Mesh &mesh);
/** Make edge and face visibility consistent with vertices. */
/** Make edge and face selection consistent with vertices. */
void mesh_select_vert_flush(Mesh &mesh);
/** Make vertex and face visibility consistent with edges. */
/** Make vertex and face selection consistent with edges. */
void mesh_select_edge_flush(Mesh &mesh);
/** Make vertex and edge visibility consistent with faces. */
/** Make vertex and edge selection consistent with faces. */
void mesh_select_face_flush(Mesh &mesh);
/** Set the default name when adding a color attribute if there is no default yet. */

View File

@ -1320,6 +1320,7 @@ void BKE_nodetree_remove_layer_n(bNodeTree *ntree, Scene *scene, int layer_index
#define FN_NODE_SEPARATE_TRANSFORM 1236
#define FN_NODE_INVERT_MATRIX 1237
#define FN_NODE_TRANSPOSE_MATRIX 1238
#define FN_NODE_PROJECT_POINT 1239
/** \} */

View File

@ -221,27 +221,28 @@ static void action_blend_read_data(BlendDataReader *reader, ID *id)
{
bAction *act = (bAction *)id;
BLO_read_list(reader, &act->curves);
BLO_read_list(reader, &act->chanbase); /* XXX deprecated - old animation system */
BLO_read_list(reader, &act->groups);
BLO_read_list(reader, &act->markers);
BLO_read_struct_list(reader, FCurve, &act->curves);
BLO_read_struct_list(
reader, bActionChannel, &act->chanbase); /* XXX deprecated - old animation system */
BLO_read_struct_list(reader, bActionGroup, &act->groups);
BLO_read_struct_list(reader, TimeMarker, &act->markers);
/* XXX deprecated - old animation system <<< */
LISTBASE_FOREACH (bActionChannel *, achan, &act->chanbase) {
BLO_read_data_address(reader, &achan->grp);
BLO_read_struct(reader, bActionGroup, &achan->grp);
BLO_read_list(reader, &achan->constraintChannels);
BLO_read_struct_list(reader, bConstraintChannel, &achan->constraintChannels);
}
/* >>> XXX deprecated - old animation system */
BKE_fcurve_blend_read_data_listbase(reader, &act->curves);
LISTBASE_FOREACH (bActionGroup *, agrp, &act->groups) {
BLO_read_data_address(reader, &agrp->channels.first);
BLO_read_data_address(reader, &agrp->channels.last);
BLO_read_struct(reader, FCurve, &agrp->channels.first);
BLO_read_struct(reader, FCurve, &agrp->channels.last);
}
BLO_read_data_address(reader, &act->preview);
BLO_read_struct(reader, PreviewImage, &act->preview);
BKE_previewimg_blend_read(reader, act->preview);
}
@ -1869,8 +1870,8 @@ void BKE_pose_blend_read_data(BlendDataReader *reader, ID *id_owner, bPose *pose
return;
}
BLO_read_list(reader, &pose->chanbase);
BLO_read_list(reader, &pose->agroups);
BLO_read_struct_list(reader, bPoseChannel, &pose->chanbase);
BLO_read_struct_list(reader, bActionGroup, &pose->agroups);
pose->chanhash = nullptr;
pose->chan_array = nullptr;
@ -1880,19 +1881,19 @@ void BKE_pose_blend_read_data(BlendDataReader *reader, ID *id_owner, bPose *pose
BKE_pose_channel_session_uid_generate(pchan);
pchan->bone = nullptr;
BLO_read_data_address(reader, &pchan->parent);
BLO_read_data_address(reader, &pchan->child);
BLO_read_data_address(reader, &pchan->custom_tx);
BLO_read_struct(reader, bPoseChannel, &pchan->parent);
BLO_read_struct(reader, bPoseChannel, &pchan->child);
BLO_read_struct(reader, bPoseChannel, &pchan->custom_tx);
BLO_read_data_address(reader, &pchan->bbone_prev);
BLO_read_data_address(reader, &pchan->bbone_next);
BLO_read_struct(reader, bPoseChannel, &pchan->bbone_prev);
BLO_read_struct(reader, bPoseChannel, &pchan->bbone_next);
BKE_constraint_blend_read_data(reader, id_owner, &pchan->constraints);
BLO_read_data_address(reader, &pchan->prop);
BLO_read_struct(reader, IDProperty, &pchan->prop);
IDP_BlendDataRead(reader, &pchan->prop);
BLO_read_data_address(reader, &pchan->mpath);
BLO_read_struct(reader, bMotionPath, &pchan->mpath);
if (pchan->mpath) {
animviz_motionpath_blend_read_data(reader, pchan->mpath);
}

View File

@ -1499,13 +1499,13 @@ void BKE_animdata_blend_read_data(BlendDataReader *reader, ID *id)
return;
}
AnimData *adt = static_cast<AnimData *>(BLO_read_data_address(reader, &iat->adt));
AnimData *adt = static_cast<AnimData *>(BLO_read_struct(reader, AnimData, &iat->adt));
if (adt == nullptr) {
return;
}
/* link drivers */
BLO_read_list(reader, &adt->drivers);
BLO_read_struct_list(reader, FCurve, &adt->drivers);
BKE_fcurve_blend_read_data_listbase(reader, &adt->drivers);
adt->driver_array = nullptr;
@ -1513,7 +1513,7 @@ void BKE_animdata_blend_read_data(BlendDataReader *reader, ID *id)
/* TODO... */
/* link NLA-data */
BLO_read_list(reader, &adt->nla_tracks);
BLO_read_struct_list(reader, NlaTrack, &adt->nla_tracks);
BKE_nla_blend_read_data(reader, id, &adt->nla_tracks);
/* relink active track/strip - even though strictly speaking this should only be used
@ -1522,8 +1522,8 @@ void BKE_animdata_blend_read_data(BlendDataReader *reader, ID *id)
*/
/* TODO: it's not really nice that anyone should be able to save the file in this
* state, but it's going to be too hard to enforce this single case. */
BLO_read_data_address(reader, &adt->act_track);
BLO_read_data_address(reader, &adt->actstrip);
BLO_read_struct(reader, NlaTrack, &adt->act_track);
BLO_read_struct(reader, NlaStrip, &adt->actstrip);
if (ID_IS_LINKED(id)) {
/* Linked NLAs should never be in tweak mode, as you cannot exit that on linked data. */

View File

@ -315,11 +315,11 @@ void BKE_keyingsets_blend_read_data(BlendDataReader *reader, ListBase *list)
{
LISTBASE_FOREACH (KeyingSet *, ks, list) {
/* paths */
BLO_read_list(reader, &ks->paths);
BLO_read_struct_list(reader, KS_Path, &ks->paths);
LISTBASE_FOREACH (KS_Path *, ksp, &ks->paths) {
/* rna path */
BLO_read_data_address(reader, &ksp->rna_path);
BLO_read_string(reader, &ksp->rna_path);
}
}
}

View File

@ -233,7 +233,7 @@ void animviz_motionpath_blend_read_data(BlendDataReader *reader, bMotionPath *mp
}
/* relink points cache */
BLO_read_data_address(reader, &mpath->points);
BLO_read_struct_array(reader, bMotionPathVert, mpath->length, &mpath->points);
mpath->points_vbo = nullptr;
mpath->batch_line = nullptr;

View File

@ -161,7 +161,7 @@ static void read_channelbag(BlendDataReader *reader, animrig::ChannelBag &channe
BLO_read_pointer_array(reader, reinterpret_cast<void **>(&channelbag.fcurve_array));
for (int i = 0; i < channelbag.fcurve_array_num; i++) {
BLO_read_data_address(reader, &channelbag.fcurve_array[i]);
BLO_read_struct(reader, FCurve, &channelbag.fcurve_array[i]);
BKE_fcurve_blend_read_data(reader, channelbag.fcurve_array[i]);
}
}
@ -171,7 +171,7 @@ static void read_keyframe_strip(BlendDataReader *reader, animrig::KeyframeStrip
BLO_read_pointer_array(reader, reinterpret_cast<void **>(&strip.channelbags_array));
for (int i = 0; i < strip.channelbags_array_num; i++) {
BLO_read_data_address(reader, &strip.channelbags_array[i]);
BLO_read_struct(reader, AnimationChannelBag, &strip.channelbags_array[i]);
AnimationChannelBag *channelbag = strip.channelbags_array[i];
read_channelbag(reader, channelbag->wrap());
}
@ -182,12 +182,12 @@ static void read_animation_layers(BlendDataReader *reader, animrig::Animation &a
BLO_read_pointer_array(reader, reinterpret_cast<void **>(&anim.layer_array));
for (int layer_idx = 0; layer_idx < anim.layer_array_num; layer_idx++) {
BLO_read_data_address(reader, &anim.layer_array[layer_idx]);
BLO_read_struct(reader, AnimationLayer, &anim.layer_array[layer_idx]);
AnimationLayer *layer = anim.layer_array[layer_idx];
BLO_read_pointer_array(reader, reinterpret_cast<void **>(&layer->strip_array));
for (int strip_idx = 0; strip_idx < layer->strip_array_num; strip_idx++) {
BLO_read_data_address(reader, &layer->strip_array[strip_idx]);
BLO_read_struct(reader, AnimationStrip, &layer->strip_array[strip_idx]);
AnimationStrip *dna_strip = layer->strip_array[strip_idx];
animrig::Strip &strip = dna_strip->wrap();
@ -205,7 +205,7 @@ static void read_animation_bindings(BlendDataReader *reader, animrig::Animation
BLO_read_pointer_array(reader, reinterpret_cast<void **>(&anim.binding_array));
for (int i = 0; i < anim.binding_array_num; i++) {
BLO_read_data_address(reader, &anim.binding_array[i]);
BLO_read_struct(reader, AnimationBinding, &anim.binding_array[i]);
}
}

View File

@ -359,16 +359,16 @@ static void armature_blend_write(BlendWriter *writer, ID *id, const void *id_add
static void direct_link_bones(BlendDataReader *reader, Bone *bone)
{
BLO_read_data_address(reader, &bone->parent);
BLO_read_data_address(reader, &bone->prop);
BLO_read_struct(reader, Bone, &bone->parent);
BLO_read_struct(reader, IDProperty, &bone->prop);
IDP_BlendDataRead(reader, &bone->prop);
BLO_read_data_address(reader, &bone->bbone_next);
BLO_read_data_address(reader, &bone->bbone_prev);
BLO_read_struct(reader, Bone, &bone->bbone_next);
BLO_read_struct(reader, Bone, &bone->bbone_prev);
bone->flag &= ~(BONE_DRAW_ACTIVE | BONE_DRAW_LOCKED_WEIGHT);
BLO_read_list(reader, &bone->childbase);
BLO_read_struct_list(reader, Bone, &bone->childbase);
LISTBASE_FOREACH (Bone *, child, &bone->childbase) {
direct_link_bones(reader, child);
@ -379,19 +379,19 @@ static void direct_link_bones(BlendDataReader *reader, Bone *bone)
static void direct_link_bone_collection(BlendDataReader *reader, BoneCollection *bcoll)
{
BLO_read_data_address(reader, &bcoll->prop);
BLO_read_struct(reader, IDProperty, &bcoll->prop);
IDP_BlendDataRead(reader, &bcoll->prop);
BLO_read_list(reader, &bcoll->bones);
BLO_read_struct_list(reader, BoneCollectionMember, &bcoll->bones);
LISTBASE_FOREACH (BoneCollectionMember *, member, &bcoll->bones) {
BLO_read_data_address(reader, &member->bone);
BLO_read_struct(reader, Bone, &member->bone);
}
}
static void read_bone_collections(BlendDataReader *reader, bArmature *arm)
{
/* Read as listbase, but convert to an array on the armature. */
BLO_read_list(reader, &arm->collections_legacy);
BLO_read_struct_list(reader, BoneCollection, &arm->collections_legacy);
arm->collection_array_num = BLI_listbase_count(&arm->collections_legacy);
arm->collection_array = (BoneCollection **)MEM_malloc_arrayN(
arm->collection_array_num, sizeof(BoneCollection *), __func__);
@ -444,7 +444,7 @@ static void read_bone_collections(BlendDataReader *reader, bArmature *arm)
static void armature_blend_read_data(BlendDataReader *reader, ID *id)
{
bArmature *arm = (bArmature *)id;
BLO_read_list(reader, &arm->bonebase);
BLO_read_struct_list(reader, Bone, &arm->bonebase);
arm->bonehash = nullptr;
arm->edbo = nullptr;
/* Must always be cleared (armatures don't have their own edit-data). */
@ -456,7 +456,7 @@ static void armature_blend_read_data(BlendDataReader *reader, ID *id)
read_bone_collections(reader, arm);
BLO_read_data_address(reader, &arm->act_bone);
BLO_read_struct(reader, Bone, &arm->act_bone);
arm->act_edbone = nullptr;
BKE_armature_bone_hash_make(arm);

View File

@ -189,18 +189,11 @@ void BKE_asset_metadata_write(BlendWriter *writer, AssetMetaData *asset_data)
if (asset_data->properties) {
IDP_BlendWrite(writer, asset_data->properties);
}
if (asset_data->author) {
BLO_write_string(writer, asset_data->author);
}
if (asset_data->description) {
BLO_write_string(writer, asset_data->description);
}
if (asset_data->copyright) {
BLO_write_string(writer, asset_data->copyright);
}
if (asset_data->license) {
BLO_write_string(writer, asset_data->license);
}
BLO_write_string(writer, asset_data->author);
BLO_write_string(writer, asset_data->description);
BLO_write_string(writer, asset_data->copyright);
BLO_write_string(writer, asset_data->license);
LISTBASE_FOREACH (AssetTag *, tag, &asset_data->tags) {
BLO_write_struct(writer, AssetTag, tag);
@ -213,14 +206,15 @@ void BKE_asset_metadata_read(BlendDataReader *reader, AssetMetaData *asset_data)
asset_data->local_type_info = nullptr;
if (asset_data->properties) {
BLO_read_data_address(reader, &asset_data->properties);
BLO_read_struct(reader, IDProperty, &asset_data->properties);
IDP_BlendDataRead(reader, &asset_data->properties);
}
BLO_read_data_address(reader, &asset_data->author);
BLO_read_data_address(reader, &asset_data->description);
BLO_read_data_address(reader, &asset_data->copyright);
BLO_read_data_address(reader, &asset_data->license);
BLO_read_list(reader, &asset_data->tags);
BLO_read_string(reader, &asset_data->author);
BLO_read_string(reader, &asset_data->description);
BLO_read_string(reader, &asset_data->copyright);
BLO_read_string(reader, &asset_data->license);
BLO_read_struct_list(reader, AssetTag, &asset_data->tags);
BLI_assert(BLI_listbase_count(&asset_data->tags) == asset_data->tot_tags);
}

View File

@ -126,8 +126,8 @@ void BKE_asset_weak_reference_write(BlendWriter *writer, const AssetWeakReferenc
void BKE_asset_weak_reference_read(BlendDataReader *reader, AssetWeakReference *weak_ref)
{
BLO_read_data_address(reader, &weak_ref->asset_library_identifier);
BLO_read_data_address(reader, &weak_ref->relative_asset_identifier);
BLO_read_string(reader, &weak_ref->asset_library_identifier);
BLO_read_string(reader, &weak_ref->relative_asset_identifier);
}
void BKE_asset_catalog_path_list_free(ListBase &catalog_path_list)

View File

@ -286,9 +286,9 @@ static void brush_blend_read_data(BlendDataReader *reader, ID *id)
Brush *brush = (Brush *)id;
/* Falloff curve. */
BLO_read_data_address(reader, &brush->curve);
BLO_read_struct(reader, CurveMapping, &brush->curve);
BLO_read_data_address(reader, &brush->gradient);
BLO_read_struct(reader, ColorBand, &brush->gradient);
if (brush->curve) {
BKE_curvemapping_blend_read(reader, brush->curve);
@ -297,7 +297,7 @@ static void brush_blend_read_data(BlendDataReader *reader, ID *id)
BKE_brush_curve_preset(brush, CURVE_PRESET_SHARP);
}
BLO_read_data_address(reader, &brush->automasking_cavity_curve);
BLO_read_struct(reader, CurveMapping, &brush->automasking_cavity_curve);
if (brush->automasking_cavity_curve) {
BKE_curvemapping_blend_read(reader, brush->automasking_cavity_curve);
}
@ -306,18 +306,18 @@ static void brush_blend_read_data(BlendDataReader *reader, ID *id)
}
/* grease pencil */
BLO_read_data_address(reader, &brush->gpencil_settings);
BLO_read_struct(reader, BrushGpencilSettings, &brush->gpencil_settings);
if (brush->gpencil_settings != nullptr) {
BLO_read_data_address(reader, &brush->gpencil_settings->curve_sensitivity);
BLO_read_data_address(reader, &brush->gpencil_settings->curve_strength);
BLO_read_data_address(reader, &brush->gpencil_settings->curve_jitter);
BLO_read_struct(reader, CurveMapping, &brush->gpencil_settings->curve_sensitivity);
BLO_read_struct(reader, CurveMapping, &brush->gpencil_settings->curve_strength);
BLO_read_struct(reader, CurveMapping, &brush->gpencil_settings->curve_jitter);
BLO_read_data_address(reader, &brush->gpencil_settings->curve_rand_pressure);
BLO_read_data_address(reader, &brush->gpencil_settings->curve_rand_strength);
BLO_read_data_address(reader, &brush->gpencil_settings->curve_rand_uv);
BLO_read_data_address(reader, &brush->gpencil_settings->curve_rand_hue);
BLO_read_data_address(reader, &brush->gpencil_settings->curve_rand_saturation);
BLO_read_data_address(reader, &brush->gpencil_settings->curve_rand_value);
BLO_read_struct(reader, CurveMapping, &brush->gpencil_settings->curve_rand_pressure);
BLO_read_struct(reader, CurveMapping, &brush->gpencil_settings->curve_rand_strength);
BLO_read_struct(reader, CurveMapping, &brush->gpencil_settings->curve_rand_uv);
BLO_read_struct(reader, CurveMapping, &brush->gpencil_settings->curve_rand_hue);
BLO_read_struct(reader, CurveMapping, &brush->gpencil_settings->curve_rand_saturation);
BLO_read_struct(reader, CurveMapping, &brush->gpencil_settings->curve_rand_value);
if (brush->gpencil_settings->curve_sensitivity) {
BKE_curvemapping_blend_read(reader, brush->gpencil_settings->curve_sensitivity);
@ -356,15 +356,15 @@ static void brush_blend_read_data(BlendDataReader *reader, ID *id)
}
}
BLO_read_data_address(reader, &brush->curves_sculpt_settings);
BLO_read_struct(reader, BrushCurvesSculptSettings, &brush->curves_sculpt_settings);
if (brush->curves_sculpt_settings) {
BLO_read_data_address(reader, &brush->curves_sculpt_settings->curve_parameter_falloff);
BLO_read_struct(reader, CurveMapping, &brush->curves_sculpt_settings->curve_parameter_falloff);
if (brush->curves_sculpt_settings->curve_parameter_falloff) {
BKE_curvemapping_blend_read(reader, brush->curves_sculpt_settings->curve_parameter_falloff);
}
}
BLO_read_data_address(reader, &brush->preview);
BLO_read_struct(reader, PreviewImage, &brush->preview);
BKE_previewimg_blend_read(reader, brush->preview);
brush->icon_imbuf = nullptr;

View File

@ -117,7 +117,7 @@ static void cache_file_blend_read_data(BlendDataReader *reader, ID *id)
cache_file->handle_readers = nullptr;
/* relink layers */
BLO_read_list(reader, &cache_file->layers);
BLO_read_struct_list(reader, CacheFileLayer, &cache_file->layers);
}
IDTypeInfo IDType_ID_CF = {

View File

@ -212,7 +212,7 @@ static void camera_blend_read_data(BlendDataReader *reader, ID *id)
{
Camera *ca = (Camera *)id;
BLO_read_list(reader, &ca->bg_images);
BLO_read_struct_list(reader, CameraBGImage, &ca->bg_images);
LISTBASE_FOREACH (CameraBGImage *, bgpic, &ca->bg_images) {
bgpic->iuser.scene = nullptr;

View File

@ -339,16 +339,16 @@ void BKE_collection_blend_read_data(BlendDataReader *reader, Collection *collect
collection->owner_id = owner_id;
BLO_read_list(reader, &collection->gobject);
BLO_read_list(reader, &collection->children);
BLO_read_struct_list(reader, CollectionObject, &collection->gobject);
BLO_read_struct_list(reader, CollectionChild, &collection->children);
BLO_read_list(reader, &collection->exporters);
BLO_read_struct_list(reader, CollectionExport, &collection->exporters);
LISTBASE_FOREACH (CollectionExport *, data, &collection->exporters) {
BLO_read_data_address(reader, &data->export_properties);
BLO_read_struct(reader, IDProperty, &data->export_properties);
IDP_BlendDataRead(reader, &data->export_properties);
}
BLO_read_data_address(reader, &collection->preview);
BLO_read_struct(reader, PreviewImage, &collection->preview);
BKE_previewimg_blend_read(reader, collection->preview);
}
@ -1055,6 +1055,20 @@ bool BKE_collection_has_object_recursive_instanced(Collection *collection, Objec
return BLI_findptr(&objects, ob, offsetof(Base, object));
}
bool BKE_collection_has_object_recursive_instanced_orig_id(Collection *collection_eval,
Object *object_eval)
{
BLI_assert(collection_eval->id.tag & LIB_TAG_COPIED_ON_EVAL);
const ID *ob_orig = DEG_get_original_id(&object_eval->id);
const ListBase objects = BKE_collection_object_cache_instanced_get(collection_eval);
LISTBASE_FOREACH (Base *, base, &objects) {
if (DEG_get_original_id(&base->object->id) == ob_orig) {
return true;
}
}
return false;
}
static Collection *collection_next_find(Main *bmain, Scene *scene, Collection *collection)
{
if (scene && collection == scene->master_collection) {

View File

@ -652,8 +652,6 @@ static void curve_eval_bezier_point(float start[3][3], float end[3][3], float *p
static void curvemap_make_table(const CurveMapping *cumap, CurveMap *cuma)
{
const rctf *clipr = &cumap->clipr;
CurveMapPoint *cmp = cuma->curve;
BezTriple *bezt;
/* Wrapping ensures that the heights of the first and last points are the same. It adds two
* virtual points, which are copies of the first and last points, and moves them to the opposite
@ -670,40 +668,58 @@ static void curvemap_make_table(const CurveMapping *cumap, CurveMap *cuma)
cuma->mintable = clipr->xmin;
cuma->maxtable = clipr->xmax;
float table_range = cuma->maxtable - cuma->mintable;
const int bezt_totpoint = max_ii(cuma->totpoint, 2);
/* Rely on Blender interpolation for bezier curves, support extra functionality here as well. */
bezt = static_cast<BezTriple *>(MEM_callocN(cuma->totpoint * sizeof(BezTriple), "beztarr"));
BezTriple *bezt = static_cast<BezTriple *>(
MEM_callocN(bezt_totpoint * sizeof(BezTriple), "beztarr"));
for (int a = 0; a < cuma->totpoint; a++) {
cuma->mintable = min_ff(cuma->mintable, cmp[a].x);
cuma->maxtable = max_ff(cuma->maxtable, cmp[a].x);
bezt[a].vec[1][0] = cmp[a].x;
bezt[a].vec[1][1] = cmp[a].y;
if (cmp[a].flag & CUMA_HANDLE_VECTOR) {
bezt[a].h1 = bezt[a].h2 = HD_VECT;
}
else if (cmp[a].flag & CUMA_HANDLE_AUTO_ANIM) {
bezt[a].h1 = bezt[a].h2 = HD_AUTO_ANIM;
}
else {
bezt[a].h1 = bezt[a].h2 = HD_AUTO;
/* Valid curve has at least 2 points. */
if (cuma->totpoint >= 2) {
CurveMapPoint *cmp = cuma->curve;
for (int a = 0; a < bezt_totpoint; a++) {
cuma->mintable = min_ff(cuma->mintable, cmp[a].x);
cuma->maxtable = max_ff(cuma->maxtable, cmp[a].x);
bezt[a].vec[1][0] = cmp[a].x;
bezt[a].vec[1][1] = cmp[a].y;
if (cmp[a].flag & CUMA_HANDLE_VECTOR) {
bezt[a].h1 = bezt[a].h2 = HD_VECT;
}
else if (cmp[a].flag & CUMA_HANDLE_AUTO_ANIM) {
bezt[a].h1 = bezt[a].h2 = HD_AUTO_ANIM;
}
else {
bezt[a].h1 = bezt[a].h2 = HD_AUTO;
}
}
}
else {
/* Fallback when points are missing. */
cuma->mintable = 0.0f;
cuma->maxtable = 0.0f;
zero_v2(bezt[0].vec[1]);
zero_v2(bezt[1].vec[1]);
bezt[0].h1 = HD_AUTO;
bezt[0].h2 = HD_AUTO;
bezt[1].h1 = HD_AUTO;
bezt[1].h2 = HD_AUTO;
}
const BezTriple *bezt_next = nullptr;
const BezTriple *bezt_prev = nullptr;
/* Create two extra points for wrapping curves. */
BezTriple bezt_pre = bezt[cuma->totpoint - 1];
BezTriple bezt_pre = bezt[bezt_totpoint - 1];
BezTriple bezt_post = bezt[0];
BezTriple *bezt_post_ptr;
if (use_wrapping) {
/* Handle location of pre and post points for wrapping curves. */
bezt_pre.h1 = bezt_pre.h2 = bezt[cuma->totpoint - 1].h2;
bezt_pre.vec[1][0] = bezt[cuma->totpoint - 1].vec[1][0] - table_range;
bezt_pre.vec[1][1] = bezt[cuma->totpoint - 1].vec[1][1];
bezt_pre.h1 = bezt_pre.h2 = bezt[bezt_totpoint - 1].h2;
bezt_pre.vec[1][0] = bezt[bezt_totpoint - 1].vec[1][0] - table_range;
bezt_pre.vec[1][1] = bezt[bezt_totpoint - 1].vec[1][1];
bezt_post.h1 = bezt_post.h2 = bezt[0].h1;
bezt_post.vec[1][0] = bezt[0].vec[1][0] + table_range;
@ -718,17 +734,17 @@ static void curvemap_make_table(const CurveMapping *cumap, CurveMap *cuma)
}
/* Process middle elements */
for (int a = 0; a < cuma->totpoint; a++) {
bezt_next = (a != cuma->totpoint - 1) ? &bezt[a + 1] : bezt_post_ptr;
calchandle_curvemap(&bezt[a], bezt_prev, bezt_next);
for (int a = 0; a < bezt_totpoint; a++) {
bezt_next = (a != bezt_totpoint - 1) ? &bezt[a + 1] : bezt_post_ptr;
calchandle_curvemap(&bezt[a], (bezt_prev) ? bezt_prev : &bezt[0], bezt_next);
bezt_prev = &bezt[a];
}
/* Correct handles of pre and post points for wrapping curves. */
bezt_pre.vec[0][0] = bezt[cuma->totpoint - 1].vec[0][0] - table_range;
bezt_pre.vec[0][1] = bezt[cuma->totpoint - 1].vec[0][1];
bezt_pre.vec[2][0] = bezt[cuma->totpoint - 1].vec[2][0] - table_range;
bezt_pre.vec[2][1] = bezt[cuma->totpoint - 1].vec[2][1];
bezt_pre.vec[0][0] = bezt[bezt_totpoint - 1].vec[0][0] - table_range;
bezt_pre.vec[0][1] = bezt[bezt_totpoint - 1].vec[0][1];
bezt_pre.vec[2][0] = bezt[bezt_totpoint - 1].vec[2][0] - table_range;
bezt_pre.vec[2][1] = bezt[bezt_totpoint - 1].vec[2][1];
bezt_post.vec[0][0] = bezt[0].vec[0][0] + table_range;
bezt_post.vec[0][1] = bezt[0].vec[0][1];
@ -737,7 +753,7 @@ static void curvemap_make_table(const CurveMapping *cumap, CurveMap *cuma)
/* first and last handle need correction, instead of pointing to center of next/prev,
* we let it point to the closest handle */
if (cuma->totpoint > 2 && !use_wrapping) {
if (bezt_totpoint > 2 && !use_wrapping) {
float hlen, nlen, vec[3];
if (bezt[0].h2 == HD_AUTO) {
@ -757,7 +773,7 @@ static void curvemap_make_table(const CurveMapping *cumap, CurveMap *cuma)
sub_v3_v3v3(bezt[0].vec[0], bezt[0].vec[1], vec);
}
}
int a = cuma->totpoint - 1;
int a = bezt_totpoint - 1;
if (bezt[a].h2 == HD_AUTO) {
hlen = len_v3v3(bezt[a].vec[1], bezt[a].vec[0]); /* original handle length */
@ -782,7 +798,8 @@ static void curvemap_make_table(const CurveMapping *cumap, CurveMap *cuma)
MEM_freeN(cuma->table);
}
int totpoint = use_wrapping ? (cuma->totpoint + 1) * CM_RESOL : (cuma->totpoint - 1) * CM_RESOL;
const int totpoint = use_wrapping ? (bezt_totpoint + 1) * CM_RESOL :
(bezt_totpoint - 1) * CM_RESOL;
float *allpoints = static_cast<float *>(MEM_callocN(totpoint * 2 * sizeof(float), "table"));
float *point = allpoints;
@ -793,14 +810,14 @@ static void curvemap_make_table(const CurveMapping *cumap, CurveMap *cuma)
}
/* Process middle elements */
for (int a = 0; a < cuma->totpoint - 1; a++, point += 2 * CM_RESOL) {
for (int a = 0; a < bezt_totpoint - 1; a++, point += 2 * CM_RESOL) {
int b = a + 1;
curve_eval_bezier_point(bezt[a].vec, bezt[b].vec, point);
}
if (use_wrapping) {
/* Handle post point for wrapping */
curve_eval_bezier_point(bezt[cuma->totpoint - 1].vec, bezt_post.vec, point);
curve_eval_bezier_point(bezt[bezt_totpoint - 1].vec, bezt_post.vec, point);
}
/* Store first and last handle for extrapolation, unit length. (Only relevant when not using
* wrapping.) */
@ -811,7 +828,7 @@ static void curvemap_make_table(const CurveMapping *cumap, CurveMap *cuma)
cuma->ext_in[0] /= ext_in_range;
cuma->ext_in[1] /= ext_in_range;
int out_a = cuma->totpoint - 1;
int out_a = bezt_totpoint - 1;
cuma->ext_out[0] = bezt[out_a].vec[1][0] - bezt[out_a].vec[2][0];
cuma->ext_out[1] = bezt[out_a].vec[1][1] - bezt[out_a].vec[2][1];
float ext_out_range = sqrtf(cuma->ext_out[0] * cuma->ext_out[0] +
@ -830,7 +847,7 @@ static void curvemap_make_table(const CurveMapping *cumap, CurveMap *cuma)
float *lastpoint = allpoints + 2 * (totpoint - 1);
point = allpoints;
cmp = static_cast<CurveMapPoint *>(
CurveMapPoint *cmp = static_cast<CurveMapPoint *>(
MEM_callocN((CM_TABLE + 1) * sizeof(CurveMapPoint), "dist table"));
for (int a = 0; a <= CM_TABLE; a++) {
@ -1384,7 +1401,7 @@ void BKE_curvemapping_blend_read(BlendDataReader *reader, CurveMapping *cumap)
cumap->flag &= ~CUMA_PREMULLED;
for (int a = 0; a < CM_TOT; a++) {
BLO_read_data_address(reader, &cumap->cm[a].curve);
BLO_read_struct_array(reader, CurveMapPoint, cumap->cm[a].totpoint, &cumap->cm[a].curve);
cumap->cm[a].table = nullptr;
cumap->cm[a].premultable = nullptr;
}
@ -1960,7 +1977,7 @@ void BKE_color_managed_view_settings_blend_write(BlendWriter *writer,
void BKE_color_managed_view_settings_blend_read_data(BlendDataReader *reader,
ColorManagedViewSettings *settings)
{
BLO_read_data_address(reader, &settings->curve_mapping);
BLO_read_struct(reader, CurveMapping, &settings->curve_mapping);
if (settings->curve_mapping) {
BKE_curvemapping_blend_read(reader, settings->curve_mapping);

View File

@ -6548,7 +6548,7 @@ void BKE_constraint_blend_write(BlendWriter *writer, ListBase *conlist)
void BKE_constraint_blend_read_data(BlendDataReader *reader, ID *id_owner, ListBase *lb)
{
BLO_read_list(reader, lb);
BLO_read_struct_list(reader, bConstraint, lb);
LISTBASE_FOREACH (bConstraint *, con, lb) {
BLO_read_data_address(reader, &con->data);
/* Patch for error introduced by changing constraints (don't know how). */
@ -6569,23 +6569,23 @@ void BKE_constraint_blend_read_data(BlendDataReader *reader, ID *id_owner, ListB
case CONSTRAINT_TYPE_PYTHON: {
bPythonConstraint *data = static_cast<bPythonConstraint *>(con->data);
BLO_read_list(reader, &data->targets);
BLO_read_struct_list(reader, bConstraintTarget, &data->targets);
BLO_read_data_address(reader, &data->prop);
BLO_read_struct(reader, IDProperty, &data->prop);
IDP_BlendDataRead(reader, &data->prop);
break;
}
case CONSTRAINT_TYPE_ARMATURE: {
bArmatureConstraint *data = static_cast<bArmatureConstraint *>(con->data);
BLO_read_list(reader, &data->targets);
BLO_read_struct_list(reader, bConstraintTarget, &data->targets);
break;
}
case CONSTRAINT_TYPE_SPLINEIK: {
bSplineIKConstraint *data = static_cast<bSplineIKConstraint *>(con->data);
BLO_read_data_address(reader, &data->points);
BLO_read_float_array(reader, data->numpoints, &data->points);
break;
}
case CONSTRAINT_TYPE_KINEMATIC: {

View File

@ -202,16 +202,6 @@ static void curve_blend_write(BlendWriter *writer, ID *id, const void *id_addres
}
}
static void switch_endian_knots(Nurb *nu)
{
if (nu->knotsu) {
BLI_endian_switch_float_array(nu->knotsu, KNOTSU(nu));
}
if (nu->knotsv) {
BLI_endian_switch_float_array(nu->knotsv, KNOTSV(nu));
}
}
static void curve_blend_read_data(BlendDataReader *reader, ID *id)
{
Curve *cu = (Curve *)id;
@ -221,12 +211,12 @@ static void curve_blend_read_data(BlendDataReader *reader, ID *id)
BLO_read_pointer_array(reader, (void **)&cu->mat);
BLO_read_data_address(reader, &cu->str);
BLO_read_data_address(reader, &cu->strinfo);
BLO_read_data_address(reader, &cu->tb);
BLO_read_string(reader, &cu->str);
BLO_read_struct_array(reader, CharInfo, cu->len_char32 + 1, &cu->strinfo);
BLO_read_struct_array(reader, TextBox, cu->totbox, &cu->tb);
if (cu->vfont == nullptr) {
BLO_read_list(reader, &(cu->nurb));
BLO_read_struct_list(reader, Nurb, &(cu->nurb));
}
else {
cu->nurb.first = cu->nurb.last = nullptr;
@ -253,21 +243,17 @@ static void curve_blend_read_data(BlendDataReader *reader, ID *id)
cu->batch_cache = nullptr;
LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) {
BLO_read_data_address(reader, &nu->bezt);
BLO_read_data_address(reader, &nu->bp);
BLO_read_data_address(reader, &nu->knotsu);
BLO_read_data_address(reader, &nu->knotsv);
BLO_read_struct_array(reader, BezTriple, nu->pntsu, &nu->bezt);
BLO_read_struct_array(reader, BPoint, nu->pntsu * nu->pntsv, &nu->bp);
BLO_read_float_array(reader, KNOTSU(nu), &nu->knotsu);
BLO_read_float_array(reader, KNOTSV(nu), &nu->knotsv);
if (cu->vfont == nullptr) {
nu->charidx = 0;
}
if (BLO_read_requires_endian_switch(reader)) {
switch_endian_knots(nu);
}
}
cu->texspace_flag &= ~CU_TEXSPACE_FLAG_AUTO_EVALUATED;
BLO_read_data_address(reader, &cu->bevel_profile);
BLO_read_struct(reader, CurveProfile, &cu->bevel_profile);
if (cu->bevel_profile != nullptr) {
BKE_curveprofile_blend_read(reader, cu->bevel_profile);
}

View File

@ -89,7 +89,7 @@ void BKE_curveprofile_blend_write(BlendWriter *writer, const CurveProfile *profi
void BKE_curveprofile_blend_read(BlendDataReader *reader, CurveProfile *profile)
{
BLO_read_data_address(reader, &profile->path);
BLO_read_struct_array(reader, CurveProfilePoint, profile->path_len, &profile->path);
profile->table = nullptr;
profile->segments = nullptr;

View File

@ -129,7 +129,7 @@ static void curves_blend_read_data(BlendDataReader *reader, ID *id)
/* Geometry */
curves->geometry.wrap().blend_read(*reader);
BLO_read_data_address(reader, &curves->surface_uv_map);
BLO_read_string(reader, &curves->surface_uv_map);
/* Materials */
BLO_read_pointer_array(reader, (void **)&curves->mat);

View File

@ -1555,7 +1555,7 @@ void CurvesGeometry::blend_read(BlendDataReader &reader)
});
}
BLO_read_list(&reader, &this->vertex_group_names);
BLO_read_struct_list(&reader, bDeformGroup, &this->vertex_group_names);
/* Recalculate curve type count cache that isn't saved in files. */
this->update_curve_types();

View File

@ -5297,7 +5297,9 @@ static void write_mdisps(BlendWriter *writer,
}
if (md->hidden) {
BLO_write_raw(writer, BLI_BITMAP_SIZE(md->totdisp), md->hidden);
BLO_write_int8_array(writer,
BLI_BITMAP_SIZE(md->totdisp) * sizeof(BLI_bitmap),
reinterpret_cast<const int8_t *>(md->hidden));
}
}
}
@ -5392,25 +5394,24 @@ static void blend_read_mdisps(BlendDataReader *reader,
{
if (mdisps) {
for (int i = 0; i < count; i++) {
BLO_read_data_address(reader, &mdisps[i].disps);
BLO_read_data_address(reader, &mdisps[i].hidden);
MDisps &md = mdisps[i];
if (mdisps[i].totdisp && !mdisps[i].level) {
BLO_read_float3_array(reader, md.totdisp, reinterpret_cast<float **>(&md.disps));
BLO_read_int8_array(reader,
BLI_BITMAP_SIZE(md.totdisp) * sizeof(BLI_bitmap),
reinterpret_cast<int8_t **>(&md.hidden));
if (md.totdisp && !md.level) {
/* this calculation is only correct for loop mdisps;
* if loading pre-BMesh face mdisps this will be
* overwritten with the correct value in
* #bm_corners_to_loops() */
float gridsize = sqrtf(mdisps[i].totdisp);
mdisps[i].level = int(logf(gridsize - 1.0f) / float(M_LN2)) + 1;
float gridsize = sqrtf(md.totdisp);
md.level = int(logf(gridsize - 1.0f) / float(M_LN2)) + 1;
}
if (BLO_read_requires_endian_switch(reader) && (mdisps[i].disps)) {
/* #DNA_struct_switch_endian doesn't do endian swap for `(*disps)[]` */
/* this does swap for data written at #write_mdisps() - `readfile.cc`. */
BLI_endian_switch_float_array(*mdisps[i].disps, mdisps[i].totdisp * 3);
}
if (!external && !mdisps[i].disps) {
mdisps[i].totdisp = 0;
if (!external && !md.disps) {
md.totdisp = 0;
}
}
}
@ -5424,7 +5425,8 @@ static void blend_read_paint_mask(BlendDataReader *reader,
for (int i = 0; i < count; i++) {
GridPaintMask *gpm = &grid_paint_mask[i];
if (gpm->data) {
BLO_read_data_address(reader, &gpm->data);
const int gridsize = BKE_ccg_gridsize(gpm->level);
BLO_read_float_array(reader, gridsize * gridsize, &gpm->data);
}
}
}
@ -5432,7 +5434,8 @@ static void blend_read_paint_mask(BlendDataReader *reader,
static void blend_read_layer_data(BlendDataReader *reader, CustomDataLayer &layer, const int count)
{
BLO_read_data_address(reader, &layer.data);
const size_t elem_size = CustomData_sizeof(eCustomDataType(layer.type));
BLO_read_struct_array(reader, char, elem_size *count, &layer.data);
if (CustomData_layer_ensure_data_exists(&layer, count)) {
/* Under normal operations, this shouldn't happen, but...
* For a CD_PROP_BOOL example, see #84935.
@ -5456,7 +5459,7 @@ static void blend_read_layer_data(BlendDataReader *reader, CustomDataLayer &laye
void CustomData_blend_read(BlendDataReader *reader, CustomData *data, const int count)
{
BLO_read_data_address(reader, &data->layers);
BLO_read_struct_array(reader, CustomDataLayer, data->totlayer, &data->layers);
/* Annoying workaround for bug #31079 loading legacy files with
* no polygons _but_ have stale custom-data. */
@ -5465,7 +5468,7 @@ void CustomData_blend_read(BlendDataReader *reader, CustomData *data, const int
return;
}
BLO_read_data_address(reader, &data->external);
BLO_read_struct(reader, CustomDataExternal, &data->external);
blender::Map<void *, const ImplicitSharingInfo *> sharing_info_by_data;

View File

@ -1639,10 +1639,9 @@ void BKE_defvert_blend_read(BlendDataReader *reader, int count, MDeformVert *mdv
for (int i = count; i > 0; i--, mdverts++) {
/* Convert to vertex group allocation system. */
MDeformWeight *dw;
if (mdverts->dw &&
(dw = static_cast<MDeformWeight *>(BLO_read_get_new_data_address(reader, mdverts->dw))))
{
MDeformWeight *dw = mdverts->dw;
BLO_read_struct_array(reader, MDeformWeight, mdverts->totweight, &dw);
if (dw) {
const size_t dw_len = sizeof(MDeformWeight) * mdverts->totweight;
void *dw_tmp = MEM_mallocN(dw_len, __func__);
memcpy(dw_tmp, dw, dw_len);

View File

@ -2592,14 +2592,14 @@ void BKE_fmodifiers_blend_read_data(BlendDataReader *reader, ListBase *fmodifier
case FMODIFIER_TYPE_ENVELOPE: {
FMod_Envelope *data = (FMod_Envelope *)fcm->data;
BLO_read_data_address(reader, &data->data);
BLO_read_struct_array(reader, FCM_EnvelopeData, data->totvert, &data->data);
break;
}
case FMODIFIER_TYPE_PYTHON: {
FMod_Python *data = (FMod_Python *)fcm->data;
BLO_read_data_address(reader, &data->prop);
BLO_read_struct(reader, IDProperty, &data->prop);
IDP_BlendDataRead(reader, &data->prop);
break;
@ -2655,14 +2655,14 @@ void BKE_fcurve_blend_write_listbase(BlendWriter *writer, ListBase *fcurves)
void BKE_fcurve_blend_read_data(BlendDataReader *reader, FCurve *fcu)
{
/* curve data */
BLO_read_data_address(reader, &fcu->bezt);
BLO_read_data_address(reader, &fcu->fpt);
BLO_read_struct_array(reader, BezTriple, fcu->totvert, &fcu->bezt);
BLO_read_struct_array(reader, FPoint, fcu->totvert, &fcu->fpt);
/* rna path */
BLO_read_data_address(reader, &fcu->rna_path);
BLO_read_string(reader, &fcu->rna_path);
/* group */
BLO_read_data_address(reader, &fcu->grp);
BLO_read_struct(reader, bActionGroup, &fcu->grp);
/* clear disabled flag - allows disabled drivers to be tried again (#32155),
* but also means that another method for "reviving disabled F-Curves" exists
@ -2670,7 +2670,7 @@ void BKE_fcurve_blend_read_data(BlendDataReader *reader, FCurve *fcu)
fcu->flag &= ~FCURVE_DISABLED;
/* driver */
BLO_read_data_address(reader, &fcu->driver);
BLO_read_struct(reader, ChannelDriver, &fcu->driver);
if (fcu->driver) {
ChannelDriver *driver = fcu->driver;
@ -2684,12 +2684,12 @@ void BKE_fcurve_blend_read_data(BlendDataReader *reader, FCurve *fcu)
driver->flag &= ~DRIVER_FLAG_INVALID;
/* relink variables, targets and their paths */
BLO_read_list(reader, &driver->variables);
BLO_read_struct_list(reader, DriverVar, &driver->variables);
LISTBASE_FOREACH (DriverVar *, dvar, &driver->variables) {
DRIVER_TARGETS_LOOPER_BEGIN (dvar) {
/* only relink the targets being used */
if (tarIndex < dvar->num_targets) {
BLO_read_data_address(reader, &dtar->rna_path);
BLO_read_string(reader, &dtar->rna_path);
}
else {
dtar->rna_path = nullptr;
@ -2701,7 +2701,7 @@ void BKE_fcurve_blend_read_data(BlendDataReader *reader, FCurve *fcu)
}
/* modifiers */
BLO_read_list(reader, &fcu->modifiers);
BLO_read_struct_list(reader, FModifier, &fcu->modifiers);
BKE_fmodifiers_blend_read_data(reader, &fcu->modifiers, fcu);
}

View File

@ -204,52 +204,54 @@ void BKE_gpencil_blend_read_data(BlendDataReader *reader, bGPdata *gpd)
gpd->runtime.update_cache = nullptr;
/* Relink palettes (old palettes deprecated, only to convert old files). */
BLO_read_list(reader, &gpd->palettes);
BLO_read_struct_list(reader, bGPDpalette, &gpd->palettes);
if (gpd->palettes.first != nullptr) {
LISTBASE_FOREACH (bGPDpalette *, palette, &gpd->palettes) {
BLO_read_list(reader, &palette->colors);
BLO_read_struct_list(reader, PaletteColor, &palette->colors);
}
}
BLO_read_list(reader, &gpd->vertex_group_names);
BLO_read_struct_list(reader, bDeformGroup, &gpd->vertex_group_names);
/* Materials. */
BLO_read_pointer_array(reader, (void **)&gpd->mat);
/* Relink layers. */
BLO_read_list(reader, &gpd->layers);
BLO_read_struct_list(reader, bGPDlayer, &gpd->layers);
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
/* Relink frames. */
BLO_read_list(reader, &gpl->frames);
BLO_read_struct_list(reader, bGPDframe, &gpl->frames);
BLO_read_data_address(reader, &gpl->actframe);
BLO_read_struct(reader, bGPDframe, &gpl->actframe);
gpl->runtime.icon_id = 0;
/* Relink masks. */
BLO_read_list(reader, &gpl->mask_layers);
BLO_read_struct_list(reader, bGPDlayer_Mask, &gpl->mask_layers);
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
/* Relink strokes (and their points). */
BLO_read_list(reader, &gpf->strokes);
BLO_read_struct_list(reader, bGPDstroke, &gpf->strokes);
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
/* Relink stroke points array. */
BLO_read_data_address(reader, &gps->points);
BLO_read_struct_array(reader, bGPDspoint, gps->totpoints, &gps->points);
/* Relink geometry. */
BLO_read_data_address(reader, &gps->triangles);
BLO_read_struct_array(reader, bGPDtriangle, gps->tot_triangles, &gps->triangles);
/* Relink stroke edit curve. */
BLO_read_data_address(reader, &gps->editcurve);
BLO_read_struct(reader, bGPDcurve, &gps->editcurve);
if (gps->editcurve != nullptr) {
/* Relink curve point array. */
BLO_read_data_address(reader, &gps->editcurve->curve_points);
bGPDcurve *gpc = gps->editcurve;
BLO_read_struct_array(
reader, bGPDcurve_point, gpc->tot_curve_points, &gps->editcurve->curve_points);
}
/* Relink weight data. */
if (gps->dvert) {
BLO_read_data_address(reader, &gps->dvert);
BLO_read_struct_array(reader, MDeformVert, gps->totpoints, &gps->dvert);
BKE_defvert_blend_read(reader, gps->totpoints, gps->dvert);
}
}

View File

@ -940,7 +940,7 @@ void BKE_gpencil_modifier_blend_write(BlendWriter *writer, ListBase *modbase)
void BKE_gpencil_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb, Object *ob)
{
BLO_read_list(reader, lb);
BLO_read_struct_list(reader, GpencilModifierData, lb);
LISTBASE_FOREACH (GpencilModifierData *, md, lb) {
md->error = nullptr;
@ -962,7 +962,7 @@ void BKE_gpencil_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb,
else if (md->type == eGpencilModifierType_Hook) {
HookGpencilModifierData *hmd = (HookGpencilModifierData *)md;
BLO_read_data_address(reader, &hmd->curfalloff);
BLO_read_struct(reader, CurveMapping, &hmd->curfalloff);
if (hmd->curfalloff) {
BKE_curvemapping_blend_read(reader, hmd->curfalloff);
BKE_curvemapping_init(hmd->curfalloff);
@ -971,7 +971,7 @@ void BKE_gpencil_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb,
else if (md->type == eGpencilModifierType_Noise) {
NoiseGpencilModifierData *gpmd = (NoiseGpencilModifierData *)md;
BLO_read_data_address(reader, &gpmd->curve_intensity);
BLO_read_struct(reader, CurveMapping, &gpmd->curve_intensity);
if (gpmd->curve_intensity) {
BKE_curvemapping_blend_read(reader, gpmd->curve_intensity);
/* Initialize the curve. Maybe this could be moved to modifier logic. */
@ -981,7 +981,7 @@ void BKE_gpencil_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb,
else if (md->type == eGpencilModifierType_Thick) {
ThickGpencilModifierData *gpmd = (ThickGpencilModifierData *)md;
BLO_read_data_address(reader, &gpmd->curve_thickness);
BLO_read_struct(reader, CurveMapping, &gpmd->curve_thickness);
if (gpmd->curve_thickness) {
BKE_curvemapping_blend_read(reader, gpmd->curve_thickness);
BKE_curvemapping_init(gpmd->curve_thickness);
@ -989,8 +989,8 @@ void BKE_gpencil_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb,
}
else if (md->type == eGpencilModifierType_Tint) {
TintGpencilModifierData *gpmd = (TintGpencilModifierData *)md;
BLO_read_data_address(reader, &gpmd->colorband);
BLO_read_data_address(reader, &gpmd->curve_intensity);
BLO_read_struct(reader, ColorBand, &gpmd->colorband);
BLO_read_struct(reader, CurveMapping, &gpmd->curve_intensity);
if (gpmd->curve_intensity) {
BKE_curvemapping_blend_read(reader, gpmd->curve_intensity);
BKE_curvemapping_init(gpmd->curve_intensity);
@ -998,7 +998,7 @@ void BKE_gpencil_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb,
}
else if (md->type == eGpencilModifierType_Smooth) {
SmoothGpencilModifierData *gpmd = (SmoothGpencilModifierData *)md;
BLO_read_data_address(reader, &gpmd->curve_intensity);
BLO_read_struct(reader, CurveMapping, &gpmd->curve_intensity);
if (gpmd->curve_intensity) {
BKE_curvemapping_blend_read(reader, gpmd->curve_intensity);
BKE_curvemapping_init(gpmd->curve_intensity);
@ -1006,7 +1006,7 @@ void BKE_gpencil_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb,
}
else if (md->type == eGpencilModifierType_Color) {
ColorGpencilModifierData *gpmd = (ColorGpencilModifierData *)md;
BLO_read_data_address(reader, &gpmd->curve_intensity);
BLO_read_struct(reader, CurveMapping, &gpmd->curve_intensity);
if (gpmd->curve_intensity) {
BKE_curvemapping_blend_read(reader, gpmd->curve_intensity);
BKE_curvemapping_init(gpmd->curve_intensity);
@ -1014,7 +1014,7 @@ void BKE_gpencil_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb,
}
else if (md->type == eGpencilModifierType_Opacity) {
OpacityGpencilModifierData *gpmd = (OpacityGpencilModifierData *)md;
BLO_read_data_address(reader, &gpmd->curve_intensity);
BLO_read_struct(reader, CurveMapping, &gpmd->curve_intensity);
if (gpmd->curve_intensity) {
BKE_curvemapping_blend_read(reader, gpmd->curve_intensity);
BKE_curvemapping_init(gpmd->curve_intensity);
@ -1022,14 +1022,16 @@ void BKE_gpencil_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb,
}
else if (md->type == eGpencilModifierType_Dash) {
DashGpencilModifierData *gpmd = (DashGpencilModifierData *)md;
BLO_read_data_address(reader, &gpmd->segments);
BLO_read_struct_array(
reader, DashGpencilModifierSegment, gpmd->segments_len, &gpmd->segments);
for (int i = 0; i < gpmd->segments_len; i++) {
gpmd->segments[i].dmd = gpmd;
}
}
else if (md->type == eGpencilModifierType_Time) {
TimeGpencilModifierData *gpmd = (TimeGpencilModifierData *)md;
BLO_read_data_address(reader, &gpmd->segments);
BLO_read_struct_array(
reader, TimeGpencilModifierSegment, gpmd->segments_len, &gpmd->segments);
for (int i = 0; i < gpmd->segments_len; i++) {
gpmd->segments[i].gpmd = gpmd;
}

View File

@ -215,7 +215,7 @@ static void grease_pencil_blend_read_data(BlendDataReader *reader, ID *id)
/* Read materials. */
BLO_read_pointer_array(reader, reinterpret_cast<void **>(&grease_pencil->material_array));
/* Read vertex group names. */
BLO_read_list(reader, &grease_pencil->vertex_group_names);
BLO_read_struct_list(reader, bDeformGroup, &grease_pencil->vertex_group_names);
grease_pencil->runtime = MEM_new<blender::bke::GreasePencilRuntime>(__func__);
}
@ -1742,7 +1742,12 @@ void BKE_grease_pencil_data_update(Depsgraph *depsgraph, Scene *scene, Object *o
}
grease_pencil_evaluate_modifiers(depsgraph, scene, object, geometry_set);
if (!geometry_set.has_grease_pencil()) {
if (geometry_set.has_grease_pencil()) {
/* Output geometry set may be different from the input,
* set the frame again to ensure a correct value. */
geometry_set.get_grease_pencil()->runtime->eval_frame = int(DEG_get_ctime(depsgraph));
}
else {
GreasePencil *empty_grease_pencil = BKE_grease_pencil_new_nomain();
empty_grease_pencil->runtime->eval_frame = int(DEG_get_ctime(depsgraph));
geometry_set.replace_grease_pencil(empty_grease_pencil);
@ -2923,7 +2928,7 @@ static void read_drawing_array(GreasePencil &grease_pencil, BlendDataReader *rea
{
BLO_read_pointer_array(reader, reinterpret_cast<void **>(&grease_pencil.drawing_array));
for (int i = 0; i < grease_pencil.drawing_array_num; i++) {
BLO_read_data_address(reader, &grease_pencil.drawing_array[i]);
BLO_read_struct(reader, GreasePencilDrawingBase, &grease_pencil.drawing_array[i]);
GreasePencilDrawingBase *drawing_base = grease_pencil.drawing_array[i];
switch (GreasePencilDrawingType(drawing_base->type)) {
case GP_DRAWING: {
@ -3002,19 +3007,20 @@ static void read_layer(BlendDataReader *reader,
GreasePencilLayer *node,
GreasePencilLayerTreeGroup *parent)
{
BLO_read_data_address(reader, &node->base.name);
BLO_read_string(reader, &node->base.name);
node->base.parent = parent;
BLO_read_data_address(reader, &node->parsubstr);
BLO_read_data_address(reader, &node->viewlayername);
BLO_read_string(reader, &node->parsubstr);
BLO_read_string(reader, &node->viewlayername);
/* Read frames storage. */
BLO_read_int32_array(reader, node->frames_storage.num, &node->frames_storage.keys);
BLO_read_data_address(reader, &node->frames_storage.values);
BLO_read_struct_array(
reader, GreasePencilFrame, node->frames_storage.num, &node->frames_storage.values);
/* Read layer masks. */
BLO_read_list(reader, &node->masks);
BLO_read_struct_list(reader, GreasePencilLayerMask, &node->masks);
LISTBASE_FOREACH (GreasePencilLayerMask *, mask, &node->masks) {
BLO_read_data_address(reader, &mask->layer_name);
BLO_read_string(reader, &mask->layer_name);
}
/* NOTE: Ideally this should be cleared on write, to reduce false 'changes' detection in memfile
@ -3028,10 +3034,10 @@ static void read_layer_tree_group(BlendDataReader *reader,
GreasePencilLayerTreeGroup *node,
GreasePencilLayerTreeGroup *parent)
{
BLO_read_data_address(reader, &node->base.name);
BLO_read_string(reader, &node->base.name);
node->base.parent = parent;
/* Read list of children. */
BLO_read_list(reader, &node->children);
BLO_read_struct_list(reader, GreasePencilLayerTreeNode, &node->children);
LISTBASE_FOREACH (GreasePencilLayerTreeNode *, child, &node->children) {
switch (child->type) {
case GP_LAYER_TREE_LEAF: {
@ -3053,7 +3059,7 @@ static void read_layer_tree_group(BlendDataReader *reader,
static void read_layer_tree(GreasePencil &grease_pencil, BlendDataReader *reader)
{
/* Read root group. */
BLO_read_data_address(reader, &grease_pencil.root_group_ptr);
BLO_read_struct(reader, GreasePencilLayerTreeGroup, &grease_pencil.root_group_ptr);
/* This shouldn't normally happen, but for files that were created before the root group became a
* pointer, this address will not exist. In this case, we clear the pointer to the active layer
* and create an empty root group to avoid crashes. */
@ -3063,7 +3069,7 @@ static void read_layer_tree(GreasePencil &grease_pencil, BlendDataReader *reader
return;
}
/* Read active layer. */
BLO_read_data_address(reader, &grease_pencil.active_layer);
BLO_read_struct(reader, GreasePencilLayer, &grease_pencil.active_layer);
read_layer_tree_group(reader, grease_pencil.root_group_ptr, nullptr);
grease_pencil.root_group_ptr->wrap().update_from_dna_read();

View File

@ -1227,7 +1227,7 @@ static void layer_adjustments_to_modifiers(ConversionData &conversion_data,
/* Ensure values are divided by 2k, to match conversion done for non-animated value. */
constexpr float thickness_adjustement_factor = 1.0f / 2000.0f;
auto fcurve_convert_thickness_cb = [&thickness_adjustement_factor](FCurve &fcurve) {
auto fcurve_convert_thickness_cb = [&](FCurve &fcurve) {
if (fcurve.bezt) {
for (uint i = 0; i < fcurve.totvert; i++) {
BezTriple &bezier_triple = fcurve.bezt[i];

View File

@ -1400,38 +1400,43 @@ static void IDP_DirectLinkProperty(IDProperty *prop, BlendDataReader *reader);
static void read_ui_data(IDProperty *prop, BlendDataReader *reader)
{
BLO_read_data_address(reader, &prop->ui_data);
if (!prop->ui_data) {
/* Can happen when opening more recent files with unknown types of IDProperties. */
return;
}
BLO_read_data_address(reader, &prop->ui_data->description);
/* Note: null UI data can happen when opening more recent files with unknown types of
* IDProperties. */
switch (IDP_ui_data_type(prop)) {
case IDP_UI_DATA_TYPE_STRING: {
IDPropertyUIDataString *ui_data_string = (IDPropertyUIDataString *)prop->ui_data;
BLO_read_data_address(reader, &ui_data_string->default_value);
BLO_read_struct(reader, IDPropertyUIDataString, &prop->ui_data);
if (prop->ui_data) {
IDPropertyUIDataString *ui_data_string = (IDPropertyUIDataString *)prop->ui_data;
BLO_read_string(reader, &ui_data_string->default_value);
}
break;
}
case IDP_UI_DATA_TYPE_ID: {
BLO_read_struct(reader, IDPropertyUIDataID, &prop->ui_data);
break;
}
case IDP_UI_DATA_TYPE_INT: {
BLO_read_struct(reader, IDPropertyUIDataInt, &prop->ui_data);
IDPropertyUIDataInt *ui_data_int = (IDPropertyUIDataInt *)prop->ui_data;
if (prop->type == IDP_ARRAY) {
BLO_read_int32_array(
reader, ui_data_int->default_array_len, (int **)&ui_data_int->default_array);
}
BLO_read_data_address(reader, &ui_data_int->enum_items);
BLO_read_struct_array(reader,
IDPropertyUIDataEnumItem,
size_t(ui_data_int->enum_items_num),
&ui_data_int->enum_items);
for (const int64_t i : blender::IndexRange(ui_data_int->enum_items_num)) {
IDPropertyUIDataEnumItem &item = ui_data_int->enum_items[i];
BLO_read_data_address(reader, &item.identifier);
BLO_read_data_address(reader, &item.name);
BLO_read_data_address(reader, &item.description);
BLO_read_string(reader, &item.identifier);
BLO_read_string(reader, &item.name);
BLO_read_string(reader, &item.description);
}
break;
}
case IDP_UI_DATA_TYPE_BOOLEAN: {
BLO_read_struct(reader, IDPropertyUIDataBool, &prop->ui_data);
IDPropertyUIDataBool *ui_data_bool = (IDPropertyUIDataBool *)prop->ui_data;
if (prop->type == IDP_ARRAY) {
BLO_read_int8_array(
@ -1440,6 +1445,7 @@ static void read_ui_data(IDProperty *prop, BlendDataReader *reader)
break;
}
case IDP_UI_DATA_TYPE_FLOAT: {
BLO_read_struct(reader, IDPropertyUIDataFloat, &prop->ui_data);
IDPropertyUIDataFloat *ui_data_float = (IDPropertyUIDataFloat *)prop->ui_data;
if (prop->type == IDP_ARRAY) {
BLO_read_double_array(
@ -1448,17 +1454,22 @@ static void read_ui_data(IDProperty *prop, BlendDataReader *reader)
break;
}
case IDP_UI_DATA_TYPE_UNSUPPORTED: {
BLO_read_data_address(reader, &prop->ui_data);
BLI_assert_unreachable();
break;
}
}
if (prop->ui_data) {
BLO_read_string(reader, &prop->ui_data->description);
}
}
static void IDP_DirectLinkIDPArray(IDProperty *prop, BlendDataReader *reader)
{
/* since we didn't save the extra buffer, set totallen to len */
prop->totallen = prop->len;
BLO_read_data_address(reader, &prop->data.pointer);
BLO_read_struct_array(reader, IDProperty, size_t(prop->len), &prop->data.pointer);
IDProperty *array = (IDProperty *)prop->data.pointer;
@ -1503,14 +1514,14 @@ static void IDP_DirectLinkString(IDProperty *prop, BlendDataReader *reader)
{
/* Since we didn't save the extra string buffer, set totallen to len. */
prop->totallen = prop->len;
BLO_read_data_address(reader, &prop->data.pointer);
BLO_read_char_array(reader, prop->len, reinterpret_cast<char **>(&prop->data.pointer));
}
static void IDP_DirectLinkGroup(IDProperty *prop, BlendDataReader *reader)
{
ListBase *lb = &prop->data.group;
BLO_read_list(reader, lb);
BLO_read_struct_list(reader, IDProperty, lb);
/* Link child id properties now. */
LISTBASE_FOREACH (IDProperty *, loop, &prop->data.group) {

View File

@ -398,16 +398,16 @@ static void image_blend_write(BlendWriter *writer, ID *id, const void *id_addres
static void image_blend_read_data(BlendDataReader *reader, ID *id)
{
Image *ima = (Image *)id;
BLO_read_list(reader, &ima->tiles);
BLO_read_struct_list(reader, ImageTile, &ima->tiles);
BLO_read_list(reader, &(ima->renderslots));
BLO_read_struct_list(reader, RenderSlot, &(ima->renderslots));
if (!BLO_read_data_is_undo(reader)) {
/* We reset this last render slot index only when actually reading a file, not for undo. */
ima->last_render_slot = ima->render_slot;
}
BLO_read_list(reader, &(ima->views));
BLO_read_list(reader, &(ima->packedfiles));
BLO_read_struct_list(reader, ImageView, &(ima->views));
BLO_read_struct_list(reader, ImagePackedFile, &(ima->packedfiles));
if (ima->packedfiles.first) {
LISTBASE_FOREACH (ImagePackedFile *, imapf, &ima->packedfiles) {
@ -420,9 +420,9 @@ static void image_blend_read_data(BlendDataReader *reader, ID *id)
}
BLI_listbase_clear(&ima->anims);
BLO_read_data_address(reader, &ima->preview);
BLO_read_struct(reader, PreviewImage, &ima->preview);
BKE_previewimg_blend_read(reader, ima->preview);
BLO_read_data_address(reader, &ima->stereo3d_format);
BLO_read_struct(reader, Stereo3dFormat, &ima->stereo3d_format);
ima->lastused = 0;
ima->gpuflag = 0;

View File

@ -117,12 +117,12 @@ static void ipo_blend_read_data(BlendDataReader *reader, ID *id)
{
Ipo *ipo = (Ipo *)id;
BLO_read_list(reader, &(ipo->curve));
BLO_read_struct_list(reader, IpoCurve, &(ipo->curve));
LISTBASE_FOREACH (IpoCurve *, icu, &ipo->curve) {
BLO_read_data_address(reader, &icu->bezt);
BLO_read_data_address(reader, &icu->bp);
BLO_read_data_address(reader, &icu->driver);
BLO_read_struct_array(reader, BezTriple, icu->totvert, &icu->bezt);
BLO_read_struct_array(reader, BPoint, icu->totvert, &icu->bp);
BLO_read_struct(reader, IpoDriver, &icu->driver);
/* Undo generic endian switching. */
if (BLO_read_requires_endian_switch(reader)) {

View File

@ -172,9 +172,9 @@ static void switch_endian_keyblock(Key *key, KeyBlock *kb)
static void shapekey_blend_read_data(BlendDataReader *reader, ID *id)
{
Key *key = (Key *)id;
BLO_read_list(reader, &(key->block));
BLO_read_struct_list(reader, KeyBlock, &(key->block));
BLO_read_data_address(reader, &key->refkey);
BLO_read_struct(reader, KeyBlock, &key->refkey);
LISTBASE_FOREACH (KeyBlock *, kb, &key->block) {
BLO_read_data_address(reader, &kb->data);

View File

@ -150,11 +150,11 @@ static void lattice_blend_write(BlendWriter *writer, ID *id, const void *id_addr
static void lattice_blend_read_data(BlendDataReader *reader, ID *id)
{
Lattice *lt = (Lattice *)id;
BLO_read_data_address(reader, &lt->def);
BLO_read_struct_array(reader, BPoint, lt->pntsu * lt->pntsv * lt->pntsw, &lt->def);
BLO_read_data_address(reader, &lt->dvert);
BLO_read_struct_array(reader, MDeformVert, lt->pntsu * lt->pntsv * lt->pntsw, &lt->dvert);
BKE_defvert_blend_read(reader, lt->pntsu * lt->pntsv * lt->pntsw, lt->dvert);
BLO_read_list(reader, &lt->vertex_group_names);
BLO_read_struct_list(reader, bDeformGroup, &lt->vertex_group_names);
lt->editlatt = nullptr;
lt->batch_cache = nullptr;

View File

@ -2407,39 +2407,57 @@ void BKE_view_layer_blend_write(BlendWriter *writer, const Scene *scene, ViewLay
write_layer_collections(writer, &view_layer->layer_collections);
}
static void direct_link_layer_collections(BlendDataReader *reader, ListBase *lb, bool master)
static void direct_link_layer_collections(BlendDataReader *reader,
ViewLayer *view_layer,
ListBase *lb,
bool master,
bool &active_collection_found)
{
BLO_read_list(reader, lb);
BLO_read_struct_list(reader, LayerCollection, lb);
LISTBASE_FOREACH (LayerCollection *, lc, lb) {
/* Master collection is not a real data-block. */
if (master) {
BLO_read_data_address(reader, &lc->collection);
BLO_read_struct(reader, Collection, &lc->collection);
}
direct_link_layer_collections(reader, &lc->layer_collections, false);
if (lc == view_layer->active_collection) {
active_collection_found = true;
}
direct_link_layer_collections(
reader, view_layer, &lc->layer_collections, false, active_collection_found);
}
}
void BKE_view_layer_blend_read_data(BlendDataReader *reader, ViewLayer *view_layer)
{
view_layer->stats = nullptr;
BLO_read_list(reader, &view_layer->object_bases);
BLO_read_data_address(reader, &view_layer->basact);
BLO_read_struct_list(reader, Base, &view_layer->object_bases);
BLO_read_struct(reader, Base, &view_layer->basact);
direct_link_layer_collections(reader, &view_layer->layer_collections, true);
BLO_read_data_address(reader, &view_layer->active_collection);
bool active_collection_found = false;
BLO_read_struct(reader, LayerCollection, &view_layer->active_collection);
BLO_read_data_address(reader, &view_layer->id_properties);
direct_link_layer_collections(
reader, view_layer, &view_layer->layer_collections, true, active_collection_found);
if (!active_collection_found) {
/* Ensure pointer is valid, in case of corrupt blend file. */
view_layer->active_collection = static_cast<LayerCollection *>(
view_layer->layer_collections.first);
}
BLO_read_struct(reader, IDProperty, &view_layer->id_properties);
IDP_BlendDataRead(reader, &view_layer->id_properties);
BLO_read_list(reader, &(view_layer->freestyle_config.modules));
BLO_read_list(reader, &(view_layer->freestyle_config.linesets));
BLO_read_struct_list(reader, FreestyleModuleConfig, &(view_layer->freestyle_config.modules));
BLO_read_struct_list(reader, FreestyleLineSet, &(view_layer->freestyle_config.linesets));
BLO_read_list(reader, &view_layer->aovs);
BLO_read_data_address(reader, &view_layer->active_aov);
BLO_read_struct_list(reader, ViewLayerAOV, &view_layer->aovs);
BLO_read_struct(reader, ViewLayerAOV, &view_layer->active_aov);
BLO_read_list(reader, &view_layer->lightgroups);
BLO_read_data_address(reader, &view_layer->active_lightgroup);
BLO_read_struct_list(reader, ViewLayerLightgroup, &view_layer->lightgroups);
BLO_read_struct(reader, ViewLayerLightgroup, &view_layer->active_lightgroup);
BLI_listbase_clear(&view_layer->drawdata);
view_layer->object_bases_array = nullptr;

View File

@ -153,7 +153,7 @@ static void light_blend_read_data(BlendDataReader *reader, ID *id)
{
Light *la = (Light *)id;
BLO_read_data_address(reader, &la->preview);
BLO_read_struct(reader, PreviewImage, &la->preview);
BKE_previewimg_blend_read(reader, la->preview);
}

View File

@ -144,7 +144,7 @@ static void lightprobe_grid_cache_frame_blend_read(BlendDataReader *reader,
return;
}
BLO_read_data_address(reader, &cache->block_infos);
BLO_read_struct_array(reader, LightProbeGridCacheFrame, cache->block_len, &cache->block_infos);
int64_t sample_count = BKE_lightprobe_grid_cache_frame_sample_count(cache);
@ -168,7 +168,7 @@ static void lightprobe_grid_cache_frame_blend_read(BlendDataReader *reader,
BLO_read_float_array(reader, sample_count, &cache->visibility.L1_b);
BLO_read_float_array(reader, sample_count, &cache->visibility.L1_c);
BLO_read_data_address(reader, &cache->connectivity.validity);
BLO_read_int8_array(reader, sample_count, (int8_t **)&cache->connectivity.validity);
}
void BKE_lightprobe_cache_blend_write(BlendWriter *writer, LightProbeObjectCache *cache)
@ -182,7 +182,7 @@ void BKE_lightprobe_cache_blend_write(BlendWriter *writer, LightProbeObjectCache
void BKE_lightprobe_cache_blend_read(BlendDataReader *reader, LightProbeObjectCache *cache)
{
if (cache->grid_static_cache != nullptr) {
BLO_read_data_address(reader, &cache->grid_static_cache);
BLO_read_struct(reader, LightProbeGridCacheFrame, &cache->grid_static_cache);
lightprobe_grid_cache_frame_blend_read(reader, cache->grid_static_cache);
}
}

View File

@ -463,44 +463,44 @@ static void direct_link_linestyle_color_modifier(BlendDataReader *reader,
switch (modifier->type) {
case LS_MODIFIER_ALONG_STROKE: {
LineStyleColorModifier_AlongStroke *m = (LineStyleColorModifier_AlongStroke *)modifier;
BLO_read_data_address(reader, &m->color_ramp);
BLO_read_struct(reader, ColorBand, &m->color_ramp);
break;
}
case LS_MODIFIER_DISTANCE_FROM_CAMERA: {
LineStyleColorModifier_DistanceFromCamera *m = (LineStyleColorModifier_DistanceFromCamera *)
modifier;
BLO_read_data_address(reader, &m->color_ramp);
BLO_read_struct(reader, ColorBand, &m->color_ramp);
break;
}
case LS_MODIFIER_DISTANCE_FROM_OBJECT: {
LineStyleColorModifier_DistanceFromObject *m = (LineStyleColorModifier_DistanceFromObject *)
modifier;
BLO_read_data_address(reader, &m->color_ramp);
BLO_read_struct(reader, ColorBand, &m->color_ramp);
break;
}
case LS_MODIFIER_MATERIAL: {
LineStyleColorModifier_Material *m = (LineStyleColorModifier_Material *)modifier;
BLO_read_data_address(reader, &m->color_ramp);
BLO_read_struct(reader, ColorBand, &m->color_ramp);
break;
}
case LS_MODIFIER_TANGENT: {
LineStyleColorModifier_Tangent *m = (LineStyleColorModifier_Tangent *)modifier;
BLO_read_data_address(reader, &m->color_ramp);
BLO_read_struct(reader, ColorBand, &m->color_ramp);
break;
}
case LS_MODIFIER_NOISE: {
LineStyleColorModifier_Noise *m = (LineStyleColorModifier_Noise *)modifier;
BLO_read_data_address(reader, &m->color_ramp);
BLO_read_struct(reader, ColorBand, &m->color_ramp);
break;
}
case LS_MODIFIER_CREASE_ANGLE: {
LineStyleColorModifier_CreaseAngle *m = (LineStyleColorModifier_CreaseAngle *)modifier;
BLO_read_data_address(reader, &m->color_ramp);
BLO_read_struct(reader, ColorBand, &m->color_ramp);
break;
}
case LS_MODIFIER_CURVATURE_3D: {
LineStyleColorModifier_Curvature_3D *m = (LineStyleColorModifier_Curvature_3D *)modifier;
BLO_read_data_address(reader, &m->color_ramp);
BLO_read_struct(reader, ColorBand, &m->color_ramp);
break;
}
}
@ -512,51 +512,51 @@ static void direct_link_linestyle_alpha_modifier(BlendDataReader *reader,
switch (modifier->type) {
case LS_MODIFIER_ALONG_STROKE: {
LineStyleAlphaModifier_AlongStroke *m = (LineStyleAlphaModifier_AlongStroke *)modifier;
BLO_read_data_address(reader, &m->curve);
BLO_read_struct(reader, CurveMapping, &m->curve);
BKE_curvemapping_blend_read(reader, m->curve);
break;
}
case LS_MODIFIER_DISTANCE_FROM_CAMERA: {
LineStyleAlphaModifier_DistanceFromCamera *m = (LineStyleAlphaModifier_DistanceFromCamera *)
modifier;
BLO_read_data_address(reader, &m->curve);
BLO_read_struct(reader, CurveMapping, &m->curve);
BKE_curvemapping_blend_read(reader, m->curve);
break;
}
case LS_MODIFIER_DISTANCE_FROM_OBJECT: {
LineStyleAlphaModifier_DistanceFromObject *m = (LineStyleAlphaModifier_DistanceFromObject *)
modifier;
BLO_read_data_address(reader, &m->curve);
BLO_read_struct(reader, CurveMapping, &m->curve);
BKE_curvemapping_blend_read(reader, m->curve);
break;
}
case LS_MODIFIER_MATERIAL: {
LineStyleAlphaModifier_Material *m = (LineStyleAlphaModifier_Material *)modifier;
BLO_read_data_address(reader, &m->curve);
BLO_read_struct(reader, CurveMapping, &m->curve);
BKE_curvemapping_blend_read(reader, m->curve);
break;
}
case LS_MODIFIER_TANGENT: {
LineStyleAlphaModifier_Tangent *m = (LineStyleAlphaModifier_Tangent *)modifier;
BLO_read_data_address(reader, &m->curve);
BLO_read_struct(reader, CurveMapping, &m->curve);
BKE_curvemapping_blend_read(reader, m->curve);
break;
}
case LS_MODIFIER_NOISE: {
LineStyleAlphaModifier_Noise *m = (LineStyleAlphaModifier_Noise *)modifier;
BLO_read_data_address(reader, &m->curve);
BLO_read_struct(reader, CurveMapping, &m->curve);
BKE_curvemapping_blend_read(reader, m->curve);
break;
}
case LS_MODIFIER_CREASE_ANGLE: {
LineStyleAlphaModifier_CreaseAngle *m = (LineStyleAlphaModifier_CreaseAngle *)modifier;
BLO_read_data_address(reader, &m->curve);
BLO_read_struct(reader, CurveMapping, &m->curve);
BKE_curvemapping_blend_read(reader, m->curve);
break;
}
case LS_MODIFIER_CURVATURE_3D: {
LineStyleAlphaModifier_Curvature_3D *m = (LineStyleAlphaModifier_Curvature_3D *)modifier;
BLO_read_data_address(reader, &m->curve);
BLO_read_struct(reader, CurveMapping, &m->curve);
BKE_curvemapping_blend_read(reader, m->curve);
break;
}
@ -570,47 +570,47 @@ static void direct_link_linestyle_thickness_modifier(BlendDataReader *reader,
case LS_MODIFIER_ALONG_STROKE: {
LineStyleThicknessModifier_AlongStroke *m = (LineStyleThicknessModifier_AlongStroke *)
modifier;
BLO_read_data_address(reader, &m->curve);
BLO_read_struct(reader, CurveMapping, &m->curve);
BKE_curvemapping_blend_read(reader, m->curve);
break;
}
case LS_MODIFIER_DISTANCE_FROM_CAMERA: {
LineStyleThicknessModifier_DistanceFromCamera *m =
(LineStyleThicknessModifier_DistanceFromCamera *)modifier;
BLO_read_data_address(reader, &m->curve);
BLO_read_struct(reader, CurveMapping, &m->curve);
BKE_curvemapping_blend_read(reader, m->curve);
break;
}
case LS_MODIFIER_DISTANCE_FROM_OBJECT: {
LineStyleThicknessModifier_DistanceFromObject *m =
(LineStyleThicknessModifier_DistanceFromObject *)modifier;
BLO_read_data_address(reader, &m->curve);
BLO_read_struct(reader, CurveMapping, &m->curve);
BKE_curvemapping_blend_read(reader, m->curve);
break;
}
case LS_MODIFIER_MATERIAL: {
LineStyleThicknessModifier_Material *m = (LineStyleThicknessModifier_Material *)modifier;
BLO_read_data_address(reader, &m->curve);
BLO_read_struct(reader, CurveMapping, &m->curve);
BKE_curvemapping_blend_read(reader, m->curve);
break;
}
case LS_MODIFIER_TANGENT: {
LineStyleThicknessModifier_Tangent *m = (LineStyleThicknessModifier_Tangent *)modifier;
BLO_read_data_address(reader, &m->curve);
BLO_read_struct(reader, CurveMapping, &m->curve);
BKE_curvemapping_blend_read(reader, m->curve);
break;
}
case LS_MODIFIER_CREASE_ANGLE: {
LineStyleThicknessModifier_CreaseAngle *m = (LineStyleThicknessModifier_CreaseAngle *)
modifier;
BLO_read_data_address(reader, &m->curve);
BLO_read_struct(reader, CurveMapping, &m->curve);
BKE_curvemapping_blend_read(reader, m->curve);
break;
}
case LS_MODIFIER_CURVATURE_3D: {
LineStyleThicknessModifier_Curvature_3D *m = (LineStyleThicknessModifier_Curvature_3D *)
modifier;
BLO_read_data_address(reader, &m->curve);
BLO_read_struct(reader, CurveMapping, &m->curve);
BKE_curvemapping_blend_read(reader, m->curve);
break;
}
@ -626,24 +626,24 @@ static void linestyle_blend_read_data(BlendDataReader *reader, ID *id)
{
FreestyleLineStyle *linestyle = (FreestyleLineStyle *)id;
BLO_read_list(reader, &linestyle->color_modifiers);
BLO_read_struct_list(reader, LineStyleModifier, &linestyle->color_modifiers);
LISTBASE_FOREACH (LineStyleModifier *, modifier, &linestyle->color_modifiers) {
direct_link_linestyle_color_modifier(reader, modifier);
}
BLO_read_list(reader, &linestyle->alpha_modifiers);
BLO_read_struct_list(reader, LineStyleModifier, &linestyle->alpha_modifiers);
LISTBASE_FOREACH (LineStyleModifier *, modifier, &linestyle->alpha_modifiers) {
direct_link_linestyle_alpha_modifier(reader, modifier);
}
BLO_read_list(reader, &linestyle->thickness_modifiers);
BLO_read_struct_list(reader, LineStyleModifier, &linestyle->thickness_modifiers);
LISTBASE_FOREACH (LineStyleModifier *, modifier, &linestyle->thickness_modifiers) {
direct_link_linestyle_thickness_modifier(reader, modifier);
}
BLO_read_list(reader, &linestyle->geometry_modifiers);
BLO_read_struct_list(reader, LineStyleModifier, &linestyle->geometry_modifiers);
LISTBASE_FOREACH (LineStyleModifier *, modifier, &linestyle->geometry_modifiers) {
direct_link_linestyle_geometry_modifier(reader, modifier);
}
for (int a = 0; a < MAX_MTEX; a++) {
BLO_read_data_address(reader, &linestyle->mtex[a]);
BLO_read_struct(reader, MTex, &linestyle->mtex[a]);
}
}

View File

@ -137,24 +137,24 @@ static void mask_blend_read_data(BlendDataReader *reader, ID *id)
{
Mask *mask = (Mask *)id;
BLO_read_list(reader, &mask->masklayers);
BLO_read_struct_list(reader, MaskLayer, &mask->masklayers);
LISTBASE_FOREACH (MaskLayer *, masklay, &mask->masklayers) {
/* Can't use #newdataadr since it's a pointer within an array. */
MaskSplinePoint *act_point_search = nullptr;
BLO_read_list(reader, &masklay->splines);
BLO_read_struct_list(reader, MaskSpline, &masklay->splines);
LISTBASE_FOREACH (MaskSpline *, spline, &masklay->splines) {
MaskSplinePoint *points_old = spline->points;
BLO_read_data_address(reader, &spline->points);
BLO_read_struct_array(reader, MaskSplinePoint, spline->tot_point, &spline->points);
for (int i = 0; i < spline->tot_point; i++) {
MaskSplinePoint *point = &spline->points[i];
if (point->tot_uw) {
BLO_read_data_address(reader, &point->uw);
BLO_read_struct_array(reader, MaskSplinePointUW, point->tot_uw, &point->uw);
}
}
@ -166,21 +166,14 @@ static void mask_blend_read_data(BlendDataReader *reader, ID *id)
}
}
BLO_read_list(reader, &masklay->splines_shapes);
BLO_read_struct_list(reader, MaskLayerShape, &masklay->splines_shapes);
LISTBASE_FOREACH (MaskLayerShape *, masklay_shape, &masklay->splines_shapes) {
BLO_read_data_address(reader, &masklay_shape->data);
if (masklay_shape->tot_vert) {
if (BLO_read_requires_endian_switch(reader)) {
BLI_endian_switch_float_array(masklay_shape->data,
masklay_shape->tot_vert * sizeof(float) *
MASK_OBJECT_SHAPE_ELEM_SIZE);
}
}
BLO_read_float_array(
reader, masklay_shape->tot_vert * MASK_OBJECT_SHAPE_ELEM_SIZE, &masklay_shape->data);
}
BLO_read_data_address(reader, &masklay->act_spline);
BLO_read_struct(reader, MaskSpline, &masklay->act_spline);
masklay->act_point = act_point_search;
}
}

View File

@ -226,12 +226,12 @@ static void material_blend_read_data(BlendDataReader *reader, ID *id)
ma->texpaintslot = nullptr;
BLO_read_data_address(reader, &ma->preview);
BLO_read_struct(reader, PreviewImage, &ma->preview);
BKE_previewimg_blend_read(reader, ma->preview);
BLI_listbase_clear(&ma->gpumaterial);
BLO_read_data_address(reader, &ma->gp_style);
BLO_read_struct(reader, MaterialGPencilStyle, &ma->gp_style);
}
IDTypeInfo IDType_ID_MA = {

View File

@ -133,7 +133,7 @@ static void metaball_blend_read_data(BlendDataReader *reader, ID *id)
BLO_read_pointer_array(reader, (void **)&mb->mat);
BLO_read_list(reader, &(mb->elems));
BLO_read_struct_list(reader, MetaElem, &(mb->elems));
mb->editelems = nullptr;
/* Must always be cleared (meta's don't have their own edit-data). */

View File

@ -333,17 +333,17 @@ static void mesh_blend_read_data(BlendDataReader *reader, ID *id)
/* Deprecated pointers to custom data layers are read here for backward compatibility
* with files where these were owning pointers rather than a view into custom data. */
BLO_read_data_address(reader, &mesh->mvert);
BLO_read_data_address(reader, &mesh->medge);
BLO_read_data_address(reader, &mesh->mface);
BLO_read_data_address(reader, &mesh->mtface);
BLO_read_data_address(reader, &mesh->dvert);
BLO_read_data_address(reader, &mesh->tface);
BLO_read_data_address(reader, &mesh->mcol);
BLO_read_struct_array(reader, MVert, mesh->verts_num, &mesh->mvert);
BLO_read_struct_array(reader, MEdge, mesh->edges_num, &mesh->medge);
BLO_read_struct_array(reader, MFace, mesh->totface_legacy, &mesh->mface);
BLO_read_struct_array(reader, MTFace, mesh->totface_legacy, &mesh->mtface);
BLO_read_struct_array(reader, MDeformVert, mesh->verts_num, &mesh->dvert);
BLO_read_struct_array(reader, TFace, mesh->totface_legacy, &mesh->tface);
BLO_read_struct_array(reader, MCol, mesh->totface_legacy, &mesh->mcol);
BLO_read_data_address(reader, &mesh->mselect);
BLO_read_struct_array(reader, MSelect, mesh->totselect, &mesh->mselect);
BLO_read_list(reader, &mesh->vertex_group_names);
BLO_read_struct_list(reader, bDeformGroup, &mesh->vertex_group_names);
CustomData_blend_read(reader, &mesh->vert_data, mesh->verts_num);
CustomData_blend_read(reader, &mesh->edge_data, mesh->edges_num);
@ -355,8 +355,8 @@ static void mesh_blend_read_data(BlendDataReader *reader, ID *id)
* Don't read them again if they were read as part of #CustomData. */
BKE_defvert_blend_read(reader, mesh->verts_num, mesh->dvert);
}
BLO_read_data_address(reader, &mesh->active_color_attribute);
BLO_read_data_address(reader, &mesh->default_color_attribute);
BLO_read_string(reader, &mesh->active_color_attribute);
BLO_read_string(reader, &mesh->default_color_attribute);
mesh->texspace_flag &= ~ME_TEXSPACE_FLAG_AUTO_EVALUATED;

View File

@ -30,6 +30,7 @@
#include "DNA_object_fluidsim_types.h"
#include "DNA_object_force_types.h"
#include "DNA_object_types.h"
#include "DNA_particle_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
@ -1242,7 +1243,7 @@ static ModifierData *modifier_replace_with_fluid(BlendDataReader *reader,
void BKE_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb, Object *ob)
{
BLO_read_list(reader, lb);
BLO_read_struct_list(reader, ModifierData, lb);
LISTBASE_FOREACH (ModifierData *, md, lb) {
md->error = nullptr;
@ -1294,8 +1295,8 @@ void BKE_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb, Object
clmd->clothObject = nullptr;
clmd->hairdata = nullptr;
BLO_read_data_address(reader, &clmd->sim_parms);
BLO_read_data_address(reader, &clmd->coll_parms);
BLO_read_struct(reader, ClothSimSettings, &clmd->sim_parms);
BLO_read_struct(reader, ClothCollSettings, &clmd->coll_parms);
BKE_ptcache_blend_read_data(reader, &clmd->ptcaches, &clmd->point_cache, 0);
@ -1306,7 +1307,7 @@ void BKE_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb, Object
clmd->sim_parms->reset = 0;
BLO_read_data_address(reader, &clmd->sim_parms->effector_weights);
BLO_read_struct(reader, EffectorWeights, &clmd->sim_parms->effector_weights);
if (!clmd->sim_parms->effector_weights) {
clmd->sim_parms->effector_weights = BKE_effector_add_weights(nullptr);
@ -1322,7 +1323,7 @@ void BKE_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb, Object
if (fmd->type == MOD_FLUID_TYPE_DOMAIN) {
fmd->flow = nullptr;
fmd->effector = nullptr;
BLO_read_data_address(reader, &fmd->domain);
BLO_read_struct(reader, FluidDomainSettings, &fmd->domain);
fmd->domain->fmd = fmd;
fmd->domain->fluid = nullptr;
@ -1338,9 +1339,9 @@ void BKE_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb, Object
fmd->domain->tex_velocity_y = nullptr;
fmd->domain->tex_velocity_z = nullptr;
fmd->domain->tex_wt = nullptr;
BLO_read_data_address(reader, &fmd->domain->coba);
BLO_read_struct(reader, ColorBand, &fmd->domain->coba);
BLO_read_data_address(reader, &fmd->domain->effector_weights);
BLO_read_struct(reader, EffectorWeights, &fmd->domain->effector_weights);
if (!fmd->domain->effector_weights) {
fmd->domain->effector_weights = BKE_effector_add_weights(nullptr);
}
@ -1373,19 +1374,19 @@ void BKE_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb, Object
else if (fmd->type == MOD_FLUID_TYPE_FLOW) {
fmd->domain = nullptr;
fmd->effector = nullptr;
BLO_read_data_address(reader, &fmd->flow);
BLO_read_struct(reader, FluidFlowSettings, &fmd->flow);
fmd->flow->fmd = fmd;
fmd->flow->mesh = nullptr;
fmd->flow->verts_old = nullptr;
fmd->flow->numverts = 0;
BLO_read_data_address(reader, &fmd->flow->psys);
BLO_read_struct(reader, ParticleSystem, &fmd->flow->psys);
fmd->flow->flags &= ~FLUID_FLOW_NEEDS_UPDATE;
}
else if (fmd->type == MOD_FLUID_TYPE_EFFEC) {
fmd->flow = nullptr;
fmd->domain = nullptr;
BLO_read_data_address(reader, &fmd->effector);
BLO_read_struct(reader, FluidEffectorSettings, &fmd->effector);
if (fmd->effector) {
fmd->effector->fmd = fmd;
fmd->effector->verts_old = nullptr;
@ -1406,19 +1407,19 @@ void BKE_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb, Object
DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md;
if (pmd->canvas) {
BLO_read_data_address(reader, &pmd->canvas);
BLO_read_struct(reader, DynamicPaintCanvasSettings, &pmd->canvas);
pmd->canvas->pmd = pmd;
pmd->canvas->flags &= ~MOD_DPAINT_BAKING; /* just in case */
if (pmd->canvas->surfaces.first) {
BLO_read_list(reader, &pmd->canvas->surfaces);
BLO_read_struct_list(reader, DynamicPaintSurface, &pmd->canvas->surfaces);
LISTBASE_FOREACH (DynamicPaintSurface *, surface, &pmd->canvas->surfaces) {
surface->canvas = pmd->canvas;
surface->data = nullptr;
BKE_ptcache_blend_read_data(reader, &(surface->ptcaches), &(surface->pointcache), 1);
BLO_read_data_address(reader, &surface->effector_weights);
BLO_read_struct(reader, EffectorWeights, &surface->effector_weights);
if (surface->effector_weights == nullptr) {
surface->effector_weights = BKE_effector_add_weights(nullptr);
}
@ -1426,11 +1427,11 @@ void BKE_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb, Object
}
}
if (pmd->brush) {
BLO_read_data_address(reader, &pmd->brush);
BLO_read_struct(reader, DynamicPaintBrushSettings, &pmd->brush);
pmd->brush->pmd = pmd;
BLO_read_data_address(reader, &pmd->brush->psys);
BLO_read_data_address(reader, &pmd->brush->paint_ramp);
BLO_read_data_address(reader, &pmd->brush->vel_ramp);
BLO_read_struct(reader, ParticleSystem, &pmd->brush->psys);
BLO_read_struct(reader, ColorBand, &pmd->brush->paint_ramp);
BLO_read_struct(reader, ColorBand, &pmd->brush->vel_ramp);
}
}

View File

@ -216,29 +216,31 @@ static void movieclip_blend_write(BlendWriter *writer, ID *id, const void *id_ad
static void direct_link_movieReconstruction(BlendDataReader *reader,
MovieTrackingReconstruction *reconstruction)
{
BLO_read_data_address(reader, &reconstruction->cameras);
BLO_read_struct_array(
reader, MovieReconstructedCamera, reconstruction->camnr, &reconstruction->cameras);
}
static void direct_link_movieTracks(BlendDataReader *reader, ListBase *tracksbase)
{
BLO_read_list(reader, tracksbase);
BLO_read_struct_list(reader, MovieTrackingTrack, tracksbase);
LISTBASE_FOREACH (MovieTrackingTrack *, track, tracksbase) {
BLO_read_data_address(reader, &track->markers);
BLO_read_struct_array(reader, MovieTrackingMarker, track->markersnr, &track->markers);
}
}
static void direct_link_moviePlaneTracks(BlendDataReader *reader, ListBase *plane_tracks_base)
{
BLO_read_list(reader, plane_tracks_base);
BLO_read_struct_list(reader, MovieTrackingPlaneTrack, plane_tracks_base);
LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track, plane_tracks_base) {
BLO_read_pointer_array(reader, (void **)&plane_track->point_tracks);
for (int i = 0; i < plane_track->point_tracksnr; i++) {
BLO_read_data_address(reader, &plane_track->point_tracks[i]);
BLO_read_struct(reader, MovieTrackingTrack, &plane_track->point_tracks[i]);
}
BLO_read_data_address(reader, &plane_track->markers);
BLO_read_struct_array(
reader, MovieTrackingPlaneMarker, plane_track->markersnr, &plane_track->markers);
}
}
@ -251,8 +253,8 @@ static void movieclip_blend_read_data(BlendDataReader *reader, ID *id)
direct_link_moviePlaneTracks(reader, &tracking->plane_tracks_legacy);
direct_link_movieReconstruction(reader, &tracking->reconstruction_legacy);
BLO_read_data_address(reader, &clip->tracking.act_track_legacy);
BLO_read_data_address(reader, &clip->tracking.act_plane_track_legacy);
BLO_read_struct(reader, MovieTrackingTrack, &clip->tracking.act_track_legacy);
BLO_read_struct(reader, MovieTrackingPlaneTrack, &clip->tracking.act_plane_track_legacy);
clip->anim = nullptr;
clip->tracking_context = nullptr;
@ -263,21 +265,21 @@ static void movieclip_blend_read_data(BlendDataReader *reader, ID *id)
BLI_listbase_clear(&clip->runtime.gputextures);
/* Needed for proper versioning, will be nullptr for all newer files anyway. */
BLO_read_data_address(reader, &clip->tracking.stabilization.rot_track_legacy);
BLO_read_struct(reader, MovieTrackingTrack, &clip->tracking.stabilization.rot_track_legacy);
clip->tracking.dopesheet.ok = 0;
BLI_listbase_clear(&clip->tracking.dopesheet.channels);
BLI_listbase_clear(&clip->tracking.dopesheet.coverage_segments);
BLO_read_list(reader, &tracking->objects);
BLO_read_struct_list(reader, MovieTrackingObject, &tracking->objects);
LISTBASE_FOREACH (MovieTrackingObject *, object, &tracking->objects) {
direct_link_movieTracks(reader, &object->tracks);
direct_link_moviePlaneTracks(reader, &object->plane_tracks);
direct_link_movieReconstruction(reader, &object->reconstruction);
BLO_read_data_address(reader, &object->active_track);
BLO_read_data_address(reader, &object->active_plane_track);
BLO_read_struct(reader, MovieTrackingTrack, &object->active_track);
BLO_read_struct(reader, MovieTrackingPlaneTrack, &object->active_plane_track);
}
}

View File

@ -2519,15 +2519,15 @@ static void blend_data_read_nla_strips(BlendDataReader *reader, ListBase *strips
{
LISTBASE_FOREACH (NlaStrip *, strip, strips) {
/* strip's child strips */
BLO_read_list(reader, &strip->strips);
BLO_read_struct_list(reader, NlaStrip, &strip->strips);
blend_data_read_nla_strips(reader, &strip->strips);
/* strip's F-Curves */
BLO_read_list(reader, &strip->fcurves);
BLO_read_struct_list(reader, FCurve, &strip->fcurves);
BKE_fcurve_blend_read_data_listbase(reader, &strip->fcurves);
/* strip's F-Modifiers */
BLO_read_list(reader, &strip->modifiers);
BLO_read_struct_list(reader, FModifier, &strip->modifiers);
BKE_fmodifiers_blend_read_data(reader, &strip->modifiers, nullptr);
}
}
@ -2553,7 +2553,7 @@ void BKE_nla_blend_read_data(BlendDataReader *reader, ID *id_owner, ListBase *tr
}
/* relink list of strips */
BLO_read_list(reader, &nlt->strips);
BLO_read_struct_list(reader, NlaStrip, &nlt->strips);
/* relink strip data */
blend_data_read_nla_strips(reader, &nlt->strips);

View File

@ -957,14 +957,14 @@ static bool is_node_socket_supported(const bNodeSocket *sock)
static void direct_link_node_socket(BlendDataReader *reader, bNodeSocket *sock)
{
BLO_read_data_address(reader, &sock->prop);
BLO_read_struct(reader, IDProperty, &sock->prop);
IDP_BlendDataRead(reader, &sock->prop);
BLO_read_data_address(reader, &sock->link);
BLO_read_struct(reader, bNodeLink, &sock->link);
sock->typeinfo = nullptr;
BLO_read_data_address(reader, &sock->storage);
BLO_read_data_address(reader, &sock->default_value);
BLO_read_data_address(reader, &sock->default_attribute_name);
BLO_read_string(reader, &sock->default_attribute_name);
sock->runtime = MEM_new<bNodeSocketRuntime>(__func__);
switch (eNodeSocketDatatype(sock->type)) {
@ -1041,7 +1041,7 @@ void ntreeBlendReadData(BlendDataReader *reader, ID *owner_id, bNodeTree *ntree)
ntree->runtime = MEM_new<bNodeTreeRuntime>(__func__);
BKE_ntree_update_tag_missing_runtime_data(ntree);
BLO_read_list(reader, &ntree->nodes);
BLO_read_struct_list(reader, bNode, &ntree->nodes);
int i;
LISTBASE_FOREACH_INDEX (bNode *, node, &ntree->nodes, i) {
node->runtime = MEM_new<bNodeRuntime>(__func__);
@ -1057,11 +1057,12 @@ void ntreeBlendReadData(BlendDataReader *reader, ID *owner_id, bNodeTree *ntree)
ntree->runtime->nodes_by_id.add_new(node);
}
BLO_read_list(reader, &node->inputs);
BLO_read_list(reader, &node->outputs);
BLO_read_data_address(reader, &node->panel_states_array);
BLO_read_struct_list(reader, bNodeSocket, &node->inputs);
BLO_read_struct_list(reader, bNodeSocket, &node->outputs);
BLO_read_struct_array(
reader, bNodePanelState, node->num_panel_states, &node->panel_states_array);
BLO_read_data_address(reader, &node->prop);
BLO_read_struct(reader, IDProperty, &node->prop);
IDP_BlendDataRead(reader, &node->prop);
if (node->type == CMP_NODE_MOVIEDISTORTION) {
@ -1088,7 +1089,7 @@ void ntreeBlendReadData(BlendDataReader *reader, ID *owner_id, bNodeTree *ntree)
}
case SH_NODE_SCRIPT: {
NodeShaderScript *nss = static_cast<NodeShaderScript *>(node->storage);
BLO_read_data_address(reader, &nss->bytecode);
BLO_read_string(reader, &nss->bytecode);
break;
}
case SH_NODE_TEX_POINTDENSITY: {
@ -1116,8 +1117,8 @@ void ntreeBlendReadData(BlendDataReader *reader, ID *owner_id, bNodeTree *ntree)
case CMP_NODE_CRYPTOMATTE_LEGACY:
case CMP_NODE_CRYPTOMATTE: {
NodeCryptomatte *nc = static_cast<NodeCryptomatte *>(node->storage);
BLO_read_data_address(reader, &nc->matte_id);
BLO_read_list(reader, &nc->entries);
BLO_read_string(reader, &nc->matte_id);
BLO_read_struct_list(reader, CryptomatteEntry, &nc->entries);
BLI_listbase_clear(&nc->runtime.layers);
break;
}
@ -1133,7 +1134,7 @@ void ntreeBlendReadData(BlendDataReader *reader, ID *owner_id, bNodeTree *ntree)
}
case FN_NODE_INPUT_STRING: {
NodeInputString *storage = static_cast<NodeInputString *>(node->storage);
BLO_read_data_address(reader, &storage->string);
BLO_read_string(reader, &storage->string);
break;
}
case GEO_NODE_SIMULATION_OUTPUT: {
@ -1154,10 +1155,13 @@ void ntreeBlendReadData(BlendDataReader *reader, ID *owner_id, bNodeTree *ntree)
}
case GEO_NODE_MENU_SWITCH: {
NodeMenuSwitch &storage = *static_cast<NodeMenuSwitch *>(node->storage);
BLO_read_data_address(reader, &storage.enum_definition.items_array);
BLO_read_struct_array(reader,
NodeEnumItem,
storage.enum_definition.items_num,
&storage.enum_definition.items_array);
for (const NodeEnumItem &item : storage.enum_definition.items()) {
BLO_read_data_address(reader, &item.name);
BLO_read_data_address(reader, &item.description);
BLO_read_string(reader, &item.name);
BLO_read_string(reader, &item.description);
}
break;
}
@ -1167,12 +1171,12 @@ void ntreeBlendReadData(BlendDataReader *reader, ID *owner_id, bNodeTree *ntree)
}
}
}
BLO_read_list(reader, &ntree->links);
BLO_read_struct_list(reader, bNodeLink, &ntree->links);
BLI_assert(ntree->all_nodes().size() == BLI_listbase_count(&ntree->nodes));
/* and we connect the rest */
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
BLO_read_data_address(reader, &node->parent);
BLO_read_struct(reader, bNode, &node->parent);
LISTBASE_FOREACH_MUTABLE (bNodeSocket *, sock, &node->inputs) {
direct_link_node_socket(reader, sock);
@ -1192,8 +1196,8 @@ void ntreeBlendReadData(BlendDataReader *reader, ID *owner_id, bNodeTree *ntree)
}
/* Read legacy interface socket lists for versioning. */
BLO_read_list(reader, &ntree->inputs_legacy);
BLO_read_list(reader, &ntree->outputs_legacy);
BLO_read_struct_list(reader, bNodeSocket, &ntree->inputs_legacy);
BLO_read_struct_list(reader, bNodeSocket, &ntree->outputs_legacy);
LISTBASE_FOREACH_MUTABLE (bNodeSocket *, sock, &ntree->inputs_legacy) {
direct_link_node_socket(reader, sock);
}
@ -1204,10 +1208,10 @@ void ntreeBlendReadData(BlendDataReader *reader, ID *owner_id, bNodeTree *ntree)
ntree->tree_interface.read_data(reader);
LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
BLO_read_data_address(reader, &link->fromnode);
BLO_read_data_address(reader, &link->tonode);
BLO_read_data_address(reader, &link->fromsock);
BLO_read_data_address(reader, &link->tosock);
BLO_read_struct(reader, bNode, &link->fromnode);
BLO_read_struct(reader, bNode, &link->tonode);
BLO_read_struct(reader, bNodeSocket, &link->fromsock);
BLO_read_struct(reader, bNodeSocket, &link->tosock);
}
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
@ -1217,13 +1221,14 @@ void ntreeBlendReadData(BlendDataReader *reader, ID *owner_id, bNodeTree *ntree)
remove_unsupported_sockets(&ntree->inputs_legacy, nullptr);
remove_unsupported_sockets(&ntree->outputs_legacy, nullptr);
BLO_read_data_address(reader, &ntree->geometry_node_asset_traits);
BLO_read_data_address(reader, &ntree->nested_node_refs);
BLO_read_struct(reader, GeometryNodeAssetTraits, &ntree->geometry_node_asset_traits);
BLO_read_struct_array(
reader, bNestedNodeRef, ntree->nested_node_refs_num, &ntree->nested_node_refs);
/* TODO: should be dealt by new generic cache handling of IDs... */
ntree->previews = nullptr;
BLO_read_data_address(reader, &ntree->preview);
BLO_read_struct(reader, PreviewImage, &ntree->preview);
BKE_previewimg_blend_read(reader, ntree->preview);
/* type verification is in lib-link */

View File

@ -575,12 +575,12 @@ static void item_read_data(BlendDataReader *reader, bNodeTreeInterfaceItem &item
switch (item.item_type) {
case NODE_INTERFACE_SOCKET: {
bNodeTreeInterfaceSocket &socket = reinterpret_cast<bNodeTreeInterfaceSocket &>(item);
BLO_read_data_address(reader, &socket.name);
BLO_read_data_address(reader, &socket.description);
BLO_read_data_address(reader, &socket.socket_type);
BLO_read_data_address(reader, &socket.default_attribute_name);
BLO_read_data_address(reader, &socket.identifier);
BLO_read_data_address(reader, &socket.properties);
BLO_read_string(reader, &socket.name);
BLO_read_string(reader, &socket.description);
BLO_read_string(reader, &socket.socket_type);
BLO_read_string(reader, &socket.default_attribute_name);
BLO_read_string(reader, &socket.identifier);
BLO_read_struct(reader, IDProperty, &socket.properties);
IDP_BlendDataRead(reader, &socket.properties);
socket_types::socket_data_read_data(reader, socket);
@ -588,11 +588,11 @@ static void item_read_data(BlendDataReader *reader, bNodeTreeInterfaceItem &item
}
case NODE_INTERFACE_PANEL: {
bNodeTreeInterfacePanel &panel = reinterpret_cast<bNodeTreeInterfacePanel &>(item);
BLO_read_data_address(reader, &panel.name);
BLO_read_data_address(reader, &panel.description);
BLO_read_string(reader, &panel.name);
BLO_read_string(reader, &panel.description);
BLO_read_pointer_array(reader, reinterpret_cast<void **>(&panel.items_array));
for (const int i : blender::IndexRange(panel.items_num)) {
BLO_read_data_address(reader, &panel.items_array[i]);
BLO_read_struct(reader, NodeEnumItem, &panel.items_array[i]);
item_read_data(reader, *panel.items_array[i]);
}
break;

View File

@ -626,7 +626,7 @@ static void object_blend_write(BlendWriter *writer, ID *id, const void *id_addre
/* direct data */
BLO_write_pointer_array(writer, ob->totcol, ob->mat);
BLO_write_raw(writer, sizeof(char) * ob->totcol, ob->matbits);
BLO_write_char_array(writer, ob->totcol, ob->matbits);
bArmature *arm = nullptr;
if (ob->type == OB_ARMATURE) {
@ -687,10 +687,10 @@ static void object_blend_write(BlendWriter *writer, ID *id, const void *id_addre
/* XXX deprecated - old animation system */
static void direct_link_nlastrips(BlendDataReader *reader, ListBase *strips)
{
BLO_read_list(reader, strips);
BLO_read_struct_list(reader, bActionStrip, strips);
LISTBASE_FOREACH (bActionStrip *, strip, strips) {
BLO_read_list(reader, &strip->modifiers);
BLO_read_struct_list(reader, bActionModifier, &strip->modifiers);
}
}
@ -719,32 +719,32 @@ static void object_blend_read_data(BlendDataReader *reader, ID *id)
ob->mode &= ~(OB_MODE_EDIT | OB_MODE_PARTICLE_EDIT);
}
BLO_read_data_address(reader, &ob->pose);
BLO_read_struct(reader, bPose, &ob->pose);
BKE_pose_blend_read_data(reader, &ob->id, ob->pose);
BLO_read_data_address(reader, &ob->mpath);
BLO_read_struct(reader, bMotionPath, &ob->mpath);
if (ob->mpath) {
animviz_motionpath_blend_read_data(reader, ob->mpath);
}
/* Only for versioning, vertex group names are now stored on object data. */
BLO_read_list(reader, &ob->defbase);
BLO_read_list(reader, &ob->fmaps);
BLO_read_struct_list(reader, bDeformGroup, &ob->defbase);
BLO_read_struct_list(reader, bFaceMap, &ob->fmaps);
/* XXX deprecated - old animation system <<< */
direct_link_nlastrips(reader, &ob->nlastrips);
BLO_read_list(reader, &ob->constraintChannels);
BLO_read_struct_list(reader, bConstraintChannel, &ob->constraintChannels);
/* >>> XXX deprecated - old animation system */
BLO_read_pointer_array(reader, (void **)&ob->mat);
BLO_read_data_address(reader, &ob->matbits);
BLO_read_char_array(reader, ob->totcol, &ob->matbits);
/* do it here, below old data gets converted */
BKE_modifier_blend_read_data(reader, &ob->modifiers, ob);
BKE_gpencil_modifier_blend_read_data(reader, &ob->greasepencil_modifiers, ob);
BKE_shaderfx_blend_read_data(reader, &ob->shader_fx, ob);
BLO_read_list(reader, &ob->effect);
BLO_read_struct_list(reader, PartEff, &ob->effect);
paf = (PartEff *)ob->effect.first;
while (paf) {
if (paf->type == EFF_PARTICLE) {
@ -797,9 +797,9 @@ static void object_blend_read_data(BlendDataReader *reader, ID *id)
paf = paf->next;
}
BLO_read_data_address(reader, &ob->pd);
BLO_read_struct(reader, PartDeflect, &ob->pd);
BKE_particle_partdeflect_blend_read_data(reader, ob->pd);
BLO_read_data_address(reader, &ob->soft);
BLO_read_struct(reader, SoftBody, &ob->soft);
if (ob->soft) {
SoftBody *sb = ob->soft;
@ -811,16 +811,16 @@ static void object_blend_read_data(BlendDataReader *reader, ID *id)
BLO_read_pointer_array(reader, (void **)&sb->keys);
if (sb->keys) {
for (int a = 0; a < sb->totkey; a++) {
BLO_read_data_address(reader, &sb->keys[a]);
BLO_read_struct(reader, SBVertex, &sb->keys[a]);
}
}
BLO_read_data_address(reader, &sb->effector_weights);
BLO_read_struct(reader, EffectorWeights, &sb->effector_weights);
if (!sb->effector_weights) {
sb->effector_weights = BKE_effector_add_weights(nullptr);
}
BLO_read_data_address(reader, &sb->shared);
BLO_read_struct(reader, SoftBody_Shared, &sb->shared);
if (sb->shared == nullptr) {
/* Link deprecated caches if they exist, so we can use them for versioning.
* We should only do this when `sb->shared == nullptr`, because those pointers
@ -833,25 +833,25 @@ static void object_blend_read_data(BlendDataReader *reader, ID *id)
BKE_ptcache_blend_read_data(reader, &sb->shared->ptcaches, &sb->shared->pointcache, false);
}
}
BLO_read_data_address(reader, &ob->fluidsimSettings); /* NT */
BLO_read_struct(reader, FluidsimSettings, &ob->fluidsimSettings); /* NT */
BLO_read_data_address(reader, &ob->rigidbody_object);
BLO_read_struct(reader, RigidBodyOb, &ob->rigidbody_object);
if (ob->rigidbody_object) {
RigidBodyOb *rbo = ob->rigidbody_object;
/* Allocate runtime-only struct */
rbo->shared = (RigidBodyOb_Shared *)MEM_callocN(sizeof(*rbo->shared), "RigidBodyObShared");
}
BLO_read_data_address(reader, &ob->rigidbody_constraint);
BLO_read_struct(reader, RigidBodyCon, &ob->rigidbody_constraint);
if (ob->rigidbody_constraint) {
ob->rigidbody_constraint->physics_constraint = nullptr;
}
BLO_read_list(reader, &ob->particlesystem);
BLO_read_struct_list(reader, ParticleSystem, &ob->particlesystem);
BKE_particle_system_blend_read_data(reader, &ob->particlesystem);
BKE_constraint_blend_read_data(reader, &ob->id, &ob->constraints);
BLO_read_list(reader, &ob->hooks);
BLO_read_struct_list(reader, ObHook, &ob->hooks);
while (ob->hooks.first) {
ObHook *hook = (ObHook *)ob->hooks.first;
HookModifierData *hmd = (HookModifierData *)BKE_modifier_new(eModifierType_Hook);
@ -879,12 +879,12 @@ static void object_blend_read_data(BlendDataReader *reader, ID *id)
MEM_freeN(hook);
}
BLO_read_data_address(reader, &ob->iuser);
BLO_read_struct(reader, ImageUser, &ob->iuser);
if (ob->type == OB_EMPTY && ob->empty_drawtype == OB_EMPTY_IMAGE && !ob->iuser) {
BKE_object_empty_draw_type_set(ob, ob->empty_drawtype);
}
BLO_read_list(reader, &ob->pc_ids);
BLO_read_struct_list(reader, LinkData, &ob->pc_ids);
/* in case this value changes in future, clamp else we get undefined behavior */
CLAMP(ob->rotmode, ROT_MODE_MIN, ROT_MODE_MAX);
@ -897,13 +897,13 @@ static void object_blend_read_data(BlendDataReader *reader, ID *id)
}
}
BLO_read_data_address(reader, &ob->preview);
BLO_read_struct(reader, PreviewImage, &ob->preview);
BKE_previewimg_blend_read(reader, ob->preview);
BLO_read_data_address(reader, &ob->lightgroup);
BLO_read_data_address(reader, &ob->light_linking);
BLO_read_struct(reader, LightgroupMembership, &ob->lightgroup);
BLO_read_struct(reader, LightLinking, &ob->light_linking);
BLO_read_data_address(reader, &ob->lightprobe_cache);
BLO_read_struct(reader, LightProbeObjectCache, &ob->lightprobe_cache);
if (ob->lightprobe_cache) {
BKE_lightprobe_cache_blend_read(reader, ob->lightprobe_cache);
}

View File

@ -138,7 +138,7 @@ static void palette_blend_write(BlendWriter *writer, ID *id, const void *id_addr
static void palette_blend_read_data(BlendDataReader *reader, ID *id)
{
Palette *palette = (Palette *)id;
BLO_read_list(reader, &palette->colors);
BLO_read_struct_list(reader, PaletteColor, &palette->colors);
}
static void palette_undo_preserve(BlendLibReader * /*reader*/, ID *id_new, ID *id_old)
@ -217,7 +217,7 @@ static void paint_curve_blend_write(BlendWriter *writer, ID *id, const void *id_
static void paint_curve_blend_read_data(BlendDataReader *reader, ID *id)
{
PaintCurve *pc = (PaintCurve *)id;
BLO_read_data_address(reader, &pc->points);
BLO_read_struct_array(reader, PaintCurvePoint, pc->tot_points, &pc->points);
}
IDTypeInfo IDType_ID_PC = {
@ -1380,7 +1380,7 @@ void BKE_paint_blend_write(BlendWriter *writer, Paint *p)
void BKE_paint_blend_read_data(BlendDataReader *reader, const Scene *scene, Paint *p)
{
BLO_read_data_address(reader, &p->cavity_curve);
BLO_read_struct(reader, CurveMapping, &p->cavity_curve);
if (p->cavity_curve) {
BKE_curvemapping_blend_read(reader, p->cavity_curve);
}
@ -1388,7 +1388,7 @@ void BKE_paint_blend_read_data(BlendDataReader *reader, const Scene *scene, Pain
BKE_paint_cavity_curve_preset(p, CURVE_PRESET_LINE);
}
BLO_read_data_address(reader, &p->brush_asset_reference);
BLO_read_struct(reader, AssetWeakReference, &p->brush_asset_reference);
if (p->brush_asset_reference) {
BKE_asset_weak_reference_read(reader, p->brush_asset_reference);
}

View File

@ -321,45 +321,48 @@ static void particle_settings_blend_read_data(BlendDataReader *reader, ID *id)
{
ParticleSettings *part = (ParticleSettings *)id;
BLO_read_data_address(reader, &part->pd);
BLO_read_data_address(reader, &part->pd2);
BLO_read_struct(reader, PartDeflect, &part->pd);
BLO_read_struct(reader, PartDeflect, &part->pd2);
BKE_particle_partdeflect_blend_read_data(reader, part->pd);
BKE_particle_partdeflect_blend_read_data(reader, part->pd2);
BLO_read_data_address(reader, &part->clumpcurve);
BLO_read_struct(reader, CurveMapping, &part->clumpcurve);
if (part->clumpcurve) {
BKE_curvemapping_blend_read(reader, part->clumpcurve);
}
BLO_read_data_address(reader, &part->roughcurve);
BLO_read_struct(reader, CurveMapping, &part->roughcurve);
if (part->roughcurve) {
BKE_curvemapping_blend_read(reader, part->roughcurve);
}
BLO_read_data_address(reader, &part->twistcurve);
BLO_read_struct(reader, CurveMapping, &part->twistcurve);
if (part->twistcurve) {
BKE_curvemapping_blend_read(reader, part->twistcurve);
}
BLO_read_data_address(reader, &part->effector_weights);
BLO_read_struct(reader, EffectorWeights, &part->effector_weights);
if (!part->effector_weights) {
part->effector_weights = BKE_effector_add_weights(part->force_group);
}
BLO_read_list(reader, &part->instance_weights);
BLO_read_struct_list(reader, ParticleDupliWeight, &part->instance_weights);
BLO_read_data_address(reader, &part->boids);
BLO_read_data_address(reader, &part->fluid);
BLO_read_struct(reader, BoidSettings, &part->boids);
BLO_read_struct(reader, SPHFluidSettings, &part->fluid);
if (part->boids) {
BLO_read_list(reader, &part->boids->states);
BLO_read_struct_list(reader, BoidState, &part->boids->states);
LISTBASE_FOREACH (BoidState *, state, &part->boids->states) {
BLO_read_list(reader, &state->rules);
BLO_read_list(reader, &state->conditions);
BLO_read_list(reader, &state->actions);
BLO_read_struct_list(reader, BoidRule, &state->rules);
#if 0
/* Not implemented yet. */
BLO_read_struct_list(reader, BoidCondition, &state->conditions);
BLO_read_struct_list(reader, BoidAction, &state->actions);
#endif
}
}
for (int a = 0; a < MAX_MTEX; a++) {
BLO_read_data_address(reader, &part->mtex[a]);
BLO_read_struct(reader, MTex, &part->mtex[a]);
}
/* Protect against integer overflow vulnerability. */
@ -5350,11 +5353,11 @@ void BKE_particle_system_blend_read_data(BlendDataReader *reader, ListBase *part
int a;
LISTBASE_FOREACH (ParticleSystem *, psys, particles) {
BLO_read_data_address(reader, &psys->particles);
BLO_read_struct_array(reader, ParticleData, psys->totpart, &psys->particles);
if (psys->particles && psys->particles->hair) {
for (a = 0, pa = psys->particles; a < psys->totpart; a++, pa++) {
BLO_read_data_address(reader, &pa->hair);
BLO_read_struct_array(reader, HairKey, pa->totkey, &pa->hair);
}
}
@ -5369,7 +5372,7 @@ void BKE_particle_system_blend_read_data(BlendDataReader *reader, ListBase *part
if (psys->particles && psys->particles->boid) {
pa = psys->particles;
BLO_read_data_address(reader, &pa->boid);
BLO_read_struct_array(reader, BoidParticle, psys->totpart, &pa->boid);
/* This is purely runtime data, but still can be an issue if left dangling. */
pa->boid->ground = nullptr;
@ -5385,12 +5388,12 @@ void BKE_particle_system_blend_read_data(BlendDataReader *reader, ListBase *part
}
}
BLO_read_data_address(reader, &psys->fluid_springs);
BLO_read_struct_array(reader, ParticleSpring, psys->tot_fluidsprings, &psys->fluid_springs);
BLO_read_data_address(reader, &psys->child);
BLO_read_struct_array(reader, ChildParticle, psys->totchild, &psys->child);
psys->effectors = nullptr;
BLO_read_list(reader, &psys->targets);
BLO_read_struct_list(reader, ParticleTarget, &psys->targets);
psys->edit = nullptr;
psys->free_edit = nullptr;
@ -5401,12 +5404,12 @@ void BKE_particle_system_blend_read_data(BlendDataReader *reader, ListBase *part
psys->pdd = nullptr;
if (psys->clmd) {
BLO_read_data_address(reader, &psys->clmd);
BLO_read_struct(reader, ClothModifierData, &psys->clmd);
psys->clmd->clothObject = nullptr;
psys->clmd->hairdata = nullptr;
BLO_read_data_address(reader, &psys->clmd->sim_parms);
BLO_read_data_address(reader, &psys->clmd->coll_parms);
BLO_read_struct(reader, ClothSimSettings, &psys->clmd->sim_parms);
BLO_read_struct(reader, ClothCollSettings, &psys->clmd->coll_parms);
if (psys->clmd->sim_parms) {
psys->clmd->sim_parms->effector_weights = nullptr;

View File

@ -3809,21 +3809,6 @@ void BKE_ptcache_invalidate(PointCache *cache)
}
}
static const char *ptcache_data_struct[] = {
"", // BPHYS_DATA_INDEX
"", // BPHYS_DATA_LOCATION
"", // BPHYS_DATA_VELOCITY
"", // BPHYS_DATA_ROTATION
"", // BPHYS_DATA_AVELOCITY / BPHYS_DATA_XCONST */
"", // BPHYS_DATA_SIZE:
"", // BPHYS_DATA_TIMES:
"BoidData", // case BPHYS_DATA_BOIDS:
};
static const char *ptcache_extra_struct[] = {
"",
"ParticleSpring",
"vec3f",
};
void BKE_ptcache_blend_write(BlendWriter *writer, ListBase *ptcaches)
{
LISTBASE_FOREACH (PointCache *, cache, ptcaches) {
@ -3835,59 +3820,68 @@ void BKE_ptcache_blend_write(BlendWriter *writer, ListBase *ptcaches)
for (int i = 0; i < BPHYS_TOT_DATA; i++) {
if (pm->data[i] && pm->data_types & (1 << i)) {
if (ptcache_data_struct[i][0] == '\0') {
BLO_write_raw(writer, MEM_allocN_len(pm->data[i]), pm->data[i]);
if (i == BPHYS_DATA_BOIDS) {
BLO_write_struct_array(writer, BoidData, pm->totpoint, pm->data[i]);
}
else {
BLO_write_struct_array_by_name(
writer, ptcache_data_struct[i], pm->totpoint, pm->data[i]);
BLO_write_raw(writer, MEM_allocN_len(pm->data[i]), pm->data[i]);
}
}
}
LISTBASE_FOREACH (PTCacheExtra *, extra, &pm->extradata) {
if (ptcache_extra_struct[extra->type][0] == '\0') {
continue;
}
BLO_write_struct(writer, PTCacheExtra, extra);
BLO_write_struct_array_by_name(
writer, ptcache_extra_struct[extra->type], extra->totdata, extra->data);
if (extra->type == BPHYS_EXTRA_FLUID_SPRINGS) {
BLO_write_struct_array(writer, ParticleSpring, extra->totdata, extra->data);
}
else if (extra->type == BPHYS_EXTRA_CLOTH_ACCELERATION) {
BLO_write_struct_array(writer, vec3f, extra->totdata, extra->data);
}
else if (extra->data) {
BLI_assert_unreachable();
}
}
}
}
}
}
static void direct_link_pointcache_cb(BlendDataReader *reader, void *data)
static void direct_link_pointcache_mem(BlendDataReader *reader, PTCacheMem *pm)
{
PTCacheMem *pm = static_cast<PTCacheMem *>(data);
for (int i = 0; i < BPHYS_TOT_DATA; i++) {
BLO_read_data_address(reader, &pm->data[i]);
/* the cache saves non-struct data without DNA */
if (pm->data[i] && ptcache_data_struct[i][0] == '\0' &&
BLO_read_requires_endian_switch(reader))
{
if (i == BPHYS_DATA_BOIDS) {
BLO_read_struct_array(reader, BoidData, pm->totpoint, &pm->data[i]);
}
else {
/* data_size returns bytes. */
int tot = (BKE_ptcache_data_size(i) * pm->totpoint) / sizeof(int);
int *poin = static_cast<int *>(pm->data[i]);
BLI_endian_switch_int32_array(poin, tot);
/* the cache saves non-struct data without DNA */
BLO_read_int32_array(reader, tot, reinterpret_cast<int **>(&pm->data[i]));
}
}
BLO_read_list(reader, &pm->extradata);
BLO_read_struct_list(reader, PTCacheExtra, &pm->extradata);
LISTBASE_FOREACH (PTCacheExtra *, extra, &pm->extradata) {
BLO_read_data_address(reader, &extra->data);
if (extra->type == BPHYS_EXTRA_FLUID_SPRINGS) {
BLO_read_struct_array(reader, ParticleSpring, extra->totdata, &extra->data);
}
else if (extra->type == BPHYS_EXTRA_CLOTH_ACCELERATION) {
BLO_read_struct_array(reader, vec3f, extra->totdata, &extra->data);
}
else if (extra->data) {
extra->data = nullptr;
}
}
}
static void direct_link_pointcache(BlendDataReader *reader, PointCache *cache)
{
if ((cache->flag & PTCACHE_DISK_CACHE) == 0) {
BLO_read_list_cb(reader, &cache->mem_cache, direct_link_pointcache_cb);
BLO_read_struct_list(reader, PTCacheMem, &cache->mem_cache);
LISTBASE_FOREACH (PTCacheMem *, pm, &cache->mem_cache) {
direct_link_pointcache_mem(reader, pm);
}
}
else {
BLI_listbase_clear(&cache->mem_cache);
@ -3907,7 +3901,7 @@ void BKE_ptcache_blend_read_data(BlendDataReader *reader,
int force_disk)
{
if (ptcaches->first) {
BLO_read_list(reader, ptcaches);
BLO_read_struct_list(reader, PointCache, ptcaches);
LISTBASE_FOREACH (PointCache *, cache, ptcaches) {
direct_link_pointcache(reader, cache);
if (force_disk) {
@ -3916,11 +3910,11 @@ void BKE_ptcache_blend_read_data(BlendDataReader *reader,
}
}
BLO_read_data_address(reader, ocache);
BLO_read_struct(reader, PointCache, ocache);
}
else if (*ocache) {
/* old "single" caches need to be linked too */
BLO_read_data_address(reader, ocache);
BLO_read_struct(reader, PointCache, ocache);
direct_link_pointcache(reader, *ocache);
if (force_disk) {
(*ocache)->flag |= PTCACHE_DISK_CACHE;

View File

@ -517,7 +517,7 @@ void BKE_previewimg_blend_read(BlendDataReader *reader, PreviewImage *prv)
for (int i = 0; i < NUM_ICON_SIZES; i++) {
if (prv->rect[i]) {
BLO_read_data_address(reader, &prv->rect[i]);
BLO_read_uint32_array(reader, prv->w[i] * prv->h[i], &prv->rect[i]);
}
/* PRV_RENDERING is a runtime only flag currently, but don't mess with it on undo! It gets

View File

@ -21,6 +21,7 @@
#include "DNA_curveprofile_types.h"
#include "DNA_defaults.h"
#include "DNA_gpencil_legacy_types.h"
#include "DNA_lightprobe_types.h"
#include "DNA_linestyle_types.h"
#include "DNA_mask_types.h"
#include "DNA_material_types.h"
@ -1182,7 +1183,7 @@ static void scene_blend_write(BlendWriter *writer, ID *id, const void *id_addres
static void direct_link_paint_helper(BlendDataReader *reader, const Scene *scene, Paint **paint)
{
/* TODO: is this needed. */
BLO_read_data_address(reader, paint);
BLO_read_struct(reader, Paint, paint);
if (*paint) {
BKE_paint_blend_read_data(reader, scene, *paint);
@ -1191,7 +1192,7 @@ static void direct_link_paint_helper(BlendDataReader *reader, const Scene *scene
static void link_recurs_seq(BlendDataReader *reader, ListBase *lb)
{
BLO_read_list(reader, lb);
BLO_read_struct_list(reader, Sequence, lb);
LISTBASE_FOREACH_MUTABLE (Sequence *, seq, lb) {
/* Sanity check. */
@ -1222,14 +1223,14 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
sce->runtime = MEM_new<SceneRuntime>(__func__);
BLO_read_list(reader, &(sce->base));
BLO_read_struct_list(reader, Base, &(sce->base));
BLO_read_list(reader, &sce->keyingsets);
BLO_read_struct_list(reader, KeyingSet, &sce->keyingsets);
BKE_keyingsets_blend_read_data(reader, &sce->keyingsets);
BLO_read_data_address(reader, &sce->basact);
BLO_read_struct(reader, Base, &sce->basact);
BLO_read_data_address(reader, &sce->toolsettings);
BLO_read_struct(reader, ToolSettings, &sce->toolsettings);
if (sce->toolsettings) {
/* Reset last_location and last_hit, so they are not remembered across sessions. In some files
@ -1256,8 +1257,9 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
sce->toolsettings->gp_sculpt.paintcursor = nullptr;
if (sce->toolsettings->sculpt) {
BLO_read_data_address(reader, &sce->toolsettings->sculpt->automasking_cavity_curve);
BLO_read_data_address(reader, &sce->toolsettings->sculpt->automasking_cavity_curve_op);
BLO_read_struct(reader, CurveMapping, &sce->toolsettings->sculpt->automasking_cavity_curve);
BLO_read_struct(
reader, CurveMapping, &sce->toolsettings->sculpt->automasking_cavity_curve_op);
if (sce->toolsettings->sculpt->automasking_cavity_curve) {
BKE_curvemapping_blend_read(reader, sce->toolsettings->sculpt->automasking_cavity_curve);
@ -1274,49 +1276,50 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
}
/* Relink grease pencil interpolation curves. */
BLO_read_data_address(reader, &sce->toolsettings->gp_interpolate.custom_ipo);
BLO_read_struct(reader, CurveMapping, &sce->toolsettings->gp_interpolate.custom_ipo);
if (sce->toolsettings->gp_interpolate.custom_ipo) {
BKE_curvemapping_blend_read(reader, sce->toolsettings->gp_interpolate.custom_ipo);
}
/* Relink grease pencil multi-frame falloff curve. */
BLO_read_data_address(reader, &sce->toolsettings->gp_sculpt.cur_falloff);
BLO_read_struct(reader, CurveMapping, &sce->toolsettings->gp_sculpt.cur_falloff);
if (sce->toolsettings->gp_sculpt.cur_falloff) {
BKE_curvemapping_blend_read(reader, sce->toolsettings->gp_sculpt.cur_falloff);
}
/* Relink grease pencil primitive curve. */
BLO_read_data_address(reader, &sce->toolsettings->gp_sculpt.cur_primitive);
BLO_read_struct(reader, CurveMapping, &sce->toolsettings->gp_sculpt.cur_primitive);
if (sce->toolsettings->gp_sculpt.cur_primitive) {
BKE_curvemapping_blend_read(reader, sce->toolsettings->gp_sculpt.cur_primitive);
}
/* Relink toolsettings curve profile. */
BLO_read_data_address(reader, &sce->toolsettings->custom_bevel_profile_preset);
BLO_read_struct(reader, CurveProfile, &sce->toolsettings->custom_bevel_profile_preset);
if (sce->toolsettings->custom_bevel_profile_preset) {
BKE_curveprofile_blend_read(reader, sce->toolsettings->custom_bevel_profile_preset);
}
BLO_read_data_address(reader, &sce->toolsettings->paint_mode.canvas_image);
BLO_read_data_address(reader, &sce->toolsettings->sequencer_tool_settings);
BLO_read_struct(reader, SequencerToolSettings, &sce->toolsettings->sequencer_tool_settings);
}
if (sce->ed) {
ListBase *old_seqbasep = &sce->ed->seqbase;
ListBase *old_displayed_channels = &sce->ed->channels;
BLO_read_data_address(reader, &sce->ed);
BLO_read_struct(reader, Editing, &sce->ed);
Editing *ed = sce->ed;
BLO_read_data_address(reader, &ed->act_seq);
BLO_read_struct(reader, Sequence, &ed->act_seq);
ed->cache = nullptr;
ed->prefetch_job = nullptr;
ed->runtime.sequence_lookup = nullptr;
ed->runtime.media_presence = nullptr;
/* recursive link sequences, lb will be correctly initialized */
link_recurs_seq(reader, &ed->seqbase);
/* Read in sequence member data. */
SEQ_blend_read(reader, &ed->seqbase);
BLO_read_list(reader, &ed->channels);
BLO_read_struct_list(reader, SeqTimelineChannel, &ed->channels);
/* link metastack, slight abuse of structs here,
* have to restore pointer to internal part in struct */
@ -1364,10 +1367,10 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
}
/* stack */
BLO_read_list(reader, &(ed->metastack));
BLO_read_struct_list(reader, MetaStack, &(ed->metastack));
LISTBASE_FOREACH (MetaStack *, ms, &ed->metastack) {
BLO_read_data_address(reader, &ms->parseq);
BLO_read_struct(reader, Sequence, &ms->parseq);
if (ms->oldbasep == old_seqbasep) {
ms->oldbasep = &ed->seqbase;
@ -1406,31 +1409,31 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
sce->r.mode &= ~R_NO_CAMERA_SWITCH;
#endif
BLO_read_list(reader, &(sce->markers));
BLO_read_struct_list(reader, TimeMarker, &(sce->markers));
LISTBASE_FOREACH (TimeMarker *, marker, &sce->markers) {
BLO_read_data_address(reader, &marker->prop);
BLO_read_struct(reader, IDProperty, &marker->prop);
IDP_BlendDataRead(reader, &marker->prop);
}
BLO_read_list(reader, &(sce->transform_spaces));
BLO_read_list(reader, &(sce->r.layers));
BLO_read_list(reader, &(sce->r.views));
BLO_read_struct_list(reader, TransformOrientation, &(sce->transform_spaces));
BLO_read_struct_list(reader, SceneRenderLayer, &(sce->r.layers));
BLO_read_struct_list(reader, SceneRenderView, &(sce->r.views));
LISTBASE_FOREACH (SceneRenderLayer *, srl, &sce->r.layers) {
BLO_read_data_address(reader, &srl->prop);
BLO_read_struct(reader, IDProperty, &srl->prop);
IDP_BlendDataRead(reader, &srl->prop);
BLO_read_list(reader, &(srl->freestyleConfig.modules));
BLO_read_list(reader, &(srl->freestyleConfig.linesets));
BLO_read_struct_list(reader, FreestyleModuleConfig, &(srl->freestyleConfig.modules));
BLO_read_struct_list(reader, FreestyleLineSet, &(srl->freestyleConfig.linesets));
}
BKE_color_managed_view_settings_blend_read_data(reader, &sce->view_settings);
BKE_image_format_blend_read_data(reader, &sce->r.im_format);
BKE_image_format_blend_read_data(reader, &sce->r.bake.im_format);
BLO_read_data_address(reader, &sce->rigidbody_world);
BLO_read_struct(reader, RigidBodyWorld, &sce->rigidbody_world);
RigidBodyWorld *rbw = sce->rigidbody_world;
if (rbw) {
BLO_read_data_address(reader, &rbw->shared);
BLO_read_struct(reader, RigidBodyWorld_Shared, &rbw->shared);
if (rbw->shared == nullptr) {
/* Link deprecated caches if they exist, so we can use them for versioning.
@ -1462,13 +1465,13 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
rbw->numbodies = 0;
/* set effector weights */
BLO_read_data_address(reader, &rbw->effector_weights);
BLO_read_struct(reader, EffectorWeights, &rbw->effector_weights);
if (!rbw->effector_weights) {
rbw->effector_weights = BKE_effector_add_weights(nullptr);
}
}
BLO_read_data_address(reader, &sce->preview);
BLO_read_struct(reader, PreviewImage, &sce->preview);
BKE_previewimg_blend_read(reader, sce->preview);
BKE_curvemapping_blend_read(reader, &sce->r.mblur_shutter_curve);
@ -1484,7 +1487,7 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
}
else {
/* else try to read the cache from file. */
BLO_read_data_address(reader, &sce->eevee.light_cache_data);
BLO_read_struct(reader, LightCache, &sce->eevee.light_cache_data);
if (sce->eevee.light_cache_data) {
EEVEE_lightcache_blend_read_data(reader, sce->eevee.light_cache_data);
}
@ -1494,7 +1497,7 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
BKE_screen_view3d_shading_blend_read_data(reader, &sce->display.shading);
BLO_read_data_address(reader, &sce->layer_properties);
BLO_read_struct(reader, IDProperty, &sce->layer_properties);
IDP_BlendDataRead(reader, &sce->layer_properties);
}

View File

@ -134,7 +134,7 @@ bool BKE_screen_blend_read_data(BlendDataReader *reader, bScreen *screen)
screen->tool_tip = nullptr;
screen->scrubbing = false;
BLO_read_data_address(reader, &screen->preview);
BLO_read_struct(reader, PreviewImage, &screen->preview);
BKE_previewimg_blend_read(reader, screen->preview);
if (!BKE_screen_area_map_blend_read_data(reader, AREAMAP_FROM_SCREEN(screen))) {
@ -1023,7 +1023,7 @@ void BKE_screen_view3d_shading_blend_write(BlendWriter *writer, View3DShading *s
void BKE_screen_view3d_shading_blend_read_data(BlendDataReader *reader, View3DShading *shading)
{
if (shading->prop) {
BLO_read_data_address(reader, &shading->prop);
BLO_read_struct(reader, IDProperty, &shading->prop);
IDP_BlendDataRead(reader, &shading->prop);
}
}
@ -1136,7 +1136,7 @@ void BKE_screen_area_map_blend_write(BlendWriter *writer, ScrAreaMap *area_map)
static void direct_link_panel_list(BlendDataReader *reader, ListBase *lb)
{
BLO_read_list(reader, lb);
BLO_read_struct_list(reader, Panel, lb);
LISTBASE_FOREACH (Panel *, panel, lb) {
panel->runtime = MEM_new<Panel_Runtime>(__func__);
@ -1144,9 +1144,9 @@ static void direct_link_panel_list(BlendDataReader *reader, ListBase *lb)
panel->activedata = nullptr;
panel->type = nullptr;
panel->drawname = nullptr;
BLO_read_list(reader, &panel->layout_panel_states);
BLO_read_struct_list(reader, LayoutPanelState, &panel->layout_panel_states);
LISTBASE_FOREACH (LayoutPanelState *, state, &panel->layout_panel_states) {
BLO_read_data_address(reader, &state->idname);
BLO_read_string(reader, &state->idname);
}
direct_link_panel_list(reader, &panel->children);
}
@ -1158,9 +1158,9 @@ static void direct_link_region(BlendDataReader *reader, ARegion *region, int spa
direct_link_panel_list(reader, &region->panels);
BLO_read_list(reader, &region->panels_category_active);
BLO_read_struct_list(reader, PanelCategoryStack, &region->panels_category_active);
BLO_read_list(reader, &region->ui_lists);
BLO_read_struct_list(reader, uiList, &region->ui_lists);
/* The area's search filter is runtime only, so we need to clear the active flag on read. */
/* Clear runtime flags (e.g. search filter is runtime only). */
@ -1169,11 +1169,11 @@ static void direct_link_region(BlendDataReader *reader, ARegion *region, int spa
LISTBASE_FOREACH (uiList *, ui_list, &region->ui_lists) {
ui_list->type = nullptr;
ui_list->dyn_data = nullptr;
BLO_read_data_address(reader, &ui_list->properties);
BLO_read_struct(reader, IDProperty, &ui_list->properties);
IDP_BlendDataRead(reader, &ui_list->properties);
}
BLO_read_list(reader, &region->ui_previews);
BLO_read_struct_list(reader, uiPreview, &region->ui_previews);
if (spacetype == SPACE_EMPTY) {
/* unknown space type, don't leak regiondata */
@ -1195,8 +1195,8 @@ static void direct_link_region(BlendDataReader *reader, ARegion *region, int spa
RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
BLO_read_data_address(reader, &rv3d->localvd);
BLO_read_data_address(reader, &rv3d->clipbb);
BLO_read_struct(reader, RegionView3D, &rv3d->localvd);
BLO_read_struct(reader, BoundBox, &rv3d->clipbb);
rv3d->view_render = nullptr;
rv3d->sms = nullptr;
@ -1250,8 +1250,8 @@ void BKE_screen_view3d_do_versions_250(View3D *v3d, ListBase *regions)
static void direct_link_area(BlendDataReader *reader, ScrArea *area)
{
BLO_read_list(reader, &(area->spacedata));
BLO_read_list(reader, &(area->regionbase));
BLO_read_struct_list(reader, SpaceLink, &(area->spacedata));
BLO_read_struct_list(reader, ARegion, &(area->regionbase));
BLI_listbase_clear(&area->handlers);
area->type = nullptr; /* spacetype callbacks */
@ -1265,7 +1265,7 @@ static void direct_link_area(BlendDataReader *reader, ScrArea *area)
area->flag &= ~AREA_FLAG_ACTIVE_TOOL_UPDATE;
BLO_read_data_address(reader, &area->global);
BLO_read_struct(reader, ScrGlobalAreaData, &area->global);
/* if we do not have the spacetype registered we cannot
* free it, so don't allocate any new memory for such spacetypes. */
@ -1294,7 +1294,7 @@ static void direct_link_area(BlendDataReader *reader, ScrArea *area)
}
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
BLO_read_list(reader, &(sl->regionbase));
BLO_read_struct_list(reader, ARegion, &(sl->regionbase));
/* if we do not have the spacetype registered we cannot
* free it, so don't allocate any new memory for such spacetypes. */
@ -1314,25 +1314,25 @@ static void direct_link_area(BlendDataReader *reader, ScrArea *area)
BLI_listbase_clear(&area->actionzones);
BLO_read_data_address(reader, &area->v1);
BLO_read_data_address(reader, &area->v2);
BLO_read_data_address(reader, &area->v3);
BLO_read_data_address(reader, &area->v4);
BLO_read_struct(reader, ScrVert, &area->v1);
BLO_read_struct(reader, ScrVert, &area->v2);
BLO_read_struct(reader, ScrVert, &area->v3);
BLO_read_struct(reader, ScrVert, &area->v4);
}
bool BKE_screen_area_map_blend_read_data(BlendDataReader *reader, ScrAreaMap *area_map)
{
BLO_read_list(reader, &area_map->vertbase);
BLO_read_list(reader, &area_map->edgebase);
BLO_read_list(reader, &area_map->areabase);
BLO_read_struct_list(reader, ScrVert, &area_map->vertbase);
BLO_read_struct_list(reader, ScrEdge, &area_map->edgebase);
BLO_read_struct_list(reader, ScrArea, &area_map->areabase);
LISTBASE_FOREACH (ScrArea *, area, &area_map->areabase) {
direct_link_area(reader, area);
}
/* edges */
LISTBASE_FOREACH (ScrEdge *, se, &area_map->edgebase) {
BLO_read_data_address(reader, &se->v1);
BLO_read_data_address(reader, &se->v2);
BLO_read_struct(reader, ScrVert, &se->v1);
BLO_read_struct(reader, ScrVert, &se->v2);
BKE_screen_sort_scrvert(&se->v1, &se->v2);
if (se->v1 == nullptr) {

View File

@ -274,7 +274,7 @@ void BKE_shaderfx_blend_write(BlendWriter *writer, ListBase *fxbase)
void BKE_shaderfx_blend_read_data(BlendDataReader *reader, ListBase *lb, Object *ob)
{
BLO_read_list(reader, lb);
BLO_read_struct_list(reader, ShaderFxData, lb);
LISTBASE_FOREACH (ShaderFxData *, fx, lb) {
fx->error = nullptr;

View File

@ -195,7 +195,7 @@ static void text_blend_write(BlendWriter *writer, ID *id, const void *id_address
static void text_blend_read_data(BlendDataReader *reader, ID *id)
{
Text *text = (Text *)id;
BLO_read_data_address(reader, &text->filepath);
BLO_read_string(reader, &text->filepath);
text->compiled = nullptr;
@ -206,13 +206,13 @@ static void text_blend_read_data(BlendDataReader *reader, ID *id)
/* else { */
#endif
BLO_read_list(reader, &text->lines);
BLO_read_struct_list(reader, TextLine, &text->lines);
BLO_read_data_address(reader, &text->curl);
BLO_read_data_address(reader, &text->sell);
BLO_read_struct(reader, TextLine, &text->curl);
BLO_read_struct(reader, TextLine, &text->sell);
LISTBASE_FOREACH (TextLine *, ln, &text->lines) {
BLO_read_data_address(reader, &ln->line);
BLO_read_string(reader, &ln->line);
ln->format = nullptr;
if (ln->len != int(strlen(ln->line))) {

View File

@ -185,9 +185,9 @@ static void texture_blend_read_data(BlendDataReader *reader, ID *id)
{
Tex *tex = (Tex *)id;
BLO_read_data_address(reader, &tex->coba);
BLO_read_struct(reader, ColorBand, &tex->coba);
BLO_read_data_address(reader, &tex->preview);
BLO_read_struct(reader, PreviewImage, &tex->preview);
BKE_previewimg_blend_read(reader, tex->preview);
tex->iuser.scene = nullptr;

View File

@ -102,9 +102,9 @@ void BKE_viewer_path_blend_write(BlendWriter *writer, const ViewerPath *viewer_p
void BKE_viewer_path_blend_read_data(BlendDataReader *reader, ViewerPath *viewer_path)
{
BLO_read_list(reader, &viewer_path->path);
BLO_read_struct_list(reader, ViewerPathElem, &viewer_path->path);
LISTBASE_FOREACH (ViewerPathElem *, elem, &viewer_path->path) {
BLO_read_data_address(reader, &elem->ui_name);
BLO_read_string(reader, &elem->ui_name);
switch (ViewerPathElemType(elem->type)) {
case VIEWER_PATH_ELEM_TYPE_GROUP_NODE:
case VIEWER_PATH_ELEM_TYPE_SIMULATION_ZONE:
@ -115,7 +115,7 @@ void BKE_viewer_path_blend_read_data(BlendDataReader *reader, ViewerPath *viewer
}
case VIEWER_PATH_ELEM_TYPE_MODIFIER: {
auto *typed_elem = reinterpret_cast<ModifierViewerPathElem *>(elem);
BLO_read_data_address(reader, &typed_elem->modifier_name);
BLO_read_string(reader, &typed_elem->modifier_name);
break;
}
}

View File

@ -98,10 +98,10 @@ static void workspace_blend_read_data(BlendDataReader *reader, ID *id)
{
WorkSpace *workspace = (WorkSpace *)id;
BLO_read_list(reader, &workspace->layouts);
BLO_read_list(reader, &workspace->hook_layout_relations);
BLO_read_list(reader, &workspace->owner_ids);
BLO_read_list(reader, &workspace->tools);
BLO_read_struct_list(reader, WorkSpaceLayout, &workspace->layouts);
BLO_read_struct_list(reader, WorkSpaceDataRelation, &workspace->hook_layout_relations);
BLO_read_struct_list(reader, wmOwnerID, &workspace->owner_ids);
BLO_read_struct_list(reader, bToolRef, &workspace->tools);
LISTBASE_FOREACH (WorkSpaceDataRelation *, relation, &workspace->hook_layout_relations) {
/* Parent pointer does not belong to workspace data and is therefore restored in lib_link step
@ -111,7 +111,7 @@ static void workspace_blend_read_data(BlendDataReader *reader, ID *id)
LISTBASE_FOREACH (bToolRef *, tref, &workspace->tools) {
tref->runtime = nullptr;
BLO_read_data_address(reader, &tref->properties);
BLO_read_struct(reader, IDProperty, &tref->properties);
IDP_BlendDataRead(reader, &tref->properties);
}

View File

@ -175,11 +175,11 @@ static void world_blend_read_data(BlendDataReader *reader, ID *id)
{
World *wrld = (World *)id;
BLO_read_data_address(reader, &wrld->preview);
BLO_read_struct(reader, PreviewImage, &wrld->preview);
BKE_previewimg_blend_read(reader, wrld->preview);
BLI_listbase_clear(&wrld->gpumaterial);
BLO_read_data_address(reader, &wrld->lightgroup);
BLO_read_struct(reader, LightgroupMembership, &wrld->lightgroup);
}
IDTypeInfo IDType_ID_WO = {

View File

@ -676,7 +676,7 @@ extern bool BLI_memory_is_zero(const void *arr, size_t arr_size);
*/
#define BLI_ENABLE_IF(condition) typename std::enable_if_t<(condition)> * = nullptr
#if defined(_MSC_VER)
#if defined(_MSC_VER) && !defined(__clang__)
# define BLI_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]]
#elif defined(__has_cpp_attribute)
# if __has_cpp_attribute(no_unique_address)

View File

@ -78,7 +78,12 @@ class Task {
other.freedata = nullptr;
}
#if defined(WITH_TBB) && TBB_INTERFACE_VERSION_MAJOR < 10
// TBB has a check in tbb/include/task_group.h where __TBB_CPP11_RVALUE_REF_PRESENT should evaluate
// to true as with the other MSVC build. However, because of the clang compiler it does not and we
// attempt to call a deleted constructor in the tbb_task_pool_run function. This check fixes this
// issue and keeps our Task constructor valid
#if (defined(WITH_TBB) && TBB_INTERFACE_VERSION_MAJOR < 10) || \
(defined(_MSC_VER) && defined(__clang__) && TBB_INTERFACE_VERSION_MAJOR < 12)
Task(const Task &other)
: pool(other.pool),
run(other.run),

View File

@ -175,7 +175,9 @@ void BLO_write_destroy_id_buffer(BLO_Write_IDBuffer **id_buffer);
* Write raw data.
*/
void BLO_write_raw(BlendWriter *writer, size_t size_in_bytes, const void *data_ptr);
void BLO_write_char_array(BlendWriter *writer, uint num, const char *data_ptr);
void BLO_write_int8_array(BlendWriter *writer, uint num, const int8_t *data_ptr);
void BLO_write_uint8_array(BlendWriter *writer, uint num, const uint8_t *data_ptr);
void BLO_write_int32_array(BlendWriter *writer, uint num, const int32_t *data_ptr);
void BLO_write_uint32_array(BlendWriter *writer, uint num, const uint32_t *data_ptr);
void BLO_write_float_array(BlendWriter *writer, uint num, const float *data_ptr);
@ -227,37 +229,53 @@ bool BLO_write_is_undo(BlendWriter *writer);
*
* \code{.c}
* BLO_write_struct(writer, ClothSimSettings, clmd->sim_parms);
* BLO_read_data_address(reader, &clmd->sim_parms);
* BLO_read_struct(reader, ClothSimSettings, &clmd->sim_parms);
*
* BLO_write_struct_list(writer, TimeMarker, &action->markers);
* BLO_read_list(reader, &action->markers);
* BLO_read_struct_list(reader, TimeMarker, &action->markers);
*
* BLO_write_int32_array(writer, hmd->totindex, hmd->indexar);
* BLO_read_int32_array(reader, hmd->totindex, &hmd->indexar);
* \endcode
*
* Avoid using the generic BLO_read_data_address when possible, use typed functions instead.
* \{ */
void *BLO_read_get_new_data_address(BlendDataReader *reader, const void *old_address);
void *BLO_read_get_new_data_address_no_us(BlendDataReader *reader, const void *old_address);
void *BLO_read_get_new_data_address_no_us(BlendDataReader *reader,
const void *old_address,
size_t data_size);
void *BLO_read_get_new_packed_address(BlendDataReader *reader, const void *old_address);
void *BLO_read_struct_array_with_size(BlendDataReader *reader,
const void *old_address,
size_t data_size);
#define BLO_read_data_address(reader, ptr_p) \
*((void **)ptr_p) = BLO_read_get_new_data_address((reader), *(ptr_p))
#define BLO_read_struct(reader, struct_name, ptr_p) \
*((void **)ptr_p) = BLO_read_struct_array_with_size( \
reader, *((void **)ptr_p), sizeof(struct_name))
#define BLO_read_struct_array(reader, struct_name, array_size, ptr_p) \
*((void **)ptr_p) = BLO_read_struct_array_with_size( \
reader, *((void **)ptr_p), sizeof(struct_name) * (array_size))
#define BLO_read_packed_address(reader, ptr_p) \
*((void **)ptr_p) = BLO_read_get_new_packed_address((reader), *(ptr_p))
using BlendReadListFn = void (*)(BlendDataReader *reader, void *data);
/**
/* Read all elements in list
*
* Updates all `->prev` and `->next` pointers of the list elements.
* Updates the `list->first` and `list->last` pointers.
* When not NULL, calls the callback on every element.
*/
void BLO_read_list_cb(BlendDataReader *reader, ListBase *list, BlendReadListFn callback);
void BLO_read_list(BlendDataReader *reader, ListBase *list);
void BLO_read_struct_list_with_size(BlendDataReader *reader, size_t elem_size, ListBase *list);
#define BLO_read_struct_list(reader, struct_name, list) \
BLO_read_struct_list_with_size(reader, sizeof(struct_name), list)
/* Update data pointers and correct byte-order if necessary. */
void BLO_read_char_array(BlendDataReader *reader, int array_size, char **ptr_p);
void BLO_read_int8_array(BlendDataReader *reader, int array_size, int8_t **ptr_p);
void BLO_read_uint8_array(BlendDataReader *reader, int array_size, uint8_t **ptr_p);
void BLO_read_int32_array(BlendDataReader *reader, int array_size, int32_t **ptr_p);
void BLO_read_uint32_array(BlendDataReader *reader, int array_size, uint32_t **ptr_p);
void BLO_read_float_array(BlendDataReader *reader, int array_size, float **ptr_p);
@ -265,6 +283,12 @@ void BLO_read_float3_array(BlendDataReader *reader, int array_size, float **ptr_
void BLO_read_double_array(BlendDataReader *reader, int array_size, double **ptr_p);
void BLO_read_pointer_array(BlendDataReader *reader, void **ptr_p);
/* Read null terminated string. */
void BLO_read_string(BlendDataReader *reader, char **ptr_p);
void BLO_read_string(BlendDataReader *reader, char *const *ptr_p);
void BLO_read_string(BlendDataReader *reader, const char **ptr_p);
/* Misc. */
void blo_read_shared_impl(BlendDataReader *reader,

View File

@ -1951,26 +1951,21 @@ static void after_liblink_id_process(BlendLibReader *reader, ID *id)
}
}
static void direct_link_id_override_property_operation_cb(BlendDataReader *reader, void *data)
static void direct_link_id_override_property(BlendDataReader *reader,
IDOverrideLibraryProperty *op)
{
IDOverrideLibraryPropertyOperation *opop = static_cast<IDOverrideLibraryPropertyOperation *>(
data);
BLO_read_data_address(reader, &opop->subitem_reference_name);
BLO_read_data_address(reader, &opop->subitem_local_name);
opop->tag = 0; /* Runtime only. */
}
static void direct_link_id_override_property_cb(BlendDataReader *reader, void *data)
{
IDOverrideLibraryProperty *op = static_cast<IDOverrideLibraryProperty *>(data);
BLO_read_data_address(reader, &op->rna_path);
BLO_read_string(reader, &op->rna_path);
op->tag = 0; /* Runtime only. */
BLO_read_list_cb(reader, &op->operations, direct_link_id_override_property_operation_cb);
BLO_read_struct_list(reader, IDOverrideLibraryPropertyOperation, &op->operations);
LISTBASE_FOREACH (IDOverrideLibraryPropertyOperation *, opop, &op->operations) {
BLO_read_string(reader, &opop->subitem_reference_name);
BLO_read_string(reader, &opop->subitem_local_name);
opop->tag = 0; /* Runtime only. */
}
}
static void direct_link_id_common(
@ -1984,7 +1979,7 @@ static void direct_link_id_embedded_id(BlendDataReader *reader,
/* Handle 'private IDs'. */
bNodeTree **nodetree = BKE_ntree_ptr_from_id(id);
if (nodetree != nullptr && *nodetree != nullptr) {
BLO_read_data_address(reader, nodetree);
BLO_read_struct(reader, bNodeTree, nodetree);
direct_link_id_common(reader,
current_library,
(ID *)*nodetree,
@ -1996,7 +1991,7 @@ static void direct_link_id_embedded_id(BlendDataReader *reader,
if (GS(id->name) == ID_SCE) {
Scene *scene = (Scene *)id;
if (scene->master_collection != nullptr) {
BLO_read_data_address(reader, &scene->master_collection);
BLO_read_struct(reader, Collection, &scene->master_collection);
direct_link_id_common(reader,
current_library,
&scene->master_collection->id,
@ -2101,7 +2096,7 @@ static void direct_link_id_common(
id->library_weak_reference = nullptr;
}
else {
BLO_read_data_address(reader, &id->library_weak_reference);
BLO_read_struct(reader, LibraryWeakReference, &id->library_weak_reference);
}
if (id_tag & LIB_TAG_ID_LINK_PLACEHOLDER) {
@ -2113,7 +2108,7 @@ static void direct_link_id_common(
BKE_animdata_blend_read_data(reader, id);
if (id->asset_data) {
BLO_read_data_address(reader, &id->asset_data);
BLO_read_struct(reader, AssetMetaData, &id->asset_data);
BKE_asset_metadata_read(reader, id->asset_data);
/* Restore runtime asset type info. */
const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(id);
@ -2122,7 +2117,7 @@ static void direct_link_id_common(
/* Link direct data of ID properties. */
if (id->properties) {
BLO_read_data_address(reader, &id->properties);
BLO_read_struct(reader, IDProperty, &id->properties);
/* this case means the data was written incorrectly, it should not happen */
IDP_BlendDataRead(reader, &id->properties);
}
@ -2148,11 +2143,13 @@ static void direct_link_id_common(
/* Link direct data of overrides. */
if (id->override_library) {
BLO_read_data_address(reader, &id->override_library);
BLO_read_struct(reader, IDOverrideLibrary, &id->override_library);
/* Work around file corruption on writing, see #86853. */
if (id->override_library != nullptr) {
BLO_read_list_cb(
reader, &id->override_library->properties, direct_link_id_override_property_cb);
BLO_read_struct_list(reader, IDOverrideLibraryProperty, &id->override_library->properties);
LISTBASE_FOREACH (IDOverrideLibraryProperty *, op, &id->override_library->properties) {
direct_link_id_override_property(reader, op);
}
id->override_library->runtime = nullptr;
}
}
@ -3014,7 +3011,7 @@ BHead *blo_read_asset_data_block(FileData *fd, BHead *bhead, AssetMetaData **r_a
bhead = read_data_into_datamap(fd, bhead, "asset-data read");
BlendDataReader reader = {fd};
BLO_read_data_address(&reader, r_asset_data);
BLO_read_struct(&reader, AssetMetaData, r_asset_data);
BKE_asset_metadata_read(&reader, *r_asset_data);
oldnewmap_clear(fd->datamap);
@ -3354,7 +3351,7 @@ static void after_liblink_merged_bmain_process(Main *bmain, BlendFileReadReport
static void direct_link_keymapitem(BlendDataReader *reader, wmKeyMapItem *kmi)
{
BLO_read_data_address(reader, &kmi->properties);
BLO_read_struct(reader, IDProperty, &kmi->properties);
IDP_BlendDataRead(reader, &kmi->properties);
kmi->ptr = nullptr;
kmi->flag &= ~KMI_UPDATE;
@ -3375,28 +3372,28 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
BlendDataReader reader_ = {fd};
BlendDataReader *reader = &reader_;
BLO_read_list(reader, &user->themes);
BLO_read_list(reader, &user->user_keymaps);
BLO_read_list(reader, &user->user_keyconfig_prefs);
BLO_read_list(reader, &user->user_menus);
BLO_read_list(reader, &user->addons);
BLO_read_list(reader, &user->autoexec_paths);
BLO_read_list(reader, &user->script_directories);
BLO_read_list(reader, &user->asset_libraries);
BLO_read_list(reader, &user->extension_repos);
BLO_read_list(reader, &user->asset_shelves_settings);
BLO_read_struct_list(reader, bTheme, &user->themes);
BLO_read_struct_list(reader, wmKeyMap, &user->user_keymaps);
BLO_read_struct_list(reader, wmKeyConfigPref, &user->user_keyconfig_prefs);
BLO_read_struct_list(reader, bUserMenu, &user->user_menus);
BLO_read_struct_list(reader, bAddon, &user->addons);
BLO_read_struct_list(reader, bPathCompare, &user->autoexec_paths);
BLO_read_struct_list(reader, bUserScriptDirectory, &user->script_directories);
BLO_read_struct_list(reader, bUserAssetLibrary, &user->asset_libraries);
BLO_read_struct_list(reader, bUserExtensionRepo, &user->extension_repos);
BLO_read_struct_list(reader, bUserAssetShelfSettings, &user->asset_shelves_settings);
LISTBASE_FOREACH (wmKeyMap *, keymap, &user->user_keymaps) {
keymap->modal_items = nullptr;
keymap->poll = nullptr;
keymap->flag &= ~KEYMAP_UPDATE;
BLO_read_list(reader, &keymap->diff_items);
BLO_read_list(reader, &keymap->items);
BLO_read_struct_list(reader, wmKeyMapDiffItem, &keymap->diff_items);
BLO_read_struct_list(reader, wmKeyMapItem, &keymap->items);
LISTBASE_FOREACH (wmKeyMapDiffItem *, kmdi, &keymap->diff_items) {
BLO_read_data_address(reader, &kmdi->remove_item);
BLO_read_data_address(reader, &kmdi->add_item);
BLO_read_struct(reader, wmKeyMapItem, &kmdi->remove_item);
BLO_read_struct(reader, wmKeyMapItem, &kmdi->add_item);
if (kmdi->remove_item) {
direct_link_keymapitem(reader, kmdi->remove_item);
@ -3412,23 +3409,23 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
}
LISTBASE_FOREACH (wmKeyConfigPref *, kpt, &user->user_keyconfig_prefs) {
BLO_read_data_address(reader, &kpt->prop);
BLO_read_struct(reader, IDProperty, &kpt->prop);
IDP_BlendDataRead(reader, &kpt->prop);
}
LISTBASE_FOREACH (bUserMenu *, um, &user->user_menus) {
BLO_read_list(reader, &um->items);
BLO_read_struct_list(reader, bUserMenuItem, &um->items);
LISTBASE_FOREACH (bUserMenuItem *, umi, &um->items) {
if (umi->type == USER_MENU_TYPE_OPERATOR) {
bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)umi;
BLO_read_data_address(reader, &umi_op->prop);
BLO_read_struct(reader, IDProperty, &umi_op->prop);
IDP_BlendDataRead(reader, &umi_op->prop);
}
}
}
LISTBASE_FOREACH (bAddon *, addon, &user->addons) {
BLO_read_data_address(reader, &addon->prop);
BLO_read_struct(reader, IDProperty, &addon->prop);
IDP_BlendDataRead(reader, &addon->prop);
}
@ -3439,7 +3436,7 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
/* XXX */
user->uifonts.first = user->uifonts.last = nullptr;
BLO_read_list(reader, &user->uistyles);
BLO_read_struct_list(reader, uiStyle, &user->uistyles);
/* Don't read the active app template, use the default one. */
user->app_template[0] = '\0';
@ -4788,14 +4785,31 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
BKE_main_free(main_newid);
}
static void *blo_verify_data_address(void *new_address,
const void * /*old_address*/,
const size_t expected_size)
{
if (new_address != nullptr) {
/* Not testing equality, since size might have been aligned up,
* or might be passed the size of a base struct with inheritance. */
BLI_assert_msg(MEM_allocN_len(new_address) >= expected_size,
"Corrupt .blend file, unexpected data size.");
}
return new_address;
}
void *BLO_read_get_new_data_address(BlendDataReader *reader, const void *old_address)
{
return newdataadr(reader->fd, old_address);
}
void *BLO_read_get_new_data_address_no_us(BlendDataReader *reader, const void *old_address)
void *BLO_read_get_new_data_address_no_us(BlendDataReader *reader,
const void *old_address,
const size_t expected_size)
{
return newdataadr_no_us(reader->fd, old_address);
void *new_address = newdataadr_no_us(reader->fd, old_address);
return blo_verify_data_address(new_address, old_address, expected_size);
}
void *BLO_read_get_new_packed_address(BlendDataReader *reader, const void *old_address)
@ -4803,6 +4817,14 @@ void *BLO_read_get_new_packed_address(BlendDataReader *reader, const void *old_a
return newpackedadr(reader->fd, old_address);
}
void *BLO_read_struct_array_with_size(BlendDataReader *reader,
const void *old_address,
const size_t expected_size)
{
void *new_address = newdataadr(reader->fd, old_address);
return blo_verify_data_address(new_address, old_address, expected_size);
}
ID *BLO_read_get_new_id_address(BlendLibReader *reader,
ID *self_id,
const bool is_linked_only,
@ -4826,23 +4848,20 @@ bool BLO_read_requires_endian_switch(BlendDataReader *reader)
return (reader->fd->flags & FD_FLAGS_SWITCH_ENDIAN) != 0;
}
void BLO_read_list_cb(BlendDataReader *reader, ListBase *list, BlendReadListFn callback)
void BLO_read_struct_list_with_size(BlendDataReader *reader,
const size_t expected_elem_size,
ListBase *list)
{
if (BLI_listbase_is_empty(list)) {
return;
}
BLO_read_data_address(reader, &list->first);
if (callback != nullptr) {
callback(reader, list->first);
}
list->first = BLO_read_struct_array_with_size(reader, list->first, expected_elem_size);
Link *ln = static_cast<Link *>(list->first);
Link *prev = nullptr;
while (ln) {
BLO_read_data_address(reader, &ln->next);
if (ln->next != nullptr && callback != nullptr) {
callback(reader, ln->next);
}
ln->next = static_cast<Link *>(
BLO_read_struct_array_with_size(reader, ln->next, expected_elem_size));
ln->prev = prev;
prev = ln;
ln = ln->next;
@ -4850,36 +4869,50 @@ void BLO_read_list_cb(BlendDataReader *reader, ListBase *list, BlendReadListFn c
list->last = prev;
}
void BLO_read_list(BlendDataReader *reader, ListBase *list)
void BLO_read_char_array(BlendDataReader *reader, int array_size, char **ptr_p)
{
BLO_read_list_cb(reader, list, nullptr);
*ptr_p = reinterpret_cast<char *>(
BLO_read_struct_array_with_size(reader, *((void **)ptr_p), sizeof(char) * array_size));
}
void BLO_read_uint8_array(BlendDataReader *reader, int array_size, uint8_t **ptr_p)
{
*ptr_p = reinterpret_cast<uint8_t *>(
BLO_read_struct_array_with_size(reader, *((void **)ptr_p), sizeof(uint8_t) * array_size));
}
void BLO_read_int8_array(BlendDataReader *reader, int array_size, int8_t **ptr_p)
{
*ptr_p = reinterpret_cast<int8_t *>(
BLO_read_struct_array_with_size(reader, *((void **)ptr_p), sizeof(int8_t) * array_size));
}
void BLO_read_int32_array(BlendDataReader *reader, int array_size, int32_t **ptr_p)
{
BLO_read_data_address(reader, ptr_p);
if (BLO_read_requires_endian_switch(reader)) {
*ptr_p = reinterpret_cast<int32_t *>(
BLO_read_struct_array_with_size(reader, *((void **)ptr_p), sizeof(int32_t) * array_size));
if (*ptr_p && BLO_read_requires_endian_switch(reader)) {
BLI_endian_switch_int32_array(*ptr_p, array_size);
}
}
void BLO_read_int8_array(BlendDataReader *reader, int /*array_size*/, int8_t **ptr_p)
{
BLO_read_data_address(reader, ptr_p);
}
void BLO_read_uint32_array(BlendDataReader *reader, int array_size, uint32_t **ptr_p)
{
BLO_read_data_address(reader, ptr_p);
if (BLO_read_requires_endian_switch(reader)) {
*ptr_p = reinterpret_cast<uint32_t *>(
BLO_read_struct_array_with_size(reader, *((void **)ptr_p), sizeof(uint32_t) * array_size));
if (*ptr_p && BLO_read_requires_endian_switch(reader)) {
BLI_endian_switch_uint32_array(*ptr_p, array_size);
}
}
void BLO_read_float_array(BlendDataReader *reader, int array_size, float **ptr_p)
{
BLO_read_data_address(reader, ptr_p);
if (BLO_read_requires_endian_switch(reader)) {
*ptr_p = reinterpret_cast<float *>(
BLO_read_struct_array_with_size(reader, *((void **)ptr_p), sizeof(float) * array_size));
if (*ptr_p && BLO_read_requires_endian_switch(reader)) {
BLI_endian_switch_float_array(*ptr_p, array_size);
}
}
@ -4891,12 +4924,43 @@ void BLO_read_float3_array(BlendDataReader *reader, int array_size, float **ptr_
void BLO_read_double_array(BlendDataReader *reader, int array_size, double **ptr_p)
{
BLO_read_data_address(reader, ptr_p);
if (BLO_read_requires_endian_switch(reader)) {
*ptr_p = reinterpret_cast<double *>(
BLO_read_struct_array_with_size(reader, *((void **)ptr_p), sizeof(double) * array_size));
if (*ptr_p && BLO_read_requires_endian_switch(reader)) {
BLI_endian_switch_double_array(*ptr_p, array_size);
}
}
void BLO_read_string(BlendDataReader *reader, char **ptr_p)
{
BLO_read_data_address(reader, ptr_p);
#ifndef NDEBUG
const char *str = *ptr_p;
if (str) {
/* Verify that we have a null terminator. */
for (size_t len = MEM_allocN_len(str); len > 0; len--) {
if (str[len - 1] == '\0') {
return;
}
}
BLI_assert_msg(0, "Corrupt .blend file, expected string to be null terminated.");
}
#endif
}
void BLO_read_string(BlendDataReader *reader, char *const *ptr_p)
{
BLO_read_string(reader, const_cast<char **>(ptr_p));
}
void BLO_read_string(BlendDataReader *reader, const char **ptr_p)
{
BLO_read_string(reader, const_cast<char **>(ptr_p));
}
static void convert_pointer_array_64_to_32(BlendDataReader *reader,
uint array_size,
const uint64_t *src,

View File

@ -2091,6 +2091,34 @@ static void versioning_node_hue_correct_set_wrappng(bNodeTree *ntree)
}
}
static void add_image_editor_asset_shelf(Main &bmain)
{
LISTBASE_FOREACH (bScreen *, screen, &bmain.screens) {
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
if (sl->spacetype != SPACE_IMAGE) {
continue;
}
ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase : &sl->regionbase;
if (ARegion *new_shelf_region = do_versions_add_region_if_not_found(
regionbase, RGN_TYPE_ASSET_SHELF, __func__, RGN_TYPE_TOOL_HEADER))
{
new_shelf_region->regiondata = MEM_cnew<RegionAssetShelf>(__func__);
new_shelf_region->alignment = RGN_ALIGN_BOTTOM;
new_shelf_region->flag |= RGN_FLAG_HIDDEN;
}
if (ARegion *new_shelf_header = do_versions_add_region_if_not_found(
regionbase, RGN_TYPE_ASSET_SHELF_HEADER, __func__, RGN_TYPE_ASSET_SHELF))
{
new_shelf_header->alignment = RGN_ALIGN_BOTTOM | RGN_ALIGN_HIDE_WITH_PREV;
}
}
}
}
}
void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
{
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 1)) {
@ -3229,7 +3257,20 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
}
}
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 20)) {
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 21)) {
add_image_editor_asset_shelf(*bmain);
}
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 22)) {
/* Display missing media in sequencer by default. */
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
if (scene->ed != nullptr) {
scene->ed->show_missing_media_flag |= SEQ_EDIT_SHOW_MISSING_MEDIA;
}
}
}
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 23)) {
update_paint_modes_for_brush_assets(*bmain);
}

View File

@ -36,6 +36,7 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_sequence_types.h"
#include "DNA_space_types.h"
#include "DNA_userdef_types.h"
#include "DNA_windowmanager_types.h"
@ -353,6 +354,11 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene)
view_layer->passflag &= ~SCE_PASS_Z;
}
/* Display missing media by default. */
if (scene->ed) {
scene->ed->show_missing_media_flag |= SEQ_EDIT_SHOW_MISSING_MEDIA;
}
/* New EEVEE defaults. */
scene->eevee.bloom_intensity = 0.05f;
scene->eevee.bloom_clamp = 0.0f;

View File

@ -155,6 +155,11 @@ static void do_versions_theme(const UserDef *userdef, bTheme *btheme)
FROM_DEFAULT_V4_UCHAR(space_action.keytype_generated_select);
}
if (!USER_VERSION_ATLEAST(402, 21)) {
FROM_DEFAULT_V4_UCHAR(space_image.asset_shelf.back);
FROM_DEFAULT_V4_UCHAR(space_image.asset_shelf.header_back);
}
/**
* Always bump subversion in BKE_blender_version.h when adding versioning
* code here, and wrap it inside a USER_VERSION_ATLEAST check.

View File

@ -1790,11 +1790,21 @@ int BLO_get_struct_id_by_name(BlendWriter *writer, const char *struct_name)
return struct_id;
}
void BLO_write_char_array(BlendWriter *writer, uint num, const char *data_ptr)
{
BLO_write_raw(writer, sizeof(char) * size_t(num), data_ptr);
}
void BLO_write_int8_array(BlendWriter *writer, uint num, const int8_t *data_ptr)
{
BLO_write_raw(writer, sizeof(int8_t) * size_t(num), data_ptr);
}
void BLO_write_uint8_array(BlendWriter *writer, uint num, const uint8_t *data_ptr)
{
BLO_write_raw(writer, sizeof(uint8_t) * size_t(num), data_ptr);
}
void BLO_write_int32_array(BlendWriter *writer, uint num, const int32_t *data_ptr)
{
BLO_write_raw(writer, sizeof(int32_t) * size_t(num), data_ptr);

View File

@ -128,6 +128,12 @@ bool DEG_is_evaluated_object(const Object *object);
*/
bool DEG_is_fully_evaluated(const Depsgraph *depsgraph);
/**
* Check every component of the data-block is evaluated. For example, an object disabled in the
* viewport is not fully evaluated, even though the copy-on-eval data-block is created.
*/
bool DEG_id_is_fully_evaluated(const Depsgraph *depsgraph, const ID *id_eval);
/** \} */
/* -------------------------------------------------------------------- */

View File

@ -32,6 +32,7 @@
#include "intern/depsgraph.hh"
#include "intern/eval/deg_eval_copy_on_write.h"
#include "intern/node/deg_node_component.hh"
#include "intern/node/deg_node_id.hh"
namespace blender::deg {
@ -340,3 +341,22 @@ bool DEG_is_fully_evaluated(const Depsgraph *depsgraph)
}
return true;
}
bool DEG_id_is_fully_evaluated(const Depsgraph *depsgraph, const ID *id_eval)
{
const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(depsgraph);
/* Only us the original ID pointer to look up the IDNode, do not dereference it. */
const ID *id_orig = deg::get_original_id(id_eval);
const deg::IDNode *id_node = deg_graph->find_id_node(id_orig);
if (!id_node) {
return false;
}
for (deg::ComponentNode *component : id_node->components.values()) {
for (deg::OperationNode *operation : component->operations) {
if (operation->flag & deg::DEPSOP_FLAG_NEEDS_UPDATE) {
return false;
}
}
}
return true;
}

View File

@ -562,17 +562,18 @@ static void direct_link_lightcache_texture(BlendDataReader *reader, LightCacheTe
lctex->tex = nullptr;
if (lctex->data) {
BLO_read_data_address(reader, &lctex->data);
if (lctex->data && BLO_read_requires_endian_switch(reader)) {
int data_size = lctex->components * lctex->tex_size[0] * lctex->tex_size[1] *
lctex->tex_size[2];
int data_size = lctex->components * lctex->tex_size[0] * lctex->tex_size[1] *
lctex->tex_size[2];
if (lctex->data_type == LIGHTCACHETEX_FLOAT) {
BLI_endian_switch_float_array((float *)lctex->data, data_size * sizeof(float));
}
else if (lctex->data_type == LIGHTCACHETEX_UINT) {
BLI_endian_switch_uint32_array((uint *)lctex->data, data_size * sizeof(uint));
}
if (lctex->data_type == LIGHTCACHETEX_FLOAT) {
BLO_read_float_array(reader, data_size, (float **)&lctex->data);
}
else if (lctex->data_type == LIGHTCACHETEX_UINT) {
BLO_read_uint32_array(reader, data_size, (uint **)&lctex->data);
}
else {
BLI_assert_unreachable();
lctex->data = nullptr;
}
}
@ -588,14 +589,14 @@ void EEVEE_lightcache_blend_read_data(BlendDataReader *reader, LightCache *cache
direct_link_lightcache_texture(reader, &cache->grid_tx);
if (cache->cube_mips) {
BLO_read_data_address(reader, &cache->cube_mips);
BLO_read_struct_array(reader, LightCacheTexture, cache->mips_len, &cache->cube_mips);
for (int i = 0; i < cache->mips_len; i++) {
direct_link_lightcache_texture(reader, &cache->cube_mips[i]);
}
}
BLO_read_data_address(reader, &cache->cube_data);
BLO_read_data_address(reader, &cache->grid_data);
BLO_read_struct_array(reader, LightGridCache, cache->grid_len, &cache->cube_data);
BLO_read_struct_array(reader, LightProbeCache, cache->cube_len, &cache->grid_data);
}
/** \} */

View File

@ -55,6 +55,9 @@
*/
#define SPHERE_PROBE_MAX 128
/** NOTE: Runtime format only. */
#define VOLUME_PROBE_FORMAT GPU_RGBA16F
/**
* Limited by the performance impact it can cause.
* Limited by the max layer count supported by a hardware (256).
@ -245,7 +248,7 @@
/* Only during shadow rendering. */
#define SHADOW_RENDER_MAP_BUF_SLOT 3
#define SHADOW_PAGE_INFO_SLOT 4
#define SHADOW_VIEWPORT_INDEX_BUF_SLOT 5
#define SHADOW_RENDER_VIEW_BUF_SLOT 5
/* Only during pre-pass. */
#define VELOCITY_OBJ_PREV_BUF_SLOT 0

View File

@ -44,7 +44,7 @@ void VolumeProbeModule::init()
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_WRITE | GPU_TEXTURE_USAGE_SHADER_READ |
GPU_TEXTURE_USAGE_ATTACHMENT;
do_full_update_ = irradiance_atlas_tx_.ensure_3d(GPU_RGBA16F, atlas_extent, usage);
do_full_update_ = irradiance_atlas_tx_.ensure_3d(VOLUME_PROBE_FORMAT, atlas_extent, usage);
if (do_full_update_) {
/* Delete all references to existing bricks. */

View File

@ -204,7 +204,7 @@ void ShadowPipeline::sync()
draw::PassMain::Sub &pass = render_ps_.sub("Shadow.Surface");
pass.state_set(state);
pass.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
pass.bind_ssbo(SHADOW_VIEWPORT_INDEX_BUF_SLOT, &inst_.shadows.viewport_index_buf_);
pass.bind_ssbo(SHADOW_RENDER_VIEW_BUF_SLOT, &inst_.shadows.render_view_buf_);
if (!shadow_update_tbdr) {
/* We do not need all of the shadow information when using the TBDR-optimized approach. */
pass.bind_image(SHADOW_ATLAS_IMG_SLOT, inst_.shadows.atlas_tx_);
@ -422,6 +422,7 @@ void ForwardPipeline::render(View &view,
inst_.shadows.set_view(view, extent);
inst_.volume_probes.set_view(view);
inst_.sphere_probes.set_view(view);
if (has_opaque_) {
combined_fb.bind();
@ -733,6 +734,7 @@ GPUTexture *DeferredLayer::render(View &main_view,
inst_.hiz_buffer.update();
inst_.volume_probes.set_view(render_view);
inst_.sphere_probes.set_view(render_view);
inst_.shadows.set_view(render_view, extent);
inst_.gbuffer.bind(gbuffer_fb);
@ -1227,6 +1229,7 @@ void DeferredProbePipeline::render(View &view,
inst_.lights.set_view(view, extent);
inst_.shadows.set_view(view, extent);
inst_.volume_probes.set_view(view);
inst_.sphere_probes.set_view(view);
/* Update for lighting pass. */
inst_.hiz_buffer.update();
@ -1343,6 +1346,7 @@ void PlanarProbePipeline::render(View &view,
inst_.lights.set_view(view, extent);
inst_.shadows.set_view(view, extent);
inst_.volume_probes.set_view(view);
inst_.sphere_probes.set_view(view);
inst_.gbuffer.bind(gbuffer_fb);
inst_.manager->submit(gbuffer_ps_, view);

View File

@ -119,6 +119,10 @@ class SphereProbeModule {
pass.bind_ubo(SPHERE_PROBE_BUF_SLOT, &data_buf_);
}
/**
* Select which probes are used for rendering.
* NOTE: Must run after `volume_probe.set_view` as it reads the volume probe data.
*/
void set_view(View &view);
/**

View File

@ -1146,9 +1146,12 @@ struct ShadowTileMapData {
int clip_data_index;
/** Bias LOD to tag for usage to lower the amount of tile used. */
float lod_bias;
int _pad0;
int _pad1;
int _pad2;
/** Light type this tilemap is from. */
eLightType light_type;
/** True if the tilemap is part of area light shadow and is one of the side projections. */
bool32_t is_area_side;
/** Distance behind the area light a shadow is shifted. */
float area_shift;
/** Near and far clip distances for punctual. */
float clip_near;
float clip_far;
@ -1159,8 +1162,29 @@ struct ShadowTileMapData {
};
BLI_STATIC_ASSERT_ALIGN(ShadowTileMapData, 16)
/**
* Lightweight version of ShadowTileMapData that only contains data used for rendering the shadow.
*/
struct ShadowRenderView {
/**
* Is either:
* - positive radial distance for point lights.
* - negative distance to light plane (divided by sqrt3) for area lights side projections.
* - zero if disabled.
* Use sign to determine with case we are in.
*/
float clip_distance_inv;
/* Viewport to submit the geometry of this tilemap view to. */
uint viewport_index;
uint _pad0;
uint _pad1;
};
BLI_STATIC_ASSERT_ALIGN(ShadowRenderView, 16)
/**
* Per tilemap data persistent on GPU.
* Kept separately for easier clearing on GPU.
*/
struct ShadowTileMapClip {
/** Clip distances that were used to render the pages. */
@ -1976,6 +2000,7 @@ using ShadowPageCacheBuf = draw::StorageArrayBuffer<uint2, SHADOW_MAX_PAGE, true
using ShadowTileMapDataBuf = draw::StorageVectorBuffer<ShadowTileMapData, SHADOW_MAX_TILEMAP>;
using ShadowTileMapClipBuf = draw::StorageArrayBuffer<ShadowTileMapClip, SHADOW_MAX_TILEMAP, true>;
using ShadowTileDataBuf = draw::StorageArrayBuffer<ShadowTileDataPacked, SHADOW_MAX_TILE, true>;
using ShadowRenderViewBuf = draw::StorageArrayBuffer<ShadowRenderView, SHADOW_VIEW_MAX, true>;
using SurfelBuf = draw::StorageArrayBuffer<Surfel, 64>;
using SurfelRadianceBuf = draw::StorageArrayBuffer<SurfelRadiance, 64>;
using CaptureInfoBuf = draw::StorageBuffer<CaptureInfoData>;

View File

@ -37,6 +37,8 @@ void ShadowTileMap::sync_orthographic(const float4x4 &object_mat_,
}
projection_type = projection_type_;
level = clipmap_level;
light_type = eLightType::LIGHT_SUN;
is_area_side = false;
if (grid_shift == int2(0)) {
/* Only replace shift if it is not already dirty. */
@ -69,7 +71,8 @@ void ShadowTileMap::sync_orthographic(const float4x4 &object_mat_,
1.0);
}
void ShadowTileMap::sync_cubeface(const float4x4 &object_mat_,
void ShadowTileMap::sync_cubeface(eLightType light_type_,
const float4x4 &object_mat_,
float near_,
float far_,
float side_,
@ -84,6 +87,8 @@ void ShadowTileMap::sync_cubeface(const float4x4 &object_mat_,
cubeface = face;
grid_offset = int2(0);
lod_bias = lod_bias_;
light_type = light_type_;
is_area_side = is_area_light(light_type) && (face != eCubeFace::Z_NEG);
if ((clip_near != near_) || (clip_far != far_) || (half_size != side_)) {
set_dirty();
@ -91,6 +96,7 @@ void ShadowTileMap::sync_cubeface(const float4x4 &object_mat_,
clip_near = near_;
clip_far = far_;
area_shift = shift;
half_size = side_;
center_offset = float2(0.0f);
@ -259,25 +265,27 @@ void ShadowPunctual::release_excess_tilemaps()
tilemaps_ = span.take_front(tilemaps_needed_);
}
void ShadowPunctual::compute_projection_boundaries(float light_radius,
void ShadowPunctual::compute_projection_boundaries(eLightType light_type,
float light_radius,
float shadow_radius,
float max_lit_distance,
float &near,
float &far,
float &side)
float &side,
float &back_shift)
{
/**
/*
* In order to make sure we can trace any ray in its entirety using a single tile-map, we have
* to make sure that the tile-map cover all potential occluder that can intersect any ray shot
* in this particular shadow quadrant.
*
* To this end, we shift the tile-map perspective origin behind the light shape and make sure the
* To this end, we inflate the tile-map perspective sides to make sure the
* tile-map frustum starts where the rays cannot go.
*
* We are interesting in finding `I` the new origin and `n` the new near plane distances.
*
* I .... Shifted light center
* /|
* I .... Intersection between tangent and
* /| projection center axis
* / |
* / |
* / |
@ -292,22 +300,22 @@ void ShadowPunctual::compute_projection_boundaries(float light_radius,
* / ... |
* /. |
* / |
* Tangent to light shape .... T\--------------N .... Shifted near plane
* Tangent to light shape .... T\--------------N
* / --\ Beta |
* / -\ |
* / --\ |
* /. --\ |
* / . -\ |
* / . Alpha -O .... Light center
* / . --/ |
* / . --/ |
* / . -/ |
* / . --/ |
* /-------------/------------x .... Desired near plane (inscribed cube)
* / --/ .. |
* / --/ ... |
* / --/ .... |
* / -/ ....|
* / . /-/ |
* Inflated side / . /--- -/ |
* . / . /---- --/ |
* . / /---- . --/ |
* /-------------/------------X .... Desired near plane (inscribed cube)
* /---- --/ .. |
* /---- / --/ ... |
* /---- / --/ .... |
* / -/ ....| .... Shadow radius
* / --/ |
* /--/ |
* F .... Most distant shadow receiver possible.
@ -315,18 +323,36 @@ void ShadowPunctual::compute_projection_boundaries(float light_radius,
* F: The most distant shadowed point at the edge of the 45° cube-face pyramid.
* O: The light origin.
* T: The tangent to the circle of radius `radius` centered at the origin and passing through F.
* I: The shifted light origin.
* I: Intersection between tangent and the projection center axis.
* N: The shifted near plane center.
* X: Intersection between the near plane and the projection center axis.
* Alpha: FOT angle.
* Beta: OTN angle.
*
* TODO(fclem): Explain derivation.
* Note: FTO, ONT and TNI are right angles.
*/
float cos_alpha = shadow_radius / max_lit_distance;
float sin_alpha = sqrt(1.0f - math::square(cos_alpha));
float near_shift = M_SQRT2 * shadow_radius * 0.5f * (sin_alpha - cos_alpha);
float side_shift = M_SQRT2 * shadow_radius * 0.5f * (sin_alpha + cos_alpha);
float origin_shift = M_SQRT2 * shadow_radius / (sin_alpha - cos_alpha);
/* Make near plane to be inside the inscribed cube of the sphere. */
near = max_ff(light_radius, max_lit_distance / 4000.0f) / M_SQRT3;
float min_near = (max_lit_distance / 4000.0f) / M_SQRT3;
if (is_area_light(light_type)) {
/* Make near plane be inside the inscribed cube of the shadow sphere. */
near = max_ff(shadow_radius / M_SQRT3, min_near);
/* Subtract min_near to make the shadow center match the light center if there is no shadow
* tracing required. This avoid light leaking issues near the light plane caused by the
* shadow discard clipping. */
back_shift = (near - min_near);
}
else {
/* Make near plane be inside the inscribed cube of the light sphere. */
near = max_ff(light_radius / M_SQRT3, min_near);
back_shift = 0.0f;
}
far = max_lit_distance;
if (shadow_radius > 1e-5f) {
side = ((side_shift / (origin_shift - near_shift)) * (origin_shift + near));
@ -340,11 +366,9 @@ void ShadowPunctual::end_sync(Light &light, float lod_bias)
{
ShadowTileMapPool &tilemap_pool = shadows_.tilemap_pool;
float side, near, far;
compute_projection_boundaries(light_radius_, shadow_radius_, max_distance_, near, far, side);
/* Shift shadow map origin for area light to avoid clipping nearby geometry. */
float shift = is_area_light(light.type) ? near : 0.0f;
float side, near, far, shift;
compute_projection_boundaries(
light.type, light_radius_, shadow_radius_, max_distance_, near, far, side, shift);
float4x4 obmat_tmp = light.object_mat;
@ -357,15 +381,20 @@ void ShadowPunctual::end_sync(Light &light, float lod_bias)
tilemaps_.append(tilemap_pool.acquire());
}
tilemaps_[Z_NEG]->sync_cubeface(obmat_tmp, near, far, side, shift, Z_NEG, lod_bias);
tilemaps_[Z_NEG]->sync_cubeface(light.type, obmat_tmp, near, far, side, shift, Z_NEG, lod_bias);
if (tilemaps_needed_ >= 5) {
tilemaps_[X_POS]->sync_cubeface(obmat_tmp, near, far, side, shift, X_POS, lod_bias);
tilemaps_[X_NEG]->sync_cubeface(obmat_tmp, near, far, side, shift, X_NEG, lod_bias);
tilemaps_[Y_POS]->sync_cubeface(obmat_tmp, near, far, side, shift, Y_POS, lod_bias);
tilemaps_[Y_NEG]->sync_cubeface(obmat_tmp, near, far, side, shift, Y_NEG, lod_bias);
tilemaps_[X_POS]->sync_cubeface(
light.type, obmat_tmp, near, far, side, shift, X_POS, lod_bias);
tilemaps_[X_NEG]->sync_cubeface(
light.type, obmat_tmp, near, far, side, shift, X_NEG, lod_bias);
tilemaps_[Y_POS]->sync_cubeface(
light.type, obmat_tmp, near, far, side, shift, Y_POS, lod_bias);
tilemaps_[Y_NEG]->sync_cubeface(
light.type, obmat_tmp, near, far, side, shift, Y_NEG, lod_bias);
}
if (tilemaps_needed_ == 6) {
tilemaps_[Z_POS]->sync_cubeface(obmat_tmp, near, far, side, shift, Z_POS, lod_bias);
tilemaps_[Z_POS]->sync_cubeface(
light.type, obmat_tmp, near, far, side, shift, Z_POS, lod_bias);
}
light.tilemap_index = tilemap_pool.tilemaps_data.size();
@ -865,6 +894,7 @@ void ShadowModule::begin_sync()
sub.push_constant("tilemap_proj_ratio", &data_.tilemap_projection_ratio);
sub.push_constant("input_depth_extent", &input_depth_extent_);
sub.bind_resources(inst_.lights);
sub.bind_resources(inst_.uniform_data);
sub.bind_resources(inst_.hiz_buffer.front);
sub.dispatch(&dispatch_depth_scan_size_);
}
@ -1194,7 +1224,7 @@ void ShadowModule::end_sync()
sub.bind_ssbo("dst_coord_buf", dst_coord_buf_);
sub.bind_ssbo("src_coord_buf", src_coord_buf_);
sub.bind_ssbo("render_map_buf", render_map_buf_);
sub.bind_ssbo("viewport_index_buf", viewport_index_buf_);
sub.bind_ssbo("render_view_buf", render_view_buf_);
sub.bind_ssbo("pages_infos_buf", pages_infos_data_);
sub.bind_image("tilemaps_img", tilemap_pool.tilemap_tx);
sub.dispatch(int3(1, 1, tilemap_pool.tilemaps_data.size()));

View File

@ -103,7 +103,8 @@ struct ShadowTileMap : public ShadowTileMapData {
float lod_bias_,
eShadowProjectionType projection_type_);
void sync_cubeface(const float4x4 &object_mat,
void sync_cubeface(eLightType light_type_,
const float4x4 &object_mat,
float near,
float far,
float side,
@ -252,8 +253,8 @@ class ShadowModule {
StorageArrayBuffer<uint, SHADOW_RENDER_MAP_SIZE, true> src_coord_buf_ = {"src_coord_buf"};
/** Same as dst_coord_buf_ but is not compact. More like a linear texture. */
StorageArrayBuffer<uint, SHADOW_RENDER_MAP_SIZE, true> render_map_buf_ = {"render_map_buf"};
/** View to viewport index mapping. */
StorageArrayBuffer<uint, SHADOW_VIEW_MAX, true> viewport_index_buf_ = {"viewport_index_buf"};
/** View to viewport index mapping and other render-only related data. */
ShadowRenderViewBuf render_view_buf_ = {"render_view_buf"};
int3 dispatch_depth_scan_size_;
float pixel_world_radius_;
@ -453,12 +454,14 @@ class ShadowPunctual : public NonCopyable, NonMovable {
* Make sure that the projection encompass all possible rays that can start in the projection
* quadrant.
*/
void compute_projection_boundaries(float light_radius,
void compute_projection_boundaries(eLightType light_type,
float light_radius,
float shadow_radius,
float max_lit_distance,
float &near,
float &far,
float &side);
float &side,
float &back_shift);
};
class ShadowDirectional : public NonCopyable, NonMovable {

View File

@ -120,7 +120,6 @@ void ShadingView::render()
/* TODO(fclem): Move it after the first prepass (and hiz update) once pipeline is stabilized. */
inst_.lights.set_view(render_view_, extent_);
inst_.sphere_probes.set_view(render_view_);
inst_.pipelines.background.render(render_view_);

View File

@ -219,6 +219,7 @@ void VolumeModule::end_sync()
scatter_ps_.bind_resources(inst_.sphere_probes);
scatter_ps_.bind_resources(inst_.volume_probes);
scatter_ps_.bind_resources(inst_.shadows);
scatter_ps_.bind_resources(inst_.uniform_data);
scatter_ps_.bind_resources(inst_.sampling);
scatter_ps_.bind_image("in_scattering_img", &prop_scattering_tx_);
scatter_ps_.bind_image("in_extinction_img", &prop_extinction_tx_);

View File

@ -13,7 +13,7 @@ void main()
{
DRW_VIEW_FROM_RESOURCE_ID;
#ifdef MAT_SHADOW
shadow_viewport_layer_set(int(drw_view_id), int(viewport_index_buf[drw_view_id]));
shadow_viewport_layer_set(int(drw_view_id), int(render_view_buf[drw_view_id].viewport_index));
#endif
init_interface();
@ -57,5 +57,10 @@ void main()
clip_interp.clip_distance = dot(clip_plane.plane, vec4(interp.P, 1.0));
#endif
#ifdef MAT_SHADOW
shadow_clip.vector = shadow_clip_vector_get(drw_point_world_to_view(interp.P),
render_view_buf[drw_view_id]);
#endif
gl_Position = drw_point_world_to_homogenous(interp.P);
}

View File

@ -13,7 +13,7 @@ void main()
{
DRW_VIEW_FROM_RESOURCE_ID;
#ifdef MAT_SHADOW
shadow_viewport_layer_set(int(drw_view_id), int(viewport_index_buf[drw_view_id]));
shadow_viewport_layer_set(int(drw_view_id), int(render_view_buf[drw_view_id].viewport_index));
#endif
init_interface();
@ -56,4 +56,9 @@ void main()
#ifdef MAT_CLIP_PLANE
clip_interp.clip_distance = dot(clip_plane.plane, vec4(interp.P, 1.0));
#endif
#ifdef MAT_SHADOW
shadow_clip.vector = shadow_clip_vector_get(drw_point_world_to_view(interp.P),
render_view_buf[drw_view_id]);
#endif
}

View File

@ -12,7 +12,7 @@ void main()
{
DRW_VIEW_FROM_RESOURCE_ID;
#ifdef MAT_SHADOW
shadow_viewport_layer_set(int(drw_view_id), int(viewport_index_buf[drw_view_id]));
shadow_viewport_layer_set(int(drw_view_id), int(render_view_buf[drw_view_id].viewport_index));
#endif
init_interface();
@ -39,5 +39,10 @@ void main()
clip_interp.clip_distance = dot(clip_plane.plane, vec4(interp.P, 1.0));
#endif
#ifdef MAT_SHADOW
shadow_clip.vector = shadow_clip_vector_get(drw_point_world_to_view(interp.P),
render_view_buf[drw_view_id]);
#endif
gl_Position = drw_point_world_to_homogenous(interp.P);
}

View File

@ -14,7 +14,7 @@ void main()
{
DRW_VIEW_FROM_RESOURCE_ID;
#ifdef MAT_SHADOW
shadow_viewport_layer_set(int(drw_view_id), int(viewport_index_buf[drw_view_id]));
shadow_viewport_layer_set(int(drw_view_id), int(render_view_buf[drw_view_id].viewport_index));
#endif
init_interface();
@ -51,5 +51,10 @@ void main()
clip_interp.clip_distance = dot(clip_plane.plane, vec4(interp.P, 1.0));
#endif
#ifdef MAT_SHADOW
shadow_clip.vector = shadow_clip_vector_get(drw_point_world_to_view(interp.P),
render_view_buf[drw_view_id]);
#endif
gl_Position = drw_point_world_to_homogenous(interp.P);
}

View File

@ -198,7 +198,8 @@ SphericalHarmonicL1 lightprobe_irradiance_sample(
SphericalHarmonicL1 lightprobe_irradiance_world()
{
return lightprobe_irradiance_sample_atlas(irradiance_atlas_tx, vec3(0.0));
/* We need a 0.5 offset because of filtering. */
return lightprobe_irradiance_sample_atlas(irradiance_atlas_tx, vec3(0.5001));
}
SphericalHarmonicL1 lightprobe_irradiance_sample(vec3 P)

View File

@ -103,7 +103,21 @@ void main()
view_index = atomicAdd(statistics_buf.view_needed_count, 1);
if (view_index < SHADOW_VIEW_MAX) {
/* Setup the view. */
viewport_index_buf[view_index] = viewport_index;
render_view_buf[view_index].viewport_index = viewport_index;
/* Clipping setup. */
if (tilemap_data.is_area_side) {
/* Negative for tagging this case. See shadow_clip_vector_get for explanation. */
render_view_buf[view_index].clip_distance_inv = -M_SQRT1_3 / tilemap_data.area_shift;
}
else if (is_point_light(tilemap_data.light_type)) {
/* Clip as a sphere around the clip_near cube. */
render_view_buf[view_index].clip_distance_inv = M_SQRT1_3 / tilemap_data.clip_near;
}
else {
/* Disable local clipping. */
render_view_buf[view_index].clip_distance_inv = 0.0;
}
view_infos_buf[view_index].viewmat = tilemap_data.viewmat;
view_infos_buf[view_index].viewinv = inverse(tilemap_data.viewmat);

View File

@ -161,6 +161,26 @@ void shadow_viewport_layer_set(int view_id, int lod)
# endif
gpu_ViewportIndex = lod;
}
/* In order to support physical clipping, we pass a vector to the fragment shader that then clips
* each fragment using a unit sphere test. This allows to support both point light and area light
* clipping at the same time. */
vec3 shadow_clip_vector_get(vec3 view_position, ShadowRenderView shadow_view)
{
float clip_distance_inv = shadow_view.clip_distance_inv;
if (clip_distance_inv == 0.0) {
/* No clipping. */
return vec3(2.0);
}
if (clip_distance_inv < 0.0) {
/* Area light side projections. Clip using the up axis (which maps to light -Z). */
/* Note: clip_distance_inv should already be scaled by M_SQRT3. */
return vec3(view_position.y * clip_distance_inv);
}
/* Sphere light case. */
return view_position * clip_distance_inv;
}
#endif
#if defined(GPU_FRAGMENT_SHADER) && defined(MAT_SHADOW)

View File

@ -26,6 +26,12 @@ void main()
{
float f_depth = gl_FragCoord.z + fwidth(gl_FragCoord.z);
/* Clip to light shape. */
if (length_squared(shadow_clip.vector) < 1.0) {
discard;
return;
}
#ifdef MAT_TRANSPARENT
init_globals();

View File

@ -179,7 +179,8 @@ GPU_SHADER_CREATE_INFO(eevee_lightprobe_irradiance_world)
.storage_buf(0, Qualifier::READ, "uint", "bricks_infos_buf[]")
.storage_buf(1, Qualifier::READ, "SphereProbeHarmonic", "harmonic_buf")
.uniform_buf(0, "VolumeProbeData", "grids_infos_buf[IRRADIANCE_GRID_MAX]")
.image(0, GPU_RGBA16F, Qualifier::READ_WRITE, ImageType::FLOAT_3D, "irradiance_atlas_img")
.image(
0, VOLUME_PROBE_FORMAT, Qualifier::READ_WRITE, ImageType::FLOAT_3D, "irradiance_atlas_img")
.compute_source("eevee_lightprobe_irradiance_world_comp.glsl")
.do_static_compilation(true);
@ -208,7 +209,8 @@ GPU_SHADER_CREATE_INFO(eevee_lightprobe_irradiance_load)
.sampler(7, ImageType::FLOAT_3D, "visibility_d_tx")
.sampler(8, ImageType::FLOAT_3D, "irradiance_atlas_tx")
.sampler(9, ImageType::FLOAT_3D, "validity_tx")
.image(0, GPU_RGBA16F, Qualifier::READ_WRITE, ImageType::FLOAT_3D, "irradiance_atlas_img")
.image(
0, VOLUME_PROBE_FORMAT, Qualifier::READ_WRITE, ImageType::FLOAT_3D, "irradiance_atlas_img")
.compute_source("eevee_lightprobe_irradiance_load_comp.glsl")
.do_static_compilation(true);

View File

@ -231,14 +231,18 @@ GPU_SHADER_CREATE_INFO(eevee_surf_world)
GPU_SHADER_INTERFACE_INFO(eevee_surf_shadow_atomic_iface, "shadow_iface")
.flat(Type::INT, "shadow_view_id");
GPU_SHADER_INTERFACE_INFO(eevee_surf_shadow_clipping_iface, "shadow_clip")
.smooth(Type::VEC3, "vector");
GPU_SHADER_CREATE_INFO(eevee_surf_shadow)
.define("DRW_VIEW_LEN", STRINGIFY(SHADOW_VIEW_MAX))
.define("MAT_SHADOW")
.builtins(BuiltinBits::VIEWPORT_INDEX)
.storage_buf(SHADOW_VIEWPORT_INDEX_BUF_SLOT,
.vertex_out(eevee_surf_shadow_clipping_iface)
.storage_buf(SHADOW_RENDER_VIEW_BUF_SLOT,
Qualifier::READ,
"uint",
"viewport_index_buf[SHADOW_VIEW_MAX]")
"ShadowRenderView",
"render_view_buf[SHADOW_VIEW_MAX]")
.fragment_source("eevee_surf_shadow_frag.glsl")
.additional_info("eevee_global_ubo", "eevee_utility_texture", "eevee_sampling_data");

View File

@ -189,7 +189,7 @@ GPU_SHADER_CREATE_INFO(eevee_shadow_tilemap_finalize)
.storage_buf(7, Qualifier::WRITE, SHADOW_PAGE_PACKED, "dst_coord_buf[SHADOW_RENDER_MAP_SIZE]")
.storage_buf(8, Qualifier::WRITE, SHADOW_PAGE_PACKED, "src_coord_buf[SHADOW_RENDER_MAP_SIZE]")
.storage_buf(9, Qualifier::WRITE, SHADOW_PAGE_PACKED, "render_map_buf[SHADOW_RENDER_MAP_SIZE]")
.storage_buf(10, Qualifier::WRITE, "uint", "viewport_index_buf[SHADOW_VIEW_MAX]")
.storage_buf(10, Qualifier::WRITE, "ShadowRenderView", "render_view_buf[SHADOW_VIEW_MAX]")
.storage_buf(11, Qualifier::READ, "ShadowTileMapClip", "tilemaps_clip_buf[]")
/* 12 is the minimum number of storage buf we require. Do not go above this limit. */
.image(0, GPU_R32UI, Qualifier::WRITE, ImageType::UINT_2D, "tilemaps_img")

View File

@ -366,24 +366,26 @@ PassType *drw_volume_object_mesh_init(PassType &ps,
volume_infos.temperature_mul = 1.0f;
volume_infos.temperature_bias = 0.0f;
bool has_fluid_modifier = (md = BKE_modifiers_findby_type(ob, eModifierType_Fluid)) &&
BKE_modifier_is_enabled(scene, md, eModifierMode_Realtime) &&
((FluidModifierData *)md)->domain != nullptr;
FluidModifierData *fmd = has_fluid_modifier ? (FluidModifierData *)md : nullptr;
FluidDomainSettings *fds = has_fluid_modifier ? fmd->domain : nullptr;
PassType *sub = nullptr;
/* Smoke Simulation. */
if ((md = BKE_modifiers_findby_type(ob, eModifierType_Fluid)) &&
BKE_modifier_is_enabled(scene, md, eModifierMode_Realtime) &&
((FluidModifierData *)md)->domain != nullptr)
{
FluidModifierData *fmd = (FluidModifierData *)md;
FluidDomainSettings *fds = fmd->domain;
/* Don't try to show liquid domains here. */
if (!fds->fluid || !(fds->type == FLUID_DOMAIN_TYPE_GAS)) {
return nullptr;
}
if (fds->type == FLUID_DOMAIN_TYPE_GAS) {
DRW_smoke_ensure(fmd, fds->flags & FLUID_DOMAIN_USE_NOISE);
if (!has_fluid_modifier || (fds->type != FLUID_DOMAIN_TYPE_GAS)) {
/* No volume attributes or fluid domain. */
sub = &ps.sub("Volume Mesh SubPass");
int grid_id = 0;
for (const GPUMaterialAttribute *attr : attrs) {
sub->bind_texture(attr->input_name, grid_default_texture(attr->default_value));
volume_infos.grids_xform[grid_id++] = float4x4::identity();
}
}
else if (!fds->fluid) {
/* Smoke Simulation. */
DRW_smoke_ensure(fmd, fds->flags & FLUID_DOMAIN_USE_NOISE);
sub = &ps.sub("Volume Modifier SubPass");
@ -419,18 +421,10 @@ PassType *drw_volume_object_mesh_init(PassType &ps,
volume_infos.color_mul = float4(UNPACK3(fds->active_color), 1.0f);
}
/* Output is such that 0..1 maps to 0..1000K */
/* Output is such that 0..1 maps to 0..1000K. */
volume_infos.temperature_mul = fds->flame_max_temp - fds->flame_ignition;
volume_infos.temperature_bias = fds->flame_ignition;
}
else {
sub = &ps.sub("Volume Mesh SubPass");
int grid_id = 0;
for (const GPUMaterialAttribute *attr : attrs) {
sub->bind_texture(attr->input_name, grid_default_texture(attr->default_value));
volume_infos.grids_xform[grid_id++] = float4x4::identity();
}
}
if (sub) {
volume_infos.push_update();

Some files were not shown because too many files have changed in this diff Show More