Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h1
-rw-r--r--source/blender/blenkernel/BKE_action.h11
-rw-r--r--source/blender/blenkernel/BKE_anim_visualization.h5
-rw-r--r--source/blender/blenkernel/BKE_blender_version.h6
-rw-r--r--source/blender/blenkernel/BKE_collection.h22
-rw-r--r--source/blender/blenkernel/BKE_colortools.h5
-rw-r--r--source/blender/blenkernel/BKE_constraint.h13
-rw-r--r--source/blender/blenkernel/BKE_fcurve.h3
-rw-r--r--source/blender/blenkernel/BKE_gpencil_modifier.h8
-rw-r--r--source/blender/blenkernel/BKE_idprop.h2
-rw-r--r--source/blender/blenkernel/BKE_idtype.h11
-rw-r--r--source/blender/blenkernel/BKE_layer.h11
-rw-r--r--source/blender/blenkernel/BKE_mesh.h2
-rw-r--r--source/blender/blenkernel/BKE_modifier.h14
-rw-r--r--source/blender/blenkernel/BKE_multires.h18
-rw-r--r--source/blender/blenkernel/BKE_node.h7
-rw-r--r--source/blender/blenkernel/BKE_object.h10
-rw-r--r--source/blender/blenkernel/BKE_paint.h16
-rw-r--r--source/blender/blenkernel/BKE_particle.h19
-rw-r--r--source/blender/blenkernel/BKE_pointcache.h12
-rw-r--r--source/blender/blenkernel/BKE_screen.h24
-rw-r--r--source/blender/blenkernel/BKE_sequencer_offscreen.h2
-rw-r--r--source/blender/blenkernel/BKE_shader_fx.h8
-rw-r--r--source/blender/blenkernel/CMakeLists.txt7
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.c2
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c17
-rw-r--r--source/blender/blenkernel/intern/action.c174
-rw-r--r--source/blender/blenkernel/intern/anim_visualization.c31
-rw-r--r--source/blender/blenkernel/intern/armature.c6
-rw-r--r--source/blender/blenkernel/intern/blender.c7
-rw-r--r--source/blender/blenkernel/intern/boids.c2
-rw-r--r--source/blender/blenkernel/intern/bpath.c3
-rw-r--r--source/blender/blenkernel/intern/brush.c35
-rw-r--r--source/blender/blenkernel/intern/cachefile.c2
-rw-r--r--source/blender/blenkernel/intern/camera.c2
-rw-r--r--source/blender/blenkernel/intern/cloth.c22
-rw-r--r--source/blender/blenkernel/intern/collection.c183
-rw-r--r--source/blender/blenkernel/intern/colortools.c24
-rw-r--r--source/blender/blenkernel/intern/constraint.c186
-rw-r--r--source/blender/blenkernel/intern/crazyspace.c4
-rw-r--r--source/blender/blenkernel/intern/curve.c798
-rw-r--r--source/blender/blenkernel/intern/curve_decimate.c4
-rw-r--r--source/blender/blenkernel/intern/curve_deform.c8
-rw-r--r--source/blender/blenkernel/intern/customdata.c4
-rw-r--r--source/blender/blenkernel/intern/displist.c423
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c19
-rw-r--r--source/blender/blenkernel/intern/editmesh_tangent.c1
-rw-r--r--source/blender/blenkernel/intern/effect.c16
-rw-r--r--source/blender/blenkernel/intern/fcurve.c86
-rw-r--r--source/blender/blenkernel/intern/fcurve_test.cc2
-rw-r--r--source/blender/blenkernel/intern/fluid.c65
-rw-r--r--source/blender/blenkernel/intern/fmodifier.c3
-rw-r--r--source/blender/blenkernel/intern/font.c4
-rw-r--r--source/blender/blenkernel/intern/gpencil.c18
-rw-r--r--source/blender/blenkernel/intern/gpencil_geom.c10
-rw-r--r--source/blender/blenkernel/intern/gpencil_modifier.c166
-rw-r--r--source/blender/blenkernel/intern/hair.c2
-rw-r--r--source/blender/blenkernel/intern/icons.c2
-rw-r--r--source/blender/blenkernel/intern/idprop.c60
-rw-r--r--source/blender/blenkernel/intern/image.c13
-rw-r--r--source/blender/blenkernel/intern/image_gen.c12
-rw-r--r--source/blender/blenkernel/intern/ipo.c77
-rw-r--r--source/blender/blenkernel/intern/key.c12
-rw-r--r--source/blender/blenkernel/intern/lattice.c2
-rw-r--r--source/blender/blenkernel/intern/lattice_deform.c2
-rw-r--r--source/blender/blenkernel/intern/lattice_deform_test.cc12
-rw-r--r--source/blender/blenkernel/intern/layer.c124
-rw-r--r--source/blender/blenkernel/intern/lib_id.c13
-rw-r--r--source/blender/blenkernel/intern/lib_override.c15
-rw-r--r--source/blender/blenkernel/intern/library.c2
-rw-r--r--source/blender/blenkernel/intern/light.c2
-rw-r--r--source/blender/blenkernel/intern/lightprobe.c2
-rw-r--r--source/blender/blenkernel/intern/linestyle.c2
-rw-r--r--source/blender/blenkernel/intern/main_idmap.c1
-rw-r--r--source/blender/blenkernel/intern/mask.c2
-rw-r--r--source/blender/blenkernel/intern/material.c2
-rw-r--r--source/blender/blenkernel/intern/mball.c2
-rw-r--r--source/blender/blenkernel/intern/mball_tessellate.c12
-rw-r--r--source/blender/blenkernel/intern/mesh.c51
-rw-r--r--source/blender/blenkernel/intern/mesh_convert.c2
-rw-r--r--source/blender/blenkernel/intern/mesh_merge.c2
-rw-r--r--source/blender/blenkernel/intern/mesh_remap.c1
-rw-r--r--source/blender/blenkernel/intern/mesh_runtime.c1
-rw-r--r--source/blender/blenkernel/intern/mesh_validate.c1
-rw-r--r--source/blender/blenkernel/intern/modifier.c451
-rw-r--r--source/blender/blenkernel/intern/movieclip.c4
-rw-r--r--source/blender/blenkernel/intern/multires.c886
-rw-r--r--source/blender/blenkernel/intern/multires_reshape.c2
-rw-r--r--source/blender/blenkernel/intern/multires_reshape.h14
-rw-r--r--source/blender/blenkernel/intern/multires_reshape_apply_base.c5
-rw-r--r--source/blender/blenkernel/intern/multires_reshape_subdivide.c2
-rw-r--r--source/blender/blenkernel/intern/multires_reshape_util.c28
-rw-r--r--source/blender/blenkernel/intern/multires_subdiv.c2
-rw-r--r--source/blender/blenkernel/intern/multires_versioning.c106
-rw-r--r--source/blender/blenkernel/intern/node.c11
-rw-r--r--source/blender/blenkernel/intern/object.c642
-rw-r--r--source/blender/blenkernel/intern/object_deform.c4
-rw-r--r--source/blender/blenkernel/intern/object_dupli.c2
-rw-r--r--source/blender/blenkernel/intern/ocean.c2
-rw-r--r--source/blender/blenkernel/intern/paint.c75
-rw-r--r--source/blender/blenkernel/intern/particle.c548
-rw-r--r--source/blender/blenkernel/intern/particle_child.c70
-rw-r--r--source/blender/blenkernel/intern/particle_distribute.c18
-rw-r--r--source/blender/blenkernel/intern/particle_system.c191
-rw-r--r--source/blender/blenkernel/intern/pbvh_bmesh.c1
-rw-r--r--source/blender/blenkernel/intern/pointcache.c164
-rw-r--r--source/blender/blenkernel/intern/pointcloud.cc (renamed from source/blender/blenkernel/intern/pointcloud.c)88
-rw-r--r--source/blender/blenkernel/intern/scene.c1122
-rw-r--r--source/blender/blenkernel/intern/screen.c876
-rw-r--r--source/blender/blenkernel/intern/shader_fx.c50
-rw-r--r--source/blender/blenkernel/intern/shrinkwrap.c4
-rw-r--r--source/blender/blenkernel/intern/simulation.cc4
-rw-r--r--source/blender/blenkernel/intern/softbody.c8
-rw-r--r--source/blender/blenkernel/intern/sound.c10
-rw-r--r--source/blender/blenkernel/intern/speaker.c2
-rw-r--r--source/blender/blenkernel/intern/text.c6
-rw-r--r--source/blender/blenkernel/intern/texture.c4
-rw-r--r--source/blender/blenkernel/intern/tracking.c1
-rw-r--r--source/blender/blenkernel/intern/tracking_solver.c8
-rw-r--r--source/blender/blenkernel/intern/tracking_util.c4
-rw-r--r--source/blender/blenkernel/intern/undo_system.c8
-rw-r--r--source/blender/blenkernel/intern/unit.c10
-rw-r--r--source/blender/blenkernel/intern/volume.cc51
-rw-r--r--source/blender/blenkernel/intern/volume_render.cc10
-rw-r--r--source/blender/blenkernel/intern/workspace.c105
-rw-r--r--source/blender/blenkernel/intern/world.c2
126 files changed, 6413 insertions, 2183 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index b517ecfa599..092eec578c9 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -364,6 +364,7 @@ struct Mesh *editbmesh_get_eval_cage_and_final(struct Depsgraph *depsgraph,
float (*editbmesh_vert_coords_alloc(struct BMEditMesh *em, int *r_vert_len))[3];
bool editbmesh_modifier_is_enabled(struct Scene *scene,
+ const struct Object *ob,
struct ModifierData *md,
bool has_prev_mesh);
void makeDerivedMesh(struct Depsgraph *depsgraph,
diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h
index 699387a18c7..d8605941974 100644
--- a/source/blender/blenkernel/BKE_action.h
+++ b/source/blender/blenkernel/BKE_action.h
@@ -30,6 +30,12 @@
extern "C" {
#endif
+struct BlendWriter;
+struct BlendDataReader;
+struct BlendLibReader;
+struct BlendExpander;
+struct bArmature;
+
/* The following structures are defined in DNA_action_types.h, and DNA_anim_types.h */
struct AnimationEvalContext;
struct FCurve;
@@ -216,6 +222,11 @@ void BKE_pose_rest(struct bPose *pose, bool selected_bones_only);
/* Tag pose for recalc. Also tag all related data to be recalc. */
void BKE_pose_tag_recalc(struct Main *bmain, struct bPose *pose);
+void BKE_pose_blend_write(struct BlendWriter *writer, struct bPose *pose, struct bArmature *arm);
+void BKE_pose_blend_read_data(struct BlendDataReader *reader, struct bPose *pose);
+void BKE_pose_blend_read_lib(struct BlendLibReader *reader, struct Object *ob, struct bPose *pose);
+void BKE_pose_blend_read_expand(struct BlendExpander *expander, struct bPose *pose);
+
#ifdef __cplusplus
};
#endif
diff --git a/source/blender/blenkernel/BKE_anim_visualization.h b/source/blender/blenkernel/BKE_anim_visualization.h
index fb7875a112e..decb2e0b210 100644
--- a/source/blender/blenkernel/BKE_anim_visualization.h
+++ b/source/blender/blenkernel/BKE_anim_visualization.h
@@ -32,6 +32,8 @@ struct Scene;
struct bAnimVizSettings;
struct bMotionPath;
struct bPoseChannel;
+struct BlendWriter;
+struct BlendDataReader;
/* ---------------------------------------------------- */
/* Animation Visualization */
@@ -48,6 +50,9 @@ struct bMotionPath *animviz_verify_motionpaths(struct ReportList *reports,
struct Object *ob,
struct bPoseChannel *pchan);
+void animviz_motionpath_blend_write(struct BlendWriter *writer, struct bMotionPath *mpath);
+void animviz_motionpath_blend_read_data(struct BlendDataReader *reader, struct bMotionPath *mpath);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index 741abb50453..9fa32013ba6 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -31,15 +31,15 @@ extern "C" {
*/
/* Blender major and minor version. */
-#define BLENDER_VERSION 291
+#define BLENDER_VERSION 292
/* Blender patch version for bugfix releases. */
#define BLENDER_VERSION_PATCH 0
/** Blender release cycle stage: alpha/beta/rc/release. */
-#define BLENDER_VERSION_CYCLE beta
+#define BLENDER_VERSION_CYCLE alpha
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
-#define BLENDER_FILE_SUBVERSION 9
+#define BLENDER_FILE_SUBVERSION 4
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and show a warning if the file
diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h
index f4393742dff..f35dafa15a8 100644
--- a/source/blender/blenkernel/BKE_collection.h
+++ b/source/blender/blenkernel/BKE_collection.h
@@ -35,10 +35,16 @@ extern "C" {
struct BLI_Iterator;
struct Base;
+struct BlendDataReader;
+struct BlendExpander;
+struct BlendLibReader;
+struct BlendWriter;
struct Collection;
+struct Library;
struct Main;
struct Object;
struct Scene;
+struct SceneCollection;
struct ViewLayer;
typedef struct CollectionParent {
@@ -160,6 +166,22 @@ bool BKE_collection_has_collection(struct Collection *parent, struct Collection
void BKE_collection_parent_relations_rebuild(struct Collection *collection);
void BKE_main_collections_parent_relations_rebuild(struct Main *bmain);
+/* .blend file I/O */
+
+void BKE_collection_blend_write_nolib(struct BlendWriter *writer, struct Collection *collection);
+void BKE_collection_blend_read_data(struct BlendDataReader *reader, struct Collection *collection);
+void BKE_collection_blend_read_lib(struct BlendLibReader *reader, struct Collection *collection);
+void BKE_collection_blend_read_expand(struct BlendExpander *expander,
+ struct Collection *collection);
+
+void BKE_collection_compat_blend_read_data(struct BlendDataReader *reader,
+ struct SceneCollection *sc);
+void BKE_collection_compat_blend_read_lib(struct BlendLibReader *reader,
+ struct Library *lib,
+ struct SceneCollection *sc);
+void BKE_collection_compat_blend_read_expand(struct BlendExpander *expander,
+ struct SceneCollection *sc);
+
/* Iteration callbacks. */
typedef void (*BKE_scene_objects_Cb)(struct Object *ob, void *data);
diff --git a/source/blender/blenkernel/BKE_colortools.h b/source/blender/blenkernel/BKE_colortools.h
index e56a1ac9ce3..3631feb5071 100644
--- a/source/blender/blenkernel/BKE_colortools.h
+++ b/source/blender/blenkernel/BKE_colortools.h
@@ -139,6 +139,11 @@ void BKE_color_managed_view_settings_copy(struct ColorManagedViewSettings *new_s
const struct ColorManagedViewSettings *settings);
void BKE_color_managed_view_settings_free(struct ColorManagedViewSettings *settings);
+void BKE_color_managed_view_settings_blend_write(struct BlendWriter *writer,
+ struct ColorManagedViewSettings *settings);
+void BKE_color_managed_view_settings_blend_read_data(struct BlendDataReader *reader,
+ struct ColorManagedViewSettings *settings);
+
void BKE_color_managed_colorspace_settings_init(
struct ColorManagedColorspaceSettings *colorspace_settings);
void BKE_color_managed_colorspace_settings_copy(
diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h
index ecb891760b7..e5c4535560d 100644
--- a/source/blender/blenkernel/BKE_constraint.h
+++ b/source/blender/blenkernel/BKE_constraint.h
@@ -31,6 +31,10 @@ struct Scene;
struct bConstraint;
struct bConstraintTarget;
struct bPoseChannel;
+struct BlendWriter;
+struct BlendDataReader;
+struct BlendLibReader;
+struct BlendExpander;
/* ---------------------------------------------------------------------------- */
#ifdef __cplusplus
@@ -183,6 +187,8 @@ bool BKE_constraint_remove_ex(ListBase *list,
bool clear_dep);
bool BKE_constraint_remove(ListBase *list, struct bConstraint *con);
+void BKE_constraint_panel_expand(struct bConstraint *con);
+
/* Constraints + Proxies function prototypes */
void BKE_constraints_proxylocal_extract(struct ListBase *dst, struct ListBase *src);
bool BKE_constraints_proxylocked_owner(struct Object *ob, struct bPoseChannel *pchan);
@@ -220,6 +226,13 @@ void BKE_constraints_solve(struct Depsgraph *depsgraph,
struct bConstraintOb *cob,
float ctime);
+void BKE_constraint_blend_write(struct BlendWriter *writer, struct ListBase *conlist);
+void BKE_constraint_blend_read_data(struct BlendDataReader *reader, struct ListBase *lb);
+void BKE_constraint_blend_read_lib(struct BlendLibReader *reader,
+ struct ID *id,
+ struct ListBase *conlist);
+void BKE_constraint_blend_read_expand(struct BlendExpander *expander, struct ListBase *lb);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h
index c9bc5e83a1f..f527f40d0d7 100644
--- a/source/blender/blenkernel/BKE_fcurve.h
+++ b/source/blender/blenkernel/BKE_fcurve.h
@@ -325,6 +325,9 @@ float fcurve_samplingcb_evalcurve(struct FCurve *fcu, void *data, float evaltime
void fcurve_store_samples(
struct FCurve *fcu, void *data, int start, int end, FcuSampleFunc sample_cb);
+/* Convert baked/sampled fcurves into bezt/regular fcurves. */
+void fcurve_samples_to_keyframes(struct FCurve *fcu, const int start, const int end);
+
/* ************* F-Curve .blend file API ******************** */
void BKE_fmodifiers_blend_write(struct BlendWriter *writer, struct ListBase *fmodifiers);
diff --git a/source/blender/blenkernel/BKE_gpencil_modifier.h b/source/blender/blenkernel/BKE_gpencil_modifier.h
index e003144047b..7729d2c53ab 100644
--- a/source/blender/blenkernel/BKE_gpencil_modifier.h
+++ b/source/blender/blenkernel/BKE_gpencil_modifier.h
@@ -35,6 +35,9 @@ struct Main;
struct ModifierUpdateDepsgraphContext;
struct Object;
struct Scene;
+struct BlendWriter;
+struct BlendDataReader;
+struct BlendLibReader;
/* NOTE: bakeModifier() called from UI:
* needs to create new data-blocks, hence the need for this. */
struct bGPDframe;
@@ -249,6 +252,7 @@ typedef struct GpencilModifierTypeInfo {
void BKE_gpencil_modifier_init(void);
void BKE_gpencil_modifierType_panel_id(GpencilModifierType type, char *r_idname);
+void BKE_gpencil_modifier_panel_expand(struct GpencilModifierData *md);
const GpencilModifierTypeInfo *BKE_gpencil_modifier_get_info(GpencilModifierType type);
struct GpencilModifierData *BKE_gpencil_modifier_new(int type);
void BKE_gpencil_modifier_free_ex(struct GpencilModifierData *md, const int flag);
@@ -302,6 +306,10 @@ struct bGPDframe *BKE_gpencil_frame_retime_get(struct Depsgraph *depsgraph,
struct Object *ob,
struct bGPDlayer *gpl);
+void BKE_gpencil_modifier_blend_write(struct BlendWriter *writer, struct ListBase *modbase);
+void BKE_gpencil_modifier_blend_read_data(struct BlendDataReader *reader, struct ListBase *lb);
+void BKE_gpencil_modifier_blend_read_lib(struct BlendLibReader *reader, struct Object *ob);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h
index 37a83a94079..9c250240e5e 100644
--- a/source/blender/blenkernel/BKE_idprop.h
+++ b/source/blender/blenkernel/BKE_idprop.h
@@ -147,8 +147,6 @@ void IDP_FreeProperty(struct IDProperty *prop);
void IDP_ClearProperty(IDProperty *prop);
-void IDP_RelinkProperty(struct IDProperty *prop);
-
void IDP_Reset(IDProperty *prop, const IDProperty *reference);
#define IDP_Int(prop) ((prop)->data.val)
diff --git a/source/blender/blenkernel/BKE_idtype.h b/source/blender/blenkernel/BKE_idtype.h
index 3caf15d1b50..1298e3c2bbf 100644
--- a/source/blender/blenkernel/BKE_idtype.h
+++ b/source/blender/blenkernel/BKE_idtype.h
@@ -102,6 +102,10 @@ typedef void (*IDTypeBlendReadDataFunction)(struct BlendDataReader *reader, stru
typedef void (*IDTypeBlendReadLibFunction)(struct BlendLibReader *reader, struct ID *id);
typedef void (*IDTypeBlendReadExpandFunction)(struct BlendExpander *expander, struct ID *id);
+typedef void (*IDTypeBlendReadUndoPreserve)(struct BlendLibReader *reader,
+ struct ID *id_new,
+ struct ID *id_old);
+
typedef struct IDTypeInfo {
/* ********** General IDType data. ********** */
@@ -196,6 +200,13 @@ typedef struct IDTypeInfo {
* Specify which other id data blocks should be loaded when the current one is loaded.
*/
IDTypeBlendReadExpandFunction blend_read_expand;
+
+ /**
+ * Allow an ID type to preserve some of its data across (memfile) undo steps.
+ *
+ * \note Called from #setup_app_data when undoing or redoing a memfile step.
+ */
+ IDTypeBlendReadUndoPreserve blend_read_undo_preserve;
} IDTypeInfo;
/* ********** Declaration of each IDTypeInfo. ********** */
diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
index 024d58174e8..1fb3e746b37 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -34,6 +34,9 @@ extern "C" {
#define TODO_LAYER /* generic todo */
struct Base;
+struct BlendDataReader;
+struct BlendLibReader;
+struct BlendWriter;
struct Collection;
struct Depsgraph;
struct LayerCollection;
@@ -147,6 +150,14 @@ void BKE_layer_eval_view_layer_indexed(struct Depsgraph *depsgraph,
struct Scene *scene,
int view_layer_index);
+/* .blend file I/O */
+
+void BKE_view_layer_blend_write(struct BlendWriter *writer, struct ViewLayer *view_layer);
+void BKE_view_layer_blend_read_data(struct BlendDataReader *reader, struct ViewLayer *view_layer);
+void BKE_view_layer_blend_read_lib(struct BlendLibReader *reader,
+ struct Library *lib,
+ struct ViewLayer *view_layer);
+
/* iterators */
typedef struct ObjectsVisibleIteratorData {
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index 789f78826e0..807f13efe14 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -177,7 +177,7 @@ void BKE_mesh_to_pointcloud(struct Main *bmain,
struct Depsgraph *depsgraph,
struct Scene *scene,
struct Object *ob);
-void BKE_mesh_from_pointcloud(struct PointCloud *pointcloud, struct Mesh *me);
+void BKE_mesh_from_pointcloud(const struct PointCloud *pointcloud, struct Mesh *me);
void BKE_pointcloud_to_mesh(struct Main *bmain,
struct Depsgraph *depsgraph,
struct Scene *scene,
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index b2015c4e6d7..a2c3787bcd2 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -30,6 +30,7 @@ extern "C" {
struct ARegionType;
struct BMEditMesh;
struct BlendDataReader;
+struct BlendLibReader;
struct BlendWriter;
struct CustomData_MeshMasks;
struct DepsNodeHandle;
@@ -396,6 +397,7 @@ const ModifierTypeInfo *BKE_modifier_get_info(ModifierType type);
/* For modifier UI panels. */
void BKE_modifier_type_panel_id(ModifierType type, char *r_idname);
+void BKE_modifier_panel_expand(struct ModifierData *md);
/* Modifier utility calls, do call through type pointer and return
* default values if pointer is optional.
@@ -427,8 +429,10 @@ bool BKE_modifier_is_non_geometrical(ModifierData *md);
bool BKE_modifier_is_enabled(const struct Scene *scene,
struct ModifierData *md,
int required_mode);
-void BKE_modifier_set_error(struct ModifierData *md, const char *format, ...)
- ATTR_PRINTF_FORMAT(2, 3);
+void BKE_modifier_set_error(const struct Object *ob,
+ struct ModifierData *md,
+ const char *format,
+ ...) ATTR_PRINTF_FORMAT(3, 4);
bool BKE_modifier_is_preview(struct ModifierData *md);
void BKE_modifiers_foreach_ID_link(struct Object *ob, IDWalkFunc walk, void *userData);
@@ -532,6 +536,12 @@ struct Mesh *BKE_modifier_get_evaluated_mesh_from_evaluated_object(struct Object
void BKE_modifier_check_uuids_unique_and_report(const struct Object *object);
+void BKE_modifier_blend_write(struct BlendWriter *writer, struct ListBase *modbase);
+void BKE_modifier_blend_read_data(struct BlendDataReader *reader,
+ struct ListBase *lb,
+ struct Object *ob);
+void BKE_modifier_blend_read_lib(struct BlendLibReader *reader, struct Object *ob);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h
index fbdfc5b76a7..5a668532033 100644
--- a/source/blender/blenkernel/BKE_multires.h
+++ b/source/blender/blenkernel/BKE_multires.h
@@ -36,7 +36,6 @@ struct DerivedMesh;
struct MDisps;
struct Mesh;
struct ModifierData;
-struct Multires;
struct MultiresModifierData;
struct Object;
struct Scene;
@@ -114,22 +113,12 @@ int multiresModifier_rebuild_subdiv(struct Depsgraph *depsgraph,
struct MultiresModifierData *mmd,
int rebuild_limit,
bool switch_view_to_lower_level);
-void multiresModifier_subdivide_legacy(struct MultiresModifierData *mmd,
- struct Scene *scene,
- struct Object *ob,
- int updateblock,
- int simple);
void multiresModifier_sync_levels_ex(struct Object *ob_dst,
struct MultiresModifierData *mmd_src,
struct MultiresModifierData *mmd_dst);
void multires_stitch_grids(struct Object *);
-/* Related to the old multires */
-void multires_free(struct Multires *mr);
-void multires_load_old(struct Object *ob, struct Mesh *me);
-void multires_load_old_250(struct Mesh *);
-
void multiresModifier_scale_disp(struct Depsgraph *depsgraph,
struct Scene *scene,
struct Object *ob);
@@ -229,6 +218,13 @@ BLI_INLINE void BKE_multires_construct_tangent_matrix(float tangent_matrix[3][3]
const float dPdv[3],
const int corner);
+/* Versioning. */
+
+/* Convert displacement which is stored for simply-subdivided mesh to a Catmull-Clark
+ * subdivided mesh. */
+void multires_do_versions_simple_to_catmull_clark(struct Object *object,
+ struct MultiresModifierData *mmd);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 38045e22def..e3591b8fcd1 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -880,8 +880,7 @@ void BKE_node_tree_unlink_id(ID *id, struct bNodeTree *ntree);
* } FOREACH_NODETREE_END;
* \endcode
*
- * \{
- */
+ * \{ */
/* should be an opaque type, only for internal use by BKE_node_tree_iter_*** */
struct NodeTreeIterStore {
@@ -1337,8 +1336,8 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
/** \} */
-void init_nodesystem(void);
-void free_nodesystem(void);
+void BKE_node_system_init(void);
+void BKE_node_system_exit(void);
/* -------------------------------------------------------------------- */
/* evaluation support, */
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 0a992f2cb58..28c912a4c9a 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -191,6 +191,8 @@ struct Base **BKE_object_pose_base_array_get(struct ViewLayer *view_layer,
unsigned int *r_bases_len);
void BKE_object_get_parent_matrix(struct Object *ob, struct Object *par, float r_parentmat[4][4]);
+
+/* Compute object world transform and store it in ob->obmat. */
void BKE_object_where_is_calc(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob);
void BKE_object_where_is_calc_ex(struct Depsgraph *depsgraph,
struct Scene *scene,
@@ -414,6 +416,14 @@ void BKE_object_to_mesh_clear(struct Object *object);
void BKE_object_check_uuids_unique_and_report(const struct Object *object);
+void BKE_object_modifiers_lib_link_common(void *userData,
+ struct Object *ob,
+ struct ID **idpoin,
+ int cb_flag);
+
+struct PartEff;
+struct PartEff *BKE_object_do_version_give_parteff_245(struct Object *ob);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 150d0d9b011..a58bf760ad5 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -66,6 +66,9 @@ struct ViewLayer;
struct bContext;
struct bToolRef;
struct tPaletteColorHSV;
+struct BlendWriter;
+struct BlendDataReader;
+struct BlendLibReader;
enum eOverlayFlags;
@@ -217,6 +220,15 @@ void BKE_paint_toolslots_brush_update(struct Paint *paint);
void BKE_paint_toolslots_brush_validate(struct Main *bmain, struct Paint *paint);
struct Brush *BKE_paint_toolslots_brush_get(struct Paint *paint, int slot_index);
+/* .blend I/O */
+void BKE_paint_blend_write(struct BlendWriter *writer, struct Paint *paint);
+void BKE_paint_blend_read_data(struct BlendDataReader *reader,
+ const struct Scene *scene,
+ struct Paint *paint);
+void BKE_paint_blend_read_lib(struct BlendLibReader *reader,
+ struct Scene *scene,
+ struct Paint *paint);
+
#define SCULPT_FACE_SET_NONE 0
/* Used for both vertex color and weight paint */
@@ -505,6 +517,9 @@ typedef struct SculptSession {
int active_face_index;
int active_grid_index;
+ /* When active, the cursor draws with faded colors, indicating that there is an action enabled.
+ */
+ bool draw_faded_cursor;
float cursor_radius;
float cursor_location[3];
float cursor_normal[3];
@@ -514,6 +529,7 @@ typedef struct SculptSession {
/* For Sculpt trimming gesture tools, initial raycast data from the position of the mouse when
* the gesture starts (intersection with the surface and if they ray hit the surface or not). */
float gesture_initial_location[3];
+ float gesture_initial_normal[3];
bool gesture_initial_hit;
/* TODO(jbakker): Replace rv3d adn v3d with ViewContext */
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index 6ed3b94b8e5..73815325594 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -45,6 +45,9 @@ struct ParticleSystemModifierData;
struct BVHTreeRay;
struct BVHTreeRayHit;
+struct BlendWriter;
+struct BlendDataReader;
+struct BlendLibReader;
struct CustomData_MeshMasks;
struct Depsgraph;
struct EdgeHash;
@@ -261,7 +264,7 @@ extern unsigned int PSYS_FRAND_SEED_OFFSET[PSYS_FRAND_COUNT];
extern unsigned int PSYS_FRAND_SEED_MULTIPLIER[PSYS_FRAND_COUNT];
extern float PSYS_FRAND_BASE[PSYS_FRAND_COUNT];
-void psys_init_rng(void);
+void BKE_particle_init_rng(void);
BLI_INLINE float psys_frand(ParticleSystem *psys, unsigned int seed)
{
@@ -625,6 +628,20 @@ void BKE_particle_batch_cache_free(struct ParticleSystem *psys);
extern void (*BKE_particle_batch_cache_dirty_tag_cb)(struct ParticleSystem *psys, int mode);
extern void (*BKE_particle_batch_cache_free_cb)(struct ParticleSystem *psys);
+/* .blend file I/O */
+void BKE_particle_partdeflect_blend_read_data(struct BlendDataReader *reader,
+ struct PartDeflect *pd);
+void BKE_particle_partdeflect_blend_read_lib(struct BlendLibReader *reader,
+ struct ID *id,
+ struct PartDeflect *pd);
+void BKE_particle_system_blend_write(struct BlendWriter *writer, struct ListBase *particles);
+void BKE_particle_system_blend_read_data(struct BlendDataReader *reader,
+ struct ListBase *particles);
+void BKE_particle_system_blend_read_lib(struct BlendLibReader *reader,
+ struct Object *ob,
+ struct ID *id,
+ struct ListBase *particles);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h
index f8e04b75b3d..470d53f6655 100644
--- a/source/blender/blenkernel/BKE_pointcache.h
+++ b/source/blender/blenkernel/BKE_pointcache.h
@@ -91,6 +91,8 @@ struct RigidBodyWorld;
struct Scene;
struct SoftBody;
struct ViewLayer;
+struct BlendWriter;
+struct BlendDataReader;
/* temp structure for read/write */
typedef struct PTCacheData {
@@ -167,7 +169,7 @@ typedef struct PTCacheID {
* (the cfra parameter is just for using same function pointer with totwrite). */
int (*totpoint)(void *calldata, int cfra);
/* report error if number of points does not match */
- void (*error)(void *calldata, const char *message);
+ void (*error)(const struct ID *owner_id, void *calldata, const char *message);
/* number of points written for current cache frame */
int (*totwrite)(void *calldata, int cfra);
@@ -374,6 +376,14 @@ void BKE_ptcache_validate(struct PointCache *cache, int framenr);
/* Set correct flags after unsuccessful simulation step */
void BKE_ptcache_invalidate(struct PointCache *cache);
+/********************** .blend File I/O *********************/
+
+void BKE_ptcache_blend_write(struct BlendWriter *writer, struct ListBase *ptcaches);
+void BKE_ptcache_blend_read_data(struct BlendDataReader *reader,
+ struct ListBase *ptcaches,
+ struct PointCache **ocache,
+ int force_disk);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h
index 35a3d0415a8..fd5339940dd 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -33,6 +33,9 @@ extern "C" {
#endif
struct ARegion;
+struct BlendDataReader;
+struct BlendLibReader;
+struct BlendWriter;
struct Header;
struct ID;
struct LibraryForeachIDData;
@@ -362,8 +365,8 @@ typedef struct Menu {
/* spacetypes */
struct SpaceType *BKE_spacetype_from_id(int spaceid);
-struct ARegionType *BKE_regiontype_from_id_or_first(struct SpaceType *st, int regionid);
-struct ARegionType *BKE_regiontype_from_id(struct SpaceType *st, int regionid);
+struct ARegionType *BKE_regiontype_from_id_or_first(const struct SpaceType *st, int regionid);
+struct ARegionType *BKE_regiontype_from_id(const struct SpaceType *st, int regionid);
const struct ListBase *BKE_spacetypes_list(void);
void BKE_spacetype_register(struct SpaceType *st);
bool BKE_spacetype_exists(int spaceid);
@@ -384,7 +387,7 @@ void BKE_spacedata_callback_id_remap_set(void (*func)(
void BKE_spacedata_id_unref(struct ScrArea *area, struct SpaceLink *sl, struct ID *id);
/* area/regions */
-struct ARegion *BKE_area_region_copy(struct SpaceType *st, struct ARegion *region);
+struct ARegion *BKE_area_region_copy(const struct SpaceType *st, const struct ARegion *region);
void BKE_area_region_free(struct SpaceType *st, struct ARegion *region);
void BKE_area_region_panels_free(struct ListBase *panels);
void BKE_screen_area_free(struct ScrArea *area);
@@ -449,6 +452,21 @@ void BKE_screen_remove_unused_scrverts(struct bScreen *screen);
void BKE_screen_header_alignment_reset(struct bScreen *screen);
+/* .blend file I/O */
+void BKE_screen_view3d_shading_blend_write(struct BlendWriter *writer,
+ struct View3DShading *shading);
+void BKE_screen_view3d_shading_blend_read_data(struct BlendDataReader *reader,
+ struct View3DShading *shading);
+
+void BKE_screen_area_map_blend_write(struct BlendWriter *writer, struct ScrAreaMap *area_map);
+bool BKE_screen_area_map_blend_read_data(struct BlendDataReader *reader,
+ struct ScrAreaMap *area_map);
+void BKE_screen_view3d_do_versions_250(struct View3D *v3d, ListBase *regions);
+void BKE_screen_area_blend_read_lib(struct BlendLibReader *reader,
+ struct ID *parent_id,
+ struct ScrArea *area);
+bool BKE_screen_blend_read_data(struct BlendDataReader *reader, struct bScreen *screen);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_sequencer_offscreen.h b/source/blender/blenkernel/BKE_sequencer_offscreen.h
index 90d3f80320a..f5f6067b06e 100644
--- a/source/blender/blenkernel/BKE_sequencer_offscreen.h
+++ b/source/blender/blenkernel/BKE_sequencer_offscreen.h
@@ -33,6 +33,8 @@
extern "C" {
#endif
+struct GPUOffScreen;
+
typedef struct ImBuf *(*SequencerDrawView)(struct Depsgraph *depsgraph,
struct Scene *scene,
struct View3DShading *shading_override,
diff --git a/source/blender/blenkernel/BKE_shader_fx.h b/source/blender/blenkernel/BKE_shader_fx.h
index da14487c1f4..7c2d363be5c 100644
--- a/source/blender/blenkernel/BKE_shader_fx.h
+++ b/source/blender/blenkernel/BKE_shader_fx.h
@@ -33,6 +33,9 @@ struct ListBase;
struct ModifierUpdateDepsgraphContext;
struct Object;
struct ShaderFxData;
+struct BlendWriter;
+struct BlendDataReader;
+struct BlendLibReader;
#define SHADER_FX_ACTIVE(_fx, _is_render) \
((((_fx)->mode & eShaderFxMode_Realtime) && (_is_render == false)) || \
@@ -151,6 +154,7 @@ typedef struct ShaderFxTypeInfo {
void BKE_shaderfx_init(void);
void BKE_shaderfxType_panel_id(ShaderFxType type, char *r_idname);
+void BKE_shaderfx_panel_expand(struct ShaderFxData *fx);
const ShaderFxTypeInfo *BKE_shaderfx_get_info(ShaderFxType type);
struct ShaderFxData *BKE_shaderfx_new(int type);
void BKE_shaderfx_free_ex(struct ShaderFxData *fx, const int flag);
@@ -169,6 +173,10 @@ void BKE_shaderfx_foreach_ID_link(struct Object *ob, ShaderFxIDWalkFunc walk, vo
bool BKE_shaderfx_has_gpencil(struct Object *ob);
+void BKE_shaderfx_blend_write(struct BlendWriter *writer, struct ListBase *fxbase);
+void BKE_shaderfx_blend_read_data(struct BlendDataReader *reader, struct ListBase *lb);
+void BKE_shaderfx_blend_read_lib(struct BlendLibReader *reader, struct Object *ob);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index f6df3f1bb62..40b2d62baac 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -39,7 +39,7 @@ set(INC
../sequencer
../shader_fx
../simulation
- ../render/extern/include
+ ../render
../../../intern/ghost
../../../intern/glew-mx
../../../intern/guardedalloc
@@ -189,6 +189,7 @@ set(SRC
intern/multires_reshape_vertcos.c
intern/multires_subdiv.c
intern/multires_unsubdivide.c
+ intern/multires_versioning.c
intern/nla.c
intern/node.c
intern/object.c
@@ -209,7 +210,7 @@ set(SRC
intern/pbvh.c
intern/pbvh_bmesh.c
intern/pointcache.c
- intern/pointcloud.c
+ intern/pointcloud.cc
intern/report.c
intern/rigidbody.c
intern/scene.c
@@ -705,7 +706,7 @@ endif()
# # Warnings as errors, this is too strict!
# if(MSVC)
-# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX")
+# string(APPEND CMAKE_C_FLAGS " /WX")
# endif()
blender_add_lib(bf_blenkernel "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c
index d63c5fe12ab..67e7b890548 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf.c
@@ -736,7 +736,7 @@ CCGError ccgSubSurf_syncFace(
}
}
else {
- if (ss->syncState == eSyncState_Vert || ss->syncState == eSyncState_Edge) {
+ if (ELEM(ss->syncState, eSyncState_Vert, eSyncState_Edge)) {
ss->syncState = eSyncState_Face;
}
else if (ss->syncState != eSyncState_Face) {
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index d551eaf04e4..eeff04788f9 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -1021,7 +1021,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
if ((mti->flags & eModifierTypeFlag_RequiresOriginalData) &&
have_non_onlydeform_modifiers_appled) {
- BKE_modifier_set_error(md, "Modifier requires original data, bad stack position");
+ BKE_modifier_set_error(ob, md, "Modifier requires original data, bad stack position");
continue;
}
@@ -1047,10 +1047,10 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
if (unsupported) {
if (sculpt_dyntopo) {
- BKE_modifier_set_error(md, "Not supported in dyntopo");
+ BKE_modifier_set_error(ob, md, "Not supported in dyntopo");
}
else {
- BKE_modifier_set_error(md, "Not supported in sculpt mode");
+ BKE_modifier_set_error(ob, md, "Not supported in sculpt mode");
}
continue;
}
@@ -1378,7 +1378,10 @@ float (*editbmesh_vert_coords_alloc(BMEditMesh *em, int *r_vert_len))[3]
return cos;
}
-bool editbmesh_modifier_is_enabled(Scene *scene, ModifierData *md, bool has_prev_mesh)
+bool editbmesh_modifier_is_enabled(Scene *scene,
+ const Object *ob,
+ ModifierData *md,
+ bool has_prev_mesh)
{
const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
const int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
@@ -1388,7 +1391,7 @@ bool editbmesh_modifier_is_enabled(Scene *scene, ModifierData *md, bool has_prev
}
if ((mti->flags & eModifierTypeFlag_RequiresOriginalData) && has_prev_mesh) {
- BKE_modifier_set_error(md, "Modifier requires original data, bad stack position");
+ BKE_modifier_set_error(ob, md, "Modifier requires original data, bad stack position");
return false;
}
@@ -1522,7 +1525,7 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
for (int i = 0; md; i++, md = md->next, md_datamask = md_datamask->next) {
const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
- if (!editbmesh_modifier_is_enabled(scene, md, mesh_final != NULL)) {
+ if (!editbmesh_modifier_is_enabled(scene, ob, md, mesh_final != NULL)) {
continue;
}
@@ -2187,7 +2190,7 @@ static void mesh_init_origspace(Mesh *mesh)
for (i = 0; i < numpoly; i++, mp++) {
OrigSpaceLoop *lof = lof_array + mp->loopstart;
- if (mp->totloop == 3 || mp->totloop == 4) {
+ if (ELEM(mp->totloop, 3, 4)) {
for (j = 0; j < mp->totloop; j++, lof++) {
copy_v2_v2(lof->uv, default_osf[j]);
}
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index cbecc91b4ec..126063288d8 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -61,6 +61,7 @@
#include "BKE_main.h"
#include "BKE_object.h"
+#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
#include "BIK_api.h"
@@ -295,6 +296,8 @@ IDTypeInfo IDType_ID_AC = {
.blend_read_data = action_blend_read_data,
.blend_read_lib = action_blend_read_lib,
.blend_read_expand = action_blend_read_expand,
+
+ .blend_read_undo_preserve = NULL,
};
/* ***************** Library data level operations on action ************** */
@@ -1844,3 +1847,174 @@ void BKE_pose_check_uuids_unique_and_report(const bPose *pose)
BLI_gset_free(used_uuids, NULL);
}
+
+void BKE_pose_blend_write(BlendWriter *writer, bPose *pose, bArmature *arm)
+{
+ /* Write each channel */
+ if (pose == NULL) {
+ return;
+ }
+
+ BLI_assert(arm != NULL);
+
+ /* Write channels */
+ LISTBASE_FOREACH (bPoseChannel *, chan, &pose->chanbase) {
+ /* Write ID Properties -- and copy this comment EXACTLY for easy finding
+ * of library blocks that implement this.*/
+ if (chan->prop) {
+ IDP_BlendWrite(writer, chan->prop);
+ }
+
+ BKE_constraint_blend_write(writer, &chan->constraints);
+
+ animviz_motionpath_blend_write(writer, chan->mpath);
+
+ /* Prevent crashes with autosave,
+ * when a bone duplicated in edit-mode has not yet been assigned to its pose-channel.
+ * Also needed with memundo, in some cases we can store a step before pose has been
+ * properly rebuilt from previous undo step. */
+ Bone *bone = (pose->flag & POSE_RECALC) ? BKE_armature_find_bone_name(arm, chan->name) :
+ chan->bone;
+ if (bone != NULL) {
+ /* gets restored on read, for library armatures */
+ chan->selectflag = bone->flag & BONE_SELECTED;
+ }
+
+ BLO_write_struct(writer, bPoseChannel, chan);
+ }
+
+ /* Write groups */
+ LISTBASE_FOREACH (bActionGroup *, grp, &pose->agroups) {
+ BLO_write_struct(writer, bActionGroup, grp);
+ }
+
+ /* write IK param */
+ if (pose->ikparam) {
+ const char *structname = BKE_pose_ikparam_get_name(pose);
+ if (structname) {
+ BLO_write_struct_by_name(writer, structname, pose->ikparam);
+ }
+ }
+
+ /* Write this pose */
+ BLO_write_struct(writer, bPose, pose);
+}
+
+void BKE_pose_blend_read_data(BlendDataReader *reader, bPose *pose)
+{
+ if (!pose) {
+ return;
+ }
+
+ BLO_read_list(reader, &pose->chanbase);
+ BLO_read_list(reader, &pose->agroups);
+
+ pose->chanhash = NULL;
+ pose->chan_array = NULL;
+
+ LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
+ BKE_pose_channel_runtime_reset(&pchan->runtime);
+ BKE_pose_channel_session_uuid_generate(pchan);
+
+ pchan->bone = NULL;
+ BLO_read_data_address(reader, &pchan->parent);
+ BLO_read_data_address(reader, &pchan->child);
+ BLO_read_data_address(reader, &pchan->custom_tx);
+
+ BLO_read_data_address(reader, &pchan->bbone_prev);
+ BLO_read_data_address(reader, &pchan->bbone_next);
+
+ BKE_constraint_blend_read_data(reader, &pchan->constraints);
+
+ BLO_read_data_address(reader, &pchan->prop);
+ IDP_BlendDataRead(reader, &pchan->prop);
+
+ BLO_read_data_address(reader, &pchan->mpath);
+ if (pchan->mpath) {
+ animviz_motionpath_blend_read_data(reader, pchan->mpath);
+ }
+
+ BLI_listbase_clear(&pchan->iktree);
+ BLI_listbase_clear(&pchan->siktree);
+
+ /* in case this value changes in future, clamp else we get undefined behavior */
+ CLAMP(pchan->rotmode, ROT_MODE_MIN, ROT_MODE_MAX);
+
+ pchan->draw_data = NULL;
+ }
+ pose->ikdata = NULL;
+ if (pose->ikparam != NULL) {
+ BLO_read_data_address(reader, &pose->ikparam);
+ }
+}
+
+void BKE_pose_blend_read_lib(BlendLibReader *reader, Object *ob, bPose *pose)
+{
+ bArmature *arm = ob->data;
+
+ if (!pose || !arm) {
+ return;
+ }
+
+ /* always rebuild to match proxy or lib changes, but on Undo */
+ bool rebuild = false;
+
+ if (!BLO_read_lib_is_undo(reader)) {
+ if (ob->proxy || ob->id.lib != arm->id.lib) {
+ rebuild = true;
+ }
+ }
+
+ if (ob->proxy) {
+ /* sync proxy layer */
+ if (pose->proxy_layer) {
+ arm->layer = pose->proxy_layer;
+ }
+
+ /* sync proxy active bone */
+ if (pose->proxy_act_bone[0]) {
+ Bone *bone = BKE_armature_find_bone_name(arm, pose->proxy_act_bone);
+ if (bone) {
+ arm->act_bone = bone;
+ }
+ }
+ }
+
+ LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
+ BKE_constraint_blend_read_lib(reader, (ID *)ob, &pchan->constraints);
+
+ pchan->bone = BKE_armature_find_bone_name(arm, pchan->name);
+
+ IDP_BlendReadLib(reader, pchan->prop);
+
+ BLO_read_id_address(reader, arm->id.lib, &pchan->custom);
+ if (UNLIKELY(pchan->bone == NULL)) {
+ rebuild = true;
+ }
+ else if ((ob->id.lib == NULL) && arm->id.lib) {
+ /* local pose selection copied to armature, bit hackish */
+ pchan->bone->flag &= ~BONE_SELECTED;
+ pchan->bone->flag |= pchan->selectflag;
+ }
+ }
+
+ if (rebuild) {
+ Main *bmain = BLO_read_lib_get_main(reader);
+ DEG_id_tag_update_ex(
+ bmain, &ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
+ BKE_pose_tag_recalc(bmain, pose);
+ }
+}
+
+void BKE_pose_blend_read_expand(BlendExpander *expander, bPose *pose)
+{
+ if (!pose) {
+ return;
+ }
+
+ LISTBASE_FOREACH (bPoseChannel *, chan, &pose->chanbase) {
+ BKE_constraint_blend_read_expand(expander, &chan->constraints);
+ IDP_BlendReadExpand(expander, chan->prop);
+ BLO_expand(expander, chan->custom);
+ }
+}
diff --git a/source/blender/blenkernel/intern/anim_visualization.c b/source/blender/blenkernel/intern/anim_visualization.c
index 5452e2513fb..ecd71ec08fe 100644
--- a/source/blender/blenkernel/intern/anim_visualization.c
+++ b/source/blender/blenkernel/intern/anim_visualization.c
@@ -34,6 +34,8 @@
#include "GPU_batch.h"
+#include "BLO_read_write.h"
+
/* ******************************************************************** */
/* Animation Visualization */
@@ -224,3 +226,32 @@ bMotionPath *animviz_verify_motionpaths(ReportList *reports,
/* return it */
return mpath;
}
+
+void animviz_motionpath_blend_write(BlendWriter *writer, bMotionPath *mpath)
+{
+ /* sanity checks */
+ if (mpath == NULL) {
+ return;
+ }
+
+ /* firstly, just write the motionpath struct */
+ BLO_write_struct(writer, bMotionPath, mpath);
+
+ /* now write the array of data */
+ BLO_write_struct_array(writer, bMotionPathVert, mpath->length, mpath->points);
+}
+
+void animviz_motionpath_blend_read_data(BlendDataReader *reader, bMotionPath *mpath)
+{
+ /* sanity check */
+ if (mpath == NULL) {
+ return;
+ }
+
+ /* relink points cache */
+ BLO_read_data_address(reader, &mpath->points);
+
+ mpath->points_vbo = NULL;
+ mpath->batch_line = NULL;
+ mpath->batch_points = NULL;
+}
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index bad2ed53436..fb885527cce 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -329,6 +329,8 @@ IDTypeInfo IDType_ID_AR = {
.blend_read_data = armature_blend_read_data,
.blend_read_lib = armature_blend_read_lib,
.blend_read_expand = armature_blend_read_expand,
+
+ .blend_read_undo_preserve = NULL,
};
/** \} */
@@ -576,7 +578,7 @@ void BKE_armature_transform(bArmature *arm, const float mat[4][4], const bool do
/* -------------------------------------------------------------------- */
/** \name Armature Bone Find by Name
*
- * Using fast #GHash look-ups when available.
+ * Using fast #GHash lookups when available.
* \{ */
static Bone *get_named_bone_bonechildren(ListBase *lb, const char *name)
@@ -799,7 +801,7 @@ bool bone_autoside_name(
while (changed) { /* remove extensions */
changed = false;
if (len > 2 && basename[len - 2] == '.') {
- if (basename[len - 1] == 'L' || basename[len - 1] == 'R') { /* L R */
+ if (ELEM(basename[len - 1], 'L', 'R')) { /* L R */
basename[len - 2] = '\0';
len -= 2;
changed = true;
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 1ad1a821129..f4f25c3a153 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -53,13 +53,14 @@
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
-#include "BKE_sequencer.h"
#include "BKE_studiolight.h"
#include "DEG_depsgraph.h"
#include "RE_pipeline.h"
-#include "RE_render_ext.h"
+#include "RE_texture.h"
+
+#include "SEQ_sequencer.h"
#include "BLF_api.h"
@@ -99,7 +100,7 @@ void BKE_blender_free(void)
IMB_moviecache_destruct();
- free_nodesystem();
+ BKE_node_system_exit();
}
/** \} */
diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c
index 78ce70a8448..96bf9fbe8d2 100644
--- a/source/blender/blenkernel/intern/boids.c
+++ b/source/blender/blenkernel/intern/boids.c
@@ -899,7 +899,7 @@ static Object *boid_find_ground(BoidBrainData *bbd,
for (coll = bbd->sim->colliders->first; coll; coll = coll->next) {
col.current = coll->ob;
col.md = coll->collmd;
- col.fac1 = col.fac2 = 0.f;
+ col.fac1 = col.fac2 = 0.0f;
if (col.md && col.md->bvhtree) {
BLI_bvhtree_ray_cast_ex(col.md->bvhtree,
diff --git a/source/blender/blenkernel/intern/bpath.c b/source/blender/blenkernel/intern/bpath.c
index 4ea9a26f0f8..f624d0ae057 100644
--- a/source/blender/blenkernel/intern/bpath.c
+++ b/source/blender/blenkernel/intern/bpath.c
@@ -73,12 +73,13 @@
#include "BKE_main.h"
#include "BKE_node.h"
#include "BKE_report.h"
-#include "BKE_sequencer.h"
#include "BKE_bpath.h" /* own include */
#include "CLG_log.h"
+#include "SEQ_sequencer.h"
+
#ifndef _MSC_VER
# include "BLI_strict_flags.h"
#endif
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 17243b328e8..1b77989c2b8 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -50,7 +50,7 @@
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
-#include "RE_render_ext.h" /* RE_texture_evaluate */
+#include "RE_texture.h" /* RE_texture_evaluate */
#include "BLO_read_write.h"
@@ -355,6 +355,37 @@ static void brush_blend_read_expand(BlendExpander *expander, ID *id)
}
}
+static int brush_undo_preserve_cb(LibraryIDLinkCallbackData *cb_data)
+{
+ BlendLibReader *reader = cb_data->user_data;
+ ID *id_old = *cb_data->id_pointer;
+ /* Old data has not been remapped to new values of the pointers, if we want to keep the old
+ * pointer here we need its new address. */
+ ID *id_old_new = id_old != NULL ? BLO_read_get_new_id_address(reader, id_old->lib, id_old) :
+ NULL;
+ BLI_assert(id_old_new == NULL || ELEM(id_old, id_old_new, id_old_new->orig_id));
+ if (cb_data->cb_flag & IDWALK_CB_USER) {
+ id_us_plus_no_lib(id_old_new);
+ id_us_min(id_old);
+ }
+ *cb_data->id_pointer = id_old_new;
+ return IDWALK_RET_NOP;
+}
+
+static void brush_undo_preserve(BlendLibReader *reader, ID *id_new, ID *id_old)
+{
+ /* Whole Brush is preserved accross undo's. */
+ BKE_lib_id_swap(NULL, id_new, id_old);
+
+ /* `id_new` now has content from `id_old`, we need to ensure those old ID pointers are valid.
+ * Note: Since we want to re-use all old pointers here, code is much simpler than for Scene. */
+ BKE_library_foreach_ID_link(NULL, id_new, brush_undo_preserve_cb, reader, IDWALK_NOP);
+
+ /* Note: We do not swap IDProperties, as dealing with potential ID pointers in those would be
+ * fairly delicate. */
+ SWAP(IDProperty *, id_new->properties, id_old->properties);
+}
+
IDTypeInfo IDType_ID_BR = {
.id_code = ID_BR,
.id_filter = FILTER_ID_BR,
@@ -376,6 +407,8 @@ IDTypeInfo IDType_ID_BR = {
.blend_read_data = brush_blend_read_data,
.blend_read_lib = brush_blend_read_lib,
.blend_read_expand = brush_blend_read_expand,
+
+ .blend_read_undo_preserve = brush_undo_preserve,
};
static RNG *brush_rng;
diff --git a/source/blender/blenkernel/intern/cachefile.c b/source/blender/blenkernel/intern/cachefile.c
index 0ee0242866f..d6c31809a2e 100644
--- a/source/blender/blenkernel/intern/cachefile.c
+++ b/source/blender/blenkernel/intern/cachefile.c
@@ -140,6 +140,8 @@ IDTypeInfo IDType_ID_CF = {
.blend_read_data = cache_file_blend_read_data,
.blend_read_lib = NULL,
.blend_read_expand = NULL,
+
+ .blend_read_undo_preserve = NULL,
};
/* TODO: make this per cache file to avoid global locks. */
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index 3980a552855..0ca22e34973 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -201,6 +201,8 @@ IDTypeInfo IDType_ID_CA = {
.blend_read_data = camera_blend_read_data,
.blend_read_lib = camera_blend_read_lib,
.blend_read_expand = camera_blend_read_expand,
+
+ .blend_read_undo_preserve = NULL,
};
/** \} */
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index 403722b80cf..e9df562a15f 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -55,7 +55,7 @@
/* Prototypes for internal functions.
*/
static void cloth_to_object(Object *ob, ClothModifierData *clmd, float (*vertexCos)[3]);
-static void cloth_from_mesh(ClothModifierData *clmd, Mesh *mesh);
+static void cloth_from_mesh(ClothModifierData *clmd, const Object *ob, Mesh *mesh);
static bool cloth_from_object(
Object *ob, ClothModifierData *clmd, Mesh *mesh, float framenr, int first);
static void cloth_update_springs(ClothModifierData *clmd);
@@ -234,13 +234,13 @@ static bool do_init_cloth(Object *ob, ClothModifierData *clmd, Mesh *result, int
if (clmd->clothObject == NULL) {
if (!cloth_from_object(ob, clmd, result, framenr, 1)) {
BKE_ptcache_invalidate(cache);
- BKE_modifier_set_error(&(clmd->modifier), "Can't initialize cloth");
+ BKE_modifier_set_error(ob, &(clmd->modifier), "Can't initialize cloth");
return false;
}
if (clmd->clothObject == NULL) {
BKE_ptcache_invalidate(cache);
- BKE_modifier_set_error(&(clmd->modifier), "Null cloth object");
+ BKE_modifier_set_error(ob, &(clmd->modifier), "Null cloth object");
return false;
}
@@ -742,7 +742,7 @@ static bool cloth_from_object(
clmd->clothObject->edgeset = NULL;
}
else {
- BKE_modifier_set_error(&(clmd->modifier), "Out of memory on allocating clmd->clothObject");
+ BKE_modifier_set_error(ob, &(clmd->modifier), "Out of memory on allocating clmd->clothObject");
return false;
}
@@ -751,7 +751,7 @@ static bool cloth_from_object(
return false;
}
- cloth_from_mesh(clmd, mesh);
+ cloth_from_mesh(clmd, ob, mesh);
/* create springs */
clmd->clothObject->springs = NULL;
@@ -814,7 +814,7 @@ static bool cloth_from_object(
if (!cloth_build_springs(clmd, mesh)) {
cloth_free_modifier(clmd);
- BKE_modifier_set_error(&(clmd->modifier), "Cannot build springs");
+ BKE_modifier_set_error(ob, &(clmd->modifier), "Cannot build springs");
return false;
}
@@ -831,7 +831,7 @@ static bool cloth_from_object(
return true;
}
-static void cloth_from_mesh(ClothModifierData *clmd, Mesh *mesh)
+static void cloth_from_mesh(ClothModifierData *clmd, const Object *ob, Mesh *mesh)
{
const MLoop *mloop = mesh->mloop;
const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(mesh);
@@ -844,8 +844,8 @@ static void cloth_from_mesh(ClothModifierData *clmd, Mesh *mesh)
"clothVertex");
if (clmd->clothObject->verts == NULL) {
cloth_free_modifier(clmd);
- BKE_modifier_set_error(&(clmd->modifier),
- "Out of memory on allocating clmd->clothObject->verts");
+ BKE_modifier_set_error(
+ ob, &(clmd->modifier), "Out of memory on allocating clmd->clothObject->verts");
printf("cloth_free_modifier clmd->clothObject->verts\n");
return;
}
@@ -861,8 +861,8 @@ static void cloth_from_mesh(ClothModifierData *clmd, Mesh *mesh)
clmd->clothObject->tri = MEM_mallocN(sizeof(MVertTri) * looptri_num, "clothLoopTris");
if (clmd->clothObject->tri == NULL) {
cloth_free_modifier(clmd);
- BKE_modifier_set_error(&(clmd->modifier),
- "Out of memory on allocating clmd->clothObject->looptri");
+ BKE_modifier_set_error(
+ ob, &(clmd->modifier), "Out of memory on allocating clmd->clothObject->looptri");
printf("cloth_free_modifier clmd->clothObject->looptri\n");
return;
}
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index 0ed6f94ce79..7ab63810719 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -18,6 +18,9 @@
* \ingroup bke
*/
+/* Allow using deprecated functionality for .blend file I/O. */
+#define DNA_DEPRECATED_ALLOW
+
#include <string.h>
#include "BLI_blenlib.h"
@@ -55,6 +58,8 @@
#include "MEM_guardedalloc.h"
+#include "BLO_read_write.h"
+
/* -------------------------------------------------------------------- */
/** \name Prototypes
* \{ */
@@ -167,6 +172,173 @@ static void collection_foreach_id(ID *id, LibraryForeachIDData *data)
}
}
+void BKE_collection_blend_write_nolib(BlendWriter *writer, Collection *collection)
+{
+ BKE_id_blend_write(writer, &collection->id);
+
+ /* Shared function for collection data-blocks and scene master collection. */
+ BKE_previewimg_blend_write(writer, collection->preview);
+
+ LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) {
+ BLO_write_struct(writer, CollectionObject, cob);
+ }
+
+ LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
+ BLO_write_struct(writer, CollectionChild, child);
+ }
+}
+
+static void collection_blend_write(BlendWriter *writer, ID *id, const void *id_address)
+{
+ Collection *collection = (Collection *)id;
+ if (collection->id.us > 0 || BLO_write_is_undo(writer)) {
+ /* Clean up, important in undo case to reduce false detection of changed data-blocks. */
+ collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE;
+ collection->tag = 0;
+ BLI_listbase_clear(&collection->object_cache);
+ BLI_listbase_clear(&collection->parents);
+
+ /* write LibData */
+ BLO_write_id_struct(writer, Collection, id_address, &collection->id);
+
+ BKE_collection_blend_write_nolib(writer, collection);
+ }
+}
+
+#ifdef USE_COLLECTION_COMPAT_28
+void BKE_collection_compat_blend_read_data(BlendDataReader *reader, SceneCollection *sc)
+{
+ BLO_read_list(reader, &sc->objects);
+ BLO_read_list(reader, &sc->scene_collections);
+
+ LISTBASE_FOREACH (SceneCollection *, nsc, &sc->scene_collections) {
+ BKE_collection_compat_blend_read_data(reader, nsc);
+ }
+}
+#endif
+
+void BKE_collection_blend_read_data(BlendDataReader *reader, Collection *collection)
+{
+ BLO_read_list(reader, &collection->gobject);
+ BLO_read_list(reader, &collection->children);
+
+ BLO_read_data_address(reader, &collection->preview);
+ BKE_previewimg_blend_read(reader, collection->preview);
+
+ collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE;
+ collection->tag = 0;
+ BLI_listbase_clear(&collection->object_cache);
+ BLI_listbase_clear(&collection->parents);
+
+#ifdef USE_COLLECTION_COMPAT_28
+ /* This runs before the very first doversion. */
+ BLO_read_data_address(reader, &collection->collection);
+ if (collection->collection != NULL) {
+ BKE_collection_compat_blend_read_data(reader, collection->collection);
+ }
+
+ BLO_read_data_address(reader, &collection->view_layer);
+ if (collection->view_layer != NULL) {
+ BKE_view_layer_blend_read_data(reader, collection->view_layer);
+ }
+#endif
+}
+
+static void collection_blend_read_data(BlendDataReader *reader, ID *id)
+{
+ Collection *collection = (Collection *)id;
+ BKE_collection_blend_read_data(reader, collection);
+}
+
+static void lib_link_collection_data(BlendLibReader *reader, Library *lib, Collection *collection)
+{
+ LISTBASE_FOREACH_MUTABLE (CollectionObject *, cob, &collection->gobject) {
+ BLO_read_id_address(reader, lib, &cob->ob);
+
+ if (cob->ob == NULL) {
+ BLI_freelinkN(&collection->gobject, cob);
+ }
+ }
+
+ LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
+ BLO_read_id_address(reader, lib, &child->collection);
+ }
+}
+
+#ifdef USE_COLLECTION_COMPAT_28
+void BKE_collection_compat_blend_read_lib(BlendLibReader *reader,
+ Library *lib,
+ SceneCollection *sc)
+{
+ LISTBASE_FOREACH (LinkData *, link, &sc->objects) {
+ BLO_read_id_address(reader, lib, &link->data);
+ BLI_assert(link->data);
+ }
+
+ LISTBASE_FOREACH (SceneCollection *, nsc, &sc->scene_collections) {
+ BKE_collection_compat_blend_read_lib(reader, lib, nsc);
+ }
+}
+#endif
+
+void BKE_collection_blend_read_lib(BlendLibReader *reader, Collection *collection)
+{
+#ifdef USE_COLLECTION_COMPAT_28
+ if (collection->collection) {
+ BKE_collection_compat_blend_read_lib(reader, collection->id.lib, collection->collection);
+ }
+
+ if (collection->view_layer) {
+ BKE_view_layer_blend_read_lib(reader, collection->id.lib, collection->view_layer);
+ }
+#endif
+
+ lib_link_collection_data(reader, collection->id.lib, collection);
+}
+
+static void collection_blend_read_lib(BlendLibReader *reader, ID *id)
+{
+ Collection *collection = (Collection *)id;
+ BKE_collection_blend_read_lib(reader, collection);
+}
+
+#ifdef USE_COLLECTION_COMPAT_28
+void BKE_collection_compat_blend_read_expand(struct BlendExpander *expander,
+ struct SceneCollection *sc)
+{
+ LISTBASE_FOREACH (LinkData *, link, &sc->objects) {
+ BLO_expand(expander, link->data);
+ }
+
+ LISTBASE_FOREACH (SceneCollection *, nsc, &sc->scene_collections) {
+ BKE_collection_compat_blend_read_expand(expander, nsc);
+ }
+}
+#endif
+
+void BKE_collection_blend_read_expand(BlendExpander *expander, Collection *collection)
+{
+ LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) {
+ BLO_expand(expander, cob->ob);
+ }
+
+ LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
+ BLO_expand(expander, child->collection);
+ }
+
+#ifdef USE_COLLECTION_COMPAT_28
+ if (collection->collection != NULL) {
+ BKE_collection_compat_blend_read_expand(expander, collection->collection);
+ }
+#endif
+}
+
+static void collection_blend_read_expand(BlendExpander *expander, ID *id)
+{
+ Collection *collection = (Collection *)id;
+ BKE_collection_blend_read_expand(expander, collection);
+}
+
IDTypeInfo IDType_ID_GR = {
.id_code = ID_GR,
.id_filter = FILTER_ID_GR,
@@ -184,10 +356,12 @@ IDTypeInfo IDType_ID_GR = {
.foreach_id = collection_foreach_id,
.foreach_cache = NULL,
- .blend_write = NULL,
- .blend_read_data = NULL,
- .blend_read_lib = NULL,
- .blend_read_expand = NULL,
+ .blend_write = collection_blend_write,
+ .blend_read_data = collection_blend_read_data,
+ .blend_read_lib = collection_blend_read_lib,
+ .blend_read_expand = collection_blend_read_expand,
+
+ .blend_read_undo_preserve = NULL,
};
/** \} */
@@ -301,6 +475,7 @@ void BKE_collection_add_from_collection(Main *bmain,
/** Free (or release) any data used by this collection (does not free the collection itself). */
void BKE_collection_free(Collection *collection)
{
+ BKE_libblock_free_data(&collection->id, false);
collection_free_data(&collection->id);
}
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index 34e8e8bc6fb..3eb9fb6161d 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -1257,7 +1257,7 @@ void BKE_curvemapping_blend_read(BlendDataReader *reader, CurveMapping *cumap)
/* ***************** Histogram **************** */
-#define INV_255 (1.f / 255.f)
+#define INV_255 (1.0f / 255.0f)
BLI_INLINE int get_bin_float(float f)
{
@@ -1570,8 +1570,8 @@ void BKE_scopes_update(Scopes *scopes,
return;
}
- if (scopes->hist.ymax == 0.f) {
- scopes->hist.ymax = 1.f;
+ if (scopes->hist.ymax == 0.0f) {
+ scopes->hist.ymax = 1.0f;
}
/* hmmmm */
@@ -1819,6 +1819,24 @@ void BKE_color_managed_view_settings_free(ColorManagedViewSettings *settings)
}
}
+void BKE_color_managed_view_settings_blend_write(BlendWriter *writer,
+ ColorManagedViewSettings *settings)
+{
+ if (settings->curve_mapping) {
+ BKE_curvemapping_blend_write(writer, settings->curve_mapping);
+ }
+}
+
+void BKE_color_managed_view_settings_blend_read_data(BlendDataReader *reader,
+ ColorManagedViewSettings *settings)
+{
+ BLO_read_data_address(reader, &settings->curve_mapping);
+
+ if (settings->curve_mapping) {
+ BKE_curvemapping_blend_read(reader, settings->curve_mapping);
+ }
+}
+
void BKE_color_managed_colorspace_settings_init(
ColorManagedColorspaceSettings *colorspace_settings)
{
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 274546132fb..a1b53b721d3 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -21,6 +21,9 @@
* \ingroup bke
*/
+/* Allow using deprecated functionality for .blend file I/O. */
+#define DNA_DEPRECATED_ALLOW
+
#include <float.h>
#include <math.h>
#include <stddef.h>
@@ -45,6 +48,7 @@
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
+#include "DNA_screen_types.h"
#include "DNA_lattice_types.h"
#include "DNA_movieclip_types.h"
@@ -79,6 +83,8 @@
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
+#include "BLO_read_write.h"
+
#include "CLG_log.h"
#ifdef WITH_PYTHON
@@ -5406,6 +5412,11 @@ bool BKE_constraint_remove_ex(ListBase *list, Object *ob, bConstraint *con, bool
return false;
}
+void BKE_constraint_panel_expand(bConstraint *con)
+{
+ con->ui_expand_flag |= UI_PANEL_DATA_EXPAND_ROOT;
+}
+
/* ......... */
/* Creates a new constraint, initializes its data, and returns it */
@@ -5421,10 +5432,10 @@ static bConstraint *add_new_constraint_internal(const char *name, short type)
con->enforce = 1.0f;
/* Only open the main panel when constraints are created, not the sub-panels. */
- con->ui_expand_flag = (1 << 0);
+ con->ui_expand_flag = UI_PANEL_DATA_EXPAND_ROOT;
if (ELEM(type, CONSTRAINT_TYPE_ACTION, CONSTRAINT_TYPE_SPLINEIK)) {
/* Expand the two sub-panels in the cases where the main panel barely has any properties. */
- con->ui_expand_flag |= (1 << 1) | (1 << 2);
+ con->ui_expand_flag |= UI_SUBPANEL_DATA_EXPAND_1 | UI_SUBPANEL_DATA_EXPAND_2;
}
/* Determine a basic name, and info */
@@ -6080,3 +6091,174 @@ void BKE_constraints_solve(struct Depsgraph *depsgraph,
}
}
}
+
+void BKE_constraint_blend_write(BlendWriter *writer, ListBase *conlist)
+{
+ LISTBASE_FOREACH (bConstraint *, con, conlist) {
+ const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
+
+ /* Write the specific data */
+ if (cti && con->data) {
+ /* firstly, just write the plain con->data struct */
+ BLO_write_struct_by_name(writer, cti->structName, con->data);
+
+ /* do any constraint specific stuff */
+ switch (con->type) {
+ case CONSTRAINT_TYPE_PYTHON: {
+ bPythonConstraint *data = con->data;
+
+ /* write targets */
+ LISTBASE_FOREACH (bConstraintTarget *, ct, &data->targets) {
+ BLO_write_struct(writer, bConstraintTarget, ct);
+ }
+
+ /* Write ID Properties -- and copy this comment EXACTLY for easy finding
+ * of library blocks that implement this.*/
+ IDP_BlendWrite(writer, data->prop);
+
+ break;
+ }
+ case CONSTRAINT_TYPE_ARMATURE: {
+ bArmatureConstraint *data = con->data;
+
+ /* write targets */
+ LISTBASE_FOREACH (bConstraintTarget *, ct, &data->targets) {
+ BLO_write_struct(writer, bConstraintTarget, ct);
+ }
+
+ break;
+ }
+ case CONSTRAINT_TYPE_SPLINEIK: {
+ bSplineIKConstraint *data = con->data;
+
+ /* write points array */
+ BLO_write_float_array(writer, data->numpoints, data->points);
+
+ break;
+ }
+ }
+ }
+
+ /* Write the constraint */
+ BLO_write_struct(writer, bConstraint, con);
+ }
+}
+
+void BKE_constraint_blend_read_data(BlendDataReader *reader, ListBase *lb)
+{
+ BLO_read_list(reader, lb);
+ LISTBASE_FOREACH (bConstraint *, con, lb) {
+ BLO_read_data_address(reader, &con->data);
+
+ switch (con->type) {
+ case CONSTRAINT_TYPE_PYTHON: {
+ bPythonConstraint *data = con->data;
+
+ BLO_read_list(reader, &data->targets);
+
+ BLO_read_data_address(reader, &data->prop);
+ IDP_BlendDataRead(reader, &data->prop);
+ break;
+ }
+ case CONSTRAINT_TYPE_ARMATURE: {
+ bArmatureConstraint *data = con->data;
+
+ BLO_read_list(reader, &data->targets);
+
+ break;
+ }
+ case CONSTRAINT_TYPE_SPLINEIK: {
+ bSplineIKConstraint *data = con->data;
+
+ BLO_read_data_address(reader, &data->points);
+ break;
+ }
+ case CONSTRAINT_TYPE_KINEMATIC: {
+ bKinematicConstraint *data = con->data;
+
+ con->lin_error = 0.0f;
+ con->rot_error = 0.0f;
+
+ /* version patch for runtime flag, was not cleared in some case */
+ data->flag &= ~CONSTRAINT_IK_AUTO;
+ break;
+ }
+ case CONSTRAINT_TYPE_CHILDOF: {
+ /* XXX version patch, in older code this flag wasn't always set, and is inherent to type */
+ if (con->ownspace == CONSTRAINT_SPACE_POSE) {
+ con->flag |= CONSTRAINT_SPACEONCE;
+ }
+ break;
+ }
+ case CONSTRAINT_TYPE_TRANSFORM_CACHE: {
+ bTransformCacheConstraint *data = con->data;
+ data->reader = NULL;
+ data->reader_object_path[0] = '\0';
+ }
+ }
+ }
+}
+
+/* temp struct used to transport needed info to lib_link_constraint_cb() */
+typedef struct tConstraintLinkData {
+ BlendLibReader *reader;
+ ID *id;
+} tConstraintLinkData;
+/* callback function used to relink constraint ID-links */
+static void lib_link_constraint_cb(bConstraint *UNUSED(con),
+ ID **idpoin,
+ bool UNUSED(is_reference),
+ void *userdata)
+{
+ tConstraintLinkData *cld = (tConstraintLinkData *)userdata;
+ BLO_read_id_address(cld->reader, cld->id->lib, idpoin);
+}
+
+void BKE_constraint_blend_read_lib(BlendLibReader *reader, ID *id, ListBase *conlist)
+{
+ tConstraintLinkData cld;
+
+ /* legacy fixes */
+ LISTBASE_FOREACH (bConstraint *, con, conlist) {
+ /* patch for error introduced by changing constraints (dunno how) */
+ /* if con->data type changes, dna cannot resolve the pointer! (ton) */
+ if (con->data == NULL) {
+ con->type = CONSTRAINT_TYPE_NULL;
+ }
+ /* own ipo, all constraints have it */
+ BLO_read_id_address(reader, id->lib, &con->ipo); /* XXX deprecated - old animation system */
+
+ /* If linking from a library, clear 'local' library override flag. */
+ if (id->lib != NULL) {
+ con->flag &= ~CONSTRAINT_OVERRIDE_LIBRARY_LOCAL;
+ }
+ }
+
+ /* relink all ID-blocks used by the constraints */
+ cld.reader = reader;
+ cld.id = id;
+
+ BKE_constraints_id_loop(conlist, lib_link_constraint_cb, &cld);
+}
+
+/* callback function used to expand constraint ID-links */
+static void expand_constraint_cb(bConstraint *UNUSED(con),
+ ID **idpoin,
+ bool UNUSED(is_reference),
+ void *userdata)
+{
+ BlendExpander *expander = userdata;
+ BLO_expand(expander, *idpoin);
+}
+
+void BKE_constraint_blend_read_expand(BlendExpander *expander, ListBase *lb)
+{
+ BKE_constraints_id_loop(lb, expand_constraint_cb, expander);
+
+ /* deprecated manual expansion stuff */
+ LISTBASE_FOREACH (bConstraint *, curcon, lb) {
+ if (curcon->ipo) {
+ BLO_expand(expander, curcon->ipo); /* XXX deprecated - old animation system */
+ }
+ }
+}
diff --git a/source/blender/blenkernel/intern/crazyspace.c b/source/blender/blenkernel/intern/crazyspace.c
index 01c05c62b70..4e1ec9ba35e 100644
--- a/source/blender/blenkernel/intern/crazyspace.c
+++ b/source/blender/blenkernel/intern/crazyspace.c
@@ -273,7 +273,7 @@ int BKE_crazyspace_get_first_deform_matrices_editbmesh(struct Depsgraph *depsgra
for (i = 0; md && i <= cageIndex; i++, md = md->next) {
const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
- if (!editbmesh_modifier_is_enabled(scene, md, me != NULL)) {
+ if (!editbmesh_modifier_is_enabled(scene, ob, md, me != NULL)) {
continue;
}
@@ -302,7 +302,7 @@ int BKE_crazyspace_get_first_deform_matrices_editbmesh(struct Depsgraph *depsgra
}
for (; md && i <= cageIndex; md = md->next, i++) {
- if (editbmesh_modifier_is_enabled(scene, md, me != NULL) &&
+ if (editbmesh_modifier_is_enabled(scene, ob, md, me != NULL) &&
BKE_modifier_is_correctable_deformed(md)) {
numleft++;
}
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index b2ebb56d828..091d542c43d 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -325,6 +325,8 @@ IDTypeInfo IDType_ID_CU = {
.blend_read_data = curve_blend_read_data,
.blend_read_lib = curve_blend_read_lib,
.blend_read_expand = curve_blend_read_expand,
+
+ .blend_read_undo_preserve = NULL,
};
static int cu_isectLL(const float v1[3],
@@ -438,7 +440,6 @@ ListBase *BKE_curve_editNurbs_get(Curve *cu)
short BKE_curve_type_get(const Curve *cu)
{
- Nurb *nu;
int type = cu->type;
if (cu->vfont) {
@@ -448,7 +449,7 @@ short BKE_curve_type_get(const Curve *cu)
if (!cu->type) {
type = OB_CURVE;
- for (nu = cu->nurb.first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) {
if (nu->pntsv > 1) {
type = OB_SURF;
}
@@ -461,15 +462,14 @@ short BKE_curve_type_get(const Curve *cu)
void BKE_curve_curve_dimension_update(Curve *cu)
{
ListBase *nurbs = BKE_curve_nurbs_get(cu);
- Nurb *nu = nurbs->first;
if (cu->flag & CU_3D) {
- for (; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, nurbs) {
nu->flag &= ~CU_2D;
}
}
else {
- for (; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, nurbs) {
nu->flag |= CU_2D;
BKE_nurb_test_2d(nu);
@@ -569,10 +569,9 @@ void BKE_curve_texspace_get(Curve *cu, float r_loc[3], float r_size[3])
bool BKE_nurbList_index_get_co(ListBase *nurb, const int index, float r_co[3])
{
- Nurb *nu;
int tot = 0;
- for (nu = nurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, nurb) {
int tot_nu;
if (nu->type == CU_BEZIER) {
tot_nu = nu->pntsu;
@@ -596,39 +595,33 @@ bool BKE_nurbList_index_get_co(ListBase *nurb, const int index, float r_co[3])
int BKE_nurbList_verts_count(ListBase *nurb)
{
- Nurb *nu;
int tot = 0;
- nu = nurb->first;
- while (nu) {
+ LISTBASE_FOREACH (Nurb *, nu, nurb) {
if (nu->bezt) {
tot += 3 * nu->pntsu;
}
else if (nu->bp) {
tot += nu->pntsu * nu->pntsv;
}
-
- nu = nu->next;
}
+
return tot;
}
int BKE_nurbList_verts_count_without_handles(ListBase *nurb)
{
- Nurb *nu;
int tot = 0;
- nu = nurb->first;
- while (nu) {
+ LISTBASE_FOREACH (Nurb *, nu, nurb) {
if (nu->bezt) {
tot += nu->pntsu;
}
else if (nu->bp) {
tot += nu->pntsu * nu->pntsv;
}
-
- nu = nu->next;
}
+
return tot;
}
@@ -636,7 +629,6 @@ int BKE_nurbList_verts_count_without_handles(ListBase *nurb)
void BKE_nurb_free(Nurb *nu)
{
-
if (nu == NULL) {
return;
}
@@ -664,17 +656,12 @@ void BKE_nurb_free(Nurb *nu)
void BKE_nurbList_free(ListBase *lb)
{
- Nurb *nu, *next;
-
if (lb == NULL) {
return;
}
- nu = lb->first;
- while (nu) {
- next = nu->next;
+ LISTBASE_FOREACH_MUTABLE (Nurb *, nu, lb) {
BKE_nurb_free(nu);
- nu = next;
}
BLI_listbase_clear(lb);
}
@@ -747,16 +734,11 @@ Nurb *BKE_nurb_copy(Nurb *src, int pntsu, int pntsv)
void BKE_nurbList_duplicate(ListBase *lb1, const ListBase *lb2)
{
- Nurb *nu, *nun;
-
BKE_nurbList_free(lb1);
- nu = lb2->first;
- while (nu) {
- nun = BKE_nurb_duplicate(nu);
- BLI_addtail(lb1, nun);
-
- nu = nu->next;
+ LISTBASE_FOREACH (const Nurb *, nu, lb2) {
+ Nurb *nurb_new = BKE_nurb_duplicate(nu);
+ BLI_addtail(lb1, nurb_new);
}
}
@@ -2202,6 +2184,22 @@ static void bevel_list_calc_bisect(BevList *bl)
bevp1 = bevp2;
bevp2++;
}
+
+ if (is_cyclic == false) {
+ bevp0 = &bl->bevpoints[0];
+ bevp1 = &bl->bevpoints[1];
+ sub_v3_v3v3(bevp0->dir, bevp1->vec, bevp0->vec);
+ if (normalize_v3(bevp0->dir) == 0.0f) {
+ copy_v3_v3(bevp0->dir, bevp1->dir);
+ }
+
+ bevp0 = &bl->bevpoints[bl->nr - 2];
+ bevp1 = &bl->bevpoints[bl->nr - 1];
+ sub_v3_v3v3(bevp1->dir, bevp1->vec, bevp0->vec);
+ if (normalize_v3(bevp1->dir) == 0.0f) {
+ copy_v3_v3(bevp1->dir, bevp0->dir);
+ }
+ }
}
static void bevel_list_flip_tangents(BevList *bl)
{
@@ -2625,9 +2623,7 @@ static void bevlist_firstlast_direction_calc_from_bpoint(Nurb *nu, BevList *bl)
void BKE_curve_bevelList_free(ListBase *bev)
{
- BevList *bl, *blnext;
- for (bl = bev->first; bl != NULL; bl = blnext) {
- blnext = bl->next;
+ LISTBASE_FOREACH_MUTABLE (BevList *, bl, bev) {
if (bl->seglen != NULL) {
MEM_freeN(bl->seglen);
}
@@ -2654,12 +2650,11 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
/* this function needs an object, because of tflag and upflag */
Curve *cu = ob->data;
- Nurb *nu;
BezTriple *bezt, *prevbezt;
BPoint *bp;
- BevList *bl, *blnew, *blnext;
+ BevList *blnew;
BevPoint *bevp2, *bevp1 = NULL, *bevp0;
- const float treshold = 0.00001f;
+ const float threshold = 0.00001f;
float min, inp;
float *seglen = NULL;
struct BevelSort *sortdata, *sd, *sd1;
@@ -2685,16 +2680,26 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
/* STEP 1: MAKE POLYS */
BKE_curve_bevelList_free(&ob->runtime.curve_cache->bev);
- nu = nurbs->first;
if (cu->editnurb && ob->type != OB_FONT) {
is_editmode = 1;
}
- for (; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, nurbs) {
if (nu->hide && is_editmode) {
continue;
}
+ /* check we are a single point? also check we are not a surface and that the orderu is sane,
+ * enforced in the UI but can go wrong possibly */
+ if (!BKE_nurb_check_valid_u(nu)) {
+ BevList *bl = MEM_callocN(sizeof(BevList), "makeBevelList1");
+ bl->bevpoints = MEM_calloc_arrayN(1, sizeof(BevPoint), "makeBevelPoints1");
+ BLI_addtail(bev, bl);
+ bl->nr = 0;
+ bl->charidx = nu->charidx;
+ continue;
+ }
+
/* check if we will calculate tilt data */
do_tilt = CU_DO_TILT(cu, nu);
@@ -2703,89 +2708,231 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
do_weight = true;
- /* check we are a single point? also check we are not a surface and that the orderu is sane,
- * enforced in the UI but can go wrong possibly */
- if (!BKE_nurb_check_valid_u(nu)) {
- bl = MEM_callocN(sizeof(BevList), "makeBevelList1");
- bl->bevpoints = MEM_calloc_arrayN(1, sizeof(BevPoint), "makeBevelPoints1");
+ BevPoint *bevp;
+
+ if (for_render && cu->resolu_ren != 0) {
+ resolu = cu->resolu_ren;
+ }
+ else {
+ resolu = nu->resolu;
+ }
+
+ segcount = SEGMENTSU(nu);
+
+ if (nu->type == CU_POLY) {
+ len = nu->pntsu;
+ BevList *bl = MEM_callocN(sizeof(BevList), "makeBevelList2");
+ bl->bevpoints = MEM_calloc_arrayN(len, sizeof(BevPoint), "makeBevelPoints2");
+ if (need_seglen && (nu->flagu & CU_NURB_CYCLIC) == 0) {
+ bl->seglen = MEM_malloc_arrayN(segcount, sizeof(float), "makeBevelList2_seglen");
+ bl->segbevcount = MEM_malloc_arrayN(segcount, sizeof(int), "makeBevelList2_segbevcount");
+ }
BLI_addtail(bev, bl);
- bl->nr = 0;
+
+ bl->poly = (nu->flagu & CU_NURB_CYCLIC) ? 0 : -1;
+ bl->nr = len;
+ bl->dupe_nr = 0;
bl->charidx = nu->charidx;
+ bevp = bl->bevpoints;
+ bevp->offset = 0;
+ bp = nu->bp;
+ seglen = bl->seglen;
+ segbevcount = bl->segbevcount;
+
+ while (len--) {
+ copy_v3_v3(bevp->vec, bp->vec);
+ bevp->tilt = bp->tilt;
+ bevp->radius = bp->radius;
+ bevp->weight = bp->weight;
+ bevp->split_tag = true;
+ bp++;
+ if (seglen != NULL && len != 0) {
+ *seglen = len_v3v3(bevp->vec, bp->vec);
+ bevp++;
+ bevp->offset = *seglen;
+ if (*seglen > threshold) {
+ *segbevcount = 1;
+ }
+ else {
+ *segbevcount = 0;
+ }
+ seglen++;
+ segbevcount++;
+ }
+ else {
+ bevp++;
+ }
+ }
+
+ if ((nu->flagu & CU_NURB_CYCLIC) == 0) {
+ bevlist_firstlast_direction_calc_from_bpoint(nu, bl);
+ }
}
- else {
- BevPoint *bevp;
+ else if (nu->type == CU_BEZIER) {
+ /* in case last point is not cyclic */
+ len = segcount * resolu + 1;
- if (for_render && cu->resolu_ren != 0) {
- resolu = cu->resolu_ren;
+ BevList *bl = MEM_callocN(sizeof(BevList), "makeBevelBPoints");
+ bl->bevpoints = MEM_calloc_arrayN(len, sizeof(BevPoint), "makeBevelBPointsPoints");
+ if (need_seglen && (nu->flagu & CU_NURB_CYCLIC) == 0) {
+ bl->seglen = MEM_malloc_arrayN(segcount, sizeof(float), "makeBevelBPoints_seglen");
+ bl->segbevcount = MEM_malloc_arrayN(segcount, sizeof(int), "makeBevelBPoints_segbevcount");
+ }
+ BLI_addtail(bev, bl);
+
+ bl->poly = (nu->flagu & CU_NURB_CYCLIC) ? 0 : -1;
+ bl->charidx = nu->charidx;
+
+ bevp = bl->bevpoints;
+ seglen = bl->seglen;
+ segbevcount = bl->segbevcount;
+
+ bevp->offset = 0;
+ if (seglen != NULL) {
+ *seglen = 0;
+ *segbevcount = 0;
+ }
+
+ a = nu->pntsu - 1;
+ bezt = nu->bezt;
+ if (nu->flagu & CU_NURB_CYCLIC) {
+ a++;
+ prevbezt = nu->bezt + (nu->pntsu - 1);
}
else {
- resolu = nu->resolu;
+ prevbezt = bezt;
+ bezt++;
}
- segcount = SEGMENTSU(nu);
+ sub_v3_v3v3(bevp->dir, prevbezt->vec[2], prevbezt->vec[1]);
+ normalize_v3(bevp->dir);
- if (nu->type == CU_POLY) {
- len = nu->pntsu;
- bl = MEM_callocN(sizeof(BevList), "makeBevelList2");
- bl->bevpoints = MEM_calloc_arrayN(len, sizeof(BevPoint), "makeBevelPoints2");
- if (need_seglen && (nu->flagu & CU_NURB_CYCLIC) == 0) {
- bl->seglen = MEM_malloc_arrayN(segcount, sizeof(float), "makeBevelList2_seglen");
- bl->segbevcount = MEM_malloc_arrayN(segcount, sizeof(int), "makeBevelList2_segbevcount");
- }
- BLI_addtail(bev, bl);
+ BLI_assert(segcount >= a);
- bl->poly = (nu->flagu & CU_NURB_CYCLIC) ? 0 : -1;
- bl->nr = len;
- bl->dupe_nr = 0;
- bl->charidx = nu->charidx;
- bevp = bl->bevpoints;
- bevp->offset = 0;
- bp = nu->bp;
- seglen = bl->seglen;
- segbevcount = bl->segbevcount;
+ while (a--) {
+ if (prevbezt->h2 == HD_VECT && bezt->h1 == HD_VECT) {
- while (len--) {
- copy_v3_v3(bevp->vec, bp->vec);
- bevp->tilt = bp->tilt;
- bevp->radius = bp->radius;
- bevp->weight = bp->weight;
+ copy_v3_v3(bevp->vec, prevbezt->vec[1]);
+ bevp->tilt = prevbezt->tilt;
+ bevp->radius = prevbezt->radius;
+ bevp->weight = prevbezt->weight;
bevp->split_tag = true;
- bp++;
- if (seglen != NULL && len != 0) {
- *seglen = len_v3v3(bevp->vec, bp->vec);
- bevp++;
+ bevp->dupe_tag = false;
+ bevp++;
+ bl->nr++;
+ bl->dupe_nr = 1;
+ if (seglen != NULL) {
+ *seglen = len_v3v3(prevbezt->vec[1], bezt->vec[1]);
bevp->offset = *seglen;
- if (*seglen > treshold) {
+ seglen++;
+ /* match segbevcount to the cleaned up bevel lists (see STEP 2) */
+ if (bevp->offset > threshold) {
*segbevcount = 1;
}
- else {
- *segbevcount = 0;
+ segbevcount++;
+ }
+ }
+ else {
+ /* always do all three, to prevent data hanging around */
+ int j;
+
+ /* BevPoint must stay aligned to 4 so sizeof(BevPoint)/sizeof(float) works */
+ for (j = 0; j < 3; j++) {
+ BKE_curve_forward_diff_bezier(prevbezt->vec[1][j],
+ prevbezt->vec[2][j],
+ bezt->vec[0][j],
+ bezt->vec[1][j],
+ &(bevp->vec[j]),
+ resolu,
+ sizeof(BevPoint));
+ }
+
+ /* if both arrays are NULL do nothiong */
+ tilt_bezpart(prevbezt,
+ bezt,
+ nu,
+ do_tilt ? &bevp->tilt : NULL,
+ do_radius ? &bevp->radius : NULL,
+ do_weight ? &bevp->weight : NULL,
+ resolu,
+ sizeof(BevPoint));
+
+ if (cu->twist_mode == CU_TWIST_TANGENT) {
+ forward_diff_bezier_cotangent(prevbezt->vec[1],
+ prevbezt->vec[2],
+ bezt->vec[0],
+ bezt->vec[1],
+ bevp->tan,
+ resolu,
+ sizeof(BevPoint));
+ }
+
+ /* indicate with handlecodes double points */
+ if (prevbezt->h1 == prevbezt->h2) {
+ if (ELEM(prevbezt->h1, 0, HD_VECT)) {
+ bevp->split_tag = true;
+ }
+ }
+ else {
+ if (ELEM(prevbezt->h1, 0, HD_VECT)) {
+ bevp->split_tag = true;
+ }
+ else if (ELEM(prevbezt->h2, 0, HD_VECT)) {
+ bevp->split_tag = true;
+ }
+ }
+
+ /* seglen */
+ if (seglen != NULL) {
+ *seglen = 0;
+ *segbevcount = 0;
+ for (j = 0; j < resolu; j++) {
+ bevp0 = bevp;
+ bevp++;
+ bevp->offset = len_v3v3(bevp0->vec, bevp->vec);
+ /* match seglen and segbevcount to the cleaned up bevel lists (see STEP 2) */
+ if (bevp->offset > threshold) {
+ *seglen += bevp->offset;
+ *segbevcount += 1;
+ }
}
seglen++;
segbevcount++;
}
else {
- bevp++;
+ bevp += resolu;
}
+ bl->nr += resolu;
}
+ prevbezt = bezt;
+ bezt++;
+ }
- if ((nu->flagu & CU_NURB_CYCLIC) == 0) {
- bevlist_firstlast_direction_calc_from_bpoint(nu, bl);
- }
+ if ((nu->flagu & CU_NURB_CYCLIC) == 0) { /* not cyclic: endpoint */
+ copy_v3_v3(bevp->vec, prevbezt->vec[1]);
+ bevp->tilt = prevbezt->tilt;
+ bevp->radius = prevbezt->radius;
+ bevp->weight = prevbezt->weight;
+
+ sub_v3_v3v3(bevp->dir, prevbezt->vec[1], prevbezt->vec[0]);
+ normalize_v3(bevp->dir);
+
+ bl->nr++;
}
- else if (nu->type == CU_BEZIER) {
- /* in case last point is not cyclic */
- len = segcount * resolu + 1;
+ }
+ else if (nu->type == CU_NURBS) {
+ if (nu->pntsv == 1) {
+ len = (resolu * segcount);
- bl = MEM_callocN(sizeof(BevList), "makeBevelBPoints");
- bl->bevpoints = MEM_calloc_arrayN(len, sizeof(BevPoint), "makeBevelBPointsPoints");
+ BevList *bl = MEM_callocN(sizeof(BevList), "makeBevelList3");
+ bl->bevpoints = MEM_calloc_arrayN(len, sizeof(BevPoint), "makeBevelPoints3");
if (need_seglen && (nu->flagu & CU_NURB_CYCLIC) == 0) {
- bl->seglen = MEM_malloc_arrayN(segcount, sizeof(float), "makeBevelBPoints_seglen");
- bl->segbevcount = MEM_malloc_arrayN(
- segcount, sizeof(int), "makeBevelBPoints_segbevcount");
+ bl->seglen = MEM_malloc_arrayN(segcount, sizeof(float), "makeBevelList3_seglen");
+ bl->segbevcount = MEM_malloc_arrayN(segcount, sizeof(int), "makeBevelList3_segbevcount");
}
BLI_addtail(bev, bl);
-
+ bl->nr = len;
+ bl->dupe_nr = 0;
bl->poly = (nu->flagu & CU_NURB_CYCLIC) ? 0 : -1;
bl->charidx = nu->charidx;
@@ -2793,292 +2940,134 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
seglen = bl->seglen;
segbevcount = bl->segbevcount;
- bevp->offset = 0;
- if (seglen != NULL) {
- *seglen = 0;
- *segbevcount = 0;
- }
-
- a = nu->pntsu - 1;
- bezt = nu->bezt;
- if (nu->flagu & CU_NURB_CYCLIC) {
- a++;
- prevbezt = nu->bezt + (nu->pntsu - 1);
- }
- else {
- prevbezt = bezt;
- bezt++;
- }
-
- sub_v3_v3v3(bevp->dir, prevbezt->vec[2], prevbezt->vec[1]);
- normalize_v3(bevp->dir);
-
- BLI_assert(segcount >= a);
+ BKE_nurb_makeCurve(nu,
+ &bevp->vec[0],
+ do_tilt ? &bevp->tilt : NULL,
+ do_radius ? &bevp->radius : NULL,
+ do_weight ? &bevp->weight : NULL,
+ resolu,
+ sizeof(BevPoint));
- while (a--) {
- if (prevbezt->h2 == HD_VECT && bezt->h1 == HD_VECT) {
-
- copy_v3_v3(bevp->vec, prevbezt->vec[1]);
- bevp->tilt = prevbezt->tilt;
- bevp->radius = prevbezt->radius;
- bevp->weight = prevbezt->weight;
- bevp->split_tag = true;
- bevp->dupe_tag = false;
- bevp++;
- bl->nr++;
- bl->dupe_nr = 1;
- if (seglen != NULL) {
- *seglen = len_v3v3(prevbezt->vec[1], bezt->vec[1]);
- bevp->offset = *seglen;
- seglen++;
- /* match segbevcount to the cleaned up bevel lists (see STEP 2) */
- if (bevp->offset > treshold) {
- *segbevcount = 1;
- }
- segbevcount++;
- }
- }
- else {
- /* always do all three, to prevent data hanging around */
+ /* match seglen and segbevcount to the cleaned up bevel lists (see STEP 2) */
+ if (seglen != NULL) {
+ nr = segcount;
+ bevp0 = bevp;
+ bevp++;
+ while (nr) {
int j;
-
- /* BevPoint must stay aligned to 4 so sizeof(BevPoint)/sizeof(float) works */
- for (j = 0; j < 3; j++) {
- BKE_curve_forward_diff_bezier(prevbezt->vec[1][j],
- prevbezt->vec[2][j],
- bezt->vec[0][j],
- bezt->vec[1][j],
- &(bevp->vec[j]),
- resolu,
- sizeof(BevPoint));
- }
-
- /* if both arrays are NULL do nothiong */
- tilt_bezpart(prevbezt,
- bezt,
- nu,
- do_tilt ? &bevp->tilt : NULL,
- do_radius ? &bevp->radius : NULL,
- do_weight ? &bevp->weight : NULL,
- resolu,
- sizeof(BevPoint));
-
- if (cu->twist_mode == CU_TWIST_TANGENT) {
- forward_diff_bezier_cotangent(prevbezt->vec[1],
- prevbezt->vec[2],
- bezt->vec[0],
- bezt->vec[1],
- bevp->tan,
- resolu,
- sizeof(BevPoint));
- }
-
- /* indicate with handlecodes double points */
- if (prevbezt->h1 == prevbezt->h2) {
- if (prevbezt->h1 == 0 || prevbezt->h1 == HD_VECT) {
- bevp->split_tag = true;
- }
- }
- else {
- if (prevbezt->h1 == 0 || prevbezt->h1 == HD_VECT) {
- bevp->split_tag = true;
- }
- else if (prevbezt->h2 == 0 || prevbezt->h2 == HD_VECT) {
- bevp->split_tag = true;
- }
- }
-
- /* seglen */
- if (seglen != NULL) {
- *seglen = 0;
- *segbevcount = 0;
- for (j = 0; j < resolu; j++) {
- bevp0 = bevp;
- bevp++;
- bevp->offset = len_v3v3(bevp0->vec, bevp->vec);
- /* match seglen and segbevcount to the cleaned up bevel lists (see STEP 2) */
- if (bevp->offset > treshold) {
- *seglen += bevp->offset;
- *segbevcount += 1;
- }
+ *seglen = 0;
+ *segbevcount = 0;
+ /* We keep last bevel segment zero-length. */
+ for (j = 0; j < ((nr == 1) ? (resolu - 1) : resolu); j++) {
+ bevp->offset = len_v3v3(bevp0->vec, bevp->vec);
+ if (bevp->offset > threshold) {
+ *seglen += bevp->offset;
+ *segbevcount += 1;
}
- seglen++;
- segbevcount++;
- }
- else {
- bevp += resolu;
+ bevp0 = bevp;
+ bevp++;
}
- bl->nr += resolu;
+ seglen++;
+ segbevcount++;
+ nr--;
}
- prevbezt = bezt;
- bezt++;
}
- if ((nu->flagu & CU_NURB_CYCLIC) == 0) { /* not cyclic: endpoint */
- copy_v3_v3(bevp->vec, prevbezt->vec[1]);
- bevp->tilt = prevbezt->tilt;
- bevp->radius = prevbezt->radius;
- bevp->weight = prevbezt->weight;
-
- sub_v3_v3v3(bevp->dir, prevbezt->vec[1], prevbezt->vec[0]);
- normalize_v3(bevp->dir);
-
- bl->nr++;
- }
- }
- else if (nu->type == CU_NURBS) {
- if (nu->pntsv == 1) {
- len = (resolu * segcount);
-
- bl = MEM_callocN(sizeof(BevList), "makeBevelList3");
- bl->bevpoints = MEM_calloc_arrayN(len, sizeof(BevPoint), "makeBevelPoints3");
- if (need_seglen && (nu->flagu & CU_NURB_CYCLIC) == 0) {
- bl->seglen = MEM_malloc_arrayN(segcount, sizeof(float), "makeBevelList3_seglen");
- bl->segbevcount = MEM_malloc_arrayN(
- segcount, sizeof(int), "makeBevelList3_segbevcount");
- }
- BLI_addtail(bev, bl);
- bl->nr = len;
- bl->dupe_nr = 0;
- bl->poly = (nu->flagu & CU_NURB_CYCLIC) ? 0 : -1;
- bl->charidx = nu->charidx;
-
- bevp = bl->bevpoints;
- seglen = bl->seglen;
- segbevcount = bl->segbevcount;
-
- BKE_nurb_makeCurve(nu,
- &bevp->vec[0],
- do_tilt ? &bevp->tilt : NULL,
- do_radius ? &bevp->radius : NULL,
- do_weight ? &bevp->weight : NULL,
- resolu,
- sizeof(BevPoint));
-
- /* match seglen and segbevcount to the cleaned up bevel lists (see STEP 2) */
- if (seglen != NULL) {
- nr = segcount;
- bevp0 = bevp;
- bevp++;
- while (nr) {
- int j;
- *seglen = 0;
- *segbevcount = 0;
- /* We keep last bevel segment zero-length. */
- for (j = 0; j < ((nr == 1) ? (resolu - 1) : resolu); j++) {
- bevp->offset = len_v3v3(bevp0->vec, bevp->vec);
- if (bevp->offset > treshold) {
- *seglen += bevp->offset;
- *segbevcount += 1;
- }
- bevp0 = bevp;
- bevp++;
- }
- seglen++;
- segbevcount++;
- nr--;
- }
- }
-
- if ((nu->flagu & CU_NURB_CYCLIC) == 0) {
- bevlist_firstlast_direction_calc_from_bpoint(nu, bl);
- }
+ if ((nu->flagu & CU_NURB_CYCLIC) == 0) {
+ bevlist_firstlast_direction_calc_from_bpoint(nu, bl);
}
}
}
}
/* STEP 2: DOUBLE POINTS AND AUTOMATIC RESOLUTION, REDUCE DATABLOCKS */
- bl = bev->first;
- while (bl) {
- if (bl->nr) { /* null bevel items come from single points */
- /* Scale the threshold so high resolution shapes don't get over reduced, see: T49850. */
- const float threshold_resolu = 0.00001f / resolu;
- bool is_cyclic = bl->poly != -1;
- nr = bl->nr;
- if (is_cyclic) {
- bevp1 = bl->bevpoints;
- bevp0 = bevp1 + (nr - 1);
+ LISTBASE_FOREACH (BevList *, bl, bev) {
+ if (bl->nr == 0) { /* null bevel items come from single points */
+ continue;
+ }
+
+ /* Scale the threshold so high resolution shapes don't get over reduced, see: T49850. */
+ const float threshold_resolu = 0.00001f / resolu;
+ bool is_cyclic = bl->poly != -1;
+ nr = bl->nr;
+ if (is_cyclic) {
+ bevp1 = bl->bevpoints;
+ bevp0 = bevp1 + (nr - 1);
+ }
+ else {
+ bevp0 = bl->bevpoints;
+ bevp0->offset = 0;
+ bevp1 = bevp0 + 1;
+ }
+ nr--;
+ while (nr--) {
+ if (seglen != NULL) {
+ if (fabsf(bevp1->offset) < threshold) {
+ bevp0->dupe_tag = true;
+ bl->dupe_nr++;
+ }
}
else {
- bevp0 = bl->bevpoints;
- bevp0->offset = 0;
- bevp1 = bevp0 + 1;
- }
- nr--;
- while (nr--) {
- if (seglen != NULL) {
- if (fabsf(bevp1->offset) < treshold) {
- bevp0->dupe_tag = true;
- bl->dupe_nr++;
- }
- }
- else {
- if (compare_v3v3(bevp0->vec, bevp1->vec, threshold_resolu)) {
- bevp0->dupe_tag = true;
- bl->dupe_nr++;
- }
+ if (compare_v3v3(bevp0->vec, bevp1->vec, threshold_resolu)) {
+ bevp0->dupe_tag = true;
+ bl->dupe_nr++;
}
- bevp0 = bevp1;
- bevp1++;
}
+ bevp0 = bevp1;
+ bevp1++;
}
- bl = bl->next;
}
- bl = bev->first;
- while (bl) {
- blnext = bl->next;
- if (bl->nr && bl->dupe_nr) {
- nr = bl->nr - bl->dupe_nr + 1; /* +1 because vectorbezier sets flag too */
- blnew = MEM_mallocN(sizeof(BevList), "makeBevelList4");
- memcpy(blnew, bl, sizeof(BevList));
- blnew->bevpoints = MEM_calloc_arrayN(nr, sizeof(BevPoint), "makeBevelPoints4");
- if (!blnew->bevpoints) {
- MEM_freeN(blnew);
- break;
- }
- blnew->segbevcount = bl->segbevcount;
- blnew->seglen = bl->seglen;
- blnew->nr = 0;
- BLI_remlink(bev, bl);
- BLI_insertlinkbefore(bev, blnext, blnew); /* to make sure bevlijst is tuned with nurblist */
- bevp0 = bl->bevpoints;
- bevp1 = blnew->bevpoints;
- nr = bl->nr;
- while (nr--) {
- if (bevp0->dupe_tag == 0) {
- memcpy(bevp1, bevp0, sizeof(BevPoint));
- bevp1++;
- blnew->nr++;
- }
- bevp0++;
- }
- if (bl->bevpoints != NULL) {
- MEM_freeN(bl->bevpoints);
+
+ LISTBASE_FOREACH_MUTABLE (BevList *, bl, bev) {
+ if (bl->nr == 0 || bl->dupe_nr == 0) {
+ continue;
+ }
+
+ nr = bl->nr - bl->dupe_nr + 1; /* +1 because vectorbezier sets flag too */
+ blnew = MEM_mallocN(sizeof(BevList), "makeBevelList4");
+ memcpy(blnew, bl, sizeof(BevList));
+ blnew->bevpoints = MEM_calloc_arrayN(nr, sizeof(BevPoint), "makeBevelPoints4");
+ if (!blnew->bevpoints) {
+ MEM_freeN(blnew);
+ break;
+ }
+ blnew->segbevcount = bl->segbevcount;
+ blnew->seglen = bl->seglen;
+ blnew->nr = 0;
+ BLI_remlink(bev, bl);
+ BLI_insertlinkbefore(bev, bl->next, blnew); /* to make sure bevlist is tuned with nurblist */
+ bevp0 = bl->bevpoints;
+ bevp1 = blnew->bevpoints;
+ nr = bl->nr;
+ while (nr--) {
+ if (bevp0->dupe_tag == 0) {
+ memcpy(bevp1, bevp0, sizeof(BevPoint));
+ bevp1++;
+ blnew->nr++;
}
- MEM_freeN(bl);
- blnew->dupe_nr = 0;
+ bevp0++;
+ }
+ if (bl->bevpoints != NULL) {
+ MEM_freeN(bl->bevpoints);
}
- bl = blnext;
+ MEM_freeN(bl);
+ blnew->dupe_nr = 0;
}
/* STEP 3: POLYS COUNT AND AUTOHOLE */
- bl = bev->first;
poly = 0;
- while (bl) {
+ LISTBASE_FOREACH (BevList *, bl, bev) {
if (bl->nr && bl->poly >= 0) {
poly++;
bl->poly = poly;
bl->hole = 0;
}
- bl = bl->next;
}
/* find extreme left points, also test (turning) direction */
if (poly > 0) {
sd = sortdata = MEM_malloc_arrayN(poly, sizeof(struct BevelSort), "makeBevelList5");
- bl = bev->first;
- while (bl) {
+ LISTBASE_FOREACH (BevList *, bl, bev) {
if (bl->poly > 0) {
BevPoint *bevp;
@@ -3123,14 +3112,12 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
sd++;
}
-
- bl = bl->next;
}
qsort(sortdata, poly, sizeof(struct BevelSort), vergxcobev);
sd = sortdata + 1;
for (a = 1; a < poly; a++, sd++) {
- bl = sd->bl; /* is bl a hole? */
+ BevList *bl = sd->bl; /* is bl a hole? */
sd1 = sortdata + (a - 1);
for (b = a - 1; b >= 0; b--, sd1--) { /* all polys to the left */
if (sd1->bl->charidx == bl->charidx) { /* for text, only check matching char */
@@ -3147,7 +3134,7 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
sd = sortdata;
for (a = 0; a < poly; a++, sd++) {
if (sd->bl->hole == sd->dir) {
- bl = sd->bl;
+ BevList *bl = sd->bl;
bevp1 = bl->bevpoints;
bevp2 = bevp1 + (bl->nr - 1);
nr = bl->nr / 2;
@@ -3165,7 +3152,7 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
/* STEP 4: 2D-COSINES or 3D ORIENTATION */
if ((cu->flag & CU_3D) == 0) {
/* 2D Curves */
- for (bl = bev->first; bl; bl = bl->next) {
+ LISTBASE_FOREACH (BevList *, bl, bev) {
if (bl->nr < 2) {
BevPoint *bevp = bl->bevpoints;
unit_qt(bevp->quat);
@@ -3180,7 +3167,7 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
}
else {
/* 3D Curves */
- for (bl = bev->first; bl; bl = bl->next) {
+ LISTBASE_FOREACH (BevList *, bl, bev) {
if (bl->nr < 2) {
BevPoint *bevp = bl->bevpoints;
unit_qt(bevp->quat);
@@ -3674,7 +3661,7 @@ static bool tridiagonal_solve_with_limits(float *a,
* is affected by all other points of the curve segment, in practice the influence
* decreases exponentially with distance.
*
- * Note: this algorithm assumes that the handle horizontal size if always 1/3 of the
+ * Note: this algorithm assumes that the handle horizontal size is always 1/3 of the
* of the interval to the next point. This rule ensures linear interpolation of time.
*
* ^ height (co 1)
@@ -4314,12 +4301,8 @@ void BKE_nurb_handles_autocalc(Nurb *nu, uint8_t flag)
void BKE_nurbList_handles_autocalc(ListBase *editnurb, uint8_t flag)
{
- Nurb *nu;
-
- nu = editnurb->first;
- while (nu) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
BKE_nurb_handles_autocalc(nu, flag);
- nu = nu->next;
}
}
@@ -4331,13 +4314,11 @@ void BKE_nurbList_handles_set(ListBase *editnurb, const char code)
/* code==4: sets icu flag to become IPO_AUTO_HORIZ, horizontal extremes on auto-handles */
/* code==5: Set align, like 3 but no toggle */
/* code==6: Clear align, like 3 but no toggle */
- Nurb *nu;
BezTriple *bezt;
int a;
if (ELEM(code, HD_AUTO, HD_VECT)) {
- nu = editnurb->first;
- while (nu) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if (nu->type == CU_BEZIER) {
bezt = nu->bezt;
a = nu->pntsu;
@@ -4364,7 +4345,6 @@ void BKE_nurbList_handles_set(ListBase *editnurb, const char code)
/* like BKE_nurb_handles_calc but moves selected */
nurb_handles_calc__align_selected(nu);
}
- nu = nu->next;
}
}
else {
@@ -4379,7 +4359,7 @@ void BKE_nurbList_handles_set(ListBase *editnurb, const char code)
}
else {
/* Toggle */
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if (nu->type == CU_BEZIER) {
bezt = nu->bezt;
a = nu->pntsu;
@@ -4395,7 +4375,7 @@ void BKE_nurbList_handles_set(ListBase *editnurb, const char code)
}
h_new = (h_new == HD_FREE) ? HD_ALIGN : HD_FREE;
}
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if (nu->type == CU_BEZIER) {
bezt = nu->bezt;
a = nu->pntsu;
@@ -4421,66 +4401,66 @@ void BKE_nurbList_handles_recalculate(ListBase *editnurb,
const bool calc_length,
const uint8_t flag)
{
- Nurb *nu;
BezTriple *bezt;
int a;
- for (nu = editnurb->first; nu; nu = nu->next) {
- if (nu->type == CU_BEZIER) {
- bool changed = false;
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
+ if (nu->type != CU_BEZIER) {
+ continue;
+ }
- for (a = nu->pntsu, bezt = nu->bezt; a--; bezt++) {
+ bool changed = false;
- const bool h1_select = (bezt->f1 & flag) == flag;
- const bool h2_select = (bezt->f3 & flag) == flag;
+ for (a = nu->pntsu, bezt = nu->bezt; a--; bezt++) {
- if (h1_select || h2_select) {
+ const bool h1_select = (bezt->f1 & flag) == flag;
+ const bool h2_select = (bezt->f3 & flag) == flag;
- float co1_back[3], co2_back[3];
+ if (h1_select || h2_select) {
- copy_v3_v3(co1_back, bezt->vec[0]);
- copy_v3_v3(co2_back, bezt->vec[2]);
+ float co1_back[3], co2_back[3];
- BKE_nurb_handle_calc_simple_auto(nu, bezt);
+ copy_v3_v3(co1_back, bezt->vec[0]);
+ copy_v3_v3(co2_back, bezt->vec[2]);
- if (h1_select) {
- if (!calc_length) {
- dist_ensure_v3_v3fl(bezt->vec[0], bezt->vec[1], len_v3v3(co1_back, bezt->vec[1]));
- }
- }
- else {
- copy_v3_v3(bezt->vec[0], co1_back);
- }
+ BKE_nurb_handle_calc_simple_auto(nu, bezt);
- if (h2_select) {
- if (!calc_length) {
- dist_ensure_v3_v3fl(bezt->vec[2], bezt->vec[1], len_v3v3(co2_back, bezt->vec[1]));
- }
- }
- else {
- copy_v3_v3(bezt->vec[2], co2_back);
+ if (h1_select) {
+ if (!calc_length) {
+ dist_ensure_v3_v3fl(bezt->vec[0], bezt->vec[1], len_v3v3(co1_back, bezt->vec[1]));
}
+ }
+ else {
+ copy_v3_v3(bezt->vec[0], co1_back);
+ }
- changed = true;
+ if (h2_select) {
+ if (!calc_length) {
+ dist_ensure_v3_v3fl(bezt->vec[2], bezt->vec[1], len_v3v3(co2_back, bezt->vec[1]));
+ }
+ }
+ else {
+ copy_v3_v3(bezt->vec[2], co2_back);
}
- }
- if (changed) {
- /* Recalculate the whole curve */
- BKE_nurb_handles_calc(nu);
+ changed = true;
}
}
+
+ if (changed) {
+ /* Recalculate the whole curve */
+ BKE_nurb_handles_calc(nu);
+ }
}
}
void BKE_nurbList_flag_set(ListBase *editnurb, uint8_t flag, bool set)
{
- Nurb *nu;
BezTriple *bezt;
BPoint *bp;
int a;
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if (nu->type == CU_BEZIER) {
a = nu->pntsu;
bezt = nu->bezt;
@@ -4516,7 +4496,7 @@ bool BKE_nurbList_flag_set_from_flag(ListBase *editnurb, uint8_t from_flag, uint
{
bool changed = false;
- for (Nurb *nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if (nu->type == CU_BEZIER) {
for (int i = 0; i < nu->pntsu; i++) {
BezTriple *bezt = &nu->bezt[i];
@@ -4981,7 +4961,7 @@ bool BKE_nurb_type_convert(Nurb *nu,
}
}
else if (nu->type == CU_BEZIER) { /* Bezier */
- if (type == CU_POLY || type == CU_NURBS) {
+ if (ELEM(type, CU_POLY, CU_NURBS)) {
nr = use_handles ? (3 * nu->pntsu) : nu->pntsu;
nu->bp = MEM_calloc_arrayN(nr, sizeof(BPoint), "setsplinetype");
a = nu->pntsu;
@@ -5230,12 +5210,11 @@ bool BKE_curve_minmax(Curve *cu, bool use_radius, float min[3], float max[3])
bool BKE_curve_center_median(Curve *cu, float cent[3])
{
ListBase *nurb_lb = BKE_curve_nurbs_get(cu);
- Nurb *nu;
int total = 0;
zero_v3(cent);
- for (nu = nurb_lb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, nurb_lb) {
int i;
if (nu->type == CU_BEZIER) {
@@ -5283,12 +5262,11 @@ void BKE_curve_transform_ex(Curve *cu,
const bool do_props,
const float unit_scale)
{
- Nurb *nu;
BPoint *bp;
BezTriple *bezt;
int i;
- for (nu = cu->nurb.first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) {
if (nu->type == CU_BEZIER) {
i = nu->pntsu;
for (bezt = nu->bezt; i--; bezt++) {
@@ -5313,12 +5291,11 @@ void BKE_curve_transform_ex(Curve *cu,
}
if (do_keys && cu->key) {
- KeyBlock *kb;
- for (kb = cu->key->block.first; kb; kb = kb->next) {
+ LISTBASE_FOREACH (KeyBlock *, kb, &cu->key->block) {
float *fp = kb->data;
int n = kb->totelem;
- for (nu = cu->nurb.first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) {
if (nu->type == CU_BEZIER) {
for (i = nu->pntsu; i && (n -= KEYELEM_ELEM_LEN_BEZTRIPLE) >= 0; i--) {
mul_m4_v3(mat, &fp[0]);
@@ -5474,9 +5451,8 @@ bool BKE_curve_material_index_validate(Curve *cu)
}
}
else {
- Nurb *nu;
const int max_idx = max_ii(0, cu->totcol - 1);
- for (nu = cu->nurb.first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) {
if (nu->mat_nr > max_idx) {
nu->mat_nr = 0;
is_valid = false;
@@ -5542,12 +5518,12 @@ void BKE_curve_material_remap(Curve *cu, const unsigned int *remap, unsigned int
void BKE_curve_smooth_flag_set(Curve *cu, const bool use_smooth)
{
if (use_smooth) {
- for (Nurb *nu = cu->nurb.first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) {
nu->flag |= CU_SMOOTH;
}
}
else {
- for (Nurb *nu = cu->nurb.first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) {
nu->flag &= ~CU_SMOOTH;
}
}
diff --git a/source/blender/blenkernel/intern/curve_decimate.c b/source/blender/blenkernel/intern/curve_decimate.c
index 68c0d2a3cec..e4647908b58 100644
--- a/source/blender/blenkernel/intern/curve_decimate.c
+++ b/source/blender/blenkernel/intern/curve_decimate.c
@@ -269,11 +269,11 @@ uint BKE_curve_decimate_bezt_array(BezTriple *bezt_array,
if (a == HD_VECT) { \
a = HD_FREE; \
} \
- else if (a == HD_AUTO || a == HD_AUTO_ANIM) { \
+ else if (ELEM(a, HD_AUTO, HD_AUTO_ANIM)) { \
a = HD_ALIGN; \
} \
/* opposite handle */ \
- if (b == HD_AUTO || b == HD_AUTO_ANIM) { \
+ if (ELEM(b, HD_AUTO, HD_AUTO_ANIM)) { \
b = HD_ALIGN; \
} \
} \
diff --git a/source/blender/blenkernel/intern/curve_deform.c b/source/blender/blenkernel/intern/curve_deform.c
index d4f197521a1..049bd46c434 100644
--- a/source/blender/blenkernel/intern/curve_deform.c
+++ b/source/blender/blenkernel/intern/curve_deform.c
@@ -222,10 +222,10 @@ static bool calc_curve_deform(
/* zero the axis which is not used,
* the big block of text above now applies to these 3 lines */
- quat_apply_track(
- quat,
- axis,
- (axis == 0 || axis == 2) ? 1 : 0); /* up flag is a dummy, set so no rotation is done */
+ quat_apply_track(quat,
+ axis,
+ (ELEM(axis, 0, 2)) ? 1 :
+ 0); /* up flag is a dummy, set so no rotation is done */
vec_apply_track(cent, axis);
cent[index] = 0.0f;
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index d762b1b0604..fdb3e246382 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -2509,7 +2509,7 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
return &data->layers[CustomData_get_layer_index(data, type)];
}
- if ((alloctype == CD_ASSIGN) || (alloctype == CD_REFERENCE)) {
+ if (ELEM(alloctype, CD_ASSIGN, CD_REFERENCE)) {
newlayerdata = layerdata;
}
else if (totelem > 0 && typeInfo->size > 0) {
@@ -2997,7 +2997,7 @@ void CustomData_free_elem(CustomData *data, int index, int count)
/**
* Interpolate given custom data source items into a single destination one.
*
- * \param src_indices Indices of every source items to interpolate into the destination one.
+ * \param src_indices: Indices of every source items to interpolate into the destination one.
* \param weights: The weight to apply to each source value individually. If NULL, they will be
* averaged.
* \param sub_weights: The weights of sub-items, only used to affect each corners of a
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index bcb467e1230..f5257eb12ab 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -92,17 +92,13 @@ void BKE_displist_free(ListBase *lb)
DispList *BKE_displist_find_or_create(ListBase *lb, int type)
{
- DispList *dl;
-
- dl = lb->first;
- while (dl) {
+ LISTBASE_FOREACH (DispList *, dl, lb) {
if (dl->type == type) {
return dl;
}
- dl = dl->next;
}
- dl = MEM_callocN(sizeof(DispList), "find_disp");
+ DispList *dl = MEM_callocN(sizeof(DispList), "find_disp");
dl->type = type;
BLI_addtail(lb, dl);
@@ -111,14 +107,10 @@ DispList *BKE_displist_find_or_create(ListBase *lb, int type)
DispList *BKE_displist_find(ListBase *lb, int type)
{
- DispList *dl;
-
- dl = lb->first;
- while (dl) {
+ LISTBASE_FOREACH (DispList *, dl, lb) {
if (dl->type == type) {
return dl;
}
- dl = dl->next;
}
return NULL;
@@ -126,9 +118,7 @@ DispList *BKE_displist_find(ListBase *lb, int type)
bool BKE_displist_has_faces(ListBase *lb)
{
- DispList *dl;
-
- for (dl = lb->first; dl; dl = dl->next) {
+ LISTBASE_FOREACH (DispList *, dl, lb) {
if (ELEM(dl->type, DL_INDEX3, DL_INDEX4, DL_SURF)) {
return true;
}
@@ -139,13 +129,10 @@ bool BKE_displist_has_faces(ListBase *lb)
void BKE_displist_copy(ListBase *lbn, ListBase *lb)
{
- DispList *dln, *dl;
-
BKE_displist_free(lbn);
- dl = lb->first;
- while (dl) {
- dln = MEM_dupallocN(dl);
+ LISTBASE_FOREACH (const DispList *, dl, lb) {
+ DispList *dln = MEM_dupallocN(dl);
BLI_addtail(lbn, dln);
dln->verts = MEM_dupallocN(dl->verts);
dln->nors = MEM_dupallocN(dl->nors);
@@ -154,22 +141,17 @@ void BKE_displist_copy(ListBase *lbn, ListBase *lb)
if (dl->bevel_split) {
dln->bevel_split = MEM_dupallocN(dl->bevel_split);
}
-
- dl = dl->next;
}
}
void BKE_displist_normals_add(ListBase *lb)
{
- DispList *dl = NULL;
float *vdata, *ndata, nor[3];
float *v1, *v2, *v3, *v4;
float *n1, *n2, *n3, *n4;
int a, b, p1, p2, p3, p4;
- dl = lb->first;
-
- while (dl) {
+ LISTBASE_FOREACH (DispList *, dl, lb) {
if (dl->type == DL_INDEX3) {
if (dl->nors == NULL) {
dl->nors = MEM_callocN(sizeof(float[3]), "dlnors");
@@ -230,15 +212,12 @@ void BKE_displist_normals_add(ListBase *lb)
}
}
}
- dl = dl->next;
}
}
void BKE_displist_count(ListBase *lb, int *totvert, int *totface, int *tottri)
{
- DispList *dl;
-
- for (dl = lb->first; dl; dl = dl->next) {
+ LISTBASE_FOREACH (DispList *, dl, lb) {
int vert_tot = 0;
int face_tot = 0;
int tri_tot = 0;
@@ -318,7 +297,6 @@ static void curve_to_displist(Curve *cu,
ListBase *dispbase,
const bool for_render)
{
- Nurb *nu;
DispList *dl;
BezTriple *bezt, *prevbezt;
BPoint *bp;
@@ -326,154 +304,154 @@ static void curve_to_displist(Curve *cu,
int a, len, resolu;
const bool editmode = (!for_render && (cu->editnurb || cu->editfont));
- nu = nubase->first;
- while (nu) {
- if (nu->hide == 0 || editmode == false) {
- if (for_render && cu->resolu_ren != 0) {
- resolu = cu->resolu_ren;
- }
- else {
- resolu = nu->resolu;
- }
-
- if (!BKE_nurb_check_valid_u(nu)) {
- /* pass */
- }
- else if (nu->type == CU_BEZIER) {
- /* count */
- len = 0;
- a = nu->pntsu - 1;
- if (nu->flagu & CU_NURB_CYCLIC) {
- a++;
- }
-
- prevbezt = nu->bezt;
- bezt = prevbezt + 1;
- while (a--) {
- if (a == 0 && (nu->flagu & CU_NURB_CYCLIC)) {
- bezt = nu->bezt;
- }
+ LISTBASE_FOREACH (Nurb *, nu, nubase) {
+ if (nu->hide != 0 && editmode) {
+ continue;
+ }
- if (prevbezt->h2 == HD_VECT && bezt->h1 == HD_VECT) {
- len++;
- }
- else {
- len += resolu;
- }
+ if (for_render && cu->resolu_ren != 0) {
+ resolu = cu->resolu_ren;
+ }
+ else {
+ resolu = nu->resolu;
+ }
- if (a == 0 && (nu->flagu & CU_NURB_CYCLIC) == 0) {
- len++;
- }
+ if (!BKE_nurb_check_valid_u(nu)) {
+ /* pass */
+ }
+ else if (nu->type == CU_BEZIER) {
+ /* count */
+ len = 0;
+ a = nu->pntsu - 1;
+ if (nu->flagu & CU_NURB_CYCLIC) {
+ a++;
+ }
- prevbezt = bezt;
- bezt++;
+ prevbezt = nu->bezt;
+ bezt = prevbezt + 1;
+ while (a--) {
+ if (a == 0 && (nu->flagu & CU_NURB_CYCLIC)) {
+ bezt = nu->bezt;
}
- dl = MEM_callocN(sizeof(DispList), "makeDispListbez");
- /* len+1 because of 'forward_diff_bezier' function */
- dl->verts = MEM_mallocN((len + 1) * sizeof(float[3]), "dlverts");
- BLI_addtail(dispbase, dl);
- dl->parts = 1;
- dl->nr = len;
- dl->col = nu->mat_nr;
- dl->charidx = nu->charidx;
-
- data = dl->verts;
-
- /* check that (len != 2) so we don't immediately loop back on ourselves */
- if (nu->flagu & CU_NURB_CYCLIC && (dl->nr != 2)) {
- dl->type = DL_POLY;
- a = nu->pntsu;
+ if (prevbezt->h2 == HD_VECT && bezt->h1 == HD_VECT) {
+ len++;
}
else {
- dl->type = DL_SEGM;
- a = nu->pntsu - 1;
+ len += resolu;
}
- prevbezt = nu->bezt;
- bezt = prevbezt + 1;
+ if (a == 0 && (nu->flagu & CU_NURB_CYCLIC) == 0) {
+ len++;
+ }
- while (a--) {
- if (a == 0 && dl->type == DL_POLY) {
- bezt = nu->bezt;
- }
+ prevbezt = bezt;
+ bezt++;
+ }
- if (prevbezt->h2 == HD_VECT && bezt->h1 == HD_VECT) {
- copy_v3_v3(data, prevbezt->vec[1]);
- data += 3;
- }
- else {
- int j;
- for (j = 0; j < 3; j++) {
- BKE_curve_forward_diff_bezier(prevbezt->vec[1][j],
- prevbezt->vec[2][j],
- bezt->vec[0][j],
- bezt->vec[1][j],
- data + j,
- resolu,
- sizeof(float[3]));
- }
+ dl = MEM_callocN(sizeof(DispList), "makeDispListbez");
+ /* len+1 because of 'forward_diff_bezier' function */
+ dl->verts = MEM_mallocN((len + 1) * sizeof(float[3]), "dlverts");
+ BLI_addtail(dispbase, dl);
+ dl->parts = 1;
+ dl->nr = len;
+ dl->col = nu->mat_nr;
+ dl->charidx = nu->charidx;
+
+ data = dl->verts;
+
+ /* check that (len != 2) so we don't immediately loop back on ourselves */
+ if (nu->flagu & CU_NURB_CYCLIC && (dl->nr != 2)) {
+ dl->type = DL_POLY;
+ a = nu->pntsu;
+ }
+ else {
+ dl->type = DL_SEGM;
+ a = nu->pntsu - 1;
+ }
- data += 3 * resolu;
- }
+ prevbezt = nu->bezt;
+ bezt = prevbezt + 1;
+
+ while (a--) {
+ if (a == 0 && dl->type == DL_POLY) {
+ bezt = nu->bezt;
+ }
- if (a == 0 && dl->type == DL_SEGM) {
- copy_v3_v3(data, bezt->vec[1]);
+ if (prevbezt->h2 == HD_VECT && bezt->h1 == HD_VECT) {
+ copy_v3_v3(data, prevbezt->vec[1]);
+ data += 3;
+ }
+ else {
+ int j;
+ for (j = 0; j < 3; j++) {
+ BKE_curve_forward_diff_bezier(prevbezt->vec[1][j],
+ prevbezt->vec[2][j],
+ bezt->vec[0][j],
+ bezt->vec[1][j],
+ data + j,
+ resolu,
+ sizeof(float[3]));
}
- prevbezt = bezt;
- bezt++;
+ data += 3 * resolu;
}
+
+ if (a == 0 && dl->type == DL_SEGM) {
+ copy_v3_v3(data, bezt->vec[1]);
+ }
+
+ prevbezt = bezt;
+ bezt++;
}
- else if (nu->type == CU_NURBS) {
- len = (resolu * SEGMENTSU(nu));
+ }
+ else if (nu->type == CU_NURBS) {
+ len = (resolu * SEGMENTSU(nu));
- dl = MEM_callocN(sizeof(DispList), "makeDispListsurf");
- dl->verts = MEM_mallocN(len * sizeof(float[3]), "dlverts");
- BLI_addtail(dispbase, dl);
- dl->parts = 1;
+ dl = MEM_callocN(sizeof(DispList), "makeDispListsurf");
+ dl->verts = MEM_mallocN(len * sizeof(float[3]), "dlverts");
+ BLI_addtail(dispbase, dl);
+ dl->parts = 1;
- dl->nr = len;
- dl->col = nu->mat_nr;
- dl->charidx = nu->charidx;
+ dl->nr = len;
+ dl->col = nu->mat_nr;
+ dl->charidx = nu->charidx;
- data = dl->verts;
- if (nu->flagu & CU_NURB_CYCLIC) {
- dl->type = DL_POLY;
- }
- else {
- dl->type = DL_SEGM;
- }
- BKE_nurb_makeCurve(nu, data, NULL, NULL, NULL, resolu, sizeof(float[3]));
+ data = dl->verts;
+ if (nu->flagu & CU_NURB_CYCLIC) {
+ dl->type = DL_POLY;
+ }
+ else {
+ dl->type = DL_SEGM;
+ }
+ BKE_nurb_makeCurve(nu, data, NULL, NULL, NULL, resolu, sizeof(float[3]));
+ }
+ else if (nu->type == CU_POLY) {
+ len = nu->pntsu;
+ dl = MEM_callocN(sizeof(DispList), "makeDispListpoly");
+ dl->verts = MEM_mallocN(len * sizeof(float[3]), "dlverts");
+ BLI_addtail(dispbase, dl);
+ dl->parts = 1;
+ dl->nr = len;
+ dl->col = nu->mat_nr;
+ dl->charidx = nu->charidx;
+
+ data = dl->verts;
+ if ((nu->flagu & CU_NURB_CYCLIC) && (dl->nr != 2)) {
+ dl->type = DL_POLY;
+ }
+ else {
+ dl->type = DL_SEGM;
}
- else if (nu->type == CU_POLY) {
- len = nu->pntsu;
- dl = MEM_callocN(sizeof(DispList), "makeDispListpoly");
- dl->verts = MEM_mallocN(len * sizeof(float[3]), "dlverts");
- BLI_addtail(dispbase, dl);
- dl->parts = 1;
- dl->nr = len;
- dl->col = nu->mat_nr;
- dl->charidx = nu->charidx;
-
- data = dl->verts;
- if ((nu->flagu & CU_NURB_CYCLIC) && (dl->nr != 2)) {
- dl->type = DL_POLY;
- }
- else {
- dl->type = DL_SEGM;
- }
- a = len;
- bp = nu->bp;
- while (a--) {
- copy_v3_v3(data, bp->vec);
- bp++;
- data += 3;
- }
+ a = len;
+ bp = nu->bp;
+ while (a--) {
+ copy_v3_v3(data, bp->vec);
+ bp++;
+ data += 3;
}
}
- nu = nu->next;
}
}
@@ -491,7 +469,7 @@ void BKE_displist_fill(ListBase *dispbase,
ScanFillVert *sf_vert, *sf_vert_new, *sf_vert_last;
ScanFillFace *sf_tri;
MemArena *sf_arena;
- DispList *dlnew = NULL, *dl;
+ DispList *dlnew = NULL;
float *f1;
int colnr = 0, charidx = 0, cont = 1, tot, a, *index, nextcol = 0;
int totvert;
@@ -515,8 +493,7 @@ void BKE_displist_fill(ListBase *dispbase,
BLI_scanfill_begin_arena(&sf_ctx, sf_arena);
- dl = dispbase->first;
- while (dl) {
+ LISTBASE_FOREACH (DispList *, dl, dispbase) {
if (dl->type == DL_POLY) {
if (charidx < dl->charidx) {
cont = 1;
@@ -558,7 +535,6 @@ void BKE_displist_fill(ListBase *dispbase,
}
dl_flag_accum |= dl->flag;
}
- dl = dl->next;
}
/* XXX (obedit && obedit->actcol) ? (obedit->actcol - 1) : 0)) { */
@@ -627,19 +603,17 @@ static void bevels_to_filledpoly(Curve *cu, ListBase *dispbase)
{
const float z_up[3] = {0.0f, 0.0f, -1.0f};
ListBase front, back;
- DispList *dl, *dlnew;
float *fp, *fp1;
int a, dpoly;
BLI_listbase_clear(&front);
BLI_listbase_clear(&back);
- dl = dispbase->first;
- while (dl) {
+ LISTBASE_FOREACH (DispList *, dl, dispbase) {
if (dl->type == DL_SURF) {
if ((dl->flag & DL_CYCL_V) && (dl->flag & DL_CYCL_U) == 0) {
if ((cu->flag & CU_BACK) && (dl->flag & DL_BACK_CURVE)) {
- dlnew = MEM_callocN(sizeof(DispList), "filldisp");
+ DispList *dlnew = MEM_callocN(sizeof(DispList), "filldisp");
BLI_addtail(&front, dlnew);
dlnew->verts = fp1 = MEM_mallocN(sizeof(float[3]) * dl->parts, "filldisp1");
dlnew->nr = dl->parts;
@@ -660,7 +634,7 @@ static void bevels_to_filledpoly(Curve *cu, ListBase *dispbase)
}
}
if ((cu->flag & CU_FRONT) && (dl->flag & DL_FRONT_CURVE)) {
- dlnew = MEM_callocN(sizeof(DispList), "filldisp");
+ DispList *dlnew = MEM_callocN(sizeof(DispList), "filldisp");
BLI_addtail(&back, dlnew);
dlnew->verts = fp1 = MEM_mallocN(sizeof(float[3]) * dl->parts, "filldisp1");
dlnew->nr = dl->parts;
@@ -682,7 +656,6 @@ static void bevels_to_filledpoly(Curve *cu, ListBase *dispbase)
}
}
}
- dl = dl->next;
}
BKE_displist_fill(&front, dispbase, z_up, true);
@@ -939,18 +912,17 @@ static bool curve_calc_modifiers_pre(
static float (*displist_vert_coords_alloc(ListBase *dispbase, int *r_vert_len))[3]
{
- DispList *dl;
float(*allverts)[3], *fp;
*r_vert_len = 0;
- for (dl = dispbase->first; dl; dl = dl->next) {
+ LISTBASE_FOREACH (DispList *, dl, dispbase) {
*r_vert_len += (dl->type == DL_INDEX3) ? dl->nr : dl->parts * dl->nr;
}
allverts = MEM_mallocN(sizeof(float[3]) * (*r_vert_len), "displist_vert_coords_alloc allverts");
fp = (float *)allverts;
- for (dl = dispbase->first; dl; dl = dl->next) {
+ LISTBASE_FOREACH (DispList *, dl, dispbase) {
int offs = 3 * ((dl->type == DL_INDEX3) ? dl->nr : dl->parts * dl->nr);
memcpy(fp, dl->verts, sizeof(float) * offs);
fp += offs;
@@ -961,11 +933,10 @@ static float (*displist_vert_coords_alloc(ListBase *dispbase, int *r_vert_len))[
static void displist_vert_coords_apply(ListBase *dispbase, float (*allverts)[3])
{
- DispList *dl;
const float *fp;
fp = (float *)allverts;
- for (dl = dispbase->first; dl; dl = dl->next) {
+ LISTBASE_FOREACH (DispList *, dl, dispbase) {
int offs = 3 * ((dl->type == DL_INDEX3) ? dl->nr : dl->parts * dl->nr);
memcpy(dl->verts, fp, sizeof(float) * offs);
fp += offs;
@@ -1218,7 +1189,6 @@ void BKE_displist_make_surf(Depsgraph *depsgraph,
const bool for_orco)
{
ListBase nubase = {NULL, NULL};
- Nurb *nu;
Curve *cu = ob->data;
DispList *dl;
float *data;
@@ -1236,76 +1206,78 @@ void BKE_displist_make_surf(Depsgraph *depsgraph,
force_mesh_conversion = curve_calc_modifiers_pre(depsgraph, scene, ob, &nubase, for_render);
}
- for (nu = nubase.first; nu; nu = nu->next) {
- if ((for_render || nu->hide == 0) && BKE_nurb_check_valid_uv(nu)) {
- int resolu = nu->resolu, resolv = nu->resolv;
+ LISTBASE_FOREACH (Nurb *, nu, &nubase) {
+ if (!(for_render || nu->hide == 0) || !BKE_nurb_check_valid_uv(nu)) {
+ continue;
+ }
+
+ int resolu = nu->resolu, resolv = nu->resolv;
- if (for_render) {
- if (cu->resolu_ren) {
- resolu = cu->resolu_ren;
- }
- if (cu->resolv_ren) {
- resolv = cu->resolv_ren;
- }
+ if (for_render) {
+ if (cu->resolu_ren) {
+ resolu = cu->resolu_ren;
+ }
+ if (cu->resolv_ren) {
+ resolv = cu->resolv_ren;
}
+ }
- if (nu->pntsv == 1) {
- len = SEGMENTSU(nu) * resolu;
+ if (nu->pntsv == 1) {
+ len = SEGMENTSU(nu) * resolu;
- dl = MEM_callocN(sizeof(DispList), "makeDispListsurf");
- dl->verts = MEM_mallocN(len * sizeof(float[3]), "dlverts");
+ dl = MEM_callocN(sizeof(DispList), "makeDispListsurf");
+ dl->verts = MEM_mallocN(len * sizeof(float[3]), "dlverts");
- BLI_addtail(dispbase, dl);
- dl->parts = 1;
- dl->nr = len;
- dl->col = nu->mat_nr;
- dl->charidx = nu->charidx;
+ BLI_addtail(dispbase, dl);
+ dl->parts = 1;
+ dl->nr = len;
+ dl->col = nu->mat_nr;
+ dl->charidx = nu->charidx;
- /* dl->rt will be used as flag for render face and */
- /* CU_2D conflicts with R_NOPUNOFLIP */
- dl->rt = nu->flag & ~CU_2D;
+ /* dl->rt will be used as flag for render face and */
+ /* CU_2D conflicts with R_NOPUNOFLIP */
+ dl->rt = nu->flag & ~CU_2D;
- data = dl->verts;
- if (nu->flagu & CU_NURB_CYCLIC) {
- dl->type = DL_POLY;
- }
- else {
- dl->type = DL_SEGM;
- }
-
- BKE_nurb_makeCurve(nu, data, NULL, NULL, NULL, resolu, sizeof(float[3]));
+ data = dl->verts;
+ if (nu->flagu & CU_NURB_CYCLIC) {
+ dl->type = DL_POLY;
}
else {
- len = (nu->pntsu * resolu) * (nu->pntsv * resolv);
+ dl->type = DL_SEGM;
+ }
- dl = MEM_callocN(sizeof(DispList), "makeDispListsurf");
- dl->verts = MEM_mallocN(len * sizeof(float[3]), "dlverts");
- BLI_addtail(dispbase, dl);
+ BKE_nurb_makeCurve(nu, data, NULL, NULL, NULL, resolu, sizeof(float[3]));
+ }
+ else {
+ len = (nu->pntsu * resolu) * (nu->pntsv * resolv);
- dl->col = nu->mat_nr;
- dl->charidx = nu->charidx;
+ dl = MEM_callocN(sizeof(DispList), "makeDispListsurf");
+ dl->verts = MEM_mallocN(len * sizeof(float[3]), "dlverts");
+ BLI_addtail(dispbase, dl);
- /* dl->rt will be used as flag for render face and */
- /* CU_2D conflicts with R_NOPUNOFLIP */
- dl->rt = nu->flag & ~CU_2D;
+ dl->col = nu->mat_nr;
+ dl->charidx = nu->charidx;
- data = dl->verts;
- dl->type = DL_SURF;
+ /* dl->rt will be used as flag for render face and */
+ /* CU_2D conflicts with R_NOPUNOFLIP */
+ dl->rt = nu->flag & ~CU_2D;
- dl->parts = (nu->pntsu * resolu); /* in reverse, because makeNurbfaces works that way */
- dl->nr = (nu->pntsv * resolv);
- if (nu->flagv & CU_NURB_CYCLIC) {
- dl->flag |= DL_CYCL_U; /* reverse too! */
- }
- if (nu->flagu & CU_NURB_CYCLIC) {
- dl->flag |= DL_CYCL_V;
- }
+ data = dl->verts;
+ dl->type = DL_SURF;
- BKE_nurb_makeFaces(nu, data, 0, resolu, resolv);
-
- /* gl array drawing: using indices */
- displist_surf_indices(dl);
+ dl->parts = (nu->pntsu * resolu); /* in reverse, because makeNurbfaces works that way */
+ dl->nr = (nu->pntsv * resolv);
+ if (nu->flagv & CU_NURB_CYCLIC) {
+ dl->flag |= DL_CYCL_U; /* reverse too! */
+ }
+ if (nu->flagu & CU_NURB_CYCLIC) {
+ dl->flag |= DL_CYCL_V;
}
+
+ BKE_nurb_makeFaces(nu, data, 0, resolu, resolv);
+
+ /* gl array drawing: using indices */
+ displist_surf_indices(dl);
}
}
@@ -1851,12 +1823,11 @@ void BKE_displist_make_curveTypes_forRender(Depsgraph *depsgraph,
void BKE_displist_minmax(ListBase *dispbase, float min[3], float max[3])
{
- DispList *dl;
const float *vert;
int a, tot = 0;
int doit = 0;
- for (dl = dispbase->first; dl; dl = dl->next) {
+ LISTBASE_FOREACH (DispList *, dl, dispbase) {
tot = (dl->type == DL_INDEX3) ? dl->nr : dl->nr * dl->parts;
vert = dl->verts;
for (a = 0; a < tot; a++, vert += 3) {
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index fef4b49de7e..b56a15b3d45 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -76,9 +76,7 @@
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
-/* to read material/texture color */
-#include "RE_render_ext.h"
-#include "RE_shader_ext.h"
+#include "RE_texture.h"
#include "atomic_ops.h"
@@ -123,7 +121,7 @@ static int neighStraightY[8] = {0, 1, 0, -1, 1, 1, -1, -1};
/* paint effect default movement per frame in global units */
#define EFF_MOVEMENT_PER_FRAME 0.05f
/* initial wave time factor */
-#define WAVE_TIME_FAC (1.0f / 24.f)
+#define WAVE_TIME_FAC (1.0f / 24.0f)
#define CANVAS_REL_SIZE 5.0f
/* drying limits */
#define MIN_WETNESS 0.001f
@@ -762,7 +760,7 @@ static void surfaceGenerateGrid(struct DynamicPaintSurface *surface)
sub_v3_v3v3(dim, grid->grid_bounds.max, grid->grid_bounds.min);
copy_v3_v3(td, dim);
copy_v3_v3(bData->dim, dim);
- min_dim = max_fff(td[0], td[1], td[2]) / 1000.f;
+ min_dim = max_fff(td[0], td[1], td[2]) / 1000.0f;
/* deactivate zero axises */
for (i = 0; i < 3; i++) {
@@ -2700,7 +2698,7 @@ static void dynamic_paint_find_island_border(const DynamicPaintCreateUVSurfaceDa
const int final_tri_index = tempPoints[final_index].tri_index;
/* If found pixel still lies on wrong face ( mesh has smaller than pixel sized faces) */
- if (final_tri_index != target_tri && final_tri_index != -1) {
+ if (!ELEM(final_tri_index, target_tri, -1)) {
/* Check if it's close enough to likely touch the intended triangle. Any triangle
* becomes thinner than a pixel at its vertices, so robustness requires some margin. */
const float final_pt[2] = {((final_index % w) + 0.5f) / w, ((final_index / w) + 0.5f) / h};
@@ -3034,7 +3032,7 @@ int dynamicPaint_createUVSurface(Scene *scene,
n_pos++;
}
}
- else if (n_target == ON_MESH_EDGE || n_target == OUT_OF_TEXTURE) {
+ else if (ELEM(n_target, ON_MESH_EDGE, OUT_OF_TEXTURE)) {
ed->flags[final_index[index]] |= ADJ_ON_MESH_EDGE;
}
}
@@ -3736,7 +3734,7 @@ static bool meshBrush_boundsIntersect(Bounds3D *b1,
if (brush->collision == MOD_DPAINT_COL_VOLUME) {
return boundsIntersect(b1, b2);
}
- if (brush->collision == MOD_DPAINT_COL_DIST || brush->collision == MOD_DPAINT_COL_VOLDIST) {
+ if (ELEM(brush->collision, MOD_DPAINT_COL_DIST, MOD_DPAINT_COL_VOLDIST)) {
return boundsIntersectDist(b1, b2, brush_radius);
}
return true;
@@ -4710,8 +4708,7 @@ static void dynamic_paint_paint_single_point_cb_ex(void *__restrict userdata,
}
/* Smooth range or color ramp */
- if (brush->proximity_falloff == MOD_DPAINT_PRFALL_SMOOTH ||
- brush->proximity_falloff == MOD_DPAINT_PRFALL_RAMP) {
+ if (ELEM(brush->proximity_falloff, MOD_DPAINT_PRFALL_SMOOTH, MOD_DPAINT_PRFALL_RAMP)) {
strength = 1.0f - distance / brush_radius;
CLAMP(strength, 0.0f, 1.0f);
}
@@ -5116,7 +5113,7 @@ static void dynamic_paint_prepare_effect_cb(void *__restrict userdata,
madd_v3_v3fl(forc,
scene->physics_settings.gravity,
surface->effector_weights->global_gravity * surface->effector_weights->weight[0] /
- 10.f);
+ 10.0f);
}
/* add surface point velocity and acceleration if enabled */
diff --git a/source/blender/blenkernel/intern/editmesh_tangent.c b/source/blender/blenkernel/intern/editmesh_tangent.c
index b3f6b543daf..9656c20f0be 100644
--- a/source/blender/blenkernel/intern/editmesh_tangent.c
+++ b/source/blender/blenkernel/intern/editmesh_tangent.c
@@ -35,6 +35,7 @@
/* interface */
#include "mikktspace.h"
+/* -------------------------------------------------------------------- */
/** \name Tangent Space Calculation
* \{ */
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index 967b961dbea..13e9bb1bf24 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -68,8 +68,7 @@
#include "DEG_depsgraph_physics.h"
#include "DEG_depsgraph_query.h"
-#include "RE_render_ext.h"
-#include "RE_shader_ext.h"
+#include "RE_texture.h"
EffectorWeights *BKE_effector_add_weights(Collection *collection)
{
@@ -699,8 +698,8 @@ int get_effector_data(EffectorCache *eff,
copy_v3_v3(efd->loc, state.co);
/* rather than use the velocity use rotated x-axis (defaults to velocity) */
- efd->nor[0] = 1.f;
- efd->nor[1] = efd->nor[2] = 0.f;
+ efd->nor[0] = 1.0f;
+ efd->nor[1] = efd->nor[2] = 0.0f;
mul_qt_v3(state.rot, efd->nor);
if (real_velocity) {
@@ -1009,9 +1008,12 @@ static void do_physical_effector(EffectorCache *eff,
else {
add_v3_v3v3(temp, efd->vec_to_point2, efd->nor2);
}
- force[0] = -1.0f + 2.0f * BLI_gTurbulence(pd->f_size, temp[0], temp[1], temp[2], 2, 0, 2);
- force[1] = -1.0f + 2.0f * BLI_gTurbulence(pd->f_size, temp[1], temp[2], temp[0], 2, 0, 2);
- force[2] = -1.0f + 2.0f * BLI_gTurbulence(pd->f_size, temp[2], temp[0], temp[1], 2, 0, 2);
+ force[0] = -1.0f + 2.0f * BLI_noise_generic_turbulence(
+ pd->f_size, temp[0], temp[1], temp[2], 2, 0, 2);
+ force[1] = -1.0f + 2.0f * BLI_noise_generic_turbulence(
+ pd->f_size, temp[1], temp[2], temp[0], 2, 0, 2);
+ force[2] = -1.0f + 2.0f * BLI_noise_generic_turbulence(
+ pd->f_size, temp[2], temp[0], temp[1], 2, 0, 2);
mul_v3_fl(force, strength * efd->falloff);
break;
case PFIELD_DRAG:
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 003e926e0ae..8bfc626379f 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -1076,6 +1076,84 @@ void fcurve_store_samples(FCurve *fcu, void *data, int start, int end, FcuSample
fcu->totvert = end - start + 1;
}
+static void init_unbaked_bezt_data(BezTriple *bezt)
+{
+ bezt->f1 = bezt->f2 = bezt->f3 = SELECT;
+ /* Baked FCurve points always use linear interpolation. */
+ bezt->ipo = BEZT_IPO_LIN;
+ bezt->h1 = bezt->h2 = HD_AUTO_ANIM;
+}
+
+/* Convert baked/sampled fcurves into bezt/regular fcurves. */
+void fcurve_samples_to_keyframes(FCurve *fcu, const int start, const int end)
+{
+
+ /* Sanity checks. */
+ /* TODO: make these tests report errors using reports not CLOG's (Joshua Leung 2009). */
+ if (fcu == NULL) {
+ CLOG_ERROR(&LOG, "No F-Curve with F-Curve Modifiers to Un-Bake");
+ return;
+ }
+
+ if (start > end) {
+ CLOG_ERROR(&LOG, "Error: Frame range to unbake F-Curve is inappropriate");
+ return;
+ }
+
+ if (fcu->fpt == NULL) {
+ /* No data to unbake. */
+ CLOG_ERROR(&LOG, "Error: Curve containts no baked keyframes");
+ return;
+ }
+
+ /* Free any existing sample/keyframe data on the curve. */
+ if (fcu->bezt) {
+ MEM_freeN(fcu->bezt);
+ }
+
+ BezTriple *bezt;
+ FPoint *fpt = fcu->fpt;
+ int keyframes_to_insert = end - start;
+ int sample_points = fcu->totvert;
+
+ bezt = fcu->bezt = MEM_callocN(sizeof(*fcu->bezt) * (size_t)keyframes_to_insert, __func__);
+ fcu->totvert = keyframes_to_insert;
+
+ /* Get first sample point to 'copy' as keyframe. */
+ for (; sample_points && (fpt->vec[0] < start); fpt++, sample_points--) {
+ /* pass */
+ }
+
+ /* Current position in the timeline. */
+ int cur_pos = start;
+
+ /* Add leading dummy flat points if needed. */
+ for (; keyframes_to_insert && (fpt->vec[0] > start); cur_pos++, bezt++, keyframes_to_insert--) {
+ init_unbaked_bezt_data(bezt);
+ bezt->vec[1][0] = (float)cur_pos;
+ bezt->vec[1][1] = fpt->vec[1];
+ }
+
+ /* Copy actual sample points. */
+ for (; keyframes_to_insert && sample_points;
+ cur_pos++, bezt++, keyframes_to_insert--, fpt++, sample_points--) {
+ init_unbaked_bezt_data(bezt);
+ copy_v2_v2(bezt->vec[1], fpt->vec);
+ }
+
+ /* Add trailing dummy flat points if needed. */
+ for (fpt--; keyframes_to_insert; cur_pos++, bezt++, keyframes_to_insert--) {
+ init_unbaked_bezt_data(bezt);
+ bezt->vec[1][0] = (float)cur_pos;
+ bezt->vec[1][1] = fpt->vec[1];
+ }
+
+ MEM_SAFE_FREE(fcu->fpt);
+
+ /* Not strictly needed since we use linear interpolation, but better be consistent here. */
+ calchandles_fcurve(fcu);
+}
+
/* ***************************** F-Curve Sanity ********************************* */
/* The functions here are used in various parts of Blender, usually after some editing
* of keyframe data has occurred. They ensure that keyframe data is properly ordered and
@@ -1194,7 +1272,7 @@ void calchandles_fcurve_ex(FCurve *fcu, eBezTriple_Flag handle_sel_flag)
/* For automatic ease in and out. */
if (BEZT_IS_AUTOH(bezt) && !cycle) {
/* Only do this on first or last beztriple. */
- if ((a == 0) || (a == fcu->totvert - 1)) {
+ if (ELEM(a, 0, fcu->totvert - 1)) {
/* Set both handles to have same horizontal value as keyframe. */
if (fcu->extend == FCURVE_EXTRAPOLATE_CONSTANT) {
bezt->vec[0][1] = bezt->vec[2][1] = bezt->vec[1][1];
@@ -1658,7 +1736,7 @@ static float fcurve_eval_keyframes_extrapolate(
return endpoint_bezt->vec[1][1] - (fac * dx);
}
- /* Use the gradient of the second handle (later) of neighbour to calculate the gradient and thus
+ /* Use the gradient of the second handle (later) of neighbor to calculate the gradient and thus
* the value of the curve at evaluation time. */
int handle = direction_to_neighbor > 0 ? 0 : 2;
float dx = endpoint_bezt->vec[1][0] - evaltime;
@@ -1934,7 +2012,7 @@ static float fcurve_eval_keyframes_interpolate(FCurve *fcu, BezTriple *bezts, fl
return 0.0f;
}
-/* Calculate F-Curve value for 'evaltime' using BezTriple keyframes. */
+/* Calculate F-Curve value for 'evaltime' using #BezTriple keyframes. */
static float fcurve_eval_keyframes(FCurve *fcu, BezTriple *bezts, float evaltime)
{
if (evaltime <= bezts->vec[1][0]) {
@@ -1949,7 +2027,7 @@ static float fcurve_eval_keyframes(FCurve *fcu, BezTriple *bezts, float evaltime
return fcurve_eval_keyframes_interpolate(fcu, bezts, evaltime);
}
-/* Calculate F-Curve value for 'evaltime' using FPoint samples. */
+/* Calculate F-Curve value for 'evaltime' using #FPoint samples. */
static float fcurve_eval_samples(FCurve *fcu, FPoint *fpts, float evaltime)
{
FPoint *prevfpt, *lastfpt, *fpt;
diff --git a/source/blender/blenkernel/intern/fcurve_test.cc b/source/blender/blenkernel/intern/fcurve_test.cc
index a230c8f2e96..97dd541e2b9 100644
--- a/source/blender/blenkernel/intern/fcurve_test.cc
+++ b/source/blender/blenkernel/intern/fcurve_test.cc
@@ -290,7 +290,7 @@ TEST(fcurve_active_keyframe, ActiveKeyframe)
EXPECT_EQ(BKE_fcurve_active_keyframe_index(fcu), 2);
/* Check clearing the index. */
- BKE_fcurve_active_keyframe_set(fcu, NULL);
+ BKE_fcurve_active_keyframe_set(fcu, nullptr);
EXPECT_EQ(fcu->active_keyframe_index, FCURVE_ACTIVE_KEYFRAME_NONE);
EXPECT_EQ(BKE_fcurve_active_keyframe_index(fcu), FCURVE_ACTIVE_KEYFRAME_NONE);
diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c
index d93b635d67d..eb1d77eb0f4 100644
--- a/source/blender/blenkernel/intern/fluid.c
+++ b/source/blender/blenkernel/intern/fluid.c
@@ -80,7 +80,7 @@
# include "DEG_depsgraph.h"
# include "DEG_depsgraph_query.h"
-# include "RE_shader_ext.h"
+# include "RE_texture.h"
# include "CLG_log.h"
@@ -343,32 +343,37 @@ void BKE_fluid_cache_free(FluidDomainSettings *fds, Object *ob, int cache_map)
flags &= ~(FLUID_DOMAIN_BAKING_DATA | FLUID_DOMAIN_BAKED_DATA | FLUID_DOMAIN_OUTDATED_DATA);
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_CONFIG, NULL);
BLI_path_abs(temp_dir, relbase);
- BLI_delete(temp_dir, true, true); /* BLI_exists(filepath) is implicit */
-
+ if (BLI_exists(temp_dir)) {
+ BLI_delete(temp_dir, true, true);
+ }
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_DATA, NULL);
BLI_path_abs(temp_dir, relbase);
- BLI_delete(temp_dir, true, true); /* BLI_exists(filepath) is implicit */
-
+ if (BLI_exists(temp_dir)) {
+ BLI_delete(temp_dir, true, true);
+ }
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_SCRIPT, NULL);
BLI_path_abs(temp_dir, relbase);
- BLI_delete(temp_dir, true, true); /* BLI_exists(filepath) is implicit */
-
+ if (BLI_exists(temp_dir)) {
+ BLI_delete(temp_dir, true, true);
+ }
fds->cache_frame_pause_data = 0;
}
if (cache_map & FLUID_DOMAIN_OUTDATED_NOISE) {
flags &= ~(FLUID_DOMAIN_BAKING_NOISE | FLUID_DOMAIN_BAKED_NOISE | FLUID_DOMAIN_OUTDATED_NOISE);
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_NOISE, NULL);
BLI_path_abs(temp_dir, relbase);
- BLI_delete(temp_dir, true, true); /* BLI_exists(filepath) is implicit */
-
+ if (BLI_exists(temp_dir)) {
+ BLI_delete(temp_dir, true, true);
+ }
fds->cache_frame_pause_noise = 0;
}
if (cache_map & FLUID_DOMAIN_OUTDATED_MESH) {
flags &= ~(FLUID_DOMAIN_BAKING_MESH | FLUID_DOMAIN_BAKED_MESH | FLUID_DOMAIN_OUTDATED_MESH);
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_MESH, NULL);
BLI_path_abs(temp_dir, relbase);
- BLI_delete(temp_dir, true, true); /* BLI_exists(filepath) is implicit */
-
+ if (BLI_exists(temp_dir)) {
+ BLI_delete(temp_dir, true, true);
+ }
fds->cache_frame_pause_mesh = 0;
}
if (cache_map & FLUID_DOMAIN_OUTDATED_PARTICLES) {
@@ -377,17 +382,18 @@ void BKE_fluid_cache_free(FluidDomainSettings *fds, Object *ob, int cache_map)
BLI_path_join(
temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_PARTICLES, NULL);
BLI_path_abs(temp_dir, relbase);
- BLI_delete(temp_dir, true, true); /* BLI_exists(filepath) is implicit */
-
+ if (BLI_exists(temp_dir)) {
+ BLI_delete(temp_dir, true, true);
+ }
fds->cache_frame_pause_particles = 0;
}
-
if (cache_map & FLUID_DOMAIN_OUTDATED_GUIDE) {
flags &= ~(FLUID_DOMAIN_BAKING_GUIDE | FLUID_DOMAIN_BAKED_GUIDE | FLUID_DOMAIN_OUTDATED_GUIDE);
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_GUIDE, NULL);
BLI_path_abs(temp_dir, relbase);
- BLI_delete(temp_dir, true, true); /* BLI_exists(filepath) is implicit */
-
+ if (BLI_exists(temp_dir)) {
+ BLI_delete(temp_dir, true, true);
+ }
fds->cache_frame_pause_guide = 0;
}
fds->cache_flag = flags;
@@ -1987,7 +1993,7 @@ static void sample_mesh(FluidFlowSettings *ffs,
/* Convert xyz velocities flow settings from world to grid space. */
float convert_vel[3];
copy_v3_v3(convert_vel, ffs->vel_coord);
- float time_mult = 1.0 / (25.f * DT_DEFAULT);
+ float time_mult = 1.0 / (25.0f * DT_DEFAULT);
float size_mult = MAX3(base_res[0], base_res[1], base_res[2]) /
MAX3(global_size[0], global_size[1], global_size[2]);
mul_v3_v3fl(convert_vel, ffs->vel_coord, size_mult * time_mult);
@@ -3296,7 +3302,7 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Obj
/* If needed, vertex velocities will be read too. */
bool use_speedvectors = fds->flags & FLUID_DOMAIN_USE_SPEED_VECTORS;
FluidDomainVertexVelocity *velarray = NULL;
- float time_mult = 25.f * DT_DEFAULT;
+ float time_mult = 25.0f * DT_DEFAULT;
if (use_speedvectors) {
if (fds->mesh_velocities) {
@@ -4433,7 +4439,7 @@ float BKE_fluid_get_velocity_at(struct Object *ob, float position[3], float velo
if (fmd && (fmd->type & MOD_FLUID_TYPE_DOMAIN) && fmd->domain && fmd->domain->fluid) {
FluidDomainSettings *fds = fmd->domain;
- float time_mult = 25.f * DT_DEFAULT;
+ float time_mult = 25.0f * DT_DEFAULT;
float size_mult = MAX3(fds->global_size[0], fds->global_size[1], fds->global_size[2]) /
MAX3(fds->base_res[0], fds->base_res[1], fds->base_res[2]);
float vel_mag;
@@ -4700,9 +4706,11 @@ void BKE_fluid_fields_sanitize(FluidDomainSettings *settings)
const char data_depth = settings->openvdb_data_depth;
if (settings->type == FLUID_DOMAIN_TYPE_GAS) {
- if (coba_field == FLUID_DOMAIN_FIELD_PHI || coba_field == FLUID_DOMAIN_FIELD_PHI_IN ||
- coba_field == FLUID_DOMAIN_FIELD_PHI_OUT ||
- coba_field == FLUID_DOMAIN_FIELD_PHI_OBSTACLE) {
+ if (ELEM(coba_field,
+ FLUID_DOMAIN_FIELD_PHI,
+ FLUID_DOMAIN_FIELD_PHI_IN,
+ FLUID_DOMAIN_FIELD_PHI_OUT,
+ FLUID_DOMAIN_FIELD_PHI_OBSTACLE)) {
/* Defaulted to density for gas domain. */
settings->coba_field = FLUID_DOMAIN_FIELD_DENSITY;
}
@@ -4713,10 +4721,14 @@ void BKE_fluid_fields_sanitize(FluidDomainSettings *settings)
}
}
else if (settings->type == FLUID_DOMAIN_TYPE_LIQUID) {
- if (coba_field == FLUID_DOMAIN_FIELD_COLOR_R || coba_field == FLUID_DOMAIN_FIELD_COLOR_G ||
- coba_field == FLUID_DOMAIN_FIELD_COLOR_B || coba_field == FLUID_DOMAIN_FIELD_DENSITY ||
- coba_field == FLUID_DOMAIN_FIELD_FLAME || coba_field == FLUID_DOMAIN_FIELD_FUEL ||
- coba_field == FLUID_DOMAIN_FIELD_HEAT) {
+ if (ELEM(coba_field,
+ FLUID_DOMAIN_FIELD_COLOR_R,
+ FLUID_DOMAIN_FIELD_COLOR_G,
+ FLUID_DOMAIN_FIELD_COLOR_B,
+ FLUID_DOMAIN_FIELD_DENSITY,
+ FLUID_DOMAIN_FIELD_FLAME,
+ FLUID_DOMAIN_FIELD_FUEL,
+ FLUID_DOMAIN_FIELD_HEAT)) {
/* Defaulted to phi for liquid domain. */
settings->coba_field = FLUID_DOMAIN_FIELD_PHI;
}
@@ -4996,6 +5008,7 @@ void BKE_fluid_modifier_copy(const struct FluidModifierData *fmd,
tfds->fractions_threshold = fds->fractions_threshold;
tfds->fractions_distance = fds->fractions_distance;
tfds->sys_particle_maximum = fds->sys_particle_maximum;
+ tfds->simulation_method = fds->simulation_method;
/* diffusion options*/
tfds->surface_tension = fds->surface_tension;
diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c
index d13425f5ec9..6ebcef5caef 100644
--- a/source/blender/blenkernel/intern/fmodifier.c
+++ b/source/blender/blenkernel/intern/fmodifier.c
@@ -824,7 +824,8 @@ static void fcm_noise_evaluate(
* - 0.1 is passed as the 'z' value, otherwise evaluation fails for size = phase = 1
* with evaltime being an integer (which happens when evaluating on frame by frame basis)
*/
- noise = BLI_turbulence(data->size, evaltime - data->offset, data->phase, 0.1f, data->depth);
+ noise = BLI_noise_turbulence(
+ data->size, evaltime - data->offset, data->phase, 0.1f, data->depth);
/* combine the noise with existing motion data */
switch (data->modification) {
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index e0bbdfaeed6..9431915b4e4 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -168,6 +168,8 @@ IDTypeInfo IDType_ID_VF = {
.blend_read_data = vfont_blend_read_data,
.blend_read_lib = NULL,
.blend_read_expand = NULL,
+
+ .blend_read_undo_preserve = NULL,
};
/***************************** VFont *******************************/
@@ -947,7 +949,7 @@ static bool vfont_to_curve(Object *ob,
// CLOG_WARN(&LOG, "linewidth exceeded: %c%c%c...", mem[i], mem[i+1], mem[i+2]);
for (j = i; j && (mem[j] != '\n') && (chartransdata[j].dobreak == 0); j--) {
bool dobreak = false;
- if (mem[j] == ' ' || mem[j] == '-') {
+ if (ELEM(mem[j], ' ', '-')) {
ct -= (i - (j - 1));
cnr -= (i - (j - 1));
if (mem[j] == ' ') {
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 6c6ca996caa..4cf8e365cf6 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -288,6 +288,8 @@ IDTypeInfo IDType_ID_GD = {
.blend_read_data = greasepencil_blend_read_data,
.blend_read_lib = greasepencil_blend_read_lib,
.blend_read_expand = greasepencil_blend_read_expand,
+
+ .blend_read_undo_preserve = NULL,
};
/* ************************************************** */
@@ -2009,12 +2011,12 @@ void BKE_gpencil_material_remap(struct bGPdata *gpd,
/**
* Load a table with material conversion index for merged materials.
- * \param ob: Grease pencil object
- * \param hue_threshold: Threshold for Hue
- * \param sat_threshold: Threshold for Saturation
- * \param val_threshold: Threshold for Value
- * \param r_mat_table : return material table
- * \return True if done
+ * \param ob: Grease pencil object.
+ * \param hue_threshold: Threshold for Hue.
+ * \param sat_threshold: Threshold for Saturation.
+ * \param val_threshold: Threshold for Value.
+ * \param r_mat_table: return material table.
+ * \return True if done.
*/
bool BKE_gpencil_merge_materials_table_get(Object *ob,
const float hue_threshold,
@@ -2668,7 +2670,7 @@ void BKE_gpencil_parent_matrix_get(const Depsgraph *depsgraph,
return;
}
- if ((gpl->partype == PAROBJECT) || (gpl->partype == PARSKEL)) {
+ if (ELEM(gpl->partype, PAROBJECT, PARSKEL)) {
mul_m4_m4m4(diff_mat, obparent_eval->obmat, gpl->inverse);
add_v3_v3(diff_mat[3], ob_eval->obmat[3]);
return;
@@ -2710,7 +2712,7 @@ void BKE_gpencil_update_layer_parent(const Depsgraph *depsgraph, Object *ob)
if ((gpl->parent != NULL) && (gpl->actframe != NULL)) {
Object *ob_parent = DEG_get_evaluated_object(depsgraph, gpl->parent);
/* calculate new matrix */
- if ((gpl->partype == PAROBJECT) || (gpl->partype == PARSKEL)) {
+ if (ELEM(gpl->partype, PAROBJECT, PARSKEL)) {
copy_m4_m4(cur_mat, ob_parent->obmat);
}
else if (gpl->partype == PARBONE) {
diff --git a/source/blender/blenkernel/intern/gpencil_geom.c b/source/blender/blenkernel/intern/gpencil_geom.c
index 66a7ae757a2..ff7dde27db8 100644
--- a/source/blender/blenkernel/intern/gpencil_geom.c
+++ b/source/blender/blenkernel/intern/gpencil_geom.c
@@ -189,7 +189,7 @@ BoundBox *BKE_gpencil_boundbox_get(Object *ob)
/* Update orig object's boundbox with re-computed evaluated values. This function can be
* called with the evaluated object and need update the original object bound box data
* to keep both values synchronized. */
- if ((ob_orig != NULL) && (ob != ob_orig)) {
+ if (!ELEM(ob_orig, NULL, ob)) {
if (ob_orig->runtime.bb == NULL) {
ob_orig->runtime.bb = MEM_callocN(sizeof(BoundBox), "GPencil boundbox");
}
@@ -778,7 +778,7 @@ bool BKE_gpencil_stroke_smooth(bGPDstroke *gps, int i, float inf)
/* Only affect endpoints by a fraction of the normal strength,
* to prevent the stroke from shrinking too much
*/
- if ((i == 0) || (i == gps->totpoints - 1)) {
+ if (ELEM(i, 0, gps->totpoints - 1)) {
inf *= 0.1f;
}
@@ -838,7 +838,7 @@ bool BKE_gpencil_stroke_smooth_strength(bGPDstroke *gps, int point_index, float
}
/* Only affect endpoints by a fraction of the normal influence */
float inf = influence;
- if ((point_index == 0) || (point_index == gps->totpoints - 1)) {
+ if (ELEM(point_index, 0, gps->totpoints - 1)) {
inf *= 0.01f;
}
/* Limit max influence to reduce pop effect. */
@@ -902,7 +902,7 @@ bool BKE_gpencil_stroke_smooth_thickness(bGPDstroke *gps, int point_index, float
}
/* Only affect endpoints by a fraction of the normal influence */
float inf = influence;
- if ((point_index == 0) || (point_index == gps->totpoints - 1)) {
+ if (ELEM(point_index, 0, gps->totpoints - 1)) {
inf *= 0.01f;
}
/* Limit max influence to reduce pop effect. */
@@ -1402,7 +1402,7 @@ bool BKE_gpencil_stroke_trim(bGPDstroke *gps)
memcpy(dvert->dw, dvert_src->dw, sizeof(MDeformWeight));
}
}
- if (idx == start || idx == end) {
+ if (ELEM(idx, start, end)) {
copy_v3_v3(&pt_new->x, point);
}
}
diff --git a/source/blender/blenkernel/intern/gpencil_modifier.c b/source/blender/blenkernel/intern/gpencil_modifier.c
index d12e445fe99..be06638ab64 100644
--- a/source/blender/blenkernel/intern/gpencil_modifier.c
+++ b/source/blender/blenkernel/intern/gpencil_modifier.c
@@ -37,9 +37,12 @@
#include "DNA_gpencil_modifier_types.h"
#include "DNA_gpencil_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "BKE_colortools.h"
#include "BKE_gpencil.h"
#include "BKE_gpencil_geom.h"
#include "BKE_gpencil_modifier.h"
@@ -54,6 +57,8 @@
#include "MOD_gpencil_modifiertypes.h"
+#include "BLO_read_write.h"
+
#include "CLG_log.h"
static CLG_LogRef LOG = {"bke.gpencil_modifier"};
@@ -411,6 +416,11 @@ void BKE_gpencil_modifierType_panel_id(GpencilModifierType type, char *r_idname)
strcat(r_idname, mti->name);
}
+void BKE_gpencil_modifier_panel_expand(GpencilModifierData *md)
+{
+ md->ui_expand_flag |= UI_PANEL_DATA_EXPAND_ROOT;
+}
+
/**
* Generic grease pencil modifier copy data.
* \param md_src: Source modifier data
@@ -771,3 +781,159 @@ void BKE_gpencil_modifiers_calc(Depsgraph *depsgraph, Scene *scene, Object *ob)
/* Clear any lattice data. */
BKE_gpencil_lattice_clear(ob);
}
+
+void BKE_gpencil_modifier_blend_write(BlendWriter *writer, ListBase *modbase)
+{
+ if (modbase == NULL) {
+ return;
+ }
+
+ LISTBASE_FOREACH (GpencilModifierData *, md, modbase) {
+ const GpencilModifierTypeInfo *mti = BKE_gpencil_modifier_get_info(md->type);
+ if (mti == NULL) {
+ return;
+ }
+
+ BLO_write_struct_by_name(writer, mti->struct_name, md);
+
+ if (md->type == eGpencilModifierType_Thick) {
+ ThickGpencilModifierData *gpmd = (ThickGpencilModifierData *)md;
+
+ if (gpmd->curve_thickness) {
+ BKE_curvemapping_blend_write(writer, gpmd->curve_thickness);
+ }
+ }
+ else if (md->type == eGpencilModifierType_Noise) {
+ NoiseGpencilModifierData *gpmd = (NoiseGpencilModifierData *)md;
+
+ if (gpmd->curve_intensity) {
+ BKE_curvemapping_blend_write(writer, gpmd->curve_intensity);
+ }
+ }
+ else if (md->type == eGpencilModifierType_Hook) {
+ HookGpencilModifierData *gpmd = (HookGpencilModifierData *)md;
+
+ if (gpmd->curfalloff) {
+ BKE_curvemapping_blend_write(writer, gpmd->curfalloff);
+ }
+ }
+ else if (md->type == eGpencilModifierType_Tint) {
+ TintGpencilModifierData *gpmd = (TintGpencilModifierData *)md;
+ if (gpmd->colorband) {
+ BLO_write_struct(writer, ColorBand, gpmd->colorband);
+ }
+ if (gpmd->curve_intensity) {
+ BKE_curvemapping_blend_write(writer, gpmd->curve_intensity);
+ }
+ }
+ else if (md->type == eGpencilModifierType_Smooth) {
+ SmoothGpencilModifierData *gpmd = (SmoothGpencilModifierData *)md;
+ if (gpmd->curve_intensity) {
+ BKE_curvemapping_blend_write(writer, gpmd->curve_intensity);
+ }
+ }
+ else if (md->type == eGpencilModifierType_Color) {
+ ColorGpencilModifierData *gpmd = (ColorGpencilModifierData *)md;
+ if (gpmd->curve_intensity) {
+ BKE_curvemapping_blend_write(writer, gpmd->curve_intensity);
+ }
+ }
+ else if (md->type == eGpencilModifierType_Opacity) {
+ OpacityGpencilModifierData *gpmd = (OpacityGpencilModifierData *)md;
+ if (gpmd->curve_intensity) {
+ BKE_curvemapping_blend_write(writer, gpmd->curve_intensity);
+ }
+ }
+ }
+}
+
+void BKE_gpencil_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb)
+{
+ BLO_read_list(reader, lb);
+
+ LISTBASE_FOREACH (GpencilModifierData *, md, lb) {
+ md->error = NULL;
+
+ /* if modifiers disappear, or for upward compatibility */
+ if (NULL == BKE_gpencil_modifier_get_info(md->type)) {
+ md->type = eModifierType_None;
+ }
+
+ if (md->type == eGpencilModifierType_Lattice) {
+ LatticeGpencilModifierData *gpmd = (LatticeGpencilModifierData *)md;
+ gpmd->cache_data = NULL;
+ }
+ else if (md->type == eGpencilModifierType_Hook) {
+ HookGpencilModifierData *hmd = (HookGpencilModifierData *)md;
+
+ BLO_read_data_address(reader, &hmd->curfalloff);
+ if (hmd->curfalloff) {
+ BKE_curvemapping_blend_read(reader, hmd->curfalloff);
+ }
+ }
+ else if (md->type == eGpencilModifierType_Noise) {
+ NoiseGpencilModifierData *gpmd = (NoiseGpencilModifierData *)md;
+
+ BLO_read_data_address(reader, &gpmd->curve_intensity);
+ if (gpmd->curve_intensity) {
+ BKE_curvemapping_blend_read(reader, gpmd->curve_intensity);
+ /* initialize the curve. Maybe this could be moved to modififer logic */
+ BKE_curvemapping_init(gpmd->curve_intensity);
+ }
+ }
+ else if (md->type == eGpencilModifierType_Thick) {
+ ThickGpencilModifierData *gpmd = (ThickGpencilModifierData *)md;
+
+ BLO_read_data_address(reader, &gpmd->curve_thickness);
+ if (gpmd->curve_thickness) {
+ BKE_curvemapping_blend_read(reader, gpmd->curve_thickness);
+ BKE_curvemapping_init(gpmd->curve_thickness);
+ }
+ }
+ 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);
+ if (gpmd->curve_intensity) {
+ BKE_curvemapping_blend_read(reader, gpmd->curve_intensity);
+ BKE_curvemapping_init(gpmd->curve_intensity);
+ }
+ }
+ else if (md->type == eGpencilModifierType_Smooth) {
+ SmoothGpencilModifierData *gpmd = (SmoothGpencilModifierData *)md;
+ BLO_read_data_address(reader, &gpmd->curve_intensity);
+ if (gpmd->curve_intensity) {
+ BKE_curvemapping_blend_read(reader, gpmd->curve_intensity);
+ BKE_curvemapping_init(gpmd->curve_intensity);
+ }
+ }
+ else if (md->type == eGpencilModifierType_Color) {
+ ColorGpencilModifierData *gpmd = (ColorGpencilModifierData *)md;
+ BLO_read_data_address(reader, &gpmd->curve_intensity);
+ if (gpmd->curve_intensity) {
+ BKE_curvemapping_blend_read(reader, gpmd->curve_intensity);
+ BKE_curvemapping_init(gpmd->curve_intensity);
+ }
+ }
+ else if (md->type == eGpencilModifierType_Opacity) {
+ OpacityGpencilModifierData *gpmd = (OpacityGpencilModifierData *)md;
+ BLO_read_data_address(reader, &gpmd->curve_intensity);
+ if (gpmd->curve_intensity) {
+ BKE_curvemapping_blend_read(reader, gpmd->curve_intensity);
+ BKE_curvemapping_init(gpmd->curve_intensity);
+ }
+ }
+ }
+}
+
+void BKE_gpencil_modifier_blend_read_lib(BlendLibReader *reader, Object *ob)
+{
+ BKE_gpencil_modifiers_foreach_ID_link(ob, BKE_object_modifiers_lib_link_common, reader);
+
+ /* If linking from a library, clear 'local' library override flag. */
+ if (ob->id.lib != NULL) {
+ LISTBASE_FOREACH (GpencilModifierData *, mod, &ob->greasepencil_modifiers) {
+ mod->flag &= ~eGpencilModifierFlag_OverrideLibrary_Local;
+ }
+ }
+}
diff --git a/source/blender/blenkernel/intern/hair.c b/source/blender/blenkernel/intern/hair.c
index 313b0d192dc..554919ad1a0 100644
--- a/source/blender/blenkernel/intern/hair.c
+++ b/source/blender/blenkernel/intern/hair.c
@@ -195,6 +195,8 @@ IDTypeInfo IDType_ID_HA = {
.blend_read_data = hair_blend_read_data,
.blend_read_lib = hair_blend_read_lib,
.blend_read_expand = hair_blend_read_expand,
+
+ .blend_read_undo_preserve = NULL,
};
static void hair_random(Hair *hair)
diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c
index bcec90cf0cf..eec9013d067 100644
--- a/source/blender/blenkernel/intern/icons.c
+++ b/source/blender/blenkernel/intern/icons.c
@@ -899,8 +899,10 @@ struct Icon_Geom *BKE_icon_geom_from_file(const char *filename)
/** \} */
+/* -------------------------------------------------------------------- */
/** \name Studio Light Icon
* \{ */
+
int BKE_icon_ensure_studio_light(struct StudioLight *sl, int id_type)
{
int icon_id = get_next_free_id();
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index 113d4cf50d7..b0991f1d343 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -68,9 +68,7 @@ static size_t idp_size_table[] = {
};
/* -------------------------------------------------------------------- */
-/* Array Functions */
-
-/** \name IDP Array API
+/** \name Array Functions (IDP Array API)
* \{ */
#define GETPROP(prop, i) &(IDP_IDPArray(prop)[i])
@@ -323,9 +321,7 @@ static IDProperty *IDP_CopyArray(const IDProperty *prop, const int flag)
/** \} */
/* -------------------------------------------------------------------- */
-/* String Functions */
-
-/** \name IDProperty String API
+/** \name String Functions (IDProperty String API)
* \{ */
/**
@@ -439,9 +435,7 @@ void IDP_FreeString(IDProperty *prop)
/** \} */
/* -------------------------------------------------------------------- */
-/* ID Type */
-
-/** \name IDProperty ID API
+/** \name ID Type (IDProperty ID API)
* \{ */
static IDProperty *IDP_CopyID(const IDProperty *prop, const int flag)
@@ -477,9 +471,7 @@ void IDP_AssignID(IDProperty *prop, ID *id, const int flag)
/** \} */
/* -------------------------------------------------------------------- */
-/* Group Functions */
-
-/** \name IDProperty Group API
+/** \name Group Functions (IDProperty Group API)
* \{ */
/**
@@ -760,10 +752,9 @@ static void IDP_FreeGroup(IDProperty *prop, const bool do_id_user)
/** \} */
/* -------------------------------------------------------------------- */
-/* Main Functions */
-
-/** \name IDProperty Main API
+/** \name Main Functions (IDProperty Main API)
* \{ */
+
IDProperty *IDP_CopyProperty_ex(const IDProperty *prop, const int flag)
{
switch (prop->type) {
@@ -800,43 +791,6 @@ void IDP_CopyPropertyContent(IDProperty *dst, IDProperty *src)
IDP_FreeProperty(idprop_tmp);
}
-/* Updates ID pointers after an object has been copied */
-/* TODO Nuke this once its only user has been correctly converted
- * to use generic ID management from BKE_library! */
-void IDP_RelinkProperty(struct IDProperty *prop)
-{
- if (!prop) {
- return;
- }
-
- switch (prop->type) {
- case IDP_GROUP: {
- LISTBASE_FOREACH (IDProperty *, loop, &prop->data.group) {
- IDP_RelinkProperty(loop);
- }
- break;
- }
- case IDP_IDPARRAY: {
- IDProperty *idp_array = IDP_Array(prop);
- for (int i = 0; i < prop->len; i++) {
- IDP_RelinkProperty(&idp_array[i]);
- }
- break;
- }
- case IDP_ID: {
- ID *id = IDP_Id(prop);
- if (id && id->newid) {
- id_us_min(IDP_Id(prop));
- prop->data.pointer = id->newid;
- id_us_plus(IDP_Id(prop));
- }
- break;
- }
- default:
- break; /* Nothing to do for other IDProp types. */
- }
-}
-
/**
* Get the Group property that contains the id properties for ID id. Set create_if_needed
* to create the Group property and attach it to id if it doesn't exist; otherwise
@@ -961,7 +915,7 @@ bool IDP_EqualsProperties(IDProperty *prop1, IDProperty *prop2)
* This function takes three arguments: the ID property type, a union which defines
* its initial value, and a name.
*
- * The union is simple to use; see the top of this header file for its definition.
+ * The union is simple to use; see the top of BKE_idprop.h for its definition.
* An example of using this function:
*
* \code{.c}
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 187908573dd..f87b1b5ff45 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -84,7 +84,6 @@
#include "BKE_packedFile.h"
#include "BKE_report.h"
#include "BKE_scene.h"
-#include "BKE_sequencer.h" /* seq_foreground_frame_get() */
#include "BKE_workspace.h"
#include "BLF_api.h"
@@ -93,6 +92,8 @@
#include "RE_pipeline.h"
+#include "SEQ_sequencer.h" /* seq_foreground_frame_get() */
+
#include "GPU_texture.h"
#include "BLI_sys_types.h" /* for intptr_t support */
@@ -324,6 +325,8 @@ IDTypeInfo IDType_ID_IM = {
.blend_read_data = image_blend_read_data,
.blend_read_lib = image_blend_read_lib,
.blend_read_expand = NULL,
+
+ .blend_read_undo_preserve = NULL,
};
/* prototypes */
@@ -665,7 +668,7 @@ ImageTile *BKE_image_get_tile(Image *ima, int tile_number)
/* Tile number 0 is a special case and refers to the first tile, typically
* coming from non-UDIM-aware code. */
- if (tile_number == 0 || tile_number == 1001) {
+ if (ELEM(tile_number, 0, 1001)) {
return ima->tiles.first;
}
@@ -802,7 +805,7 @@ Image *BKE_image_load_exists_ex(Main *bmain, const char *filepath, bool *r_exist
/* first search an identical filepath */
for (ima = bmain->images.first; ima; ima = ima->id.next) {
- if (ima->source != IMA_SRC_VIEWER && ima->source != IMA_SRC_GENERATED) {
+ if (!ELEM(ima->source, IMA_SRC_VIEWER, IMA_SRC_GENERATED)) {
STRNCPY(strtest, ima->filepath);
BLI_path_abs(strtest, ID_BLEND_PATH(bmain, &ima->id));
@@ -1313,7 +1316,7 @@ int BKE_image_imtype_to_ftype(const char imtype, ImbFormatOptions *r_options)
return IMB_FTYPE_TIF;
}
#endif
- if (imtype == R_IMF_IMTYPE_OPENEXR || imtype == R_IMF_IMTYPE_MULTILAYER) {
+ if (ELEM(imtype, R_IMF_IMTYPE_OPENEXR, R_IMF_IMTYPE_MULTILAYER)) {
return IMB_FTYPE_OPENEXR;
}
#ifdef WITH_CINEON
@@ -1663,7 +1666,7 @@ static bool do_add_image_extension(char *string,
}
#endif
#ifdef WITH_OPENEXR
- else if (imtype == R_IMF_IMTYPE_OPENEXR || imtype == R_IMF_IMTYPE_MULTILAYER) {
+ else if (ELEM(imtype, R_IMF_IMTYPE_OPENEXR, R_IMF_IMTYPE_MULTILAYER)) {
if (!BLI_path_extension_check(string, extension_test = ".exr")) {
extension = extension_test;
}
diff --git a/source/blender/blenkernel/intern/image_gen.c b/source/blender/blenkernel/intern/image_gen.c
index 877747a257e..ceb13c4955e 100644
--- a/source/blender/blenkernel/intern/image_gen.c
+++ b/source/blender/blenkernel/intern/image_gen.c
@@ -379,10 +379,16 @@ static void checker_board_text(
const float text_color[4] = {0.0, 0.0, 0.0, 1.0};
const float text_outline[4] = {1.0, 1.0, 1.0, 1.0};
+ const char char_array[36] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
+ int first_char_index = 0;
for (y = 0; y < height; y += step) {
- text[1] = '1';
+ text[0] = char_array[first_char_index];
+ int second_char_index = 27;
for (x = 0; x < width; x += step) {
+ text[1] = char_array[second_char_index];
+
/* hard coded offset */
pen_x = x + 33;
pen_y = y + 44;
@@ -412,9 +418,9 @@ static void checker_board_text(
BLF_position(mono, pen_x, pen_y, 0.0);
BLF_draw_buffer(mono, text, 2);
- text[1]++;
+ second_char_index = (second_char_index + 1) % ARRAY_SIZE(char_array);
}
- text[0]++;
+ first_char_index = (first_char_index + 1) % ARRAY_SIZE(char_array);
}
/* cleanup the buffer. */
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index 1a87b931689..9696d920640 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -52,6 +52,7 @@
#include "BLI_blenlib.h"
#include "BLI_dynstr.h"
+#include "BLI_endian_switch.h"
#include "BLI_string_utils.h"
#include "BLI_utildefines.h"
@@ -68,12 +69,15 @@
#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_nla.h"
-#include "BKE_sequencer.h"
#include "CLG_log.h"
#include "MEM_guardedalloc.h"
+#include "SEQ_sequencer.h"
+
+#include "BLO_read_write.h"
+
#ifdef WIN32
# include "BLI_math_base.h" /* M_PI */
#endif
@@ -109,6 +113,69 @@ static void ipo_free_data(ID *id)
}
}
+static void ipo_blend_read_data(BlendDataReader *reader, ID *id)
+{
+ Ipo *ipo = (Ipo *)id;
+
+ BLO_read_list(reader, &(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);
+
+ /* Undo generic endian switching. */
+ if (BLO_read_requires_endian_switch(reader)) {
+ BLI_endian_switch_int16(&icu->blocktype);
+ if (icu->driver != NULL) {
+
+ /* Undo generic endian switching. */
+ if (BLO_read_requires_endian_switch(reader)) {
+ BLI_endian_switch_int16(&icu->blocktype);
+ if (icu->driver != NULL) {
+ BLI_endian_switch_int16(&icu->driver->blocktype);
+ }
+ }
+ }
+
+ /* Undo generic endian switching. */
+ if (BLO_read_requires_endian_switch(reader)) {
+ BLI_endian_switch_int16(&ipo->blocktype);
+ if (icu->driver != NULL) {
+ BLI_endian_switch_int16(&icu->driver->blocktype);
+ }
+ }
+ }
+ }
+
+ /* Undo generic endian switching. */
+ if (BLO_read_requires_endian_switch(reader)) {
+ BLI_endian_switch_int16(&ipo->blocktype);
+ }
+}
+
+static void ipo_blend_read_lib(BlendLibReader *reader, ID *id)
+{
+ Ipo *ipo = (Ipo *)id;
+
+ LISTBASE_FOREACH (IpoCurve *, icu, &ipo->curve) {
+ if (icu->driver) {
+ BLO_read_id_address(reader, ipo->id.lib, &icu->driver->ob);
+ }
+ }
+}
+
+static void ipo_blend_read_expand(BlendExpander *expander, ID *id)
+{
+ Ipo *ipo = (Ipo *)id;
+
+ LISTBASE_FOREACH (IpoCurve *, icu, &ipo->curve) {
+ if (icu->driver) {
+ BLO_expand(expander, icu->driver->ob);
+ }
+ }
+}
+
IDTypeInfo IDType_ID_IP = {
.id_code = ID_IP,
.id_filter = 0,
@@ -128,9 +195,11 @@ IDTypeInfo IDType_ID_IP = {
.foreach_cache = NULL,
.blend_write = NULL,
- .blend_read_data = NULL,
- .blend_read_lib = NULL,
- .blend_read_expand = NULL,
+ .blend_read_data = ipo_blend_read_data,
+ .blend_read_lib = ipo_blend_read_lib,
+ .blend_read_expand = ipo_blend_read_expand,
+
+ .blend_read_undo_preserve = NULL,
};
/* *************************************************** */
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index 95a8419b95d..7468112b40e 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -214,6 +214,8 @@ IDTypeInfo IDType_ID_KE = {
.blend_read_data = shapekey_blend_read_data,
.blend_read_lib = shapekey_blend_read_lib,
.blend_read_expand = shapekey_blend_read_expand,
+
+ .blend_read_undo_preserve = NULL,
};
#define KEY_MODE_DUMMY 0 /* use where mode isn't checked for */
@@ -1614,7 +1616,7 @@ int BKE_keyblock_element_count_from_shape(const Key *key, const int shape_index)
int result = 0;
int index = 0;
for (const KeyBlock *kb = key->block.first; kb; kb = kb->next, index++) {
- if ((shape_index == -1) || (index == shape_index)) {
+ if (ELEM(shape_index, -1, index)) {
result += kb->totelem;
}
}
@@ -1654,7 +1656,7 @@ void BKE_keyblock_data_get_from_shape(const Key *key, float (*arr)[3], const int
uint8_t *elements = (uint8_t *)arr;
int index = 0;
for (const KeyBlock *kb = key->block.first; kb; kb = kb->next, index++) {
- if ((shape_index == -1) || (index == shape_index)) {
+ if (ELEM(shape_index, -1, index)) {
const int block_elem_len = kb->totelem * key->elemsize;
memcpy(elements, kb->data, block_elem_len);
elements += block_elem_len;
@@ -1684,7 +1686,7 @@ void BKE_keyblock_data_set_with_mat4(Key *key,
int index = 0;
for (KeyBlock *kb = key->block.first; kb; kb = kb->next, index++) {
- if ((shape_index == -1) || (index == shape_index)) {
+ if (ELEM(shape_index, -1, index)) {
const int block_elem_len = kb->totelem;
float(*block_data)[3] = (float(*)[3])kb->data;
for (int data_offset = 0; data_offset < block_elem_len; ++data_offset) {
@@ -1708,7 +1710,7 @@ void BKE_keyblock_curve_data_set_with_mat4(
int index = 0;
for (KeyBlock *kb = key->block.first; kb; kb = kb->next, index++) {
- if ((shape_index == -1) || (index == shape_index)) {
+ if (ELEM(shape_index, -1, index)) {
const int block_elem_size = kb->totelem * key->elemsize;
BKE_keyblock_curve_data_transform(nurb, mat, elements, kb->data);
elements += block_elem_size;
@@ -1724,7 +1726,7 @@ void BKE_keyblock_data_set(Key *key, const int shape_index, const void *data)
const uint8_t *elements = data;
int index = 0;
for (KeyBlock *kb = key->block.first; kb; kb = kb->next, index++) {
- if ((shape_index == -1) || (index == shape_index)) {
+ if (ELEM(shape_index, -1, index)) {
const int block_elem_size = kb->totelem * key->elemsize;
memcpy(kb->data, elements, block_elem_size);
elements += block_elem_size;
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index c0eb6b4b134..74f78106be5 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -203,6 +203,8 @@ IDTypeInfo IDType_ID_LT = {
.blend_read_data = lattice_blend_read_data,
.blend_read_lib = lattice_blend_read_lib,
.blend_read_expand = lattice_blend_read_expand,
+
+ .blend_read_undo_preserve = NULL,
};
int BKE_lattice_index_from_uvw(Lattice *lt, const int u, const int v, const int w)
diff --git a/source/blender/blenkernel/intern/lattice_deform.c b/source/blender/blenkernel/intern/lattice_deform.c
index 382661ff070..14c600caa46 100644
--- a/source/blender/blenkernel/intern/lattice_deform.c
+++ b/source/blender/blenkernel/intern/lattice_deform.c
@@ -169,7 +169,7 @@ void BKE_lattice_deform_data_eval_co(LatticeDeformData *lattice_deform_data,
int ui, vi, wi, uu, vv, ww;
/* vgroup influence */
- float co_prev[3], weight_blend = 0.0f;
+ float co_prev[4] = {0}, weight_blend = 0.0f;
copy_v3_v3(co_prev, co);
#ifdef __SSE2__
__m128 co_vec = _mm_loadu_ps(co_prev);
diff --git a/source/blender/blenkernel/intern/lattice_deform_test.cc b/source/blender/blenkernel/intern/lattice_deform_test.cc
index 7db9d941458..f08d0349598 100644
--- a/source/blender/blenkernel/intern/lattice_deform_test.cc
+++ b/source/blender/blenkernel/intern/lattice_deform_test.cc
@@ -83,7 +83,7 @@ static void test_lattice_deform_free(LatticeDeformTestContext *ctx)
TEST(lattice_deform_performance, performance_no_dvert_1)
{
const int32_t num_items = 1;
- LatticeDeformTestContext ctx = {{{0}}};
+ LatticeDeformTestContext ctx = {{{nullptr}}};
RandomNumberGenerator rng;
test_lattice_deform_init(&ctx, &rng, num_items);
test_lattice_deform(&ctx, num_items);
@@ -92,7 +92,7 @@ TEST(lattice_deform_performance, performance_no_dvert_1)
TEST(lattice_deform_performance, performance_no_dvert_1000)
{
const int32_t num_items = 1000;
- LatticeDeformTestContext ctx = {{{0}}};
+ LatticeDeformTestContext ctx = {{{nullptr}}};
RandomNumberGenerator rng;
test_lattice_deform_init(&ctx, &rng, num_items);
test_lattice_deform(&ctx, num_items);
@@ -101,7 +101,7 @@ TEST(lattice_deform_performance, performance_no_dvert_1000)
TEST(lattice_deform_performance, performance_no_dvert_10000)
{
const int32_t num_items = 10000;
- LatticeDeformTestContext ctx = {{{0}}};
+ LatticeDeformTestContext ctx = {{{nullptr}}};
RandomNumberGenerator rng;
test_lattice_deform_init(&ctx, &rng, num_items);
test_lattice_deform(&ctx, num_items);
@@ -110,7 +110,7 @@ TEST(lattice_deform_performance, performance_no_dvert_10000)
TEST(lattice_deform_performance, performance_no_dvert_100000)
{
const int32_t num_items = 100000;
- LatticeDeformTestContext ctx = {{{0}}};
+ LatticeDeformTestContext ctx = {{{nullptr}}};
RandomNumberGenerator rng;
test_lattice_deform_init(&ctx, &rng, num_items);
test_lattice_deform(&ctx, num_items);
@@ -119,7 +119,7 @@ TEST(lattice_deform_performance, performance_no_dvert_100000)
TEST(lattice_deform_performance, performance_no_dvert_1000000)
{
const int32_t num_items = 1000000;
- LatticeDeformTestContext ctx = {{{0}}};
+ LatticeDeformTestContext ctx = {{{nullptr}}};
RandomNumberGenerator rng;
test_lattice_deform_init(&ctx, &rng, num_items);
test_lattice_deform(&ctx, num_items);
@@ -128,7 +128,7 @@ TEST(lattice_deform_performance, performance_no_dvert_1000000)
TEST(lattice_deform_performance, performance_no_dvert_10000000)
{
const int32_t num_items = 10000000;
- LatticeDeformTestContext ctx = {{{0}}};
+ LatticeDeformTestContext ctx = {{{nullptr}}};
RandomNumberGenerator rng;
test_lattice_deform_init(&ctx, &rng, num_items);
test_lattice_deform(&ctx, num_items);
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index 6efc9d0753e..784cd5b2edf 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -18,6 +18,9 @@
* \ingroup bke
*/
+/* Allow using deprecated functionality for .blend file I/O. */
+#define DNA_DEPRECATED_ALLOW
+
#include <string.h>
#include "BLI_listbase.h"
@@ -56,6 +59,8 @@
#include "MEM_guardedalloc.h"
+#include "BLO_read_write.h"
+
/* Set of flags which are dependent on a collection settings. */
static const short g_base_collection_flags = (BASE_VISIBLE_DEPSGRAPH | BASE_VISIBLE_VIEWLAYER |
BASE_SELECTABLE | BASE_ENABLED_VIEWPORT |
@@ -1445,12 +1450,9 @@ static LayerCollection *find_layer_collection_by_scene_collection(LayerCollectio
LayerCollection *BKE_layer_collection_first_from_scene_collection(ViewLayer *view_layer,
const Collection *collection)
{
- for (LayerCollection *layer_collection = view_layer->layer_collections.first;
- layer_collection != NULL;
- layer_collection = layer_collection->next) {
+ LISTBASE_FOREACH (LayerCollection *, layer_collection, &view_layer->layer_collections) {
LayerCollection *found = find_layer_collection_by_scene_collection(layer_collection,
collection);
-
if (found != NULL) {
return found;
}
@@ -1830,3 +1832,117 @@ void BKE_layer_eval_view_layer_indexed(struct Depsgraph *depsgraph,
BLI_assert(view_layer != NULL);
layer_eval_view_layer(depsgraph, scene, view_layer);
}
+
+static void write_layer_collections(BlendWriter *writer, ListBase *lb)
+{
+ LISTBASE_FOREACH (LayerCollection *, lc, lb) {
+ BLO_write_struct(writer, LayerCollection, lc);
+
+ write_layer_collections(writer, &lc->layer_collections);
+ }
+}
+
+void BKE_view_layer_blend_write(BlendWriter *writer, ViewLayer *view_layer)
+{
+ BLO_write_struct(writer, ViewLayer, view_layer);
+ BLO_write_struct_list(writer, Base, &view_layer->object_bases);
+
+ if (view_layer->id_properties) {
+ IDP_BlendWrite(writer, view_layer->id_properties);
+ }
+
+ LISTBASE_FOREACH (FreestyleModuleConfig *, fmc, &view_layer->freestyle_config.modules) {
+ BLO_write_struct(writer, FreestyleModuleConfig, fmc);
+ }
+
+ LISTBASE_FOREACH (FreestyleLineSet *, fls, &view_layer->freestyle_config.linesets) {
+ BLO_write_struct(writer, FreestyleLineSet, fls);
+ }
+ write_layer_collections(writer, &view_layer->layer_collections);
+}
+
+static void direct_link_layer_collections(BlendDataReader *reader, ListBase *lb, bool master)
+{
+ BLO_read_list(reader, lb);
+ LISTBASE_FOREACH (LayerCollection *, lc, lb) {
+#ifdef USE_COLLECTION_COMPAT_28
+ BLO_read_data_address(reader, &lc->scene_collection);
+#endif
+
+ /* Master collection is not a real data-lock. */
+ if (master) {
+ BLO_read_data_address(reader, &lc->collection);
+ }
+
+ direct_link_layer_collections(reader, &lc->layer_collections, false);
+ }
+}
+
+void BKE_view_layer_blend_read_data(BlendDataReader *reader, ViewLayer *view_layer)
+{
+ view_layer->stats = NULL;
+ BLO_read_list(reader, &view_layer->object_bases);
+ BLO_read_data_address(reader, &view_layer->basact);
+
+ direct_link_layer_collections(reader, &view_layer->layer_collections, true);
+ BLO_read_data_address(reader, &view_layer->active_collection);
+
+ BLO_read_data_address(reader, &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));
+
+ BLI_listbase_clear(&view_layer->drawdata);
+ view_layer->object_bases_array = NULL;
+ view_layer->object_bases_hash = NULL;
+}
+
+static void lib_link_layer_collection(BlendLibReader *reader,
+ Library *lib,
+ LayerCollection *layer_collection,
+ bool master)
+{
+ /* Master collection is not a real data-lock. */
+ if (!master) {
+ BLO_read_id_address(reader, lib, &layer_collection->collection);
+ }
+
+ LISTBASE_FOREACH (
+ LayerCollection *, layer_collection_nested, &layer_collection->layer_collections) {
+ lib_link_layer_collection(reader, lib, layer_collection_nested, false);
+ }
+}
+
+void BKE_view_layer_blend_read_lib(BlendLibReader *reader, Library *lib, ViewLayer *view_layer)
+{
+ LISTBASE_FOREACH (FreestyleModuleConfig *, fmc, &view_layer->freestyle_config.modules) {
+ BLO_read_id_address(reader, lib, &fmc->script);
+ }
+
+ LISTBASE_FOREACH (FreestyleLineSet *, fls, &view_layer->freestyle_config.linesets) {
+ BLO_read_id_address(reader, lib, &fls->linestyle);
+ BLO_read_id_address(reader, lib, &fls->group);
+ }
+
+ LISTBASE_FOREACH_MUTABLE (Base *, base, &view_layer->object_bases) {
+ /* we only bump the use count for the collection objects */
+ BLO_read_id_address(reader, lib, &base->object);
+
+ if (base->object == NULL) {
+ /* Free in case linked object got lost. */
+ BLI_freelinkN(&view_layer->object_bases, base);
+ if (view_layer->basact == base) {
+ view_layer->basact = NULL;
+ }
+ }
+ }
+
+ LISTBASE_FOREACH (LayerCollection *, layer_collection, &view_layer->layer_collections) {
+ lib_link_layer_collection(reader, lib, layer_collection, true);
+ }
+
+ BLO_read_id_address(reader, lib, &view_layer->mat_override);
+
+ IDP_BlendReadLib(reader, view_layer->id_properties);
+}
diff --git a/source/blender/blenkernel/intern/lib_id.c b/source/blender/blenkernel/intern/lib_id.c
index ae6ee71da82..cf9fff811ce 100644
--- a/source/blender/blenkernel/intern/lib_id.c
+++ b/source/blender/blenkernel/intern/lib_id.c
@@ -101,6 +101,15 @@ IDTypeInfo IDType_ID_LINK_PLACEHOLDER = {
.copy_data = NULL,
.free_data = NULL,
.make_local = NULL,
+ .foreach_id = NULL,
+ .foreach_cache = NULL,
+
+ .blend_write = NULL,
+ .blend_read_data = NULL,
+ .blend_read_lib = NULL,
+ .blend_read_expand = NULL,
+
+ .blend_read_undo_preserve = NULL,
};
/* GS reads the memory pointed at in a specific ordering.
@@ -1322,7 +1331,7 @@ void id_sort_by_name(ListBase *lb, ID *id, ID *id_sorting_hint)
BLI_remlink(lb, id);
/* Check if we can actually insert id before or after id_sorting_hint, if given. */
- if (id_sorting_hint != NULL && id_sorting_hint != id) {
+ if (!ELEM(id_sorting_hint, NULL, id)) {
BLI_assert(BLI_findindex(lb, id_sorting_hint) >= 0);
ID *id_sorting_hint_next = id_sorting_hint->next;
@@ -1560,7 +1569,7 @@ static bool check_for_dupid(ListBase *lb, ID *id, char *name, ID **r_id_sorting_
char base_name_test[MAX_ID_NAME - 2];
int number_test;
if ((id != id_test) && !ID_IS_LINKED(id_test) && (name[0] == id_test->name[2]) &&
- (id_test->name[base_name_len + 2] == '.' || id_test->name[base_name_len + 2] == '\0') &&
+ (ELEM(id_test->name[base_name_len + 2], '.', '\0')) &&
STREQLEN(name, id_test->name + 2, base_name_len) &&
(BLI_split_name_num(base_name_test, &number_test, id_test->name + 2, '.') ==
base_name_len)) {
diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c
index f19ab96588e..aa5e28b35bf 100644
--- a/source/blender/blenkernel/intern/lib_override.c
+++ b/source/blender/blenkernel/intern/lib_override.c
@@ -1359,7 +1359,7 @@ bool BKE_lib_override_library_operations_create(Main *bmain, ID *local)
}
if (GS(local->name) == ID_OB) {
- /* Our beloved pose's bone cross-data pointers.. Usually, depsgraph evaluation would
+ /* Our beloved pose's bone cross-data pointers. Usually, depsgraph evaluation would
* ensure this is valid, but in some situations (like hidden collections etc.) this won't
* be the case, so we need to take care of this ourselves. */
Object *ob_local = (Object *)local;
@@ -1427,9 +1427,9 @@ void BKE_lib_override_library_main_operations_create(Main *bmain, const bool for
}
/* Usual pose bones issue, need to be done outside of the threaded process or we may run into
- * concurency issues here.
+ * concurrency issues here.
* Note that calling #BKE_pose_ensure again in thread in
- * #BKE_lib_override_library_operations_create is not a problem then.. */
+ * #BKE_lib_override_library_operations_create is not a problem then. */
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
if (ob->type == OB_ARMATURE) {
BLI_assert(ob->data != NULL);
@@ -1442,6 +1442,15 @@ void BKE_lib_override_library_main_operations_create(Main *bmain, const bool for
FOREACH_MAIN_ID_BEGIN (bmain, id) {
if (ID_IS_OVERRIDE_LIBRARY_REAL(id) &&
(force_auto || (id->tag & LIB_TAG_OVERRIDE_LIBRARY_AUTOREFRESH))) {
+ /* Usual issue with pose, it's quiet rare but sometimes they may not be up to date when this
+ * function is called. */
+ if (GS(id->name) == ID_OB) {
+ Object *ob = (Object *)id;
+ if (ob->type == OB_ARMATURE) {
+ BLI_assert(ob->data != NULL);
+ BKE_pose_ensure(bmain, ob, ob->data, true);
+ }
+ }
/* Only check overrides if we do have the real reference data available, and not some empty
* 'placeholder' for missing data (broken links). */
if ((id->override_library->reference->tag & LIB_TAG_MISSING) == 0) {
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 949e10d4721..6a560d51362 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -82,6 +82,8 @@ IDTypeInfo IDType_ID_LI = {
.blend_read_data = NULL,
.blend_read_lib = NULL,
.blend_read_expand = NULL,
+
+ .blend_read_undo_preserve = NULL,
};
void BKE_library_filepath_set(Main *bmain, Library *lib, const char *filepath)
diff --git a/source/blender/blenkernel/intern/light.c b/source/blender/blenkernel/intern/light.c
index 4780f0cf208..a47a0c043ff 100644
--- a/source/blender/blenkernel/intern/light.c
+++ b/source/blender/blenkernel/intern/light.c
@@ -207,6 +207,8 @@ IDTypeInfo IDType_ID_LA = {
.blend_read_data = light_blend_read_data,
.blend_read_lib = light_blend_read_lib,
.blend_read_expand = light_blend_read_expand,
+
+ .blend_read_undo_preserve = NULL,
};
Light *BKE_light_add(Main *bmain, const char *name)
diff --git a/source/blender/blenkernel/intern/lightprobe.c b/source/blender/blenkernel/intern/lightprobe.c
index 31653a9a0ac..0553c070fdf 100644
--- a/source/blender/blenkernel/intern/lightprobe.c
+++ b/source/blender/blenkernel/intern/lightprobe.c
@@ -105,6 +105,8 @@ IDTypeInfo IDType_ID_LP = {
.blend_read_data = lightprobe_blend_read_data,
.blend_read_lib = lightprobe_blend_read_lib,
.blend_read_expand = NULL,
+
+ .blend_read_undo_preserve = NULL,
};
void BKE_lightprobe_type_set(LightProbe *probe, const short lightprobe_type)
diff --git a/source/blender/blenkernel/intern/linestyle.c b/source/blender/blenkernel/intern/linestyle.c
index 733a2bcd1e1..69e6535a59f 100644
--- a/source/blender/blenkernel/intern/linestyle.c
+++ b/source/blender/blenkernel/intern/linestyle.c
@@ -765,6 +765,8 @@ IDTypeInfo IDType_ID_LS = {
.blend_read_data = linestyle_blend_read_data,
.blend_read_lib = linestyle_blend_read_lib,
.blend_read_expand = linestyle_blend_read_expand,
+
+ .blend_read_undo_preserve = NULL,
};
static const char *modifier_name[LS_MODIFIER_NUM] = {
diff --git a/source/blender/blenkernel/intern/main_idmap.c b/source/blender/blenkernel/intern/main_idmap.c
index 9a6ead7eb2b..21f5e9c6fb2 100644
--- a/source/blender/blenkernel/intern/main_idmap.c
+++ b/source/blender/blenkernel/intern/main_idmap.c
@@ -36,6 +36,7 @@
* Utility functions for faster ID lookups.
*/
+/* -------------------------------------------------------------------- */
/** \name BKE_main_idmap API
*
* Cache ID (name, library lookups).
diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index 1f9f155ee55..04fec1e57c4 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -268,6 +268,8 @@ IDTypeInfo IDType_ID_MSK = {
.blend_read_data = mask_blend_read_data,
.blend_read_lib = mask_blend_read_lib,
.blend_read_expand = mask_blend_read_expand,
+
+ .blend_read_undo_preserve = NULL,
};
static struct {
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 4a85fab4e18..e892a3f4d53 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -272,6 +272,8 @@ IDTypeInfo IDType_ID_MA = {
.blend_read_data = material_blend_read_data,
.blend_read_lib = material_blend_read_lib,
.blend_read_expand = material_blend_read_expand,
+
+ .blend_read_undo_preserve = NULL,
};
void BKE_gpencil_material_attr_init(Material *ma)
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c
index d2bacb7d3bc..65ec91c57cf 100644
--- a/source/blender/blenkernel/intern/mball.c
+++ b/source/blender/blenkernel/intern/mball.c
@@ -202,6 +202,8 @@ IDTypeInfo IDType_ID_MB = {
.blend_read_data = metaball_blend_read_data,
.blend_read_lib = metaball_blend_read_lib,
.blend_read_expand = metaball_blend_read_expand,
+
+ .blend_read_undo_preserve = NULL,
};
/* Functions */
diff --git a/source/blender/blenkernel/intern/mball_tessellate.c b/source/blender/blenkernel/intern/mball_tessellate.c
index 7273d2a920d..cb01927d992 100644
--- a/source/blender/blenkernel/intern/mball_tessellate.c
+++ b/source/blender/blenkernel/intern/mball_tessellate.c
@@ -807,22 +807,22 @@ static void makecubetable(void)
INTLIST *edges;
for (edges = polys->list; edges; edges = edges->next) {
- if (edges->i == LB || edges->i == LT || edges->i == LN || edges->i == LF) {
+ if (ELEM(edges->i, LB, LT, LN, LF)) {
faces[i] |= 1 << L;
}
- if (edges->i == RB || edges->i == RT || edges->i == RN || edges->i == RF) {
+ if (ELEM(edges->i, RB, RT, RN, RF)) {
faces[i] |= 1 << R;
}
- if (edges->i == LB || edges->i == RB || edges->i == BN || edges->i == BF) {
+ if (ELEM(edges->i, LB, RB, BN, BF)) {
faces[i] |= 1 << B;
}
- if (edges->i == LT || edges->i == RT || edges->i == TN || edges->i == TF) {
+ if (ELEM(edges->i, LT, RT, TN, TF)) {
faces[i] |= 1 << T;
}
- if (edges->i == LN || edges->i == RN || edges->i == BN || edges->i == TN) {
+ if (ELEM(edges->i, LN, RN, BN, TN)) {
faces[i] |= 1 << N;
}
- if (edges->i == LF || edges->i == RF || edges->i == BF || edges->i == TF) {
+ if (ELEM(edges->i, LF, RF, BF, TF)) {
faces[i] |= 1 << F;
}
}
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index ba47b8fc4af..9ccdf5189d1 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -275,50 +275,6 @@ static void mesh_blend_read_data(BlendDataReader *reader, ID *id)
mesh->totselect = 0;
}
- /* Multires data */
- BLO_read_data_address(reader, &mesh->mr);
- if (mesh->mr) {
- BLO_read_list(reader, &mesh->mr->levels);
- MultiresLevel *lvl = mesh->mr->levels.first;
-
- CustomData_blend_read(reader, &mesh->mr->vdata, lvl->totvert);
- BKE_defvert_blend_read(
- reader, lvl->totvert, CustomData_get(&mesh->mr->vdata, 0, CD_MDEFORMVERT));
- CustomData_blend_read(reader, &mesh->mr->fdata, lvl->totface);
-
- BLO_read_data_address(reader, &mesh->mr->edge_flags);
- BLO_read_data_address(reader, &mesh->mr->edge_creases);
-
- BLO_read_data_address(reader, &mesh->mr->verts);
-
- /* If mesh has the same number of vertices as the
- * highest multires level, load the current mesh verts
- * into multires and discard the old data. Needed
- * because some saved files either do not have a verts
- * array, or the verts array contains out-of-date
- * data. */
- if (mesh->totvert == ((MultiresLevel *)mesh->mr->levels.last)->totvert) {
- if (mesh->mr->verts) {
- MEM_freeN(mesh->mr->verts);
- }
- mesh->mr->verts = MEM_dupallocN(mesh->mvert);
- }
-
- for (; lvl; lvl = lvl->next) {
- BLO_read_data_address(reader, &lvl->verts);
- BLO_read_data_address(reader, &lvl->faces);
- BLO_read_data_address(reader, &lvl->edges);
- BLO_read_data_address(reader, &lvl->colfaces);
- }
- }
-
- /* if multires is present but has no valid vertex data,
- * there's no way to recover it; silently remove multires */
- if (mesh->mr && !mesh->mr->verts) {
- multires_free(mesh->mr);
- mesh->mr = NULL;
- }
-
if ((BLO_read_requires_endian_switch(reader)) && mesh->tface) {
TFace *tf = mesh->tface;
for (int i = 0; i < mesh->totface; i++, tf++) {
@@ -377,6 +333,8 @@ IDTypeInfo IDType_ID_ME = {
.blend_read_data = mesh_blend_read_data,
.blend_read_lib = mesh_blend_read_lib,
.blend_read_expand = mesh_read_expand,
+
+ .blend_read_undo_preserve = NULL,
};
enum {
@@ -1540,8 +1498,11 @@ void BKE_mesh_transform(Mesh *me, const float mat[4][4], bool do_keys)
void BKE_mesh_translate(Mesh *me, const float offset[3], const bool do_keys)
{
+ MVert *mvert = CustomData_duplicate_referenced_layer(&me->vdata, CD_MVERT, me->totvert);
+ /* If the referenced layer has been re-allocated need to update pointers stored in the mesh. */
+ BKE_mesh_update_customdata_pointers(me, false);
+
int i = me->totvert;
- MVert *mvert;
for (mvert = me->mvert; i--; mvert++) {
add_v3_v3(mvert->co, offset);
}
diff --git a/source/blender/blenkernel/intern/mesh_convert.c b/source/blender/blenkernel/intern/mesh_convert.c
index ae301aca25a..8272bd07411 100644
--- a/source/blender/blenkernel/intern/mesh_convert.c
+++ b/source/blender/blenkernel/intern/mesh_convert.c
@@ -949,7 +949,7 @@ void BKE_mesh_to_pointcloud(Main *bmain, Depsgraph *depsgraph, Scene *UNUSED(sce
BKE_object_free_derived_caches(ob);
}
-void BKE_mesh_from_pointcloud(PointCloud *pointcloud, Mesh *me)
+void BKE_mesh_from_pointcloud(const PointCloud *pointcloud, Mesh *me)
{
BLI_assert(pointcloud != NULL);
diff --git a/source/blender/blenkernel/intern/mesh_merge.c b/source/blender/blenkernel/intern/mesh_merge.c
index 868694931cb..e118c1b6f6e 100644
--- a/source/blender/blenkernel/intern/mesh_merge.c
+++ b/source/blender/blenkernel/intern/mesh_merge.c
@@ -61,7 +61,7 @@ static int cddm_poly_compare(MLoop *mloop_array,
MLoop *mloop_source, *mloop_target;
- BLI_assert(direct_reverse == 1 || direct_reverse == -1);
+ BLI_assert(ELEM(direct_reverse, 1, -1));
i_loop_source = 0;
mloop_source = mloop_array + mpoly_source->loopstart;
diff --git a/source/blender/blenkernel/intern/mesh_remap.c b/source/blender/blenkernel/intern/mesh_remap.c
index 1c48cf6f3cb..f3b29171762 100644
--- a/source/blender/blenkernel/intern/mesh_remap.c
+++ b/source/blender/blenkernel/intern/mesh_remap.c
@@ -327,6 +327,7 @@ void BKE_mesh_remap_find_best_match_from_mesh(const MVert *verts_dst,
/** \} */
+/* -------------------------------------------------------------------- */
/** \name Mesh to mesh mapping
* \{ */
diff --git a/source/blender/blenkernel/intern/mesh_runtime.c b/source/blender/blenkernel/intern/mesh_runtime.c
index 150f7f19edc..f35f4ae3501 100644
--- a/source/blender/blenkernel/intern/mesh_runtime.c
+++ b/source/blender/blenkernel/intern/mesh_runtime.c
@@ -267,6 +267,7 @@ void BKE_mesh_batch_cache_free(Mesh *me)
/** \} */
+/* -------------------------------------------------------------------- */
/** \name Mesh runtime debug helpers.
* \{ */
/* evaluated mesh info printing function,
diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c
index 6fea2cc8bf5..b3c53df2d5f 100644
--- a/source/blender/blenkernel/intern/mesh_validate.c
+++ b/source/blender/blenkernel/intern/mesh_validate.c
@@ -52,6 +52,7 @@
static CLG_LogRef LOG = {"bke.mesh"};
+/* -------------------------------------------------------------------- */
/** \name Internal functions
* \{ */
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 0aa85f0ad50..3c8b685a0e0 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -24,6 +24,9 @@
* \ingroup bke
*/
+/* Allow using deprecated functionality for .blend file I/O. */
+#define DNA_DEPRECATED_ALLOW
+
#include <float.h>
#include <math.h>
#include <stdarg.h>
@@ -34,10 +37,15 @@
#include "MEM_guardedalloc.h"
#include "DNA_armature_types.h"
+#include "DNA_cloth_types.h"
+#include "DNA_fluid_types.h"
#include "DNA_gpencil_modifier_types.h"
#include "DNA_mesh_types.h"
+#include "DNA_object_fluidsim_types.h"
+#include "DNA_object_force_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
#include "BLI_linklist.h"
#include "BLI_listbase.h"
@@ -53,6 +61,8 @@
#include "BKE_appdir.h"
#include "BKE_editmesh.h"
#include "BKE_editmesh_cache.h"
+#include "BKE_effect.h"
+#include "BKE_fluid.h"
#include "BKE_global.h"
#include "BKE_gpencil_modifier.h"
#include "BKE_idtype.h"
@@ -63,6 +73,7 @@
#include "BKE_mesh_wrapper.h"
#include "BKE_multires.h"
#include "BKE_object.h"
+#include "BKE_pointcache.h"
/* may move these, only for BKE_modifier_path_relbase */
#include "BKE_main.h"
@@ -73,6 +84,8 @@
#include "MOD_modifiertypes.h"
+#include "BLO_read_write.h"
+
#include "CLG_log.h"
static CLG_LogRef LOG = {"bke.modifier"};
@@ -130,6 +143,11 @@ void BKE_modifier_type_panel_id(ModifierType type, char *r_idname)
strcat(r_idname, mti->name);
}
+void BKE_modifier_panel_expand(ModifierData *md)
+{
+ md->ui_expand_flag |= UI_PANEL_DATA_EXPAND_ROOT;
+}
+
/***/
ModifierData *BKE_modifier_new(int type)
@@ -389,7 +407,7 @@ bool BKE_modifier_is_non_geometrical(ModifierData *md)
return (mti->type == eModifierTypeType_NonGeometrical);
}
-void BKE_modifier_set_error(ModifierData *md, const char *_format, ...)
+void BKE_modifier_set_error(const Object *ob, ModifierData *md, const char *_format, ...)
{
char buffer[512];
va_list ap;
@@ -406,7 +424,16 @@ void BKE_modifier_set_error(ModifierData *md, const char *_format, ...)
md->error = BLI_strdup(buffer);
- CLOG_STR_ERROR(&LOG, md->error);
+#ifndef NDEBUG
+ if ((md->mode & eModifierMode_Virtual) == 0) {
+ /* Ensure correct object is passed in. */
+ const Object *ob_orig = (Object *)DEG_get_original_id((ID *)&ob->id);
+ const ModifierData *md_orig = md->orig_modifier_data ? md->orig_modifier_data : md;
+ BLI_assert(BLI_findindex(&ob_orig->modifiers, md_orig) != -1);
+ }
+#endif
+
+ CLOG_ERROR(&LOG, "Object: \"%s\", Modifier: \"%s\", %s", ob->id.name + 2, md->name, md->error);
}
/* used for buttons, to find out if the 'draw deformed in editmode' option is
@@ -1101,3 +1128,423 @@ void BKE_modifier_check_uuids_unique_and_report(const Object *object)
BLI_gset_free(used_uuids, NULL);
}
+
+void BKE_modifier_blend_write(BlendWriter *writer, ListBase *modbase)
+{
+ if (modbase == NULL) {
+ return;
+ }
+
+ LISTBASE_FOREACH (ModifierData *, md, modbase) {
+ const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
+ if (mti == NULL) {
+ return;
+ }
+
+ BLO_write_struct_by_name(writer, mti->structName, md);
+
+ if (md->type == eModifierType_Cloth) {
+ ClothModifierData *clmd = (ClothModifierData *)md;
+
+ BLO_write_struct(writer, ClothSimSettings, clmd->sim_parms);
+ BLO_write_struct(writer, ClothCollSettings, clmd->coll_parms);
+ BLO_write_struct(writer, EffectorWeights, clmd->sim_parms->effector_weights);
+ BKE_ptcache_blend_write(writer, &clmd->ptcaches);
+ }
+ else if (md->type == eModifierType_Fluid) {
+ FluidModifierData *fmd = (FluidModifierData *)md;
+
+ if (fmd->type & MOD_FLUID_TYPE_DOMAIN) {
+ BLO_write_struct(writer, FluidDomainSettings, fmd->domain);
+
+ if (fmd->domain) {
+ BKE_ptcache_blend_write(writer, &(fmd->domain->ptcaches[0]));
+
+ /* create fake pointcache so that old blender versions can read it */
+ fmd->domain->point_cache[1] = BKE_ptcache_add(&fmd->domain->ptcaches[1]);
+ fmd->domain->point_cache[1]->flag |= PTCACHE_DISK_CACHE | PTCACHE_FAKE_SMOKE;
+ fmd->domain->point_cache[1]->step = 1;
+
+ BKE_ptcache_blend_write(writer, &(fmd->domain->ptcaches[1]));
+
+ if (fmd->domain->coba) {
+ BLO_write_struct(writer, ColorBand, fmd->domain->coba);
+ }
+
+ /* cleanup the fake pointcache */
+ BKE_ptcache_free_list(&fmd->domain->ptcaches[1]);
+ fmd->domain->point_cache[1] = NULL;
+
+ BLO_write_struct(writer, EffectorWeights, fmd->domain->effector_weights);
+ }
+ }
+ else if (fmd->type & MOD_FLUID_TYPE_FLOW) {
+ BLO_write_struct(writer, FluidFlowSettings, fmd->flow);
+ }
+ else if (fmd->type & MOD_FLUID_TYPE_EFFEC) {
+ BLO_write_struct(writer, FluidEffectorSettings, fmd->effector);
+ }
+ }
+ else if (md->type == eModifierType_Fluidsim) {
+ FluidsimModifierData *fluidmd = (FluidsimModifierData *)md;
+
+ BLO_write_struct(writer, FluidsimSettings, fluidmd->fss);
+ }
+ else if (md->type == eModifierType_DynamicPaint) {
+ DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md;
+
+ if (pmd->canvas) {
+ BLO_write_struct(writer, DynamicPaintCanvasSettings, pmd->canvas);
+
+ /* write surfaces */
+ LISTBASE_FOREACH (DynamicPaintSurface *, surface, &pmd->canvas->surfaces) {
+ BLO_write_struct(writer, DynamicPaintSurface, surface);
+ }
+ /* write caches and effector weights */
+ LISTBASE_FOREACH (DynamicPaintSurface *, surface, &pmd->canvas->surfaces) {
+ BKE_ptcache_blend_write(writer, &(surface->ptcaches));
+
+ BLO_write_struct(writer, EffectorWeights, surface->effector_weights);
+ }
+ }
+ if (pmd->brush) {
+ BLO_write_struct(writer, DynamicPaintBrushSettings, pmd->brush);
+ BLO_write_struct(writer, ColorBand, pmd->brush->paint_ramp);
+ BLO_write_struct(writer, ColorBand, pmd->brush->vel_ramp);
+ }
+ }
+ else if (md->type == eModifierType_Collision) {
+
+#if 0
+ CollisionModifierData *collmd = (CollisionModifierData *)md;
+ // TODO: CollisionModifier should use pointcache
+ // + have proper reset events before enabling this
+ writestruct(wd, DATA, MVert, collmd->numverts, collmd->x);
+ writestruct(wd, DATA, MVert, collmd->numverts, collmd->xnew);
+ writestruct(wd, DATA, MFace, collmd->numfaces, collmd->mfaces);
+#endif
+ }
+
+ if (mti->blendWrite != NULL) {
+ mti->blendWrite(writer, md);
+ }
+ }
+}
+
+/* TODO(sergey): Find a better place for this.
+ *
+ * Unfortunately, this can not be done as a regular do_versions() since the modifier type is
+ * set to NONE, so the do_versions code wouldn't know where the modifier came from.
+ *
+ * The best approach seems to have the functionality in versioning_280.c but still call the
+ * function from #BKE_modifier_blend_read_data().
+ */
+
+/* Domain, inflow, ... */
+static void modifier_ensure_type(FluidModifierData *fluid_modifier_data, int type)
+{
+ fluid_modifier_data->type = type;
+ BKE_fluid_modifier_free(fluid_modifier_data);
+ BKE_fluid_modifier_create_type_data(fluid_modifier_data);
+}
+
+/**
+ * \note The old_modifier_data is NOT linked.
+ * This means that in order to access sub-data pointers #BLO_read_get_new_data_address is to be
+ * used.
+ */
+static ModifierData *modifier_replace_with_fluid(BlendDataReader *reader,
+ Object *object,
+ ListBase *modifiers,
+ ModifierData *old_modifier_data)
+{
+ ModifierData *new_modifier_data = BKE_modifier_new(eModifierType_Fluid);
+ FluidModifierData *fluid_modifier_data = (FluidModifierData *)new_modifier_data;
+
+ if (old_modifier_data->type == eModifierType_Fluidsim) {
+ FluidsimModifierData *old_fluidsim_modifier_data = (FluidsimModifierData *)old_modifier_data;
+ FluidsimSettings *old_fluidsim_settings = BLO_read_get_new_data_address(
+ reader, old_fluidsim_modifier_data->fss);
+ switch (old_fluidsim_settings->type) {
+ case OB_FLUIDSIM_ENABLE:
+ modifier_ensure_type(fluid_modifier_data, 0);
+ break;
+ case OB_FLUIDSIM_DOMAIN:
+ modifier_ensure_type(fluid_modifier_data, MOD_FLUID_TYPE_DOMAIN);
+ BKE_fluid_domain_type_set(object, fluid_modifier_data->domain, FLUID_DOMAIN_TYPE_LIQUID);
+ break;
+ case OB_FLUIDSIM_FLUID:
+ modifier_ensure_type(fluid_modifier_data, MOD_FLUID_TYPE_FLOW);
+ BKE_fluid_flow_type_set(object, fluid_modifier_data->flow, FLUID_FLOW_TYPE_LIQUID);
+ /* No need to emit liquid far away from surface. */
+ fluid_modifier_data->flow->surface_distance = 0.0f;
+ break;
+ case OB_FLUIDSIM_OBSTACLE:
+ modifier_ensure_type(fluid_modifier_data, MOD_FLUID_TYPE_EFFEC);
+ BKE_fluid_effector_type_set(
+ object, fluid_modifier_data->effector, FLUID_EFFECTOR_TYPE_COLLISION);
+ break;
+ case OB_FLUIDSIM_INFLOW:
+ modifier_ensure_type(fluid_modifier_data, MOD_FLUID_TYPE_FLOW);
+ BKE_fluid_flow_type_set(object, fluid_modifier_data->flow, FLUID_FLOW_TYPE_LIQUID);
+ BKE_fluid_flow_behavior_set(object, fluid_modifier_data->flow, FLUID_FLOW_BEHAVIOR_INFLOW);
+ /* No need to emit liquid far away from surface. */
+ fluid_modifier_data->flow->surface_distance = 0.0f;
+ break;
+ case OB_FLUIDSIM_OUTFLOW:
+ modifier_ensure_type(fluid_modifier_data, MOD_FLUID_TYPE_FLOW);
+ BKE_fluid_flow_type_set(object, fluid_modifier_data->flow, FLUID_FLOW_TYPE_LIQUID);
+ BKE_fluid_flow_behavior_set(
+ object, fluid_modifier_data->flow, FLUID_FLOW_BEHAVIOR_OUTFLOW);
+ break;
+ case OB_FLUIDSIM_PARTICLE:
+ /* "Particle" type objects not being used by Mantaflow fluid simulations.
+ * Skip this object, secondary particles can only be enabled through the domain object. */
+ break;
+ case OB_FLUIDSIM_CONTROL:
+ /* "Control" type objects not being used by Mantaflow fluid simulations.
+ * Use guiding type instead which is similar. */
+ modifier_ensure_type(fluid_modifier_data, MOD_FLUID_TYPE_EFFEC);
+ BKE_fluid_effector_type_set(
+ object, fluid_modifier_data->effector, FLUID_EFFECTOR_TYPE_GUIDE);
+ break;
+ }
+ }
+ else if (old_modifier_data->type == eModifierType_Smoke) {
+ SmokeModifierData *old_smoke_modifier_data = (SmokeModifierData *)old_modifier_data;
+ modifier_ensure_type(fluid_modifier_data, old_smoke_modifier_data->type);
+ if (fluid_modifier_data->type == MOD_FLUID_TYPE_DOMAIN) {
+ BKE_fluid_domain_type_set(object, fluid_modifier_data->domain, FLUID_DOMAIN_TYPE_GAS);
+ }
+ else if (fluid_modifier_data->type == MOD_FLUID_TYPE_FLOW) {
+ BKE_fluid_flow_type_set(object, fluid_modifier_data->flow, FLUID_FLOW_TYPE_SMOKE);
+ }
+ else if (fluid_modifier_data->type == MOD_FLUID_TYPE_EFFEC) {
+ BKE_fluid_effector_type_set(
+ object, fluid_modifier_data->effector, FLUID_EFFECTOR_TYPE_COLLISION);
+ }
+ }
+
+ /* Replace modifier data in the stack. */
+ new_modifier_data->next = old_modifier_data->next;
+ new_modifier_data->prev = old_modifier_data->prev;
+ if (new_modifier_data->prev != NULL) {
+ new_modifier_data->prev->next = new_modifier_data;
+ }
+ if (new_modifier_data->next != NULL) {
+ new_modifier_data->next->prev = new_modifier_data;
+ }
+ if (modifiers->first == old_modifier_data) {
+ modifiers->first = new_modifier_data;
+ }
+ if (modifiers->last == old_modifier_data) {
+ modifiers->last = new_modifier_data;
+ }
+
+ /* Free old modifier data. */
+ MEM_freeN(old_modifier_data);
+
+ return new_modifier_data;
+}
+
+void BKE_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb, Object *ob)
+{
+ BLO_read_list(reader, lb);
+
+ LISTBASE_FOREACH (ModifierData *, md, lb) {
+ BKE_modifier_session_uuid_generate(md);
+
+ md->error = NULL;
+ md->runtime = NULL;
+
+ /* Modifier data has been allocated as a part of data migration process and
+ * no reading of nested fields from file is needed. */
+ bool is_allocated = false;
+
+ if (md->type == eModifierType_Fluidsim) {
+ BLO_reportf_wrap(
+ BLO_read_data_reports(reader),
+ RPT_WARNING,
+ TIP_("Possible data loss when saving this file! %s modifier is deprecated (Object: %s)"),
+ md->name,
+ ob->id.name + 2);
+ md = modifier_replace_with_fluid(reader, ob, lb, md);
+ is_allocated = true;
+ }
+ else if (md->type == eModifierType_Smoke) {
+ BLO_reportf_wrap(
+ BLO_read_data_reports(reader),
+ RPT_WARNING,
+ TIP_("Possible data loss when saving this file! %s modifier is deprecated (Object: %s)"),
+ md->name,
+ ob->id.name + 2);
+ md = modifier_replace_with_fluid(reader, ob, lb, md);
+ is_allocated = true;
+ }
+
+ const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
+
+ /* if modifiers disappear, or for upward compatibility */
+ if (mti == NULL) {
+ md->type = eModifierType_None;
+ }
+
+ if (is_allocated) {
+ /* All the fields has been properly allocated. */
+ }
+ else if (md->type == eModifierType_Cloth) {
+ ClothModifierData *clmd = (ClothModifierData *)md;
+
+ clmd->clothObject = NULL;
+ clmd->hairdata = NULL;
+
+ BLO_read_data_address(reader, &clmd->sim_parms);
+ BLO_read_data_address(reader, &clmd->coll_parms);
+
+ BKE_ptcache_blend_read_data(reader, &clmd->ptcaches, &clmd->point_cache, 0);
+
+ if (clmd->sim_parms) {
+ if (clmd->sim_parms->presets > 10) {
+ clmd->sim_parms->presets = 0;
+ }
+
+ clmd->sim_parms->reset = 0;
+
+ BLO_read_data_address(reader, &clmd->sim_parms->effector_weights);
+
+ if (!clmd->sim_parms->effector_weights) {
+ clmd->sim_parms->effector_weights = BKE_effector_add_weights(NULL);
+ }
+ }
+
+ clmd->solver_result = NULL;
+ }
+ else if (md->type == eModifierType_Fluid) {
+
+ FluidModifierData *fmd = (FluidModifierData *)md;
+
+ if (fmd->type == MOD_FLUID_TYPE_DOMAIN) {
+ fmd->flow = NULL;
+ fmd->effector = NULL;
+ BLO_read_data_address(reader, &fmd->domain);
+ fmd->domain->fmd = fmd;
+
+ fmd->domain->fluid = NULL;
+ fmd->domain->fluid_mutex = BLI_rw_mutex_alloc();
+ fmd->domain->tex_density = NULL;
+ fmd->domain->tex_color = NULL;
+ fmd->domain->tex_shadow = NULL;
+ fmd->domain->tex_flame = NULL;
+ fmd->domain->tex_flame_coba = NULL;
+ fmd->domain->tex_coba = NULL;
+ fmd->domain->tex_field = NULL;
+ fmd->domain->tex_velocity_x = NULL;
+ fmd->domain->tex_velocity_y = NULL;
+ fmd->domain->tex_velocity_z = NULL;
+ fmd->domain->tex_wt = NULL;
+ fmd->domain->mesh_velocities = NULL;
+ BLO_read_data_address(reader, &fmd->domain->coba);
+
+ BLO_read_data_address(reader, &fmd->domain->effector_weights);
+ if (!fmd->domain->effector_weights) {
+ fmd->domain->effector_weights = BKE_effector_add_weights(NULL);
+ }
+
+ BKE_ptcache_blend_read_data(
+ reader, &(fmd->domain->ptcaches[0]), &(fmd->domain->point_cache[0]), 1);
+
+ /* Manta sim uses only one cache from now on, so store pointer convert */
+ if (fmd->domain->ptcaches[1].first || fmd->domain->point_cache[1]) {
+ if (fmd->domain->point_cache[1]) {
+ PointCache *cache = BLO_read_get_new_data_address(reader, fmd->domain->point_cache[1]);
+ if (cache->flag & PTCACHE_FAKE_SMOKE) {
+ /* Manta-sim/smoke was already saved in "new format" and this cache is a fake one. */
+ }
+ else {
+ printf(
+ "High resolution manta cache not available due to pointcache update. Please "
+ "reset the simulation.\n");
+ }
+ BKE_ptcache_free(cache);
+ }
+ BLI_listbase_clear(&fmd->domain->ptcaches[1]);
+ fmd->domain->point_cache[1] = NULL;
+ }
+ }
+ else if (fmd->type == MOD_FLUID_TYPE_FLOW) {
+ fmd->domain = NULL;
+ fmd->effector = NULL;
+ BLO_read_data_address(reader, &fmd->flow);
+ fmd->flow->fmd = fmd;
+ fmd->flow->mesh = NULL;
+ fmd->flow->verts_old = NULL;
+ fmd->flow->numverts = 0;
+ BLO_read_data_address(reader, &fmd->flow->psys);
+ }
+ else if (fmd->type == MOD_FLUID_TYPE_EFFEC) {
+ fmd->flow = NULL;
+ fmd->domain = NULL;
+ BLO_read_data_address(reader, &fmd->effector);
+ if (fmd->effector) {
+ fmd->effector->fmd = fmd;
+ fmd->effector->verts_old = NULL;
+ fmd->effector->numverts = 0;
+ fmd->effector->mesh = NULL;
+ }
+ else {
+ fmd->type = 0;
+ fmd->flow = NULL;
+ fmd->domain = NULL;
+ fmd->effector = NULL;
+ }
+ }
+ }
+ else if (md->type == eModifierType_DynamicPaint) {
+ DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md;
+
+ if (pmd->canvas) {
+ BLO_read_data_address(reader, &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);
+
+ LISTBASE_FOREACH (DynamicPaintSurface *, surface, &pmd->canvas->surfaces) {
+ surface->canvas = pmd->canvas;
+ surface->data = NULL;
+ BKE_ptcache_blend_read_data(reader, &(surface->ptcaches), &(surface->pointcache), 1);
+
+ BLO_read_data_address(reader, &surface->effector_weights);
+ if (surface->effector_weights == NULL) {
+ surface->effector_weights = BKE_effector_add_weights(NULL);
+ }
+ }
+ }
+ }
+ if (pmd->brush) {
+ BLO_read_data_address(reader, &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);
+ }
+ }
+
+ if (mti->blendRead != NULL) {
+ mti->blendRead(reader, md);
+ }
+ }
+}
+
+void BKE_modifier_blend_read_lib(BlendLibReader *reader, Object *ob)
+{
+ BKE_modifiers_foreach_ID_link(ob, BKE_object_modifiers_lib_link_common, reader);
+
+ /* If linking from a library, clear 'local' library override flag. */
+ if (ob->id.lib != NULL) {
+ LISTBASE_FOREACH (ModifierData *, mod, &ob->modifiers) {
+ mod->flag &= ~eModifierFlag_OverrideLibrary_Local;
+ }
+ }
+}
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index 40b12d8a777..564496744df 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -359,6 +359,8 @@ IDTypeInfo IDType_ID_MC = {
.blend_read_data = movieclip_blend_read_data,
.blend_read_lib = movieclip_blend_read_lib,
.blend_read_expand = NULL,
+
+ .blend_read_undo_preserve = NULL,
};
/*********************** movieclip buffer loaders *************************/
@@ -519,7 +521,7 @@ static void movieclip_convert_multilayer_add_pass(void *UNUSED(layer),
MEM_freeN(rect);
return;
}
- if (STREQ(pass_name, RE_PASSNAME_COMBINED) || STREQ(chan_id, "RGBA") || STREQ(chan_id, "RGB")) {
+ if (STREQ(pass_name, RE_PASSNAME_COMBINED) || STR_ELEM(chan_id, "RGBA", "RGB")) {
ctx->combined_pass = rect;
ctx->num_combined_channels = num_channels;
}
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index 6e1168d8a16..441da8b134a 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -63,7 +63,6 @@
#include <string.h>
/* MULTIRES MODIFIER */
-static const int multires_max_levels = 13;
static const int multires_grid_tot[] = {
0, 4, 9, 25, 81, 289, 1089, 4225, 16641, 66049, 263169, 1050625, 4198401, 16785409};
static const int multires_side_tot[] = {
@@ -76,7 +75,6 @@ typedef enum {
ADD_DISPLACEMENTS,
} DispOp;
-static void multires_mvert_to_ss(DerivedMesh *dm, MVert *mvert);
static void multiresModifier_disp_run(
DerivedMesh *dm, Mesh *me, DerivedMesh *dm2, DispOp op, CCGElem **oldGridData, int totlvl);
@@ -241,40 +239,6 @@ static void multires_mdisps_subdivide_hidden(MDisps *md, int new_level)
md->hidden = subd;
}
-static MDisps *multires_mdisps_init_hidden(Mesh *me, int level)
-{
- MDisps *mdisps = CustomData_add_layer(&me->ldata, CD_MDISPS, CD_CALLOC, NULL, me->totloop);
- int gridsize = BKE_ccg_gridsize(level);
- int gridarea = square_i(gridsize);
- int i, j;
-
- for (i = 0; i < me->totpoly; i++) {
- bool hide = false;
-
- for (j = 0; j < me->mpoly[i].totloop; j++) {
- if (me->mvert[me->mloop[me->mpoly[i].loopstart + j].v].flag & ME_HIDE) {
- hide = true;
- break;
- }
- }
-
- if (!hide) {
- continue;
- }
-
- for (j = 0; j < me->mpoly[i].totloop; j++) {
- MDisps *md = &mdisps[me->mpoly[i].loopstart + j];
-
- BLI_assert(!md->hidden);
-
- md->hidden = BLI_BITMAP_NEW(gridarea, "MDisps.hidden initialize");
- BLI_bitmap_set_all(md->hidden, true, gridarea);
- }
- }
-
- return mdisps;
-}
-
Mesh *BKE_multires_create_mesh(struct Depsgraph *depsgraph,
Object *object,
MultiresModifierData *mmd)
@@ -429,12 +393,6 @@ void multires_set_tot_level(Object *ob, MultiresModifierData *mmd, int lvl)
mmd->renderlvl = CLAMPIS(MAX2(mmd->renderlvl, lvl), 0, mmd->totlvl);
}
-static void multires_dm_mark_as_modified(DerivedMesh *dm, MultiresModifiedFlags flags)
-{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
- ccgdm->multires.modified_flags |= flags;
-}
-
static void multires_ccg_mark_as_modified(SubdivCCG *subdiv_ccg, MultiresModifiedFlags flags)
{
if (flags & MULTIRES_COORDS_MODIFIED) {
@@ -789,7 +747,6 @@ static DerivedMesh *multires_dm_create_local(Scene *scene,
DerivedMesh *dm,
int lvl,
int totlvl,
- int simple,
bool alloc_paint_mask,
int flags)
{
@@ -799,7 +756,6 @@ static DerivedMesh *multires_dm_create_local(Scene *scene,
mmd.sculptlvl = lvl;
mmd.renderlvl = lvl;
mmd.totlvl = totlvl;
- mmd.simple = simple;
flags |= MULTIRES_USE_LOCAL_MMD;
if (alloc_paint_mask) {
@@ -850,110 +806,6 @@ static DerivedMesh *subsurf_dm_create_local(Scene *scene,
return subsurf_make_derived_from_derived(dm, &smd, scene, NULL, flags);
}
-static void multires_subdivide_legacy(
- MultiresModifierData *mmd, Scene *scene, Object *ob, int totlvl, int updateblock, int simple)
-{
- Mesh *me = ob->data;
- MDisps *mdisps;
- const int lvl = mmd->totlvl;
-
- if ((totlvl > multires_max_levels) || (me->totpoly == 0)) {
- return;
- }
-
- BLI_assert(totlvl > lvl);
-
- multires_force_sculpt_rebuild(ob);
-
- mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
- if (!mdisps) {
- mdisps = multires_mdisps_init_hidden(me, totlvl);
- }
-
- if (mdisps->disps && !updateblock && lvl != 0) {
- /* upsample */
- DerivedMesh *lowdm, *cddm, *highdm;
- CCGElem **highGridData, **lowGridData, **subGridData;
- CCGKey highGridKey, lowGridKey;
- CCGSubSurf *ss;
- int i, numGrids, highGridSize;
- const bool has_mask = CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK);
-
- /* create subsurf DM from original mesh at high level */
- cddm = CDDM_from_mesh(me);
- DM_set_only_copy(cddm, &CD_MASK_BAREMESH);
- highdm = subsurf_dm_create_local(NULL,
- ob,
- cddm,
- totlvl,
- simple,
- 0,
- mmd->uv_smooth == SUBSURF_UV_SMOOTH_NONE,
- has_mask,
- false,
- SUBSURF_IGNORE_SIMPLIFY);
- ss = ((CCGDerivedMesh *)highdm)->ss;
-
- /* create multires DM from original mesh at low level */
- lowdm = multires_dm_create_local(
- scene, ob, cddm, lvl, lvl, simple, has_mask, MULTIRES_IGNORE_SIMPLIFY);
- BLI_assert(lowdm != cddm);
- cddm->release(cddm);
-
- /* copy subsurf grids and replace them with low displaced grids */
- numGrids = highdm->getNumGrids(highdm);
- highGridSize = highdm->getGridSize(highdm);
- highGridData = highdm->getGridData(highdm);
- highdm->getGridKey(highdm, &highGridKey);
- lowGridData = lowdm->getGridData(lowdm);
- lowdm->getGridKey(lowdm, &lowGridKey);
-
- subGridData = MEM_calloc_arrayN(numGrids, sizeof(float *), "subGridData*");
-
- for (i = 0; i < numGrids; i++) {
- /* backup subsurf grids */
- subGridData[i] = MEM_calloc_arrayN(
- highGridKey.elem_size, highGridSize * highGridSize, "subGridData");
- memcpy(subGridData[i], highGridData[i], highGridKey.elem_size * highGridSize * highGridSize);
-
- /* overwrite with current displaced grids */
- multires_copy_dm_grid(highGridData[i], lowGridData[i], &highGridKey, &lowGridKey);
- }
-
- /* low lower level dm no longer needed at this point */
- lowdm->release(lowdm);
-
- /* subsurf higher levels again with displaced data */
- ccgSubSurf_updateFromFaces(ss, lvl, NULL, 0);
- ccgSubSurf_updateLevels(ss, lvl, NULL, 0);
-
- /* reallocate displacements */
- multires_reallocate_mdisps(me->totloop, mdisps, totlvl);
-
- /* compute displacements */
- multiresModifier_disp_run(highdm, me, NULL, CALC_DISPLACEMENTS, subGridData, totlvl);
-
- /* free */
- highdm->release(highdm);
- for (i = 0; i < numGrids; i++) {
- MEM_freeN(subGridData[i]);
- }
- MEM_freeN(subGridData);
- }
- else {
- /* only reallocate, nothing to upsample */
- multires_reallocate_mdisps(me->totloop, mdisps, totlvl);
- }
-
- multires_set_tot_level(ob, mmd, totlvl);
-}
-
-void multiresModifier_subdivide_legacy(
- MultiresModifierData *mmd, Scene *scene, Object *ob, int updateblock, int simple)
-{
- multires_subdivide_legacy(mmd, scene, ob, mmd->totlvl + 1, updateblock, simple);
-}
-
static void grid_tangent(const CCGKey *key, int x, int y, int axis, CCGElem *grid, float t[3])
{
if (axis == 0) {
@@ -1227,7 +1079,7 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm, Scene *scene)
ob,
cddm,
totlvl,
- mmd->simple,
+ false,
0,
mmd->uv_smooth == SUBSURF_UV_SMOOTH_NONE,
has_mask,
@@ -1237,7 +1089,7 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm, Scene *scene)
/* create multires DM from original mesh and displacements */
lowdm = multires_dm_create_local(
- scene, ob, cddm, lvl, totlvl, mmd->simple, has_mask, MULTIRES_IGNORE_SIMPLIFY);
+ scene, ob, cddm, lvl, totlvl, has_mask, MULTIRES_IGNORE_SIMPLIFY);
cddm->release(cddm);
/* gather grid data */
@@ -1302,7 +1154,7 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm, Scene *scene)
ob,
cddm,
mmd->totlvl,
- mmd->simple,
+ false,
0,
mmd->uv_smooth == SUBSURF_UV_SMOOTH_NONE,
has_mask,
@@ -1400,7 +1252,7 @@ DerivedMesh *multires_make_derived_from_derived(
ob,
dm,
lvl,
- mmd->simple,
+ false,
mmd->flags & eMultiresModifierFlag_ControlEdges,
mmd->uv_smooth == SUBSURF_UV_SMOOTH_NONE,
flags & MULTIRES_ALLOC_PAINT_MASK,
@@ -1449,9 +1301,6 @@ DerivedMesh *multires_make_derived_from_derived(
return result;
}
-/**** Old Multires code ****
- ***************************/
-
/* Adapted from sculptmode.c */
void old_mdisps_bilinear(float out[3], float (*disps)[3], const int st, float u, float v)
{
@@ -1506,723 +1355,6 @@ void old_mdisps_bilinear(float out[3], float (*disps)[3], const int st, float u,
add_v3_v3v3(out, d2[0], d2[1]);
}
-static void old_mdisps_rotate(
- int S, int UNUSED(newside), int oldside, int x, int y, float *u, float *v)
-{
- float offset = oldside * 0.5f - 0.5f;
-
- if (S == 1) {
- *u = offset + x;
- *v = offset - y;
- }
- if (S == 2) {
- *u = offset + y;
- *v = offset + x;
- }
- if (S == 3) {
- *u = offset - x;
- *v = offset + y;
- }
- if (S == 0) {
- *u = offset - y;
- *v = offset - x;
- }
-}
-
-static void old_mdisps_convert(MFace *mface, MDisps *mdisp)
-{
- int newlvl = log(sqrt(mdisp->totdisp) - 1) / M_LN2;
- int oldlvl = newlvl + 1;
- int oldside = multires_side_tot[oldlvl];
- int newside = multires_side_tot[newlvl];
- int nvert = (mface->v4) ? 4 : 3;
- int newtotdisp = multires_grid_tot[newlvl] * nvert;
- int x, y, S;
- float(*disps)[3], (*out)[3], u = 0.0f, v = 0.0f; /* Quite gcc barking. */
-
- disps = MEM_calloc_arrayN(newtotdisp, sizeof(float[3]), "multires disps");
-
- out = disps;
- for (S = 0; S < nvert; S++) {
- for (y = 0; y < newside; y++) {
- for (x = 0; x < newside; x++, out++) {
- old_mdisps_rotate(S, newside, oldside, x, y, &u, &v);
- old_mdisps_bilinear(*out, mdisp->disps, oldside, u, v);
-
- if (S == 1) {
- (*out)[1] = -(*out)[1];
- }
- else if (S == 2) {
- SWAP(float, (*out)[0], (*out)[1]);
- }
- else if (S == 3) {
- (*out)[0] = -(*out)[0];
- }
- else if (S == 0) {
- SWAP(float, (*out)[0], (*out)[1]);
- (*out)[0] = -(*out)[0];
- (*out)[1] = -(*out)[1];
- }
- }
- }
- }
-
- MEM_freeN(mdisp->disps);
-
- mdisp->totdisp = newtotdisp;
- mdisp->level = newlvl;
- mdisp->disps = disps;
-}
-
-void multires_load_old_250(Mesh *me)
-{
- MDisps *mdisps, *mdisps2;
- MFace *mf;
- int i, j, k;
-
- mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS);
-
- if (mdisps) {
- for (i = 0; i < me->totface; i++) {
- if (mdisps[i].totdisp) {
- old_mdisps_convert(&me->mface[i], &mdisps[i]);
- }
- }
-
- CustomData_add_layer(&me->ldata, CD_MDISPS, CD_CALLOC, NULL, me->totloop);
- mdisps2 = CustomData_get_layer(&me->ldata, CD_MDISPS);
-
- k = 0;
- mf = me->mface;
- for (i = 0; i < me->totface; i++, mf++) {
- int nvert = mf->v4 ? 4 : 3;
- int totdisp = mdisps[i].totdisp / nvert;
-
- for (j = 0; j < nvert; j++, k++) {
- mdisps2[k].disps = MEM_calloc_arrayN(
- totdisp, sizeof(float[3]), "multires disp in conversion");
- mdisps2[k].totdisp = totdisp;
- mdisps2[k].level = mdisps[i].level;
- memcpy(mdisps2[k].disps, mdisps[i].disps + totdisp * j, totdisp);
- }
- }
- }
-}
-
-/* Does not actually free lvl itself */
-static void multires_free_level(MultiresLevel *lvl)
-{
- if (lvl) {
- if (lvl->faces) {
- MEM_freeN(lvl->faces);
- }
- if (lvl->edges) {
- MEM_freeN(lvl->edges);
- }
- if (lvl->colfaces) {
- MEM_freeN(lvl->colfaces);
- }
- }
-}
-
-void multires_free(Multires *mr)
-{
- if (mr) {
- MultiresLevel *lvl = mr->levels.first;
-
- /* Free the first-level data */
- if (lvl) {
- CustomData_free(&mr->vdata, lvl->totvert);
- CustomData_free(&mr->fdata, lvl->totface);
- if (mr->edge_flags) {
- MEM_freeN(mr->edge_flags);
- }
- if (mr->edge_creases) {
- MEM_freeN(mr->edge_creases);
- }
- }
-
- while (lvl) {
- multires_free_level(lvl);
- lvl = lvl->next;
- }
-
- /* mr->verts may be NULL when loading old files,
- * see direct_link_mesh() in readfile.c, and T43560. */
- MEM_SAFE_FREE(mr->verts);
-
- BLI_freelistN(&mr->levels);
-
- MEM_freeN(mr);
- }
-}
-
-typedef struct IndexNode {
- struct IndexNode *next, *prev;
- int index;
-} IndexNode;
-
-static void create_old_vert_face_map(ListBase **map,
- IndexNode **mem,
- const MultiresFace *mface,
- const int totvert,
- const int totface)
-{
- int i, j;
- IndexNode *node = NULL;
-
- (*map) = MEM_calloc_arrayN(totvert, sizeof(ListBase), "vert face map");
- (*mem) = MEM_calloc_arrayN(totface, sizeof(IndexNode[4]), "vert face map mem");
- node = *mem;
-
- /* Find the users */
- for (i = 0; i < totface; i++) {
- for (j = 0; j < (mface[i].v[3] ? 4 : 3); j++, node++) {
- node->index = i;
- BLI_addtail(&(*map)[mface[i].v[j]], node);
- }
- }
-}
-
-static void create_old_vert_edge_map(ListBase **map,
- IndexNode **mem,
- const MultiresEdge *medge,
- const int totvert,
- const int totedge)
-{
- int i, j;
- IndexNode *node = NULL;
-
- (*map) = MEM_calloc_arrayN(totvert, sizeof(ListBase), "vert edge map");
- (*mem) = MEM_calloc_arrayN(totedge, sizeof(IndexNode[2]), "vert edge map mem");
- node = *mem;
-
- /* Find the users */
- for (i = 0; i < totedge; i++) {
- for (j = 0; j < 2; j++, node++) {
- node->index = i;
- BLI_addtail(&(*map)[medge[i].v[j]], node);
- }
- }
-}
-
-static MultiresFace *find_old_face(
- ListBase *map, MultiresFace *faces, int v1, int v2, int v3, int v4)
-{
- IndexNode *n1;
- int v[4], i, j;
-
- v[0] = v1;
- v[1] = v2;
- v[2] = v3;
- v[3] = v4;
-
- for (n1 = map[v1].first; n1; n1 = n1->next) {
- int fnd[4] = {0, 0, 0, 0};
-
- for (i = 0; i < 4; i++) {
- for (j = 0; j < 4; j++) {
- if (v[i] == faces[n1->index].v[j]) {
- fnd[i] = 1;
- }
- }
- }
-
- if (fnd[0] && fnd[1] && fnd[2] && fnd[3]) {
- return &faces[n1->index];
- }
- }
-
- return NULL;
-}
-
-static MultiresEdge *find_old_edge(ListBase *map, MultiresEdge *edges, int v1, int v2)
-{
- IndexNode *n1, *n2;
-
- for (n1 = map[v1].first; n1; n1 = n1->next) {
- for (n2 = map[v2].first; n2; n2 = n2->next) {
- if (n1->index == n2->index) {
- return &edges[n1->index];
- }
- }
- }
-
- return NULL;
-}
-
-static void multires_load_old_edges(
- ListBase **emap, MultiresLevel *lvl, int *vvmap, int dst, int v1, int v2, int mov)
-{
- int emid = find_old_edge(emap[2], lvl->edges, v1, v2)->mid;
- vvmap[dst + mov] = emid;
-
- if (lvl->next->next) {
- multires_load_old_edges(emap + 1, lvl->next, vvmap, dst + mov, v1, emid, mov / 2);
- multires_load_old_edges(emap + 1, lvl->next, vvmap, dst + mov, v2, emid, -mov / 2);
- }
-}
-
-static void multires_load_old_faces(ListBase **fmap,
- ListBase **emap,
- MultiresLevel *lvl,
- int *vvmap,
- int dst,
- int v1,
- int v2,
- int v3,
- int v4,
- int st2,
- int st3)
-{
- int fmid;
- int emid13, emid14, emid23, emid24;
-
- if (lvl && lvl->next) {
- fmid = find_old_face(fmap[1], lvl->faces, v1, v2, v3, v4)->mid;
- vvmap[dst] = fmid;
-
- emid13 = find_old_edge(emap[1], lvl->edges, v1, v3)->mid;
- emid14 = find_old_edge(emap[1], lvl->edges, v1, v4)->mid;
- emid23 = find_old_edge(emap[1], lvl->edges, v2, v3)->mid;
- emid24 = find_old_edge(emap[1], lvl->edges, v2, v4)->mid;
-
- multires_load_old_faces(fmap + 1,
- emap + 1,
- lvl->next,
- vvmap,
- dst + st2 * st3 + st3,
- fmid,
- v2,
- emid23,
- emid24,
- st2,
- st3 / 2);
-
- multires_load_old_faces(fmap + 1,
- emap + 1,
- lvl->next,
- vvmap,
- dst - st2 * st3 + st3,
- emid14,
- emid24,
- fmid,
- v4,
- st2,
- st3 / 2);
-
- multires_load_old_faces(fmap + 1,
- emap + 1,
- lvl->next,
- vvmap,
- dst + st2 * st3 - st3,
- emid13,
- emid23,
- v3,
- fmid,
- st2,
- st3 / 2);
-
- multires_load_old_faces(fmap + 1,
- emap + 1,
- lvl->next,
- vvmap,
- dst - st2 * st3 - st3,
- v1,
- fmid,
- emid13,
- emid14,
- st2,
- st3 / 2);
-
- if (lvl->next->next) {
- multires_load_old_edges(emap, lvl->next, vvmap, dst, emid24, fmid, st3);
- multires_load_old_edges(emap, lvl->next, vvmap, dst, emid13, fmid, -st3);
- multires_load_old_edges(emap, lvl->next, vvmap, dst, emid14, fmid, -st2 * st3);
- multires_load_old_edges(emap, lvl->next, vvmap, dst, emid23, fmid, st2 * st3);
- }
- }
-}
-
-static void multires_mvert_to_ss(DerivedMesh *dm, MVert *mvert)
-{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
- CCGSubSurf *ss = ccgdm->ss;
- CCGElem *vd;
- CCGKey key;
- int index;
- int totvert, totedge, totface;
- int gridSize = ccgSubSurf_getGridSize(ss);
- int edgeSize = ccgSubSurf_getEdgeSize(ss);
- int i = 0;
-
- dm->getGridKey(dm, &key);
-
- totface = ccgSubSurf_getNumFaces(ss);
- for (index = 0; index < totface; index++) {
- CCGFace *f = ccgdm->faceMap[index].face;
- int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
-
- vd = ccgSubSurf_getFaceCenterData(f);
- copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co);
- i++;
-
- for (S = 0; S < numVerts; S++) {
- for (x = 1; x < gridSize - 1; x++, i++) {
- vd = ccgSubSurf_getFaceGridEdgeData(ss, f, S, x);
- copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co);
- }
- }
-
- for (S = 0; S < numVerts; S++) {
- for (y = 1; y < gridSize - 1; y++) {
- for (x = 1; x < gridSize - 1; x++, i++) {
- vd = ccgSubSurf_getFaceGridData(ss, f, S, x, y);
- copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co);
- }
- }
- }
- }
-
- totedge = ccgSubSurf_getNumEdges(ss);
- for (index = 0; index < totedge; index++) {
- CCGEdge *e = ccgdm->edgeMap[index].edge;
- int x;
-
- for (x = 1; x < edgeSize - 1; x++, i++) {
- vd = ccgSubSurf_getEdgeData(ss, e, x);
- copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co);
- }
- }
-
- totvert = ccgSubSurf_getNumVerts(ss);
- for (index = 0; index < totvert; index++) {
- CCGVert *v = ccgdm->vertMap[index].vert;
-
- vd = ccgSubSurf_getVertData(ss, v);
- copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co);
- i++;
- }
-
- ccgSubSurf_updateToFaces(ss, 0, NULL, 0);
-}
-
-/* Loads a multires object stored in the old Multires struct into the new format */
-static void multires_load_old_dm(DerivedMesh *dm, Mesh *me, int totlvl)
-{
- MultiresLevel *lvl, *lvl1;
- Multires *mr = me->mr;
- MVert *vsrc, *vdst;
- unsigned int src, dst;
- int st_last = multires_side_tot[totlvl - 1] - 1;
- int extedgelen = multires_side_tot[totlvl] - 2;
- int *vvmap; // inorder for dst, map to src
- int crossedgelen;
- int s, x, tottri, totquad;
- unsigned int i, j, totvert;
-
- src = 0;
- vsrc = mr->verts;
- vdst = dm->getVertArray(dm);
- totvert = (unsigned int)dm->getNumVerts(dm);
- vvmap = MEM_calloc_arrayN(totvert, sizeof(int), "multires vvmap");
-
- if (!vvmap) {
- return;
- }
-
- lvl1 = mr->levels.first;
- /* Load base verts */
- for (i = 0; i < lvl1->totvert; i++) {
- vvmap[totvert - lvl1->totvert + i] = src;
- src++;
- }
-
- /* Original edges */
- dst = totvert - lvl1->totvert - extedgelen * lvl1->totedge;
- for (i = 0; i < lvl1->totedge; i++) {
- int ldst = dst + extedgelen * i;
- int lsrc = src;
- lvl = lvl1->next;
-
- for (j = 2; j <= mr->level_count; j++) {
- int base = multires_side_tot[totlvl - j + 1] - 2;
- int skip = multires_side_tot[totlvl - j + 2] - 1;
- int st = multires_side_tot[j - 1] - 1;
-
- for (x = 0; x < st; x++) {
- vvmap[ldst + base + x * skip] = lsrc + st * i + x;
- }
-
- lsrc += lvl->totvert - lvl->prev->totvert;
- lvl = lvl->next;
- }
- }
-
- /* Center points */
- dst = 0;
- for (i = 0; i < lvl1->totface; i++) {
- int sides = lvl1->faces[i].v[3] ? 4 : 3;
-
- vvmap[dst] = src + lvl1->totedge + i;
- dst += 1 + sides * (st_last - 1) * st_last;
- }
-
- /* The rest is only for level 3 and up */
- if (lvl1->next && lvl1->next->next) {
- ListBase **fmap, **emap;
- IndexNode **fmem, **emem;
-
- /* Face edge cross */
- tottri = totquad = 0;
- crossedgelen = multires_side_tot[totlvl - 1] - 2;
- dst = 0;
- for (i = 0; i < lvl1->totface; i++) {
- int sides = lvl1->faces[i].v[3] ? 4 : 3;
-
- lvl = lvl1->next->next;
- dst++;
-
- for (j = 3; j <= mr->level_count; j++) {
- int base = multires_side_tot[totlvl - j + 1] - 2;
- int skip = multires_side_tot[totlvl - j + 2] - 1;
- int st = pow(2, j - 2);
- int st2 = pow(2, j - 3);
- int lsrc = lvl->prev->totvert;
-
- /* Skip exterior edge verts */
- lsrc += lvl1->totedge * st;
-
- /* Skip earlier face edge crosses */
- lsrc += st2 * (tottri * 3 + totquad * 4);
-
- for (s = 0; s < sides; s++) {
- for (x = 0; x < st2; x++) {
- vvmap[dst + crossedgelen * (s + 1) - base - x * skip - 1] = lsrc;
- lsrc++;
- }
- }
-
- lvl = lvl->next;
- }
-
- dst += sides * (st_last - 1) * st_last;
-
- if (sides == 4) {
- totquad++;
- }
- else {
- tottri++;
- }
- }
-
- /* calculate vert to edge/face maps for each level (except the last) */
- fmap = MEM_calloc_arrayN((mr->level_count - 1), sizeof(ListBase *), "multires fmap");
- emap = MEM_calloc_arrayN((mr->level_count - 1), sizeof(ListBase *), "multires emap");
- fmem = MEM_calloc_arrayN((mr->level_count - 1), sizeof(IndexNode *), "multires fmem");
- emem = MEM_calloc_arrayN((mr->level_count - 1), sizeof(IndexNode *), "multires emem");
- lvl = lvl1;
- for (i = 0; i < (unsigned int)mr->level_count - 1; i++) {
- create_old_vert_face_map(fmap + i, fmem + i, lvl->faces, lvl->totvert, lvl->totface);
- create_old_vert_edge_map(emap + i, emem + i, lvl->edges, lvl->totvert, lvl->totedge);
- lvl = lvl->next;
- }
-
- /* Interior face verts */
- /* lvl = lvl1->next->next; */ /* UNUSED */
- dst = 0;
- for (j = 0; j < lvl1->totface; j++) {
- int sides = lvl1->faces[j].v[3] ? 4 : 3;
- int ldst = dst + 1 + sides * (st_last - 1);
-
- for (s = 0; s < sides; s++) {
- int st2 = multires_side_tot[totlvl - 1] - 2;
- int st3 = multires_side_tot[totlvl - 2] - 2;
- int st4 = st3 == 0 ? 1 : (st3 + 1) / 2;
- int mid = ldst + st2 * st3 + st3;
- int cv = lvl1->faces[j].v[s];
- int nv = lvl1->faces[j].v[s == sides - 1 ? 0 : s + 1];
- int pv = lvl1->faces[j].v[s == 0 ? sides - 1 : s - 1];
-
- multires_load_old_faces(fmap,
- emap,
- lvl1->next,
- vvmap,
- mid,
- vvmap[dst],
- cv,
- find_old_edge(emap[0], lvl1->edges, pv, cv)->mid,
- find_old_edge(emap[0], lvl1->edges, cv, nv)->mid,
- st2,
- st4);
-
- ldst += (st_last - 1) * (st_last - 1);
- }
-
- dst = ldst;
- }
-
- /*lvl = lvl->next;*/ /*UNUSED*/
-
- for (i = 0; i < (unsigned int)(mr->level_count - 1); i++) {
- MEM_freeN(fmap[i]);
- MEM_freeN(fmem[i]);
- MEM_freeN(emap[i]);
- MEM_freeN(emem[i]);
- }
-
- MEM_freeN(fmap);
- MEM_freeN(emap);
- MEM_freeN(fmem);
- MEM_freeN(emem);
- }
-
- /* Transfer verts */
- for (i = 0; i < totvert; i++) {
- copy_v3_v3(vdst[i].co, vsrc[vvmap[i]].co);
- }
-
- MEM_freeN(vvmap);
-
- multires_mvert_to_ss(dm, vdst);
-}
-
-/* Copy the first-level vcol data to the mesh, if it exists */
-/* Warning: higher-level vcol data will be lost */
-static void multires_load_old_vcols(Mesh *me)
-{
- MultiresLevel *lvl;
- MultiresColFace *colface;
- MCol *mcol;
- int i, j;
-
- if (!(lvl = me->mr->levels.first)) {
- return;
- }
-
- if (!(colface = lvl->colfaces)) {
- return;
- }
-
- /* older multires format never supported multiple vcol layers,
- * so we can assume the active vcol layer is the correct one */
- if (!(mcol = CustomData_get_layer(&me->fdata, CD_MCOL))) {
- return;
- }
-
- for (i = 0; i < me->totface; i++) {
- for (j = 0; j < 4; j++) {
- mcol[i * 4 + j].a = colface[i].col[j].a;
- mcol[i * 4 + j].r = colface[i].col[j].r;
- mcol[i * 4 + j].g = colface[i].col[j].g;
- mcol[i * 4 + j].b = colface[i].col[j].b;
- }
- }
-}
-
-/* Copy the first-level face-flag data to the mesh */
-static void multires_load_old_face_flags(Mesh *me)
-{
- MultiresLevel *lvl;
- MultiresFace *faces;
- int i;
-
- if (!(lvl = me->mr->levels.first)) {
- return;
- }
-
- if (!(faces = lvl->faces)) {
- return;
- }
-
- for (i = 0; i < me->totface; i++) {
- me->mface[i].flag = faces[i].flag;
- }
-}
-
-void multires_load_old(Object *ob, Mesh *me)
-{
- MultiresLevel *lvl;
- ModifierData *md;
- MultiresModifierData *mmd;
- DerivedMesh *dm, *orig;
- CustomDataLayer *l;
- int i;
-
- /* Load original level into the mesh */
- lvl = me->mr->levels.first;
- CustomData_free_layers(&me->vdata, CD_MVERT, lvl->totvert);
- CustomData_free_layers(&me->edata, CD_MEDGE, lvl->totedge);
- CustomData_free_layers(&me->fdata, CD_MFACE, lvl->totface);
- me->totvert = lvl->totvert;
- me->totedge = lvl->totedge;
- me->totface = lvl->totface;
- me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert);
- me->medge = CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, me->totedge);
- me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface);
- memcpy(me->mvert, me->mr->verts, sizeof(MVert) * me->totvert);
- for (i = 0; i < me->totedge; i++) {
- me->medge[i].v1 = lvl->edges[i].v[0];
- me->medge[i].v2 = lvl->edges[i].v[1];
- }
- for (i = 0; i < me->totface; i++) {
- me->mface[i].v1 = lvl->faces[i].v[0];
- me->mface[i].v2 = lvl->faces[i].v[1];
- me->mface[i].v3 = lvl->faces[i].v[2];
- me->mface[i].v4 = lvl->faces[i].v[3];
- me->mface[i].mat_nr = lvl->faces[i].mat_nr;
- }
-
- /* Copy the first-level data to the mesh */
- /* XXX We must do this before converting tessfaces to polys/lopps! */
- for (i = 0, l = me->mr->vdata.layers; i < me->mr->vdata.totlayer; i++, l++) {
- CustomData_add_layer(&me->vdata, l->type, CD_REFERENCE, l->data, me->totvert);
- }
- for (i = 0, l = me->mr->fdata.layers; i < me->mr->fdata.totlayer; i++, l++) {
- CustomData_add_layer(&me->fdata, l->type, CD_REFERENCE, l->data, me->totface);
- }
- CustomData_reset(&me->mr->vdata);
- CustomData_reset(&me->mr->fdata);
-
- multires_load_old_vcols(me);
- multires_load_old_face_flags(me);
-
- /* multiresModifier_subdivide_legacy (actually, multires_subdivide_legacy) expects polys, not
- * tessfaces! */
- BKE_mesh_convert_mfaces_to_mpolys(me);
-
- /* Add a multires modifier to the object */
- md = ob->modifiers.first;
- while (md && BKE_modifier_get_info(md->type)->type == eModifierTypeType_OnlyDeform) {
- md = md->next;
- }
- mmd = (MultiresModifierData *)BKE_modifier_new(eModifierType_Multires);
- BLI_insertlinkbefore(&ob->modifiers, md, mmd);
-
- for (i = 0; i < me->mr->level_count - 1; i++) {
- multiresModifier_subdivide_legacy(mmd, NULL, ob, 1, 0);
- }
-
- mmd->lvl = mmd->totlvl;
- orig = CDDM_from_mesh(me);
- /* XXX We *must* alloc paint mask here, else we have some kind of mismatch in
- * multires_modifier_update_mdisps() (called by dm->release(dm)), which always creates the
- * reference subsurfed dm with this option, before calling multiresModifier_disp_run(),
- * which implicitly expects both subsurfs from its first dm and oldGridData parameters to
- * be of the same "format"! */
- dm = multires_make_derived_from_derived(orig, mmd, NULL, ob, 0);
-
- multires_load_old_dm(dm, me, mmd->totlvl + 1);
-
- multires_dm_mark_as_modified(dm, MULTIRES_COORDS_MODIFIED);
- dm->release(dm);
- orig->release(orig);
-
- /* Remove the old multires */
- multires_free(me->mr);
- me->mr = NULL;
-}
-
/* If 'ob_src' and 'ob_dst' both have multires modifiers, synchronize them
* such that 'ob_dst' has the same total number of levels as 'ob_src'. */
void multiresModifier_sync_levels_ex(Object *ob_dst,
@@ -2234,14 +1366,8 @@ void multiresModifier_sync_levels_ex(Object *ob_dst,
}
if (mmd_src->totlvl > mmd_dst->totlvl) {
- if (mmd_dst->simple) {
- multiresModifier_subdivide_to_level(
- ob_dst, mmd_dst, mmd_src->totlvl, MULTIRES_SUBDIVIDE_SIMPLE);
- }
- else {
- multiresModifier_subdivide_to_level(
- ob_dst, mmd_dst, mmd_src->totlvl, MULTIRES_SUBDIVIDE_CATMULL_CLARK);
- }
+ multiresModifier_subdivide_to_level(
+ ob_dst, mmd_dst, mmd_src->totlvl, MULTIRES_SUBDIVIDE_CATMULL_CLARK);
}
else {
multires_del_higher(mmd_dst, ob_dst, mmd_src->totlvl);
diff --git a/source/blender/blenkernel/intern/multires_reshape.c b/source/blender/blenkernel/intern/multires_reshape.c
index 5bcf8f62f86..04ad78ec0de 100644
--- a/source/blender/blenkernel/intern/multires_reshape.c
+++ b/source/blender/blenkernel/intern/multires_reshape.c
@@ -225,7 +225,7 @@ void multiresModifier_subdivide_to_level(struct Object *object,
multires_flush_sculpt_updates(object);
- if (!multires_reshape_context_create_from_subdivide(&reshape_context, object, mmd, top_level)) {
+ if (!multires_reshape_context_create_from_modifier(&reshape_context, object, mmd, top_level)) {
return;
}
diff --git a/source/blender/blenkernel/intern/multires_reshape.h b/source/blender/blenkernel/intern/multires_reshape.h
index d6c1d79dfd7..36ecf1a6395 100644
--- a/source/blender/blenkernel/intern/multires_reshape.h
+++ b/source/blender/blenkernel/intern/multires_reshape.h
@@ -167,10 +167,16 @@ bool multires_reshape_context_create_from_ccg(MultiresReshapeContext *reshape_co
struct Mesh *base_mesh,
int top_level);
-bool multires_reshape_context_create_from_subdivide(MultiresReshapeContext *reshape_context,
- struct Object *object,
- struct MultiresModifierData *mmd,
- int top_level);
+bool multires_reshape_context_create_from_modifier(MultiresReshapeContext *reshape_context,
+ struct Object *object,
+ struct MultiresModifierData *mmd,
+ int top_level);
+
+bool multires_reshape_context_create_from_subdiv(MultiresReshapeContext *reshape_context,
+ struct Object *object,
+ struct MultiresModifierData *mmd,
+ struct Subdiv *subdiv,
+ int top_level);
void multires_reshape_free_original_grids(MultiresReshapeContext *reshape_context);
void multires_reshape_context_free(MultiresReshapeContext *reshape_context);
diff --git a/source/blender/blenkernel/intern/multires_reshape_apply_base.c b/source/blender/blenkernel/intern/multires_reshape_apply_base.c
index 6e7e2b90c05..b693b1114ba 100644
--- a/source/blender/blenkernel/intern/multires_reshape_apply_base.c
+++ b/source/blender/blenkernel/intern/multires_reshape_apply_base.c
@@ -81,11 +81,6 @@ static float v3_dist_from_plane(const float v[3], const float center[3], const f
void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape_context)
{
- if (reshape_context->mmd->simple) {
- /* Simple subdivisions does not move base mesh verticies, so no refitting is needed. */
- return;
- }
-
Mesh *base_mesh = reshape_context->base_mesh;
MeshElemMap *pmap;
diff --git a/source/blender/blenkernel/intern/multires_reshape_subdivide.c b/source/blender/blenkernel/intern/multires_reshape_subdivide.c
index 7b7c1efc533..d42a061084f 100644
--- a/source/blender/blenkernel/intern/multires_reshape_subdivide.c
+++ b/source/blender/blenkernel/intern/multires_reshape_subdivide.c
@@ -96,7 +96,7 @@ void multires_subdivide_create_tangent_displacement_linear_grids(Object *object,
/* Convert the new grids to tangent displacement. */
multires_set_tot_level(object, mmd, new_top_level);
- if (!multires_reshape_context_create_from_subdivide(
+ if (!multires_reshape_context_create_from_modifier(
&reshape_context, object, mmd, new_top_level)) {
return;
}
diff --git a/source/blender/blenkernel/intern/multires_reshape_util.c b/source/blender/blenkernel/intern/multires_reshape_util.c
index c8179dd8a2d..8fb406e54a5 100644
--- a/source/blender/blenkernel/intern/multires_reshape_util.c
+++ b/source/blender/blenkernel/intern/multires_reshape_util.c
@@ -242,10 +242,26 @@ bool multires_reshape_context_create_from_ccg(MultiresReshapeContext *reshape_co
return context_verify_or_free(reshape_context);
}
-bool multires_reshape_context_create_from_subdivide(MultiresReshapeContext *reshape_context,
- struct Object *object,
- struct MultiresModifierData *mmd,
- int top_level)
+bool multires_reshape_context_create_from_modifier(MultiresReshapeContext *reshape_context,
+ struct Object *object,
+ struct MultiresModifierData *mmd,
+ int top_level)
+{
+ Subdiv *subdiv = multires_reshape_create_subdiv(NULL, object, mmd);
+
+ const bool result = multires_reshape_context_create_from_subdiv(
+ reshape_context, object, mmd, subdiv, top_level);
+
+ reshape_context->need_free_subdiv = true;
+
+ return result;
+}
+
+bool multires_reshape_context_create_from_subdiv(MultiresReshapeContext *reshape_context,
+ struct Object *object,
+ struct MultiresModifierData *mmd,
+ struct Subdiv *subdiv,
+ int top_level)
{
context_zero(reshape_context);
@@ -254,8 +270,8 @@ bool multires_reshape_context_create_from_subdivide(MultiresReshapeContext *resh
reshape_context->mmd = mmd;
reshape_context->base_mesh = base_mesh;
- reshape_context->subdiv = multires_reshape_create_subdiv(NULL, object, mmd);
- reshape_context->need_free_subdiv = true;
+ reshape_context->subdiv = subdiv;
+ reshape_context->need_free_subdiv = false;
reshape_context->reshape.level = mmd->totlvl;
reshape_context->reshape.grid_size = BKE_subdiv_grid_size_from_level(
diff --git a/source/blender/blenkernel/intern/multires_subdiv.c b/source/blender/blenkernel/intern/multires_subdiv.c
index 73ef623fbfd..8156814d9f1 100644
--- a/source/blender/blenkernel/intern/multires_subdiv.c
+++ b/source/blender/blenkernel/intern/multires_subdiv.c
@@ -36,7 +36,7 @@
void BKE_multires_subdiv_settings_init(SubdivSettings *settings, const MultiresModifierData *mmd)
{
- settings->is_simple = (mmd->simple != 0);
+ settings->is_simple = false;
settings->is_adaptive = true;
settings->level = settings->is_simple ? 1 : mmd->quality;
settings->use_creases = (mmd->flags & eMultiresModifierFlag_UseCrease);
diff --git a/source/blender/blenkernel/intern/multires_versioning.c b/source/blender/blenkernel/intern/multires_versioning.c
new file mode 100644
index 00000000000..4c0d7165cd0
--- /dev/null
+++ b/source/blender/blenkernel/intern/multires_versioning.c
@@ -0,0 +1,106 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 by Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup bke
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_object_types.h"
+
+#include "BKE_subdiv.h"
+#include "BKE_subdiv_eval.h"
+
+#include "multires_reshape.h"
+#include "opensubdiv_converter_capi.h"
+#include "subdiv_converter.h"
+
+static float simple_to_catmull_clark_get_edge_sharpness(
+ const OpenSubdiv_Converter *UNUSED(converter), int UNUSED(manifold_edge_index))
+{
+ return 10.0f;
+}
+
+static bool simple_to_catmull_clark_is_infinite_sharp_vertex(
+ const OpenSubdiv_Converter *UNUSED(converter), int UNUSED(manifold_vertex_index))
+{
+ return true;
+}
+
+static Subdiv *subdiv_for_simple_to_catmull_clark(Object *object, MultiresModifierData *mmd)
+{
+ SubdivSettings subdiv_settings;
+ BKE_multires_subdiv_settings_init(&subdiv_settings, mmd);
+
+ Mesh *base_mesh = object->data;
+
+ OpenSubdiv_Converter converter;
+ BKE_subdiv_converter_init_for_mesh(&converter, &subdiv_settings, base_mesh);
+ converter.getEdgeSharpness = simple_to_catmull_clark_get_edge_sharpness;
+ converter.isInfiniteSharpVertex = simple_to_catmull_clark_is_infinite_sharp_vertex;
+
+ Subdiv *subdiv = BKE_subdiv_new_from_converter(&subdiv_settings, &converter);
+ BKE_subdiv_converter_free(&converter);
+
+ if (!BKE_subdiv_eval_begin_from_mesh(subdiv, base_mesh, NULL)) {
+ BKE_subdiv_free(subdiv);
+ return NULL;
+ }
+
+ return subdiv;
+}
+
+void multires_do_versions_simple_to_catmull_clark(Object *object, MultiresModifierData *mmd)
+{
+ const Mesh *base_mesh = object->data;
+ if (base_mesh->totloop == 0) {
+ return;
+ }
+
+ /* Store the grids displacement in object space against the simple limit surface. */
+ {
+ Subdiv *subdiv = subdiv_for_simple_to_catmull_clark(object, mmd);
+ MultiresReshapeContext reshape_context;
+ if (!multires_reshape_context_create_from_subdiv(
+ &reshape_context, object, mmd, subdiv, mmd->totlvl)) {
+ BKE_subdiv_free(subdiv);
+ return;
+ }
+
+ multires_reshape_store_original_grids(&reshape_context);
+ multires_reshape_assign_final_coords_from_mdisps(&reshape_context);
+ multires_reshape_context_free(&reshape_context);
+
+ BKE_subdiv_free(subdiv);
+ }
+
+ /* Calculate the new tangent displacement against the new Catmull-Clark limit surface. */
+ {
+ MultiresReshapeContext reshape_context;
+ if (!multires_reshape_context_create_from_modifier(
+ &reshape_context, object, mmd, mmd->totlvl)) {
+ return;
+ }
+ multires_reshape_object_grids_to_tangent_displacement(&reshape_context);
+ multires_reshape_context_free(&reshape_context);
+ }
+}
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 80a553ff525..e2e61284d2e 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -404,6 +404,8 @@ static void write_node_socket_interface(BlendWriter *writer, bNodeSocket *sock)
/* this is only direct data, tree itself should have been written */
void ntreeBlendWrite(BlendWriter *writer, bNodeTree *ntree)
{
+ BKE_id_blend_write(writer, &ntree->id);
+
/* for link_list() speed, we write per list */
if (ntree->adt) {
@@ -525,9 +527,6 @@ static void ntree_blend_write(BlendWriter *writer, ID *id, const void *id_addres
ntree->execdata = NULL;
BLO_write_id_struct(writer, bNodeTree, id_address, &ntree->id);
- /* Note that trees directly used by other IDs (materials etc.) are not 'real' ID, they cannot
- * be linked, etc., so we write actual id data here only, for 'real' ID trees. */
- BKE_id_blend_write(writer, &ntree->id);
ntreeBlendWrite(writer, ntree);
}
@@ -853,6 +852,8 @@ IDTypeInfo IDType_ID_NT = {
.blend_read_data = ntree_blend_read_data,
.blend_read_lib = ntree_blend_read_lib,
.blend_read_expand = ntree_blend_read_expand,
+
+ .blend_read_undo_preserve = NULL,
};
static void node_add_sockets_from_type(bNodeTree *ntree, bNode *node, bNodeType *ntype)
@@ -4662,7 +4663,7 @@ static void registerFunctionNodes(void)
register_node_type_fn_random_float();
}
-void init_nodesystem(void)
+void BKE_node_system_init(void)
{
nodetreetypes_hash = BLI_ghash_str_new("nodetreetypes_hash gh");
nodetypes_hash = BLI_ghash_str_new("nodetypes_hash gh");
@@ -4689,7 +4690,7 @@ void init_nodesystem(void)
registerFunctionNodes();
}
-void free_nodesystem(void)
+void BKE_node_system_exit(void)
{
if (nodetypes_hash) {
NODE_TYPES_BEGIN (nt) {
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 971f79e296f..5b0b1f333f4 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -21,6 +21,9 @@
* \ingroup bke
*/
+/* Allow using deprecated functionality for .blend file I/O. */
+#define DNA_DEPRECATED_ALLOW
+
#include <math.h>
#include <stdio.h>
#include <string.h>
@@ -35,6 +38,7 @@
#include "DNA_collection_types.h"
#include "DNA_constraint_types.h"
#include "DNA_defaults.h"
+#include "DNA_effect_types.h"
#include "DNA_fluid_types.h"
#include "DNA_gpencil_modifier_types.h"
#include "DNA_gpencil_types.h"
@@ -47,6 +51,8 @@
#include "DNA_meshdata_types.h"
#include "DNA_meta_types.h"
#include "DNA_movieclip_types.h"
+#include "DNA_nla_types.h"
+#include "DNA_object_fluidsim_types.h"
#include "DNA_object_types.h"
#include "DNA_pointcloud_types.h"
#include "DNA_rigidbody_types.h"
@@ -123,7 +129,6 @@
#include "BKE_pointcloud.h"
#include "BKE_rigidbody.h"
#include "BKE_scene.h"
-#include "BKE_sequencer.h"
#include "BKE_shader_fx.h"
#include "BKE_softbody.h"
#include "BKE_speaker.h"
@@ -136,6 +141,10 @@
#include "DRW_engine.h"
+#include "BLO_read_write.h"
+
+#include "SEQ_sequencer.h"
+
#ifdef WITH_PYTHON
# include "BPY_extern.h"
#endif
@@ -516,6 +525,614 @@ static void object_foreach_id(ID *id, LibraryForeachIDData *data)
}
}
+static void write_defgroups(BlendWriter *writer, ListBase *defbase)
+{
+ LISTBASE_FOREACH (bDeformGroup *, defgroup, defbase) {
+ BLO_write_struct(writer, bDeformGroup, defgroup);
+ }
+}
+
+static void write_fmaps(BlendWriter *writer, ListBase *fbase)
+{
+ LISTBASE_FOREACH (bFaceMap *, fmap, fbase) {
+ BLO_write_struct(writer, bFaceMap, fmap);
+ }
+}
+
+static void object_blend_write(BlendWriter *writer, ID *id, const void *id_address)
+{
+ Object *ob = (Object *)id;
+
+ const bool is_undo = BLO_write_is_undo(writer);
+ if (ob->id.us > 0 || is_undo) {
+ /* Clean up, important in undo case to reduce false detection of changed data-blocks. */
+ BKE_object_runtime_reset(ob);
+
+ if (is_undo) {
+ /* For undo we stay in object mode during undo presses, so keep edit-mode disabled on save as
+ * well, can help reducing false detection of changed data-blocks. */
+ ob->mode &= ~OB_MODE_EDIT;
+ }
+
+ /* write LibData */
+ BLO_write_id_struct(writer, Object, id_address, &ob->id);
+ BKE_id_blend_write(writer, &ob->id);
+
+ if (ob->adt) {
+ BKE_animdata_blend_write(writer, ob->adt);
+ }
+
+ /* direct data */
+ BLO_write_pointer_array(writer, ob->totcol, ob->mat);
+ BLO_write_raw(writer, sizeof(char) * ob->totcol, ob->matbits);
+
+ bArmature *arm = NULL;
+ if (ob->type == OB_ARMATURE) {
+ arm = ob->data;
+ if (arm && ob->pose && arm->act_bone) {
+ BLI_strncpy(
+ ob->pose->proxy_act_bone, arm->act_bone->name, sizeof(ob->pose->proxy_act_bone));
+ }
+ }
+
+ BKE_pose_blend_write(writer, ob->pose, arm);
+ write_defgroups(writer, &ob->defbase);
+ write_fmaps(writer, &ob->fmaps);
+ BKE_constraint_blend_write(writer, &ob->constraints);
+ animviz_motionpath_blend_write(writer, ob->mpath);
+
+ BLO_write_struct(writer, PartDeflect, ob->pd);
+ if (ob->soft) {
+ /* Set deprecated pointers to prevent crashes of older Blenders */
+ ob->soft->pointcache = ob->soft->shared->pointcache;
+ ob->soft->ptcaches = ob->soft->shared->ptcaches;
+ BLO_write_struct(writer, SoftBody, ob->soft);
+ BLO_write_struct(writer, SoftBody_Shared, ob->soft->shared);
+ BKE_ptcache_blend_write(writer, &(ob->soft->shared->ptcaches));
+ BLO_write_struct(writer, EffectorWeights, ob->soft->effector_weights);
+ }
+
+ if (ob->rigidbody_object) {
+ /* TODO: if any extra data is added to handle duplis, will need separate function then */
+ BLO_write_struct(writer, RigidBodyOb, ob->rigidbody_object);
+ }
+ if (ob->rigidbody_constraint) {
+ BLO_write_struct(writer, RigidBodyCon, ob->rigidbody_constraint);
+ }
+
+ if (ob->type == OB_EMPTY && ob->empty_drawtype == OB_EMPTY_IMAGE) {
+ BLO_write_struct(writer, ImageUser, ob->iuser);
+ }
+
+ BKE_particle_system_blend_write(writer, &ob->particlesystem);
+ BKE_modifier_blend_write(writer, &ob->modifiers);
+ BKE_gpencil_modifier_blend_write(writer, &ob->greasepencil_modifiers);
+ BKE_shaderfx_blend_write(writer, &ob->shader_fx);
+
+ BLO_write_struct_list(writer, LinkData, &ob->pc_ids);
+
+ BKE_previewimg_blend_write(writer, ob->preview);
+ }
+}
+
+/* XXX deprecated - old animation system */
+static void direct_link_nlastrips(BlendDataReader *reader, ListBase *strips)
+{
+ BLO_read_list(reader, strips);
+
+ LISTBASE_FOREACH (bActionStrip *, strip, strips) {
+ BLO_read_list(reader, &strip->modifiers);
+ }
+}
+
+static void object_blend_read_data(BlendDataReader *reader, ID *id)
+{
+ Object *ob = (Object *)id;
+
+ PartEff *paf;
+
+ /* XXX This should not be needed - but seems like it can happen in some cases,
+ * so for now play safe. */
+ ob->proxy_from = NULL;
+
+ const bool is_undo = BLO_read_data_is_undo(reader);
+ if (ob->id.tag & (LIB_TAG_EXTERN | LIB_TAG_INDIRECT)) {
+ /* Do not allow any non-object mode for linked data.
+ * See T34776, T42780, T81027 for more information. */
+ ob->mode &= ~OB_MODE_ALL_MODE_DATA;
+ }
+ else if (is_undo) {
+ /* For undo we want to stay in object mode during undo presses, so keep some edit modes
+ * disabled.
+ * TODO: Check if we should not disable more edit modes here? */
+ ob->mode &= ~(OB_MODE_EDIT | OB_MODE_PARTICLE_EDIT);
+ }
+
+ BLO_read_data_address(reader, &ob->adt);
+ BKE_animdata_blend_read_data(reader, ob->adt);
+
+ BLO_read_data_address(reader, &ob->pose);
+ BKE_pose_blend_read_data(reader, ob->pose);
+
+ BLO_read_data_address(reader, &ob->mpath);
+ if (ob->mpath) {
+ animviz_motionpath_blend_read_data(reader, ob->mpath);
+ }
+
+ BLO_read_list(reader, &ob->defbase);
+ BLO_read_list(reader, &ob->fmaps);
+ /* XXX deprecated - old animation system <<< */
+ direct_link_nlastrips(reader, &ob->nlastrips);
+ BLO_read_list(reader, &ob->constraintChannels);
+ /* >>> XXX deprecated - old animation system */
+
+ BLO_read_pointer_array(reader, (void **)&ob->mat);
+ BLO_read_data_address(reader, &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);
+ BKE_shaderfx_blend_read_data(reader, &ob->shader_fx);
+
+ BLO_read_list(reader, &ob->effect);
+ paf = ob->effect.first;
+ while (paf) {
+ if (paf->type == EFF_PARTICLE) {
+ paf->keys = NULL;
+ }
+ if (paf->type == EFF_WAVE) {
+ WaveEff *wav = (WaveEff *)paf;
+ PartEff *next = paf->next;
+ WaveModifierData *wmd = (WaveModifierData *)BKE_modifier_new(eModifierType_Wave);
+
+ wmd->damp = wav->damp;
+ wmd->flag = wav->flag;
+ wmd->height = wav->height;
+ wmd->lifetime = wav->lifetime;
+ wmd->narrow = wav->narrow;
+ wmd->speed = wav->speed;
+ wmd->startx = wav->startx;
+ wmd->starty = wav->startx;
+ wmd->timeoffs = wav->timeoffs;
+ wmd->width = wav->width;
+
+ BLI_addtail(&ob->modifiers, wmd);
+
+ BLI_remlink(&ob->effect, paf);
+ MEM_freeN(paf);
+
+ paf = next;
+ continue;
+ }
+ if (paf->type == EFF_BUILD) {
+ BuildEff *baf = (BuildEff *)paf;
+ PartEff *next = paf->next;
+ BuildModifierData *bmd = (BuildModifierData *)BKE_modifier_new(eModifierType_Build);
+
+ bmd->start = baf->sfra;
+ bmd->length = baf->len;
+ bmd->randomize = 0;
+ bmd->seed = 1;
+
+ BLI_addtail(&ob->modifiers, bmd);
+
+ BLI_remlink(&ob->effect, paf);
+ MEM_freeN(paf);
+
+ paf = next;
+ continue;
+ }
+ paf = paf->next;
+ }
+
+ BLO_read_data_address(reader, &ob->pd);
+ BKE_particle_partdeflect_blend_read_data(reader, ob->pd);
+ BLO_read_data_address(reader, &ob->soft);
+ if (ob->soft) {
+ SoftBody *sb = ob->soft;
+
+ sb->bpoint = NULL; /* init pointers so it gets rebuilt nicely */
+ sb->bspring = NULL;
+ sb->scratch = NULL;
+ /* although not used anymore */
+ /* still have to be loaded to be compatible with old files */
+ 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_data_address(reader, &sb->effector_weights);
+ if (!sb->effector_weights) {
+ sb->effector_weights = BKE_effector_add_weights(NULL);
+ }
+
+ BLO_read_data_address(reader, &sb->shared);
+ if (sb->shared == NULL) {
+ /* Link deprecated caches if they exist, so we can use them for versioning.
+ * We should only do this when sb->shared == NULL, because those pointers
+ * are always set (for compatibility with older Blenders). We mustn't link
+ * the same pointcache twice. */
+ BKE_ptcache_blend_read_data(reader, &sb->ptcaches, &sb->pointcache, false);
+ }
+ else {
+ /* link caches */
+ BKE_ptcache_blend_read_data(reader, &sb->shared->ptcaches, &sb->shared->pointcache, false);
+ }
+ }
+ BLO_read_data_address(reader, &ob->fluidsimSettings); /* NT */
+
+ BLO_read_data_address(reader, &ob->rigidbody_object);
+ if (ob->rigidbody_object) {
+ RigidBodyOb *rbo = ob->rigidbody_object;
+ /* Allocate runtime-only struct */
+ rbo->shared = MEM_callocN(sizeof(*rbo->shared), "RigidBodyObShared");
+ }
+ BLO_read_data_address(reader, &ob->rigidbody_constraint);
+ if (ob->rigidbody_constraint) {
+ ob->rigidbody_constraint->physics_constraint = NULL;
+ }
+
+ BLO_read_list(reader, &ob->particlesystem);
+ BKE_particle_system_blend_read_data(reader, &ob->particlesystem);
+
+ BKE_constraint_blend_read_data(reader, &ob->constraints);
+
+ BLO_read_list(reader, &ob->hooks);
+ while (ob->hooks.first) {
+ ObHook *hook = ob->hooks.first;
+ HookModifierData *hmd = (HookModifierData *)BKE_modifier_new(eModifierType_Hook);
+
+ BLO_read_int32_array(reader, hook->totindex, &hook->indexar);
+
+ /* Do conversion here because if we have loaded
+ * a hook we need to make sure it gets converted
+ * and freed, regardless of version.
+ */
+ copy_v3_v3(hmd->cent, hook->cent);
+ hmd->falloff = hook->falloff;
+ hmd->force = hook->force;
+ hmd->indexar = hook->indexar;
+ hmd->object = hook->parent;
+ memcpy(hmd->parentinv, hook->parentinv, sizeof(hmd->parentinv));
+ hmd->totindex = hook->totindex;
+
+ BLI_addhead(&ob->modifiers, hmd);
+ BLI_remlink(&ob->hooks, hook);
+
+ BKE_modifier_unique_name(&ob->modifiers, (ModifierData *)hmd);
+
+ MEM_freeN(hook);
+ }
+
+ BLO_read_data_address(reader, &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);
+ }
+
+ BKE_object_runtime_reset(ob);
+ BLO_read_list(reader, &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);
+
+ if (ob->sculpt) {
+ ob->sculpt = NULL;
+ /* Only create data on undo, otherwise rely on editor mode switching. */
+ if (BLO_read_data_is_undo(reader) && (ob->mode & OB_MODE_ALL_SCULPT)) {
+ BKE_object_sculpt_data_create(ob);
+ }
+ }
+
+ BLO_read_data_address(reader, &ob->preview);
+ BKE_previewimg_blend_read(reader, ob->preview);
+}
+
+/* XXX deprecated - old animation system */
+static void lib_link_nlastrips(BlendLibReader *reader, ID *id, ListBase *striplist)
+{
+ LISTBASE_FOREACH (bActionStrip *, strip, striplist) {
+ BLO_read_id_address(reader, id->lib, &strip->object);
+ BLO_read_id_address(reader, id->lib, &strip->act);
+ BLO_read_id_address(reader, id->lib, &strip->ipo);
+ LISTBASE_FOREACH (bActionModifier *, amod, &strip->modifiers) {
+ BLO_read_id_address(reader, id->lib, &amod->ob);
+ }
+ }
+}
+
+/* XXX deprecated - old animation system */
+static void lib_link_constraint_channels(BlendLibReader *reader, ID *id, ListBase *chanbase)
+{
+ LISTBASE_FOREACH (bConstraintChannel *, chan, chanbase) {
+ BLO_read_id_address(reader, id->lib, &chan->ipo);
+ }
+}
+
+static void object_blend_read_lib(BlendLibReader *reader, ID *id)
+{
+ Object *ob = (Object *)id;
+
+ bool warn = false;
+
+ /* XXX deprecated - old animation system <<< */
+ BLO_read_id_address(reader, ob->id.lib, &ob->ipo);
+ BLO_read_id_address(reader, ob->id.lib, &ob->action);
+ /* >>> XXX deprecated - old animation system */
+
+ BLO_read_id_address(reader, ob->id.lib, &ob->parent);
+ BLO_read_id_address(reader, ob->id.lib, &ob->track);
+ BLO_read_id_address(reader, ob->id.lib, &ob->poselib);
+
+ /* 2.8x drops support for non-empty dupli instances. */
+ if (ob->type == OB_EMPTY) {
+ BLO_read_id_address(reader, ob->id.lib, &ob->instance_collection);
+ }
+ else {
+ if (ob->instance_collection != NULL) {
+ ID *new_id = BLO_read_get_new_id_address(reader, ob->id.lib, &ob->instance_collection->id);
+ BLO_reportf_wrap(BLO_read_lib_reports(reader),
+ RPT_WARNING,
+ TIP_("Non-Empty object '%s' cannot duplicate collection '%s' "
+ "anymore in Blender 2.80, removed instancing"),
+ ob->id.name + 2,
+ new_id->name + 2);
+ }
+ ob->instance_collection = NULL;
+ ob->transflag &= ~OB_DUPLICOLLECTION;
+ }
+
+ BLO_read_id_address(reader, ob->id.lib, &ob->proxy);
+ if (ob->proxy) {
+ /* paranoia check, actually a proxy_from pointer should never be written... */
+ if (ob->proxy->id.lib == NULL) {
+ ob->proxy->proxy_from = NULL;
+ ob->proxy = NULL;
+
+ if (ob->id.lib) {
+ printf("Proxy lost from object %s lib %s\n", ob->id.name + 2, ob->id.lib->filepath);
+ }
+ else {
+ printf("Proxy lost from object %s lib <NONE>\n", ob->id.name + 2);
+ }
+ }
+ else {
+ /* this triggers object_update to always use a copy */
+ ob->proxy->proxy_from = ob;
+ }
+ }
+ BLO_read_id_address(reader, ob->id.lib, &ob->proxy_group);
+
+ void *poin = ob->data;
+ BLO_read_id_address(reader, ob->id.lib, &ob->data);
+
+ if (ob->data == NULL && poin != NULL) {
+ if (ob->id.lib) {
+ printf("Can't find obdata of %s lib %s\n", ob->id.name + 2, ob->id.lib->filepath);
+ }
+ else {
+ printf("Object %s lost data.\n", ob->id.name + 2);
+ }
+
+ ob->type = OB_EMPTY;
+ warn = true;
+
+ if (ob->pose) {
+ /* we can't call #BKE_pose_free() here because of library linking
+ * freeing will recurse down into every pose constraints ID pointers
+ * which are not always valid, so for now free directly and suffer
+ * some leaked memory rather than crashing immediately
+ * while bad this _is_ an exceptional case - campbell */
+#if 0
+ BKE_pose_free(ob->pose);
+#else
+ MEM_freeN(ob->pose);
+#endif
+ ob->pose = NULL;
+ ob->mode &= ~OB_MODE_POSE;
+ }
+ }
+ for (int a = 0; a < ob->totcol; a++) {
+ BLO_read_id_address(reader, ob->id.lib, &ob->mat[a]);
+ }
+
+ /* When the object is local and the data is library its possible
+ * the material list size gets out of sync. T22663. */
+ if (ob->data && ob->id.lib != ((ID *)ob->data)->lib) {
+ const short *totcol_data = BKE_object_material_len_p(ob);
+ /* Only expand so as not to lose any object materials that might be set. */
+ if (totcol_data && (*totcol_data > ob->totcol)) {
+ /* printf("'%s' %d -> %d\n", ob->id.name, ob->totcol, *totcol_data); */
+ BKE_object_material_resize(BLO_read_lib_get_main(reader), ob, *totcol_data, false);
+ }
+ }
+
+ BLO_read_id_address(reader, ob->id.lib, &ob->gpd);
+
+ /* if id.us==0 a new base will be created later on */
+
+ /* WARNING! Also check expand_object(), should reflect the stuff below. */
+ BKE_pose_blend_read_lib(reader, ob, ob->pose);
+ BKE_constraint_blend_read_lib(reader, &ob->id, &ob->constraints);
+
+ /* XXX deprecated - old animation system <<< */
+ lib_link_constraint_channels(reader, &ob->id, &ob->constraintChannels);
+ lib_link_nlastrips(reader, &ob->id, &ob->nlastrips);
+ /* >>> XXX deprecated - old animation system */
+
+ LISTBASE_FOREACH (PartEff *, paf, &ob->effect) {
+ if (paf->type == EFF_PARTICLE) {
+ BLO_read_id_address(reader, ob->id.lib, &paf->group);
+ }
+ }
+
+ {
+ FluidsimModifierData *fluidmd = (FluidsimModifierData *)BKE_modifiers_findby_type(
+ ob, eModifierType_Fluidsim);
+
+ if (fluidmd && fluidmd->fss) {
+ BLO_read_id_address(
+ reader, ob->id.lib, &fluidmd->fss->ipo); /* XXX deprecated - old animation system */
+ }
+ }
+
+ {
+ FluidModifierData *fmd = (FluidModifierData *)BKE_modifiers_findby_type(ob,
+ eModifierType_Fluid);
+
+ if (fmd && (fmd->type == MOD_FLUID_TYPE_DOMAIN) && fmd->domain) {
+ /* Flag for refreshing the simulation after loading */
+ fmd->domain->flags |= FLUID_DOMAIN_FILE_LOAD;
+ }
+ else if (fmd && (fmd->type == MOD_FLUID_TYPE_FLOW) && fmd->flow) {
+ fmd->flow->flags &= ~FLUID_FLOW_NEEDS_UPDATE;
+ }
+ else if (fmd && (fmd->type == MOD_FLUID_TYPE_EFFEC) && fmd->effector) {
+ fmd->effector->flags &= ~FLUID_EFFECTOR_NEEDS_UPDATE;
+ }
+ }
+
+ /* texture field */
+ if (ob->pd) {
+ BKE_particle_partdeflect_blend_read_lib(reader, &ob->id, ob->pd);
+ }
+
+ if (ob->soft) {
+ BLO_read_id_address(reader, ob->id.lib, &ob->soft->collision_group);
+
+ BLO_read_id_address(reader, ob->id.lib, &ob->soft->effector_weights->group);
+ }
+
+ BKE_particle_system_blend_read_lib(reader, ob, &ob->id, &ob->particlesystem);
+ BKE_modifier_blend_read_lib(reader, ob);
+ BKE_gpencil_modifier_blend_read_lib(reader, ob);
+ BKE_shaderfx_blend_read_lib(reader, ob);
+
+ if (ob->rigidbody_constraint) {
+ BLO_read_id_address(reader, ob->id.lib, &ob->rigidbody_constraint->ob1);
+ BLO_read_id_address(reader, ob->id.lib, &ob->rigidbody_constraint->ob2);
+ }
+
+ if (warn) {
+ BLO_reportf_wrap(BLO_read_lib_reports(reader), RPT_WARNING, "Warning in console");
+ }
+}
+
+/* XXX deprecated - old animation system */
+static void expand_constraint_channels(BlendExpander *expander, ListBase *chanbase)
+{
+ LISTBASE_FOREACH (bConstraintChannel *, chan, chanbase) {
+ BLO_expand(expander, chan->ipo);
+ }
+}
+
+static void expand_object_expandModifiers(void *userData,
+ Object *UNUSED(ob),
+ ID **idpoin,
+ int UNUSED(cb_flag))
+{
+ BlendExpander *expander = userData;
+ BLO_expand(expander, *idpoin);
+}
+
+PartEff *BKE_object_do_version_give_parteff_245(Object *ob)
+{
+ PartEff *paf;
+
+ paf = ob->effect.first;
+ while (paf) {
+ if (paf->type == EFF_PARTICLE) {
+ return paf;
+ }
+ paf = paf->next;
+ }
+ return NULL;
+}
+
+static void object_blend_read_expand(BlendExpander *expander, ID *id)
+{
+ Object *ob = (Object *)id;
+
+ BLO_expand(expander, ob->data);
+
+ /* expand_object_expandModifier() */
+ if (ob->modifiers.first) {
+ BKE_modifiers_foreach_ID_link(ob, expand_object_expandModifiers, expander);
+ }
+
+ /* expand_object_expandModifier() */
+ if (ob->greasepencil_modifiers.first) {
+ BKE_gpencil_modifiers_foreach_ID_link(ob, expand_object_expandModifiers, expander);
+ }
+
+ /* expand_object_expandShaderFx() */
+ if (ob->shader_fx.first) {
+ BKE_shaderfx_foreach_ID_link(ob, expand_object_expandModifiers, expander);
+ }
+
+ BKE_pose_blend_read_expand(expander, ob->pose);
+ BLO_expand(expander, ob->poselib);
+ BKE_constraint_blend_read_expand(expander, &ob->constraints);
+
+ BLO_expand(expander, ob->gpd);
+
+ /* XXX deprecated - old animation system (for version patching only) */
+ BLO_expand(expander, ob->ipo);
+ BLO_expand(expander, ob->action);
+
+ expand_constraint_channels(expander, &ob->constraintChannels);
+
+ LISTBASE_FOREACH (bActionStrip *, strip, &ob->nlastrips) {
+ BLO_expand(expander, strip->object);
+ BLO_expand(expander, strip->act);
+ BLO_expand(expander, strip->ipo);
+ }
+ /* XXX deprecated - old animation system (for version patching only) */
+
+ for (int a = 0; a < ob->totcol; a++) {
+ BLO_expand(expander, ob->mat[a]);
+ }
+
+ PartEff *paf = BKE_object_do_version_give_parteff_245(ob);
+ if (paf && paf->group) {
+ BLO_expand(expander, paf->group);
+ }
+
+ if (ob->instance_collection) {
+ BLO_expand(expander, ob->instance_collection);
+ }
+
+ if (ob->proxy) {
+ BLO_expand(expander, ob->proxy);
+ }
+ if (ob->proxy_group) {
+ BLO_expand(expander, ob->proxy_group);
+ }
+
+ LISTBASE_FOREACH (ParticleSystem *, psys, &ob->particlesystem) {
+ BLO_expand(expander, psys->part);
+ }
+
+ if (ob->pd) {
+ BLO_expand(expander, ob->pd->tex);
+ BLO_expand(expander, ob->pd->f_source);
+ }
+
+ if (ob->soft) {
+ BLO_expand(expander, ob->soft->collision_group);
+
+ if (ob->soft->effector_weights) {
+ BLO_expand(expander, ob->soft->effector_weights->group);
+ }
+ }
+
+ if (ob->rigidbody_constraint) {
+ BLO_expand(expander, ob->rigidbody_constraint->ob1);
+ BLO_expand(expander, ob->rigidbody_constraint->ob2);
+ }
+}
+
IDTypeInfo IDType_ID_OB = {
.id_code = ID_OB,
.id_filter = FILTER_ID_OB,
@@ -533,10 +1150,12 @@ IDTypeInfo IDType_ID_OB = {
.foreach_id = object_foreach_id,
.foreach_cache = NULL,
- .blend_write = NULL,
- .blend_read_data = NULL,
- .blend_read_lib = NULL,
- .blend_read_expand = NULL,
+ .blend_write = object_blend_write,
+ .blend_read_data = object_blend_read_data,
+ .blend_read_lib = object_blend_read_lib,
+ .blend_read_expand = object_blend_read_expand,
+
+ .blend_read_undo_preserve = NULL,
};
void BKE_object_workob_clear(Object *workob)
@@ -4806,3 +5425,16 @@ void BKE_object_check_uuids_unique_and_report(const Object *object)
BKE_pose_check_uuids_unique_and_report(object->pose);
BKE_modifier_check_uuids_unique_and_report(object);
}
+
+void BKE_object_modifiers_lib_link_common(void *userData,
+ struct Object *ob,
+ struct ID **idpoin,
+ int cb_flag)
+{
+ BlendLibReader *reader = userData;
+
+ BLO_read_id_address(reader, ob->id.lib, idpoin);
+ if (*idpoin != NULL && (cb_flag & IDWALK_CB_USER) != 0) {
+ id_us_plus_no_lib(*idpoin);
+ }
+}
diff --git a/source/blender/blenkernel/intern/object_deform.c b/source/blender/blenkernel/intern/object_deform.c
index 04f7529c6cd..1e7624d0d7d 100644
--- a/source/blender/blenkernel/intern/object_deform.c
+++ b/source/blender/blenkernel/intern/object_deform.c
@@ -51,6 +51,7 @@
#include "BKE_object.h"
#include "BKE_object_deform.h" /* own include */
+/* -------------------------------------------------------------------- */
/** \name Misc helpers
* \{ */
@@ -106,6 +107,7 @@ void BKE_object_defgroup_remap_update_users(Object *ob, const int *map)
}
/** \} */
+/* -------------------------------------------------------------------- */
/** \name Group creation
* \{ */
@@ -156,6 +158,7 @@ MDeformVert *BKE_object_defgroup_data_create(ID *id)
}
/** \} */
+/* -------------------------------------------------------------------- */
/** \name Group clearing
* \{ */
@@ -256,6 +259,7 @@ bool BKE_object_defgroup_clear_all(Object *ob, const bool use_selection)
}
/** \} */
+/* -------------------------------------------------------------------- */
/** \name Group removal
* \{ */
diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c
index 39d6ee2700c..a1b01bce6c9 100644
--- a/source/blender/blenkernel/intern/object_dupli.c
+++ b/source/blender/blenkernel/intern/object_dupli.c
@@ -1392,7 +1392,7 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
mat4_to_size(original_size, obmat);
size_to_mat4(size_mat, original_size);
- xvec[0] = -1.f;
+ xvec[0] = -1.0f;
xvec[1] = xvec[2] = 0;
vec_to_quat(q, xvec, ob->trackflag, ob->upflag);
quat_to_mat4(obmat, q);
diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c
index 6c770e53000..1d62a1cce2a 100644
--- a/source/blender/blenkernel/intern/ocean.c
+++ b/source/blender/blenkernel/intern/ocean.c
@@ -47,7 +47,7 @@
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
-#include "RE_render_ext.h"
+#include "RE_texture.h"
#include "BLI_hash.h"
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 42749a93988..d726a4b1e37 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -125,6 +125,16 @@ static void palette_blend_read_data(BlendDataReader *reader, ID *id)
BLO_read_list(reader, &palette->colors);
}
+static void palette_undo_preserve(BlendLibReader *UNUSED(reader), ID *id_new, ID *id_old)
+{
+ /* Whole Palette is preserved accross undo's, and it has no extra pointer, simple. */
+ /* Note: We do not care about potential internal references to self here, Palette has none. */
+ /* Note: We do not swap IDProperties, as dealing with potential ID pointers in those would be
+ * fairly delicate. */
+ BKE_lib_id_swap(NULL, id_new, id_old);
+ SWAP(IDProperty *, id_new->properties, id_old->properties);
+}
+
IDTypeInfo IDType_ID_PAL = {
.id_code = ID_PAL,
.id_filter = FILTER_ID_PAL,
@@ -146,6 +156,8 @@ IDTypeInfo IDType_ID_PAL = {
.blend_read_data = palette_blend_read_data,
.blend_read_lib = NULL,
.blend_read_expand = NULL,
+
+ .blend_read_undo_preserve = palette_undo_preserve,
};
static void paint_curve_copy_data(Main *UNUSED(bmain),
@@ -207,6 +219,8 @@ IDTypeInfo IDType_ID_PC = {
.blend_read_data = paint_curve_blend_read_data,
.blend_read_lib = NULL,
.blend_read_expand = NULL,
+
+ .blend_read_undo_preserve = NULL,
};
const char PAINT_CURSOR_SCULPT[3] = {255, 100, 100};
@@ -1162,6 +1176,56 @@ void BKE_paint_stroke_get_average(Scene *scene, Object *ob, float stroke[3])
}
}
+void BKE_paint_blend_write(BlendWriter *writer, Paint *p)
+{
+ if (p->cavity_curve) {
+ BKE_curvemapping_blend_write(writer, p->cavity_curve);
+ }
+ BLO_write_struct_array(writer, PaintToolSlot, p->tool_slots_len, p->tool_slots);
+}
+
+void BKE_paint_blend_read_data(BlendDataReader *reader, const Scene *scene, Paint *p)
+{
+ if (p->num_input_samples < 1) {
+ p->num_input_samples = 1;
+ }
+
+ BLO_read_data_address(reader, &p->cavity_curve);
+ if (p->cavity_curve) {
+ BKE_curvemapping_blend_read(reader, p->cavity_curve);
+ }
+ else {
+ BKE_paint_cavity_curve_preset(p, CURVE_PRESET_LINE);
+ }
+
+ BLO_read_data_address(reader, &p->tool_slots);
+
+ /* Workaround for invalid data written in older versions. */
+ const size_t expected_size = sizeof(PaintToolSlot) * p->tool_slots_len;
+ if (p->tool_slots && MEM_allocN_len(p->tool_slots) < expected_size) {
+ MEM_freeN(p->tool_slots);
+ p->tool_slots = MEM_callocN(expected_size, "PaintToolSlot");
+ }
+
+ BKE_paint_runtime_init(scene->toolsettings, p);
+}
+
+void BKE_paint_blend_read_lib(BlendLibReader *reader, Scene *sce, Paint *p)
+{
+ if (p) {
+ BLO_read_id_address(reader, sce->id.lib, &p->brush);
+ for (int i = 0; i < p->tool_slots_len; i++) {
+ if (p->tool_slots[i].brush != NULL) {
+ BLO_read_id_address(reader, sce->id.lib, &p->tool_slots[i].brush);
+ }
+ }
+ BLO_read_id_address(reader, sce->id.lib, &p->palette);
+ p->paint_cursor = NULL;
+
+ BKE_paint_runtime_init(sce->toolsettings, p);
+ }
+}
+
/* returns non-zero if any of the face's vertices
* are hidden, zero otherwise */
bool paint_is_face_hidden(const MLoopTri *lt, const MVert *mvert, const MLoop *mloop)
@@ -1734,17 +1798,16 @@ void BKE_sculpt_color_layer_create_if_needed(struct Object *object)
DEG_id_tag_update(&orig_me->id, ID_RECALC_GEOMETRY);
}
+/** \warning Expects a fully evaluated depsgraph. */
void BKE_sculpt_update_object_for_edit(
Depsgraph *depsgraph, Object *ob_orig, bool need_pmap, bool need_mask, bool need_colors)
{
- /* Update from sculpt operators and undo, to update sculpt session
- * and PBVH after edits. */
- Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
- Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob_orig);
- Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH);
-
BLI_assert(ob_orig == DEG_get_original_object(ob_orig));
+ Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob_orig);
+ Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval);
+ BLI_assert(me_eval != NULL);
+
sculpt_update_object(depsgraph, ob_orig, me_eval, need_pmap, need_mask, need_colors);
}
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 7b8ee7343ee..0b331fb88d2 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -21,6 +21,9 @@
* \ingroup bke
*/
+/* Allow using deprecated functionality for .blend file I/O. */
+#define DNA_DEPRECATED_ALLOW
+
#include <math.h>
#include <stdlib.h>
#include <string.h>
@@ -29,6 +32,7 @@
#include "DNA_defaults.h"
+#include "DNA_cloth_types.h"
#include "DNA_collection_types.h"
#include "DNA_curve_types.h"
#include "DNA_dynamicpaint_types.h"
@@ -52,6 +56,7 @@
#include "BLT_translation.h"
+#include "BKE_anim_data.h"
#include "BKE_anim_path.h"
#include "BKE_boids.h"
#include "BKE_cloth.h"
@@ -78,7 +83,9 @@
#include "DEG_depsgraph_build.h"
#include "DEG_depsgraph_query.h"
-#include "RE_render_ext.h"
+#include "RE_texture.h"
+
+#include "BLO_read_write.h"
#include "particle_private.h"
@@ -206,6 +213,279 @@ static void particle_settings_foreach_id(ID *id, LibraryForeachIDData *data)
}
}
+static void write_boid_state(BlendWriter *writer, BoidState *state)
+{
+ BLO_write_struct(writer, BoidState, state);
+
+ LISTBASE_FOREACH (BoidRule *, rule, &state->rules) {
+ switch (rule->type) {
+ case eBoidRuleType_Goal:
+ case eBoidRuleType_Avoid:
+ BLO_write_struct(writer, BoidRuleGoalAvoid, rule);
+ break;
+ case eBoidRuleType_AvoidCollision:
+ BLO_write_struct(writer, BoidRuleAvoidCollision, rule);
+ break;
+ case eBoidRuleType_FollowLeader:
+ BLO_write_struct(writer, BoidRuleFollowLeader, rule);
+ break;
+ case eBoidRuleType_AverageSpeed:
+ BLO_write_struct(writer, BoidRuleAverageSpeed, rule);
+ break;
+ case eBoidRuleType_Fight:
+ BLO_write_struct(writer, BoidRuleFight, rule);
+ break;
+ default:
+ BLO_write_struct(writer, BoidRule, rule);
+ break;
+ }
+ }
+#if 0
+ BoidCondition *cond = state->conditions.first;
+ for (; cond; cond = cond->next) {
+ BLO_write_struct(writer, BoidCondition, cond);
+ }
+#endif
+}
+
+static void particle_settings_blend_write(BlendWriter *writer, ID *id, const void *id_address)
+{
+ ParticleSettings *part = (ParticleSettings *)id;
+ if (part->id.us > 0 || BLO_write_is_undo(writer)) {
+ /* write LibData */
+ BLO_write_id_struct(writer, ParticleSettings, id_address, &part->id);
+ BKE_id_blend_write(writer, &part->id);
+
+ if (part->adt) {
+ BKE_animdata_blend_write(writer, part->adt);
+ }
+ BLO_write_struct(writer, PartDeflect, part->pd);
+ BLO_write_struct(writer, PartDeflect, part->pd2);
+ BLO_write_struct(writer, EffectorWeights, part->effector_weights);
+
+ if (part->clumpcurve) {
+ BKE_curvemapping_blend_write(writer, part->clumpcurve);
+ }
+ if (part->roughcurve) {
+ BKE_curvemapping_blend_write(writer, part->roughcurve);
+ }
+ if (part->twistcurve) {
+ BKE_curvemapping_blend_write(writer, part->twistcurve);
+ }
+
+ LISTBASE_FOREACH (ParticleDupliWeight *, dw, &part->instance_weights) {
+ /* update indices, but only if dw->ob is set (can be NULL after loading e.g.) */
+ if (dw->ob != NULL) {
+ dw->index = 0;
+ if (part->instance_collection) { /* can be NULL if lining fails or set to None */
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (part->instance_collection, object) {
+ if (object == dw->ob) {
+ break;
+ }
+ dw->index++;
+ }
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
+ }
+ }
+ BLO_write_struct(writer, ParticleDupliWeight, dw);
+ }
+
+ if (part->boids && part->phystype == PART_PHYS_BOIDS) {
+ BLO_write_struct(writer, BoidSettings, part->boids);
+
+ LISTBASE_FOREACH (BoidState *, state, &part->boids->states) {
+ write_boid_state(writer, state);
+ }
+ }
+ if (part->fluid && part->phystype == PART_PHYS_FLUID) {
+ BLO_write_struct(writer, SPHFluidSettings, part->fluid);
+ }
+
+ for (int a = 0; a < MAX_MTEX; a++) {
+ if (part->mtex[a]) {
+ BLO_write_struct(writer, MTex, part->mtex[a]);
+ }
+ }
+ }
+}
+
+void BKE_particle_partdeflect_blend_read_data(BlendDataReader *UNUSED(reader), PartDeflect *pd)
+{
+ if (pd) {
+ pd->rng = NULL;
+ }
+}
+
+static void particle_settings_blend_read_data(BlendDataReader *reader, ID *id)
+{
+ ParticleSettings *part = (ParticleSettings *)id;
+ BLO_read_data_address(reader, &part->adt);
+ BLO_read_data_address(reader, &part->pd);
+ BLO_read_data_address(reader, &part->pd2);
+
+ BKE_animdata_blend_read_data(reader, part->adt);
+ 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);
+ if (part->clumpcurve) {
+ BKE_curvemapping_blend_read(reader, part->clumpcurve);
+ }
+ BLO_read_data_address(reader, &part->roughcurve);
+ if (part->roughcurve) {
+ BKE_curvemapping_blend_read(reader, part->roughcurve);
+ }
+ BLO_read_data_address(reader, &part->twistcurve);
+ if (part->twistcurve) {
+ BKE_curvemapping_blend_read(reader, part->twistcurve);
+ }
+
+ BLO_read_data_address(reader, &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_data_address(reader, &part->boids);
+ BLO_read_data_address(reader, &part->fluid);
+
+ if (part->boids) {
+ BLO_read_list(reader, &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);
+ }
+ }
+ for (int a = 0; a < MAX_MTEX; a++) {
+ BLO_read_data_address(reader, &part->mtex[a]);
+ }
+
+ /* Protect against integer overflow vulnerability. */
+ CLAMP(part->trail_count, 1, 100000);
+}
+
+void BKE_particle_partdeflect_blend_read_lib(BlendLibReader *reader, ID *id, PartDeflect *pd)
+{
+ if (pd && pd->tex) {
+ BLO_read_id_address(reader, id->lib, &pd->tex);
+ }
+ if (pd && pd->f_source) {
+ BLO_read_id_address(reader, id->lib, &pd->f_source);
+ }
+}
+
+static void particle_settings_blend_read_lib(BlendLibReader *reader, ID *id)
+{
+ ParticleSettings *part = (ParticleSettings *)id;
+ BLO_read_id_address(
+ reader, part->id.lib, &part->ipo); /* XXX deprecated - old animation system */
+
+ BLO_read_id_address(reader, part->id.lib, &part->instance_object);
+ BLO_read_id_address(reader, part->id.lib, &part->instance_collection);
+ BLO_read_id_address(reader, part->id.lib, &part->force_group);
+ BLO_read_id_address(reader, part->id.lib, &part->bb_ob);
+ BLO_read_id_address(reader, part->id.lib, &part->collision_group);
+
+ BKE_particle_partdeflect_blend_read_lib(reader, &part->id, part->pd);
+ BKE_particle_partdeflect_blend_read_lib(reader, &part->id, part->pd2);
+
+ if (part->effector_weights) {
+ BLO_read_id_address(reader, part->id.lib, &part->effector_weights->group);
+ }
+ else {
+ part->effector_weights = BKE_effector_add_weights(part->force_group);
+ }
+
+ if (part->instance_weights.first && part->instance_collection) {
+ LISTBASE_FOREACH (ParticleDupliWeight *, dw, &part->instance_weights) {
+ BLO_read_id_address(reader, part->id.lib, &dw->ob);
+ }
+ }
+ else {
+ BLI_listbase_clear(&part->instance_weights);
+ }
+
+ if (part->boids) {
+ LISTBASE_FOREACH (BoidState *, state, &part->boids->states) {
+ LISTBASE_FOREACH (BoidRule *, rule, &state->rules) {
+ switch (rule->type) {
+ case eBoidRuleType_Goal:
+ case eBoidRuleType_Avoid: {
+ BoidRuleGoalAvoid *brga = (BoidRuleGoalAvoid *)rule;
+ BLO_read_id_address(reader, part->id.lib, &brga->ob);
+ break;
+ }
+ case eBoidRuleType_FollowLeader: {
+ BoidRuleFollowLeader *brfl = (BoidRuleFollowLeader *)rule;
+ BLO_read_id_address(reader, part->id.lib, &brfl->ob);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ for (int a = 0; a < MAX_MTEX; a++) {
+ MTex *mtex = part->mtex[a];
+ if (mtex) {
+ BLO_read_id_address(reader, part->id.lib, &mtex->tex);
+ BLO_read_id_address(reader, part->id.lib, &mtex->object);
+ }
+ }
+}
+
+static void particle_settings_blend_read_expand(BlendExpander *expander, ID *id)
+{
+ ParticleSettings *part = (ParticleSettings *)id;
+ BLO_expand(expander, part->instance_object);
+ BLO_expand(expander, part->instance_collection);
+ BLO_expand(expander, part->force_group);
+ BLO_expand(expander, part->bb_ob);
+ BLO_expand(expander, part->collision_group);
+
+ for (int a = 0; a < MAX_MTEX; a++) {
+ if (part->mtex[a]) {
+ BLO_expand(expander, part->mtex[a]->tex);
+ BLO_expand(expander, part->mtex[a]->object);
+ }
+ }
+
+ if (part->effector_weights) {
+ BLO_expand(expander, part->effector_weights->group);
+ }
+
+ if (part->pd) {
+ BLO_expand(expander, part->pd->tex);
+ BLO_expand(expander, part->pd->f_source);
+ }
+ if (part->pd2) {
+ BLO_expand(expander, part->pd2->tex);
+ BLO_expand(expander, part->pd2->f_source);
+ }
+
+ if (part->boids) {
+ LISTBASE_FOREACH (BoidState *, state, &part->boids->states) {
+ LISTBASE_FOREACH (BoidRule *, rule, &state->rules) {
+ if (rule->type == eBoidRuleType_Avoid) {
+ BoidRuleGoalAvoid *gabr = (BoidRuleGoalAvoid *)rule;
+ BLO_expand(expander, gabr->ob);
+ }
+ else if (rule->type == eBoidRuleType_FollowLeader) {
+ BoidRuleFollowLeader *flbr = (BoidRuleFollowLeader *)rule;
+ BLO_expand(expander, flbr->ob);
+ }
+ }
+ }
+ }
+
+ LISTBASE_FOREACH (ParticleDupliWeight *, dw, &part->instance_weights) {
+ BLO_expand(expander, dw->ob);
+ }
+}
+
IDTypeInfo IDType_ID_PA = {
.id_code = ID_PA,
.id_filter = FILTER_ID_PA,
@@ -223,17 +503,19 @@ IDTypeInfo IDType_ID_PA = {
.foreach_id = particle_settings_foreach_id,
.foreach_cache = NULL,
- .blend_write = NULL,
- .blend_read_data = NULL,
- .blend_read_lib = NULL,
- .blend_read_expand = NULL,
+ .blend_write = particle_settings_blend_write,
+ .blend_read_data = particle_settings_blend_read_data,
+ .blend_read_lib = particle_settings_blend_read_lib,
+ .blend_read_expand = particle_settings_blend_read_expand,
+
+ .blend_read_undo_preserve = NULL,
};
unsigned int PSYS_FRAND_SEED_OFFSET[PSYS_FRAND_COUNT];
unsigned int PSYS_FRAND_SEED_MULTIPLIER[PSYS_FRAND_COUNT];
float PSYS_FRAND_BASE[PSYS_FRAND_COUNT];
-void psys_init_rng(void)
+void BKE_particle_init_rng(void)
{
RNG *rng = BLI_rng_new_srandom(5831); /* arbitrary */
for (int i = 0; i < PSYS_FRAND_COUNT; i++) {
@@ -917,7 +1199,7 @@ static float interpolate_particle_value(
value += w[3] * v4;
}
- CLAMP(value, 0.f, 1.f);
+ CLAMP(value, 0.0f, 1.0f);
return value;
}
@@ -1146,7 +1428,7 @@ static void do_particle_interpolation(ParticleSystem *psys,
PTCacheEditPoint *point = pind->epoint;
ParticleKey keys[4];
int point_vel = (point && point->keys->vel);
- float real_t, dfra, keytime, invdt = 1.f;
+ float real_t, dfra, keytime, invdt = 1.0f;
/* billboards wont fill in all of these, so start cleared */
memset(keys, 0, sizeof(keys));
@@ -1316,7 +1598,7 @@ static void do_particle_interpolation(ParticleSystem *psys,
/* Convert velocity to time-step size. */
if (pind->keyed || pind->cache || point_vel) {
- invdt = dfra * 0.04f * (psys ? psys->part->timetweak : 1.f);
+ invdt = dfra * 0.04f * (psys ? psys->part->timetweak : 1.0f);
mul_v3_fl(keys[1].vel, invdt);
mul_v3_fl(keys[2].vel, invdt);
interp_qt_qtqt(result->rot, keys[1].rot, keys[2].rot, keytime);
@@ -1335,7 +1617,7 @@ static void do_particle_interpolation(ParticleSystem *psys,
/* the velocity needs to be converted back from cubic interpolation */
if (pind->keyed || pind->cache || point_vel) {
- mul_v3_fl(result->vel, 1.f / invdt);
+ mul_v3_fl(result->vel, 1.0f / invdt);
}
}
@@ -2200,7 +2482,7 @@ int do_guides(Depsgraph *depsgraph,
pd->kink_freq,
pd->kink_shape,
pd->kink_amp,
- 0.f,
+ 0.0f,
pd->kink,
pd->kink_axis,
0,
@@ -2550,12 +2832,12 @@ static void psys_thread_create_path(ParticleTask *task,
if (ctx->between) {
ParticleData *pa = psys->particles + cpa->pa[0];
int w, needupdate;
- float foffset, wsum = 0.f;
+ float foffset, wsum = 0.0f;
float co[3];
float p_min = part->parting_min;
float p_max = part->parting_max;
/* Virtual parents don't work nicely with parting. */
- float p_fac = part->parents > 0.f ? 0.f : part->parting_fac;
+ float p_fac = part->parents > 0.0f ? 0.0f : part->parting_fac;
if (ctx->editupdate) {
needupdate = 0;
@@ -2583,15 +2865,15 @@ static void psys_thread_create_path(ParticleTask *task,
}
else {
key[w] = pcache[0];
- weight[w] = 0.f;
+ weight[w] = 0.0f;
}
}
/* modify weights to create parting */
- if (p_fac > 0.f) {
+ if (p_fac > 0.0f) {
const ParticleCacheKey *key_0_last = pcache_key_segment_endpoint_safe(key[0]);
for (w = 0; w < 4; w++) {
- if (w && (weight[w] > 0.f)) {
+ if (w && (weight[w] > 0.0f)) {
const ParticleCacheKey *key_w_last = pcache_key_segment_endpoint_safe(key[w]);
float d;
if (part->flag & PART_CHILD_LONG_HAIR) {
@@ -2600,7 +2882,7 @@ static void psys_thread_create_path(ParticleTask *task,
float d1 = len_v3v3(key[0]->co, key[w]->co);
float d2 = len_v3v3(key_0_last->co, key_w_last->co);
- d = d1 > 0.f ? d2 / d1 - 1.f : 10000.f;
+ d = d1 > 0.0f ? d2 / d1 - 1.0f : 10000.0f;
}
else {
float v1[3], v2[3];
@@ -2616,13 +2898,13 @@ static void psys_thread_create_path(ParticleTask *task,
d = (d - p_min) / (p_max - p_min);
}
else {
- d = (d - p_min) <= 0.f ? 0.f : 1.f;
+ d = (d - p_min) <= 0.0f ? 0.0f : 1.0f;
}
- CLAMP(d, 0.f, 1.f);
+ CLAMP(d, 0.0f, 1.0f);
- if (d > 0.f) {
- weight[w] *= (1.f - d);
+ if (d > 0.0f) {
+ weight[w] *= (1.0f - d);
}
}
wsum += weight[w];
@@ -3059,7 +3341,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re
LOOP_PARTICLES
{
if (!psys->totchild) {
- psys_get_texture(sim, pa, &ptex, PAMAP_LENGTH, 0.f);
+ psys_get_texture(sim, pa, &ptex, PAMAP_LENGTH, 0.0f);
pa_length = ptex.length * (1.0f - part->randlength * psys_frand(psys, psys->seed + p));
if (vg_length) {
pa_length *= psys_particle_value_from_verts(psmd->mesh_final, part->from, pa, vg_length);
@@ -3716,19 +3998,25 @@ void object_remove_particle_system(Main *bmain, Scene *UNUSED(scene), Object *ob
if (psys->part->type == PART_FLUID_FLIP) {
fmd->domain->particle_type &= ~FLUID_DOMAIN_PARTICLE_FLIP;
}
- if (psys->part->type == PART_FLUID_SPRAY || psys->part->type == PART_FLUID_SPRAYFOAM ||
- psys->part->type == PART_FLUID_SPRAYBUBBLE ||
- psys->part->type == PART_FLUID_SPRAYFOAMBUBBLE) {
+ if (ELEM(psys->part->type,
+ PART_FLUID_SPRAY,
+ PART_FLUID_SPRAYFOAM,
+ PART_FLUID_SPRAYBUBBLE,
+ PART_FLUID_SPRAYFOAMBUBBLE)) {
fmd->domain->particle_type &= ~FLUID_DOMAIN_PARTICLE_SPRAY;
}
- if (psys->part->type == PART_FLUID_FOAM || psys->part->type == PART_FLUID_SPRAYFOAM ||
- psys->part->type == PART_FLUID_FOAMBUBBLE ||
- psys->part->type == PART_FLUID_SPRAYFOAMBUBBLE) {
+ if (ELEM(psys->part->type,
+ PART_FLUID_FOAM,
+ PART_FLUID_SPRAYFOAM,
+ PART_FLUID_FOAMBUBBLE,
+ PART_FLUID_SPRAYFOAMBUBBLE)) {
fmd->domain->particle_type &= ~FLUID_DOMAIN_PARTICLE_FOAM;
}
- if (psys->part->type == PART_FLUID_BUBBLE || psys->part->type == PART_FLUID_FOAMBUBBLE ||
- psys->part->type == PART_FLUID_SPRAYBUBBLE ||
- psys->part->type == PART_FLUID_SPRAYFOAMBUBBLE) {
+ if (ELEM(psys->part->type,
+ PART_FLUID_BUBBLE,
+ PART_FLUID_FOAMBUBBLE,
+ PART_FLUID_SPRAYBUBBLE,
+ PART_FLUID_SPRAYFOAMBUBBLE)) {
fmd->domain->particle_type &= ~FLUID_DOMAIN_PARTICLE_BUBBLE;
}
if (psys->part->type == PART_FLUID_TRACER) {
@@ -3736,9 +4024,11 @@ void object_remove_particle_system(Main *bmain, Scene *UNUSED(scene), Object *ob
}
/* Disable combined export if combined particle system was deleted. */
- if (psys->part->type == PART_FLUID_SPRAYFOAM || psys->part->type == PART_FLUID_SPRAYBUBBLE ||
- psys->part->type == PART_FLUID_FOAMBUBBLE ||
- psys->part->type == PART_FLUID_SPRAYFOAMBUBBLE) {
+ if (ELEM(psys->part->type,
+ PART_FLUID_SPRAYFOAM,
+ PART_FLUID_SPRAYBUBBLE,
+ PART_FLUID_FOAMBUBBLE,
+ PART_FLUID_SPRAYFOAMBUBBLE)) {
fmd->domain->sndparticle_combined_export = SNDPARTICLE_COMBINED_EXPORT_OFF;
}
}
@@ -3992,9 +4282,9 @@ static void get_cpa_texture(Mesh *mesh,
break;
case TEXCO_PARTICLE:
/* texture coordinates in range [-1, 1] */
- texvec[0] = 2.f * (cfra - par->time) / (par->dietime - par->time) - 1.f;
- texvec[1] = 0.f;
- texvec[2] = 0.f;
+ texvec[0] = 2.0f * (cfra - par->time) / (par->dietime - par->time) - 1.0f;
+ texvec[1] = 0.0f;
+ texvec[2] = 0.0f;
break;
}
@@ -4102,14 +4392,15 @@ void psys_get_texture(
break;
case TEXCO_PARTICLE:
/* texture coordinates in range [-1, 1] */
- texvec[0] = 2.f * (cfra - pa->time) / (pa->dietime - pa->time) - 1.f;
+ texvec[0] = 2.0f * (cfra - pa->time) / (pa->dietime - pa->time) - 1.0f;
if (sim->psys->totpart > 0) {
- texvec[1] = 2.f * (float)(pa - sim->psys->particles) / (float)sim->psys->totpart - 1.f;
+ texvec[1] = 2.0f * (float)(pa - sim->psys->particles) / (float)sim->psys->totpart -
+ 1.0f;
}
else {
texvec[1] = 0.0f;
}
- texvec[2] = 0.f;
+ texvec[2] = 0.0f;
break;
}
@@ -4654,8 +4945,8 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta
else {
float dfra, frs_sec = sim->scene->r.frs_sec;
/* let's interpolate to try to be as accurate as possible */
- if (pa->state.time + 2.f >= state->time && pa->prev_state.time - 2.f <= state->time) {
- if (pa->prev_state.time >= pa->state.time || pa->prev_state.time < 0.f) {
+ if (pa->state.time + 2.0f >= state->time && pa->prev_state.time - 2.0f <= state->time) {
+ if (pa->prev_state.time >= pa->state.time || pa->prev_state.time < 0.0f) {
/* prev_state is wrong so let's not use it,
* this can happen at frames 1, 0 or particle birth. */
dfra = state->time - pa->state.time;
@@ -4682,13 +4973,13 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta
psys_interpolate_particle(-1, keys, keytime, state, 1);
/* convert back to real velocity */
- mul_v3_fl(state->vel, 1.f / (dfra * timestep));
+ mul_v3_fl(state->vel, 1.0f / (dfra * timestep));
interp_v3_v3v3(state->ave, keys[1].ave, keys[2].ave, keytime);
interp_qt_qtqt(state->rot, keys[1].rot, keys[2].rot, keytime);
}
}
- else if (pa->state.time + 1.f >= state->time && pa->state.time - 1.f <= state->time) {
+ else if (pa->state.time + 1.0f >= state->time && pa->state.time - 1.0f <= state->time) {
/* linear interpolation using only pa->state */
dfra = state->time - pa->state.time;
@@ -4949,3 +5240,172 @@ void BKE_particle_batch_cache_free(ParticleSystem *psys)
BKE_particle_batch_cache_free_cb(psys);
}
}
+
+void BKE_particle_system_blend_write(BlendWriter *writer, ListBase *particles)
+{
+ LISTBASE_FOREACH (ParticleSystem *, psys, particles) {
+ BLO_write_struct(writer, ParticleSystem, psys);
+
+ if (psys->particles) {
+ BLO_write_struct_array(writer, ParticleData, psys->totpart, psys->particles);
+
+ if (psys->particles->hair) {
+ ParticleData *pa = psys->particles;
+
+ for (int a = 0; a < psys->totpart; a++, pa++) {
+ BLO_write_struct_array(writer, HairKey, pa->totkey, pa->hair);
+ }
+ }
+
+ if (psys->particles->boid && (psys->part->phystype == PART_PHYS_BOIDS)) {
+ BLO_write_struct_array(writer, BoidParticle, psys->totpart, psys->particles->boid);
+ }
+
+ if (psys->part->fluid && (psys->part->phystype == PART_PHYS_FLUID) &&
+ (psys->part->fluid->flag & SPH_VISCOELASTIC_SPRINGS)) {
+ BLO_write_struct_array(
+ writer, ParticleSpring, psys->tot_fluidsprings, psys->fluid_springs);
+ }
+ }
+ LISTBASE_FOREACH (ParticleTarget *, pt, &psys->targets) {
+ BLO_write_struct(writer, ParticleTarget, pt);
+ }
+
+ if (psys->child) {
+ BLO_write_struct_array(writer, ChildParticle, psys->totchild, psys->child);
+ }
+
+ if (psys->clmd) {
+ BLO_write_struct(writer, ClothModifierData, psys->clmd);
+ BLO_write_struct(writer, ClothSimSettings, psys->clmd->sim_parms);
+ BLO_write_struct(writer, ClothCollSettings, psys->clmd->coll_parms);
+ }
+
+ BKE_ptcache_blend_write(writer, &psys->ptcaches);
+ }
+}
+
+void BKE_particle_system_blend_read_data(BlendDataReader *reader, ListBase *particles)
+{
+ ParticleData *pa;
+ int a;
+
+ LISTBASE_FOREACH (ParticleSystem *, psys, particles) {
+ BLO_read_data_address(reader, &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);
+ }
+ }
+
+ if (psys->particles && psys->particles->keys) {
+ for (a = 0, pa = psys->particles; a < psys->totpart; a++, pa++) {
+ pa->keys = NULL;
+ pa->totkey = 0;
+ }
+
+ psys->flag &= ~PSYS_KEYED;
+ }
+
+ if (psys->particles && psys->particles->boid) {
+ pa = psys->particles;
+ BLO_read_data_address(reader, &pa->boid);
+
+ /* This is purely runtime data, but still can be an issue if left dangling. */
+ pa->boid->ground = NULL;
+
+ for (a = 1, pa++; a < psys->totpart; a++, pa++) {
+ pa->boid = (pa - 1)->boid + 1;
+ pa->boid->ground = NULL;
+ }
+ }
+ else if (psys->particles) {
+ for (a = 0, pa = psys->particles; a < psys->totpart; a++, pa++) {
+ pa->boid = NULL;
+ }
+ }
+
+ BLO_read_data_address(reader, &psys->fluid_springs);
+
+ BLO_read_data_address(reader, &psys->child);
+ psys->effectors = NULL;
+
+ BLO_read_list(reader, &psys->targets);
+
+ psys->edit = NULL;
+ psys->free_edit = NULL;
+ psys->pathcache = NULL;
+ psys->childcache = NULL;
+ BLI_listbase_clear(&psys->pathcachebufs);
+ BLI_listbase_clear(&psys->childcachebufs);
+ psys->pdd = NULL;
+
+ if (psys->clmd) {
+ BLO_read_data_address(reader, &psys->clmd);
+ psys->clmd->clothObject = NULL;
+ psys->clmd->hairdata = NULL;
+
+ BLO_read_data_address(reader, &psys->clmd->sim_parms);
+ BLO_read_data_address(reader, &psys->clmd->coll_parms);
+
+ if (psys->clmd->sim_parms) {
+ psys->clmd->sim_parms->effector_weights = NULL;
+ if (psys->clmd->sim_parms->presets > 10) {
+ psys->clmd->sim_parms->presets = 0;
+ }
+ }
+
+ psys->hair_in_mesh = psys->hair_out_mesh = NULL;
+ psys->clmd->solver_result = NULL;
+ }
+
+ BKE_ptcache_blend_read_data(reader, &psys->ptcaches, &psys->pointcache, 0);
+ if (psys->clmd) {
+ psys->clmd->point_cache = psys->pointcache;
+ }
+
+ psys->tree = NULL;
+ psys->bvhtree = NULL;
+
+ psys->orig_psys = NULL;
+ psys->batch_cache = NULL;
+ }
+}
+
+void BKE_particle_system_blend_read_lib(BlendLibReader *reader,
+ Object *ob,
+ ID *id,
+ ListBase *particles)
+{
+ LISTBASE_FOREACH_MUTABLE (ParticleSystem *, psys, particles) {
+
+ BLO_read_id_address(reader, id->lib, &psys->part);
+ if (psys->part) {
+ LISTBASE_FOREACH (ParticleTarget *, pt, &psys->targets) {
+ BLO_read_id_address(reader, id->lib, &pt->ob);
+ }
+
+ BLO_read_id_address(reader, id->lib, &psys->parent);
+ BLO_read_id_address(reader, id->lib, &psys->target_ob);
+
+ if (psys->clmd) {
+ /* XXX - from reading existing code this seems correct but intended usage of
+ * pointcache /w cloth should be added in 'ParticleSystem' - campbell */
+ psys->clmd->point_cache = psys->pointcache;
+ psys->clmd->ptcaches.first = psys->clmd->ptcaches.last = NULL;
+ BLO_read_id_address(reader, id->lib, &psys->clmd->coll_parms->group);
+ psys->clmd->modifier.error = NULL;
+ }
+ }
+ else {
+ /* particle modifier must be removed before particle system */
+ ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
+ BLI_remlink(&ob->modifiers, psmd);
+ BKE_modifier_free((ModifierData *)psmd);
+
+ BLI_remlink(particles, psys);
+ MEM_freeN(psys);
+ }
+ }
+}
diff --git a/source/blender/blenkernel/intern/particle_child.c b/source/blender/blenkernel/intern/particle_child.c
index da5fdc85561..98a55c3de95 100644
--- a/source/blender/blenkernel/intern/particle_child.c
+++ b/source/blender/blenkernel/intern/particle_child.c
@@ -88,7 +88,7 @@ static void do_kink_spiral_deform(ParticleKey *state,
{
float result[3];
- CLAMP(time, 0.f, 1.f);
+ CLAMP(time, 0.0f, 1.0f);
copy_v3_v3(result, state->co);
@@ -426,21 +426,21 @@ void do_kink(ParticleKey *state,
float obmat[4][4],
int smooth_start)
{
- float kink[3] = {1.f, 0.f, 0.f}, par_vec[3], q1[4] = {1.f, 0.f, 0.f, 0.f};
- float t, dt = 1.f, result[3];
+ float kink[3] = {1.0f, 0.0f, 0.0f}, par_vec[3], q1[4] = {1.0f, 0.0f, 0.0f, 0.0f};
+ float t, dt = 1.0f, result[3];
if (ELEM(type, PART_KINK_NO, PART_KINK_SPIRAL)) {
return;
}
- CLAMP(time, 0.f, 1.f);
+ CLAMP(time, 0.0f, 1.0f);
if (shape != 0.0f && !ELEM(type, PART_KINK_BRAID)) {
if (shape < 0.0f) {
- time = (float)pow(time, 1.f + shape);
+ time = (float)pow(time, 1.0f + shape);
}
else {
- time = (float)pow(time, 1.f / (1.f - shape));
+ time = (float)pow(time, 1.0f / (1.0f - shape));
}
}
@@ -449,14 +449,14 @@ void do_kink(ParticleKey *state,
if (smooth_start) {
dt = fabsf(t);
/* smooth the beginning of kink */
- CLAMP(dt, 0.f, (float)M_PI);
- dt = sinf(dt / 2.f);
+ CLAMP(dt, 0.0f, (float)M_PI);
+ dt = sinf(dt / 2.0f);
}
if (!ELEM(type, PART_KINK_RADIAL)) {
float temp[3];
- kink[axis] = 1.f;
+ kink[axis] = 1.0f;
if (obmat) {
mul_mat3_m4_v3(obmat, kink);
@@ -487,7 +487,7 @@ void do_kink(ParticleKey *state,
break;
}
case PART_KINK_RADIAL: {
- if (flat > 0.f) {
+ if (flat > 0.0f) {
float proj[3];
/* flatten along strand */
project_v3_v3v3(proj, par_vec, par_vel);
@@ -500,7 +500,7 @@ void do_kink(ParticleKey *state,
case PART_KINK_WAVE: {
madd_v3_v3fl(result, kink, amplitude * sinf(t));
- if (flat > 0.f) {
+ if (flat > 0.0f) {
float proj[3];
/* flatten along wave */
project_v3_v3v3(proj, par_vec, kink);
@@ -513,8 +513,8 @@ void do_kink(ParticleKey *state,
break;
}
case PART_KINK_BRAID: {
- float y_vec[3] = {0.f, 1.f, 0.f};
- float z_vec[3] = {0.f, 0.f, 1.f};
+ float y_vec[3] = {0.0f, 1.0f, 0.0f};
+ float z_vec[3] = {0.0f, 0.0f, 1.0f};
float vec_one[3], state_co[3];
float inp_y, inp_z, length;
@@ -533,21 +533,21 @@ void do_kink(ParticleKey *state,
copy_v3_v3(state_co, y_vec);
mul_v3_fl(y_vec, amplitude * cosf(t));
- mul_v3_fl(z_vec, amplitude / 2.f * sinf(2.f * t));
+ mul_v3_fl(z_vec, amplitude / 2.0f * sinf(2.0f * t));
}
else if (inp_z > 0.0f) {
- mul_v3_v3fl(state_co, z_vec, sinf((float)M_PI / 3.f));
+ mul_v3_v3fl(state_co, z_vec, sinf((float)M_PI / 3.0f));
madd_v3_v3fl(state_co, y_vec, -0.5f);
- mul_v3_fl(y_vec, -amplitude * cosf(t + (float)M_PI / 3.f));
- mul_v3_fl(z_vec, amplitude / 2.f * cosf(2.f * t + (float)M_PI / 6.f));
+ mul_v3_fl(y_vec, -amplitude * cosf(t + (float)M_PI / 3.0f));
+ mul_v3_fl(z_vec, amplitude / 2.0f * cosf(2.0f * t + (float)M_PI / 6.0f));
}
else {
- mul_v3_v3fl(state_co, z_vec, -sinf((float)M_PI / 3.f));
+ mul_v3_v3fl(state_co, z_vec, -sinf((float)M_PI / 3.0f));
madd_v3_v3fl(state_co, y_vec, -0.5f);
- mul_v3_fl(y_vec, amplitude * -sinf(t + (float)M_PI / 6.f));
- mul_v3_fl(z_vec, amplitude / 2.f * -sinf(2.f * t + (float)M_PI / 3.f));
+ mul_v3_fl(y_vec, amplitude * -sinf(t + (float)M_PI / 6.0f));
+ mul_v3_fl(z_vec, amplitude / 2.0f * -sinf(2.0f * t + (float)M_PI / 3.0f));
}
mul_v3_fl(state_co, amplitude);
@@ -555,13 +555,13 @@ void do_kink(ParticleKey *state,
sub_v3_v3v3(par_vec, state->co, state_co);
length = normalize_v3(par_vec);
- mul_v3_fl(par_vec, MIN2(length, amplitude / 2.f));
+ mul_v3_fl(par_vec, MIN2(length, amplitude / 2.0f));
add_v3_v3v3(state_co, par_co, y_vec);
add_v3_v3(state_co, z_vec);
add_v3_v3(state_co, par_vec);
- shape = 2.f * (float)M_PI * (1.f + shape);
+ shape = 2.0f * (float)M_PI * (1.0f + shape);
if (t < shape) {
shape = t / shape;
@@ -576,7 +576,7 @@ void do_kink(ParticleKey *state,
}
/* blend the start of the kink */
- if (dt < 1.f) {
+ if (dt < 1.0f) {
interp_v3_v3v3(state->co, state->co, result, dt);
}
else {
@@ -642,7 +642,7 @@ float do_clump(ParticleKey *state,
float da[4], pa[12];
mul_v3_v3fl(noisevec, orco_offset, 1.0f / clump_noise_size);
- voronoi(noisevec[0], noisevec[1], noisevec[2], da, pa, 1.0f, 0);
+ BLI_noise_voronoi(noisevec[0], noisevec[1], noisevec[2], da, pa, 1.0f, 0);
mul_v3_fl(&pa[0], clump_noise_size);
add_v3_v3v3(center, par_co, &pa[0]);
@@ -674,9 +674,9 @@ static void do_rough(const float loc[3],
copy_v3_v3(rco, loc);
mul_v3_fl(rco, t);
- rough[0] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[0], rco[1], rco[2], 2, 0, 2);
- rough[1] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[1], rco[2], rco[0], 2, 0, 2);
- rough[2] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[2], rco[0], rco[1], 2, 0, 2);
+ rough[0] = -1.0f + 2.0f * BLI_noise_generic_turbulence(size, rco[0], rco[1], rco[2], 2, 0, 2);
+ rough[1] = -1.0f + 2.0f * BLI_noise_generic_turbulence(size, rco[1], rco[2], rco[0], 2, 0, 2);
+ rough[2] = -1.0f + 2.0f * BLI_noise_generic_turbulence(size, rco[2], rco[0], rco[1], 2, 0, 2);
madd_v3_v3fl(state->co, mat[0], fac * rough[0]);
madd_v3_v3fl(state->co, mat[1], fac * rough[1]);
@@ -718,9 +718,9 @@ static void do_rough_curve(const float loc[3],
copy_v3_v3(rco, loc);
mul_v3_fl(rco, time);
- rough[0] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[0], rco[1], rco[2], 2, 0, 2);
- rough[1] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[1], rco[2], rco[0], 2, 0, 2);
- rough[2] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[2], rco[0], rco[1], 2, 0, 2);
+ rough[0] = -1.0f + 2.0f * BLI_noise_generic_turbulence(size, rco[0], rco[1], rco[2], 2, 0, 2);
+ rough[1] = -1.0f + 2.0f * BLI_noise_generic_turbulence(size, rco[1], rco[2], rco[0], 2, 0, 2);
+ rough[2] = -1.0f + 2.0f * BLI_noise_generic_turbulence(size, rco[2], rco[0], rco[1], 2, 0, 2);
madd_v3_v3fl(state->co, mat[0], fac * rough[0]);
madd_v3_v3fl(state->co, mat[1], fac * rough[1]);
@@ -881,8 +881,8 @@ void do_child_modifiers(const ParticleChildModifierContext *modifier_ctx,
part->clump_noise_size,
clumpcurve);
- if (kink_freq != 0.f) {
- kink_amp *= (1.f - kink_amp_clump * clump);
+ if (kink_freq != 0.0f) {
+ kink_amp *= (1.0f - kink_amp_clump * clump);
do_kink(state,
modifier_ctx->par_co,
@@ -904,17 +904,17 @@ void do_child_modifiers(const ParticleChildModifierContext *modifier_ctx,
do_rough_curve(modifier_ctx->orco, mat, t, rough1, part->rough1_size, roughcurve, state);
}
else {
- if (rough1 > 0.f) {
+ if (rough1 > 0.0f) {
do_rough(modifier_ctx->orco, mat, t, rough1, part->rough1_size, 0.0, state);
}
- if (rough2 > 0.f) {
+ if (rough2 > 0.0f) {
float vec[3];
psys_frand_vec(sim->psys, i + 27, vec);
do_rough(vec, mat, t, rough2, part->rough2_size, part->rough2_thres, state);
}
- if (rough_end > 0.f) {
+ if (rough_end > 0.0f) {
float vec[3];
psys_frand_vec(sim->psys, i + 27, vec);
do_rough_end(vec, mat, t, rough_end, part->rough_end_shape, state);
diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c
index d5999196b60..194593be4ff 100644
--- a/source/blender/blenkernel/intern/particle_distribute.c
+++ b/source/blender/blenkernel/intern/particle_distribute.c
@@ -150,9 +150,9 @@ static void distribute_grid(Mesh *mesh, ParticleSystem *psys)
size[2] = MAX2(size[2], 1);
/* no full offset for flat/thin objects */
- min[0] += d < delta[0] ? d / 2.f : delta[0] / 2.f;
- min[1] += d < delta[1] ? d / 2.f : delta[1] / 2.f;
- min[2] += d < delta[2] ? d / 2.f : delta[2] / 2.f;
+ min[0] += d < delta[0] ? d / 2.0f : delta[0] / 2.0f;
+ min[1] += d < delta[1] ? d / 2.0f : delta[1] / 2.0f;
+ min[2] += d < delta[2] ? d / 2.0f : delta[2] / 2.0f;
for (i = 0, p = 0, pa = psys->particles; i < res; i++) {
for (j = 0; j < res; j++) {
@@ -220,7 +220,7 @@ static void distribute_grid(Mesh *mesh, ParticleSystem *psys)
pa = psys->particles + a1 * a1mul + a2 * a2mul;
copy_v3_v3(co1, pa->fuv);
- co1[a] -= d < delta[a] ? d / 2.f : delta[a] / 2.f;
+ co1[a] -= d < delta[a] ? d / 2.0f : delta[a] / 2.0f;
copy_v3_v3(co2, co1);
co2[a] += delta[a] + 0.001f * d;
co1[a] -= 0.001f * d;
@@ -295,12 +295,12 @@ static void distribute_grid(Mesh *mesh, ParticleSystem *psys)
for (j = 0; j < res; j++) {
for (k = 0; k < res; k++, p++, pa++) {
if (j % 2) {
- pa->fuv[0] += d / 2.f;
+ pa->fuv[0] += d / 2.0f;
}
if (k % 2) {
- pa->fuv[0] += d / 2.f;
- pa->fuv[1] += d / 2.f;
+ pa->fuv[0] += d / 2.0f;
+ pa->fuv[1] += d / 2.0f;
}
}
}
@@ -318,7 +318,7 @@ static void distribute_grid(Mesh *mesh, ParticleSystem *psys)
}
}
- if (psys->part->grid_rand > 0.f) {
+ if (psys->part->grid_rand > 0.0f) {
float rfac = d * psys->part->grid_rand;
for (p = 0, pa = psys->particles; p < psys->totpart; p++, pa++) {
if (pa->flag & PARS_UNEXIST) {
@@ -1052,7 +1052,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx,
/* Calculate weights from face areas */
if ((part->flag & PART_EDISTR || children) && from != PART_FROM_VERT) {
MVert *v1, *v2, *v3, *v4;
- float totarea = 0.f, co1[3], co2[3], co3[3], co4[3];
+ float totarea = 0.0f, co1[3], co2[3], co3[3], co4[3];
float(*orcodata)[3];
orcodata = CustomData_get_layer(&mesh->vdata, CD_ORCO);
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 060a9b4d794..4117dfc0b23 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -83,7 +83,7 @@
#include "PIL_time.h"
-#include "RE_shader_ext.h"
+#include "RE_texture.h"
/* FLUID sim particle import */
#ifdef WITH_FLUID
@@ -574,7 +574,7 @@ static void init_particle_texture(ParticleSimulationData *sim, ParticleData *pa,
ParticleSettings *part = psys->part;
ParticleTexture ptex;
- psys_get_texture(sim, pa, &ptex, PAMAP_INIT, 0.f);
+ psys_get_texture(sim, pa, &ptex, PAMAP_INIT, 0.0f);
switch (part->type) {
case PART_EMITTER:
@@ -587,7 +587,7 @@ static void init_particle_texture(ParticleSimulationData *sim, ParticleData *pa,
if (ptex.exist < psys_frand(psys, p + 125)) {
pa->flag |= PARS_UNEXIST;
}
- pa->time = 0.f;
+ pa->time = 0.0f;
break;
}
}
@@ -697,28 +697,28 @@ static void get_angular_velocity_vector(short avemode, ParticleKey *state, float
case PART_AVE_HORIZONTAL: {
float zvec[3];
zvec[0] = zvec[1] = 0;
- zvec[2] = 1.f;
+ zvec[2] = 1.0f;
cross_v3_v3v3(vec, state->vel, zvec);
break;
}
case PART_AVE_VERTICAL: {
float zvec[3], temp[3];
zvec[0] = zvec[1] = 0;
- zvec[2] = 1.f;
+ zvec[2] = 1.0f;
cross_v3_v3v3(temp, state->vel, zvec);
cross_v3_v3v3(vec, temp, state->vel);
break;
}
case PART_AVE_GLOBAL_X:
- vec[0] = 1.f;
+ vec[0] = 1.0f;
vec[1] = vec[2] = 0;
break;
case PART_AVE_GLOBAL_Y:
- vec[1] = 1.f;
+ vec[1] = 1.0f;
vec[0] = vec[2] = 0;
break;
case PART_AVE_GLOBAL_Z:
- vec[2] = 1.f;
+ vec[2] = 1.0f;
vec[0] = vec[1] = 0;
break;
}
@@ -864,36 +864,36 @@ void psys_get_birth_coords(
/* -velocity from: */
/* *reactions */
- if (dtime > 0.f) {
+ if (dtime > 0.0f) {
sub_v3_v3v3(vel, pa->state.vel, pa->prev_state.vel);
}
/* *emitter velocity */
- if (dtime != 0.f && part->obfac != 0.f) {
+ if (dtime != 0.0f && part->obfac != 0.0f) {
sub_v3_v3v3(vel, loc, state->co);
mul_v3_fl(vel, part->obfac / dtime);
}
/* *emitter normal */
- if (part->normfac != 0.f) {
+ if (part->normfac != 0.0f) {
madd_v3_v3fl(vel, nor, part->normfac);
}
/* *emitter tangent */
- if (sim->psmd && part->tanfac != 0.f) {
+ if (sim->psmd && part->tanfac != 0.0f) {
madd_v3_v3fl(vel, vtan, part->tanfac);
}
/* *emitter object orientation */
- if (part->ob_vel[0] != 0.f) {
+ if (part->ob_vel[0] != 0.0f) {
normalize_v3_v3(vec, ob->obmat[0]);
madd_v3_v3fl(vel, vec, part->ob_vel[0]);
}
- if (part->ob_vel[1] != 0.f) {
+ if (part->ob_vel[1] != 0.0f) {
normalize_v3_v3(vec, ob->obmat[1]);
madd_v3_v3fl(vel, vec, part->ob_vel[1]);
}
- if (part->ob_vel[2] != 0.f) {
+ if (part->ob_vel[2] != 0.0f) {
normalize_v3_v3(vec, ob->obmat[2]);
madd_v3_v3fl(vel, vec, part->ob_vel[2]);
}
@@ -902,12 +902,12 @@ void psys_get_birth_coords(
/* TODO */
/* *random */
- if (part->randfac != 0.f) {
+ if (part->randfac != 0.0f) {
madd_v3_v3fl(vel, r_vel, part->randfac);
}
/* *particle */
- if (part->partfac != 0.f) {
+ if (part->partfac != 0.0f) {
madd_v3_v3fl(vel, p_vel, part->partfac);
}
@@ -1077,7 +1077,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
part = psys->part;
/* get precise emitter matrix if particle is born */
- if (part->type != PART_HAIR && dtime > 0.f && pa->time < cfra && pa->time >= sim->psys->cfra) {
+ if (part->type != PART_HAIR && dtime > 0.0f && pa->time < cfra && pa->time >= sim->psys->cfra) {
evaluate_emitter_anim(sim->depsgraph, sim->scene, sim->ob, pa->time);
psys->flag |= PSYS_OB_ANIM_RESTORE;
@@ -1165,7 +1165,7 @@ ParticleSystem *psys_get_target_system(Object *ob, ParticleTarget *pt)
{
ParticleSystem *psys = NULL;
- if (pt->ob == NULL || pt->ob == ob) {
+ if (ELEM(pt->ob, NULL, ob)) {
psys = BLI_findlink(&ob->particlesystem, pt->psys - 1);
}
else {
@@ -1427,7 +1427,7 @@ static void integrate_particle(
copy_v3_v3(oldpos, pa->state.co);
/* Verlet integration behaves strangely with moving emitters, so do first step with euler. */
- if (pa->prev_state.time < 0.f && integrator == PART_INT_VERLET) {
+ if (pa->prev_state.time < 0.0f && integrator == PART_INT_VERLET) {
integrator = PART_INT_EULER;
}
@@ -1450,7 +1450,7 @@ static void integrate_particle(
copy_particle_key(states + i, &pa->state, 1);
}
- states->time = 0.f;
+ states->time = 0.0f;
for (i = 0; i < steps; i++) {
zero_v3(force);
@@ -1611,9 +1611,9 @@ static void sph_springs_modify(ParticleSystem *psys, float dtime)
float yield_ratio = fluid->yield_ratio;
float plasticity = fluid->plasticity_constant;
/* scale things according to dtime */
- float timefix = 25.f * dtime;
+ float timefix = 25.0f * dtime;
- if ((fluid->flag & SPH_VISCOELASTIC_SPRINGS) == 0 || fluid->spring_k == 0.f) {
+ if ((fluid->flag & SPH_VISCOELASTIC_SPRINGS) == 0 || fluid->spring_k == 0.0f) {
return;
}
@@ -1636,7 +1636,7 @@ static void sph_springs_modify(ParticleSystem *psys, float dtime)
spring->rest_length -= plasticity * (Lij - d - rij) * timefix;
}
- h = 4.f * pa1->size;
+ h = 4.0f * pa1->size;
if (spring->rest_length > h) {
spring->delete_flag = 1;
@@ -1743,7 +1743,7 @@ static void sph_density_accum_cb(void *userdata, int index, const float co[3], f
pfr->tot_neighbors++;
dist = sqrtf(squared_dist);
- q = (1.f - dist / pfr->h) * pfr->massfac;
+ q = (1.0f - dist / pfr->h) * pfr->massfac;
if (pfr->use_size) {
q *= npa->size;
@@ -1799,7 +1799,7 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa
float visc = fluid->viscosity_omega;
float stiff_visc = fluid->viscosity_beta *
- (fluid->flag & SPH_FAC_VISCOSITY ? fluid->viscosity_omega : 1.f);
+ (fluid->flag & SPH_FAC_VISCOSITY ? fluid->viscosity_omega : 1.0f);
float inv_mass = 1.0f / sphdata->mass;
float spring_constant = fluid->spring_k;
@@ -1809,13 +1809,13 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa
(fluid->flag & SPH_FAC_RADIUS ? 4.0f * pa->size : 1.0f);
float h = interaction_radius * sphdata->hfac;
/* 4.77 is an experimentally determined density factor */
- float rest_density = fluid->rest_density * (fluid->flag & SPH_FAC_DENSITY ? 4.77f : 1.f);
+ float rest_density = fluid->rest_density * (fluid->flag & SPH_FAC_DENSITY ? 4.77f : 1.0f);
float rest_length = fluid->rest_length *
- (fluid->flag & SPH_FAC_REST_LENGTH ? 2.588f * pa->size : 1.f);
+ (fluid->flag & SPH_FAC_REST_LENGTH ? 2.588f * pa->size : 1.0f);
float stiffness = fluid->stiffness_k;
float stiffness_near_fac = fluid->stiffness_knear *
- (fluid->flag & SPH_FAC_REPULSION ? fluid->stiffness_k : 1.f);
+ (fluid->flag & SPH_FAC_REPULSION ? fluid->stiffness_k : 1.0f);
ParticleData *npa;
float vec[3];
@@ -1849,7 +1849,7 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa
sub_v3_v3v3(vec, co, state->co);
rij = normalize_v3(vec);
- q = (1.f - rij / h) * pfn->psys->part->mass * inv_mass;
+ q = (1.0f - rij / h) * pfn->psys->part->mass * inv_mass;
if (pfn->psys->part->flag & PART_SIZEMASS) {
q *= npa->size;
@@ -1861,20 +1861,20 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa
madd_v3_v3fl(force, vec, -(pressure + near_pressure * q) * q);
/* Viscosity */
- if (visc > 0.f || stiff_visc > 0.f) {
+ if (visc > 0.0f || stiff_visc > 0.0f) {
sub_v3_v3v3(dv, vel, state->vel);
u = dot_v3v3(vec, dv);
- if (u < 0.f && visc > 0.f) {
+ if (u < 0.0f && visc > 0.0f) {
madd_v3_v3fl(force, vec, 0.5f * q * visc * u);
}
- if (u > 0.f && stiff_visc > 0.f) {
+ if (u > 0.0f && stiff_visc > 0.0f) {
madd_v3_v3fl(force, vec, 0.5f * q * stiff_visc * u);
}
}
- if (spring_constant > 0.f) {
+ if (spring_constant > 0.0f) {
/* Viscoelastic spring force */
if (pfn->psys == psys[0] && fluid->flag & SPH_VISCOELASTIC_SPRINGS && springhash) {
/* BLI_edgehash_lookup appears to be thread-safe. - z0r */
@@ -1883,8 +1883,9 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa
if (spring_index) {
spring = psys[0]->fluid_springs + spring_index - 1;
- madd_v3_v3fl(
- force, vec, -10.f * spring_constant * (1.f - rij / h) * (spring->rest_length - rij));
+ madd_v3_v3fl(force,
+ vec,
+ -10.0f * spring_constant * (1.0f - rij / h) * (spring->rest_length - rij));
}
else if (fluid->spring_frames == 0 ||
(pa->prev_state.time - pa->time) <= fluid->spring_frames) {
@@ -1898,13 +1899,14 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa
}
}
else { /* PART_SPRING_HOOKES - Hooke's spring force */
- madd_v3_v3fl(force, vec, -10.f * spring_constant * (1.f - rij / h) * (rest_length - rij));
+ madd_v3_v3fl(
+ force, vec, -10.0f * spring_constant * (1.0f - rij / h) * (rest_length - rij));
}
}
}
/* Artificial buoyancy force in negative gravity direction */
- if (fluid->buoyancy > 0.f && gravity) {
+ if (fluid->buoyancy > 0.0f && gravity) {
madd_v3_v3fl(force, gravity, fluid->buoyancy * (density - rest_density));
}
@@ -1922,7 +1924,7 @@ static void sphclassical_density_accum_cb(void *userdata,
SPHRangeData *pfr = (SPHRangeData *)userdata;
ParticleData *npa = pfr->npsys->particles + index;
float q;
- float qfac = 21.0f / (256.f * (float)M_PI);
+ float qfac = 21.0f / (256.0f * (float)M_PI);
float rij, rij_h;
float vec[3];
@@ -2079,7 +2081,7 @@ static void sphclassical_force_cb(void *sphdata_v,
}
/* Artificial buoyancy force in negative gravity direction */
- if (fluid->buoyancy > 0.f && gravity) {
+ if (fluid->buoyancy > 0.0f && gravity) {
madd_v3_v3fl(force, gravity, fluid->buoyancy * (pa->sphdensity - rest_density));
}
@@ -2199,7 +2201,7 @@ static void sph_integrate(ParticleSimulationData *sim,
{
ParticleSettings *part = sim->psys->part;
// float timestep = psys_get_timestep(sim); // UNUSED
- float pa_mass = part->mass * (part->flag & PART_SIZEMASS ? pa->size : 1.f);
+ float pa_mass = part->mass * (part->flag & PART_SIZEMASS ? pa->size : 1.0f);
float dtime = dfra * psys_get_timestep(sim);
// int steps = 1; // UNUSED
float effector_acceleration[3];
@@ -2211,7 +2213,7 @@ static void sph_integrate(ParticleSimulationData *sim,
/* restore previous state and treat gravity & effectors as external acceleration*/
sub_v3_v3v3(effector_acceleration, pa->state.vel, pa->prev_state.vel);
- mul_v3_fl(effector_acceleration, 1.f / dtime);
+ mul_v3_fl(effector_acceleration, 1.0f / dtime);
copy_particle_key(&pa->state, &pa->prev_state, 0);
@@ -2300,8 +2302,8 @@ static void basic_integrate(ParticleSimulationData *sim, int p, float dfra, floa
integrate_particle(part, pa, dtime, gravity, basic_force_cb, &efdata);
/* damp affects final velocity */
- if (part->dampfac != 0.f) {
- mul_v3_fl(pa->state.vel, 1.f - part->dampfac * efdata.ptex.damp * 25.f * dtime);
+ if (part->dampfac != 0.0f) {
+ mul_v3_fl(pa->state.vel, 1.0f - part->dampfac * efdata.ptex.damp * 25.0f * dtime);
}
// copy_v3_v3(pa->state.ave, states->ave);
@@ -2406,7 +2408,7 @@ static float nr_signed_distance_to_plane(float *p,
d = dot_v3v3(p0, nor);
if (pce->inv_nor == -1) {
- if (d < 0.f) {
+ if (d < 0.0f) {
pce->inv_nor = 1;
}
else {
@@ -2452,7 +2454,7 @@ static void collision_interpolate_element(ParticleCollisionElement *pce,
/* fac is the starting factor for current collision iteration */
/* The col->fac's are factors for the particle subframe step start
* and end during collision modifier step. */
- float f = fac + t * (1.f - fac);
+ float f = fac + t * (1.0f - fac);
float mul = col->fac1 + f * (col->fac2 - col->fac1);
if (pce->tot > 0) {
madd_v3_v3v3fl(pce->x0, pce->x[0], pce->v[0], mul);
@@ -2485,8 +2487,8 @@ static void collision_point_velocity(ParticleCollisionElement *pce)
static float collision_point_distance_with_normal(
float p[3], ParticleCollisionElement *pce, float fac, ParticleCollision *col, float *nor)
{
- if (fac >= 0.f) {
- collision_interpolate_element(pce, 0.f, fac, col);
+ if (fac >= 0.0f) {
+ collision_interpolate_element(pce, 0.0f, fac, col);
}
switch (pce->tot) {
@@ -2504,14 +2506,14 @@ static float collision_point_distance_with_normal(
return normalize_v3(nor);
}
case 3:
- return nr_signed_distance_to_plane(p, 0.f, pce, nor);
+ return nr_signed_distance_to_plane(p, 0.0f, pce, nor);
}
return 0;
}
static void collision_point_on_surface(
const float p[3], ParticleCollisionElement *pce, float fac, ParticleCollision *col, float *co)
{
- collision_interpolate_element(pce, 0.f, fac, col);
+ collision_interpolate_element(pce, 0.0f, fac, col);
switch (pce->tot) {
case 1: {
@@ -2575,11 +2577,11 @@ static float collision_newton_rhapson(ParticleCollision *col,
}
/* start from the beginning */
- t0 = 0.f;
+ t0 = 0.0f;
collision_interpolate_element(pce, t0, col->f, col);
d0 = distance_func(col->co1, radius, pce, n);
t1 = dt_init;
- d1 = 0.f;
+ d1 = 0.0f;
for (iter = 0; iter < 10; iter++) { //, itersum++) {
/* get current location */
@@ -2589,11 +2591,11 @@ static float collision_newton_rhapson(ParticleCollision *col,
d1 = distance_func(pce->p, radius, pce, n);
/* particle already inside face, so report collision */
- if (iter == 0 && d0 < 0.f && d0 > -radius) {
+ if (iter == 0 && d0 < 0.0f && d0 > -radius) {
copy_v3_v3(pce->p, col->co1);
copy_v3_v3(pce->nor, n);
pce->inside = 1;
- return 0.f;
+ return 0.0f;
}
/* Zero gradient (no movement relative to element). Can't step from
@@ -2602,15 +2604,15 @@ static float collision_newton_rhapson(ParticleCollision *col,
/* If first iteration, try from other end where the gradient may be
* greater. Note: code duplicated below. */
if (iter == 0) {
- t0 = 1.f;
+ t0 = 1.0f;
collision_interpolate_element(pce, t0, col->f, col);
d0 = distance_func(col->co2, radius, pce, n);
t1 = 1.0f - dt_init;
- d1 = 0.f;
+ d1 = 0.0f;
continue;
}
- return -1.f;
+ return -1.0f;
}
dd = (t1 - t0) / (d1 - d0);
@@ -2622,30 +2624,30 @@ static float collision_newton_rhapson(ParticleCollision *col,
/* Particle moving away from plane could also mean a strangely rotating
* face, so check from end. Note: code duplicated above. */
- if (iter == 0 && t1 < 0.f) {
- t0 = 1.f;
+ if (iter == 0 && t1 < 0.0f) {
+ t0 = 1.0f;
collision_interpolate_element(pce, t0, col->f, col);
d0 = distance_func(col->co2, radius, pce, n);
t1 = 1.0f - dt_init;
- d1 = 0.f;
+ d1 = 0.0f;
continue;
}
- if (iter == 1 && (t1 < -COLLISION_ZERO || t1 > 1.f)) {
- return -1.f;
+ if (iter == 1 && (t1 < -COLLISION_ZERO || t1 > 1.0f)) {
+ return -1.0f;
}
if (d1 <= COLLISION_ZERO && d1 >= -COLLISION_ZERO) {
- if (t1 >= -COLLISION_ZERO && t1 <= 1.f) {
+ if (t1 >= -COLLISION_ZERO && t1 <= 1.0f) {
if (distance_func == nr_signed_distance_to_plane) {
copy_v3_v3(pce->nor, n);
}
- CLAMP(t1, 0.f, 1.f);
+ CLAMP(t1, 0.0f, 1.0f);
return t1;
}
- return -1.f;
+ return -1.0f;
}
}
return -1.0;
@@ -2663,7 +2665,7 @@ static int collision_sphere_to_tri(ParticleCollision *col,
ct = collision_newton_rhapson(col, radius, pce, nr_signed_distance_to_plane);
- if (ct >= 0.f && ct < *t && (result->inside == 0 || pce->inside == 1)) {
+ if (ct >= 0.0f && ct < *t && (result->inside == 0 || pce->inside == 1)) {
float e1[3], e2[3], p0[3];
float e1e1, e1e2, e1p0, e2e2, e2p0, inv;
@@ -2678,11 +2680,11 @@ static int collision_sphere_to_tri(ParticleCollision *col,
e2e2 = dot_v3v3(e2, e2);
e2p0 = dot_v3v3(e2, p0);
- inv = 1.f / (e1e1 * e2e2 - e1e2 * e1e2);
+ inv = 1.0f / (e1e1 * e2e2 - e1e2 * e1e2);
u = (e2e2 * e1p0 - e1e2 * e2p0) * inv;
v = (e1e1 * e2p0 - e1e2 * e1p0) * inv;
- if (u >= 0.f && u <= 1.f && v >= 0.f && u + v <= 1.f) {
+ if (u >= 0.0f && u <= 1.0f && v >= 0.0f && u + v <= 1.0f) {
*result = *pce;
/* normal already calculated in pce */
@@ -2718,14 +2720,14 @@ static int collision_sphere_to_edges(ParticleCollision *col,
ct = collision_newton_rhapson(col, radius, cur, nr_distance_to_edge);
- if (ct >= 0.f && ct < *t) {
+ if (ct >= 0.0f && ct < *t) {
float u, e[3], vec[3];
sub_v3_v3v3(e, cur->x1, cur->x0);
sub_v3_v3v3(vec, cur->p, cur->x0);
u = dot_v3v3(vec, e) / dot_v3v3(e, e);
- if (u < 0.f || u > 1.f) {
+ if (u < 0.0f || u > 1.0f) {
break;
}
@@ -2763,7 +2765,7 @@ static int collision_sphere_to_verts(ParticleCollision *col,
ct = collision_newton_rhapson(col, radius, cur, nr_distance_to_vert);
- if (ct >= 0.f && ct < *t) {
+ if (ct >= 0.0f && ct < *t) {
*result = *cur;
sub_v3_v3v3(result->nor, cur->p, cur->x0);
@@ -3019,7 +3021,7 @@ static int collision_response(ParticleSimulationData *sim,
(vc_dot < 0.0f && v0_dot < 0.0f && vc_dot < v0_dot))) {
mul_v3_v3fl(v0_nor, pce->nor, vc_dot);
}
- else if (v0_dot > 0.f) {
+ else if (v0_dot > 0.0f) {
mul_v3_v3fl(v0_nor, pce->nor, vc_dot + v0_dot);
}
else {
@@ -3045,25 +3047,25 @@ static int collision_response(ParticleSimulationData *sim,
/* make sure particle stays on the right side of the surface */
if (!through) {
- distance = collision_point_distance_with_normal(co, pce, -1.f, col, nor);
+ distance = collision_point_distance_with_normal(co, pce, -1.0f, col, nor);
if (distance < col->radius + COLLISION_MIN_DISTANCE) {
madd_v3_v3fl(co, nor, col->radius + COLLISION_MIN_DISTANCE - distance);
}
dot = dot_v3v3(nor, v0);
- if (dot < 0.f) {
+ if (dot < 0.0f) {
madd_v3_v3fl(v0, nor, -dot);
}
- distance = collision_point_distance_with_normal(pa->state.co, pce, 1.f, col, nor);
+ distance = collision_point_distance_with_normal(pa->state.co, pce, 1.0f, col, nor);
if (distance < col->radius + COLLISION_MIN_DISTANCE) {
madd_v3_v3fl(pa->state.co, nor, col->radius + COLLISION_MIN_DISTANCE - distance);
}
dot = dot_v3v3(nor, pa->state.vel);
- if (dot < 0.f) {
+ if (dot < 0.0f) {
madd_v3_v3fl(pa->state.vel, nor, -dot);
}
}
@@ -3090,7 +3092,7 @@ static int collision_response(ParticleSimulationData *sim,
static void collision_fail(ParticleData *pa, ParticleCollision *col)
{
/* final chance to prevent total failure, so stick to the surface and hope for the best */
- collision_point_on_surface(col->co1, &col->pce, 1.f, col, pa->state.co);
+ collision_point_on_surface(col->co1, &col->pce, 1.0f, col, pa->state.co);
copy_v3_v3(pa->state.vel, col->pce.vel);
mul_v3_fl(pa->state.vel, col->inv_timestep);
@@ -3128,7 +3130,7 @@ static void collision_check(ParticleSimulationData *sim, int p, float dfra, floa
/* get acceleration (from gravity, forcefields etc. to be re-applied in collision response) */
sub_v3_v3v3(col.acc, pa->state.vel, pa->prev_state.vel);
- mul_v3_fl(col.acc, 1.f / col.total_time);
+ mul_v3_fl(col.acc, 1.0f / col.total_time);
/* set values for first iteration */
copy_v3_v3(col.co1, pa->prev_state.co);
@@ -3925,7 +3927,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
if (ELEM(pa->alive, PARS_ALIVE, PARS_DYING) == 0 ||
(pa->flag & (PARS_UNEXIST | PARS_NO_DISP))) {
- pa->state.time = -1.f;
+ pa->state.time = -1.0f;
}
}
@@ -4149,20 +4151,17 @@ static bool particles_has_tracer(short parttype)
static bool particles_has_spray(short parttype)
{
- return ((parttype == PART_FLUID_SPRAY) || (parttype == PART_FLUID_SPRAYFOAM) ||
- (parttype == PART_FLUID_SPRAYFOAMBUBBLE));
+ return (ELEM(parttype, PART_FLUID_SPRAY, PART_FLUID_SPRAYFOAM, PART_FLUID_SPRAYFOAMBUBBLE));
}
static bool particles_has_bubble(short parttype)
{
- return ((parttype == PART_FLUID_BUBBLE) || (parttype == PART_FLUID_FOAMBUBBLE) ||
- (parttype == PART_FLUID_SPRAYFOAMBUBBLE));
+ return (ELEM(parttype, PART_FLUID_BUBBLE, PART_FLUID_FOAMBUBBLE, PART_FLUID_SPRAYFOAMBUBBLE));
}
static bool particles_has_foam(short parttype)
{
- return ((parttype == PART_FLUID_FOAM) || (parttype == PART_FLUID_SPRAYFOAM) ||
- (parttype == PART_FLUID_SPRAYFOAMBUBBLE));
+ return (ELEM(parttype, PART_FLUID_FOAM, PART_FLUID_SPRAYFOAM, PART_FLUID_SPRAYFOAMBUBBLE));
}
static void particles_fluid_step(ParticleSimulationData *sim,
@@ -4410,7 +4409,7 @@ static void particles_fluid_step(ParticleSimulationData *sim,
zero_v3(pa->state.ave);
unit_qt(pa->state.rot);
- pa->time = 1.f;
+ pa->time = 1.0f;
pa->dietime = sim->scene->r.efra + 1;
pa->lifetime = sim->scene->r.efra;
pa->alive = PARS_ALIVE;
@@ -4590,8 +4589,8 @@ static void system_step(ParticleSimulationData *sim, float cfra, const bool use_
dt_frac = psys->dt_frac;
for (t_frac = dt_frac; t_frac <= 1.0f; t_frac += dt_frac) {
sim->courant_num = 0.0f;
- dynamics_step(sim, cfra + dframe + t_frac - 1.f);
- psys->cfra = cfra + dframe + t_frac - 1.f;
+ dynamics_step(sim, cfra + dframe + t_frac - 1.0f);
+ psys->cfra = cfra + dframe + t_frac - 1.0f;
if (part->time_flag & PART_TIME_AUTOSF) {
update_timestep(psys, sim);
@@ -4692,17 +4691,17 @@ void BKE_particlesettings_fluid_default_settings(ParticleSettings *part)
{
SPHFluidSettings *fluid = part->fluid;
- fluid->spring_k = 0.f;
+ fluid->spring_k = 0.0f;
fluid->plasticity_constant = 0.1f;
fluid->yield_ratio = 0.1f;
- fluid->rest_length = 1.f;
- fluid->viscosity_omega = 2.f;
+ fluid->rest_length = 1.0f;
+ fluid->viscosity_omega = 2.0f;
fluid->viscosity_beta = 0.1f;
- fluid->stiffness_k = 1.f;
- fluid->stiffness_knear = 1.f;
- fluid->rest_density = 1.f;
- fluid->buoyancy = 0.f;
- fluid->radius = 1.f;
+ fluid->stiffness_k = 1.0f;
+ fluid->stiffness_knear = 1.0f;
+ fluid->rest_density = 1.0f;
+ fluid->buoyancy = 0.0f;
+ fluid->radius = 1.0f;
fluid->flag |= SPH_FAC_REPULSION | SPH_FAC_DENSITY | SPH_FAC_RADIUS | SPH_FAC_VISCOSITY |
SPH_FAC_REST_LENGTH;
}
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index d31b0d54784..09e4ad93baa 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -63,6 +63,7 @@
static void pbvh_bmesh_verify(PBVH *pbvh);
#endif
+/* -------------------------------------------------------------------- */
/** \name BMesh Utility API
*
* Use some local functions which assume triangles.
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 7c8527a8702..5c60b39e9c8 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -44,6 +44,7 @@
#include "DNA_simulation_types.h"
#include "BLI_blenlib.h"
+#include "BLI_endian_switch.h"
#include "BLI_math.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
@@ -67,6 +68,8 @@
#include "BKE_scene.h"
#include "BKE_softbody.h"
+#include "BLO_read_write.h"
+
#include "BIK_api.h"
#ifdef WITH_BULLET
@@ -256,7 +259,9 @@ static int ptcache_softbody_totpoint(void *soft_v, int UNUSED(cfra))
SoftBody *soft = soft_v;
return soft->totpoint;
}
-static void ptcache_softbody_error(void *UNUSED(soft_v), const char *UNUSED(message))
+static void ptcache_softbody_error(const ID *UNUSED(owner_id),
+ void *UNUSED(soft_v),
+ const char *UNUSED(message))
{
/* ignored for now */
}
@@ -460,7 +465,7 @@ static void ptcache_particle_interpolate(int index,
psys_interpolate_particle(-1, keys, (cfra - cfra1) / dfra, &pa->state, 1);
interp_qt_qtqt(pa->state.rot, keys[1].rot, keys[2].rot, (cfra - cfra1) / dfra);
- mul_v3_fl(pa->state.vel, 1.f / (dfra * timestep));
+ mul_v3_fl(pa->state.vel, 1.0f / (dfra * timestep));
pa->state.time = cfra;
}
@@ -471,7 +476,9 @@ static int ptcache_particle_totpoint(void *psys_v, int UNUSED(cfra))
return psys->totpart;
}
-static void ptcache_particle_error(void *UNUSED(psys_v), const char *UNUSED(message))
+static void ptcache_particle_error(const ID *UNUSED(owner_id),
+ void *UNUSED(psys_v),
+ const char *UNUSED(message))
{
/* ignored for now */
}
@@ -642,10 +649,11 @@ static int ptcache_cloth_totpoint(void *cloth_v, int UNUSED(cfra))
return clmd->clothObject ? clmd->clothObject->mvert_num : 0;
}
-static void ptcache_cloth_error(void *cloth_v, const char *message)
+static void ptcache_cloth_error(const ID *owner_id, void *cloth_v, const char *message)
{
ClothModifierData *clmd = cloth_v;
- BKE_modifier_set_error(&clmd->modifier, "%s", message);
+ BLI_assert(GS(owner_id->name) == ID_OB);
+ BKE_modifier_set_error((Object *)owner_id, &clmd->modifier, "%s", message);
}
static int ptcache_dynamicpaint_totpoint(void *sd, int UNUSED(cfra))
@@ -659,7 +667,9 @@ static int ptcache_dynamicpaint_totpoint(void *sd, int UNUSED(cfra))
return surface->data->total_points;
}
-static void ptcache_dynamicpaint_error(void *UNUSED(sd), const char *UNUSED(message))
+static void ptcache_dynamicpaint_error(const ID *UNUSED(owner_id),
+ void *UNUSED(sd),
+ const char *UNUSED(message))
{
/* ignored for now */
}
@@ -731,8 +741,7 @@ static int ptcache_dynamicpaint_read(PTCacheFile *pf, void *dp_v)
if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
data_len = sizeof(PaintPoint);
}
- else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE ||
- surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) {
+ else if (ELEM(surface->type, MOD_DPAINT_SURFACE_T_DISPLACE, MOD_DPAINT_SURFACE_T_WEIGHT)) {
data_len = sizeof(float);
}
else if (surface->type == MOD_DPAINT_SURFACE_T_WAVE) {
@@ -853,7 +862,9 @@ static int ptcache_rigidbody_totpoint(void *rb_v, int UNUSED(cfra))
return rbw->numbodies;
}
-static void ptcache_rigidbody_error(void *UNUSED(rb_v), const char *UNUSED(message))
+static void ptcache_rigidbody_error(const struct ID *UNUSED(owner_id),
+ void *UNUSED(rb_v),
+ const char *UNUSED(message))
{
/* ignored for now */
}
@@ -2098,19 +2109,19 @@ static int ptcache_read_stream(PTCacheID *pid, int cfra)
}
if (!ptcache_file_header_begin_read(pf)) {
- pid->error(pid->calldata, "Failed to read point cache file");
+ pid->error(pid->owner_id, pid->calldata, "Failed to read point cache file");
error = 1;
}
else if (pf->type != pid->type) {
- pid->error(pid->calldata, "Point cache file has wrong type");
+ pid->error(pid->owner_id, pid->calldata, "Point cache file has wrong type");
error = 1;
}
else if (!pid->read_header(pf)) {
- pid->error(pid->calldata, "Failed to read point cache file header");
+ pid->error(pid->owner_id, pid->calldata, "Failed to read point cache file header");
error = 1;
}
else if (pf->totpoint != pid->totpoint(pid->calldata, cfra)) {
- pid->error(pid->calldata, "Number of points in cache does not match mesh");
+ pid->error(pid->owner_id, pid->calldata, "Number of points in cache does not match mesh");
error = 1;
}
@@ -2119,7 +2130,7 @@ static int ptcache_read_stream(PTCacheID *pid, int cfra)
/* We have stream reading here. */
if (!pid->read_stream(pf, pid->calldata)) {
- pid->error(pid->calldata, "Failed to read point cache file data");
+ pid->error(pid->owner_id, pid->calldata, "Failed to read point cache file data");
error = 1;
}
}
@@ -2155,7 +2166,7 @@ static int ptcache_read(PTCacheID *pid, int cfra)
int pid_totpoint = pid->totpoint(pid->calldata, cfra);
if (totpoint != pid_totpoint) {
- pid->error(pid->calldata, "Number of points in cache does not match mesh");
+ pid->error(pid->owner_id, pid->calldata, "Number of points in cache does not match mesh");
totpoint = MIN2(totpoint, pid_totpoint);
}
}
@@ -2211,7 +2222,7 @@ static int ptcache_interpolate(PTCacheID *pid, float cfra, int cfra1, int cfra2)
int pid_totpoint = pid->totpoint(pid->calldata, (int)cfra);
if (totpoint != pid_totpoint) {
- pid->error(pid->calldata, "Number of points in cache does not match mesh");
+ pid->error(pid->owner_id, pid->calldata, "Number of points in cache does not match mesh");
totpoint = MIN2(totpoint, pid_totpoint);
}
}
@@ -3771,3 +3782,124 @@ void BKE_ptcache_invalidate(PointCache *cache)
cache->last_exact = MIN2(cache->startframe, 0);
}
}
+
+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) {
+ BLO_write_struct(writer, PointCache, cache);
+
+ if ((cache->flag & PTCACHE_DISK_CACHE) == 0) {
+ LISTBASE_FOREACH (PTCacheMem *, pm, &cache->mem_cache) {
+ BLO_write_struct(writer, PTCacheMem, pm);
+
+ 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]);
+ }
+ else {
+ BLO_write_struct_array_by_name(
+ writer, ptcache_data_struct[i], pm->totpoint, 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);
+ }
+ }
+ }
+ }
+}
+
+static void direct_link_pointcache_cb(BlendDataReader *reader, void *data)
+{
+ PTCacheMem *pm = 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)) {
+ /* data_size returns bytes. */
+ int tot = (BKE_ptcache_data_size(i) * pm->totpoint) / sizeof(int);
+
+ int *poin = pm->data[i];
+
+ BLI_endian_switch_int32_array(poin, tot);
+ }
+ }
+
+ BLO_read_list(reader, &pm->extradata);
+
+ LISTBASE_FOREACH (PTCacheExtra *, extra, &pm->extradata) {
+ BLO_read_data_address(reader, &extra->data);
+ }
+}
+
+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);
+ }
+ else {
+ BLI_listbase_clear(&cache->mem_cache);
+ }
+
+ cache->flag &= ~PTCACHE_SIMULATION_VALID;
+ cache->simframe = 0;
+ cache->edit = NULL;
+ cache->free_edit = NULL;
+ cache->cached_frames = NULL;
+ cache->cached_frames_len = 0;
+}
+
+void BKE_ptcache_blend_read_data(BlendDataReader *reader,
+ ListBase *ptcaches,
+ PointCache **ocache,
+ int force_disk)
+{
+ if (ptcaches->first) {
+ BLO_read_list(reader, ptcaches);
+ LISTBASE_FOREACH (PointCache *, cache, ptcaches) {
+ direct_link_pointcache(reader, cache);
+ if (force_disk) {
+ cache->flag |= PTCACHE_DISK_CACHE;
+ cache->step = 1;
+ }
+ }
+
+ BLO_read_data_address(reader, ocache);
+ }
+ else if (*ocache) {
+ /* old "single" caches need to be linked too */
+ BLO_read_data_address(reader, ocache);
+ direct_link_pointcache(reader, *ocache);
+ if (force_disk) {
+ (*ocache)->flag |= PTCACHE_DISK_CACHE;
+ (*ocache)->step = 1;
+ }
+
+ ptcaches->first = ptcaches->last = *ocache;
+ }
+}
diff --git a/source/blender/blenkernel/intern/pointcloud.c b/source/blender/blenkernel/intern/pointcloud.cc
index 78acf7251fa..cbfb1086e8d 100644
--- a/source/blender/blenkernel/intern/pointcloud.c
+++ b/source/blender/blenkernel/intern/pointcloud.cc
@@ -67,7 +67,7 @@ static void pointcloud_init_data(ID *id)
CustomData_add_layer_named(&pointcloud->pdata,
CD_PROP_FLOAT3,
CD_CALLOC,
- NULL,
+ nullptr,
pointcloud->totpoint,
POINTCLOUD_ATTR_POSITION);
BKE_pointcloud_update_customdata_pointers(pointcloud);
@@ -77,7 +77,7 @@ static void pointcloud_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_s
{
PointCloud *pointcloud_dst = (PointCloud *)id_dst;
const PointCloud *pointcloud_src = (const PointCloud *)id_src;
- pointcloud_dst->mat = MEM_dupallocN(pointcloud_dst->mat);
+ pointcloud_dst->mat = static_cast<Material **>(MEM_dupallocN(pointcloud_dst->mat));
const eCDAllocType alloc_type = (flag & LIB_ID_COPY_CD_REFERENCE) ? CD_REFERENCE : CD_DUPLICATE;
CustomData_copy(&pointcloud_src->pdata,
@@ -109,7 +109,7 @@ static void pointcloud_blend_write(BlendWriter *writer, ID *id, const void *id_a
{
PointCloud *pointcloud = (PointCloud *)id;
if (pointcloud->id.us > 0 || BLO_write_is_undo(writer)) {
- CustomDataLayer *players = NULL, players_buff[CD_TEMP_CHUNK_SIZE];
+ CustomDataLayer *players = nullptr, players_buff[CD_TEMP_CHUNK_SIZE];
CustomData_blend_write_prepare(
&pointcloud->pdata, &players, players_buff, ARRAY_SIZE(players_buff));
@@ -164,26 +164,28 @@ static void pointcloud_blend_read_expand(BlendExpander *expander, ID *id)
}
IDTypeInfo IDType_ID_PT = {
- .id_code = ID_PT,
- .id_filter = FILTER_ID_PT,
- .main_listbase_index = INDEX_ID_PT,
- .struct_size = sizeof(PointCloud),
- .name = "PointCloud",
- .name_plural = "pointclouds",
- .translation_context = BLT_I18NCONTEXT_ID_POINTCLOUD,
- .flags = 0,
-
- .init_data = pointcloud_init_data,
- .copy_data = pointcloud_copy_data,
- .free_data = pointcloud_free_data,
- .make_local = NULL,
- .foreach_id = pointcloud_foreach_id,
- .foreach_cache = NULL,
-
- .blend_write = pointcloud_blend_write,
- .blend_read_data = pointcloud_blend_read_data,
- .blend_read_lib = pointcloud_blend_read_lib,
- .blend_read_expand = pointcloud_blend_read_expand,
+ /* id_code */ ID_PT,
+ /* id_filter */ FILTER_ID_PT,
+ /* main_listbase_index */ INDEX_ID_PT,
+ /* struct_size */ sizeof(PointCloud),
+ /* name */ "PointCloud",
+ /* name_plural */ "pointclouds",
+ /* translation_context */ BLT_I18NCONTEXT_ID_POINTCLOUD,
+ /* flags */ 0,
+
+ /* init_data */ pointcloud_init_data,
+ /* copy_data */ pointcloud_copy_data,
+ /* free_data */ pointcloud_free_data,
+ /* make_local */ nullptr,
+ /* foreach_id */ pointcloud_foreach_id,
+ /* foreach_cache */ nullptr,
+
+ /* blend_write */ pointcloud_blend_write,
+ /* blend_read_data */ pointcloud_blend_read_data,
+ /* blend_read_lib */ pointcloud_blend_read_lib,
+ /* blend_read_expand */ pointcloud_blend_read_expand,
+
+ /* blend_read_undo_preserve */ nullptr,
};
static void pointcloud_random(PointCloud *pointcloud)
@@ -206,21 +208,21 @@ static void pointcloud_random(PointCloud *pointcloud)
void *BKE_pointcloud_add(Main *bmain, const char *name)
{
- PointCloud *pointcloud = BKE_id_new(bmain, ID_PT, name);
+ PointCloud *pointcloud = static_cast<PointCloud *>(BKE_id_new(bmain, ID_PT, name));
return pointcloud;
}
void *BKE_pointcloud_add_default(Main *bmain, const char *name)
{
- PointCloud *pointcloud = BKE_libblock_alloc(bmain, ID_PT, name, 0);
+ PointCloud *pointcloud = static_cast<PointCloud *>(BKE_libblock_alloc(bmain, ID_PT, name, 0));
pointcloud_init_data(&pointcloud->id);
CustomData_add_layer_named(&pointcloud->pdata,
CD_PROP_FLOAT,
CD_CALLOC,
- NULL,
+ nullptr,
pointcloud->totpoint,
POINTCLOUD_ATTR_RADIUS);
pointcloud_random(pointcloud);
@@ -231,14 +233,14 @@ void *BKE_pointcloud_add_default(Main *bmain, const char *name)
BoundBox *BKE_pointcloud_boundbox_get(Object *ob)
{
BLI_assert(ob->type == OB_POINTCLOUD);
- PointCloud *pointcloud = ob->data;
+ PointCloud *pointcloud = static_cast<PointCloud *>(ob->data);
- if (ob->runtime.bb != NULL && (ob->runtime.bb->flag & BOUNDBOX_DIRTY) == 0) {
+ if (ob->runtime.bb != nullptr && (ob->runtime.bb->flag & BOUNDBOX_DIRTY) == 0) {
return ob->runtime.bb;
}
- if (ob->runtime.bb == NULL) {
- ob->runtime.bb = MEM_callocN(sizeof(BoundBox), "pointcloud boundbox");
+ if (ob->runtime.bb == nullptr) {
+ ob->runtime.bb = static_cast<BoundBox *>(MEM_callocN(sizeof(BoundBox), "pointcloud boundbox"));
float min[3], max[3];
INIT_MINMAX(min, max);
@@ -262,10 +264,10 @@ BoundBox *BKE_pointcloud_boundbox_get(Object *ob)
void BKE_pointcloud_update_customdata_pointers(PointCloud *pointcloud)
{
- pointcloud->co = CustomData_get_layer_named(
- &pointcloud->pdata, CD_PROP_FLOAT3, POINTCLOUD_ATTR_POSITION);
- pointcloud->radius = CustomData_get_layer_named(
- &pointcloud->pdata, CD_PROP_FLOAT, POINTCLOUD_ATTR_RADIUS);
+ pointcloud->co = static_cast<float(*)[3]>(
+ CustomData_get_layer_named(&pointcloud->pdata, CD_PROP_FLOAT3, POINTCLOUD_ATTR_POSITION));
+ pointcloud->radius = static_cast<float *>(
+ CustomData_get_layer_named(&pointcloud->pdata, CD_PROP_FLOAT, POINTCLOUD_ATTR_RADIUS));
}
bool BKE_pointcloud_customdata_required(PointCloud *UNUSED(pointcloud), CustomDataLayer *layer)
@@ -277,11 +279,11 @@ bool BKE_pointcloud_customdata_required(PointCloud *UNUSED(pointcloud), CustomDa
PointCloud *BKE_pointcloud_new_for_eval(const PointCloud *pointcloud_src, int totpoint)
{
- PointCloud *pointcloud_dst = BKE_id_new_nomain(ID_PT, NULL);
+ PointCloud *pointcloud_dst = static_cast<PointCloud *>(BKE_id_new_nomain(ID_PT, nullptr));
CustomData_free(&pointcloud_dst->pdata, pointcloud_dst->totpoint);
STRNCPY(pointcloud_dst->id.name, pointcloud_src->id.name);
- pointcloud_dst->mat = MEM_dupallocN(pointcloud_src->mat);
+ pointcloud_dst->mat = static_cast<Material **>(MEM_dupallocN(pointcloud_src->mat));
pointcloud_dst->totcol = pointcloud_src->totcol;
pointcloud_dst->totpoint = totpoint;
@@ -300,7 +302,7 @@ PointCloud *BKE_pointcloud_copy_for_eval(struct PointCloud *pointcloud_src, bool
flags |= LIB_ID_COPY_CD_REFERENCE;
}
- PointCloud *result = (PointCloud *)BKE_id_copy_ex(NULL, &pointcloud_src->id, NULL, flags);
+ PointCloud *result = (PointCloud *)BKE_id_copy_ex(nullptr, &pointcloud_src->id, nullptr, flags);
return result;
}
@@ -324,7 +326,7 @@ static PointCloud *pointcloud_evaluate_modifiers(struct Depsgraph *depsgraph,
/* Evaluate modifiers. */
for (; md; md = md->next) {
- const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
+ const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md->type);
if (!BKE_modifier_is_enabled(scene, md, required_mode)) {
continue;
@@ -343,7 +345,7 @@ static PointCloud *pointcloud_evaluate_modifiers(struct Depsgraph *depsgraph,
BKE_pointcloud_update_customdata_pointers(pointcloud);
/* Created deformed coordinates array on demand. */
- mti->deformVerts(md, &mectx, NULL, pointcloud->co, pointcloud->totpoint);
+ mti->deformVerts(md, &mectx, nullptr, pointcloud->co, pointcloud->totpoint);
}
else if (mti->modifyPointCloud) {
/* Ensure we are not modifying the input. */
@@ -356,7 +358,7 @@ static PointCloud *pointcloud_evaluate_modifiers(struct Depsgraph *depsgraph,
if (pointcloud_next && pointcloud_next != pointcloud) {
/* If the modifier returned a new pointcloud, release the old one. */
if (pointcloud != pointcloud_input) {
- BKE_id_free(NULL, pointcloud);
+ BKE_id_free(nullptr, pointcloud);
}
pointcloud = pointcloud_next;
}
@@ -372,7 +374,7 @@ void BKE_pointcloud_data_update(struct Depsgraph *depsgraph, struct Scene *scene
BKE_object_free_derived_caches(object);
/* Evaluate modifiers. */
- PointCloud *pointcloud = object->data;
+ PointCloud *pointcloud = static_cast<PointCloud *>(object->data);
PointCloud *pointcloud_eval = pointcloud_evaluate_modifiers(
depsgraph, scene, object, pointcloud);
@@ -382,8 +384,8 @@ void BKE_pointcloud_data_update(struct Depsgraph *depsgraph, struct Scene *scene
}
/* Draw Cache */
-void (*BKE_pointcloud_batch_cache_dirty_tag_cb)(PointCloud *pointcloud, int mode) = NULL;
-void (*BKE_pointcloud_batch_cache_free_cb)(PointCloud *pointcloud) = NULL;
+void (*BKE_pointcloud_batch_cache_dirty_tag_cb)(PointCloud *pointcloud, int mode) = nullptr;
+void (*BKE_pointcloud_batch_cache_free_cb)(PointCloud *pointcloud) = nullptr;
void BKE_pointcloud_batch_cache_dirty_tag(PointCloud *pointcloud, int mode)
{
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 416f5aa7edd..bed10df5ace 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -21,6 +21,9 @@
* \ingroup bke
*/
+/* Allow using deprecated functionality for .blend file I/O. */
+#define DNA_DEPRECATED_ALLOW
+
#include <stddef.h>
#include <stdio.h>
#include <string.h>
@@ -70,6 +73,7 @@
#include "BKE_curveprofile.h"
#include "BKE_duplilist.h"
#include "BKE_editmesh.h"
+#include "BKE_effect.h"
#include "BKE_fcurve.h"
#include "BKE_freestyle.h"
#include "BKE_gpencil.h"
@@ -87,10 +91,10 @@
#include "BKE_node.h"
#include "BKE_object.h"
#include "BKE_paint.h"
+#include "BKE_pointcache.h"
#include "BKE_rigidbody.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
-#include "BKE_sequencer.h"
#include "BKE_sound.h"
#include "BKE_unit.h"
#include "BKE_workspace.h"
@@ -103,6 +107,10 @@
#include "RE_engine.h"
+#include "SEQ_sequencer.h"
+
+#include "BLO_read_write.h"
+
#include "engines/eevee/eevee_lightcache.h"
#include "PIL_time.h"
@@ -454,53 +462,216 @@ static void scene_foreach_rigidbodyworldSceneLooper(struct RigidBodyWorld *UNUSE
BKE_lib_query_foreachid_process(data, id_pointer, cb_flag);
}
-static void scene_foreach_paint(LibraryForeachIDData *data, Paint *paint)
-{
- BKE_LIB_FOREACHID_PROCESS(data, paint->brush, IDWALK_CB_USER);
- for (int i = 0; i < paint->tool_slots_len; i++) {
- BKE_LIB_FOREACHID_PROCESS(data, paint->tool_slots[i].brush, IDWALK_CB_USER);
+/**
+ * This code is shared by both the regular `foreach_id` looper, and the code trying to restore or
+ * preserve ID pointers like brushes across undoes.
+ */
+typedef enum eSceneForeachUndoPreserveProcess {
+ /* Undo when preserving tool-settings from old scene, we also want to try to preserve that ID
+ * pointer from its old scene's value. */
+ SCENE_FOREACH_UNDO_RESTORE,
+ /* Undo when preserving tool-settings from old scene, we want to keep the new value of that ID
+ * pointer. */
+ SCENE_FOREACH_UNDO_NO_RESTORE,
+} eSceneForeachUndoPreserveProcess;
+
+static void scene_foreach_toolsettings_id_pointer_process(
+ ID **id_p,
+ const eSceneForeachUndoPreserveProcess action,
+ BlendLibReader *reader,
+ ID **id_old_p,
+ const uint cb_flag)
+{
+ switch (action) {
+ case SCENE_FOREACH_UNDO_RESTORE: {
+ ID *id_old = *id_old_p;
+ /* Old data has not been remapped to new values of the pointers, if we want to keep the old
+ * pointer here we need its new address. */
+ ID *id_old_new = id_old != NULL ? BLO_read_get_new_id_address(reader, id_old->lib, id_old) :
+ NULL;
+ if (id_old_new != NULL) {
+ BLI_assert(ELEM(id_old, id_old_new, id_old_new->orig_id));
+ *id_old_p = id_old_new;
+ if (cb_flag & IDWALK_CB_USER) {
+ id_us_plus_no_lib(id_old_new);
+ id_us_min(id_old);
+ }
+ break;
+ }
+ /* We failed to find a new valid pointer for the previous ID, just keep the current one as
+ * if we had been under SCENE_FOREACH_UNDO_NO_RESTORE case. */
+ SWAP(ID *, *id_p, *id_old_p);
+ break;
+ }
+ case SCENE_FOREACH_UNDO_NO_RESTORE:
+ /* Counteract the swap of the whole ToolSettings container struct. */
+ SWAP(ID *, *id_p, *id_old_p);
+ break;
}
- BKE_LIB_FOREACHID_PROCESS(data, paint->palette, IDWALK_CB_USER);
}
-static void scene_foreach_toolsettings(LibraryForeachIDData *data, ToolSettings *toolsett)
-{
- BKE_LIB_FOREACHID_PROCESS(data, toolsett->particle.scene, IDWALK_CB_NOP);
- BKE_LIB_FOREACHID_PROCESS(data, toolsett->particle.object, IDWALK_CB_NOP);
- BKE_LIB_FOREACHID_PROCESS(data, toolsett->particle.shape_object, IDWALK_CB_NOP);
-
- scene_foreach_paint(data, &toolsett->imapaint.paint);
- BKE_LIB_FOREACHID_PROCESS(data, toolsett->imapaint.stencil, IDWALK_CB_USER);
- BKE_LIB_FOREACHID_PROCESS(data, toolsett->imapaint.clone, IDWALK_CB_USER);
- BKE_LIB_FOREACHID_PROCESS(data, toolsett->imapaint.canvas, IDWALK_CB_USER);
+#define BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS( \
+ __data, __id, __do_undo_restore, __action, __reader, __id_old, __cb_flag) \
+ { \
+ if (__do_undo_restore) { \
+ scene_foreach_toolsettings_id_pointer_process( \
+ (ID **)&(__id), __action, __reader, (ID **)&(__id_old), __cb_flag); \
+ } \
+ else { \
+ BKE_LIB_FOREACHID_PROCESS(__data, __id, __cb_flag); \
+ } \
+ } \
+ (void)0
+
+static void scene_foreach_paint(LibraryForeachIDData *data,
+ Paint *paint,
+ const bool do_undo_restore,
+ BlendLibReader *reader,
+ Paint *paint_old)
+{
+ BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data,
+ paint->brush,
+ do_undo_restore,
+ SCENE_FOREACH_UNDO_RESTORE,
+ reader,
+ paint_old->brush,
+ IDWALK_CB_USER);
+ for (int i = 0; i < paint_old->tool_slots_len; i++) {
+ /* This is a bit tricky.
+ * - In case we do not do `undo_restore`, `paint` and `paint_old` pointers are the same, so
+ * this is equivalent to simply looping over slots from `paint`.
+ * - In case we do `undo_restore`, we only want to consider the slots from the old one, since
+ * those are the one we keep in the end.
+ * + In case the new data has less valid slots, we feed in a dummy NULL pointer.
+ * + In case the new data has more valid slots, the extra ones are ignored.
+ */
+ Brush *brush_tmp = NULL;
+ Brush **brush_p = i < paint->tool_slots_len ? &paint->tool_slots[i].brush : &brush_tmp;
+ BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data,
+ *brush_p,
+ do_undo_restore,
+ SCENE_FOREACH_UNDO_RESTORE,
+ reader,
+ paint_old->brush,
+ IDWALK_CB_USER);
+ }
+ BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data,
+ paint->palette,
+ do_undo_restore,
+ SCENE_FOREACH_UNDO_RESTORE,
+ reader,
+ paint_old->palette,
+ IDWALK_CB_USER);
+}
+
+static void scene_foreach_toolsettings(LibraryForeachIDData *data,
+ ToolSettings *toolsett,
+ const bool do_undo_restore,
+ BlendLibReader *reader,
+ ToolSettings *toolsett_old)
+{
+ BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data,
+ toolsett->particle.scene,
+ do_undo_restore,
+ SCENE_FOREACH_UNDO_NO_RESTORE,
+ reader,
+ toolsett_old->particle.scene,
+ IDWALK_CB_NOP);
+ BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data,
+ toolsett->particle.object,
+ do_undo_restore,
+ SCENE_FOREACH_UNDO_NO_RESTORE,
+ reader,
+ toolsett_old->particle.object,
+ IDWALK_CB_NOP);
+ BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data,
+ toolsett->particle.shape_object,
+ do_undo_restore,
+ SCENE_FOREACH_UNDO_NO_RESTORE,
+ reader,
+ toolsett_old->particle.shape_object,
+ IDWALK_CB_NOP);
+
+ scene_foreach_paint(
+ data, &toolsett->imapaint.paint, do_undo_restore, reader, &toolsett_old->imapaint.paint);
+ BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data,
+ toolsett->imapaint.stencil,
+ do_undo_restore,
+ SCENE_FOREACH_UNDO_RESTORE,
+ reader,
+ toolsett_old->imapaint.stencil,
+ IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data,
+ toolsett->imapaint.clone,
+ do_undo_restore,
+ SCENE_FOREACH_UNDO_RESTORE,
+ reader,
+ toolsett_old->imapaint.clone,
+ IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data,
+ toolsett->imapaint.canvas,
+ do_undo_restore,
+ SCENE_FOREACH_UNDO_RESTORE,
+ reader,
+ toolsett_old->imapaint.canvas,
+ IDWALK_CB_USER);
if (toolsett->vpaint) {
- scene_foreach_paint(data, &toolsett->vpaint->paint);
+ scene_foreach_paint(
+ data, &toolsett->vpaint->paint, do_undo_restore, reader, &toolsett_old->vpaint->paint);
}
if (toolsett->wpaint) {
- scene_foreach_paint(data, &toolsett->wpaint->paint);
+ scene_foreach_paint(
+ data, &toolsett->wpaint->paint, do_undo_restore, reader, &toolsett_old->wpaint->paint);
}
if (toolsett->sculpt) {
- scene_foreach_paint(data, &toolsett->sculpt->paint);
- BKE_LIB_FOREACHID_PROCESS(data, toolsett->sculpt->gravity_object, IDWALK_CB_NOP);
+ scene_foreach_paint(
+ data, &toolsett->sculpt->paint, do_undo_restore, reader, &toolsett_old->sculpt->paint);
+ BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data,
+ toolsett->sculpt->gravity_object,
+ do_undo_restore,
+ SCENE_FOREACH_UNDO_NO_RESTORE,
+ reader,
+ toolsett_old->sculpt->gravity_object,
+ IDWALK_CB_NOP);
}
if (toolsett->uvsculpt) {
- scene_foreach_paint(data, &toolsett->uvsculpt->paint);
+ scene_foreach_paint(
+ data, &toolsett->uvsculpt->paint, do_undo_restore, reader, &toolsett_old->uvsculpt->paint);
}
if (toolsett->gp_paint) {
- scene_foreach_paint(data, &toolsett->gp_paint->paint);
+ scene_foreach_paint(
+ data, &toolsett->gp_paint->paint, do_undo_restore, reader, &toolsett_old->gp_paint->paint);
}
if (toolsett->gp_vertexpaint) {
- scene_foreach_paint(data, &toolsett->gp_vertexpaint->paint);
+ scene_foreach_paint(data,
+ &toolsett->gp_vertexpaint->paint,
+ do_undo_restore,
+ reader,
+ &toolsett_old->gp_vertexpaint->paint);
}
if (toolsett->gp_sculptpaint) {
- scene_foreach_paint(data, &toolsett->gp_sculptpaint->paint);
+ scene_foreach_paint(data,
+ &toolsett->gp_sculptpaint->paint,
+ do_undo_restore,
+ reader,
+ &toolsett_old->gp_sculptpaint->paint);
}
if (toolsett->gp_weightpaint) {
- scene_foreach_paint(data, &toolsett->gp_weightpaint->paint);
+ scene_foreach_paint(data,
+ &toolsett->gp_weightpaint->paint,
+ do_undo_restore,
+ reader,
+ &toolsett_old->gp_weightpaint->paint);
}
- BKE_LIB_FOREACHID_PROCESS(data, toolsett->gp_sculpt.guide.reference_object, IDWALK_CB_NOP);
+ BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data,
+ toolsett->gp_sculpt.guide.reference_object,
+ do_undo_restore,
+ SCENE_FOREACH_UNDO_NO_RESTORE,
+ reader,
+ toolsett_old->gp_sculpt.guide.reference_object,
+ IDWALK_CB_NOP);
}
static void scene_foreach_layer_collection(LibraryForeachIDData *data, ListBase *lb)
@@ -592,7 +763,7 @@ static void scene_foreach_id(ID *id, LibraryForeachIDData *data)
ToolSettings *toolsett = scene->toolsettings;
if (toolsett) {
- scene_foreach_toolsettings(data, toolsett);
+ scene_foreach_toolsettings(data, toolsett, false, NULL, toolsett);
}
if (scene->rigidbody_world) {
@@ -619,6 +790,889 @@ static void scene_foreach_cache(ID *id,
user_data);
}
+static void scene_blend_write(BlendWriter *writer, ID *id, const void *id_address)
+{
+ Scene *sce = (Scene *)id;
+
+ if (BLO_write_is_undo(writer)) {
+ /* Clean up, important in undo case to reduce false detection of changed data-blocks. */
+ /* XXX This UI data should not be stored in Scene at all... */
+ memset(&sce->cursor, 0, sizeof(sce->cursor));
+ }
+
+ /* write LibData */
+ BLO_write_id_struct(writer, Scene, id_address, &sce->id);
+ BKE_id_blend_write(writer, &sce->id);
+
+ if (sce->adt) {
+ BKE_animdata_blend_write(writer, sce->adt);
+ }
+ BKE_keyingsets_blend_write(writer, &sce->keyingsets);
+
+ /* direct data */
+ ToolSettings *tos = sce->toolsettings;
+ BLO_write_struct(writer, ToolSettings, tos);
+ if (tos->vpaint) {
+ BLO_write_struct(writer, VPaint, tos->vpaint);
+ BKE_paint_blend_write(writer, &tos->vpaint->paint);
+ }
+ if (tos->wpaint) {
+ BLO_write_struct(writer, VPaint, tos->wpaint);
+ BKE_paint_blend_write(writer, &tos->wpaint->paint);
+ }
+ if (tos->sculpt) {
+ BLO_write_struct(writer, Sculpt, tos->sculpt);
+ BKE_paint_blend_write(writer, &tos->sculpt->paint);
+ }
+ if (tos->uvsculpt) {
+ BLO_write_struct(writer, UvSculpt, tos->uvsculpt);
+ BKE_paint_blend_write(writer, &tos->uvsculpt->paint);
+ }
+ if (tos->gp_paint) {
+ BLO_write_struct(writer, GpPaint, tos->gp_paint);
+ BKE_paint_blend_write(writer, &tos->gp_paint->paint);
+ }
+ if (tos->gp_vertexpaint) {
+ BLO_write_struct(writer, GpVertexPaint, tos->gp_vertexpaint);
+ BKE_paint_blend_write(writer, &tos->gp_vertexpaint->paint);
+ }
+ if (tos->gp_sculptpaint) {
+ BLO_write_struct(writer, GpSculptPaint, tos->gp_sculptpaint);
+ BKE_paint_blend_write(writer, &tos->gp_sculptpaint->paint);
+ }
+ if (tos->gp_weightpaint) {
+ BLO_write_struct(writer, GpWeightPaint, tos->gp_weightpaint);
+ BKE_paint_blend_write(writer, &tos->gp_weightpaint->paint);
+ }
+ /* write grease-pencil custom ipo curve to file */
+ if (tos->gp_interpolate.custom_ipo) {
+ BKE_curvemapping_blend_write(writer, tos->gp_interpolate.custom_ipo);
+ }
+ /* write grease-pencil multiframe falloff curve to file */
+ if (tos->gp_sculpt.cur_falloff) {
+ BKE_curvemapping_blend_write(writer, tos->gp_sculpt.cur_falloff);
+ }
+ /* write grease-pencil primitive curve to file */
+ if (tos->gp_sculpt.cur_primitive) {
+ BKE_curvemapping_blend_write(writer, tos->gp_sculpt.cur_primitive);
+ }
+ /* Write the curve profile to the file. */
+ if (tos->custom_bevel_profile_preset) {
+ BKE_curveprofile_blend_write(writer, tos->custom_bevel_profile_preset);
+ }
+
+ BKE_paint_blend_write(writer, &tos->imapaint.paint);
+
+ Editing *ed = sce->ed;
+ if (ed) {
+ Sequence *seq;
+
+ BLO_write_struct(writer, Editing, ed);
+
+ /* reset write flags too */
+
+ SEQ_ALL_BEGIN (ed, seq) {
+ if (seq->strip) {
+ seq->strip->done = false;
+ }
+ BLO_write_struct(writer, Sequence, seq);
+ }
+ SEQ_ALL_END;
+
+ SEQ_ALL_BEGIN (ed, seq) {
+ if (seq->strip && seq->strip->done == 0) {
+ /* write strip with 'done' at 0 because readfile */
+
+ if (seq->effectdata) {
+ switch (seq->type) {
+ case SEQ_TYPE_COLOR:
+ BLO_write_struct(writer, SolidColorVars, seq->effectdata);
+ break;
+ case SEQ_TYPE_SPEED:
+ BLO_write_struct(writer, SpeedControlVars, seq->effectdata);
+ break;
+ case SEQ_TYPE_WIPE:
+ BLO_write_struct(writer, WipeVars, seq->effectdata);
+ break;
+ case SEQ_TYPE_GLOW:
+ BLO_write_struct(writer, GlowVars, seq->effectdata);
+ break;
+ case SEQ_TYPE_TRANSFORM:
+ BLO_write_struct(writer, TransformVars, seq->effectdata);
+ break;
+ case SEQ_TYPE_GAUSSIAN_BLUR:
+ BLO_write_struct(writer, GaussianBlurVars, seq->effectdata);
+ break;
+ case SEQ_TYPE_TEXT:
+ BLO_write_struct(writer, TextVars, seq->effectdata);
+ break;
+ case SEQ_TYPE_COLORMIX:
+ BLO_write_struct(writer, ColorMixVars, seq->effectdata);
+ break;
+ }
+ }
+
+ BLO_write_struct(writer, Stereo3dFormat, seq->stereo3d_format);
+
+ Strip *strip = seq->strip;
+ BLO_write_struct(writer, Strip, strip);
+ if (strip->crop) {
+ BLO_write_struct(writer, StripCrop, strip->crop);
+ }
+ if (strip->transform) {
+ BLO_write_struct(writer, StripTransform, strip->transform);
+ }
+ if (strip->proxy) {
+ BLO_write_struct(writer, StripProxy, strip->proxy);
+ }
+ if (seq->type == SEQ_TYPE_IMAGE) {
+ BLO_write_struct_array(writer,
+ StripElem,
+ MEM_allocN_len(strip->stripdata) / sizeof(struct StripElem),
+ strip->stripdata);
+ }
+ else if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD)) {
+ BLO_write_struct(writer, StripElem, strip->stripdata);
+ }
+
+ strip->done = true;
+ }
+
+ if (seq->prop) {
+ IDP_BlendWrite(writer, seq->prop);
+ }
+
+ BKE_sequence_modifier_blend_write(writer, &seq->modifiers);
+ }
+ SEQ_ALL_END;
+
+ /* new; meta stack too, even when its nasty restore code */
+ LISTBASE_FOREACH (MetaStack *, ms, &ed->metastack) {
+ BLO_write_struct(writer, MetaStack, ms);
+ }
+ }
+
+ if (sce->r.avicodecdata) {
+ BLO_write_struct(writer, AviCodecData, sce->r.avicodecdata);
+ if (sce->r.avicodecdata->lpFormat) {
+ BLO_write_raw(writer, (size_t)sce->r.avicodecdata->cbFormat, sce->r.avicodecdata->lpFormat);
+ }
+ if (sce->r.avicodecdata->lpParms) {
+ BLO_write_raw(writer, (size_t)sce->r.avicodecdata->cbParms, sce->r.avicodecdata->lpParms);
+ }
+ }
+ if (sce->r.ffcodecdata.properties) {
+ IDP_BlendWrite(writer, sce->r.ffcodecdata.properties);
+ }
+
+ /* writing dynamic list of TimeMarkers to the blend file */
+ LISTBASE_FOREACH (TimeMarker *, marker, &sce->markers) {
+ BLO_write_struct(writer, TimeMarker, marker);
+
+ if (marker->prop != NULL) {
+ IDP_BlendWrite(writer, marker->prop);
+ }
+ }
+
+ /* writing dynamic list of TransformOrientations to the blend file */
+ LISTBASE_FOREACH (TransformOrientation *, ts, &sce->transform_spaces) {
+ BLO_write_struct(writer, TransformOrientation, ts);
+ }
+
+ /* writing MultiView to the blend file */
+ LISTBASE_FOREACH (SceneRenderView *, srv, &sce->r.views) {
+ BLO_write_struct(writer, SceneRenderView, srv);
+ }
+
+ if (sce->nodetree) {
+ BLO_write_struct(writer, bNodeTree, sce->nodetree);
+ ntreeBlendWrite(writer, sce->nodetree);
+ }
+
+ BKE_color_managed_view_settings_blend_write(writer, &sce->view_settings);
+
+ /* writing RigidBodyWorld data to the blend file */
+ if (sce->rigidbody_world) {
+ /* Set deprecated pointers to prevent crashes of older Blenders */
+ sce->rigidbody_world->pointcache = sce->rigidbody_world->shared->pointcache;
+ sce->rigidbody_world->ptcaches = sce->rigidbody_world->shared->ptcaches;
+ BLO_write_struct(writer, RigidBodyWorld, sce->rigidbody_world);
+
+ BLO_write_struct(writer, RigidBodyWorld_Shared, sce->rigidbody_world->shared);
+ BLO_write_struct(writer, EffectorWeights, sce->rigidbody_world->effector_weights);
+ BKE_ptcache_blend_write(writer, &(sce->rigidbody_world->shared->ptcaches));
+ }
+
+ BKE_previewimg_blend_write(writer, sce->preview);
+ BKE_curvemapping_curves_blend_write(writer, &sce->r.mblur_shutter_curve);
+
+ LISTBASE_FOREACH (ViewLayer *, view_layer, &sce->view_layers) {
+ BKE_view_layer_blend_write(writer, view_layer);
+ }
+
+ if (sce->master_collection) {
+ BLO_write_struct(writer, Collection, sce->master_collection);
+ BKE_collection_blend_write_nolib(writer, sce->master_collection);
+ }
+
+ /* Eevee Lightcache */
+ if (sce->eevee.light_cache_data && !BLO_write_is_undo(writer)) {
+ BLO_write_struct(writer, LightCache, sce->eevee.light_cache_data);
+ EEVEE_lightcache_blend_write(writer, sce->eevee.light_cache_data);
+ }
+
+ BKE_screen_view3d_shading_blend_write(writer, &sce->display.shading);
+
+ /* Freed on doversion. */
+ BLI_assert(sce->layer_properties == NULL);
+}
+
+static void direct_link_paint_helper(BlendDataReader *reader, const Scene *scene, Paint **paint)
+{
+ /* TODO. is this needed */
+ BLO_read_data_address(reader, paint);
+
+ if (*paint) {
+ BKE_paint_blend_read_data(reader, scene, *paint);
+ }
+}
+
+static void link_recurs_seq(BlendDataReader *reader, ListBase *lb)
+{
+ BLO_read_list(reader, lb);
+
+ LISTBASE_FOREACH (Sequence *, seq, lb) {
+ if (seq->seqbase.first) {
+ link_recurs_seq(reader, &seq->seqbase);
+ }
+ }
+}
+
+static void scene_blend_read_data(BlendDataReader *reader, ID *id)
+{
+ Scene *sce = (Scene *)id;
+
+ sce->depsgraph_hash = NULL;
+ sce->fps_info = NULL;
+
+ memset(&sce->customdata_mask, 0, sizeof(sce->customdata_mask));
+ memset(&sce->customdata_mask_modal, 0, sizeof(sce->customdata_mask_modal));
+
+ BKE_sound_reset_scene_runtime(sce);
+
+ /* set users to one by default, not in lib-link, this will increase it for compo nodes */
+ id_us_ensure_real(&sce->id);
+
+ BLO_read_list(reader, &(sce->base));
+
+ BLO_read_data_address(reader, &sce->adt);
+ BKE_animdata_blend_read_data(reader, sce->adt);
+
+ BLO_read_list(reader, &sce->keyingsets);
+ BKE_keyingsets_blend_read_data(reader, &sce->keyingsets);
+
+ BLO_read_data_address(reader, &sce->basact);
+
+ BLO_read_data_address(reader, &sce->toolsettings);
+ if (sce->toolsettings) {
+
+ /* Reset last_location and last_hit, so they are not remembered across sessions. In some files
+ * these are also NaN, which could lead to crashes in painting. */
+ struct UnifiedPaintSettings *ups = &sce->toolsettings->unified_paint_settings;
+ zero_v3(ups->last_location);
+ ups->last_hit = 0;
+
+ direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->sculpt);
+ direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->vpaint);
+ direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->wpaint);
+ direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->uvsculpt);
+ direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->gp_paint);
+ direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->gp_vertexpaint);
+ direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->gp_sculptpaint);
+ direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->gp_weightpaint);
+
+ BKE_paint_blend_read_data(reader, sce, &sce->toolsettings->imapaint.paint);
+
+ sce->toolsettings->particle.paintcursor = NULL;
+ sce->toolsettings->particle.scene = NULL;
+ sce->toolsettings->particle.object = NULL;
+ sce->toolsettings->gp_sculpt.paintcursor = NULL;
+
+ /* relink grease pencil interpolation curves */
+ BLO_read_data_address(reader, &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 multiframe falloff curve */
+ BLO_read_data_address(reader, &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);
+ 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);
+ if (sce->toolsettings->custom_bevel_profile_preset) {
+ BKE_curveprofile_blend_read(reader, sce->toolsettings->custom_bevel_profile_preset);
+ }
+ }
+
+ if (sce->ed) {
+ ListBase *old_seqbasep = &sce->ed->seqbase;
+
+ BLO_read_data_address(reader, &sce->ed);
+ Editing *ed = sce->ed;
+
+ BLO_read_data_address(reader, &ed->act_seq);
+ ed->cache = NULL;
+ ed->prefetch_job = NULL;
+
+ /* recursive link sequences, lb will be correctly initialized */
+ link_recurs_seq(reader, &ed->seqbase);
+
+ Sequence *seq;
+ SEQ_ALL_BEGIN (ed, seq) {
+ /* Do as early as possible, so that other parts of reading can rely on valid session UUID. */
+ BKE_sequence_session_uuid_generate(seq);
+
+ BLO_read_data_address(reader, &seq->seq1);
+ BLO_read_data_address(reader, &seq->seq2);
+ BLO_read_data_address(reader, &seq->seq3);
+
+ /* a patch: after introduction of effects with 3 input strips */
+ if (seq->seq3 == NULL) {
+ seq->seq3 = seq->seq2;
+ }
+
+ BLO_read_data_address(reader, &seq->effectdata);
+ BLO_read_data_address(reader, &seq->stereo3d_format);
+
+ if (seq->type & SEQ_TYPE_EFFECT) {
+ seq->flag |= SEQ_EFFECT_NOT_LOADED;
+ }
+
+ if (seq->type == SEQ_TYPE_SPEED) {
+ SpeedControlVars *s = seq->effectdata;
+ s->frameMap = NULL;
+ }
+
+ if (seq->type == SEQ_TYPE_TEXT) {
+ TextVars *t = seq->effectdata;
+ t->text_blf_id = SEQ_FONT_NOT_LOADED;
+ }
+
+ BLO_read_data_address(reader, &seq->prop);
+ IDP_BlendDataRead(reader, &seq->prop);
+
+ BLO_read_data_address(reader, &seq->strip);
+ if (seq->strip && seq->strip->done == 0) {
+ seq->strip->done = true;
+
+ if (ELEM(seq->type,
+ SEQ_TYPE_IMAGE,
+ SEQ_TYPE_MOVIE,
+ SEQ_TYPE_SOUND_RAM,
+ SEQ_TYPE_SOUND_HD)) {
+ BLO_read_data_address(reader, &seq->strip->stripdata);
+ }
+ else {
+ seq->strip->stripdata = NULL;
+ }
+ BLO_read_data_address(reader, &seq->strip->crop);
+ BLO_read_data_address(reader, &seq->strip->transform);
+ BLO_read_data_address(reader, &seq->strip->proxy);
+ if (seq->strip->proxy) {
+ seq->strip->proxy->anim = NULL;
+ }
+ else if (seq->flag & SEQ_USE_PROXY) {
+ SEQ_proxy_set(seq, true);
+ }
+
+ /* need to load color balance to it could be converted to modifier */
+ BLO_read_data_address(reader, &seq->strip->color_balance);
+ }
+
+ BKE_sequence_modifier_blend_read_data(reader, &seq->modifiers);
+ }
+ SEQ_ALL_END;
+
+ /* link metastack, slight abuse of structs here,
+ * have to restore pointer to internal part in struct */
+ {
+ Sequence temp;
+ void *poin;
+ intptr_t offset;
+
+ offset = ((intptr_t) & (temp.seqbase)) - ((intptr_t)&temp);
+
+ /* root pointer */
+ if (ed->seqbasep == old_seqbasep) {
+ ed->seqbasep = &ed->seqbase;
+ }
+ else {
+ poin = POINTER_OFFSET(ed->seqbasep, -offset);
+
+ poin = BLO_read_get_new_data_address(reader, poin);
+
+ if (poin) {
+ ed->seqbasep = (ListBase *)POINTER_OFFSET(poin, offset);
+ }
+ else {
+ ed->seqbasep = &ed->seqbase;
+ }
+ }
+ /* stack */
+ BLO_read_list(reader, &(ed->metastack));
+
+ LISTBASE_FOREACH (MetaStack *, ms, &ed->metastack) {
+ BLO_read_data_address(reader, &ms->parseq);
+
+ if (ms->oldbasep == old_seqbasep) {
+ ms->oldbasep = &ed->seqbase;
+ }
+ else {
+ poin = POINTER_OFFSET(ms->oldbasep, -offset);
+ poin = BLO_read_get_new_data_address(reader, poin);
+ if (poin) {
+ ms->oldbasep = (ListBase *)POINTER_OFFSET(poin, offset);
+ }
+ else {
+ ms->oldbasep = &ed->seqbase;
+ }
+ }
+ }
+ }
+ }
+
+#ifdef DURIAN_CAMERA_SWITCH
+ /* Runtime */
+ sce->r.mode &= ~R_NO_CAMERA_SWITCH;
+#endif
+
+ BLO_read_data_address(reader, &sce->r.avicodecdata);
+ if (sce->r.avicodecdata) {
+ BLO_read_data_address(reader, &sce->r.avicodecdata->lpFormat);
+ BLO_read_data_address(reader, &sce->r.avicodecdata->lpParms);
+ }
+ if (sce->r.ffcodecdata.properties) {
+ BLO_read_data_address(reader, &sce->r.ffcodecdata.properties);
+ IDP_BlendDataRead(reader, &sce->r.ffcodecdata.properties);
+ }
+
+ BLO_read_list(reader, &(sce->markers));
+ LISTBASE_FOREACH (TimeMarker *, marker, &sce->markers) {
+ BLO_read_data_address(reader, &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));
+
+ LISTBASE_FOREACH (SceneRenderLayer *, srl, &sce->r.layers) {
+ BLO_read_data_address(reader, &srl->prop);
+ IDP_BlendDataRead(reader, &srl->prop);
+ BLO_read_list(reader, &(srl->freestyleConfig.modules));
+ BLO_read_list(reader, &(srl->freestyleConfig.linesets));
+ }
+
+ BKE_color_managed_view_settings_blend_read_data(reader, &sce->view_settings);
+
+ BLO_read_data_address(reader, &sce->rigidbody_world);
+ RigidBodyWorld *rbw = sce->rigidbody_world;
+ if (rbw) {
+ BLO_read_data_address(reader, &rbw->shared);
+
+ if (rbw->shared == NULL) {
+ /* Link deprecated caches if they exist, so we can use them for versioning.
+ * We should only do this when rbw->shared == NULL, because those pointers
+ * are always set (for compatibility with older Blenders). We mustn't link
+ * the same pointcache twice. */
+ BKE_ptcache_blend_read_data(reader, &rbw->ptcaches, &rbw->pointcache, false);
+
+ /* make sure simulation starts from the beginning after loading file */
+ if (rbw->pointcache) {
+ rbw->ltime = (float)rbw->pointcache->startframe;
+ }
+ }
+ else {
+ /* must nullify the reference to physics sim object, since it no-longer exist
+ * (and will need to be recalculated)
+ */
+ rbw->shared->physics_world = NULL;
+
+ /* link caches */
+ BKE_ptcache_blend_read_data(reader, &rbw->shared->ptcaches, &rbw->shared->pointcache, false);
+
+ /* make sure simulation starts from the beginning after loading file */
+ if (rbw->shared->pointcache) {
+ rbw->ltime = (float)rbw->shared->pointcache->startframe;
+ }
+ }
+ rbw->objects = NULL;
+ rbw->numbodies = 0;
+
+ /* set effector weights */
+ BLO_read_data_address(reader, &rbw->effector_weights);
+ if (!rbw->effector_weights) {
+ rbw->effector_weights = BKE_effector_add_weights(NULL);
+ }
+ }
+
+ BLO_read_data_address(reader, &sce->preview);
+ BKE_previewimg_blend_read(reader, sce->preview);
+
+ BKE_curvemapping_blend_read(reader, &sce->r.mblur_shutter_curve);
+
+#ifdef USE_COLLECTION_COMPAT_28
+ /* this runs before the very first doversion */
+ if (sce->collection) {
+ BLO_read_data_address(reader, &sce->collection);
+ BKE_collection_compat_blend_read_data(reader, sce->collection);
+ }
+#endif
+
+ /* insert into global old-new map for reading without UI (link_global accesses it again) */
+ BLO_read_glob_list(reader, &sce->view_layers);
+ LISTBASE_FOREACH (ViewLayer *, view_layer, &sce->view_layers) {
+ BKE_view_layer_blend_read_data(reader, view_layer);
+ }
+
+ if (BLO_read_data_is_undo(reader)) {
+ /* If it's undo do nothing here, caches are handled by higher-level generic calling code. */
+ }
+ else {
+ /* else try to read the cache from file. */
+ BLO_read_data_address(reader, &sce->eevee.light_cache_data);
+ if (sce->eevee.light_cache_data) {
+ EEVEE_lightcache_blend_read_data(reader, sce->eevee.light_cache_data);
+ }
+ }
+ EEVEE_lightcache_info_update(&sce->eevee);
+
+ BKE_screen_view3d_shading_blend_read_data(reader, &sce->display.shading);
+
+ BLO_read_data_address(reader, &sce->layer_properties);
+ IDP_BlendDataRead(reader, &sce->layer_properties);
+}
+
+/* patch for missing scene IDs, can't be in do-versions */
+static void composite_patch(bNodeTree *ntree, Scene *scene)
+{
+
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
+ if (node->id == NULL && node->type == CMP_NODE_R_LAYERS) {
+ node->id = &scene->id;
+ }
+ }
+}
+
+static void scene_blend_read_lib(BlendLibReader *reader, ID *id)
+{
+ Scene *sce = (Scene *)id;
+
+ BKE_keyingsets_blend_read_lib(reader, &sce->id, &sce->keyingsets);
+
+ BLO_read_id_address(reader, sce->id.lib, &sce->camera);
+ BLO_read_id_address(reader, sce->id.lib, &sce->world);
+ BLO_read_id_address(reader, sce->id.lib, &sce->set);
+ BLO_read_id_address(reader, sce->id.lib, &sce->gpd);
+
+ BKE_paint_blend_read_lib(reader, sce, &sce->toolsettings->imapaint.paint);
+ if (sce->toolsettings->sculpt) {
+ BKE_paint_blend_read_lib(reader, sce, &sce->toolsettings->sculpt->paint);
+ }
+ if (sce->toolsettings->vpaint) {
+ BKE_paint_blend_read_lib(reader, sce, &sce->toolsettings->vpaint->paint);
+ }
+ if (sce->toolsettings->wpaint) {
+ BKE_paint_blend_read_lib(reader, sce, &sce->toolsettings->wpaint->paint);
+ }
+ if (sce->toolsettings->uvsculpt) {
+ BKE_paint_blend_read_lib(reader, sce, &sce->toolsettings->uvsculpt->paint);
+ }
+ if (sce->toolsettings->gp_paint) {
+ BKE_paint_blend_read_lib(reader, sce, &sce->toolsettings->gp_paint->paint);
+ }
+ if (sce->toolsettings->gp_vertexpaint) {
+ BKE_paint_blend_read_lib(reader, sce, &sce->toolsettings->gp_vertexpaint->paint);
+ }
+ if (sce->toolsettings->gp_sculptpaint) {
+ BKE_paint_blend_read_lib(reader, sce, &sce->toolsettings->gp_sculptpaint->paint);
+ }
+ if (sce->toolsettings->gp_weightpaint) {
+ BKE_paint_blend_read_lib(reader, sce, &sce->toolsettings->gp_weightpaint->paint);
+ }
+
+ if (sce->toolsettings->sculpt) {
+ BLO_read_id_address(reader, sce->id.lib, &sce->toolsettings->sculpt->gravity_object);
+ }
+
+ if (sce->toolsettings->imapaint.stencil) {
+ BLO_read_id_address(reader, sce->id.lib, &sce->toolsettings->imapaint.stencil);
+ }
+
+ if (sce->toolsettings->imapaint.clone) {
+ BLO_read_id_address(reader, sce->id.lib, &sce->toolsettings->imapaint.clone);
+ }
+
+ if (sce->toolsettings->imapaint.canvas) {
+ BLO_read_id_address(reader, sce->id.lib, &sce->toolsettings->imapaint.canvas);
+ }
+
+ BLO_read_id_address(reader, sce->id.lib, &sce->toolsettings->particle.shape_object);
+
+ BLO_read_id_address(reader, sce->id.lib, &sce->toolsettings->gp_sculpt.guide.reference_object);
+
+ LISTBASE_FOREACH_MUTABLE (Base *, base_legacy, &sce->base) {
+ BLO_read_id_address(reader, sce->id.lib, &base_legacy->object);
+
+ if (base_legacy->object == NULL) {
+ BLO_reportf_wrap(BLO_read_lib_reports(reader),
+ RPT_WARNING,
+ TIP_("LIB: object lost from scene: '%s'"),
+ sce->id.name + 2);
+ BLI_remlink(&sce->base, base_legacy);
+ if (base_legacy == sce->basact) {
+ sce->basact = NULL;
+ }
+ MEM_freeN(base_legacy);
+ }
+ }
+
+ Sequence *seq;
+ SEQ_ALL_BEGIN (sce->ed, seq) {
+ IDP_BlendReadLib(reader, seq->prop);
+
+ if (seq->ipo) {
+ BLO_read_id_address(
+ reader, sce->id.lib, &seq->ipo); /* XXX deprecated - old animation system */
+ }
+ seq->scene_sound = NULL;
+ if (seq->scene) {
+ BLO_read_id_address(reader, sce->id.lib, &seq->scene);
+ seq->scene_sound = NULL;
+ }
+ if (seq->clip) {
+ BLO_read_id_address(reader, sce->id.lib, &seq->clip);
+ }
+ if (seq->mask) {
+ BLO_read_id_address(reader, sce->id.lib, &seq->mask);
+ }
+ if (seq->scene_camera) {
+ BLO_read_id_address(reader, sce->id.lib, &seq->scene_camera);
+ }
+ if (seq->sound) {
+ seq->scene_sound = NULL;
+ if (seq->type == SEQ_TYPE_SOUND_HD) {
+ seq->type = SEQ_TYPE_SOUND_RAM;
+ }
+ else {
+ BLO_read_id_address(reader, sce->id.lib, &seq->sound);
+ }
+ if (seq->sound) {
+ id_us_plus_no_lib((ID *)seq->sound);
+ seq->scene_sound = NULL;
+ }
+ }
+ if (seq->type == SEQ_TYPE_TEXT) {
+ TextVars *t = seq->effectdata;
+ BLO_read_id_address(reader, sce->id.lib, &t->text_font);
+ }
+ BLI_listbase_clear(&seq->anims);
+
+ BKE_sequence_modifier_blend_read_lib(reader, sce, &seq->modifiers);
+ }
+ SEQ_ALL_END;
+
+ LISTBASE_FOREACH (TimeMarker *, marker, &sce->markers) {
+ IDP_BlendReadLib(reader, marker->prop);
+
+ if (marker->camera) {
+ BLO_read_id_address(reader, sce->id.lib, &marker->camera);
+ }
+ }
+
+ /* rigidbody world relies on its linked collections */
+ if (sce->rigidbody_world) {
+ RigidBodyWorld *rbw = sce->rigidbody_world;
+ if (rbw->group) {
+ BLO_read_id_address(reader, sce->id.lib, &rbw->group);
+ }
+ if (rbw->constraints) {
+ BLO_read_id_address(reader, sce->id.lib, &rbw->constraints);
+ }
+ if (rbw->effector_weights) {
+ BLO_read_id_address(reader, sce->id.lib, &rbw->effector_weights->group);
+ }
+ }
+
+ if (sce->nodetree) {
+ composite_patch(sce->nodetree, sce);
+ }
+
+ LISTBASE_FOREACH (SceneRenderLayer *, srl, &sce->r.layers) {
+ BLO_read_id_address(reader, sce->id.lib, &srl->mat_override);
+ LISTBASE_FOREACH (FreestyleModuleConfig *, fmc, &srl->freestyleConfig.modules) {
+ BLO_read_id_address(reader, sce->id.lib, &fmc->script);
+ }
+ LISTBASE_FOREACH (FreestyleLineSet *, fls, &srl->freestyleConfig.linesets) {
+ BLO_read_id_address(reader, sce->id.lib, &fls->linestyle);
+ BLO_read_id_address(reader, sce->id.lib, &fls->group);
+ }
+ }
+ /* Motion Tracking */
+ BLO_read_id_address(reader, sce->id.lib, &sce->clip);
+
+#ifdef USE_COLLECTION_COMPAT_28
+ if (sce->collection) {
+ BKE_collection_compat_blend_read_lib(reader, sce->id.lib, sce->collection);
+ }
+#endif
+
+ LISTBASE_FOREACH (ViewLayer *, view_layer, &sce->view_layers) {
+ BKE_view_layer_blend_read_lib(reader, sce->id.lib, view_layer);
+ }
+
+ if (sce->r.bake.cage_object) {
+ BLO_read_id_address(reader, sce->id.lib, &sce->r.bake.cage_object);
+ }
+
+#ifdef USE_SETSCENE_CHECK
+ if (sce->set != NULL) {
+ sce->flag |= SCE_READFILE_LIBLINK_NEED_SETSCENE_CHECK;
+ }
+#endif
+}
+
+static void scene_blend_read_expand(BlendExpander *expander, ID *id)
+{
+ Scene *sce = (Scene *)id;
+
+ LISTBASE_FOREACH (Base *, base_legacy, &sce->base) {
+ BLO_expand(expander, base_legacy->object);
+ }
+ BLO_expand(expander, sce->camera);
+ BLO_expand(expander, sce->world);
+
+ BKE_keyingsets_blend_read_expand(expander, &sce->keyingsets);
+
+ if (sce->set) {
+ BLO_expand(expander, sce->set);
+ }
+
+ LISTBASE_FOREACH (SceneRenderLayer *, srl, &sce->r.layers) {
+ BLO_expand(expander, srl->mat_override);
+ LISTBASE_FOREACH (FreestyleModuleConfig *, module, &srl->freestyleConfig.modules) {
+ if (module->script) {
+ BLO_expand(expander, module->script);
+ }
+ }
+ LISTBASE_FOREACH (FreestyleLineSet *, lineset, &srl->freestyleConfig.linesets) {
+ if (lineset->group) {
+ BLO_expand(expander, lineset->group);
+ }
+ BLO_expand(expander, lineset->linestyle);
+ }
+ }
+
+ LISTBASE_FOREACH (ViewLayer *, view_layer, &sce->view_layers) {
+ IDP_BlendReadExpand(expander, view_layer->id_properties);
+
+ LISTBASE_FOREACH (FreestyleModuleConfig *, module, &view_layer->freestyle_config.modules) {
+ if (module->script) {
+ BLO_expand(expander, module->script);
+ }
+ }
+
+ LISTBASE_FOREACH (FreestyleLineSet *, lineset, &view_layer->freestyle_config.linesets) {
+ if (lineset->group) {
+ BLO_expand(expander, lineset->group);
+ }
+ BLO_expand(expander, lineset->linestyle);
+ }
+ }
+
+ if (sce->gpd) {
+ BLO_expand(expander, sce->gpd);
+ }
+
+ if (sce->ed) {
+ Sequence *seq;
+
+ SEQ_ALL_BEGIN (sce->ed, seq) {
+ IDP_BlendReadExpand(expander, seq->prop);
+
+ if (seq->scene) {
+ BLO_expand(expander, seq->scene);
+ }
+ if (seq->scene_camera) {
+ BLO_expand(expander, seq->scene_camera);
+ }
+ if (seq->clip) {
+ BLO_expand(expander, seq->clip);
+ }
+ if (seq->mask) {
+ BLO_expand(expander, seq->mask);
+ }
+ if (seq->sound) {
+ BLO_expand(expander, seq->sound);
+ }
+
+ if (seq->type == SEQ_TYPE_TEXT && seq->effectdata) {
+ TextVars *data = seq->effectdata;
+ BLO_expand(expander, data->text_font);
+ }
+ }
+ SEQ_ALL_END;
+ }
+
+ if (sce->rigidbody_world) {
+ BLO_expand(expander, sce->rigidbody_world->group);
+ BLO_expand(expander, sce->rigidbody_world->constraints);
+ }
+
+ LISTBASE_FOREACH (TimeMarker *, marker, &sce->markers) {
+ IDP_BlendReadExpand(expander, marker->prop);
+
+ if (marker->camera) {
+ BLO_expand(expander, marker->camera);
+ }
+ }
+
+ BLO_expand(expander, sce->clip);
+
+#ifdef USE_COLLECTION_COMPAT_28
+ if (sce->collection) {
+ BKE_collection_compat_blend_read_expand(expander, sce->collection);
+ }
+#endif
+
+ if (sce->r.bake.cage_object) {
+ BLO_expand(expander, sce->r.bake.cage_object);
+ }
+}
+
+static void scene_undo_preserve(BlendLibReader *reader, ID *id_new, ID *id_old)
+{
+ Scene *scene_new = (Scene *)id_new;
+ Scene *scene_old = (Scene *)id_old;
+
+ SWAP(View3DCursor, scene_old->cursor, scene_new->cursor);
+ if (scene_new->toolsettings != NULL && scene_old->toolsettings != NULL) {
+ /* First try to restore ID pointers that can be and should be preserved (like brushes or
+ * palettes), and counteract the swap of the whole ToolSettings structs below for the others
+ * (like object ones). */
+ scene_foreach_toolsettings(
+ NULL, scene_new->toolsettings, true, reader, scene_old->toolsettings);
+ SWAP(ToolSettings, *scene_old->toolsettings, *scene_new->toolsettings);
+ }
+}
+
IDTypeInfo IDType_ID_SCE = {
.id_code = ID_SCE,
.id_filter = FILTER_ID_SCE,
@@ -638,10 +1692,12 @@ IDTypeInfo IDType_ID_SCE = {
.foreach_id = scene_foreach_id,
.foreach_cache = scene_foreach_cache,
- .blend_write = NULL,
- .blend_read_data = NULL,
- .blend_read_lib = NULL,
- .blend_read_expand = NULL,
+ .blend_write = scene_blend_write,
+ .blend_read_data = scene_blend_read_data,
+ .blend_read_lib = scene_blend_read_lib,
+ .blend_read_expand = scene_blend_read_expand,
+
+ .blend_read_undo_preserve = scene_undo_preserve,
};
const char *RE_engine_id_BLENDER_EEVEE = "BLENDER_EEVEE";
@@ -1971,7 +3027,7 @@ bool BKE_scene_multiview_is_render_view_active(const RenderData *rd, const Scene
}
/* SCE_VIEWS_SETUP_BASIC */
- if (STREQ(srv->name, STEREO_LEFT_NAME) || STREQ(srv->name, STEREO_RIGHT_NAME)) {
+ if (STR_ELEM(srv->name, STEREO_LEFT_NAME, STEREO_RIGHT_NAME)) {
return true;
}
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index d9686eba29a..568c0c6f567 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -21,6 +21,9 @@
* \ingroup bke
*/
+/* Allow using deprecated functionality for .blend file I/O. */
+#define DNA_DEPRECATED_ALLOW
+
#ifdef WIN32
# include "BLI_winstuff.h"
#endif
@@ -49,14 +52,18 @@
#include "BLT_translation.h"
+#include "BKE_gpencil.h"
#include "BKE_icons.h"
#include "BKE_idprop.h"
#include "BKE_idtype.h"
+#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
#include "BKE_node.h"
#include "BKE_screen.h"
#include "BKE_workspace.h"
+#include "BLO_read_write.h"
+
static void screen_free_data(ID *id)
{
bScreen *screen = (bScreen *)id;
@@ -230,6 +237,60 @@ static void screen_foreach_id(ID *id, LibraryForeachIDData *data)
}
}
+static void screen_blend_write(BlendWriter *writer, ID *id, const void *id_address)
+{
+ bScreen *screen = (bScreen *)id;
+ /* Screens are reference counted, only saved if used by a workspace. */
+ if (screen->id.us > 0 || BLO_write_is_undo(writer)) {
+ /* write LibData */
+ /* in 2.50+ files, the file identifier for screens is patched, forward compatibility */
+ BLO_write_struct_at_address_with_filecode(writer, ID_SCRN, bScreen, id_address, screen);
+ BKE_id_blend_write(writer, &screen->id);
+
+ BKE_previewimg_blend_write(writer, screen->preview);
+
+ /* direct data */
+ BKE_screen_area_map_blend_write(writer, AREAMAP_FROM_SCREEN(screen));
+ }
+}
+
+/* Cannot use IDTypeInfo callback yet, because of the return value. */
+bool BKE_screen_blend_read_data(BlendDataReader *reader, bScreen *screen)
+{
+ bool success = true;
+
+ screen->regionbase.first = screen->regionbase.last = NULL;
+ screen->context = NULL;
+ screen->active_region = NULL;
+
+ BLO_read_data_address(reader, &screen->preview);
+ BKE_previewimg_blend_read(reader, screen->preview);
+
+ if (!BKE_screen_area_map_blend_read_data(reader, AREAMAP_FROM_SCREEN(screen))) {
+ printf("Error reading Screen %s... removing it.\n", screen->id.name + 2);
+ success = false;
+ }
+
+ return success;
+}
+
+/* note: file read without screens option G_FILE_NO_UI;
+ * check lib pointers in call below */
+static void screen_blend_read_lib(BlendLibReader *reader, ID *id)
+{
+ bScreen *screen = (bScreen *)id;
+ /* deprecated, but needed for versioning (will be NULL'ed then) */
+ BLO_read_id_address(reader, screen->id.lib, &screen->scene);
+
+ screen->animtimer = NULL; /* saved in rare cases */
+ screen->tool_tip = NULL;
+ screen->scrubbing = false;
+
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ BKE_screen_area_blend_read_lib(reader, &screen->id, area);
+ }
+}
+
IDTypeInfo IDType_ID_SCR = {
.id_code = ID_SCR,
.id_filter = 0,
@@ -247,10 +308,13 @@ IDTypeInfo IDType_ID_SCR = {
.foreach_id = screen_foreach_id,
.foreach_cache = NULL,
- .blend_write = NULL,
+ .blend_write = screen_blend_write,
+ /* Cannot be used yet, because #direct_link_screen has a return value. */
.blend_read_data = NULL,
- .blend_read_lib = NULL,
+ .blend_read_lib = screen_blend_read_lib,
.blend_read_expand = NULL,
+
+ .blend_read_undo_preserve = NULL,
};
/* ************ Spacetype/regiontype handling ************** */
@@ -312,7 +376,7 @@ SpaceType *BKE_spacetype_from_id(int spaceid)
return NULL;
}
-ARegionType *BKE_regiontype_from_id_or_first(SpaceType *st, int regionid)
+ARegionType *BKE_regiontype_from_id_or_first(const SpaceType *st, int regionid)
{
ARegionType *art;
@@ -327,7 +391,7 @@ ARegionType *BKE_regiontype_from_id_or_first(SpaceType *st, int regionid)
return st->regiontypes.first;
}
-ARegionType *BKE_regiontype_from_id(SpaceType *st, int regionid)
+ARegionType *BKE_regiontype_from_id(const SpaceType *st, int regionid)
{
ARegionType *art;
@@ -404,7 +468,7 @@ static void panel_list_copy(ListBase *newlb, const ListBase *lb)
}
}
-ARegion *BKE_area_region_copy(SpaceType *st, ARegion *region)
+ARegion *BKE_area_region_copy(const SpaceType *st, const ARegion *region)
{
ARegion *newar = MEM_dupallocN(region);
@@ -918,7 +982,7 @@ ARegion *BKE_area_find_region_xy(ScrArea *area, const int regiontype, int x, int
if (area) {
ARegion *region;
for (region = area->regionbase.first; region; region = region->next) {
- if ((regiontype == RGN_TYPE_ANY) || (region->regiontype == regiontype)) {
+ if (ELEM(regiontype, RGN_TYPE_ANY, region->regiontype)) {
if (BLI_rcti_isect_pt(&region->winrct, x, y)) {
region_found = region;
break;
@@ -936,7 +1000,7 @@ ARegion *BKE_screen_find_region_xy(bScreen *screen, const int regiontype, int x,
{
ARegion *region_found = NULL;
LISTBASE_FOREACH (ARegion *, region, &screen->regionbase) {
- if ((regiontype == RGN_TYPE_ANY) || (region->regiontype == regiontype)) {
+ if (ELEM(regiontype, RGN_TYPE_ANY, region->regiontype)) {
if (BLI_rcti_isect_pt(&region->winrct, x, y)) {
region_found = region;
break;
@@ -973,7 +1037,7 @@ ScrArea *BKE_screen_find_big_area(bScreen *screen, const int spacetype, const sh
int size, maxsize = 0;
for (area = screen->areabase.first; area; area = area->next) {
- if ((spacetype == SPACE_TYPE_ANY) || (area->spacetype == spacetype)) {
+ if (ELEM(spacetype, SPACE_TYPE_ANY, area->spacetype)) {
if (min <= area->winx && min <= area->winy) {
size = area->winx * area->winy;
if (size > maxsize) {
@@ -994,7 +1058,7 @@ ScrArea *BKE_screen_area_map_find_area_xy(const ScrAreaMap *areamap,
{
LISTBASE_FOREACH (ScrArea *, area, &areamap->areabase) {
if (BLI_rcti_isect_pt(&area->totrct, x, y)) {
- if ((spacetype == SPACE_TYPE_ANY) || (area->spacetype == spacetype)) {
+ if (ELEM(spacetype, SPACE_TYPE_ANY, area->spacetype)) {
return area;
}
break;
@@ -1111,3 +1175,797 @@ void BKE_screen_header_alignment_reset(bScreen *screen)
}
screen->do_refresh = true;
}
+
+void BKE_screen_view3d_shading_blend_write(BlendWriter *writer, View3DShading *shading)
+{
+ if (shading->prop) {
+ IDP_BlendWrite(writer, shading->prop);
+ }
+}
+
+void BKE_screen_view3d_shading_blend_read_data(BlendDataReader *reader, View3DShading *shading)
+{
+ if (shading->prop) {
+ BLO_read_data_address(reader, &shading->prop);
+ IDP_BlendDataRead(reader, &shading->prop);
+ }
+}
+
+static void write_region(BlendWriter *writer, ARegion *region, int spacetype)
+{
+ BLO_write_struct(writer, ARegion, region);
+
+ if (region->regiondata) {
+ if (region->flag & RGN_FLAG_TEMP_REGIONDATA) {
+ return;
+ }
+
+ switch (spacetype) {
+ case SPACE_VIEW3D:
+ if (region->regiontype == RGN_TYPE_WINDOW) {
+ RegionView3D *rv3d = region->regiondata;
+ BLO_write_struct(writer, RegionView3D, rv3d);
+
+ if (rv3d->localvd) {
+ BLO_write_struct(writer, RegionView3D, rv3d->localvd);
+ }
+ if (rv3d->clipbb) {
+ BLO_write_struct(writer, BoundBox, rv3d->clipbb);
+ }
+ }
+ else {
+ printf("regiondata write missing!\n");
+ }
+ break;
+ default:
+ printf("regiondata write missing!\n");
+ }
+ }
+}
+
+static void write_uilist(BlendWriter *writer, uiList *ui_list)
+{
+ BLO_write_struct(writer, uiList, ui_list);
+
+ if (ui_list->properties) {
+ IDP_BlendWrite(writer, ui_list->properties);
+ }
+}
+
+static void write_space_outliner(BlendWriter *writer, SpaceOutliner *space_outliner)
+{
+ BLI_mempool *ts = space_outliner->treestore;
+
+ if (ts) {
+ SpaceOutliner space_outliner_flat = *space_outliner;
+
+ int elems = BLI_mempool_len(ts);
+ /* linearize mempool to array */
+ TreeStoreElem *data = elems ? BLI_mempool_as_arrayN(ts, "TreeStoreElem") : NULL;
+
+ if (data) {
+ /* In this block we use the memory location of the treestore
+ * but _not_ its data, the addresses in this case are UUID's,
+ * since we can't rely on malloc giving us different values each time.
+ */
+ TreeStore ts_flat = {0};
+
+ /* we know the treestore is at least as big as a pointer,
+ * so offsetting works to give us a UUID. */
+ void *data_addr = (void *)POINTER_OFFSET(ts, sizeof(void *));
+
+ ts_flat.usedelem = elems;
+ ts_flat.totelem = elems;
+ ts_flat.data = data_addr;
+
+ BLO_write_struct(writer, SpaceOutliner, space_outliner);
+
+ BLO_write_struct_at_address(writer, TreeStore, ts, &ts_flat);
+ BLO_write_struct_array_at_address(writer, TreeStoreElem, elems, data_addr, data);
+
+ MEM_freeN(data);
+ }
+ else {
+ space_outliner_flat.treestore = NULL;
+ BLO_write_struct_at_address(writer, SpaceOutliner, space_outliner, &space_outliner_flat);
+ }
+ }
+ else {
+ BLO_write_struct(writer, SpaceOutliner, space_outliner);
+ }
+}
+
+static void write_panel_list(BlendWriter *writer, ListBase *lb)
+{
+ LISTBASE_FOREACH (Panel *, panel, lb) {
+ BLO_write_struct(writer, Panel, panel);
+ write_panel_list(writer, &panel->children);
+ }
+}
+
+static void write_area_regions(BlendWriter *writer, ScrArea *area)
+{
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
+ write_region(writer, region, area->spacetype);
+ write_panel_list(writer, &region->panels);
+
+ LISTBASE_FOREACH (PanelCategoryStack *, pc_act, &region->panels_category_active) {
+ BLO_write_struct(writer, PanelCategoryStack, pc_act);
+ }
+
+ LISTBASE_FOREACH (uiList *, ui_list, &region->ui_lists) {
+ write_uilist(writer, ui_list);
+ }
+
+ LISTBASE_FOREACH (uiPreview *, ui_preview, &region->ui_previews) {
+ BLO_write_struct(writer, uiPreview, ui_preview);
+ }
+ }
+
+ LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
+ LISTBASE_FOREACH (ARegion *, region, &sl->regionbase) {
+ write_region(writer, region, sl->spacetype);
+ }
+
+ if (sl->spacetype == SPACE_VIEW3D) {
+ View3D *v3d = (View3D *)sl;
+ BLO_write_struct(writer, View3D, v3d);
+
+ if (v3d->localvd) {
+ BLO_write_struct(writer, View3D, v3d->localvd);
+ }
+
+ BKE_screen_view3d_shading_blend_write(writer, &v3d->shading);
+ }
+ else if (sl->spacetype == SPACE_GRAPH) {
+ SpaceGraph *sipo = (SpaceGraph *)sl;
+ ListBase tmpGhosts = sipo->runtime.ghost_curves;
+
+ /* temporarily disable ghost curves when saving */
+ BLI_listbase_clear(&sipo->runtime.ghost_curves);
+
+ BLO_write_struct(writer, SpaceGraph, sl);
+ if (sipo->ads) {
+ BLO_write_struct(writer, bDopeSheet, sipo->ads);
+ }
+
+ /* reenable ghost curves */
+ sipo->runtime.ghost_curves = tmpGhosts;
+ }
+ else if (sl->spacetype == SPACE_PROPERTIES) {
+ BLO_write_struct(writer, SpaceProperties, sl);
+ }
+ else if (sl->spacetype == SPACE_FILE) {
+ SpaceFile *sfile = (SpaceFile *)sl;
+
+ BLO_write_struct(writer, SpaceFile, sl);
+ if (sfile->params) {
+ BLO_write_struct(writer, FileSelectParams, sfile->params);
+ }
+ }
+ else if (sl->spacetype == SPACE_SEQ) {
+ BLO_write_struct(writer, SpaceSeq, sl);
+ }
+ else if (sl->spacetype == SPACE_OUTLINER) {
+ SpaceOutliner *space_outliner = (SpaceOutliner *)sl;
+ write_space_outliner(writer, space_outliner);
+ }
+ else if (sl->spacetype == SPACE_IMAGE) {
+ BLO_write_struct(writer, SpaceImage, sl);
+ }
+ else if (sl->spacetype == SPACE_TEXT) {
+ BLO_write_struct(writer, SpaceText, sl);
+ }
+ else if (sl->spacetype == SPACE_SCRIPT) {
+ SpaceScript *scr = (SpaceScript *)sl;
+ scr->but_refs = NULL;
+ BLO_write_struct(writer, SpaceScript, sl);
+ }
+ else if (sl->spacetype == SPACE_ACTION) {
+ BLO_write_struct(writer, SpaceAction, sl);
+ }
+ else if (sl->spacetype == SPACE_NLA) {
+ SpaceNla *snla = (SpaceNla *)sl;
+
+ BLO_write_struct(writer, SpaceNla, snla);
+ if (snla->ads) {
+ BLO_write_struct(writer, bDopeSheet, snla->ads);
+ }
+ }
+ else if (sl->spacetype == SPACE_NODE) {
+ SpaceNode *snode = (SpaceNode *)sl;
+ BLO_write_struct(writer, SpaceNode, snode);
+
+ LISTBASE_FOREACH (bNodeTreePath *, path, &snode->treepath) {
+ BLO_write_struct(writer, bNodeTreePath, path);
+ }
+ }
+ else if (sl->spacetype == SPACE_CONSOLE) {
+ SpaceConsole *con = (SpaceConsole *)sl;
+
+ LISTBASE_FOREACH (ConsoleLine *, cl, &con->history) {
+ /* 'len_alloc' is invalid on write, set from 'len' on read */
+ BLO_write_struct(writer, ConsoleLine, cl);
+ BLO_write_raw(writer, (size_t)cl->len + 1, cl->line);
+ }
+ BLO_write_struct(writer, SpaceConsole, sl);
+ }
+ else if (sl->spacetype == SPACE_TOPBAR) {
+ BLO_write_struct(writer, SpaceTopBar, sl);
+ }
+ else if (sl->spacetype == SPACE_STATUSBAR) {
+ BLO_write_struct(writer, SpaceStatusBar, sl);
+ }
+ else if (sl->spacetype == SPACE_USERPREF) {
+ BLO_write_struct(writer, SpaceUserPref, sl);
+ }
+ else if (sl->spacetype == SPACE_CLIP) {
+ BLO_write_struct(writer, SpaceClip, sl);
+ }
+ else if (sl->spacetype == SPACE_INFO) {
+ BLO_write_struct(writer, SpaceInfo, sl);
+ }
+ }
+}
+
+void BKE_screen_area_map_blend_write(BlendWriter *writer, ScrAreaMap *area_map)
+{
+ BLO_write_struct_list(writer, ScrVert, &area_map->vertbase);
+ BLO_write_struct_list(writer, ScrEdge, &area_map->edgebase);
+ LISTBASE_FOREACH (ScrArea *, area, &area_map->areabase) {
+ area->butspacetype = area->spacetype; /* Just for compatibility, will be reset below. */
+
+ BLO_write_struct(writer, ScrArea, area);
+
+ BLO_write_struct(writer, ScrGlobalAreaData, area->global);
+
+ write_area_regions(writer, area);
+
+ area->butspacetype = SPACE_EMPTY; /* Unset again, was changed above. */
+ }
+}
+
+static void direct_link_panel_list(BlendDataReader *reader, ListBase *lb)
+{
+ BLO_read_list(reader, lb);
+
+ LISTBASE_FOREACH (Panel *, panel, lb) {
+ panel->runtime_flag = 0;
+ panel->activedata = NULL;
+ panel->type = NULL;
+ panel->runtime.custom_data_ptr = NULL;
+ direct_link_panel_list(reader, &panel->children);
+ }
+}
+
+static void direct_link_region(BlendDataReader *reader, ARegion *region, int spacetype)
+{
+ direct_link_panel_list(reader, &region->panels);
+
+ BLO_read_list(reader, &region->panels_category_active);
+
+ BLO_read_list(reader, &region->ui_lists);
+
+ /* The area's search filter is runtime only, so we need to clear the active flag on read. */
+ region->flag &= ~RGN_FLAG_SEARCH_FILTER_ACTIVE;
+
+ LISTBASE_FOREACH (uiList *, ui_list, &region->ui_lists) {
+ ui_list->type = NULL;
+ ui_list->dyn_data = NULL;
+ BLO_read_data_address(reader, &ui_list->properties);
+ IDP_BlendDataRead(reader, &ui_list->properties);
+ }
+
+ BLO_read_list(reader, &region->ui_previews);
+
+ if (spacetype == SPACE_EMPTY) {
+ /* unknown space type, don't leak regiondata */
+ region->regiondata = NULL;
+ }
+ else if (region->flag & RGN_FLAG_TEMP_REGIONDATA) {
+ /* Runtime data, don't use. */
+ region->regiondata = NULL;
+ }
+ else {
+ BLO_read_data_address(reader, &region->regiondata);
+ if (region->regiondata) {
+ if (spacetype == SPACE_VIEW3D) {
+ RegionView3D *rv3d = region->regiondata;
+
+ BLO_read_data_address(reader, &rv3d->localvd);
+ BLO_read_data_address(reader, &rv3d->clipbb);
+
+ rv3d->depths = NULL;
+ rv3d->render_engine = NULL;
+ rv3d->sms = NULL;
+ rv3d->smooth_timer = NULL;
+
+ rv3d->rflag &= ~(RV3D_NAVIGATING | RV3D_PAINTING);
+ rv3d->runtime_viewlock = 0;
+ }
+ }
+ }
+
+ region->v2d.sms = NULL;
+ region->v2d.alpha_hor = region->v2d.alpha_vert = 255; /* visible by default */
+ BLI_listbase_clear(&region->panels_category);
+ BLI_listbase_clear(&region->handlers);
+ BLI_listbase_clear(&region->uiblocks);
+ region->headerstr = NULL;
+ region->visible = 0;
+ region->type = NULL;
+ region->do_draw = 0;
+ region->gizmo_map = NULL;
+ region->regiontimer = NULL;
+ region->draw_buffer = NULL;
+ memset(&region->drawrct, 0, sizeof(region->drawrct));
+}
+
+/* for the saved 2.50 files without regiondata */
+/* and as patch for 2.48 and older */
+void BKE_screen_view3d_do_versions_250(View3D *v3d, ListBase *regions)
+{
+ LISTBASE_FOREACH (ARegion *, region, regions) {
+ if (region->regiontype == RGN_TYPE_WINDOW && region->regiondata == NULL) {
+ RegionView3D *rv3d;
+
+ rv3d = region->regiondata = MEM_callocN(sizeof(RegionView3D), "region v3d patch");
+ rv3d->persp = (char)v3d->persp;
+ rv3d->view = (char)v3d->view;
+ rv3d->dist = v3d->dist;
+ copy_v3_v3(rv3d->ofs, v3d->ofs);
+ copy_qt_qt(rv3d->viewquat, v3d->viewquat);
+ }
+ }
+
+ /* this was not initialized correct always */
+ if (v3d->gridsubdiv == 0) {
+ v3d->gridsubdiv = 10;
+ }
+}
+
+static void direct_link_area(BlendDataReader *reader, ScrArea *area)
+{
+ BLO_read_list(reader, &(area->spacedata));
+ BLO_read_list(reader, &(area->regionbase));
+
+ BLI_listbase_clear(&area->handlers);
+ area->type = NULL; /* spacetype callbacks */
+
+ /* Should always be unset so that rna_Area_type_get works correctly. */
+ area->butspacetype = SPACE_EMPTY;
+
+ area->region_active_win = -1;
+
+ area->flag &= ~AREA_FLAG_ACTIVE_TOOL_UPDATE;
+
+ BLO_read_data_address(reader, &area->global);
+
+ /* if we do not have the spacetype registered we cannot
+ * free it, so don't allocate any new memory for such spacetypes. */
+ if (!BKE_spacetype_exists(area->spacetype)) {
+ /* Hint for versioning code to replace deprecated space types. */
+ area->butspacetype = area->spacetype;
+
+ area->spacetype = SPACE_EMPTY;
+ }
+
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
+ direct_link_region(reader, region, area->spacetype);
+ }
+
+ /* accident can happen when read/save new file with older version */
+ /* 2.50: we now always add spacedata for info */
+ if (area->spacedata.first == NULL) {
+ SpaceInfo *sinfo = MEM_callocN(sizeof(SpaceInfo), "spaceinfo");
+ area->spacetype = sinfo->spacetype = SPACE_INFO;
+ BLI_addtail(&area->spacedata, sinfo);
+ }
+ /* add local view3d too */
+ else if (area->spacetype == SPACE_VIEW3D) {
+ BKE_screen_view3d_do_versions_250(area->spacedata.first, &area->regionbase);
+ }
+
+ LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
+ BLO_read_list(reader, &(sl->regionbase));
+
+ /* if we do not have the spacetype registered we cannot
+ * free it, so don't allocate any new memory for such spacetypes. */
+ if (!BKE_spacetype_exists(sl->spacetype)) {
+ sl->spacetype = SPACE_EMPTY;
+ }
+
+ LISTBASE_FOREACH (ARegion *, region, &sl->regionbase) {
+ direct_link_region(reader, region, sl->spacetype);
+ }
+
+ if (sl->spacetype == SPACE_VIEW3D) {
+ View3D *v3d = (View3D *)sl;
+
+ v3d->flag |= V3D_INVALID_BACKBUF;
+
+ if (v3d->gpd) {
+ BLO_read_data_address(reader, &v3d->gpd);
+ BKE_gpencil_blend_read_data(reader, v3d->gpd);
+ }
+ BLO_read_data_address(reader, &v3d->localvd);
+
+ /* Runtime data */
+ v3d->runtime.properties_storage = NULL;
+ v3d->runtime.flag = 0;
+
+ /* render can be quite heavy, set to solid on load */
+ if (v3d->shading.type == OB_RENDER) {
+ v3d->shading.type = OB_SOLID;
+ }
+ v3d->shading.prev_type = OB_SOLID;
+
+ BKE_screen_view3d_shading_blend_read_data(reader, &v3d->shading);
+
+ BKE_screen_view3d_do_versions_250(v3d, &sl->regionbase);
+ }
+ else if (sl->spacetype == SPACE_GRAPH) {
+ SpaceGraph *sipo = (SpaceGraph *)sl;
+
+ BLO_read_data_address(reader, &sipo->ads);
+ BLI_listbase_clear(&sipo->runtime.ghost_curves);
+ }
+ else if (sl->spacetype == SPACE_NLA) {
+ SpaceNla *snla = (SpaceNla *)sl;
+
+ BLO_read_data_address(reader, &snla->ads);
+ }
+ else if (sl->spacetype == SPACE_OUTLINER) {
+ SpaceOutliner *space_outliner = (SpaceOutliner *)sl;
+
+ /* use #BLO_read_get_new_data_address_no_us and do not free old memory avoiding double
+ * frees and use of freed memory. this could happen because of a
+ * bug fixed in revision 58959 where the treestore memory address
+ * was not unique */
+ TreeStore *ts = BLO_read_get_new_data_address_no_us(reader, space_outliner->treestore);
+ space_outliner->treestore = NULL;
+ if (ts) {
+ TreeStoreElem *elems = BLO_read_get_new_data_address_no_us(reader, ts->data);
+
+ space_outliner->treestore = BLI_mempool_create(
+ sizeof(TreeStoreElem), ts->usedelem, 512, BLI_MEMPOOL_ALLOW_ITER);
+ if (ts->usedelem && elems) {
+ for (int i = 0; i < ts->usedelem; i++) {
+ TreeStoreElem *new_elem = BLI_mempool_alloc(space_outliner->treestore);
+ *new_elem = elems[i];
+ }
+ }
+ /* we only saved what was used */
+ space_outliner->storeflag |= SO_TREESTORE_CLEANUP; /* at first draw */
+ }
+ space_outliner->treehash = NULL;
+ space_outliner->tree.first = space_outliner->tree.last = NULL;
+ }
+ else if (sl->spacetype == SPACE_IMAGE) {
+ SpaceImage *sima = (SpaceImage *)sl;
+
+ sima->iuser.scene = NULL;
+ sima->iuser.ok = 1;
+ sima->scopes.waveform_1 = NULL;
+ sima->scopes.waveform_2 = NULL;
+ sima->scopes.waveform_3 = NULL;
+ sima->scopes.vecscope = NULL;
+ sima->scopes.ok = 0;
+
+ /* WARNING: gpencil data is no longer stored directly in sima after 2.5
+ * so sacrifice a few old files for now to avoid crashes with new files!
+ * committed: r28002 */
+#if 0
+ sima->gpd = newdataadr(fd, sima->gpd);
+ if (sima->gpd) {
+ BKE_gpencil_blend_read_data(fd, sima->gpd);
+ }
+#endif
+ }
+ else if (sl->spacetype == SPACE_NODE) {
+ SpaceNode *snode = (SpaceNode *)sl;
+
+ if (snode->gpd) {
+ BLO_read_data_address(reader, &snode->gpd);
+ BKE_gpencil_blend_read_data(reader, snode->gpd);
+ }
+
+ BLO_read_list(reader, &snode->treepath);
+ snode->edittree = NULL;
+ snode->iofsd = NULL;
+ BLI_listbase_clear(&snode->linkdrag);
+ }
+ else if (sl->spacetype == SPACE_TEXT) {
+ SpaceText *st = (SpaceText *)sl;
+ memset(&st->runtime, 0, sizeof(st->runtime));
+ }
+ else if (sl->spacetype == SPACE_SEQ) {
+ SpaceSeq *sseq = (SpaceSeq *)sl;
+
+ /* grease pencil data is not a direct data and can't be linked from direct_link*
+ * functions, it should be linked from lib_link* functions instead
+ *
+ * otherwise it'll lead to lost grease data on open because it'll likely be
+ * read from file after all other users of grease pencil and newdataadr would
+ * simple return NULL here (sergey)
+ */
+#if 0
+ if (sseq->gpd) {
+ sseq->gpd = newdataadr(fd, sseq->gpd);
+ BKE_gpencil_blend_read_data(fd, sseq->gpd);
+ }
+#endif
+ sseq->scopes.reference_ibuf = NULL;
+ sseq->scopes.zebra_ibuf = NULL;
+ sseq->scopes.waveform_ibuf = NULL;
+ sseq->scopes.sep_waveform_ibuf = NULL;
+ sseq->scopes.vector_ibuf = NULL;
+ sseq->scopes.histogram_ibuf = NULL;
+ }
+ else if (sl->spacetype == SPACE_PROPERTIES) {
+ SpaceProperties *sbuts = (SpaceProperties *)sl;
+
+ sbuts->path = NULL;
+ sbuts->texuser = NULL;
+ sbuts->mainbo = sbuts->mainb;
+ sbuts->mainbuser = sbuts->mainb;
+ sbuts->runtime = NULL;
+ }
+ else if (sl->spacetype == SPACE_CONSOLE) {
+ SpaceConsole *sconsole = (SpaceConsole *)sl;
+
+ BLO_read_list(reader, &sconsole->scrollback);
+ BLO_read_list(reader, &sconsole->history);
+
+ /* comma expressions, (e.g. expr1, expr2, expr3) evaluate each expression,
+ * from left to right. the right-most expression sets the result of the comma
+ * expression as a whole*/
+ LISTBASE_FOREACH_MUTABLE (ConsoleLine *, cl, &sconsole->history) {
+ BLO_read_data_address(reader, &cl->line);
+ if (cl->line) {
+ /* the allocted length is not written, so reset here */
+ cl->len_alloc = cl->len + 1;
+ }
+ else {
+ BLI_remlink(&sconsole->history, cl);
+ MEM_freeN(cl);
+ }
+ }
+ }
+ else if (sl->spacetype == SPACE_FILE) {
+ SpaceFile *sfile = (SpaceFile *)sl;
+
+ /* this sort of info is probably irrelevant for reloading...
+ * plus, it isn't saved to files yet!
+ */
+ sfile->folders_prev = sfile->folders_next = NULL;
+ sfile->files = NULL;
+ sfile->layout = NULL;
+ sfile->op = NULL;
+ sfile->previews_timer = NULL;
+ BLO_read_data_address(reader, &sfile->params);
+ }
+ else if (sl->spacetype == SPACE_CLIP) {
+ SpaceClip *sclip = (SpaceClip *)sl;
+
+ sclip->scopes.track_search = NULL;
+ sclip->scopes.track_preview = NULL;
+ sclip->scopes.ok = 0;
+ }
+ }
+
+ 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);
+}
+
+/**
+ * \return false on error.
+ */
+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);
+ 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);
+ BKE_screen_sort_scrvert(&se->v1, &se->v2);
+
+ if (se->v1 == NULL) {
+ BLI_remlink(&area_map->edgebase, se);
+
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void BKE_screen_area_blend_read_lib(BlendLibReader *reader, ID *parent_id, ScrArea *area)
+{
+ BLO_read_id_address(reader, parent_id->lib, &area->full);
+
+ memset(&area->runtime, 0x0, sizeof(area->runtime));
+
+ LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
+ switch (sl->spacetype) {
+ case SPACE_VIEW3D: {
+ View3D *v3d = (View3D *)sl;
+
+ BLO_read_id_address(reader, parent_id->lib, &v3d->camera);
+ BLO_read_id_address(reader, parent_id->lib, &v3d->ob_center);
+
+ if (v3d->localvd) {
+ BLO_read_id_address(reader, parent_id->lib, &v3d->localvd->camera);
+ }
+ break;
+ }
+ case SPACE_GRAPH: {
+ SpaceGraph *sipo = (SpaceGraph *)sl;
+ bDopeSheet *ads = sipo->ads;
+
+ if (ads) {
+ BLO_read_id_address(reader, parent_id->lib, &ads->source);
+ BLO_read_id_address(reader, parent_id->lib, &ads->filter_grp);
+ }
+ break;
+ }
+ case SPACE_PROPERTIES: {
+ SpaceProperties *sbuts = (SpaceProperties *)sl;
+ BLO_read_id_address(reader, parent_id->lib, &sbuts->pinid);
+ if (sbuts->pinid == NULL) {
+ sbuts->flag &= ~SB_PIN_CONTEXT;
+ }
+ break;
+ }
+ case SPACE_FILE:
+ break;
+ case SPACE_ACTION: {
+ SpaceAction *saction = (SpaceAction *)sl;
+ bDopeSheet *ads = &saction->ads;
+
+ if (ads) {
+ BLO_read_id_address(reader, parent_id->lib, &ads->source);
+ BLO_read_id_address(reader, parent_id->lib, &ads->filter_grp);
+ }
+
+ BLO_read_id_address(reader, parent_id->lib, &saction->action);
+ break;
+ }
+ case SPACE_IMAGE: {
+ SpaceImage *sima = (SpaceImage *)sl;
+
+ BLO_read_id_address(reader, parent_id->lib, &sima->image);
+ BLO_read_id_address(reader, parent_id->lib, &sima->mask_info.mask);
+
+ /* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data
+ * so fingers crossed this works fine!
+ */
+ BLO_read_id_address(reader, parent_id->lib, &sima->gpd);
+ break;
+ }
+ case SPACE_SEQ: {
+ SpaceSeq *sseq = (SpaceSeq *)sl;
+
+ /* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data
+ * so fingers crossed this works fine!
+ */
+ BLO_read_id_address(reader, parent_id->lib, &sseq->gpd);
+ break;
+ }
+ case SPACE_NLA: {
+ SpaceNla *snla = (SpaceNla *)sl;
+ bDopeSheet *ads = snla->ads;
+
+ if (ads) {
+ BLO_read_id_address(reader, parent_id->lib, &ads->source);
+ BLO_read_id_address(reader, parent_id->lib, &ads->filter_grp);
+ }
+ break;
+ }
+ case SPACE_TEXT: {
+ SpaceText *st = (SpaceText *)sl;
+
+ BLO_read_id_address(reader, parent_id->lib, &st->text);
+ break;
+ }
+ case SPACE_SCRIPT: {
+ SpaceScript *scpt = (SpaceScript *)sl;
+ /*scpt->script = NULL; - 2.45 set to null, better re-run the script */
+ if (scpt->script) {
+ BLO_read_id_address(reader, parent_id->lib, &scpt->script);
+ if (scpt->script) {
+ SCRIPT_SET_NULL(scpt->script);
+ }
+ }
+ break;
+ }
+ case SPACE_OUTLINER: {
+ SpaceOutliner *space_outliner = (SpaceOutliner *)sl;
+ BLO_read_id_address(reader, NULL, &space_outliner->search_tse.id);
+
+ if (space_outliner->treestore) {
+ TreeStoreElem *tselem;
+ BLI_mempool_iter iter;
+
+ BLI_mempool_iternew(space_outliner->treestore, &iter);
+ while ((tselem = BLI_mempool_iterstep(&iter))) {
+ BLO_read_id_address(reader, NULL, &tselem->id);
+ }
+ if (space_outliner->treehash) {
+ /* rebuild hash table, because it depends on ids too */
+ space_outliner->storeflag |= SO_TREESTORE_REBUILD;
+ }
+ }
+ break;
+ }
+ case SPACE_NODE: {
+ SpaceNode *snode = (SpaceNode *)sl;
+
+ /* node tree can be stored locally in id too, link this first */
+ BLO_read_id_address(reader, parent_id->lib, &snode->id);
+ BLO_read_id_address(reader, parent_id->lib, &snode->from);
+
+ bNodeTree *ntree = snode->id ? ntreeFromID(snode->id) : NULL;
+ if (ntree) {
+ snode->nodetree = ntree;
+ }
+ else {
+ BLO_read_id_address(reader, parent_id->lib, &snode->nodetree);
+ }
+
+ bNodeTreePath *path;
+ for (path = snode->treepath.first; path; path = path->next) {
+ if (path == snode->treepath.first) {
+ /* first nodetree in path is same as snode->nodetree */
+ path->nodetree = snode->nodetree;
+ }
+ else {
+ BLO_read_id_address(reader, parent_id->lib, &path->nodetree);
+ }
+
+ if (!path->nodetree) {
+ break;
+ }
+ }
+
+ /* remaining path entries are invalid, remove */
+ bNodeTreePath *path_next;
+ for (; path; path = path_next) {
+ path_next = path->next;
+
+ BLI_remlink(&snode->treepath, path);
+ MEM_freeN(path);
+ }
+
+ /* edittree is just the last in the path,
+ * set this directly since the path may have been shortened above */
+ if (snode->treepath.last) {
+ path = snode->treepath.last;
+ snode->edittree = path->nodetree;
+ }
+ else {
+ snode->edittree = NULL;
+ }
+ break;
+ }
+ case SPACE_CLIP: {
+ SpaceClip *sclip = (SpaceClip *)sl;
+ BLO_read_id_address(reader, parent_id->lib, &sclip->clip);
+ BLO_read_id_address(reader, parent_id->lib, &sclip->mask_info.mask);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+}
diff --git a/source/blender/blenkernel/intern/shader_fx.c b/source/blender/blenkernel/intern/shader_fx.c
index f2cdf08b415..3727ec866ca 100644
--- a/source/blender/blenkernel/intern/shader_fx.c
+++ b/source/blender/blenkernel/intern/shader_fx.c
@@ -36,6 +36,7 @@
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
#include "DNA_shader_fx_types.h"
#include "BKE_gpencil.h"
@@ -49,6 +50,8 @@
#include "FX_shader_types.h"
+#include "BLO_read_write.h"
+
static ShaderFxTypeInfo *shader_fx_types[NUM_SHADER_FX_TYPES] = {NULL};
/* *************************************************** */
@@ -175,6 +178,11 @@ void BKE_shaderfxType_panel_id(ShaderFxType type, char *r_idname)
strcat(r_idname, fxi->name);
}
+void BKE_shaderfx_panel_expand(ShaderFxData *fx)
+{
+ fx->ui_expand_flag |= UI_PANEL_DATA_EXPAND_ROOT;
+}
+
void BKE_shaderfx_copydata_generic(const ShaderFxData *fx_src, ShaderFxData *fx_dst)
{
const ShaderFxTypeInfo *fxi = BKE_shaderfx_get_info(fx_src->type);
@@ -270,3 +278,45 @@ ShaderFxData *BKE_shaderfx_findby_name(Object *ob, const char *name)
{
return BLI_findstring(&(ob->shader_fx), name, offsetof(ShaderFxData, name));
}
+
+void BKE_shaderfx_blend_write(BlendWriter *writer, ListBase *fxbase)
+{
+ if (fxbase == NULL) {
+ return;
+ }
+
+ LISTBASE_FOREACH (ShaderFxData *, fx, fxbase) {
+ const ShaderFxTypeInfo *fxi = BKE_shaderfx_get_info(fx->type);
+ if (fxi == NULL) {
+ return;
+ }
+
+ BLO_write_struct_by_name(writer, fxi->struct_name, fx);
+ }
+}
+
+void BKE_shaderfx_blend_read_data(BlendDataReader *reader, ListBase *lb)
+{
+ BLO_read_list(reader, lb);
+
+ LISTBASE_FOREACH (ShaderFxData *, fx, lb) {
+ fx->error = NULL;
+
+ /* if shader disappear, or for upward compatibility */
+ if (NULL == BKE_shaderfx_get_info(fx->type)) {
+ fx->type = eShaderFxType_None;
+ }
+ }
+}
+
+void BKE_shaderfx_blend_read_lib(BlendLibReader *reader, Object *ob)
+{
+ BKE_shaderfx_foreach_ID_link(ob, BKE_object_modifiers_lib_link_common, reader);
+
+ /* If linking from a library, clear 'local' library override flag. */
+ if (ob->id.lib != NULL) {
+ LISTBASE_FOREACH (ShaderFxData *, fx, &ob->shader_fx) {
+ fx->flag &= ~eShaderFxFlag_OverrideLibrary_Local;
+ }
+ }
+}
diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c
index 0c9ee61ca19..ae39b200b56 100644
--- a/source/blender/blenkernel/intern/shrinkwrap.c
+++ b/source/blender/blenkernel/intern/shrinkwrap.c
@@ -1548,8 +1548,8 @@ void BKE_shrinkwrap_remesh_target_project(Mesh *src_me, Mesh *target_me, Object
ssmd.shrinkMode = MOD_SHRINKWRAP_ON_SURFACE;
ssmd.shrinkOpts = MOD_SHRINKWRAP_PROJECT_ALLOW_NEG_DIR | MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR;
ssmd.keepDist = 0.0f;
-
- /* Tolerance value to prevent artifacts on sharp edges of a mesh.
+
+ /* Tolerance value to prevent artifacts on sharp edges of a mesh.
* This constant and based on experimenting with different values. */
const float projLimitTolerance = 5.0f;
ssmd.projLimit = target_me->remesh_voxel_size * projLimitTolerance;
diff --git a/source/blender/blenkernel/intern/simulation.cc b/source/blender/blenkernel/intern/simulation.cc
index 2e1f8bd581e..861779ec700 100644
--- a/source/blender/blenkernel/intern/simulation.cc
+++ b/source/blender/blenkernel/intern/simulation.cc
@@ -165,12 +165,14 @@ IDTypeInfo IDType_ID_SIM = {
/* free_data */ simulation_free_data,
/* make_local */ nullptr,
/* foreach_id */ simulation_foreach_id,
- /* foreach_cache */ NULL,
+ /* foreach_cache */ nullptr,
/* blend_write */ simulation_blend_write,
/* blend_read_data */ simulation_blend_read_data,
/* blend_read_lib */ simulation_blend_read_lib,
/* blend_read_expand */ simulation_blend_read_expand,
+
+ /* blend_read_undo_preserve */ nullptr,
};
void *BKE_simulation_add(Main *bmain, const char *name)
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index bf61c27ee2f..efed9453003 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -1063,7 +1063,7 @@ static int sb_detect_face_pointCached(const float face_v1[3],
GHash *hash;
GHashIterator *ihash;
float nv1[3], edge1[3], edge2[3], d_nvect[3], aabbmin[3], aabbmax[3];
- float facedist, outerfacethickness, tune = 10.f;
+ float facedist, outerfacethickness, tune = 10.0f;
int a, deflected = 0;
aabbmin[0] = min_fff(face_v1[0], face_v2[0], face_v3[0]);
@@ -2032,7 +2032,7 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene,
attached = 0;
for (b = obp->nofsprings; b > 0; b--) {
bs = sb->bspring + obp->springs[b - 1];
- if ((ilast - bb == bs->v2) || (ilast - bb == bs->v1)) {
+ if (ELEM(ilast - bb, bs->v2, bs->v1)) {
attached = 1;
continue;
}
@@ -2797,8 +2797,8 @@ static void reference_to_scratch(Object *ob)
SoftBody *sb = ob->soft;
ReferenceVert *rp;
BodyPoint *bp;
- float accu_pos[3] = {0.f, 0.f, 0.f};
- float accu_mass = 0.f;
+ float accu_pos[3] = {0.0f, 0.0f, 0.0f};
+ float accu_mass = 0.0f;
int a;
sb->scratch->Ref.ivert = MEM_mallocN(sizeof(ReferenceVert) * sb->totpoint, "SB_Reference");
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index 8bec9f331c5..8b66b1fc628 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -60,7 +60,6 @@
#include "BKE_main.h"
#include "BKE_packedFile.h"
#include "BKE_scene.h"
-#include "BKE_sequencer.h"
#include "BKE_sound.h"
#include "DEG_depsgraph.h"
@@ -68,6 +67,8 @@
#include "BLO_read_write.h"
+#include "SEQ_sequencer.h"
+
static void sound_free_audio(bSound *sound);
static void sound_copy_data(Main *UNUSED(bmain),
@@ -211,6 +212,8 @@ IDTypeInfo IDType_ID_SO = {
.blend_read_data = sound_blend_read_data,
.blend_read_lib = sound_blend_read_lib,
.blend_read_expand = sound_blend_read_expand,
+
+ .blend_read_undo_preserve = NULL,
};
#ifdef WITH_AUDASPACE
@@ -1320,7 +1323,10 @@ int BKE_sound_scene_playing(Scene *UNUSED(scene))
{
return -1;
}
-void BKE_sound_read_waveform(Main *bmain, bSound *sound, short *stop)
+void BKE_sound_read_waveform(Main *bmain,
+ bSound *sound,
+ /* NOLINTNEXTLINE: readability-non-const-parameter. */
+ short *stop)
{
UNUSED_VARS(sound, stop, bmain);
}
diff --git a/source/blender/blenkernel/intern/speaker.c b/source/blender/blenkernel/intern/speaker.c
index a98093d1893..fabf0bb8971 100644
--- a/source/blender/blenkernel/intern/speaker.c
+++ b/source/blender/blenkernel/intern/speaker.c
@@ -112,6 +112,8 @@ IDTypeInfo IDType_ID_SPK = {
.blend_read_data = speaker_blend_read_data,
.blend_read_lib = speaker_blend_read_lib,
.blend_read_expand = speaker_blend_read_expand,
+
+ .blend_read_undo_preserve = NULL,
};
void *BKE_speaker_add(Main *bmain, const char *name)
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 93306703686..6f4ac4c44a0 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -256,6 +256,8 @@ IDTypeInfo IDType_ID_TXT = {
.blend_read_data = text_blend_read_data,
.blend_read_lib = NULL,
.blend_read_expand = NULL,
+
+ .blend_read_undo_preserve = NULL,
};
/** \} */
@@ -2333,7 +2335,7 @@ int txt_setcurr_tab_spaces(Text *text, int space)
if (ch == ':') {
is_indent = 1;
}
- else if (ch != ' ' && ch != '\t') {
+ else if (!ELEM(ch, ' ', '\t')) {
is_indent = 0;
}
}
@@ -2459,7 +2461,7 @@ int text_check_identifier_nodigit_unicode(const unsigned int ch)
bool text_check_whitespace(const char ch)
{
- if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') {
+ if (ELEM(ch, ' ', '\t', '\r', '\n')) {
return true;
}
return false;
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 90c4f71ce7a..4c2e4a82acb 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -67,7 +67,7 @@
#include "BKE_scene.h"
#include "BKE_texture.h"
-#include "RE_shader_ext.h"
+#include "RE_texture.h"
#include "BLO_read_write.h"
@@ -224,6 +224,8 @@ IDTypeInfo IDType_ID_TE = {
.blend_read_data = texture_blend_read_data,
.blend_read_lib = texture_blend_read_lib,
.blend_read_expand = texture_blend_read_expand,
+
+ .blend_read_undo_preserve = NULL,
};
/* Utils for all IDs using those texture slots. */
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index cb33610a93f..7f927a8838e 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -338,6 +338,7 @@ void BKE_tracking_settings_init(MovieTracking *tracking)
tracking->settings.default_weight = 1.0f;
tracking->settings.dist = 1;
tracking->settings.object_distance = 1;
+ tracking->settings.refine_camera_intrinsics = REFINE_NO_INTRINSICS;
tracking->stabilization.scaleinf = 1.0f;
tracking->stabilization.anchor_frame = 1;
diff --git a/source/blender/blenkernel/intern/tracking_solver.c b/source/blender/blenkernel/intern/tracking_solver.c
index 7df8bf62b16..d89d36f85ea 100644
--- a/source/blender/blenkernel/intern/tracking_solver.c
+++ b/source/blender/blenkernel/intern/tracking_solver.c
@@ -291,12 +291,12 @@ static int reconstruct_refine_intrinsics_get_flags(MovieTracking *tracking,
flags |= LIBMV_REFINE_PRINCIPAL_POINT;
}
- if (refine & REFINE_RADIAL_DISTORTION_K1) {
- flags |= LIBMV_REFINE_RADIAL_DISTORTION_K1;
+ if (refine & REFINE_RADIAL_DISTORTION) {
+ flags |= LIBMV_REFINE_RADIAL_DISTORTION;
}
- if (refine & REFINE_RADIAL_DISTORTION_K2) {
- flags |= LIBMV_REFINE_RADIAL_DISTORTION_K2;
+ if (refine & REFINE_TANGENTIAL_DISTORTION) {
+ flags |= LIBMV_REFINE_TANGENTIAL_DISTORTION;
}
return flags;
diff --git a/source/blender/blenkernel/intern/tracking_util.c b/source/blender/blenkernel/intern/tracking_util.c
index bc6c94343b5..c7e4e0d5c08 100644
--- a/source/blender/blenkernel/intern/tracking_util.c
+++ b/source/blender/blenkernel/intern/tracking_util.c
@@ -722,7 +722,7 @@ static ImBuf *make_grayscale_ibuf_copy(ImBuf *ibuf)
{
ImBuf *grayscale = IMB_allocImBuf(ibuf->x, ibuf->y, 32, 0);
- BLI_assert(ibuf->channels == 3 || ibuf->channels == 4);
+ BLI_assert(ELEM(ibuf->channels, 3, 4));
/* TODO(sergey): Bummer, currently IMB API only allows to create 4 channels
* float buffer, so we do it manually here.
@@ -880,7 +880,7 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor,
}
/* Transform number of channels. */
if (input_mode == LIBMV_IMAGE_MODE_RGBA) {
- BLI_assert(orig_ibuf->channels == 3 || orig_ibuf->channels == 4);
+ BLI_assert(ELEM(orig_ibuf->channels, 3, 4));
/* pass */
}
else /* if (input_mode == LIBMV_IMAGE_MODE_MONO) */ {
diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c
index 93f70b606dc..b687254fd69 100644
--- a/source/blender/blenkernel/intern/undo_system.c
+++ b/source/blender/blenkernel/intern/undo_system.c
@@ -95,7 +95,7 @@ static bool g_undo_callback_running = false;
/** \name Public Undo Types
*
* Unfortunately we need this for a handful of places.
- */
+ * \{ */
const UndoType *BKE_UNDOSYS_TYPE_IMAGE = NULL;
const UndoType *BKE_UNDOSYS_TYPE_MEMFILE = NULL;
const UndoType *BKE_UNDOSYS_TYPE_PAINTCURVE = NULL;
@@ -357,7 +357,7 @@ void BKE_undosys_stack_init_from_main(UndoStack *ustack, struct Main *bmain)
void BKE_undosys_stack_init_from_context(UndoStack *ustack, bContext *C)
{
const UndoType *ut = BKE_undosys_type_from_context(C);
- if ((ut != NULL) && (ut != BKE_UNDOSYS_TYPE_MEMFILE)) {
+ if (!ELEM(ut, NULL, BKE_UNDOSYS_TYPE_MEMFILE)) {
BKE_undosys_step_push_with_type(ustack, C, IFACE_("Original Mode"), ut);
}
}
@@ -549,6 +549,8 @@ bool BKE_undosys_step_push_with_type(UndoStack *ustack,
BLI_strncpy(us->name, name, sizeof(us->name));
}
us->type = ut;
+ /* True by default, code needs to explicitely set it to false if necessary. */
+ us->use_old_bmain_data = true;
/* Initialized, not added yet. */
CLOG_INFO(&LOG, 1, "addr=%p, name='%s', type='%s'", us, us->name, us->type->name);
@@ -897,7 +899,7 @@ void BKE_undosys_stack_group_end(UndoStack *ustack)
/** \name ID Reference Utilities
*
* Unfortunately we need this for a handful of places.
- */
+ * \{ */
static void UNUSED_FUNCTION(BKE_undosys_foreach_ID_ref(UndoStack *ustack,
UndoTypeForEachIDRefFn foreach_ID_ref_fn,
diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c
index 73bf149bf2a..b55f80c6473 100644
--- a/source/blender/blenkernel/intern/unit.c
+++ b/source/blender/blenkernel/intern/unit.c
@@ -802,17 +802,12 @@ static char *find_next_negative(const char *str, const char *remaining_str)
static char *find_next_op(const char *str, char *remaining_str, int len_max)
{
int i;
- bool scientific_notation = false;
for (i = 0; i < len_max; i++) {
if (remaining_str[i] == '\0') {
return remaining_str + i;
}
if (ch_is_op(remaining_str[i])) {
- if (scientific_notation) {
- scientific_notation = false;
- }
-
/* Make sure we don't look backwards before the start of the string. */
if (remaining_str != str && i != 0) {
/* Check for velocity or acceleration (e.g. '/' in 'ft/s' is not an op). */
@@ -822,8 +817,7 @@ static char *find_next_op(const char *str, char *remaining_str, int len_max)
}
/* Check for scientific notation. */
- if (remaining_str[i - 1] == 'e' || remaining_str[i - 1] == 'E') {
- scientific_notation = true;
+ if (ELEM(remaining_str[i - 1], 'e', 'E')) {
continue;
}
@@ -1184,7 +1178,7 @@ bool BKE_unit_replace_string(
/* Any operators after this? */
for (ch = str_found + 1; *ch != '\0'; ch++) {
- if (*ch == ' ' || *ch == '\t') {
+ if (ELEM(*ch, ' ', '\t')) {
continue;
}
op_found = (ch_is_op(*ch) || ELEM(*ch, ',', ')'));
diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc
index 87993695486..11aa9597740 100644
--- a/source/blender/blenkernel/intern/volume.cc
+++ b/source/blender/blenkernel/intern/volume.cc
@@ -265,12 +265,13 @@ static struct VolumeFileCache {
struct VolumeGrid {
VolumeGrid(const VolumeFileCache::Entry &template_entry, const int simplify_level)
- : entry(NULL), simplify_level(simplify_level), is_loaded(false)
+ : entry(nullptr), simplify_level(simplify_level), is_loaded(false)
{
entry = GLOBAL_CACHE.add_metadata_user(template_entry);
}
- VolumeGrid(const openvdb::GridBase::Ptr &grid) : entry(NULL), local_grid(grid), is_loaded(true)
+ VolumeGrid(const openvdb::GridBase::Ptr &grid)
+ : entry(nullptr), local_grid(grid), is_loaded(true)
{
}
@@ -295,7 +296,7 @@ struct VolumeGrid {
void load(const char *volume_name, const char *filepath)
{
/* If already loaded or not file-backed, nothing to do. */
- if (is_loaded || entry == NULL) {
+ if (is_loaded || entry == nullptr) {
return;
}
@@ -337,7 +338,7 @@ struct VolumeGrid {
void unload(const char *volume_name)
{
/* Not loaded or not file-backed, nothing to do. */
- if (!is_loaded || entry == NULL) {
+ if (!is_loaded || entry == nullptr) {
return;
}
@@ -364,7 +365,7 @@ struct VolumeGrid {
local_grid = grid()->copyGridWithNewTree();
if (entry) {
GLOBAL_CACHE.remove_user(*entry, is_loaded);
- entry = NULL;
+ entry = nullptr;
}
is_loaded = true;
}
@@ -378,7 +379,7 @@ struct VolumeGrid {
local_grid = grid()->deepCopyGrid();
if (entry) {
GLOBAL_CACHE.remove_user(*entry, is_loaded);
- entry = NULL;
+ entry = nullptr;
}
is_loaded = true;
}
@@ -398,7 +399,7 @@ struct VolumeGrid {
return entry->error_msg.c_str();
}
- return NULL;
+ return nullptr;
}
bool grid_is_loaded() const
@@ -562,7 +563,7 @@ static void volume_blend_write(BlendWriter *writer, ID *id, const void *id_addre
Volume *volume = (Volume *)id;
if (volume->id.us > 0 || BLO_write_is_undo(writer)) {
/* Clean up, important in undo case to reduce false detection of changed datablocks. */
- volume->runtime.grids = 0;
+ volume->runtime.grids = nullptr;
/* write LibData */
BLO_write_id_struct(writer, Volume, id_address, &volume->id);
@@ -633,12 +634,14 @@ IDTypeInfo IDType_ID_VO = {
/* blend_read_data */ volume_blend_read_data,
/* blend_read_lib */ volume_blend_read_lib,
/* blend_read_expand */ volume_blend_read_expand,
+
+ /* blend_read_undo_preserve */ nullptr,
};
void BKE_volume_init_grids(Volume *volume)
{
#ifdef WITH_OPENVDB
- if (volume->runtime.grids == NULL) {
+ if (volume->runtime.grids == nullptr) {
volume->runtime.grids = OBJECT_GUARDED_NEW(VolumeGridVector);
}
#else
@@ -869,11 +872,11 @@ BoundBox *BKE_volume_boundbox_get(Object *ob)
{
BLI_assert(ob->type == OB_VOLUME);
- if (ob->runtime.bb != NULL && (ob->runtime.bb->flag & BOUNDBOX_DIRTY) == 0) {
+ if (ob->runtime.bb != nullptr && (ob->runtime.bb->flag & BOUNDBOX_DIRTY) == 0) {
return ob->runtime.bb;
}
- if (ob->runtime.bb == NULL) {
+ if (ob->runtime.bb == nullptr) {
Volume *volume = (Volume *)ob->data;
ob->runtime.bb = (BoundBox *)MEM_callocN(sizeof(BoundBox), "volume boundbox");
@@ -1004,7 +1007,7 @@ static Volume *volume_evaluate_modifiers(struct Depsgraph *depsgraph,
if (volume_next && volume_next != volume) {
/* If the modifier returned a new volume, release the old one. */
if (volume != volume_input) {
- BKE_id_free(NULL, volume);
+ BKE_id_free(nullptr, volume);
}
volume = volume_next;
}
@@ -1055,7 +1058,7 @@ void BKE_volume_grids_backup_restore(Volume *volume, VolumeGridVector *grids, co
/* Restore grids after datablock was re-copied from original by depsgraph,
* we don't want to load them again if possible. */
BLI_assert(volume->id.tag & LIB_TAG_COPIED_ON_WRITE);
- BLI_assert(volume->runtime.grids != NULL && grids != NULL);
+ BLI_assert(volume->runtime.grids != nullptr && grids != nullptr);
if (!grids->is_loaded()) {
/* No grids loaded in CoW datablock, nothing lost by discarding. */
@@ -1078,8 +1081,8 @@ void BKE_volume_grids_backup_restore(Volume *volume, VolumeGridVector *grids, co
/* Draw Cache */
-void (*BKE_volume_batch_cache_dirty_tag_cb)(Volume *volume, int mode) = NULL;
-void (*BKE_volume_batch_cache_free_cb)(Volume *volume) = NULL;
+void (*BKE_volume_batch_cache_dirty_tag_cb)(Volume *volume, int mode) = nullptr;
+void (*BKE_volume_batch_cache_free_cb)(Volume *volume) = nullptr;
void BKE_volume_batch_cache_dirty_tag(Volume *volume, int mode)
{
@@ -1136,10 +1139,10 @@ VolumeGrid *BKE_volume_grid_get(const Volume *volume, int grid_index)
return &grid;
}
}
- return NULL;
+ return nullptr;
#else
UNUSED_VARS(volume, grid_index);
- return NULL;
+ return nullptr;
#endif
}
@@ -1147,7 +1150,7 @@ VolumeGrid *BKE_volume_grid_active_get(const Volume *volume)
{
const int num_grids = BKE_volume_num_grids(volume);
if (num_grids == 0) {
- return NULL;
+ return nullptr;
}
const int index = clamp_i(volume->active_grid, 0, num_grids - 1);
@@ -1165,7 +1168,7 @@ VolumeGrid *BKE_volume_grid_find(const Volume *volume, const char *name)
}
}
- return NULL;
+ return nullptr;
}
/* Grid Loading */
@@ -1350,7 +1353,7 @@ bool BKE_volume_grid_bounds(const VolumeGrid *volume_grid, float min[3], float m
Volume *BKE_volume_new_for_eval(const Volume *volume_src)
{
- Volume *volume_dst = (Volume *)BKE_id_new_nomain(ID_VO, NULL);
+ Volume *volume_dst = (Volume *)BKE_id_new_nomain(ID_VO, nullptr);
STRNCPY(volume_dst->id.name, volume_src->id.name);
volume_dst->mat = (Material **)MEM_dupallocN(volume_src->mat);
@@ -1370,7 +1373,7 @@ Volume *BKE_volume_copy_for_eval(Volume *volume_src, bool reference)
flags |= LIB_ID_COPY_CD_REFERENCE;
}
- Volume *result = (Volume *)BKE_id_copy_ex(NULL, &volume_src->id, NULL, flags);
+ Volume *result = (Volume *)BKE_id_copy_ex(nullptr, &volume_src->id, nullptr, flags);
return result;
}
@@ -1393,12 +1396,12 @@ VolumeGrid *BKE_volume_grid_add(Volume *volume, const char *name, VolumeGridType
{
#ifdef WITH_OPENVDB
VolumeGridVector &grids = *volume->runtime.grids;
- BLI_assert(BKE_volume_grid_find(volume, name) == NULL);
+ BLI_assert(BKE_volume_grid_find(volume, name) == nullptr);
BLI_assert(type != VOLUME_GRID_UNKNOWN);
openvdb::GridBase::Ptr vdb_grid = BKE_volume_grid_type_operation(type, CreateGridOp{});
if (!vdb_grid) {
- return NULL;
+ return nullptr;
}
vdb_grid->setName(name);
@@ -1406,7 +1409,7 @@ VolumeGrid *BKE_volume_grid_add(Volume *volume, const char *name, VolumeGridType
return &grids.back();
#else
UNUSED_VARS(volume, name, type);
- return NULL;
+ return nullptr;
#endif
}
diff --git a/source/blender/blenkernel/intern/volume_render.cc b/source/blender/blenkernel/intern/volume_render.cc
index 37b397a9c6d..5c71f1d7eca 100644
--- a/source/blender/blenkernel/intern/volume_render.cc
+++ b/source/blender/blenkernel/intern/volume_render.cc
@@ -123,7 +123,7 @@ bool BKE_volume_grid_dense_floats(const Volume *volume,
const int channels = BKE_volume_grid_channels(volume_grid);
const int elem_size = sizeof(float) * channels;
float *voxels = static_cast<float *>(MEM_malloc_arrayN(num_voxels, elem_size, __func__));
- if (voxels == NULL) {
+ if (voxels == nullptr) {
return false;
}
@@ -143,7 +143,7 @@ bool BKE_volume_grid_dense_floats(const Volume *volume,
void BKE_volume_dense_float_grid_clear(DenseFloatVolumeGrid *dense_grid)
{
- if (dense_grid->voxels != NULL) {
+ if (dense_grid->voxels != nullptr) {
MEM_freeN(dense_grid->voxels);
}
}
@@ -339,7 +339,7 @@ void BKE_volume_grid_wireframe(const Volume *volume,
void *cb_userdata)
{
if (volume->display.wireframe_type == VOLUME_WIREFRAME_NONE) {
- cb(cb_userdata, NULL, NULL, 0, 0);
+ cb(cb_userdata, nullptr, nullptr, 0, 0);
return;
}
@@ -386,7 +386,7 @@ void BKE_volume_grid_wireframe(const Volume *volume,
#else
UNUSED_VARS(volume, volume_grid);
- cb(cb_userdata, NULL, NULL, 0, 0);
+ cb(cb_userdata, nullptr, nullptr, 0, 0);
#endif
}
@@ -432,7 +432,7 @@ void BKE_volume_grid_selection_surface(const Volume *volume,
cb(cb_userdata, (float(*)[3])verts.data(), (int(*)[3])tris.data(), verts.size(), tris.size());
#else
UNUSED_VARS(volume, volume_grid);
- cb(cb_userdata, NULL, NULL, 0, 0);
+ cb(cb_userdata, nullptr, nullptr, 0, 0);
#endif
}
diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c
index cd163b7c8bf..291116556c3 100644
--- a/source/blender/blenkernel/intern/workspace.c
+++ b/source/blender/blenkernel/intern/workspace.c
@@ -48,6 +48,8 @@
#include "MEM_guardedalloc.h"
+#include "BLO_read_write.h"
+
/* -------------------------------------------------------------------- */
static void workspace_free_data(ID *id)
@@ -75,6 +77,98 @@ static void workspace_foreach_id(ID *id, LibraryForeachIDData *data)
}
}
+static void workspace_blend_write(BlendWriter *writer, ID *id, const void *id_address)
+{
+ WorkSpace *workspace = (WorkSpace *)id;
+
+ BLO_write_id_struct(writer, WorkSpace, id_address, &workspace->id);
+ BKE_id_blend_write(writer, &workspace->id);
+ BLO_write_struct_list(writer, WorkSpaceLayout, &workspace->layouts);
+ BLO_write_struct_list(writer, WorkSpaceDataRelation, &workspace->hook_layout_relations);
+ BLO_write_struct_list(writer, wmOwnerID, &workspace->owner_ids);
+ BLO_write_struct_list(writer, bToolRef, &workspace->tools);
+ LISTBASE_FOREACH (bToolRef *, tref, &workspace->tools) {
+ if (tref->properties) {
+ IDP_BlendWrite(writer, tref->properties);
+ }
+ }
+}
+
+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);
+
+ LISTBASE_FOREACH (WorkSpaceDataRelation *, relation, &workspace->hook_layout_relations) {
+ /* parent pointer does not belong to workspace data and is therefore restored in lib_link step
+ * of window manager.*/
+ BLO_read_data_address(reader, &relation->value);
+ }
+
+ LISTBASE_FOREACH (bToolRef *, tref, &workspace->tools) {
+ tref->runtime = NULL;
+ BLO_read_data_address(reader, &tref->properties);
+ IDP_BlendDataRead(reader, &tref->properties);
+ }
+
+ workspace->status_text = NULL;
+
+ id_us_ensure_real(&workspace->id);
+}
+
+static void workspace_blend_read_lib(BlendLibReader *reader, ID *id)
+{
+ WorkSpace *workspace = (WorkSpace *)id;
+ Main *bmain = BLO_read_lib_get_main(reader);
+
+ /* Restore proper 'parent' pointers to relevant data, and clean up unused/invalid entries. */
+ LISTBASE_FOREACH_MUTABLE (WorkSpaceDataRelation *, relation, &workspace->hook_layout_relations) {
+ relation->parent = NULL;
+ LISTBASE_FOREACH (wmWindowManager *, wm, &bmain->wm) {
+ LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
+ if (win->winid == relation->parentid) {
+ relation->parent = win->workspace_hook;
+ }
+ }
+ }
+ if (relation->parent == NULL) {
+ BLI_freelinkN(&workspace->hook_layout_relations, relation);
+ }
+ }
+
+ LISTBASE_FOREACH_MUTABLE (WorkSpaceLayout *, layout, &workspace->layouts) {
+ BLO_read_id_address(reader, id->lib, &layout->screen);
+
+ if (layout->screen) {
+ if (ID_IS_LINKED(id)) {
+ layout->screen->winid = 0;
+ if (layout->screen->temp) {
+ /* delete temp layouts when appending */
+ BKE_workspace_layout_remove(bmain, workspace, layout);
+ }
+ }
+ }
+ else {
+ /* If we're reading a layout without screen stored, it's useless and we shouldn't keep it
+ * around. */
+ BKE_workspace_layout_remove(bmain, workspace, layout);
+ }
+ }
+}
+
+static void workspace_blend_read_expand(BlendExpander *expander, ID *id)
+{
+ WorkSpace *workspace = (WorkSpace *)id;
+
+ LISTBASE_FOREACH (WorkSpaceLayout *, layout, &workspace->layouts) {
+ BLO_expand(expander, BKE_workspace_layout_screen_get(layout));
+ }
+}
+
IDTypeInfo IDType_ID_WS = {
.id_code = ID_WS,
.id_filter = FILTER_ID_WS,
@@ -92,12 +186,15 @@ IDTypeInfo IDType_ID_WS = {
.foreach_id = workspace_foreach_id,
.foreach_cache = NULL,
- .blend_write = NULL,
- .blend_read_data = NULL,
- .blend_read_lib = NULL,
- .blend_read_expand = NULL,
+ .blend_write = workspace_blend_write,
+ .blend_read_data = workspace_blend_read_data,
+ .blend_read_lib = workspace_blend_read_lib,
+ .blend_read_expand = workspace_blend_read_expand,
+
+ .blend_read_undo_preserve = NULL,
};
+/* -------------------------------------------------------------------- */
/** \name Internal Utils
* \{ */
diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c
index 094557502a3..8fe7653fc25 100644
--- a/source/blender/blenkernel/intern/world.c
+++ b/source/blender/blenkernel/intern/world.c
@@ -204,6 +204,8 @@ IDTypeInfo IDType_ID_WO = {
.blend_read_data = world_blend_read_data,
.blend_read_lib = world_blend_read_lib,
.blend_read_expand = world_blend_read_expand,
+
+ .blend_read_undo_preserve = NULL,
};
World *BKE_world_add(Main *bmain, const char *name)