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.h6
-rw-r--r--source/blender/blenkernel/BKE_action.h17
-rw-r--r--source/blender/blenkernel/BKE_addon.h5
-rw-r--r--source/blender/blenkernel/BKE_anim_data.h11
-rw-r--r--source/blender/blenkernel/BKE_anim_path.h5
-rw-r--r--source/blender/blenkernel/BKE_anim_visualization.h5
-rw-r--r--source/blender/blenkernel/BKE_animsys.h52
-rw-r--r--source/blender/blenkernel/BKE_appdir.h5
-rw-r--r--source/blender/blenkernel/BKE_armature.h27
-rw-r--r--source/blender/blenkernel/BKE_autoexec.h5
-rw-r--r--source/blender/blenkernel/BKE_blender.h5
-rw-r--r--source/blender/blenkernel/BKE_blender_copybuffer.h5
-rw-r--r--source/blender/blenkernel/BKE_blender_undo.h5
-rw-r--r--source/blender/blenkernel/BKE_blender_user_menu.h5
-rw-r--r--source/blender/blenkernel/BKE_blender_version.h9
-rw-r--r--source/blender/blenkernel/BKE_blendfile.h5
-rw-r--r--source/blender/blenkernel/BKE_boids.h5
-rw-r--r--source/blender/blenkernel/BKE_bpath.h5
-rw-r--r--source/blender/blenkernel/BKE_brush.h5
-rw-r--r--source/blender/blenkernel/BKE_bvhutils.h5
-rw-r--r--source/blender/blenkernel/BKE_cachefile.h5
-rw-r--r--source/blender/blenkernel/BKE_callbacks.h5
-rw-r--r--source/blender/blenkernel/BKE_camera.h5
-rw-r--r--source/blender/blenkernel/BKE_ccg.h5
-rw-r--r--source/blender/blenkernel/BKE_cdderivedmesh.h5
-rw-r--r--source/blender/blenkernel/BKE_cloth.h13
-rw-r--r--source/blender/blenkernel/BKE_collection.h12
-rw-r--r--source/blender/blenkernel/BKE_collision.h5
-rw-r--r--source/blender/blenkernel/BKE_colorband.h5
-rw-r--r--source/blender/blenkernel/BKE_colortools.h7
-rw-r--r--source/blender/blenkernel/BKE_constraint.h5
-rw-r--r--source/blender/blenkernel/BKE_context.h7
-rw-r--r--source/blender/blenkernel/BKE_crazyspace.h5
-rw-r--r--source/blender/blenkernel/BKE_curve.h13
-rw-r--r--source/blender/blenkernel/BKE_curveprofile.h7
-rw-r--r--source/blender/blenkernel/BKE_customdata.h6
-rw-r--r--source/blender/blenkernel/BKE_customdata_file.h5
-rw-r--r--source/blender/blenkernel/BKE_data_transfer.h5
-rw-r--r--source/blender/blenkernel/BKE_deform.h7
-rw-r--r--source/blender/blenkernel/BKE_derived_node_tree.hh498
-rw-r--r--source/blender/blenkernel/BKE_displist.h5
-rw-r--r--source/blender/blenkernel/BKE_displist_tangent.h5
-rw-r--r--source/blender/blenkernel/BKE_duplilist.h7
-rw-r--r--source/blender/blenkernel/BKE_dynamicpaint.h5
-rw-r--r--source/blender/blenkernel/BKE_editlattice.h5
-rw-r--r--source/blender/blenkernel/BKE_editmesh.h5
-rw-r--r--source/blender/blenkernel/BKE_editmesh_bvh.h5
-rw-r--r--source/blender/blenkernel/BKE_editmesh_cache.h5
-rw-r--r--source/blender/blenkernel/BKE_editmesh_tangent.h5
-rw-r--r--source/blender/blenkernel/BKE_effect.h5
-rw-r--r--source/blender/blenkernel/BKE_fcurve.h14
-rw-r--r--source/blender/blenkernel/BKE_fcurve_driver.h8
-rw-r--r--source/blender/blenkernel/BKE_fluid.h13
-rw-r--r--source/blender/blenkernel/BKE_font.h5
-rw-r--r--source/blender/blenkernel/BKE_freestyle.h5
-rw-r--r--source/blender/blenkernel/BKE_global.h28
-rw-r--r--source/blender/blenkernel/BKE_gpencil.h5
-rw-r--r--source/blender/blenkernel/BKE_gpencil_curve.h5
-rw-r--r--source/blender/blenkernel/BKE_gpencil_geom.h26
-rw-r--r--source/blender/blenkernel/BKE_gpencil_modifier.h5
-rw-r--r--source/blender/blenkernel/BKE_hair.h5
-rw-r--r--source/blender/blenkernel/BKE_icons.h5
-rw-r--r--source/blender/blenkernel/BKE_idprop.h5
-rw-r--r--source/blender/blenkernel/BKE_idtype.h25
-rw-r--r--source/blender/blenkernel/BKE_image.h34
-rw-r--r--source/blender/blenkernel/BKE_image_save.h5
-rw-r--r--source/blender/blenkernel/BKE_ipo.h5
-rw-r--r--source/blender/blenkernel/BKE_kelvinlet.h5
-rw-r--r--source/blender/blenkernel/BKE_key.h37
-rw-r--r--source/blender/blenkernel/BKE_keyconfig.h5
-rw-r--r--source/blender/blenkernel/BKE_lattice.h9
-rw-r--r--source/blender/blenkernel/BKE_layer.h5
-rw-r--r--source/blender/blenkernel/BKE_lib_id.h9
-rw-r--r--source/blender/blenkernel/BKE_lib_override.h24
-rw-r--r--source/blender/blenkernel/BKE_lib_query.h5
-rw-r--r--source/blender/blenkernel/BKE_lib_remap.h5
-rw-r--r--source/blender/blenkernel/BKE_library.h5
-rw-r--r--source/blender/blenkernel/BKE_light.h5
-rw-r--r--source/blender/blenkernel/BKE_lightprobe.h5
-rw-r--r--source/blender/blenkernel/BKE_linestyle.h5
-rw-r--r--source/blender/blenkernel/BKE_main.h5
-rw-r--r--source/blender/blenkernel/BKE_main_idmap.h5
-rw-r--r--source/blender/blenkernel/BKE_mask.h5
-rw-r--r--source/blender/blenkernel/BKE_material.h8
-rw-r--r--source/blender/blenkernel/BKE_mball.h5
-rw-r--r--source/blender/blenkernel/BKE_mball_tessellate.h5
-rw-r--r--source/blender/blenkernel/BKE_mesh.h11
-rw-r--r--source/blender/blenkernel/BKE_mesh_iterators.h5
-rw-r--r--source/blender/blenkernel/BKE_mesh_mapping.h7
-rw-r--r--source/blender/blenkernel/BKE_mesh_mirror.h5
-rw-r--r--source/blender/blenkernel/BKE_mesh_remap.h5
-rw-r--r--source/blender/blenkernel/BKE_mesh_remesh_voxel.h5
-rw-r--r--source/blender/blenkernel/BKE_mesh_runtime.h5
-rw-r--r--source/blender/blenkernel/BKE_mesh_tangent.h5
-rw-r--r--source/blender/blenkernel/BKE_mesh_wrapper.h5
-rw-r--r--source/blender/blenkernel/BKE_modifier.h5
-rw-r--r--source/blender/blenkernel/BKE_movieclip.h10
-rw-r--r--source/blender/blenkernel/BKE_multires.h5
-rw-r--r--source/blender/blenkernel/BKE_nla.h5
-rw-r--r--source/blender/blenkernel/BKE_node.h41
-rw-r--r--source/blender/blenkernel/BKE_node_tree_ref.hh445
-rw-r--r--source/blender/blenkernel/BKE_object.h35
-rw-r--r--source/blender/blenkernel/BKE_object_deform.h7
-rw-r--r--source/blender/blenkernel/BKE_object_facemap.h5
-rw-r--r--source/blender/blenkernel/BKE_ocean.h11
-rw-r--r--source/blender/blenkernel/BKE_outliner_treehash.h5
-rw-r--r--source/blender/blenkernel/BKE_packedFile.h5
-rw-r--r--source/blender/blenkernel/BKE_paint.h42
-rw-r--r--source/blender/blenkernel/BKE_particle.h13
-rw-r--r--source/blender/blenkernel/BKE_pbvh.h8
-rw-r--r--source/blender/blenkernel/BKE_persistent_data_handle.hh129
-rw-r--r--source/blender/blenkernel/BKE_pointcache.h12
-rw-r--r--source/blender/blenkernel/BKE_pointcloud.h5
-rw-r--r--source/blender/blenkernel/BKE_report.h5
-rw-r--r--source/blender/blenkernel/BKE_rigidbody.h5
-rw-r--r--source/blender/blenkernel/BKE_scene.h5
-rw-r--r--source/blender/blenkernel/BKE_screen.h15
-rw-r--r--source/blender/blenkernel/BKE_sequencer.h22
-rw-r--r--source/blender/blenkernel/BKE_sequencer_offscreen.h5
-rw-r--r--source/blender/blenkernel/BKE_shader_fx.h5
-rw-r--r--source/blender/blenkernel/BKE_shrinkwrap.h5
-rw-r--r--source/blender/blenkernel/BKE_simulation.h27
-rw-r--r--source/blender/blenkernel/BKE_softbody.h5
-rw-r--r--source/blender/blenkernel/BKE_sound.h5
-rw-r--r--source/blender/blenkernel/BKE_speaker.h5
-rw-r--r--source/blender/blenkernel/BKE_studiolight.h5
-rw-r--r--source/blender/blenkernel/BKE_subdiv.h5
-rw-r--r--source/blender/blenkernel/BKE_subdiv_ccg.h23
-rw-r--r--source/blender/blenkernel/BKE_subdiv_deform.h5
-rw-r--r--source/blender/blenkernel/BKE_subdiv_eval.h5
-rw-r--r--source/blender/blenkernel/BKE_subdiv_foreach.h5
-rw-r--r--source/blender/blenkernel/BKE_subdiv_mesh.h5
-rw-r--r--source/blender/blenkernel/BKE_subdiv_topology.h5
-rw-r--r--source/blender/blenkernel/BKE_subsurf.h5
-rw-r--r--source/blender/blenkernel/BKE_text.h5
-rw-r--r--source/blender/blenkernel/BKE_text_suggestions.h5
-rw-r--r--source/blender/blenkernel/BKE_texture.h5
-rw-r--r--source/blender/blenkernel/BKE_tracking.h5
-rw-r--r--source/blender/blenkernel/BKE_undo_system.h5
-rw-r--r--source/blender/blenkernel/BKE_unit.h5
-rw-r--r--source/blender/blenkernel/BKE_volume.h5
-rw-r--r--source/blender/blenkernel/BKE_volume_render.h5
-rw-r--r--source/blender/blenkernel/BKE_workspace.h5
-rw-r--r--source/blender/blenkernel/BKE_world.h5
-rw-r--r--source/blender/blenkernel/BKE_writeavi.h5
-rw-r--r--source/blender/blenkernel/BKE_writeffmpeg.h5
-rw-r--r--source/blender/blenkernel/CMakeLists.txt29
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.c181
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.h5
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf_inline.h5
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf_intern.h5
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf_legacy.c17
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf_util.c2
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c53
-rw-r--r--source/blender/blenkernel/intern/action.c70
-rw-r--r--source/blender/blenkernel/intern/anim_data.c128
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c198
-rw-r--r--source/blender/blenkernel/intern/anim_visualization.c6
-rw-r--r--source/blender/blenkernel/intern/appdir.c68
-rw-r--r--source/blender/blenkernel/intern/armature.c59
-rw-r--r--source/blender/blenkernel/intern/armature_deform.c18
-rw-r--r--source/blender/blenkernel/intern/armature_test.cc93
-rw-r--r--source/blender/blenkernel/intern/armature_update.c9
-rw-r--r--source/blender/blenkernel/intern/boids.c159
-rw-r--r--source/blender/blenkernel/intern/bpath.c96
-rw-r--r--source/blender/blenkernel/intern/brush.c67
-rw-r--r--source/blender/blenkernel/intern/bvhutils.c22
-rw-r--r--source/blender/blenkernel/intern/cachefile.c2
-rw-r--r--source/blender/blenkernel/intern/cloth.c52
-rw-r--r--source/blender/blenkernel/intern/collection.c144
-rw-r--r--source/blender/blenkernel/intern/collision.c14
-rw-r--r--source/blender/blenkernel/intern/colortools.c2
-rw-r--r--source/blender/blenkernel/intern/constraint.c9
-rw-r--r--source/blender/blenkernel/intern/context.c5
-rw-r--r--source/blender/blenkernel/intern/curve.c334
-rw-r--r--source/blender/blenkernel/intern/curve_bevel.c272
-rw-r--r--source/blender/blenkernel/intern/curveprofile.c18
-rw-r--r--source/blender/blenkernel/intern/customdata.c171
-rw-r--r--source/blender/blenkernel/intern/data_transfer.c4
-rw-r--r--source/blender/blenkernel/intern/data_transfer_intern.h5
-rw-r--r--source/blender/blenkernel/intern/deform.c4
-rw-r--r--source/blender/blenkernel/intern/derived_node_tree.cc441
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c38
-rw-r--r--source/blender/blenkernel/intern/editmesh_tangent.c4
-rw-r--r--source/blender/blenkernel/intern/effect.c4
-rw-r--r--source/blender/blenkernel/intern/fcurve.c15
-rw-r--r--source/blender/blenkernel/intern/fcurve_driver.c378
-rw-r--r--source/blender/blenkernel/intern/fcurve_test.cc213
-rw-r--r--source/blender/blenkernel/intern/fluid.c458
-rw-r--r--source/blender/blenkernel/intern/font.c2
-rw-r--r--source/blender/blenkernel/intern/gpencil.c26
-rw-r--r--source/blender/blenkernel/intern/gpencil_curve.c2
-rw-r--r--source/blender/blenkernel/intern/gpencil_geom.c219
-rw-r--r--source/blender/blenkernel/intern/gpencil_modifier.c10
-rw-r--r--source/blender/blenkernel/intern/idtype.c33
-rw-r--r--source/blender/blenkernel/intern/image.c77
-rw-r--r--source/blender/blenkernel/intern/image_gpu.c774
-rw-r--r--source/blender/blenkernel/intern/key.c169
-rw-r--r--source/blender/blenkernel/intern/lattice.c4
-rw-r--r--source/blender/blenkernel/intern/lattice_deform.c4
-rw-r--r--source/blender/blenkernel/intern/layer.c34
-rw-r--r--source/blender/blenkernel/intern/lib_id.c64
-rw-r--r--source/blender/blenkernel/intern/lib_id_delete.c9
-rw-r--r--source/blender/blenkernel/intern/lib_intern.h5
-rw-r--r--source/blender/blenkernel/intern/lib_override.c471
-rw-r--r--source/blender/blenkernel/intern/lib_query.c3
-rw-r--r--source/blender/blenkernel/intern/light.c2
-rw-r--r--source/blender/blenkernel/intern/mask.c2
-rw-r--r--source/blender/blenkernel/intern/mask_rasterize.c8
-rw-r--r--source/blender/blenkernel/intern/material.c42
-rw-r--r--source/blender/blenkernel/intern/mball_tessellate.c2
-rw-r--r--source/blender/blenkernel/intern/mesh.c2
-rw-r--r--source/blender/blenkernel/intern/mesh_convert.c14
-rw-r--r--source/blender/blenkernel/intern/mesh_evaluate.c4
-rw-r--r--source/blender/blenkernel/intern/mesh_mapping.c2
-rw-r--r--source/blender/blenkernel/intern/mesh_remap.c2
-rw-r--r--source/blender/blenkernel/intern/mesh_runtime.c18
-rw-r--r--source/blender/blenkernel/intern/mesh_validate.c15
-rw-r--r--source/blender/blenkernel/intern/mesh_wrapper.c8
-rw-r--r--source/blender/blenkernel/intern/movieclip.c103
-rw-r--r--source/blender/blenkernel/intern/multires.c6
-rw-r--r--source/blender/blenkernel/intern/multires_inline.h5
-rw-r--r--source/blender/blenkernel/intern/multires_reshape.h4
-rw-r--r--source/blender/blenkernel/intern/multires_reshape_smooth.c2
-rw-r--r--source/blender/blenkernel/intern/multires_unsubdivide.c2
-rw-r--r--source/blender/blenkernel/intern/multires_unsubdivide.h5
-rw-r--r--source/blender/blenkernel/intern/node.c54
-rw-r--r--source/blender/blenkernel/intern/node_tree_ref.cc177
-rw-r--r--source/blender/blenkernel/intern/object.c201
-rw-r--r--source/blender/blenkernel/intern/object_deform.c2
-rw-r--r--source/blender/blenkernel/intern/object_dupli.c79
-rw-r--r--source/blender/blenkernel/intern/ocean.c36
-rw-r--r--source/blender/blenkernel/intern/ocean_intern.h5
-rw-r--r--source/blender/blenkernel/intern/paint.c107
-rw-r--r--source/blender/blenkernel/intern/particle.c44
-rw-r--r--source/blender/blenkernel/intern/particle_distribute.c2
-rw-r--r--source/blender/blenkernel/intern/particle_system.c21
-rw-r--r--source/blender/blenkernel/intern/pbvh.c13
-rw-r--r--source/blender/blenkernel/intern/pbvh_intern.h5
-rw-r--r--source/blender/blenkernel/intern/pointcache.c147
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c123
-rw-r--r--source/blender/blenkernel/intern/scene.c44
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c6
-rw-r--r--source/blender/blenkernel/intern/seqmodifier.c20
-rw-r--r--source/blender/blenkernel/intern/seqprefetch.c7
-rw-r--r--source/blender/blenkernel/intern/sequencer.c325
-rw-r--r--source/blender/blenkernel/intern/simulation.cc305
-rw-r--r--source/blender/blenkernel/intern/softbody.c19
-rw-r--r--source/blender/blenkernel/intern/sound.c2
-rw-r--r--source/blender/blenkernel/intern/studiolight.c1
-rw-r--r--source/blender/blenkernel/intern/subdiv_ccg.c105
-rw-r--r--source/blender/blenkernel/intern/subdiv_converter.h5
-rw-r--r--source/blender/blenkernel/intern/subdiv_inline.h5
-rw-r--r--source/blender/blenkernel/intern/tracking.c2
-rw-r--r--source/blender/blenkernel/intern/tracking_stabilize.c40
-rw-r--r--source/blender/blenkernel/intern/undo_system.c4
-rw-r--r--source/blender/blenkernel/intern/unit.c1
-rw-r--r--source/blender/blenkernel/intern/volume.cc49
-rw-r--r--source/blender/blenkernel/nla_private.h15
-rw-r--r--source/blender/blenkernel/particle_private.h5
-rw-r--r--source/blender/blenkernel/tracking_private.h5
261 files changed, 5914 insertions, 4395 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 9162ed56655..76c610fb5bd 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_DERIVEDMESH_H__
-#define __BKE_DERIVEDMESH_H__
+#pragma once
/** \file
* \ingroup bke
@@ -382,7 +381,6 @@ void DM_calc_loop_tangents(DerivedMesh *dm,
#ifndef NDEBUG
char *DM_debug_info(DerivedMesh *dm);
void DM_debug_print(DerivedMesh *dm);
-void DM_debug_print_cdlayers(CustomData *cdata);
bool DM_is_valid(DerivedMesh *dm);
#endif
@@ -390,5 +388,3 @@ bool DM_is_valid(DerivedMesh *dm);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_DERIVEDMESH_H__ */
diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h
index 104582be932..e08604f02ad 100644
--- a/source/blender/blenkernel/BKE_action.h
+++ b/source/blender/blenkernel/BKE_action.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_ACTION_H__
-#define __BKE_ACTION_H__
+#pragma once
/** \file
* \ingroup bke
@@ -32,6 +31,7 @@ extern "C" {
#endif
/* The following structures are defined in DNA_action_types.h, and DNA_anim_types.h */
+struct AnimationEvalContext;
struct FCurve;
struct Main;
struct Object;
@@ -128,6 +128,8 @@ void BKE_pose_channel_free(struct bPoseChannel *pchan);
void BKE_pose_channel_free_ex(struct bPoseChannel *pchan, bool do_id_user);
void BKE_pose_channel_runtime_reset(struct bPoseChannel_Runtime *runtime);
+void BKE_pose_channel_runtime_reset_on_copy(struct bPoseChannel_Runtime *runtime);
+
void BKE_pose_channel_runtime_free(struct bPoseChannel_Runtime *runtime);
void BKE_pose_channel_free_bbone_cache(struct bPoseChannel_Runtime *runtime);
@@ -152,12 +154,15 @@ void BKE_pose_copy_data_ex(struct bPose **dst,
const bool copy_constraints);
void BKE_pose_copy_data(struct bPose **dst, const struct bPose *src, const bool copy_constraints);
void BKE_pose_channel_copy_data(struct bPoseChannel *pchan, const struct bPoseChannel *pchan_from);
+void BKE_pose_channel_session_uuid_generate(struct bPoseChannel *pchan);
struct bPoseChannel *BKE_pose_channel_find_name(const struct bPose *pose, const char *name);
struct bPoseChannel *BKE_pose_channel_active(struct Object *ob);
struct bPoseChannel *BKE_pose_channel_active_or_first_selected(struct Object *ob);
struct bPoseChannel *BKE_pose_channel_verify(struct bPose *pose, const char *name);
struct bPoseChannel *BKE_pose_channel_get_mirrored(const struct bPose *pose, const char *name);
+void BKE_pose_check_uuids_unique_and_report(const struct bPose *pose);
+
#ifndef NDEBUG
bool BKE_pose_channels_is_valid(const struct bPose *pose);
#endif
@@ -202,14 +207,14 @@ void what_does_obaction(struct Object *ob,
struct bPose *pose,
struct bAction *act,
char groupname[],
- float cframe);
+ const struct AnimationEvalContext *anim_eval_context);
/* for proxy */
void BKE_pose_copy_pchan_result(struct bPoseChannel *pchanto,
const struct bPoseChannel *pchanfrom);
bool BKE_pose_copy_result(struct bPose *to, struct bPose *from);
-/* clear all transforms */
-void BKE_pose_rest(struct bPose *pose);
+/* Clear transforms. */
+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);
@@ -217,5 +222,3 @@ void BKE_pose_tag_recalc(struct Main *bmain, struct bPose *pose);
#ifdef __cplusplus
};
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_addon.h b/source/blender/blenkernel/BKE_addon.h
index 741be17bb25..73e3f6e41dc 100644
--- a/source/blender/blenkernel/BKE_addon.h
+++ b/source/blender/blenkernel/BKE_addon.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_ADDON_H__
-#define __BKE_ADDON_H__
+#pragma once
/** \file
* \ingroup bke
@@ -56,5 +55,3 @@ void BKE_addon_free(struct bAddon *addon);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_ADDON_H__ */
diff --git a/source/blender/blenkernel/BKE_anim_data.h b/source/blender/blenkernel/BKE_anim_data.h
index 5aeaf4405f5..189e45f4fe5 100644
--- a/source/blender/blenkernel/BKE_anim_data.h
+++ b/source/blender/blenkernel/BKE_anim_data.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_ANIM_DATA_H__
-#define __BKE_ANIM_DATA_H__
+#pragma once
/** \file
* \ingroup bke
@@ -71,7 +70,11 @@ bool BKE_animdata_copy_id(struct Main *bmain,
const int flag);
/* Copy AnimData Actions */
-void BKE_animdata_copy_id_action(struct Main *bmain, struct ID *id, const bool set_newid);
+void BKE_animdata_copy_id_action(struct Main *bmain, struct ID *id);
+
+void BKE_animdata_duplicate_id_action(struct Main *bmain,
+ struct ID *id,
+ const uint duplicate_flags);
/* Merge copies of data from source AnimData block */
typedef enum eAnimData_MergeCopy_Modes {
@@ -94,5 +97,3 @@ void BKE_animdata_merge_copy(struct Main *bmain,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_ANIM_DATA_H__*/
diff --git a/source/blender/blenkernel/BKE_anim_path.h b/source/blender/blenkernel/BKE_anim_path.h
index 4de853303ad..ae2d13530ed 100644
--- a/source/blender/blenkernel/BKE_anim_path.h
+++ b/source/blender/blenkernel/BKE_anim_path.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_ANIM_PATH_H__
-#define __BKE_ANIM_PATH_H__
+#pragma once
/** \file
* \ingroup bke
@@ -47,5 +46,3 @@ bool where_on_path(const struct Object *ob,
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_anim_visualization.h b/source/blender/blenkernel/BKE_anim_visualization.h
index 5dcbfa0919e..fb7875a112e 100644
--- a/source/blender/blenkernel/BKE_anim_visualization.h
+++ b/source/blender/blenkernel/BKE_anim_visualization.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_ANIM_VISUALIZATION_H__
-#define __BKE_ANIM_VISUALIZATION_H__
+#pragma once
/** \file
* \ingroup bke
@@ -52,5 +51,3 @@ struct bMotionPath *animviz_verify_motionpaths(struct ReportList *reports,
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index 4a2ad28f90f..ef74bb61a7e 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_ANIMSYS_H__
-#define __BKE_ANIMSYS_H__
+#pragma once
/** \file
* \ingroup bke
@@ -48,6 +47,23 @@ struct bAction;
struct bActionGroup;
struct bContext;
+/* Container for data required to do FCurve and Driver evaluation. */
+typedef struct AnimationEvalContext {
+ /* For drivers, so that they have access to the dependency graph and the current view layer. See
+ * T77086. */
+ struct Depsgraph *depsgraph;
+
+ /* FCurves and Drivers can be evaluated at a different time than the current scene time, for
+ * example when evaluating NLA strips. This means that, even though the current time is stored in
+ * the dependency graph, we need an explicit evaluation time. */
+ float eval_time;
+} AnimationEvalContext;
+
+AnimationEvalContext BKE_animsys_eval_context_construct(struct Depsgraph *depsgraph,
+ float eval_time);
+AnimationEvalContext BKE_animsys_eval_context_construct_at(
+ const AnimationEvalContext *anim_eval_context, float eval_time);
+
/* ************************************* */
/* KeyingSets API */
@@ -131,17 +147,18 @@ bool BKE_animdata_fix_paths_remove(struct ID *id, const char *path);
/* -------------------------------------- */
+typedef struct AnimationBasePathChange {
+ struct AnimationBasePathChange *next, *prev;
+ const char *src_basepath;
+ const char *dst_basepath;
+} AnimationBasePathChange;
+
/* Move animation data from src to destination if it's paths are based on basepaths */
-void BKE_animdata_separate_by_basepath(struct Main *bmain,
+void BKE_animdata_transfer_by_basepath(struct Main *bmain,
struct ID *srcID,
struct ID *dstID,
struct ListBase *basepaths);
-/* Move F-Curves from src to destination if it's path is based on basepath */
-void action_move_fcurves_by_basepath(struct bAction *srcAct,
- struct bAction *dstAct,
- const char basepath[]);
-
char *BKE_animdata_driver_path_hack(struct bContext *C,
struct PointerRNA *ptr,
struct PropertyRNA *prop,
@@ -172,11 +189,12 @@ void BKE_fcurves_id_cb(struct ID *id, ID_FCurve_Edit_Callback func, void *user_d
typedef struct NlaKeyframingContext NlaKeyframingContext;
-struct NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(struct ListBase *cache,
- struct PointerRNA *ptr,
- struct AnimData *adt,
- float ctime,
- const bool flush_to_original);
+struct NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(
+ struct ListBase *cache,
+ struct PointerRNA *ptr,
+ struct AnimData *adt,
+ const struct AnimationEvalContext *anim_eval_context,
+ const bool flush_to_original);
bool BKE_animsys_nla_remap_keyframe_values(struct NlaKeyframingContext *context,
struct PointerRNA *prop_ptr,
struct PropertyRNA *prop,
@@ -209,7 +227,7 @@ bool BKE_animsys_write_rna_setting(struct PathResolvedRNA *anim_rna, const float
/* Evaluation loop for evaluating animation data */
void BKE_animsys_evaluate_animdata(struct ID *id,
struct AnimData *adt,
- float ctime,
+ const struct AnimationEvalContext *anim_eval_context,
eAnimData_Recalc recalc,
const bool flush_to_original);
@@ -229,14 +247,14 @@ void BKE_animsys_evaluate_all_animation(struct Main *main,
/* Evaluate Action (F-Curve Bag) */
void animsys_evaluate_action(struct PointerRNA *ptr,
struct bAction *act,
- float ctime,
+ const struct AnimationEvalContext *anim_eval_context,
const bool flush_to_original);
/* Evaluate Action Group */
void animsys_evaluate_action_group(struct PointerRNA *ptr,
struct bAction *act,
struct bActionGroup *agrp,
- float ctime);
+ const struct AnimationEvalContext *anim_eval_context);
/* ************************************* */
@@ -257,5 +275,3 @@ void BKE_animsys_update_driver_array(struct ID *id);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_ANIMSYS_H__*/
diff --git a/source/blender/blenkernel/BKE_appdir.h b/source/blender/blenkernel/BKE_appdir.h
index e49fc260810..b8a4497c7be 100644
--- a/source/blender/blenkernel/BKE_appdir.h
+++ b/source/blender/blenkernel/BKE_appdir.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_APPDIR_H__
-#define __BKE_APPDIR_H__
+#pragma once
/** \file
* \ingroup bli
@@ -101,5 +100,3 @@ enum {
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_APPDIR_H__ */
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h
index 6fb6675a05a..6d48397b1af 100644
--- a/source/blender/blenkernel/BKE_armature.h
+++ b/source/blender/blenkernel/BKE_armature.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_ARMATURE_H__
-#define __BKE_ARMATURE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -123,22 +122,24 @@ void get_objectspace_bone_matrix(struct Bone *bone,
float M_accumulatedMatrix[4][4],
int root,
int posed);
-void vec_roll_to_mat3(const float vec[3], const float roll, float mat[3][3]);
-void vec_roll_to_mat3_normalized(const float nor[3], const float roll, float mat[3][3]);
+void vec_roll_to_mat3(const float vec[3], const float roll, float r_mat[3][3]);
+void vec_roll_to_mat3_normalized(const float nor[3], const float roll, float r_mat[3][3]);
void mat3_to_vec_roll(const float mat[3][3], float r_vec[3], float *r_roll);
void mat3_vec_to_roll(const float mat[3][3], const float vec[3], float *r_roll);
/* Common Conversions Between Co-ordinate Spaces */
-void BKE_armature_mat_world_to_pose(struct Object *ob, float inmat[4][4], float outmat[4][4]);
+void BKE_armature_mat_world_to_pose(struct Object *ob,
+ const float inmat[4][4],
+ float outmat[4][4]);
void BKE_armature_loc_world_to_pose(struct Object *ob, const float inloc[3], float outloc[3]);
void BKE_armature_mat_pose_to_bone(struct bPoseChannel *pchan,
- float inmat[4][4],
+ const float inmat[4][4],
float outmat[4][4]);
void BKE_armature_loc_pose_to_bone(struct bPoseChannel *pchan,
const float inloc[3],
float outloc[3]);
void BKE_armature_mat_bone_to_pose(struct bPoseChannel *pchan,
- float inmat[4][4],
+ const float inmat[4][4],
float outmat[4][4]);
void BKE_armature_mat_pose_to_delta(float delta_mat[4][4],
float pose_mat[4][4],
@@ -147,13 +148,13 @@ void BKE_armature_mat_pose_to_delta(float delta_mat[4][4],
void BKE_armature_mat_pose_to_bone_ex(struct Depsgraph *depsgraph,
struct Object *ob,
struct bPoseChannel *pchan,
- float inmat[4][4],
+ const float inmat[4][4],
float outmat[4][4]);
-void BKE_pchan_mat3_to_rot(struct bPoseChannel *pchan, float mat[3][3], bool use_compat);
-void BKE_pchan_rot_to_mat3(const struct bPoseChannel *pchan, float mat[3][3]);
-void BKE_pchan_apply_mat4(struct bPoseChannel *pchan, float mat[4][4], bool use_comat);
-void BKE_pchan_to_mat4(const struct bPoseChannel *pchan, float chan_mat[4][4]);
+void BKE_pchan_mat3_to_rot(struct bPoseChannel *pchan, const float mat[3][3], bool use_compat);
+void BKE_pchan_rot_to_mat3(const struct bPoseChannel *pchan, float r_mat[3][3]);
+void BKE_pchan_apply_mat4(struct bPoseChannel *pchan, const float mat[4][4], bool use_comat);
+void BKE_pchan_to_mat4(const struct bPoseChannel *pchan, float r_mat[4][4]);
void BKE_pchan_calc_mat(struct bPoseChannel *pchan);
/* Simple helper, computes the offset bone matrix. */
@@ -387,5 +388,3 @@ void BKE_armature_deform_coords_with_editmesh(const struct Object *ob_arm,
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_autoexec.h b/source/blender/blenkernel/BKE_autoexec.h
index bb847d49a4b..84d83ae5d30 100644
--- a/source/blender/blenkernel/BKE_autoexec.h
+++ b/source/blender/blenkernel/BKE_autoexec.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_AUTOEXEC_H__
-#define __BKE_AUTOEXEC_H__
+#pragma once
/** \file
* \ingroup bke
@@ -29,5 +28,3 @@ bool BKE_autoexec_match(const char *path);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_AUTOEXEC_H__ */
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index 3feba4b3a66..abc0ce1f092 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_BLENDER_H__
-#define __BKE_BLENDER_H__
+#pragma once
/** \file
* \ingroup bke
@@ -54,5 +53,3 @@ void BKE_blender_atexit(void);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_BLENDER_H__ */
diff --git a/source/blender/blenkernel/BKE_blender_copybuffer.h b/source/blender/blenkernel/BKE_blender_copybuffer.h
index ca20d3d9bba..1dd6d495276 100644
--- a/source/blender/blenkernel/BKE_blender_copybuffer.h
+++ b/source/blender/blenkernel/BKE_blender_copybuffer.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_BLENDER_COPYBUFFER_H__
-#define __BKE_BLENDER_COPYBUFFER_H__
+#pragma once
/** \file
* \ingroup bke
@@ -48,5 +47,3 @@ int BKE_copybuffer_paste(struct bContext *C,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_BLENDER_COPYBUFFER_H__ */
diff --git a/source/blender/blenkernel/BKE_blender_undo.h b/source/blender/blenkernel/BKE_blender_undo.h
index 4ecedbbfc1e..e5ce91df3fb 100644
--- a/source/blender/blenkernel/BKE_blender_undo.h
+++ b/source/blender/blenkernel/BKE_blender_undo.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_BLENDER_UNDO_H__
-#define __BKE_BLENDER_UNDO_H__
+#pragma once
/** \file
* \ingroup bke
@@ -41,5 +40,3 @@ void BKE_memfile_undo_free(struct MemFileUndoData *mfu);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_BLENDER_UNDO_H__ */
diff --git a/source/blender/blenkernel/BKE_blender_user_menu.h b/source/blender/blenkernel/BKE_blender_user_menu.h
index 805a343b976..8d00cde488e 100644
--- a/source/blender/blenkernel/BKE_blender_user_menu.h
+++ b/source/blender/blenkernel/BKE_blender_user_menu.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_BLENDER_USER_MENU_H__
-#define __BKE_BLENDER_USER_MENU_H__
+#pragma once
/** \file
* \ingroup bke
@@ -43,5 +42,3 @@ void BKE_blender_user_menu_item_free_list(struct ListBase *lb);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_BLENDER_USER_MENU_H__ */
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index 229b5193e9c..ae0a669bfb3 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_BLENDER_VERSION_H__
-#define __BKE_BLENDER_VERSION_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -32,7 +31,7 @@ extern "C" {
*/
/* Blender major and minor version. */
-#define BLENDER_VERSION 290
+#define BLENDER_VERSION 291
/* Blender patch version for bugfix releases. */
#define BLENDER_VERSION_PATCH 0
/** Blender release cycle stage: alpha/beta/rc/release. */
@@ -40,7 +39,7 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
-#define BLENDER_FILE_SUBVERSION 5
+#define BLENDER_FILE_SUBVERSION 0
/* 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
@@ -54,5 +53,3 @@ const char *BKE_blender_version_string(void);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_BLENDER_VERSION_H__ */
diff --git a/source/blender/blenkernel/BKE_blendfile.h b/source/blender/blenkernel/BKE_blendfile.h
index e835137bfa1..94d203eeb2c 100644
--- a/source/blender/blenkernel/BKE_blendfile.h
+++ b/source/blender/blenkernel/BKE_blendfile.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_BLENDFILE_H__
-#define __BKE_BLENDFILE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -81,5 +80,3 @@ void BKE_blendfile_write_partial_end(struct Main *bmain_src);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_BLENDFILE_H__ */
diff --git a/source/blender/blenkernel/BKE_boids.h b/source/blender/blenkernel/BKE_boids.h
index f9fd814b5f2..c9e6f0e7346 100644
--- a/source/blender/blenkernel/BKE_boids.h
+++ b/source/blender/blenkernel/BKE_boids.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_BOIDS_H__
-#define __BKE_BOIDS_H__
+#pragma once
/** \file
* \ingroup bke
@@ -62,5 +61,3 @@ BoidState *boid_get_current_state(BoidSettings *boids);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_bpath.h b/source/blender/blenkernel/BKE_bpath.h
index cc8dd0d5b33..787dc4d1147 100644
--- a/source/blender/blenkernel/BKE_bpath.h
+++ b/source/blender/blenkernel/BKE_bpath.h
@@ -20,8 +20,7 @@
* so for BPath we don't need to malloc
*/
-#ifndef __BKE_BPATH_H__
-#define __BKE_BPATH_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -92,5 +91,3 @@ void BKE_bpath_absolute_convert(struct Main *bmain,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_BPATH_H__ */
diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h
index 4e9430ab3e1..af299c917eb 100644
--- a/source/blender/blenkernel/BKE_brush.h
+++ b/source/blender/blenkernel/BKE_brush.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_BRUSH_H__
-#define __BKE_BRUSH_H__
+#pragma once
/** \file
* \ingroup bke
@@ -157,5 +156,3 @@ void BKE_brush_debug_print_state(struct Brush *br);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_bvhutils.h b/source/blender/blenkernel/BKE_bvhutils.h
index 5d7e8fe743e..e973bee9e20 100644
--- a/source/blender/blenkernel/BKE_bvhutils.h
+++ b/source/blender/blenkernel/BKE_bvhutils.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2006 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_BVHUTILS_H__
-#define __BKE_BVHUTILS_H__
+#pragma once
/** \file
* \ingroup bke
@@ -263,5 +262,3 @@ void bvhcache_free(struct BVHCache *bvh_cache);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_cachefile.h b/source/blender/blenkernel/BKE_cachefile.h
index 596085f9c6f..9912b4e4b70 100644
--- a/source/blender/blenkernel/BKE_cachefile.h
+++ b/source/blender/blenkernel/BKE_cachefile.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_CACHEFILE_H__
-#define __BKE_CACHEFILE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -66,5 +65,3 @@ void BKE_cachefile_reader_free(struct CacheFile *cache_file, struct CacheReader
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_CACHEFILE_H__ */
diff --git a/source/blender/blenkernel/BKE_callbacks.h b/source/blender/blenkernel/BKE_callbacks.h
index 284948da634..fadba5644de 100644
--- a/source/blender/blenkernel/BKE_callbacks.h
+++ b/source/blender/blenkernel/BKE_callbacks.h
@@ -18,8 +18,7 @@
* \ingroup bke
*/
-#ifndef __BKE_CALLBACKS_H__
-#define __BKE_CALLBACKS_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -88,5 +87,3 @@ void BKE_callback_global_finalize(void);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_CALLBACKS_H__ */
diff --git a/source/blender/blenkernel/BKE_camera.h b/source/blender/blenkernel/BKE_camera.h
index 812f5d520d7..533d5ae13cd 100644
--- a/source/blender/blenkernel/BKE_camera.h
+++ b/source/blender/blenkernel/BKE_camera.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_CAMERA_H__
-#define __BKE_CAMERA_H__
+#pragma once
/** \file
* \ingroup bke
@@ -167,5 +166,3 @@ void BKE_camera_background_image_clear(struct Camera *cam);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_ccg.h b/source/blender/blenkernel/BKE_ccg.h
index ad1e05ee367..acdaa81da8d 100644
--- a/source/blender/blenkernel/BKE_ccg.h
+++ b/source/blender/blenkernel/BKE_ccg.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_CCG_H__
-#define __BKE_CCG_H__
+#pragma once
/** \file
* \ingroup bke
@@ -166,5 +165,3 @@ BLI_INLINE CCGElem *CCG_elem_next(const CCGKey *key, CCGElem *elem)
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_cdderivedmesh.h b/source/blender/blenkernel/BKE_cdderivedmesh.h
index dd7d20c0407..e997678001f 100644
--- a/source/blender/blenkernel/BKE_cdderivedmesh.h
+++ b/source/blender/blenkernel/BKE_cdderivedmesh.h
@@ -26,8 +26,7 @@
* \note This is deprecated & should eventually be removed.
*/
-#ifndef __BKE_CDDERIVEDMESH_H__
-#define __BKE_CDDERIVEDMESH_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -49,5 +48,3 @@ struct DerivedMesh *CDDM_copy(struct DerivedMesh *dm);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h
index f25482570b1..5af37829577 100644
--- a/source/blender/blenkernel/BKE_cloth.h
+++ b/source/blender/blenkernel/BKE_cloth.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) Blender Foundation.
* All rights reserved.
*/
-#ifndef __BKE_CLOTH_H__
-#define __BKE_CLOTH_H__
+#pragma once
/** \file
* \ingroup bke
@@ -93,10 +92,10 @@ typedef struct Cloth {
struct Implicit_Data *implicit; /* our implicit solver connects to this pointer */
struct EdgeSet *edgeset; /* used for selfcollisions */
int last_frame;
- float initial_mesh_volume; /* Initial volume of the mesh. Used for pressure */
- float average_acceleration[3]; /* Moving average of overall acceleration. */
- struct MEdge *edges; /* Used for hair collisions. */
- struct GHash *sew_edge_graph; /* Sewing edges represented using a GHash */
+ float initial_mesh_volume; /* Initial volume of the mesh. Used for pressure */
+ float average_acceleration[3]; /* Moving average of overall acceleration. */
+ struct MEdge *edges; /* Used for hair collisions. */
+ struct EdgeSet *sew_edge_graph; /* Sewing edges represented using a GHash */
} Cloth;
/**
@@ -307,5 +306,3 @@ void cloth_parallel_transport_hair_frame(float mat[3][3],
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h
index 4cf33640ebd..f4393742dff 100644
--- a/source/blender/blenkernel/BKE_collection.h
+++ b/source/blender/blenkernel/BKE_collection.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_COLLECTION_H__
-#define __BKE_COLLECTION_H__
+#pragma once
/** \file
* \ingroup bke
@@ -56,6 +55,10 @@ void BKE_collection_add_from_object(struct Main *bmain,
struct Scene *scene,
const struct Object *ob_src,
struct Collection *collection_dst);
+void BKE_collection_add_from_collection(struct Main *bmain,
+ struct Scene *scene,
+ struct Collection *collection_src,
+ struct Collection *collection_dst);
void BKE_collection_free(struct Collection *collection);
bool BKE_collection_delete(struct Main *bmain, struct Collection *collection, bool hierarchy);
@@ -149,7 +152,8 @@ bool BKE_collection_move(struct Main *bmain,
bool relative_after,
struct Collection *collection);
-bool BKE_collection_find_cycle(struct Collection *new_ancestor, struct Collection *collection);
+bool BKE_collection_cycle_find(struct Collection *new_ancestor, struct Collection *collection);
+bool BKE_collection_cycles_fix(struct Main *bmain, struct Collection *collection);
bool BKE_collection_has_collection(struct Collection *parent, struct Collection *collection);
@@ -250,5 +254,3 @@ void BKE_scene_objects_iterator_end(struct BLI_Iterator *iter);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_COLLECTION_H__ */
diff --git a/source/blender/blenkernel/BKE_collision.h b/source/blender/blenkernel/BKE_collision.h
index c3ecd0b7ed0..579adb61057 100644
--- a/source/blender/blenkernel/BKE_collision.h
+++ b/source/blender/blenkernel/BKE_collision.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) Blender Foundation.
* All rights reserved.
*/
-#ifndef __BKE_COLLISION_H__
-#define __BKE_COLLISION_H__
+#pragma once
/** \file
* \ingroup bke
@@ -178,5 +177,3 @@ void BKE_collider_cache_free(struct ListBase **colliders);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_colorband.h b/source/blender/blenkernel/BKE_colorband.h
index 355682671fe..6ac96a1ed36 100644
--- a/source/blender/blenkernel/BKE_colorband.h
+++ b/source/blender/blenkernel/BKE_colorband.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_COLORBAND_H__
-#define __BKE_COLORBAND_H__
+#pragma once
/** \file
* \ingroup bke
@@ -47,5 +46,3 @@ void BKE_colorband_update_sort(struct ColorBand *coba);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_COLORBAND_H__ */
diff --git a/source/blender/blenkernel/BKE_colortools.h b/source/blender/blenkernel/BKE_colortools.h
index 0623e0e5395..1ada83c0163 100644
--- a/source/blender/blenkernel/BKE_colortools.h
+++ b/source/blender/blenkernel/BKE_colortools.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2006 Blender Foundation.
* All rights reserved.
*/
-#ifndef __BKE_COLORTOOLS_H__
-#define __BKE_COLORTOOLS_H__
+#pragma once
/** \file
* \ingroup bke
@@ -70,7 +69,7 @@ void BKE_curvemapping_changed(struct CurveMapping *cumap, const bool rem_doubles
void BKE_curvemapping_changed_all(struct CurveMapping *cumap);
/* call before _all_ evaluation functions */
-void BKE_curvemapping_initialize(struct CurveMapping *cumap);
+void BKE_curvemapping_init(struct CurveMapping *cumap);
/* keep these (const CurveMap) - to help with thread safety */
/* single curve, no table check */
@@ -152,5 +151,3 @@ bool BKE_color_managed_colorspace_settings_equals(
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h
index 8d7fe875c37..94349f4db22 100644
--- a/source/blender/blenkernel/BKE_constraint.h
+++ b/source/blender/blenkernel/BKE_constraint.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_CONSTRAINT_H__
-#define __BKE_CONSTRAINT_H__
+#pragma once
/** \file
* \ingroup bke
@@ -224,5 +223,3 @@ void BKE_constraints_solve(struct Depsgraph *depsgraph,
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h
index 70ca29d5795..eb26f1c3969 100644
--- a/source/blender/blenkernel/BKE_context.h
+++ b/source/blender/blenkernel/BKE_context.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_CONTEXT_H__
-#define __BKE_CONTEXT_H__
+#pragma once
/** \file
* \ingroup bke
@@ -312,6 +311,8 @@ int CTX_data_visible_gpencil_layers(const bContext *C, ListBase *list);
int CTX_data_editable_gpencil_layers(const bContext *C, ListBase *list);
int CTX_data_editable_gpencil_strokes(const bContext *C, ListBase *list);
+bool CTX_wm_interface_locked(const bContext *C);
+
/* Gets pointer to the dependency graph.
* If it doesn't exist yet, it will be allocated.
*
@@ -344,5 +345,3 @@ struct Depsgraph *CTX_data_depsgraph_on_load(const bContext *C);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_crazyspace.h b/source/blender/blenkernel/BKE_crazyspace.h
index 6ac6b17d468..b95be70379f 100644
--- a/source/blender/blenkernel/BKE_crazyspace.h
+++ b/source/blender/blenkernel/BKE_crazyspace.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __BKE_CRAZYSPACE_H__
-#define __BKE_CRAZYSPACE_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -65,5 +64,3 @@ void BKE_crazyspace_build_sculpt(struct Depsgraph *depsgraph,
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index d32ab474229..0bd4e3a7582 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_CURVE_H__
-#define __BKE_CURVE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -98,15 +97,15 @@ bool BKE_curve_minmax(struct Curve *cu, bool use_radius, float min[3], float max
bool BKE_curve_center_median(struct Curve *cu, float cent[3]);
bool BKE_curve_center_bounds(struct Curve *cu, float cent[3]);
void BKE_curve_transform_ex(struct Curve *cu,
- float mat[4][4],
+ const float mat[4][4],
const bool do_keys,
const bool do_props,
const float unit_scale);
void BKE_curve_transform(struct Curve *cu,
- float mat[4][4],
+ const float mat[4][4],
const bool do_keys,
const bool do_props);
-void BKE_curve_translate(struct Curve *cu, float offset[3], const bool do_keys);
+void BKE_curve_translate(struct Curve *cu, const float offset[3], const bool do_keys);
void BKE_curve_material_index_remove(struct Curve *cu, int index);
bool BKE_curve_material_index_used(struct Curve *cu, int index);
void BKE_curve_material_index_clear(struct Curve *cu);
@@ -140,7 +139,7 @@ void BKE_curve_nurbs_vert_coords_apply(struct ListBase *lb,
float (*BKE_curve_nurbs_key_vert_coords_alloc(struct ListBase *lb,
float *key,
int *r_vert_len))[3];
-void BKE_curve_nurbs_key_vert_tilts_apply(struct ListBase *lb, float *key);
+void BKE_curve_nurbs_key_vert_tilts_apply(struct ListBase *lb, const float *key);
void BKE_curve_editNurb_keyIndex_delCV(struct GHash *keyindex, const void *cv);
void BKE_curve_editNurb_keyIndex_free(struct GHash **keyindex);
@@ -339,5 +338,3 @@ void BKE_curve_deform_co(const struct Object *ob_curve,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_CURVE_H__ */
diff --git a/source/blender/blenkernel/BKE_curveprofile.h b/source/blender/blenkernel/BKE_curveprofile.h
index 877ab887138..9c72a866fa9 100644
--- a/source/blender/blenkernel/BKE_curveprofile.h
+++ b/source/blender/blenkernel/BKE_curveprofile.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_CURVEPROFILE_H__
-#define __BKE_CURVEPROFILE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -72,7 +71,7 @@ void BKE_curveprofile_create_samples(struct CurveProfile *profile,
bool sample_straight_edges,
struct CurveProfilePoint *r_samples);
-void BKE_curveprofile_initialize(struct CurveProfile *profile, short segments_len);
+void BKE_curveprofile_init(struct CurveProfile *profile, short segments_len);
/* Called for a complete update of the widget after modifications */
enum {
@@ -101,5 +100,3 @@ void BKE_curveprofile_blend_read(struct BlendDataReader *reader, struct CurvePro
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index 42beda352f5..92bfa3a9490 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -22,8 +22,7 @@
* \brief CustomData interface, see also DNA_customdata_types.h.
*/
-#ifndef __BKE_CUSTOMDATA_H__
-#define __BKE_CUSTOMDATA_H__
+#pragma once
#include "BLI_sys_types.h"
#include "BLI_utildefines.h"
@@ -455,6 +454,7 @@ bool CustomData_from_bmeshpoly_test(CustomData *fdata, CustomData *ldata, bool f
bool CustomData_layer_validate(struct CustomDataLayer *layer,
const uint totitems,
const bool do_fixes);
+void CustomData_layers__print(struct CustomData *data);
/* External file storage */
@@ -574,5 +574,3 @@ void CustomData_data_transfer(const struct MeshPairRemap *me_remap,
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_customdata_file.h b/source/blender/blenkernel/BKE_customdata_file.h
index 2be2f71a168..f9f02204bb9 100644
--- a/source/blender/blenkernel/BKE_customdata_file.h
+++ b/source/blender/blenkernel/BKE_customdata_file.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_CUSTOMDATA_FILE_H__
-#define __BKE_CUSTOMDATA_FILE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -60,5 +59,3 @@ CDataFileLayer *cdf_layer_add(CDataFile *cdf, int type, const char *name, size_t
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_CUSTOMDATA_FILE_H__ */
diff --git a/source/blender/blenkernel/BKE_data_transfer.h b/source/blender/blenkernel/BKE_data_transfer.h
index a723a9ed38c..d861baba14d 100644
--- a/source/blender/blenkernel/BKE_data_transfer.h
+++ b/source/blender/blenkernel/BKE_data_transfer.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __BKE_DATA_TRANSFER_H__
-#define __BKE_DATA_TRANSFER_H__
+#pragma once
#include "BKE_customdata.h"
@@ -181,5 +180,3 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_DATA_TRANSFER_H__ */
diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h
index 04b85aebb39..35111d5240e 100644
--- a/source/blender/blenkernel/BKE_deform.h
+++ b/source/blender/blenkernel/BKE_deform.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_DEFORM_H__
-#define __BKE_DEFORM_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -111,7 +110,7 @@ void BKE_defvert_sync_mapped(struct MDeformVert *dvert_dst,
const int *flip_map,
const int flip_map_len,
const bool use_ensure);
-void BKE_defvert_remap(struct MDeformVert *dvert, int *map, const int map_len);
+void BKE_defvert_remap(struct MDeformVert *dvert, const int *map, const int map_len);
void BKE_defvert_flip(struct MDeformVert *dvert, const int *flip_map, const int flip_map_len);
void BKE_defvert_flip_merged(struct MDeformVert *dvert,
const int *flip_map,
@@ -166,5 +165,3 @@ void BKE_defvert_weight_to_rgb(float r_rgb[3], const float weight);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_DEFORM_H__ */
diff --git a/source/blender/blenkernel/BKE_derived_node_tree.hh b/source/blender/blenkernel/BKE_derived_node_tree.hh
deleted file mode 100644
index 2ed96f0c60d..00000000000
--- a/source/blender/blenkernel/BKE_derived_node_tree.hh
+++ /dev/null
@@ -1,498 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef __BKE_DERIVED_NODE_TREE_HH__
-#define __BKE_DERIVED_NODE_TREE_HH__
-
-/** \file
- * \ingroup bke
- *
- * DerivedNodeTree provides a flattened view on a bNodeTree, i.e. node groups are inlined. It
- * builds on top of NodeTreeRef and supports similar queries efficiently.
- *
- * Every inlined node remembers its path to the parent ("call stack").
- *
- * Unlinked group node inputs are handled separately from other sockets.
- *
- * There is a dot graph exporter for debugging purposes.
- */
-
-#include "BKE_node_tree_ref.hh"
-
-namespace blender::bke {
-
-class DSocket;
-class DInputSocket;
-class DOutputSocket;
-class DNode;
-class DParentNode;
-class DGroupInput;
-class DerivedNodeTree;
-
-class DSocket : NonCopyable, NonMovable {
- protected:
- DNode *node_;
- const SocketRef *socket_ref_;
- uint id_;
-
- friend DerivedNodeTree;
-
- public:
- const DNode &node() const;
-
- uint id() const;
- uint index() const;
-
- bool is_input() const;
- bool is_output() const;
-
- const DSocket &as_base() const;
- const DInputSocket &as_input() const;
- const DOutputSocket &as_output() const;
-
- PointerRNA *rna() const;
- StringRefNull idname() const;
- StringRefNull name() const;
-
- const SocketRef &socket_ref() const;
- bNodeSocket *bsocket() const;
-
- bool is_available() const;
-};
-
-class DInputSocket : public DSocket {
- private:
- Vector<DOutputSocket *> linked_sockets_;
- Vector<DGroupInput *> linked_group_inputs_;
-
- friend DerivedNodeTree;
-
- public:
- const InputSocketRef &socket_ref() const;
-
- Span<const DOutputSocket *> linked_sockets() const;
- Span<const DGroupInput *> linked_group_inputs() const;
-
- bool is_linked() const;
-};
-
-class DOutputSocket : public DSocket {
- private:
- Vector<DInputSocket *> linked_sockets_;
-
- friend DerivedNodeTree;
-
- public:
- const OutputSocketRef &socket_ref() const;
- Span<const DInputSocket *> linked_sockets() const;
-};
-
-class DGroupInput : NonCopyable, NonMovable {
- private:
- const InputSocketRef *socket_ref_;
- DParentNode *parent_;
- Vector<DInputSocket *> linked_sockets_;
- uint id_;
-
- friend DerivedNodeTree;
-
- public:
- const InputSocketRef &socket_ref() const;
- bNodeSocket *bsocket() const;
- const DParentNode *parent() const;
- Span<const DInputSocket *> linked_sockets() const;
- uint id() const;
- StringRefNull name() const;
-};
-
-class DNode : NonCopyable, NonMovable {
- private:
- const NodeRef *node_ref_;
- DParentNode *parent_;
-
- Span<DInputSocket *> inputs_;
- Span<DOutputSocket *> outputs_;
-
- uint id_;
-
- friend DerivedNodeTree;
-
- public:
- const NodeRef &node_ref() const;
- const DParentNode *parent() const;
-
- Span<const DInputSocket *> inputs() const;
- Span<const DOutputSocket *> outputs() const;
-
- const DInputSocket &input(uint index) const;
- const DOutputSocket &output(uint index) const;
-
- uint id() const;
-
- PointerRNA *rna() const;
- StringRefNull idname() const;
- StringRefNull name() const;
-
- private:
- void destruct_with_sockets();
-};
-
-class DParentNode : NonCopyable, NonMovable {
- private:
- const NodeRef *node_ref_;
- DParentNode *parent_;
- uint id_;
-
- friend DerivedNodeTree;
-
- public:
- const DParentNode *parent() const;
- const NodeRef &node_ref() const;
- uint id() const;
-};
-
-using NodeTreeRefMap = Map<bNodeTree *, std::unique_ptr<const NodeTreeRef>>;
-
-class DerivedNodeTree : NonCopyable, NonMovable {
- private:
- LinearAllocator<> allocator_;
- bNodeTree *btree_;
- Vector<DNode *> nodes_by_id_;
- Vector<DGroupInput *> group_inputs_;
- Vector<DParentNode *> parent_nodes_;
-
- Vector<DSocket *> sockets_by_id_;
- Vector<DInputSocket *> input_sockets_;
- Vector<DOutputSocket *> output_sockets_;
-
- Map<const bNodeType *, Vector<DNode *>> nodes_by_type_;
-
- public:
- DerivedNodeTree(bNodeTree *btree, NodeTreeRefMap &node_tree_refs);
- ~DerivedNodeTree();
-
- Span<const DNode *> nodes() const;
- Span<const DNode *> nodes_by_type(StringRefNull idname) const;
- Span<const DNode *> nodes_by_type(const bNodeType *nodetype) const;
-
- Span<const DSocket *> sockets() const;
- Span<const DInputSocket *> input_sockets() const;
- Span<const DOutputSocket *> output_sockets() const;
-
- Span<const DGroupInput *> group_inputs() const;
-
- std::string to_dot() const;
-
- private:
- /* Utility functions used during construction. */
- void insert_nodes_and_links_in_id_order(const NodeTreeRef &tree_ref,
- DParentNode *parent,
- Vector<DNode *> &all_nodes);
- DNode &create_node(const NodeRef &node_ref,
- DParentNode *parent,
- MutableSpan<DSocket *> r_sockets_map);
- void expand_groups(Vector<DNode *> &all_nodes,
- Vector<DGroupInput *> &all_group_inputs,
- Vector<DParentNode *> &all_parent_nodes,
- NodeTreeRefMap &node_tree_refs);
- void expand_group_node(DNode &group_node,
- Vector<DNode *> &all_nodes,
- Vector<DGroupInput *> &all_group_inputs,
- Vector<DParentNode *> &all_parent_nodes,
- NodeTreeRefMap &node_tree_refs);
- void create_group_inputs_for_unlinked_inputs(DNode &node,
- Vector<DGroupInput *> &all_group_inputs);
- void relink_group_inputs(const NodeTreeRef &group_ref,
- Span<DNode *> nodes_by_id,
- DNode &group_node);
- void relink_group_outputs(const NodeTreeRef &group_ref,
- Span<DNode *> nodes_by_id,
- DNode &group_node);
- void remove_expanded_group_interfaces(Vector<DNode *> &all_nodes);
- void remove_unused_group_inputs(Vector<DGroupInput *> &all_group_inputs);
- void store_in_this_and_init_ids(Vector<DNode *> &&all_nodes,
- Vector<DGroupInput *> &&all_group_inputs,
- Vector<DParentNode *> &&all_parent_nodes);
-};
-
-/* --------------------------------------------------------------------
- * DSocket inline methods.
- */
-
-inline const DNode &DSocket::node() const
-{
- return *node_;
-}
-
-inline uint DSocket::id() const
-{
- return id_;
-}
-
-inline uint DSocket::index() const
-{
- return socket_ref_->index();
-}
-
-inline bool DSocket::is_input() const
-{
- return socket_ref_->is_input();
-}
-
-inline bool DSocket::is_output() const
-{
- return socket_ref_->is_output();
-}
-
-inline const DSocket &DSocket::as_base() const
-{
- return *this;
-}
-
-inline const DInputSocket &DSocket::as_input() const
-{
- return *(DInputSocket *)this;
-}
-
-inline const DOutputSocket &DSocket::as_output() const
-{
- return *(DOutputSocket *)this;
-}
-
-inline PointerRNA *DSocket::rna() const
-{
- return socket_ref_->rna();
-}
-
-inline StringRefNull DSocket::idname() const
-{
- return socket_ref_->idname();
-}
-
-inline StringRefNull DSocket::name() const
-{
- return socket_ref_->name();
-}
-
-inline const SocketRef &DSocket::socket_ref() const
-{
- return *socket_ref_;
-}
-
-inline bNodeSocket *DSocket::bsocket() const
-{
- return socket_ref_->bsocket();
-}
-
-inline bool DSocket::is_available() const
-{
- return (socket_ref_->bsocket()->flag & SOCK_UNAVAIL) == 0;
-}
-
-/* --------------------------------------------------------------------
- * DInputSocket inline methods.
- */
-
-inline const InputSocketRef &DInputSocket::socket_ref() const
-{
- return socket_ref_->as_input();
-}
-
-inline Span<const DOutputSocket *> DInputSocket::linked_sockets() const
-{
- return linked_sockets_.as_span();
-}
-
-inline Span<const DGroupInput *> DInputSocket::linked_group_inputs() const
-{
- return linked_group_inputs_.as_span();
-}
-
-inline bool DInputSocket::is_linked() const
-{
- return linked_sockets_.size() > 0 || linked_group_inputs_.size() > 0;
-}
-
-/* --------------------------------------------------------------------
- * DOutputSocket inline methods.
- */
-
-inline const OutputSocketRef &DOutputSocket::socket_ref() const
-{
- return socket_ref_->as_output();
-}
-
-inline Span<const DInputSocket *> DOutputSocket::linked_sockets() const
-{
- return linked_sockets_.as_span();
-}
-
-/* --------------------------------------------------------------------
- * DGroupInput inline methods.
- */
-
-inline const InputSocketRef &DGroupInput::socket_ref() const
-{
- return *socket_ref_;
-}
-
-inline bNodeSocket *DGroupInput::bsocket() const
-{
- return socket_ref_->bsocket();
-}
-
-inline const DParentNode *DGroupInput::parent() const
-{
- return parent_;
-}
-
-inline Span<const DInputSocket *> DGroupInput::linked_sockets() const
-{
- return linked_sockets_.as_span();
-}
-
-inline uint DGroupInput::id() const
-{
- return id_;
-}
-
-inline StringRefNull DGroupInput::name() const
-{
- return socket_ref_->name();
-}
-
-/* --------------------------------------------------------------------
- * DNode inline methods.
- */
-
-inline const NodeRef &DNode::node_ref() const
-{
- return *node_ref_;
-}
-
-inline const DParentNode *DNode::parent() const
-{
- return parent_;
-}
-
-inline Span<const DInputSocket *> DNode::inputs() const
-{
- return inputs_;
-}
-
-inline Span<const DOutputSocket *> DNode::outputs() const
-{
- return outputs_;
-}
-
-inline const DInputSocket &DNode::input(uint index) const
-{
- return *inputs_[index];
-}
-
-inline const DOutputSocket &DNode::output(uint index) const
-{
- return *outputs_[index];
-}
-
-inline uint DNode::id() const
-{
- return id_;
-}
-
-inline PointerRNA *DNode::rna() const
-{
- return node_ref_->rna();
-}
-
-inline StringRefNull DNode::idname() const
-{
- return node_ref_->idname();
-}
-
-inline StringRefNull DNode::name() const
-{
- return node_ref_->name();
-}
-
-/* --------------------------------------------------------------------
- * DParentNode inline methods.
- */
-
-inline const DParentNode *DParentNode::parent() const
-{
- return parent_;
-}
-
-inline const NodeRef &DParentNode::node_ref() const
-{
- return *node_ref_;
-}
-
-inline uint DParentNode::id() const
-{
- return id_;
-}
-
-/* --------------------------------------------------------------------
- * DerivedNodeTree inline methods.
- */
-
-inline Span<const DNode *> DerivedNodeTree::nodes() const
-{
- return nodes_by_id_.as_span();
-}
-
-inline Span<const DNode *> DerivedNodeTree::nodes_by_type(StringRefNull idname) const
-{
- const bNodeType *nodetype = nodeTypeFind(idname.data());
- return this->nodes_by_type(nodetype);
-}
-
-inline Span<const DNode *> DerivedNodeTree::nodes_by_type(const bNodeType *nodetype) const
-{
- const Vector<DNode *> *nodes = nodes_by_type_.lookup_ptr(nodetype);
- if (nodes == nullptr) {
- return {};
- }
- else {
- return nodes->as_span();
- }
-}
-
-inline Span<const DSocket *> DerivedNodeTree::sockets() const
-{
- return sockets_by_id_.as_span();
-}
-
-inline Span<const DInputSocket *> DerivedNodeTree::input_sockets() const
-{
- return input_sockets_.as_span();
-}
-
-inline Span<const DOutputSocket *> DerivedNodeTree::output_sockets() const
-{
- return output_sockets_.as_span();
-}
-
-inline Span<const DGroupInput *> DerivedNodeTree::group_inputs() const
-{
- return group_inputs_.as_span();
-}
-
-} // namespace blender::bke
-
-#endif /* __BKE_DERIVED_NODE_TREE_HH__ */
diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h
index b7e4acdc636..7e1a6e54ede 100644
--- a/source/blender/blenkernel/BKE_displist.h
+++ b/source/blender/blenkernel/BKE_displist.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_DISPLIST_H__
-#define __BKE_DISPLIST_H__
+#pragma once
/** \file
* \ingroup bke
@@ -119,5 +118,3 @@ void BKE_displist_minmax(struct ListBase *dispbase, float min[3], float max[3]);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_displist_tangent.h b/source/blender/blenkernel/BKE_displist_tangent.h
index 5e1c6ac8a21..c91c2c97dda 100644
--- a/source/blender/blenkernel/BKE_displist_tangent.h
+++ b/source/blender/blenkernel/BKE_displist_tangent.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_DISPLIST_TANGENT_H__
-#define __BKE_DISPLIST_TANGENT_H__
+#pragma once
/** \file
* \ingroup bke
@@ -30,5 +29,3 @@ void BKE_displist_tangent_calc(const DispList *dl, float (*fnormals)[3], float (
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_DISPLIST_TANGENT_H__ */
diff --git a/source/blender/blenkernel/BKE_duplilist.h b/source/blender/blenkernel/BKE_duplilist.h
index 71b6d06b450..c142d5338d1 100644
--- a/source/blender/blenkernel/BKE_duplilist.h
+++ b/source/blender/blenkernel/BKE_duplilist.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_DUPLILIST_H__
-#define __BKE_DUPLILIST_H__
+#pragma once
/** \file
* \ingroup bke
@@ -52,7 +51,7 @@ typedef struct DupliObject {
/* Persistent identifier for a dupli object, for inter-frame matching of
* objects with motion blur, or inter-update matching for syncing. */
- int persistent_id[16]; /* 2*MAX_DUPLI_RECUR */
+ int persistent_id[8]; /* MAX_DUPLI_RECUR */
/* Particle this dupli was generated from. */
struct ParticleSystem *particle_system;
@@ -64,5 +63,3 @@ typedef struct DupliObject {
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_dynamicpaint.h b/source/blender/blenkernel/BKE_dynamicpaint.h
index 5e3603a8339..99b58b2f40a 100644
--- a/source/blender/blenkernel/BKE_dynamicpaint.h
+++ b/source/blender/blenkernel/BKE_dynamicpaint.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_DYNAMICPAINT_H__
-#define __BKE_DYNAMICPAINT_H__
+#pragma once
/** \file
* \ingroup bke
@@ -124,5 +123,3 @@ void dynamicPaint_outputSurfaceImage(struct DynamicPaintSurface *surface,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_DYNAMICPAINT_H__ */
diff --git a/source/blender/blenkernel/BKE_editlattice.h b/source/blender/blenkernel/BKE_editlattice.h
index c587ddb551b..be791487c27 100644
--- a/source/blender/blenkernel/BKE_editlattice.h
+++ b/source/blender/blenkernel/BKE_editlattice.h
@@ -18,8 +18,7 @@
* \ingroup bke
*/
-#ifndef __BKE_EDITLATTICE_H__
-#define __BKE_EDITLATTICE_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -34,5 +33,3 @@ void BKE_editlattice_load(struct Object *obedit);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_EDITLATTICE_H__ */
diff --git a/source/blender/blenkernel/BKE_editmesh.h b/source/blender/blenkernel/BKE_editmesh.h
index 9bd62858902..819e91b438e 100644
--- a/source/blender/blenkernel/BKE_editmesh.h
+++ b/source/blender/blenkernel/BKE_editmesh.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_EDITMESH_H__
-#define __BKE_EDITMESH_H__
+#pragma once
/** \file
* \ingroup bke
@@ -107,5 +106,3 @@ struct BoundBox *BKE_editmesh_cage_boundbox_get(BMEditMesh *em);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_EDITMESH_H__ */
diff --git a/source/blender/blenkernel/BKE_editmesh_bvh.h b/source/blender/blenkernel/BKE_editmesh_bvh.h
index b8d1e26fad2..8f8e573ee2f 100644
--- a/source/blender/blenkernel/BKE_editmesh_bvh.h
+++ b/source/blender/blenkernel/BKE_editmesh_bvh.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __BKE_EDITMESH_BVH_H__
-#define __BKE_EDITMESH_BVH_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -104,5 +103,3 @@ enum {
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_EDITMESH_BVH_H__ */
diff --git a/source/blender/blenkernel/BKE_editmesh_cache.h b/source/blender/blenkernel/BKE_editmesh_cache.h
index 6c812098b2e..bc2a70124fe 100644
--- a/source/blender/blenkernel/BKE_editmesh_cache.h
+++ b/source/blender/blenkernel/BKE_editmesh_cache.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_EDITMESH_CACHE_H__
-#define __BKE_EDITMESH_CACHE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -41,5 +40,3 @@ bool BKE_editmesh_cache_calc_minmax(struct BMEditMesh *em,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_EDITMESH_CACHE_H__ */
diff --git a/source/blender/blenkernel/BKE_editmesh_tangent.h b/source/blender/blenkernel/BKE_editmesh_tangent.h
index 27f24438528..0e3f063ae44 100644
--- a/source/blender/blenkernel/BKE_editmesh_tangent.h
+++ b/source/blender/blenkernel/BKE_editmesh_tangent.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_EDITMESH_TANGENT_H__
-#define __BKE_EDITMESH_TANGENT_H__
+#pragma once
/** \file
* \ingroup bke
@@ -39,5 +38,3 @@ void BKE_editmesh_loop_tangent_calc(BMEditMesh *em,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_EDITMESH_TANGENT_H__ */
diff --git a/source/blender/blenkernel/BKE_effect.h b/source/blender/blenkernel/BKE_effect.h
index 0518ce8ffa3..0585f67703c 100644
--- a/source/blender/blenkernel/BKE_effect.h
+++ b/source/blender/blenkernel/BKE_effect.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_EFFECT_H__
-#define __BKE_EFFECT_H__
+#pragma once
/** \file
* \ingroup bke
@@ -283,5 +282,3 @@ void BKE_sim_debug_data_clear_category(const char *category);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h
index c3a597e29b9..3717eb0f282 100644
--- a/source/blender/blenkernel/BKE_fcurve.h
+++ b/source/blender/blenkernel/BKE_fcurve.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_FCURVE_H__
-#define __BKE_FCURVE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -36,6 +35,7 @@ struct FCurve;
struct FModifier;
struct AnimData;
+struct AnimationEvalContext;
struct BezTriple;
struct LibraryForeachIDData;
struct PathResolvedRNA;
@@ -271,7 +271,7 @@ void testhandles_fcurve(struct FCurve *fcu, eBezTriple_Flag sel_flag, const bool
void sort_time_fcurve(struct FCurve *fcu);
short test_time_fcurve(struct FCurve *fcu);
-void correct_bezpart(float v1[2], float v2[2], float v3[2], float v4[2]);
+void correct_bezpart(const float v1[2], float v2[2], float v3[2], const float v4[2]);
/* -------- Evaluation -------- */
@@ -281,10 +281,12 @@ float evaluate_fcurve_only_curve(struct FCurve *fcu, float evaltime);
float evaluate_fcurve_driver(struct PathResolvedRNA *anim_rna,
struct FCurve *fcu,
struct ChannelDriver *driver_orig,
- float evaltime);
+ const struct AnimationEvalContext *anim_eval_context);
bool BKE_fcurve_is_empty(struct FCurve *fcu);
/* evaluate fcurve and store value */
-float calculate_fcurve(struct PathResolvedRNA *anim_rna, struct FCurve *fcu, float evaltime);
+float calculate_fcurve(struct PathResolvedRNA *anim_rna,
+ struct FCurve *fcu,
+ const struct AnimationEvalContext *anim_eval_context);
/* ************* F-Curve Samples API ******************** */
@@ -312,5 +314,3 @@ void fcurve_store_samples(
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_FCURVE_H__*/
diff --git a/source/blender/blenkernel/BKE_fcurve_driver.h b/source/blender/blenkernel/BKE_fcurve_driver.h
index 563ed408ed7..5b4da4a78a4 100644
--- a/source/blender/blenkernel/BKE_fcurve_driver.h
+++ b/source/blender/blenkernel/BKE_fcurve_driver.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_FCURVE_DRIVER_H__
-#define __BKE_FCURVE_DRIVER_H__
+#pragma once
/** \file
* \ingroup bke
@@ -30,6 +29,7 @@
extern "C" {
#endif
+struct AnimationEvalContext;
struct ChannelDriver;
struct DriverTarget;
struct DriverVar;
@@ -97,10 +97,8 @@ void BKE_driver_invalidate_expression(struct ChannelDriver *driver,
float evaluate_driver(struct PathResolvedRNA *anim_rna,
struct ChannelDriver *driver,
struct ChannelDriver *driver_orig,
- const float evaltime);
+ const struct AnimationEvalContext *anim_eval_context);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_FCURVE_DRIVER_H__*/
diff --git a/source/blender/blenkernel/BKE_fluid.h b/source/blender/blenkernel/BKE_fluid.h
index c958afb212e..88a5492d85b 100644
--- a/source/blender/blenkernel/BKE_fluid.h
+++ b/source/blender/blenkernel/BKE_fluid.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_FLUID_H__
-#define __BKE_FLUID_H__
+#pragma once
/** \file
* \ingroup bke
@@ -37,7 +36,7 @@ struct Main;
struct Scene;
typedef float (*BKE_Fluid_BresenhamFn)(
- float *result, float *input, int res[3], int *pixel, float *tRay, float correct);
+ float *result, const float *input, int res[3], int *pixel, float *tRay, float correct);
struct Mesh *BKE_fluid_modifier_do(struct FluidModifierData *fmd,
struct Depsgraph *depsgraph,
@@ -56,9 +55,9 @@ bool BKE_fluid_reallocate_fluid(struct FluidDomainSettings *fds, int res[3], int
void BKE_fluid_reallocate_copy_fluid(struct FluidDomainSettings *fds,
int o_res[3],
int n_res[3],
- int o_min[3],
- int n_min[3],
- int o_max[3],
+ const int o_min[3],
+ const int n_min[3],
+ const int o_max[3],
int o_shift[3],
int n_shift[3]);
void BKE_fluid_cache_free_all(struct FluidDomainSettings *fds, struct Object *ob);
@@ -101,5 +100,3 @@ void BKE_fluid_flow_behavior_set(struct Object *object,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_FLUID_H__ */
diff --git a/source/blender/blenkernel/BKE_font.h b/source/blender/blenkernel/BKE_font.h
index 35f7d8b7d53..b23ccbe25ff 100644
--- a/source/blender/blenkernel/BKE_font.h
+++ b/source/blender/blenkernel/BKE_font.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_FONT_H__
-#define __BKE_FONT_H__
+#pragma once
/** \file
* \ingroup bke
@@ -102,5 +101,3 @@ void BKE_vfont_clipboard_get(char32_t **r_text_buf,
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_freestyle.h b/source/blender/blenkernel/BKE_freestyle.h
index 888a3d96aa2..47f0b547d83 100644
--- a/source/blender/blenkernel/BKE_freestyle.h
+++ b/source/blender/blenkernel/BKE_freestyle.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_FREESTYLE_H__
-#define __BKE_FREESTYLE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -66,5 +65,3 @@ void BKE_freestyle_lineset_unique_name(FreestyleConfig *config, FreestyleLineSet
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h
index 61c270202f1..9ffd496616d 100644
--- a/source/blender/blenkernel/BKE_global.h
+++ b/source/blender/blenkernel/BKE_global.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_GLOBAL_H__
-#define __BKE_GLOBAL_H__
+#pragma once
/** \file
* \ingroup bke
@@ -145,18 +144,19 @@ enum {
G_DEBUG_DEPSGRAPH_TIME = (1 << 11), /* depsgraph timing statistics and messages */
G_DEBUG_DEPSGRAPH_NO_THREADS = (1 << 12), /* single threaded depsgraph */
G_DEBUG_DEPSGRAPH_PRETTY = (1 << 13), /* use pretty colors in depsgraph messages */
+ G_DEBUG_DEPSGRAPH_UUID = (1 << 14), /* use pretty colors in depsgraph messages */
G_DEBUG_DEPSGRAPH = (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_EVAL | G_DEBUG_DEPSGRAPH_TAG |
- G_DEBUG_DEPSGRAPH_TIME),
- G_DEBUG_SIMDATA = (1 << 14), /* sim debug data display */
- G_DEBUG_GPU_MEM = (1 << 15), /* gpu memory in status bar */
- G_DEBUG_GPU = (1 << 16), /* gpu debug */
- G_DEBUG_IO = (1 << 17), /* IO Debugging (for Collada, ...)*/
- G_DEBUG_GPU_SHADERS = (1 << 18), /* GLSL shaders */
- G_DEBUG_GPU_FORCE_WORKAROUNDS = (1 << 19), /* force gpu workarounds bypassing detections. */
- G_DEBUG_XR = (1 << 20), /* XR/OpenXR messages */
- G_DEBUG_XR_TIME = (1 << 21), /* XR/OpenXR timing messages */
-
- G_DEBUG_GHOST = (1 << 20), /* Debug GHOST module. */
+ G_DEBUG_DEPSGRAPH_TIME | G_DEBUG_DEPSGRAPH_UUID),
+ G_DEBUG_SIMDATA = (1 << 15), /* sim debug data display */
+ G_DEBUG_GPU_MEM = (1 << 16), /* gpu memory in status bar */
+ G_DEBUG_GPU = (1 << 17), /* gpu debug */
+ G_DEBUG_IO = (1 << 18), /* IO Debugging (for Collada, ...)*/
+ G_DEBUG_GPU_SHADERS = (1 << 19), /* GLSL shaders */
+ G_DEBUG_GPU_FORCE_WORKAROUNDS = (1 << 20), /* force gpu workarounds bypassing detections. */
+ G_DEBUG_XR = (1 << 21), /* XR/OpenXR messages */
+ G_DEBUG_XR_TIME = (1 << 22), /* XR/OpenXR timing messages */
+
+ G_DEBUG_GHOST = (1 << 23), /* Debug GHOST module. */
};
#define G_DEBUG_ALL \
@@ -223,5 +223,3 @@ extern Global G;
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h
index cd434566e43..6defc2ffd68 100644
--- a/source/blender/blenkernel/BKE_gpencil.h
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -17,8 +17,7 @@
* This is a new part of Blender
*/
-#ifndef __BKE_GPENCIL_H__
-#define __BKE_GPENCIL_H__
+#pragma once
/** \file
* \ingroup bke
@@ -280,5 +279,3 @@ void BKE_gpencil_update_layer_parent(const struct Depsgraph *depsgraph, struct O
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_GPENCIL_H__ */
diff --git a/source/blender/blenkernel/BKE_gpencil_curve.h b/source/blender/blenkernel/BKE_gpencil_curve.h
index cf6f9074bda..3fbd0ce1a51 100644
--- a/source/blender/blenkernel/BKE_gpencil_curve.h
+++ b/source/blender/blenkernel/BKE_gpencil_curve.h
@@ -17,8 +17,7 @@
* This is a new part of Blender
*/
-#ifndef __BKE_GPENCIL_CURVE_H__
-#define __BKE_GPENCIL_CURVE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -43,5 +42,3 @@ void BKE_gpencil_convert_curve(struct Main *bmain,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_GPENCIL_CURVE_H__ */
diff --git a/source/blender/blenkernel/BKE_gpencil_geom.h b/source/blender/blenkernel/BKE_gpencil_geom.h
index b79bbf3948f..0abd87d3d4e 100644
--- a/source/blender/blenkernel/BKE_gpencil_geom.h
+++ b/source/blender/blenkernel/BKE_gpencil_geom.h
@@ -17,8 +17,7 @@
* This is a new part of Blender
*/
-#ifndef __BKE_GPENCIL_GEOM_H__
-#define __BKE_GPENCIL_GEOM_H__
+#pragma once
/** \file
* \ingroup bke
@@ -76,7 +75,21 @@ void BKE_gpencil_stroke_fill_triangulate(struct bGPDstroke *gps);
void BKE_gpencil_stroke_geometry_update(struct bGPDstroke *gps);
void BKE_gpencil_stroke_uv_update(struct bGPDstroke *gps);
-void BKE_gpencil_transform(struct bGPdata *gpd, float mat[4][4]);
+void BKE_gpencil_transform(struct bGPdata *gpd, const float mat[4][4]);
+
+typedef struct GPencilPointCoordinates {
+ /* This is used when doing "move only origin" in object_data_transform.c.
+ * pressure is needs to be stored here as it is tied to object scale. */
+ float co[3];
+ float pressure;
+} GPencilPointCoordinates;
+
+int BKE_gpencil_stroke_point_count(struct bGPdata *gpd);
+void BKE_gpencil_point_coords_get(struct bGPdata *gpd, GPencilPointCoordinates *elem_data);
+void BKE_gpencil_point_coords_apply(struct bGPdata *gpd, const GPencilPointCoordinates *elem_data);
+void BKE_gpencil_point_coords_apply_with_mat4(struct bGPdata *gpd,
+ const GPencilPointCoordinates *elem_data,
+ const float mat[4][4]);
bool BKE_gpencil_stroke_sample(struct bGPDstroke *gps, const float dist, const bool select);
bool BKE_gpencil_stroke_smooth(struct bGPDstroke *gps, int i, float inf);
@@ -98,6 +111,8 @@ bool BKE_gpencil_stroke_shrink(struct bGPDstroke *gps, const float dist);
float BKE_gpencil_stroke_length(const struct bGPDstroke *gps, bool use_3d);
+void BKE_gpencil_stroke_set_random_color(struct bGPDstroke *gps);
+
void BKE_gpencil_convert_mesh(struct Main *bmain,
struct Depsgraph *depsgraph,
struct Scene *scene,
@@ -109,10 +124,9 @@ void BKE_gpencil_convert_mesh(struct Main *bmain,
const float matrix[4][4],
const int frame_offset,
const bool use_seams,
- const bool use_faces);
+ const bool use_faces,
+ const bool simple_material);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_GPENCIL_GEOM_H__ */
diff --git a/source/blender/blenkernel/BKE_gpencil_modifier.h b/source/blender/blenkernel/BKE_gpencil_modifier.h
index ac5f4607838..8eafbe04a14 100644
--- a/source/blender/blenkernel/BKE_gpencil_modifier.h
+++ b/source/blender/blenkernel/BKE_gpencil_modifier.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_GPENCIL_MODIFIER_H__
-#define __BKE_GPENCIL_MODIFIER_H__
+#pragma once
/** \file
* \ingroup bke
@@ -316,5 +315,3 @@ struct bGPDframe *BKE_gpencil_frame_retime_get(struct Depsgraph *depsgraph,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_GPENCIL_MODIFIER_H__ */
diff --git a/source/blender/blenkernel/BKE_hair.h b/source/blender/blenkernel/BKE_hair.h
index ea515416b58..bf386e099e0 100644
--- a/source/blender/blenkernel/BKE_hair.h
+++ b/source/blender/blenkernel/BKE_hair.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_HAIR_H__
-#define __BKE_HAIR_H__
+#pragma once
/** \file
* \ingroup bke
@@ -61,5 +60,3 @@ extern void (*BKE_hair_batch_cache_free_cb)(struct Hair *hair);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_icons.h b/source/blender/blenkernel/BKE_icons.h
index 56c50c22bf4..8a4fc78eb97 100644
--- a/source/blender/blenkernel/BKE_icons.h
+++ b/source/blender/blenkernel/BKE_icons.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_ICONS_H__
-#define __BKE_ICONS_H__
+#pragma once
/** \file
* \ingroup bke
@@ -173,5 +172,3 @@ int BKE_icon_ensure_studio_light(struct StudioLight *sl, int id_type);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_ICONS_H__ */
diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h
index dc01e8ea27b..58629cde6ec 100644
--- a/source/blender/blenkernel/BKE_idprop.h
+++ b/source/blender/blenkernel/BKE_idprop.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_IDPROP_H__
-#define __BKE_IDPROP_H__
+#pragma once
/** \file
* \ingroup bke
@@ -200,5 +199,3 @@ void IDP_print(const struct IDProperty *prop);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_IDPROP_H__ */
diff --git a/source/blender/blenkernel/BKE_idtype.h b/source/blender/blenkernel/BKE_idtype.h
index a823693e126..aefba9ef02a 100644
--- a/source/blender/blenkernel/BKE_idtype.h
+++ b/source/blender/blenkernel/BKE_idtype.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_IDTYPE_H__
-#define __BKE_IDTYPE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -47,9 +46,9 @@ enum {
};
typedef struct IDCacheKey {
- /* The session uuid of the ID owning the cached data. */
+ /* The session UUID of the ID owning the cached data. */
unsigned int id_session_uuid;
- /* Value uniquely indentifying the cache whithin its ID.
+ /* Value uniquely identifying the cache within its ID.
* Typically the offset of its member in the data-block struct, but can be anything. */
size_t offset_in_ID;
/* Actual address of the cached data to save and restore. */
@@ -59,7 +58,7 @@ typedef struct IDCacheKey {
uint BKE_idtype_cache_key_hash(const void *key_v);
bool BKE_idtype_cache_key_cmp(const void *key_a_v, const void *key_b_v);
-/* ********** Prototypes for IDTypeInfo callbacks. ********** */
+/* ********** Prototypes for #IDTypeInfo callbacks. ********** */
typedef void (*IDTypeInitDataFunction)(struct ID *id);
@@ -76,9 +75,15 @@ typedef void (*IDTypeMakeLocalFunction)(struct Main *bmain, struct ID *id, const
typedef void (*IDTypeForeachIDFunction)(struct ID *id, struct LibraryForeachIDData *data);
+typedef enum eIDTypeInfoCacheCallbackFlags {
+ /** Indicates to the callback that that cache may be stored in the .blend file, so its pointer
+ * should not be cleared at read-time. */
+ IDTYPE_CACHE_CB_FLAGS_PERSISTENT = 1 << 0,
+} eIDTypeInfoCacheCallbackFlags;
typedef void (*IDTypeForeachCacheFunctionCallback)(struct ID *id,
const struct IDCacheKey *cache_key,
void **cache_p,
+ uint flags,
void *user_data);
typedef void (*IDTypeForeachCacheFunction)(struct ID *id,
IDTypeForeachCacheFunctionCallback function_callback,
@@ -229,8 +234,14 @@ short BKE_idtype_idcode_from_index(const int index);
short BKE_idtype_idcode_iter_step(int *index);
+/* Some helpers/wrappers around callbacks defined in #IDTypeInfo, dealing e.g. with embedded IDs.
+ * XXX Ideally those would rather belong to #BKE_lib_id, but using callback function pointers makes
+ * this hard to do properly if we want to avoid headers includes in headers. */
+
+void BKE_idtype_id_foreach_cache(struct ID *id,
+ IDTypeForeachCacheFunctionCallback function_callback,
+ void *user_data);
+
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_IDTYPE_H__ */
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index 1e5573ab014..f052ba400fc 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_IMAGE_H__
-#define __BKE_IMAGE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -55,6 +54,7 @@ void BKE_image_free_packedfiles(struct Image *image);
void BKE_image_free_views(struct Image *image);
void BKE_image_free_buffers(struct Image *image);
void BKE_image_free_buffers_ex(struct Image *image, bool do_lock);
+void BKE_image_free_gputextures(struct Image *ima);
/* call from library */
void BKE_image_free(struct Image *image);
@@ -274,6 +274,10 @@ void BKE_image_free_anim_ibufs(struct Image *ima, int except_frame);
/* does all images with type MOVIE or SEQUENCE */
void BKE_image_all_free_anim_ibufs(struct Main *bmain, int except_frame);
+void BKE_image_free_all_gputextures(struct Main *bmain);
+void BKE_image_free_anim_gputextures(struct Main *bmain);
+void BKE_image_free_old_gputextures(struct Main *bmain);
+
bool BKE_image_memorypack(struct Image *ima);
void BKE_image_packfiles(struct ReportList *reports, struct Image *ima, const char *basepath);
void BKE_image_packfiles_from_mem(struct ReportList *reports,
@@ -362,6 +366,30 @@ bool BKE_image_has_loaded_ibuf(struct Image *image);
struct ImBuf *BKE_image_get_ibuf_with_name(struct Image *image, const char *name);
struct ImBuf *BKE_image_get_first_ibuf(struct Image *image);
+/* Not to be use directly. */
+struct GPUTexture *BKE_image_create_gpu_texture_from_ibuf(struct Image *image, struct ImBuf *ibuf);
+
+/* Get the GPUTexture for a given `Image`.
+ *
+ * `iuser` and `ibuf` are mutual exclusive parameters. The caller can pass the `ibuf` when already
+ * available. It is also required when requesting the GPUTexture for a render result. */
+struct GPUTexture *BKE_image_get_gpu_texture(struct Image *image,
+ struct ImageUser *iuser,
+ struct ImBuf *ibuf);
+struct GPUTexture *BKE_image_get_gpu_tiles(struct Image *image,
+ struct ImageUser *iuser,
+ struct ImBuf *ibuf);
+struct GPUTexture *BKE_image_get_gpu_tilemap(struct Image *image,
+ struct ImageUser *iuser,
+ struct ImBuf *ibuf);
+
+void BKE_image_update_gputexture(
+ struct Image *ima, struct ImageUser *iuser, int x, int y, int w, int h);
+void BKE_image_paint_set_mipmap(struct Main *bmain, bool mipmap);
+
+/* Delayed free of OpenGL buffers by main thread */
+void BKE_image_free_unused_gpu_textures(void);
+
struct RenderSlot *BKE_image_add_renderslot(struct Image *ima, const char *name);
bool BKE_image_remove_renderslot(struct Image *ima, struct ImageUser *iuser, int slot);
struct RenderSlot *BKE_image_get_renderslot(struct Image *ima, int slot);
@@ -370,5 +398,3 @@ bool BKE_image_clear_renderslot(struct Image *ima, struct ImageUser *iuser, int
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_image_save.h b/source/blender/blenkernel/BKE_image_save.h
index 8dfece944ff..0620442d998 100644
--- a/source/blender/blenkernel/BKE_image_save.h
+++ b/source/blender/blenkernel/BKE_image_save.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_IMAGE_SAVE_H__
-#define __BKE_IMAGE_SAVE_H__
+#pragma once
#include "DNA_scene_types.h"
@@ -62,5 +61,3 @@ bool BKE_image_save(struct ReportList *reports,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_IMAGE_SAVE_H__ */
diff --git a/source/blender/blenkernel/BKE_ipo.h b/source/blender/blenkernel/BKE_ipo.h
index ab5d2f66441..40b9f738bfd 100644
--- a/source/blender/blenkernel/BKE_ipo.h
+++ b/source/blender/blenkernel/BKE_ipo.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_IPO_H__
-#define __BKE_IPO_H__
+#pragma once
/** \file
* \ingroup bke
@@ -37,5 +36,3 @@ void do_versions_ipos_to_animato(struct Main *main);
#ifdef __cplusplus
};
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_kelvinlet.h b/source/blender/blenkernel/BKE_kelvinlet.h
index b8290730751..b3966d3ca4a 100644
--- a/source/blender/blenkernel/BKE_kelvinlet.h
+++ b/source/blender/blenkernel/BKE_kelvinlet.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) Blender Foundation.
* All rights reserved.
*/
-#ifndef __BKE_KELVINLET_H__
-#define __BKE_KELVINLET_H__
+#pragma once
/** \file
* \ingroup bke
@@ -81,5 +80,3 @@ void BKE_kelvinlet_twist(float r_elem_disp[3],
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h
index 6581891062c..e67df194431 100644
--- a/source/blender/blenkernel/BKE_key.h
+++ b/source/blender/blenkernel/BKE_key.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_KEY_H__
-#define __BKE_KEY_H__
+#pragma once
/** \file
* \ingroup bke
@@ -51,6 +50,12 @@ void key_curve_normal_weights(float t, float data[4], int type);
float *BKE_key_evaluate_object_ex(struct Object *ob, int *r_totelem, float *arr, size_t arr_size);
float *BKE_key_evaluate_object(struct Object *ob, int *r_totelem);
+int BKE_keyblock_element_count_from_shape(const struct Key *key, const int shape_index);
+int BKE_keyblock_element_count(const struct Key *key);
+
+size_t BKE_keyblock_element_calc_size_from_shape(const struct Key *key, const int shape_index);
+size_t BKE_keyblock_element_calc_size(const struct Key *key);
+
bool BKE_key_idtype_support(const short id_type);
struct Key **BKE_key_from_id_p(struct ID *id);
@@ -74,6 +79,10 @@ void BKE_keyblock_convert_from_lattice(struct Lattice *lt, struct KeyBlock *kb);
void BKE_keyblock_convert_to_lattice(struct KeyBlock *kb, struct Lattice *lt);
int BKE_keyblock_curve_element_count(struct ListBase *nurb);
+void BKE_keyblock_curve_data_transform(const struct ListBase *nurb,
+ const float mat[4][4],
+ const void *src,
+ void *dst);
void BKE_keyblock_update_from_curve(struct Curve *cu, struct KeyBlock *kb, struct ListBase *nurb);
void BKE_keyblock_convert_from_curve(struct Curve *cu, struct KeyBlock *kb, struct ListBase *nurb);
void BKE_keyblock_convert_to_curve(struct KeyBlock *kb, struct Curve *cu, struct ListBase *nurb);
@@ -104,8 +113,28 @@ bool BKE_keyblock_move(struct Object *ob, int org_index, int new_index);
bool BKE_keyblock_is_basis(struct Key *key, const int index);
+/* -------------------------------------------------------------------- */
+/** \name Key-Block Data Access
+ * \{ */
+
+void BKE_keyblock_data_get_from_shape(const struct Key *key,
+ float (*arr)[3],
+ const int shape_index);
+void BKE_keyblock_data_get(const struct Key *key, float (*arr)[3]);
+
+void BKE_keyblock_data_set_with_mat4(struct Key *key,
+ const int shape_index,
+ const float (*vertices)[3],
+ const float mat[4][4]);
+void BKE_keyblock_curve_data_set_with_mat4(struct Key *key,
+ const struct ListBase *nurb,
+ const int shape_index,
+ const void *data,
+ const float mat[4][4]);
+void BKE_keyblock_data_set(struct Key *key, const int shape_index, const void *data);
+
+/** \} */
+
#ifdef __cplusplus
};
#endif
-
-#endif /* __BKE_KEY_H__ */
diff --git a/source/blender/blenkernel/BKE_keyconfig.h b/source/blender/blenkernel/BKE_keyconfig.h
index bc33cc2669e..ab42d5742ea 100644
--- a/source/blender/blenkernel/BKE_keyconfig.h
+++ b/source/blender/blenkernel/BKE_keyconfig.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_KEYCONFIG_H__
-#define __BKE_KEYCONFIG_H__
+#pragma once
/** \file
* \ingroup bke
@@ -76,5 +75,3 @@ void BKE_keyconfig_pref_filter_items(struct UserDef *userdef,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_KEYCONFIG_H__ */
diff --git a/source/blender/blenkernel/BKE_lattice.h b/source/blender/blenkernel/BKE_lattice.h
index bb23ad63020..03c57d4caac 100644
--- a/source/blender/blenkernel/BKE_lattice.h
+++ b/source/blender/blenkernel/BKE_lattice.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_LATTICE_H__
-#define __BKE_LATTICE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -67,8 +66,8 @@ void BKE_lattice_minmax_dl(struct Object *ob, struct Lattice *lt, float min[3],
void BKE_lattice_minmax(struct Lattice *lt, float min[3], float max[3]);
void BKE_lattice_center_median(struct Lattice *lt, float cent[3]);
void BKE_lattice_center_bounds(struct Lattice *lt, float cent[3]);
-void BKE_lattice_translate(struct Lattice *lt, float offset[3], bool do_keys);
-void BKE_lattice_transform(struct Lattice *lt, float mat[4][4], bool do_keys);
+void BKE_lattice_translate(struct Lattice *lt, const float offset[3], bool do_keys);
+void BKE_lattice_transform(struct Lattice *lt, const float mat[4][4], bool do_keys);
bool BKE_lattice_is_any_selected(const struct Lattice *lt);
@@ -140,5 +139,3 @@ void BKE_lattice_deform_coords_with_editmesh(const struct Object *ob_lattice,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_LATTICE_H__ */
diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
index 7a0252e6813..7fe932edf31 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_LAYER_H__
-#define __BKE_LAYER_H__
+#pragma once
/** \file
* \ingroup bke
@@ -416,5 +415,3 @@ bool BKE_view_layer_filter_edit_mesh_has_edges(struct Object *ob, void *user_dat
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_LAYER_H__ */
diff --git a/source/blender/blenkernel/BKE_lib_id.h b/source/blender/blenkernel/BKE_lib_id.h
index bc72afdd08d..a2cbe537349 100644
--- a/source/blender/blenkernel/BKE_lib_id.h
+++ b/source/blender/blenkernel/BKE_lib_id.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_LIB_ID_H__
-#define __BKE_LIB_ID_H__
+#pragma once
/** \file
* \ingroup bke
@@ -229,7 +228,6 @@ bool BKE_id_copy(struct Main *bmain, const struct ID *id, struct ID **newid);
bool BKE_id_copy_ex(struct Main *bmain, const struct ID *id, struct ID **r_newid, const int flag);
struct ID *BKE_id_copy_for_duplicate(struct Main *bmain,
struct ID *id,
- const bool is_owner_id_liboverride,
const uint duplicate_flags);
void BKE_lib_id_swap(struct Main *bmain, struct ID *id_a, struct ID *id_b);
@@ -268,7 +266,8 @@ void BKE_id_full_name_get(char name[MAX_ID_FULL_NAME], const struct ID *id, char
void BKE_id_full_name_ui_prefix_get(char name[MAX_ID_FULL_NAME_UI],
const struct ID *id,
const bool add_lib_hint,
- char separator_char);
+ char separator_char,
+ int *r_prefix_len);
char *BKE_id_to_unique_string_key(const struct ID *id);
@@ -291,5 +290,3 @@ void BKE_id_reorder(const struct ListBase *lb, struct ID *id, struct ID *relativ
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_LIB_ID_H__ */
diff --git a/source/blender/blenkernel/BKE_lib_override.h b/source/blender/blenkernel/BKE_lib_override.h
index 411df66fe36..5843992b25c 100644
--- a/source/blender/blenkernel/BKE_lib_override.h
+++ b/source/blender/blenkernel/BKE_lib_override.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_LIB_OVERRIDE_H__
-#define __BKE_LIB_OVERRIDE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -50,9 +49,8 @@ struct IDOverrideLibraryPropertyOperation;
struct Main;
struct PointerRNA;
struct PropertyRNA;
-
-void BKE_lib_override_library_enable(const bool do_enable);
-bool BKE_lib_override_library_is_enabled(void);
+struct Scene;
+struct ViewLayer;
struct IDOverrideLibrary *BKE_lib_override_library_init(struct ID *local_id,
struct ID *reference_id);
@@ -66,6 +64,15 @@ struct ID *BKE_lib_override_library_create_from_id(struct Main *bmain,
struct ID *reference_id,
const bool do_tagged_remap);
bool BKE_lib_override_library_create_from_tag(struct Main *bmain);
+void BKE_lib_override_library_dependencies_tag(struct Main *bmain,
+ struct ID *id_root,
+ const uint tag,
+ const bool do_create_main_relashionships);
+bool BKE_lib_override_library_create(struct Main *bmain,
+ struct Scene *scene,
+ struct ViewLayer *view_layer,
+ struct ID *id_root,
+ struct ID *id_reference);
struct IDOverrideLibraryProperty *BKE_lib_override_library_property_find(
struct IDOverrideLibrary *override, const char *rna_path);
@@ -111,6 +118,9 @@ bool BKE_lib_override_library_status_check_reference(struct Main *bmain, struct
bool BKE_lib_override_library_operations_create(struct Main *bmain, struct ID *local);
void BKE_lib_override_library_main_operations_create(struct Main *bmain, const bool force_auto);
+void BKE_lib_override_library_id_reset(struct Main *bmain, struct ID *id_root);
+void BKE_lib_override_library_id_hierarchy_reset(struct Main *bmain, struct ID *id_root);
+
void BKE_lib_override_library_operations_tag(struct IDOverrideLibraryProperty *override_property,
const short tag,
const bool do_set);
@@ -130,7 +140,7 @@ void BKE_lib_override_library_main_update(struct Main *bmain);
/* For now, we just use a temp main list. */
typedef struct Main OverrideLibraryStorage;
-OverrideLibraryStorage *BKE_lib_override_library_operations_store_initialize(void);
+OverrideLibraryStorage *BKE_lib_override_library_operations_store_init(void);
struct ID *BKE_lib_override_library_operations_store_start(
struct Main *bmain, OverrideLibraryStorage *override_storage, struct ID *local);
void BKE_lib_override_library_operations_store_end(OverrideLibraryStorage *override_storage,
@@ -140,5 +150,3 @@ void BKE_lib_override_library_operations_store_finalize(OverrideLibraryStorage *
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_LIB_OVERRIDE_H__ */
diff --git a/source/blender/blenkernel/BKE_lib_query.h b/source/blender/blenkernel/BKE_lib_query.h
index c5a25e8e7af..b6abe0bf18c 100644
--- a/source/blender/blenkernel/BKE_lib_query.h
+++ b/source/blender/blenkernel/BKE_lib_query.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2014 by Blender Foundation.
* All rights reserved.
*/
-#ifndef __BKE_LIB_QUERY_H__
-#define __BKE_LIB_QUERY_H__
+#pragma once
/** \file
* \ingroup bke
@@ -182,5 +181,3 @@ void BKE_library_indirectly_used_data_tag_clear(struct Main *bmain);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_LIB_QUERY_H__ */
diff --git a/source/blender/blenkernel/BKE_lib_remap.h b/source/blender/blenkernel/BKE_lib_remap.h
index 8129b9dbafb..fb14e340d8b 100644
--- a/source/blender/blenkernel/BKE_lib_remap.h
+++ b/source/blender/blenkernel/BKE_lib_remap.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_LIB_REMAP_H__
-#define __BKE_LIB_REMAP_H__
+#pragma once
/** \file
* \ingroup bke
@@ -113,5 +112,3 @@ void BKE_library_callback_remap_editor_id_reference_set(
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_LIB_REMAP_H__ */
diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index 7883d740b0a..3981a4c14ea 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_LIBRARY_H__
-#define __BKE_LIBRARY_H__
+#pragma once
/** \file
* \ingroup bke
@@ -39,5 +38,3 @@ void BKE_library_filepath_set(struct Main *bmain, struct Library *lib, const cha
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_LIBRARY_H__ */
diff --git a/source/blender/blenkernel/BKE_light.h b/source/blender/blenkernel/BKE_light.h
index ead27ec8002..026e5d1a13b 100644
--- a/source/blender/blenkernel/BKE_light.h
+++ b/source/blender/blenkernel/BKE_light.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_LIGHT_H__
-#define __BKE_LIGHT_H__
+#pragma once
/** \file
* \ingroup bke
@@ -44,5 +43,3 @@ void BKE_light_eval(struct Depsgraph *depsgraph, struct Light *la);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_lightprobe.h b/source/blender/blenkernel/BKE_lightprobe.h
index 6304f61a1f4..e66d4ef75ca 100644
--- a/source/blender/blenkernel/BKE_lightprobe.h
+++ b/source/blender/blenkernel/BKE_lightprobe.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_LIGHTPROBE_H__
-#define __BKE_LIGHTPROBE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -39,5 +38,3 @@ struct LightProbe *BKE_lightprobe_copy(struct Main *bmain, const struct LightPro
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_LIGHTPROBE_H__ */
diff --git a/source/blender/blenkernel/BKE_linestyle.h b/source/blender/blenkernel/BKE_linestyle.h
index b086f244923..19238c4d090 100644
--- a/source/blender/blenkernel/BKE_linestyle.h
+++ b/source/blender/blenkernel/BKE_linestyle.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_LINESTYLE_H__
-#define __BKE_LINESTYLE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -106,5 +105,3 @@ void BKE_linestyle_default_shader(const struct bContext *C, FreestyleLineStyle *
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_LINESTYLE_H__ */
diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h
index b7c70168a49..2187ab6b9f5 100644
--- a/source/blender/blenkernel/BKE_main.h
+++ b/source/blender/blenkernel/BKE_main.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_MAIN_H__
-#define __BKE_MAIN_H__
+#pragma once
/** \file
* \ingroup bke
@@ -250,5 +249,3 @@ int set_listbasepointers(struct Main *main, struct ListBase *lb[MAX_LIBARRAY]);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_MAIN_H__ */
diff --git a/source/blender/blenkernel/BKE_main_idmap.h b/source/blender/blenkernel/BKE_main_idmap.h
index e392b7db60e..b89714cefa4 100644
--- a/source/blender/blenkernel/BKE_main_idmap.h
+++ b/source/blender/blenkernel/BKE_main_idmap.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_MAIN_IDMAP_H__
-#define __BKE_MAIN_IDMAP_H__
+#pragma once
/** \file
* \ingroup bke
@@ -69,5 +68,3 @@ struct ID *BKE_main_idmap_lookup_uuid(struct IDNameLib_Map *id_typemap,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_MAIN_IDMAP_H__ */
diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h
index dca677343ce..ab731c5e42f 100644
--- a/source/blender/blenkernel/BKE_mask.h
+++ b/source/blender/blenkernel/BKE_mask.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_MASK_H__
-#define __BKE_MASK_H__
+#pragma once
/** \file
* \ingroup bke
@@ -331,5 +330,3 @@ void BKE_maskrasterize_buffer(MaskRasterHandle *mr_handle,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_MASK_H__ */
diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h
index 225d966a51a..a30d7d55985 100644
--- a/source/blender/blenkernel/BKE_material.h
+++ b/source/blender/blenkernel/BKE_material.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_MATERIAL_H__
-#define __BKE_MATERIAL_H__
+#pragma once
/** \file
* \ingroup bke
@@ -84,7 +83,8 @@ void BKE_object_material_assign(
void BKE_object_material_array_assign(struct Main *bmain,
struct Object *ob,
struct Material ***matar,
- short totcol);
+ int totcol,
+ const bool to_object_only);
short BKE_object_material_slot_find_index(struct Object *ob, struct Material *ma);
bool BKE_object_material_slot_add(struct Main *bmain, struct Object *ob);
@@ -135,5 +135,3 @@ void BKE_material_eval(struct Depsgraph *depsgraph, struct Material *material);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_mball.h b/source/blender/blenkernel/BKE_mball.h
index 5f51f528d14..f2ad23a35f1 100644
--- a/source/blender/blenkernel/BKE_mball.h
+++ b/source/blender/blenkernel/BKE_mball.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_MBALL_H__
-#define __BKE_MBALL_H__
+#pragma once
/** \file
* \ingroup bke
@@ -92,5 +91,3 @@ extern void (*BKE_mball_batch_cache_free_cb)(struct MetaBall *mb);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_mball_tessellate.h b/source/blender/blenkernel/BKE_mball_tessellate.h
index 4e0649cf930..0ffbcf5bb05 100644
--- a/source/blender/blenkernel/BKE_mball_tessellate.h
+++ b/source/blender/blenkernel/BKE_mball_tessellate.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_MBALL_TESSELLATE_H__
-#define __BKE_MBALL_TESSELLATE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -38,5 +37,3 @@ void BKE_mball_cubeTable_free(void);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_MBALL_TESSELLATE_H__ */
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index 7d989bfcf69..045563f8e52 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_MESH_H__
-#define __BKE_MESH_H__
+#pragma once
/** \file
* \ingroup bke
@@ -231,7 +230,7 @@ void BKE_mesh_nomain_to_meshkey(struct Mesh *mesh_src, struct Mesh *mesh_dst, st
/* vertex level transformations & checks (no derived mesh) */
bool BKE_mesh_minmax(const struct Mesh *me, float r_min[3], float r_max[3]);
-void BKE_mesh_transform(struct Mesh *me, float mat[4][4], bool do_keys);
+void BKE_mesh_transform(struct Mesh *me, const float mat[4][4], bool do_keys);
void BKE_mesh_translate(struct Mesh *me, const float offset[3], const bool do_keys);
void BKE_mesh_ensure_navmesh(struct Mesh *me);
@@ -513,13 +512,13 @@ void BKE_mesh_loops_to_mface_corners(struct CustomData *fdata,
void BKE_mesh_loops_to_tessdata(struct CustomData *fdata,
struct CustomData *ldata,
struct MFace *mface,
- int *polyindices,
+ const int *polyindices,
unsigned int (*loopindices)[4],
const int num_faces);
void BKE_mesh_tangent_loops_to_tessdata(struct CustomData *fdata,
struct CustomData *ldata,
struct MFace *mface,
- int *polyindices,
+ const int *polyindices,
unsigned int (*loopindices)[4],
const int num_faces,
const char *layer_name);
@@ -707,5 +706,3 @@ BLI_INLINE int BKE_mesh_origindex_mface_mpoly(const int *index_mf_to_mpoly,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_MESH_H__ */
diff --git a/source/blender/blenkernel/BKE_mesh_iterators.h b/source/blender/blenkernel/BKE_mesh_iterators.h
index f7eaa7f69b8..103e7b5b78f 100644
--- a/source/blender/blenkernel/BKE_mesh_iterators.h
+++ b/source/blender/blenkernel/BKE_mesh_iterators.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_MESH_ITERATORS_H__
-#define __BKE_MESH_ITERATORS_H__
+#pragma once
/** \file
* \ingroup bke
@@ -70,5 +69,3 @@ void BKE_mesh_foreach_mapped_vert_coords_get(struct Mesh *me_eval,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_MESH_ITERATORS_H__ */
diff --git a/source/blender/blenkernel/BKE_mesh_mapping.h b/source/blender/blenkernel/BKE_mesh_mapping.h
index 9864cc4d28d..140a60dbdb7 100644
--- a/source/blender/blenkernel/BKE_mesh_mapping.h
+++ b/source/blender/blenkernel/BKE_mesh_mapping.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_MESH_MAPPING_H__
-#define __BKE_MESH_MAPPING_H__
+#pragma once
/** \file
* \ingroup bke
@@ -199,7 +198,7 @@ void BKE_mesh_loop_islands_clear(MeshIslandStore *island_store);
void BKE_mesh_loop_islands_free(MeshIslandStore *island_store);
void BKE_mesh_loop_islands_add(MeshIslandStore *islands,
const int item_num,
- int *item_indices,
+ const int *item_indices,
const int num_island_items,
int *island_item_indices,
const int num_innercut_items,
@@ -258,5 +257,3 @@ int *BKE_mesh_calc_smoothgroups(const struct MEdge *medge,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_MESH_MAPPING_H__ */
diff --git a/source/blender/blenkernel/BKE_mesh_mirror.h b/source/blender/blenkernel/BKE_mesh_mirror.h
index 0a68d028e35..2c6920a18bf 100644
--- a/source/blender/blenkernel/BKE_mesh_mirror.h
+++ b/source/blender/blenkernel/BKE_mesh_mirror.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_MESH_MIRROR_H__
-#define __BKE_MESH_MIRROR_H__
+#pragma once
/** \file
* \ingroup bke
@@ -49,5 +48,3 @@ struct Mesh *BKE_mesh_mirror_apply_mirror_on_axis(struct MirrorModifierData *mmd
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_MESH_MIRROR_H__ */
diff --git a/source/blender/blenkernel/BKE_mesh_remap.h b/source/blender/blenkernel/BKE_mesh_remap.h
index fff89e50744..d9b6ab3813e 100644
--- a/source/blender/blenkernel/BKE_mesh_remap.h
+++ b/source/blender/blenkernel/BKE_mesh_remap.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_MESH_REMAP_H__
-#define __BKE_MESH_REMAP_H__
+#pragma once
/** \file
* \ingroup bke
@@ -234,5 +233,3 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_MESH_REMAP_H__ */
diff --git a/source/blender/blenkernel/BKE_mesh_remesh_voxel.h b/source/blender/blenkernel/BKE_mesh_remesh_voxel.h
index 24f95f7ed20..2265fa6e105 100644
--- a/source/blender/blenkernel/BKE_mesh_remesh_voxel.h
+++ b/source/blender/blenkernel/BKE_mesh_remesh_voxel.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_MESH_REMESH_VOXEL_H__
-#define __BKE_MESH_REMESH_VOXEL_H__
+#pragma once
/** \file
* \ingroup bke
@@ -66,5 +65,3 @@ void BKE_remesh_reproject_sculpt_face_sets(struct Mesh *target, struct Mesh *sou
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_MESH_REMESH_VOXEL_H__ */
diff --git a/source/blender/blenkernel/BKE_mesh_runtime.h b/source/blender/blenkernel/BKE_mesh_runtime.h
index 468ec6a44cd..adb7c357049 100644
--- a/source/blender/blenkernel/BKE_mesh_runtime.h
+++ b/source/blender/blenkernel/BKE_mesh_runtime.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_MESH_RUNTIME_H__
-#define __BKE_MESH_RUNTIME_H__
+#pragma once
/** \file
* \ingroup bke
@@ -111,5 +110,3 @@ bool BKE_mesh_runtime_is_valid(struct Mesh *me_eval);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_MESH_RUNTIME_H__ */
diff --git a/source/blender/blenkernel/BKE_mesh_tangent.h b/source/blender/blenkernel/BKE_mesh_tangent.h
index 7b686f112aa..96eaa23ce71 100644
--- a/source/blender/blenkernel/BKE_mesh_tangent.h
+++ b/source/blender/blenkernel/BKE_mesh_tangent.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_MESH_TANGENT_H__
-#define __BKE_MESH_TANGENT_H__
+#pragma once
/** \file
* \ingroup bke
@@ -87,5 +86,3 @@ void BKE_mesh_calc_loop_tangent_step_0(const struct CustomData *loopData,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_MESH_TANGENT_H__ */
diff --git a/source/blender/blenkernel/BKE_mesh_wrapper.h b/source/blender/blenkernel/BKE_mesh_wrapper.h
index 00e2dd08726..2fe264fd0f7 100644
--- a/source/blender/blenkernel/BKE_mesh_wrapper.h
+++ b/source/blender/blenkernel/BKE_mesh_wrapper.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_MESH_WRAPPER_H__
-#define __BKE_MESH_WRAPPER_H__
+#pragma once
/** \file
* \ingroup bke
@@ -55,5 +54,3 @@ void BKE_mesh_wrapper_vert_coords_copy_with_mat4(const struct Mesh *me,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_MESH_WRAPPER_H__ */
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index e16a9284425..f9590696c2e 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_MODIFIER_H__
-#define __BKE_MODIFIER_H__
+#pragma once
/** \file
* \ingroup bke
@@ -543,5 +542,3 @@ struct Mesh *BKE_modifier_get_evaluated_mesh_from_evaluated_object(struct Object
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_movieclip.h b/source/blender/blenkernel/BKE_movieclip.h
index dbd6eb15bf2..958fbef1f97 100644
--- a/source/blender/blenkernel/BKE_movieclip.h
+++ b/source/blender/blenkernel/BKE_movieclip.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_MOVIECLIP_H__
-#define __BKE_MOVIECLIP_H__
+#pragma once
/** \file
* \ingroup bke
@@ -113,6 +112,11 @@ bool BKE_movieclip_put_frame_if_possible(struct MovieClip *clip,
struct MovieClipUser *user,
struct ImBuf *ibuf);
+struct GPUTexture *BKE_movieclip_get_gpu_texture(struct MovieClip *clip,
+ struct MovieClipUser *cuser);
+
+void BKE_movieclip_free_gputexture(struct MovieClip *clip);
+
/* Dependency graph evaluation. */
void BKE_movieclip_eval_update(struct Depsgraph *depsgraph,
@@ -132,5 +136,3 @@ void BKE_movieclip_eval_selection_update(struct Depsgraph *depsgraph, struct Mov
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h
index 15ba72ef5b5..db2dc7ec87f 100644
--- a/source/blender/blenkernel/BKE_multires.h
+++ b/source/blender/blenkernel/BKE_multires.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_MULTIRES_H__
-#define __BKE_MULTIRES_H__
+#pragma once
/** \file
* \ingroup bke
@@ -235,5 +234,3 @@ BLI_INLINE void BKE_multires_construct_tangent_matrix(float tangent_matrix[3][3]
#endif
#include "intern/multires_inline.h"
-
-#endif /* __BKE_MULTIRES_H__ */
diff --git a/source/blender/blenkernel/BKE_nla.h b/source/blender/blenkernel/BKE_nla.h
index 2be8d657bf4..8b3231e5302 100644
--- a/source/blender/blenkernel/BKE_nla.h
+++ b/source/blender/blenkernel/BKE_nla.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_NLA_H__
-#define __BKE_NLA_H__
+#pragma once
/** \file
* \ingroup bke
@@ -149,5 +148,3 @@ float BKE_nla_tweakedit_remap(struct AnimData *adt, float cframe, short mode);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index bdcbe2129c8..ef46bc0f202 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_NODE_H__
-#define __BKE_NODE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -101,6 +100,30 @@ typedef struct bNodeSocketTemplate {
char identifier[64]; /* generated from name */
} bNodeSocketTemplate;
+/* Use `void *` for callbacks that require C++. This is rather ugly, but works well for now. This
+ * would not be necessary if we would use bNodeSocketType and bNodeType only in C++ code.
+ * However, achieving this requires quite a few changes currently. */
+#ifdef __cplusplus
+namespace blender {
+namespace nodes {
+class SocketMFNetworkBuilder;
+class NodeMFNetworkBuilder;
+} // namespace nodes
+namespace fn {
+class MFDataType;
+}
+} // namespace blender
+
+using NodeExpandInMFNetworkFunction = void (*)(blender::nodes::NodeMFNetworkBuilder &builder);
+using SocketGetMFDataTypeFunction = blender::fn::MFDataType (*)();
+using SocketExpandInMFNetworkFunction = void (*)(blender::nodes::SocketMFNetworkBuilder &builder);
+
+#else
+typedef void *NodeExpandInMFNetworkFunction;
+typedef void *SocketGetMFDataTypeFunction;
+typedef void *SocketExpandInMFNetworkFunction;
+#endif
+
/**
* \brief Defines a socket type.
*
@@ -153,6 +176,11 @@ typedef struct bNodeSocketType {
/* Callback to free the socket type. */
void (*free_self)(struct bNodeSocketType *stype);
+
+ /* Returns the multi-function data type of this socket type. */
+ SocketGetMFDataTypeFunction get_mf_data_type;
+ /* Expands the socket into a multi-function node that outputs the socket value. */
+ SocketExpandInMFNetworkFunction expand_in_mf_network;
} bNodeSocketType;
typedef void *(*NodeInitExecFunction)(struct bNodeExecContext *context,
@@ -267,6 +295,9 @@ typedef struct bNodeType {
/* gpu */
NodeGPUExecFunction gpufunc;
+ /* Expands the bNode into nodes in a multi-function network, which will be evaluated later on. */
+ NodeExpandInMFNetworkFunction expand_in_mf_network;
+
/* RNA integration */
ExtensionRNA rna_ext;
} bNodeType;
@@ -1299,6 +1330,8 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
#define SIM_NODE_EMIT_PARTICLES 1009
#define SIM_NODE_TIME 1010
#define SIM_NODE_PARTICLE_ATTRIBUTE 1011
+#define SIM_NODE_AGE_REACHED_EVENT 1012
+#define SIM_NODE_KILL_PARTICLE 1013
/** \} */
@@ -1311,6 +1344,8 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
#define FN_NODE_FLOAT_COMPARE 1202
#define FN_NODE_GROUP_INSTANCE_ID 1203
#define FN_NODE_COMBINE_STRINGS 1204
+#define FN_NODE_OBJECT_TRANSFORMS 1205
+#define FN_NODE_RANDOM_FLOAT 1206
/** \} */
@@ -1332,5 +1367,3 @@ extern struct bNodeSocketType NodeSocketTypeUndefined;
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_NODE_H__ */
diff --git a/source/blender/blenkernel/BKE_node_tree_ref.hh b/source/blender/blenkernel/BKE_node_tree_ref.hh
deleted file mode 100644
index e25849cb569..00000000000
--- a/source/blender/blenkernel/BKE_node_tree_ref.hh
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef __BKE_NODE_TREE_REF_HH__
-#define __BKE_NODE_TREE_REF_HH__
-
-/** \file
- * \ingroup bke
- *
- * NodeTreeRef makes querying information about a bNodeTree more efficient. It is an immutable data
- * structure. It should not be used after anymore, after the underlying node tree changed.
- *
- * The following queries are supported efficiently:
- * - socket -> index of socket
- * - socket -> directly linked sockets
- * - socket -> linked sockets when skipping reroutes
- * - socket -> node
- * - socket/node -> rna pointer
- * - node -> inputs/outputs
- * - node -> tree
- * - tree -> all nodes
- * - tree -> all (input/output) sockets
- * - idname -> nodes
- *
- * Every socket has an id. The id-space is shared between input and output sockets.
- * When storing data per socket, it is often better to use the id as index into an array, instead
- * of a hash table.
- *
- * Every node has an id as well. The same rule regarding hash tables applies.
- *
- * There is an utility to export this data structure as graph in dot format.
- */
-
-#include "BLI_array.hh"
-#include "BLI_linear_allocator.hh"
-#include "BLI_map.hh"
-#include "BLI_string_ref.hh"
-#include "BLI_timeit.hh"
-#include "BLI_utility_mixins.hh"
-#include "BLI_vector.hh"
-
-#include "BKE_node.h"
-
-#include "DNA_node_types.h"
-
-#include "RNA_access.h"
-
-namespace blender::bke {
-
-class SocketRef;
-class InputSocketRef;
-class OutputSocketRef;
-class NodeRef;
-class NodeTreeRef;
-
-class SocketRef : NonCopyable, NonMovable {
- protected:
- NodeRef *node_;
- bNodeSocket *bsocket_;
- bool is_input_;
- uint id_;
- uint index_;
- PointerRNA rna_;
- Vector<SocketRef *> linked_sockets_;
- Vector<SocketRef *> directly_linked_sockets_;
-
- friend NodeTreeRef;
-
- public:
- Span<const SocketRef *> linked_sockets() const;
- Span<const SocketRef *> directly_linked_sockets() const;
- bool is_linked() const;
-
- const NodeRef &node() const;
- const NodeTreeRef &tree() const;
-
- uint id() const;
- uint index() const;
-
- bool is_input() const;
- bool is_output() const;
-
- const SocketRef &as_base() const;
- const InputSocketRef &as_input() const;
- const OutputSocketRef &as_output() const;
-
- PointerRNA *rna() const;
-
- StringRefNull idname() const;
- StringRefNull name() const;
-
- bNodeSocket *bsocket() const;
- bNode *bnode() const;
- bNodeTree *btree() const;
-};
-
-class InputSocketRef final : public SocketRef {
- public:
- Span<const OutputSocketRef *> linked_sockets() const;
- Span<const OutputSocketRef *> directly_linked_sockets() const;
-};
-
-class OutputSocketRef final : public SocketRef {
- public:
- Span<const InputSocketRef *> linked_sockets() const;
- Span<const InputSocketRef *> directly_linked_sockets() const;
-};
-
-class NodeRef : NonCopyable, NonMovable {
- private:
- NodeTreeRef *tree_;
- bNode *bnode_;
- PointerRNA rna_;
- uint id_;
- Vector<InputSocketRef *> inputs_;
- Vector<OutputSocketRef *> outputs_;
-
- friend NodeTreeRef;
-
- public:
- const NodeTreeRef &tree() const;
-
- Span<const InputSocketRef *> inputs() const;
- Span<const OutputSocketRef *> outputs() const;
-
- const InputSocketRef &input(uint index) const;
- const OutputSocketRef &output(uint index) const;
-
- bNode *bnode() const;
- bNodeTree *btree() const;
-
- PointerRNA *rna() const;
- StringRefNull idname() const;
- StringRefNull name() const;
-
- uint id() const;
-
- bool is_reroute_node() const;
- bool is_group_node() const;
- bool is_group_input_node() const;
- bool is_group_output_node() const;
-};
-
-class NodeTreeRef : NonCopyable, NonMovable {
- private:
- LinearAllocator<> allocator_;
- bNodeTree *btree_;
- Vector<NodeRef *> nodes_by_id_;
- Vector<SocketRef *> sockets_by_id_;
- Vector<InputSocketRef *> input_sockets_;
- Vector<OutputSocketRef *> output_sockets_;
- Map<const bNodeType *, Vector<NodeRef *>> nodes_by_type_;
-
- public:
- NodeTreeRef(bNodeTree *btree);
- ~NodeTreeRef();
-
- Span<const NodeRef *> nodes() const;
- Span<const NodeRef *> nodes_by_type(StringRefNull idname) const;
- Span<const NodeRef *> nodes_by_type(const bNodeType *nodetype) const;
-
- Span<const SocketRef *> sockets() const;
- Span<const InputSocketRef *> input_sockets() const;
- Span<const OutputSocketRef *> output_sockets() const;
-
- bNodeTree *btree() const;
-
- std::string to_dot() const;
-
- private:
- /* Utility functions used during construction. */
- InputSocketRef &find_input_socket(Map<bNode *, NodeRef *> &node_mapping,
- bNode *bnode,
- bNodeSocket *bsocket);
- OutputSocketRef &find_output_socket(Map<bNode *, NodeRef *> &node_mapping,
- bNode *bnode,
- bNodeSocket *bsocket);
- void find_targets_skipping_reroutes(OutputSocketRef &socket_ref, Vector<SocketRef *> &r_targets);
-};
-
-/* --------------------------------------------------------------------
- * SocketRef inline methods.
- */
-
-inline Span<const SocketRef *> SocketRef::linked_sockets() const
-{
- return linked_sockets_.as_span();
-}
-
-inline Span<const SocketRef *> SocketRef::directly_linked_sockets() const
-{
- return directly_linked_sockets_.as_span();
-}
-
-inline bool SocketRef::is_linked() const
-{
- return linked_sockets_.size() > 0;
-}
-
-inline const NodeRef &SocketRef::node() const
-{
- return *node_;
-}
-
-inline const NodeTreeRef &SocketRef::tree() const
-{
- return node_->tree();
-}
-
-inline uint SocketRef::id() const
-{
- return id_;
-}
-
-inline uint SocketRef::index() const
-{
- return index_;
-}
-
-inline bool SocketRef::is_input() const
-{
- return is_input_;
-}
-
-inline bool SocketRef::is_output() const
-{
- return !is_input_;
-}
-
-inline const SocketRef &SocketRef::as_base() const
-{
- return *this;
-}
-
-inline const InputSocketRef &SocketRef::as_input() const
-{
- BLI_assert(this->is_input());
- return *(const InputSocketRef *)this;
-}
-
-inline const OutputSocketRef &SocketRef::as_output() const
-{
- BLI_assert(this->is_output());
- return *(const OutputSocketRef *)this;
-}
-
-inline PointerRNA *SocketRef::rna() const
-{
- return const_cast<PointerRNA *>(&rna_);
-}
-
-inline StringRefNull SocketRef::idname() const
-{
- return bsocket_->idname;
-}
-
-inline StringRefNull SocketRef::name() const
-{
- return bsocket_->name;
-}
-
-inline bNodeSocket *SocketRef::bsocket() const
-{
- return bsocket_;
-}
-
-inline bNode *SocketRef::bnode() const
-{
- return node_->bnode();
-}
-
-inline bNodeTree *SocketRef::btree() const
-{
- return node_->btree();
-}
-
-/* --------------------------------------------------------------------
- * InputSocketRef inline methods.
- */
-
-inline Span<const OutputSocketRef *> InputSocketRef::linked_sockets() const
-{
- return linked_sockets_.as_span().cast<const OutputSocketRef *>();
-}
-
-inline Span<const OutputSocketRef *> InputSocketRef::directly_linked_sockets() const
-{
- return directly_linked_sockets_.as_span().cast<const OutputSocketRef *>();
-}
-
-/* --------------------------------------------------------------------
- * OutputSocketRef inline methods.
- */
-
-inline Span<const InputSocketRef *> OutputSocketRef::linked_sockets() const
-{
- return linked_sockets_.as_span().cast<const InputSocketRef *>();
-}
-
-inline Span<const InputSocketRef *> OutputSocketRef::directly_linked_sockets() const
-{
- return directly_linked_sockets_.as_span().cast<const InputSocketRef *>();
-}
-
-/* --------------------------------------------------------------------
- * NodeRef inline methods.
- */
-
-inline const NodeTreeRef &NodeRef::tree() const
-{
- return *tree_;
-}
-
-inline Span<const InputSocketRef *> NodeRef::inputs() const
-{
- return inputs_.as_span();
-}
-
-inline Span<const OutputSocketRef *> NodeRef::outputs() const
-{
- return outputs_.as_span();
-}
-
-inline const InputSocketRef &NodeRef::input(uint index) const
-{
- return *inputs_[index];
-}
-
-inline const OutputSocketRef &NodeRef::output(uint index) const
-{
- return *outputs_[index];
-}
-
-inline bNode *NodeRef::bnode() const
-{
- return bnode_;
-}
-
-inline bNodeTree *NodeRef::btree() const
-{
- return tree_->btree();
-}
-
-inline PointerRNA *NodeRef::rna() const
-{
- return const_cast<PointerRNA *>(&rna_);
-}
-
-inline StringRefNull NodeRef::idname() const
-{
- return bnode_->idname;
-}
-
-inline StringRefNull NodeRef::name() const
-{
- return bnode_->name;
-}
-
-inline uint NodeRef::id() const
-{
- return id_;
-}
-
-inline bool NodeRef::is_reroute_node() const
-{
- return bnode_->type == NODE_REROUTE;
-}
-
-inline bool NodeRef::is_group_node() const
-{
- return bnode_->type == NODE_GROUP;
-}
-
-inline bool NodeRef::is_group_input_node() const
-{
- return bnode_->type == NODE_GROUP_INPUT;
-}
-
-inline bool NodeRef::is_group_output_node() const
-{
- return bnode_->type == NODE_GROUP_OUTPUT;
-}
-
-/* --------------------------------------------------------------------
- * NodeRef inline methods.
- */
-
-inline Span<const NodeRef *> NodeTreeRef::nodes() const
-{
- return nodes_by_id_.as_span();
-}
-
-inline Span<const NodeRef *> NodeTreeRef::nodes_by_type(StringRefNull idname) const
-{
- const bNodeType *nodetype = nodeTypeFind(idname.data());
- return this->nodes_by_type(nodetype);
-}
-
-inline Span<const NodeRef *> NodeTreeRef::nodes_by_type(const bNodeType *nodetype) const
-{
- const Vector<NodeRef *> *nodes = nodes_by_type_.lookup_ptr(nodetype);
- if (nodes == nullptr) {
- return {};
- }
- else {
- return nodes->as_span();
- }
-}
-
-inline Span<const SocketRef *> NodeTreeRef::sockets() const
-{
- return sockets_by_id_.as_span();
-}
-
-inline Span<const InputSocketRef *> NodeTreeRef::input_sockets() const
-{
- return input_sockets_.as_span();
-}
-
-inline Span<const OutputSocketRef *> NodeTreeRef::output_sockets() const
-{
- return output_sockets_.as_span();
-}
-
-inline bNodeTree *NodeTreeRef::btree() const
-{
- return btree_;
-}
-
-} // namespace blender::bke
-
-#endif /* __BKE_NODE_TREE_REF_HH__ */
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index d830a35dda0..215f4043e34 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_OBJECT_H__
-#define __BKE_OBJECT_H__
+#pragma once
/** \file
* \ingroup bke
@@ -139,26 +138,26 @@ bool BKE_object_obdata_is_libdata(const struct Object *ob);
struct Object *BKE_object_duplicate(struct Main *bmain,
struct Object *ob,
- const uint dupflag,
+ uint dupflag,
const uint duplicate_options);
void BKE_object_obdata_size_init(struct Object *ob, const float scale);
-void BKE_object_scale_to_mat3(struct Object *ob, float mat[3][3]);
-void BKE_object_rot_to_mat3(const struct Object *ob, float mat[3][3], bool use_drot);
-void BKE_object_mat3_to_rot(struct Object *ob, float mat[3][3], bool use_compat);
-void BKE_object_to_mat3(struct Object *ob, float mat[3][3]);
-void BKE_object_to_mat4(struct Object *ob, float mat[4][4]);
+void BKE_object_scale_to_mat3(struct Object *ob, float r_mat[3][3]);
+void BKE_object_rot_to_mat3(const struct Object *ob, float r_mat[3][3], bool use_drot);
+void BKE_object_mat3_to_rot(struct Object *ob, float r_mat[3][3], bool use_compat);
+void BKE_object_to_mat3(struct Object *ob, float r_mat[3][3]);
+void BKE_object_to_mat4(struct Object *ob, float r_mat[4][4]);
void BKE_object_apply_mat4(struct Object *ob,
- float mat[4][4],
+ const float mat[4][4],
const bool use_compat,
const bool use_parent);
void BKE_object_apply_mat4_ex(struct Object *ob,
- float mat[4][4],
+ const float mat[4][4],
struct Object *parent,
- float parentinv[4][4],
+ const float parentinv[4][4],
const bool use_compat);
-void BKE_object_matrix_local_get(struct Object *ob, float mat[4][4]);
+void BKE_object_matrix_local_get(struct Object *ob, float r_mat[4][4]);
bool BKE_object_pose_context_check(const struct Object *ob);
struct Object *BKE_object_pose_armature_get(struct Object *ob);
@@ -188,7 +187,7 @@ struct Base **BKE_object_pose_base_array_get(struct ViewLayer *view_layer,
struct View3D *v3d,
unsigned int *r_bases_len);
-void BKE_object_get_parent_matrix(struct Object *ob, struct Object *par, float parentmat[4][4]);
+void BKE_object_get_parent_matrix(struct Object *ob, struct Object *par, float r_parentmat[4][4]);
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,
@@ -199,7 +198,7 @@ void BKE_object_where_is_calc_time(struct Depsgraph *depsgraph,
struct Scene *scene,
struct Object *ob,
float ctime);
-void BKE_object_where_is_calc_mat4(struct Object *ob, float obmat[4][4]);
+void BKE_object_where_is_calc_mat4(struct Object *ob, float r_obmat[4][4]);
/* possibly belong in own moduke? */
struct BoundBox *BKE_boundbox_alloc_unit(void);
@@ -207,12 +206,12 @@ void BKE_boundbox_init_from_minmax(struct BoundBox *bb, const float min[3], cons
void BKE_boundbox_calc_center_aabb(const struct BoundBox *bb, float r_cent[3]);
void BKE_boundbox_calc_size_aabb(const struct BoundBox *bb, float r_size[3]);
void BKE_boundbox_minmax(const struct BoundBox *bb,
- float obmat[4][4],
+ const float obmat[4][4],
float r_min[3],
float r_max[3]);
struct BoundBox *BKE_object_boundbox_get(struct Object *ob);
-void BKE_object_dimensions_get(struct Object *ob, float vec[3]);
+void BKE_object_dimensions_get(struct Object *ob, float r_vec[3]);
void BKE_object_dimensions_set_ex(struct Object *ob,
const float value[3],
int axis_mask,
@@ -233,7 +232,7 @@ bool BKE_object_minmax_dupli(struct Depsgraph *depsgraph,
/* sometimes min-max isn't enough, we need to loop over each point */
void BKE_object_foreach_display_point(struct Object *ob,
- float obmat[4][4],
+ const float obmat[4][4],
void (*func_cb)(const float[3], void *),
void *user_data);
void BKE_scene_foreach_display_point(struct Depsgraph *depsgraph,
@@ -413,5 +412,3 @@ void BKE_object_to_mesh_clear(struct Object *object);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_object_deform.h b/source/blender/blenkernel/BKE_object_deform.h
index 410cb862aa7..a10158254c2 100644
--- a/source/blender/blenkernel/BKE_object_deform.h
+++ b/source/blender/blenkernel/BKE_object_deform.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_OBJECT_DEFORM_H__
-#define __BKE_OBJECT_DEFORM_H__
+#pragma once
/** \file
* \ingroup bke
@@ -33,7 +32,7 @@ struct Object;
struct bDeformGroup;
/* General vgroup operations */
-void BKE_object_defgroup_remap_update_users(struct Object *ob, int *map);
+void BKE_object_defgroup_remap_update_users(struct Object *ob, const int *map);
bool BKE_object_defgroup_array_get(struct ID *id, struct MDeformVert **dvert_arr, int *dvert_tot);
@@ -95,5 +94,3 @@ void BKE_object_defgroup_mirror_selection(struct Object *ob,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_OBJECT_DEFORM_H__ */
diff --git a/source/blender/blenkernel/BKE_object_facemap.h b/source/blender/blenkernel/BKE_object_facemap.h
index 83780d8fad5..10cb4a54bde 100644
--- a/source/blender/blenkernel/BKE_object_facemap.h
+++ b/source/blender/blenkernel/BKE_object_facemap.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_OBJECT_FACEMAP_H__
-#define __BKE_OBJECT_FACEMAP_H__
+#pragma once
/** \file
* \ingroup bke
@@ -48,5 +47,3 @@ void BKE_object_facemap_index_map_apply(int *fmap, int fmap_len, const int *map,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_OBJECT_FACEMAP_H__ */
diff --git a/source/blender/blenkernel/BKE_ocean.h b/source/blender/blenkernel/BKE_ocean.h
index 6ce2e13cf18..1f8cdf27eb1 100644
--- a/source/blender/blenkernel/BKE_ocean.h
+++ b/source/blender/blenkernel/BKE_ocean.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_OCEAN_H__
-#define __BKE_OCEAN_H__
+#pragma once
#include <stdbool.h>
@@ -70,8 +69,10 @@ typedef struct OceanCache {
struct Ocean *BKE_ocean_add(void);
void BKE_ocean_free_data(struct Ocean *oc);
void BKE_ocean_free(struct Ocean *oc);
-bool BKE_ocean_ensure(struct OceanModifierData *omd);
-void BKE_ocean_init_from_modifier(struct Ocean *ocean, struct OceanModifierData const *omd);
+bool BKE_ocean_ensure(struct OceanModifierData *omd, const int resolution);
+void BKE_ocean_init_from_modifier(struct Ocean *ocean,
+ struct OceanModifierData const *omd,
+ const int resolution);
void BKE_ocean_init(struct Ocean *o,
int M,
@@ -135,5 +136,3 @@ float BLI_ocean_spectrum_jonswap(const struct Ocean *oc, const float kx, const f
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_outliner_treehash.h b/source/blender/blenkernel/BKE_outliner_treehash.h
index 9f4ebffdcf4..94bf0f622d6 100644
--- a/source/blender/blenkernel/BKE_outliner_treehash.h
+++ b/source/blender/blenkernel/BKE_outliner_treehash.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_OUTLINER_TREEHASH_H__
-#define __BKE_OUTLINER_TREEHASH_H__
+#pragma once
/** \file
* \ingroup bke
@@ -59,5 +58,3 @@ void BKE_outliner_treehash_free(void *treehash);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_packedFile.h b/source/blender/blenkernel/BKE_packedFile.h
index fb2578b81b0..1e8721045cd 100644
--- a/source/blender/blenkernel/BKE_packedFile.h
+++ b/source/blender/blenkernel/BKE_packedFile.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_PACKEDFILE_H__
-#define __BKE_PACKEDFILE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -125,5 +124,3 @@ void BKE_packedfile_id_unpack(struct Main *bmain,
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index e08d3fe26fb..4e520948bcb 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -17,13 +17,13 @@
* All rights reserved.
*/
-#ifndef __BKE_PAINT_H__
-#define __BKE_PAINT_H__
+#pragma once
/** \file
* \ingroup bke
*/
+#include "BLI_bitmap.h"
#include "BLI_utildefines.h"
#include "DNA_object_enums.h"
@@ -41,6 +41,7 @@ struct EdgeSet;
struct GHash;
struct GridPaintMask;
struct ImagePool;
+struct ListBase;
struct MLoop;
struct MLoopTri;
struct MVert;
@@ -259,10 +260,20 @@ typedef struct SculptPoseIKChain {
/* Cloth Brush */
typedef struct SculptClothLengthConstraint {
- int v1;
- int v2;
+ /* Elements that are affected by the constraint. */
+ /* Element a should always be a mesh vertex with the index stored in elem_index_a as it is always
+ * deformed. Element b could be another vertex of the same mesh or any other position (arbitrary
+ * point, position for a previous state). In that case, elem_index_a and elem_index_b should be
+ * the same to avoid affecting two different vertices when solving the constraints.
+ * *elem_position points to the position which is owned by the element. */
+ int elem_index_a;
+ float *elem_position_a;
+
+ int elem_index_b;
+ float *elem_position_b;
float length;
+ float strength;
} SculptClothLengthConstraint;
typedef struct SculptClothSimulation {
@@ -272,6 +283,11 @@ typedef struct SculptClothSimulation {
int capacity_length_constraints;
float *length_constraint_tweak;
+ /* Position anchors for deformation brushes. These positions are modified by the brush and the
+ * final positions of the simulated vertices are updated with constraints that use these points
+ * as targets. */
+ float (*deformation_pos)[3];
+
float mass;
float damping;
@@ -279,7 +295,9 @@ typedef struct SculptClothSimulation {
float (*pos)[3];
float (*init_pos)[3];
float (*prev_pos)[3];
+ float (*last_iteration_pos)[3];
+ struct ListBase *collider_list;
} SculptClothSimulation;
typedef struct SculptPersistentBase {
@@ -291,6 +309,9 @@ typedef struct SculptPersistentBase {
typedef struct SculptVertexInfo {
/* Idexed by vertex, stores and ID of its topologycally connected component. */
int *connected_component;
+
+ /* Indexed by base mesh vertex index, stores if that vertex is a boundary. */
+ BLI_bitmap *boundary;
} SculptVertexInfo;
typedef struct SculptFakeNeighbors {
@@ -314,6 +335,9 @@ typedef struct SculptSession {
int level;
} multires;
+ /* Depsgraph for the Cloth Brush solver to get the colliders. */
+ struct Depsgraph *depsgraph;
+
/* These are always assigned to base mesh data when using PBVH_FACES and PBVH_GRIDS. */
struct MVert *mvert;
struct MPoly *mpoly;
@@ -447,6 +471,10 @@ void BKE_sculptsession_free_vwpaint_data(struct SculptSession *ss);
void BKE_sculptsession_bm_to_me(struct Object *ob, bool reorder);
void BKE_sculptsession_bm_to_me_for_render(struct Object *object);
+/* Create new color layer on object if it doesn't have one and if experimental feature set has
+ * sculpt vertex color enabled. Returns truth if new layer has been added, false otherwise. */
+void BKE_sculpt_color_layer_create_if_needed(struct Object *object);
+
void BKE_sculpt_update_object_for_edit(struct Depsgraph *depsgraph,
struct Object *ob_orig,
bool need_pmap,
@@ -463,6 +491,10 @@ struct PBVH *BKE_sculpt_object_pbvh_ensure(struct Depsgraph *depsgraph, struct O
void BKE_sculpt_bvh_update_from_ccg(struct PBVH *pbvh, struct SubdivCCG *subdiv_ccg);
+/* This ensure that all elements in the mesh (both vertices and grids) have their visibility
+ * updated according to the face sets. */
+void BKE_sculpt_sync_face_set_visibility(struct Mesh *mesh, struct SubdivCCG *subdiv_ccg);
+
bool BKE_sculptsession_use_pbvh_draw(const struct Object *ob, const struct View3D *v3d);
enum {
@@ -473,5 +505,3 @@ enum {
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index a22cb9ef126..7d317538f44 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -20,8 +20,7 @@
* Copyright 2011-2012 AutoCRC
*/
-#ifndef __BKE_PARTICLE_H__
-#define __BKE_PARTICLE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -217,7 +216,7 @@ typedef struct ParticleCollision {
/** Collision modifier for current object. */
struct CollisionModifierData *md;
- /** Time factor of previous collision, needed for substracting face velocity. */
+ /** Time factor of previous collision, needed for subtracting face velocity. */
float f;
float fac1, fac2;
@@ -365,6 +364,10 @@ struct ModifierData *object_add_particle_system(struct Main *bmain,
struct Scene *scene,
struct Object *ob,
const char *name);
+struct ModifierData *object_copy_particle_system(struct Main *bmain,
+ struct Scene *scene,
+ struct Object *ob,
+ const struct ParticleSystem *psys_orig);
void object_remove_particle_system(struct Main *bmain, struct Scene *scene, struct Object *ob);
struct ParticleSettings *BKE_particlesettings_add(struct Main *bmain, const char *name);
struct ParticleSettings *BKE_particlesettings_copy(struct Main *bmain,
@@ -576,7 +579,7 @@ void psys_particle_on_dm(struct Mesh *mesh_final,
/* particle_system.c */
void distribute_particles(struct ParticleSimulationData *sim, int from);
-void initialize_particle(struct ParticleSimulationData *sim, struct ParticleData *pa);
+void init_particle(struct ParticleSimulationData *sim, struct ParticleData *pa);
void psys_calc_dmcache(struct Object *ob,
struct Mesh *mesh_final,
struct Mesh *mesh_original,
@@ -627,5 +630,3 @@ extern void (*BKE_particle_batch_cache_free_cb)(struct ParticleSystem *psys);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_PARTICLE_H__ */
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 87875314aec..9826dfaa4a5 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_PBVH_H__
-#define __BKE_PBVH_H__
+#pragma once
/** \file
* \ingroup bke
@@ -224,7 +223,7 @@ void BKE_pbvh_bounding_box(const PBVH *pbvh, float min[3], float max[3]);
unsigned int **BKE_pbvh_grid_hidden(const PBVH *pbvh);
int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden,
- int *grid_indices,
+ const int *grid_indices,
int totgrid,
int gridsize);
@@ -264,6 +263,7 @@ void BKE_pbvh_node_mark_redraw(PBVHNode *node);
void BKE_pbvh_node_mark_normals_update(PBVHNode *node);
void BKE_pbvh_node_mark_topology_update(PBVHNode *node);
void BKE_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden);
+bool BKE_pbvh_node_fully_hidden_get(PBVHNode *node);
void BKE_pbvh_node_fully_masked_set(PBVHNode *node, int fully_masked);
bool BKE_pbvh_node_fully_masked_get(PBVHNode *node);
void BKE_pbvh_node_fully_unmasked_set(PBVHNode *node, int fully_masked);
@@ -488,5 +488,3 @@ void BKE_pbvh_node_color_buffer_free(PBVH *pbvh);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_PBVH_H__ */
diff --git a/source/blender/blenkernel/BKE_persistent_data_handle.hh b/source/blender/blenkernel/BKE_persistent_data_handle.hh
new file mode 100644
index 00000000000..bcc84f9c9d0
--- /dev/null
+++ b/source/blender/blenkernel/BKE_persistent_data_handle.hh
@@ -0,0 +1,129 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+/** \file
+ * \ingroup bke
+ *
+ * A PersistentDataHandle is a weak reference to some data in a Blender file. The handle itself is
+ * just a number. A PersistentDataHandleMap is used to convert between handles and the actual data.
+ */
+
+#include "BLI_map.hh"
+
+#include "DNA_ID.h"
+
+struct Object;
+
+namespace blender::bke {
+
+class PersistentDataHandleMap;
+
+class PersistentDataHandle {
+ private:
+ /* Negative values indicate that the handle is "empty". */
+ int32_t handle_;
+
+ friend PersistentDataHandleMap;
+
+ protected:
+ PersistentDataHandle(int handle) : handle_(handle)
+ {
+ }
+
+ public:
+ PersistentDataHandle() : handle_(-1)
+ {
+ }
+
+ friend bool operator==(const PersistentDataHandle &a, const PersistentDataHandle &b)
+ {
+ return a.handle_ == b.handle_;
+ }
+
+ friend bool operator!=(const PersistentDataHandle &a, const PersistentDataHandle &b)
+ {
+ return !(a == b);
+ }
+
+ friend std::ostream &operator<<(std::ostream &stream, const PersistentDataHandle &a)
+ {
+ stream << a.handle_;
+ return stream;
+ }
+
+ uint64_t hash() const
+ {
+ return (uint64_t)handle_;
+ }
+};
+
+class PersistentIDHandle : public PersistentDataHandle {
+ friend PersistentDataHandleMap;
+ using PersistentDataHandle::PersistentDataHandle;
+};
+
+class PersistentObjectHandle : public PersistentIDHandle {
+ friend PersistentDataHandleMap;
+ using PersistentIDHandle::PersistentIDHandle;
+};
+
+class PersistentDataHandleMap {
+ private:
+ Map<int32_t, ID *> id_by_handle_;
+ Map<ID *, int32_t> handle_by_id_;
+
+ public:
+ void add(int32_t handle, ID &id)
+ {
+ BLI_assert(handle >= 0);
+ handle_by_id_.add(&id, handle);
+ id_by_handle_.add(handle, &id);
+ }
+
+ PersistentIDHandle lookup(ID *id) const
+ {
+ const int handle = handle_by_id_.lookup_default(id, -1);
+ return PersistentIDHandle(handle);
+ }
+
+ PersistentObjectHandle lookup(Object *object) const
+ {
+ const int handle = handle_by_id_.lookup_default((ID *)object, -1);
+ return PersistentObjectHandle(handle);
+ }
+
+ ID *lookup(const PersistentIDHandle &handle) const
+ {
+ ID *id = id_by_handle_.lookup_default(handle.handle_, nullptr);
+ return id;
+ }
+
+ Object *lookup(const PersistentObjectHandle &handle) const
+ {
+ ID *id = this->lookup((const PersistentIDHandle &)handle);
+ if (id == nullptr) {
+ return nullptr;
+ }
+ if (GS(id->name) != ID_OB) {
+ return nullptr;
+ }
+ return (Object *)id;
+ }
+};
+
+} // namespace blender::bke
diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h
index b0973ed458c..c5bf94cc0c8 100644
--- a/source/blender/blenkernel/BKE_pointcache.h
+++ b/source/blender/blenkernel/BKE_pointcache.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_POINTCACHE_H__
-#define __BKE_POINTCACHE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -86,12 +85,10 @@ struct ListBase;
struct Main;
struct Object;
struct ParticleKey;
-struct ParticleSimulationState;
struct ParticleSystem;
struct PointCache;
struct RigidBodyWorld;
struct Scene;
-struct Simulation;
struct SoftBody;
struct ViewLayer;
@@ -147,7 +144,7 @@ typedef struct PTCacheID {
/* copies point data to cache data */
int (*write_point)(int index, void *calldata, void **data, int cfra);
/* copies cache cata to point data */
- void (*read_point)(int index, void *calldata, void **data, float cfra, float *old_data);
+ void (*read_point)(int index, void *calldata, void **data, float cfra, const float *old_data);
/* interpolated between previously read point data and cache data */
void (*interpolate_point)(int index,
void *calldata,
@@ -155,7 +152,7 @@ typedef struct PTCacheID {
float cfra,
float cfra1,
float cfra2,
- float *old_data);
+ const float *old_data);
/* copies point data to cache data */
int (*write_stream)(PTCacheFile *pf, void *calldata);
@@ -296,7 +293,6 @@ void BKE_ptcache_id_from_dynamicpaint(PTCacheID *pid,
struct Object *ob,
struct DynamicPaintSurface *surface);
void BKE_ptcache_id_from_rigidbody(PTCacheID *pid, struct Object *ob, struct RigidBodyWorld *rbw);
-void BKE_ptcache_id_from_sim_particles(PTCacheID *pid, struct ParticleSimulationState *state);
PTCacheID BKE_ptcache_id_find(struct Object *ob, struct Scene *scene, struct PointCache *cache);
void BKE_ptcache_ids_from_object(struct ListBase *lb,
@@ -390,5 +386,3 @@ void BKE_ptcache_invalidate(struct PointCache *cache);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_pointcloud.h b/source/blender/blenkernel/BKE_pointcloud.h
index d641d3feb62..b2e7e1d23ee 100644
--- a/source/blender/blenkernel/BKE_pointcloud.h
+++ b/source/blender/blenkernel/BKE_pointcloud.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_POINTCLOUD_H__
-#define __BKE_POINTCLOUD_H__
+#pragma once
/** \file
* \ingroup bke
@@ -64,5 +63,3 @@ extern void (*BKE_pointcloud_batch_cache_free_cb)(struct PointCloud *pointcloud)
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_report.h b/source/blender/blenkernel/BKE_report.h
index 063c0831a0d..5b22918e84c 100644
--- a/source/blender/blenkernel/BKE_report.h
+++ b/source/blender/blenkernel/BKE_report.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_REPORT_H__
-#define __BKE_REPORT_H__
+#pragma once
/** \file
* \ingroup bke
@@ -69,5 +68,3 @@ bool BKE_report_write_file(const char *filepath, ReportList *reports, const char
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_rigidbody.h b/source/blender/blenkernel/BKE_rigidbody.h
index b4aa0ac2b93..c2059144388 100644
--- a/source/blender/blenkernel/BKE_rigidbody.h
+++ b/source/blender/blenkernel/BKE_rigidbody.h
@@ -22,8 +22,7 @@
* \brief API for Blender-side Rigid Body stuff
*/
-#ifndef __BKE_RIGIDBODY_H__
-#define __BKE_RIGIDBODY_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -162,5 +161,3 @@ void BKE_rigidbody_object_sync_transforms(struct Depsgraph *depsgraph,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_RIGIDBODY_H__ */
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h
index 800370318c4..8cd86593873 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_SCENE_H__
-#define __BKE_SCENE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -260,5 +259,3 @@ void BKE_scene_eval_sequencer_sequences(struct Depsgraph *depsgraph, struct Scen
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h
index 91f241018ec..edab543fc37 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_SCREEN_H__
-#define __BKE_SCREEN_H__
+#pragma once
/** \file
* \ingroup bke
@@ -73,7 +72,7 @@ typedef struct SpaceType {
/* Initial allocation, after this WM will call init() too. Some editors need
* area and scene data (e.g. frame range) to set their initial scrolling. */
- struct SpaceLink *(*new)(const struct ScrArea *area, const struct Scene *scene);
+ struct SpaceLink *(*create)(const struct ScrArea *area, const struct Scene *scene);
/* not free spacelink itself */
void (*free)(struct SpaceLink *sl);
@@ -142,7 +141,13 @@ typedef struct ARegionType {
void (*exit)(struct wmWindowManager *wm, struct ARegion *region);
/* draw entirely, view changes should be handled here */
void (*draw)(const struct bContext *C, struct ARegion *region);
- /* Handler to draw overlays. This handler is called every draw loop. */
+ /**
+ * Handler to draw overlays. This handler is called every draw loop.
+ *
+ * \note Some editors should return early if the interface is locked
+ * (check with #CTX_wm_interface_locked) to avoid accessing scene data
+ * that another thread may be modifying
+ */
void (*draw_overlay)(const struct bContext *C, struct ARegion *region);
/* optional, compute button layout before drawing for dynamic size */
void (*layout)(const struct bContext *C, struct ARegion *region);
@@ -430,5 +435,3 @@ void BKE_screen_header_alignment_reset(struct bScreen *screen);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h
index a50f9b24c61..b6d901c8ef2 100644
--- a/source/blender/blenkernel/BKE_sequencer.h
+++ b/source/blender/blenkernel/BKE_sequencer.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_SEQUENCER_H__
-#define __BKE_SEQUENCER_H__
+#pragma once
/** \file
* \ingroup bke
@@ -285,6 +284,11 @@ void BKE_sequence_reload_new_file(struct Main *bmain,
struct Scene *scene,
struct Sequence *seq,
const bool lock_range);
+void BKE_sequence_movie_reload_if_needed(struct Main *bmain,
+ struct Scene *scene,
+ struct Sequence *seq,
+ bool *r_was_reloaded,
+ bool *r_can_produce_frames);
int BKE_sequencer_evaluate_frame(struct Scene *scene, int cfra);
int BKE_sequencer_get_shown_sequences(struct ListBase *seqbasep,
int cfra,
@@ -522,6 +526,9 @@ typedef struct Sequence *(*SeqLoadFn)(struct bContext *, ListBase *, struct SeqL
struct Sequence *BKE_sequence_alloc(ListBase *lb, int cfra, int machine, int type);
+/* Generate new UUID for the given sequence. */
+void BKE_sequence_session_uuid_generate(struct Sequence *sequence);
+
void BKE_sequence_alpha_mode_from_extension(struct Sequence *seq);
void BKE_sequence_init_colorspace(struct Sequence *seq);
@@ -619,9 +626,16 @@ void BKE_sequencer_color_balance_apply(struct StripColorBalance *cb,
void BKE_sequencer_all_free_anim_ibufs(struct Scene *scene, int cfra);
bool BKE_sequencer_check_scene_recursion(struct Scene *scene, struct ReportList *reports);
+bool BKE_sequencer_render_loop_check(struct Sequence *seq_main, struct Sequence *seq);
+void BKE_sequencer_flag_for_removal(struct Scene *scene,
+ struct ListBase *seqbase,
+ struct Sequence *seq);
+void BKE_sequencer_remove_flagged_sequences(struct Scene *scene, struct ListBase *seqbase);
+
+/* A debug and development function which checks whether sequences have unique UUIDs.
+ * Errors will be reported to the console. */
+void BKE_sequencer_check_uuids_unique_and_report(const struct Scene *scene);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_SEQUENCER_H__ */
diff --git a/source/blender/blenkernel/BKE_sequencer_offscreen.h b/source/blender/blenkernel/BKE_sequencer_offscreen.h
index cc822e97270..90d3f80320a 100644
--- a/source/blender/blenkernel/BKE_sequencer_offscreen.h
+++ b/source/blender/blenkernel/BKE_sequencer_offscreen.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_SEQUENCER_OFFSCREEN_H__
-#define __BKE_SEQUENCER_OFFSCREEN_H__
+#pragma once
/** \file
* \ingroup bke
@@ -52,5 +51,3 @@ extern SequencerDrawView sequencer_view3d_fn;
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_SEQUENCER_H__ */
diff --git a/source/blender/blenkernel/BKE_shader_fx.h b/source/blender/blenkernel/BKE_shader_fx.h
index 31e14c6c884..1eb52b389d1 100644
--- a/source/blender/blenkernel/BKE_shader_fx.h
+++ b/source/blender/blenkernel/BKE_shader_fx.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_SHADER_FX_H__
-#define __BKE_SHADER_FX_H__
+#pragma once
/** \file
* \ingroup bke
@@ -189,5 +188,3 @@ bool BKE_shaderfx_has_gpencil(struct Object *ob);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_SHADER_FX_H__ */
diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h
index 83129bed5f7..bcf702ea797 100644
--- a/source/blender/blenkernel/BKE_shrinkwrap.h
+++ b/source/blender/blenkernel/BKE_shrinkwrap.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) Blender Foundation.
* All rights reserved.
*/
-#ifndef __BKE_SHRINKWRAP_H__
-#define __BKE_SHRINKWRAP_H__
+#pragma once
/** \file
* \ingroup bke
@@ -192,5 +191,3 @@ void BKE_shrinkwrap_snap_point_to_surface(const struct ShrinkwrapTreeData *tree,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_SHRINKWRAP_H__ */
diff --git a/source/blender/blenkernel/BKE_simulation.h b/source/blender/blenkernel/BKE_simulation.h
index ff6aaa5e30e..2c436f2bff8 100644
--- a/source/blender/blenkernel/BKE_simulation.h
+++ b/source/blender/blenkernel/BKE_simulation.h
@@ -14,8 +14,9 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_SIMULATION_H__
-#define __BKE_SIMULATION_H__
+#pragma once
+
+#include "DNA_simulation_types.h"
#ifdef __cplusplus
extern "C" {
@@ -23,16 +24,34 @@ extern "C" {
struct Depsgraph;
struct Main;
-struct Simulation;
+struct Scene;
void *BKE_simulation_add(struct Main *bmain, const char *name);
void BKE_simulation_data_update(struct Depsgraph *depsgraph,
struct Scene *scene,
struct Simulation *simulation);
+void BKE_simulation_update_dependencies(struct Simulation *simulation, struct Main *bmain);
+
+SimulationState *BKE_simulation_state_add(Simulation *simulation,
+ const char *type,
+ const char *name);
+void BKE_simulation_state_remove(Simulation *simulation, SimulationState *state);
+void BKE_simulation_state_remove_all(Simulation *simulation);
+void BKE_simulation_state_reset(Simulation *simulation, SimulationState *state);
+void BKE_simulation_state_reset_all(Simulation *simulation);
+SimulationState *BKE_simulation_state_try_find_by_name(Simulation *simulation, const char *name);
+SimulationState *BKE_simulation_state_try_find_by_name_and_type(Simulation *simulation,
+ const char *name,
+ const char *type);
+void BKE_simulation_state_copy_data(const SimulationState *src_state, SimulationState *dst_state);
#ifdef __cplusplus
}
#endif
-#endif /* __BKE_SIMULATION_H__ */
+#ifdef __cplusplus
+
+template<typename StateType> const char *BKE_simulation_get_state_type_name();
+
+#endif
diff --git a/source/blender/blenkernel/BKE_softbody.h b/source/blender/blenkernel/BKE_softbody.h
index e4012094b74..28d299679ed 100644
--- a/source/blender/blenkernel/BKE_softbody.h
+++ b/source/blender/blenkernel/BKE_softbody.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) Blender Foundation.
* All rights reserved.
*/
-#ifndef __BKE_SOFTBODY_H__
-#define __BKE_SOFTBODY_H__
+#pragma once
/** \file
* \ingroup bke
@@ -76,5 +75,3 @@ extern void SB_estimate_transform(Object *ob, float lloc[3], float lrot[3][3], f
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h
index b93591b7b60..57ce33a239f 100644
--- a/source/blender/blenkernel/BKE_sound.h
+++ b/source/blender/blenkernel/BKE_sound.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_SOUND_H__
-#define __BKE_SOUND_H__
+#pragma once
/** \file
* \ingroup bke
@@ -194,5 +193,3 @@ void BKE_sound_evaluate(struct Depsgraph *depsgraph, struct Main *bmain, struct
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_SOUND_H__ */
diff --git a/source/blender/blenkernel/BKE_speaker.h b/source/blender/blenkernel/BKE_speaker.h
index 54bb7274e4b..b01824dd794 100644
--- a/source/blender/blenkernel/BKE_speaker.h
+++ b/source/blender/blenkernel/BKE_speaker.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_SPEAKER_H__
-#define __BKE_SPEAKER_H__
+#pragma once
/** \file
* \ingroup bke
@@ -35,5 +34,3 @@ struct Speaker *BKE_speaker_copy(struct Main *bmain, const struct Speaker *spk);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_studiolight.h b/source/blender/blenkernel/BKE_studiolight.h
index ff11f581cc4..32c571e5f91 100644
--- a/source/blender/blenkernel/BKE_studiolight.h
+++ b/source/blender/blenkernel/BKE_studiolight.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_STUDIOLIGHT_H__
-#define __BKE_STUDIOLIGHT_H__
+#pragma once
/** \file
* \ingroup bke
@@ -168,5 +167,3 @@ void BKE_studiolight_unset_icon_id(StudioLight *sl, int icon_id);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_STUDIOLIGHT_H__ */
diff --git a/source/blender/blenkernel/BKE_subdiv.h b/source/blender/blenkernel/BKE_subdiv.h
index 1323938e479..96a79d753cf 100644
--- a/source/blender/blenkernel/BKE_subdiv.h
+++ b/source/blender/blenkernel/BKE_subdiv.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __BKE_SUBDIV_H__
-#define __BKE_SUBDIV_H__
+#pragma once
#include "BLI_compiler_compat.h"
#include "BLI_sys_types.h"
@@ -302,5 +301,3 @@ BLI_INLINE float BKE_subdiv_edge_crease_to_sharpness_char(char edge_crease);
#endif
#include "intern/subdiv_inline.h"
-
-#endif /* __BKE_SUBDIV_H__ */
diff --git a/source/blender/blenkernel/BKE_subdiv_ccg.h b/source/blender/blenkernel/BKE_subdiv_ccg.h
index 78e91d3ad2f..2277eb27ef1 100644
--- a/source/blender/blenkernel/BKE_subdiv_ccg.h
+++ b/source/blender/blenkernel/BKE_subdiv_ccg.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __BKE_SUBDIV_CCG_H__
-#define __BKE_SUBDIV_CCG_H__
+#pragma once
#include "BKE_DerivedMesh.h"
#include "BKE_customdata.h"
@@ -313,6 +312,22 @@ void BKE_subdiv_ccg_neighbor_coords_get(const SubdivCCG *subdiv_ccg,
int BKE_subdiv_ccg_grid_to_face_index(const SubdivCCG *subdiv_ccg, const int grid_index);
+typedef enum SubdivCCGAdjacencyType {
+ SUBDIV_CCG_ADJACENT_NONE,
+ SUBDIV_CCG_ADJACENT_VERTEX,
+ SUBDIV_CCG_ADJACENT_EDGE,
+} SubdivCCGAdjacencyType;
+
+/* Returns if a grid coordinates is adjacent to a coarse mesh edge, vertex or nothing. If it is
+ * adjacent to an edge, r_v1 and r_v2 will be set to the two vertices of that edge. If it is
+ * adjacent to a vertex, r_v1 and r_v2 will be the index of that vertex. */
+SubdivCCGAdjacencyType BKE_subdiv_ccg_coarse_mesh_adjacency_info_get(const SubdivCCG *subdiv_ccg,
+ const SubdivCCGCoord *coord,
+ const MLoop *mloop,
+ const MPoly *mpoly,
+ int *r_v1,
+ int *r_v2);
+
/* Get array which is indexed by face index and contains index of a first grid of the face.
*
* The "ensure" version allocates the mapping if it's not know yet and stores it in the subdiv_ccg
@@ -322,8 +337,8 @@ int BKE_subdiv_ccg_grid_to_face_index(const SubdivCCG *subdiv_ccg, const int gri
const int *BKE_subdiv_ccg_start_face_grid_index_ensure(SubdivCCG *subdiv_ccg);
const int *BKE_subdiv_ccg_start_face_grid_index_get(const SubdivCCG *subdiv_ccg);
+void BKE_subdiv_ccg_grid_hidden_ensure(SubdivCCG *subdiv_ccg, int grid_index);
+
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_SUBDIV_CCG_H__ */
diff --git a/source/blender/blenkernel/BKE_subdiv_deform.h b/source/blender/blenkernel/BKE_subdiv_deform.h
index 735cd20a6c8..1cdb8d2c794 100644
--- a/source/blender/blenkernel/BKE_subdiv_deform.h
+++ b/source/blender/blenkernel/BKE_subdiv_deform.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __BKE_SUBDIV_DEFORM_H__
-#define __BKE_SUBDIV_DEFORM_H__
+#pragma once
#include "BLI_sys_types.h"
@@ -48,5 +47,3 @@ void BKE_subdiv_deform_coarse_vertices(struct Subdiv *subdiv,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_SUBDIV_DEFORM_H__ */
diff --git a/source/blender/blenkernel/BKE_subdiv_eval.h b/source/blender/blenkernel/BKE_subdiv_eval.h
index aa27df88be8..204e802da6e 100644
--- a/source/blender/blenkernel/BKE_subdiv_eval.h
+++ b/source/blender/blenkernel/BKE_subdiv_eval.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __BKE_SUBDIV_EVAL_H__
-#define __BKE_SUBDIV_EVAL_H__
+#pragma once
#include "BLI_sys_types.h"
@@ -149,5 +148,3 @@ void BKE_subdiv_eval_limit_patch_resolution_point_and_short_normal(struct Subdiv
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_SUBDIV_EVAL_H__ */
diff --git a/source/blender/blenkernel/BKE_subdiv_foreach.h b/source/blender/blenkernel/BKE_subdiv_foreach.h
index bef141b5ac5..a351b9a3d11 100644
--- a/source/blender/blenkernel/BKE_subdiv_foreach.h
+++ b/source/blender/blenkernel/BKE_subdiv_foreach.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __BKE_SUBDIV_FOREACH_H__
-#define __BKE_SUBDIV_FOREACH_H__
+#pragma once
#include "BLI_sys_types.h"
@@ -178,5 +177,3 @@ bool BKE_subdiv_foreach_subdiv_geometry(struct Subdiv *subdiv,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_SUBDIV_FOREACH_H__ */
diff --git a/source/blender/blenkernel/BKE_subdiv_mesh.h b/source/blender/blenkernel/BKE_subdiv_mesh.h
index 9928c41a92b..73a3e8ed02e 100644
--- a/source/blender/blenkernel/BKE_subdiv_mesh.h
+++ b/source/blender/blenkernel/BKE_subdiv_mesh.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __BKE_SUBDIV_MESH_H__
-#define __BKE_SUBDIV_MESH_H__
+#pragma once
#include "BLI_sys_types.h"
@@ -53,5 +52,3 @@ struct Mesh *BKE_subdiv_to_mesh(struct Subdiv *subdiv,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_SUBDIV)MESH_H__ */
diff --git a/source/blender/blenkernel/BKE_subdiv_topology.h b/source/blender/blenkernel/BKE_subdiv_topology.h
index cc32b4c03b3..42bd9392aa4 100644
--- a/source/blender/blenkernel/BKE_subdiv_topology.h
+++ b/source/blender/blenkernel/BKE_subdiv_topology.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __BKE_SUBDIV_TOPOLOGY_H__
-#define __BKE_SUBDIV_TOPOLOGY_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -35,5 +34,3 @@ int BKE_subdiv_topology_num_fvar_layers_get(const struct Subdiv *subdiv);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_SUBDIV_TOPOLOGY_H__ */
diff --git a/source/blender/blenkernel/BKE_subsurf.h b/source/blender/blenkernel/BKE_subsurf.h
index 0ed58180ffa..07bbeafb1ae 100644
--- a/source/blender/blenkernel/BKE_subsurf.h
+++ b/source/blender/blenkernel/BKE_subsurf.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_SUBSURF_H__
-#define __BKE_SUBSURF_H__
+#pragma once
/** \file
* \ingroup bke
@@ -158,5 +157,3 @@ typedef struct CCGDerivedMesh {
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_text.h b/source/blender/blenkernel/BKE_text.h
index 51d589e61c3..289ad351429 100644
--- a/source/blender/blenkernel/BKE_text.h
+++ b/source/blender/blenkernel/BKE_text.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_TEXT_H__
-#define __BKE_TEXT_H__
+#pragma once
/** \file
* \ingroup bke
@@ -118,5 +117,3 @@ void txt_from_buf_for_undo(struct Text *text, const char *buf, int buf_len);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_text_suggestions.h b/source/blender/blenkernel/BKE_text_suggestions.h
index d618fcd6d11..f54e45b6c2f 100644
--- a/source/blender/blenkernel/BKE_text_suggestions.h
+++ b/source/blender/blenkernel/BKE_text_suggestions.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2008, Blender Foundation
* All rights reserved.
*/
-#ifndef __BKE_TEXT_SUGGESTIONS_H__
-#define __BKE_TEXT_SUGGESTIONS_H__
+#pragma once
/** \file
* \ingroup bke
@@ -85,5 +84,3 @@ void texttool_docs_clear(void);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_TEXT_SUGGESTIONS_H__ */
diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h
index 43ef2b1ba7f..c4c2498c2b1 100644
--- a/source/blender/blenkernel/BKE_texture.h
+++ b/source/blender/blenkernel/BKE_texture.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_TEXTURE_H__
-#define __BKE_TEXTURE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -102,5 +101,3 @@ void BKE_texture_fetch_images_for_pool(struct Tex *texture, struct ImagePool *po
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h
index bb88fbf863b..2d763132923 100644
--- a/source/blender/blenkernel/BKE_tracking.h
+++ b/source/blender/blenkernel/BKE_tracking.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_TRACKING_H__
-#define __BKE_TRACKING_H__
+#pragma once
/** \file
* \ingroup bke
@@ -493,5 +492,3 @@ void BKE_tracking_get_rna_path_prefix_for_plane_track(
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_undo_system.h b/source/blender/blenkernel/BKE_undo_system.h
index b32c3e315ff..4f933ca7a87 100644
--- a/source/blender/blenkernel/BKE_undo_system.h
+++ b/source/blender/blenkernel/BKE_undo_system.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_UNDO_SYSTEM_H__
-#define __BKE_UNDO_SYSTEM_H__
+#pragma once
/** \file
* \ingroup bke
@@ -212,5 +211,3 @@ void BKE_undosys_print(UndoStack *ustack);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_UNDO_SYSTEM_H__ */
diff --git a/source/blender/blenkernel/BKE_unit.h b/source/blender/blenkernel/BKE_unit.h
index 4f9ff61c9a6..a797c5555ff 100644
--- a/source/blender/blenkernel/BKE_unit.h
+++ b/source/blender/blenkernel/BKE_unit.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_UNIT_H__
-#define __BKE_UNIT_H__
+#pragma once
/** \file
* \ingroup bke
@@ -93,5 +92,3 @@ enum {
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_UNIT_H__ */
diff --git a/source/blender/blenkernel/BKE_volume.h b/source/blender/blenkernel/BKE_volume.h
index 224f3ede45d..b3437454f31 100644
--- a/source/blender/blenkernel/BKE_volume.h
+++ b/source/blender/blenkernel/BKE_volume.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_VOLUME_H__
-#define __BKE_VOLUME_H__
+#pragma once
/** \file
* \ingroup bke
@@ -159,5 +158,3 @@ openvdb::GridBase::Ptr BKE_volume_grid_openvdb_for_write(const struct Volume *vo
struct VolumeGrid *grid,
const bool clear);
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_volume_render.h b/source/blender/blenkernel/BKE_volume_render.h
index 5c3cd0102cf..a42f24a5312 100644
--- a/source/blender/blenkernel/BKE_volume_render.h
+++ b/source/blender/blenkernel/BKE_volume_render.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_VOLUME_RENDER_H__
-#define __BKE_VOLUME_RENDER_H__
+#pragma once
/** \file
* \ingroup bke
@@ -66,5 +65,3 @@ float BKE_volume_density_scale(const struct Volume *volume, const float matrix[4
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_workspace.h b/source/blender/blenkernel/BKE_workspace.h
index 8a6afd8a753..5ff1ba2c6f5 100644
--- a/source/blender/blenkernel/BKE_workspace.h
+++ b/source/blender/blenkernel/BKE_workspace.h
@@ -18,8 +18,7 @@
* \ingroup bke
*/
-#ifndef __BKE_WORKSPACE_H__
-#define __BKE_WORKSPACE_H__
+#pragma once
#include "BLI_compiler_attrs.h"
@@ -112,5 +111,3 @@ void BKE_workspace_id_tag_all_visible(struct Main *bmain, int tag) ATTR_NONNULL(
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_WORKSPACE_H__ */
diff --git a/source/blender/blenkernel/BKE_world.h b/source/blender/blenkernel/BKE_world.h
index 3c8f8547b46..82830facccc 100644
--- a/source/blender/blenkernel/BKE_world.h
+++ b/source/blender/blenkernel/BKE_world.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_WORLD_H__
-#define __BKE_WORLD_H__
+#pragma once
/** \file
* \ingroup bke
@@ -39,5 +38,3 @@ void BKE_world_eval(struct Depsgraph *depsgraph, struct World *world);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_writeavi.h b/source/blender/blenkernel/BKE_writeavi.h
index 79605e99306..97f998cc1c1 100644
--- a/source/blender/blenkernel/BKE_writeavi.h
+++ b/source/blender/blenkernel/BKE_writeavi.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_WRITEAVI_H__
-#define __BKE_WRITEAVI_H__
+#pragma once
/** \file
* \ingroup bke
@@ -73,5 +72,3 @@ void BKE_movie_filepath_get(char *string,
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_writeffmpeg.h b/source/blender/blenkernel/BKE_writeffmpeg.h
index 467e6ab7242..4c966c55e41 100644
--- a/source/blender/blenkernel/BKE_writeffmpeg.h
+++ b/source/blender/blenkernel/BKE_writeffmpeg.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_WRITEFFMPEG_H__
-#define __BKE_WRITEFFMPEG_H__
+#pragma once
/** \file
* \ingroup bke
@@ -100,5 +99,3 @@ void BKE_ffmpeg_context_free(void *context_v);
# endif
#endif
-
-#endif
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index b9054d29752..ada341ff570 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -27,6 +27,7 @@ set(INC
../bmesh
../depsgraph
../draw
+ ../functions
../gpencil_modifiers
../gpu
../ikplugin
@@ -35,7 +36,7 @@ set(INC
../makesrna
../modifiers
../nodes
- ../physics
+ ../simulation
../shader_fx
../render/extern/include
../../../intern/ghost
@@ -99,6 +100,7 @@ set(SRC
intern/context.c
intern/crazyspace.c
intern/curve.c
+ intern/curve_bevel.c
intern/curve_decimate.c
intern/curve_deform.c
intern/curveprofile.c
@@ -106,7 +108,6 @@ set(SRC
intern/customdata_file.c
intern/data_transfer.c
intern/deform.c
- intern/derived_node_tree.cc
intern/displist.c
intern/displist_tangent.c
intern/dynamicpaint.c
@@ -134,6 +135,7 @@ set(SRC
intern/idtype.c
intern/image.c
intern/image_gen.c
+ intern/image_gpu.c
intern/image_save.c
intern/ipo.c
intern/kelvinlet.c
@@ -187,7 +189,6 @@ set(SRC
intern/multires_unsubdivide.c
intern/nla.c
intern/node.c
- intern/node_tree_ref.cc
intern/object.c
intern/object_deform.c
intern/object_dupli.c
@@ -296,7 +297,6 @@ set(SRC
BKE_customdata_file.h
BKE_data_transfer.h
BKE_deform.h
- BKE_derived_node_tree.hh
BKE_displist.h
BKE_displist_tangent.h
BKE_duplilist.h
@@ -322,6 +322,7 @@ set(SRC
BKE_idprop.h
BKE_idtype.h
BKE_image.h
+ BKE_image_save.h
BKE_ipo.h
BKE_kelvinlet.h
BKE_key.h
@@ -356,7 +357,6 @@ set(SRC
BKE_multires.h
BKE_nla.h
BKE_node.h
- BKE_node_tree_ref.hh
BKE_object.h
BKE_object_deform.h
BKE_object_facemap.h
@@ -365,6 +365,7 @@ set(SRC
BKE_packedFile.h
BKE_paint.h
BKE_particle.h
+ BKE_persistent_data_handle.hh
BKE_pbvh.h
BKE_pointcache.h
BKE_pointcloud.h
@@ -373,6 +374,7 @@ set(SRC
BKE_scene.h
BKE_screen.h
BKE_sequencer.h
+ BKE_sequencer_offscreen.h
BKE_shader_fx.h
BKE_shrinkwrap.h
BKE_simulation.h
@@ -411,6 +413,7 @@ set(SRC
intern/multires_inline.h
intern/multires_reshape.h
intern/multires_unsubdivide.h
+ intern/ocean_intern.h
intern/pbvh_intern.h
intern/subdiv_converter.h
intern/subdiv_inline.h
@@ -424,6 +427,7 @@ set(LIB
bf_bmesh
bf_depsgraph
bf_draw
+ bf_functions
bf_gpencil_modifiers
bf_gpu
bf_ikplugin
@@ -436,7 +440,7 @@ set(LIB
bf_intern_opensubdiv # Uses stub when disabled.
bf_modifiers
bf_nodes
- bf_physics
+ bf_simulation
bf_rna
bf_shader_fx
)
@@ -694,3 +698,16 @@ blender_add_lib(bf_blenkernel "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
# Needed so we can use dna_type_offsets.h for defaults initialization.
add_dependencies(bf_blenkernel bf_dna)
+
+
+if(WITH_GTESTS)
+ set(TEST_SRC
+ intern/armature_test.cc
+ intern/fcurve_test.cc
+ )
+ set(TEST_INC
+ ../editors/include
+ )
+ include(GTestTesting)
+ blender_add_test_lib(bf_blenkernel_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB}")
+endif()
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c
index 98deddb4316..8d8301362b3 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf.c
@@ -32,8 +32,6 @@
#include "CCGSubSurf.h"
#include "CCGSubSurf_intern.h"
-#include "GPU_glew.h"
-
/***/
int BKE_ccg_gridsize(int level)
@@ -177,9 +175,7 @@ static void *_edge_getCoVert(CCGEdge *e, CCGVert *v, int lvl, int x, int dataSiz
if (v == e->v0) {
return &EDGE_getLevelData(e)[dataSize * (levelBase + x)];
}
- else {
- return &EDGE_getLevelData(e)[dataSize * (levelBase + (1 << lvl) - x)];
- }
+ return &EDGE_getLevelData(e)[dataSize * (levelBase + (1 << lvl) - x)];
}
static void _edge_free(CCGEdge *e, CCGSubSurf *ss)
@@ -260,46 +256,45 @@ CCGSubSurf *ccgSubSurf_new(CCGMeshIFC *ifc,
if (subdivLevels < 1) {
return NULL;
}
- else {
- CCGSubSurf *ss = allocatorIFC->alloc(allocator, sizeof(*ss));
- ss->allocatorIFC = *allocatorIFC;
- ss->allocator = allocator;
+ CCGSubSurf *ss = allocatorIFC->alloc(allocator, sizeof(*ss));
- ss->vMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator);
- ss->eMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator);
- ss->fMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator);
+ ss->allocatorIFC = *allocatorIFC;
+ ss->allocator = allocator;
- ss->meshIFC = *ifc;
+ ss->vMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator);
+ ss->eMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator);
+ ss->fMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator);
- ss->subdivLevels = subdivLevels;
- ss->numGrids = 0;
- ss->allowEdgeCreation = 0;
- ss->defaultCreaseValue = 0;
- ss->defaultEdgeUserData = NULL;
+ ss->meshIFC = *ifc;
- ss->useAgeCounts = 0;
- ss->vertUserAgeOffset = ss->edgeUserAgeOffset = ss->faceUserAgeOffset = 0;
+ ss->subdivLevels = subdivLevels;
+ ss->numGrids = 0;
+ ss->allowEdgeCreation = 0;
+ ss->defaultCreaseValue = 0;
+ ss->defaultEdgeUserData = NULL;
- ss->calcVertNormals = 0;
- ss->normalDataOffset = 0;
+ ss->useAgeCounts = 0;
+ ss->vertUserAgeOffset = ss->edgeUserAgeOffset = ss->faceUserAgeOffset = 0;
- ss->allocMask = 0;
+ ss->calcVertNormals = 0;
+ ss->normalDataOffset = 0;
- ss->q = CCGSUBSURF_alloc(ss, ss->meshIFC.vertDataSize);
- ss->r = CCGSUBSURF_alloc(ss, ss->meshIFC.vertDataSize);
+ ss->allocMask = 0;
- ss->currentAge = 0;
+ ss->q = CCGSUBSURF_alloc(ss, ss->meshIFC.vertDataSize);
+ ss->r = CCGSUBSURF_alloc(ss, ss->meshIFC.vertDataSize);
- ss->syncState = eSyncState_None;
+ ss->currentAge = 0;
- ss->oldVMap = ss->oldEMap = ss->oldFMap = NULL;
- ss->lenTempArrays = 0;
- ss->tempVerts = NULL;
- ss->tempEdges = NULL;
+ ss->syncState = eSyncState_None;
- return ss;
- }
+ ss->oldVMap = ss->oldEMap = ss->oldFMap = NULL;
+ ss->lenTempArrays = 0;
+ ss->tempVerts = NULL;
+ ss->tempEdges = NULL;
+
+ return ss;
}
void ccgSubSurf_free(CCGSubSurf *ss)
@@ -378,7 +373,7 @@ CCGError ccgSubSurf_setSubdivisionLevels(CCGSubSurf *ss, int subdivisionLevels)
if (subdivisionLevels <= 0) {
return eCCGError_InvalidValue;
}
- else if (subdivisionLevels != ss->subdivLevels) {
+ if (subdivisionLevels != ss->subdivLevels) {
ss->numGrids = 0;
ss->subdivLevels = subdivisionLevels;
ccg_ehash_free(ss->vMap, (EHEntryFreeFP)_vert_free, ss);
@@ -420,12 +415,10 @@ CCGError ccgSubSurf_setUseAgeCounts(
(faceUserOffset + 4 > ss->meshIFC.faceUserSize)) {
return eCCGError_InvalidValue;
}
- else {
- ss->useAgeCounts = 1;
- ss->vertUserAgeOffset = vertUserOffset;
- ss->edgeUserAgeOffset = edgeUserOffset;
- ss->faceUserAgeOffset = faceUserOffset;
- }
+ ss->useAgeCounts = 1;
+ ss->vertUserAgeOffset = vertUserOffset;
+ ss->edgeUserAgeOffset = edgeUserOffset;
+ ss->faceUserAgeOffset = faceUserOffset;
}
else {
ss->useAgeCounts = 0;
@@ -441,10 +434,8 @@ CCGError ccgSubSurf_setCalcVertexNormals(CCGSubSurf *ss, int useVertNormals, int
if (normalDataOffset < 0 || normalDataOffset + 12 > ss->meshIFC.vertDataSize) {
return eCCGError_InvalidValue;
}
- else {
- ss->calcVertNormals = 1;
- ss->normalDataOffset = normalDataOffset;
- }
+ ss->calcVertNormals = 1;
+ ss->normalDataOffset = normalDataOffset;
}
else {
ss->calcVertNormals = 0;
@@ -512,19 +503,17 @@ CCGError ccgSubSurf_syncVertDel(CCGSubSurf *ss, CCGVertHDL vHDL)
if (ss->syncState != eSyncState_Partial) {
return eCCGError_InvalidSyncState;
}
- else {
- void **prevp;
- CCGVert *v = ccg_ehash_lookupWithPrev(ss->vMap, vHDL, &prevp);
- if (!v || v->numFaces || v->numEdges) {
- return eCCGError_InvalidValue;
- }
- else {
- *prevp = v->next;
- _vert_free(v, ss);
- }
+ void **prevp;
+ CCGVert *v = ccg_ehash_lookupWithPrev(ss->vMap, vHDL, &prevp);
+
+ if (!v || v->numFaces || v->numEdges) {
+ return eCCGError_InvalidValue;
}
+ *prevp = v->next;
+ _vert_free(v, ss);
+
return eCCGError_None;
}
@@ -533,19 +522,17 @@ CCGError ccgSubSurf_syncEdgeDel(CCGSubSurf *ss, CCGEdgeHDL eHDL)
if (ss->syncState != eSyncState_Partial) {
return eCCGError_InvalidSyncState;
}
- else {
- void **prevp;
- CCGEdge *e = ccg_ehash_lookupWithPrev(ss->eMap, eHDL, &prevp);
- if (!e || e->numFaces) {
- return eCCGError_InvalidValue;
- }
- else {
- *prevp = e->next;
- _edge_unlinkMarkAndFree(e, ss);
- }
+ void **prevp;
+ CCGEdge *e = ccg_ehash_lookupWithPrev(ss->eMap, eHDL, &prevp);
+
+ if (!e || e->numFaces) {
+ return eCCGError_InvalidValue;
}
+ *prevp = e->next;
+ _edge_unlinkMarkAndFree(e, ss);
+
return eCCGError_None;
}
@@ -554,19 +541,17 @@ CCGError ccgSubSurf_syncFaceDel(CCGSubSurf *ss, CCGFaceHDL fHDL)
if (ss->syncState != eSyncState_Partial) {
return eCCGError_InvalidSyncState;
}
- else {
- void **prevp;
- CCGFace *f = ccg_ehash_lookupWithPrev(ss->fMap, fHDL, &prevp);
- if (!f) {
- return eCCGError_InvalidValue;
- }
- else {
- *prevp = f->next;
- _face_unlinkMarkAndFree(f, ss);
- }
+ void **prevp;
+ CCGFace *f = ccg_ehash_lookupWithPrev(ss->fMap, fHDL, &prevp);
+
+ if (!f) {
+ return eCCGError_InvalidValue;
}
+ *prevp = f->next;
+ _face_unlinkMarkAndFree(f, ss);
+
return eCCGError_None;
}
@@ -1264,9 +1249,7 @@ int ccgSubSurf_getEdgeLevelSize(const CCGSubSurf *ss, int level)
if (level < 1 || level > ss->subdivLevels) {
return -1;
}
- else {
- return ccg_edgesize(level);
- }
+ return ccg_edgesize(level);
}
int ccgSubSurf_getGridSize(const CCGSubSurf *ss)
{
@@ -1277,9 +1260,7 @@ int ccgSubSurf_getGridLevelSize(const CCGSubSurf *ss, int level)
if (level < 1 || level > ss->subdivLevels) {
return -1;
}
- else {
- return ccg_gridsize(level);
- }
+ return ccg_gridsize(level);
}
int ccgSubSurf_getSimpleSubdiv(const CCGSubSurf *ss)
@@ -1299,9 +1280,7 @@ int ccgSubSurf_getVertAge(CCGSubSurf *ss, CCGVert *v)
byte *userData = ccgSubSurf_getVertUserData(ss, v);
return ss->currentAge - *((int *)&userData[ss->vertUserAgeOffset]);
}
- else {
- return 0;
- }
+ return 0;
}
void *ccgSubSurf_getVertUserData(CCGSubSurf *ss, CCGVert *v)
{
@@ -1316,9 +1295,7 @@ CCGFace *ccgSubSurf_getVertFace(CCGVert *v, int index)
if (index < 0 || index >= v->numFaces) {
return NULL;
}
- else {
- return v->faces[index];
- }
+ return v->faces[index];
}
int ccgSubSurf_getVertNumEdges(CCGVert *v)
{
@@ -1329,9 +1306,7 @@ CCGEdge *ccgSubSurf_getVertEdge(CCGVert *v, int index)
if (index < 0 || index >= v->numEdges) {
return NULL;
}
- else {
- return v->edges[index];
- }
+ return v->edges[index];
}
void *ccgSubSurf_getVertData(CCGSubSurf *ss, CCGVert *v)
{
@@ -1342,9 +1317,7 @@ void *ccgSubSurf_getVertLevelData(CCGSubSurf *ss, CCGVert *v, int level)
if (level < 0 || level > ss->subdivLevels) {
return NULL;
}
- else {
- return ccg_vert_getCo(v, level, ss->meshIFC.vertDataSize);
- }
+ return ccg_vert_getCo(v, level, ss->meshIFC.vertDataSize);
}
/* Edge accessors */
@@ -1359,9 +1332,7 @@ int ccgSubSurf_getEdgeAge(CCGSubSurf *ss, CCGEdge *e)
byte *userData = ccgSubSurf_getEdgeUserData(ss, e);
return ss->currentAge - *((int *)&userData[ss->edgeUserAgeOffset]);
}
- else {
- return 0;
- }
+ return 0;
}
void *ccgSubSurf_getEdgeUserData(CCGSubSurf *ss, CCGEdge *e)
{
@@ -1376,9 +1347,7 @@ CCGFace *ccgSubSurf_getEdgeFace(CCGEdge *e, int index)
if (index < 0 || index >= e->numFaces) {
return NULL;
}
- else {
- return e->faces[index];
- }
+ return e->faces[index];
}
CCGVert *ccgSubSurf_getEdgeVert0(CCGEdge *e)
{
@@ -1401,9 +1370,7 @@ void *ccgSubSurf_getEdgeLevelData(CCGSubSurf *ss, CCGEdge *e, int x, int level)
if (level < 0 || level > ss->subdivLevels) {
return NULL;
}
- else {
- return ccg_edge_getCo(e, level, x, ss->meshIFC.vertDataSize);
- }
+ return ccg_edge_getCo(e, level, x, ss->meshIFC.vertDataSize);
}
float ccgSubSurf_getEdgeCrease(CCGEdge *e)
{
@@ -1422,9 +1389,7 @@ int ccgSubSurf_getFaceAge(CCGSubSurf *ss, CCGFace *f)
byte *userData = ccgSubSurf_getFaceUserData(ss, f);
return ss->currentAge - *((int *)&userData[ss->faceUserAgeOffset]);
}
- else {
- return 0;
- }
+ return 0;
}
void *ccgSubSurf_getFaceUserData(CCGSubSurf *ss, CCGFace *f)
{
@@ -1442,18 +1407,14 @@ CCGVert *ccgSubSurf_getFaceVert(CCGFace *f, int index)
if (index < 0 || index >= f->numVerts) {
return NULL;
}
- else {
- return FACE_getVerts(f)[index];
- }
+ return FACE_getVerts(f)[index];
}
CCGEdge *ccgSubSurf_getFaceEdge(CCGFace *f, int index)
{
if (index < 0 || index >= f->numVerts) {
return NULL;
}
- else {
- return FACE_getEdges(f)[index];
- }
+ return FACE_getEdges(f)[index];
}
int ccgSubSurf_getFaceEdgeIndex(CCGFace *f, CCGEdge *e)
{
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.h b/source/blender/blenkernel/intern/CCGSubSurf.h
index 2e5100db6de..e1805a9c512 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.h
+++ b/source/blender/blenkernel/intern/CCGSubSurf.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __CCGSUBSURF_H__
-#define __CCGSUBSURF_H__
+#pragma once
/** \file
* \ingroup bke
@@ -210,5 +209,3 @@ void ccgEdgeIterator_next(CCGEdgeIterator *ei);
CCGFace *ccgFaceIterator_getCurrent(CCGFaceIterator *fi);
int ccgFaceIterator_isStopped(CCGFaceIterator *fi);
void ccgFaceIterator_next(CCGFaceIterator *fi);
-
-#endif /* __CCGSUBSURF_H__ */
diff --git a/source/blender/blenkernel/intern/CCGSubSurf_inline.h b/source/blender/blenkernel/intern/CCGSubSurf_inline.h
index 86012bd2a43..8aa1fede57d 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf_inline.h
+++ b/source/blender/blenkernel/intern/CCGSubSurf_inline.h
@@ -18,8 +18,7 @@
* \ingroup bke
*/
-#ifndef __CCGSUBSURF_INLINE_H__
-#define __CCGSUBSURF_INLINE_H__
+#pragma once
BLI_INLINE int ccg_gridsize(int level)
{
@@ -274,5 +273,3 @@ BLI_INLINE void VertDataAvg4(float v[],
v[i] = (a[i] + b[i] + c[i] + d[i]) * 0.25f;
}
}
-
-#endif /* __CCGSUBSURF_INLINE_H__ */
diff --git a/source/blender/blenkernel/intern/CCGSubSurf_intern.h b/source/blender/blenkernel/intern/CCGSubSurf_intern.h
index 7c35d2ccfce..82ca22e193a 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf_intern.h
+++ b/source/blender/blenkernel/intern/CCGSubSurf_intern.h
@@ -18,8 +18,7 @@
* \ingroup bke
*/
-#ifndef __CCGSUBSURF_INTERN_H__
-#define __CCGSUBSURF_INTERN_H__
+#pragma once
/**
* Definitions which defines internal behavior of CCGSubSurf.
@@ -286,5 +285,3 @@ void ccgSubSurf__dumpCoords(CCGSubSurf *ss);
#endif
#include "CCGSubSurf_inline.h"
-
-#endif /* __CCGSUBSURF_INTERN_H__ */
diff --git a/source/blender/blenkernel/intern/CCGSubSurf_legacy.c b/source/blender/blenkernel/intern/CCGSubSurf_legacy.c
index f3f681baa01..8fc9afd58f1 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf_legacy.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf_legacy.c
@@ -38,9 +38,7 @@ static void *_edge_getCoVert(CCGEdge *e, CCGVert *v, int lvl, int x, int dataSiz
if (v == e->v0) {
return &EDGE_getLevelData(e)[dataSize * (levelBase + x)];
}
- else {
- return &EDGE_getLevelData(e)[dataSize * (levelBase + (1 << lvl) - x)];
- }
+ return &EDGE_getLevelData(e)[dataSize * (levelBase + (1 << lvl) - x)];
}
/* *************************************************** */
@@ -65,9 +63,8 @@ static CCGVert *_edge_getOtherVert(CCGEdge *e, CCGVert *vQ)
if (vQ == e->v0) {
return e->v1;
}
- else {
- return e->v0;
- }
+
+ return e->v0;
}
static float *_face_getIFNoEdge(CCGFace *f,
@@ -111,15 +108,13 @@ static float EDGE_getSharpness(CCGEdge *e, int lvl)
if (!lvl) {
return e->crease;
}
- else if (!e->crease) {
+ if (!e->crease) {
return 0.0f;
}
- else if (e->crease - lvl < 0.0f) {
+ if (e->crease - lvl < 0.0f) {
return 0.0f;
}
- else {
- return e->crease - lvl;
- }
+ return e->crease - lvl;
}
typedef struct CCGSubSurfCalcSubdivData {
diff --git a/source/blender/blenkernel/intern/CCGSubSurf_util.c b/source/blender/blenkernel/intern/CCGSubSurf_util.c
index 58d5f2e0495..bc63d8b97f7 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf_util.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf_util.c
@@ -304,7 +304,7 @@ void ccgSubSurf__dumpCoords(CCGSubSurf *ss)
}
for (x = 0; x < gridSize; x++) {
float *co = FACE_getIECo(f, subdivLevels, S, x);
- printf("face index=%d. cornder=%d, ie_index=%d, coord=(%f, %f, %f)\n",
+ printf("face index=%d. corner=%d, ie_index=%d, coord=(%f, %f, %f)\n",
index,
S,
x,
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 8a5be6b9cb3..af4829691c2 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -80,11 +80,9 @@
//#define USE_MODIFIER_VALIDATE
#ifdef USE_MODIFIER_VALIDATE
-# define ASSERT_IS_VALID_DM(dm) (BLI_assert((dm == NULL) || (DM_is_valid(dm) == true)))
# define ASSERT_IS_VALID_MESH(mesh) \
(BLI_assert((mesh == NULL) || (BKE_mesh_is_valid(mesh) == true)))
#else
-# define ASSERT_IS_VALID_DM(dm)
# define ASSERT_IS_VALID_MESH(mesh)
#endif
@@ -424,15 +422,14 @@ int DM_release(DerivedMesh *dm)
return 1;
}
- else {
- CustomData_free_temporary(&dm->vertData, dm->numVertData);
- CustomData_free_temporary(&dm->edgeData, dm->numEdgeData);
- CustomData_free_temporary(&dm->faceData, dm->numTessFaceData);
- CustomData_free_temporary(&dm->loopData, dm->numLoopData);
- CustomData_free_temporary(&dm->polyData, dm->numPolyData);
- return 0;
- }
+ CustomData_free_temporary(&dm->vertData, dm->numVertData);
+ CustomData_free_temporary(&dm->edgeData, dm->numEdgeData);
+ CustomData_free_temporary(&dm->faceData, dm->numTessFaceData);
+ CustomData_free_temporary(&dm->loopData, dm->numLoopData);
+ CustomData_free_temporary(&dm->polyData, dm->numPolyData);
+
+ return 0;
}
void DM_DupPolys(DerivedMesh *source, DerivedMesh *target)
@@ -693,11 +690,9 @@ static float (*get_orco_coords(Object *ob, BMEditMesh *em, int layer, int *free)
if (em) {
return get_editbmesh_orco_verts(em);
}
- else {
- return BKE_mesh_orco_verts_get(ob);
- }
+ return BKE_mesh_orco_verts_get(ob);
}
- else if (layer == CD_CLOTH_ORCO) {
+ if (layer == CD_CLOTH_ORCO) {
/* apply shape key for cloth, this should really be solved
* by a more flexible customdata system, but not simple */
if (!em) {
@@ -1060,9 +1055,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
}
continue;
}
- else {
- BKE_modifier_set_error(md, "Sculpt: Hide, Mask and optimized display disabled");
- }
+ BKE_modifier_set_error(md, "Sculpt: Hide, Mask and optimized display disabled");
}
if (need_mapping && !BKE_modifier_supports_mapping(md)) {
@@ -2363,32 +2356,6 @@ void DM_debug_print(DerivedMesh *dm)
MEM_freeN(str);
}
-void DM_debug_print_cdlayers(CustomData *data)
-{
- int i;
- const CustomDataLayer *layer;
-
- printf("{\n");
-
- for (i = 0, layer = data->layers; i < data->totlayer; i++, layer++) {
-
- const char *name = CustomData_layertype_name(layer->type);
- const int size = CustomData_sizeof(layer->type);
- const char *structname;
- int structnum;
- CustomData_file_write_info(layer->type, &structname, &structnum);
- printf(" dict(name='%s', struct='%s', type=%d, ptr='%p', elem=%d, length=%d),\n",
- name,
- structname,
- layer->type,
- (const void *)layer->data,
- size,
- (int)(MEM_allocN_len(layer->data) / size));
- }
-
- printf("}\n");
-}
-
bool DM_is_valid(DerivedMesh *dm)
{
const bool do_verbose = true;
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index b35d2183408..85ac2c693cb 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -37,6 +37,7 @@
#include "BLI_blenlib.h"
#include "BLI_ghash.h"
#include "BLI_math.h"
+#include "BLI_session_uuid.h"
#include "BLI_string_utils.h"
#include "BLI_utildefines.h"
@@ -482,6 +483,11 @@ void action_groups_clear_tempflags(bAction *act)
/* *************** Pose channels *************** */
+void BKE_pose_channel_session_uuid_generate(bPoseChannel *pchan)
+{
+ pchan->runtime.session_uuid = BLI_session_uuid_generate();
+}
+
/**
* Return a pointer to the pose channel of the given name
* from this pose.
@@ -524,6 +530,8 @@ bPoseChannel *BKE_pose_channel_verify(bPose *pose, const char *name)
/* If not, create it and add it */
chan = MEM_callocN(sizeof(bPoseChannel), "verifyPoseChannel");
+ BKE_pose_channel_session_uuid_generate(chan);
+
BLI_strncpy(chan->name, name, sizeof(chan->name));
chan->custom_scale = 1.0f;
@@ -698,6 +706,10 @@ void BKE_pose_copy_data_ex(bPose **dst,
id_us_plus((ID *)pchan->custom);
}
+ if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) {
+ BKE_pose_channel_session_uuid_generate(pchan);
+ }
+
/* warning, O(n2) here, if done without the hash, but these are rarely used features. */
if (pchan->custom_tx) {
pchan->custom_tx = BKE_pose_channel_find_name(outPose, pchan->custom_tx->name);
@@ -726,7 +738,7 @@ void BKE_pose_copy_data_ex(bPose **dst,
pchan->draw_data = NULL; /* Drawing cache, no need to copy. */
/* Runtime data, no need to copy. */
- memset(&pchan->runtime, 0, sizeof(pchan->runtime));
+ BKE_pose_channel_runtime_reset_on_copy(&pchan->runtime);
}
/* for now, duplicate Bone Groups too when doing this */
@@ -956,6 +968,14 @@ void BKE_pose_channel_runtime_reset(bPoseChannel_Runtime *runtime)
memset(runtime, 0, sizeof(*runtime));
}
+/* Reset all non-persistent fields. */
+void BKE_pose_channel_runtime_reset_on_copy(bPoseChannel_Runtime *runtime)
+{
+ const SessionUUID uuid = runtime->session_uuid;
+ memset(runtime, 0, sizeof(*runtime));
+ runtime->session_uuid = uuid;
+}
+
/** Deallocates runtime cache of a pose channel */
void BKE_pose_channel_runtime_free(bPoseChannel_Runtime *runtime)
{
@@ -1512,8 +1532,10 @@ short action_get_item_transforms(bAction *act, Object *ob, bPoseChannel *pchan,
/* ************** Pose Management Tools ****************** */
-/* for do_all_pose_actions, clears the pose. Now also exported for proxy and tools */
-void BKE_pose_rest(bPose *pose)
+/**
+ * Zero the pose transforms for the entire pose or only for selected bones.
+ */
+void BKE_pose_rest(bPose *pose, bool selected_bones_only)
{
bPoseChannel *pchan;
@@ -1525,6 +1547,9 @@ void BKE_pose_rest(bPose *pose)
memset(pose->cyclic_offset, 0, sizeof(pose->cyclic_offset));
for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
+ if (selected_bones_only && pchan->bone != NULL && (pchan->bone->flag & BONE_SELECTED) == 0) {
+ continue;
+ }
zero_v3(pchan->loc);
zero_v3(pchan->eul);
unit_qt(pchan->quat);
@@ -1612,8 +1637,12 @@ void BKE_pose_tag_recalc(Main *bmain, bPose *pose)
/* For the calculation of the effects of an Action at the given frame on an object
* This is currently only used for the Action Constraint
*/
-void what_does_obaction(
- Object *ob, Object *workob, bPose *pose, bAction *act, char groupname[], float cframe)
+void what_does_obaction(Object *ob,
+ Object *workob,
+ bPose *pose,
+ bAction *act,
+ char groupname[],
+ const AnimationEvalContext *anim_eval_context)
{
bActionGroup *agrp = BKE_action_group_find_name(act, groupname);
@@ -1669,7 +1698,7 @@ void what_does_obaction(
RNA_id_pointer_create(&workob->id, &id_ptr);
/* execute action for this group only */
- animsys_evaluate_action_group(&id_ptr, act, agrp, cframe);
+ animsys_evaluate_action_group(&id_ptr, act, agrp, anim_eval_context);
}
else {
AnimData adt = {NULL};
@@ -1680,6 +1709,33 @@ void what_does_obaction(
adt.action = act;
/* execute effects of Action on to workob (or it's PoseChannels) */
- BKE_animsys_evaluate_animdata(&workob->id, &adt, cframe, ADT_RECALC_ANIM, false);
+ BKE_animsys_evaluate_animdata(&workob->id, &adt, anim_eval_context, ADT_RECALC_ANIM, false);
+ }
+}
+
+void BKE_pose_check_uuids_unique_and_report(const bPose *pose)
+{
+ if (pose == NULL) {
+ return;
}
+
+ struct GSet *used_uuids = BLI_gset_new(
+ BLI_session_uuid_ghash_hash, BLI_session_uuid_ghash_compare, "sequencer used uuids");
+
+ LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
+ const SessionUUID *session_uuid = &pchan->runtime.session_uuid;
+ if (!BLI_session_uuid_is_generated(session_uuid)) {
+ printf("Pose channel %s does not have UUID generated.\n", pchan->name);
+ continue;
+ }
+
+ if (BLI_gset_lookup(used_uuids, session_uuid) != NULL) {
+ printf("Pose channel %s has duplicate UUID generated.\n", pchan->name);
+ continue;
+ }
+
+ BLI_gset_insert(used_uuids, (void *)session_uuid);
+ }
+
+ BLI_gset_free(used_uuids, NULL);
}
diff --git a/source/blender/blenkernel/intern/anim_data.c b/source/blender/blenkernel/intern/anim_data.c
index 841fdaa3b2c..038a0d14ddb 100644
--- a/source/blender/blenkernel/intern/anim_data.c
+++ b/source/blender/blenkernel/intern/anim_data.c
@@ -130,9 +130,7 @@ AnimData *BKE_animdata_from_id(ID *id)
IdAdtTemplate *iat = (IdAdtTemplate *)id;
return iat->adt;
}
- else {
- return NULL;
- }
+ return NULL;
}
/* Add AnimData to the given ID-block. In order for this to work, we assume that
@@ -161,9 +159,7 @@ AnimData *BKE_animdata_add_id(ID *id)
return iat->adt;
}
- else {
- return NULL;
- }
+ return NULL;
}
/* Action Setter --------------------------------------- */
@@ -379,17 +375,19 @@ bool BKE_animdata_copy_id(Main *bmain, ID *id_to, ID *id_from, const int flag)
return true;
}
-void BKE_animdata_copy_id_action(Main *bmain, ID *id, const bool set_newid)
+static void animdata_copy_id_action(Main *bmain,
+ ID *id,
+ const bool set_newid,
+ const bool do_linked_id)
{
- const bool is_id_liboverride = ID_IS_OVERRIDE_LIBRARY(id);
AnimData *adt = BKE_animdata_from_id(id);
if (adt) {
- if (adt->action && (!is_id_liboverride || !ID_IS_LINKED(adt->action))) {
+ if (adt->action && (do_linked_id || !ID_IS_LINKED(adt->action))) {
id_us_min((ID *)adt->action);
adt->action = set_newid ? ID_NEW_SET(adt->action, BKE_action_copy(bmain, adt->action)) :
BKE_action_copy(bmain, adt->action);
}
- if (adt->tmpact && (!is_id_liboverride || !ID_IS_LINKED(adt->tmpact))) {
+ if (adt->tmpact && (do_linked_id || !ID_IS_LINKED(adt->tmpact))) {
id_us_min((ID *)adt->tmpact);
adt->tmpact = set_newid ? ID_NEW_SET(adt->tmpact, BKE_action_copy(bmain, adt->tmpact)) :
BKE_action_copy(bmain, adt->tmpact);
@@ -397,12 +395,27 @@ void BKE_animdata_copy_id_action(Main *bmain, ID *id, const bool set_newid)
}
bNodeTree *ntree = ntreeFromID(id);
if (ntree) {
- BKE_animdata_copy_id_action(bmain, &ntree->id, set_newid);
+ animdata_copy_id_action(bmain, &ntree->id, set_newid, do_linked_id);
}
/* Note that collections are not animatable currently, so no need to handle scenes' master
* collection here. */
}
+void BKE_animdata_copy_id_action(Main *bmain, ID *id)
+{
+ const bool is_id_liboverride = ID_IS_OVERRIDE_LIBRARY(id);
+ animdata_copy_id_action(bmain, id, false, !is_id_liboverride);
+}
+
+void BKE_animdata_duplicate_id_action(struct Main *bmain,
+ struct ID *id,
+ const eDupli_ID_Flags duplicate_flags)
+{
+ if (duplicate_flags & USER_DUP_ACT) {
+ animdata_copy_id_action(bmain, id, true, (duplicate_flags & USER_DUP_LINKED_ID) != 0);
+ }
+}
+
/* Merge copies of the data from the src AnimData into the destination AnimData */
void BKE_animdata_merge_copy(
Main *bmain, ID *dst_id, ID *src_id, eAnimData_MergeCopy_Modes action_mode, bool fix_drivers)
@@ -492,24 +505,43 @@ static bool animpath_matches_basepath(const char path[], const char basepath[])
return (path && basepath) && STRPREFIX(path, basepath);
}
+static void animpath_update_basepath(FCurve *fcu,
+ const char *old_basepath,
+ const char *new_basepath)
+{
+ BLI_assert(animpath_matches_basepath(fcu->rna_path, old_basepath));
+ if (STREQ(old_basepath, new_basepath)) {
+ return;
+ }
+
+ char *new_path = BLI_sprintfN("%s%s", new_basepath, fcu->rna_path + strlen(old_basepath));
+ MEM_freeN(fcu->rna_path);
+ fcu->rna_path = new_path;
+}
+
/* Move F-Curves in src action to dst action, setting up all the necessary groups
* for this to happen, but only if the F-Curves being moved have the appropriate
* "base path".
* - This is used when data moves from one data-block to another, causing the
* F-Curves to need to be moved over too
*/
-void action_move_fcurves_by_basepath(bAction *srcAct, bAction *dstAct, const char basepath[])
+static void action_move_fcurves_by_basepath(bAction *srcAct,
+ bAction *dstAct,
+ const char *src_basepath,
+ const char *dst_basepath)
{
FCurve *fcu, *fcn = NULL;
/* sanity checks */
- if (ELEM(NULL, srcAct, dstAct, basepath)) {
+ if (ELEM(NULL, srcAct, dstAct, src_basepath, dst_basepath)) {
if (G.debug & G_DEBUG) {
CLOG_ERROR(&LOG,
- "srcAct: %p, dstAct: %p, basepath: %p has insufficient info to work with",
+ "srcAct: %p, dstAct: %p, src_basepath: %p, dst_basepath: %p has insufficient "
+ "info to work with",
(void *)srcAct,
(void *)dstAct,
- (void *)basepath);
+ (void *)src_basepath,
+ (void *)dst_basepath);
}
return;
}
@@ -527,7 +559,7 @@ void action_move_fcurves_by_basepath(bAction *srcAct, bAction *dstAct, const cha
/* should F-Curve be moved over?
* - we only need the start of the path to match basepath
*/
- if (animpath_matches_basepath(fcu->rna_path, basepath)) {
+ if (animpath_matches_basepath(fcu->rna_path, src_basepath)) {
bActionGroup *agrp = NULL;
/* if grouped... */
@@ -549,6 +581,8 @@ void action_move_fcurves_by_basepath(bAction *srcAct, bAction *dstAct, const cha
/* perform the migration now */
action_groups_remove_channel(srcAct, fcu);
+ animpath_update_basepath(fcu, src_basepath, dst_basepath);
+
if (agrp) {
action_groups_add_channel(dstAct, agrp, fcu);
}
@@ -581,14 +615,31 @@ void action_move_fcurves_by_basepath(bAction *srcAct, bAction *dstAct, const cha
}
}
+static void animdata_move_drivers_by_basepath(AnimData *srcAdt,
+ AnimData *dstAdt,
+ const char *src_basepath,
+ const char *dst_basepath)
+{
+ LISTBASE_FOREACH_MUTABLE (FCurve *, fcu, &srcAdt->drivers) {
+ if (animpath_matches_basepath(fcu->rna_path, src_basepath)) {
+ animpath_update_basepath(fcu, src_basepath, dst_basepath);
+ BLI_remlink(&srcAdt->drivers, fcu);
+ BLI_addtail(&dstAdt->drivers, fcu);
+
+ /* TODO: add depsgraph flushing calls? */
+ }
+ }
+}
+
/* Transfer the animation data from srcID to dstID where the srcID
* animation data is based off "basepath", creating new AnimData and
- * associated data as necessary
+ * associated data as necessary.
+ *
+ * basepaths is a list of AnimationBasePathChange.
*/
-void BKE_animdata_separate_by_basepath(Main *bmain, ID *srcID, ID *dstID, ListBase *basepaths)
+void BKE_animdata_transfer_by_basepath(Main *bmain, ID *srcID, ID *dstID, ListBase *basepaths)
{
AnimData *srcAdt = NULL, *dstAdt = NULL;
- LinkData *ld;
/* sanity checks */
if (ELEM(NULL, srcID, dstID)) {
@@ -630,35 +681,19 @@ void BKE_animdata_separate_by_basepath(Main *bmain, ID *srcID, ID *dstID, ListBa
}
/* loop over base paths, trying to fix for each one... */
- for (ld = basepaths->first; ld; ld = ld->next) {
- const char *basepath = (const char *)ld->data;
- action_move_fcurves_by_basepath(srcAdt->action, dstAdt->action, basepath);
+ LISTBASE_FOREACH (const AnimationBasePathChange *, basepath_change, basepaths) {
+ action_move_fcurves_by_basepath(srcAdt->action,
+ dstAdt->action,
+ basepath_change->src_basepath,
+ basepath_change->dst_basepath);
}
}
/* drivers */
if (srcAdt->drivers.first) {
- FCurve *fcu, *fcn = NULL;
-
- /* check each driver against all the base paths to see if any should go */
- for (fcu = srcAdt->drivers.first; fcu; fcu = fcn) {
- fcn = fcu->next;
-
- /* try each basepath in turn, but stop on the first one which works */
- for (ld = basepaths->first; ld; ld = ld->next) {
- const char *basepath = (const char *)ld->data;
-
- if (animpath_matches_basepath(fcu->rna_path, basepath)) {
- /* just need to change lists */
- BLI_remlink(&srcAdt->drivers, fcu);
- BLI_addtail(&dstAdt->drivers, fcu);
-
- /* TODO: add depsgraph flushing calls? */
-
- /* can stop now, as moved already */
- break;
- }
- }
+ LISTBASE_FOREACH (const AnimationBasePathChange *, basepath_change, basepaths) {
+ animdata_move_drivers_by_basepath(
+ srcAdt, dstAdt, basepath_change->src_basepath, basepath_change->dst_basepath);
}
}
}
@@ -775,10 +810,9 @@ static char *rna_path_rename_fix(ID *owner_id,
MEM_freeN(oldpath);
return newPath;
}
- else {
- /* still couldn't resolve the path... so, might as well just leave it alone */
- MEM_freeN(newPath);
- }
+
+ /* still couldn't resolve the path... so, might as well just leave it alone */
+ MEM_freeN(newPath);
}
}
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 5e4b280d0d0..5b5e32f1d81 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -538,7 +538,7 @@ static void animsys_write_orig_anim_rna(PointerRNA *ptr,
*/
static void animsys_evaluate_fcurves(PointerRNA *ptr,
ListBase *list,
- float ctime,
+ const AnimationEvalContext *anim_eval_context,
bool flush_to_original)
{
/* Calculate then execute each curve. */
@@ -557,7 +557,7 @@ static void animsys_evaluate_fcurves(PointerRNA *ptr,
}
PathResolvedRNA anim_rna;
if (BKE_animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
- const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
+ const float curval = calculate_fcurve(&anim_rna, fcu, anim_eval_context);
BKE_animsys_write_rna_setting(&anim_rna, curval);
if (flush_to_original) {
animsys_write_orig_anim_rna(ptr, fcu->rna_path, fcu->array_index, curval);
@@ -569,8 +569,26 @@ static void animsys_evaluate_fcurves(PointerRNA *ptr,
/* ***************************************** */
/* Driver Evaluation */
+AnimationEvalContext BKE_animsys_eval_context_construct(struct Depsgraph *depsgraph,
+ float eval_time)
+{
+ AnimationEvalContext ctx = {
+ .depsgraph = depsgraph,
+ .eval_time = eval_time,
+ };
+ return ctx;
+}
+
+AnimationEvalContext BKE_animsys_eval_context_construct_at(
+ const AnimationEvalContext *anim_eval_context, float eval_time)
+{
+ return BKE_animsys_eval_context_construct(anim_eval_context->depsgraph, eval_time);
+}
+
/* Evaluate Drivers */
-static void animsys_evaluate_drivers(PointerRNA *ptr, AnimData *adt, float ctime)
+static void animsys_evaluate_drivers(PointerRNA *ptr,
+ AnimData *adt,
+ const AnimationEvalContext *anim_eval_context)
{
FCurve *fcu;
@@ -591,7 +609,7 @@ static void animsys_evaluate_drivers(PointerRNA *ptr, AnimData *adt, float ctime
* before adding new to only be done when drivers only changed. */
PathResolvedRNA anim_rna;
if (BKE_animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
- const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
+ const float curval = calculate_fcurve(&anim_rna, fcu, anim_eval_context);
ok = BKE_animsys_write_rna_setting(&anim_rna, curval);
}
@@ -619,9 +637,8 @@ static void action_idcode_patch_check(ID *id, bAction *act)
if (ELEM(NULL, id, act)) {
return;
}
- else {
- idcode = GS(id->name);
- }
+
+ idcode = GS(id->name);
/* the actual checks... hopefully not too much of a performance hit in the long run... */
if (act->idroot == 0) {
@@ -648,7 +665,10 @@ static void action_idcode_patch_check(ID *id, bAction *act)
/* ----------------------------------------- */
/* Evaluate Action Group */
-void animsys_evaluate_action_group(PointerRNA *ptr, bAction *act, bActionGroup *agrp, float ctime)
+void animsys_evaluate_action_group(PointerRNA *ptr,
+ bAction *act,
+ bActionGroup *agrp,
+ const AnimationEvalContext *anim_eval_context)
{
FCurve *fcu;
@@ -670,7 +690,7 @@ void animsys_evaluate_action_group(PointerRNA *ptr, bAction *act, bActionGroup *
if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0 && !BKE_fcurve_is_empty(fcu)) {
PathResolvedRNA anim_rna;
if (BKE_animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
- const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
+ const float curval = calculate_fcurve(&anim_rna, fcu, anim_eval_context);
BKE_animsys_write_rna_setting(&anim_rna, curval);
}
}
@@ -680,7 +700,7 @@ void animsys_evaluate_action_group(PointerRNA *ptr, bAction *act, bActionGroup *
/* Evaluate Action (F-Curve Bag) */
static void animsys_evaluate_action_ex(PointerRNA *ptr,
bAction *act,
- float ctime,
+ const AnimationEvalContext *anim_eval_context,
const bool flush_to_original)
{
/* check if mapper is appropriate for use here (we set to NULL if it's inappropriate) */
@@ -691,15 +711,15 @@ static void animsys_evaluate_action_ex(PointerRNA *ptr,
action_idcode_patch_check(ptr->owner_id, act);
/* calculate then execute each curve */
- animsys_evaluate_fcurves(ptr, &act->curves, ctime, flush_to_original);
+ animsys_evaluate_fcurves(ptr, &act->curves, anim_eval_context, flush_to_original);
}
void animsys_evaluate_action(PointerRNA *ptr,
bAction *act,
- float ctime,
+ const AnimationEvalContext *anim_eval_context,
const bool flush_to_original)
{
- animsys_evaluate_action_ex(ptr, act, ctime, flush_to_original);
+ animsys_evaluate_action_ex(ptr, act, anim_eval_context, flush_to_original);
}
/* ***************************************** */
@@ -717,18 +737,19 @@ static float nlastrip_get_influence(NlaStrip *strip, float cframe)
/* there is some blend-in */
return fabsf(cframe - strip->start) / (strip->blendin);
}
- else if (IS_EQF(strip->blendout, 0.0f) == false && (cframe >= (strip->end - strip->blendout))) {
+ if (IS_EQF(strip->blendout, 0.0f) == false && (cframe >= (strip->end - strip->blendout))) {
/* there is some blend-out */
return fabsf(strip->end - cframe) / (strip->blendout);
}
- else {
- /* in the middle of the strip, we should be full strength */
- return 1.0f;
- }
+
+ /* in the middle of the strip, we should be full strength */
+ return 1.0f;
}
/* evaluate the evaluation time and influence for the strip, storing the results in the strip */
-static void nlastrip_evaluate_controls(NlaStrip *strip, float ctime, const bool flush_to_original)
+static void nlastrip_evaluate_controls(NlaStrip *strip,
+ const AnimationEvalContext *anim_eval_context,
+ const bool flush_to_original)
{
/* now strip's evaluate F-Curves for these settings (if applicable) */
if (strip->fcurves.first) {
@@ -738,7 +759,7 @@ static void nlastrip_evaluate_controls(NlaStrip *strip, float ctime, const bool
RNA_pointer_create(NULL, &RNA_NlaStrip, strip, &strip_ptr);
/* execute these settings as per normal */
- animsys_evaluate_fcurves(&strip_ptr, &strip->fcurves, ctime, flush_to_original);
+ animsys_evaluate_fcurves(&strip_ptr, &strip->fcurves, anim_eval_context, flush_to_original);
}
/* analytically generate values for influence and time (if applicable)
@@ -746,17 +767,18 @@ static void nlastrip_evaluate_controls(NlaStrip *strip, float ctime, const bool
* in case the override has been turned off.
*/
if ((strip->flag & NLASTRIP_FLAG_USR_INFLUENCE) == 0) {
- strip->influence = nlastrip_get_influence(strip, ctime);
+ strip->influence = nlastrip_get_influence(strip, anim_eval_context->eval_time);
}
/* Bypass evaluation time computation if time mapping is disabled. */
if ((strip->flag & NLASTRIP_FLAG_NO_TIME_MAP) != 0) {
- strip->strip_time = ctime;
+ strip->strip_time = anim_eval_context->eval_time;
return;
}
if ((strip->flag & NLASTRIP_FLAG_USR_TIME) == 0) {
- strip->strip_time = nlastrip_get_frame(strip, ctime, NLATIME_CONVERT_EVAL);
+ strip->strip_time = nlastrip_get_frame(
+ strip, anim_eval_context->eval_time, NLATIME_CONVERT_EVAL);
}
/* if user can control the evaluation time (using F-Curves), consider the option which allows
@@ -770,12 +792,16 @@ static void nlastrip_evaluate_controls(NlaStrip *strip, float ctime, const bool
}
/* gets the strip active at the current time for a list of strips for evaluation purposes */
-NlaEvalStrip *nlastrips_ctime_get_strip(
- ListBase *list, ListBase *strips, short index, float ctime, const bool flush_to_original)
+NlaEvalStrip *nlastrips_ctime_get_strip(ListBase *list,
+ ListBase *strips,
+ short index,
+ const AnimationEvalContext *anim_eval_context,
+ const bool flush_to_original)
{
NlaStrip *strip, *estrip = NULL;
NlaEvalStrip *nes;
short side = 0;
+ float ctime = anim_eval_context->eval_time;
/* loop over strips, checking if they fall within the range */
for (strip = strips->first; strip; strip = strip->next) {
@@ -854,7 +880,9 @@ NlaEvalStrip *nlastrips_ctime_get_strip(
*/
/* TODO: this sounds a bit hacky having a few isolated F-Curves
* stuck on some data it operates on... */
- nlastrip_evaluate_controls(estrip, ctime, flush_to_original);
+ AnimationEvalContext clamped_eval_context = BKE_animsys_eval_context_construct_at(
+ anim_eval_context, ctime);
+ nlastrip_evaluate_controls(estrip, &clamped_eval_context, flush_to_original);
if (estrip->influence <= 0.0f) {
return NULL;
}
@@ -876,8 +904,12 @@ NlaEvalStrip *nlastrips_ctime_get_strip(
}
/* evaluate controls for the relevant extents of the bordering strips... */
- nlastrip_evaluate_controls(estrip->prev, estrip->start, flush_to_original);
- nlastrip_evaluate_controls(estrip->next, estrip->end, flush_to_original);
+ AnimationEvalContext start_eval_context = BKE_animsys_eval_context_construct_at(
+ anim_eval_context, estrip->start);
+ AnimationEvalContext end_eval_context = BKE_animsys_eval_context_construct_at(
+ anim_eval_context, estrip->end);
+ nlastrip_evaluate_controls(estrip->prev, &start_eval_context, flush_to_original);
+ nlastrip_evaluate_controls(estrip->next, &end_eval_context, flush_to_original);
break;
}
@@ -1115,12 +1147,10 @@ static int nlaevalchan_validate_index(NlaEvalChannel *nec, int index)
return -1;
}
- else {
- return 0;
- }
+ return 0;
}
-/* Initialise default values for NlaEvalChannel from the property data. */
+/* Initialize default values for NlaEvalChannel from the property data. */
static void nlaevalchan_get_default_values(NlaEvalChannel *nec, float *r_values)
{
PointerRNA *ptr = &nec->key.ptr;
@@ -1209,15 +1239,13 @@ static char nlaevalchan_detect_mix_mode(NlaEvalChannelKey *key, int length)
if (subtype == PROP_QUATERNION && length == 4) {
return NEC_MIX_QUATERNION;
}
- else if (subtype == PROP_AXISANGLE && length == 4) {
+ if (subtype == PROP_AXISANGLE && length == 4) {
return NEC_MIX_AXIS_ANGLE;
}
- else if (RNA_property_flag(key->prop) & PROP_PROPORTIONAL) {
+ if (RNA_property_flag(key->prop) & PROP_PROPORTIONAL) {
return NEC_MIX_MULTIPLY;
}
- else {
- return NEC_MIX_ADD;
- }
+ return NEC_MIX_ADD;
}
/* Verify that an appropriate NlaEvalChannel for this property exists. */
@@ -1454,10 +1482,9 @@ static bool nla_invert_combine_value(int mix_mode,
/* Division by zero. */
return false;
}
- else {
- *r_value = base_value * powf(target_value / old_value, 1.0f / influence);
- return true;
- }
+
+ *r_value = base_value * powf(target_value / old_value, 1.0f / influence);
+ return true;
case NEC_MIX_QUATERNION:
default:
@@ -1802,6 +1829,7 @@ static void nlastrip_evaluate_transition(PointerRNA *ptr,
ListBase *modifiers,
NlaEvalStrip *nes,
NlaEvalSnapshot *snapshot,
+ const AnimationEvalContext *anim_eval_context,
const bool flush_to_original)
{
ListBase tmp_modifiers = {NULL, NULL};
@@ -1843,13 +1871,15 @@ static void nlastrip_evaluate_transition(PointerRNA *ptr,
tmp_nes.strip_mode = NES_TIME_TRANSITION_START;
tmp_nes.strip = s1;
nlaeval_snapshot_init(&snapshot1, channels, snapshot);
- nlastrip_evaluate(ptr, channels, &tmp_modifiers, &tmp_nes, &snapshot1, flush_to_original);
+ nlastrip_evaluate(
+ ptr, channels, &tmp_modifiers, &tmp_nes, &snapshot1, anim_eval_context, flush_to_original);
/* second strip */
tmp_nes.strip_mode = NES_TIME_TRANSITION_END;
tmp_nes.strip = s2;
nlaeval_snapshot_init(&snapshot2, channels, snapshot);
- nlastrip_evaluate(ptr, channels, &tmp_modifiers, &tmp_nes, &snapshot2, flush_to_original);
+ nlastrip_evaluate(
+ ptr, channels, &tmp_modifiers, &tmp_nes, &snapshot2, anim_eval_context, flush_to_original);
/* accumulate temp-buffer and full-buffer, using the 'real' strip */
nlaeval_snapshot_mix_and_free(channels, snapshot, &snapshot1, &snapshot2, nes->strip_time);
@@ -1864,6 +1894,7 @@ static void nlastrip_evaluate_meta(PointerRNA *ptr,
ListBase *modifiers,
NlaEvalStrip *nes,
NlaEvalSnapshot *snapshot,
+ const AnimationEvalContext *anim_eval_context,
const bool flush_to_original)
{
ListBase tmp_modifiers = {NULL, NULL};
@@ -1884,13 +1915,16 @@ static void nlastrip_evaluate_meta(PointerRNA *ptr,
/* find the child-strip to evaluate */
evaltime = (nes->strip_time * (strip->end - strip->start)) + strip->start;
- tmp_nes = nlastrips_ctime_get_strip(NULL, &strip->strips, -1, evaltime, flush_to_original);
+ AnimationEvalContext child_context = BKE_animsys_eval_context_construct_at(anim_eval_context,
+ evaltime);
+ tmp_nes = nlastrips_ctime_get_strip(NULL, &strip->strips, -1, &child_context, flush_to_original);
/* directly evaluate child strip into accumulation buffer...
* - there's no need to use a temporary buffer (as it causes issues [T40082])
*/
if (tmp_nes) {
- nlastrip_evaluate(ptr, channels, &tmp_modifiers, tmp_nes, snapshot, flush_to_original);
+ nlastrip_evaluate(
+ ptr, channels, &tmp_modifiers, tmp_nes, snapshot, &child_context, flush_to_original);
/* free temp eval-strip */
MEM_freeN(tmp_nes);
@@ -1906,6 +1940,7 @@ void nlastrip_evaluate(PointerRNA *ptr,
ListBase *modifiers,
NlaEvalStrip *nes,
NlaEvalSnapshot *snapshot,
+ const AnimationEvalContext *anim_eval_context,
const bool flush_to_original)
{
NlaStrip *strip = nes->strip;
@@ -1928,10 +1963,12 @@ void nlastrip_evaluate(PointerRNA *ptr,
nlastrip_evaluate_actionclip(ptr, channels, modifiers, nes, snapshot);
break;
case NLASTRIP_TYPE_TRANSITION: /* transition */
- nlastrip_evaluate_transition(ptr, channels, modifiers, nes, snapshot, flush_to_original);
+ nlastrip_evaluate_transition(
+ ptr, channels, modifiers, nes, snapshot, anim_eval_context, flush_to_original);
break;
case NLASTRIP_TYPE_META: /* meta */
- nlastrip_evaluate_meta(ptr, channels, modifiers, nes, snapshot, flush_to_original);
+ nlastrip_evaluate_meta(
+ ptr, channels, modifiers, nes, snapshot, anim_eval_context, flush_to_original);
break;
default: /* do nothing */
@@ -2079,7 +2116,7 @@ static void animsys_evaluate_nla_domain(PointerRNA *ptr, NlaEvalData *channels,
static bool animsys_evaluate_nla(NlaEvalData *echannels,
PointerRNA *ptr,
AnimData *adt,
- float ctime,
+ const AnimationEvalContext *anim_eval_context,
const bool flush_to_original,
NlaKeyframingContext *r_context)
{
@@ -2127,7 +2164,8 @@ static bool animsys_evaluate_nla(NlaEvalData *echannels,
}
/* otherwise, get strip to evaluate for this channel */
- nes = nlastrips_ctime_get_strip(&estrips, &nlt->strips, track_index, ctime, flush_to_original);
+ nes = nlastrips_ctime_get_strip(
+ &estrips, &nlt->strips, track_index, anim_eval_context, flush_to_original);
if (nes) {
nes->track = nlt;
}
@@ -2193,7 +2231,8 @@ static bool animsys_evaluate_nla(NlaEvalData *echannels,
/* add this to our list of evaluation strips */
if (r_context == NULL) {
- nlastrips_ctime_get_strip(&estrips, &dummy_trackslist, -1, ctime, flush_to_original);
+ nlastrips_ctime_get_strip(
+ &estrips, &dummy_trackslist, -1, anim_eval_context, flush_to_original);
}
/* If computing the context for keyframing, store data there instead of the list. */
else {
@@ -2203,7 +2242,7 @@ static bool animsys_evaluate_nla(NlaEvalData *echannels,
NLASTRIP_EXTEND_HOLD;
r_context->eval_strip = nes = nlastrips_ctime_get_strip(
- NULL, &dummy_trackslist, -1, ctime, flush_to_original);
+ NULL, &dummy_trackslist, -1, anim_eval_context, flush_to_original);
/* These setting combinations require no data from strips below, so exit immediately. */
if ((nes == NULL) ||
@@ -2228,7 +2267,13 @@ static bool animsys_evaluate_nla(NlaEvalData *echannels,
/* 2. for each strip, evaluate then accumulate on top of existing channels,
* but don't set values yet. */
for (nes = estrips.first; nes; nes = nes->next) {
- nlastrip_evaluate(ptr, echannels, NULL, nes, &echannels->eval_snapshot, flush_to_original);
+ nlastrip_evaluate(ptr,
+ echannels,
+ NULL,
+ nes,
+ &echannels->eval_snapshot,
+ anim_eval_context,
+ flush_to_original);
}
/* 3. free temporary evaluation data that's not used elsewhere */
@@ -2242,7 +2287,7 @@ static bool animsys_evaluate_nla(NlaEvalData *echannels,
*/
static void animsys_calculate_nla(PointerRNA *ptr,
AnimData *adt,
- float ctime,
+ const AnimationEvalContext *anim_eval_context,
const bool flush_to_original)
{
NlaEvalData echannels;
@@ -2250,7 +2295,7 @@ static void animsys_calculate_nla(PointerRNA *ptr,
nlaeval_init(&echannels);
/* evaluate the NLA stack, obtaining a set of values to flush */
- if (animsys_evaluate_nla(&echannels, ptr, adt, ctime, flush_to_original, NULL)) {
+ if (animsys_evaluate_nla(&echannels, ptr, adt, anim_eval_context, flush_to_original, NULL)) {
/* reset any channels touched by currently inactive actions to default value */
animsys_evaluate_nla_domain(ptr, &echannels, adt);
@@ -2264,7 +2309,7 @@ static void animsys_calculate_nla(PointerRNA *ptr,
CLOG_WARN(&LOG, "NLA Eval: Stopgap for active action on NLA Stack - no strips case");
}
- animsys_evaluate_action(ptr, adt->action, ctime, flush_to_original);
+ animsys_evaluate_action(ptr, adt->action, anim_eval_context, flush_to_original);
}
/* free temp data */
@@ -2282,11 +2327,12 @@ static void animsys_calculate_nla(PointerRNA *ptr,
* \param ptr: RNA pointer to the Object with the animation.
* \return Keyframing context, or NULL if not necessary.
*/
-NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(struct ListBase *cache,
- struct PointerRNA *ptr,
- struct AnimData *adt,
- float ctime,
- const bool flush_to_original)
+NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(
+ struct ListBase *cache,
+ struct PointerRNA *ptr,
+ struct AnimData *adt,
+ const AnimationEvalContext *anim_eval_context,
+ const bool flush_to_original)
{
/* No remapping needed if NLA is off or no action. */
if ((adt == NULL) || (adt->action == NULL) || (adt->nla_tracks.first == NULL) ||
@@ -2309,7 +2355,7 @@ NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(struct ListBase *ca
ctx->adt = adt;
nlaeval_init(&ctx->nla_channels);
- animsys_evaluate_nla(&ctx->nla_channels, ptr, adt, ctime, flush_to_original, ctx);
+ animsys_evaluate_nla(&ctx->nla_channels, ptr, adt, anim_eval_context, flush_to_original, ctx);
BLI_assert(ELEM(ctx->strip.act, NULL, adt->action));
BLI_addtail(cache, ctx);
@@ -2499,8 +2545,11 @@ static void animsys_evaluate_overrides(PointerRNA *ptr, AnimData *adt)
* and that the flags for which parts of the anim-data settings need to be recalculated
* have been set already by the depsgraph. Now, we use the recalc
*/
-void BKE_animsys_evaluate_animdata(
- ID *id, AnimData *adt, float ctime, eAnimData_Recalc recalc, const bool flush_to_original)
+void BKE_animsys_evaluate_animdata(ID *id,
+ AnimData *adt,
+ const AnimationEvalContext *anim_eval_context,
+ eAnimData_Recalc recalc,
+ const bool flush_to_original)
{
PointerRNA id_ptr;
@@ -2523,11 +2572,11 @@ void BKE_animsys_evaluate_animdata(
/* evaluate NLA-stack
* - active action is evaluated as part of the NLA stack as the last item
*/
- animsys_calculate_nla(&id_ptr, adt, ctime, flush_to_original);
+ animsys_calculate_nla(&id_ptr, adt, anim_eval_context, flush_to_original);
}
/* evaluate Active Action only */
else if (adt->action) {
- animsys_evaluate_action_ex(&id_ptr, adt->action, ctime, flush_to_original);
+ animsys_evaluate_action_ex(&id_ptr, adt->action, anim_eval_context, flush_to_original);
}
}
@@ -2537,7 +2586,7 @@ void BKE_animsys_evaluate_animdata(
* - Drivers should be in the appropriate order to be evaluated without problems...
*/
if (recalc & ADT_RECALC_DRIVERS) {
- animsys_evaluate_drivers(&id_ptr, adt, ctime);
+ animsys_evaluate_drivers(&id_ptr, adt, anim_eval_context);
}
/* always execute 'overrides'
@@ -2565,6 +2614,8 @@ void BKE_animsys_evaluate_all_animation(Main *main, Depsgraph *depsgraph, float
}
const bool flush_to_original = DEG_is_active(depsgraph);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ ctime);
/* macros for less typing
* - only evaluate animation data for id if it has users (and not just fake ones)
@@ -2575,7 +2626,7 @@ void BKE_animsys_evaluate_all_animation(Main *main, Depsgraph *depsgraph, float
for (id = first; id; id = id->next) { \
if (ID_REAL_USERS(id) > 0) { \
AnimData *adt = BKE_animdata_from_id(id); \
- BKE_animsys_evaluate_animdata(id, adt, ctime, aflag, flush_to_original); \
+ BKE_animsys_evaluate_animdata(id, adt, &anim_eval_context, aflag, flush_to_original); \
} \
} \
(void)0
@@ -2594,9 +2645,9 @@ void BKE_animsys_evaluate_all_animation(Main *main, Depsgraph *depsgraph, float
if (ntp->nodetree) { \
AnimData *adt2 = BKE_animdata_from_id((ID *)ntp->nodetree); \
BKE_animsys_evaluate_animdata( \
- &ntp->nodetree->id, adt2, ctime, ADT_RECALC_ANIM, flush_to_original); \
+ &ntp->nodetree->id, adt2, &anim_eval_context, ADT_RECALC_ANIM, flush_to_original); \
} \
- BKE_animsys_evaluate_animdata(id, adt, ctime, aflag, flush_to_original); \
+ BKE_animsys_evaluate_animdata(id, adt, &anim_eval_context, aflag, flush_to_original); \
} \
} \
(void)0
@@ -2713,7 +2764,10 @@ void BKE_animsys_eval_animdata(Depsgraph *depsgraph, ID *id)
* which should get handled as part of the dependency graph instead. */
DEG_debug_print_eval_time(depsgraph, __func__, id->name, id, ctime);
const bool flush_to_original = DEG_is_active(depsgraph);
- BKE_animsys_evaluate_animdata(id, adt, ctime, ADT_RECALC_ANIM, flush_to_original);
+
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ ctime);
+ BKE_animsys_evaluate_animdata(id, adt, &anim_eval_context, ADT_RECALC_ANIM, flush_to_original);
}
void BKE_animsys_update_driver_array(ID *id)
@@ -2775,7 +2829,9 @@ void BKE_animsys_eval_driver(Depsgraph *depsgraph, ID *id, int driver_index, FCu
if (BKE_animsys_store_rna_setting(&id_ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
/* Evaluate driver, and write results to COW-domain destination */
const float ctime = DEG_get_ctime(depsgraph);
- const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
+ depsgraph, ctime);
+ const float curval = calculate_fcurve(&anim_rna, fcu, &anim_eval_context);
ok = BKE_animsys_write_rna_setting(&anim_rna, curval);
/* Flush results & status codes to original data for UI (T59984) */
diff --git a/source/blender/blenkernel/intern/anim_visualization.c b/source/blender/blenkernel/intern/anim_visualization.c
index 04dbe4102cc..a6f63c2ba95 100644
--- a/source/blender/blenkernel/intern/anim_visualization.c
+++ b/source/blender/blenkernel/intern/anim_visualization.c
@@ -184,10 +184,8 @@ bMotionPath *animviz_verify_motionpaths(ReportList *reports,
/* return/use this as it is already valid length */
return mpath;
}
- else {
- /* clear the existing path (as the range has changed), and reallocate below */
- animviz_free_motionpath_cache(mpath);
- }
+ /* clear the existing path (as the range has changed), and reallocate below */
+ animviz_free_motionpath_cache(mpath);
}
}
else {
diff --git a/source/blender/blenkernel/intern/appdir.c b/source/blender/blenkernel/intern/appdir.c
index 8189385a69d..2cc715464ad 100644
--- a/source/blender/blenkernel/intern/appdir.c
+++ b/source/blender/blenkernel/intern/appdir.c
@@ -56,7 +56,7 @@
# ifdef WITH_BINRELOC
# include "binreloc.h"
# endif
-/* mkdtemp on OSX (and probably all *BSD?), not worth making specific check for this OS. */
+/* #mkdtemp on OSX (and probably all *BSD?), not worth making specific check for this OS. */
# include <unistd.h>
#endif /* WIN32 */
@@ -120,7 +120,7 @@ static char *blender_version_decimal(const int ver)
}
/**
- * Concatenates path_base, (optional) path_sep and (optional) folder_name into targetpath,
+ * Concatenates path_base, (optional) path_sep and (optional) folder_name into \a targetpath,
* returning true if result points to a directory.
*/
static bool test_path(char *targetpath,
@@ -138,14 +138,14 @@ static bool test_path(char *targetpath,
BLI_strncpy(tmppath, path_base, sizeof(tmppath));
}
- /* rare cases folder_name is omitted (when looking for ~/.config/blender/2.xx dir only) */
+ /* Rare cases folder_name is omitted (when looking for `~/.config/blender/2.xx` dir only). */
if (folder_name) {
BLI_join_dirfile(targetpath, targetpath_len, tmppath, folder_name);
}
else {
BLI_strncpy(targetpath, tmppath, targetpath_len);
}
- /* FIXME: why is "//" on front of tmppath expanded to "/" (by BLI_join_dirfile)
+ /* FIXME: why is "//" on front of \a tmppath expanded to "/" (by BLI_join_dirfile)
* if folder_name is specified but not otherwise? */
if (BLI_is_dir(targetpath)) {
@@ -154,13 +154,12 @@ static bool test_path(char *targetpath,
#endif
return true;
}
- else {
+
#ifdef PATH_DEBUG
- printf("\t%s missing: %s\n", __func__, targetpath);
+ printf("\t%s missing: %s\n", __func__, targetpath);
#endif
- // targetpath[0] = '\0';
- return false;
- }
+ // targetpath[0] = '\0';
+ return false;
}
/**
@@ -181,18 +180,17 @@ static bool test_env_path(char *path, const char *envvar)
#endif
return true;
}
- else {
- path[0] = '\0';
+
+ path[0] = '\0';
#ifdef PATH_DEBUG
- printf("\t%s env %s missing: %s\n", __func__, envvar, env);
+ printf("\t%s env %s missing: %s\n", __func__, envvar, env);
#endif
- return false;
- }
+ return false;
}
/**
* Constructs in \a targetpath the name of a directory relative to a version-specific
- * subdirectory in the parent directory of the Blender executable.
+ * sub-directory in the parent directory of the Blender executable.
*
* \param targetpath: String to return path
* \param folder_name: Optional folder name within version-specific directory
@@ -272,10 +270,8 @@ static bool get_path_environment(char *targetpath,
if (subfolder_name) {
return test_path(targetpath, targetpath_len, user_path, NULL, subfolder_name);
}
- else {
- BLI_strncpy(targetpath, user_path, FILE_MAX);
- return true;
- }
+ BLI_strncpy(targetpath, user_path, FILE_MAX);
+ return true;
}
return false;
}
@@ -300,10 +296,8 @@ static bool get_path_environment_notest(char *targetpath,
BLI_join_dirfile(targetpath, targetpath_len, user_path, subfolder_name);
return true;
}
- else {
- BLI_strncpy(targetpath, user_path, FILE_MAX);
- return true;
- }
+ BLI_strncpy(targetpath, user_path, FILE_MAX);
+ return true;
}
return false;
}
@@ -313,7 +307,7 @@ static bool get_path_environment_notest(char *targetpath,
* \param targetpath: String to return path
* \param folder_name: default name of folder within user area
* \param subfolder_name: optional name of subfolder within folder
- * \param ver: Blender version, used to construct a subdirectory name
+ * \param ver: Blender version, used to construct a sub-directory name
* \return true if it was able to construct such a path.
*/
static bool get_path_user(char *targetpath,
@@ -347,9 +341,8 @@ static bool get_path_user(char *targetpath,
if (subfolder_name) {
return test_path(targetpath, targetpath_len, user_path, folder_name, subfolder_name);
}
- else {
- return test_path(targetpath, targetpath_len, user_path, NULL, folder_name);
- }
+
+ return test_path(targetpath, targetpath_len, user_path, NULL, folder_name);
}
/**
@@ -357,8 +350,8 @@ static bool get_path_user(char *targetpath,
*
* \param targetpath: String to return path
* \param folder_name: default name of folder within installation area
- * \param subfolder_name: optional name of subfolder within folder
- * \param ver: Blender version, used to construct a subdirectory name
+ * \param subfolder_name: optional name of sub-folder within folder
+ * \param ver: Blender version, used to construct a sub-directory name
* \return true if it was able to construct such a path.
*/
static bool get_path_system(char *targetpath,
@@ -401,10 +394,9 @@ static bool get_path_system(char *targetpath,
/* try $BLENDERPATH/folder_name/subfolder_name */
return test_path(targetpath, targetpath_len, system_path, folder_name, subfolder_name);
}
- else {
- /* try $BLENDERPATH/folder_name */
- return test_path(targetpath, targetpath_len, system_path, NULL, folder_name);
- }
+
+ /* try $BLENDERPATH/folder_name */
+ return test_path(targetpath, targetpath_len, system_path, NULL, folder_name);
}
/**
@@ -643,7 +635,7 @@ const char *BKE_appdir_folder_id_version(const int folder_id, const int ver, con
* adds the correct extension (.com .exe etc) from
* $PATHEXT if necessary. Also on Windows it translates
* the name to its 8.3 version to prevent problems with
- * spaces and stuff. Final result is returned in fullname.
+ * spaces and stuff. Final result is returned in \a fullname.
*
* \param fullname: The full path and full name of the executable
* (must be FILE_MAX minimum)
@@ -983,7 +975,7 @@ static void where_is_temp(char *fullname, char *basename, const size_t maxlen, c
/**
* Sets btempdir_base to userdir if specified and is a valid directory, otherwise
* chooses a suitable OS-specific temporary directory.
- * Sets btempdir_session to a mkdtemp-generated sub-dir of btempdir_base.
+ * Sets btempdir_session to a #mkdtemp generated sub-dir of btempdir_base.
*
* \note On Window userdir will be set to the temporary directory!
*/
@@ -1027,7 +1019,11 @@ void BKE_tempdir_session_purge(void)
}
/* Gets a good default directory for fonts */
-bool BKE_appdir_font_folder_default(char *dir)
+
+bool BKE_appdir_font_folder_default(
+ /* This parameter can only be `const` on non-windows platforms.
+ * NOLINTNEXTLINE: readability-non-const-parameter. */
+ char *dir)
{
bool success = false;
#ifdef WIN32
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 007062abb5b..631ce4edd20 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -512,12 +512,10 @@ bool BKE_armature_bone_flag_test_recursive(const Bone *bone, int flag)
if (bone->flag & flag) {
return true;
}
- else if (bone->parent) {
+ if (bone->parent) {
return BKE_armature_bone_flag_test_recursive(bone->parent, flag);
}
- else {
- return false;
- }
+ return false;
}
/** \} */
@@ -687,10 +685,7 @@ int bone_autoside_name(
return 1;
}
-
- else {
- return 0;
- }
+ return 0;
}
/** \} */
@@ -1387,7 +1382,7 @@ void get_objectspace_bone_matrix(struct Bone *bone,
}
/* Convert World-Space Matrix to Pose-Space Matrix */
-void BKE_armature_mat_world_to_pose(Object *ob, float inmat[4][4], float outmat[4][4])
+void BKE_armature_mat_world_to_pose(Object *ob, const float inmat[4][4], float outmat[4][4])
{
float obmat[4][4];
@@ -1679,7 +1674,9 @@ void BKE_bone_parent_transform_apply(const struct BoneParentTransform *bpt,
/* Convert Pose-Space Matrix to Bone-Space Matrix.
* NOTE: this cannot be used to convert to pose-space transforms of the supplied
* pose-channel into its local space (i.e. 'visual'-keyframing) */
-void BKE_armature_mat_pose_to_bone(bPoseChannel *pchan, float inmat[4][4], float outmat[4][4])
+void BKE_armature_mat_pose_to_bone(bPoseChannel *pchan,
+ const float inmat[4][4],
+ float outmat[4][4])
{
BoneParentTransform bpt;
@@ -1689,7 +1686,9 @@ void BKE_armature_mat_pose_to_bone(bPoseChannel *pchan, float inmat[4][4], float
}
/* Convert Bone-Space Matrix to Pose-Space Matrix. */
-void BKE_armature_mat_bone_to_pose(bPoseChannel *pchan, float inmat[4][4], float outmat[4][4])
+void BKE_armature_mat_bone_to_pose(bPoseChannel *pchan,
+ const float inmat[4][4],
+ float outmat[4][4])
{
BoneParentTransform bpt;
@@ -1725,7 +1724,7 @@ void BKE_armature_loc_pose_to_bone(bPoseChannel *pchan, const float inloc[3], fl
void BKE_armature_mat_pose_to_bone_ex(struct Depsgraph *depsgraph,
Object *ob,
bPoseChannel *pchan,
- float inmat[4][4],
+ const float inmat[4][4],
float outmat[4][4])
{
bPoseChannel work_pchan = *pchan;
@@ -1746,7 +1745,7 @@ void BKE_armature_mat_pose_to_bone_ex(struct Depsgraph *depsgraph,
/**
* Same as #BKE_object_mat3_to_rot().
*/
-void BKE_pchan_mat3_to_rot(bPoseChannel *pchan, float mat[3][3], bool use_compat)
+void BKE_pchan_mat3_to_rot(bPoseChannel *pchan, const float mat[3][3], bool use_compat)
{
BLI_ASSERT_UNIT_M3(mat);
@@ -1771,17 +1770,17 @@ void BKE_pchan_mat3_to_rot(bPoseChannel *pchan, float mat[3][3], bool use_compat
/**
* Same as #BKE_object_rot_to_mat3().
*/
-void BKE_pchan_rot_to_mat3(const bPoseChannel *pchan, float mat[3][3])
+void BKE_pchan_rot_to_mat3(const bPoseChannel *pchan, float r_mat[3][3])
{
/* rotations may either be quats, eulers (with various rotation orders), or axis-angle */
if (pchan->rotmode > 0) {
/* euler rotations (will cause gimble lock,
* but this can be alleviated a bit with rotation orders) */
- eulO_to_mat3(mat, pchan->eul, pchan->rotmode);
+ eulO_to_mat3(r_mat, pchan->eul, pchan->rotmode);
}
else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
/* axis-angle - not really that great for 3D-changing orientations */
- axis_angle_to_mat3(mat, pchan->rotAxis, pchan->rotAngle);
+ axis_angle_to_mat3(r_mat, pchan->rotAxis, pchan->rotAngle);
}
else {
/* quats are normalized before use to eliminate scaling issues */
@@ -1791,7 +1790,7 @@ void BKE_pchan_rot_to_mat3(const bPoseChannel *pchan, float mat[3][3])
* since this was kindof evil in some cases but if this proves to be too problematic,
* switch back to the old system of operating directly on the stored copy. */
normalize_qt_qt(quat, pchan->quat);
- quat_to_mat3(mat, quat);
+ quat_to_mat3(r_mat, quat);
}
}
@@ -1799,7 +1798,7 @@ void BKE_pchan_rot_to_mat3(const bPoseChannel *pchan, float mat[3][3])
* Apply a 4x4 matrix to the pose bone,
* similar to #BKE_object_apply_mat4().
*/
-void BKE_pchan_apply_mat4(bPoseChannel *pchan, float mat[4][4], bool use_compat)
+void BKE_pchan_apply_mat4(bPoseChannel *pchan, const float mat[4][4], bool use_compat)
{
float rot[3][3];
mat4_to_loc_rot_size(pchan->loc, rot, pchan->size, mat);
@@ -2003,7 +2002,7 @@ void mat3_vec_to_roll(const float mat[3][3], const float vec[3], float *r_roll)
* └ -2 * x * z, x^2 - z^2 ┘
* </pre>
*/
-void vec_roll_to_mat3_normalized(const float nor[3], const float roll, float mat[3][3])
+void vec_roll_to_mat3_normalized(const float nor[3], const float roll, float r_mat[3][3])
{
#define THETA_THRESHOLD_NEGY 1.0e-9f
#define THETA_THRESHOLD_NEGY_CLOSE 1.0e-5f
@@ -2057,18 +2056,18 @@ void vec_roll_to_mat3_normalized(const float nor[3], const float roll, float mat
axis_angle_normalized_to_mat3(rMatrix, nor, roll);
/* Combine and output result */
- mul_m3_m3m3(mat, rMatrix, bMatrix);
+ mul_m3_m3m3(r_mat, rMatrix, bMatrix);
#undef THETA_THRESHOLD_NEGY
#undef THETA_THRESHOLD_NEGY_CLOSE
}
-void vec_roll_to_mat3(const float vec[3], const float roll, float mat[3][3])
+void vec_roll_to_mat3(const float vec[3], const float roll, float r_mat[3][3])
{
float nor[3];
normalize_v3_v3(nor, vec);
- vec_roll_to_mat3_normalized(nor, roll, mat);
+ vec_roll_to_mat3_normalized(nor, roll, r_mat);
}
/** \} */
@@ -2169,7 +2168,7 @@ static void pose_proxy_sync(Object *ob, Object *from, int layer_protected)
}
/* clear all transformation values from library */
- BKE_pose_rest(frompose);
+ BKE_pose_rest(frompose, false);
/* copy over all of the proxy's bone groups */
/* TODO for later
@@ -2206,7 +2205,7 @@ static void pose_proxy_sync(Object *ob, Object *from, int layer_protected)
pchan->mpath = NULL;
/* Reset runtime data, we don't want to share that with the proxy. */
- BKE_pose_channel_runtime_reset(&pchanw.runtime);
+ BKE_pose_channel_runtime_reset_on_copy(&pchanw.runtime);
/* this is freed so copy a copy, else undo crashes */
if (pchanw.prop) {
@@ -2423,8 +2422,10 @@ void BKE_pose_rebuild(Main *bmain, Object *ob, bArmature *arm, const bool do_id_
/** \name Pose Solver
* \{ */
-/* loc/rot/size to given mat4 */
-void BKE_pchan_to_mat4(const bPoseChannel *pchan, float chan_mat[4][4])
+/**
+ * Convert the loc/rot/size to \a r_chanmat (typically #bPoseChannel.chan_mat).
+ */
+void BKE_pchan_to_mat4(const bPoseChannel *pchan, float r_chanmat[4][4])
{
float smat[3][3];
float rmat[3][3];
@@ -2438,12 +2439,12 @@ void BKE_pchan_to_mat4(const bPoseChannel *pchan, float chan_mat[4][4])
/* calculate matrix of bone (as 3x3 matrix, but then copy the 4x4) */
mul_m3_m3m3(tmat, rmat, smat);
- copy_m4_m3(chan_mat, tmat);
+ copy_m4_m3(r_chanmat, tmat);
/* prevent action channels breaking chains */
/* need to check for bone here, CONSTRAINT_TYPE_ACTION uses this call */
if ((pchan->bone == NULL) || !(pchan->bone->flag & BONE_CONNECTED)) {
- copy_v3_v3(chan_mat[3], pchan->loc);
+ copy_v3_v3(r_chanmat[3], pchan->loc);
}
}
@@ -2581,7 +2582,7 @@ void BKE_pose_where_is(struct Depsgraph *depsgraph, Scene *scene, Object *ob)
}
/* 2a. construct the IK tree (standard IK) */
- BIK_initialize_tree(depsgraph, scene, ob, ctime);
+ BIK_init_tree(depsgraph, scene, ob, ctime);
/* 2b. construct the Spline IK trees
* - this is not integrated as an IK plugin, since it should be able
diff --git a/source/blender/blenkernel/intern/armature_deform.c b/source/blender/blenkernel/intern/armature_deform.c
index 44b50ab96d3..8711a001e32 100644
--- a/source/blender/blenkernel/intern/armature_deform.c
+++ b/source/blender/blenkernel/intern/armature_deform.c
@@ -163,17 +163,15 @@ float distfactor_to_bone(
if (dist_sq < a) {
return 1.0f;
}
- else {
- l = rad + rdist;
- l *= l;
- if (rdist == 0.0f || dist_sq >= l) {
- return 0.0f;
- }
- else {
- a = sqrtf(dist_sq) - rad;
- return 1.0f - (a * a) / (rdist * rdist);
- }
+
+ l = rad + rdist;
+ l *= l;
+ if (rdist == 0.0f || dist_sq >= l) {
+ return 0.0f;
}
+
+ a = sqrtf(dist_sq) - rad;
+ return 1.0f - (a * a) / (rdist * rdist);
}
static float dist_bone_deform(
diff --git a/source/blender/blenkernel/intern/armature_test.cc b/source/blender/blenkernel/intern/armature_test.cc
new file mode 100644
index 00000000000..cf17c37bc69
--- /dev/null
+++ b/source/blender/blenkernel/intern/armature_test.cc
@@ -0,0 +1,93 @@
+/*
+ * 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 Blender Foundation
+ * All rights reserved.
+ */
+
+#include "BKE_armature.h"
+
+#include "BLI_math.h"
+
+#include "testing/testing.h"
+
+namespace blender::bke::tests {
+
+static const float FLOAT_EPSILON = 1.2e-7;
+
+TEST(mat3_vec_to_roll, UnitMatrix)
+{
+ float unit_matrix[3][3];
+ float roll;
+
+ unit_m3(unit_matrix);
+
+ // Any vector with a unit matrix should return zero roll.
+ mat3_vec_to_roll(unit_matrix, unit_matrix[0], &roll);
+ EXPECT_FLOAT_EQ(0.0f, roll);
+
+ mat3_vec_to_roll(unit_matrix, unit_matrix[1], &roll);
+ EXPECT_FLOAT_EQ(0.0f, roll);
+
+ mat3_vec_to_roll(unit_matrix, unit_matrix[2], &roll);
+ EXPECT_FLOAT_EQ(0.0f, roll);
+
+ {
+ // Non-unit vector.
+ float vector[3] = {1.0f, 1.0f, 1.0f};
+ mat3_vec_to_roll(unit_matrix, vector, &roll);
+ EXPECT_NEAR(0.0f, roll, FLOAT_EPSILON);
+
+ // Normalized version of the above vector.
+ normalize_v3(vector);
+ mat3_vec_to_roll(unit_matrix, vector, &roll);
+ EXPECT_NEAR(0.0f, roll, FLOAT_EPSILON);
+ }
+}
+
+TEST(mat3_vec_to_roll, Rotationmatrix)
+{
+ float rotation_matrix[3][3];
+ float roll;
+
+ const float rot_around_x[3] = {1.234f, 0.0f, 0.0f};
+ eul_to_mat3(rotation_matrix, rot_around_x);
+
+ {
+ const float unit_axis_x[3] = {1.0f, 0.0f, 0.0f};
+ mat3_vec_to_roll(rotation_matrix, unit_axis_x, &roll);
+ EXPECT_NEAR(1.234f, roll, FLOAT_EPSILON);
+ }
+
+ {
+ const float unit_axis_y[3] = {0.0f, 1.0f, 0.0f};
+ mat3_vec_to_roll(rotation_matrix, unit_axis_y, &roll);
+ EXPECT_NEAR(0, roll, FLOAT_EPSILON);
+ }
+
+ {
+ const float unit_axis_z[3] = {0.0f, 0.0f, 1.0f};
+ mat3_vec_to_roll(rotation_matrix, unit_axis_z, &roll);
+ EXPECT_NEAR(0, roll, FLOAT_EPSILON);
+ }
+
+ {
+ const float between_x_and_y[3] = {1.0f, 1.0f, 0.0f};
+ mat3_vec_to_roll(rotation_matrix, between_x_and_y, &roll);
+ EXPECT_NEAR(0.57158958f, roll, FLOAT_EPSILON);
+ }
+}
+
+} // namespace blender::bke::tests
diff --git a/source/blender/blenkernel/intern/armature_update.c b/source/blender/blenkernel/intern/armature_update.c
index d0a5e4348b9..97c717572bc 100644
--- a/source/blender/blenkernel/intern/armature_update.c
+++ b/source/blender/blenkernel/intern/armature_update.c
@@ -119,9 +119,8 @@ static void splineik_init_tree_from_pchan(Scene *UNUSED(scene),
if (segcount == 0) {
return;
}
- else {
- pchanRoot = pchanChain[segcount - 1];
- }
+
+ pchanRoot = pchanChain[segcount - 1];
/* perform binding step if required */
if ((ikData->flag & CONSTRAINT_SPLINEIK_BOUND) == 0) {
@@ -659,7 +658,7 @@ void BKE_pose_eval_init_ik(struct Depsgraph *depsgraph, Scene *scene, Object *ob
return;
}
/* construct the IK tree (standard IK) */
- BIK_initialize_tree(depsgraph, scene, object, ctime);
+ BIK_init_tree(depsgraph, scene, object, ctime);
/* construct the Spline IK trees
* - this is not integrated as an IK plugin, since it should be able
* to function in conjunction with standard IK. */
@@ -717,7 +716,7 @@ void BKE_pose_constraints_evaluate(struct Depsgraph *depsgraph,
if (armature->flag & ARM_RESTPOS) {
return;
}
- else if (pchan->flag & POSE_IKTREE || pchan->flag & POSE_IKSPLINE) {
+ if (pchan->flag & POSE_IKTREE || pchan->flag & POSE_IKSPLINE) {
/* IK are being solved separately/ */
}
else {
diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c
index d5064629451..a0da1b1677d 100644
--- a/source/blender/blenkernel/intern/boids.c
+++ b/source/blender/blenkernel/intern/boids.c
@@ -872,91 +872,90 @@ static Object *boid_find_ground(BoidBrainData *bbd,
return bpa->ground;
}
- else {
- float zvec[3] = {0.0f, 0.0f, 2000.0f};
- ParticleCollision col;
- ColliderCache *coll;
- BVHTreeRayHit hit;
- float radius = 0.0f, t, ray_dir[3];
-
- if (!bbd->sim->colliders) {
- return NULL;
- }
-
- memset(&col, 0, sizeof(ParticleCollision));
- /* first try to find below boid */
- copy_v3_v3(col.co1, pa->state.co);
- sub_v3_v3v3(col.co2, pa->state.co, zvec);
- sub_v3_v3v3(ray_dir, col.co2, col.co1);
- col.f = 0.0f;
- hit.index = -1;
- hit.dist = col.original_ray_length = normalize_v3(ray_dir);
- col.pce.inside = 0;
+ float zvec[3] = {0.0f, 0.0f, 2000.0f};
+ ParticleCollision col;
+ ColliderCache *coll;
+ BVHTreeRayHit hit;
+ float radius = 0.0f, t, ray_dir[3];
- for (coll = bbd->sim->colliders->first; coll; coll = coll->next) {
- col.current = coll->ob;
- col.md = coll->collmd;
- col.fac1 = col.fac2 = 0.f;
+ if (!bbd->sim->colliders) {
+ return NULL;
+ }
- if (col.md && col.md->bvhtree) {
- BLI_bvhtree_ray_cast_ex(col.md->bvhtree,
- col.co1,
- ray_dir,
- radius,
- &hit,
- BKE_psys_collision_neartest_cb,
- &col,
- raycast_flag);
- }
+ memset(&col, 0, sizeof(ParticleCollision));
+
+ /* first try to find below boid */
+ copy_v3_v3(col.co1, pa->state.co);
+ sub_v3_v3v3(col.co2, pa->state.co, zvec);
+ sub_v3_v3v3(ray_dir, col.co2, col.co1);
+ col.f = 0.0f;
+ hit.index = -1;
+ hit.dist = col.original_ray_length = normalize_v3(ray_dir);
+ col.pce.inside = 0;
+
+ for (coll = bbd->sim->colliders->first; coll; coll = coll->next) {
+ col.current = coll->ob;
+ col.md = coll->collmd;
+ col.fac1 = col.fac2 = 0.f;
+
+ if (col.md && col.md->bvhtree) {
+ BLI_bvhtree_ray_cast_ex(col.md->bvhtree,
+ col.co1,
+ ray_dir,
+ radius,
+ &hit,
+ BKE_psys_collision_neartest_cb,
+ &col,
+ raycast_flag);
}
- /* then use that object */
- if (hit.index >= 0) {
- t = hit.dist / col.original_ray_length;
- interp_v3_v3v3(ground_co, col.co1, col.co2, t);
- normalize_v3_v3(ground_nor, col.pce.nor);
- return col.hit;
- }
-
- /* couldn't find below, so find upmost deflector object */
- add_v3_v3v3(col.co1, pa->state.co, zvec);
- sub_v3_v3v3(col.co2, pa->state.co, zvec);
- sub_v3_v3(col.co2, zvec);
- sub_v3_v3v3(ray_dir, col.co2, col.co1);
- col.f = 0.0f;
- hit.index = -1;
- hit.dist = col.original_ray_length = normalize_v3(ray_dir);
-
- for (coll = bbd->sim->colliders->first; coll; coll = coll->next) {
- col.current = coll->ob;
- col.md = coll->collmd;
+ }
+ /* then use that object */
+ if (hit.index >= 0) {
+ t = hit.dist / col.original_ray_length;
+ interp_v3_v3v3(ground_co, col.co1, col.co2, t);
+ normalize_v3_v3(ground_nor, col.pce.nor);
+ return col.hit;
+ }
- if (col.md && col.md->bvhtree) {
- BLI_bvhtree_ray_cast_ex(col.md->bvhtree,
- col.co1,
- ray_dir,
- radius,
- &hit,
- BKE_psys_collision_neartest_cb,
- &col,
- raycast_flag);
- }
+ /* couldn't find below, so find upmost deflector object */
+ add_v3_v3v3(col.co1, pa->state.co, zvec);
+ sub_v3_v3v3(col.co2, pa->state.co, zvec);
+ sub_v3_v3(col.co2, zvec);
+ sub_v3_v3v3(ray_dir, col.co2, col.co1);
+ col.f = 0.0f;
+ hit.index = -1;
+ hit.dist = col.original_ray_length = normalize_v3(ray_dir);
+
+ for (coll = bbd->sim->colliders->first; coll; coll = coll->next) {
+ col.current = coll->ob;
+ col.md = coll->collmd;
+
+ if (col.md && col.md->bvhtree) {
+ BLI_bvhtree_ray_cast_ex(col.md->bvhtree,
+ col.co1,
+ ray_dir,
+ radius,
+ &hit,
+ BKE_psys_collision_neartest_cb,
+ &col,
+ raycast_flag);
}
- /* then use that object */
- if (hit.index >= 0) {
- t = hit.dist / col.original_ray_length;
- interp_v3_v3v3(ground_co, col.co1, col.co2, t);
- normalize_v3_v3(ground_nor, col.pce.nor);
- return col.hit;
- }
-
- /* default to z=0 */
- copy_v3_v3(ground_co, pa->state.co);
- ground_co[2] = 0;
- ground_nor[0] = ground_nor[1] = 0.0f;
- ground_nor[2] = 1.0f;
- return NULL;
}
+ /* then use that object */
+ if (hit.index >= 0) {
+ t = hit.dist / col.original_ray_length;
+ interp_v3_v3v3(ground_co, col.co1, col.co2, t);
+ normalize_v3_v3(ground_nor, col.pce.nor);
+ return col.hit;
+ }
+
+ /* default to z=0 */
+ copy_v3_v3(ground_co, pa->state.co);
+ ground_co[2] = 0;
+ ground_nor[0] = ground_nor[1] = 0.0f;
+ ground_nor[2] = 1.0f;
+ return NULL;
}
static int boid_rule_applies(ParticleData *pa, BoidSettings *UNUSED(boids), BoidRule *rule)
{
@@ -1046,9 +1045,7 @@ static int apply_boid_rule(
fuzziness * len_v3(pa->prev_state.vel)) == 0) {
return 1;
}
- else {
- return 0;
- }
+ return 0;
}
static BoidState *get_boid_state(BoidSettings *boids, ParticleData *pa)
{
diff --git a/source/blender/blenkernel/intern/bpath.c b/source/blender/blenkernel/intern/bpath.c
index 44873c54469..e2d17f34992 100644
--- a/source/blender/blenkernel/intern/bpath.c
+++ b/source/blender/blenkernel/intern/bpath.c
@@ -147,19 +147,16 @@ static bool bpath_relative_rebase_visit_cb(void *userdata, char *path_dst, const
data->count_changed++;
return true;
}
- else {
- /* Failed to make relative path absolute. */
- BLI_assert(0);
- BKE_reportf(data->reports, RPT_WARNING, "Path '%s' cannot be made absolute", path_src);
- data->count_failed++;
- return false;
- }
- return false;
- }
- else {
- /* Absolute, leave this as-is. */
+
+ /* Failed to make relative path absolute. */
+ BLI_assert(0);
+ BKE_reportf(data->reports, RPT_WARNING, "Path '%s' cannot be made absolute", path_src);
+ data->count_failed++;
return false;
}
+
+ /* Absolute, leave this as-is. */
+ return false;
}
void BKE_bpath_relative_rebase(Main *bmain,
@@ -211,18 +208,17 @@ static bool bpath_relative_convert_visit_cb(void *userdata, char *path_dst, cons
if (BLI_path_is_rel(path_src)) {
return false; /* already relative */
}
+
+ strcpy(path_dst, path_src);
+ BLI_path_rel(path_dst, data->basedir);
+ if (BLI_path_is_rel(path_dst)) {
+ data->count_changed++;
+ }
else {
- strcpy(path_dst, path_src);
- BLI_path_rel(path_dst, data->basedir);
- if (BLI_path_is_rel(path_dst)) {
- data->count_changed++;
- }
- else {
- BKE_reportf(data->reports, RPT_WARNING, "Path '%s' cannot be made relative", path_src);
- data->count_failed++;
- }
- return true;
+ BKE_reportf(data->reports, RPT_WARNING, "Path '%s' cannot be made relative", path_src);
+ data->count_failed++;
}
+ return true;
}
void BKE_bpath_relative_convert(Main *bmain, const char *basedir, ReportList *reports)
@@ -263,18 +259,17 @@ static bool bpath_absolute_convert_visit_cb(void *userdata, char *path_dst, cons
if (BLI_path_is_rel(path_src) == false) {
return false; /* already absolute */
}
+
+ strcpy(path_dst, path_src);
+ BLI_path_abs(path_dst, data->basedir);
+ if (BLI_path_is_rel(path_dst) == false) {
+ data->count_changed++;
+ }
else {
- strcpy(path_dst, path_src);
- BLI_path_abs(path_dst, data->basedir);
- if (BLI_path_is_rel(path_dst) == false) {
- data->count_changed++;
- }
- else {
- BKE_reportf(data->reports, RPT_WARNING, "Path '%s' cannot be made absolute", path_src);
- data->count_failed++;
- }
- return true;
+ BKE_reportf(data->reports, RPT_WARNING, "Path '%s' cannot be made absolute", path_src);
+ data->count_failed++;
}
+ return true;
}
/* similar to BKE_bpath_relative_convert - keep in sync! */
@@ -411,7 +406,7 @@ static bool missing_files_find__visit_cb(void *userdata, char *path_dst, const c
BLI_path_basename(data->searchdir));
return false;
}
- else if (found == false) {
+ if (found == false) {
BKE_reportf(data->reports,
RPT_WARNING,
"Could not find '%s' in '%s'",
@@ -419,18 +414,17 @@ static bool missing_files_find__visit_cb(void *userdata, char *path_dst, const c
data->searchdir);
return false;
}
- else {
- bool was_relative = BLI_path_is_rel(path_dst);
- BLI_strncpy(path_dst, filename_new, FILE_MAX);
+ bool was_relative = BLI_path_is_rel(path_dst);
- /* keep path relative if the previous one was relative */
- if (was_relative) {
- BLI_path_rel(path_dst, data->basedir);
- }
+ BLI_strncpy(path_dst, filename_new, FILE_MAX);
- return true;
+ /* keep path relative if the previous one was relative */
+ if (was_relative) {
+ BLI_path_rel(path_dst, data->basedir);
}
+
+ return true;
}
void BKE_bpath_missing_files_find(Main *bmain,
@@ -483,9 +477,8 @@ static bool rewrite_path_fixed(char *path,
BLI_strncpy(path, path_dst, FILE_MAX);
return true;
}
- else {
- return false;
- }
+
+ return false;
}
static bool rewrite_path_fixed_dirfile(char path_dir[FILE_MAXDIR],
@@ -510,9 +503,8 @@ static bool rewrite_path_fixed_dirfile(char path_dir[FILE_MAXDIR],
BLI_split_dirfile(path_dst, path_dir, path_file, FILE_MAXDIR, FILE_MAXFILE);
return true;
}
- else {
- return false;
- }
+
+ return false;
}
static bool rewrite_path_alloc(char **path,
@@ -538,9 +530,8 @@ static bool rewrite_path_alloc(char **path,
(*path) = BLI_strdup(path_dst);
return true;
}
- else {
- return false;
- }
+
+ return false;
}
/**
@@ -827,10 +818,9 @@ bool BKE_bpath_relocate_visitor(void *pathbase_v, char *path_dst, const char *pa
BLI_strncpy(path_dst, filepath, FILE_MAX);
return true;
}
- else {
- /* Path was not relative to begin with. */
- return false;
- }
+
+ /* Path was not relative to begin with. */
+ return false;
}
/** \} */
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index a8f52593429..39fbea66637 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -372,8 +372,8 @@ bool BKE_brush_delete(Main *bmain, Brush *brush)
if (brush->id.tag & LIB_TAG_INDIRECT) {
return false;
}
- else if (BKE_library_ID_is_indirectly_used(bmain, brush) && ID_REAL_USERS(brush) <= 1 &&
- ID_EXTRA_USERS(brush) == 0) {
+ if (BKE_library_ID_is_indirectly_used(bmain, brush) && ID_REAL_USERS(brush) <= 1 &&
+ ID_EXTRA_USERS(brush) == 0) {
return false;
}
@@ -503,7 +503,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.4f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
brush->gpencil_settings->input_samples = 10;
brush->gpencil_settings->active_smooth = ACTIVE_SMOOTH;
@@ -557,7 +557,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
/* Curve. */
custom_curve = brush->gpencil_settings->curve_sensitivity;
BKE_curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f);
- BKE_curvemapping_initialize(custom_curve);
+ BKE_curvemapping_init(custom_curve);
brush_gpencil_curvemap_reset(custom_curve->cm, 3, GPCURVE_PRESET_INK);
brush->gpencil_settings->icon_id = GP_BRUSH_ICON_INK;
@@ -594,7 +594,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
/* Curve. */
custom_curve = brush->gpencil_settings->curve_sensitivity;
BKE_curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f);
- BKE_curvemapping_initialize(custom_curve);
+ BKE_curvemapping_init(custom_curve);
brush_gpencil_curvemap_reset(custom_curve->cm, 3, GPCURVE_PRESET_INKNOISE);
brush->gpencil_settings->icon_id = GP_BRUSH_ICON_INKNOISE;
@@ -631,7 +631,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
/* Curve. */
custom_curve = brush->gpencil_settings->curve_sensitivity;
BKE_curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f);
- BKE_curvemapping_initialize(custom_curve);
+ BKE_curvemapping_init(custom_curve);
brush_gpencil_curvemap_reset(custom_curve->cm, 4, GPCURVE_PRESET_MARKER);
brush->gpencil_settings->icon_id = GP_BRUSH_ICON_MARKER;
@@ -667,12 +667,12 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
/* Curve. */
custom_curve = brush->gpencil_settings->curve_sensitivity;
BKE_curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f);
- BKE_curvemapping_initialize(custom_curve);
+ BKE_curvemapping_init(custom_curve);
brush_gpencil_curvemap_reset(custom_curve->cm, 3, GPCURVE_PRESET_CHISEL_SENSIVITY);
custom_curve = brush->gpencil_settings->curve_strength;
BKE_curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f);
- BKE_curvemapping_initialize(custom_curve);
+ BKE_curvemapping_init(custom_curve);
brush_gpencil_curvemap_reset(custom_curve->cm, 4, GPCURVE_PRESET_CHISEL_STRENGTH);
brush->gpencil_settings->icon_id = GP_BRUSH_ICON_CHISEL;
@@ -686,7 +686,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag &= ~GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 1.0f;
- brush->gpencil_settings->flag &= ~GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag &= ~GP_BRUSH_USE_STRENGTH_PRESSURE;
brush->gpencil_settings->input_samples = 10;
brush->gpencil_settings->active_smooth = ACTIVE_SMOOTH;
@@ -717,7 +717,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.4f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
brush->gpencil_settings->input_samples = 10;
brush->gpencil_settings->active_smooth = ACTIVE_SMOOTH;
@@ -760,7 +760,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.6f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
brush->gpencil_settings->input_samples = 10;
brush->gpencil_settings->active_smooth = ACTIVE_SMOOTH;
@@ -812,7 +812,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->draw_strength = 0.5f;
brush->gpencil_settings->flag |= GP_BRUSH_DEFAULT_ERASER;
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
brush->gpencil_settings->icon_id = GP_BRUSH_ICON_ERASE_SOFT;
brush->gpencil_tool = GPAINT_TOOL_ERASE;
brush->gpencil_settings->eraser_mode = GP_BRUSH_ERASER_SOFT;
@@ -859,7 +859,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.8f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
zero_v3(brush->secondary_rgb);
break;
@@ -872,7 +872,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.8f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
zero_v3(brush->secondary_rgb);
break;
@@ -885,7 +885,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.8f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
zero_v3(brush->secondary_rgb);
break;
@@ -898,7 +898,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.8f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
zero_v3(brush->secondary_rgb);
break;
@@ -911,7 +911,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.8f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
zero_v3(brush->secondary_rgb);
break;
@@ -924,7 +924,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.8f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
zero_v3(brush->secondary_rgb);
break;
@@ -937,7 +937,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.3f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
brush->gpencil_settings->sculpt_flag = GP_SCULPT_FLAG_SMOOTH_PRESSURE;
brush->gpencil_settings->sculpt_mode_flag |= GP_SCULPT_FLAGMODE_APPLY_POSITION;
@@ -951,7 +951,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.3f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
brush->gpencil_settings->sculpt_flag = GP_SCULPT_FLAG_SMOOTH_PRESSURE;
brush->gpencil_settings->sculpt_mode_flag |= GP_SCULPT_FLAGMODE_APPLY_POSITION;
@@ -965,7 +965,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.5f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
brush->gpencil_settings->sculpt_mode_flag |= GP_SCULPT_FLAGMODE_APPLY_POSITION;
break;
@@ -978,7 +978,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->size = 25.0f;
brush->gpencil_settings->draw_strength = 0.3f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
brush->gpencil_settings->sculpt_mode_flag |= GP_SCULPT_FLAGMODE_APPLY_POSITION;
break;
@@ -991,7 +991,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.3f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
brush->gpencil_settings->sculpt_mode_flag |= GP_SCULPT_FLAGMODE_APPLY_POSITION;
break;
@@ -1004,7 +1004,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.3f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
brush->gpencil_settings->sculpt_mode_flag |= GP_SCULPT_FLAGMODE_APPLY_POSITION;
break;
@@ -1017,7 +1017,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.5f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
brush->gpencil_settings->sculpt_mode_flag |= GP_SCULPT_FLAGMODE_APPLY_POSITION;
break;
@@ -1030,7 +1030,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.5f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
brush->gpencil_settings->sculpt_mode_flag |= GP_SCULPT_FLAGMODE_APPLY_POSITION;
break;
@@ -1043,7 +1043,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->size = 25.0f;
brush->gpencil_settings->draw_strength = 1.0f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
brush->gpencil_settings->sculpt_mode_flag |= GP_SCULPT_FLAGMODE_APPLY_POSITION;
break;
@@ -1056,7 +1056,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.8f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
brush->gpencil_settings->sculpt_mode_flag |= GP_SCULPT_FLAGMODE_APPLY_POSITION;
break;
@@ -1484,6 +1484,7 @@ void BKE_brush_sculpt_reset(Brush *br)
case SCULPT_TOOL_SLIDE_RELAX:
br->spacing = 10;
br->alpha = 1.0f;
+ br->slide_deform_type = BRUSH_SLIDE_DEFORM_DRAG;
break;
case SCULPT_TOOL_CLAY:
br->flag |= BRUSH_SIZE_PRESSURE;
@@ -1533,6 +1534,7 @@ void BKE_brush_sculpt_reset(Brush *br)
break;
case SCULPT_TOOL_SMOOTH:
br->flag &= ~BRUSH_SPACE_ATTEN;
+ br->automasking_flags |= BRUSH_AUTOMASKING_BOUNDARY_EDGES;
br->spacing = 5;
br->alpha = 0.7f;
br->surface_smooth_shape_preservation = 0.5f;
@@ -2180,10 +2182,9 @@ float BKE_brush_curve_strength(const Brush *br, float p, const float len)
if (p >= len) {
return 0;
}
- else {
- p = p / len;
- p = 1.0f - p;
- }
+
+ p = p / len;
+ p = 1.0f - p;
switch (br->curve_preset) {
case BRUSH_CURVE_CUSTOM:
@@ -2273,7 +2274,7 @@ struct ImBuf *BKE_brush_gen_radial_control_imbuf(Brush *br, bool secondary, bool
int half = side / 2;
int i, j;
- BKE_curvemapping_initialize(br->curve);
+ BKE_curvemapping_init(br->curve);
texcache = BKE_brush_gen_texture_cache(br, half, secondary);
im->rect_float = MEM_callocN(sizeof(float) * side * side, "radial control rect");
im->x = im->y = side;
diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c
index 93794eb9709..bea8fdd5719 100644
--- a/source/blender/blenkernel/intern/bvhutils.c
+++ b/source/blender/blenkernel/intern/bvhutils.c
@@ -717,11 +717,14 @@ BVHTree *bvhtree_from_mesh_verts_ex(BVHTreeFromMesh *data,
/* printf("BVHTree built and saved on cache\n"); */
BVHCache *bvh_cache = *bvh_cache_p;
bvhcache_insert(bvh_cache, tree, bvh_cache_type);
- bvhcache_unlock(bvh_cache, lock_started);
in_cache = true;
}
}
+ if (bvh_cache_p) {
+ bvhcache_unlock(*bvh_cache_p, lock_started);
+ }
+
/* Setup BVHTreeFromMesh */
bvhtree_from_mesh_verts_setup_data(data, tree, in_cache, vert, vert_allocated);
@@ -929,11 +932,14 @@ BVHTree *bvhtree_from_mesh_edges_ex(BVHTreeFromMesh *data,
/* Save on cache for later use */
/* printf("BVHTree built and saved on cache\n"); */
bvhcache_insert(bvh_cache, tree, bvh_cache_type);
- bvhcache_unlock(bvh_cache, lock_started);
in_cache = true;
}
}
+ if (bvh_cache_p) {
+ bvhcache_unlock(*bvh_cache_p, lock_started);
+ }
+
/* Setup BVHTreeFromMesh */
bvhtree_from_mesh_edges_setup_data(
data, tree, in_cache, vert, vert_allocated, edge, edge_allocated);
@@ -1058,11 +1064,14 @@ BVHTree *bvhtree_from_mesh_faces_ex(BVHTreeFromMesh *data,
/* printf("BVHTree built and saved on cache\n"); */
BVHCache *bvh_cache = *bvh_cache_p;
bvhcache_insert(bvh_cache, tree, bvh_cache_type);
- bvhcache_unlock(bvh_cache, lock_started);
in_cache = true;
}
}
+ if (bvh_cache_p) {
+ bvhcache_unlock(*bvh_cache_p, lock_started);
+ }
+
/* Setup BVHTreeFromMesh */
bvhtree_from_mesh_faces_setup_data(
data, tree, in_cache, vert, vert_allocated, face, face_allocated);
@@ -1298,11 +1307,14 @@ BVHTree *bvhtree_from_mesh_looptri_ex(BVHTreeFromMesh *data,
if (bvh_cache_p) {
BVHCache *bvh_cache = *bvh_cache_p;
bvhcache_insert(bvh_cache, tree, bvh_cache_type);
- bvhcache_unlock(bvh_cache, lock_started);
in_cache = true;
}
}
+ if (bvh_cache_p) {
+ bvhcache_unlock(*bvh_cache_p, lock_started);
+ }
+
/* Setup BVHTreeFromMesh */
bvhtree_from_mesh_looptri_setup_data(data,
tree,
@@ -1428,8 +1440,6 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
mesh->medge, mesh->totedge, mesh->mvert, verts_len, &loose_vert_len);
}
- /* TODO: a global mutex lock held during the expensive operation of
- * building the BVH tree is really bad for performance. */
tree = bvhtree_from_mesh_verts_ex(data,
mesh->mvert,
verts_len,
diff --git a/source/blender/blenkernel/intern/cachefile.c b/source/blender/blenkernel/intern/cachefile.c
index da9dab36044..9ad6ae84c5c 100644
--- a/source/blender/blenkernel/intern/cachefile.c
+++ b/source/blender/blenkernel/intern/cachefile.c
@@ -61,6 +61,8 @@ static void cache_file_init_data(ID *id)
BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(cache_file, id));
cache_file->scale = 1.0f;
+ cache_file->velocity_unit = CACHEFILE_VELOCITY_UNIT_SECOND;
+ BLI_strncpy(cache_file->velocity_name, ".velocities", sizeof(cache_file->velocity_name));
}
static void cache_file_copy_data(Main *UNUSED(bmain),
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index 566954fd5fa..467bd68c631 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -30,7 +30,6 @@
#include "DNA_scene_types.h"
#include "BLI_edgehash.h"
-#include "BLI_ghash.h"
#include "BLI_linklist.h"
#include "BLI_math.h"
#include "BLI_rand.h"
@@ -48,7 +47,7 @@
#include "BKE_modifier.h"
#include "BKE_pointcache.h"
-#include "BPH_mass_spring.h"
+#include "SIM_mass_spring.h"
// #include "PIL_time.h" /* timing for debug prints */
@@ -345,12 +344,12 @@ static int do_init_cloth(Object *ob, ClothModifierData *clmd, Mesh *result, int
return 0;
}
- BKE_cloth_solver_set_positions(clmd);
+ SIM_cloth_solver_set_positions(clmd);
ClothSimSettings *parms = clmd->sim_parms;
if (parms->flags & CLOTH_SIMSETTINGS_FLAG_PRESSURE &&
!(parms->flags & CLOTH_SIMSETTINGS_FLAG_PRESSURE_VOL)) {
- BKE_cloth_solver_set_volume(clmd);
+ SIM_cloth_solver_set_volume(clmd);
}
clmd->clothObject->last_frame = MINFRAME - 1;
@@ -405,7 +404,7 @@ static int do_step_cloth(
// TIMEIT_START(cloth_step)
/* call the solver. */
- ret = BPH_cloth_solve(depsgraph, ob, framenr, clmd, effectors);
+ ret = SIM_cloth_solve(depsgraph, ob, framenr, clmd, effectors);
// TIMEIT_END(cloth_step)
@@ -454,7 +453,7 @@ void clothModifier_do(ClothModifierData *clmd,
BKE_ptcache_invalidate(cache);
return;
}
- else if (framenr > endframe) {
+ if (framenr > endframe) {
framenr = endframe;
}
@@ -480,7 +479,7 @@ void clothModifier_do(ClothModifierData *clmd,
if (cache_result == PTCACHE_READ_EXACT || cache_result == PTCACHE_READ_INTERPOLATED ||
(!can_simulate && cache_result == PTCACHE_READ_OLD)) {
- BKE_cloth_solver_set_positions(clmd);
+ SIM_cloth_solver_set_positions(clmd);
cloth_to_object(ob, clmd, vertexCos);
BKE_ptcache_validate(cache, framenr);
@@ -493,8 +492,8 @@ void clothModifier_do(ClothModifierData *clmd,
return;
}
- else if (cache_result == PTCACHE_READ_OLD) {
- BKE_cloth_solver_set_positions(clmd);
+ if (cache_result == PTCACHE_READ_OLD) {
+ SIM_cloth_solver_set_positions(clmd);
}
else if (
/* 2.4x disabled lib, but this can be used in some cases, testing further - campbell */
@@ -538,7 +537,7 @@ void cloth_free_modifier(ClothModifierData *clmd)
cloth = clmd->clothObject;
if (cloth) {
- BPH_cloth_solver_free(clmd);
+ SIM_cloth_solver_free(clmd);
// Free the verts.
if (cloth->verts != NULL) {
@@ -587,7 +586,7 @@ void cloth_free_modifier(ClothModifierData *clmd)
}
if (cloth->sew_edge_graph) {
- BLI_ghash_free(cloth->sew_edge_graph, MEM_freeN, NULL);
+ BLI_edgeset_free(cloth->sew_edge_graph);
cloth->sew_edge_graph = NULL;
}
@@ -620,7 +619,7 @@ void cloth_free_modifier_extern(ClothModifierData *clmd)
printf("cloth_free_modifier_extern in\n");
}
- BPH_cloth_solver_free(clmd);
+ SIM_cloth_solver_free(clmd);
// Free the verts.
if (cloth->verts != NULL) {
@@ -669,7 +668,7 @@ void cloth_free_modifier_extern(ClothModifierData *clmd)
}
if (cloth->sew_edge_graph) {
- BLI_ghash_free(cloth->sew_edge_graph, MEM_freeN, NULL);
+ BLI_edgeset_free(cloth->sew_edge_graph);
cloth->sew_edge_graph = NULL;
}
@@ -920,10 +919,10 @@ static int cloth_from_object(
}
// init our solver
- BPH_cloth_solver_init(ob, clmd);
+ SIM_cloth_solver_init(ob, clmd);
if (!first) {
- BKE_cloth_solver_set_positions(clmd);
+ SIM_cloth_solver_set_positions(clmd);
}
clmd->clothObject->bvhtree = bvhtree_build_from_cloth(clmd, clmd->coll_parms->epsilon);
@@ -1038,7 +1037,7 @@ static void cloth_free_errorsprings(Cloth *cloth,
}
BLI_INLINE void cloth_bend_poly_dir(
- ClothVertex *verts, int i, int j, int *inds, int len, float r_dir[3])
+ ClothVertex *verts, int i, int j, const int *inds, int len, float r_dir[3])
{
float cent[3] = {0};
float fact = 1.0f / len;
@@ -1557,9 +1556,8 @@ static bool find_internal_spring_target_vertex(BVHTreeFromMesh *treedata,
*r_tar_v_idx = vert_idx;
return true;
}
- else {
- return false;
- }
+
+ return false;
}
static int cloth_build_springs(ClothModifierData *clmd, Mesh *mesh)
@@ -1693,8 +1691,7 @@ static int cloth_build_springs(ClothModifierData *clmd, Mesh *mesh)
if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SEW) {
/* cloth->sew_edge_graph should not exist before this */
BLI_assert(cloth->sew_edge_graph == NULL);
- cloth->sew_edge_graph = BLI_ghash_new(
- BLI_ghashutil_inthash_v2_p, BLI_ghashutil_inthash_v2_cmp, "cloth_sewing_edges_graph");
+ cloth->sew_edge_graph = BLI_edgeset_new("cloth_sewing_edges_graph");
}
/* Structural springs. */
@@ -1709,18 +1706,7 @@ static int cloth_build_springs(ClothModifierData *clmd, Mesh *mesh)
spring->lin_stiffness = 1.0f;
spring->type = CLOTH_SPRING_TYPE_SEWING;
- /* set indices of verts of the sewing edge symmetrically in sew_edge_graph */
- unsigned int *vertex_index_pair = MEM_mallocN(sizeof(unsigned int) * 2,
- "sewing_edge_index_pair_01");
- if (medge[i].v1 < medge[i].v2) {
- vertex_index_pair[0] = medge[i].v1;
- vertex_index_pair[1] = medge[i].v2;
- }
- else {
- vertex_index_pair[0] = medge[i].v2;
- vertex_index_pair[1] = medge[i].v1;
- }
- BLI_ghash_insert(cloth->sew_edge_graph, vertex_index_pair, NULL);
+ BLI_edgeset_insert(cloth->sew_edge_graph, medge[i].v1, medge[i].v2);
}
else {
shrink_factor = cloth_shrink_factor(clmd, cloth->verts, spring->ij, spring->kl);
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index 080d61f1500..6118325c231 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -249,6 +249,34 @@ void BKE_collection_add_from_object(Main *bmain,
BKE_main_collection_sync(bmain);
}
+/**
+ * Add \a collection_dst to all scene collections that reference collection \a collection_src is
+ * in.
+ *
+ * Logic is very similar to #BKE_collection_object_add_from().
+ */
+void BKE_collection_add_from_collection(Main *bmain,
+ Scene *scene,
+ Collection *collection_src,
+ Collection *collection_dst)
+{
+ bool is_instantiated = false;
+
+ FOREACH_SCENE_COLLECTION_BEGIN (scene, collection) {
+ if (!ID_IS_LINKED(collection) && BKE_collection_has_collection(collection, collection_src)) {
+ collection_child_add(collection, collection_dst, 0, true);
+ is_instantiated = true;
+ }
+ }
+ FOREACH_SCENE_COLLECTION_END;
+
+ if (!is_instantiated) {
+ collection_child_add(scene->master_collection, collection_dst, 0, true);
+ }
+
+ BKE_main_collection_sync(bmain);
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -333,7 +361,6 @@ static Collection *collection_duplicate_recursive(Main *bmain,
Collection *collection_new;
bool do_full_process = false;
const bool is_collection_master = (collection_old->flag & COLLECTION_IS_MASTER) != 0;
- const bool is_collection_liboverride = ID_IS_OVERRIDE_LIBRARY(collection_old);
const bool do_objects = (duplicate_flags & USER_DUP_OBJECT) != 0;
@@ -346,7 +373,12 @@ static Collection *collection_duplicate_recursive(Main *bmain,
}
else if (collection_old->id.newid == NULL) {
collection_new = (Collection *)BKE_id_copy_for_duplicate(
- bmain, (ID *)collection_old, is_collection_liboverride, duplicate_flags);
+ bmain, (ID *)collection_old, duplicate_flags);
+
+ if (collection_new == collection_old) {
+ return collection_new;
+ }
+
do_full_process = true;
}
else {
@@ -382,17 +414,15 @@ static Collection *collection_duplicate_recursive(Main *bmain,
Object *ob_old = cob->ob;
Object *ob_new = (Object *)ob_old->id.newid;
- /* If collection is an override, we do not want to duplicate any linked data-block, as that
- * would generate a purely local data. */
- if (is_collection_liboverride && ID_IS_LINKED(ob_old)) {
- continue;
- }
-
if (ob_new == NULL) {
ob_new = BKE_object_duplicate(
bmain, ob_old, duplicate_flags, duplicate_options | LIB_ID_DUPLICATE_IS_SUBPROCESS);
}
+ if (ob_new == ob_old) {
+ continue;
+ }
+
collection_object_add(bmain, collection_new, ob_new, 0, true);
collection_object_remove(bmain, collection_new, ob_old, false);
}
@@ -403,13 +433,11 @@ static Collection *collection_duplicate_recursive(Main *bmain,
LISTBASE_FOREACH_MUTABLE (CollectionChild *, child, &collection_old->children) {
Collection *child_collection_old = child->collection;
- if (is_collection_liboverride && ID_IS_LINKED(child_collection_old)) {
- continue;
- }
-
- collection_duplicate_recursive(
+ Collection *child_collection_new = collection_duplicate_recursive(
bmain, collection_new, child_collection_old, duplicate_flags, duplicate_options);
- collection_child_remove(collection_new, child_collection_old);
+ if (child_collection_new != child_collection_old) {
+ collection_child_remove(collection_new, child_collection_old);
+ }
}
return collection_new;
@@ -434,6 +462,11 @@ Collection *BKE_collection_duplicate(Main *bmain,
if (!is_subprocess) {
BKE_main_id_tag_all(bmain, LIB_TAG_NEW, false);
BKE_main_id_clear_newpoins(bmain);
+ /* In case root duplicated ID is linked, assume we want to get a local copy of it and duplicate
+ * all expected linked data. */
+ if (ID_IS_LINKED(collection)) {
+ duplicate_flags |= USER_DUP_LINKED_ID;
+ }
}
Collection *collection_new = collection_duplicate_recursive(
@@ -1114,7 +1147,7 @@ void BKE_collections_after_lib_link(Main *bmain)
/** \name Collection Children
* \{ */
-static bool collection_find_instance_recursive(Collection *collection,
+static bool collection_instance_find_recursive(Collection *collection,
Collection *instance_collection)
{
LISTBASE_FOREACH (CollectionObject *, collection_object, &collection->gobject) {
@@ -1126,7 +1159,7 @@ static bool collection_find_instance_recursive(Collection *collection,
}
LISTBASE_FOREACH (CollectionChild *, collection_child, &collection->children) {
- if (collection_find_instance_recursive(collection_child->collection, instance_collection)) {
+ if (collection_instance_find_recursive(collection_child->collection, instance_collection)) {
return true;
}
}
@@ -1134,21 +1167,88 @@ static bool collection_find_instance_recursive(Collection *collection,
return false;
}
-bool BKE_collection_find_cycle(Collection *new_ancestor, Collection *collection)
+/**
+ * Find potential cycles in collections.
+ *
+ * \param new_ancestor the potential new owner of given \a collection, or the collection to check
+ * if the later is NULL.
+ * \param collection the collection we want to add to \a new_ancestor, may be NULL if we just want
+ * to ensure \a new_ancestor does not already have cycles.
+ * \return true if a cycle is found.
+ */
+bool BKE_collection_cycle_find(Collection *new_ancestor, Collection *collection)
{
if (collection == new_ancestor) {
return true;
}
+ if (collection == NULL) {
+ collection = new_ancestor;
+ }
+
LISTBASE_FOREACH (CollectionParent *, parent, &new_ancestor->parents) {
- if (BKE_collection_find_cycle(parent->collection, collection)) {
+ if (BKE_collection_cycle_find(parent->collection, collection)) {
return true;
}
}
/* Find possible objects in collection or its children, that would instantiate the given ancestor
* collection (that would also make a fully invalid cycle of dependencies) .*/
- return collection_find_instance_recursive(collection, new_ancestor);
+ return collection_instance_find_recursive(collection, new_ancestor);
+}
+
+static bool collection_instance_fix_recursive(Collection *parent_collection,
+ Collection *collection)
+{
+ bool cycles_found = false;
+
+ LISTBASE_FOREACH (CollectionObject *, collection_object, &parent_collection->gobject) {
+ if (collection_object->ob != NULL &&
+ collection_object->ob->instance_collection == collection) {
+ id_us_min(&collection->id);
+ collection_object->ob->instance_collection = NULL;
+ cycles_found = true;
+ }
+ }
+
+ LISTBASE_FOREACH (CollectionChild *, collection_child, &parent_collection->children) {
+ if (collection_instance_fix_recursive(collection_child->collection, collection)) {
+ cycles_found = true;
+ }
+ }
+
+ return cycles_found;
+}
+
+static bool collection_cycle_fix_recursive(Main *bmain,
+ Collection *parent_collection,
+ Collection *collection)
+{
+ bool cycles_found = false;
+
+ LISTBASE_FOREACH_MUTABLE (CollectionParent *, parent, &parent_collection->parents) {
+ if (BKE_collection_cycle_find(parent->collection, collection)) {
+ BKE_collection_child_remove(bmain, parent->collection, parent_collection);
+ cycles_found = true;
+ }
+ else if (collection_cycle_fix_recursive(bmain, parent->collection, collection)) {
+ cycles_found = true;
+ }
+ }
+
+ return cycles_found;
+}
+
+/**
+ * Find and fix potential cycles in collections.
+ *
+ * \param collection the collection to check for existing cycles.
+ * \return true if cycles are found and fixed.
+ */
+bool BKE_collection_cycles_fix(Main *bmain, Collection *collection)
+{
+ return collection_cycle_fix_recursive(bmain, collection, collection) ||
+ collection_instance_fix_recursive(collection, collection);
}
static CollectionChild *collection_find_child(Collection *parent, Collection *collection)
@@ -1190,7 +1290,7 @@ static bool collection_child_add(Collection *parent,
if (child) {
return false;
}
- if (BKE_collection_find_cycle(parent, collection)) {
+ if (BKE_collection_cycle_find(parent, collection)) {
return false;
}
@@ -1268,7 +1368,7 @@ void BKE_collection_parent_relations_rebuild(Collection *collection)
child = child_next) {
child_next = child->next;
- if (child->collection == NULL || BKE_collection_find_cycle(collection, child->collection)) {
+ if (child->collection == NULL || BKE_collection_cycle_find(collection, child->collection)) {
BLI_freelinkN(&collection->children, child);
}
else {
@@ -1431,7 +1531,7 @@ bool BKE_collection_move(Main *bmain,
if (collection->flag & COLLECTION_IS_MASTER) {
return false;
}
- if (BKE_collection_find_cycle(to_parent, collection)) {
+ if (BKE_collection_cycle_find(to_parent, collection)) {
return false;
}
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index daf1602319f..31d49dd4508 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -32,7 +32,7 @@
#include "DNA_scene_types.h"
#include "BLI_blenlib.h"
-#include "BLI_ghash.h"
+#include "BLI_edgehash.h"
#include "BLI_linklist.h"
#include "BLI_math.h"
#include "BLI_task.h"
@@ -1153,17 +1153,7 @@ static bool cloth_bvh_selfcollision_is_active(const Cloth *cloth,
}
if (sewing_active) {
- unsigned int vertex_index_pair[2];
- /* The indices pair are ordered, thus must ensure the same here as well */
- if (tri_a->tri[i] < tri_b->tri[j]) {
- vertex_index_pair[0] = tri_a->tri[i];
- vertex_index_pair[1] = tri_b->tri[j];
- }
- else {
- vertex_index_pair[0] = tri_b->tri[j];
- vertex_index_pair[1] = tri_a->tri[i];
- }
- if (BLI_ghash_haskey(cloth->sew_edge_graph, vertex_index_pair)) {
+ if (BLI_edgeset_haskey(cloth->sew_edge_graph, tri_a->tri[i], tri_b->tri[j])) {
return false;
}
}
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index 4f4eb8f9f9d..fc326ffb390 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -1202,7 +1202,7 @@ int BKE_curvemapping_RGBA_does_something(const CurveMapping *cumap)
return 0;
}
-void BKE_curvemapping_initialize(CurveMapping *cumap)
+void BKE_curvemapping_init(CurveMapping *cumap)
{
int a;
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 06c28776840..2ef32895db9 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -53,6 +53,7 @@
#include "BKE_action.h"
#include "BKE_anim_path.h"
+#include "BKE_animsys.h"
#include "BKE_armature.h"
#include "BKE_bvhutils.h"
#include "BKE_cachefile.h"
@@ -2625,7 +2626,7 @@ static void actcon_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
}
}
-static void actcon_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
+static void actcon_get_tarmat(struct Depsgraph *depsgraph,
bConstraint *con,
bConstraintOb *cob,
bConstraintTarget *ct,
@@ -2679,6 +2680,8 @@ static void actcon_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
s = (vec[axis] - data->min) / (data->max - data->min);
CLAMP(s, 0, 1);
t = (s * (data->end - data->start)) + data->start;
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ t);
if (G.debug & G_DEBUG) {
printf("do Action Constraint %s - Ob %s Pchan %s\n",
@@ -2693,7 +2696,7 @@ static void actcon_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
/* evaluate using workob */
/* FIXME: we don't have any consistent standards on limiting effects on object... */
- what_does_obaction(cob->ob, &workob, NULL, data->act, NULL, t);
+ what_does_obaction(cob->ob, &workob, NULL, data->act, NULL, &anim_eval_context);
BKE_object_to_mat4(&workob, ct->matrix);
}
else if (cob->type == CONSTRAINT_OBTYPE_BONE) {
@@ -2710,7 +2713,7 @@ static void actcon_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
tchan->rotmode = pchan->rotmode;
/* evaluate action using workob (it will only set the PoseChannel in question) */
- what_does_obaction(cob->ob, &workob, &pose, data->act, pchan->name, t);
+ what_does_obaction(cob->ob, &workob, &pose, data->act, pchan->name, &anim_eval_context);
/* convert animation to matrices for use here */
BKE_pchan_calc_mat(tchan);
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index 8de12139306..30f021b0e81 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -694,6 +694,11 @@ wmWindowManager *CTX_wm_manager(const bContext *C)
return C->wm.manager;
}
+bool CTX_wm_interface_locked(const bContext *C)
+{
+ return (bool)C->wm.manager->is_interface_locked;
+}
+
wmWindow *CTX_wm_window(const bContext *C)
{
return ctx_wm_python_context_get(C, "window", &RNA_Window, C->wm.window);
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 6b28297622c..e126fb7f632 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -223,7 +223,7 @@ void BKE_curve_init(Curve *cu, const short curve_type)
cu->vfont->id.us += 4;
cu->str = MEM_malloc_arrayN(12, sizeof(unsigned char), "str");
BLI_strncpy(cu->str, "Text", 12);
- cu->len = cu->len_wchar = cu->pos = 4;
+ cu->len = cu->len_char32 = cu->pos = 4;
cu->strinfo = MEM_calloc_arrayN(12, sizeof(CharInfo), "strinfo new");
cu->totbox = cu->actbox = 1;
cu->tb = MEM_calloc_arrayN(MAXTEXTBOX, sizeof(TextBox), "textbox");
@@ -1157,7 +1157,7 @@ void BKE_nurb_knot_calc_v(Nurb *nu)
}
static void basisNurb(
- float t, short order, int pnts, float *knots, float *basis, int *start, int *end)
+ float t, short order, int pnts, const float *knots, float *basis, int *start, int *end)
{
float d, e;
int i, i1 = 0, i2 = 0, j, orderpluspnts, opp2, o2;
@@ -1190,9 +1190,8 @@ static void basisNurb(
}
break;
}
- else {
- basis[i] = 0.0;
- }
+
+ basis[i] = 0.0;
}
basis[i] = 0.0;
@@ -1727,205 +1726,6 @@ static void forward_diff_bezier_cotangent(const float p0[3],
}
}
-/* ***************** BEVEL ****************** */
-
-void BKE_curve_bevel_make(Object *ob, ListBase *disp)
-{
- DispList *dl, *dlnew;
- Curve *bevcu, *cu;
- float *fp, facx, facy, angle, dangle;
- int nr, a;
-
- cu = ob->data;
- BLI_listbase_clear(disp);
-
- /* if a font object is being edited, then do nothing */
- // XXX if ( ob == obedit && ob->type == OB_FONT ) return;
-
- if (cu->bevobj) {
- if (cu->bevobj->type != OB_CURVE) {
- return;
- }
-
- bevcu = cu->bevobj->data;
- if (bevcu->ext1 == 0.0f && bevcu->ext2 == 0.0f) {
- ListBase bevdisp = {NULL, NULL};
- facx = cu->bevobj->scale[0];
- facy = cu->bevobj->scale[1];
-
- if (cu->bevobj->runtime.curve_cache) {
- dl = cu->bevobj->runtime.curve_cache->disp.first;
- }
- else {
- BLI_assert(cu->bevobj->runtime.curve_cache != NULL);
- dl = NULL;
- }
-
- while (dl) {
- if (ELEM(dl->type, DL_POLY, DL_SEGM)) {
- dlnew = MEM_mallocN(sizeof(DispList), "makebevelcurve1");
- *dlnew = *dl;
- dlnew->verts = MEM_malloc_arrayN(
- dl->parts * dl->nr, 3 * sizeof(float), "makebevelcurve1");
- memcpy(dlnew->verts, dl->verts, 3 * sizeof(float) * dl->parts * dl->nr);
-
- if (dlnew->type == DL_SEGM) {
- dlnew->flag |= (DL_FRONT_CURVE | DL_BACK_CURVE);
- }
-
- BLI_addtail(disp, dlnew);
- fp = dlnew->verts;
- nr = dlnew->parts * dlnew->nr;
- while (nr--) {
- fp[2] = fp[1] * facy;
- fp[1] = -fp[0] * facx;
- fp[0] = 0.0;
- fp += 3;
- }
- }
- dl = dl->next;
- }
-
- BKE_displist_free(&bevdisp);
- }
- }
- else if (cu->ext1 == 0.0f && cu->ext2 == 0.0f) {
- /* pass */
- }
- else if (cu->ext2 == 0.0f) {
- dl = MEM_callocN(sizeof(DispList), "makebevelcurve2");
- dl->verts = MEM_malloc_arrayN(2, sizeof(float[3]), "makebevelcurve2");
- BLI_addtail(disp, dl);
- dl->type = DL_SEGM;
- dl->parts = 1;
- dl->flag = DL_FRONT_CURVE | DL_BACK_CURVE;
- dl->nr = 2;
-
- fp = dl->verts;
- fp[0] = fp[1] = 0.0;
- fp[2] = -cu->ext1;
- fp[3] = fp[4] = 0.0;
- fp[5] = cu->ext1;
- }
- else if ((cu->flag & (CU_FRONT | CU_BACK)) == 0 && cu->ext1 == 0.0f) {
- /* We make a full round bevel in that case. */
-
- nr = 4 + 2 * cu->bevresol;
-
- dl = MEM_callocN(sizeof(DispList), "makebevelcurve p1");
- dl->verts = MEM_malloc_arrayN(nr, sizeof(float[3]), "makebevelcurve p1");
- BLI_addtail(disp, dl);
- dl->type = DL_POLY;
- dl->parts = 1;
- dl->flag = DL_BACK_CURVE;
- dl->nr = nr;
-
- /* a circle */
- fp = dl->verts;
- dangle = (2.0f * (float)M_PI / (nr));
- angle = -(nr - 1) * dangle;
-
- for (a = 0; a < nr; a++) {
- fp[0] = 0.0;
- fp[1] = (cosf(angle) * (cu->ext2));
- fp[2] = (sinf(angle) * (cu->ext2)) - cu->ext1;
- angle += dangle;
- fp += 3;
- }
- }
- else {
- /* The general case for nonzero extrusion or an incomplete loop. */
- dl = MEM_callocN(sizeof(DispList), "makebevelcurve");
- if ((cu->flag & (CU_FRONT | CU_BACK)) == 0) {
- /* The full loop. */
- nr = 4 * cu->bevresol + 6;
- dl->flag = DL_FRONT_CURVE | DL_BACK_CURVE;
- }
- else if ((cu->flag & CU_FRONT) && (cu->flag & CU_BACK)) {
- /* Half the loop. */
- nr = 2 * (cu->bevresol + 1) + ((cu->ext1 == 0.0f) ? 1 : 2);
- dl->flag = DL_FRONT_CURVE | DL_BACK_CURVE;
- }
- else {
- /* One quarter of the loop (just front or back). */
- nr = (cu->ext1 == 0.0f) ? cu->bevresol + 2 : cu->bevresol + 3;
- dl->flag = (cu->flag & CU_FRONT) ? DL_FRONT_CURVE : DL_BACK_CURVE;
- }
-
- dl->verts = MEM_malloc_arrayN(nr, sizeof(float[3]), "makebevelcurve");
- BLI_addtail(disp, dl);
- /* Use a different type depending on whether the loop is complete or not. */
- dl->type = ((cu->flag & (CU_FRONT | CU_BACK)) == 0) ? DL_POLY : DL_SEGM;
- dl->parts = 1;
- dl->nr = nr;
-
- fp = dl->verts;
- dangle = (float)M_PI_2 / (cu->bevresol + 1);
- angle = 0.0;
-
- /* Build the back section. */
- if (cu->flag & CU_BACK || !(cu->flag & CU_FRONT)) {
- angle = (float)M_PI_2 * 3.0f;
- for (a = 0; a < cu->bevresol + 2; a++) {
- fp[0] = 0.0;
- fp[1] = (float)(cosf(angle) * (cu->ext2));
- fp[2] = (float)(sinf(angle) * (cu->ext2)) - cu->ext1;
- angle += dangle;
- fp += 3;
- }
- if ((cu->ext1 != 0.0f) && !(cu->flag & CU_FRONT) && (cu->flag & CU_BACK)) {
- /* Add the extrusion if we're only building the back. */
- fp[0] = 0.0;
- fp[1] = cu->ext2;
- fp[2] = cu->ext1;
- }
- }
-
- /* Build the front section. */
- if (cu->flag & CU_FRONT || !(cu->flag & CU_BACK)) {
- if ((cu->ext1 != 0.0f) && !(cu->flag & CU_BACK) && (cu->flag & CU_FRONT)) {
- /* Add the extrusion if we're only building the back. */
- fp[0] = 0.0;
- fp[1] = cu->ext2;
- fp[2] = -cu->ext1;
- fp += 3;
- }
- /* Don't duplicate the last back vertex. */
- angle = (cu->ext1 == 0.0f && (cu->flag & CU_BACK)) ? dangle : 0;
- int front_len = (cu->ext1 == 0.0f && ((cu->flag & CU_BACK) || !(cu->flag & CU_FRONT))) ?
- cu->bevresol + 1 :
- cu->bevresol + 2;
- for (a = 0; a < front_len; a++) {
- fp[0] = 0.0;
- fp[1] = (float)(cosf(angle) * (cu->ext2));
- fp[2] = (float)(sinf(angle) * (cu->ext2)) + cu->ext1;
- angle += dangle;
- fp += 3;
- }
- }
-
- /* Build the other half only if we're building the full loop. */
- if (!(cu->flag & (CU_FRONT | CU_BACK))) {
- for (a = 0; a < cu->bevresol + 1; a++) {
- fp[0] = 0.0;
- fp[1] = (float)(cosf(angle) * (cu->ext2));
- fp[2] = (float)(sinf(angle) * (cu->ext2)) + cu->ext1;
- angle += dangle;
- fp += 3;
- }
-
- angle = (float)M_PI;
- for (a = 0; a < cu->bevresol + 1; a++) {
- fp[0] = 0.0;
- fp[1] = (float)(cosf(angle) * (cu->ext2));
- fp[2] = (float)(sinf(angle) * (cu->ext2)) - cu->ext1;
- angle += dangle;
- fp += 3;
- }
- }
- }
-}
-
static int cu_isectLL(const float v1[3],
const float v2[3],
const float v3[3],
@@ -2040,7 +1840,7 @@ static int vergxcobev(const void *a1, const void *a2)
if (x1->left > x2->left) {
return 1;
}
- else if (x1->left < x2->left) {
+ if (x1->left < x2->left) {
return -1;
}
return 0;
@@ -3113,8 +2913,9 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
if (bl->poly > 0) {
BevPoint *bevp;
- min = 300000.0;
bevp = bl->bevpoints;
+ bevp1 = bl->bevpoints;
+ min = bevp1->vec[0];
nr = bl->nr;
while (nr--) {
if (min > bevp->vec[0]) {
@@ -3561,8 +3362,13 @@ static void free_arrays(void *buffer)
}
/* computes in which direction to change h[i] to satisfy conditions better */
-static float bezier_relax_direction(
- float *a, float *b, float *c, float *d, float *h, int i, int count)
+static float bezier_relax_direction(const float *a,
+ const float *b,
+ const float *c,
+ const float *d,
+ const float *h,
+ int i,
+ int count)
{
/* current deviation between sides of the equation */
float state = a[i] * h[(i + count - 1) % count] + b[i] * h[i] + c[i] * h[(i + 1) % count] - d[i];
@@ -3578,8 +3384,15 @@ static void bezier_lock_unknown(float *a, float *b, float *c, float *d, int i, f
d[i] = value;
}
-static void bezier_restore_equation(
- float *a, float *b, float *c, float *d, float *a0, float *b0, float *c0, float *d0, int i)
+static void bezier_restore_equation(float *a,
+ float *b,
+ float *c,
+ float *d,
+ const float *a0,
+ const float *b0,
+ const float *c0,
+ const float *d0,
+ int i)
{
a[i] = a0[i];
b[i] = b0[i];
@@ -3587,8 +3400,14 @@ static void bezier_restore_equation(
d[i] = d0[i];
}
-static bool tridiagonal_solve_with_limits(
- float *a, float *b, float *c, float *d, float *h, float *hmin, float *hmax, int solve_count)
+static bool tridiagonal_solve_with_limits(float *a,
+ float *b,
+ float *c,
+ float *d,
+ float *h,
+ const float *hmin,
+ const float *hmax,
+ int solve_count)
{
float *a0, *b0, *c0, *d0;
float **arrays[] = {&a0, &b0, &c0, &d0, NULL};
@@ -3727,7 +3546,7 @@ static bool tridiagonal_solve_with_limits(
/* clang-format on */
static void bezier_eq_continuous(
- float *a, float *b, float *c, float *d, float *dy, float *l, int i)
+ float *a, float *b, float *c, float *d, const float *dy, const float *l, int i)
{
a[i] = l[i] * l[i];
b[i] = 2.0f * (l[i] + 1);
@@ -3736,7 +3555,7 @@ static void bezier_eq_continuous(
}
static void bezier_eq_noaccel_right(
- float *a, float *b, float *c, float *d, float *dy, float *l, int i)
+ float *a, float *b, float *c, float *d, const float *dy, const float *l, int i)
{
a[i] = 0.0f;
b[i] = 2.0f;
@@ -3745,7 +3564,7 @@ static void bezier_eq_noaccel_right(
}
static void bezier_eq_noaccel_left(
- float *a, float *b, float *c, float *d, float *dy, float *l, int i)
+ float *a, float *b, float *c, float *d, const float *dy, const float *l, int i)
{
a[i] = l[i] * l[i];
b[i] = 2.0f * l[i];
@@ -4612,7 +4431,7 @@ void BKE_nurb_direction_switch(Nurb *nu)
bp1++;
bp2--;
}
- /* If there're odd number of points no need to touch coord of middle one,
+ /* If there are odd number of points no need to touch coord of middle one,
* but still need to change it's tilt.
*/
if (nu->pntsu & 1) {
@@ -4824,7 +4643,7 @@ float (*BKE_curve_nurbs_key_vert_coords_alloc(ListBase *lb, float *key, int *r_v
return cos;
}
-void BKE_curve_nurbs_key_vert_tilts_apply(ListBase *lb, float *key)
+void BKE_curve_nurbs_key_vert_tilts_apply(ListBase *lb, const float *key)
{
Nurb *nu;
int i;
@@ -5064,32 +4883,31 @@ bool BKE_nurb_type_convert(Nurb *nu,
}
return false; /* conversion impossible */
}
- else {
- bezt = MEM_calloc_arrayN(nr, sizeof(BezTriple), "setsplinetype2");
- nu->bezt = bezt;
- a = nr;
- bp = nu->bp;
- while (a--) {
- copy_v3_v3(bezt->vec[0], bp->vec);
- bezt->f1 = bp->f1;
- bp++;
- copy_v3_v3(bezt->vec[1], bp->vec);
- bezt->f2 = bp->f1;
- bp++;
- copy_v3_v3(bezt->vec[2], bp->vec);
- bezt->f3 = bp->f1;
- bezt->radius = bp->radius;
- bezt->weight = bp->weight;
- bp++;
- bezt++;
- }
- MEM_freeN(nu->bp);
- nu->bp = NULL;
- MEM_freeN(nu->knotsu);
- nu->knotsu = NULL;
- nu->pntsu = nr;
- nu->type = CU_BEZIER;
+
+ bezt = MEM_calloc_arrayN(nr, sizeof(BezTriple), "setsplinetype2");
+ nu->bezt = bezt;
+ a = nr;
+ bp = nu->bp;
+ while (a--) {
+ copy_v3_v3(bezt->vec[0], bp->vec);
+ bezt->f1 = bp->f1;
+ bp++;
+ copy_v3_v3(bezt->vec[1], bp->vec);
+ bezt->f2 = bp->f1;
+ bp++;
+ copy_v3_v3(bezt->vec[2], bp->vec);
+ bezt->f3 = bp->f1;
+ bezt->radius = bp->radius;
+ bezt->weight = bp->weight;
+ bp++;
+ bezt++;
}
+ MEM_freeN(nu->bp);
+ nu->bp = NULL;
+ MEM_freeN(nu->knotsu);
+ nu->knotsu = NULL;
+ nu->pntsu = nr;
+ nu->type = CU_BEZIER;
}
}
@@ -5140,10 +4958,9 @@ int BKE_curve_nurb_vert_index_get(const Nurb *nu, const void *vert)
BLI_assert(ARRAY_HAS_ITEM((BezTriple *)vert, nu->bezt, nu->pntsu));
return (BezTriple *)vert - nu->bezt;
}
- else {
- BLI_assert(ARRAY_HAS_ITEM((BPoint *)vert, nu->bp, nu->pntsu * nu->pntsv));
- return (BPoint *)vert - nu->bp;
- }
+
+ BLI_assert(ARRAY_HAS_ITEM((BPoint *)vert, nu->bp, nu->pntsu * nu->pntsv));
+ return (BPoint *)vert - nu->bp;
}
/* Set active nurb and active vert for curve */
@@ -5293,8 +5110,11 @@ bool BKE_curve_center_bounds(Curve *cu, float cent[3])
return false;
}
-void BKE_curve_transform_ex(
- Curve *cu, float mat[4][4], const bool do_keys, const bool do_props, const float unit_scale)
+void BKE_curve_transform_ex(Curve *cu,
+ const float mat[4][4],
+ const bool do_keys,
+ const bool do_props,
+ const float unit_scale)
{
Nurb *nu;
BPoint *bp;
@@ -5357,13 +5177,13 @@ void BKE_curve_transform_ex(
}
}
-void BKE_curve_transform(Curve *cu, float mat[4][4], const bool do_keys, const bool do_props)
+void BKE_curve_transform(Curve *cu, const float mat[4][4], const bool do_keys, const bool do_props)
{
float unit_scale = mat4_to_scale(mat);
BKE_curve_transform_ex(cu, mat, do_keys, do_props, unit_scale);
}
-void BKE_curve_translate(Curve *cu, float offset[3], const bool do_keys)
+void BKE_curve_translate(Curve *cu, const float offset[3], const bool do_keys)
{
ListBase *nurb_lb = BKE_curve_nurbs_get(cu);
Nurb *nu;
@@ -5422,7 +5242,7 @@ void BKE_curve_material_index_remove(Curve *cu, int index)
if (curvetype == OB_FONT) {
struct CharInfo *info = cu->strinfo;
int i;
- for (i = cu->len_wchar - 1; i >= 0; i--, info++) {
+ for (i = cu->len_char32 - 1; i >= 0; i--, info++) {
if (info->mat_nr && info->mat_nr >= index) {
info->mat_nr--;
}
@@ -5446,7 +5266,7 @@ bool BKE_curve_material_index_used(Curve *cu, int index)
if (curvetype == OB_FONT) {
struct CharInfo *info = cu->strinfo;
int i;
- for (i = cu->len_wchar - 1; i >= 0; i--, info++) {
+ for (i = cu->len_char32 - 1; i >= 0; i--, info++) {
if (info->mat_nr == index) {
return true;
}
@@ -5472,7 +5292,7 @@ void BKE_curve_material_index_clear(Curve *cu)
if (curvetype == OB_FONT) {
struct CharInfo *info = cu->strinfo;
int i;
- for (i = cu->len_wchar - 1; i >= 0; i--, info++) {
+ for (i = cu->len_char32 - 1; i >= 0; i--, info++) {
info->mat_nr = 0;
}
}
@@ -5494,7 +5314,7 @@ bool BKE_curve_material_index_validate(Curve *cu)
CharInfo *info = cu->strinfo;
const int max_idx = max_ii(0, cu->totcol); /* OB_FONT use 1 as first mat index, not 0!!! */
int i;
- for (i = cu->len_wchar - 1; i >= 0; i--, info++) {
+ for (i = cu->len_char32 - 1; i >= 0; i--, info++) {
if (info->mat_nr > max_idx) {
info->mat_nr = 0;
is_valid = false;
@@ -5516,9 +5336,7 @@ bool BKE_curve_material_index_validate(Curve *cu)
DEG_id_tag_update(&cu->id, ID_RECALC_GEOMETRY);
return true;
}
- else {
- return false;
- }
+ return false;
}
void BKE_curve_material_remap(Curve *cu, const unsigned int *remap, unsigned int remap_len)
@@ -5544,7 +5362,7 @@ void BKE_curve_material_remap(Curve *cu, const unsigned int *remap, unsigned int
}
else {
strinfo = cu->strinfo;
- charinfo_len = cu->len_wchar;
+ charinfo_len = cu->len_char32;
}
for (i = 0; i <= charinfo_len; i++) {
diff --git a/source/blender/blenkernel/intern/curve_bevel.c b/source/blender/blenkernel/intern/curve_bevel.c
new file mode 100644
index 00000000000..7f23f0215cc
--- /dev/null
+++ b/source/blender/blenkernel/intern/curve_bevel.c
@@ -0,0 +1,272 @@
+/*
+ * 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.
+ */
+
+/** \file
+ * \ingroup bke
+ *
+ * Handle curve object data bevel options,
+ * both extruding
+ */
+
+#include <string.h>
+
+#include "BLI_listbase.h"
+#include "BLI_math_base.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_curve_types.h"
+#include "DNA_object_types.h"
+
+#include "BKE_curve.h"
+#include "BKE_displist.h"
+
+typedef enum CurveBevelFillType {
+ BACK = 0,
+ FRONT,
+ HALF,
+ FULL,
+} CurveBevelFillType;
+
+static CurveBevelFillType curve_bevel_get_fill_type(const Curve *curve)
+{
+ if (!(curve->flag & (CU_FRONT | CU_BACK))) {
+ return FULL;
+ }
+ if ((curve->flag & CU_FRONT) && (curve->flag & CU_BACK)) {
+ return HALF;
+ }
+
+ return (curve->flag & CU_FRONT) ? FRONT : BACK;
+}
+
+static void curve_bevel_make_extrude_and_fill(Curve *cu,
+ ListBase *disp,
+ const bool use_extrude,
+ const CurveBevelFillType fill_type)
+{
+ DispList *dl = MEM_callocN(sizeof(DispList), __func__);
+
+ int nr;
+ if (fill_type == FULL) {
+ /* The full loop. */
+ nr = 4 * cu->bevresol + 6;
+ dl->flag = DL_FRONT_CURVE | DL_BACK_CURVE;
+ }
+ else if (fill_type == HALF) {
+ /* Half the loop. */
+ nr = 2 * (cu->bevresol + 1) + (use_extrude ? 2 : 1);
+ dl->flag = DL_FRONT_CURVE | DL_BACK_CURVE;
+ }
+ else {
+ /* One quarter of the loop (just front or back). */
+ nr = use_extrude ? cu->bevresol + 3 : cu->bevresol + 2;
+ dl->flag = (fill_type == FRONT) ? DL_FRONT_CURVE : DL_BACK_CURVE;
+ }
+
+ dl->verts = MEM_malloc_arrayN(nr, sizeof(float[3]), __func__);
+ BLI_addtail(disp, dl);
+ /* Use a different type depending on whether the loop is complete or not. */
+ dl->type = (fill_type == FULL) ? DL_POLY : DL_SEGM;
+ dl->parts = 1;
+ dl->nr = nr;
+
+ float *fp = dl->verts;
+ const float dangle = (float)M_PI_2 / (cu->bevresol + 1);
+ float angle = 0.0f;
+
+ /* Build the back section. */
+ if (ELEM(fill_type, BACK, HALF, FULL)) {
+ angle = (float)M_PI_2 * 3.0f;
+ for (int i = 0; i < cu->bevresol + 2; i++) {
+ fp[0] = 0.0f;
+ fp[1] = (float)(cosf(angle) * (cu->ext2));
+ fp[2] = (float)(sinf(angle) * (cu->ext2)) - cu->ext1;
+ angle += dangle;
+ fp += 3;
+ }
+ if (use_extrude && fill_type == BACK) {
+ /* Add the extrusion if we're only building the back. */
+ fp[0] = 0.0f;
+ fp[1] = cu->ext2;
+ fp[2] = cu->ext1;
+ }
+ }
+
+ /* Build the front section. */
+ if (ELEM(fill_type, FRONT, HALF, FULL)) {
+ if (use_extrude && fill_type == FRONT) {
+ /* Add the extrusion if we're only building the front. */
+ fp[0] = 0.0f;
+ fp[1] = cu->ext2;
+ fp[2] = -cu->ext1;
+ fp += 3;
+ }
+ /* Don't duplicate the last back vertex. */
+ angle = (!use_extrude && ELEM(fill_type, HALF, FULL)) ? dangle : 0;
+ int front_len = (!use_extrude && ELEM(fill_type, HALF, FULL)) ? cu->bevresol + 1 :
+ cu->bevresol + 2;
+ for (int i = 0; i < front_len; i++) {
+ fp[0] = 0.0f;
+ fp[1] = (float)(cosf(angle) * (cu->ext2));
+ fp[2] = (float)(sinf(angle) * (cu->ext2)) + cu->ext1;
+ angle += dangle;
+ fp += 3;
+ }
+ }
+
+ /* Build the other half only if we're building the full loop. */
+ if (fill_type == FULL) {
+ for (int i = 0; i < cu->bevresol + 1; i++) {
+ fp[0] = 0.0f;
+ fp[1] = (float)(cosf(angle) * (cu->ext2));
+ fp[2] = (float)(sinf(angle) * (cu->ext2)) + cu->ext1;
+ angle += dangle;
+ fp += 3;
+ }
+
+ angle = (float)M_PI;
+ for (int i = 0; i < cu->bevresol + 1; i++) {
+ fp[0] = 0.0f;
+ fp[1] = (float)(cosf(angle) * (cu->ext2));
+ fp[2] = (float)(sinf(angle) * (cu->ext2)) - cu->ext1;
+ angle += dangle;
+ fp += 3;
+ }
+ }
+}
+
+static void curve_bevel_make_full_circle(Curve *cu, ListBase *disp)
+{
+ const int nr = 4 + 2 * cu->bevresol;
+
+ DispList *dl = MEM_callocN(sizeof(DispList), __func__);
+ dl->verts = MEM_malloc_arrayN(nr, sizeof(float[3]), __func__);
+ BLI_addtail(disp, dl);
+ dl->type = DL_POLY;
+ dl->parts = 1;
+ dl->flag = DL_BACK_CURVE;
+ dl->nr = nr;
+
+ float *fp = dl->verts;
+ const float dangle = (2.0f * (float)M_PI / (nr));
+ float angle = -(nr - 1) * dangle;
+
+ for (int i = 0; i < nr; i++) {
+ fp[0] = 0.0;
+ fp[1] = (cosf(angle) * (cu->ext2));
+ fp[2] = (sinf(angle) * (cu->ext2)) - cu->ext1;
+ angle += dangle;
+ fp += 3;
+ }
+}
+
+static void curve_bevel_make_only_extrude(Curve *cu, ListBase *disp)
+{
+ DispList *dl = MEM_callocN(sizeof(DispList), __func__);
+ dl->verts = MEM_malloc_arrayN(2, sizeof(float[3]), __func__);
+ BLI_addtail(disp, dl);
+ dl->type = DL_SEGM;
+ dl->parts = 1;
+ dl->flag = DL_FRONT_CURVE | DL_BACK_CURVE;
+ dl->nr = 2;
+
+ float *fp = dl->verts;
+ fp[0] = fp[1] = 0.0;
+ fp[2] = -cu->ext1;
+ fp[3] = fp[4] = 0.0;
+ fp[5] = cu->ext1;
+}
+
+static void curve_bevel_make_from_object(Curve *cu, ListBase *disp)
+{
+ if (cu->bevobj->type != OB_CURVE) {
+ return;
+ }
+
+ Curve *bevcu = cu->bevobj->data;
+ if (bevcu->ext1 == 0.0f && bevcu->ext2 == 0.0f) {
+ ListBase bevdisp = {NULL, NULL};
+ float facx = cu->bevobj->scale[0];
+ float facy = cu->bevobj->scale[1];
+
+ DispList *dl;
+ if (cu->bevobj->runtime.curve_cache) {
+ dl = cu->bevobj->runtime.curve_cache->disp.first;
+ }
+ else {
+ BLI_assert(cu->bevobj->runtime.curve_cache != NULL);
+ dl = NULL;
+ }
+
+ while (dl) {
+ if (ELEM(dl->type, DL_POLY, DL_SEGM)) {
+ DispList *dlnew = MEM_mallocN(sizeof(DispList), __func__);
+ *dlnew = *dl;
+ dlnew->verts = MEM_malloc_arrayN(dl->parts * dl->nr, 3 * sizeof(float), __func__);
+ memcpy(dlnew->verts, dl->verts, 3 * sizeof(float) * dl->parts * dl->nr);
+
+ if (dlnew->type == DL_SEGM) {
+ dlnew->flag |= (DL_FRONT_CURVE | DL_BACK_CURVE);
+ }
+
+ BLI_addtail(disp, dlnew);
+ float *fp = dlnew->verts;
+ int nr = dlnew->parts * dlnew->nr;
+ while (nr--) {
+ fp[2] = fp[1] * facy;
+ fp[1] = -fp[0] * facx;
+ fp[0] = 0.0;
+ fp += 3;
+ }
+ }
+ dl = dl->next;
+ }
+
+ BKE_displist_free(&bevdisp);
+ }
+}
+
+void BKE_curve_bevel_make(Object *ob, ListBase *disp)
+{
+ Curve *curve = ob->data;
+
+ const bool use_extrude = curve->ext1 != 0.0f;
+ const bool use_bevel = curve->ext2 != 0.0f;
+
+ BLI_listbase_clear(disp);
+
+ if (curve->bevobj) {
+ curve_bevel_make_from_object(curve, disp);
+ }
+ else if (!(use_extrude || use_bevel)) {
+ /* Pass. */
+ }
+ else if (use_extrude && !use_bevel) {
+ curve_bevel_make_only_extrude(curve, disp);
+ }
+ else {
+ CurveBevelFillType fill_type = curve_bevel_get_fill_type(curve);
+
+ if (!use_extrude && fill_type == FULL) {
+ curve_bevel_make_full_circle(curve, disp);
+ }
+ else {
+ /* The general case for nonzero extrusion or an incomplete loop. */
+ curve_bevel_make_extrude_and_fill(curve, disp, use_extrude, fill_type);
+ }
+ }
+}
diff --git a/source/blender/blenkernel/intern/curveprofile.c b/source/blender/blenkernel/intern/curveprofile.c
index 6919d4fa10f..0a41529aac1 100644
--- a/source/blender/blenkernel/intern/curveprofile.c
+++ b/source/blender/blenkernel/intern/curveprofile.c
@@ -886,7 +886,7 @@ void BKE_curveprofile_create_samples(CurveProfile *profile,
*/
static void curveprofile_make_table(CurveProfile *profile)
{
- int n_samples = PROF_N_TABLE(profile->path_len);
+ int n_samples = PROF_TABLE_LEN(profile->path_len);
CurveProfilePoint *new_table = MEM_callocN(sizeof(CurveProfilePoint) * (n_samples + 1),
"high-res table");
@@ -1040,7 +1040,7 @@ void BKE_curveprofile_update(CurveProfile *profile, const int update_flags)
* Also sets the number of segments used for the display preview of the locations
* of the sampled points.
*/
-void BKE_curveprofile_initialize(CurveProfile *profile, short segments_len)
+void BKE_curveprofile_init(CurveProfile *profile, short segments_len)
{
if (segments_len != profile->segments_len) {
profile->flag |= PROF_DIRTY_PRESET;
@@ -1055,11 +1055,11 @@ void BKE_curveprofile_initialize(CurveProfile *profile, short segments_len)
* Gives the distance to the next point in the widgets sampled table, in other words the length
* of the \a 'i' edge of the table.
*
- * \note Requires curveprofile_initialize or #BKE_curveprofile_update call before to fill table.
+ * \note Requires #BKE_curveprofile_init or #BKE_curveprofile_update call before to fill table.
*/
static float curveprofile_distance_to_next_table_point(const CurveProfile *profile, int i)
{
- BLI_assert(i < PROF_N_TABLE(profile->path_len));
+ BLI_assert(i < PROF_TABLE_LEN(profile->path_len));
return len_v2v2(&profile->table[i].x, &profile->table[i + 1].x);
}
@@ -1067,12 +1067,12 @@ static float curveprofile_distance_to_next_table_point(const CurveProfile *profi
/**
* Calculates the total length of the profile from the curves sampled in the table.
*
- * \note Requires curveprofile_initialize or #BKE_curveprofile_update call before to fill table.
+ * \note Requires #BKE_curveprofile_init or #BKE_curveprofile_update call before to fill table.
*/
float BKE_curveprofile_total_length(const CurveProfile *profile)
{
float total_length = 0;
- for (int i = 0; i < PROF_N_TABLE(profile->path_len) - 1; i++) {
+ for (int i = 0; i < PROF_TABLE_LEN(profile->path_len) - 1; i++) {
total_length += len_v2v2(&profile->table[i].x, &profile->table[i + 1].x);
}
return total_length;
@@ -1082,7 +1082,7 @@ float BKE_curveprofile_total_length(const CurveProfile *profile)
* Samples evenly spaced positions along the curve profile's table (generated from path). Fills
* an entire table at once for a speedup if all of the results are going to be used anyway.
*
- * \note Requires curveprofile_initialize or #BKE_curveprofile_update call before to fill table.
+ * \note Requires #BKE_curveprofile_init or #BKE_curveprofile_update call before to fill table.
* \note Working, but would conflict with "Sample Straight Edges" option, so this is unused for
* now.
*/
@@ -1145,7 +1145,7 @@ void BKE_curveprofile_create_samples_even_spacing(CurveProfile *profile,
* Travels down (length_portion * path) length and returns the position at that point.
*
* \param length_portion: The portion (0 to 1) of the path's full length to sample at.
- * \note Requires curveprofile_initialize or #BKE_curveprofile_update call before to fill table.
+ * \note Requires #BKE_curveprofile_init or #BKE_curveprofile_update call before to fill table.
*/
void BKE_curveprofile_evaluate_length_portion(const CurveProfile *profile,
float length_portion,
@@ -1160,7 +1160,7 @@ void BKE_curveprofile_evaluate_length_portion(const CurveProfile *profile,
float length_travelled = 0.0f;
while (length_travelled < requested_length) {
/* Check if we reached the last point before the final one. */
- if (i == PROF_N_TABLE(profile->path_len) - 2) {
+ if (i == PROF_TABLE_LEN(profile->path_len) - 2) {
break;
}
float new_length = curveprofile_distance_to_next_table_point(profile, i);
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 2be61239ac6..7ddb0a6862d 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -300,7 +300,7 @@ static void layerInterp_mdeformvert(const void **sources,
/* now we know how many unique deform weights there are, so realloc */
if (dvert->dw && (dvert->totweight == totweight)) {
- /* pass (fastpath if we don't need to realloc) */
+ /* pass (fast-path if we don't need to realloc). */
}
else {
if (dvert->dw) {
@@ -1464,6 +1464,102 @@ static int layerMaxNum_propcol(void)
return MAX_MCOL;
}
+static void layerInterp_propfloat3(
+ const void **sources, const float *weights, const float *sub_weights, int count, void *dest)
+{
+ vec3f result = {0.0f, 0.0f, 0.0f};
+ for (int i = 0; i < count; i++) {
+ float weight = weights ? weights[i] : 1.0f;
+ const vec3f *src = sources[i];
+ if (sub_weights) {
+ madd_v3_v3fl(&result.x, &src->x, sub_weights[i] * weight);
+ }
+ else {
+ madd_v3_v3fl(&result.x, &src->x, weight);
+ }
+ }
+ copy_v3_v3((float *)dest, &result.x);
+}
+
+static void layerMultiply_propfloat3(void *data, float fac)
+{
+ vec3f *vec = data;
+ vec->x *= fac;
+ vec->y *= fac;
+ vec->z *= fac;
+}
+
+static void layerAdd_propfloat3(void *data1, const void *data2)
+{
+ vec3f *vec1 = data1;
+ const vec3f *vec2 = data2;
+ vec1->x += vec2->x;
+ vec1->y += vec2->y;
+ vec1->z += vec2->z;
+}
+
+static bool layerValidate_propfloat3(void *data, const uint totitems, const bool do_fixes)
+{
+ float *values = data;
+ bool has_errors = false;
+ for (int i = 0; i < totitems * 3; i++) {
+ if (!isfinite(values[i])) {
+ if (do_fixes) {
+ values[i] = 0.0f;
+ }
+ has_errors = true;
+ }
+ }
+ return has_errors;
+}
+
+static void layerInterp_propfloat2(
+ const void **sources, const float *weights, const float *sub_weights, int count, void *dest)
+{
+ vec2f result = {0.0f, 0.0f};
+ for (int i = 0; i < count; i++) {
+ float weight = weights ? weights[i] : 1.0f;
+ const vec2f *src = sources[i];
+ if (sub_weights) {
+ madd_v2_v2fl(&result.x, &src->x, sub_weights[i] * weight);
+ }
+ else {
+ madd_v2_v2fl(&result.x, &src->x, weight);
+ }
+ }
+ copy_v2_v2((float *)dest, &result.x);
+}
+
+static void layerMultiply_propfloat2(void *data, float fac)
+{
+ vec2f *vec = data;
+ vec->x *= fac;
+ vec->y *= fac;
+}
+
+static void layerAdd_propfloat2(void *data1, const void *data2)
+{
+ vec2f *vec1 = data1;
+ const vec2f *vec2 = data2;
+ vec1->x += vec2->x;
+ vec1->y += vec2->y;
+}
+
+static bool layerValidate_propfloat2(void *data, const uint totitems, const bool do_fixes)
+{
+ float *values = data;
+ bool has_errors = false;
+ for (int i = 0; i < totitems * 2; i++) {
+ if (!isfinite(values[i])) {
+ if (do_fixes) {
+ values[i] = 0.0f;
+ }
+ has_errors = true;
+ }
+ }
+ return has_errors;
+}
+
static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
/* 0: CD_MVERT */
{sizeof(MVert), "MVert", 1, NULL, NULL, NULL, NULL, NULL, NULL},
@@ -1799,7 +1895,38 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
NULL,
NULL,
NULL,
- layerMaxNum_propcol}};
+ layerMaxNum_propcol},
+ /* 48: CD_PROP_FLOAT3 */
+ {sizeof(float[3]),
+ "vec3f",
+ 1,
+ N_("Float3"),
+ NULL,
+ NULL,
+ layerInterp_propfloat3,
+ NULL,
+ NULL,
+ layerValidate_propfloat3,
+ NULL,
+ layerMultiply_propfloat3,
+ NULL,
+ layerAdd_propfloat3},
+ /* 49: CD_PROP_FLOAT2 */
+ {sizeof(float[2]),
+ "vec2f",
+ 1,
+ N_("Float2"),
+ NULL,
+ NULL,
+ layerInterp_propfloat2,
+ NULL,
+ NULL,
+ layerValidate_propfloat2,
+ NULL,
+ layerMultiply_propfloat2,
+ NULL,
+ layerAdd_propfloat2},
+};
static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
/* 0-4 */ "CDMVert",
@@ -1852,6 +1979,8 @@ static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
"CDHairMapping",
"CDPoint",
"CDPropCol",
+ "CDPropFloat3",
+ "CDPropFloat2",
};
const CustomData_MeshMasks CD_MASK_BAREMESH = {
@@ -2514,11 +2643,13 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
}
if (alloctype == CD_DUPLICATE && layerdata) {
- if (typeInfo->copy) {
- typeInfo->copy(layerdata, newlayerdata, totelem);
- }
- else {
- memcpy(newlayerdata, layerdata, (size_t)totelem * typeInfo->size);
+ if (totelem > 0) {
+ if (typeInfo->copy) {
+ typeInfo->copy(layerdata, newlayerdata, totelem);
+ }
+ else {
+ memcpy(newlayerdata, layerdata, (size_t)totelem * typeInfo->size);
+ }
}
}
else if (alloctype == CD_DEFAULT) {
@@ -4440,6 +4571,32 @@ bool CustomData_layer_validate(CustomDataLayer *layer, const uint totitems, cons
return false;
}
+void CustomData_layers__print(CustomData *data)
+{
+ int i;
+ const CustomDataLayer *layer;
+
+ printf("{\n");
+
+ for (i = 0, layer = data->layers; i < data->totlayer; i++, layer++) {
+
+ const char *name = CustomData_layertype_name(layer->type);
+ const int size = CustomData_sizeof(layer->type);
+ const char *structname;
+ int structnum;
+ CustomData_file_write_info(layer->type, &structname, &structnum);
+ printf(" dict(name='%s', struct='%s', type=%d, ptr='%p', elem=%d, length=%d),\n",
+ name,
+ structname,
+ layer->type,
+ (const void *)layer->data,
+ size,
+ (int)(MEM_allocN_len(layer->data) / size));
+ }
+
+ printf("}\n");
+}
+
/****************************** External Files *******************************/
static void customdata_external_filename(char filename[FILE_MAX],
diff --git a/source/blender/blenkernel/intern/data_transfer.c b/source/blender/blenkernel/intern/data_transfer.c
index 48e0ee50d43..7bf87d0e639 100644
--- a/source/blender/blenkernel/intern/data_transfer.c
+++ b/source/blender/blenkernel/intern/data_transfer.c
@@ -43,6 +43,7 @@
#include "BKE_mesh_mapping.h"
#include "BKE_mesh_remap.h"
#include "BKE_mesh_runtime.h"
+#include "BKE_mesh_wrapper.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_object_deform.h"
@@ -562,7 +563,7 @@ static bool data_transfer_layersmapping_cdlayers_multisrc_to_dst(ListBase *r_map
CustomData *cd_dst,
const bool use_dupref_dst,
const int tolayers,
- bool *use_layers_src,
+ const bool *use_layers_src,
const int num_layers_src,
cd_datatransfer_interp interp,
void *interp_data)
@@ -1467,6 +1468,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
if (!me_src) {
return changed;
}
+ BKE_mesh_wrapper_ensure_mdata(me_src);
if (auto_transform) {
if (space_transform == NULL) {
diff --git a/source/blender/blenkernel/intern/data_transfer_intern.h b/source/blender/blenkernel/intern/data_transfer_intern.h
index 68ded6e2bc4..c5d7dd42cb8 100644
--- a/source/blender/blenkernel/intern/data_transfer_intern.h
+++ b/source/blender/blenkernel/intern/data_transfer_intern.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __DATA_TRANSFER_INTERN_H__
-#define __DATA_TRANSFER_INTERN_H__
+#pragma once
#include "BKE_customdata.h" /* For cd_datatransfer_interp */
@@ -75,5 +74,3 @@ void customdata_data_transfer_interp_normal_normals(const CustomDataTransferLaye
const float *weights,
const int count,
const float mix_factor);
-
-#endif /* __DATA_TRANSFER_INTERN_H__ */
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index b97935d57f2..98fc5f9a23a 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -249,7 +249,7 @@ void BKE_defvert_sync_mapped(MDeformVert *dvert_dst,
/**
* be sure all flip_map values are valid
*/
-void BKE_defvert_remap(MDeformVert *dvert, int *map, const int map_len)
+void BKE_defvert_remap(MDeformVert *dvert, const int *map, const int map_len)
{
MDeformWeight *dw = dvert->dw;
unsigned int i;
@@ -1184,7 +1184,7 @@ static bool data_transfer_layersmapping_vgroups_multisrc_to_dst(ListBase *r_map,
CustomData *cd_dst,
const bool UNUSED(use_dupref_dst),
const int tolayers,
- bool *use_layers_src,
+ const bool *use_layers_src,
const int num_layers_src)
{
int idx_src;
diff --git a/source/blender/blenkernel/intern/derived_node_tree.cc b/source/blender/blenkernel/intern/derived_node_tree.cc
deleted file mode 100644
index 01317eeb5ce..00000000000
--- a/source/blender/blenkernel/intern/derived_node_tree.cc
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * 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.
- */
-
-#include "BKE_derived_node_tree.hh"
-
-#include "BLI_dot_export.hh"
-
-#define UNINITIALIZED_ID UINT32_MAX
-
-namespace blender::bke {
-
-static const NodeTreeRef &get_tree_ref(NodeTreeRefMap &node_tree_refs, bNodeTree *btree)
-{
- return *node_tree_refs.lookup_or_add_cb(btree,
- [&]() { return std::make_unique<NodeTreeRef>(btree); });
-}
-
-DerivedNodeTree::DerivedNodeTree(bNodeTree *btree, NodeTreeRefMap &node_tree_refs) : btree_(btree)
-{
- const NodeTreeRef &main_tree_ref = get_tree_ref(node_tree_refs, btree);
-
- Vector<DNode *> all_nodes;
- Vector<DGroupInput *> all_group_inputs;
- Vector<DParentNode *> all_parent_nodes;
-
- this->insert_nodes_and_links_in_id_order(main_tree_ref, nullptr, all_nodes);
- this->expand_groups(all_nodes, all_group_inputs, all_parent_nodes, node_tree_refs);
- this->remove_expanded_group_interfaces(all_nodes);
- this->remove_unused_group_inputs(all_group_inputs);
- this->store_in_this_and_init_ids(
- std::move(all_nodes), std::move(all_group_inputs), std::move(all_parent_nodes));
-}
-
-BLI_NOINLINE void DerivedNodeTree::insert_nodes_and_links_in_id_order(const NodeTreeRef &tree_ref,
- DParentNode *parent,
- Vector<DNode *> &all_nodes)
-{
- Array<DSocket *, 64> sockets_map(tree_ref.sockets().size());
-
- /* Insert nodes. */
- for (const NodeRef *node_ref : tree_ref.nodes()) {
- DNode &node = this->create_node(*node_ref, parent, sockets_map);
- all_nodes.append(&node);
- }
-
- /* Insert links. */
- for (const NodeRef *node_ref : tree_ref.nodes()) {
- for (const InputSocketRef *to_socket_ref : node_ref->inputs()) {
- DInputSocket *to_socket = (DInputSocket *)sockets_map[to_socket_ref->id()];
- for (const OutputSocketRef *from_socket_ref : to_socket_ref->linked_sockets()) {
- DOutputSocket *from_socket = (DOutputSocket *)sockets_map[from_socket_ref->id()];
- to_socket->linked_sockets_.append(from_socket);
- from_socket->linked_sockets_.append(to_socket);
- }
- }
- }
-}
-
-DNode &DerivedNodeTree::create_node(const NodeRef &node_ref,
- DParentNode *parent,
- MutableSpan<DSocket *> r_sockets_map)
-{
- DNode &node = *allocator_.construct<DNode>();
- node.node_ref_ = &node_ref;
- node.parent_ = parent;
- node.id_ = UNINITIALIZED_ID;
-
- node.inputs_ = allocator_.construct_elements_and_pointer_array<DInputSocket>(
- node_ref.inputs().size());
- node.outputs_ = allocator_.construct_elements_and_pointer_array<DOutputSocket>(
- node_ref.outputs().size());
-
- for (uint i : node.inputs_.index_range()) {
- const InputSocketRef &socket_ref = node_ref.input(i);
- DInputSocket &socket = *node.inputs_[i];
-
- socket.id_ = UNINITIALIZED_ID;
- socket.node_ = &node;
- socket.socket_ref_ = &socket_ref;
-
- r_sockets_map[socket_ref.id()] = &socket;
- }
-
- for (uint i : node.outputs_.index_range()) {
- const OutputSocketRef &socket_ref = node_ref.output(i);
- DOutputSocket &socket = *node.outputs_[i];
-
- socket.id_ = UNINITIALIZED_ID;
- socket.node_ = &node;
- socket.socket_ref_ = &socket_ref;
-
- r_sockets_map[socket_ref.id()] = &socket;
- }
-
- return node;
-}
-
-BLI_NOINLINE void DerivedNodeTree::expand_groups(Vector<DNode *> &all_nodes,
- Vector<DGroupInput *> &all_group_inputs,
- Vector<DParentNode *> &all_parent_nodes,
- NodeTreeRefMap &node_tree_refs)
-{
- for (uint i = 0; i < all_nodes.size(); i++) {
- DNode &node = *all_nodes[i];
- if (node.node_ref_->is_group_node()) {
- this->expand_group_node(node, all_nodes, all_group_inputs, all_parent_nodes, node_tree_refs);
- }
- }
-}
-
-BLI_NOINLINE void DerivedNodeTree::expand_group_node(DNode &group_node,
- Vector<DNode *> &all_nodes,
- Vector<DGroupInput *> &all_group_inputs,
- Vector<DParentNode *> &all_parent_nodes,
- NodeTreeRefMap &node_tree_refs)
-{
- const NodeRef &group_node_ref = *group_node.node_ref_;
- BLI_assert(group_node_ref.is_group_node());
-
- bNodeTree *btree = (bNodeTree *)group_node_ref.bnode()->id;
- if (btree == nullptr) {
- return;
- }
-
- const NodeTreeRef &group_ref = get_tree_ref(node_tree_refs, btree);
-
- DParentNode &parent = *allocator_.construct<DParentNode>();
- parent.id_ = all_parent_nodes.append_and_get_index(&parent);
- parent.parent_ = group_node.parent_;
- parent.node_ref_ = &group_node_ref;
-
- this->insert_nodes_and_links_in_id_order(group_ref, &parent, all_nodes);
- Span<DNode *> new_nodes_by_id = all_nodes.as_span().take_back(group_ref.nodes().size());
-
- this->create_group_inputs_for_unlinked_inputs(group_node, all_group_inputs);
- this->relink_group_inputs(group_ref, new_nodes_by_id, group_node);
- this->relink_group_outputs(group_ref, new_nodes_by_id, group_node);
-}
-
-BLI_NOINLINE void DerivedNodeTree::create_group_inputs_for_unlinked_inputs(
- DNode &node, Vector<DGroupInput *> &all_group_inputs)
-{
- for (DInputSocket *input_socket : node.inputs_) {
- if (input_socket->is_linked()) {
- continue;
- }
-
- DGroupInput &group_input = *allocator_.construct<DGroupInput>();
- group_input.id_ = UNINITIALIZED_ID;
- group_input.socket_ref_ = &input_socket->socket_ref();
- group_input.parent_ = node.parent_;
-
- group_input.linked_sockets_.append(input_socket);
- input_socket->linked_group_inputs_.append(&group_input);
- all_group_inputs.append(&group_input);
- }
-}
-
-BLI_NOINLINE void DerivedNodeTree::relink_group_inputs(const NodeTreeRef &group_ref,
- Span<DNode *> nodes_by_id,
- DNode &group_node)
-{
- Span<const NodeRef *> node_refs = group_ref.nodes_by_type("NodeGroupInput");
- if (node_refs.size() == 0) {
- return;
- }
- /* TODO: Pick correct group input node if there are more than one. */
- const NodeRef &input_node_ref = *node_refs[0];
- DNode &input_node = *nodes_by_id[input_node_ref.id()];
-
- uint input_amount = group_node.inputs().size();
- BLI_assert(input_amount == input_node_ref.outputs().size() - 1);
-
- for (uint input_index : IndexRange(input_amount)) {
- DInputSocket *outside_group = group_node.inputs_[input_index];
- DOutputSocket *inside_group = input_node.outputs_[input_index];
-
- for (DOutputSocket *outside_connected : outside_group->linked_sockets_) {
- outside_connected->linked_sockets_.remove_first_occurrence_and_reorder(outside_group);
- }
-
- for (DGroupInput *outside_connected : outside_group->linked_group_inputs_) {
- outside_connected->linked_sockets_.remove_first_occurrence_and_reorder(outside_group);
- }
-
- for (DInputSocket *inside_connected : inside_group->linked_sockets_) {
- inside_connected->linked_sockets_.remove_first_occurrence_and_reorder(inside_group);
-
- for (DOutputSocket *outside_connected : outside_group->linked_sockets_) {
- inside_connected->linked_sockets_.append(outside_connected);
- outside_connected->linked_sockets_.append(inside_connected);
- }
-
- for (DGroupInput *outside_connected : outside_group->linked_group_inputs_) {
- inside_connected->linked_group_inputs_.append(outside_connected);
- outside_connected->linked_sockets_.append(inside_connected);
- }
- }
-
- inside_group->linked_sockets_.clear();
- outside_group->linked_sockets_.clear();
- outside_group->linked_group_inputs_.clear();
- }
-}
-
-BLI_NOINLINE void DerivedNodeTree::relink_group_outputs(const NodeTreeRef &group_ref,
- Span<DNode *> nodes_by_id,
- DNode &group_node)
-{
- Span<const NodeRef *> node_refs = group_ref.nodes_by_type("NodeGroupOutput");
- if (node_refs.size() == 0) {
- return;
- }
- /* TODO: Pick correct group output node if there are more than one. */
- const NodeRef &output_node_ref = *node_refs[0];
- DNode &output_node = *nodes_by_id[output_node_ref.id()];
-
- uint output_amount = group_node.outputs().size();
- BLI_assert(output_amount == output_node_ref.inputs().size() - 1);
-
- for (uint output_index : IndexRange(output_amount)) {
- DOutputSocket *outside_group = group_node.outputs_[output_index];
- DInputSocket *inside_group = output_node.inputs_[output_index];
-
- for (DInputSocket *outside_connected : outside_group->linked_sockets_) {
- outside_connected->linked_sockets_.remove_first_occurrence_and_reorder(outside_group);
- }
-
- for (DOutputSocket *inside_connected : inside_group->linked_sockets_) {
- inside_connected->linked_sockets_.remove_first_occurrence_and_reorder(inside_group);
-
- for (DInputSocket *outside_connected : outside_group->linked_sockets_) {
- inside_connected->linked_sockets_.append(outside_connected);
- outside_connected->linked_sockets_.append(inside_connected);
- }
- }
-
- for (DGroupInput *inside_connected : inside_group->linked_group_inputs_) {
- inside_connected->linked_sockets_.remove_first_occurrence_and_reorder(inside_group);
-
- for (DInputSocket *outside_connected : outside_group->linked_sockets_) {
- inside_connected->linked_sockets_.append(outside_connected);
- outside_connected->linked_group_inputs_.append(inside_connected);
- }
- }
-
- outside_group->linked_sockets_.clear();
- inside_group->linked_sockets_.clear();
- }
-}
-
-BLI_NOINLINE void DerivedNodeTree::remove_expanded_group_interfaces(Vector<DNode *> &all_nodes)
-{
- int index = 0;
- while (index < all_nodes.size()) {
- DNode &node = *all_nodes[index];
- const NodeRef &node_ref = *node.node_ref_;
- if (node_ref.is_group_node() ||
- (node.parent_ != nullptr &&
- (node_ref.is_group_input_node() || node_ref.is_group_output_node()))) {
- all_nodes.remove_and_reorder(index);
- node.destruct_with_sockets();
- }
- else {
- index++;
- }
- }
-}
-
-BLI_NOINLINE void DerivedNodeTree::remove_unused_group_inputs(
- Vector<DGroupInput *> &all_group_inputs)
-{
- int index = 0;
- while (index < all_group_inputs.size()) {
- DGroupInput &group_input = *all_group_inputs[index];
- if (group_input.linked_sockets_.is_empty()) {
- all_group_inputs.remove_and_reorder(index);
- group_input.~DGroupInput();
- }
- else {
- index++;
- }
- }
-}
-
-void DNode::destruct_with_sockets()
-{
- for (DInputSocket *socket : inputs_) {
- socket->~DInputSocket();
- }
- for (DOutputSocket *socket : outputs_) {
- socket->~DOutputSocket();
- }
- this->~DNode();
-}
-
-BLI_NOINLINE void DerivedNodeTree::store_in_this_and_init_ids(
- Vector<DNode *> &&all_nodes,
- Vector<DGroupInput *> &&all_group_inputs,
- Vector<DParentNode *> &&all_parent_nodes)
-{
- nodes_by_id_ = std::move(all_nodes);
- group_inputs_ = std::move(all_group_inputs);
- parent_nodes_ = std::move(all_parent_nodes);
-
- for (uint node_index : nodes_by_id_.index_range()) {
- DNode *node = nodes_by_id_[node_index];
- node->id_ = node_index;
-
- const bNodeType *nodetype = node->node_ref_->bnode()->typeinfo;
- nodes_by_type_.lookup_or_add_default(nodetype).append(node);
-
- for (DInputSocket *socket : node->inputs_) {
- socket->id_ = sockets_by_id_.append_and_get_index(socket);
- input_sockets_.append(socket);
- }
- for (DOutputSocket *socket : node->outputs_) {
- socket->id_ = sockets_by_id_.append_and_get_index(socket);
- output_sockets_.append(socket);
- }
- }
-
- for (uint i : group_inputs_.index_range()) {
- group_inputs_[i]->id_ = i;
- }
-}
-
-DerivedNodeTree::~DerivedNodeTree()
-{
- for (DInputSocket *socket : input_sockets_) {
- socket->~DInputSocket();
- }
- for (DOutputSocket *socket : output_sockets_) {
- socket->~DOutputSocket();
- }
- for (DNode *node : nodes_by_id_) {
- node->~DNode();
- }
- for (DGroupInput *group_input : group_inputs_) {
- group_input->~DGroupInput();
- }
- for (DParentNode *parent : parent_nodes_) {
- parent->~DParentNode();
- }
-}
-
-static dot::Cluster *get_cluster_for_parent(dot::DirectedGraph &graph,
- Map<const DParentNode *, dot::Cluster *> &clusters,
- const DParentNode *parent)
-{
- if (parent == nullptr) {
- return nullptr;
- }
- return clusters.lookup_or_add_cb(parent, [&]() {
- dot::Cluster *parent_cluster = get_cluster_for_parent(graph, clusters, parent->parent());
- bNodeTree *btree = (bNodeTree *)parent->node_ref().bnode()->id;
- dot::Cluster *new_cluster = &graph.new_cluster(parent->node_ref().name() + " / " +
- StringRef(btree->id.name + 2));
- new_cluster->set_parent_cluster(parent_cluster);
- return new_cluster;
- });
-}
-
-std::string DerivedNodeTree::to_dot() const
-{
- dot::DirectedGraph digraph;
- digraph.set_rankdir(dot::Attr_rankdir::LeftToRight);
-
- Map<const DNode *, dot::NodeWithSocketsRef> dot_nodes;
- Map<const DGroupInput *, dot::NodeWithSocketsRef> dot_group_inputs;
- Map<const DParentNode *, dot::Cluster *> dot_clusters;
-
- for (const DNode *node : nodes_by_id_) {
- dot::Node &dot_node = digraph.new_node("");
- dot_node.set_background_color("white");
-
- Vector<std::string> input_names;
- for (const DInputSocket *socket : node->inputs()) {
- input_names.append(socket->name());
- }
- Vector<std::string> output_names;
- for (const DOutputSocket *socket : node->outputs()) {
- output_names.append(socket->name());
- }
-
- dot_nodes.add_new(node,
- dot::NodeWithSocketsRef(dot_node, node->name(), input_names, output_names));
-
- dot::Cluster *cluster = get_cluster_for_parent(digraph, dot_clusters, node->parent());
- dot_node.set_parent_cluster(cluster);
- }
-
- for (const DGroupInput *group_input : group_inputs_) {
- dot::Node &dot_node = digraph.new_node("");
- dot_node.set_background_color("white");
-
- std::string group_input_name = group_input->name();
- dot_group_inputs.add_new(
- group_input, dot::NodeWithSocketsRef(dot_node, "Group Input", {}, {group_input_name}));
-
- dot::Cluster *cluster = get_cluster_for_parent(digraph, dot_clusters, group_input->parent());
- dot_node.set_parent_cluster(cluster);
- }
-
- for (const DNode *to_node : nodes_by_id_) {
- dot::NodeWithSocketsRef &to_dot_node = dot_nodes.lookup(to_node);
-
- for (const DInputSocket *to_socket : to_node->inputs()) {
- for (const DOutputSocket *from_socket : to_socket->linked_sockets()) {
- const DNode *from_node = &from_socket->node();
- dot::NodeWithSocketsRef &from_dot_node = dot_nodes.lookup(from_node);
-
- digraph.new_edge(from_dot_node.output(from_socket->index()),
- to_dot_node.input(to_socket->index()));
- }
- for (const DGroupInput *group_input : to_socket->linked_group_inputs()) {
- dot::NodeWithSocketsRef &from_dot_node = dot_group_inputs.lookup(group_input);
-
- digraph.new_edge(from_dot_node.output(0), to_dot_node.input(to_socket->index()));
- }
- }
- }
-
- digraph.set_random_cluster_bgcolors();
- return digraph.to_dot_string();
-}
-
-} // namespace blender::bke
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 2e1fa519284..7b7b7ceb84b 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -588,7 +588,7 @@ static bool boundsIntersectDist(Bounds3D *b1, Bounds3D *b2, const float dist)
}
/* check whether bounds intersects a point with given radius */
-static bool boundIntersectPoint(Bounds3D *b, float point[3], const float radius)
+static bool boundIntersectPoint(Bounds3D *b, const float point[3], const float radius)
{
if (!b->valid) {
return false;
@@ -4203,7 +4203,7 @@ static void dynamic_paint_paint_mesh_cell_point_cb_ex(
brushVelocity[v3].v,
weights);
- /* substract canvas point velocity */
+ /* subtract canvas point velocity */
if (bData->velocity) {
sub_v3_v3v3(velocity, brushPointVelocity, bData->velocity[index].v);
}
@@ -4548,7 +4548,7 @@ static void dynamic_paint_paint_particle_cell_point_cb_ex(
ParticleData *pa = psys->particles + part_index;
mul_v3_v3fl(velocity, pa->state.vel, particle_timestep);
- /* substract canvas point velocity */
+ /* subtract canvas point velocity */
if (bData->velocity) {
sub_v3_v3(velocity, bData->velocity[index].v);
}
@@ -4739,7 +4739,7 @@ static void dynamic_paint_paint_single_point_cb_ex(void *__restrict userdata,
if (brush->flags & MOD_DPAINT_USES_VELOCITY) {
float velocity[3];
- /* substract canvas point velocity */
+ /* subtract canvas point velocity */
if (bData->velocity) {
sub_v3_v3v3(velocity, brushVelocity->v, bData->velocity[index].v);
}
@@ -4780,13 +4780,16 @@ static void dynamic_paint_paint_single_point_cb_ex(void *__restrict userdata,
}
}
-static int dynamicPaint_paintSinglePoint(Depsgraph *depsgraph,
- DynamicPaintSurface *surface,
- float *pointCoord,
- DynamicPaintBrushSettings *brush,
- Object *brushOb,
- Scene *scene,
- float timescale)
+static int dynamicPaint_paintSinglePoint(
+ Depsgraph *depsgraph,
+ DynamicPaintSurface *surface,
+ /* Cannot be const, because it is assigned to non-const variable.
+ * NOLINTNEXTLINE: readability-non-const-parameter. */
+ float *pointCoord,
+ DynamicPaintBrushSettings *brush,
+ Object *brushOb,
+ Scene *scene,
+ float timescale)
{
PaintSurfaceData *sData = surface->data;
float brush_radius = brush->paint_distance * surface->radius_scale;
@@ -5456,11 +5459,14 @@ static void dynamic_paint_effect_drip_cb(void *__restrict userdata,
}
}
-static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface,
- float *force,
- PaintPoint *prevPoint,
- float timescale,
- float steps)
+static void dynamicPaint_doEffectStep(
+ DynamicPaintSurface *surface,
+ /* Cannot be const, because it is assigned to non-const variable.
+ * NOLINTNEXTLINE: readability-non-const-parameter. */
+ float *force,
+ PaintPoint *prevPoint,
+ float timescale,
+ float steps)
{
PaintSurfaceData *sData = surface->data;
diff --git a/source/blender/blenkernel/intern/editmesh_tangent.c b/source/blender/blenkernel/intern/editmesh_tangent.c
index 6fcaf84d4ca..897fc7e692b 100644
--- a/source/blender/blenkernel/intern/editmesh_tangent.c
+++ b/source/blender/blenkernel/intern/editmesh_tangent.c
@@ -274,8 +274,8 @@ static void emDM_calc_loop_tangents_thread(TaskPool *__restrict UNUSED(pool), vo
/**
* \see #BKE_mesh_calc_loop_tangent, same logic but used arrays instead of #BMesh data.
*
- * \note This function is not so normal, its using `bm->ldata` as input,
- * but output's to `dm->loopData`.
+ * \note This function is not so normal, its using #BMesh.ldata as input,
+ * but output's to #Mesh.ldata.
* This is done because #CD_TANGENT is cache data used only for drawing.
*/
void BKE_editmesh_loop_tangent_calc(BMEditMesh *em,
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index 235c834fde9..a43553ee89f 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -1094,11 +1094,11 @@ void BKE_effectors_apply(ListBase *effectors,
* Modifies the force on a particle according to its
* relation with the effector object
* Different kind of effectors include:
- * Forcefields: Gravity-like attractor
+ * Force-fields: Gravity-like attractor
* (force power is related to the inverse of distance to the power of a falloff value)
* Vortex fields: swirling effectors
* (particles rotate around Z-axis of the object. otherwise, same relation as)
- * (Forcefields, but this is not done through a force/acceleration)
+ * (Force-fields, but this is not done through a force/acceleration)
* Guide: particles on a path
* (particles are guided along a curve bezier or old nurbs)
* (is independent of other effectors)
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index bc14f525c2c..acbbf50701a 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -1277,7 +1277,7 @@ short test_time_fcurve(FCurve *fcu)
* than the horizontal distance between (v1-v4).
* This is to prevent curve loops.
*/
-void correct_bezpart(float v1[2], float v2[2], float v3[2], float v4[2])
+void correct_bezpart(const float v1[2], float v2[2], float v3[2], const float v4[2])
{
float h1[2], h2[2], len1, len2, len, fac;
@@ -1872,17 +1872,18 @@ float evaluate_fcurve_only_curve(FCurve *fcu, float evaltime)
float evaluate_fcurve_driver(PathResolvedRNA *anim_rna,
FCurve *fcu,
ChannelDriver *driver_orig,
- float evaltime)
+ const AnimationEvalContext *anim_eval_context)
{
BLI_assert(fcu->driver != NULL);
float cvalue = 0.0f;
+ float evaltime = anim_eval_context->eval_time;
/* If there is a driver (only if this F-Curve is acting as 'driver'),
* evaluate it to find value to use as "evaltime" since drivers essentially act as alternative
* input (i.e. in place of 'time') for F-Curves. */
if (fcu->driver) {
/* evaltime now serves as input for the curve */
- evaltime = evaluate_driver(anim_rna, fcu->driver, driver_orig, evaltime);
+ evaltime = evaluate_driver(anim_rna, fcu->driver, driver_orig, anim_eval_context);
/* only do a default 1-1 mapping if it's unlikely that anything else will set a value... */
if (fcu->totvert == 0) {
@@ -1924,7 +1925,9 @@ bool BKE_fcurve_is_empty(FCurve *fcu)
}
/* Calculate the value of the given F-Curve at the given frame, and set its curval */
-float calculate_fcurve(PathResolvedRNA *anim_rna, FCurve *fcu, float evaltime)
+float calculate_fcurve(PathResolvedRNA *anim_rna,
+ FCurve *fcu,
+ const AnimationEvalContext *anim_eval_context)
{
/* only calculate + set curval (overriding the existing value) if curve has
* any data which warrants this...
@@ -1936,10 +1939,10 @@ float calculate_fcurve(PathResolvedRNA *anim_rna, FCurve *fcu, float evaltime)
/* calculate and set curval (evaluates driver too if necessary) */
float curval;
if (fcu->driver) {
- curval = evaluate_fcurve_driver(anim_rna, fcu, fcu->driver, evaltime);
+ curval = evaluate_fcurve_driver(anim_rna, fcu, fcu->driver, anim_eval_context);
}
else {
- curval = evaluate_fcurve(fcu, evaltime);
+ curval = evaluate_fcurve(fcu, anim_eval_context->eval_time);
}
fcu->curval = curval; /* debug display only, not thread safe! */
return curval;
diff --git a/source/blender/blenkernel/intern/fcurve_driver.c b/source/blender/blenkernel/intern/fcurve_driver.c
index a0625918a62..87cb77930f5 100644
--- a/source/blender/blenkernel/intern/fcurve_driver.c
+++ b/source/blender/blenkernel/intern/fcurve_driver.c
@@ -21,12 +21,6 @@
* \ingroup bke
*/
-// #include <float.h>
-// #include <math.h>
-// #include <stddef.h>
-// #include <stdio.h>
-// #include <string.h>
-
#include "MEM_guardedalloc.h"
#include "DNA_anim_types.h"
@@ -43,6 +37,7 @@
#include "BLT_translation.h"
#include "BKE_action.h"
+#include "BKE_animsys.h"
#include "BKE_armature.h"
#include "BKE_constraint.h"
#include "BKE_fcurve_driver.h"
@@ -65,17 +60,19 @@ static ThreadMutex python_driver_lock = BLI_MUTEX_INITIALIZER;
static CLG_LogRef LOG = {"bke.fcurve"};
-/* Driver Variables --------------------------- */
+/* -------------------------------------------------------------------- */
+/** \name Driver Variables
+ * \{ */
/* TypeInfo for Driver Variables (dvti) */
typedef struct DriverVarTypeInfo {
- /* evaluation callback */
+ /* Evaluation callback. */
float (*get_value)(ChannelDriver *driver, DriverVar *dvar);
- /* allocation of target slots */
- int num_targets; /* number of target slots required */
- const char *target_names[MAX_DRIVER_TARGETS]; /* UI names that should be given to the slots */
- short target_flags[MAX_DRIVER_TARGETS]; /* flags defining the requirements for each slot */
+ /* Allocation of target slots. */
+ int num_targets; /* Number of target slots required. */
+ const char *target_names[MAX_DRIVER_TARGETS]; /* UI names that should be given to the slots. */
+ short target_flags[MAX_DRIVER_TARGETS]; /* Flags defining the requirements for each slot. */
} DriverVarTypeInfo;
/* Macro to begin definitions */
@@ -84,7 +81,11 @@ typedef struct DriverVarTypeInfo {
/* Macro to end definitions */
#define END_DVAR_TYPEDEF }
-/* ......... */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Driver Target Utilities
+ * \{ */
static ID *dtar_id_ensure_proxy_from(ID *id)
{
@@ -106,14 +107,14 @@ static float dtar_get_prop_val(ChannelDriver *driver, DriverTarget *dtar)
int index = -1;
float value = 0.0f;
- /* sanity check */
+ /* Sanity check. */
if (ELEM(NULL, driver, dtar)) {
return 0.0f;
}
id = dtar_id_ensure_proxy_from(dtar->id);
- /* error check for missing pointer... */
+ /* Error check for missing pointer. */
if (id == NULL) {
if (G.debug & G_DEBUG) {
CLOG_ERROR(&LOG, "driver has an invalid target to use (path = %s)", dtar->rna_path);
@@ -124,12 +125,12 @@ static float dtar_get_prop_val(ChannelDriver *driver, DriverTarget *dtar)
return 0.0f;
}
- /* get RNA-pointer for the ID-block given in target */
+ /* Get RNA-pointer for the ID-block given in target. */
RNA_id_pointer_create(id, &id_ptr);
- /* get property to read from, and get value as appropriate */
+ /* Get property to read from, and get value as appropriate. */
if (!RNA_path_resolve_property_full(&id_ptr, dtar->rna_path, &ptr, &prop, &index)) {
- /* path couldn't be resolved */
+ /* Path couldn't be resolved. */
if (G.debug & G_DEBUG) {
CLOG_ERROR(&LOG,
"Driver Evaluation Error: cannot resolve target for %s -> %s",
@@ -143,9 +144,9 @@ static float dtar_get_prop_val(ChannelDriver *driver, DriverTarget *dtar)
}
if (RNA_property_array_check(prop)) {
- /* array */
+ /* Array. */
if (index < 0 || index >= RNA_property_array_length(&ptr, prop)) {
- /* out of bounds */
+ /* Out of bounds. */
if (G.debug & G_DEBUG) {
CLOG_ERROR(&LOG,
"Driver Evaluation Error: array index is out of bounds for %s -> %s (%d)",
@@ -174,7 +175,7 @@ static float dtar_get_prop_val(ChannelDriver *driver, DriverTarget *dtar)
}
}
else {
- /* not an array */
+ /* Not an array. */
switch (RNA_property_type(prop)) {
case PROP_BOOLEAN:
value = (float)RNA_property_boolean_get(&ptr, prop);
@@ -193,7 +194,7 @@ static float dtar_get_prop_val(ChannelDriver *driver, DriverTarget *dtar)
}
}
- /* if we're still here, we should be ok... */
+ /* If we're still here, we should be ok. */
dtar->flag &= ~DTAR_FLAG_INVALID;
return value;
}
@@ -213,14 +214,14 @@ bool driver_get_variable_property(ChannelDriver *driver,
ID *id;
int index = -1;
- /* sanity check */
+ /* Sanity check. */
if (ELEM(NULL, driver, dtar)) {
return false;
}
id = dtar_id_ensure_proxy_from(dtar->id);
- /* error check for missing pointer... */
+ /* Error check for missing pointer. */
if (id == NULL) {
if (G.debug & G_DEBUG) {
CLOG_ERROR(&LOG, "driver has an invalid target to use (path = %s)", dtar->rna_path);
@@ -231,19 +232,19 @@ bool driver_get_variable_property(ChannelDriver *driver,
return false;
}
- /* get RNA-pointer for the ID-block given in target */
+ /* Get RNA-pointer for the ID-block given in target. */
RNA_id_pointer_create(id, &id_ptr);
- /* get property to read from, and get value as appropriate */
+ /* Get property to read from, and get value as appropriate. */
if (dtar->rna_path == NULL || dtar->rna_path[0] == '\0') {
ptr = PointerRNA_NULL;
- prop = NULL; /* ok */
+ prop = NULL; /* OK. */
}
else if (RNA_path_resolve_property_full(&id_ptr, dtar->rna_path, &ptr, &prop, &index)) {
- /* ok */
+ /* OK. */
}
else {
- /* path couldn't be resolved */
+ /* Path couldn't be resolved. */
if (G.debug & G_DEBUG) {
CLOG_ERROR(&LOG,
"Driver Evaluation Error: cannot resolve target for %s -> %s",
@@ -264,7 +265,7 @@ bool driver_get_variable_property(ChannelDriver *driver,
*r_prop = prop;
*r_index = index;
- /* if we're still here, we should be ok... */
+ /* If we're still here, we should be ok. */
dtar->flag &= ~DTAR_FLAG_INVALID;
return true;
}
@@ -276,14 +277,14 @@ static short driver_check_valid_targets(ChannelDriver *driver, DriverVar *dvar)
DRIVER_TARGETS_USED_LOOPER_BEGIN (dvar) {
Object *ob = (Object *)dtar_id_ensure_proxy_from(dtar->id);
- /* check if this target has valid data */
+ /* Check if this target has valid data. */
if ((ob == NULL) || (GS(ob->id.name) != ID_OB)) {
- /* invalid target, so will not have enough targets */
+ /* Invalid target, so will not have enough targets. */
driver->flag |= DRIVER_FLAG_INVALID;
dtar->flag |= DTAR_FLAG_INVALID;
}
else {
- /* target seems to be OK now... */
+ /* Target seems to be OK now. */
dtar->flag &= ~DTAR_FLAG_INVALID;
valid_targets++;
}
@@ -293,21 +294,25 @@ static short driver_check_valid_targets(ChannelDriver *driver, DriverVar *dvar)
return valid_targets;
}
-/* ......... */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Driver Variable Utilities
+ * \{ */
-/* evaluate 'single prop' driver variable */
+/* Evaluate 'single prop' driver variable. */
static float dvar_eval_singleProp(ChannelDriver *driver, DriverVar *dvar)
{
- /* just evaluate the first target slot */
+ /* Just evaluate the first target slot. */
return dtar_get_prop_val(driver, &dvar->targets[0]);
}
-/* evaluate 'rotation difference' driver variable */
+/* Evaluate 'rotation difference' driver variable. */
static float dvar_eval_rotDiff(ChannelDriver *driver, DriverVar *dvar)
{
short valid_targets = driver_check_valid_targets(driver, dvar);
- /* make sure we have enough valid targets to use - all or nothing for now... */
+ /* Make sure we have enough valid targets to use - all or nothing for now. */
if (driver_check_valid_targets(driver, dvar) != 2) {
if (G.debug & G_DEBUG) {
CLOG_WARN(&LOG,
@@ -323,31 +328,31 @@ static float dvar_eval_rotDiff(ChannelDriver *driver, DriverVar *dvar)
/* NOTE: for now, these are all just worldspace */
for (int i = 0; i < 2; i++) {
- /* get pointer to loc values to store in */
+ /* Get pointer to loc values to store in. */
DriverTarget *dtar = &dvar->targets[i];
Object *ob = (Object *)dtar_id_ensure_proxy_from(dtar->id);
bPoseChannel *pchan;
- /* after the checks above, the targets should be valid here... */
+ /* After the checks above, the targets should be valid here. */
BLI_assert((ob != NULL) && (GS(ob->id.name) == ID_OB));
- /* try to get posechannel */
+ /* Try to get pose-channel. */
pchan = BKE_pose_channel_find_name(ob->pose, dtar->pchan_name);
- /* check if object or bone */
+ /* Check if object or bone. */
if (pchan) {
- /* bone */
+ /* Bone. */
mat[i] = pchan->pose_mat;
}
else {
- /* object */
+ /* Object. */
mat[i] = ob->obmat;
}
}
float q1[4], q2[4], quat[4], angle;
- /* use the final posed locations */
+ /* Use the final posed locations. */
mat4_to_quat(q1, mat[0]);
mat4_to_quat(q2, mat[1]);
@@ -359,15 +364,18 @@ static float dvar_eval_rotDiff(ChannelDriver *driver, DriverVar *dvar)
return (angle > (float)M_PI) ? (float)((2.0f * (float)M_PI) - angle) : (float)(angle);
}
-/* evaluate 'location difference' driver variable */
-/* TODO: this needs to take into account space conversions... */
+/**
+ * Evaluate 'location difference' driver variable.
+ *
+ * TODO: this needs to take into account space conversions.
+ */
static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar)
{
float loc1[3] = {0.0f, 0.0f, 0.0f};
float loc2[3] = {0.0f, 0.0f, 0.0f};
short valid_targets = driver_check_valid_targets(driver, dvar);
- /* make sure we have enough valid targets to use - all or nothing for now... */
+ /* Make sure we have enough valid targets to use - all or nothing for now. */
if (valid_targets < dvar->num_targets) {
if (G.debug & G_DEBUG) {
CLOG_WARN(&LOG,
@@ -380,72 +388,72 @@ static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar)
}
/* SECOND PASS: get two location values */
- /* NOTE: for now, these are all just worldspace */
+ /* NOTE: for now, these are all just world-space */
DRIVER_TARGETS_USED_LOOPER_BEGIN (dvar) {
- /* get pointer to loc values to store in */
+ /* Get pointer to loc values to store in. */
Object *ob = (Object *)dtar_id_ensure_proxy_from(dtar->id);
bPoseChannel *pchan;
float tmp_loc[3];
- /* after the checks above, the targets should be valid here... */
+ /* After the checks above, the targets should be valid here. */
BLI_assert((ob != NULL) && (GS(ob->id.name) == ID_OB));
- /* try to get posechannel */
+ /* Try to get pose-channel. */
pchan = BKE_pose_channel_find_name(ob->pose, dtar->pchan_name);
- /* check if object or bone */
+ /* Check if object or bone. */
if (pchan) {
- /* bone */
+ /* Bone. */
if (dtar->flag & DTAR_FLAG_LOCALSPACE) {
if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
float mat[4][4];
- /* extract transform just like how the constraints do it! */
+ /* Extract transform just like how the constraints do it! */
copy_m4_m4(mat, pchan->pose_mat);
BKE_constraint_mat_convertspace(
ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL, false);
- /* ... and from that, we get our transform */
+ /* ... and from that, we get our transform. */
copy_v3_v3(tmp_loc, mat[3]);
}
else {
- /* transform space (use transform values directly) */
+ /* Transform space (use transform values directly). */
copy_v3_v3(tmp_loc, pchan->loc);
}
}
else {
- /* convert to worldspace */
+ /* Convert to worldspace. */
copy_v3_v3(tmp_loc, pchan->pose_head);
mul_m4_v3(ob->obmat, tmp_loc);
}
}
else {
- /* object */
+ /* Object. */
if (dtar->flag & DTAR_FLAG_LOCALSPACE) {
if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
- /* XXX: this should practically be the same as transform space... */
+ /* XXX: this should practically be the same as transform space. */
float mat[4][4];
- /* extract transform just like how the constraints do it! */
+ /* Extract transform just like how the constraints do it! */
copy_m4_m4(mat, ob->obmat);
BKE_constraint_mat_convertspace(
ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, false);
- /* ... and from that, we get our transform */
+ /* ... and from that, we get our transform. */
copy_v3_v3(tmp_loc, mat[3]);
}
else {
- /* transform space (use transform values directly) */
+ /* Transform space (use transform values directly). */
copy_v3_v3(tmp_loc, ob->loc);
}
}
else {
- /* worldspace */
+ /* World-space. */
copy_v3_v3(tmp_loc, ob->obmat[3]);
}
}
- /* copy the location to the right place */
+ /* Copy the location to the right place. */
if (tarIndex) {
copy_v3_v3(loc2, tmp_loc);
}
@@ -455,13 +463,14 @@ static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar)
}
DRIVER_TARGETS_LOOPER_END;
- /* if we're still here, there should now be two targets to use,
- * so just take the length of the vector between these points
- */
+ /* If we're still here, there should now be two targets to use,
+ * so just take the length of the vector between these points. */
return len_v3v3(loc1, loc2);
}
-/* evaluate 'transform channel' driver variable */
+/**
+ * Evaluate 'transform channel' driver variable.
+ */
static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
{
DriverTarget *dtar = &dvar->targets[0];
@@ -472,15 +481,15 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
bool use_eulers = false;
short rot_order = ROT_MODE_EUL;
- /* check if this target has valid data */
+ /* Check if this target has valid data. */
if ((ob == NULL) || (GS(ob->id.name) != ID_OB)) {
- /* invalid target, so will not have enough targets */
+ /* Invalid target, so will not have enough targets. */
driver->flag |= DRIVER_FLAG_INVALID;
dtar->flag |= DTAR_FLAG_INVALID;
return 0.0f;
}
else {
- /* target should be valid now */
+ /* Target should be valid now. */
dtar->flag &= ~DTAR_FLAG_INVALID;
}
@@ -494,7 +503,7 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
* but #DTAR_FLAG_LOCAL_CONSTS is for all the common "corrective-shapes-for-limbs" situations.
*/
if (pchan) {
- /* bone */
+ /* Bone. */
if (pchan->rotmode > 0) {
copy_v3_v3(oldEul, pchan->eul);
rot_order = pchan->rotmode;
@@ -503,16 +512,15 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
if (dtar->flag & DTAR_FLAG_LOCALSPACE) {
if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
- /* just like how the constraints do it! */
+ /* Just like how the constraints do it! */
copy_m4_m4(mat, pchan->pose_mat);
BKE_constraint_mat_convertspace(
ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL, false);
}
else {
- /* specially calculate local matrix, since chan_mat is not valid
+ /* Specially calculate local matrix, since chan_mat is not valid
* since it stores delta transform of pose_mat so that deforms work
- * so it cannot be used here for "transform" space
- */
+ * so it cannot be used here for "transform" space. */
BKE_pchan_to_mat4(pchan, mat);
}
}
@@ -522,7 +530,7 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
}
}
else {
- /* object */
+ /* Object. */
if (ob->rotmode > 0) {
copy_v3_v3(oldEul, ob->rot);
rot_order = ob->rotmode;
@@ -531,25 +539,25 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
if (dtar->flag & DTAR_FLAG_LOCALSPACE) {
if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
- /* just like how the constraints do it! */
+ /* Just like how the constraints do it! */
copy_m4_m4(mat, ob->obmat);
BKE_constraint_mat_convertspace(
ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, false);
}
else {
- /* transforms to matrix */
+ /* Transforms to matrix. */
BKE_object_to_mat4(ob, mat);
}
}
else {
- /* worldspace matrix - just the good-old one */
+ /* World-space matrix - just the good-old one. */
copy_m4_m4(mat, ob->obmat);
}
}
- /* check which transform */
+ /* Check which transform. */
if (dtar->transChan >= MAX_DTAR_TRANSCHAN_TYPES) {
- /* not valid channel */
+ /* Not valid channel. */
return 0.0f;
}
else if (dtar->transChan == DTAR_TRANSCHAN_SCALE_AVG) {
@@ -566,7 +574,7 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
return len_v3(mat[dtar->transChan - DTAR_TRANSCHAN_SCALEX]);
}
else if (dtar->transChan >= DTAR_TRANSCHAN_ROTX) {
- /* extract rotation as eulers (if needed)
+ /* Extract rotation as eulers (if needed)
* - definitely if rotation order isn't eulers already
* - if eulers, then we have 2 options:
* a) decompose transform matrix as required, then try to make eulers from
@@ -595,7 +603,7 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
return quat[channel];
}
else {
- /* extract location and choose right axis */
+ /* Extract location and choose right axis. */
return mat[3][dtar->transChan];
}
}
@@ -665,41 +673,45 @@ void BKE_driver_target_matrix_to_rot_channels(
}
}
-/* ......... */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Driver Variable Type Info
+ * \{ */
/* Table of Driver Variable Type Info Data */
static DriverVarTypeInfo dvar_types[MAX_DVAR_TYPES] = {
- BEGIN_DVAR_TYPEDEF(DVAR_TYPE_SINGLE_PROP) dvar_eval_singleProp, /* eval callback */
- 1, /* number of targets used */
+ BEGIN_DVAR_TYPEDEF(DVAR_TYPE_SINGLE_PROP) dvar_eval_singleProp, /* Eval callback. */
+ 1, /* Number of targets used. */
{"Property"}, /* UI names for targets */
- {0} /* flags */
+ {0} /* Flags. */
END_DVAR_TYPEDEF,
- BEGIN_DVAR_TYPEDEF(DVAR_TYPE_ROT_DIFF) dvar_eval_rotDiff, /* eval callback */
- 2, /* number of targets used */
+ BEGIN_DVAR_TYPEDEF(DVAR_TYPE_ROT_DIFF) dvar_eval_rotDiff, /* Eval callback. */
+ 2, /* Number of targets used. */
{"Object/Bone 1", "Object/Bone 2"}, /* UI names for targets */
{DTAR_FLAG_STRUCT_REF | DTAR_FLAG_ID_OB_ONLY,
- DTAR_FLAG_STRUCT_REF | DTAR_FLAG_ID_OB_ONLY} /* flags */
+ DTAR_FLAG_STRUCT_REF | DTAR_FLAG_ID_OB_ONLY} /* Flags. */
END_DVAR_TYPEDEF,
- BEGIN_DVAR_TYPEDEF(DVAR_TYPE_LOC_DIFF) dvar_eval_locDiff, /* eval callback */
- 2, /* number of targets used */
+ BEGIN_DVAR_TYPEDEF(DVAR_TYPE_LOC_DIFF) dvar_eval_locDiff, /* Eval callback. */
+ 2, /* Number of targets used. */
{"Object/Bone 1", "Object/Bone 2"}, /* UI names for targets */
{DTAR_FLAG_STRUCT_REF | DTAR_FLAG_ID_OB_ONLY,
- DTAR_FLAG_STRUCT_REF | DTAR_FLAG_ID_OB_ONLY} /* flags */
+ DTAR_FLAG_STRUCT_REF | DTAR_FLAG_ID_OB_ONLY} /* Flags. */
END_DVAR_TYPEDEF,
- BEGIN_DVAR_TYPEDEF(DVAR_TYPE_TRANSFORM_CHAN) dvar_eval_transChan, /* eval callback */
- 1, /* number of targets used */
+ BEGIN_DVAR_TYPEDEF(DVAR_TYPE_TRANSFORM_CHAN) dvar_eval_transChan, /* Eval callback. */
+ 1, /* Number of targets used. */
{"Object/Bone"}, /* UI names for targets */
- {DTAR_FLAG_STRUCT_REF | DTAR_FLAG_ID_OB_ONLY} /* flags */
+ {DTAR_FLAG_STRUCT_REF | DTAR_FLAG_ID_OB_ONLY} /* Flags. */
END_DVAR_TYPEDEF,
};
/* Get driver variable typeinfo */
static const DriverVarTypeInfo *get_dvar_typeinfo(int type)
{
- /* check if valid type */
+ /* Check if valid type. */
if ((type >= 0) && (type < MAX_DVAR_TYPES)) {
return &dvar_types[type];
}
@@ -708,40 +720,44 @@ static const DriverVarTypeInfo *get_dvar_typeinfo(int type)
}
}
-/* Driver API --------------------------------- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Driver API
+ * \{ */
/* Perform actual freeing driver variable and remove it from the given list */
void driver_free_variable(ListBase *variables, DriverVar *dvar)
{
- /* sanity checks */
+ /* Sanity checks. */
if (dvar == NULL) {
return;
}
- /* free target vars
+ /* Free target vars:
* - need to go over all of them, not just up to the ones that are used
* currently, since there may be some lingering RNA paths from
* previous users needing freeing
*/
DRIVER_TARGETS_LOOPER_BEGIN (dvar) {
- /* free RNA path if applicable */
+ /* Free RNA path if applicable. */
if (dtar->rna_path) {
MEM_freeN(dtar->rna_path);
}
}
DRIVER_TARGETS_LOOPER_END;
- /* remove the variable from the driver */
+ /* Remove the variable from the driver. */
BLI_freelinkN(variables, dvar);
}
/* Free the driver variable and do extra updates */
void driver_free_variable_ex(ChannelDriver *driver, DriverVar *dvar)
{
- /* remove and free the driver variable */
+ /* Remove and free the driver variable. */
driver_free_variable(&driver->variables, dvar);
- /* since driver variables are cached, the expression needs re-compiling too */
+ /* Since driver variables are cached, the expression needs re-compiling too. */
BKE_driver_invalidate_expression(driver, false, true);
}
@@ -752,9 +768,9 @@ void driver_variables_copy(ListBase *dst_vars, const ListBase *src_vars)
BLI_duplicatelist(dst_vars, src_vars);
LISTBASE_FOREACH (DriverVar *, dvar, dst_vars) {
- /* need to go over all targets so that we don't leave any dangling paths */
+ /* Need to go over all targets so that we don't leave any dangling paths. */
DRIVER_TARGETS_LOOPER_BEGIN (dvar) {
- /* make a copy of target's rna path if available */
+ /* Make a copy of target's rna path if available. */
if (dtar->rna_path) {
dtar->rna_path = MEM_dupallocN(dtar->rna_path);
}
@@ -768,25 +784,24 @@ void driver_change_variable_type(DriverVar *dvar, int type)
{
const DriverVarTypeInfo *dvti = get_dvar_typeinfo(type);
- /* sanity check */
+ /* Sanity check. */
if (ELEM(NULL, dvar, dvti)) {
return;
}
- /* set the new settings */
+ /* Set the new settings. */
dvar->type = type;
dvar->num_targets = dvti->num_targets;
- /* make changes to the targets based on the defines for these types
- * NOTE: only need to make sure the ones we're using here are valid...
- */
+ /* Make changes to the targets based on the defines for these types.
+ * NOTE: only need to make sure the ones we're using here are valid. */
DRIVER_TARGETS_USED_LOOPER_BEGIN (dvar) {
short flags = dvti->target_flags[tarIndex];
- /* store the flags */
+ /* Store the flags. */
dtar->flag = flags;
- /* object ID types only, or idtype not yet initialized */
+ /* Object ID types only, or idtype not yet initialized. */
if ((flags & DTAR_FLAG_ID_OB_ONLY) || (dtar->idtype == 0)) {
dtar->idtype = ID_OB;
}
@@ -803,12 +818,12 @@ void driver_variable_name_validate(DriverVar *dvar)
'?', ':', ';', '<', '>', '{', '}', '[', ']', '|', ' ', '.', '\t', '\n', '\r',
};
- /* sanity checks */
+ /* Sanity checks. */
if (dvar == NULL) {
return;
}
- /* clear all invalid-name flags */
+ /* Clear all invalid-name flags. */
dvar->flag &= ~DVAR_ALL_INVALID_FLAGS;
/* 0) Zero-length identifiers are not allowed */
@@ -869,16 +884,16 @@ DriverVar *driver_add_new_variable(ChannelDriver *driver)
{
DriverVar *dvar;
- /* sanity checks */
+ /* Sanity checks. */
if (driver == NULL) {
return NULL;
}
- /* make a new variable */
+ /* Make a new variable. */
dvar = MEM_callocN(sizeof(DriverVar), "DriverVar");
BLI_addtail(&driver->variables, dvar);
- /* give the variable a 'unique' name */
+ /* Give the variable a 'unique' name. */
strcpy(dvar->name, CTX_DATA_(BLT_I18NCONTEXT_ID_ACTION, "var"));
BLI_uniquename(&driver->variables,
dvar,
@@ -887,13 +902,13 @@ DriverVar *driver_add_new_variable(ChannelDriver *driver)
offsetof(DriverVar, name),
sizeof(dvar->name));
- /* set the default type to 'single prop' */
+ /* Set the default type to 'single prop'. */
driver_change_variable_type(dvar, DVAR_TYPE_SINGLE_PROP);
- /* since driver variables are cached, the expression needs re-compiling too */
+ /* Since driver variables are cached, the expression needs re-compiling too. */
BKE_driver_invalidate_expression(driver, false, true);
- /* return the target */
+ /* Return the target. */
return dvar;
}
@@ -903,20 +918,20 @@ void fcurve_free_driver(FCurve *fcu)
ChannelDriver *driver;
DriverVar *dvar, *dvarn;
- /* sanity checks */
+ /* Sanity checks. */
if (ELEM(NULL, fcu, fcu->driver)) {
return;
}
driver = fcu->driver;
- /* free driver targets */
+ /* Free driver targets. */
for (dvar = driver->variables.first; dvar; dvar = dvarn) {
dvarn = dvar->next;
driver_free_variable_ex(driver, dvar);
}
#ifdef WITH_PYTHON
- /* free compiled driver expression */
+ /* Free compiled driver expression. */
if (driver->expr_comp) {
BPY_DECREF(driver->expr_comp);
}
@@ -935,27 +950,31 @@ ChannelDriver *fcurve_copy_driver(const ChannelDriver *driver)
{
ChannelDriver *ndriver;
- /* sanity checks */
+ /* Sanity checks. */
if (driver == NULL) {
return NULL;
}
- /* copy all data */
+ /* Copy all data. */
ndriver = MEM_dupallocN(driver);
ndriver->expr_comp = NULL;
ndriver->expr_simple = NULL;
- /* copy variables */
+ /* Copy variables. */
- /* to get rid of refs to non-copied data (that's still used on original) */
+ /* To get rid of refs to non-copied data (that's still used on original). */
BLI_listbase_clear(&ndriver->variables);
driver_variables_copy(&ndriver->variables, &driver->variables);
- /* return the new driver */
+ /* Return the new driver. */
return ndriver;
}
-/* Driver Expression Evaluation --------------- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Driver Expression Evaluation
+ * \{ */
/* Index constants for the expression parameter array. */
enum {
@@ -1025,7 +1044,7 @@ static bool driver_evaluate_simple_expr(ChannelDriver *driver,
return true;
default:
- /* arriving here means a bug, not user error */
+ /* Arriving here means a bug, not user error. */
CLOG_ERROR(&LOG, "simple driver expression evaluation failed: '%s'", driver->expression);
return false;
}
@@ -1134,22 +1153,25 @@ void BKE_driver_invalidate_expression(ChannelDriver *driver,
#endif
}
-/* Driver Evaluation -------------------------- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Driver Evaluation
+ * \{ */
/* Evaluate a Driver Variable to get a value that contributes to the final */
float driver_get_variable_value(ChannelDriver *driver, DriverVar *dvar)
{
const DriverVarTypeInfo *dvti;
- /* sanity check */
+ /* Sanity check. */
if (ELEM(NULL, driver, dvar)) {
return 0.0f;
}
- /* call the relevant callbacks to get the variable value
+ /* Call the relevant callbacks to get the variable value
* using the variable type info, storing the obtained value
- * in dvar->curval so that drivers can be debugged
- */
+ * in `dvar->curval` so that drivers can be debugged. */
dvti = get_dvar_typeinfo(dvar->type);
if (dvti && dvti->get_value) {
@@ -1166,25 +1188,25 @@ static void evaluate_driver_sum(ChannelDriver *driver)
{
DriverVar *dvar;
- /* check how many variables there are first (i.e. just one?) */
+ /* Check how many variables there are first (i.e. just one?). */
if (BLI_listbase_is_single(&driver->variables)) {
- /* just one target, so just use that */
+ /* Just one target, so just use that. */
dvar = driver->variables.first;
driver->curval = driver_get_variable_value(driver, dvar);
return;
}
- /* more than one target, so average the values of the targets */
+ /* More than one target, so average the values of the targets. */
float value = 0.0f;
int tot = 0;
- /* loop through targets, adding (hopefully we don't get any overflow!) */
+ /* Loop through targets, adding (hopefully we don't get any overflow!). */
for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
value += driver_get_variable_value(driver, dvar);
tot++;
}
- /* perform operations on the total if appropriate */
+ /* Perform operations on the total if appropriate. */
if (driver->type == DRIVER_TYPE_AVERAGE) {
driver->curval = tot ? (value / (float)tot) : 0.0f;
}
@@ -1198,97 +1220,99 @@ static void evaluate_driver_min_max(ChannelDriver *driver)
DriverVar *dvar;
float value = 0.0f;
- /* loop through the variables, getting the values and comparing them to existing ones */
+ /* Loop through the variables, getting the values and comparing them to existing ones. */
for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
- /* get value */
+ /* Get value. */
float tmp_val = driver_get_variable_value(driver, dvar);
- /* store this value if appropriate */
+ /* Store this value if appropriate. */
if (dvar->prev) {
- /* check if greater/smaller than the baseline */
+ /* Check if greater/smaller than the baseline. */
if (driver->type == DRIVER_TYPE_MAX) {
- /* max? */
+ /* Max? */
if (tmp_val > value) {
value = tmp_val;
}
}
else {
- /* min? */
+ /* Min? */
if (tmp_val < value) {
value = tmp_val;
}
}
}
else {
- /* first item - make this the baseline for comparisons */
+ /* First item - make this the baseline for comparisons. */
value = tmp_val;
}
}
- /* store value in driver */
+ /* Store value in driver. */
driver->curval = value;
}
static void evaluate_driver_python(PathResolvedRNA *anim_rna,
ChannelDriver *driver,
ChannelDriver *driver_orig,
- const float evaltime)
+ const AnimationEvalContext *anim_eval_context)
{
- /* check for empty or invalid expression */
+ /* Check for empty or invalid expression. */
if ((driver_orig->expression[0] == '\0') || (driver_orig->flag & DRIVER_FLAG_INVALID)) {
driver->curval = 0.0f;
}
- else if (!driver_try_evaluate_simple_expr(driver, driver_orig, &driver->curval, evaltime)) {
+ else if (!driver_try_evaluate_simple_expr(
+ driver, driver_orig, &driver->curval, anim_eval_context->eval_time)) {
#ifdef WITH_PYTHON
- /* this evaluates the expression using Python, and returns its result:
- * - on errors it reports, then returns 0.0f
- */
+ /* This evaluates the expression using Python, and returns its result:
+ * - on errors it reports, then returns 0.0f. */
BLI_mutex_lock(&python_driver_lock);
- driver->curval = BPY_driver_exec(anim_rna, driver, driver_orig, evaltime);
+ driver->curval = BPY_driver_exec(anim_rna, driver, driver_orig, anim_eval_context);
BLI_mutex_unlock(&python_driver_lock);
-#else /* WITH_PYTHON*/
- UNUSED_VARS(anim_rna, evaltime);
-#endif /* WITH_PYTHON*/
+#else /* WITH_PYTHON */
+ UNUSED_VARS(anim_rna, anim_eval_context);
+#endif /* WITH_PYTHON */
}
}
-/* Evaluate an Channel-Driver to get a 'time' value to use instead of "evaltime"
- * - "evaltime" is the frame at which F-Curve is being evaluated
- * - has to return a float value
- * - driver_orig is where we cache Python expressions, in case of COW
+/**
+ * Evaluate an Channel-Driver to get a 'time' value to use
+ * instead of `anim_eval_context->eval_time`.
+ *
+ * - `anim_eval_context->eval_time` is the frame at which F-Curve is being evaluated.
+ * - Has to return a float value.
+ * - \a driver_orig is where we cache Python expressions, in case of COW
*/
float evaluate_driver(PathResolvedRNA *anim_rna,
ChannelDriver *driver,
ChannelDriver *driver_orig,
- const float evaltime)
+ const AnimationEvalContext *anim_eval_context)
{
- /* check if driver can be evaluated */
+ /* Check if driver can be evaluated. */
if (driver_orig->flag & DRIVER_FLAG_INVALID) {
return 0.0f;
}
switch (driver->type) {
- case DRIVER_TYPE_AVERAGE: /* average values of driver targets */
- case DRIVER_TYPE_SUM: /* sum values of driver targets */
+ case DRIVER_TYPE_AVERAGE: /* Average values of driver targets. */
+ case DRIVER_TYPE_SUM: /* Sum values of driver targets. */
evaluate_driver_sum(driver);
break;
- case DRIVER_TYPE_MIN: /* smallest value */
- case DRIVER_TYPE_MAX: /* largest value */
+ case DRIVER_TYPE_MIN: /* Smallest value. */
+ case DRIVER_TYPE_MAX: /* Largest value. */
evaluate_driver_min_max(driver);
break;
- case DRIVER_TYPE_PYTHON: /* expression */
- evaluate_driver_python(anim_rna, driver, driver_orig, evaltime);
+ case DRIVER_TYPE_PYTHON: /* Expression. */
+ evaluate_driver_python(anim_rna, driver, driver_orig, anim_eval_context);
break;
default:
- /* special 'hack' - just use stored value
+ /* Special 'hack' - just use stored value
* This is currently used as the mechanism which allows animated settings to be able
- * to be changed via the UI.
- */
+ * to be changed via the UI. */
break;
}
- /* return value for driver */
+ /* Return value for driver. */
return driver->curval;
}
diff --git a/source/blender/blenkernel/intern/fcurve_test.cc b/source/blender/blenkernel/intern/fcurve_test.cc
new file mode 100644
index 00000000000..a6f65a7c9b3
--- /dev/null
+++ b/source/blender/blenkernel/intern/fcurve_test.cc
@@ -0,0 +1,213 @@
+/*
+ * 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.
+ */
+#include "testing/testing.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BKE_fcurve.h"
+
+#include "ED_keyframing.h"
+
+#include "DNA_anim_types.h"
+
+namespace blender::bke::tests {
+
+// Epsilon for floating point comparisons.
+static const float EPSILON = 1e-7f;
+
+TEST(evaluate_fcurve, EmptyFCurve)
+{
+ FCurve *fcu = BKE_fcurve_create();
+ EXPECT_EQ(evaluate_fcurve(fcu, 47.0f), 0.0f);
+ BKE_fcurve_free(fcu);
+}
+
+TEST(evaluate_fcurve, OnKeys)
+{
+ FCurve *fcu = BKE_fcurve_create();
+
+ insert_vert_fcurve(fcu, 1.0f, 7.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
+ insert_vert_fcurve(fcu, 2.0f, 13.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
+ insert_vert_fcurve(fcu, 3.0f, 19.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
+
+ EXPECT_NEAR(evaluate_fcurve(fcu, 1.0f), 7.0f, EPSILON); // hits 'on or before first' function
+ EXPECT_NEAR(evaluate_fcurve(fcu, 2.0f), 13.0f, EPSILON); // hits 'between' function
+ EXPECT_NEAR(evaluate_fcurve(fcu, 3.0f), 19.0f, EPSILON); // hits 'on or after last' function
+
+ /* Also test within a specific time epsilon of the keys, as this was an issue in T39207.
+ * This epsilon is just slightly smaller than the epsilon given to binarysearch_bezt_index_ex()
+ * in fcurve_eval_between_keyframes(), so it should hit the "exact" code path. */
+ float time_epsilon = 0.00008f;
+ EXPECT_NEAR(evaluate_fcurve(fcu, 2.0f - time_epsilon), 13.0f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, 2.0f + time_epsilon), 13.0f, EPSILON);
+
+ BKE_fcurve_free(fcu);
+}
+
+TEST(evaluate_fcurve, InterpolationConstant)
+{
+ FCurve *fcu = BKE_fcurve_create();
+
+ EXPECT_EQ(insert_vert_fcurve(fcu, 1.0f, 7.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 0);
+ EXPECT_EQ(insert_vert_fcurve(fcu, 2.0f, 13.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 1);
+
+ fcu->bezt[0].ipo = BEZT_IPO_CONST;
+ fcu->bezt[1].ipo = BEZT_IPO_CONST;
+
+ EXPECT_NEAR(evaluate_fcurve(fcu, 1.25f), 7.0f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, 1.50f), 7.0f, EPSILON);
+
+ BKE_fcurve_free(fcu);
+}
+
+TEST(evaluate_fcurve, InterpolationLinear)
+{
+ FCurve *fcu = BKE_fcurve_create();
+
+ EXPECT_EQ(insert_vert_fcurve(fcu, 1.0f, 7.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 0);
+ EXPECT_EQ(insert_vert_fcurve(fcu, 2.0f, 13.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 1);
+
+ fcu->bezt[0].ipo = BEZT_IPO_LIN;
+ fcu->bezt[1].ipo = BEZT_IPO_LIN;
+
+ EXPECT_NEAR(evaluate_fcurve(fcu, 1.25f), 8.5f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, 1.50f), 10.0f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, 1.75f), 11.5f, EPSILON);
+
+ BKE_fcurve_free(fcu);
+}
+
+TEST(evaluate_fcurve, InterpolationBezier)
+{
+ FCurve *fcu = BKE_fcurve_create();
+
+ EXPECT_EQ(insert_vert_fcurve(fcu, 1.0f, 7.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 0);
+ EXPECT_EQ(insert_vert_fcurve(fcu, 2.0f, 13.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 1);
+
+ EXPECT_EQ(fcu->bezt[0].ipo, BEZT_IPO_BEZ);
+ EXPECT_EQ(fcu->bezt[1].ipo, BEZT_IPO_BEZ);
+
+ // Test with default handles.
+ EXPECT_NEAR(evaluate_fcurve(fcu, 1.25f), 7.8297067f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, 1.50f), 10.0f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, 1.75f), 12.170294f, EPSILON);
+
+ // Test with modified handles.
+ fcu->bezt[0].vec[0][0] = 0.71855f; // left handle X
+ fcu->bezt[0].vec[0][1] = 6.22482f; // left handle Y
+ fcu->bezt[0].vec[2][0] = 1.35148f; // right handle X
+ fcu->bezt[0].vec[2][1] = 7.96806f; // right handle Y
+
+ fcu->bezt[1].vec[0][0] = 1.66667f; // left handle X
+ fcu->bezt[1].vec[0][1] = 10.4136f; // left handle Y
+ fcu->bezt[1].vec[2][0] = 2.33333f; // right handle X
+ fcu->bezt[1].vec[2][1] = 15.5864f; // right handle Y
+
+ EXPECT_NEAR(evaluate_fcurve(fcu, 1.25f), 7.945497f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, 1.50f), 9.3495407f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, 1.75f), 11.088551f, EPSILON);
+
+ BKE_fcurve_free(fcu);
+}
+
+TEST(evaluate_fcurve, InterpolationBounce)
+{
+ FCurve *fcu = BKE_fcurve_create();
+
+ EXPECT_EQ(insert_vert_fcurve(fcu, 1.0f, 7.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 0);
+ EXPECT_EQ(insert_vert_fcurve(fcu, 2.0f, 13.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 1);
+
+ fcu->bezt[0].ipo = BEZT_IPO_BOUNCE;
+ fcu->bezt[1].ipo = BEZT_IPO_BOUNCE;
+
+ fcu->bezt[0].easing = BEZT_IPO_EASE_IN;
+ fcu->bezt[1].easing = BEZT_IPO_EASE_AUTO;
+
+ EXPECT_NEAR(evaluate_fcurve(fcu, 1.4f), 8.3649998f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, 1.5f), 8.4062500f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, 1.8f), 11.184999f, EPSILON);
+
+ BKE_fcurve_free(fcu);
+}
+
+TEST(evaluate_fcurve, ExtrapolationLinearKeys)
+{
+ FCurve *fcu = BKE_fcurve_create();
+
+ EXPECT_EQ(insert_vert_fcurve(fcu, 1.0f, 7.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 0);
+ EXPECT_EQ(insert_vert_fcurve(fcu, 2.0f, 13.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 1);
+ fcu->bezt[0].ipo = BEZT_IPO_LIN;
+ fcu->bezt[1].ipo = BEZT_IPO_LIN;
+
+ fcu->extend = FCURVE_EXTRAPOLATE_LINEAR;
+ // Before first keyframe.
+ EXPECT_NEAR(evaluate_fcurve(fcu, 0.75f), 5.5f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, 0.50f), 4.0f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, -1.50f), -8.0f, EPSILON);
+ // After last keyframe.
+ EXPECT_NEAR(evaluate_fcurve(fcu, 2.75f), 17.5f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, 3.50f), 22.0f, EPSILON);
+
+ fcu->extend = FCURVE_EXTRAPOLATE_CONSTANT;
+ // Before first keyframe.
+ EXPECT_NEAR(evaluate_fcurve(fcu, 0.75f), 7.0f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, -1.50f), 7.0f, EPSILON);
+ // After last keyframe.
+ EXPECT_NEAR(evaluate_fcurve(fcu, 2.75f), 13.0f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, 3.50f), 13.0f, EPSILON);
+
+ BKE_fcurve_free(fcu);
+}
+
+TEST(evaluate_fcurve, ExtrapolationBezierKeys)
+{
+ FCurve *fcu = BKE_fcurve_create();
+
+ EXPECT_EQ(insert_vert_fcurve(fcu, 1.0f, 7.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 0);
+ EXPECT_EQ(insert_vert_fcurve(fcu, 2.0f, 13.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 1);
+
+ fcu->bezt[0].vec[0][0] = 0.71855f; // left handle X
+ fcu->bezt[0].vec[0][1] = 6.22482f; // left handle Y
+ fcu->bezt[0].vec[2][0] = 1.35148f; // right handle X
+ fcu->bezt[0].vec[2][1] = 7.96806f; // right handle Y
+
+ fcu->bezt[1].vec[0][0] = 1.66667f; // left handle X
+ fcu->bezt[1].vec[0][1] = 10.4136f; // left handle Y
+ fcu->bezt[1].vec[2][0] = 2.33333f; // right handle X
+ fcu->bezt[1].vec[2][1] = 15.5864f; // right handle Y
+
+ fcu->extend = FCURVE_EXTRAPOLATE_LINEAR;
+ // Before first keyframe.
+ EXPECT_NEAR(evaluate_fcurve(fcu, 0.75f), 6.3114409f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, -0.50f), 2.8686447f, EPSILON);
+ // After last keyframe.
+ EXPECT_NEAR(evaluate_fcurve(fcu, 2.75f), 18.81946f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, 3.50f), 24.63892f, EPSILON);
+
+ fcu->extend = FCURVE_EXTRAPOLATE_CONSTANT;
+ // Before first keyframe.
+ EXPECT_NEAR(evaluate_fcurve(fcu, 0.75f), 7.0f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, -1.50f), 7.0f, EPSILON);
+ // After last keyframe.
+ EXPECT_NEAR(evaluate_fcurve(fcu, 2.75f), 13.0f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, 3.50f), 13.0f, EPSILON);
+
+ BKE_fcurve_free(fcu);
+}
+
+} // namespace blender::bke::tests
diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c
index 1f748487841..2245af31f0d 100644
--- a/source/blender/blenkernel/intern/fluid.c
+++ b/source/blender/blenkernel/intern/fluid.c
@@ -137,109 +137,84 @@ bool BKE_fluid_reallocate_fluid(FluidDomainSettings *fds, int res[3], int free_o
void BKE_fluid_reallocate_copy_fluid(FluidDomainSettings *fds,
int o_res[3],
int n_res[3],
- int o_min[3],
- int n_min[3],
- int o_max[3],
+ const int o_min[3],
+ const int n_min[3],
+ const int o_max[3],
int o_shift[3],
int n_shift[3])
{
- int x, y, z;
struct MANTA *fluid_old = fds->fluid;
const int block_size = fds->noise_scale;
int new_shift[3] = {0};
sub_v3_v3v3_int(new_shift, n_shift, o_shift);
- /* allocate new fluid data */
+ /* Allocate new fluid data. */
BKE_fluid_reallocate_fluid(fds, n_res, 0);
int o_total_cells = o_res[0] * o_res[1] * o_res[2];
int n_total_cells = n_res[0] * n_res[1] * n_res[2];
- /* boundary cells will be skipped when copying data */
- int bwidth = fds->boundary_width;
-
- /* copy values from old fluid to new */
+ /* Copy values from old fluid to new fluid object. */
if (o_total_cells > 1 && n_total_cells > 1) {
- /* base smoke */
- float *o_dens, *o_react, *o_flame, *o_fuel, *o_heat, *o_vx, *o_vy, *o_vz, *o_r, *o_g, *o_b;
- float *n_dens, *n_react, *n_flame, *n_fuel, *n_heat, *n_vx, *n_vy, *n_vz, *n_r, *n_g, *n_b;
- float dummy, *dummy_s;
- int *dummy_p;
- /* noise smoke */
+ float *o_dens = manta_smoke_get_density(fluid_old);
+ float *o_react = manta_smoke_get_react(fluid_old);
+ float *o_flame = manta_smoke_get_flame(fluid_old);
+ float *o_fuel = manta_smoke_get_fuel(fluid_old);
+ float *o_heat = manta_smoke_get_heat(fluid_old);
+ float *o_vx = manta_get_velocity_x(fluid_old);
+ float *o_vy = manta_get_velocity_y(fluid_old);
+ float *o_vz = manta_get_velocity_z(fluid_old);
+ float *o_r = manta_smoke_get_color_r(fluid_old);
+ float *o_g = manta_smoke_get_color_g(fluid_old);
+ float *o_b = manta_smoke_get_color_b(fluid_old);
+
+ float *n_dens = manta_smoke_get_density(fds->fluid);
+ float *n_react = manta_smoke_get_react(fds->fluid);
+ float *n_flame = manta_smoke_get_flame(fds->fluid);
+ float *n_fuel = manta_smoke_get_fuel(fds->fluid);
+ float *n_heat = manta_smoke_get_heat(fds->fluid);
+ float *n_vx = manta_get_velocity_x(fds->fluid);
+ float *n_vy = manta_get_velocity_y(fds->fluid);
+ float *n_vz = manta_get_velocity_z(fds->fluid);
+ float *n_r = manta_smoke_get_color_r(fds->fluid);
+ float *n_g = manta_smoke_get_color_g(fds->fluid);
+ float *n_b = manta_smoke_get_color_b(fds->fluid);
+
+ /* Noise smoke fields. */
int wt_res_old[3];
- float *o_wt_dens, *o_wt_react, *o_wt_flame, *o_wt_fuel, *o_wt_tcu, *o_wt_tcv, *o_wt_tcw,
- *o_wt_tcu2, *o_wt_tcv2, *o_wt_tcw2, *o_wt_r, *o_wt_g, *o_wt_b;
- float *n_wt_dens, *n_wt_react, *n_wt_flame, *n_wt_fuel, *n_wt_tcu, *n_wt_tcv, *n_wt_tcw,
- *n_wt_tcu2, *n_wt_tcv2, *n_wt_tcw2, *n_wt_r, *n_wt_g, *n_wt_b;
-
- if (fds->flags & FLUID_DOMAIN_USE_NOISE) {
- manta_smoke_turbulence_export(fluid_old,
- &o_wt_dens,
- &o_wt_react,
- &o_wt_flame,
- &o_wt_fuel,
- &o_wt_r,
- &o_wt_g,
- &o_wt_b,
- &o_wt_tcu,
- &o_wt_tcv,
- &o_wt_tcw,
- &o_wt_tcu2,
- &o_wt_tcv2,
- &o_wt_tcw2);
- manta_smoke_turbulence_get_res(fluid_old, wt_res_old);
- manta_smoke_turbulence_export(fds->fluid,
- &n_wt_dens,
- &n_wt_react,
- &n_wt_flame,
- &n_wt_fuel,
- &n_wt_r,
- &n_wt_g,
- &n_wt_b,
- &n_wt_tcu,
- &n_wt_tcv,
- &n_wt_tcw,
- &n_wt_tcu2,
- &n_wt_tcv2,
- &n_wt_tcw2);
- }
-
- manta_smoke_export(fluid_old,
- &dummy,
- &dummy,
- &o_dens,
- &o_react,
- &o_flame,
- &o_fuel,
- &o_heat,
- &o_vx,
- &o_vy,
- &o_vz,
- &o_r,
- &o_g,
- &o_b,
- &dummy_p,
- &dummy_s);
- manta_smoke_export(fds->fluid,
- &dummy,
- &dummy,
- &n_dens,
- &n_react,
- &n_flame,
- &n_fuel,
- &n_heat,
- &n_vx,
- &n_vy,
- &n_vz,
- &n_r,
- &n_g,
- &n_b,
- &dummy_p,
- &dummy_s);
-
- for (x = o_min[0]; x < o_max[0]; x++) {
- for (y = o_min[1]; y < o_max[1]; y++) {
- for (z = o_min[2]; z < o_max[2]; z++) {
+ float *o_wt_dens = manta_noise_get_density(fluid_old);
+ float *o_wt_react = manta_noise_get_react(fluid_old);
+ float *o_wt_flame = manta_noise_get_flame(fluid_old);
+ float *o_wt_fuel = manta_noise_get_fuel(fluid_old);
+ float *o_wt_r = manta_noise_get_color_r(fluid_old);
+ float *o_wt_g = manta_noise_get_color_g(fluid_old);
+ float *o_wt_b = manta_noise_get_color_b(fluid_old);
+ float *o_wt_tcu = manta_noise_get_texture_u(fluid_old);
+ float *o_wt_tcv = manta_noise_get_texture_v(fluid_old);
+ float *o_wt_tcw = manta_noise_get_texture_w(fluid_old);
+ float *o_wt_tcu2 = manta_noise_get_texture_u2(fluid_old);
+ float *o_wt_tcv2 = manta_noise_get_texture_v2(fluid_old);
+ float *o_wt_tcw2 = manta_noise_get_texture_w2(fluid_old);
+
+ float *n_wt_dens = manta_noise_get_density(fds->fluid);
+ float *n_wt_react = manta_noise_get_react(fds->fluid);
+ float *n_wt_flame = manta_noise_get_flame(fds->fluid);
+ float *n_wt_fuel = manta_noise_get_fuel(fds->fluid);
+ float *n_wt_r = manta_noise_get_color_r(fds->fluid);
+ float *n_wt_g = manta_noise_get_color_g(fds->fluid);
+ float *n_wt_b = manta_noise_get_color_b(fds->fluid);
+ float *n_wt_tcu = manta_noise_get_texture_u(fds->fluid);
+ float *n_wt_tcv = manta_noise_get_texture_v(fds->fluid);
+ float *n_wt_tcw = manta_noise_get_texture_w(fds->fluid);
+ float *n_wt_tcu2 = manta_noise_get_texture_u2(fds->fluid);
+ float *n_wt_tcv2 = manta_noise_get_texture_v2(fds->fluid);
+ float *n_wt_tcw2 = manta_noise_get_texture_w2(fds->fluid);
+
+ manta_noise_get_res(fluid_old, wt_res_old);
+
+ for (int z = o_min[2]; z < o_max[2]; z++) {
+ for (int y = o_min[1]; y < o_max[1]; y++) {
+ for (int x = o_min[0]; x < o_max[0]; x++) {
/* old grid index */
int xo = x - o_min[0];
int yo = y - o_min[1];
@@ -251,20 +226,31 @@ void BKE_fluid_reallocate_copy_fluid(FluidDomainSettings *fds,
int zn = z - n_min[2] - new_shift[2];
int index_new = manta_get_index(xn, n_res[0], yn, n_res[1], zn);
- /* skip if outside new domain */
+ /* Skip if outside new domain. */
if (xn < 0 || xn >= n_res[0] || yn < 0 || yn >= n_res[1] || zn < 0 || zn >= n_res[2]) {
continue;
}
- /* skip if trying to copy from old boundary cell */
+# if 0
+ /* Note (sebbas):
+ * Disabling this "skip section" as not copying borders results in weird cut-off effects.
+ * It is possible that this cutting off is the reason for line effects as seen in T74559.
+ * Since domain borders will be handled on the simulation side anyways,
+ * copying border values should not be an issue. */
+
+ /* boundary cells will be skipped when copying data */
+ int bwidth = fds->boundary_width;
+
+ /* Skip if trying to copy from old boundary cell. */
if (xo < bwidth || yo < bwidth || zo < bwidth || xo >= o_res[0] - bwidth ||
yo >= o_res[1] - bwidth || zo >= o_res[2] - bwidth) {
continue;
}
- /* skip if trying to copy into new boundary cell */
+ /* Skip if trying to copy into new boundary cell. */
if (xn < bwidth || yn < bwidth || zn < bwidth || xn >= n_res[0] - bwidth ||
yn >= n_res[1] - bwidth || zn >= n_res[2] - bwidth) {
continue;
}
+# endif
/* copy data */
if (fds->flags & FLUID_DOMAIN_USE_NOISE) {
@@ -491,6 +477,17 @@ static void manta_set_domain_from_mesh(FluidDomainSettings *fds,
fds->cell_size[2] /= (float)fds->base_res[2];
}
+static void update_final_gravity(FluidDomainSettings *fds, Scene *scene)
+{
+ if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) {
+ copy_v3_v3(fds->gravity_final, scene->physics_settings.gravity);
+ }
+ else {
+ copy_v3_v3(fds->gravity_final, fds->gravity);
+ }
+ mul_v3_fl(fds->gravity_final, fds->effector_weights->global_gravity);
+}
+
static bool BKE_fluid_modifier_init(
FluidModifierData *fmd, Depsgraph *depsgraph, Object *ob, Scene *scene, Mesh *me)
{
@@ -502,10 +499,7 @@ static bool BKE_fluid_modifier_init(
/* Set domain dimensions from mesh. */
manta_set_domain_from_mesh(fds, ob, me, true);
/* Set domain gravity, use global gravity if enabled. */
- if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) {
- copy_v3_v3(fds->gravity, scene->physics_settings.gravity);
- }
- mul_v3_fl(fds->gravity, fds->effector_weights->global_gravity);
+ update_final_gravity(fds, scene);
/* Reset domain values. */
zero_v3_int(fds->shift);
zero_v3(fds->shift_f);
@@ -559,7 +553,7 @@ static bool BKE_fluid_modifier_init(
// forward declaration
static void manta_smoke_calc_transparency(FluidDomainSettings *fds, ViewLayer *view_layer);
static float calc_voxel_transp(
- float *result, float *input, int res[3], int *pixel, float *t_ray, float correct);
+ float *result, const float *input, int res[3], int *pixel, float *t_ray, float correct);
static void update_distances(int index,
float *fesh_distances,
BVHTreeFromMesh *tree_data,
@@ -594,8 +588,8 @@ static int get_light(ViewLayer *view_layer, float *light)
static void clamp_bounds_in_domain(FluidDomainSettings *fds,
int min[3],
int max[3],
- float *min_vel,
- float *max_vel,
+ const float *min_vel,
+ const float *max_vel,
int margin,
float dt)
{
@@ -1125,6 +1119,7 @@ static void ensure_obstaclefields(FluidDomainSettings *fds)
if (fds->active_fields & FLUID_DOMAIN_ACTIVE_GUIDE) {
manta_ensure_guiding(fds->fluid, fds->fmd);
}
+ manta_update_pointers(fds->fluid, fds->fmd, false);
}
static void update_obstacleflags(FluidDomainSettings *fds,
@@ -1398,8 +1393,7 @@ static void update_obstacles(Depsgraph *depsgraph,
/* Cannot use static mode with adaptive domain.
* The adaptive domain might expand and only later in the simulations discover the static
* object. */
- bool is_static = is_static_object(effecobj) &&
- ((fds->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN) == 0);
+ bool is_static = is_static_object(effecobj) && !use_adaptivedomain;
/* Check for initialized effector object. */
if ((fmd2->type & MOD_FLUID_TYPE_EFFEC) && fmd2->effector) {
@@ -1830,7 +1824,7 @@ static void sample_mesh(FluidFlowSettings *ffs,
float *velocity_map,
int index,
const int base_res[3],
- float flow_center[3],
+ const float flow_center[3],
BVHTreeFromMesh *tree_data,
const float ray_start[3],
const float *vert_vel,
@@ -2256,15 +2250,15 @@ static void adaptive_domain_adjust(
int x, y, z;
float *density = manta_smoke_get_density(fds->fluid);
float *fuel = manta_smoke_get_fuel(fds->fluid);
- float *bigdensity = manta_smoke_turbulence_get_density(fds->fluid);
- float *bigfuel = manta_smoke_turbulence_get_fuel(fds->fluid);
+ float *bigdensity = manta_noise_get_density(fds->fluid);
+ float *bigfuel = manta_noise_get_fuel(fds->fluid);
float *vx = manta_get_velocity_x(fds->fluid);
float *vy = manta_get_velocity_y(fds->fluid);
float *vz = manta_get_velocity_z(fds->fluid);
int wt_res[3];
if (fds->flags & FLUID_DOMAIN_USE_NOISE && fds->fluid) {
- manta_smoke_turbulence_get_res(fds->fluid, wt_res);
+ manta_noise_get_res(fds->fluid, wt_res);
}
INIT_MINMAX(min_vel, max_vel);
@@ -2603,7 +2597,7 @@ static void ensure_flowsfields(FluidDomainSettings *fds)
manta_smoke_ensure_fire(fds->fluid, fds->fmd);
}
if (fds->active_fields & FLUID_DOMAIN_ACTIVE_COLORS) {
- /* initialize all smoke with "active_color" */
+ /* Initialize all smoke with "active_color". */
manta_smoke_ensure_colors(fds->fluid, fds->fmd);
}
if (fds->type == FLUID_DOMAIN_TYPE_LIQUID &&
@@ -2612,6 +2606,7 @@ static void ensure_flowsfields(FluidDomainSettings *fds)
fds->particle_type & FLUID_DOMAIN_PARTICLE_TRACER)) {
manta_liquid_ensure_sndparts(fds->fluid, fds->fmd);
}
+ manta_update_pointers(fds->fluid, fds->fmd, false);
}
static void update_flowsflags(FluidDomainSettings *fds, Object **flowobjs, int numflowobj)
@@ -2624,7 +2619,7 @@ static void update_flowsflags(FluidDomainSettings *fds, Object **flowobjs, int n
FLUID_DOMAIN_ACTIVE_HEAT | FLUID_DOMAIN_ACTIVE_FIRE);
active_fields &= ~prev_flags;
- /* Monitor active fields based on flow settings */
+ /* Monitor active fields based on flow settings. */
for (flow_index = 0; flow_index < numflowobj; flow_index++) {
Object *flow_ob = flowobjs[flow_index];
FluidModifierData *fmd2 = (FluidModifierData *)BKE_modifiers_findby_type(flow_ob,
@@ -2635,6 +2630,7 @@ static void update_flowsflags(FluidDomainSettings *fds, Object **flowobjs, int n
continue;
}
+ /* Activate specific grids if at least one flow object requires this grid. */
if ((fmd2->type & MOD_FLUID_TYPE_FLOW) && fmd2->flow) {
FluidFlowSettings *ffs = fmd2->flow;
if (!ffs) {
@@ -2655,17 +2651,17 @@ static void update_flowsflags(FluidDomainSettings *fds, Object **flowobjs, int n
continue;
}
- /* activate heat field if flow produces any heat */
- if (ffs->temperature) {
+ /* Activate heat field if a flow object produces any heat. */
+ if (ffs->temperature != 0.0) {
active_fields |= FLUID_DOMAIN_ACTIVE_HEAT;
}
- /* activate fuel field if flow adds any fuel */
- if (ffs->fuel_amount &&
- (ffs->type == FLUID_FLOW_TYPE_FIRE || ffs->type == FLUID_FLOW_TYPE_SMOKEFIRE)) {
+ /* Activate fuel field if a flow object is of fire type. */
+ if (ffs->fuel_amount != 0.0 || ffs->type == FLUID_FLOW_TYPE_FIRE ||
+ ffs->type == FLUID_FLOW_TYPE_SMOKEFIRE) {
active_fields |= FLUID_DOMAIN_ACTIVE_FIRE;
}
- /* activate color field if flows add smoke with varying colors */
- if (ffs->density &&
+ /* Activate color field if flows add smoke with varying colors. */
+ if (ffs->density != 0.0 &&
(ffs->type == FLUID_FLOW_TYPE_SMOKE || ffs->type == FLUID_FLOW_TYPE_SMOKEFIRE)) {
if (!(active_fields & FLUID_DOMAIN_ACTIVE_COLOR_SET)) {
copy_v3_v3(fds->active_color, ffs->color);
@@ -2678,11 +2674,11 @@ static void update_flowsflags(FluidDomainSettings *fds, Object **flowobjs, int n
}
}
}
- /* Monitor active fields based on domain settings */
+ /* Monitor active fields based on domain settings. */
if (fds->type == FLUID_DOMAIN_TYPE_GAS && active_fields & FLUID_DOMAIN_ACTIVE_FIRE) {
- /* heat is always needed for fire */
+ /* Heat is always needed for fire. */
active_fields |= FLUID_DOMAIN_ACTIVE_HEAT;
- /* also activate colors if domain smoke color differs from active color */
+ /* Also activate colors if domain smoke color differs from active color. */
if (!(active_fields & FLUID_DOMAIN_ACTIVE_COLOR_SET)) {
copy_v3_v3(fds->active_color, fds->flame_smoke_color);
active_fields |= FLUID_DOMAIN_ACTIVE_COLOR_SET;
@@ -2931,8 +2927,21 @@ static void update_flowsfluids(struct Depsgraph *depsgraph,
float *velx_initial = manta_get_in_velocity_x(fds->fluid);
float *vely_initial = manta_get_in_velocity_y(fds->fluid);
float *velz_initial = manta_get_in_velocity_z(fds->fluid);
- uint z;
+ float *forcex = manta_get_force_x(fds->fluid);
+ float *forcey = manta_get_force_y(fds->fluid);
+ float *forcez = manta_get_force_z(fds->fluid);
+
+ BLI_assert(forcex && forcey && forcez);
+
+ /* Either all or no components have to exist. */
+ BLI_assert((color_r && color_g && color_b) || (!color_r && !color_g && !color_b));
+ BLI_assert((color_r_in && color_g_in && color_b_in) ||
+ (!color_r_in && !color_g_in && !color_b_in));
+ BLI_assert((velx_initial && vely_initial && velz_initial) ||
+ (!velx_initial && !vely_initial && !velz_initial));
+
+ uint z;
/* Grid reset before writing again. */
for (z = 0; z < fds->res[0] * fds->res[1] * fds->res[2]; z++) {
/* Only reset static phi on first frame, dynamic phi gets reset every time. */
@@ -2956,7 +2965,7 @@ static void update_flowsfluids(struct Depsgraph *depsgraph,
if (heat_in) {
heat_in[z] = heat[z];
}
- if (color_r_in) {
+ if (color_r_in && color_g_in && color_b_in) {
color_r_in[z] = color_r[z];
color_g_in[z] = color_b[z];
color_b_in[z] = color_g[z];
@@ -2968,11 +2977,15 @@ static void update_flowsfluids(struct Depsgraph *depsgraph,
if (emission_in) {
emission_in[z] = 0.0f;
}
- if (velx_initial) {
+ if (velx_initial && vely_initial && velz_initial) {
velx_initial[z] = 0.0f;
vely_initial[z] = 0.0f;
velz_initial[z] = 0.0f;
}
+ /* Reset forces here as update_effectors() is skipped when no external forces are present. */
+ forcex[z] = 0.0f;
+ forcey[z] = 0.0f;
+ forcez[z] = 0.0f;
}
/* Apply emission data for every flow object. */
@@ -3156,13 +3169,13 @@ static void update_effectors_task_cb(void *__restrict userdata,
continue;
}
- /* get velocities from manta grid space and convert to blender units */
+ /* Get velocities from manta grid space and convert to blender units. */
vel[0] = data->velocity_x[index];
vel[1] = data->velocity_y[index];
vel[2] = data->velocity_z[index];
mul_v3_fl(vel, fds->dx);
- /* convert vel to global space */
+ /* Convert vel to global space. */
mag = len_v3(vel);
mul_mat3_m4_v3(fds->obmat, vel);
normalize_v3(vel);
@@ -3173,18 +3186,18 @@ static void update_effectors_task_cb(void *__restrict userdata,
voxel_center[2] = fds->p0[2] + fds->cell_size[2] * ((float)(z + fds->res_min[2]) + 0.5f);
mul_m4_v3(fds->obmat, voxel_center);
- /* do effectors */
+ /* Do effectors. */
pd_point_from_loc(data->scene, voxel_center, vel, index, &epoint);
BKE_effectors_apply(
data->effectors, NULL, fds->effector_weights, &epoint, retvel, NULL, NULL);
- /* convert retvel to local space */
+ /* Convert retvel to local space. */
mag = len_v3(retvel);
mul_mat3_m4_v3(fds->imat, retvel);
normalize_v3(retvel);
mul_v3_fl(retvel, mag);
- /* constrain forces to interval -1 to 1 */
+ /* Constrain forces to interval -1 to 1. */
data->force_x[index] = min_ff(max_ff(-1.0f, retvel[0] * 0.2f), 1.0f);
data->force_y[index] = min_ff(max_ff(-1.0f, retvel[1] * 0.2f), 1.0f);
data->force_z[index] = min_ff(max_ff(-1.0f, retvel[2] * 0.2f), 1.0f);
@@ -3328,17 +3341,13 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Obj
mverts->co[1] = manta_liquid_get_vertex_y_at(fds->fluid, i);
mverts->co[2] = manta_liquid_get_vertex_z_at(fds->fluid, i);
- /* If reading raw data directly from manta, normalize now (e.g. during replay mode).
- * If reading data from files from disk, omit this normalization. */
- if (!manta_liquid_mesh_from_file(fds->fluid)) {
- // normalize to unit cube around 0
- mverts->co[0] -= ((float)fds->res[0] * fds->mesh_scale) * 0.5f;
- mverts->co[1] -= ((float)fds->res[1] * fds->mesh_scale) * 0.5f;
- mverts->co[2] -= ((float)fds->res[2] * fds->mesh_scale) * 0.5f;
- mverts->co[0] *= fds->dx / fds->mesh_scale;
- mverts->co[1] *= fds->dx / fds->mesh_scale;
- mverts->co[2] *= fds->dx / fds->mesh_scale;
- }
+ /* Adjust coordinates from Mantaflow to match viewport scaling. */
+ float tmp[3] = {(float)fds->res[0], (float)fds->res[1], (float)fds->res[2]};
+ /* Scale to unit cube around 0. */
+ mul_v3_fl(tmp, fds->mesh_scale * 0.5f);
+ sub_v3_v3(mverts->co, tmp);
+ /* Apply scaling of domain object. */
+ mul_v3_fl(mverts->co, fds->dx / fds->mesh_scale);
mul_v3_v3(mverts->co, co_scale);
add_v3_v3(mverts->co, co_offset);
@@ -3628,14 +3637,16 @@ static int manta_step(
fds->time_per_frame = time_per_frame;
fds->time_total = time_total;
}
+
/* Total time must not exceed framecount times framelength. Correct tiny errors here. */
CLAMP(fds->time_total, fds->time_total, time_total_old + fds->frame_length);
+ /* Compute shadow grid for gas simulations. Make sure to skip if bake job was canceled early. */
if (fds->type == FLUID_DOMAIN_TYPE_GAS && result) {
manta_smoke_calc_transparency(fds, DEG_get_evaluated_view_layer(depsgraph));
}
- BLI_mutex_unlock(&object_update_lock);
+ BLI_mutex_unlock(&object_update_lock);
return result;
}
@@ -3727,29 +3738,35 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd,
int mode = fds->cache_type;
/* Do not process modifier if current frame is out of cache range. */
+ bool escape = false;
switch (mode) {
case FLUID_DOMAIN_CACHE_ALL:
case FLUID_DOMAIN_CACHE_MODULAR:
if (fds->cache_frame_offset > 0) {
if (scene_framenr < fds->cache_frame_start ||
scene_framenr > fds->cache_frame_end + fds->cache_frame_offset) {
- return;
+ escape = true;
}
}
else {
if (scene_framenr < fds->cache_frame_start + fds->cache_frame_offset ||
scene_framenr > fds->cache_frame_end) {
- return;
+ escape = true;
}
}
break;
case FLUID_DOMAIN_CACHE_REPLAY:
default:
if (scene_framenr < fds->cache_frame_start || scene_framenr > fds->cache_frame_end) {
- return;
+ escape = true;
}
break;
}
+ /* If modifier will not be processed, update/flush pointers from (old) fluid object once more. */
+ if (escape && fds->fluid) {
+ manta_update_pointers(fds->fluid, fmd, true);
+ return;
+ }
/* Reset fluid if no fluid present. Also resets active fields. */
if (!fds->fluid) {
@@ -3808,10 +3825,7 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd,
fds->time_per_frame = 0;
/* Ensure that gravity is copied over every frame (could be keyframed). */
- if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) {
- copy_v3_v3(fds->gravity, scene->physics_settings.gravity);
- mul_v3_fl(fds->gravity, fds->effector_weights->global_gravity);
- }
+ update_final_gravity(fds, scene);
int next_frame = scene_framenr + 1;
int prev_frame = scene_framenr - 1;
@@ -3831,9 +3845,8 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd,
floater = fds->particle_type & FLUID_DOMAIN_PARTICLE_FOAM;
bool with_resumable_cache = fds->flags & FLUID_DOMAIN_USE_RESUMABLE_CACHE;
- bool with_script, with_adaptive, with_noise, with_mesh, with_particles, with_guide;
+ bool with_script, with_noise, with_mesh, with_particles, with_guide;
with_script = fds->flags & FLUID_DOMAIN_EXPORT_MANTA_SCRIPT;
- with_adaptive = fds->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN;
with_noise = fds->flags & FLUID_DOMAIN_USE_NOISE;
with_mesh = fds->flags & FLUID_DOMAIN_USE_MESH;
with_guide = fds->flags & FLUID_DOMAIN_USE_GUIDE;
@@ -3845,7 +3858,15 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd,
has_mesh = manta_has_mesh(fds->fluid, fmd, scene_framenr);
has_particles = manta_has_particles(fds->fluid, fmd, scene_framenr);
has_guide = manta_has_guiding(fds->fluid, fmd, scene_framenr, guide_parent);
- has_config = false;
+ has_config = manta_read_config(fds->fluid, fmd, scene_framenr);
+
+ /* When reading data from cache (has_config == true) ensure that active fields are allocated.
+ * update_flowsflags() and update_obstacleflags() will not find flow sources hidden from renders.
+ * See also: T72192. */
+ if (has_config) {
+ ensure_flowsfields(fds);
+ ensure_obstaclefields(fds);
+ }
bool baking_data, baking_noise, baking_mesh, baking_particles, baking_guide;
baking_data = fds->cache_flag & FLUID_DOMAIN_BAKING_DATA;
@@ -3950,13 +3971,21 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd,
break;
}
+ /* Adaptive domain needs to know about current state, so save it here. */
+ copy_v3_v3_int(o_res, fds->res);
+ copy_v3_v3_int(o_min, fds->res_min);
+ copy_v3_v3_int(o_max, fds->res_max);
+ copy_v3_v3_int(o_shift, fds->shift);
+
bool read_partial = false, read_all = false;
/* Try to read from cache and keep track of read success. */
if (read_cache) {
/* Read mesh cache. */
if (with_liquid && with_mesh) {
- has_config = manta_read_config(fds->fluid, fmd, mesh_frame);
+ if (mesh_frame != scene_framenr) {
+ has_config = manta_read_config(fds->fluid, fmd, mesh_frame);
+ }
/* Update mesh data from file is faster than via Python (manta_read_mesh()). */
has_mesh = manta_read_mesh(fds->fluid, fmd, mesh_frame);
@@ -3964,7 +3993,9 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd,
/* Read particles cache. */
if (with_liquid && with_particles) {
- has_config = manta_read_config(fds->fluid, fmd, particles_frame);
+ if (particles_frame != scene_framenr) {
+ has_config = manta_read_config(fds->fluid, fmd, particles_frame);
+ }
read_partial = !baking_data && !baking_particles && next_particles;
read_all = !read_partial && with_resumable_cache;
@@ -3979,38 +4010,29 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd,
/* Read noise and data cache */
if (with_smoke && with_noise) {
- has_config = manta_read_config(fds->fluid, fmd, noise_frame);
+ if (noise_frame != scene_framenr) {
+ has_config = manta_read_config(fds->fluid, fmd, noise_frame);
+ }
/* Only reallocate when just reading cache or when resuming during bake. */
- if ((!baking_noise || (baking_noise && resume_noise)) && has_config &&
- manta_needs_realloc(fds->fluid, fmd)) {
- BKE_fluid_reallocate_fluid(fds, fds->res, 1);
+ if (has_data && has_config && manta_needs_realloc(fds->fluid, fmd)) {
+ BKE_fluid_reallocate_copy_fluid(
+ fds, o_res, fds->res, o_min, fds->res_min, o_max, o_shift, fds->shift);
}
read_partial = !baking_data && !baking_noise && next_noise;
read_all = !read_partial && with_resumable_cache;
has_noise = manta_read_noise(fds->fluid, fmd, noise_frame, read_all);
- /* When using the adaptive domain, copy all data that was read to a new fluid object. */
- if (with_adaptive && baking_noise) {
- /* Adaptive domain needs to know about current state, so save it, then copy. */
- copy_v3_v3_int(o_res, fds->res);
- copy_v3_v3_int(o_min, fds->res_min);
- copy_v3_v3_int(o_max, fds->res_max);
- copy_v3_v3_int(o_shift, fds->shift);
- if (has_config && manta_needs_realloc(fds->fluid, fmd)) {
- BKE_fluid_reallocate_copy_fluid(
- fds, o_res, fds->res, o_min, fds->res_min, o_max, o_shift, fds->shift);
- }
- }
-
read_partial = !baking_data && !baking_noise && next_data && next_noise;
read_all = !read_partial && with_resumable_cache;
has_data = manta_read_data(fds->fluid, fmd, data_frame, read_all);
}
/* Read data cache only */
else {
- has_config = manta_read_config(fds->fluid, fmd, data_frame);
+ if (data_frame != scene_framenr) {
+ has_config = manta_read_config(fds->fluid, fmd, data_frame);
+ }
if (with_smoke) {
/* Read config and realloc fluid object if needed. */
@@ -4095,6 +4117,9 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd,
}
}
+ /* Ensure that fluid pointers are always up to date at the end of modifier processing. */
+ manta_update_pointers(fds->fluid, fmd, false);
+
fds->flags &= ~FLUID_DOMAIN_FILE_LOAD;
fmd->time = scene_framenr;
}
@@ -4118,43 +4143,47 @@ static void BKE_fluid_modifier_process(
struct Mesh *BKE_fluid_modifier_do(
FluidModifierData *fmd, Depsgraph *depsgraph, Scene *scene, Object *ob, Mesh *me)
{
- /* Lock so preview render does not read smoke data while it gets modified. */
- if ((fmd->type & MOD_FLUID_TYPE_DOMAIN) && fmd->domain) {
- BLI_rw_mutex_lock(fmd->domain->fluid_mutex, THREAD_LOCK_WRITE);
- }
-
- BKE_fluid_modifier_process(fmd, depsgraph, scene, ob, me);
-
- if ((fmd->type & MOD_FLUID_TYPE_DOMAIN) && fmd->domain) {
- BLI_rw_mutex_unlock(fmd->domain->fluid_mutex);
- }
-
/* Optimization: Do not update viewport during bakes (except in replay mode)
* Reason: UI is locked and updated liquid / smoke geometry is not visible anyways. */
bool needs_viewport_update = false;
- if (fmd->domain) {
- FluidDomainSettings *fds = fmd->domain;
- /* Always update viewport in cache replay mode. */
- if (fds->cache_type == FLUID_DOMAIN_CACHE_REPLAY ||
- fds->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN) {
- needs_viewport_update = true;
+ /* Optimization: Only process modifier if object is not being altered. */
+ if (!G.moving) {
+ /* Lock so preview render does not read smoke data while it gets modified. */
+ if ((fmd->type & MOD_FLUID_TYPE_DOMAIN) && fmd->domain) {
+ BLI_rw_mutex_lock(fmd->domain->fluid_mutex, THREAD_LOCK_WRITE);
}
- /* In other cache modes, only update the viewport when no bake is going on. */
- else {
- bool with_mesh;
- with_mesh = fds->flags & FLUID_DOMAIN_USE_MESH;
- bool baking_data, baking_noise, baking_mesh, baking_particles, baking_guide;
- baking_data = fds->cache_flag & FLUID_DOMAIN_BAKING_DATA;
- baking_noise = fds->cache_flag & FLUID_DOMAIN_BAKING_NOISE;
- baking_mesh = fds->cache_flag & FLUID_DOMAIN_BAKING_MESH;
- baking_particles = fds->cache_flag & FLUID_DOMAIN_BAKING_PARTICLES;
- baking_guide = fds->cache_flag & FLUID_DOMAIN_BAKING_GUIDE;
-
- if (with_mesh && !baking_data && !baking_noise && !baking_mesh && !baking_particles &&
- !baking_guide) {
+
+ BKE_fluid_modifier_process(fmd, depsgraph, scene, ob, me);
+
+ if ((fmd->type & MOD_FLUID_TYPE_DOMAIN) && fmd->domain) {
+ BLI_rw_mutex_unlock(fmd->domain->fluid_mutex);
+ }
+
+ if (fmd->domain) {
+ FluidDomainSettings *fds = fmd->domain;
+
+ /* Always update viewport in cache replay mode. */
+ if (fds->cache_type == FLUID_DOMAIN_CACHE_REPLAY ||
+ fds->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN) {
needs_viewport_update = true;
}
+ /* In other cache modes, only update the viewport when no bake is going on. */
+ else {
+ bool with_mesh;
+ with_mesh = fds->flags & FLUID_DOMAIN_USE_MESH;
+ bool baking_data, baking_noise, baking_mesh, baking_particles, baking_guide;
+ baking_data = fds->cache_flag & FLUID_DOMAIN_BAKING_DATA;
+ baking_noise = fds->cache_flag & FLUID_DOMAIN_BAKING_NOISE;
+ baking_mesh = fds->cache_flag & FLUID_DOMAIN_BAKING_MESH;
+ baking_particles = fds->cache_flag & FLUID_DOMAIN_BAKING_PARTICLES;
+ baking_guide = fds->cache_flag & FLUID_DOMAIN_BAKING_GUIDE;
+
+ if (with_mesh && !baking_data && !baking_noise && !baking_mesh && !baking_particles &&
+ !baking_guide) {
+ needs_viewport_update = true;
+ }
+ }
}
}
@@ -4196,7 +4225,7 @@ struct Mesh *BKE_fluid_modifier_do(
}
static float calc_voxel_transp(
- float *result, float *input, int res[3], int *pixel, float *t_ray, float correct)
+ float *result, const float *input, int res[3], int *pixel, float *t_ray, float correct)
{
const size_t index = manta_get_index(pixel[0], res[0], pixel[1], res[1], pixel[2]);
@@ -4311,7 +4340,7 @@ static void manta_smoke_calc_transparency(FluidDomainSettings *fds, ViewLayer *v
{
float bv[6] = {0};
float light[3];
- int a, z, slabsize = fds->res[0] * fds->res[1], size = fds->res[0] * fds->res[1] * fds->res[2];
+ int slabsize = fds->res[0] * fds->res[1];
float *density = manta_smoke_get_density(fds->fluid);
float *shadow = manta_smoke_get_shadow(fds->fluid);
float correct = -7.0f * fds->dx;
@@ -4320,54 +4349,49 @@ static void manta_smoke_calc_transparency(FluidDomainSettings *fds, ViewLayer *v
return;
}
- /* convert light pos to sim cell space */
+ /* Convert light pos to sim cell space. */
mul_m4_v3(fds->imat, light);
light[0] = (light[0] - fds->p0[0]) / fds->cell_size[0] - 0.5f - (float)fds->res_min[0];
light[1] = (light[1] - fds->p0[1]) / fds->cell_size[1] - 0.5f - (float)fds->res_min[1];
light[2] = (light[2] - fds->p0[2]) / fds->cell_size[2] - 0.5f - (float)fds->res_min[2];
- for (a = 0; a < size; a++) {
- shadow[a] = -1.0f;
- }
-
- /* calculate domain bounds in sim cell space */
+ /* Calculate domain bounds in sim cell space. */
// 0,2,4 = 0.0f
bv[1] = (float)fds->res[0]; // x
bv[3] = (float)fds->res[1]; // y
bv[5] = (float)fds->res[2]; // z
- for (z = 0; z < fds->res[2]; z++) {
+ for (int z = 0; z < fds->res[2]; z++) {
size_t index = z * slabsize;
- int x, y;
- for (y = 0; y < fds->res[1]; y++) {
- for (x = 0; x < fds->res[0]; x++, index++) {
+ for (int y = 0; y < fds->res[1]; y++) {
+ for (int x = 0; x < fds->res[0]; x++, index++) {
float voxel_center[3];
float pos[3];
int cell[3];
float t_ray = 1.0;
- if (shadow[index] >= 0.0f) {
- continue;
- }
+ /* Reset shadow value.*/
+ shadow[index] = -1.0f;
+
voxel_center[0] = (float)x;
voxel_center[1] = (float)y;
voxel_center[2] = (float)z;
- // get starting cell (light pos)
+ /* Get starting cell (light pos). */
if (BLI_bvhtree_bb_raycast(bv, light, voxel_center, pos) > FLT_EPSILON) {
- // we're outside -> use point on side of domain
+ /* We're outside -> use point on side of domain. */
cell[0] = (int)floor(pos[0]);
cell[1] = (int)floor(pos[1]);
cell[2] = (int)floor(pos[2]);
}
else {
- // we're inside -> use light itself
+ /* We're inside -> use light itself. */
cell[0] = (int)floor(light[0]);
cell[1] = (int)floor(light[1]);
cell[2] = (int)floor(light[2]);
}
- /* clamp within grid bounds */
+ /* Clamp within grid bounds */
CLAMP(cell[0], 0, fds->res[0] - 1);
CLAMP(cell[1], 0, fds->res[1] - 1);
CLAMP(cell[2], 0, fds->res[2] - 1);
@@ -4385,7 +4409,7 @@ static void manta_smoke_calc_transparency(FluidDomainSettings *fds, ViewLayer *v
fds->res,
correct);
- // convention -> from a RGBA float array, use G value for t_ray
+ /* Convention -> from a RGBA float array, use G value for t_ray. */
shadow[index] = t_ray;
}
}
@@ -4879,6 +4903,7 @@ void BKE_fluid_modifier_create_type_data(struct FluidModifierData *fmd)
fmd->domain->particle_radius = 1.0f;
fmd->domain->particle_band_width = 3.0f;
fmd->domain->fractions_threshold = 0.05f;
+ fmd->domain->sys_particle_maximum = 0;
/* diffusion options*/
fmd->domain->surface_tension = 0.0f;
@@ -5123,6 +5148,7 @@ void BKE_fluid_modifier_copy(const struct FluidModifierData *fmd,
tfds->particle_radius = fds->particle_radius;
tfds->particle_band_width = fds->particle_band_width;
tfds->fractions_threshold = fds->fractions_threshold;
+ tfds->sys_particle_maximum = fds->sys_particle_maximum;
/* diffusion options*/
tfds->surface_tension = fds->surface_tension;
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index dfa5ff6975f..958acf0589b 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -797,7 +797,7 @@ static bool vfont_to_curve(Object *ob,
}
else {
char32_t *mem_tmp;
- slen = cu->len_wchar;
+ slen = cu->len_char32;
/* Create unicode string */
mem_tmp = MEM_malloc_arrayN((slen + 1), sizeof(*mem_tmp), "convertedmem");
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 6a9511d8275..eeb55c44d6e 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -681,10 +681,10 @@ void BKE_gpencil_stroke_weights_duplicate(bGPDstroke *gps_src, bGPDstroke *gps_d
}
/**
- * Make a copy of a given gpencil stroke.
- * \param gps_src: Source grease pencil strokeyes
- * \param dup_points: Duplicate points data
- * \return Pointer to new stroke
+ * Make a copy of a given grease-pencil stroke.
+ * \param gps_src: Source grease pencil strokes.
+ * \param dup_points: Duplicate points data.
+ * \return Pointer to new stroke.
*/
bGPDstroke *BKE_gpencil_stroke_duplicate(bGPDstroke *gps_src, const bool dup_points)
{
@@ -1512,12 +1512,12 @@ int BKE_gpencil_object_material_ensure(Main *bmain, Object *ob, Material *materi
}
/**
- * Creates a new gpencil material and assigns it to object.
+ * Creates a new grease-pencil material and assigns it to object.
* \param bmain: Main pointer
* \param ob: Grease pencil object
* \param name: Material name
* \param r_index: value is set to zero based index of the new material if \a r_index is not NULL.
- * \return Materil pointer
+ * \return Material pointer.
*/
Material *BKE_gpencil_object_material_new(Main *bmain, Object *ob, const char *name, int *r_index)
{
@@ -1555,7 +1555,7 @@ Material *BKE_gpencil_object_material_from_brush_get(Object *ob, Brush *brush)
* Returns the material index for a brush with respect to its pinned state.
* \param ob: Grease pencil object
* \param brush: Brush
- * \return Materil index
+ * \return Material index.
*/
int BKE_gpencil_object_material_get_index_from_brush(Object *ob, Brush *brush)
{
@@ -1571,8 +1571,7 @@ int BKE_gpencil_object_material_get_index_from_brush(Object *ob, Brush *brush)
* Guaranteed to return a material assigned to object. Returns never NULL.
* \param bmain: Main pointer
* \param ob: Grease pencil object
- * \param ts: Toolsettings
- * \return Material pointer
+ * \return Material pointer.
*/
Material *BKE_gpencil_object_material_ensure_from_active_input_toolsettings(Main *bmain,
Object *ob,
@@ -1590,7 +1589,7 @@ Material *BKE_gpencil_object_material_ensure_from_active_input_toolsettings(Main
/**
* Guaranteed to return a material assigned to object. Returns never NULL.
* \param bmain: Main pointer
- * \param ob: Grease pencil obejct
+ * \param ob: Grease pencil object.
* \param brush: Brush
* \return Material pointer
*/
@@ -1783,7 +1782,8 @@ float BKE_gpencil_multiframe_falloff_calc(
value = BKE_curvemapping_evaluateF(cur_falloff, 0, fnum + 0.5f);
}
else {
- value = 1.0f;
+ /* Center of the curve. */
+ value = BKE_curvemapping_evaluateF(cur_falloff, 0, 0.5f);
}
return value;
@@ -2330,8 +2330,8 @@ void BKE_gpencil_visible_stroke_iter(ViewLayer *view_layer,
/**
* Update original pointers in evaluated frame.
- * \param gpf_orig: Original greas epencil frame
- * \param gpf_eval: Evaluated grease pencil frame
+ * \param gpf_orig: Original grease-pencil frame.
+ * \param gpf_eval: Evaluated grease pencil frame.
*/
void BKE_gpencil_frame_original_pointers_update(const struct bGPDframe *gpf_orig,
const struct bGPDframe *gpf_eval)
diff --git a/source/blender/blenkernel/intern/gpencil_curve.c b/source/blender/blenkernel/intern/gpencil_curve.c
index 66e9e2184c1..a7adbed6c4b 100644
--- a/source/blender/blenkernel/intern/gpencil_curve.c
+++ b/source/blender/blenkernel/intern/gpencil_curve.c
@@ -363,7 +363,7 @@ static void gpencil_convert_spline(Main *bmain,
BKE_nurb_makeCurve(nu, coord_array, NULL, NULL, NULL, resolu, sizeof(float[3]));
/* Allocate memory for storage points. */
- gps->totpoints = nurb_points - 1;
+ gps->totpoints = nurb_points;
gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
/* Add points. */
diff --git a/source/blender/blenkernel/intern/gpencil_geom.c b/source/blender/blenkernel/intern/gpencil_geom.c
index 49940c2d466..14eb6bb4f4c 100644
--- a/source/blender/blenkernel/intern/gpencil_geom.c
+++ b/source/blender/blenkernel/intern/gpencil_geom.c
@@ -33,6 +33,7 @@
#include "BLI_blenlib.h"
#include "BLI_ghash.h"
+#include "BLI_hash.h"
#include "BLI_math_vector.h"
#include "BLI_polyfill_2d.h"
@@ -989,7 +990,7 @@ bool BKE_gpencil_stroke_smooth_uv(bGPDstroke *gps, int point_index, float influe
* \param points: Array of grease pencil points (3D)
* \param totpoints: Total of points
* \param points2d: Result array of 2D points
- * \param r_direction: Return Concave (-1), Convex (1), or Autodetect (0)
+ * \param r_direction: Return Concave (-1), Convex (1), or Auto-detect (0)
*/
void BKE_gpencil_stroke_2d_flat(const bGPDspoint *points,
int totpoints,
@@ -1043,7 +1044,7 @@ void BKE_gpencil_stroke_2d_flat(const bGPDspoint *points,
points2d[i][1] = dot_v3v3(loc, locy);
}
- /* Concave (-1), Convex (1), or Autodetect (0)? */
+ /* Concave (-1), Convex (1), or Auto-detect (0)? */
*r_direction = (int)locy[2];
}
@@ -1056,7 +1057,7 @@ void BKE_gpencil_stroke_2d_flat(const bGPDspoint *points,
* \param totpoints: Total points
* \param points2d: Result array of 2D points
* \param scale: Scale factor
- * \param r_direction: Return Concave (-1), Convex (1), or Autodetect (0)
+ * \param r_direction: Return Concave (-1), Convex (1), or Auto-detect (0)
*/
void BKE_gpencil_stroke_2d_flat_ref(const bGPDspoint *ref_points,
int ref_totpoints,
@@ -1138,7 +1139,7 @@ void BKE_gpencil_stroke_2d_flat_ref(const bGPDspoint *ref_points,
points2d[i][1] = dot_v3v3(loc, locy);
}
- /* Concave (-1), Convex (1), or Autodetect (0)? */
+ /* Concave (-1), Convex (1), or Auto-detect (0)? */
*r_direction = (int)locy[2];
}
@@ -1146,7 +1147,7 @@ void BKE_gpencil_stroke_2d_flat_ref(const bGPDspoint *ref_points,
static void gpencil_calc_stroke_fill_uv(const float (*points2d)[2],
bGPDstroke *gps,
const float minv[2],
- float maxv[2],
+ const float maxv[2],
float (*r_uv)[2])
{
const float s = sin(gps->uv_rotation);
@@ -1289,9 +1290,9 @@ void BKE_gpencil_stroke_geometry_update(bGPDstroke *gps)
/**
* Calculate grease pencil stroke length.
- * @param gps Grease pencil stroke
- * @param use_3d Set to true to use 3D points
- * @return Length of the stroke
+ * \param gps: Grease pencil stroke
+ * \param use_3d: Set to true to use 3D points
+ * \return Length of the stroke
*/
float BKE_gpencil_stroke_length(const bGPDstroke *gps, bool use_3d)
{
@@ -2088,6 +2089,7 @@ static int gpencil_walk_edge(GHash *v_table,
static void gpencil_generate_edgeloops(Object *ob,
bGPDframe *gpf_stroke,
+ int stroke_mat_index,
const float angle,
const int thickness,
const float offset,
@@ -2175,7 +2177,7 @@ static void gpencil_generate_edgeloops(Object *ob,
/* Create Stroke. */
bGPDstroke *gps_stroke = BKE_gpencil_stroke_add(
- gpf_stroke, 0, array_len + 1, thickness * thickness, false);
+ gpf_stroke, MAX2(stroke_mat_index, 0), array_len + 1, thickness * thickness, false);
/* Create first segment. */
float fpt[3];
@@ -2258,6 +2260,19 @@ static Material *gpencil_add_material(Main *bmain,
return mat_gp;
}
+static int gpencil_material_find_index_by_name_prefix(Object *ob, const char *name_prefix)
+{
+ const int name_prefix_len = strlen(name_prefix);
+ for (int i = 0; i < ob->totcol; i++) {
+ Material *ma = BKE_object_material_get(ob, i + 1);
+ if ((ma != NULL) && (ma->gp_style != NULL) &&
+ (STREQLEN(ma->id.name + 2, name_prefix, name_prefix_len))) {
+ return i;
+ }
+ }
+
+ return -1;
+}
/**
* Convert a mesh object to grease pencil stroke.
*
@@ -2273,6 +2288,7 @@ static Material *gpencil_add_material(Main *bmain,
* \param frame_offset: Destination frame number offset.
* \param use_seams: Only export seam edges.
* \param use_faces: Export faces as filled strokes.
+ * \simple_material: Create only 2 materials (stroke and fill)
*/
void BKE_gpencil_convert_mesh(Main *bmain,
Depsgraph *depsgraph,
@@ -2285,7 +2301,8 @@ void BKE_gpencil_convert_mesh(Main *bmain,
const float matrix[4][4],
const int frame_offset,
const bool use_seams,
- const bool use_faces)
+ const bool use_faces,
+ const bool simple_material)
{
if (ELEM(NULL, ob_gp, ob_mesh) || (ob_gp->type != OB_GPENCIL) || (ob_gp->data == NULL)) {
return;
@@ -2300,6 +2317,8 @@ void BKE_gpencil_convert_mesh(Main *bmain,
MLoop *mloop = me_eval->mloop;
int mpoly_len = me_eval->totpoly;
int i;
+ int stroke_mat_index = gpencil_material_find_index_by_name_prefix(ob_gp, "Stroke");
+ int fill_mat_index = gpencil_material_find_index_by_name_prefix(ob_gp, "Fill");
/* If the object has enough materials means it was created in a previous step. */
const bool create_mat = ((ob_gp->totcol > 0) && (ob_gp->totcol >= ob_mesh->totcol)) ? false :
@@ -2314,12 +2333,15 @@ void BKE_gpencil_convert_mesh(Main *bmain,
const float default_colors[2][4] = {{0.0f, 0.0f, 0.0f, 1.0f}, {0.7f, 0.7f, 0.7f, 1.0f}};
/* Create stroke material. */
if (create_mat) {
- gpencil_add_material(bmain, ob_gp, "Stroke", default_colors[0], true, false, &r_idx);
+ if (stroke_mat_index == -1) {
+ gpencil_add_material(bmain, ob_gp, "Stroke", default_colors[0], true, false, &r_idx);
+ stroke_mat_index = ob_gp->totcol - 1;
+ }
}
/* Export faces as filled strokes. */
if (use_faces) {
if (create_mat) {
- /* Find a material slot with material assigned */
+ /* Find a material slot with material assigned. */
bool material_found = false;
for (i = 0; i < ob_mesh->totcol; i++) {
Material *ma = BKE_object_material_get(ob_mesh, i + 1);
@@ -2329,9 +2351,12 @@ void BKE_gpencil_convert_mesh(Main *bmain,
}
}
- /* If no materials, create a simple fill. */
- if (!material_found) {
- gpencil_add_material(bmain, ob_gp, "Fill", default_colors[1], false, true, &r_idx);
+ /* If no materials or use simple materials, create a simple fill. */
+ if ((!material_found) || (simple_material)) {
+ if (fill_mat_index == -1) {
+ gpencil_add_material(bmain, ob_gp, "Fill", default_colors[1], false, true, &r_idx);
+ fill_mat_index = ob_gp->totcol - 1;
+ }
}
else {
/* Create all materials for fill. */
@@ -2359,8 +2384,11 @@ void BKE_gpencil_convert_mesh(Main *bmain,
for (i = 0, mp = mpoly; i < mpoly_len; i++, mp++) {
MLoop *ml = &mloop[mp->loopstart];
/* Create fill stroke. */
- bGPDstroke *gps_fill = BKE_gpencil_stroke_add(
- gpf_fill, mp->mat_nr + 1, mp->totloop, 10, false);
+ int mat_idx = (simple_material) || (mp->mat_nr + 1 > ob_gp->totcol - 1) ?
+ MAX2(fill_mat_index, 0) :
+ mp->mat_nr + 1;
+
+ bGPDstroke *gps_fill = BKE_gpencil_stroke_add(gpf_fill, mat_idx, mp->totloop, 10, false);
gps_fill->flag |= GP_STROKE_CYCLIC;
/* Add points to strokes. */
@@ -2387,7 +2415,8 @@ void BKE_gpencil_convert_mesh(Main *bmain,
}
bGPDframe *gpf_stroke = BKE_gpencil_layer_frame_get(
gpl_stroke, CFRA + frame_offset, GP_GETFRAME_ADD_NEW);
- gpencil_generate_edgeloops(ob_eval, gpf_stroke, angle, thickness, offset, matrix, use_seams);
+ gpencil_generate_edgeloops(
+ ob_eval, gpf_stroke, stroke_mat_index, angle, thickness, offset, matrix, use_seams);
/* Tag for recalculation */
DEG_id_tag_update(&gpd->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
@@ -2395,10 +2424,10 @@ void BKE_gpencil_convert_mesh(Main *bmain,
/**
* Apply grease pencil Transforms.
- * @param gpd Grease pencil data-block
- * @param mat Transformation matrix
+ * \param gpd: Grease pencil data-block
+ * \param mat: Transformation matrix
*/
-void BKE_gpencil_transform(bGPdata *gpd, float mat[4][4])
+void BKE_gpencil_transform(bGPdata *gpd, const float mat[4][4])
{
if (gpd == NULL) {
return;
@@ -2430,4 +2459,152 @@ void BKE_gpencil_transform(bGPdata *gpd, float mat[4][4])
}
}
}
+
+/* Used for "move only origins" in object_data_transform.c */
+int BKE_gpencil_stroke_point_count(bGPdata *gpd)
+{
+ int total_points = 0;
+
+ if (gpd == NULL) {
+ return 0;
+ }
+
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ /* FIXME: For now, we just skip parented layers.
+ * Otherwise, we have to update each frame to find
+ * the current parent position/effects.
+ */
+ if (gpl->parent) {
+ continue;
+ }
+
+ LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ total_points += gps->totpoints;
+ }
+ }
+ }
+ return total_points;
+}
+
+/* Used for "move only origins" in object_data_transform.c */
+void BKE_gpencil_point_coords_get(bGPdata *gpd, GPencilPointCoordinates *elem_data)
+{
+ if (gpd == NULL) {
+ return;
+ }
+
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ /* FIXME: For now, we just skip parented layers.
+ * Otherwise, we have to update each frame to find
+ * the current parent position/effects.
+ */
+ if (gpl->parent) {
+ continue;
+ }
+
+ LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ bGPDspoint *pt;
+ int i;
+
+ for (pt = gps->points, i = 0; i < gps->totpoints; pt++, i++) {
+ copy_v3_v3(elem_data->co, &pt->x);
+ elem_data->pressure = pt->pressure;
+ elem_data++;
+ }
+ }
+ }
+ }
+}
+
+/* Used for "move only origins" in object_data_transform.c */
+void BKE_gpencil_point_coords_apply(bGPdata *gpd, const GPencilPointCoordinates *elem_data)
+{
+ if (gpd == NULL) {
+ return;
+ }
+
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ /* FIXME: For now, we just skip parented layers.
+ * Otherwise, we have to update each frame to find
+ * the current parent position/effects.
+ */
+ if (gpl->parent) {
+ continue;
+ }
+
+ LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ bGPDspoint *pt;
+ int i;
+
+ for (pt = gps->points, i = 0; i < gps->totpoints; pt++, i++) {
+ copy_v3_v3(&pt->x, elem_data->co);
+ pt->pressure = elem_data->pressure;
+ elem_data++;
+ }
+
+ /* Distortion may mean we need to re-triangulate. */
+ BKE_gpencil_stroke_geometry_update(gps);
+ }
+ }
+ }
+}
+
+/* Used for "move only origins" in object_data_transform.c */
+void BKE_gpencil_point_coords_apply_with_mat4(bGPdata *gpd,
+ const GPencilPointCoordinates *elem_data,
+ const float mat[4][4])
+{
+ if (gpd == NULL) {
+ return;
+ }
+
+ const float scalef = mat4_to_scale(mat);
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ /* FIXME: For now, we just skip parented layers.
+ * Otherwise, we have to update each frame to find
+ * the current parent position/effects.
+ */
+ if (gpl->parent) {
+ continue;
+ }
+
+ LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ bGPDspoint *pt;
+ int i;
+
+ for (pt = gps->points, i = 0; i < gps->totpoints; pt++, i++) {
+ mul_v3_m4v3(&pt->x, mat, elem_data->co);
+ pt->pressure = elem_data->pressure * scalef;
+ elem_data++;
+ }
+
+ /* Distortion may mean we need to re-triangulate. */
+ BKE_gpencil_stroke_geometry_update(gps);
+ }
+ }
+ }
+}
+
+/**
+ * Set a random color to stroke using vertex color.
+ * \param gps: Stroke
+ */
+void BKE_gpencil_stroke_set_random_color(bGPDstroke *gps)
+{
+ BLI_assert(gps->totpoints > 0);
+
+ float color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+ bGPDspoint *pt = &gps->points[0];
+ color[0] *= BLI_hash_int_01(BLI_hash_int_2d(gps->totpoints / 5, pt->x + pt->z));
+ color[1] *= BLI_hash_int_01(BLI_hash_int_2d(gps->totpoints + pt->x, pt->y * pt->z + pt->x));
+ color[2] *= BLI_hash_int_01(BLI_hash_int_2d(gps->totpoints - pt->x, pt->z * pt->x + pt->y));
+ for (int i = 0; i < gps->totpoints; i++) {
+ pt = &gps->points[i];
+ copy_v4_v4(pt->vert_color, color);
+ }
+}
/** \} */
diff --git a/source/blender/blenkernel/intern/gpencil_modifier.c b/source/blender/blenkernel/intern/gpencil_modifier.c
index 24cfc65a8fe..e92bf5a4502 100644
--- a/source/blender/blenkernel/intern/gpencil_modifier.c
+++ b/source/blender/blenkernel/intern/gpencil_modifier.c
@@ -197,7 +197,7 @@ static int gpencil_time_modifier(
/**
* Set current grease pencil active frame.
* \param depsgraph: Current depsgraph
- * \param gpd: Grease pencil data-block
+ * \param gpd: Grease pencil data-block.
*/
void BKE_gpencil_frame_active_set(Depsgraph *depsgraph, bGPdata *gpd)
{
@@ -223,8 +223,7 @@ void BKE_gpencil_frame_active_set(Depsgraph *depsgraph, bGPdata *gpd)
}
/**
- * Init grease pencil modifier.
- * \param void
+ * Initialize grease pencil modifier.
*/
void BKE_gpencil_modifier_init(void)
{
@@ -460,7 +459,6 @@ GpencilModifierData *BKE_gpencil_modifiers_findby_type(Object *ob, GpencilModifi
* Set grease pencil modifier error.
* \param md: Modifier data
* \param _format: Format
- * \param
*/
void BKE_gpencil_modifier_set_error(GpencilModifierData *md, const char *_format, ...)
{
@@ -560,8 +558,8 @@ static int gpencil_remap_time_get(Depsgraph *depsgraph, Scene *scene, Object *ob
return remap_cfra;
}
-/** Get the current frame retimed with time modifiers.
- * \param depsgraph: Current depsgraph
+/** Get the current frame re-timed with time modifiers.
+ * \param depsgraph: Current depsgraph.
* \param scene: Current scene
* \param ob: Grease pencil object
* \param gpl: Grease pencil layer
diff --git a/source/blender/blenkernel/intern/idtype.c b/source/blender/blenkernel/intern/idtype.c
index 2684e964eb1..1166ad9ad2f 100644
--- a/source/blender/blenkernel/intern/idtype.c
+++ b/source/blender/blenkernel/intern/idtype.c
@@ -36,8 +36,11 @@
#include "BLT_translation.h"
#include "DNA_ID.h"
+#include "DNA_node_types.h"
+#include "DNA_scene_types.h"
#include "BKE_main.h"
+#include "BKE_node.h"
#include "BKE_idtype.h"
@@ -470,3 +473,33 @@ short BKE_idtype_idcode_iter_step(int *index)
{
return (*index < ARRAY_SIZE(id_types)) ? BKE_idtype_idcode_from_index((*index)++) : 0;
}
+
+/** Wrapper around IDTypeInfo foreach_cache that also handles embedded IDs. */
+void BKE_idtype_id_foreach_cache(struct ID *id,
+ IDTypeForeachCacheFunctionCallback function_callback,
+ void *user_data)
+{
+ const IDTypeInfo *type_info = BKE_idtype_get_info_from_id(id);
+ if (type_info->foreach_cache != NULL) {
+ type_info->foreach_cache(id, function_callback, user_data);
+ }
+
+ /* Handle 'private IDs'. */
+ bNodeTree *nodetree = ntreeFromID(id);
+ if (nodetree != NULL) {
+ type_info = BKE_idtype_get_info_from_id(&nodetree->id);
+ if (type_info->foreach_cache != NULL) {
+ type_info->foreach_cache(&nodetree->id, function_callback, user_data);
+ }
+ }
+
+ if (GS(id->name) == ID_SCE) {
+ Scene *scene = (Scene *)id;
+ if (scene->master_collection != NULL) {
+ type_info = BKE_idtype_get_info_from_id(&scene->master_collection->id);
+ if (type_info->foreach_cache != NULL) {
+ type_info->foreach_cache(&scene->master_collection->id, function_callback, user_data);
+ }
+ }
+ }
+}
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 41ef5dc00ef..e331e5ae1dd 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -57,6 +57,7 @@
#include "DNA_packedFile_types.h"
#include "DNA_scene_types.h"
#include "DNA_sequence_types.h"
+#include "DNA_simulation_types.h"
#include "DNA_world_types.h"
#include "BLI_blenlib.h"
@@ -64,7 +65,7 @@
#include "BLI_mempool.h"
#include "BLI_system.h"
#include "BLI_threads.h"
-#include "BLI_timecode.h" /* for stamp timecode format */
+#include "BLI_timecode.h" /* For stamp time-code format. */
#include "BLI_utildefines.h"
#include "BLT_translation.h"
@@ -89,7 +90,6 @@
#include "RE_pipeline.h"
-#include "GPU_draw.h"
#include "GPU_texture.h"
#include "BLI_sys_types.h" // for intptr_t support
@@ -195,24 +195,24 @@ static void image_foreach_cache(ID *id,
.offset_in_ID = offsetof(Image, cache),
.cache_v = image->cache,
};
- function_callback(id, &key, (void **)&image->cache, user_data);
+ function_callback(id, &key, (void **)&image->cache, 0, user_data);
for (int eye = 0; eye < 2; eye++) {
for (int a = 0; a < TEXTARGET_COUNT; a++) {
key.offset_in_ID = offsetof(Image, gputexture[a][eye]);
key.cache_v = image->gputexture[a][eye];
- function_callback(id, &key, (void **)&image->gputexture[a][eye], user_data);
+ function_callback(id, &key, (void **)&image->gputexture[a][eye], 0, user_data);
}
}
key.offset_in_ID = offsetof(Image, rr);
key.cache_v = image->rr;
- function_callback(id, &key, (void **)&image->rr, user_data);
+ function_callback(id, &key, (void **)&image->rr, 0, user_data);
LISTBASE_FOREACH (RenderSlot *, slot, &image->renderslots) {
key.offset_in_ID = (size_t)BLI_ghashutil_strhash_p(slot->name);
key.cache_v = slot->render;
- function_callback(id, &key, (void **)&slot->render, user_data);
+ function_callback(id, &key, (void **)&slot->render, 0, user_data);
}
}
@@ -392,7 +392,7 @@ void BKE_image_free_buffers_ex(Image *ima, bool do_lock)
ima->rr = NULL;
}
- GPU_free_image(ima);
+ BKE_image_free_gputextures(ima);
LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
tile->ok = IMA_OK;
@@ -3240,6 +3240,12 @@ static void image_walk_id_all_users(
if (scene->nodetree && scene->use_nodes && !skip_nested_nodes) {
image_walk_ntree_all_users(scene->nodetree, &scene->id, customdata, callback);
}
+ break;
+ }
+ case ID_SIM: {
+ Simulation *simulation = (Simulation *)id;
+ image_walk_ntree_all_users(simulation->nodetree, &simulation->id, customdata, callback);
+ break;
}
default:
break;
@@ -3344,8 +3350,7 @@ static void image_free_tile(Image *ima, ImageTile *tile)
for (int i = 0; i < TEXTARGET_COUNT; i++) {
/* Only two textures depends on all tiles, so if this is a secondary tile we can keep the other
* two. */
- if (tile != ima->tiles.first &&
- !(ELEM(i, TEXTARGET_TEXTURE_2D_ARRAY, TEXTARGET_TEXTURE_TILE_MAPPING))) {
+ if (tile != ima->tiles.first && !(ELEM(i, TEXTARGET_2D_ARRAY, TEXTARGET_TILE_MAPPING))) {
continue;
}
@@ -3622,13 +3627,13 @@ ImageTile *BKE_image_add_tile(struct Image *ima, int tile_number, const char *la
for (int eye = 0; eye < 2; eye++) {
/* Reallocate GPU tile array. */
- if (ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY][eye] != NULL) {
- GPU_texture_free(ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY][eye]);
- ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY][eye] = NULL;
+ if (ima->gputexture[TEXTARGET_2D_ARRAY][eye] != NULL) {
+ GPU_texture_free(ima->gputexture[TEXTARGET_2D_ARRAY][eye]);
+ ima->gputexture[TEXTARGET_2D_ARRAY][eye] = NULL;
}
- if (ima->gputexture[TEXTARGET_TEXTURE_TILE_MAPPING][eye] != NULL) {
- GPU_texture_free(ima->gputexture[TEXTARGET_TEXTURE_TILE_MAPPING][eye]);
- ima->gputexture[TEXTARGET_TEXTURE_TILE_MAPPING][eye] = NULL;
+ if (ima->gputexture[TEXTARGET_TILE_MAPPING][eye] != NULL) {
+ GPU_texture_free(ima->gputexture[TEXTARGET_TILE_MAPPING][eye]);
+ ima->gputexture[TEXTARGET_TILE_MAPPING][eye] = NULL;
}
}
@@ -3937,7 +3942,7 @@ static void image_create_multilayer(Image *ima, ImBuf *ibuf, int framenr)
#endif /* WITH_OPENEXR */
/* common stuff to do with images after loading */
-static void image_initialize_after_load(Image *ima, ImageUser *iuser, ImBuf *UNUSED(ibuf))
+static void image_init_after_load(Image *ima, ImageUser *iuser, ImBuf *UNUSED(ibuf))
{
/* Preview is NULL when it has never been used as an icon before.
* Never handle previews/icons outside of main thread. */
@@ -4040,11 +4045,11 @@ static ImBuf *load_sequence_single(
}
}
else {
- image_initialize_after_load(ima, iuser, ibuf);
+ image_init_after_load(ima, iuser, ibuf);
*r_assign = true;
}
#else
- image_initialize_after_load(ima, iuser, ibuf);
+ image_init_after_load(ima, iuser, ibuf);
*r_assign = true;
#endif
}
@@ -4149,7 +4154,7 @@ static ImBuf *image_load_sequence_multilayer(Image *ima, ImageUser *iuser, int e
BKE_imbuf_stamp_info(ima->rr, ibuf);
- image_initialize_after_load(ima, iuser, ibuf);
+ image_init_after_load(ima, iuser, ibuf);
image_assign_ibuf(ima, ibuf, iuser ? iuser->multi_index : 0, entry);
}
// else printf("pass not found\n");
@@ -4213,7 +4218,7 @@ static ImBuf *load_movie_single(Image *ima, ImageUser *iuser, int frame, const i
ibuf = IMB_makeSingleUser(IMB_anim_absolute(ia->anim, fra, IMB_TC_RECORD_RUN, IMB_PROXY_NONE));
if (ibuf) {
- image_initialize_after_load(ima, iuser, ibuf);
+ image_init_after_load(ima, iuser, ibuf);
}
else {
tile->ok = 0;
@@ -4358,12 +4363,12 @@ static ImBuf *load_image_single(Image *ima,
else
#endif
{
- image_initialize_after_load(ima, iuser, ibuf);
+ image_init_after_load(ima, iuser, ibuf);
*r_assign = true;
/* make packed file for autopack */
if ((has_packed == false) && (G.fileflags & G_FILE_AUTOPACK)) {
- ImagePackedFile *imapf = MEM_mallocN(sizeof(ImagePackedFile), "Image Packefile");
+ ImagePackedFile *imapf = MEM_mallocN(sizeof(ImagePackedFile), "Image Pack-file");
BLI_addtail(&ima->packedfiles, imapf);
STRNCPY(imapf->filepath, filepath);
@@ -4472,7 +4477,7 @@ static ImBuf *image_get_ibuf_multilayer(Image *ima, ImageUser *iuser)
if (rpass) {
ibuf = IMB_allocImBuf(ima->rr->rectx, ima->rr->recty, 32, 0);
- image_initialize_after_load(ima, iuser, ibuf);
+ image_init_after_load(ima, iuser, ibuf);
ibuf->rect_float = rpass->rect;
ibuf->flags |= IB_rectfloat;
@@ -5213,24 +5218,32 @@ int BKE_image_user_frame_get(const ImageUser *iuser, int cfra, bool *r_is_in_ran
void BKE_image_user_frame_calc(Image *ima, ImageUser *iuser, int cfra)
{
if (iuser) {
- bool is_in_range;
- const int framenr = BKE_image_user_frame_get(iuser, cfra, &is_in_range);
+ if (ima && BKE_image_is_animated(ima)) {
+ /* Compute current frame for animated image. */
+ bool is_in_range;
+ const int framenr = BKE_image_user_frame_get(iuser, cfra, &is_in_range);
- if (is_in_range) {
- iuser->flag |= IMA_USER_FRAME_IN_RANGE;
+ if (is_in_range) {
+ iuser->flag |= IMA_USER_FRAME_IN_RANGE;
+ }
+ else {
+ iuser->flag &= ~IMA_USER_FRAME_IN_RANGE;
+ }
+
+ iuser->framenr = framenr;
}
else {
- iuser->flag &= ~IMA_USER_FRAME_IN_RANGE;
+ /* Set fixed frame number for still image. */
+ iuser->framenr = 0;
+ iuser->flag |= IMA_USER_FRAME_IN_RANGE;
}
- iuser->framenr = framenr;
-
- if (ima && BKE_image_is_animated(ima) && ima->gpuframenr != framenr) {
+ if (ima && ima->gpuframenr != iuser->framenr) {
/* Note: a single texture and refresh doesn't really work when
* multiple image users may use different frames, this is to
* be improved with perhaps a GPU texture cache. */
ima->gpuflag |= IMA_GPU_REFRESH;
- ima->gpuframenr = framenr;
+ ima->gpuframenr = iuser->framenr;
}
if (iuser->ok == 0) {
diff --git a/source/blender/blenkernel/intern/image_gpu.c b/source/blender/blenkernel/intern/image_gpu.c
new file mode 100644
index 00000000000..22fb6dfd02a
--- /dev/null
+++ b/source/blender/blenkernel/intern/image_gpu.c
@@ -0,0 +1,774 @@
+/*
+ * 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) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup bke
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_boxpack_2d.h"
+#include "BLI_linklist.h"
+#include "BLI_listbase.h"
+#include "BLI_threads.h"
+
+#include "DNA_image_types.h"
+#include "DNA_userdef_types.h"
+
+#include "IMB_colormanagement.h"
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+
+#include "BKE_global.h"
+#include "BKE_image.h"
+#include "BKE_main.h"
+
+#include "GPU_extensions.h"
+#include "GPU_state.h"
+#include "GPU_texture.h"
+
+#include "PIL_time.h"
+
+/* Prototypes. */
+static void gpu_free_unused_buffers(void);
+static void image_free_gpu(Image *ima, const bool immediate);
+
+/* -------------------------------------------------------------------- */
+/** \name UDIM gpu texture
+ * \{ */
+
+static bool is_over_resolution_limit(int w, int h)
+{
+ return (w > GPU_texture_size_with_limit(w) || h > GPU_texture_size_with_limit(h));
+}
+
+static int smaller_power_of_2_limit(int num)
+{
+ return power_of_2_min_i(GPU_texture_size_with_limit(num));
+}
+
+static GPUTexture *gpu_texture_create_tile_mapping(Image *ima, const int multiview_eye)
+{
+ GPUTexture *tilearray = ima->gputexture[TEXTARGET_2D_ARRAY][multiview_eye];
+
+ if (tilearray == NULL) {
+ return 0;
+ }
+
+ float array_w = GPU_texture_width(tilearray);
+ float array_h = GPU_texture_height(tilearray);
+
+ ImageTile *last_tile = (ImageTile *)ima->tiles.last;
+ /* Tiles are sorted by number. */
+ int max_tile = last_tile->tile_number - 1001;
+
+ /* create image */
+ int width = max_tile + 1;
+ float *data = (float *)MEM_callocN(width * 8 * sizeof(float), __func__);
+ for (int i = 0; i < width; i++) {
+ data[4 * i] = -1.0f;
+ }
+ LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
+ int i = tile->tile_number - 1001;
+ data[4 * i] = tile->runtime.tilearray_layer;
+
+ float *tile_info = &data[4 * width + 4 * i];
+ tile_info[0] = tile->runtime.tilearray_offset[0] / array_w;
+ tile_info[1] = tile->runtime.tilearray_offset[1] / array_h;
+ tile_info[2] = tile->runtime.tilearray_size[0] / array_w;
+ tile_info[3] = tile->runtime.tilearray_size[1] / array_h;
+ }
+
+ GPUTexture *tex = GPU_texture_create_1d_array(width, 2, GPU_RGBA32F, data, NULL);
+ GPU_texture_mipmap_mode(tex, false, false);
+
+ MEM_freeN(data);
+
+ return tex;
+}
+
+typedef struct PackTile {
+ FixedSizeBoxPack boxpack;
+ ImageTile *tile;
+ float pack_score;
+} PackTile;
+
+static int compare_packtile(const void *a, const void *b)
+{
+ const PackTile *tile_a = (const PackTile *)a;
+ const PackTile *tile_b = (const PackTile *)b;
+
+ return tile_a->pack_score < tile_b->pack_score;
+}
+
+static GPUTexture *gpu_texture_create_tile_array(Image *ima, ImBuf *main_ibuf)
+{
+ int arraywidth = 0, arrayheight = 0;
+ ListBase boxes = {NULL};
+
+ LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
+ ImageUser iuser;
+ BKE_imageuser_default(&iuser);
+ iuser.tile = tile->tile_number;
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
+
+ if (ibuf) {
+ PackTile *packtile = (PackTile *)MEM_callocN(sizeof(PackTile), __func__);
+ packtile->tile = tile;
+ packtile->boxpack.w = ibuf->x;
+ packtile->boxpack.h = ibuf->y;
+
+ if (is_over_resolution_limit(packtile->boxpack.w, packtile->boxpack.h)) {
+ packtile->boxpack.w = smaller_power_of_2_limit(packtile->boxpack.w);
+ packtile->boxpack.h = smaller_power_of_2_limit(packtile->boxpack.h);
+ }
+ arraywidth = max_ii(arraywidth, packtile->boxpack.w);
+ arrayheight = max_ii(arrayheight, packtile->boxpack.h);
+
+ /* We sort the tiles by decreasing size, with an additional penalty term
+ * for high aspect ratios. This improves packing efficiency. */
+ float w = packtile->boxpack.w, h = packtile->boxpack.h;
+ packtile->pack_score = max_ff(w, h) / min_ff(w, h) * w * h;
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ BLI_addtail(&boxes, packtile);
+ }
+ }
+
+ BLI_assert(arraywidth > 0 && arrayheight > 0);
+
+ BLI_listbase_sort(&boxes, compare_packtile);
+ int arraylayers = 0;
+ /* Keep adding layers until all tiles are packed. */
+ while (boxes.first != NULL) {
+ ListBase packed = {NULL};
+ BLI_box_pack_2d_fixedarea(&boxes, arraywidth, arrayheight, &packed);
+ BLI_assert(packed.first != NULL);
+
+ LISTBASE_FOREACH (PackTile *, packtile, &packed) {
+ ImageTile *tile = packtile->tile;
+ int *tileoffset = tile->runtime.tilearray_offset;
+ int *tilesize = tile->runtime.tilearray_size;
+
+ tileoffset[0] = packtile->boxpack.x;
+ tileoffset[1] = packtile->boxpack.y;
+ tilesize[0] = packtile->boxpack.w;
+ tilesize[1] = packtile->boxpack.h;
+ tile->runtime.tilearray_layer = arraylayers;
+ }
+
+ BLI_freelistN(&packed);
+ arraylayers++;
+ }
+
+ const bool use_high_bitdepth = (ima->flag & IMA_HIGH_BITDEPTH);
+ /* Create Texture without content. */
+ GPUTexture *tex = IMB_touch_gpu_texture(
+ main_ibuf, arraywidth, arrayheight, arraylayers, use_high_bitdepth);
+
+ GPU_texture_bind(tex, 0);
+
+ /* Upload each tile one by one. */
+ LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
+ int tilelayer = tile->runtime.tilearray_layer;
+ int *tileoffset = tile->runtime.tilearray_offset;
+ int *tilesize = tile->runtime.tilearray_size;
+
+ if (tilesize[0] == 0 || tilesize[1] == 0) {
+ continue;
+ }
+
+ ImageUser iuser;
+ BKE_imageuser_default(&iuser);
+ iuser.tile = tile->tile_number;
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
+
+ if (ibuf) {
+ const bool store_premultiplied = ibuf->rect_float ? (ima->alpha_mode != IMA_ALPHA_STRAIGHT) :
+ (ima->alpha_mode == IMA_ALPHA_PREMUL);
+ IMB_update_gpu_texture_sub(tex,
+ ibuf,
+ UNPACK2(tileoffset),
+ tilelayer,
+ UNPACK2(tilesize),
+ use_high_bitdepth,
+ store_premultiplied);
+ }
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ }
+
+ if (GPU_mipmap_enabled()) {
+ GPU_texture_generate_mipmap(tex);
+ GPU_texture_mipmap_mode(tex, true, true);
+ if (ima) {
+ ima->gpuflag |= IMA_GPU_MIPMAP_COMPLETE;
+ }
+ }
+ else {
+ GPU_texture_mipmap_mode(tex, false, true);
+ }
+
+ GPU_texture_unbind(tex);
+
+ return tex;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Regular gpu texture
+ * \{ */
+
+static GPUTexture **get_image_gpu_texture_ptr(Image *ima,
+ eGPUTextureTarget textarget,
+ const int multiview_eye)
+{
+ const bool in_range = (textarget >= 0) && (textarget < TEXTARGET_COUNT);
+ BLI_assert(in_range);
+
+ if (in_range) {
+ return &(ima->gputexture[textarget][multiview_eye]);
+ }
+ return NULL;
+}
+
+static GPUTexture *image_gpu_texture_error_create(eGPUTextureTarget textarget)
+{
+ switch (textarget) {
+ case TEXTARGET_2D_ARRAY:
+ return GPU_texture_create_error(2, true);
+ case TEXTARGET_TILE_MAPPING:
+ return GPU_texture_create_error(1, true);
+ case TEXTARGET_2D:
+ default:
+ return GPU_texture_create_error(2, false);
+ }
+}
+
+static GPUTexture *image_get_gpu_texture(Image *ima,
+ ImageUser *iuser,
+ ImBuf *ibuf,
+ eGPUTextureTarget textarget)
+{
+ if (ima == NULL) {
+ return NULL;
+ }
+
+ /* Free any unused GPU textures, since we know we are in a thread with OpenGL
+ * context and might as well ensure we have as much space free as possible. */
+ gpu_free_unused_buffers();
+
+ /* currently, gpu refresh tagging is used by ima sequences */
+ if (ima->gpuflag & IMA_GPU_REFRESH) {
+ image_free_gpu(ima, true);
+ ima->gpuflag &= ~IMA_GPU_REFRESH;
+ }
+
+ /* Tag as in active use for garbage collector. */
+ BKE_image_tag_time(ima);
+
+ /* Test if we already have a texture. */
+ GPUTexture **tex = get_image_gpu_texture_ptr(ima, textarget, iuser ? iuser->multiview_eye : 0);
+ if (*tex) {
+ return *tex;
+ }
+
+ /* Check if we have a valid image. If not, we return a dummy
+ * texture with zero bind-code so we don't keep trying. */
+ ImageTile *tile = BKE_image_get_tile(ima, 0);
+ if (tile == NULL || tile->ok == 0) {
+ *tex = image_gpu_texture_error_create(textarget);
+ return *tex;
+ }
+
+ /* check if we have a valid image buffer */
+ ImBuf *ibuf_intern = ibuf;
+ if (ibuf_intern == NULL) {
+ ibuf_intern = BKE_image_acquire_ibuf(ima, iuser, NULL);
+ if (ibuf_intern == NULL) {
+ *tex = image_gpu_texture_error_create(textarget);
+ return *tex;
+ }
+ }
+
+ if (textarget == TEXTARGET_2D_ARRAY) {
+ *tex = gpu_texture_create_tile_array(ima, ibuf_intern);
+ }
+ else if (textarget == TEXTARGET_TILE_MAPPING) {
+ *tex = gpu_texture_create_tile_mapping(ima, iuser ? iuser->multiview_eye : 0);
+ }
+ else {
+ const bool use_high_bitdepth = (ima->flag & IMA_HIGH_BITDEPTH);
+ const bool store_premultiplied = ibuf_intern->rect_float ?
+ (ima ? (ima->alpha_mode != IMA_ALPHA_STRAIGHT) : false) :
+ (ima ? (ima->alpha_mode == IMA_ALPHA_PREMUL) : true);
+
+ *tex = IMB_create_gpu_texture(ibuf_intern, use_high_bitdepth, store_premultiplied);
+
+ if (GPU_mipmap_enabled()) {
+ GPU_texture_bind(*tex, 0);
+ GPU_texture_generate_mipmap(*tex);
+ GPU_texture_unbind(*tex);
+ if (ima) {
+ ima->gpuflag |= IMA_GPU_MIPMAP_COMPLETE;
+ }
+ GPU_texture_mipmap_mode(*tex, true, true);
+ }
+ else {
+ GPU_texture_mipmap_mode(*tex, false, true);
+ }
+ }
+
+ /* if `ibuf` was given, we don't own the `ibuf_intern` */
+ if (ibuf == NULL) {
+ BKE_image_release_ibuf(ima, ibuf_intern, NULL);
+ }
+
+ GPU_texture_orig_size_set(*tex, ibuf_intern->x, ibuf_intern->y);
+
+ return *tex;
+}
+
+GPUTexture *BKE_image_get_gpu_texture(Image *image, ImageUser *iuser, ImBuf *ibuf)
+{
+ return image_get_gpu_texture(image, iuser, ibuf, TEXTARGET_2D);
+}
+
+GPUTexture *BKE_image_get_gpu_tiles(Image *image, ImageUser *iuser, ImBuf *ibuf)
+{
+ return image_get_gpu_texture(image, iuser, ibuf, TEXTARGET_2D_ARRAY);
+}
+
+GPUTexture *BKE_image_get_gpu_tilemap(Image *image, ImageUser *iuser, ImBuf *ibuf)
+{
+ return image_get_gpu_texture(image, iuser, ibuf, TEXTARGET_TILE_MAPPING);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Delayed GPU texture free
+ *
+ * Image datablocks can be deleted by any thread, but there may not be any active OpenGL context.
+ * In that case we push them into a queue and free the buffers later.
+ * \{ */
+
+static LinkNode *gpu_texture_free_queue = NULL;
+static ThreadMutex gpu_texture_queue_mutex = BLI_MUTEX_INITIALIZER;
+
+static void gpu_free_unused_buffers(void)
+{
+ if (gpu_texture_free_queue == NULL) {
+ return;
+ }
+
+ BLI_mutex_lock(&gpu_texture_queue_mutex);
+
+ while (gpu_texture_free_queue != NULL) {
+ GPUTexture *tex = BLI_linklist_pop(&gpu_texture_free_queue);
+ GPU_texture_free(tex);
+ }
+
+ BLI_mutex_unlock(&gpu_texture_queue_mutex);
+}
+
+void BKE_image_free_unused_gpu_textures()
+{
+ if (BLI_thread_is_main()) {
+ gpu_free_unused_buffers();
+ }
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Deletion
+ * \{ */
+
+static void image_free_gpu(Image *ima, const bool immediate)
+{
+ for (int eye = 0; eye < 2; eye++) {
+ for (int i = 0; i < TEXTARGET_COUNT; i++) {
+ if (ima->gputexture[i][eye] != NULL) {
+ if (immediate) {
+ GPU_texture_free(ima->gputexture[i][eye]);
+ }
+ else {
+ BLI_mutex_lock(&gpu_texture_queue_mutex);
+ BLI_linklist_prepend(&gpu_texture_free_queue, ima->gputexture[i][eye]);
+ BLI_mutex_unlock(&gpu_texture_queue_mutex);
+ }
+
+ ima->gputexture[i][eye] = NULL;
+ }
+ }
+ }
+
+ ima->gpuflag &= ~IMA_GPU_MIPMAP_COMPLETE;
+}
+
+void BKE_image_free_gputextures(Image *ima)
+{
+ image_free_gpu(ima, BLI_thread_is_main());
+}
+
+void BKE_image_free_all_gputextures(Main *bmain)
+{
+ if (bmain) {
+ LISTBASE_FOREACH (Image *, ima, &bmain->images) {
+ BKE_image_free_gputextures(ima);
+ }
+ }
+}
+
+/* same as above but only free animated images */
+void BKE_image_free_anim_gputextures(Main *bmain)
+{
+ if (bmain) {
+ LISTBASE_FOREACH (Image *, ima, &bmain->images) {
+ if (BKE_image_is_animated(ima)) {
+ BKE_image_free_gputextures(ima);
+ }
+ }
+ }
+}
+
+void BKE_image_free_old_gputextures(Main *bmain)
+{
+ static int lasttime = 0;
+ int ctime = (int)PIL_check_seconds_timer();
+
+ /*
+ * Run garbage collector once for every collecting period of time
+ * if textimeout is 0, that's the option to NOT run the collector
+ */
+ if (U.textimeout == 0 || ctime % U.texcollectrate || ctime == lasttime) {
+ return;
+ }
+
+ /* of course not! */
+ if (G.is_rendering) {
+ return;
+ }
+
+ lasttime = ctime;
+
+ LISTBASE_FOREACH (Image *, ima, &bmain->images) {
+ if ((ima->flag & IMA_NOCOLLECT) == 0 && ctime - ima->lastused > U.textimeout) {
+ /* If it's in GL memory, deallocate and set time tag to current time
+ * This gives textures a "second chance" to be used before dying. */
+ if (BKE_image_has_opengl_texture(ima)) {
+ BKE_image_free_gputextures(ima);
+ ima->lastused = ctime;
+ }
+ /* Otherwise, just kill the buffers */
+ else {
+ BKE_image_free_buffers(ima);
+ }
+ }
+ }
+}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Paint Update
+ * \{ */
+
+static ImBuf *update_do_scale(uchar *rect,
+ float *rect_float,
+ int *x,
+ int *y,
+ int *w,
+ int *h,
+ int limit_w,
+ int limit_h,
+ int full_w,
+ int full_h)
+{
+ /* Partial update with scaling. */
+ float xratio = limit_w / (float)full_w;
+ float yratio = limit_h / (float)full_h;
+
+ int part_w = *w, part_h = *h;
+
+ /* Find sub coordinates in scaled image. Take ceiling because we will be
+ * losing 1 pixel due to rounding errors in x,y. */
+ *x *= xratio;
+ *y *= yratio;
+ *w = (int)ceil(xratio * (*w));
+ *h = (int)ceil(yratio * (*h));
+
+ /* ...but take back if we are over the limit! */
+ if (*x + *w > limit_w) {
+ (*w)--;
+ }
+ if (*y + *h > limit_h) {
+ (*h)--;
+ }
+
+ /* Scale pixels. */
+ ImBuf *ibuf = IMB_allocFromBuffer((uint *)rect, rect_float, part_w, part_h, 4);
+ IMB_scaleImBuf(ibuf, *w, *h);
+
+ return ibuf;
+}
+
+static void gpu_texture_update_scaled(GPUTexture *tex,
+ uchar *rect,
+ float *rect_float,
+ int full_w,
+ int full_h,
+ int x,
+ int y,
+ int layer,
+ const int *tile_offset,
+ const int *tile_size,
+ int w,
+ int h)
+{
+ ImBuf *ibuf;
+ if (layer > -1) {
+ ibuf = update_do_scale(
+ rect, rect_float, &x, &y, &w, &h, tile_size[0], tile_size[1], full_w, full_h);
+
+ /* Shift to account for tile packing. */
+ x += tile_offset[0];
+ y += tile_offset[1];
+ }
+ else {
+ /* Partial update with scaling. */
+ int limit_w = smaller_power_of_2_limit(full_w);
+ int limit_h = smaller_power_of_2_limit(full_h);
+
+ ibuf = update_do_scale(rect, rect_float, &x, &y, &w, &h, limit_w, limit_h, full_w, full_h);
+ }
+
+ void *data = (ibuf->rect_float) ? (void *)(ibuf->rect_float) : (void *)(ibuf->rect);
+ eGPUDataFormat data_format = (ibuf->rect_float) ? GPU_DATA_FLOAT : GPU_DATA_UNSIGNED_BYTE;
+
+ GPU_texture_update_sub(tex, data_format, data, x, y, layer, w, h, 1);
+
+ IMB_freeImBuf(ibuf);
+}
+
+static void gpu_texture_update_unscaled(GPUTexture *tex,
+ uchar *rect,
+ float *rect_float,
+ int x,
+ int y,
+ int layer,
+ const int tile_offset[2],
+ int w,
+ int h,
+ int tex_stride,
+ int tex_offset)
+{
+ if (layer > -1) {
+ /* Shift to account for tile packing. */
+ x += tile_offset[0];
+ y += tile_offset[1];
+ }
+
+ void *data = (rect_float) ? (void *)(rect_float + tex_offset) : (void *)(rect + tex_offset);
+ eGPUDataFormat data_format = (rect_float) ? GPU_DATA_FLOAT : GPU_DATA_UNSIGNED_BYTE;
+
+ /* Partial update without scaling. Stride and offset are used to copy only a
+ * subset of a possible larger buffer than what we are updating. */
+ GPU_unpack_row_length_set(tex_stride);
+
+ GPU_texture_update_sub(tex, data_format, data, x, y, layer, w, h, 1);
+ /* Restore default. */
+ GPU_unpack_row_length_set(0);
+}
+
+static void gpu_texture_update_from_ibuf(
+ GPUTexture *tex, Image *ima, ImBuf *ibuf, ImageTile *tile, int x, int y, int w, int h)
+{
+ bool scaled;
+ if (tile != NULL) {
+ int *tilesize = tile->runtime.tilearray_size;
+ scaled = (ibuf->x != tilesize[0]) || (ibuf->y != tilesize[1]);
+ }
+ else {
+ scaled = is_over_resolution_limit(ibuf->x, ibuf->y);
+ }
+
+ if (scaled) {
+ /* Extra padding to account for bleed from neighboring pixels. */
+ const int padding = 4;
+ const int xmax = min_ii(x + w + padding, ibuf->x);
+ const int ymax = min_ii(y + h + padding, ibuf->y);
+ x = max_ii(x - padding, 0);
+ y = max_ii(y - padding, 0);
+ w = xmax - x;
+ h = ymax - y;
+ }
+
+ /* Get texture data pointers. */
+ float *rect_float = ibuf->rect_float;
+ uchar *rect = (uchar *)ibuf->rect;
+ int tex_stride = ibuf->x;
+ int tex_offset = ibuf->channels * (y * ibuf->x + x);
+
+ if (rect_float == NULL) {
+ /* Byte pixels. */
+ if (!IMB_colormanagement_space_is_data(ibuf->rect_colorspace)) {
+ const bool compress_as_srgb = !IMB_colormanagement_space_is_scene_linear(
+ ibuf->rect_colorspace);
+
+ rect = (uchar *)MEM_mallocN(sizeof(uchar) * 4 * w * h, __func__);
+ if (rect == NULL) {
+ return;
+ }
+
+ tex_stride = w;
+ tex_offset = 0;
+
+ /* Convert to scene linear with sRGB compression, and premultiplied for
+ * correct texture interpolation. */
+ const bool store_premultiplied = (ima->alpha_mode == IMA_ALPHA_PREMUL);
+ IMB_colormanagement_imbuf_to_byte_texture(
+ rect, x, y, w, h, ibuf, compress_as_srgb, store_premultiplied);
+ }
+ }
+ else {
+ /* Float pixels. */
+ const bool store_premultiplied = (ima->alpha_mode != IMA_ALPHA_STRAIGHT);
+
+ if (ibuf->channels != 4 || scaled || !store_premultiplied) {
+ rect_float = (float *)MEM_mallocN(sizeof(float) * 4 * w * h, __func__);
+ if (rect_float == NULL) {
+ return;
+ }
+
+ tex_stride = w;
+ tex_offset = 0;
+
+ IMB_colormanagement_imbuf_to_float_texture(
+ rect_float, x, y, w, h, ibuf, store_premultiplied);
+ }
+ }
+
+ GPU_texture_bind(tex, 0);
+
+ if (scaled) {
+ /* Slower update where we first have to scale the input pixels. */
+ if (tile != NULL) {
+ int *tileoffset = tile->runtime.tilearray_offset;
+ int *tilesize = tile->runtime.tilearray_size;
+ int tilelayer = tile->runtime.tilearray_layer;
+ gpu_texture_update_scaled(
+ tex, rect, rect_float, ibuf->x, ibuf->y, x, y, tilelayer, tileoffset, tilesize, w, h);
+ }
+ else {
+ gpu_texture_update_scaled(
+ tex, rect, rect_float, ibuf->x, ibuf->y, x, y, -1, NULL, NULL, w, h);
+ }
+ }
+ else {
+ /* Fast update at same resolution. */
+ if (tile != NULL) {
+ int *tileoffset = tile->runtime.tilearray_offset;
+ int tilelayer = tile->runtime.tilearray_layer;
+ gpu_texture_update_unscaled(
+ tex, rect, rect_float, x, y, tilelayer, tileoffset, w, h, tex_stride, tex_offset);
+ }
+ else {
+ gpu_texture_update_unscaled(
+ tex, rect, rect_float, x, y, -1, NULL, w, h, tex_stride, tex_offset);
+ }
+ }
+
+ /* Free buffers if needed. */
+ if (rect && rect != (uchar *)ibuf->rect) {
+ MEM_freeN(rect);
+ }
+ if (rect_float && rect_float != ibuf->rect_float) {
+ MEM_freeN(rect_float);
+ }
+
+ if (GPU_mipmap_enabled()) {
+ GPU_texture_generate_mipmap(tex);
+ }
+ else {
+ ima->gpuflag &= ~IMA_GPU_MIPMAP_COMPLETE;
+ }
+
+ GPU_texture_unbind(tex);
+}
+
+/* Partial update of texture for texture painting. This is often much
+ * quicker than fully updating the texture for high resolution images. */
+void BKE_image_update_gputexture(Image *ima, ImageUser *iuser, int x, int y, int w, int h)
+{
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
+ ImageTile *tile = BKE_image_get_tile_from_iuser(ima, iuser);
+
+ if ((ibuf == NULL) || (w == 0) || (h == 0)) {
+ /* Full reload of texture. */
+ BKE_image_free_gputextures(ima);
+ }
+
+ GPUTexture *tex = ima->gputexture[TEXTARGET_2D][0];
+ /* Check if we need to update the main gputexture. */
+ if (tex != NULL && tile == ima->tiles.first) {
+ gpu_texture_update_from_ibuf(tex, ima, ibuf, NULL, x, y, w, h);
+ }
+
+ /* Check if we need to update the array gputexture. */
+ tex = ima->gputexture[TEXTARGET_2D_ARRAY][0];
+ if (tex != NULL) {
+ gpu_texture_update_from_ibuf(tex, ima, ibuf, tile, x, y, w, h);
+ }
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+}
+
+/* these two functions are called on entering and exiting texture paint mode,
+ * temporary disabling/enabling mipmapping on all images for quick texture
+ * updates with glTexSubImage2D. images that didn't change don't have to be
+ * re-uploaded to OpenGL */
+void BKE_image_paint_set_mipmap(Main *bmain, bool mipmap)
+{
+ LISTBASE_FOREACH (Image *, ima, &bmain->images) {
+ if (BKE_image_has_opengl_texture(ima)) {
+ if (ima->gpuflag & IMA_GPU_MIPMAP_COMPLETE) {
+ for (int eye = 0; eye < 2; eye++) {
+ for (int a = 0; a < TEXTARGET_COUNT; a++) {
+ if (ELEM(a, TEXTARGET_2D, TEXTARGET_2D_ARRAY)) {
+ GPUTexture *tex = ima->gputexture[a][eye];
+ if (tex != NULL) {
+ GPU_texture_mipmap_mode(tex, mipmap, true);
+ }
+ }
+ }
+ }
+ }
+ else {
+ BKE_image_free_gputextures(ima);
+ }
+ }
+ else {
+ ima->gpuflag &= ~IMA_GPU_MIPMAP_COMPLETE;
+ }
+ }
+}
+
+/** \} */
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index af8ab22e14b..a71b9cc2a1d 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -529,7 +529,13 @@ static int setkeys(float fac, ListBase *lb, KeyBlock *k[], float t[4], int cycl)
return 0;
}
-static void flerp(int tot, float *in, float *f0, float *f1, float *f2, float *f3, float *t)
+static void flerp(int tot,
+ float *in,
+ const float *f0,
+ const float *f1,
+ const float *f2,
+ const float *f3,
+ const float *t)
{
int a;
@@ -538,7 +544,7 @@ static void flerp(int tot, float *in, float *f0, float *f1, float *f2, float *f3
}
}
-static void rel_flerp(int tot, float *in, float *ref, float *out, float fac)
+static void rel_flerp(int tot, float *in, const float *ref, const float *out, float fac)
{
int a;
@@ -1541,6 +1547,134 @@ float *BKE_key_evaluate_object(Object *ob, int *r_totelem)
return BKE_key_evaluate_object_ex(ob, r_totelem, NULL, 0);
}
+/**
+ * \param shape_index: The index to use or all (when -1).
+ */
+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)) {
+ result += kb->totelem;
+ }
+ }
+ return result;
+}
+
+int BKE_keyblock_element_count(const Key *key)
+{
+ return BKE_keyblock_element_count_from_shape(key, -1);
+}
+
+/**
+ * \param shape_index: The index to use or all (when -1).
+ */
+size_t BKE_keyblock_element_calc_size_from_shape(const Key *key, const int shape_index)
+{
+ return (size_t)BKE_keyblock_element_count_from_shape(key, shape_index) * key->elemsize;
+}
+
+size_t BKE_keyblock_element_calc_size(const Key *key)
+{
+ return BKE_keyblock_element_calc_size_from_shape(key, -1);
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Key-Block Data Access
+ *
+ * Utilities for getting/setting key data as a single array,
+ * use #BKE_keyblock_element_calc_size to allocate the size of the data needed.
+ * \{ */
+
+/**
+ * \param shape_index: The index to use or all (when -1).
+ */
+void BKE_keyblock_data_get_from_shape(const Key *key, float (*arr)[3], const int shape_index)
+{
+ 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)) {
+ const int block_elem_len = kb->totelem * key->elemsize;
+ memcpy(elements, kb->data, block_elem_len);
+ elements += block_elem_len;
+ }
+ }
+}
+
+void BKE_keyblock_data_get(const Key *key, float (*arr)[3])
+{
+ BKE_keyblock_data_get_from_shape(key, arr, -1);
+}
+
+/**
+ * Set the data to all key-blocks (or shape_index if != -1).
+ */
+void BKE_keyblock_data_set_with_mat4(Key *key,
+ const int shape_index,
+ const float (*coords)[3],
+ const float mat[4][4])
+{
+ if (key->elemsize != sizeof(float[3])) {
+ BLI_assert(!"Invalid elemsize");
+ return;
+ }
+
+ const float(*elements)[3] = coords;
+
+ int index = 0;
+ for (KeyBlock *kb = key->block.first; kb; kb = kb->next, index++) {
+ if ((shape_index == -1) || (index == shape_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) {
+ const float *src_data = (const float *)(elements + data_offset);
+ float *dst_data = (float *)(block_data + data_offset);
+ mul_v3_m4v3(dst_data, mat, src_data);
+ }
+ elements += block_elem_len;
+ }
+ }
+}
+
+/**
+ * Set the data for all key-blocks (or shape_index if != -1),
+ * transforming by \a mat.
+ */
+void BKE_keyblock_curve_data_set_with_mat4(
+ Key *key, const ListBase *nurb, const int shape_index, const void *data, const float mat[4][4])
+{
+ 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)) {
+ const int block_elem_size = kb->totelem * key->elemsize;
+ BKE_keyblock_curve_data_transform(nurb, mat, elements, kb->data);
+ elements += block_elem_size;
+ }
+ }
+}
+
+/**
+ * Set the data for all key-blocks (or shape_index if != -1).
+ */
+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)) {
+ const int block_elem_size = kb->totelem * key->elemsize;
+ memcpy(kb->data, elements, block_elem_size);
+ elements += block_elem_size;
+ }
+ }
+}
+
+/** \} */
+
bool BKE_key_idtype_support(const short id_type)
{
switch (id_type) {
@@ -1897,6 +2031,37 @@ void BKE_keyblock_update_from_curve(Curve *UNUSED(cu), KeyBlock *kb, ListBase *n
}
}
+void BKE_keyblock_curve_data_transform(const ListBase *nurb,
+ const float mat[4][4],
+ const void *src_data,
+ void *dst_data)
+{
+ const float *src = src_data;
+ float *dst = dst_data;
+ for (Nurb *nu = nurb->first; nu; nu = nu->next) {
+ if (nu->bezt) {
+ for (int a = nu->pntsu; a; a--) {
+ for (int i = 0; i < 3; i++) {
+ mul_v3_m4v3(&dst[i * 3], mat, &src[i * 3]);
+ }
+ dst[9] = src[9];
+ dst[10] = src[10];
+ src += KEYELEM_FLOAT_LEN_BEZTRIPLE;
+ dst += KEYELEM_FLOAT_LEN_BEZTRIPLE;
+ }
+ }
+ else {
+ for (int a = nu->pntsu * nu->pntsv; a; a--) {
+ mul_v3_m4v3(dst, mat, src);
+ dst[3] = src[3];
+ dst[4] = src[4];
+ src += KEYELEM_FLOAT_LEN_BPOINT;
+ dst += KEYELEM_FLOAT_LEN_BPOINT;
+ }
+ }
+ }
+}
+
void BKE_keyblock_convert_from_curve(Curve *cu, KeyBlock *kb, ListBase *nurb)
{
int tot;
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index 8820434cbcf..4d523ffa2e0 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -672,7 +672,7 @@ void BKE_lattice_center_bounds(Lattice *lt, float cent[3])
mid_v3_v3v3(cent, min, max);
}
-void BKE_lattice_transform(Lattice *lt, float mat[4][4], bool do_keys)
+void BKE_lattice_transform(Lattice *lt, const float mat[4][4], bool do_keys)
{
BPoint *bp = lt->def;
int i = lt->pntsu * lt->pntsv * lt->pntsw;
@@ -694,7 +694,7 @@ void BKE_lattice_transform(Lattice *lt, float mat[4][4], bool do_keys)
}
}
-void BKE_lattice_translate(Lattice *lt, float offset[3], bool do_keys)
+void BKE_lattice_translate(Lattice *lt, const float offset[3], bool do_keys)
{
int i, numVerts;
diff --git a/source/blender/blenkernel/intern/lattice_deform.c b/source/blender/blenkernel/intern/lattice_deform.c
index 2b3349d4d9a..674ee9ed2c5 100644
--- a/source/blender/blenkernel/intern/lattice_deform.c
+++ b/source/blender/blenkernel/intern/lattice_deform.c
@@ -418,8 +418,8 @@ static void lattice_deform_coords_impl(const Object *ob_lattice,
void BKE_lattice_deform_coords(const Object *ob_lattice,
const Object *ob_target,
float (*vert_coords)[3],
- int vert_coords_len,
- short flag,
+ const int vert_coords_len,
+ const short flag,
const char *defgrp_name,
float fac)
{
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index f03bf60817f..83071fd5dd3 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -221,7 +221,7 @@ ViewLayer *BKE_view_layer_add(Scene *scene,
view_layer_new = view_layer_add(name);
BLI_addtail(&scene->view_layers, view_layer_new);
- /* Initialise layercollections */
+ /* Initialize layer-collections. */
BKE_layer_collection_sync(scene, view_layer_new);
layer_collection_exclude_all(view_layer_new->layer_collections.first);
@@ -695,8 +695,8 @@ int BKE_layer_collection_findindex(ViewLayer *view_layer, const LayerCollection
* stores state like selection. */
static void layer_collection_sync(ViewLayer *view_layer,
- const ListBase *lb_scene,
- ListBase *lb_layer,
+ const ListBase *lb_collections,
+ ListBase *lb_layer_collections,
ListBase *new_object_bases,
short parent_exclude,
short parent_restrict,
@@ -708,11 +708,10 @@ static void layer_collection_sync(ViewLayer *view_layer,
* linking we can only sync after the fact. */
/* Remove layer collections that no longer have a corresponding scene collection. */
- for (LayerCollection *lc = lb_layer->first; lc;) {
- /* Note ID remap can set lc->collection to NULL when deleting collections. */
- LayerCollection *lc_next = lc->next;
+ LISTBASE_FOREACH_MUTABLE (LayerCollection *, lc, lb_layer_collections) {
+ /* Note that ID remap can set lc->collection to NULL when deleting collections. */
Collection *collection = (lc->collection) ?
- BLI_findptr(lb_scene,
+ BLI_findptr(lb_collections,
lc->collection,
offsetof(CollectionChild, collection)) :
NULL;
@@ -724,21 +723,20 @@ static void layer_collection_sync(ViewLayer *view_layer,
/* Free recursively. */
layer_collection_free(view_layer, lc);
- BLI_freelinkN(lb_layer, lc);
+ BLI_freelinkN(lb_layer_collections, lc);
}
-
- lc = lc_next;
}
/* Add layer collections for any new scene collections, and ensure order is the same. */
ListBase new_lb_layer = {NULL, NULL};
- LISTBASE_FOREACH (const CollectionChild *, child, lb_scene) {
+ LISTBASE_FOREACH (const CollectionChild *, child, lb_collections) {
Collection *collection = child->collection;
- LayerCollection *lc = BLI_findptr(lb_layer, collection, offsetof(LayerCollection, collection));
+ LayerCollection *lc = BLI_findptr(
+ lb_layer_collections, collection, offsetof(LayerCollection, collection));
if (lc) {
- BLI_remlink(lb_layer, lc);
+ BLI_remlink(lb_layer_collections, lc);
BLI_addtail(&new_lb_layer, lc);
}
else {
@@ -845,8 +843,8 @@ static void layer_collection_sync(ViewLayer *view_layer,
}
/* Replace layer collection list with new one. */
- *lb_layer = new_lb_layer;
- BLI_assert(BLI_listbase_count(lb_scene) == BLI_listbase_count(lb_layer));
+ *lb_layer_collections = new_lb_layer;
+ BLI_assert(BLI_listbase_count(lb_collections) == BLI_listbase_count(lb_layer_collections));
}
/**
@@ -876,9 +874,9 @@ void BKE_layer_collection_sync(const Scene *scene, ViewLayer *view_layer)
}
/* Generate new layer connections and object bases when collections changed. */
- CollectionChild child = {NULL, NULL, scene->master_collection};
- const ListBase collections = {&child, &child};
- ListBase new_object_bases = {NULL, NULL};
+ CollectionChild child = {.next = NULL, .prev = NULL, .collection = scene->master_collection};
+ const ListBase collections = {.first = &child, .last = &child};
+ ListBase new_object_bases = {.first = NULL, .last = NULL};
const short parent_exclude = 0, parent_restrict = 0, parent_layer_restrict = 0;
layer_collection_sync(view_layer,
diff --git a/source/blender/blenkernel/intern/lib_id.c b/source/blender/blenkernel/intern/lib_id.c
index 7c09ae51344..a64e550579d 100644
--- a/source/blender/blenkernel/intern/lib_id.c
+++ b/source/blender/blenkernel/intern/lib_id.c
@@ -611,41 +611,39 @@ bool BKE_id_copy(Main *bmain, const ID *id, ID **newid)
* Invokes the appropriate copy method for the block and returns the result in
* newid, unless test. Returns true if the block can be copied.
*/
-ID *BKE_id_copy_for_duplicate(Main *bmain,
- ID *id,
- const bool is_owner_id_liboverride,
- const eDupli_ID_Flags duplicate_flags)
+ID *BKE_id_copy_for_duplicate(Main *bmain, ID *id, const eDupli_ID_Flags duplicate_flags)
{
if (id == NULL) {
- return NULL;
+ return id;
}
if (id->newid == NULL) {
- if (!is_owner_id_liboverride || !ID_IS_LINKED(id)) {
- ID *id_new;
- BKE_id_copy(bmain, id, &id_new);
- /* Copying add one user by default, need to get rid of that one. */
- id_us_min(id_new);
- ID_NEW_SET(id, id_new);
-
- /* Shape keys are always copied with their owner ID, by default. */
- ID *key_new = (ID *)BKE_key_from_id(id_new);
- ID *key = (ID *)BKE_key_from_id(id);
- if (key != NULL) {
- ID_NEW_SET(key, key_new);
- }
+ const bool do_linked_id = (duplicate_flags & USER_DUP_LINKED_ID) != 0;
+ if (!(do_linked_id || !ID_IS_LINKED(id))) {
+ return id;
+ }
- /* Note: embedded data (root nodetrees and master collections) should never be referenced by
- * anything else, so we do not need to set their newid pointer and flag. */
+ ID *id_new;
+ BKE_id_copy(bmain, id, &id_new);
+ /* Copying add one user by default, need to get rid of that one. */
+ id_us_min(id_new);
+ ID_NEW_SET(id, id_new);
- if (duplicate_flags & USER_DUP_ACT) {
- BKE_animdata_copy_id_action(bmain, id_new, true);
- if (key_new != NULL) {
- BKE_animdata_copy_id_action(bmain, key_new, true);
- }
- /* Note that actions of embedded data (root nodetrees and master collections) are handled
- * by `BKE_animdata_copy_id_action` as well. */
- }
+ /* Shape keys are always copied with their owner ID, by default. */
+ ID *key_new = (ID *)BKE_key_from_id(id_new);
+ ID *key = (ID *)BKE_key_from_id(id);
+ if (key != NULL) {
+ ID_NEW_SET(key, key_new);
}
+
+ /* Note: embedded data (root nodetrees and master collections) should never be referenced by
+ * anything else, so we do not need to set their newid pointer and flag. */
+
+ BKE_animdata_duplicate_id_action(bmain, id_new, duplicate_flags);
+ if (key_new != NULL) {
+ BKE_animdata_duplicate_id_action(bmain, id_new, duplicate_flags);
+ }
+ /* Note that actions of embedded data (root nodetrees and master collections) are handled
+ * by `BKE_animdata_duplicate_id_action` as well. */
}
return id->newid;
}
@@ -2163,7 +2161,7 @@ void BKE_id_full_name_get(char name[MAX_ID_FULL_NAME], const ID *id, char separa
/**
* Generate full name of the data-block (without ID code, but with library if any),
- * with a 3-character prefix prepended indicating whether it comes from a library,
+ * with a 2 to 3 character prefix prepended indicating whether it comes from a library,
* is overriding, has a fake or no user, etc.
*
* \note Result is unique to a given ID type in a given Main database.
@@ -2172,11 +2170,13 @@ void BKE_id_full_name_get(char name[MAX_ID_FULL_NAME], const ID *id, char separa
* will be filled with generated string.
* \param separator_char: Character to use for separating name and library name. Can be 0 to use
* default (' ').
+ * \param r_prefix_len: The length of the prefix added.
*/
void BKE_id_full_name_ui_prefix_get(char name[MAX_ID_FULL_NAME_UI],
const ID *id,
const bool add_lib_hint,
- char separator_char)
+ char separator_char,
+ int *r_prefix_len)
{
int i = 0;
@@ -2187,6 +2187,10 @@ void BKE_id_full_name_ui_prefix_get(char name[MAX_ID_FULL_NAME_UI],
name[i++] = ' ';
BKE_id_full_name_get(name + i, id, separator_char);
+
+ if (r_prefix_len) {
+ *r_prefix_len = i;
+ }
}
/**
diff --git a/source/blender/blenkernel/intern/lib_id_delete.c b/source/blender/blenkernel/intern/lib_id_delete.c
index b4f2caac861..561db7d62c2 100644
--- a/source/blender/blenkernel/intern/lib_id_delete.c
+++ b/source/blender/blenkernel/intern/lib_id_delete.c
@@ -144,15 +144,14 @@ void BKE_id_free_ex(Main *bmain, void *idv, int flag, const bool use_flag_from_i
}
#endif
+ Key *key = ((flag & LIB_ID_FREE_NO_MAIN) == 0) ? BKE_key_from_id(id) : NULL;
+
if ((flag & LIB_ID_FREE_NO_USER_REFCOUNT) == 0) {
BKE_libblock_relink_ex(bmain, id, NULL, NULL, 0);
}
- if ((flag & LIB_ID_FREE_NO_MAIN) == 0) {
- Key *key = BKE_key_from_id(id);
- if (key != NULL) {
- BKE_id_free_ex(bmain, &key->id, flag, use_flag_from_idtag);
- }
+ if ((flag & LIB_ID_FREE_NO_MAIN) == 0 && key != NULL) {
+ BKE_id_free_ex(bmain, &key->id, flag, use_flag_from_idtag);
}
BKE_libblock_free_datablock(id, flag);
diff --git a/source/blender/blenkernel/intern/lib_intern.h b/source/blender/blenkernel/intern/lib_intern.h
index 9cc5db64d17..7305785573b 100644
--- a/source/blender/blenkernel/intern/lib_intern.h
+++ b/source/blender/blenkernel/intern/lib_intern.h
@@ -21,11 +21,8 @@
* \ingroup bke
*/
-#ifndef __LIB_INTERN_H__
-#define __LIB_INTERN_H__
+#pragma once
extern BKE_library_free_notifier_reference_cb free_notifier_reference_cb;
extern BKE_library_remap_editor_id_reference_cb remap_editor_id_reference_cb;
-
-#endif /* __LIB_INTERN_H__ */
diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c
index 457d096f983..8b0517a77fb 100644
--- a/source/blender/blenkernel/intern/lib_override.c
+++ b/source/blender/blenkernel/intern/lib_override.c
@@ -27,19 +27,25 @@
#include "MEM_guardedalloc.h"
#include "DNA_ID.h"
+#include "DNA_collection_types.h"
#include "DNA_key_types.h"
#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
#include "BKE_armature.h"
+#include "BKE_collection.h"
#include "BKE_idtype.h"
#include "BKE_key.h"
+#include "BKE_layer.h"
#include "BKE_lib_id.h"
#include "BKE_lib_override.h"
+#include "BKE_lib_query.h"
#include "BKE_lib_remap.h"
#include "BKE_main.h"
+#include "BKE_scene.h"
#include "BLI_ghash.h"
#include "BLI_listbase.h"
@@ -66,20 +72,6 @@ static void lib_override_library_property_clear(IDOverrideLibraryProperty *op);
static void lib_override_library_property_operation_clear(
IDOverrideLibraryPropertyOperation *opop);
-/* Temp, for until library override is ready and tested enough to go 'public',
- * we hide it by default in UI and such. */
-static bool _lib_override_library_enabled = true;
-
-void BKE_lib_override_library_enable(const bool do_enable)
-{
- _lib_override_library_enabled = do_enable;
-}
-
-bool BKE_lib_override_library_is_enabled()
-{
- return _lib_override_library_enabled;
-}
-
/** Initialize empty overriding of \a reference_id by \a local_id. */
IDOverrideLibrary *BKE_lib_override_library_init(ID *local_id, ID *reference_id)
{
@@ -163,8 +155,8 @@ void BKE_lib_override_library_clear(IDOverrideLibrary *override, const bool do_i
{
BLI_assert(override != NULL);
- if (override->runtime != NULL) {
- BLI_ghash_clear(override->runtime, NULL, NULL);
+ if (!ELEM(NULL, override->runtime, override->runtime->rna_path_to_override_properties)) {
+ BLI_ghash_clear(override->runtime->rna_path_to_override_properties, NULL, NULL);
}
LISTBASE_FOREACH (IDOverrideLibraryProperty *, op, &override->properties) {
@@ -184,8 +176,10 @@ void BKE_lib_override_library_free(struct IDOverrideLibrary **override, const bo
BLI_assert(*override != NULL);
if ((*override)->runtime != NULL) {
- BLI_ghash_free((*override)->runtime, NULL, NULL);
- (*override)->runtime = NULL;
+ if ((*override)->runtime->rna_path_to_override_properties != NULL) {
+ BLI_ghash_free((*override)->runtime->rna_path_to_override_properties, NULL, NULL);
+ }
+ MEM_SAFE_FREE((*override)->runtime);
}
BKE_lib_override_library_clear(*override, do_id_user);
@@ -368,19 +362,284 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain)
return success;
}
-/* We only build override GHash on request. */
-BLI_INLINE IDOverrideLibraryRuntime *override_library_rna_path_mapping_ensure(
+static bool lib_override_hierarchy_recursive_tag(Main *bmain, ID *id, const uint tag)
+{
+ void **entry_vp = BLI_ghash_lookup_p(bmain->relations->id_user_to_used, id);
+ if (entry_vp == NULL) {
+ /* Already processed. */
+ return (id->tag & tag) != 0;
+ }
+
+ /* This way we won't process again that ID should we encounter it again through another
+ * relationship hierarchy.
+ * Note that this does not free any memory from relations, so we can still use the entries.
+ */
+ BKE_main_relations_ID_remove(bmain, id);
+
+ for (MainIDRelationsEntry *entry = *entry_vp; entry != NULL; entry = entry->next) {
+ if ((entry->usage_flag & IDWALK_CB_LOOPBACK) != 0) {
+ /* Never consider 'loop back' relationships ('from', 'parents', 'owner' etc. pointers) as
+ * actual dependencies. */
+ continue;
+ }
+ /* We only consider IDs from the same library. */
+ if (entry->id_pointer != NULL && (*entry->id_pointer)->lib == id->lib) {
+ if (lib_override_hierarchy_recursive_tag(bmain, *entry->id_pointer, tag)) {
+ id->tag |= tag;
+ }
+ }
+ }
+
+ return (id->tag & tag) != 0;
+}
+
+/**
+ * Tag all IDs in given \a bmain that are being used by given \a id_root ID or its dependencies,
+ * recursively.
+ *
+ * This will include all local IDs, and all IDs from the same library as the \a id_root.
+ *
+ * \param id_root The root of the hierarchy of dependencies to be tagged.
+ * \param do_create_main_relashionships Whether main relations needs to be created or already exist
+ * (in any case, they will be freed by this function).
+ */
+void BKE_lib_override_library_dependencies_tag(struct Main *bmain,
+ struct ID *id_root,
+ const uint tag,
+ const bool do_create_main_relashionships)
+{
+ if (do_create_main_relashionships) {
+ BKE_main_relations_create(bmain, 0);
+ }
+
+ /* Then we tag all intermediary data-blocks in-between two overridden ones (e.g. if a shapekey
+ * has a driver using an armature object's bone, we need to override the shapekey/obdata, the
+ * objects using them, etc.) */
+ lib_override_hierarchy_recursive_tag(bmain, id_root, tag);
+
+ BKE_main_relations_free(bmain);
+}
+
+static int lib_override_library_make_tag_ids_cb(LibraryIDLinkCallbackData *cb_data)
+{
+ if (cb_data->cb_flag & (IDWALK_CB_EMBEDDED | IDWALK_CB_LOOPBACK)) {
+ return IDWALK_RET_STOP_RECURSION;
+ }
+
+ ID *id_root = cb_data->user_data;
+ Library *library_root = id_root->lib;
+ ID *id = *cb_data->id_pointer;
+ ID *id_owner = cb_data->id_owner;
+
+ BLI_assert(id_owner == cb_data->id_self);
+
+ if (ELEM(id, NULL, id_owner)) {
+ return IDWALK_RET_NOP;
+ }
+
+ BLI_assert(id->lib != NULL);
+ BLI_assert(id_owner->lib == library_root);
+
+ if (id->tag & LIB_TAG_DOIT) {
+ /* Already processed, but maybe not with the same chain of dependency, so we need to check that
+ * one nonetheless. */
+ return IDWALK_RET_STOP_RECURSION;
+ }
+
+ if (id->lib != library_root) {
+ /* We do not override data-blocks from other libraries, nor do we process them. */
+ return IDWALK_RET_STOP_RECURSION;
+ }
+
+ /* We tag all collections and objects for override. And we also tag all other data-blocks which
+ * would user one of those. */
+ if (ELEM(GS(id->name), ID_OB, ID_GR)) {
+ id->tag |= LIB_TAG_DOIT;
+ }
+
+ return IDWALK_RET_NOP;
+}
+
+/**
+ * Advanced 'smart' function to create fully functional overrides.
+ *
+ * \note Currently it only does special things if given \a id_root is an object of collection, more
+ * specific behaviors may be added in the future for other ID types.
+ *
+ * \note It will overrides all IDs tagged with \a LIB_TAG_DOIT, and it does not clear that tag at
+ * its beginning, so caller code can add extra data-blocks to be overridden as well.
+ *
+ * \note In the future that same function may be extended to support 'refresh' of overrides
+ * (rebuilding overrides from linked data, trying to preserve local overrides already defined).
+ *
+ * \param id_root The root ID to create an override from.
+ * \param id_reference some reference ID used to do some post-processing after overrides have been
+ * created, may be NULL. Typically, the Empty object instantiating the linked
+ * collection we override, currently.
+ * \return true if override was successfully created.
+ */
+bool BKE_lib_override_library_create(
+ Main *bmain, Scene *scene, ViewLayer *view_layer, ID *id_root, ID *id_reference)
+{
+ /* Tag all collections and objects, as well as other IDs using them. */
+ id_root->tag |= LIB_TAG_DOIT;
+
+ BKE_main_relations_create(bmain, 0);
+
+ if (ELEM(GS(id_root->name), ID_OB, ID_GR)) {
+ BKE_library_foreach_ID_link(bmain,
+ id_root,
+ lib_override_library_make_tag_ids_cb,
+ id_root,
+ IDWALK_READONLY | IDWALK_RECURSE);
+
+ /* Then, we remove (untag) bone shape objects, you shall never want to override those
+ * (hopefully)... */
+ LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
+ if (ob->type == OB_ARMATURE && ob->pose != NULL && (ob->id.tag & LIB_TAG_DOIT)) {
+ for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan != NULL; pchan = pchan->next) {
+ if (pchan->custom != NULL) {
+ pchan->custom->id.tag &= ~LIB_TAG_DOIT;
+ }
+ }
+ }
+ }
+ }
+
+ /* Note that this call will also free the main relations data we created above. */
+ BKE_lib_override_library_dependencies_tag(bmain, id_root, LIB_TAG_DOIT, false);
+
+ const bool success = BKE_lib_override_library_create_from_tag(bmain);
+
+ if (success) {
+ BKE_main_collection_sync(bmain);
+
+ switch (GS(id_root->name)) {
+ case ID_GR: {
+ Object *ob_reference = id_reference != NULL && GS(id_reference->name) == ID_OB ?
+ (Object *)id_reference :
+ NULL;
+ Collection *collection_new = ((Collection *)id_root->newid);
+ if (ob_reference != NULL) {
+ BKE_collection_add_from_object(bmain, scene, ob_reference, collection_new);
+ }
+ else {
+ BKE_collection_add_from_collection(
+ bmain, scene, ((Collection *)id_root), collection_new);
+ }
+
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (collection_new, ob_new) {
+ if (ob_new != NULL && ob_new->id.override_library != NULL) {
+ if (ob_reference != NULL) {
+ Base *base;
+ if ((base = BKE_view_layer_base_find(view_layer, ob_new)) == NULL) {
+ BKE_collection_object_add_from(bmain, scene, ob_reference, ob_new);
+ base = BKE_view_layer_base_find(view_layer, ob_new);
+ DEG_id_tag_update_ex(
+ bmain, &ob_new->id, ID_RECALC_TRANSFORM | ID_RECALC_BASE_FLAGS);
+ }
+
+ if (ob_new == (Object *)ob_reference->id.newid) {
+ /* TODO: is setting active needed? */
+ BKE_view_layer_base_select_and_set_active(view_layer, base);
+ }
+ }
+ else if (BKE_view_layer_base_find(view_layer, ob_new) == NULL) {
+ BKE_collection_object_add(bmain, collection_new, ob_new);
+ DEG_id_tag_update_ex(bmain, &ob_new->id, ID_RECALC_TRANSFORM | ID_RECALC_BASE_FLAGS);
+ }
+ }
+ }
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
+ break;
+ }
+ case ID_OB: {
+ BKE_collection_object_add_from(
+ bmain, scene, (Object *)id_root, ((Object *)id_root->newid));
+ break;
+ }
+ default:
+ break;
+ }
+
+ /* We need to ensure all new overrides of objects are properly instantiated. */
+ LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
+ Object *ob_new = (Object *)ob->id.newid;
+ if (ob_new != NULL) {
+ BLI_assert(ob_new->id.override_library != NULL &&
+ ob_new->id.override_library->reference == &ob->id);
+
+ Collection *default_instantiating_collection = NULL;
+ if (BKE_view_layer_base_find(view_layer, ob_new) == NULL) {
+ if (default_instantiating_collection == NULL) {
+ switch (GS(id_root->name)) {
+ case ID_GR: {
+ default_instantiating_collection = BKE_collection_add(
+ bmain, (Collection *)id_root, "OVERRIDE_HIDDEN");
+ break;
+ }
+ case ID_OB: {
+ /* Add the new container collection to one of the collections instantiating the
+ * root object, or scene's master collection if none found. */
+ Object *ob_root = (Object *)id_root;
+ LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
+ if (BKE_collection_has_object(collection, ob_root) &&
+ BKE_view_layer_has_collection(view_layer, collection) &&
+ !ID_IS_LINKED(collection) && !ID_IS_OVERRIDE_LIBRARY(collection)) {
+ default_instantiating_collection = BKE_collection_add(
+ bmain, collection, "OVERRIDE_HIDDEN");
+ }
+ }
+ if (default_instantiating_collection == NULL) {
+ default_instantiating_collection = BKE_collection_add(
+ bmain, scene->master_collection, "OVERRIDE_HIDDEN");
+ }
+ break;
+ }
+ default:
+ BLI_assert(0);
+ }
+ /* Hide the collection from viewport and render. */
+ default_instantiating_collection->flag |= COLLECTION_RESTRICT_VIEWPORT |
+ COLLECTION_RESTRICT_RENDER;
+ }
+
+ BKE_collection_object_add(bmain, default_instantiating_collection, ob_new);
+ DEG_id_tag_update_ex(bmain, &ob_new->id, ID_RECALC_TRANSFORM | ID_RECALC_BASE_FLAGS);
+ }
+ }
+ }
+ }
+
+ /* Cleanup. */
+ BKE_main_id_clear_newpoins(bmain);
+ BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
+
+ return success;
+}
+
+BLI_INLINE IDOverrideLibraryRuntime *override_library_rna_path_runtime_ensure(
IDOverrideLibrary *override)
{
if (override->runtime == NULL) {
- override->runtime = BLI_ghash_new(
+ override->runtime = MEM_callocN(sizeof(*override->runtime), __func__);
+ }
+ return override->runtime;
+}
+
+/* We only build override GHash on request. */
+BLI_INLINE GHash *override_library_rna_path_mapping_ensure(IDOverrideLibrary *override)
+{
+ IDOverrideLibraryRuntime *override_runtime = override_library_rna_path_runtime_ensure(override);
+ if (override_runtime->rna_path_to_override_properties == NULL) {
+ override_runtime->rna_path_to_override_properties = BLI_ghash_new(
BLI_ghashutil_strhash_p_murmur, BLI_ghashutil_strcmp, __func__);
for (IDOverrideLibraryProperty *op = override->properties.first; op != NULL; op = op->next) {
- BLI_ghash_insert(override->runtime, op->rna_path, op);
+ BLI_ghash_insert(override_runtime->rna_path_to_override_properties, op->rna_path, op);
}
}
- return override->runtime;
+ return override_runtime->rna_path_to_override_properties;
}
/**
@@ -389,7 +648,7 @@ BLI_INLINE IDOverrideLibraryRuntime *override_library_rna_path_mapping_ensure(
IDOverrideLibraryProperty *BKE_lib_override_library_property_find(IDOverrideLibrary *override,
const char *rna_path)
{
- IDOverrideLibraryRuntime *override_runtime = override_library_rna_path_mapping_ensure(override);
+ GHash *override_runtime = override_library_rna_path_mapping_ensure(override);
return BLI_ghash_lookup(override_runtime, rna_path);
}
@@ -407,8 +666,7 @@ IDOverrideLibraryProperty *BKE_lib_override_library_property_get(IDOverrideLibra
op->rna_path = BLI_strdup(rna_path);
BLI_addtail(&override->properties, op);
- IDOverrideLibraryRuntime *override_runtime = override_library_rna_path_mapping_ensure(
- override);
+ GHash *override_runtime = override_library_rna_path_mapping_ensure(override);
BLI_ghash_insert(override_runtime, op->rna_path, op);
if (r_created) {
@@ -454,8 +712,11 @@ void lib_override_library_property_clear(IDOverrideLibraryProperty *op)
void BKE_lib_override_library_property_delete(IDOverrideLibrary *override,
IDOverrideLibraryProperty *override_property)
{
- if (override->runtime != NULL) {
- BLI_ghash_remove(override->runtime, override_property->rna_path, NULL, NULL);
+ if (!ELEM(NULL, override->runtime, override->runtime->rna_path_to_override_properties)) {
+ BLI_ghash_remove(override->runtime->rna_path_to_override_properties,
+ override_property->rna_path,
+ NULL,
+ NULL);
}
lib_override_library_property_clear(override_property);
BLI_freelinkN(&override->properties, override_property);
@@ -884,11 +1145,11 @@ void BKE_lib_override_library_main_operations_create(Main *bmain, const bool for
TaskPool *task_pool = BLI_task_pool_create(bmain, TASK_PRIORITY_HIGH);
FOREACH_MAIN_ID_BEGIN (bmain, id) {
- if ((ID_IS_OVERRIDE_LIBRARY_REAL(id) && force_auto) ||
- (id->tag & LIB_TAG_OVERRIDE_LIBRARY_AUTOREFRESH)) {
+ if (ID_IS_OVERRIDE_LIBRARY_REAL(id) &&
+ (force_auto || (id->tag & LIB_TAG_OVERRIDE_LIBRARY_AUTOREFRESH))) {
BLI_task_pool_push(task_pool, lib_override_library_operations_create_cb, id, false, NULL);
- id->tag &= ~LIB_TAG_OVERRIDE_LIBRARY_AUTOREFRESH;
}
+ id->tag &= ~LIB_TAG_OVERRIDE_LIBRARY_AUTOREFRESH;
}
FOREACH_MAIN_ID_END;
@@ -905,6 +1166,137 @@ void BKE_lib_override_library_main_operations_create(Main *bmain, const bool for
#endif
}
+static bool lib_override_library_id_reset_do(Main *bmain, ID *id_root)
+{
+ bool was_op_deleted = false;
+
+ LISTBASE_FOREACH_MUTABLE (
+ IDOverrideLibraryProperty *, op, &id_root->override_library->properties) {
+ bool do_op_delete = true;
+ const bool is_collection = op->rna_prop_type == PROP_COLLECTION;
+ if (is_collection || op->rna_prop_type == PROP_POINTER) {
+ PointerRNA ptr_root, ptr_root_lib, ptr, ptr_lib;
+ PropertyRNA *prop, *prop_lib;
+
+ RNA_pointer_create(id_root, &RNA_ID, id_root, &ptr_root);
+ RNA_pointer_create(id_root->override_library->reference,
+ &RNA_ID,
+ id_root->override_library->reference,
+ &ptr_root_lib);
+
+ bool prop_exists = RNA_path_resolve_property(&ptr_root, op->rna_path, &ptr, &prop);
+ BLI_assert(prop_exists);
+ prop_exists = RNA_path_resolve_property(&ptr_root_lib, op->rna_path, &ptr_lib, &prop_lib);
+
+ if (prop_exists) {
+ BLI_assert(ELEM(RNA_property_type(prop), PROP_POINTER, PROP_COLLECTION));
+ BLI_assert(RNA_property_type(prop) == RNA_property_type(prop_lib));
+ if (is_collection) {
+ ptr.type = RNA_property_pointer_type(&ptr, prop);
+ ptr_lib.type = RNA_property_pointer_type(&ptr_lib, prop_lib);
+ }
+ else {
+ ptr = RNA_property_pointer_get(&ptr, prop);
+ ptr_lib = RNA_property_pointer_get(&ptr_lib, prop_lib);
+ }
+ if (ptr.owner_id != NULL && ptr_lib.owner_id != NULL) {
+ BLI_assert(ptr.type == ptr_lib.type);
+ do_op_delete = !(RNA_struct_is_ID(ptr.type) && ptr.owner_id->override_library != NULL &&
+ ptr.owner_id->override_library->reference == ptr_lib.owner_id);
+ }
+ }
+ }
+
+ if (do_op_delete) {
+ BKE_lib_override_library_property_delete(id_root->override_library, op);
+ was_op_deleted = true;
+ }
+ }
+
+ if (was_op_deleted) {
+ DEG_id_tag_update_ex(bmain, id_root, ID_RECALC_COPY_ON_WRITE);
+ IDOverrideLibraryRuntime *override_runtime = override_library_rna_path_runtime_ensure(
+ id_root->override_library);
+ override_runtime->tag |= IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RELOAD;
+ }
+
+ return was_op_deleted;
+}
+
+/** Reset all overrides in given \a id_root, while preserving ID relations. */
+void BKE_lib_override_library_id_reset(Main *bmain, ID *id_root)
+{
+ if (!ID_IS_OVERRIDE_LIBRARY_REAL(id_root)) {
+ return;
+ }
+
+ if (lib_override_library_id_reset_do(bmain, id_root)) {
+ if (id_root->override_library->runtime != NULL &&
+ (id_root->override_library->runtime->tag & IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RELOAD) !=
+ 0) {
+ BKE_lib_override_library_update(bmain, id_root);
+ id_root->override_library->runtime->tag &= ~IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RELOAD;
+ }
+ }
+}
+
+static void lib_override_library_id_hierarchy_recursive_reset(Main *bmain, ID *id_root)
+{
+ if (!ID_IS_OVERRIDE_LIBRARY_REAL(id_root)) {
+ return;
+ }
+
+ void **entry_pp = BLI_ghash_lookup(bmain->relations->id_user_to_used, id_root);
+ if (entry_pp == NULL) {
+ /* Already processed. */
+ return;
+ }
+
+ lib_override_library_id_reset_do(bmain, id_root);
+
+ /* This way we won't process again that ID should we encounter it again through another
+ * relationship hierarchy.
+ * Note that this does not free any memory from relations, so we can still use the entries.
+ */
+ BKE_main_relations_ID_remove(bmain, id_root);
+
+ for (MainIDRelationsEntry *entry = *entry_pp; entry != NULL; entry = entry->next) {
+ if ((entry->usage_flag & IDWALK_CB_LOOPBACK) != 0) {
+ /* Never consider 'loop back' relationships ('from', 'parents', 'owner' etc. pointers) as
+ * actual dependencies. */
+ continue;
+ }
+ /* We only consider IDs from the same library. */
+ if (entry->id_pointer != NULL) {
+ ID *id_entry = *entry->id_pointer;
+ if (id_entry->override_library != NULL) {
+ lib_override_library_id_hierarchy_recursive_reset(bmain, id_entry);
+ }
+ }
+ }
+}
+
+/** Reset all overrides in given \a id_root and its dependencies, while preserving ID relations. */
+void BKE_lib_override_library_id_hierarchy_reset(Main *bmain, ID *id_root)
+{
+ BKE_main_relations_create(bmain, 0);
+
+ lib_override_library_id_hierarchy_recursive_reset(bmain, id_root);
+
+ BKE_main_relations_free(bmain);
+
+ ID *id;
+ FOREACH_MAIN_ID_BEGIN (bmain, id) {
+ if (!ID_IS_OVERRIDE_LIBRARY_REAL(id) || id->override_library->runtime == NULL ||
+ (id->override_library->runtime->tag & IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RELOAD) == 0) {
+ continue;
+ }
+ BKE_lib_override_library_update(bmain, id);
+ id->override_library->runtime->tag &= ~IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RELOAD;
+ }
+ FOREACH_MAIN_ID_END;
+}
+
/** Set or clear given tag in all operations as unused in that override property data. */
void BKE_lib_override_library_operations_tag(struct IDOverrideLibraryProperty *override_property,
const short tag,
@@ -1040,8 +1432,6 @@ void BKE_lib_override_library_update(Main *bmain, ID *local)
Key *local_key = BKE_key_from_id(local);
Key *tmp_key = BKE_key_from_id(tmp_id);
if (local_key != NULL && tmp_key != NULL) {
- /* This is some kind of hard-coded 'always enforced override'... */
- tmp_key->from = local_key->from;
tmp_key->id.flag |= (local_key->id.flag & LIB_EMBEDDED_DATA_LIB_OVERRIDE);
}
@@ -1060,6 +1450,18 @@ void BKE_lib_override_library_update(Main *bmain, ID *local)
* So when we'll free tmp_id, we'll actually free old, outdated data from local. */
BKE_lib_id_swap(bmain, local, tmp_id);
+ if (local_key != NULL && tmp_key != NULL) {
+ /* This is some kind of hard-coded 'always enforced override'... */
+ BKE_lib_id_swap(bmain, &local_key->id, &tmp_key->id);
+ tmp_key->id.flag |= (local_key->id.flag & LIB_EMBEDDED_DATA_LIB_OVERRIDE);
+ /* The swap of local and tmp_id inverted those pointers, we need to redefine proper
+ * relationships. */
+ *BKE_key_from_id_p(local) = local_key;
+ *BKE_key_from_id_p(tmp_id) = tmp_key;
+ local_key->from = local;
+ tmp_key->from = tmp_id;
+ }
+
/* Again, horribly inn-efficient in our case, we need something off-Main
* (aka more generic nolib copy/free stuff)! */
/* XXX And crashing in complex cases (e.g. because depsgraph uses same data...). */
@@ -1078,6 +1480,7 @@ void BKE_lib_override_library_update(Main *bmain, ID *local)
/* Full rebuild of Depsgraph! */
/* Note: this is really brute force, in theory updates from RNA should have handle this already,
* but for now let's play it safe. */
+ DEG_id_tag_update_ex(bmain, local, ID_RECALC_ALL);
DEG_relations_tag_update(bmain);
}
@@ -1112,7 +1515,7 @@ void BKE_lib_override_library_main_update(Main *bmain)
*/
/** Initialize an override storage. */
-OverrideLibraryStorage *BKE_lib_override_library_operations_store_initialize(void)
+OverrideLibraryStorage *BKE_lib_override_library_operations_store_init(void)
{
return BKE_main_new();
}
diff --git a/source/blender/blenkernel/intern/lib_query.c b/source/blender/blenkernel/intern/lib_query.c
index 00a42b12e07..0f81d45c10f 100644
--- a/source/blender/blenkernel/intern/lib_query.c
+++ b/source/blender/blenkernel/intern/lib_query.c
@@ -412,6 +412,8 @@ bool BKE_library_id_can_use_idtype(ID *id_owner, const short id_type_used)
return ELEM(id_type_used, ID_MA);
case ID_VO:
return ELEM(id_type_used, ID_MA);
+ case ID_SIM:
+ return ELEM(id_type_used, ID_OB, ID_IM);
case ID_IM:
case ID_VF:
case ID_TXT:
@@ -422,7 +424,6 @@ bool BKE_library_id_can_use_idtype(ID *id_owner, const short id_type_used)
case ID_PAL:
case ID_PC:
case ID_CF:
- case ID_SIM:
/* Those types never use/reference other IDs... */
return false;
case ID_IP:
diff --git a/source/blender/blenkernel/intern/light.c b/source/blender/blenkernel/intern/light.c
index aa1005c663f..f42df6765c4 100644
--- a/source/blender/blenkernel/intern/light.c
+++ b/source/blender/blenkernel/intern/light.c
@@ -58,7 +58,7 @@ static void light_init_data(ID *id)
MEMCPY_STRUCT_AFTER(la, DNA_struct_default_get(Light), id);
la->curfalloff = BKE_curvemapping_add(1, 0.0f, 1.0f, 1.0f, 0.0f);
- BKE_curvemapping_initialize(la->curfalloff);
+ BKE_curvemapping_init(la->curfalloff);
}
/**
diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index 49c909850de..7e859799a4e 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -624,7 +624,7 @@ void BKE_mask_point_segment_co(MaskSpline *spline, MaskSplinePoint *point, float
co, bezt->vec[1], bezt->vec[2], bezt_next->vec[0], bezt_next->vec[1], u);
}
-BLI_INLINE void orthogonal_direction_get(float vec[2], float result[2])
+BLI_INLINE void orthogonal_direction_get(const float vec[2], float result[2])
{
result[0] = -vec[1];
result[1] = vec[0];
diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c
index 412ccd3ab39..01d44d070b3 100644
--- a/source/blender/blenkernel/intern/mask_rasterize.c
+++ b/source/blender/blenkernel/intern/mask_rasterize.c
@@ -769,8 +769,8 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle,
BLI_assert(tot_diff_feather_points == tot_diff_point);
- /* note: only added for convenience, we don't infact use these to scanfill,
- * only to create feather faces after scanfill */
+ /* Note: only added for convenience, we don't in fact use these to scan-fill,
+ * only to create feather faces after scan-fill. */
for (j = 0; j < tot_diff_feather_points; j++) {
copy_v2_v2(co_feather, diff_feather_points[j]);
sf_vert = BLI_scanfill_vert_add(&sf_ctx, co_feather);
@@ -1256,7 +1256,7 @@ static float maskrasterize_layer_z_depth_quad(
return w[2] + w[3]; /* we can make this assumption for small speedup */
}
-static float maskrasterize_layer_isect(unsigned int *face,
+static float maskrasterize_layer_isect(const unsigned int *face,
float (*cos)[3],
const float dist_orig,
const float xy[2])
@@ -1489,6 +1489,8 @@ static void maskrasterize_buffer_cb(void *__restrict userdata,
void BKE_maskrasterize_buffer(MaskRasterHandle *mr_handle,
const unsigned int width,
const unsigned int height,
+ /* Cannot be const, because it is assigned to non-const variable.
+ * NOLINTNEXTLINE: readability-non-const-parameter. */
float *buffer)
{
const float x_inv = 1.0f / (float)width;
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index d4de04a9e98..e878a894b27 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -955,18 +955,26 @@ void BKE_object_material_remap_calc(Object *ob_dst, Object *ob_src, short *remap
void BKE_object_material_array_assign(Main *bmain,
struct Object *ob,
struct Material ***matar,
- short totcol)
+ int totcol,
+ const bool to_object_only)
{
int actcol_orig = ob->actcol;
- short i;
while ((ob->totcol > totcol) && BKE_object_material_slot_remove(bmain, ob)) {
/* pass */
}
/* now we have the right number of slots */
- for (i = 0; i < totcol; i++) {
- BKE_object_material_assign(bmain, ob, (*matar)[i], i + 1, BKE_MAT_ASSIGN_USERPREF);
+ for (int i = 0; i < totcol; i++) {
+ if (to_object_only && ob->matbits[i] == 0) {
+ /* If we only assign to object, and that slot uses obdata material, do nothing. */
+ continue;
+ }
+ BKE_object_material_assign(bmain,
+ ob,
+ (*matar)[i],
+ i + 1,
+ to_object_only ? BKE_MAT_ASSIGN_OBJECT : BKE_MAT_ASSIGN_USERPREF);
}
if (actcol_orig > ob->totcol) {
@@ -1272,8 +1280,6 @@ void BKE_texpaint_slot_refresh_cache(Scene *scene, Material *ma)
if (ma->paint_clone_slot >= count) {
ma->paint_clone_slot = count - 1;
}
-
- return;
}
void BKE_texpaint_slots_refresh_object(Scene *scene, struct Object *ob)
@@ -1712,6 +1718,29 @@ static void material_default_volume_init(Material *ma)
nodeSetActive(ntree, output);
}
+static void material_default_holdout_init(Material *ma)
+{
+ bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname);
+ ma->nodetree = ntree;
+ ma->use_nodes = true;
+
+ bNode *holdout = nodeAddStaticNode(NULL, ntree, SH_NODE_HOLDOUT);
+ bNode *output = nodeAddStaticNode(NULL, ntree, SH_NODE_OUTPUT_MATERIAL);
+
+ nodeAddLink(ntree,
+ holdout,
+ nodeFindSocket(holdout, SOCK_OUT, "Holdout"),
+ output,
+ nodeFindSocket(output, SOCK_IN, "Surface"));
+
+ holdout->locx = 10.0f;
+ holdout->locy = 300.0f;
+ output->locx = 300.0f;
+ output->locy = 300.0f;
+
+ nodeSetActive(ntree, output);
+}
+
Material *BKE_material_default_empty(void)
{
return &default_material_empty;
@@ -1757,6 +1786,7 @@ void BKE_materials_init(void)
material_default_surface_init(&default_material_surface);
material_default_volume_init(&default_material_volume);
+ material_default_holdout_init(&default_material_holdout);
material_default_gpencil_init(&default_material_gpencil);
}
diff --git a/source/blender/blenkernel/intern/mball_tessellate.c b/source/blender/blenkernel/intern/mball_tessellate.c
index ad178e76ef6..72b99bea0f4 100644
--- a/source/blender/blenkernel/intern/mball_tessellate.c
+++ b/source/blender/blenkernel/intern/mball_tessellate.c
@@ -315,7 +315,7 @@ static float densfunc(const MetaElem *ball, float x, float y, float z)
float dist2;
float dvec[3] = {x, y, z};
- mul_m4_v3((float(*)[4])ball->imat, dvec);
+ mul_m4_v3((const float(*)[4])ball->imat, dvec);
switch (ball->type) {
case MB_BALL:
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 48baedadd73..048af022adb 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -1305,7 +1305,7 @@ bool BKE_mesh_minmax(const Mesh *me, float r_min[3], float r_max[3])
return (me->totvert != 0);
}
-void BKE_mesh_transform(Mesh *me, float mat[4][4], bool do_keys)
+void BKE_mesh_transform(Mesh *me, const float mat[4][4], bool do_keys)
{
int i;
MVert *mvert = me->mvert;
diff --git a/source/blender/blenkernel/intern/mesh_convert.c b/source/blender/blenkernel/intern/mesh_convert.c
index 9e5565d744a..a0f3bc9e74d 100644
--- a/source/blender/blenkernel/intern/mesh_convert.c
+++ b/source/blender/blenkernel/intern/mesh_convert.c
@@ -286,12 +286,14 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob,
}
}
else if (dl->type == DL_SURF) {
- int tot;
- totvert += dl->parts * dl->nr;
- tot = (dl->parts - 1 + ((dl->flag & DL_CYCL_V) == 2)) *
- (dl->nr - 1 + (dl->flag & DL_CYCL_U));
- totpoly += tot;
- totloop += tot * 4;
+ if (dl->parts != 0) {
+ int tot;
+ totvert += dl->parts * dl->nr;
+ tot = (((dl->flag & DL_CYCL_U) ? 1 : 0) + (dl->nr - 1)) *
+ (((dl->flag & DL_CYCL_V) ? 1 : 0) + (dl->parts - 1));
+ totpoly += tot;
+ totloop += tot * 4;
+ }
}
else if (dl->type == DL_INDEX3) {
int tot;
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c
index b298a6a2787..49957b584ad 100644
--- a/source/blender/blenkernel/intern/mesh_evaluate.c
+++ b/source/blender/blenkernel/intern/mesh_evaluate.c
@@ -2888,7 +2888,7 @@ void BKE_mesh_loops_to_mface_corners(
void BKE_mesh_loops_to_tessdata(CustomData *fdata,
CustomData *ldata,
MFace *mface,
- int *polyindices,
+ const int *polyindices,
unsigned int (*loopindices)[4],
const int num_faces)
{
@@ -2981,7 +2981,7 @@ void BKE_mesh_loops_to_tessdata(CustomData *fdata,
void BKE_mesh_tangent_loops_to_tessdata(CustomData *fdata,
CustomData *ldata,
MFace *mface,
- int *polyindices,
+ const int *polyindices,
unsigned int (*loopindices)[4],
const int num_faces,
const char *layer_name)
diff --git a/source/blender/blenkernel/intern/mesh_mapping.c b/source/blender/blenkernel/intern/mesh_mapping.c
index 4ed9b31dbb5..686f58a0ceb 100644
--- a/source/blender/blenkernel/intern/mesh_mapping.c
+++ b/source/blender/blenkernel/intern/mesh_mapping.c
@@ -953,7 +953,7 @@ void BKE_mesh_loop_islands_free(MeshIslandStore *island_store)
void BKE_mesh_loop_islands_add(MeshIslandStore *island_store,
const int item_num,
- int *items_indices,
+ const int *items_indices,
const int num_island_items,
int *island_item_indices,
const int num_innercut_items,
diff --git a/source/blender/blenkernel/intern/mesh_remap.c b/source/blender/blenkernel/intern/mesh_remap.c
index 404d6a581ae..a4991675d2d 100644
--- a/source/blender/blenkernel/intern/mesh_remap.c
+++ b/source/blender/blenkernel/intern/mesh_remap.c
@@ -1071,7 +1071,7 @@ static void mesh_island_to_astar_graph_edge_process(MeshIslandStore *islands,
BLI_bitmap *done_edges,
MeshElemMap *edge_to_poly_map,
const bool is_edge_innercut,
- int *poly_island_index_map,
+ const int *poly_island_index_map,
float (*poly_centers)[3],
unsigned char *poly_status)
{
diff --git a/source/blender/blenkernel/intern/mesh_runtime.c b/source/blender/blenkernel/intern/mesh_runtime.c
index 932423bc445..b9eb3876dde 100644
--- a/source/blender/blenkernel/intern/mesh_runtime.c
+++ b/source/blender/blenkernel/intern/mesh_runtime.c
@@ -43,8 +43,6 @@
/** \name Mesh Runtime Struct Utils
* \{ */
-static ThreadRWMutex loops_cache_lock = PTHREAD_RWLOCK_INITIALIZER;
-
/**
* Default values defined at read time.
*/
@@ -159,23 +157,21 @@ const MLoopTri *BKE_mesh_runtime_looptri_ensure(Mesh *mesh)
{
MLoopTri *looptri;
- BLI_rw_mutex_lock(&loops_cache_lock, THREAD_LOCK_READ);
+ ThreadMutex *mesh_eval_mutex = (ThreadMutex *)mesh->runtime.eval_mutex;
+ BLI_mutex_lock(mesh_eval_mutex);
+
looptri = mesh->runtime.looptris.array;
- BLI_rw_mutex_unlock(&loops_cache_lock);
if (looptri != NULL) {
BLI_assert(BKE_mesh_runtime_looptri_len(mesh) == mesh->runtime.looptris.len);
}
else {
- BLI_rw_mutex_lock(&loops_cache_lock, THREAD_LOCK_WRITE);
- /* We need to ensure array is still NULL inside mutex-protected code,
- * some other thread might have already recomputed those looptris. */
- if (mesh->runtime.looptris.array == NULL) {
- BKE_mesh_runtime_looptri_recalc(mesh);
- }
+ BKE_mesh_runtime_looptri_recalc(mesh);
looptri = mesh->runtime.looptris.array;
- BLI_rw_mutex_unlock(&loops_cache_lock);
}
+
+ BLI_mutex_unlock(mesh_eval_mutex);
+
return looptri;
}
diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c
index f64ed609d18..4d8c0568eb6 100644
--- a/source/blender/blenkernel/intern/mesh_validate.c
+++ b/source/blender/blenkernel/intern/mesh_validate.c
@@ -547,6 +547,16 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
for (i = 0, mp = mpolys; i < totpoly; i++, mp++, sp++) {
sp->index = i;
+ /* Material index, isolated from other tests here. While large indices are clamped,
+ * negative indices aren't supported by drawing, exporters etc.
+ * To check the indices are in range, use #BKE_mesh_validate_material_indices */
+ if (mp->mat_nr < 0) {
+ PRINT_ERR("\tPoly %u has invalid material (%d)", sp->index, mp->mat_nr);
+ if (do_fixes) {
+ mp->mat_nr = 0;
+ }
+ }
+
if (mp->loopstart < 0 || mp->totloop < 3) {
/* Invalid loop data. */
PRINT_ERR("\tPoly %u is invalid (loopstart: %d, totloop: %d)",
@@ -1133,14 +1143,15 @@ bool BKE_mesh_is_valid(Mesh *me)
*/
bool BKE_mesh_validate_material_indices(Mesh *me)
{
+ /* Cast to unsigned to catch negative indices too. */
+ const uint16_t mat_nr_max = max_ii(0, me->totcol - 1);
MPoly *mp;
- const int max_idx = max_ii(0, me->totcol - 1);
const int totpoly = me->totpoly;
int i;
bool is_valid = true;
for (mp = me->mpoly, i = 0; i < totpoly; i++, mp++) {
- if (mp->mat_nr > max_idx) {
+ if ((uint16_t)mp->mat_nr > mat_nr_max) {
mp->mat_nr = 0;
is_valid = false;
}
diff --git a/source/blender/blenkernel/intern/mesh_wrapper.c b/source/blender/blenkernel/intern/mesh_wrapper.c
index 6a8bc698b11..acd272ac305 100644
--- a/source/blender/blenkernel/intern/mesh_wrapper.c
+++ b/source/blender/blenkernel/intern/mesh_wrapper.c
@@ -40,6 +40,7 @@
#include "BLI_ghash.h"
#include "BLI_math.h"
+#include "BLI_threads.h"
#include "BLI_utildefines.h"
#include "BKE_editmesh.h"
@@ -96,9 +97,14 @@ Mesh *BKE_mesh_wrapper_from_editmesh(BMEditMesh *em,
void BKE_mesh_wrapper_ensure_mdata(Mesh *me)
{
+ ThreadMutex *mesh_eval_mutex = (ThreadMutex *)me->runtime.eval_mutex;
+ BLI_mutex_lock(mesh_eval_mutex);
+
if (me->runtime.wrapper_type == ME_WRAPPER_TYPE_MDATA) {
+ BLI_mutex_unlock(mesh_eval_mutex);
return;
}
+
const eMeshWrapperType geom_type_orig = me->runtime.wrapper_type;
me->runtime.wrapper_type = ME_WRAPPER_TYPE_MDATA;
@@ -130,6 +136,8 @@ void BKE_mesh_wrapper_ensure_mdata(Mesh *me)
if (me->runtime.wrapper_type_finalize) {
BKE_mesh_wrapper_deferred_finalize(me, &me->runtime.cd_mask_extra);
}
+
+ BLI_mutex_unlock(mesh_eval_mutex);
}
bool BKE_mesh_wrapper_minmax(const Mesh *me, float min[3], float max[3])
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index f0efc9b8c50..a5bd2ecf68a 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -129,6 +129,23 @@ static void movie_clip_foreach_id(ID *id, LibraryForeachIDData *data)
}
}
+static void movie_clip_foreach_cache(ID *id,
+ IDTypeForeachCacheFunctionCallback function_callback,
+ void *user_data)
+{
+ MovieClip *movie_clip = (MovieClip *)id;
+ IDCacheKey key = {
+ .id_session_uuid = id->session_uuid,
+ .offset_in_ID = offsetof(MovieClip, cache),
+ .cache_v = movie_clip->cache,
+ };
+ function_callback(id, &key, (void **)&movie_clip->cache, 0, user_data);
+
+ key.offset_in_ID = offsetof(MovieClip, tracking.camera.intrinsics);
+ key.cache_v = movie_clip->tracking.camera.intrinsics;
+ function_callback(id, &key, (void **)&movie_clip->tracking.camera.intrinsics, 0, user_data);
+}
+
IDTypeInfo IDType_ID_MC = {
.id_code = ID_MC,
.id_filter = FILTER_ID_MC,
@@ -144,6 +161,7 @@ IDTypeInfo IDType_ID_MC = {
.free_data = movie_clip_free_data,
.make_local = NULL,
.foreach_id = movie_clip_foreach_id,
+ .foreach_cache = movie_clip_foreach_cache,
};
/*********************** movieclip buffer loaders *************************/
@@ -1848,3 +1866,88 @@ void BKE_movieclip_eval_selection_update(struct Depsgraph *depsgraph, MovieClip
DEG_debug_print_eval(depsgraph, __func__, clip->id.name, clip);
movieclip_selection_sync(clip, (MovieClip *)clip->id.orig_id);
}
+
+/* -------------------------------------------------------------------- */
+/** \name GPU textures
+ * \{ */
+
+static GPUTexture **movieclip_get_gputexture_ptr(MovieClip *clip,
+ MovieClipUser *cuser,
+ eGPUTextureTarget textarget)
+{
+ /* Check if we have an existing entry for that clip user. */
+ MovieClip_RuntimeGPUTexture *tex;
+ for (tex = clip->runtime.gputextures.first; tex; tex = tex->next) {
+ if (memcmp(&tex->user, cuser, sizeof(MovieClipUser)) == 0) {
+ break;
+ }
+ }
+
+ /* If not, allocate a new one. */
+ if (tex == NULL) {
+ tex = (MovieClip_RuntimeGPUTexture *)MEM_mallocN(sizeof(MovieClip_RuntimeGPUTexture),
+ __func__);
+
+ for (int i = 0; i < TEXTARGET_COUNT; i++) {
+ tex->gputexture[i] = NULL;
+ }
+
+ memcpy(&tex->user, cuser, sizeof(MovieClipUser));
+ BLI_addtail(&clip->runtime.gputextures, tex);
+ }
+
+ return &tex->gputexture[textarget];
+}
+
+GPUTexture *BKE_movieclip_get_gpu_texture(MovieClip *clip, MovieClipUser *cuser)
+{
+ if (clip == NULL) {
+ return NULL;
+ }
+
+ GPUTexture **tex = movieclip_get_gputexture_ptr(clip, cuser, TEXTARGET_2D);
+ if (*tex) {
+ return *tex;
+ }
+
+ /* check if we have a valid image buffer */
+ ImBuf *ibuf = BKE_movieclip_get_ibuf(clip, cuser);
+ if (ibuf == NULL) {
+ *tex = GPU_texture_create_error(2, false);
+ return *tex;
+ }
+
+ /* This only means RGBA16F instead of RGBA32F. */
+ const bool high_bitdepth = false;
+ const bool store_premultiplied = ibuf->rect_float ? false : true;
+ *tex = IMB_create_gpu_texture(ibuf, high_bitdepth, store_premultiplied);
+
+ /* Do not generate mips for movieclips... too slow. */
+ GPU_texture_mipmap_mode(*tex, false, true);
+
+ IMB_freeImBuf(ibuf);
+
+ return *tex;
+}
+
+void BKE_movieclip_free_gputexture(struct MovieClip *clip)
+{
+ /* number of gpu textures to keep around as cache
+ * We don't want to keep too many GPU textures for
+ * movie clips around, as they can be large.*/
+ const int MOVIECLIP_NUM_GPUTEXTURES = 1;
+
+ while (BLI_listbase_count(&clip->runtime.gputextures) > MOVIECLIP_NUM_GPUTEXTURES) {
+ MovieClip_RuntimeGPUTexture *tex = (MovieClip_RuntimeGPUTexture *)BLI_pophead(
+ &clip->runtime.gputextures);
+ for (int i = 0; i < TEXTARGET_COUNT; i++) {
+ /* free glsl image binding */
+ if (tex->gputexture[i]) {
+ GPU_texture_free(tex->gputexture[i]);
+ tex->gputexture[i] = NULL;
+ }
+ }
+ MEM_freeN(tex);
+ }
+}
+/** \} */
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index 7e78be6d66e..6c10f6de855 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -175,7 +175,7 @@ static BLI_bitmap *multires_mdisps_upsample_hidden(BLI_bitmap *lo_hidden,
return subd;
}
-static BLI_bitmap *multires_mdisps_downsample_hidden(BLI_bitmap *old_hidden,
+static BLI_bitmap *multires_mdisps_downsample_hidden(const BLI_bitmap *old_hidden,
int old_level,
int new_level)
{
@@ -241,7 +241,7 @@ static void multires_mdisps_subdivide_hidden(MDisps *md, int new_level)
md->hidden = subd;
}
-static MDisps *multires_mdisps_initialize_hidden(Mesh *me, int level)
+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);
@@ -868,7 +868,7 @@ static void multires_subdivide_legacy(
mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
if (!mdisps) {
- mdisps = multires_mdisps_initialize_hidden(me, totlvl);
+ mdisps = multires_mdisps_init_hidden(me, totlvl);
}
if (mdisps->disps && !updateblock && lvl != 0) {
diff --git a/source/blender/blenkernel/intern/multires_inline.h b/source/blender/blenkernel/intern/multires_inline.h
index 3d00101ec29..49329698b3a 100644
--- a/source/blender/blenkernel/intern/multires_inline.h
+++ b/source/blender/blenkernel/intern/multires_inline.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __MULTIRES_INLINE_H__
-#define __MULTIRES_INLINE_H__
+#pragma once
#include "BKE_multires.h"
#include "BLI_math_vector.h"
@@ -57,5 +56,3 @@ BLI_INLINE void BKE_multires_construct_tangent_matrix(float tangent_matrix[3][3]
normalize_v3(tangent_matrix[1]);
normalize_v3(tangent_matrix[2]);
}
-
-#endif /* __MULTIRES_INLINE_H__ */
diff --git a/source/blender/blenkernel/intern/multires_reshape.h b/source/blender/blenkernel/intern/multires_reshape.h
index 12816a455ee..d6c1d79dfd7 100644
--- a/source/blender/blenkernel/intern/multires_reshape.h
+++ b/source/blender/blenkernel/intern/multires_reshape.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __BKE_INTERN_MULTIRES_RESHAPE_H__
-#define __BKE_INTERN_MULTIRES_RESHAPE_H__
+#pragma once
#include "BLI_sys_types.h"
@@ -331,4 +330,3 @@ void multires_reshape_apply_base_refine_from_base(MultiresReshapeContext *reshap
*
* NOTE: Will re-evaluate all leading modifiers, so it's not cheap. */
void multires_reshape_apply_base_refine_from_deform(MultiresReshapeContext *reshape_context);
-#endif /* __BKE_INTERN_MULTIRES_RESHAPE_H__ */
diff --git a/source/blender/blenkernel/intern/multires_reshape_smooth.c b/source/blender/blenkernel/intern/multires_reshape_smooth.c
index 3564ae80d24..e12e692ea23 100644
--- a/source/blender/blenkernel/intern/multires_reshape_smooth.c
+++ b/source/blender/blenkernel/intern/multires_reshape_smooth.c
@@ -271,7 +271,7 @@ static void base_surface_grids_allocate(MultiresReshapeSmoothContext *reshape_sm
for (int grid_index = 0; grid_index < num_grids; ++grid_index) {
surface_grid[grid_index].points = MEM_calloc_arrayN(
- sizeof(SurfacePoint), grid_area, "delta grid dispalcement");
+ sizeof(SurfacePoint), grid_area, "delta grid displacement");
}
reshape_smooth_context->base_surface_grids = surface_grid;
diff --git a/source/blender/blenkernel/intern/multires_unsubdivide.c b/source/blender/blenkernel/intern/multires_unsubdivide.c
index 6bd7b6b6a98..fa1a53f946e 100644
--- a/source/blender/blenkernel/intern/multires_unsubdivide.c
+++ b/source/blender/blenkernel/intern/multires_unsubdivide.c
@@ -80,7 +80,7 @@
/**
* Used to check if a vertex is in a disconnected element ID.
*/
-static bool is_vertex_in_id(BMVert *v, int *elem_id, int elem)
+static bool is_vertex_in_id(BMVert *v, const int *elem_id, int elem)
{
const int v_index = BM_elem_index_get(v);
return elem_id[v_index] == elem;
diff --git a/source/blender/blenkernel/intern/multires_unsubdivide.h b/source/blender/blenkernel/intern/multires_unsubdivide.h
index e00a1ae6d8b..39c6da0b6c8 100644
--- a/source/blender/blenkernel/intern/multires_unsubdivide.h
+++ b/source/blender/blenkernel/intern/multires_unsubdivide.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __BKE_INTERN_MULTIRES_UNSUBDIVIDE_H__
-#define __BKE_INTERN_MULTIRES_UNSUBDIVIDE_H__
+#pragma once
#include "BLI_sys_types.h"
@@ -90,5 +89,3 @@ void multires_unsubdivide_context_free(MultiresUnsubdivideContext *context);
/* Rebuilds all subdivision to the level 0 base mesh. */
bool multires_unsubdivide_to_basemesh(MultiresUnsubdivideContext *context);
-
-#endif /* __BKE_INTERN_MULTIRES_UNSUBDIVIDE_H__ */
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index b73f957535c..91693abd1cf 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -61,6 +61,7 @@
#include "BKE_lib_query.h"
#include "BKE_main.h"
#include "BKE_node.h"
+#include "BKE_simulation.h"
#include "BLI_ghash.h"
#include "BLI_threads.h"
@@ -315,6 +316,33 @@ static void node_foreach_id(ID *id, LibraryForeachIDData *data)
}
}
+static void node_foreach_cache(ID *id,
+ IDTypeForeachCacheFunctionCallback function_callback,
+ void *user_data)
+{
+ bNodeTree *nodetree = (bNodeTree *)id;
+ IDCacheKey key = {
+ .id_session_uuid = id->session_uuid,
+ .offset_in_ID = offsetof(bNodeTree, previews),
+ .cache_v = nodetree->previews,
+ };
+
+ /* TODO, see also `direct_link_nodetree()` in readfile.c. */
+#if 0
+ function_callback(id, &key, (void **)&nodetree->previews, 0, user_data);
+#endif
+
+ if (nodetree->type == NTREE_COMPOSIT) {
+ for (bNode *node = nodetree->nodes.first; node; node = node->next) {
+ if (node->type == CMP_NODE_MOVIEDISTORTION) {
+ key.offset_in_ID = (size_t)BLI_ghashutil_strhash_p(node->name);
+ key.cache_v = node->storage;
+ function_callback(id, &key, (void **)&node->storage, 0, user_data);
+ }
+ }
+ }
+}
+
IDTypeInfo IDType_ID_NT = {
.id_code = ID_NT,
.id_filter = FILTER_ID_NT,
@@ -330,6 +358,7 @@ IDTypeInfo IDType_ID_NT = {
.free_data = ntree_free_data,
.make_local = NULL,
.foreach_id = node_foreach_id,
+ .foreach_cache = node_foreach_cache,
};
static void node_add_sockets_from_type(bNodeTree *ntree, bNode *node, bNodeType *ntype)
@@ -817,12 +846,12 @@ static void socket_id_user_increment(bNodeSocket *sock)
switch ((eNodeSocketDatatype)sock->type) {
case SOCK_OBJECT: {
bNodeSocketValueObject *default_value = sock->default_value;
- id_us_plus(&default_value->value->id);
+ id_us_plus((ID *)default_value->value);
break;
}
case SOCK_IMAGE: {
bNodeSocketValueImage *default_value = sock->default_value;
- id_us_plus(&default_value->value->id);
+ id_us_plus((ID *)default_value->value);
break;
}
case SOCK_FLOAT:
@@ -2465,6 +2494,7 @@ ID *BKE_node_tree_find_owner_ID(Main *bmain, struct bNodeTree *ntree)
&bmain->textures,
&bmain->scenes,
&bmain->linestyles,
+ &bmain->simulations,
NULL};
for (int i = 0; lists[i] != NULL; i++) {
@@ -3609,6 +3639,16 @@ void ntreeUpdateAllUsers(Main *main, ID *ngroup)
FOREACH_NODETREE_END;
}
+static void ntreeUpdateSimulationDependencies(Main *main, bNodeTree *simulation_ntree)
+{
+ FOREACH_NODETREE_BEGIN (main, ntree, owner_id) {
+ if (GS(owner_id->name) == ID_SIM && ntree == simulation_ntree) {
+ BKE_simulation_update_dependencies((Simulation *)owner_id, main);
+ }
+ }
+ FOREACH_NODETREE_END;
+}
+
void ntreeUpdateTree(Main *bmain, bNodeTree *ntree)
{
bNode *node;
@@ -3651,7 +3691,6 @@ void ntreeUpdateTree(Main *bmain, bNodeTree *ntree)
ntreeInterfaceTypeUpdate(ntree);
}
- /* XXX hack, should be done by depsgraph!! */
if (bmain) {
ntreeUpdateAllUsers(bmain, &ntree->id);
}
@@ -3667,6 +3706,11 @@ void ntreeUpdateTree(Main *bmain, bNodeTree *ntree)
ntree_validate_links(ntree);
}
+ if (bmain != NULL && ntree->typeinfo == ntreeType_Simulation &&
+ (ntree->id.flag & LIB_EMBEDDED_DATA)) {
+ ntreeUpdateSimulationDependencies(bmain, ntree);
+ }
+
/* clear update flags */
for (node = ntree->nodes.first; node; node = node->next) {
node->update = 0;
@@ -4308,6 +4352,8 @@ static void registerSimulationNodes(void)
register_node_type_sim_emit_particles();
register_node_type_sim_time();
register_node_type_sim_particle_attribute();
+ register_node_type_sim_age_reached_event();
+ register_node_type_sim_kill_particle();
}
static void registerFunctionNodes(void)
@@ -4317,6 +4363,8 @@ static void registerFunctionNodes(void)
register_node_type_fn_switch();
register_node_type_fn_group_instance_id();
register_node_type_fn_combine_strings();
+ register_node_type_fn_object_transforms();
+ register_node_type_fn_random_float();
}
void init_nodesystem(void)
diff --git a/source/blender/blenkernel/intern/node_tree_ref.cc b/source/blender/blenkernel/intern/node_tree_ref.cc
deleted file mode 100644
index 54ea2d338db..00000000000
--- a/source/blender/blenkernel/intern/node_tree_ref.cc
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * 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.
- */
-
-#include "BKE_node_tree_ref.hh"
-
-#include "BLI_dot_export.hh"
-
-namespace blender::bke {
-
-NodeTreeRef::NodeTreeRef(bNodeTree *btree) : btree_(btree)
-{
- Map<bNode *, NodeRef *> node_mapping;
-
- LISTBASE_FOREACH (bNode *, bnode, &btree->nodes) {
- NodeRef &node = *allocator_.construct<NodeRef>();
-
- node.tree_ = this;
- node.bnode_ = bnode;
- node.id_ = nodes_by_id_.append_and_get_index(&node);
- RNA_pointer_create(&btree->id, &RNA_Node, bnode, &node.rna_);
-
- LISTBASE_FOREACH (bNodeSocket *, bsocket, &bnode->inputs) {
- InputSocketRef &socket = *allocator_.construct<InputSocketRef>();
- socket.node_ = &node;
- socket.index_ = node.inputs_.append_and_get_index(&socket);
- socket.is_input_ = true;
- socket.bsocket_ = bsocket;
- socket.id_ = sockets_by_id_.append_and_get_index(&socket);
- RNA_pointer_create(&btree->id, &RNA_NodeSocket, bsocket, &socket.rna_);
- }
-
- LISTBASE_FOREACH (bNodeSocket *, bsocket, &bnode->outputs) {
- OutputSocketRef &socket = *allocator_.construct<OutputSocketRef>();
- socket.node_ = &node;
- socket.index_ = node.outputs_.append_and_get_index(&socket);
- socket.is_input_ = false;
- socket.bsocket_ = bsocket;
- socket.id_ = sockets_by_id_.append_and_get_index(&socket);
- RNA_pointer_create(&btree->id, &RNA_NodeSocket, bsocket, &socket.rna_);
- }
-
- input_sockets_.extend(node.inputs_);
- output_sockets_.extend(node.outputs_);
-
- node_mapping.add_new(bnode, &node);
- }
-
- LISTBASE_FOREACH (bNodeLink *, blink, &btree->links) {
- OutputSocketRef &from_socket = this->find_output_socket(
- node_mapping, blink->fromnode, blink->fromsock);
- InputSocketRef &to_socket = this->find_input_socket(
- node_mapping, blink->tonode, blink->tosock);
-
- from_socket.directly_linked_sockets_.append(&to_socket);
- to_socket.directly_linked_sockets_.append(&from_socket);
- }
-
- for (OutputSocketRef *socket : output_sockets_) {
- if (!socket->node_->is_reroute_node()) {
- this->find_targets_skipping_reroutes(*socket, socket->linked_sockets_);
- for (SocketRef *target : socket->linked_sockets_) {
- target->linked_sockets_.append(socket);
- }
- }
- }
-
- for (NodeRef *node : nodes_by_id_) {
- const bNodeType *nodetype = node->bnode_->typeinfo;
- nodes_by_type_.lookup_or_add_default(nodetype).append(node);
- }
-}
-
-NodeTreeRef::~NodeTreeRef()
-{
- for (NodeRef *node : nodes_by_id_) {
- node->~NodeRef();
- }
- for (InputSocketRef *socket : input_sockets_) {
- socket->~InputSocketRef();
- }
- for (OutputSocketRef *socket : output_sockets_) {
- socket->~OutputSocketRef();
- }
-}
-
-InputSocketRef &NodeTreeRef::find_input_socket(Map<bNode *, NodeRef *> &node_mapping,
- bNode *bnode,
- bNodeSocket *bsocket)
-{
- NodeRef *node = node_mapping.lookup(bnode);
- for (SocketRef *socket : node->inputs_) {
- if (socket->bsocket_ == bsocket) {
- return *(InputSocketRef *)socket;
- }
- }
- BLI_assert(false);
- return *node->inputs_[0];
-}
-
-OutputSocketRef &NodeTreeRef::find_output_socket(Map<bNode *, NodeRef *> &node_mapping,
- bNode *bnode,
- bNodeSocket *bsocket)
-{
- NodeRef *node = node_mapping.lookup(bnode);
- for (SocketRef *socket : node->outputs_) {
- if (socket->bsocket_ == bsocket) {
- return *(OutputSocketRef *)socket;
- }
- }
- BLI_assert(false);
- return *node->outputs_[0];
-}
-
-void NodeTreeRef::find_targets_skipping_reroutes(OutputSocketRef &socket,
- Vector<SocketRef *> &r_targets)
-{
- for (SocketRef *direct_target : socket.directly_linked_sockets_) {
- if (direct_target->node_->is_reroute_node()) {
- this->find_targets_skipping_reroutes(*direct_target->node_->outputs_[0], r_targets);
- }
- else {
- r_targets.append_non_duplicates(direct_target);
- }
- }
-}
-
-std::string NodeTreeRef::to_dot() const
-{
- dot::DirectedGraph digraph;
- digraph.set_rankdir(dot::Attr_rankdir::LeftToRight);
-
- Map<const NodeRef *, dot::NodeWithSocketsRef> dot_nodes;
-
- for (const NodeRef *node : nodes_by_id_) {
- dot::Node &dot_node = digraph.new_node("");
- dot_node.set_background_color("white");
-
- Vector<std::string> input_names;
- Vector<std::string> output_names;
- for (const InputSocketRef *socket : node->inputs()) {
- input_names.append(socket->name());
- }
- for (const OutputSocketRef *socket : node->outputs()) {
- output_names.append(socket->name());
- }
-
- dot_nodes.add_new(node,
- dot::NodeWithSocketsRef(dot_node, node->name(), input_names, output_names));
- }
-
- for (const OutputSocketRef *from_socket : output_sockets_) {
- for (const InputSocketRef *to_socket : from_socket->directly_linked_sockets()) {
- dot::NodeWithSocketsRef &from_dot_node = dot_nodes.lookup(&from_socket->node());
- dot::NodeWithSocketsRef &to_dot_node = dot_nodes.lookup(&to_socket->node());
-
- digraph.new_edge(from_dot_node.output(from_socket->index()),
- to_dot_node.input(to_socket->index()));
- }
- }
-
- return digraph.to_dot_string();
-}
-
-} // namespace blender::bke
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 6331f87f09f..fe559d2a44e 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -1760,7 +1760,7 @@ Object *BKE_object_copy(Main *bmain, const Object *ob)
*/
Object *BKE_object_duplicate(Main *bmain,
Object *ob,
- const eDupli_ID_Flags dupflag,
+ eDupli_ID_Flags dupflag,
const eLibIDDuplicateFlags duplicate_options)
{
const bool is_subprocess = (duplicate_options & LIB_ID_DUPLICATE_IS_SUBPROCESS) != 0;
@@ -1768,10 +1768,14 @@ Object *BKE_object_duplicate(Main *bmain,
if (!is_subprocess) {
BKE_main_id_tag_all(bmain, LIB_TAG_NEW, false);
BKE_main_id_clear_newpoins(bmain);
+ /* In case root duplicated ID is linked, assume we want to get a local copy of it and duplicate
+ * all expected linked data. */
+ if (ID_IS_LINKED(ob)) {
+ dupflag |= USER_DUP_LINKED_ID;
+ }
}
Material ***matarar;
- const bool is_object_liboverride = ID_IS_OVERRIDE_LIBRARY(ob);
Object *obn;
BKE_id_copy(bmain, &ob->id, (ID **)&obn);
@@ -1785,112 +1789,109 @@ Object *BKE_object_duplicate(Main *bmain,
return obn;
}
- /* duplicates using userflags */
- if (dupflag & USER_DUP_ACT) {
- BKE_animdata_copy_id_action(bmain, &obn->id, true);
- }
+ BKE_animdata_duplicate_id_action(bmain, &obn->id, dupflag);
if (dupflag & USER_DUP_MAT) {
for (int i = 0; i < obn->totcol; i++) {
- BKE_id_copy_for_duplicate(bmain, (ID *)obn->mat[i], is_object_liboverride, dupflag);
+ BKE_id_copy_for_duplicate(bmain, (ID *)obn->mat[i], dupflag);
}
}
if (dupflag & USER_DUP_PSYS) {
ParticleSystem *psys;
for (psys = obn->particlesystem.first; psys; psys = psys->next) {
- BKE_id_copy_for_duplicate(bmain, (ID *)psys->part, is_object_liboverride, dupflag);
+ BKE_id_copy_for_duplicate(bmain, (ID *)psys->part, dupflag);
}
}
- ID *id = obn->data;
+ ID *id_old = obn->data;
ID *id_new = NULL;
- const bool need_to_duplicate_obdata = (id != NULL) && (id->newid == NULL);
+ const bool need_to_duplicate_obdata = (id_old != NULL) && (id_old->newid == NULL);
switch (obn->type) {
case OB_MESH:
if (dupflag & USER_DUP_MESH) {
- id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag);
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
}
break;
case OB_CURVE:
if (dupflag & USER_DUP_CURVE) {
- id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag);
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
}
break;
case OB_SURF:
if (dupflag & USER_DUP_SURF) {
- id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag);
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
}
break;
case OB_FONT:
if (dupflag & USER_DUP_FONT) {
- id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag);
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
}
break;
case OB_MBALL:
if (dupflag & USER_DUP_MBALL) {
- id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag);
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
}
break;
case OB_LAMP:
if (dupflag & USER_DUP_LAMP) {
- id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag);
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
}
break;
case OB_ARMATURE:
if (dupflag & USER_DUP_ARM) {
- id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag);
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
}
break;
case OB_LATTICE:
if (dupflag != 0) {
- id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag);
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
}
break;
case OB_CAMERA:
if (dupflag != 0) {
- id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag);
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
}
break;
case OB_LIGHTPROBE:
if (dupflag & USER_DUP_LIGHTPROBE) {
- id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag);
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
}
break;
case OB_SPEAKER:
if (dupflag != 0) {
- id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag);
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
}
break;
case OB_GPENCIL:
if (dupflag & USER_DUP_GPENCIL) {
- id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag);
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
}
break;
case OB_HAIR:
if (dupflag & USER_DUP_HAIR) {
- id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag);
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
}
break;
case OB_POINTCLOUD:
if (dupflag & USER_DUP_POINTCLOUD) {
- id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag);
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
}
break;
case OB_VOLUME:
if (dupflag & USER_DUP_VOLUME) {
- id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag);
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
}
break;
}
/* If obdata has been copied, we may also have to duplicate the materials assigned to it. */
- if (need_to_duplicate_obdata && id_new != NULL) {
+ if (need_to_duplicate_obdata && !ELEM(id_new, NULL, id_old)) {
if (dupflag & USER_DUP_MAT) {
matarar = BKE_object_material_array_p(obn);
if (matarar) {
for (int i = 0; i < obn->totcol; i++) {
- BKE_id_copy_for_duplicate(bmain, (ID *)(*matarar)[i], is_object_liboverride, dupflag);
+ BKE_id_copy_for_duplicate(bmain, (ID *)(*matarar)[i], dupflag);
}
}
}
@@ -2087,7 +2088,7 @@ void BKE_object_make_proxy(Main *bmain, Object *ob, Object *target, Object *cob)
/* type conversions */
if (target->type == OB_ARMATURE) {
copy_object_pose(ob, target, 0); /* data copy, object pointers in constraints */
- BKE_pose_rest(ob->pose); /* clear all transforms in channels */
+ BKE_pose_rest(ob->pose, false); /* clear all transforms in channels */
BKE_pose_rebuild(bmain, ob, ob->data, true); /* set all internal links */
armature_set_id_extern(ob);
@@ -2343,7 +2344,7 @@ void BKE_object_tfm_copy(Object *object_dst, const Object *object_src)
#undef TFMCPY4D
}
-void BKE_object_to_mat3(Object *ob, float mat[3][3]) /* no parent */
+void BKE_object_to_mat3(Object *ob, float r_mat[3][3]) /* no parent */
{
float smat[3][3];
float rmat[3][3];
@@ -2354,38 +2355,38 @@ void BKE_object_to_mat3(Object *ob, float mat[3][3]) /* no parent */
/* rot */
BKE_object_rot_to_mat3(ob, rmat, true);
- mul_m3_m3m3(mat, rmat, smat);
+ mul_m3_m3m3(r_mat, rmat, smat);
}
-void BKE_object_to_mat4(Object *ob, float mat[4][4])
+void BKE_object_to_mat4(Object *ob, float r_mat[4][4])
{
float tmat[3][3];
BKE_object_to_mat3(ob, tmat);
- copy_m4_m3(mat, tmat);
+ copy_m4_m3(r_mat, tmat);
- add_v3_v3v3(mat[3], ob->loc, ob->dloc);
+ add_v3_v3v3(r_mat[3], ob->loc, ob->dloc);
}
-void BKE_object_matrix_local_get(struct Object *ob, float mat[4][4])
+void BKE_object_matrix_local_get(struct Object *ob, float r_mat[4][4])
{
if (ob->parent) {
float par_imat[4][4];
BKE_object_get_parent_matrix(ob, ob->parent, par_imat);
invert_m4(par_imat);
- mul_m4_m4m4(mat, par_imat, ob->obmat);
+ mul_m4_m4m4(r_mat, par_imat, ob->obmat);
}
else {
- copy_m4_m4(mat, ob->obmat);
+ copy_m4_m4(r_mat, ob->obmat);
}
}
/**
* \return success if \a mat is set.
*/
-static bool ob_parcurve(Object *ob, Object *par, float mat[4][4])
+static bool ob_parcurve(Object *ob, Object *par, float r_mat[4][4])
{
Curve *cu = par->data;
float vec[4], dir[3], quat[4], radius, ctime;
@@ -2408,7 +2409,7 @@ static bool ob_parcurve(Object *ob, Object *par, float mat[4][4])
/* ctime is now a proper var setting of Curve which gets set by Animato like any other var
* that's animated, but this will only work if it actually is animated.
*
- * We divide the curvetime calculated in the previous step by the length of the path,
+ * We divide the curve-time calculated in the previous step by the length of the path,
* to get a time factor, which then gets clamped to lie within 0.0 - 1.0 range.
*/
if (cu->pathlen) {
@@ -2419,34 +2420,34 @@ static bool ob_parcurve(Object *ob, Object *par, float mat[4][4])
}
CLAMP(ctime, 0.0f, 1.0f);
- unit_m4(mat);
+ unit_m4(r_mat);
/* vec: 4 items! */
if (where_on_path(par, ctime, vec, dir, (cu->flag & CU_FOLLOW) ? quat : NULL, &radius, NULL)) {
if (cu->flag & CU_FOLLOW) {
quat_apply_track(quat, ob->trackflag, ob->upflag);
normalize_qt(quat);
- quat_to_mat4(mat, quat);
+ quat_to_mat4(r_mat, quat);
}
if (cu->flag & CU_PATH_RADIUS) {
float tmat[4][4], rmat[4][4];
scale_m4_fl(tmat, radius);
- mul_m4_m4m4(rmat, tmat, mat);
- copy_m4_m4(mat, rmat);
+ mul_m4_m4m4(rmat, tmat, r_mat);
+ copy_m4_m4(r_mat, rmat);
}
- copy_v3_v3(mat[3], vec);
+ copy_v3_v3(r_mat[3], vec);
}
return true;
}
-static void ob_parbone(Object *ob, Object *par, float mat[4][4])
+static void ob_parbone(Object *ob, Object *par, float r_mat[4][4])
{
bPoseChannel *pchan;
float vec[3];
if (par->type != OB_ARMATURE) {
- unit_m4(mat);
+ unit_m4(r_mat);
return;
}
@@ -2455,7 +2456,7 @@ static void ob_parbone(Object *ob, Object *par, float mat[4][4])
if (!pchan || !pchan->bone) {
CLOG_ERROR(
&LOG, "Object %s with Bone parent: bone %s doesn't exist", ob->id.name + 2, ob->parsubstr);
- unit_m4(mat);
+ unit_m4(r_mat);
return;
}
@@ -2463,15 +2464,15 @@ static void ob_parbone(Object *ob, Object *par, float mat[4][4])
if (pchan->bone->flag & BONE_RELATIVE_PARENTING) {
/* the new option uses the root - expected behavior, but differs from old... */
/* XXX check on version patching? */
- copy_m4_m4(mat, pchan->chan_mat);
+ copy_m4_m4(r_mat, pchan->chan_mat);
}
else {
- copy_m4_m4(mat, pchan->pose_mat);
+ copy_m4_m4(r_mat, pchan->pose_mat);
/* but for backwards compatibility, the child has to move to the tail */
- copy_v3_v3(vec, mat[1]);
+ copy_v3_v3(vec, r_mat[1]);
mul_v3_fl(vec, pchan->bone->length);
- add_v3_v3(mat[3], vec);
+ add_v3_v3(r_mat[3], vec);
}
}
@@ -2593,7 +2594,7 @@ static void give_parvert(Object *par, int nr, float vec[3])
}
}
-static void ob_parvert3(Object *ob, Object *par, float mat[4][4])
+static void ob_parvert3(Object *ob, Object *par, float r_mat[4][4])
{
/* in local ob space */
@@ -2606,16 +2607,16 @@ static void ob_parvert3(Object *ob, Object *par, float mat[4][4])
tri_to_quat(q, v1, v2, v3);
quat_to_mat3(cmat, q);
- copy_m4_m3(mat, cmat);
+ copy_m4_m3(r_mat, cmat);
- mid_v3_v3v3v3(mat[3], v1, v2, v3);
+ mid_v3_v3v3v3(r_mat[3], v1, v2, v3);
}
else {
- unit_m4(mat);
+ unit_m4(r_mat);
}
}
-void BKE_object_get_parent_matrix(Object *ob, Object *par, float parentmat[4][4])
+void BKE_object_get_parent_matrix(Object *ob, Object *par, float r_parentmat[4][4])
{
float tmat[4][4];
float vec[3];
@@ -2631,31 +2632,31 @@ void BKE_object_get_parent_matrix(Object *ob, Object *par, float parentmat[4][4]
}
if (ok) {
- mul_m4_m4m4(parentmat, par->obmat, tmat);
+ mul_m4_m4m4(r_parentmat, par->obmat, tmat);
}
else {
- copy_m4_m4(parentmat, par->obmat);
+ copy_m4_m4(r_parentmat, par->obmat);
}
break;
case PARBONE:
ob_parbone(ob, par, tmat);
- mul_m4_m4m4(parentmat, par->obmat, tmat);
+ mul_m4_m4m4(r_parentmat, par->obmat, tmat);
break;
case PARVERT1:
- unit_m4(parentmat);
+ unit_m4(r_parentmat);
give_parvert(par, ob->par1, vec);
- mul_v3_m4v3(parentmat[3], par->obmat, vec);
+ mul_v3_m4v3(r_parentmat[3], par->obmat, vec);
break;
case PARVERT3:
ob_parvert3(ob, par, tmat);
- mul_m4_m4m4(parentmat, par->obmat, tmat);
+ mul_m4_m4m4(r_parentmat, par->obmat, tmat);
break;
case PARSKEL:
- copy_m4_m4(parentmat, par->obmat);
+ copy_m4_m4(r_parentmat, par->obmat);
break;
}
}
@@ -2671,7 +2672,7 @@ void BKE_object_get_parent_matrix(Object *ob, Object *par, float parentmat[4][4]
* (without its own matrix applied)
*/
static void solve_parenting(
- Object *ob, Object *par, float obmat[4][4], float r_originmat[3][3], const bool set_origin)
+ Object *ob, Object *par, const bool set_origin, float r_obmat[4][4], float r_originmat[3][3])
{
float totmat[4][4];
float tmat[4][4];
@@ -2683,7 +2684,7 @@ static void solve_parenting(
/* total */
mul_m4_m4m4(tmat, totmat, ob->parentinv);
- mul_m4_m4m4(obmat, tmat, locmat);
+ mul_m4_m4m4(r_obmat, tmat, locmat);
if (r_originmat) {
/* usable originmat */
@@ -2713,7 +2714,7 @@ static void object_where_is_calc_ex(Depsgraph *depsgraph,
Object *par = ob->parent;
/* calculate parent matrix */
- solve_parenting(ob, par, ob->obmat, r_originmat, true);
+ solve_parenting(ob, par, true, ob->obmat, r_originmat);
}
else {
BKE_object_to_mat4(ob, ob->obmat);
@@ -2745,7 +2746,10 @@ void BKE_object_where_is_calc_time(Depsgraph *depsgraph, Scene *scene, Object *o
{
/* Execute drivers and animation. */
const bool flush_to_original = DEG_is_active(depsgraph);
- BKE_animsys_evaluate_animdata(&ob->id, ob->adt, ctime, ADT_RECALC_ALL, flush_to_original);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ ctime);
+ BKE_animsys_evaluate_animdata(
+ &ob->id, ob->adt, &anim_eval_context, ADT_RECALC_ALL, flush_to_original);
object_where_is_calc_ex(depsgraph, scene, ob, ctime, NULL, NULL);
}
@@ -2753,14 +2757,14 @@ void BKE_object_where_is_calc_time(Depsgraph *depsgraph, Scene *scene, Object *o
* constraints -- assume dependencies are already solved by depsgraph.
* no changes to object and it's parent would be done.
* used for bundles orientation in 3d space relative to parented blender camera */
-void BKE_object_where_is_calc_mat4(Object *ob, float obmat[4][4])
+void BKE_object_where_is_calc_mat4(Object *ob, float r_obmat[4][4])
{
if (ob->parent) {
Object *par = ob->parent;
- solve_parenting(ob, par, obmat, NULL, false);
+ solve_parenting(ob, par, false, r_obmat, NULL);
}
else {
- BKE_object_to_mat4(ob, obmat);
+ BKE_object_to_mat4(ob, r_obmat);
}
}
@@ -2821,8 +2825,11 @@ void BKE_object_workob_calc_parent(Depsgraph *depsgraph, Scene *scene, Object *o
* \param use_compat: true to ensure that rotations are set using the
* min difference between the old and new orientation.
*/
-void BKE_object_apply_mat4_ex(
- Object *ob, float mat[4][4], Object *parent, float parentinv[4][4], const bool use_compat)
+void BKE_object_apply_mat4_ex(Object *ob,
+ const float mat[4][4],
+ Object *parent,
+ const float parentinv[4][4],
+ const bool use_compat)
{
/* see BKE_pchan_apply_mat4() for the equivalent 'pchan' function */
@@ -2863,7 +2870,7 @@ void BKE_object_apply_mat4_ex(
/* XXX: should be removed after COW operators port to use BKE_object_apply_mat4_ex directly */
void BKE_object_apply_mat4(Object *ob,
- float mat[4][4],
+ const float mat[4][4],
const bool use_compat,
const bool use_parent)
{
@@ -2913,7 +2920,10 @@ void BKE_boundbox_calc_size_aabb(const BoundBox *bb, float r_size[3])
r_size[2] = 0.5f * fabsf(bb->vec[0][2] - bb->vec[1][2]);
}
-void BKE_boundbox_minmax(const BoundBox *bb, float obmat[4][4], float r_min[3], float r_max[3])
+void BKE_boundbox_minmax(const BoundBox *bb,
+ const float obmat[4][4],
+ float r_min[3],
+ float r_max[3])
{
int i;
for (i = 0; i < 8; i++) {
@@ -3005,7 +3015,7 @@ void BKE_object_boundbox_calc_from_mesh(struct Object *ob, struct Mesh *me_eval)
* \warning Setting dimensions is prone to feedback loops in evaluation.
* \{ */
-void BKE_object_dimensions_get(Object *ob, float vec[3])
+void BKE_object_dimensions_get(Object *ob, float r_vec[3])
{
BoundBox *bb = NULL;
@@ -3015,12 +3025,12 @@ void BKE_object_dimensions_get(Object *ob, float vec[3])
mat4_to_size(scale, ob->obmat);
- vec[0] = fabsf(scale[0]) * (bb->vec[4][0] - bb->vec[0][0]);
- vec[1] = fabsf(scale[1]) * (bb->vec[2][1] - bb->vec[0][1]);
- vec[2] = fabsf(scale[2]) * (bb->vec[1][2] - bb->vec[0][2]);
+ r_vec[0] = fabsf(scale[0]) * (bb->vec[4][0] - bb->vec[0][0]);
+ r_vec[1] = fabsf(scale[1]) * (bb->vec[2][1] - bb->vec[0][1]);
+ r_vec[2] = fabsf(scale[2]) * (bb->vec[1][2] - bb->vec[0][2]);
}
else {
- zero_v3(vec);
+ zero_v3(r_vec);
}
}
@@ -3058,9 +3068,9 @@ void BKE_object_dimensions_set_ex(Object *ob,
}
}
- if (len[i] > 0.0f) {
-
- ob->scale[i] = copysignf(value[i] / len[i], ob->scale[i]);
+ const float scale = copysignf(value[i] / len[i], ob->scale[i]);
+ if (isfinite(scale)) {
+ ob->scale[i] = scale;
}
}
}
@@ -3289,7 +3299,7 @@ bool BKE_object_minmax_dupli(Depsgraph *depsgraph,
}
void BKE_object_foreach_display_point(Object *ob,
- float obmat[4][4],
+ const float obmat[4][4],
void (*func_cb)(const float[3], void *),
void *user_data)
{
@@ -3960,15 +3970,20 @@ int BKE_object_is_modified(Scene *scene, Object *ob)
return flag;
}
-/* Check of objects moves in time. */
-/* NOTE: This function is currently optimized for usage in combination
- * with mti->canDeform, so modifiers can quickly check if their target
- * objects moves (causing deformation motion blur) or not.
+/**
+ * Check of objects moves in time.
+ *
+ * \note This function is currently optimized for usage in combination
+ * with modifier deformation checks (#eModifierTypeType_OnlyDeform),
+ * so modifiers can quickly check if their target objects moves
+ * (causing deformation motion blur) or not.
*
* This makes it possible to give some degree of false-positives here,
* but it's currently an acceptable tradeoff between complexity and check
* speed. In combination with checks of modifier stack and real life usage
- * percentage of false-positives shouldn't be that height.
+ * percentage of false-positives shouldn't be that high.
+ *
+ * \note This function does not consider physics systems.
*/
bool BKE_object_moves_in_time(const Object *object, bool recurse_parent)
{
@@ -4642,9 +4657,13 @@ bool BKE_object_modifier_update_subframe(Depsgraph *depsgraph,
/* was originally ID_RECALC_ALL - TODO - which flags are really needed??? */
/* TODO(sergey): What about animation? */
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ frame);
+
ob->id.recalc |= ID_RECALC_ALL;
if (update_mesh) {
- BKE_animsys_evaluate_animdata(&ob->id, ob->adt, frame, ADT_RECALC_ANIM, flush_to_original);
+ BKE_animsys_evaluate_animdata(
+ &ob->id, ob->adt, &anim_eval_context, ADT_RECALC_ANIM, flush_to_original);
/* ignore cache clear during subframe updates
* to not mess up cache validity */
object_cacheIgnoreClear(ob, 1);
@@ -4658,12 +4677,14 @@ bool BKE_object_modifier_update_subframe(Depsgraph *depsgraph,
/* for curve following objects, parented curve has to be updated too */
if (ob->type == OB_CURVE) {
Curve *cu = ob->data;
- BKE_animsys_evaluate_animdata(&cu->id, cu->adt, frame, ADT_RECALC_ANIM, flush_to_original);
+ BKE_animsys_evaluate_animdata(
+ &cu->id, cu->adt, &anim_eval_context, ADT_RECALC_ANIM, flush_to_original);
}
/* and armatures... */
if (ob->type == OB_ARMATURE) {
bArmature *arm = ob->data;
- BKE_animsys_evaluate_animdata(&arm->id, arm->adt, frame, ADT_RECALC_ANIM, flush_to_original);
+ BKE_animsys_evaluate_animdata(
+ &arm->id, arm->adt, &anim_eval_context, ADT_RECALC_ANIM, flush_to_original);
BKE_pose_where_is(depsgraph, scene, ob);
}
diff --git a/source/blender/blenkernel/intern/object_deform.c b/source/blender/blenkernel/intern/object_deform.c
index 6ca1442497a..51ec89cf77d 100644
--- a/source/blender/blenkernel/intern/object_deform.c
+++ b/source/blender/blenkernel/intern/object_deform.c
@@ -68,7 +68,7 @@ static Lattice *object_defgroup_lattice_get(ID *id)
*
* \param map: an array mapping old indices to new indices.
*/
-void BKE_object_defgroup_remap_update_users(Object *ob, int *map)
+void BKE_object_defgroup_remap_update_users(Object *ob, const int *map)
{
ModifierData *md;
ParticleSystem *psys;
diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c
index 4c6354f12a1..e0aea3a2910 100644
--- a/source/blender/blenkernel/intern/object_dupli.c
+++ b/source/blender/blenkernel/intern/object_dupli.c
@@ -37,6 +37,7 @@
#include "DNA_collection_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_pointcloud_types.h"
#include "DNA_scene_types.h"
#include "DNA_vfont_types.h"
@@ -186,7 +187,7 @@ static DupliObject *make_dupli(const DupliContext *ctx, Object *ob, float mat[4]
dob->random_id = BLI_hash_string(dob->ob->id.name + 2);
if (dob->persistent_id[0] != INT_MAX) {
- for (i = 0; i < MAX_DUPLI_RECUR * 2; i++) {
+ for (i = 0; i < MAX_DUPLI_RECUR; i++) {
dob->random_id = BLI_hash_int_2d(dob->random_id, (unsigned int)dob->persistent_id[i]);
}
}
@@ -367,17 +368,13 @@ static void vertex_dupli(const VertexDupliData *vdd,
DupliObject *dob;
float obmat[4][4], space_mat[4][4];
- /* obmat is transform to vertex */
- get_duplivert_transform(co, no, vdd->use_rotation, inst_ob->trackflag, inst_ob->upflag, obmat);
+ /* space_mat is transform to vertex */
+ get_duplivert_transform(
+ co, no, vdd->use_rotation, inst_ob->trackflag, inst_ob->upflag, space_mat);
/* make offset relative to inst_ob using relative child transform */
- mul_mat3_m4_v3((float(*)[4])vdd->child_imat, obmat[3]);
+ mul_mat3_m4_v3((float(*)[4])vdd->child_imat, space_mat[3]);
/* apply obmat _after_ the local vertex transform */
- mul_m4_m4m4(obmat, inst_ob->obmat, obmat);
-
- /* space matrix is constructed by removing obmat transform,
- * this yields the worldspace transform for recursive duplis
- */
- mul_m4_m4m4(space_mat, obmat, inst_ob->imat);
+ mul_m4_m4m4(obmat, inst_ob->obmat, space_mat);
dob = make_dupli(vdd->ctx, vdd->inst_ob, obmat, index);
@@ -523,7 +520,7 @@ static void make_duplis_font(const DupliContext *ctx)
/* Safety check even if it might fail badly when called for original object. */
const bool is_eval_curve = DEG_is_evaluated_id(&cu->id);
- /* advance matching BLI_strncpy_wchar_from_utf8 */
+ /* Advance matching BLI_str_utf8_as_utf32. */
for (a = 0; a < text_len; a++, ct++) {
/* XXX That G.main is *really* ugly, but not sure what to do here...
@@ -573,6 +570,63 @@ static const DupliGenerator gen_dupli_verts_font = {
make_duplis_font /* make_duplis */
};
+/* OB_DUPLIVERTS - PointCloud */
+static void make_child_duplis_pointcloud(const DupliContext *ctx,
+ void *UNUSED(userdata),
+ Object *child)
+{
+ const Object *parent = ctx->object;
+ const PointCloud *pointcloud = parent->data;
+ const float(*co)[3] = pointcloud->co;
+ const float *radius = pointcloud->radius;
+ const float(*rotation)[4] = NULL; /* TODO: add optional rotation attribute. */
+ const float(*orco)[3] = NULL; /* TODO: add optional texture coordinate attribute. */
+
+ /* Relative transform from parent to child space. */
+ float child_imat[4][4];
+ mul_m4_m4m4(child_imat, child->imat, parent->obmat);
+
+ for (int i = 0; i < pointcloud->totpoint; i++) {
+ /* Transform matrix from point position, radius and rotation. */
+ float quat[4] = {1.0f, 0.0f, 0.0f, 0.0f};
+ float size[3] = {1.0f, 1.0f, 1.0f};
+ if (radius) {
+ copy_v3_fl(size, radius[i]);
+ }
+ if (rotation) {
+ copy_v4_v4(quat, rotation[i]);
+ }
+
+ float space_mat[4][4];
+ loc_quat_size_to_mat4(space_mat, co[i], quat, size);
+
+ /* Make offset relative to child object using relative child transform,
+ * and apply object matrix after local vertex transform. */
+ mul_mat3_m4_v3(child_imat, space_mat[3]);
+
+ /* Create dupli object. */
+ float obmat[4][4];
+ mul_m4_m4m4(obmat, child->obmat, space_mat);
+ DupliObject *dob = make_dupli(ctx, child, obmat, i);
+ if (orco) {
+ copy_v3_v3(dob->orco, orco[i]);
+ }
+
+ /* Recursion. */
+ make_recursive_duplis(ctx, child, space_mat, i);
+ }
+}
+
+static void make_duplis_pointcloud(const DupliContext *ctx)
+{
+ make_child_duplis(ctx, NULL, make_child_duplis_pointcloud);
+}
+
+static const DupliGenerator gen_dupli_verts_pointcloud = {
+ OB_DUPLIVERTS, /* type */
+ make_duplis_pointcloud /* make_duplis */
+};
+
/* OB_DUPLIFACES */
typedef struct FaceDupliData {
Mesh *me_eval;
@@ -1105,6 +1159,9 @@ static const DupliGenerator *get_dupli_generator(const DupliContext *ctx)
else if (ctx->object->type == OB_FONT) {
return &gen_dupli_verts_font;
}
+ else if (ctx->object->type == OB_POINTCLOUD) {
+ return &gen_dupli_verts_pointcloud;
+ }
}
else if (transflag & OB_DUPLIFACES) {
if (ctx->object->type == OB_MESH) {
diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c
index 8957628c76a..198ff5a0540 100644
--- a/source/blender/blenkernel/intern/ocean.c
+++ b/source/blender/blenkernel/intern/ocean.c
@@ -147,19 +147,19 @@ static void init_complex(fftw_complex cmpl, float real, float image)
cmpl[1] = image;
}
-static void add_comlex_c(fftw_complex res, fftw_complex cmpl1, fftw_complex cmpl2)
+static void add_comlex_c(fftw_complex res, const fftw_complex cmpl1, const fftw_complex cmpl2)
{
res[0] = cmpl1[0] + cmpl2[0];
res[1] = cmpl1[1] + cmpl2[1];
}
-static void mul_complex_f(fftw_complex res, fftw_complex cmpl, float f)
+static void mul_complex_f(fftw_complex res, const fftw_complex cmpl, float f)
{
res[0] = cmpl[0] * (double)f;
res[1] = cmpl[1] * (double)f;
}
-static void mul_complex_c(fftw_complex res, fftw_complex cmpl1, fftw_complex cmpl2)
+static void mul_complex_c(fftw_complex res, const fftw_complex cmpl1, const fftw_complex cmpl2)
{
fftwf_complex temp;
temp[0] = cmpl1[0] * cmpl2[0] - cmpl1[1] * cmpl2[1];
@@ -178,7 +178,7 @@ static float image_c(fftw_complex cmpl)
return cmpl[1];
}
-static void conj_complex(fftw_complex res, fftw_complex cmpl1)
+static void conj_complex(fftw_complex res, const fftw_complex cmpl1)
{
res[0] = cmpl1[0];
res[1] = -cmpl1[1];
@@ -753,18 +753,26 @@ struct Ocean *BKE_ocean_add(void)
return oc;
}
-bool BKE_ocean_ensure(struct OceanModifierData *omd)
+bool BKE_ocean_ensure(struct OceanModifierData *omd, const int resolution)
{
if (omd->ocean) {
- return false;
+ /* Check that the ocean has the same resolution than we want now. */
+ if (omd->ocean->_M == resolution * resolution) {
+ return false;
+ }
+ else {
+ BKE_ocean_free(omd->ocean);
+ }
}
omd->ocean = BKE_ocean_add();
- BKE_ocean_init_from_modifier(omd->ocean, omd);
+ BKE_ocean_init_from_modifier(omd->ocean, omd, resolution);
return true;
}
-void BKE_ocean_init_from_modifier(struct Ocean *ocean, struct OceanModifierData const *omd)
+void BKE_ocean_init_from_modifier(struct Ocean *ocean,
+ struct OceanModifierData const *omd,
+ const int resolution)
{
short do_heightfield, do_chop, do_normals, do_jacobian;
@@ -774,9 +782,10 @@ void BKE_ocean_init_from_modifier(struct Ocean *ocean, struct OceanModifierData
do_jacobian = (omd->flag & MOD_OCEAN_GENERATE_FOAM);
BKE_ocean_free_data(ocean);
+
BKE_ocean_init(ocean,
- omd->resolution * omd->resolution,
- omd->resolution * omd->resolution,
+ resolution * resolution,
+ resolution * resolution,
omd->spatial_size,
omd->spatial_size,
omd->wind_velocity,
@@ -831,7 +840,7 @@ void BKE_ocean_init(struct Ocean *o,
o->_A = A;
o->_w = w;
o->_damp_reflections = 1.0f - damp;
- o->_wind_alignment = alignment;
+ o->_wind_alignment = alignment * 10.0f;
o->_depth = depth;
o->_Lx = Lx;
o->_Lz = Lz;
@@ -845,7 +854,7 @@ void BKE_ocean_init(struct Ocean *o,
/* Common JONSWAP parameters. */
o->_fetch_jonswap = fetch_jonswap;
- o->_sharpen_peak_jonswap = sharpen_peak_jonswap;
+ o->_sharpen_peak_jonswap = sharpen_peak_jonswap * 10.0f;
o->_do_disp_y = do_height_field;
o->_do_normals = do_normals;
@@ -1607,7 +1616,8 @@ void BKE_ocean_bake(struct Ocean *UNUSED(o),
}
void BKE_ocean_init_from_modifier(struct Ocean *UNUSED(ocean),
- struct OceanModifierData const *UNUSED(omd))
+ struct OceanModifierData const *UNUSED(omd),
+ int UNUSED(resolution))
{
}
diff --git a/source/blender/blenkernel/intern/ocean_intern.h b/source/blender/blenkernel/intern/ocean_intern.h
index 7da88419219..39ce0db09d6 100644
--- a/source/blender/blenkernel/intern/ocean_intern.h
+++ b/source/blender/blenkernel/intern/ocean_intern.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_OCEAN_INTERN_H__
-#define __BKE_OCEAN_INTERN_H__
+#pragma once
/** \file
* \ingroup bli
@@ -133,5 +132,3 @@ typedef struct Ocean {
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index b3ab856468c..e7ff53f27b6 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -1314,6 +1314,13 @@ static void sculptsession_free_pbvh(Object *object)
MEM_SAFE_FREE(ss->preview_vert_index_list);
ss->preview_vert_index_count = 0;
+
+ MEM_SAFE_FREE(ss->preview_vert_index_list);
+
+ MEM_SAFE_FREE(ss->vertex_info.connected_component);
+ MEM_SAFE_FREE(ss->vertex_info.boundary);
+
+ MEM_SAFE_FREE(ss->fake_neighbors.fake_neighbor_index);
}
void BKE_sculptsession_bm_to_me_for_render(Object *object)
@@ -1366,11 +1373,6 @@ void BKE_sculptsession_free(Object *ob)
MEM_SAFE_FREE(ss->deform_cos);
MEM_SAFE_FREE(ss->deform_imats);
- MEM_SAFE_FREE(ss->preview_vert_index_list);
-
- MEM_SAFE_FREE(ss->vertex_info.connected_component);
- MEM_SAFE_FREE(ss->fake_neighbors.fake_neighbor_index);
-
if (ss->pose_ik_chain_preview) {
for (int i = 0; i < ss->pose_ik_chain_preview->tot_segments; i++) {
MEM_SAFE_FREE(ss->pose_ik_chain_preview->segments[i].weights);
@@ -1482,7 +1484,7 @@ static void sculpt_update_object(Depsgraph *depsgraph,
Mesh *me_eval,
bool need_pmap,
bool need_mask,
- bool need_colors)
+ bool UNUSED(need_colors))
{
Scene *scene = DEG_get_input_scene(depsgraph);
Sculpt *sd = scene->toolsettings->sculpt;
@@ -1491,6 +1493,8 @@ static void sculpt_update_object(Depsgraph *depsgraph,
MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
const bool use_face_sets = (ob->mode & OB_MODE_SCULPT) != 0;
+ ss->depsgraph = depsgraph;
+
ss->deform_modifiers_active = sculpt_modifiers_active(scene, sd, ob);
ss->show_mask = (sd->flags & SCULPT_HIDE_MASK) == 0;
ss->show_face_sets = (sd->flags & SCULPT_HIDE_FACE_SETS) == 0;
@@ -1512,16 +1516,6 @@ static void sculpt_update_object(Depsgraph *depsgraph,
}
}
- /* Add a color layer if a color tool is used. */
- Mesh *orig_me = BKE_object_get_original_mesh(ob);
- if (need_colors) {
- if (!CustomData_has_layer(&orig_me->vdata, CD_PROP_COLOR)) {
- CustomData_add_layer(&orig_me->vdata, CD_PROP_COLOR, CD_DEFAULT, NULL, orig_me->totvert);
- BKE_mesh_update_customdata_pointers(orig_me, true);
- DEG_id_tag_update(&orig_me->id, ID_RECALC_GEOMETRY);
- }
- }
-
/* tessfaces aren't used and will become invalid */
BKE_mesh_tessface_clear(me);
@@ -1682,10 +1676,25 @@ void BKE_sculpt_update_object_after_eval(Depsgraph *depsgraph, Object *ob_eval)
Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval);
BLI_assert(me_eval != NULL);
-
sculpt_update_object(depsgraph, ob_orig, me_eval, false, false, false);
}
+void BKE_sculpt_color_layer_create_if_needed(struct Object *object)
+{
+ Mesh *orig_me = BKE_object_get_original_mesh(object);
+ if (!U.experimental.use_sculpt_vertex_colors) {
+ return;
+ }
+
+ if (CustomData_has_layer(&orig_me->vdata, CD_PROP_COLOR)) {
+ return;
+ }
+
+ CustomData_add_layer(&orig_me->vdata, CD_PROP_COLOR, CD_DEFAULT, NULL, orig_me->totvert);
+ BKE_mesh_update_customdata_pointers(orig_me, true);
+ DEG_id_tag_update(&orig_me->id, ID_RECALC_GEOMETRY);
+}
+
void BKE_sculpt_update_object_for_edit(
Depsgraph *depsgraph, Object *ob_orig, bool need_pmap, bool need_mask, bool need_colors)
{
@@ -1817,6 +1826,64 @@ static bool check_sculpt_object_deformed(Object *object, const bool for_construc
return deformed;
}
+static void sculpt_sync_face_sets_visibility_to_base_mesh(Mesh *mesh)
+{
+ int *face_sets = CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS);
+ if (!face_sets) {
+ return;
+ }
+
+ for (int i = 0; i < mesh->totvert; i++) {
+ mesh->mvert[i].flag |= ME_HIDE;
+ }
+
+ for (int i = 0; i < mesh->totpoly; i++) {
+ if (face_sets[i] >= 0) {
+ for (int l = 0; l < mesh->mpoly[i].totloop; l++) {
+ MLoop *loop = &mesh->mloop[mesh->mpoly[i].loopstart + l];
+ mesh->mvert[loop->v].flag &= ~ME_HIDE;
+ }
+ }
+ }
+}
+
+static void sculpt_sync_face_sets_visibility_to_grids(Mesh *mesh, SubdivCCG *subdiv_ccg)
+{
+ int *face_sets = CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS);
+ if (!face_sets) {
+ return;
+ }
+
+ if (!subdiv_ccg) {
+ return;
+ }
+
+ CCGKey key;
+ BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
+ for (int i = 0; i < mesh->totloop; i++) {
+ const int face_index = BKE_subdiv_ccg_grid_to_face_index(subdiv_ccg, i);
+ const bool is_hidden = (face_sets[face_index] < 0);
+
+ /* Avoid creating and modifying the grid_hidden bitmap if the base mesh face is visible and
+ * there is not bitmap for the grid. This is because missing grid_hidden implies grid is fully
+ * visible. */
+ if (is_hidden) {
+ BKE_subdiv_ccg_grid_hidden_ensure(subdiv_ccg, i);
+ }
+
+ BLI_bitmap *gh = subdiv_ccg->grid_hidden[i];
+ if (gh) {
+ BLI_bitmap_set_all(gh, is_hidden, key.grid_area);
+ }
+ }
+}
+
+void BKE_sculpt_sync_face_set_visibility(struct Mesh *mesh, struct SubdivCCG *subdiv_ccg)
+{
+ sculpt_sync_face_sets_visibility_to_base_mesh(mesh);
+ sculpt_sync_face_sets_visibility_to_grids(mesh, subdiv_ccg);
+}
+
static PBVH *build_pbvh_for_dynamic_topology(Object *ob)
{
PBVH *pbvh = BKE_pbvh_new();
@@ -1842,6 +1909,8 @@ static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform, bool
BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, looptri);
+ BKE_sculpt_sync_face_set_visibility(me, NULL);
+
BKE_pbvh_build_mesh(pbvh,
me,
me->mpoly,
@@ -1874,6 +1943,10 @@ static PBVH *build_pbvh_from_ccg(Object *ob, SubdivCCG *subdiv_ccg, bool respect
BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
PBVH *pbvh = BKE_pbvh_new();
BKE_pbvh_respect_hide_set(pbvh, respect_hide);
+
+ Mesh *base_mesh = BKE_mesh_from_object(ob);
+ BKE_sculpt_sync_face_set_visibility(base_mesh, subdiv_ccg);
+
BKE_pbvh_build_grids(pbvh,
subdiv_ccg->grids,
subdiv_ccg->num_grids,
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 942f3e0ca2b..1df5cda0ce5 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -283,8 +283,8 @@ int count_particles_mod(ParticleSystem *psys, int totgr, int cur)
}
return tot;
}
-/* we allocate path cache memory in chunks instead of a big contiguous
- * chunk, windows' memory allocater fails to find big blocks of memory often */
+/* We allocate path cache memory in chunks instead of a big contiguous
+ * chunk, windows' memory allocator fails to find big blocks of memory often. */
#define PATH_CACHE_BUF_SIZE 1024
@@ -1297,7 +1297,7 @@ static void do_particle_interpolation(ParticleSystem *psys,
dfra = keys[2].time - keys[1].time;
keytime = (real_t - keys[1].time) / dfra;
- /* convert velocity to timestep size */
+ /* Convert velocity to time-step size. */
if (pind->keyed || pind->cache || point_vel) {
invdt = dfra * 0.04f * (psys ? psys->part->timetweak : 1.f);
mul_v3_fl(keys[1].vel, invdt);
@@ -1305,8 +1305,8 @@ static void do_particle_interpolation(ParticleSystem *psys,
interp_qt_qtqt(result->rot, keys[1].rot, keys[2].rot, keytime);
}
- /* Now we should have in chronologiacl order k1<=k2<=t<=k3<=k4 with keytime between
- * [0, 1]->[k2, k3] (k1 & k4 used for cardinal & bspline interpolation). */
+ /* Now we should have in chronological order k1<=k2<=t<=k3<=k4 with key-time between
+ * [0, 1]->[k2, k3] (k1 & k4 used for cardinal & b-spline interpolation). */
psys_interpolate_particle((pind->keyed || pind->cache || point_vel) ?
-1 /* signal for cubic interpolation */
:
@@ -3611,7 +3611,8 @@ void psys_mat_hair_to_global(
/************************************************/
/* ParticleSettings handling */
/************************************************/
-ModifierData *object_add_particle_system(Main *bmain, Scene *scene, Object *ob, const char *name)
+static ModifierData *object_add_or_copy_particle_system(
+ Main *bmain, Scene *scene, Object *ob, const char *name, const ParticleSystem *psys_orig)
{
ParticleSystem *psys;
ModifierData *md;
@@ -3622,7 +3623,7 @@ ModifierData *object_add_particle_system(Main *bmain, Scene *scene, Object *ob,
}
if (name == NULL) {
- name = DATA_("ParticleSettings");
+ name = (psys_orig != NULL) ? psys_orig->name : DATA_("ParticleSettings");
}
psys = ob->particlesystem.first;
@@ -3635,8 +3636,13 @@ ModifierData *object_add_particle_system(Main *bmain, Scene *scene, Object *ob,
BLI_addtail(&ob->particlesystem, psys);
psys_unique_name(ob, psys, name);
- psys->part = BKE_particlesettings_add(bmain, psys->name);
-
+ if (psys_orig != NULL) {
+ psys->part = psys_orig->part;
+ id_us_plus(&psys->part->id);
+ }
+ else {
+ psys->part = BKE_particlesettings_add(bmain, psys->name);
+ }
md = BKE_modifier_new(eModifierType_ParticleSystem);
BLI_strncpy(md->name, psys->name, sizeof(md->name));
BKE_modifier_unique_name(&ob->modifiers, md);
@@ -3656,6 +3662,20 @@ ModifierData *object_add_particle_system(Main *bmain, Scene *scene, Object *ob,
return md;
}
+
+ModifierData *object_add_particle_system(Main *bmain, Scene *scene, Object *ob, const char *name)
+{
+ return object_add_or_copy_particle_system(bmain, scene, ob, name, NULL);
+}
+
+ModifierData *object_copy_particle_system(Main *bmain,
+ Scene *scene,
+ Object *ob,
+ const ParticleSystem *psys_orig)
+{
+ return object_add_or_copy_particle_system(bmain, scene, ob, NULL, psys_orig);
+}
+
void object_remove_particle_system(Main *bmain, Scene *UNUSED(scene), Object *ob)
{
ParticleSystem *psys = psys_get_current(ob);
@@ -3851,7 +3871,7 @@ void BKE_particlesettings_clump_curve_init(ParticleSettings *part)
cumap->cm[0].curve[1].x = 1.0f;
cumap->cm[0].curve[1].y = 1.0f;
- BKE_curvemapping_initialize(cumap);
+ BKE_curvemapping_init(cumap);
part->clumpcurve = cumap;
}
@@ -3865,7 +3885,7 @@ void BKE_particlesettings_rough_curve_init(ParticleSettings *part)
cumap->cm[0].curve[1].x = 1.0f;
cumap->cm[0].curve[1].y = 1.0f;
- BKE_curvemapping_initialize(cumap);
+ BKE_curvemapping_init(cumap);
part->roughcurve = cumap;
}
@@ -3879,7 +3899,7 @@ void BKE_particlesettings_twist_curve_init(ParticleSettings *part)
cumap->cm[0].curve[1].x = 1.0f;
cumap->cm[0].curve[1].y = 1.0f;
- BKE_curvemapping_initialize(cumap);
+ BKE_curvemapping_init(cumap);
part->twistcurve = cumap;
}
diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c
index 7b9b2484dbe..e0dccd4d14a 100644
--- a/source/blender/blenkernel/intern/particle_distribute.c
+++ b/source/blender/blenkernel/intern/particle_distribute.c
@@ -433,7 +433,7 @@ static void psys_uv_to_w(float u, float v, int quad, float *w)
}
/* Find the index in "sum" array before "value" is crossed. */
-static int distribute_binary_search(float *sum, int n, float value)
+static int distribute_binary_search(const float *sum, int n, float value)
{
int mid, low = 0, high = n - 1;
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 4dc4aea04a7..6bfbb4b9d00 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -570,7 +570,7 @@ void psys_thread_context_free(ParticleThreadContext *ctx)
}
}
-static void initialize_particle_texture(ParticleSimulationData *sim, ParticleData *pa, int p)
+static void init_particle_texture(ParticleSimulationData *sim, ParticleData *pa, int p)
{
ParticleSystem *psys = sim->psys;
ParticleSettings *part = psys->part;
@@ -595,7 +595,7 @@ static void initialize_particle_texture(ParticleSimulationData *sim, ParticleDat
}
/* set particle parameters that don't change during particle's life */
-void initialize_particle(ParticleSimulationData *sim, ParticleData *pa)
+void init_particle(ParticleSimulationData *sim, ParticleData *pa)
{
ParticleSettings *part = sim->psys->part;
float birth_time = (float)(pa - sim->psys->particles) / (float)sim->psys->totpart;
@@ -629,7 +629,7 @@ static void initialize_all_particles(ParticleSimulationData *sim)
LOOP_PARTICLES
{
if (!(emit_from_volume_grid && (pa->flag & PARS_UNEXIST) != 0)) {
- initialize_particle(sim, pa);
+ init_particle(sim, pa);
}
}
}
@@ -1092,7 +1092,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
* We could only do it now because we'll need to know coordinate
* before sampling the texture.
*/
- initialize_particle_texture(sim, pa, p);
+ init_particle_texture(sim, pa, p);
if (part->phystype == PART_PHYS_BOIDS && pa->boid) {
BoidParticle *bpa = pa->boid;
@@ -1939,7 +1939,7 @@ static void sphclassical_density_accum_cb(void *userdata,
return;
}
- /* Smoothing factor. Utilise the Wendland kernel. gnuplot:
+ /* Smoothing factor. Utilize the Wendland kernel. gnuplot:
* q1(x) = (2.0 - x)**4 * ( 1.0 + 2.0 * x)
* plot [0:2] q1(x) */
q = qfac / pow3f(pfr->h) * pow4f(2.0f - rij_h) * (1.0f + 2.0f * rij_h);
@@ -2054,7 +2054,7 @@ static void sphclassical_force_cb(void *sphdata_v,
npressure = stiffness * (pow7f(npa->sphdensity / rest_density) - 1.0f);
- /* First derivative of smoothing factor. Utilise the Wendland kernel.
+ /* First derivative of smoothing factor. Utilize the Wendland kernel.
* gnuplot:
* q2(x) = 2.0 * (2.0 - x)**4 - 4.0 * (2.0 - x)**3 * (1.0 + 2.0 * x)
* plot [0:2] q2(x)
@@ -2947,7 +2947,7 @@ static int collision_response(ParticleSimulationData *sim,
/* get exact velocity right before collision */
madd_v3_v3v3fl(v0, col->ve1, col->acc, dt1);
- /* Convert collider velocity from 1/framestep to 1/s TODO:
+ /* Convert collider velocity from `1/frame_step` to `1/s` TODO:
* here we assume 1 frame step for collision modifier. */
mul_v3_fl(pce->vel, col->inv_timestep);
@@ -4584,7 +4584,7 @@ static void system_step(ParticleSimulationData *sim, float cfra, const bool use_
psys->dt_frac = get_base_time_step(part);
}
else if ((int)cfra == startframe) {
- /* Variable time step; initialise to subframes */
+ /* Variable time step; initialize to sub-frames. */
psys->dt_frac = get_base_time_step(part);
}
else if (psys->dt_frac < MIN_TIMESTEP) {
@@ -4854,8 +4854,10 @@ void particle_system_update(struct Depsgraph *depsgraph,
for (i = 0; i <= part->hair_step; i++) {
hcfra = 100.0f * (float)i / (float)psys->part->hair_step;
if ((part->flag & PART_HAIR_REGROW) == 0) {
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
+ depsgraph, hcfra);
BKE_animsys_evaluate_animdata(
- &part_local->id, part_local->adt, hcfra, ADT_RECALC_ANIM, false);
+ &part_local->id, part_local->adt, &anim_eval_context, ADT_RECALC_ANIM, false);
}
system_step(&sim, hcfra, use_render_params);
psys->cfra = hcfra;
@@ -4966,6 +4968,7 @@ void particle_system_update(struct Depsgraph *depsgraph,
psys_orig->flag = (psys->flag & ~PSYS_SHARED_CACHES);
psys_orig->cfra = psys->cfra;
psys_orig->recalc = psys->recalc;
+ psys_orig->part->totpart = part->totpart;
}
}
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 8d7dabf9859..92a47f24240 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -358,7 +358,7 @@ static void update_vb(PBVH *pbvh, PBVHNode *node, BBC *prim_bbc, int offset, int
/* Returns the number of visible quads in the nodes' grids. */
int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden,
- int *grid_indices,
+ const int *grid_indices,
int totgrid,
int gridsize)
{
@@ -644,7 +644,7 @@ void BKE_pbvh_build_grids(PBVH *pbvh,
pbvh->totgrid = totgrid;
pbvh->gridkey = *key;
pbvh->grid_hidden = grid_hidden;
- pbvh->leaf_limit = max_ii(LEAF_LIMIT / ((gridsize - 1) * (gridsize - 1)), 1);
+ pbvh->leaf_limit = max_ii(LEAF_LIMIT / (gridsize * gridsize), 1);
BB cb;
BB_reset(&cb);
@@ -1542,7 +1542,7 @@ static void pbvh_update_visibility_task_cb(void *__restrict userdata,
PBVHUpdateData *data = userdata;
PBVH *pbvh = data->pbvh;
PBVHNode *node = data->nodes[n];
- if (node->flag & PBVH_UpdateMask) {
+ if (node->flag & PBVH_UpdateVisibility) {
switch (BKE_pbvh_type(pbvh)) {
case PBVH_FACES:
pbvh_faces_node_visibility_update(pbvh, node);
@@ -1554,7 +1554,7 @@ static void pbvh_update_visibility_task_cb(void *__restrict userdata,
pbvh_bmesh_node_visibility_update(node);
break;
}
- node->flag &= ~PBVH_UpdateMask;
+ node->flag &= ~PBVH_UpdateVisibility;
}
}
@@ -1772,6 +1772,11 @@ void BKE_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden)
}
}
+bool BKE_pbvh_node_fully_hidden_get(PBVHNode *node)
+{
+ return (node->flag & PBVH_Leaf) && (node->flag & PBVH_FullyHidden);
+}
+
void BKE_pbvh_node_fully_masked_set(PBVHNode *node, int fully_masked)
{
BLI_assert(node->flag & PBVH_Leaf);
diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h
index 6f8bae822ea..63bc8753fc7 100644
--- a/source/blender/blenkernel/intern/pbvh_intern.h
+++ b/source/blender/blenkernel/intern/pbvh_intern.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __PBVH_INTERN_H__
-#define __PBVH_INTERN_H__
+#pragma once
/** \file
* \ingroup bli
@@ -235,5 +234,3 @@ bool pbvh_bmesh_node_nearest_to_ray(PBVHNode *node,
bool use_original);
void pbvh_bmesh_normals_update(PBVHNode **nodes, int totnode);
-
-#endif
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 61308810191..c2c5b42dbb0 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -206,7 +206,7 @@ static int ptcache_softbody_write(int index, void *soft_v, void **data, int UNUS
return 1;
}
static void ptcache_softbody_read(
- int index, void *soft_v, void **data, float UNUSED(cfra), float *old_data)
+ int index, void *soft_v, void **data, float UNUSED(cfra), const float *old_data)
{
SoftBody *soft = soft_v;
BodyPoint *bp = soft->bpoint + index;
@@ -220,8 +220,13 @@ static void ptcache_softbody_read(
PTCACHE_DATA_TO(data, BPHYS_DATA_VELOCITY, 0, bp->vec);
}
}
-static void ptcache_softbody_interpolate(
- int index, void *soft_v, void **data, float cfra, float cfra1, float cfra2, float *old_data)
+static void ptcache_softbody_interpolate(int index,
+ void *soft_v,
+ void **data,
+ float cfra,
+ float cfra1,
+ float cfra2,
+ const float *old_data)
{
SoftBody *soft = soft_v;
BodyPoint *bp = soft->bpoint + index;
@@ -316,7 +321,7 @@ static int ptcache_particle_write(int index, void *psys_v, void **data, int cfra
return 1 + (pa->state.time >= pa->time && pa->prev_state.time <= pa->time);
}
static void ptcache_particle_read(
- int index, void *psys_v, void **data, float cfra, float *old_data)
+ int index, void *psys_v, void **data, float cfra, const float *old_data)
{
ParticleSystem *psys = psys_v;
ParticleData *pa;
@@ -383,8 +388,13 @@ static void ptcache_particle_read(
unit_qt(pa->state.rot);
}
}
-static void ptcache_particle_interpolate(
- int index, void *psys_v, void **data, float cfra, float cfra1, float cfra2, float *old_data)
+static void ptcache_particle_interpolate(int index,
+ void *psys_v,
+ void **data,
+ float cfra,
+ float cfra1,
+ float cfra2,
+ const float *old_data)
{
ParticleSystem *psys = psys_v;
ParticleData *pa;
@@ -528,7 +538,7 @@ static int ptcache_cloth_write(int index, void *cloth_v, void **data, int UNUSED
return 1;
}
static void ptcache_cloth_read(
- int index, void *cloth_v, void **data, float UNUSED(cfra), float *old_data)
+ int index, void *cloth_v, void **data, float UNUSED(cfra), const float *old_data)
{
ClothModifierData *clmd = cloth_v;
Cloth *cloth = clmd->clothObject;
@@ -545,8 +555,13 @@ static void ptcache_cloth_read(
PTCACHE_DATA_TO(data, BPHYS_DATA_XCONST, 0, vert->xconst);
}
}
-static void ptcache_cloth_interpolate(
- int index, void *cloth_v, void **data, float cfra, float cfra1, float cfra2, float *old_data)
+static void ptcache_cloth_interpolate(int index,
+ void *cloth_v,
+ void **data,
+ float cfra,
+ float cfra1,
+ float cfra2,
+ const float *old_data)
{
ClothModifierData *clmd = cloth_v;
Cloth *cloth = clmd->clothObject;
@@ -1496,7 +1511,7 @@ static int ptcache_rigidbody_write(int index, void *rb_v, void **data, int UNUSE
if (ob && ob->rigidbody_object) {
RigidBodyOb *rbo = ob->rigidbody_object;
- if (rbo->type == RBO_TYPE_ACTIVE) {
+ if (rbo->type == RBO_TYPE_ACTIVE && rbo->shared->physics_object != NULL) {
#ifdef WITH_BULLET
RB_body_get_position(rbo->shared->physics_object, rbo->pos);
RB_body_get_orientation(rbo->shared->physics_object, rbo->orn);
@@ -1509,7 +1524,7 @@ static int ptcache_rigidbody_write(int index, void *rb_v, void **data, int UNUSE
return 1;
}
static void ptcache_rigidbody_read(
- int index, void *rb_v, void **data, float UNUSED(cfra), float *old_data)
+ int index, void *rb_v, void **data, float UNUSED(cfra), const float *old_data)
{
RigidBodyWorld *rbw = rb_v;
Object *ob = NULL;
@@ -1534,8 +1549,13 @@ static void ptcache_rigidbody_read(
}
}
}
-static void ptcache_rigidbody_interpolate(
- int index, void *rb_v, void **data, float cfra, float cfra1, float cfra2, float *old_data)
+static void ptcache_rigidbody_interpolate(int index,
+ void *rb_v,
+ void **data,
+ float cfra,
+ float cfra1,
+ float cfra2,
+ const float *old_data)
{
RigidBodyWorld *rbw = rb_v;
Object *ob = NULL;
@@ -1865,87 +1885,6 @@ void BKE_ptcache_id_from_rigidbody(PTCacheID *pid, Object *ob, RigidBodyWorld *r
pid->file_type = PTCACHE_FILE_PTCACHE;
}
-static int ptcache_sim_particle_totpoint(void *state_v, int UNUSED(cfra))
-{
- ParticleSimulationState *state = (ParticleSimulationState *)state_v;
- return state->tot_particles;
-}
-
-static void ptcache_sim_particle_error(void *UNUSED(state_v), const char *UNUSED(message))
-{
-}
-
-static int ptcache_sim_particle_write(int index, void *state_v, void **data, int UNUSED(cfra))
-{
- ParticleSimulationState *state = (ParticleSimulationState *)state_v;
-
- const float *positions = (const float *)CustomData_get_layer_named(
- &state->attributes, CD_LOCATION, "Position");
-
- PTCACHE_DATA_FROM(data, BPHYS_DATA_LOCATION, positions + (index * 3));
-
- return 1;
-}
-static void ptcache_sim_particle_read(
- int index, void *state_v, void **data, float UNUSED(cfra), float *UNUSED(old_data))
-{
- ParticleSimulationState *state = (ParticleSimulationState *)state_v;
-
- BLI_assert(index < state->tot_particles);
- float *positions = (float *)CustomData_get_layer_named(
- &state->attributes, CD_LOCATION, "Position");
-
- PTCACHE_DATA_TO(data, BPHYS_DATA_LOCATION, 0, positions + (index * 3));
-}
-
-void BKE_ptcache_id_from_sim_particles(PTCacheID *pid, ParticleSimulationState *state)
-{
- memset(pid, 0, sizeof(PTCacheID));
-
- ParticleSimulationState *state_orig;
- if (state->head.orig_state != NULL) {
- state_orig = (ParticleSimulationState *)state->head.orig_state;
- }
- else {
- state_orig = state;
- }
-
- pid->calldata = state;
- pid->type = PTCACHE_TYPE_SIM_PARTICLES;
- pid->cache = state_orig->point_cache;
- pid->cache_ptr = &state_orig->point_cache;
- pid->ptcaches = &state_orig->ptcaches;
- pid->totpoint = ptcache_sim_particle_totpoint;
- pid->totwrite = ptcache_sim_particle_totpoint;
- pid->error = ptcache_sim_particle_error;
-
- pid->write_point = ptcache_sim_particle_write;
- pid->read_point = ptcache_sim_particle_read;
- pid->interpolate_point = NULL;
-
- pid->write_stream = NULL;
- pid->read_stream = NULL;
-
- pid->write_openvdb_stream = NULL;
- pid->read_openvdb_stream = NULL;
-
- pid->write_extra_data = NULL;
- pid->read_extra_data = NULL;
- pid->interpolate_extra_data = NULL;
-
- pid->write_header = NULL;
- pid->read_header = NULL;
-
- pid->data_types = 1 << BPHYS_DATA_LOCATION;
- pid->info_types = 0;
-
- pid->stack_index = 0;
-
- pid->default_step = 1;
- pid->max_step = 1;
- pid->file_type = PTCACHE_FILE_PTCACHE;
-}
-
/**
* \param ob: Optional, may be NULL.
* \param scene: Optional may be NULL.
@@ -2045,21 +1984,7 @@ static bool foreach_object_modifier_ptcache(Object *object,
}
}
else if (md->type == eModifierType_Simulation) {
- SimulationModifierData *smd = (SimulationModifierData *)md;
- if (smd->simulation) {
- LISTBASE_FOREACH (SimulationState *, state, &smd->simulation->states) {
- switch ((eSimulationStateType)state->type) {
- case SIM_STATE_TYPE_PARTICLES: {
- ParticleSimulationState *particle_state = (ParticleSimulationState *)state;
- BKE_ptcache_id_from_sim_particles(&pid, particle_state);
- if (!callback(&pid, callback_user_data)) {
- return false;
- }
- break;
- }
- }
- }
- }
+ /* TODO(jacques) */
}
}
return true;
@@ -2289,7 +2214,9 @@ static int ptcache_filename(PTCacheID *pid, char *filename, int cfra, short do_p
return len; /* make sure the above string is always 16 chars */
}
-/* youll need to close yourself after! */
+/**
+ * Caller must close after!
+ */
static PTCacheFile *ptcache_file_open(PTCacheID *pid, int mode, int cfra)
{
PTCacheFile *pf;
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index 4752782eaeb..7c335a8e98c 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -466,10 +466,10 @@ static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob)
return shape;
}
-/* Create new physics sim collision shape for object and store it,
- * or remove the existing one first and replace...
+/* Helper function to create physics collision shape for object.
+ * Returns a new collision shape.
*/
-static void rigidbody_validate_sim_shape(Object *ob, bool rebuild)
+static rbCollisionShape *rigidbody_validate_sim_shape_helper(RigidBodyWorld *rbw, Object *ob)
{
RigidBodyOb *rbo = ob->rigidbody_object;
rbCollisionShape *new_shape = NULL;
@@ -484,12 +484,7 @@ static void rigidbody_validate_sim_shape(Object *ob, bool rebuild)
/* sanity check */
if (rbo == NULL) {
- return;
- }
-
- /* don't create a new shape if we already have one and don't want to rebuild it */
- if (rbo->shared->physics_shape && !rebuild) {
- return;
+ return NULL;
}
/* if automatically determining dimensions, use the Object's boundbox
@@ -539,7 +534,7 @@ static void rigidbody_validate_sim_shape(Object *ob, bool rebuild)
break;
case RB_SHAPE_CONVEXH:
- /* try to emged collision margin */
+ /* try to embed collision margin */
has_volume = (MIN3(size[0], size[1], size[2]) > 0.0f);
if (!(rbo->flag & RBO_FLAG_USE_MARGIN) && has_volume) {
@@ -555,18 +550,69 @@ static void rigidbody_validate_sim_shape(Object *ob, bool rebuild)
case RB_SHAPE_TRIMESH:
new_shape = rigidbody_get_shape_trimesh_from_mesh(ob);
break;
+ case RB_SHAPE_COMPOUND:
+ new_shape = RB_shape_new_compound();
+ rbCollisionShape *childShape = NULL;
+ float loc[3], rot[4];
+ float mat[4][4];
+ /* Add children to the compound shape */
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->group, childObject) {
+ if (childObject->parent == ob) {
+ childShape = rigidbody_validate_sim_shape_helper(rbw, childObject);
+ if (childShape) {
+ BKE_object_matrix_local_get(childObject, mat);
+ mat4_to_loc_quat(loc, rot, mat);
+ RB_compound_add_child_shape(new_shape, childShape, loc, rot);
+ }
+ }
+ }
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
+
+ break;
}
- /* use box shape if we can't fall back to old shape */
- if (new_shape == NULL && rbo->shared->physics_shape == NULL) {
+ /* use box shape if it failed to create new shape */
+ if (new_shape == NULL) {
new_shape = RB_shape_new_box(size[0], size[1], size[2]);
}
+ if (new_shape) {
+ RB_shape_set_margin(new_shape, RBO_GET_MARGIN(rbo));
+ }
+
+ return new_shape;
+}
+
+/* Create new physics sim collision shape for object and store it,
+ * or remove the existing one first and replace...
+ */
+static void rigidbody_validate_sim_shape(RigidBodyWorld *rbw, Object *ob, bool rebuild)
+{
+ RigidBodyOb *rbo = ob->rigidbody_object;
+ rbCollisionShape *new_shape = NULL;
+
+ /* sanity check */
+ if (rbo == NULL) {
+ return;
+ }
+
+ /* don't create a new shape if we already have one and don't want to rebuild it */
+ if (rbo->shared->physics_shape && !rebuild) {
+ return;
+ }
+
+ /* Also don't create a shape if this object is parent of a compound shape */
+ if (ob->parent != NULL && ob->parent->rigidbody_object != NULL &&
+ ob->parent->rigidbody_object->shape == RB_SHAPE_COMPOUND) {
+ return;
+ }
+
+ new_shape = rigidbody_validate_sim_shape_helper(rbw, ob);
+
/* assign new collision shape if creation was successful */
if (new_shape) {
if (rbo->shared->physics_shape) {
RB_shape_delete(rbo->shared->physics_shape);
}
rbo->shared->physics_shape = new_shape;
- RB_shape_set_margin(rbo->shared->physics_shape, RBO_GET_MARGIN(rbo));
}
}
@@ -750,7 +796,7 @@ static void rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, bool
/* FIXME we shouldn't always have to rebuild collision shapes when rebuilding objects,
* but it's needed for constraints to update correctly. */
if (rbo->shared->physics_shape == NULL || rebuild) {
- rigidbody_validate_sim_shape(ob, true);
+ rigidbody_validate_sim_shape(rbw, ob, true);
}
if (rbo->shared->physics_object) {
@@ -760,6 +806,12 @@ static void rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, bool
/* remove rigid body if it already exists before creating a new one */
if (rbo->shared->physics_object) {
RB_body_delete(rbo->shared->physics_object);
+ rbo->shared->physics_object = NULL;
+ }
+ /* Don't create rigid body object if the parent is a compound shape */
+ if (ob->parent != NULL && ob->parent->rigidbody_object != NULL &&
+ ob->parent->rigidbody_object->shape == RB_SHAPE_COMPOUND) {
+ return;
}
mat4_to_loc_quat(loc, rot, ob->obmat);
@@ -793,7 +845,7 @@ static void rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, bool
rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED);
}
- if (rbw && rbw->shared->physics_world) {
+ if (rbw && rbw->shared->physics_world && rbo->shared->physics_object) {
RB_dworld_add_body(rbw->shared->physics_world, rbo->shared->physics_object, rbo->col_groups);
}
}
@@ -1179,9 +1231,12 @@ RigidBodyOb *BKE_rigidbody_create_object(Scene *scene, Object *ob, short type)
* - object must exist
* - cannot add rigid body if it already exists
*/
- if (ob == NULL || (ob->rigidbody_object != NULL)) {
+ if (ob == NULL) {
return NULL;
}
+ if (ob->rigidbody_object != NULL) {
+ return ob->rigidbody_object;
+ }
/* create new settings data, and link it up */
rbo = MEM_callocN(sizeof(RigidBodyOb), "RigidBodyOb");
@@ -1530,7 +1585,11 @@ static void rigidbody_update_ob_array(RigidBodyWorld *rbw)
int n = 0;
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->group, object) {
(void)object;
- n++;
+ /* Ignore if this object is the direct child of an object with a compound shape */
+ if (object->parent == NULL || object->parent->rigidbody_object == NULL ||
+ object->parent->rigidbody_object->shape != RB_SHAPE_COMPOUND) {
+ n++;
+ }
}
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
@@ -1541,8 +1600,12 @@ static void rigidbody_update_ob_array(RigidBodyWorld *rbw)
int i = 0;
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->group, object) {
- rbw->objects[i] = object;
- i++;
+ /* Ignore if this object is the direct child of an object with a compound shape */
+ if (object->parent == NULL || object->parent->rigidbody_object == NULL ||
+ object->parent->rigidbody_object->shape != RB_SHAPE_COMPOUND) {
+ rbw->objects[i] = object;
+ i++;
+ }
}
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
}
@@ -1754,11 +1817,13 @@ static void rigidbody_update_simulation(Depsgraph *depsgraph,
/* refresh shape... */
if (rbo->flag & RBO_FLAG_NEEDS_RESHAPE) {
/* mesh/shape data changed, so force shape refresh */
- rigidbody_validate_sim_shape(ob, true);
+ rigidbody_validate_sim_shape(rbw, ob, true);
/* now tell RB sim about it */
/* XXX: we assume that this can only get applied for active/passive shapes
* that will be included as rigidbodies. */
- RB_body_set_collision_shape(rbo->shared->physics_object, rbo->shared->physics_shape);
+ if (rbo->shared->physics_object != NULL && rbo->shared->physics_shape != NULL) {
+ RB_body_set_collision_shape(rbo->shared->physics_object, rbo->shared->physics_shape);
+ }
}
}
rbo->flag &= ~(RBO_FLAG_NEEDS_VALIDATE | RBO_FLAG_NEEDS_RESHAPE);
@@ -1817,7 +1882,8 @@ static void rigidbody_update_simulation_post_step(Depsgraph *depsgraph, RigidBod
Base *base = BKE_view_layer_base_find(view_layer, ob);
RigidBodyOb *rbo = ob->rigidbody_object;
/* Reset kinematic state for transformed objects. */
- if (rbo && base && (base->flag & BASE_SELECTED) && (G.moving & G_TRANSFORM_OBJ)) {
+ if (rbo && base && (base->flag & BASE_SELECTED) && (G.moving & G_TRANSFORM_OBJ) &&
+ rbo->shared->physics_object) {
RB_body_set_kinematic_state(rbo->shared->physics_object,
rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED);
RB_body_set_mass(rbo->shared->physics_object, RBO_GET_MASS(rbo));
@@ -1840,8 +1906,13 @@ void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime)
{
RigidBodyOb *rbo = ob->rigidbody_object;
+ /* True if the shape of this object's parent is of type compound */
+ bool obCompoundParent = (ob->parent != NULL && ob->parent->rigidbody_object != NULL &&
+ ob->parent->rigidbody_object->shape == RB_SHAPE_COMPOUND);
+
/* keep original transform for kinematic and passive objects */
- if (ELEM(NULL, rbw, rbo) || rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE) {
+ if (ELEM(NULL, rbw, rbo) || rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE ||
+ obCompoundParent) {
return;
}
@@ -1963,7 +2034,11 @@ void BKE_rigidbody_rebuild_world(Depsgraph *depsgraph, Scene *scene, float ctime
int n = 0;
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->group, object) {
(void)object;
- n++;
+ /* Ignore if this object is the direct child of an object with a compound shape */
+ if (object->parent == NULL || object->parent->rigidbody_object == NULL ||
+ object->parent->rigidbody_object->shape != RB_SHAPE_COMPOUND) {
+ n++;
+ }
}
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index b0faa555f29..fdec29dd43e 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -127,7 +127,7 @@ static void scene_init_data(ID *id)
mblur_shutter_curve = &scene->r.mblur_shutter_curve;
BKE_curvemapping_set_defaults(mblur_shutter_curve, 1, 0.0f, 0.0f, 1.0f, 1.0f);
- BKE_curvemapping_initialize(mblur_shutter_curve);
+ BKE_curvemapping_init(mblur_shutter_curve);
BKE_curvemap_reset(mblur_shutter_curve->cm,
&mblur_shutter_curve->clipr,
CURVE_PRESET_MAX,
@@ -140,13 +140,13 @@ static void scene_init_data(ID *id)
/* grease pencil multiframe falloff curve */
scene->toolsettings->gp_sculpt.cur_falloff = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
CurveMapping *gp_falloff_curve = scene->toolsettings->gp_sculpt.cur_falloff;
- BKE_curvemapping_initialize(gp_falloff_curve);
+ BKE_curvemapping_init(gp_falloff_curve);
BKE_curvemap_reset(
gp_falloff_curve->cm, &gp_falloff_curve->clipr, CURVE_PRESET_GAUSS, CURVEMAP_SLOPE_POSITIVE);
scene->toolsettings->gp_sculpt.cur_primitive = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
CurveMapping *gp_primitive_curve = scene->toolsettings->gp_sculpt.cur_primitive;
- BKE_curvemapping_initialize(gp_primitive_curve);
+ BKE_curvemapping_init(gp_primitive_curve);
BKE_curvemap_reset(gp_primitive_curve->cm,
&gp_primitive_curve->clipr,
CURVE_PRESET_BELL,
@@ -570,6 +570,24 @@ static void scene_foreach_id(ID *id, LibraryForeachIDData *data)
}
}
+static void scene_foreach_cache(ID *id,
+ IDTypeForeachCacheFunctionCallback function_callback,
+ void *user_data)
+{
+ Scene *scene = (Scene *)id;
+ IDCacheKey key = {
+ .id_session_uuid = id->session_uuid,
+ .offset_in_ID = offsetof(Scene, eevee.light_cache_data),
+ .cache_v = scene->eevee.light_cache_data,
+ };
+
+ function_callback(id,
+ &key,
+ (void **)&scene->eevee.light_cache_data,
+ IDTYPE_CACHE_CB_FLAGS_PERSISTENT,
+ user_data);
+}
+
IDTypeInfo IDType_ID_SCE = {
.id_code = ID_SCE,
.id_filter = FILTER_ID_SCE,
@@ -587,6 +605,7 @@ IDTypeInfo IDType_ID_SCE = {
* support all possible corner cases. */
.make_local = NULL,
.foreach_id = scene_foreach_id,
+ .foreach_cache = scene_foreach_cache,
};
const char *RE_engine_id_BLENDER_EEVEE = "BLENDER_EEVEE";
@@ -751,7 +770,6 @@ void BKE_scene_copy_data_eevee(Scene *sce_dst, const Scene *sce_src)
Scene *BKE_scene_duplicate(Main *bmain, Scene *sce, eSceneCopyMethod type)
{
- const bool is_scene_liboverride = ID_IS_OVERRIDE_LIBRARY(sce);
Scene *sce_copy;
/* TODO this should/could most likely be replaced by call to more generic code at some point...
@@ -822,15 +840,13 @@ Scene *BKE_scene_duplicate(Main *bmain, Scene *sce, eSceneCopyMethod type)
return sce_copy;
}
else {
- const eDupli_ID_Flags duplicate_flags = U.dupflag | USER_DUP_OBJECT;
+ eDupli_ID_Flags duplicate_flags = U.dupflag | USER_DUP_OBJECT;
BKE_id_copy(bmain, (ID *)sce, (ID **)&sce_copy);
id_us_min(&sce_copy->id);
id_us_ensure_real(&sce_copy->id);
- if (duplicate_flags & USER_DUP_ACT) {
- BKE_animdata_copy_id_action(bmain, &sce_copy->id, true);
- }
+ BKE_animdata_duplicate_id_action(bmain, &sce_copy->id, duplicate_flags);
/* Extra actions, most notably SCE_FULL_COPY also duplicates several 'children' datablocks. */
@@ -841,22 +857,26 @@ Scene *BKE_scene_duplicate(Main *bmain, Scene *sce, eSceneCopyMethod type)
if (!is_subprocess) {
BKE_main_id_tag_all(bmain, LIB_TAG_NEW, false);
BKE_main_id_clear_newpoins(bmain);
+ /* In case root duplicated ID is linked, assume we want to get a local copy of it and
+ * duplicate all expected linked data. */
+ if (ID_IS_LINKED(sce)) {
+ duplicate_flags |= USER_DUP_LINKED_ID;
+ }
}
/* Copy Freestyle LineStyle datablocks. */
LISTBASE_FOREACH (ViewLayer *, view_layer_dst, &sce_copy->view_layers) {
LISTBASE_FOREACH (
FreestyleLineSet *, lineset, &view_layer_dst->freestyle_config.linesets) {
- BKE_id_copy_for_duplicate(
- bmain, &lineset->linestyle->id, is_scene_liboverride, duplicate_flags);
+ BKE_id_copy_for_duplicate(bmain, (ID *)lineset->linestyle, duplicate_flags);
}
}
/* Full copy of world (included animations) */
- BKE_id_copy_for_duplicate(bmain, &sce->world->id, is_scene_liboverride, duplicate_flags);
+ BKE_id_copy_for_duplicate(bmain, (ID *)sce->world, duplicate_flags);
/* Full copy of GreasePencil. */
- BKE_id_copy_for_duplicate(bmain, &sce->gpd->id, is_scene_liboverride, duplicate_flags);
+ BKE_id_copy_for_duplicate(bmain, (ID *)sce->gpd, duplicate_flags);
/* Deep-duplicate collections and objects (using preferences' settings for which sub-data to
* duplicate along the object itself). */
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index de233a8d473..4a2ad88bb28 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -2668,7 +2668,7 @@ static void RVAddBitmaps_float(float *a, float *b, float *c, int width, int heig
}
static void RVIsolateHighlights_float(
- float *in, float *out, int width, int height, float threshold, float boost, float clamp)
+ const float *in, float *out, int width, int height, float threshold, float boost, float clamp)
{
int x, y, index;
float intensity;
@@ -3423,7 +3423,7 @@ static void do_gaussian_blur_effect_byte_x(Sequence *seq,
int y,
int frame_width,
int UNUSED(frame_height),
- unsigned char *rect,
+ const unsigned char *rect,
unsigned char *out)
{
#define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4)
@@ -3473,7 +3473,7 @@ static void do_gaussian_blur_effect_byte_y(Sequence *seq,
int y,
int UNUSED(frame_width),
int frame_height,
- unsigned char *rect,
+ const unsigned char *rect,
unsigned char *out)
{
#define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4)
diff --git a/source/blender/blenkernel/intern/seqmodifier.c b/source/blender/blenkernel/intern/seqmodifier.c
index 604cbf476a8..0bf7fffb833 100644
--- a/source/blender/blenkernel/intern/seqmodifier.c
+++ b/source/blender/blenkernel/intern/seqmodifier.c
@@ -57,7 +57,7 @@ typedef void (*modifier_apply_threaded_cb)(int width,
unsigned char *rect,
float *rect_float,
unsigned char *mask_rect,
- float *mask_rect_float,
+ const float *mask_rect_float,
void *data_v);
typedef struct ModifierInitData {
@@ -223,7 +223,7 @@ static void whiteBalance_apply_threaded(int width,
unsigned char *rect,
float *rect_float,
unsigned char *mask_rect,
- float *mask_rect_float,
+ const float *mask_rect_float,
void *data_v)
{
int x, y;
@@ -331,7 +331,7 @@ static void curves_apply_threaded(int width,
unsigned char *rect,
float *rect_float,
unsigned char *mask_rect,
- float *mask_rect_float,
+ const float *mask_rect_float,
void *data_v)
{
CurveMapping *curve_mapping = (CurveMapping *)data_v;
@@ -396,7 +396,7 @@ static void curves_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *m
float black[3] = {0.0f, 0.0f, 0.0f};
float white[3] = {1.0f, 1.0f, 1.0f};
- BKE_curvemapping_initialize(&cmd->curve_mapping);
+ BKE_curvemapping_init(&cmd->curve_mapping);
BKE_curvemapping_premultiply(&cmd->curve_mapping, 0);
BKE_curvemapping_set_black_white(&cmd->curve_mapping, black, white);
@@ -461,7 +461,7 @@ static void hue_correct_apply_threaded(int width,
unsigned char *rect,
float *rect_float,
unsigned char *mask_rect,
- float *mask_rect_float,
+ const float *mask_rect_float,
void *data_v)
{
CurveMapping *curve_mapping = (CurveMapping *)data_v;
@@ -525,7 +525,7 @@ static void hue_correct_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImB
{
HueCorrectModifierData *hcmd = (HueCorrectModifierData *)smd;
- BKE_curvemapping_initialize(&hcmd->curve_mapping);
+ BKE_curvemapping_init(&hcmd->curve_mapping);
modifier_apply_threaded(ibuf, mask, hue_correct_apply_threaded, &hcmd->curve_mapping);
}
@@ -556,7 +556,7 @@ static void brightcontrast_apply_threaded(int width,
unsigned char *rect,
float *rect_float,
unsigned char *mask_rect,
- float *mask_rect_float,
+ const float *mask_rect_float,
void *data_v)
{
BrightContrastThreadData *data = (BrightContrastThreadData *)data_v;
@@ -658,7 +658,7 @@ static void maskmodifier_apply_threaded(int width,
unsigned char *rect,
float *rect_float,
unsigned char *mask_rect,
- float *mask_rect_float,
+ const float *mask_rect_float,
void *UNUSED(data_v))
{
int x, y;
@@ -755,7 +755,7 @@ static void tonemapmodifier_apply_threaded_simple(int width,
unsigned char *rect,
float *rect_float,
unsigned char *mask_rect,
- float *mask_rect_float,
+ const float *mask_rect_float,
void *data_v)
{
AvgLogLum *avg = (AvgLogLum *)data_v;
@@ -814,7 +814,7 @@ static void tonemapmodifier_apply_threaded_photoreceptor(int width,
unsigned char *rect,
float *rect_float,
unsigned char *mask_rect,
- float *mask_rect_float,
+ const float *mask_rect_float,
void *data_v)
{
AvgLogLum *avg = (AvgLogLum *)data_v;
diff --git a/source/blender/blenkernel/intern/seqprefetch.c b/source/blender/blenkernel/intern/seqprefetch.c
index 30a371b5b28..ff3829bdebb 100644
--- a/source/blender/blenkernel/intern/seqprefetch.c
+++ b/source/blender/blenkernel/intern/seqprefetch.c
@@ -183,6 +183,10 @@ static float seq_prefetch_cfra(PrefetchJob *pfjob)
{
return pfjob->cfra + pfjob->num_frames_prefetched;
}
+static AnimationEvalContext seq_prefetch_anim_eval_context(PrefetchJob *pfjob)
+{
+ return BKE_animsys_eval_context_construct(pfjob->depsgraph, seq_prefetch_cfra(pfjob));
+}
void BKE_sequencer_prefetch_get_time_range(Scene *scene, int *start, int *end)
{
@@ -435,8 +439,9 @@ static void *seq_prefetch_frames(void *job)
seq_prefetch_update_depsgraph(pfjob);
AnimData *adt = BKE_animdata_from_id(&pfjob->context_cpy.scene->id);
+ AnimationEvalContext anim_eval_context = seq_prefetch_anim_eval_context(pfjob);
BKE_animsys_evaluate_animdata(
- &pfjob->context_cpy.scene->id, adt, seq_prefetch_cfra(pfjob), ADT_RECALC_ALL, false);
+ &pfjob->context_cpy.scene->id, adt, &anim_eval_context, ADT_RECALC_ALL, false);
/* This is quite hacky solution:
* We need cross-reference original scene with copy for cache.
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 297d60e5976..b0a8f709399 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -46,6 +46,7 @@
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_path_util.h"
+#include "BLI_session_uuid.h"
#include "BLI_string.h"
#include "BLI_string_utf8.h"
#include "BLI_threads.h"
@@ -114,8 +115,7 @@ static ImBuf *seq_render_preprocess_ibuf(const SeqRenderData *context,
float cfra,
clock_t begin,
bool use_preprocess,
- const bool is_proxy_image,
- const bool is_preprocessed);
+ const bool is_proxy_image);
static ImBuf *seq_render_strip(const SeqRenderData *context,
SeqRenderState *state,
Sequence *seq,
@@ -1091,6 +1091,64 @@ void BKE_sequence_reload_new_file(Main *bmain, Scene *scene, Sequence *seq, cons
BKE_sequence_calc(scene, seq);
}
+void BKE_sequence_movie_reload_if_needed(struct Main *bmain,
+ struct Scene *scene,
+ struct Sequence *seq,
+ bool *r_was_reloaded,
+ bool *r_can_produce_frames)
+{
+ BLI_assert(seq->type == SEQ_TYPE_MOVIE ||
+ !"This function is only implemented for movie strips.");
+
+ bool must_reload = false;
+
+ /* The Sequence struct allows for multiple anim structs to be associated with one strip. This
+ * function will return true only if there is at least one 'anim' AND all anims can produce
+ * frames. */
+
+ if (BLI_listbase_is_empty(&seq->anims)) {
+ /* No anim present, so reloading is always necessary. */
+ must_reload = true;
+ }
+ else {
+ LISTBASE_FOREACH (StripAnim *, sanim, &seq->anims) {
+ if (!IMB_anim_can_produce_frames(sanim->anim)) {
+ /* Anim cannot produce frames, try reloading. */
+ must_reload = true;
+ break;
+ }
+ };
+ }
+
+ if (!must_reload) {
+ /* There are one or more anims, and all can produce frames. */
+ *r_was_reloaded = false;
+ *r_can_produce_frames = true;
+ return;
+ }
+
+ BKE_sequence_reload_new_file(bmain, scene, seq, true);
+ *r_was_reloaded = true;
+
+ if (BLI_listbase_is_empty(&seq->anims)) {
+ /* No anims present after reloading => no frames can be produced. */
+ *r_can_produce_frames = false;
+ return;
+ }
+
+ /* Check if there are still anims that cannot produce frames. */
+ LISTBASE_FOREACH (StripAnim *, sanim, &seq->anims) {
+ if (!IMB_anim_can_produce_frames(sanim->anim)) {
+ /* There still is an anim that cannot produce frames. */
+ *r_can_produce_frames = false;
+ return;
+ }
+ };
+
+ /* There are one or more anims, and all can produce frames. */
+ *r_can_produce_frames = true;
+}
+
void BKE_sequencer_sort(Scene *scene)
{
/* all strips together per kind, and in order of y location ("machine") */
@@ -1332,30 +1390,6 @@ ListBase *BKE_sequence_seqbase_get(Sequence *seq, int *r_offset)
/*********************** DO THE SEQUENCE *************************/
-static void make_black_ibuf(ImBuf *ibuf)
-{
- unsigned int *rect;
- float *rect_float;
- int tot;
-
- if (ibuf == NULL || (ibuf->rect == NULL && ibuf->rect_float == NULL)) {
- return;
- }
-
- tot = ibuf->x * ibuf->y;
-
- rect = ibuf->rect;
- rect_float = ibuf->rect_float;
-
- if (rect) {
- memset(rect, 0, tot * sizeof(char) * 4);
- }
-
- if (rect_float) {
- memset(rect_float, 0, tot * sizeof(float) * 4);
- }
-}
-
static void multibuf(ImBuf *ibuf, const float fmul)
{
char *rt;
@@ -2415,7 +2449,7 @@ static void color_balance_byte_float(StripColorBalance *cb_,
static void color_balance_float_float(StripColorBalance *cb_,
float *rect_float,
- float *mask_rect_float,
+ const float *mask_rect_float,
int width,
int height,
float mul)
@@ -2657,8 +2691,7 @@ static ImBuf *input_preprocess(const SeqRenderData *context,
Sequence *seq,
float cfra,
ImBuf *ibuf,
- const bool is_proxy_image,
- const bool is_preprocessed)
+ const bool is_proxy_image)
{
Scene *scene = context->scene;
float mul;
@@ -2672,15 +2705,6 @@ static ImBuf *input_preprocess(const SeqRenderData *context,
if (seq->flag & (SEQ_USE_CROP | SEQ_USE_TRANSFORM)) {
StripCrop c = {0};
StripTransform t = {0};
- int sx, sy, dx, dy;
-
- if (is_proxy_image) {
- double f = BKE_sequencer_rendersize_to_scale_factor(context->preview_render_size);
-
- if (f != 1.0) {
- IMB_scalefastImBuf(ibuf, ibuf->x * f, ibuf->y * f);
- }
- }
if (seq->flag & SEQ_USE_CROP && seq->strip->crop) {
c = *seq->strip->crop;
@@ -2689,33 +2713,41 @@ static ImBuf *input_preprocess(const SeqRenderData *context,
t = *seq->strip->transform;
}
- if (is_preprocessed) {
- double xscale = scene->r.xsch ? ((double)context->rectx / (double)scene->r.xsch) : 1.0;
- double yscale = scene->r.ysch ? ((double)context->recty / (double)scene->r.ysch) : 1.0;
- if (seq->flag & SEQ_USE_TRANSFORM) {
- t.xofs *= xscale;
- t.yofs *= yscale;
+ /* Calculate scale factor for current image if needed. */
+ double scale_factor, image_scale_factor = 1.0;
+ if (context->preview_render_size == SEQ_PROXY_RENDER_SIZE_SCENE) {
+ scale_factor = image_scale_factor = (double)scene->r.size / 100;
+ }
+ else {
+ scale_factor = BKE_sequencer_rendersize_to_scale_factor(context->preview_render_size);
+ if (!is_proxy_image) {
+ image_scale_factor = scale_factor;
}
- if (seq->flag & SEQ_USE_CROP) {
- c.left *= xscale;
- c.right *= xscale;
- c.top *= yscale;
- c.bottom *= yscale;
+ }
+
+ if (image_scale_factor != 1.0) {
+ if (context->for_render) {
+ IMB_scaleImBuf(ibuf, ibuf->x * image_scale_factor, ibuf->y * image_scale_factor);
+ }
+ else {
+ IMB_scalefastImBuf(ibuf, ibuf->x * image_scale_factor, ibuf->y * image_scale_factor);
}
}
+ t.xofs *= scale_factor;
+ t.yofs *= scale_factor;
+ c.left *= scale_factor;
+ c.right *= scale_factor;
+ c.top *= scale_factor;
+ c.bottom *= scale_factor;
+
+ int sx, sy, dx, dy;
sx = ibuf->x - c.left - c.right;
sy = ibuf->y - c.top - c.bottom;
if (seq->flag & SEQ_USE_TRANSFORM) {
- if (is_preprocessed) {
- dx = context->rectx;
- dy = context->recty;
- }
- else {
- dx = scene->r.xsch;
- dy = scene->r.ysch;
- }
+ dx = context->rectx;
+ dy = context->recty;
}
else {
dx = sx;
@@ -2724,19 +2756,15 @@ static ImBuf *input_preprocess(const SeqRenderData *context,
if (c.top + c.bottom >= ibuf->y || c.left + c.right >= ibuf->x || t.xofs >= dx ||
t.yofs >= dy) {
- make_black_ibuf(ibuf);
+ return NULL;
}
- else {
- ImBuf *i = IMB_allocImBuf(dx, dy, 32, ibuf->rect_float ? IB_rectfloat : IB_rect);
-
- IMB_rectcpy(i, ibuf, t.xofs, t.yofs, c.left, c.bottom, sx, sy);
- sequencer_imbuf_assign_spaces(scene, i);
-
- IMB_metadata_copy(i, ibuf);
- IMB_freeImBuf(ibuf);
- ibuf = i;
- }
+ ImBuf *i = IMB_allocImBuf(dx, dy, 32, ibuf->rect_float ? IB_rectfloat : IB_rect);
+ IMB_rectcpy(i, ibuf, t.xofs, t.yofs, c.left, c.bottom, sx, sy);
+ sequencer_imbuf_assign_spaces(scene, i);
+ IMB_metadata_copy(i, ibuf);
+ IMB_freeImBuf(ibuf);
+ ibuf = i;
}
if (seq->flag & SEQ_FLIPX) {
@@ -3097,7 +3125,7 @@ static ImBuf *seq_render_image_strip(const SeqRenderData *context,
if (view_id != context->view_id) {
ibufs_arr[view_id] = seq_render_preprocess_ibuf(
- &localcontext, seq, ibufs_arr[view_id], cfra, clock(), true, false, false);
+ &localcontext, seq, ibufs_arr[view_id], cfra, clock(), true, false);
}
}
@@ -3214,7 +3242,7 @@ static ImBuf *seq_render_movie_strip(
if (view_id != context->view_id) {
ibuf_arr[view_id] = seq_render_preprocess_ibuf(
- &localcontext, seq, ibuf_arr[view_id], cfra, clock(), true, false, false);
+ &localcontext, seq, ibuf_arr[view_id], cfra, clock(), true, false);
}
}
@@ -3334,7 +3362,9 @@ static ImBuf *seq_render_mask(const SeqRenderData *context, Mask *mask, float nr
/* anim-data */
adt = BKE_animdata_from_id(&mask->id);
- BKE_animsys_evaluate_animdata(&mask_temp->id, adt, mask->sfra + nr, ADT_RECALC_ANIM, false);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
+ context->depsgraph, mask->sfra + nr);
+ BKE_animsys_evaluate_animdata(&mask_temp->id, adt, &anim_eval_context, ADT_RECALC_ANIM, false);
maskbuf = MEM_mallocN(sizeof(float) * context->rectx * context->recty, __func__);
@@ -3804,8 +3834,7 @@ static ImBuf *seq_render_preprocess_ibuf(const SeqRenderData *context,
float cfra,
clock_t begin,
bool use_preprocess,
- const bool is_proxy_image,
- const bool is_preprocessed)
+ const bool is_proxy_image)
{
if (context->is_proxy_render == false &&
(ibuf->x != context->rectx || ibuf->y != context->recty)) {
@@ -3814,11 +3843,17 @@ static ImBuf *seq_render_preprocess_ibuf(const SeqRenderData *context,
if (use_preprocess) {
float cost = seq_estimate_render_cost_end(context->scene, begin);
- BKE_sequencer_cache_put(context, seq, cfra, SEQ_CACHE_STORE_RAW, ibuf, cost, false);
+
+ /* TODO (Richard): It should be possible to store in cache if image is proxy,
+ * but it adds quite a bit of complexity. Since proxies are fast to read, I would
+ * rather simplify existing code a bit. */
+ if (!is_proxy_image) {
+ BKE_sequencer_cache_put(context, seq, cfra, SEQ_CACHE_STORE_RAW, ibuf, cost, false);
+ }
/* Reset timer so we can get partial render time. */
begin = seq_estimate_render_cost_begin();
- ibuf = input_preprocess(context, seq, cfra, ibuf, is_proxy_image, is_preprocessed);
+ ibuf = input_preprocess(context, seq, cfra, ibuf, is_proxy_image);
}
float cost = seq_estimate_render_cost_end(context->scene, begin);
@@ -3834,11 +3869,6 @@ static ImBuf *seq_render_strip(const SeqRenderData *context,
ImBuf *ibuf = NULL;
bool use_preprocess = false;
bool is_proxy_image = false;
- /* all effects are handled similarly with the exception of speed effect */
- int type = (seq->type & SEQ_TYPE_EFFECT && seq->type != SEQ_TYPE_SPEED) ? SEQ_TYPE_EFFECT :
- seq->type;
- bool is_preprocessed = !ELEM(
- type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE, SEQ_TYPE_SCENE, SEQ_TYPE_MOVIECLIP);
clock_t begin = seq_estimate_render_cost_begin();
@@ -3855,7 +3885,7 @@ static ImBuf *seq_render_strip(const SeqRenderData *context,
if (ibuf) {
use_preprocess = BKE_sequencer_input_have_to_preprocess(context, seq, cfra);
ibuf = seq_render_preprocess_ibuf(
- context, seq, ibuf, cfra, begin, use_preprocess, is_proxy_image, is_preprocessed);
+ context, seq, ibuf, cfra, begin, use_preprocess, is_proxy_image);
}
if (ibuf == NULL) {
@@ -4272,6 +4302,10 @@ void BKE_sequence_invalidate_movieclip_strips(Main *bmain, MovieClip *clip_targe
void BKE_sequencer_free_imbuf(Scene *scene, ListBase *seqbase, bool for_render)
{
+ if (scene->ed == NULL) {
+ return;
+ }
+
Sequence *seq;
BKE_sequencer_cache_cleanup(scene);
@@ -5319,9 +5353,16 @@ Sequence *BKE_sequence_alloc(ListBase *lb, int cfra, int machine, int type)
seq->stereo3d_format = MEM_callocN(sizeof(Stereo3dFormat), "Sequence Stereo Format");
seq->cache_flag = SEQ_CACHE_STORE_RAW | SEQ_CACHE_STORE_PREPROCESSED | SEQ_CACHE_STORE_COMPOSITE;
+ BKE_sequence_session_uuid_generate(seq);
+
return seq;
}
+void BKE_sequence_session_uuid_generate(struct Sequence *sequence)
+{
+ sequence->runtime.session_uuid = BLI_session_uuid_generate();
+}
+
void BKE_sequence_alpha_mode_from_extension(Sequence *seq)
{
if (seq->strip && seq->strip->stripdata) {
@@ -5551,6 +5592,9 @@ Sequence *BKE_sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoad
}
}
+ if (seq_load->flag & SEQ_LOAD_MOVIE_SOUND) {
+ seq_load->channel++;
+ }
seq = BKE_sequence_alloc(seqbasep, seq_load->start_frame, seq_load->channel, SEQ_TYPE_MOVIE);
/* multiview settings */
@@ -5607,11 +5651,8 @@ Sequence *BKE_sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoad
if (seq_load->flag & SEQ_LOAD_MOVIE_SOUND) {
int start_frame_back = seq_load->start_frame;
seq_load->channel--;
-
seq_load->seq_sound = BKE_sequencer_add_sound_strip(C, seqbasep, seq_load);
-
seq_load->start_frame = start_frame_back;
- seq_load->channel++;
}
/* can be NULL */
@@ -5631,6 +5672,10 @@ static Sequence *seq_dupli(const Scene *scene_src,
{
Sequence *seqn = MEM_dupallocN(seq);
+ if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) {
+ BKE_sequence_session_uuid_generate(seq);
+ }
+
seq->tmp = seqn;
seqn->strip = MEM_dupallocN(seq->strip);
@@ -5698,7 +5743,7 @@ static Sequence *seq_dupli(const Scene *scene_src,
struct SeqEffectHandle sh;
sh = BKE_sequence_get_effect(seq);
if (sh.copy) {
- sh.copy(seq, seqn, flag);
+ sh.copy(seqn, seq, flag);
}
seqn->strip->stripdata = NULL;
@@ -6013,3 +6058,113 @@ bool BKE_sequencer_check_scene_recursion(Scene *scene, ReportList *reports)
return false;
}
+
+/* Check if "seq_main" (indirectly) uses strip "seq". */
+bool BKE_sequencer_render_loop_check(Sequence *seq_main, Sequence *seq)
+{
+ if (seq_main == seq) {
+ return true;
+ }
+
+ if ((seq_main->seq1 && BKE_sequencer_render_loop_check(seq_main->seq1, seq)) ||
+ (seq_main->seq2 && BKE_sequencer_render_loop_check(seq_main->seq2, seq)) ||
+ (seq_main->seq3 && BKE_sequencer_render_loop_check(seq_main->seq3, seq))) {
+ return true;
+ }
+
+ SequenceModifierData *smd;
+ for (smd = seq_main->modifiers.first; smd; smd = smd->next) {
+ if (smd->mask_sequence && BKE_sequencer_render_loop_check(smd->mask_sequence, seq)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static void sequencer_flag_users_for_removal(Scene *scene, ListBase *seqbase, Sequence *seq)
+{
+ LISTBASE_FOREACH (Sequence *, user_seq, seqbase) {
+ /* Look in metas for usage of seq. */
+ if (user_seq->type == SEQ_TYPE_META) {
+ sequencer_flag_users_for_removal(scene, &user_seq->seqbase, seq);
+ }
+
+ /* Clear seq from modifiers. */
+ SequenceModifierData *smd;
+ for (smd = user_seq->modifiers.first; smd; smd = smd->next) {
+ if (smd->mask_sequence == seq) {
+ smd->mask_sequence = NULL;
+ }
+ }
+
+ /* Remove effects, that use seq. */
+ if ((user_seq->seq1 && user_seq->seq1 == seq) || (user_seq->seq2 && user_seq->seq2 == seq) ||
+ (user_seq->seq3 && user_seq->seq3 == seq)) {
+ user_seq->flag |= SEQ_FLAG_DELETE;
+ /* Strips can be used as mask even if not in same seqbase. */
+ sequencer_flag_users_for_removal(scene, &scene->ed->seqbase, user_seq);
+ }
+ }
+}
+
+/* Flag seq and its users (effects) for removal. */
+void BKE_sequencer_flag_for_removal(Scene *scene, ListBase *seqbase, Sequence *seq)
+{
+ if (seq == NULL || (seq->flag & SEQ_FLAG_DELETE) != 0) {
+ return;
+ }
+
+ /* Flag and remove meta children. */
+ if (seq->type == SEQ_TYPE_META) {
+ LISTBASE_FOREACH (Sequence *, meta_child, &seq->seqbase) {
+ BKE_sequencer_flag_for_removal(scene, &seq->seqbase, meta_child);
+ }
+ }
+
+ seq->flag |= SEQ_FLAG_DELETE;
+ sequencer_flag_users_for_removal(scene, seqbase, seq);
+}
+
+/* Remove all flagged sequences, return true if sequence is removed. */
+void BKE_sequencer_remove_flagged_sequences(Scene *scene, ListBase *seqbase)
+{
+ LISTBASE_FOREACH_MUTABLE (Sequence *, seq, seqbase) {
+ if (seq->flag & SEQ_FLAG_DELETE) {
+ if (seq->type == SEQ_TYPE_META) {
+ BKE_sequencer_remove_flagged_sequences(scene, &seq->seqbase);
+ }
+ BLI_remlink(seqbase, seq);
+ BKE_sequence_free(scene, seq, true);
+ }
+ }
+}
+
+void BKE_sequencer_check_uuids_unique_and_report(const Scene *scene)
+{
+ if (scene->ed == NULL) {
+ return;
+ }
+
+ struct GSet *used_uuids = BLI_gset_new(
+ BLI_session_uuid_ghash_hash, BLI_session_uuid_ghash_compare, "sequencer used uuids");
+
+ const Sequence *sequence;
+ SEQ_BEGIN (scene->ed, sequence) {
+ const SessionUUID *session_uuid = &sequence->runtime.session_uuid;
+ if (!BLI_session_uuid_is_generated(session_uuid)) {
+ printf("Sequence %s does not have UUID generated.\n", sequence->name);
+ continue;
+ }
+
+ if (BLI_gset_lookup(used_uuids, session_uuid) != NULL) {
+ printf("Sequence %s has duplicate UUID generated.\n", sequence->name);
+ continue;
+ }
+
+ BLI_gset_insert(used_uuids, (void *)session_uuid);
+ }
+ SEQ_END;
+
+ BLI_gset_free(used_uuids, NULL);
+}
diff --git a/source/blender/blenkernel/intern/simulation.cc b/source/blender/blenkernel/intern/simulation.cc
index c4a35141b0d..c0fc8fcb464 100644
--- a/source/blender/blenkernel/intern/simulation.cc
+++ b/source/blender/blenkernel/intern/simulation.cc
@@ -31,6 +31,7 @@
#include "BLI_float3.hh"
#include "BLI_listbase.h"
#include "BLI_math.h"
+#include "BLI_rand.h"
#include "BLI_span.hh"
#include "BLI_string.h"
#include "BLI_utildefines.h"
@@ -47,13 +48,37 @@
#include "BKE_pointcache.h"
#include "BKE_simulation.h"
+#include "NOD_node_tree_multi_function.hh"
#include "NOD_simulation.h"
+#include "BLI_map.hh"
#include "BLT_translation.h"
+#include "FN_attributes_ref.hh"
+#include "FN_multi_function_network_evaluation.hh"
+#include "FN_multi_function_network_optimization.hh"
+
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
+#include "SIM_simulation_update.hh"
+
+using StateInitFunction = void (*)(SimulationState *state);
+using StateResetFunction = void (*)(SimulationState *state);
+using StateRemoveFunction = void (*)(SimulationState *state);
+using StateCopyFunction = void (*)(const SimulationState *src, SimulationState *dst);
+
+struct SimulationStateType {
+ const char *name;
+ int size;
+ StateInitFunction init;
+ StateResetFunction reset;
+ StateRemoveFunction remove;
+ StateCopyFunction copy;
+};
+
+static const SimulationStateType *try_get_state_type(blender::StringRefNull type_name);
+
static void simulation_init_data(ID *id)
{
Simulation *simulation = (Simulation *)id;
@@ -63,20 +88,12 @@ static void simulation_init_data(ID *id)
bNodeTree *ntree = ntreeAddTree(nullptr, "Simulation Nodetree", ntreeType_Simulation->idname);
simulation->nodetree = ntree;
-
- /* Add a default particle simulation state for now. */
- ParticleSimulationState *state = (ParticleSimulationState *)MEM_callocN(
- sizeof(ParticleSimulationState), __func__);
- CustomData_reset(&state->attributes);
-
- state->point_cache = BKE_ptcache_add(&state->ptcaches);
- BLI_addtail(&simulation->states, state);
}
static void simulation_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int flag)
{
Simulation *simulation_dst = (Simulation *)id_dst;
- Simulation *simulation_src = (Simulation *)id_src;
+ const Simulation *simulation_src = (const Simulation *)id_src;
/* We always need allocation of our private ID data. */
const int flag_private_id_data = flag & ~LIB_ID_CREATE_NO_ALLOCATE;
@@ -89,19 +106,14 @@ static void simulation_copy_data(Main *bmain, ID *id_dst, const ID *id_src, cons
}
BLI_listbase_clear(&simulation_dst->states);
-
LISTBASE_FOREACH (const SimulationState *, state_src, &simulation_src->states) {
- switch ((eSimulationStateType)state_src->type) {
- case SIM_STATE_TYPE_PARTICLES: {
- ParticleSimulationState *particle_state_dst = (ParticleSimulationState *)MEM_callocN(
- sizeof(ParticleSimulationState), __func__);
- CustomData_reset(&particle_state_dst->attributes);
-
- BLI_addtail(&simulation_dst->states, particle_state_dst);
- break;
- }
- }
+ SimulationState *state_dst = BKE_simulation_state_add(
+ simulation_dst, state_src->type, state_src->name);
+ BKE_simulation_state_copy_data(state_src, state_dst);
}
+
+ BLI_listbase_clear(&simulation_dst->dependencies);
+ BLI_duplicatelist(&simulation_dst->dependencies, &simulation_src->dependencies);
}
static void simulation_free_data(ID *id)
@@ -116,17 +128,9 @@ static void simulation_free_data(ID *id)
simulation->nodetree = nullptr;
}
- LISTBASE_FOREACH_MUTABLE (SimulationState *, state, &simulation->states) {
- switch ((eSimulationStateType)state->type) {
- case SIM_STATE_TYPE_PARTICLES: {
- ParticleSimulationState *particle_state = (ParticleSimulationState *)state;
- CustomData_free(&particle_state->attributes, particle_state->tot_particles);
- BKE_ptcache_free_list(&particle_state->ptcaches);
- break;
- }
- }
- MEM_freeN(state);
- }
+ BKE_simulation_state_remove_all(simulation);
+
+ BLI_freelistN(&simulation->dependencies);
}
static void simulation_foreach_id(ID *id, LibraryForeachIDData *data)
@@ -136,6 +140,9 @@ static void simulation_foreach_id(ID *id, LibraryForeachIDData *data)
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
BKE_library_foreach_ID_embedded(data, (ID **)&simulation->nodetree);
}
+ LISTBASE_FOREACH (SimulationDependency *, dependency, &simulation->dependencies) {
+ BKE_LIB_FOREACHID_PROCESS_ID(data, dependency->id, IDWALK_CB_USER);
+ }
}
IDTypeInfo IDType_ID_SIM = {
@@ -164,103 +171,203 @@ void *BKE_simulation_add(Main *bmain, const char *name)
return simulation;
}
-namespace blender::bke {
+SimulationState *BKE_simulation_state_add(Simulation *simulation,
+ const char *type,
+ const char *name)
+{
+ BLI_assert(simulation != nullptr);
+ BLI_assert(name != nullptr);
+
+ const SimulationStateType *state_type = try_get_state_type(type);
+ BLI_assert(state_type != nullptr);
+
+ SimulationState *state = (SimulationState *)MEM_callocN(state_type->size, AT);
+ state->type = BLI_strdup(type);
+ state->name = BLI_strdup(name);
+
+ state_type->init(state);
+ BLI_addtail(&simulation->states, state);
+ return state;
+}
-static MutableSpan<float3> get_particle_positions(ParticleSimulationState *state)
+void BKE_simulation_state_remove(Simulation *simulation, SimulationState *state)
{
- return MutableSpan<float3>(
- (float3 *)CustomData_get_layer_named(&state->attributes, CD_LOCATION, "Position"),
- state->tot_particles);
+ BLI_assert(simulation != nullptr);
+ BLI_assert(state != nullptr);
+ BLI_assert(BLI_findindex(&simulation->states, state) >= 0);
+
+ BLI_remlink(&simulation->states, state);
+ const SimulationStateType *state_type = try_get_state_type(state->type);
+ BLI_assert(state_type != nullptr);
+ state_type->remove(state);
+ MEM_freeN(state->name);
+ MEM_freeN(state->type);
+ MEM_freeN(state);
}
-static void ensure_attributes_exist(ParticleSimulationState *state)
+void BKE_simulation_state_remove_all(Simulation *simulation)
{
- if (CustomData_get_layer_named(&state->attributes, CD_LOCATION, "Position") == nullptr) {
- CustomData_add_layer_named(
- &state->attributes, CD_LOCATION, CD_CALLOC, nullptr, state->tot_particles, "Position");
+ BLI_assert(simulation != nullptr);
+
+ while (!BLI_listbase_is_empty(&simulation->states)) {
+ BKE_simulation_state_remove(simulation, (SimulationState *)simulation->states.first);
}
}
-static void copy_particle_state_to_cow(ParticleSimulationState *state_orig,
- ParticleSimulationState *state_cow)
+void BKE_simulation_state_reset(Simulation *UNUSED(simulation), SimulationState *state)
{
- ensure_attributes_exist(state_cow);
- CustomData_free(&state_cow->attributes, state_cow->tot_particles);
- CustomData_copy(&state_orig->attributes,
- &state_cow->attributes,
- CD_MASK_ALL,
- CD_DUPLICATE,
- state_orig->tot_particles);
- state_cow->current_frame = state_orig->current_frame;
- state_cow->tot_particles = state_orig->tot_particles;
+ BLI_assert(state != nullptr);
+
+ const SimulationStateType *state_type = try_get_state_type(state->type);
+ BLI_assert(state_type != nullptr);
+ state_type->reset(state);
}
-static void simulation_data_update(Depsgraph *depsgraph, Scene *scene, Simulation *simulation)
+void BKE_simulation_state_reset_all(Simulation *simulation)
{
- int current_frame = scene->r.cfra;
+ BLI_assert(simulation != nullptr);
- ParticleSimulationState *state_cow = (ParticleSimulationState *)simulation->states.first;
- ParticleSimulationState *state_orig = (ParticleSimulationState *)state_cow->head.orig_state;
-
- if (current_frame == state_cow->current_frame) {
- return;
+ LISTBASE_FOREACH (SimulationState *, state, &simulation->states) {
+ BKE_simulation_state_reset(simulation, state);
}
+}
- /* Number of particles should be stored in the cache, but for now assume it is constant. */
- state_cow->tot_particles = state_orig->tot_particles;
- CustomData_realloc(&state_cow->attributes, state_orig->tot_particles);
- ensure_attributes_exist(state_cow);
+void BKE_simulation_state_copy_data(const SimulationState *src_state, SimulationState *dst_state)
+{
+ BLI_assert(src_state != nullptr);
+ BLI_assert(dst_state != nullptr);
+ BLI_assert(STREQ(src_state->type, dst_state->type));
- PTCacheID pid_cow;
- BKE_ptcache_id_from_sim_particles(&pid_cow, state_cow);
- BKE_ptcache_id_time(&pid_cow, scene, current_frame, nullptr, nullptr, nullptr);
+ const SimulationStateType *state_type = try_get_state_type(src_state->type);
+ BLI_assert(state_type != nullptr);
+ state_type->copy(src_state, dst_state);
+}
- /* If successfull, this will read the state directly into the cow state. */
- int cache_result = BKE_ptcache_read(&pid_cow, current_frame, true);
- if (cache_result == PTCACHE_READ_EXACT) {
- state_cow->current_frame = current_frame;
- return;
+SimulationState *BKE_simulation_state_try_find_by_name(Simulation *simulation, const char *name)
+{
+ if (simulation == nullptr) {
+ return nullptr;
+ }
+ if (name == nullptr) {
+ return nullptr;
}
- /* Below we modify the original state/cache. Only the active depsgraph is allowed to do that. */
- if (!DEG_is_active(depsgraph)) {
- return;
+ LISTBASE_FOREACH (SimulationState *, state, &simulation->states) {
+ if (STREQ(state->name, name)) {
+ return state;
+ }
}
+ return nullptr;
+}
- PTCacheID pid_orig;
- BKE_ptcache_id_from_sim_particles(&pid_orig, state_orig);
- BKE_ptcache_id_time(&pid_orig, scene, current_frame, nullptr, nullptr, nullptr);
+SimulationState *BKE_simulation_state_try_find_by_name_and_type(Simulation *simulation,
+ const char *name,
+ const char *type)
+{
+ if (type == nullptr) {
+ return nullptr;
+ }
- if (current_frame == 1) {
- state_orig->tot_particles = 100;
- state_orig->current_frame = 1;
- CustomData_realloc(&state_orig->attributes, state_orig->tot_particles);
- ensure_attributes_exist(state_orig);
+ SimulationState *state = BKE_simulation_state_try_find_by_name(simulation, name);
+ if (state == nullptr) {
+ return nullptr;
+ }
+ if (STREQ(state->type, type)) {
+ return state;
+ }
+ return nullptr;
+}
- MutableSpan<float3> positions = get_particle_positions(state_orig);
- for (uint i : positions.index_range()) {
- positions[i] = {i / 10.0f, 0, 0};
- }
+void BKE_simulation_data_update(Depsgraph *depsgraph, Scene *scene, Simulation *simulation)
+{
+ blender::sim::update_simulation_in_depsgraph(depsgraph, scene, simulation);
+}
- BKE_ptcache_write(&pid_orig, current_frame);
- copy_particle_state_to_cow(state_orig, state_cow);
+void BKE_simulation_update_dependencies(Simulation *simulation, Main *bmain)
+{
+ bool dependencies_changed = blender::sim::update_simulation_dependencies(simulation);
+ if (dependencies_changed) {
+ DEG_relations_tag_update(bmain);
}
- else if (current_frame == state_orig->current_frame + 1) {
- state_orig->current_frame = current_frame;
- ensure_attributes_exist(state_orig);
- MutableSpan<float3> positions = get_particle_positions(state_orig);
- for (float3 &position : positions) {
- position.z += 0.1f;
- }
+}
- BKE_ptcache_write(&pid_orig, current_frame);
- copy_particle_state_to_cow(state_orig, state_cow);
+using StateTypeMap = blender::Map<std::string, std::unique_ptr<SimulationStateType>>;
+
+template<typename T>
+static void add_state_type(StateTypeMap &map,
+ const char *name,
+ void (*init)(T *state),
+ void (*reset)(T *state),
+ void (*remove)(T *state),
+ void (*copy)(const T *src, T *dst))
+{
+ SimulationStateType state_type{
+ name,
+ (int)sizeof(T),
+ (StateInitFunction)init,
+ (StateResetFunction)reset,
+ (StateRemoveFunction)remove,
+ (StateCopyFunction)copy,
+ };
+ map.add_new(name, std::make_unique<SimulationStateType>(state_type));
+}
+
+static StateTypeMap init_state_types()
+{
+ StateTypeMap map;
+ add_state_type<ParticleSimulationState>(
+ map,
+ SIM_TYPE_NAME_PARTICLE_SIMULATION,
+ [](ParticleSimulationState *state) { CustomData_reset(&state->attributes); },
+ [](ParticleSimulationState *state) {
+ CustomData_free(&state->attributes, state->tot_particles);
+ state->tot_particles = 0;
+ state->next_particle_id = 0;
+ },
+ [](ParticleSimulationState *state) {
+ CustomData_free(&state->attributes, state->tot_particles);
+ },
+ [](const ParticleSimulationState *src, ParticleSimulationState *dst) {
+ CustomData_free(&dst->attributes, dst->tot_particles);
+ dst->tot_particles = src->tot_particles;
+ dst->next_particle_id = src->next_particle_id;
+ CustomData_copy(
+ &src->attributes, &dst->attributes, CD_MASK_ALL, CD_DUPLICATE, src->tot_particles);
+ });
+
+ add_state_type<ParticleMeshEmitterSimulationState>(
+ map,
+ SIM_TYPE_NAME_PARTICLE_MESH_EMITTER,
+ [](ParticleMeshEmitterSimulationState *UNUSED(state)) {},
+ [](ParticleMeshEmitterSimulationState *state) { state->last_birth_time = 0.0f; },
+ [](ParticleMeshEmitterSimulationState *UNUSED(state)) {},
+ [](const ParticleMeshEmitterSimulationState *src, ParticleMeshEmitterSimulationState *dst) {
+ dst->last_birth_time = src->last_birth_time;
+ });
+ return map;
+}
+
+static StateTypeMap &get_state_types()
+{
+ static StateTypeMap state_type_map = init_state_types();
+ return state_type_map;
+}
+
+static const SimulationStateType *try_get_state_type(blender::StringRefNull type_name)
+{
+ std::unique_ptr<SimulationStateType> *type = get_state_types().lookup_ptr_as(type_name);
+ if (type == nullptr) {
+ return nullptr;
}
+ return type->get();
}
-} // namespace blender::bke
+template<> const char *BKE_simulation_get_state_type_name<ParticleSimulationState>()
+{
+ return SIM_TYPE_NAME_PARTICLE_SIMULATION;
+}
-void BKE_simulation_data_update(Depsgraph *depsgraph, Scene *scene, Simulation *simulation)
+template<> const char *BKE_simulation_get_state_type_name<ParticleMeshEmitterSimulationState>()
{
- blender::bke::simulation_data_update(depsgraph, scene, simulation);
+ return SIM_TYPE_NAME_PARTICLE_MESH_EMITTER;
}
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index 9c7abbdf876..b7b325644ca 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -165,24 +165,28 @@ static void free_softbody_intern(SoftBody *sb);
/*physical unit of force is [kg * m / sec^2]*/
-static float sb_grav_force_scale(Object *UNUSED(ob))
-/* since unit of g is [m/sec^2] and F = mass * g we rescale unit mass of node to 1 gramm
- * put it to a function here, so we can add user options later without touching simulation code
+/**
+ * Since unit of g is [m/sec^2] and F = mass * g we re-scale unit mass of node to 1 gram
+ * put it to a function here, so we can add user options later without touching simulation code.
*/
+static float sb_grav_force_scale(Object *UNUSED(ob))
{
return (0.001f);
}
-static float sb_fric_force_scale(Object *UNUSED(ob))
-/* rescaling unit of drag [1 / sec] to somehow reasonable
- * put it to a function here, so we can add user options later without touching simulation code
+/**
+ * Re-scaling unit of drag [1 / sec] to somehow reasonable
+ * put it to a function here, so we can add user options later without touching simulation code.
*/
+static float sb_fric_force_scale(Object *UNUSED(ob))
{
return (0.01f);
}
+/**
+ * Defining the frames to *real* time relation.
+ */
static float sb_time_scale(Object *ob)
-/* defining the frames to *real* time relation */
{
SoftBody *sb = ob->soft; /* is supposed to be there */
if (sb) {
@@ -481,7 +485,6 @@ static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M)
mima->maxy = max_ff(mima->maxy, v[1] + hull);
mima->maxz = max_ff(mima->maxz, v[2] + hull);
}
- return;
}
static void ccd_mesh_free(ccd_Mesh *ccdm)
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index 18fd8a10cc1..1fcfc9b060f 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -123,7 +123,7 @@ static void sound_foreach_cache(ID *id,
.cache_v = sound->waveform,
};
- function_callback(id, &key, &sound->waveform, user_data);
+ function_callback(id, &key, &sound->waveform, 0, user_data);
}
IDTypeInfo IDType_ID_SO = {
diff --git a/source/blender/blenkernel/intern/studiolight.c b/source/blender/blenkernel/intern/studiolight.c
index 8455b60c894..46341652544 100644
--- a/source/blender/blenkernel/intern/studiolight.c
+++ b/source/blender/blenkernel/intern/studiolight.c
@@ -875,7 +875,6 @@ BLI_INLINE void studiolight_spherical_harmonics_eval(StudioLight *sl,
color[i] = studiolight_spherical_harmonics_geomerics_eval(
normal, sh[0][i], sh[1][i], sh[2][i], sh[3][i]);
}
- return;
#else
/* L0 */
mul_v3_v3fl(color, sl->spherical_harmonics_coefs[0], 0.282095f);
diff --git a/source/blender/blenkernel/intern/subdiv_ccg.c b/source/blender/blenkernel/intern/subdiv_ccg.c
index a1e218390c3..c992990e0a0 100644
--- a/source/blender/blenkernel/intern/subdiv_ccg.c
+++ b/source/blender/blenkernel/intern/subdiv_ccg.c
@@ -1618,6 +1618,18 @@ static int prev_adjacent_edge_point_index(const SubdivCCG *subdiv_ccg, const int
return point_index - 1;
}
+/* When the point index corresponds to a grid corner, returns the point index which corresponds to
+ * the corner of the adjacent grid, as the adjacent edge has two separate points for each grid
+ * corner at the middle of the edge. */
+static int adjacent_grid_corner_point_index_on_edge(const SubdivCCG *subdiv_ccg,
+ const int point_index)
+{
+ if (point_index == subdiv_ccg->grid_size) {
+ return point_index - 1;
+ }
+ return point_index + 1;
+}
+
/* Common implementation of neighbor calculation when input coordinate is at the edge between two
* coarse faces, but is not at the coarse vertex. */
static void neighbor_coords_edge_get(const SubdivCCG *subdiv_ccg,
@@ -1626,6 +1638,7 @@ static void neighbor_coords_edge_get(const SubdivCCG *subdiv_ccg,
SubdivCCGNeighbors *r_neighbors)
{
+ const bool is_corner = is_corner_grid_coord(subdiv_ccg, coord);
const int adjacent_edge_index = adjacent_edge_index_from_coord(subdiv_ccg, coord);
BLI_assert(adjacent_edge_index >= 0);
BLI_assert(adjacent_edge_index < subdiv_ccg->num_adjacent_edges);
@@ -1633,15 +1646,27 @@ static void neighbor_coords_edge_get(const SubdivCCG *subdiv_ccg,
/* 2 neighbor points along the edge, plus one inner point per every adjacent grid. */
const int num_adjacent_faces = adjacent_edge->num_adjacent_faces;
- subdiv_ccg_neighbors_init(
- r_neighbors, num_adjacent_faces + 2, (include_duplicates) ? num_adjacent_faces - 1 : 0);
+ int num_duplicates = 0;
+ if (include_duplicates) {
+ num_duplicates += num_adjacent_faces - 1;
+ if (is_corner) {
+ /* When the coord is a grid corner, add an extra duplicate per adjacent grid in all adjacent
+ * faces to the edge. */
+ num_duplicates += num_adjacent_faces;
+ }
+ }
+ subdiv_ccg_neighbors_init(r_neighbors, num_adjacent_faces + 2, num_duplicates);
const int point_index = adjacent_edge_point_index_from_coord(
subdiv_ccg, coord, adjacent_edge_index);
+ const int point_index_duplicate = adjacent_grid_corner_point_index_on_edge(subdiv_ccg,
+ point_index);
+
const int next_point_index = next_adjacent_edge_point_index(subdiv_ccg, point_index);
const int prev_point_index = prev_adjacent_edge_point_index(subdiv_ccg, point_index);
- for (int i = 0, duplicate_i = num_adjacent_faces; i < num_adjacent_faces; ++i) {
+ int duplicate_i = num_adjacent_faces;
+ for (int i = 0; i < num_adjacent_faces; ++i) {
SubdivCCGCoord *boundary_coords = adjacent_edge->boundary_coords[i];
/* One step into the grid from the edge for each adjacent face. */
SubdivCCGCoord grid_coord = boundary_coords[point_index];
@@ -1657,7 +1682,15 @@ static void neighbor_coords_edge_get(const SubdivCCG *subdiv_ccg,
r_neighbors->coords[duplicate_i + 2] = grid_coord;
duplicate_i++;
}
+
+ /* When it is a corner, add the duplicate of the adjacent grid in the same face. */
+ if (include_duplicates && is_corner) {
+ SubdivCCGCoord duplicate_corner_grid_coord = boundary_coords[point_index_duplicate];
+ r_neighbors->coords[duplicate_i + 2] = duplicate_corner_grid_coord;
+ duplicate_i++;
+ }
}
+ BLI_assert(duplicate_i - num_adjacent_faces == num_duplicates);
}
/* The corner is at the middle of edge between faces. */
@@ -1834,4 +1867,70 @@ const int *BKE_subdiv_ccg_start_face_grid_index_get(const SubdivCCG *subdiv_ccg)
return subdiv_ccg->cache_.start_face_grid_index;
}
+static void adjacet_vertices_index_from_adjacent_edge(const SubdivCCG *subdiv_ccg,
+ const SubdivCCGCoord *coord,
+ const MLoop *mloop,
+ const MPoly *mpoly,
+ int *r_v1,
+ int *r_v2)
+{
+ const int grid_size_1 = subdiv_ccg->grid_size - 1;
+ const int poly_index = BKE_subdiv_ccg_grid_to_face_index(subdiv_ccg, coord->grid_index);
+ const MPoly *p = &mpoly[poly_index];
+ *r_v1 = mloop[coord->grid_index].v;
+ if (coord->x == grid_size_1) {
+ const MLoop *next = ME_POLY_LOOP_NEXT(mloop, p, coord->grid_index);
+ *r_v2 = next->v;
+ }
+ if (coord->y == grid_size_1) {
+ const MLoop *prev = ME_POLY_LOOP_PREV(mloop, p, coord->grid_index);
+ *r_v2 = prev->v;
+ }
+}
+
+SubdivCCGAdjacencyType BKE_subdiv_ccg_coarse_mesh_adjacency_info_get(const SubdivCCG *subdiv_ccg,
+ const SubdivCCGCoord *coord,
+ const MLoop *mloop,
+ const MPoly *mpoly,
+ int *r_v1,
+ int *r_v2)
+{
+
+ const int grid_size_1 = subdiv_ccg->grid_size - 1;
+ if (is_corner_grid_coord(subdiv_ccg, coord)) {
+ if (coord->x == 0 && coord->y == 0) {
+ /* Grid corner in the center of a poly. */
+ return SUBDIV_CCG_ADJACENT_NONE;
+ }
+ if (coord->x == grid_size_1 && coord->y == grid_size_1) {
+ /* Grid corner adjacent to a coarse mesh vertex. */
+ *r_v1 = *r_v2 = mloop[coord->grid_index].v;
+ return SUBDIV_CCG_ADJACENT_VERTEX;
+ }
+ /* Grid corner adjacent to the middle of a coarse mesh edge. */
+ adjacet_vertices_index_from_adjacent_edge(subdiv_ccg, coord, mloop, mpoly, r_v1, r_v2);
+ return SUBDIV_CCG_ADJACENT_EDGE;
+ }
+
+ if (is_boundary_grid_coord(subdiv_ccg, coord)) {
+ if (!is_inner_edge_grid_coordinate(subdiv_ccg, coord)) {
+ /* Grid boundary adjacent to a coarse mesh edge. */
+ adjacet_vertices_index_from_adjacent_edge(subdiv_ccg, coord, mloop, mpoly, r_v1, r_v2);
+ return SUBDIV_CCG_ADJACENT_EDGE;
+ }
+ }
+ return SUBDIV_CCG_ADJACENT_NONE;
+}
+
+void BKE_subdiv_ccg_grid_hidden_ensure(SubdivCCG *subdiv_ccg, int grid_index)
+{
+ if (subdiv_ccg->grid_hidden[grid_index] != NULL) {
+ return;
+ }
+
+ CCGKey key;
+ BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
+ subdiv_ccg->grid_hidden[grid_index] = BLI_BITMAP_NEW(key.grid_area, __func__);
+}
+
/** \} */
diff --git a/source/blender/blenkernel/intern/subdiv_converter.h b/source/blender/blenkernel/intern/subdiv_converter.h
index fb0e84ade13..ea0efe994b5 100644
--- a/source/blender/blenkernel/intern/subdiv_converter.h
+++ b/source/blender/blenkernel/intern/subdiv_converter.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __SUBDIV_CONVERTER_H__
-#define __SUBDIV_CONVERTER_H__
+#pragma once
/** \file
* \ingroup bke
@@ -51,5 +50,3 @@ int BKE_subdiv_converter_vtx_boundary_interpolation_from_settings(const SubdivSe
/* TODO(sergey): Find a way to make it OpenSubdiv_FVarLinearInterpolation,
* without breaking compilation without OpenSubdiv. */
int BKE_subdiv_converter_fvar_linear_from_settings(const SubdivSettings *settings);
-
-#endif /* __SUBDIV_CONVERTER_H__ */
diff --git a/source/blender/blenkernel/intern/subdiv_inline.h b/source/blender/blenkernel/intern/subdiv_inline.h
index a51a33feb3d..ba45d0a4997 100644
--- a/source/blender/blenkernel/intern/subdiv_inline.h
+++ b/source/blender/blenkernel/intern/subdiv_inline.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __SUBDIV_INLINE_H__
-#define __SUBDIV_INLINE_H__
+#pragma once
#include "BLI_assert.h"
#include "BLI_compiler_compat.h"
@@ -114,5 +113,3 @@ BLI_INLINE float BKE_subdiv_edge_crease_to_sharpness_char(char edge_crease)
const float edge_crease_f = edge_crease / 255.0f;
return BKE_subdiv_edge_crease_to_sharpness_f(edge_crease_f);
}
-
-#endif /* __SUBDIV_INLINE_H__ */
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index 97d95cb7e46..f17467e4a26 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -509,7 +509,7 @@ void BKE_tracking_clipboard_copy_tracks(MovieTracking *tracking, MovieTrackingOb
}
}
-/* Check whether there're any tracks in the clipboard. */
+/* Check whether there are any tracks in the clipboard. */
bool BKE_tracking_clipboard_has_tracks(void)
{
return (BLI_listbase_is_empty(&tracking_clipboard.tracks) == false);
diff --git a/source/blender/blenkernel/intern/tracking_stabilize.c b/source/blender/blenkernel/intern/tracking_stabilize.c
index e09e92588c6..b9c6bb83157 100644
--- a/source/blender/blenkernel/intern/tracking_stabilize.c
+++ b/source/blender/blenkernel/intern/tracking_stabilize.c
@@ -215,7 +215,7 @@ static void use_values_from_fcurves(StabContext *ctx, bool toggle)
/* Prepare per call private working area.
* Used for access to possibly animated values: retrieve available F-curves.
*/
-static StabContext *initialize_stabilization_working_context(MovieClip *clip)
+static StabContext *init_stabilization_working_context(MovieClip *clip)
{
StabContext *ctx = MEM_callocN(sizeof(StabContext), "2D stabilization animation runtime data");
ctx->clip = clip;
@@ -841,14 +841,14 @@ static int establish_track_initialization_order(StabContext *ctx, TrackInitOrder
*
* NOTE: when done, this track is marked as initialized
*/
-static void initialize_track_for_stabilization(StabContext *ctx,
- MovieTrackingTrack *track,
- int reference_frame,
- float aspect,
- const float average_translation[2],
- const float pivot[2],
- const float average_angle,
- const float average_scale_step)
+static void init_track_for_stabilization(StabContext *ctx,
+ MovieTrackingTrack *track,
+ int reference_frame,
+ float aspect,
+ const float average_translation[2],
+ const float pivot[2],
+ const float average_angle,
+ const float average_scale_step)
{
float pos[2], angle, len;
TrackStabilizationBase *local_data = access_stabilization_baseline_data(ctx, track);
@@ -876,7 +876,7 @@ static void initialize_track_for_stabilization(StabContext *ctx,
local_data->is_init_for_stabilization = true;
}
-static void initialize_all_tracks(StabContext *ctx, float aspect)
+static void init_all_tracks(StabContext *ctx, float aspect)
{
size_t track_len = 0;
MovieClip *clip = ctx->clip;
@@ -936,14 +936,14 @@ static void initialize_all_tracks(StabContext *ctx, float aspect)
&average_angle,
&average_scale_step);
}
- initialize_track_for_stabilization(ctx,
- track,
- reference_frame,
- aspect,
- average_translation,
- pivot,
- average_angle,
- average_scale_step);
+ init_track_for_stabilization(ctx,
+ track,
+ reference_frame,
+ aspect,
+ average_translation,
+ pivot,
+ average_angle,
+ average_scale_step);
}
cleanup:
@@ -1257,9 +1257,9 @@ static float calculate_autoscale_factor(StabContext *ctx, int size, float aspect
*/
static StabContext *init_stabilizer(MovieClip *clip, int size, float aspect)
{
- StabContext *ctx = initialize_stabilization_working_context(clip);
+ StabContext *ctx = init_stabilization_working_context(clip);
BLI_assert(ctx != NULL);
- initialize_all_tracks(ctx, aspect);
+ init_all_tracks(ctx, aspect);
if (ctx->stab->flag & TRACKING_AUTOSCALE) {
ctx->stab->scale = 1.0;
ctx->stab->scale = calculate_autoscale_factor(ctx, size, aspect);
diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c
index e155dedeef0..0809e8dda6d 100644
--- a/source/blender/blenkernel/intern/undo_system.c
+++ b/source/blender/blenkernel/intern/undo_system.c
@@ -507,9 +507,7 @@ bool BKE_undosys_step_push_with_type(UndoStack *ustack,
/* Might not be final place for this to be called - probably only want to call it from some
* undo handlers, not all of them? */
- if (BKE_lib_override_library_is_enabled()) {
- BKE_lib_override_library_main_operations_create(G_MAIN, false);
- }
+ BKE_lib_override_library_main_operations_create(G_MAIN, false);
/* Remove all undos after (also when 'ustack->step_active == NULL'). */
while (ustack->steps.last != ustack->step_active) {
diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c
index f37feab4b85..efe10b02940 100644
--- a/source/blender/blenkernel/intern/unit.c
+++ b/source/blender/blenkernel/intern/unit.c
@@ -1005,7 +1005,6 @@ bool bUnit_ReplaceString(
/* Fix cases like "-1m50cm" which would evaluate to -0.5m without this. */
changed |= unit_distribute_negatives(str, len_max);
- printf("%s\n", str);
/* Try to find a default unit from current or previous string. */
default_unit = unit_detect_from_str(usys, str, str_prev);
diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc
index 18859869b4e..633ad250a67 100644
--- a/source/blender/blenkernel/intern/volume.cc
+++ b/source/blender/blenkernel/intern/volume.cc
@@ -218,7 +218,9 @@ static struct VolumeFileCache {
cache.erase(entry);
}
else if (entry.num_tree_users == 0) {
- entry.grid->clear();
+ /* Note we replace the grid rather than clearing, so that if there is
+ * any other shared pointer to the grid it will keep the tree. */
+ entry.grid = entry.grid->copyGridWithNewTree();
entry.is_loaded = false;
}
}
@@ -239,15 +241,14 @@ struct VolumeGrid {
VolumeGrid(const VolumeFileCache::Entry &template_entry) : entry(NULL), is_loaded(false)
{
entry = GLOBAL_CACHE.add_metadata_user(template_entry);
- vdb = entry->grid;
}
- VolumeGrid(const openvdb::GridBase::Ptr &vdb) : vdb(vdb), entry(NULL), is_loaded(true)
+ VolumeGrid(const openvdb::GridBase::Ptr &grid) : entry(NULL), local_grid(grid), is_loaded(true)
{
}
VolumeGrid(const VolumeGrid &other)
- : vdb(other.vdb), entry(other.entry), is_loaded(other.is_loaded)
+ : entry(other.entry), local_grid(other.local_grid), is_loaded(other.is_loaded)
{
if (entry) {
GLOBAL_CACHE.copy_user(*entry, is_loaded);
@@ -330,7 +331,7 @@ struct VolumeGrid {
void clear_reference(const char *UNUSED(volume_name))
{
/* Clear any reference to a grid in the file cache. */
- vdb = vdb->copyGridWithNewTree();
+ local_grid = grid()->copyGridWithNewTree();
if (entry) {
GLOBAL_CACHE.remove_user(*entry, is_loaded);
entry = NULL;
@@ -344,7 +345,7 @@ struct VolumeGrid {
* file cache. Load file grid into memory first if needed. */
load(volume_name, filepath);
/* TODO: avoid deep copy if we are the only user. */
- vdb = vdb->deepCopyGrid();
+ local_grid = grid()->deepCopyGrid();
if (entry) {
GLOBAL_CACHE.remove_user(*entry, is_loaded);
entry = NULL;
@@ -356,7 +357,7 @@ struct VolumeGrid {
{
/* Don't use vdb.getName() since it copies the string, we want a pointer to the
* original so it doesn't get freed out of scope. */
- openvdb::StringMetadata::ConstPtr name_meta = vdb->getMetadata<openvdb::StringMetadata>(
+ openvdb::StringMetadata::ConstPtr name_meta = grid()->getMetadata<openvdb::StringMetadata>(
openvdb::GridBase::META_GRID_NAME);
return (name_meta) ? name_meta->value().c_str() : "";
}
@@ -371,10 +372,22 @@ struct VolumeGrid {
}
}
- /* OpenVDB grid. */
- openvdb::GridBase::Ptr vdb;
- /* File cache entry. */
+ const bool grid_is_loaded() const
+ {
+ return is_loaded;
+ }
+
+ const openvdb::GridBase::Ptr &grid() const
+ {
+ return (entry) ? entry->grid : local_grid;
+ }
+
+ protected:
+ /* File cache entry when grid comes directly from a file and may be shared
+ * with other volume datablocks. */
VolumeFileCache::Entry *entry;
+ /* OpenVDB grid if it's not shared through the file cache. */
+ openvdb::GridBase::Ptr local_grid;
/* Indicates if the tree has been loaded for this grid. Note that vdb.tree()
* may actually be loaded by another user while this is false. But only after
* calling load() and is_loaded changes to true is it safe to access. */
@@ -494,7 +507,7 @@ static void volume_foreach_cache(ID *id,
/* cache_v */ volume->runtime.grids,
};
- function_callback(id, &key, (void **)&volume->runtime.grids, user_data);
+ function_callback(id, &key, (void **)&volume->runtime.grids, 0, user_data);
}
IDTypeInfo IDType_ID_VO = {
@@ -1047,7 +1060,7 @@ void BKE_volume_grid_unload(const Volume *volume, VolumeGrid *grid)
bool BKE_volume_grid_is_loaded(const VolumeGrid *grid)
{
#ifdef WITH_OPENVDB
- return grid->is_loaded;
+ return grid->grid_is_loaded();
#else
UNUSED_VARS(grid);
return true;
@@ -1069,7 +1082,7 @@ const char *BKE_volume_grid_name(const VolumeGrid *volume_grid)
VolumeGridType BKE_volume_grid_type(const VolumeGrid *volume_grid)
{
#ifdef WITH_OPENVDB
- const openvdb::GridBase::Ptr &grid = volume_grid->vdb;
+ const openvdb::GridBase::Ptr &grid = volume_grid->grid();
if (grid->isType<openvdb::FloatGrid>()) {
return VOLUME_GRID_FLOAT;
@@ -1138,7 +1151,7 @@ int BKE_volume_grid_channels(const VolumeGrid *grid)
void BKE_volume_grid_transform_matrix(const VolumeGrid *volume_grid, float mat[4][4])
{
#ifdef WITH_OPENVDB
- const openvdb::GridBase::Ptr &grid = volume_grid->vdb;
+ const openvdb::GridBase::Ptr &grid = volume_grid->grid();
const openvdb::math::Transform &transform = grid->transform();
/* Perspective not supported for now, getAffineMap() will leave out the
@@ -1162,7 +1175,7 @@ bool BKE_volume_grid_bounds(const VolumeGrid *volume_grid, float min[3], float m
{
#ifdef WITH_OPENVDB
/* TODO: we can get this from grid metadata in some cases? */
- const openvdb::GridBase::Ptr &grid = volume_grid->vdb;
+ const openvdb::GridBase::Ptr &grid = volume_grid->grid();
BLI_assert(BKE_volume_grid_is_loaded(volume_grid));
openvdb::CoordBBox coordbbox;
@@ -1287,14 +1300,14 @@ void BKE_volume_grid_remove(Volume *volume, VolumeGrid *grid)
#ifdef WITH_OPENVDB
openvdb::GridBase::ConstPtr BKE_volume_grid_openvdb_for_metadata(const VolumeGrid *grid)
{
- return grid->vdb;
+ return grid->grid();
}
openvdb::GridBase::ConstPtr BKE_volume_grid_openvdb_for_read(const Volume *volume,
VolumeGrid *grid)
{
BKE_volume_grid_load(volume, grid);
- return grid->vdb;
+ return grid->grid();
}
openvdb::GridBase::Ptr BKE_volume_grid_openvdb_for_write(const Volume *volume,
@@ -1310,6 +1323,6 @@ openvdb::GridBase::Ptr BKE_volume_grid_openvdb_for_write(const Volume *volume,
grid->duplicate_reference(volume_name, grids.filepath);
}
- return grid->vdb;
+ return grid->grid();
}
#endif
diff --git a/source/blender/blenkernel/nla_private.h b/source/blender/blenkernel/nla_private.h
index c72747a8c51..7057e9ab5bd 100644
--- a/source/blender/blenkernel/nla_private.h
+++ b/source/blender/blenkernel/nla_private.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __NLA_PRIVATE_H__
-#define __NLA_PRIVATE_H__
+#pragma once
#include "BLI_bitmap.h"
#include "BLI_ghash.h"
@@ -32,6 +31,8 @@
extern "C" {
#endif
+struct AnimationEvalContext;
+
/* --------------- NLA Evaluation DataTypes ----------------------- */
/* used for list of strips to accumulate at current time */
@@ -168,13 +169,17 @@ float nlastrip_get_frame(NlaStrip *strip, float cframe, short mode);
/* these functions are only defined here to avoid problems with the order
* in which they get defined. */
-NlaEvalStrip *nlastrips_ctime_get_strip(
- ListBase *list, ListBase *strips, short index, float ctime, const bool flush_to_original);
+NlaEvalStrip *nlastrips_ctime_get_strip(ListBase *list,
+ ListBase *strips,
+ short index,
+ const struct AnimationEvalContext *anim_eval_context,
+ const bool flush_to_original);
void nlastrip_evaluate(PointerRNA *ptr,
NlaEvalData *channels,
ListBase *modifiers,
NlaEvalStrip *nes,
NlaEvalSnapshot *snapshot,
+ const struct AnimationEvalContext *anim_eval_context,
const bool flush_to_original);
void nladata_flush_channels(PointerRNA *ptr,
NlaEvalData *channels,
@@ -184,5 +189,3 @@ void nladata_flush_channels(PointerRNA *ptr,
#ifdef __cplusplus
}
#endif
-
-#endif /* __NLA_PRIVATE_H__ */
diff --git a/source/blender/blenkernel/particle_private.h b/source/blender/blenkernel/particle_private.h
index 6f80089be29..33277d1caac 100644
--- a/source/blender/blenkernel/particle_private.h
+++ b/source/blender/blenkernel/particle_private.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __PARTICLE_PRIVATE_H__
-#define __PARTICLE_PRIVATE_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -72,5 +71,3 @@ void do_child_modifiers(const ParticleChildModifierContext *modifier_ctx,
#ifdef __cplusplus
}
#endif
-
-#endif /* __PARTICLE_PRIVATE_H__ */
diff --git a/source/blender/blenkernel/tracking_private.h b/source/blender/blenkernel/tracking_private.h
index 955a0b8753e..0965cef0d9b 100644
--- a/source/blender/blenkernel/tracking_private.h
+++ b/source/blender/blenkernel/tracking_private.h
@@ -24,8 +24,7 @@
* by multiple tracking files but which should not be public.
*/
-#ifndef __TRACKING_PRIVATE_H__
-#define __TRACKING_PRIVATE_H__
+#pragma once
#include "BLI_threads.h"
@@ -152,5 +151,3 @@ void tracking_image_accessor_destroy(TrackingImageAccessor *accessor);
#ifdef __cplusplus
}
#endif
-
-#endif /* __TRACKING_PRIVATE_H__ */