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.h2
-rw-r--r--source/blender/blenkernel/BKE_action.h2
-rw-r--r--source/blender/blenkernel/BKE_animsys.h2
-rw-r--r--source/blender/blenkernel/BKE_armature.h20
-rw-r--r--source/blender/blenkernel/BKE_attribute.h8
-rw-r--r--source/blender/blenkernel/BKE_attribute_math.hh2
-rw-r--r--source/blender/blenkernel/BKE_blender_version.h2
-rw-r--r--source/blender/blenkernel/BKE_blendfile.h7
-rw-r--r--source/blender/blenkernel/BKE_bvhutils.h2
-rw-r--r--source/blender/blenkernel/BKE_cloth.h8
-rw-r--r--source/blender/blenkernel/BKE_collection.h3
-rw-r--r--source/blender/blenkernel/BKE_collision.h2
-rw-r--r--source/blender/blenkernel/BKE_constraint.h2
-rw-r--r--source/blender/blenkernel/BKE_curve.h4
-rw-r--r--source/blender/blenkernel/BKE_customdata.h19
-rw-r--r--source/blender/blenkernel/BKE_displist.h10
-rw-r--r--source/blender/blenkernel/BKE_editmesh.h10
-rw-r--r--source/blender/blenkernel/BKE_effect.h2
-rw-r--r--source/blender/blenkernel/BKE_fcurve.h18
-rw-r--r--source/blender/blenkernel/BKE_font.h4
-rw-r--r--source/blender/blenkernel/BKE_geometry_set.hh2
-rw-r--r--source/blender/blenkernel/BKE_global.h2
-rw-r--r--source/blender/blenkernel/BKE_gpencil.h4
-rw-r--r--source/blender/blenkernel/BKE_gpencil_geom.h2
-rw-r--r--source/blender/blenkernel/BKE_idprop.h2
-rw-r--r--source/blender/blenkernel/BKE_idtype.h4
-rw-r--r--source/blender/blenkernel/BKE_key.h2
-rw-r--r--source/blender/blenkernel/BKE_layer.h14
-rw-r--r--source/blender/blenkernel/BKE_lib_id.h3
-rw-r--r--source/blender/blenkernel/BKE_lib_override.h7
-rw-r--r--source/blender/blenkernel/BKE_mesh.h9
-rw-r--r--source/blender/blenkernel/BKE_mesh_remap.h2
-rw-r--r--source/blender/blenkernel/BKE_mesh_runtime.h2
-rw-r--r--source/blender/blenkernel/BKE_multires.h2
-rw-r--r--source/blender/blenkernel/BKE_node.h5
-rw-r--r--source/blender/blenkernel/BKE_object.h23
-rw-r--r--source/blender/blenkernel/BKE_particle.h4
-rw-r--r--source/blender/blenkernel/BKE_pbvh.h2
-rw-r--r--source/blender/blenkernel/BKE_screen.h4
-rw-r--r--source/blender/blenkernel/BKE_shader_fx.h2
-rw-r--r--source/blender/blenkernel/BKE_spline.hh8
-rw-r--r--source/blender/blenkernel/BKE_subsurf.h2
-rw-r--r--source/blender/blenkernel/BKE_text.h8
-rw-r--r--source/blender/blenkernel/BKE_tracking.h2
-rw-r--r--source/blender/blenkernel/BKE_undo_system.h2
-rw-r--r--source/blender/blenkernel/CMakeLists.txt4
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.cc26
-rw-r--r--source/blender/blenkernel/intern/action.c7
-rw-r--r--source/blender/blenkernel/intern/action_mirror.c2
-rw-r--r--source/blender/blenkernel/intern/anim_data.c4
-rw-r--r--source/blender/blenkernel/intern/anim_path.c2
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c6
-rw-r--r--source/blender/blenkernel/intern/appdir.c2
-rw-r--r--source/blender/blenkernel/intern/armature.c14
-rw-r--r--source/blender/blenkernel/intern/armature_test.cc2
-rw-r--r--source/blender/blenkernel/intern/armature_update.c2
-rw-r--r--source/blender/blenkernel/intern/attribute_access.cc2
-rw-r--r--source/blender/blenkernel/intern/blender_copybuffer.c6
-rw-r--r--source/blender/blenkernel/intern/blender_undo.c7
-rw-r--r--source/blender/blenkernel/intern/blendfile.c35
-rw-r--r--source/blender/blenkernel/intern/bvhutils.cc (renamed from source/blender/blenkernel/intern/bvhutils.c)216
-rw-r--r--source/blender/blenkernel/intern/camera.c4
-rw-r--r--source/blender/blenkernel/intern/collection.c13
-rw-r--r--source/blender/blenkernel/intern/colorband.c2
-rw-r--r--source/blender/blenkernel/intern/colortools.c8
-rw-r--r--source/blender/blenkernel/intern/constraint.c163
-rw-r--r--source/blender/blenkernel/intern/context.c7
-rw-r--r--source/blender/blenkernel/intern/curve.c40
-rw-r--r--source/blender/blenkernel/intern/curve_bevel.c2
-rw-r--r--source/blender/blenkernel/intern/curve_decimate.c4
-rw-r--r--source/blender/blenkernel/intern/curve_eval.cc10
-rw-r--r--source/blender/blenkernel/intern/customdata.c24
-rw-r--r--source/blender/blenkernel/intern/customdata_file.c4
-rw-r--r--source/blender/blenkernel/intern/data_transfer.c4
-rw-r--r--source/blender/blenkernel/intern/displist.cc217
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c4
-rw-r--r--source/blender/blenkernel/intern/editmesh.c2
-rw-r--r--source/blender/blenkernel/intern/effect.c8
-rw-r--r--source/blender/blenkernel/intern/fcurve.c23
-rw-r--r--source/blender/blenkernel/intern/fluid.c4
-rw-r--r--source/blender/blenkernel/intern/fmodifier.c2
-rw-r--r--source/blender/blenkernel/intern/font.c10
-rw-r--r--source/blender/blenkernel/intern/geometry_component_mesh.cc2
-rw-r--r--source/blender/blenkernel/intern/geometry_set.cc14
-rw-r--r--source/blender/blenkernel/intern/geometry_set_instances.cc6
-rw-r--r--source/blender/blenkernel/intern/gpencil.c79
-rw-r--r--source/blender/blenkernel/intern/gpencil_curve.c6
-rw-r--r--source/blender/blenkernel/intern/gpencil_geom.c118
-rw-r--r--source/blender/blenkernel/intern/idprop.c40
-rw-r--r--source/blender/blenkernel/intern/image.c12
-rw-r--r--source/blender/blenkernel/intern/image_save.c2
-rw-r--r--source/blender/blenkernel/intern/ipo.c20
-rw-r--r--source/blender/blenkernel/intern/key.c12
-rw-r--r--source/blender/blenkernel/intern/keyconfig.c2
-rw-r--r--source/blender/blenkernel/intern/lattice_deform.c6
-rw-r--r--source/blender/blenkernel/intern/layer.c20
-rw-r--r--source/blender/blenkernel/intern/layer_utils.c12
-rw-r--r--source/blender/blenkernel/intern/lib_id.c4
-rw-r--r--source/blender/blenkernel/intern/lib_id_eval.c48
-rw-r--r--source/blender/blenkernel/intern/lib_override.c121
-rw-r--r--source/blender/blenkernel/intern/lib_query.c2
-rw-r--r--source/blender/blenkernel/intern/mask.c2
-rw-r--r--source/blender/blenkernel/intern/mball.c2
-rw-r--r--source/blender/blenkernel/intern/mball_tessellate.c31
-rw-r--r--source/blender/blenkernel/intern/mesh.c25
-rw-r--r--source/blender/blenkernel/intern/mesh_boolean_convert.cc4
-rw-r--r--source/blender/blenkernel/intern/mesh_convert.c34
-rw-r--r--source/blender/blenkernel/intern/mesh_evaluate.c2114
-rw-r--r--source/blender/blenkernel/intern/mesh_mapping.c2
-rw-r--r--source/blender/blenkernel/intern/mesh_merge.c16
-rw-r--r--source/blender/blenkernel/intern/mesh_mirror.c6
-rw-r--r--source/blender/blenkernel/intern/mesh_normals.c2144
-rw-r--r--source/blender/blenkernel/intern/mesh_runtime.c10
-rw-r--r--source/blender/blenkernel/intern/mesh_validate.c4
-rw-r--r--source/blender/blenkernel/intern/movieclip.c6
-rw-r--r--source/blender/blenkernel/intern/multires.c6
-rw-r--r--source/blender/blenkernel/intern/multires_reshape.c2
-rw-r--r--source/blender/blenkernel/intern/multires_reshape_smooth.c6
-rw-r--r--source/blender/blenkernel/intern/multires_unsubdivide.c2
-rw-r--r--source/blender/blenkernel/intern/nla.c4
-rw-r--r--source/blender/blenkernel/intern/node.cc11
-rw-r--r--source/blender/blenkernel/intern/object.c17
-rw-r--r--source/blender/blenkernel/intern/object_dupli.cc14
-rw-r--r--source/blender/blenkernel/intern/object_update.c2
-rw-r--r--source/blender/blenkernel/intern/ocean.c16
-rw-r--r--source/blender/blenkernel/intern/ocean_intern.h2
-rw-r--r--source/blender/blenkernel/intern/ocean_spectrum.c2
-rw-r--r--source/blender/blenkernel/intern/paint.c2
-rw-r--r--source/blender/blenkernel/intern/particle.c2
-rw-r--r--source/blender/blenkernel/intern/particle_child.c2
-rw-r--r--source/blender/blenkernel/intern/particle_distribute.c2
-rw-r--r--source/blender/blenkernel/intern/particle_system.c26
-rw-r--r--source/blender/blenkernel/intern/pbvh.c2
-rw-r--r--source/blender/blenkernel/intern/pbvh_bmesh.c4
-rw-r--r--source/blender/blenkernel/intern/pointcache.c26
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c6
-rw-r--r--source/blender/blenkernel/intern/scene.c7
-rw-r--r--source/blender/blenkernel/intern/screen.c4
-rw-r--r--source/blender/blenkernel/intern/shader_fx.c4
-rw-r--r--source/blender/blenkernel/intern/shrinkwrap.c2
-rw-r--r--source/blender/blenkernel/intern/softbody.c184
-rw-r--r--source/blender/blenkernel/intern/spline_nurbs.cc2
-rw-r--r--source/blender/blenkernel/intern/subdiv_ccg.c6
-rw-r--r--source/blender/blenkernel/intern/subdiv_eval.c2
-rw-r--r--source/blender/blenkernel/intern/subdiv_foreach.c2
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c32
-rw-r--r--source/blender/blenkernel/intern/text.c6
-rw-r--r--source/blender/blenkernel/intern/tracking_stabilize.c2
-rw-r--r--source/blender/blenkernel/intern/undo_system.c4
-rw-r--r--source/blender/blenkernel/intern/unit.c6
-rw-r--r--source/blender/blenkernel/intern/volume.cc2
-rw-r--r--source/blender/blenkernel/intern/workspace.c4
-rw-r--r--source/blender/blenkernel/nla_private.h10
153 files changed, 3475 insertions, 3026 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 7d553b68185..684296381eb 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -329,7 +329,7 @@ void DM_copy_vert_data(struct DerivedMesh *source,
int dest_index,
int count);
-/*sets up mpolys for a DM based on face iterators in source*/
+/* Sets up mpolys for a DM based on face iterators in source. */
void DM_DupPolys(DerivedMesh *source, DerivedMesh *target);
void DM_ensure_normals(DerivedMesh *dm);
diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h
index 3d81fcba37d..9f69c5e3976 100644
--- a/source/blender/blenkernel/BKE_action.h
+++ b/source/blender/blenkernel/BKE_action.h
@@ -108,7 +108,7 @@ void action_group_colors_sync(struct bActionGroup *grp, const struct bActionGrou
/* Add a new action group with the given name to the action */
struct bActionGroup *action_groups_add_new(struct bAction *act, const char name[]);
-/* Add given channel into (active) group */
+/* Add given channel into (active) group */
void action_groups_add_channel(struct bAction *act,
struct bActionGroup *agrp,
struct FCurve *fcurve);
diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index d43332ae1ac..030560015a9 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -242,7 +242,7 @@ bool BKE_animsys_rna_path_resolve(struct PointerRNA *ptr,
bool BKE_animsys_read_from_rna_path(struct PathResolvedRNA *anim_rna, float *r_value);
bool BKE_animsys_write_to_rna_path(struct PathResolvedRNA *anim_rna, const float value);
-/* Evaluation loop for evaluating animation data */
+/* Evaluation loop for evaluating animation data. */
void BKE_animsys_evaluate_animdata(struct ID *id,
struct AnimData *adt,
const struct AnimationEvalContext *anim_eval_context,
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h
index 112b8bf3ad4..86aa18e5739 100644
--- a/source/blender/blenkernel/BKE_armature.h
+++ b/source/blender/blenkernel/BKE_armature.h
@@ -49,24 +49,30 @@ typedef struct EditBone {
struct EditBone *next, *prev;
/** User-Defined Properties on this Bone */
struct IDProperty *prop;
- /** Editbones have a one-way link (i.e. children refer
+ /**
+ * Editbones have a one-way link (i.e. children refer
* to parents. This is converted to a two-way link for
- * normal bones when leaving editmode. */
+ * normal bones when leaving editmode.
+ */
struct EditBone *parent;
/** (64 == MAXBONENAME) */
char name[64];
- /** Roll along axis. We'll ultimately use the axis/angle method
+ /**
+ * Roll along axis. We'll ultimately use the axis/angle method
* for determining the transformation matrix of the bone. The axis
* is tail-head while roll provides the angle. Refer to Graphics
- * Gems 1 p. 466 (section IX.6) if it's not already in here somewhere*/
+ * Gems 1 p. 466 (section IX.6) if it's not already in here somewhere.
+ */
float roll;
/** Orientation and length is implicit during editing */
float head[3];
float tail[3];
- /** All joints are considered to have zero rotation with respect to
+ /**
+ * All joints are considered to have zero rotation with respect to
* their parents. Therefore any rotations specified during the
- * animation are automatically relative to the bones' rest positions*/
+ * animation are automatically relative to the bones' rest positions.
+ */
int flag;
int layer;
char inherit_scale_mode;
@@ -145,7 +151,7 @@ typedef struct PoseTree {
struct bArmature *BKE_armature_add(struct Main *bmain, const char *name);
struct bArmature *BKE_armature_from_object(struct Object *ob);
-int BKE_armature_bonelist_count(struct ListBase *lb);
+int BKE_armature_bonelist_count(const struct ListBase *lb);
void BKE_armature_bonelist_free(struct ListBase *lb, const bool do_id_user);
void BKE_armature_editbonelist_free(struct ListBase *lb, const bool do_id_user);
diff --git a/source/blender/blenkernel/BKE_attribute.h b/source/blender/blenkernel/BKE_attribute.h
index 30a595dba8e..6a1f1feb14f 100644
--- a/source/blender/blenkernel/BKE_attribute.h
+++ b/source/blender/blenkernel/BKE_attribute.h
@@ -38,12 +38,16 @@ struct ID;
struct ReportList;
/* Attribute.domain */
+/**
+ * \warning: Careful when changing existing items. Arrays may be initialized from this (e.g.
+ * #DATASET_layout_hierarchy).
+ */
typedef enum AttributeDomain {
ATTR_DOMAIN_AUTO = -1, /* Use for nodes to choose automatically based on other data. */
ATTR_DOMAIN_POINT = 0, /* Mesh, Hair or PointCloud Point */
ATTR_DOMAIN_EDGE = 1, /* Mesh Edge */
- ATTR_DOMAIN_CORNER = 2, /* Mesh Corner */
- ATTR_DOMAIN_FACE = 3, /* Mesh Face */
+ ATTR_DOMAIN_FACE = 2, /* Mesh Face */
+ ATTR_DOMAIN_CORNER = 3, /* Mesh Corner */
ATTR_DOMAIN_CURVE = 4, /* Hair Curve */
ATTR_DOMAIN_NUM
diff --git a/source/blender/blenkernel/BKE_attribute_math.hh b/source/blender/blenkernel/BKE_attribute_math.hh
index ba683362e69..2ce41e95b65 100644
--- a/source/blender/blenkernel/BKE_attribute_math.hh
+++ b/source/blender/blenkernel/BKE_attribute_math.hh
@@ -306,7 +306,7 @@ template<> struct DefaultMixerStruct<float3> {
};
template<> struct DefaultMixerStruct<ColorGeometry4f> {
/* Use a special mixer for colors. ColorGeometry4f can't be added/multiplied, because this is not
- * something one should usually do with colors. */
+ * something one should usually do with colors. */
using type = ColorGeometryMixer;
};
template<> struct DefaultMixerStruct<int> {
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index 1767077fa45..d5baeb08ccc 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -39,7 +39,7 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
-#define BLENDER_FILE_SUBVERSION 4
+#define BLENDER_FILE_SUBVERSION 7
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and show a warning if the file
diff --git a/source/blender/blenkernel/BKE_blendfile.h b/source/blender/blenkernel/BKE_blendfile.h
index 429e294a337..3e0a343a766 100644
--- a/source/blender/blenkernel/BKE_blendfile.h
+++ b/source/blender/blenkernel/BKE_blendfile.h
@@ -25,6 +25,7 @@ extern "C" {
struct BlendFileData;
struct BlendFileReadParams;
+struct BlendFileReadReport;
struct ID;
struct Main;
struct MemFile;
@@ -35,7 +36,7 @@ struct bContext;
void BKE_blendfile_read_setup_ex(struct bContext *C,
struct BlendFileData *bfd,
const struct BlendFileReadParams *params,
- struct ReportList *reports,
+ struct BlendFileReadReport *reports,
/* Extra args. */
const bool startup_update_defaults,
const char *startup_app_template);
@@ -43,11 +44,11 @@ void BKE_blendfile_read_setup_ex(struct bContext *C,
void BKE_blendfile_read_setup(struct bContext *C,
struct BlendFileData *bfd,
const struct BlendFileReadParams *params,
- struct ReportList *reports);
+ struct BlendFileReadReport *reports);
struct BlendFileData *BKE_blendfile_read(const char *filepath,
const struct BlendFileReadParams *params,
- struct ReportList *reports);
+ struct BlendFileReadReport *reports);
struct BlendFileData *BKE_blendfile_read_from_memory(const void *filebuf,
int filelength,
diff --git a/source/blender/blenkernel/BKE_bvhutils.h b/source/blender/blenkernel/BKE_bvhutils.h
index 78908908343..8be2fcbdb83 100644
--- a/source/blender/blenkernel/BKE_bvhutils.h
+++ b/source/blender/blenkernel/BKE_bvhutils.h
@@ -218,7 +218,7 @@ BVHTree *bvhtree_from_mesh_looptri_ex(struct BVHTreeFromMesh *data,
ThreadMutex *mesh_eval_mutex);
BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
- struct Mesh *mesh,
+ const struct Mesh *mesh,
const BVHCacheType bvh_cache_type,
const int tree_type);
diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h
index 04fcdd6ed6f..a0e3d5dc142 100644
--- a/source/blender/blenkernel/BKE_cloth.h
+++ b/source/blender/blenkernel/BKE_cloth.h
@@ -103,11 +103,11 @@ typedef struct Cloth {
* The definition of a cloth vertex.
*/
typedef struct ClothVertex {
- int flags; /* General flags per vertex. */
- float v[3]; /* The velocity of the point. */
+ int flags; /* General flags per vertex. */
+ float v[3]; /* The velocity of the point. */
float xconst[3]; /* constrained position */
float x[3]; /* The current position of this vertex. */
- float xold[3]; /* The previous position of this vertex.*/
+ float xold[3]; /* The previous position of this vertex. */
float tx[3]; /* temporary position */
float txold[3]; /* temporary old position */
float tv[3]; /* temporary "velocity", mostly used as tv = tx-txold */
@@ -194,7 +194,7 @@ typedef struct ClothSpring {
} \
((void)0)
-/* Spring types as defined in the paper.*/
+/* Spring types as defined in the paper. */
typedef enum {
CLOTH_SPRING_TYPE_STRUCTURAL = (1 << 1),
CLOTH_SPRING_TYPE_SHEAR = (1 << 2),
diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h
index 7963d54126e..f47cdf32ca0 100644
--- a/source/blender/blenkernel/BKE_collection.h
+++ b/source/blender/blenkernel/BKE_collection.h
@@ -164,7 +164,8 @@ bool BKE_collection_move(struct Main *bmain,
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);
+bool BKE_collection_has_collection(const struct Collection *parent,
+ const struct Collection *collection);
void BKE_collection_parent_relations_rebuild(struct Collection *collection);
void BKE_main_collections_parent_relations_rebuild(struct Main *bmain);
diff --git a/source/blender/blenkernel/BKE_collision.h b/source/blender/blenkernel/BKE_collision.h
index ff1bca896b1..2c21b7355d6 100644
--- a/source/blender/blenkernel/BKE_collision.h
+++ b/source/blender/blenkernel/BKE_collision.h
@@ -63,7 +63,7 @@ typedef struct CollPair {
float time; /* collision time, from 0 up to 1 */
/* mesh-mesh collision */
-#ifdef WITH_ELTOPO /*either ap* or bp* can be set, but not both*/
+#ifdef WITH_ELTOPO /* Either ap* or bp* can be set, but not both. */
float bary[3];
int ap1, ap2, ap3, collp, bp1, bp2, bp3;
int collface;
diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h
index afad1e26159..575df93a9fc 100644
--- a/source/blender/blenkernel/BKE_constraint.h
+++ b/source/blender/blenkernel/BKE_constraint.h
@@ -59,7 +59,7 @@ typedef struct bConstraintOb {
/** space matrix for custom object space */
float space_obj_world_matrix[4][4];
- /** type of owner */
+ /** type of owner. */
short type;
/** rotation order for constraint owner (as defined in eEulerRotationOrders in BLI_math.h) */
short rotOrder;
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index 2687a5ea16c..c7c5f59cab2 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -121,6 +121,7 @@ void BKE_curve_material_remap(struct Curve *cu, const unsigned int *remap, unsig
void BKE_curve_smooth_flag_set(struct Curve *cu, const bool use_smooth);
ListBase *BKE_curve_nurbs_get(struct Curve *cu);
+const ListBase *BKE_curve_nurbs_get_for_read(const struct Curve *cu);
int BKE_curve_nurb_vert_index_get(const struct Nurb *nu, const void *vert);
void BKE_curve_nurb_active_set(struct Curve *cu, const struct Nurb *nu);
@@ -153,9 +154,10 @@ void BKE_curve_editNurb_keyIndex_delCV(struct GHash *keyindex, const void *cv);
void BKE_curve_editNurb_keyIndex_free(struct GHash **keyindex);
void BKE_curve_editNurb_free(struct Curve *cu);
struct ListBase *BKE_curve_editNurbs_get(struct Curve *cu);
+const struct ListBase *BKE_curve_editNurbs_get_for_read(const struct Curve *cu);
void BKE_curve_bevelList_free(struct ListBase *bev);
-void BKE_curve_bevelList_make(struct Object *ob, struct ListBase *nurbs, bool for_render);
+void BKE_curve_bevelList_make(struct Object *ob, const struct ListBase *nurbs, bool for_render);
ListBase BKE_curve_bevel_make(const struct Curve *curve);
void BKE_curve_forward_diff_bezier(
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index ed319948160..c4db8ee925e 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -41,7 +41,7 @@ struct CustomData_MeshMasks;
struct ID;
typedef uint64_t CustomDataMask;
-/*a data type large enough to hold 1 element from any customdata layer type*/
+/* A data type large enough to hold 1 element from any custom-data layer type. */
typedef struct {
unsigned char data[64];
} CDBlockBytes;
@@ -109,9 +109,9 @@ bool CustomData_bmesh_has_free(const struct CustomData *data);
*/
bool CustomData_has_referenced(const struct CustomData *data);
-/* copies the "value" (e.g. mloopuv uv or mloopcol colors) from one block to
+/* Copies the "value" (e.g. mloopuv uv or mloopcol colors) from one block to
* another, while not overwriting anything else (e.g. flags). probably only
- * implemented for mloopuv/mloopcol, for now.*/
+ * implemented for mloopuv/mloopcol, for now. */
void CustomData_data_copy_value(int type, const void *source, void *dest);
/* Same as above, but doing advanced mixing.
@@ -121,7 +121,7 @@ void CustomData_data_mix_value(
/* compares if data1 is equal to data2. type is a valid CustomData type
* enum (e.g. CD_MLOOPUV). the layer type's equal function is used to compare
- * the data, if it exists, otherwise memcmp is used.*/
+ * the data, if it exists, otherwise memcmp is used. */
bool CustomData_data_equals(int type, const void *data1, const void *data2);
void CustomData_data_initminmax(int type, void *min, void *max);
void CustomData_data_dominmax(int type, const void *data, void *min, void *max);
@@ -158,7 +158,7 @@ void CustomData_realloc(struct CustomData *data, int totelem);
/* bmesh version of CustomData_merge; merges the layouts of source and dest,
* then goes through the mesh and makes sure all the customdata blocks are
- * consistent with the new layout.*/
+ * consistent with the new layout. */
bool CustomData_bmesh_merge(const struct CustomData *source,
struct CustomData *dest,
CustomDataMask mask,
@@ -186,7 +186,7 @@ void CustomData_free_temporary(struct CustomData *data, int totelem);
*/
void *CustomData_add_layer(
struct CustomData *data, int type, eCDAllocType alloctype, void *layer, int totelem);
-/*same as above but accepts a name */
+/* Same as above but accepts a name. */
void *CustomData_add_layer_named(struct CustomData *data,
int type,
eCDAllocType alloctype,
@@ -233,6 +233,9 @@ void *CustomData_duplicate_referenced_layer_named(struct CustomData *data,
const int totelem);
bool CustomData_is_referenced_layer(struct CustomData *data, int type);
+/* Duplicate all the layers with flag NOFREE, and remove the flag from duplicated layers. */
+void CustomData_duplicate_referenced_layers(CustomData *data, int totelem);
+
/* set the CD_FLAG_NOCOPY flag in custom data layers where the mask is
* zero for the layer type, so only layer types specified by the mask
* will be copied
@@ -443,7 +446,7 @@ void CustomData_validate_layer_name(const struct CustomData *data,
* only after this test passes, layer->data should be assigned */
bool CustomData_verify_versions(struct CustomData *data, int index);
-/*BMesh specific customdata stuff*/
+/* BMesh specific custom-data stuff. */
void CustomData_to_bmeshpoly(struct CustomData *fdata, struct CustomData *ldata, int totloop);
void CustomData_from_bmeshpoly(struct CustomData *fdata, struct CustomData *ldata, int total);
void CustomData_bmesh_update_active_layers(struct CustomData *fdata, struct CustomData *ldata);
@@ -536,7 +539,7 @@ enum {
CDT_MIX_ADD = 17,
CDT_MIX_SUB = 18,
CDT_MIX_MUL = 19,
- /* etc. etc. */
+ /* Etc. */
};
typedef struct CustomDataTransferLayerMap {
diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h
index a2d9bbcd011..0f37ba6c4ce 100644
--- a/source/blender/blenkernel/BKE_displist.h
+++ b/source/blender/blenkernel/BKE_displist.h
@@ -32,11 +32,11 @@ extern "C" {
/** #DispList.type */
enum {
- /** A closed polygon (that can be filled). */
+ /** A closed polygon (that can be filled). */
DL_POLY = 0,
- /** An open polygon. */
+ /** An open polygon. */
DL_SEGM = 1,
- /** A grid surface that respects #DL_CYCL_U & #DL_CYCL_V. */
+ /** A grid surface that respects #DL_CYCL_U & #DL_CYCL_V. */
DL_SURF = 2,
/** Triangles. */
DL_INDEX3 = 4,
@@ -87,13 +87,11 @@ bool BKE_displist_has_faces(const struct ListBase *lb);
void BKE_displist_make_curveTypes(struct Depsgraph *depsgraph,
const struct Scene *scene,
struct Object *ob,
- const bool for_render,
- const bool for_orco);
+ const bool for_render);
void BKE_displist_make_curveTypes_forRender(struct Depsgraph *depsgraph,
const struct Scene *scene,
struct Object *ob,
struct ListBase *dispbase,
- const bool for_orco,
struct Mesh **r_final);
void BKE_displist_make_mball(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob);
void BKE_displist_make_mball_forRender(struct Depsgraph *depsgraph,
diff --git a/source/blender/blenkernel/BKE_editmesh.h b/source/blender/blenkernel/BKE_editmesh.h
index 075a9bc0eac..e31a0a16408 100644
--- a/source/blender/blenkernel/BKE_editmesh.h
+++ b/source/blender/blenkernel/BKE_editmesh.h
@@ -53,12 +53,12 @@ struct Scene;
typedef struct BMEditMesh {
struct BMesh *bm;
- /*this is for undoing failed operations*/
+ /* This is for undoing failed operations. */
struct BMEditMesh *emcopy;
int emcopyusers;
/* we store tessellations as triplets of three loops,
- * which each define a triangle.*/
+ * which each define a triangle. */
struct BMLoop *(*looptris)[3];
int tottri;
@@ -67,14 +67,14 @@ typedef struct BMEditMesh {
/** Cached cage bounding box for selection. */
struct BoundBox *bb_cage;
- /*derivedmesh stuff*/
+ /** Evaluated mesh data-mask. */
CustomData_MeshMasks lastDataMask;
- /*selection mode*/
+ /* Selection mode. */
short selectmode;
short mat_nr;
- /*temp variables for x-mirror editing*/
+ /* Temp variables for x-mirror editing. */
int mirror_cdlayer; /* -1 is invalid */
/**
diff --git a/source/blender/blenkernel/BKE_effect.h b/source/blender/blenkernel/BKE_effect.h
index 231a4563630..3a964ddb1aa 100644
--- a/source/blender/blenkernel/BKE_effect.h
+++ b/source/blender/blenkernel/BKE_effect.h
@@ -179,7 +179,7 @@ unsigned int BKE_sim_debug_data_hash(int i);
unsigned int BKE_sim_debug_data_hash_combine(unsigned int kx, unsigned int ky);
/* _VA_SIM_DEBUG_HASH#(i, ...): combined hash value of multiple integers */
-/* internal helpers*/
+/* Internal helpers. */
#define _VA_SIM_DEBUG_HASH1(a) (BKE_sim_debug_data_hash(a))
#define _VA_SIM_DEBUG_HASH2(a, b) \
(BKE_sim_debug_data_hash_combine(BKE_sim_debug_data_hash(a), _VA_SIM_DEBUG_HASH1(b)))
diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h
index 589d1839dd4..f494c2e30cc 100644
--- a/source/blender/blenkernel/BKE_fcurve.h
+++ b/source/blender/blenkernel/BKE_fcurve.h
@@ -180,7 +180,7 @@ int BKE_fcm_envelope_find_index(struct FCM_EnvelopeData *array,
* but should become userpref */
#define BEZT_BINARYSEARCH_THRESH 0.01f /* was 0.00001, but giving errors */
-/* -------- Data Management -------- */
+/* -------- Data Management -------- */
struct FCurve *BKE_fcurve_create(void);
void BKE_fcurve_free(struct FCurve *fcu);
struct FCurve *BKE_fcurve_copy(const struct FCurve *fcu);
@@ -227,9 +227,9 @@ struct FCurve *BKE_fcurve_find_by_rna_context_ui(struct bContext *C,
/* Binary search algorithm for finding where to 'insert' BezTriple with given frame number.
* Returns the index to insert at (data already at that index will be offset if replace is 0)
*/
-int BKE_fcurve_bezt_binarysearch_index(struct BezTriple array[],
- float frame,
- int arraylen,
+int BKE_fcurve_bezt_binarysearch_index(const struct BezTriple array[],
+ const float frame,
+ const int arraylen,
bool *r_replace);
/* fcurve_cache.c */
@@ -302,7 +302,7 @@ bool BKE_fcurve_bezt_subdivide_handles(struct BezTriple *bezt,
struct BezTriple *next,
float *r_pdelta);
-/* -------- Curve Sanity -------- */
+/* -------- Curve Sanity -------- */
void calchandles_fcurve(struct FCurve *fcu);
void calchandles_fcurve_ex(struct FCurve *fcu, eBezTriple_Flag handle_sel_flag);
@@ -312,7 +312,7 @@ bool test_time_fcurve(struct FCurve *fcu);
void BKE_fcurve_correct_bezpart(const float v1[2], float v2[2], float v3[2], const float v4[2]);
-/* -------- Evaluation -------- */
+/* -------- Evaluation -------- */
/* evaluate fcurve */
float evaluate_fcurve(struct FCurve *fcu, float evaltime);
@@ -329,7 +329,7 @@ float calculate_fcurve(struct PathResolvedRNA *anim_rna,
/* ************* F-Curve Samples API ******************** */
-/* -------- Defines -------- */
+/* -------- Defines -------- */
/* Basic signature for F-Curve sample-creation function
* - fcu: the F-Curve being operated on
@@ -337,12 +337,12 @@ float calculate_fcurve(struct PathResolvedRNA *anim_rna,
*/
typedef float (*FcuSampleFunc)(struct FCurve *fcu, void *data, float evaltime);
-/* ----- Sampling Callbacks ------ */
+/* ----- Sampling Callbacks ------ */
/* Basic sampling callback which acts as a wrapper for evaluate_fcurve() */
float fcurve_samplingcb_evalcurve(struct FCurve *fcu, void *data, float evaltime);
-/* -------- Main Methods -------- */
+/* -------- Main Methods -------- */
/* Main API function for creating a set of sampled curve data, given some callback function
* used to retrieve the values to store.
diff --git a/source/blender/blenkernel/BKE_font.h b/source/blender/blenkernel/BKE_font.h
index b23ccbe25ff..522d3843bb2 100644
--- a/source/blender/blenkernel/BKE_font.h
+++ b/source/blender/blenkernel/BKE_font.h
@@ -66,8 +66,8 @@ typedef struct EditFont {
} EditFont;
-bool BKE_vfont_is_builtin(struct VFont *vfont);
-void BKE_vfont_builtin_register(void *mem, int size);
+bool BKE_vfont_is_builtin(const struct VFont *vfont);
+void BKE_vfont_builtin_register(const void *mem, int size);
void BKE_vfont_free_data(struct VFont *vfont);
struct VFont *BKE_vfont_builtin_get(void);
diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh
index b2342a5fd96..82c9a31dfce 100644
--- a/source/blender/blenkernel/BKE_geometry_set.hh
+++ b/source/blender/blenkernel/BKE_geometry_set.hh
@@ -280,8 +280,6 @@ struct GeometrySet {
void compute_boundbox_without_instances(blender::float3 *r_min, blender::float3 *r_max) const;
friend std::ostream &operator<<(std::ostream &stream, const GeometrySet &geometry_set);
- friend bool operator==(const GeometrySet &a, const GeometrySet &b);
- uint64_t hash() const;
void clear();
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h
index 74f2bf7c6ad..69c950a86dc 100644
--- a/source/blender/blenkernel/BKE_global.h
+++ b/source/blender/blenkernel/BKE_global.h
@@ -149,7 +149,7 @@ enum {
G_DEBUG_DEPSGRAPH_TIME | G_DEBUG_DEPSGRAPH_UUID),
G_DEBUG_SIMDATA = (1 << 15), /* sim debug data display */
G_DEBUG_GPU = (1 << 16), /* gpu debug */
- G_DEBUG_IO = (1 << 17), /* IO Debugging (for Collada, ...)*/
+ G_DEBUG_IO = (1 << 17), /* IO Debugging (for Collada, ...). */
G_DEBUG_GPU_FORCE_WORKAROUNDS = (1 << 18), /* force gpu workarounds bypassing detections. */
G_DEBUG_XR = (1 << 19), /* XR/OpenXR messages */
G_DEBUG_XR_TIME = (1 << 20), /* XR/OpenXR timing messages */
diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h
index d0a1f102a43..657e66729e1 100644
--- a/source/blender/blenkernel/BKE_gpencil.h
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -214,6 +214,10 @@ void BKE_gpencil_layer_mask_remove_ref(struct bGPdata *gpd, const char *name);
struct bGPDlayer_Mask *BKE_gpencil_layer_mask_named_get(struct bGPDlayer *gpl, const char *name);
void BKE_gpencil_layer_mask_sort(struct bGPdata *gpd, struct bGPDlayer *gpl);
void BKE_gpencil_layer_mask_sort_all(struct bGPdata *gpd);
+void BKE_gpencil_layer_mask_copy(const struct bGPDlayer *gpl_src, struct bGPDlayer *gpl_dst);
+void BKE_gpencil_layer_mask_cleanup(struct bGPdata *gpd, struct bGPDlayer *gpl);
+void BKE_gpencil_layer_mask_cleanup_all_layers(struct bGPdata *gpd);
+
void BKE_gpencil_layer_frames_sort(struct bGPDlayer *gpl, bool *r_has_duplicate_frames);
struct bGPDlayer *BKE_gpencil_layer_get_by_name(struct bGPdata *gpd,
diff --git a/source/blender/blenkernel/BKE_gpencil_geom.h b/source/blender/blenkernel/BKE_gpencil_geom.h
index 8fc3ce133a0..c1ccae7a437 100644
--- a/source/blender/blenkernel/BKE_gpencil_geom.h
+++ b/source/blender/blenkernel/BKE_gpencil_geom.h
@@ -90,7 +90,7 @@ typedef struct GPencilPointCoordinates {
float pressure;
} GPencilPointCoordinates;
-int BKE_gpencil_stroke_point_count(struct bGPdata *gpd);
+int BKE_gpencil_stroke_point_count(const 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,
diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h
index bcf35bf1197..a5cb6489194 100644
--- a/source/blender/blenkernel/BKE_idprop.h
+++ b/source/blender/blenkernel/BKE_idprop.h
@@ -67,7 +67,7 @@ void IDP_AppendArray(struct IDProperty *prop, struct IDProperty *item);
void IDP_ResizeIDPArray(struct IDProperty *prop, int len);
/* ----------- Numeric Array Type ----------- */
-/*this function works for strings too!*/
+/* This function works for strings too! */
void IDP_ResizeArray(struct IDProperty *prop, int newlen);
void IDP_FreeArray(struct IDProperty *prop);
diff --git a/source/blender/blenkernel/BKE_idtype.h b/source/blender/blenkernel/BKE_idtype.h
index 4578f1c3ca5..28171b2b363 100644
--- a/source/blender/blenkernel/BKE_idtype.h
+++ b/source/blender/blenkernel/BKE_idtype.h
@@ -82,8 +82,8 @@ 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. */
+ /** Indicates to the callback 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,
diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h
index c969ce07d74..58b8d19abaa 100644
--- a/source/blender/blenkernel/BKE_key.h
+++ b/source/blender/blenkernel/BKE_key.h
@@ -76,7 +76,7 @@ void BKE_keyblock_update_from_lattice(struct Lattice *lt, struct KeyBlock *kb);
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);
+int BKE_keyblock_curve_element_count(const struct ListBase *nurb);
void BKE_keyblock_curve_data_transform(const struct ListBase *nurb,
const float mat[4][4],
const void *src,
diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
index 240d6cb18ec..404f344919c 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -92,7 +92,7 @@ bool BKE_layer_collection_activate(struct ViewLayer *view_layer, struct LayerCol
struct LayerCollection *BKE_layer_collection_activate_parent(struct ViewLayer *view_layer,
struct LayerCollection *lc);
-int BKE_layer_collection_count(struct ViewLayer *view_layer);
+int BKE_layer_collection_count(const struct ViewLayer *view_layer);
struct LayerCollection *BKE_layer_collection_from_index(struct ViewLayer *view_layer,
const int index);
@@ -107,8 +107,8 @@ void BKE_layer_collection_local_sync_all(const struct Main *bmain);
void BKE_main_collection_sync_remap(const struct Main *bmain);
struct LayerCollection *BKE_layer_collection_first_from_scene_collection(
- struct ViewLayer *view_layer, const struct Collection *collection);
-bool BKE_view_layer_has_collection(struct ViewLayer *view_layer,
+ const struct ViewLayer *view_layer, const struct Collection *collection);
+bool BKE_view_layer_has_collection(const struct ViewLayer *view_layer,
const struct Collection *collection);
bool BKE_scene_has_object(struct Scene *scene, struct Object *ob);
@@ -367,7 +367,7 @@ void BKE_view_layer_visible_bases_iterator_end(BLI_Iterator *iter);
struct ObjectsInViewLayerParams {
uint no_dup_data : 1;
- bool (*filter_fn)(struct Object *ob, void *user_data);
+ bool (*filter_fn)(const struct Object *ob, void *user_data);
void *filter_userdata;
};
@@ -388,7 +388,7 @@ struct ObjectsInModeParams {
int object_mode;
uint no_dup_data : 1;
- bool (*filter_fn)(struct Object *ob, void *user_data);
+ bool (*filter_fn)(const struct Object *ob, void *user_data);
void *filter_userdata;
};
@@ -412,8 +412,8 @@ struct Object **BKE_view_layer_array_from_objects_in_mode_params(
BKE_view_layer_array_from_bases_in_mode_params( \
view_layer, v3d, r_len, &(const struct ObjectsInModeParams)__VA_ARGS__)
-bool BKE_view_layer_filter_edit_mesh_has_uvs(struct Object *ob, void *user_data);
-bool BKE_view_layer_filter_edit_mesh_has_edges(struct Object *ob, void *user_data);
+bool BKE_view_layer_filter_edit_mesh_has_uvs(const struct Object *ob, void *user_data);
+bool BKE_view_layer_filter_edit_mesh_has_edges(const struct Object *ob, void *user_data);
/* Utility macros that wrap common args (add more as needed). */
diff --git a/source/blender/blenkernel/BKE_lib_id.h b/source/blender/blenkernel/BKE_lib_id.h
index e16507bf3cc..fac5dc8c010 100644
--- a/source/blender/blenkernel/BKE_lib_id.h
+++ b/source/blender/blenkernel/BKE_lib_id.h
@@ -315,6 +315,9 @@ void BKE_id_blend_write(struct BlendWriter *writer, struct ID *id);
#define IS_TAGGED(_id) ((_id) && (((ID *)_id)->tag & LIB_TAG_DOIT))
+/* lib_id_eval.c */
+void BKE_id_eval_properties_copy(struct ID *id_cow, struct ID *id);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_lib_override.h b/source/blender/blenkernel/BKE_lib_override.h
index 4dc99e64cf2..27076d908e7 100644
--- a/source/blender/blenkernel/BKE_lib_override.h
+++ b/source/blender/blenkernel/BKE_lib_override.h
@@ -43,6 +43,7 @@ extern "C" {
#endif
struct Collection;
+struct BlendFileReadReport;
struct ID;
struct IDOverrideLibrary;
struct IDOverrideLibraryProperty;
@@ -90,14 +91,16 @@ bool BKE_lib_override_library_resync(struct Main *bmain,
struct Collection *override_resync_residual_storage,
const bool do_hierarchy_enforce,
const bool do_post_process,
- struct ReportList *reports);
+ struct BlendFileReadReport *reports);
void BKE_lib_override_library_main_resync(struct Main *bmain,
struct Scene *scene,
struct ViewLayer *view_layer,
- struct ReportList *reports);
+ struct BlendFileReadReport *reports);
void BKE_lib_override_library_delete(struct Main *bmain, struct ID *id_root);
+void BKE_lib_override_library_make_local(struct ID *id);
+
struct IDOverrideLibraryProperty *BKE_lib_override_library_property_find(
struct IDOverrideLibrary *override, const char *rna_path);
struct IDOverrideLibraryProperty *BKE_lib_override_library_property_get(
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index 8ddfb0c8eb2..8d76a025e87 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -128,7 +128,8 @@ struct Mesh *BKE_mesh_copy_for_eval(struct Mesh *source, bool reference);
/* These functions construct a new Mesh,
* contrary to BKE_mesh_from_nurbs which modifies ob itself. */
struct Mesh *BKE_mesh_new_nomain_from_curve(struct Object *ob);
-struct Mesh *BKE_mesh_new_nomain_from_curve_displist(struct Object *ob, struct ListBase *dispbase);
+struct Mesh *BKE_mesh_new_nomain_from_curve_displist(const struct Object *ob,
+ const struct ListBase *dispbase);
bool BKE_mesh_ensure_facemap_customdata(struct Mesh *me);
bool BKE_mesh_clear_facemap_customdata(struct Mesh *me);
@@ -151,7 +152,7 @@ int BKE_mesh_nurbs_to_mdata(struct Object *ob,
struct MPoly **r_allpoly,
int *r_totloop,
int *r_totpoly);
-int BKE_mesh_nurbs_displist_to_mdata(struct Object *ob,
+int BKE_mesh_nurbs_displist_to_mdata(const struct Object *ob,
const struct ListBase *dispbase,
struct MVert **r_allvert,
int *r_totvert,
@@ -298,7 +299,7 @@ void BKE_mesh_recalc_looptri_with_normals(const struct MLoop *mloop,
struct MLoopTri *mlooptri,
const float (*poly_normals)[3]);
-/* *** mesh_evaluate.c *** */
+/* *** mesh_normals.c *** */
void BKE_mesh_calc_normals_mapping_simple(struct Mesh *me);
void BKE_mesh_calc_normals_mapping(struct MVert *mverts,
@@ -493,6 +494,8 @@ void BKE_mesh_calc_normals_split_ex(struct Mesh *mesh,
void BKE_mesh_set_custom_normals(struct Mesh *mesh, float (*r_custom_loopnors)[3]);
void BKE_mesh_set_custom_normals_from_vertices(struct Mesh *mesh, float (*r_custom_vertnors)[3]);
+/* *** mesh_evaluate.c *** */
+
void BKE_mesh_calc_poly_normal(const struct MPoly *mpoly,
const struct MLoop *loopstart,
const struct MVert *mvarray,
diff --git a/source/blender/blenkernel/BKE_mesh_remap.h b/source/blender/blenkernel/BKE_mesh_remap.h
index d9b6ab3813e..02f8af6443c 100644
--- a/source/blender/blenkernel/BKE_mesh_remap.h
+++ b/source/blender/blenkernel/BKE_mesh_remap.h
@@ -36,7 +36,7 @@ typedef struct MeshPairRemapItem {
int sources_num;
int *indices_src; /* NULL if no source found. */
float *weights_src; /* NULL if no source found, else, always normalized! */
- /* UNUSED (at the moment)*/
+ /* UNUSED (at the moment). */
// float hit_dist; /* FLT_MAX if irrelevant or no source found. */
int island; /* For loops only. */
} MeshPairRemapItem;
diff --git a/source/blender/blenkernel/BKE_mesh_runtime.h b/source/blender/blenkernel/BKE_mesh_runtime.h
index 67c87e96aff..3efbef94081 100644
--- a/source/blender/blenkernel/BKE_mesh_runtime.h
+++ b/source/blender/blenkernel/BKE_mesh_runtime.h
@@ -45,7 +45,7 @@ void BKE_mesh_runtime_reset(struct Mesh *mesh);
void BKE_mesh_runtime_reset_on_copy(struct Mesh *mesh, const int flag);
int BKE_mesh_runtime_looptri_len(const struct Mesh *mesh);
void BKE_mesh_runtime_looptri_recalc(struct Mesh *mesh);
-const struct MLoopTri *BKE_mesh_runtime_looptri_ensure(struct Mesh *mesh);
+const struct MLoopTri *BKE_mesh_runtime_looptri_ensure(const struct Mesh *mesh);
bool BKE_mesh_runtime_ensure_edit_data(struct Mesh *mesh);
bool BKE_mesh_runtime_clear_edit_data(struct Mesh *mesh);
bool BKE_mesh_runtime_reset_edit_data(struct Mesh *mesh);
diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h
index fce25abba7f..11bfc4b2b3a 100644
--- a/source/blender/blenkernel/BKE_multires.h
+++ b/source/blender/blenkernel/BKE_multires.h
@@ -220,7 +220,7 @@ BLI_INLINE void BKE_multires_construct_tangent_matrix(float tangent_matrix[3][3]
/* Versioning. */
/* Convert displacement which is stored for simply-subdivided mesh to a Catmull-Clark
- * subdivided mesh. */
+ * subdivided mesh. */
void multires_do_versions_simple_to_catmull_clark(struct Object *object,
struct MultiresModifierData *mmd);
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index a0f6be6b3e9..3562a3e8d63 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -1439,6 +1439,11 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
#define GEO_NODE_SEPARATE_COMPONENTS 1059
#define GEO_NODE_CURVE_SUBDIVIDE 1060
#define GEO_NODE_RAYCAST 1061
+#define GEO_NODE_CURVE_PRIMITIVE_STAR 1062
+#define GEO_NODE_CURVE_PRIMITIVE_SPIRAL 1063
+#define GEO_NODE_CURVE_PRIMITIVE_QUADRATIC_BEZIER 1064
+#define GEO_NODE_CURVE_PRIMITIVE_BEZIER_SEGMENT 1065
+#define GEO_NODE_CURVE_PRIMITIVE_CIRCLE 1066
/** \} */
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index b0b1657c162..cd66f026828 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -243,7 +243,7 @@ void BKE_object_dimensions_set(struct Object *ob, const float value[3], int axis
void BKE_object_empty_draw_type_set(struct Object *ob, const int value);
void BKE_object_boundbox_flag(struct Object *ob, int flag, const bool set);
-void BKE_object_boundbox_calc_from_mesh(struct Object *ob, struct Mesh *me_eval);
+void BKE_object_boundbox_calc_from_mesh(struct Object *ob, const struct Mesh *me_eval);
void BKE_object_minmax(struct Object *ob, float r_min[3], float r_max[3], const bool use_hidden);
bool BKE_object_minmax_dupli(struct Depsgraph *depsgraph,
struct Scene *scene,
@@ -382,20 +382,19 @@ void BKE_object_data_batch_cache_dirty_tag(struct ID *object_data);
/* this function returns a superset of the scenes selection based on relationships */
typedef enum eObRelationTypes {
- OB_REL_NONE = 0, /* just the selection as is */
- OB_REL_PARENT = (1 << 0), /* immediate parent */
- OB_REL_PARENT_RECURSIVE = (1 << 1), /* parents up to root of selection tree*/
- OB_REL_CHILDREN = (1 << 2), /* immediate children */
- OB_REL_CHILDREN_RECURSIVE = (1 << 3), /* All children */
- OB_REL_MOD_ARMATURE = (1 << 4), /* Armatures related to the selected objects */
- /* OB_REL_SCENE_CAMERA = (1 << 5), */ /* you might want the scene camera too even if unselected?
- */
+ OB_REL_NONE = 0, /* Just the selection as is. */
+ OB_REL_PARENT = (1 << 0), /* Immediate parent. */
+ OB_REL_PARENT_RECURSIVE = (1 << 1), /* Parents up to root of selection tree. */
+ OB_REL_CHILDREN = (1 << 2), /* Immediate children. */
+ OB_REL_CHILDREN_RECURSIVE = (1 << 3), /* All children. */
+ OB_REL_MOD_ARMATURE = (1 << 4), /* Armatures related to the selected objects. */
+ // OB_REL_SCENE_CAMERA = (1 << 5), /* You might want the scene camera too even if unselected? */
} eObRelationTypes;
typedef enum eObjectSet {
- OB_SET_SELECTED, /* Selected Objects */
- OB_SET_VISIBLE, /* Visible Objects */
- OB_SET_ALL, /* All Objects */
+ OB_SET_SELECTED, /* Selected Objects. */
+ OB_SET_VISIBLE, /* Visible Objects. */
+ OB_SET_ALL, /* All Objects. */
} eObjectSet;
struct LinkNode *BKE_object_relational_superset(struct ViewLayer *view_layer,
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index 3913ede9049..e5b547d2557 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -78,7 +78,7 @@ struct Scene;
for (p = 0; p < psys->totpart; p++) \
if ((pa = psys->particles + p)->state.time > 0.0f)
-/* fast but sure way to get the modifier*/
+/* Fast but sure way to get the modifier. */
#define PARTICLE_PSMD \
ParticleSystemModifierData *psmd = sim->psmd ? sim->psmd : psys_get_modifier(sim->ob, sim->psys)
@@ -190,7 +190,7 @@ typedef struct ParticleCollisionElement {
/* pointers to original data */
float *x[3], *v[3];
- /* values interpolated from original data*/
+ /* Values interpolated from original data. */
float x0[3], x1[3], x2[3], p[3];
/* results for found intersection point */
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 0fa44067b16..97e5698d6f9 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -474,7 +474,7 @@ bool BKE_pbvh_node_vert_update_check_any(PBVH *pbvh, PBVHNode *node);
// void BKE_pbvh_node_BB_reset(PBVHNode *node);
// void BKE_pbvh_node_BB_expand(PBVHNode *node, float co[3]);
-bool pbvh_has_mask(PBVH *pbvh);
+bool pbvh_has_mask(const PBVH *pbvh);
void pbvh_show_mask_set(PBVH *pbvh, bool show_mask);
bool pbvh_has_face_sets(PBVH *pbvh);
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h
index 085851ba5e6..fed155626ed 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -62,7 +62,7 @@ struct wmWindow;
struct wmWindowManager;
/* spacetype has everything stored to get an editor working, it gets initialized via
- * ED_spacetypes_init() in editors/space_api/spacetypes.c */
+ * #ED_spacetypes_init() in `editors/space_api/spacetypes.c` */
/* an editor in Blender is a combined ScrArea + SpaceType + SpaceData */
#define BKE_ST_MAXNAME 64
@@ -206,7 +206,7 @@ typedef struct ARegionType {
* performed.
*
* This callback is not called on indirect changes of the current viewport (which could happen
- * when the `v2d->tot is changed and `cur` is adopted accordingly). */
+ * when the `v2d->tot is changed and `cur` is adopted accordingly). */
void (*on_view2d_changed)(const struct bContext *C, struct ARegion *region);
/* custom drawing callbacks */
diff --git a/source/blender/blenkernel/BKE_shader_fx.h b/source/blender/blenkernel/BKE_shader_fx.h
index 7e3783a3ee9..8d1fe709355 100644
--- a/source/blender/blenkernel/BKE_shader_fx.h
+++ b/source/blender/blenkernel/BKE_shader_fx.h
@@ -172,7 +172,7 @@ void BKE_shaderfx_copydata_ex(struct ShaderFxData *fx,
void BKE_shaderfx_copy(struct ListBase *dst, const struct ListBase *src);
void BKE_shaderfx_foreach_ID_link(struct Object *ob, ShaderFxIDWalkFunc walk, void *userData);
-bool BKE_shaderfx_has_gpencil(struct Object *ob);
+bool BKE_shaderfx_has_gpencil(const struct Object *ob);
void BKE_shaderfx_blend_write(struct BlendWriter *writer, struct ListBase *fxbase);
void BKE_shaderfx_blend_read_data(struct BlendDataReader *reader, struct ListBase *lb);
diff --git a/source/blender/blenkernel/BKE_spline.hh b/source/blender/blenkernel/BKE_spline.hh
index 24b5a78e598..1aac2e311e3 100644
--- a/source/blender/blenkernel/BKE_spline.hh
+++ b/source/blender/blenkernel/BKE_spline.hh
@@ -32,6 +32,7 @@
#include "BKE_attribute_math.hh"
struct Curve;
+struct ListBase;
class Spline;
using SplinePtr = std::unique_ptr<Spline>;
@@ -328,7 +329,8 @@ class BezierSpline final : public Spline {
};
InterpolationData interpolation_data_from_index_factor(const float index_factor) const;
- virtual blender::fn::GVArrayPtr interpolate_to_evaluated(const blender::fn::GVArray &src) const;
+ virtual blender::fn::GVArrayPtr interpolate_to_evaluated(
+ const blender::fn::GVArray &src) const override;
void evaluate_segment(const int index,
const int next_index,
@@ -545,4 +547,6 @@ struct CurveEval {
void assert_valid_point_attributes() const;
};
-std::unique_ptr<CurveEval> curve_eval_from_dna_curve(const Curve &curve);
+std::unique_ptr<CurveEval> curve_eval_from_dna_curve(const Curve &curve,
+ const ListBase &nurbs_list);
+std::unique_ptr<CurveEval> curve_eval_from_dna_curve(const Curve &dna_curve);
diff --git a/source/blender/blenkernel/BKE_subsurf.h b/source/blender/blenkernel/BKE_subsurf.h
index 07bbeafb1ae..3816a822279 100644
--- a/source/blender/blenkernel/BKE_subsurf.h
+++ b/source/blender/blenkernel/BKE_subsurf.h
@@ -25,7 +25,7 @@
/* struct DerivedMesh is used directly */
#include "BKE_DerivedMesh.h"
-/* Thread sync primitives used directly. */
+/* Thread sync primitives used directly. */
#include "BLI_threads.h"
#ifdef __cplusplus
diff --git a/source/blender/blenkernel/BKE_text.h b/source/blender/blenkernel/BKE_text.h
index c60d5c7bfec..c7120c60020 100644
--- a/source/blender/blenkernel/BKE_text.h
+++ b/source/blender/blenkernel/BKE_text.h
@@ -48,7 +48,7 @@ char *txt_to_buf(struct Text *text, int *r_buf_strlen);
void txt_clean_text(struct Text *text);
void txt_order_cursors(struct Text *text, const bool reverse);
int txt_find_string(struct Text *text, const char *findstr, int wrap, int match_case);
-bool txt_has_sel(struct Text *text);
+bool txt_has_sel(const struct Text *text);
int txt_get_span(struct TextLine *from, struct TextLine *to);
void txt_move_up(struct Text *text, const bool sel);
void txt_move_down(struct Text *text, const bool sel);
@@ -85,13 +85,13 @@ bool txt_uncomment(struct Text *text);
void txt_move_lines(struct Text *text, const int direction);
void txt_duplicate_line(struct Text *text);
int txt_setcurr_tab_spaces(struct Text *text, int space);
-bool txt_cursor_is_line_start(struct Text *text);
-bool txt_cursor_is_line_end(struct Text *text);
+bool txt_cursor_is_line_start(const struct Text *text);
+bool txt_cursor_is_line_end(const struct Text *text);
int txt_calc_tab_left(struct TextLine *tl, int ch);
int txt_calc_tab_right(struct TextLine *tl, int ch);
-/* utility functions, could be moved somewhere more generic but are python/text related */
+/* Utility functions, could be moved somewhere more generic but are python/text related. */
int text_check_bracket(const char ch);
bool text_check_delim(const char ch);
bool text_check_digit(const char ch);
diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h
index c2544c06514..47145a7d6bd 100644
--- a/source/blender/blenkernel/BKE_tracking.h
+++ b/source/blender/blenkernel/BKE_tracking.h
@@ -161,7 +161,7 @@ struct MovieTrackingMarker *BKE_tracking_marker_get_exact(struct MovieTrackingTr
struct MovieTrackingMarker *BKE_tracking_marker_ensure(struct MovieTrackingTrack *track,
int framenr);
-/* Get marker position, possibly interpolating interpolating gap between keyframed/tracked markers.
+/* Get marker position, possibly interpolating gap between key-framed/tracked markers.
*
* The result marker frame number is set to the requested frame number. Its flags are 0 if the
* marker is interpolated, and is set to original marker flag if there were no interpolation
diff --git a/source/blender/blenkernel/BKE_undo_system.h b/source/blender/blenkernel/BKE_undo_system.h
index 620496864f5..efac5d9097f 100644
--- a/source/blender/blenkernel/BKE_undo_system.h
+++ b/source/blender/blenkernel/BKE_undo_system.h
@@ -178,7 +178,7 @@ UndoStack *BKE_undosys_stack_create(void);
void BKE_undosys_stack_destroy(UndoStack *ustack);
void BKE_undosys_stack_clear(UndoStack *ustack);
void BKE_undosys_stack_clear_active(UndoStack *ustack);
-bool BKE_undosys_stack_has_undo(UndoStack *ustack, const char *name);
+bool BKE_undosys_stack_has_undo(const UndoStack *ustack, const char *name);
void BKE_undosys_stack_init_from_main(UndoStack *ustack, struct Main *bmain);
void BKE_undosys_stack_init_from_context(UndoStack *ustack, struct bContext *C);
UndoStep *BKE_undosys_stack_active_with_type(UndoStack *ustack, const UndoType *ut);
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 0f36887b234..7a057d8fc1b 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -93,7 +93,7 @@ set(SRC
intern/boids.c
intern/bpath.c
intern/brush.c
- intern/bvhutils.c
+ intern/bvhutils.cc
intern/cachefile.c
intern/callbacks.c
intern/camera.c
@@ -165,6 +165,7 @@ set(SRC
intern/layer_utils.c
intern/lib_id.c
intern/lib_id_delete.c
+ intern/lib_id_eval.c
intern/lib_override.c
intern/lib_query.c
intern/lib_remap.c
@@ -189,6 +190,7 @@ set(SRC
intern/mesh_mapping.c
intern/mesh_merge.c
intern/mesh_mirror.c
+ intern/mesh_normals.c
intern/mesh_remap.c
intern/mesh_remesh_voxel.c
intern/mesh_runtime.c
diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc
index 6caed3936d4..bc49c086532 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.cc
+++ b/source/blender/blenkernel/intern/DerivedMesh.cc
@@ -960,7 +960,7 @@ static Mesh *modifier_modify_mesh_and_geometry_set(ModifierData *md,
mesh_output = mesh_component.release();
}
- /* Return an empty mesh instead of null. */
+ /* Return an empty mesh instead of null. */
if (mesh_output == nullptr) {
mesh_output = BKE_mesh_new_nomain(0, 0, 0, 0, 0);
BKE_mesh_copy_parameters_for_eval(mesh_output, input_mesh);
@@ -973,7 +973,7 @@ static Mesh *modifier_modify_mesh_and_geometry_set(ModifierData *md,
static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
Scene *scene,
Object *ob,
- int useDeform,
+ const bool use_deform,
const bool need_mapping,
const CustomData_MeshMasks *dataMask,
const int index,
@@ -1068,7 +1068,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
BKE_modifiers_clear_errors(ob);
/* Apply all leading deform modifiers. */
- if (useDeform) {
+ if (use_deform) {
for (; md; md = md->next, md_datamask = md_datamask->next) {
const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md->type);
@@ -1076,10 +1076,6 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
continue;
}
- if (useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) {
- continue;
- }
-
if (mti->type == eModifierTypeType_OnlyDeform && !sculpt_dyntopo) {
if (!deformed_verts) {
deformed_verts = BKE_mesh_vert_coords_alloc(mesh_input, &num_deformed_verts);
@@ -1128,7 +1124,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
continue;
}
- if (mti->type == eModifierTypeType_OnlyDeform && !useDeform) {
+ if (mti->type == eModifierTypeType_OnlyDeform && !use_deform) {
continue;
}
@@ -1173,10 +1169,6 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
continue;
}
- if (useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) {
- continue;
- }
-
/* Add orco mesh as layer if needed by this modifier. */
if (mesh_final && mesh_orco && mti->requiredDataMask) {
CustomData_MeshMasks mask = {0};
@@ -1937,7 +1929,7 @@ static void mesh_build_data(struct Depsgraph *depsgraph,
mesh_calc_modifiers(depsgraph,
scene,
ob,
- 1,
+ true,
need_mapping,
dataMask,
-1,
@@ -2162,7 +2154,7 @@ Mesh *mesh_create_eval_final(Depsgraph *depsgraph,
Mesh *final;
mesh_calc_modifiers(
- depsgraph, scene, ob, 1, false, dataMask, -1, false, false, nullptr, &final, nullptr);
+ depsgraph, scene, ob, true, false, dataMask, -1, false, false, nullptr, &final, nullptr);
return final;
}
@@ -2176,7 +2168,7 @@ Mesh *mesh_create_eval_final_index_render(Depsgraph *depsgraph,
Mesh *final;
mesh_calc_modifiers(
- depsgraph, scene, ob, 1, false, dataMask, index, false, false, nullptr, &final, nullptr);
+ depsgraph, scene, ob, true, false, dataMask, index, false, false, nullptr, &final, nullptr);
return final;
}
@@ -2189,7 +2181,7 @@ Mesh *mesh_create_eval_no_deform(Depsgraph *depsgraph,
Mesh *final;
mesh_calc_modifiers(
- depsgraph, scene, ob, 0, false, dataMask, -1, false, false, nullptr, &final, nullptr);
+ depsgraph, scene, ob, false, false, dataMask, -1, false, false, nullptr, &final, nullptr);
return final;
}
@@ -2202,7 +2194,7 @@ Mesh *mesh_create_eval_no_deform_render(Depsgraph *depsgraph,
Mesh *final;
mesh_calc_modifiers(
- depsgraph, scene, ob, 0, false, dataMask, -1, false, false, nullptr, &final, nullptr);
+ depsgraph, scene, ob, false, false, dataMask, -1, false, false, nullptr, &final, nullptr);
return final;
}
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 71d242e9c79..fdf3558abed 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -370,7 +370,7 @@ void set_active_action_group(bAction *act, bActionGroup *agrp, short select)
/* Sync colors used for action/bone group with theme settings */
void action_group_colors_sync(bActionGroup *grp, const bActionGroup *ref_grp)
{
- /* only do color copying if using a custom color (i.e. not default color) */
+ /* Only do color copying if using a custom color (i.e. not default color). */
if (grp->customCol) {
if (grp->customCol > 0) {
/* copy theme colors on-to group's custom color in case user tries to edit color */
@@ -486,8 +486,7 @@ void action_groups_add_channel(bAction *act, bActionGroup *agrp, FCurve *fcurve)
/* If grp is NULL, that means we fell through, and this F-Curve should be added as the new
* first since group is (effectively) the first group. Thus, the existing first F-Curve becomes
- * the second in the chain, etc. etc.
- */
+ * the second in the chain, etc. */
if (grp == NULL) {
BLI_insertlinkbefore(&act->curves, act->curves.first, fcurve);
}
@@ -1856,7 +1855,7 @@ void BKE_pose_blend_write(BlendWriter *writer, bPose *pose, bArmature *arm)
/* Write channels */
LISTBASE_FOREACH (bPoseChannel *, chan, &pose->chanbase) {
/* Write ID Properties -- and copy this comment EXACTLY for easy finding
- * of library blocks that implement this.*/
+ * of library blocks that implement this. */
if (chan->prop) {
IDP_BlendWrite(writer, chan->prop);
}
diff --git a/source/blender/blenkernel/intern/action_mirror.c b/source/blender/blenkernel/intern/action_mirror.c
index c975d2bfb9c..69e0091444b 100644
--- a/source/blender/blenkernel/intern/action_mirror.c
+++ b/source/blender/blenkernel/intern/action_mirror.c
@@ -343,7 +343,7 @@ static void action_flip_pchan(Object *ob_arm,
} \
((void)0)
- /* Write the values back the the F-curves. */
+ /* Write the values back the F-curves. */
WRITE_ARRAY_FLT(loc);
WRITE_ARRAY_FLT(eul);
WRITE_ARRAY_FLT(quat);
diff --git a/source/blender/blenkernel/intern/anim_data.c b/source/blender/blenkernel/intern/anim_data.c
index 44b760aefc8..2f71dda17f2 100644
--- a/source/blender/blenkernel/intern/anim_data.c
+++ b/source/blender/blenkernel/intern/anim_data.c
@@ -946,7 +946,7 @@ static bool nlastrips_path_rename_fix(ID *owner_id,
is_changed |= fcurves_path_rename_fix(
owner_id, prefix, oldName, newName, oldKey, newKey, &strip->act->curves, verify_paths);
}
- /* Ignore own F-Curves, since those are local. */
+ /* Ignore own F-Curves, since those are local. */
/* Check sub-strips (if meta-strips). */
is_changed |= nlastrips_path_rename_fix(
owner_id, prefix, oldName, newName, oldKey, newKey, &strip->strips, verify_paths);
@@ -1422,7 +1422,7 @@ void BKE_animdata_fix_paths_rename_all(ID *ref_id,
* NOTE: it is assumed that the structure we're replacing is <prefix><["><name><"]>
* i.e. pose.bones["Bone"]
*/
-/* TODO: use BKE_animdata_main_cb for looping over all data */
+/* TODO: use BKE_animdata_main_cb for looping over all data. */
void BKE_animdata_fix_paths_rename_all_ex(Main *bmain,
ID *ref_id,
const char *prefix,
diff --git a/source/blender/blenkernel/intern/anim_path.c b/source/blender/blenkernel/intern/anim_path.c
index af2b386a30a..e2c2708101b 100644
--- a/source/blender/blenkernel/intern/anim_path.c
+++ b/source/blender/blenkernel/intern/anim_path.c
@@ -327,7 +327,7 @@ bool BKE_where_on_path(const Object *ob,
}
const Nurb *nu = nurbs->first;
- /* make sure that first and last frame are included in the vectors here */
+ /* Make sure that first and last frame are included in the vectors here. */
if (ELEM(nu->type, CU_POLY, CU_BEZIER, CU_NURBS)) {
key_curve_position_weights(frac, w, KEY_LINEAR);
}
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index e347306e0ae..08a3f3fcf4f 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -852,7 +852,7 @@ NlaEvalStrip *nlastrips_ctime_get_strip(ListBase *list,
/* loop over strips, checking if they fall within the range */
for (strip = strips->first; strip; strip = strip->next) {
- /* check if current time occurs within this strip */
+ /* Check if current time occurs within this strip. */
if (IN_RANGE_INCL(ctime, strip->start, strip->end) ||
(strip->flag & NLASTRIP_FLAG_NO_TIME_MAP)) {
/* this strip is active, so try to use it */
@@ -1564,7 +1564,7 @@ static bool nla_blend_get_inverted_strip_value(const int blendmode,
}
}
-/** \returns true if solution exists and output is written to. */
+/** \returns true if solution exists and output is written to. */
static bool nla_combine_get_inverted_strip_value(const int mix_mode,
float base_value,
const float lower_value,
@@ -2017,7 +2017,7 @@ static void nlaeval_fmodifiers_join_stacks(ListBase *result, ListBase *list1, Li
{
FModifier *fcm1, *fcm2;
- /* if list1 is invalid... */
+ /* if list1 is invalid... */
if (ELEM(NULL, list1, list1->first)) {
if (list2 && list2->first) {
result->first = list2->first;
diff --git a/source/blender/blenkernel/intern/appdir.c b/source/blender/blenkernel/intern/appdir.c
index bcfd34ab42f..579f671e2b0 100644
--- a/source/blender/blenkernel/intern/appdir.c
+++ b/source/blender/blenkernel/intern/appdir.c
@@ -200,7 +200,7 @@ bool BKE_appdir_folder_documents(char *dir)
return true;
}
- /* Ghost couldn't give us a documents path, let's try if we can find it ourselves.*/
+ /* Ghost couldn't give us a documents path, let's try if we can find it ourselves. */
const char *home_path = BKE_appdir_folder_home();
if (!home_path || !BLI_is_dir(home_path)) {
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index a57e1d6b2dd..d0604f4bfda 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -198,7 +198,7 @@ static void write_bone(BlendWriter *writer, Bone *bone)
BLO_write_struct(writer, Bone, bone);
/* Write ID Properties -- and copy this comment EXACTLY for easy finding
- * of library blocks that implement this.*/
+ * of library blocks that implement this. */
if (bone->prop) {
IDP_BlendWrite(writer, bone->prop);
}
@@ -358,7 +358,7 @@ bArmature *BKE_armature_from_object(Object *ob)
return NULL;
}
-int BKE_armature_bonelist_count(ListBase *lb)
+int BKE_armature_bonelist_count(const ListBase *lb)
{
int i = 0;
LISTBASE_FOREACH (Bone *, bone, lb) {
@@ -1627,7 +1627,7 @@ void BKE_armature_mat_world_to_pose(Object *ob, const float inmat[4][4], float o
return;
}
- /* get inverse of (armature) object's matrix */
+ /* Get inverse of (armature) object's matrix. */
invert_m4_m4(obmat, ob->obmat);
/* multiply given matrix by object's-inverse to find pose-space matrix */
@@ -2063,9 +2063,11 @@ void BKE_armature_mat_pose_to_delta(float delta_mat[4][4],
* Used for Objects and Pose Channels, since both can have multiple rotation representations.
* \{ */
-/* Called from RNA when rotation mode changes
+/**
+ * Called from RNA when rotation mode changes
* - the result should be that the rotations given in the provided pointers have had conversions
- * applied (as appropriate), such that the rotation of the element hasn't 'visually' changed */
+ * applied (as appropriate), such that the rotation of the element hasn't 'visually' changed.
+ */
void BKE_rotMode_change_values(
float quat[4], float eul[3], float axis[3], float *angle, short oldMode, short newMode)
{
@@ -2333,7 +2335,7 @@ void BKE_armature_where_is_bone(Bone *bone, const Bone *bone_parent, const bool
/* yoffs(b-1) + root(b) + bonemat(b) */
BKE_bone_offset_matrix_get(bone, offs_bone);
- /* Compose the matrix for this bone */
+ /* Compose the matrix for this bone. */
mul_m4_m4m4(bone->arm_mat, bone_parent->arm_mat, offs_bone);
}
else {
diff --git a/source/blender/blenkernel/intern/armature_test.cc b/source/blender/blenkernel/intern/armature_test.cc
index 366bbe3e37c..589337d9d01 100644
--- a/source/blender/blenkernel/intern/armature_test.cc
+++ b/source/blender/blenkernel/intern/armature_test.cc
@@ -121,7 +121,7 @@ TEST(vec_roll_to_mat3_normalized, Rotationmatrix)
/* TODO: This test will pass after fixing T82455) */
/* If normalized_vector is close to -Y and
* it has X and Z values above a threshold,
- * apply the special case. */
+ * apply the special case. */
{
const float expected_roll_mat[3][3] = {{0.000000f, -9.99999975e-06f, 1.000000f},
{9.99999975e-06f, -0.999999881f, 9.99999975e-06f},
diff --git a/source/blender/blenkernel/intern/armature_update.c b/source/blender/blenkernel/intern/armature_update.c
index 4504f10967c..0f8956a1a91 100644
--- a/source/blender/blenkernel/intern/armature_update.c
+++ b/source/blender/blenkernel/intern/armature_update.c
@@ -837,7 +837,7 @@ void BKE_pose_eval_init_ik(struct Depsgraph *depsgraph, Scene *scene, Object *ob
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. */
+ * to function in conjunction with standard IK. */
BKE_pose_splineik_init_tree(scene, object, ctime);
}
diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc
index 8bbb3014dac..aa0af294bc3 100644
--- a/source/blender/blenkernel/intern/attribute_access.cc
+++ b/source/blender/blenkernel/intern/attribute_access.cc
@@ -1197,7 +1197,7 @@ static blender::bke::OutputAttribute create_output_attribute(
cpp_type->size() * domain_size, cpp_type->alignment(), __func__);
if (ignore_old_values) {
/* This does nothing for trivially constructible types, but is necessary for correctness. */
- cpp_type->construct_default_n(data, domain);
+ cpp_type->default_construct_n(data, domain);
}
else {
/* Fill the temporary array with values from the existing attribute. */
diff --git a/source/blender/blenkernel/intern/blender_copybuffer.c b/source/blender/blenkernel/intern/blender_copybuffer.c
index dfd49a347ca..9c9f898afef 100644
--- a/source/blender/blenkernel/intern/blender_copybuffer.c
+++ b/source/blender/blenkernel/intern/blender_copybuffer.c
@@ -87,7 +87,8 @@ bool BKE_copybuffer_read(Main *bmain_dst,
ReportList *reports,
const uint64_t id_types_mask)
{
- BlendHandle *bh = BLO_blendhandle_from_file(libname, reports);
+ BlendFileReadReport bf_reports = {.reports = reports};
+ BlendHandle *bh = BLO_blendhandle_from_file(libname, &bf_reports);
if (bh == NULL) {
/* Error reports will have been made by BLO_blendhandle_from_file(). */
return false;
@@ -133,7 +134,8 @@ int BKE_copybuffer_paste(bContext *C,
BlendHandle *bh;
const int id_tag_extra = 0;
- bh = BLO_blendhandle_from_file(libname, reports);
+ BlendFileReadReport bf_reports = {.reports = reports};
+ bh = BLO_blendhandle_from_file(libname, &bf_reports);
if (bh == NULL) {
/* error reports will have been made by BLO_blendhandle_from_file() */
diff --git a/source/blender/blenkernel/intern/blender_undo.c b/source/blender/blenkernel/intern/blender_undo.c
index ba41786c7fd..411ece21599 100644
--- a/source/blender/blenkernel/intern/blender_undo.c
+++ b/source/blender/blenkernel/intern/blender_undo.c
@@ -78,9 +78,10 @@ bool BKE_memfile_undo_decode(MemFileUndoData *mfu,
if (UNDO_DISK) {
const struct BlendFileReadParams params = {0};
- struct BlendFileData *bfd = BKE_blendfile_read(mfu->filename, &params, NULL);
+ BlendFileReadReport bf_reports = {.reports = NULL};
+ struct BlendFileData *bfd = BKE_blendfile_read(mfu->filename, &params, &bf_reports);
if (bfd != NULL) {
- BKE_blendfile_read_setup(C, bfd, &params, NULL);
+ BKE_blendfile_read_setup(C, bfd, &params, &bf_reports);
success = true;
}
}
@@ -93,7 +94,7 @@ bool BKE_memfile_undo_decode(MemFileUndoData *mfu,
struct BlendFileData *bfd = BKE_blendfile_read_from_memfile(
bmain, &mfu->memfile, &params, NULL);
if (bfd != NULL) {
- BKE_blendfile_read_setup(C, bfd, &params, NULL);
+ BKE_blendfile_read_setup(C, bfd, &params, &(BlendFileReadReport){NULL});
success = true;
}
}
diff --git a/source/blender/blenkernel/intern/blendfile.c b/source/blender/blenkernel/intern/blendfile.c
index e335dd4bdcd..f31d8f5ade7 100644
--- a/source/blender/blenkernel/intern/blendfile.c
+++ b/source/blender/blenkernel/intern/blendfile.c
@@ -36,6 +36,8 @@
#include "BLI_system.h"
#include "BLI_utildefines.h"
+#include "PIL_time.h"
+
#include "IMB_colormanagement.h"
#include "BKE_addon.h"
@@ -136,7 +138,7 @@ static void setup_app_userdef(BlendFileData *bfd)
static void setup_app_data(bContext *C,
BlendFileData *bfd,
const struct BlendFileReadParams *params,
- ReportList *reports)
+ BlendFileReadReport *reports)
{
Main *bmain = G_MAIN;
Scene *curscene = NULL;
@@ -155,7 +157,7 @@ static void setup_app_data(bContext *C,
/* may happen with library files - UNDO file should never have NULL curscene (but may have a
* NULL curscreen)... */
else if (ELEM(NULL, bfd->curscreen, bfd->curscene)) {
- BKE_report(reports, RPT_WARNING, "Library file, loading empty scene");
+ BKE_report(reports->reports, RPT_WARNING, "Library file, loading empty scene");
mode = LOAD_UI_OFF;
}
else if (G.fileflags & G_FILE_NO_UI) {
@@ -270,7 +272,7 @@ static void setup_app_data(bContext *C,
/* We need to tag this here because events may be handled immediately after.
* only the current screen is important because we won't have to handle
- * events from multiple screens at once.*/
+ * events from multiple screens at once. */
if (curscreen) {
BKE_screen_gizmo_tag_refresh(curscreen);
}
@@ -396,11 +398,17 @@ static void setup_app_data(bContext *C,
}
if (mode != LOAD_UNDO && !USER_EXPERIMENTAL_TEST(&U, no_override_auto_resync)) {
+ reports->duration.lib_overrides_resync = PIL_check_seconds_timer();
+
BKE_lib_override_library_main_resync(
bmain,
curscene,
bfd->cur_view_layer ? bfd->cur_view_layer : BKE_view_layer_default_view(curscene),
reports);
+
+ reports->duration.lib_overrides_resync = PIL_check_seconds_timer() -
+ reports->duration.lib_overrides_resync;
+
/* We need to rebuild some of the deleted override rules (for UI feedback purpose). */
BKE_lib_override_library_main_operations_create(bmain, true);
}
@@ -409,7 +417,7 @@ static void setup_app_data(bContext *C,
static void setup_app_blend_file_data(bContext *C,
BlendFileData *bfd,
const struct BlendFileReadParams *params,
- ReportList *reports)
+ BlendFileReadReport *reports)
{
if ((params->skip_flags & BLO_READ_SKIP_USERDEF) == 0) {
setup_app_userdef(bfd);
@@ -419,12 +427,12 @@ static void setup_app_blend_file_data(bContext *C,
}
}
-static void handle_subversion_warning(Main *main, ReportList *reports)
+static void handle_subversion_warning(Main *main, BlendFileReadReport *reports)
{
if (main->minversionfile > BLENDER_FILE_VERSION ||
(main->minversionfile == BLENDER_FILE_VERSION &&
main->minsubversionfile > BLENDER_FILE_SUBVERSION)) {
- BKE_reportf(reports,
+ BKE_reportf(reports->reports,
RPT_ERROR,
"File written by newer Blender binary (%d.%d), expect loss of data!",
main->minversionfile,
@@ -443,7 +451,7 @@ static void handle_subversion_warning(Main *main, ReportList *reports)
void BKE_blendfile_read_setup_ex(bContext *C,
BlendFileData *bfd,
const struct BlendFileReadParams *params,
- ReportList *reports,
+ BlendFileReadReport *reports,
/* Extra args. */
const bool startup_update_defaults,
const char *startup_app_template)
@@ -460,7 +468,7 @@ void BKE_blendfile_read_setup_ex(bContext *C,
void BKE_blendfile_read_setup(bContext *C,
BlendFileData *bfd,
const struct BlendFileReadParams *params,
- ReportList *reports)
+ BlendFileReadReport *reports)
{
BKE_blendfile_read_setup_ex(C, bfd, params, reports, false, NULL);
}
@@ -470,7 +478,7 @@ void BKE_blendfile_read_setup(bContext *C,
*/
struct BlendFileData *BKE_blendfile_read(const char *filepath,
const struct BlendFileReadParams *params,
- ReportList *reports)
+ BlendFileReadReport *reports)
{
/* Don't print startup file loading. */
if (params->is_startup == false) {
@@ -482,7 +490,7 @@ struct BlendFileData *BKE_blendfile_read(const char *filepath,
handle_subversion_warning(bfd->main, reports);
}
else {
- BKE_reports_prependf(reports, "Loading '%s' failed: ", filepath);
+ BKE_reports_prependf(reports->reports, "Loading '%s' failed: ", filepath);
}
return bfd;
}
@@ -559,7 +567,9 @@ UserDef *BKE_blendfile_userdef_read(const char *filepath, ReportList *reports)
BlendFileData *bfd;
UserDef *userdef = NULL;
- bfd = BLO_read_from_file(filepath, BLO_READ_SKIP_ALL & ~BLO_READ_SKIP_USERDEF, reports);
+ bfd = BLO_read_from_file(filepath,
+ BLO_READ_SKIP_ALL & ~BLO_READ_SKIP_USERDEF,
+ &(struct BlendFileReadReport){.reports = reports});
if (bfd) {
if (bfd->user) {
userdef = bfd->user;
@@ -770,7 +780,8 @@ WorkspaceConfigFileData *BKE_blendfile_workspace_config_read(const char *filepat
WorkspaceConfigFileData *workspace_config = NULL;
if (filepath) {
- bfd = BLO_read_from_file(filepath, BLO_READ_SKIP_USERDEF, reports);
+ bfd = BLO_read_from_file(
+ filepath, BLO_READ_SKIP_USERDEF, &(struct BlendFileReadReport){.reports = reports});
}
else {
bfd = BLO_read_from_memory(filebuf, filelength, BLO_READ_SKIP_USERDEF, reports);
diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.cc
index 116e6279657..3dea49d1953 100644
--- a/source/blender/blenkernel/intern/bvhutils.c
+++ b/source/blender/blenkernel/intern/bvhutils.cc
@@ -21,9 +21,9 @@
* \ingroup bke
*/
-#include <math.h>
-#include <stdio.h>
-#include <string.h>
+#include <cmath>
+#include <cstdio>
+#include <cstring>
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
@@ -46,15 +46,15 @@
/** \name BVHCache
* \{ */
-typedef struct BVHCacheItem {
+struct BVHCacheItem {
bool is_filled;
BVHTree *tree;
-} BVHCacheItem;
+};
-typedef struct BVHCache {
+struct BVHCache {
BVHCacheItem items[BVHTREE_MAX_ITEM];
ThreadMutex mutex;
-} BVHCache;
+};
/**
* Queries a bvhcache for the cache bvhtree of the request type
@@ -74,14 +74,14 @@ static bool bvhcache_find(BVHCache **bvh_cache_p,
if (r_locked) {
*r_locked = false;
}
- if (*bvh_cache_p == NULL) {
+ if (*bvh_cache_p == nullptr) {
if (!do_lock) {
/* Cache does not exist and no lock is requested. */
return false;
}
/* Lazy initialization of the bvh_cache using the `mesh_eval_mutex`. */
BLI_mutex_lock(mesh_eval_mutex);
- if (*bvh_cache_p == NULL) {
+ if (*bvh_cache_p == nullptr) {
*bvh_cache_p = bvhcache_init();
}
BLI_mutex_unlock(mesh_eval_mutex);
@@ -94,7 +94,7 @@ static bool bvhcache_find(BVHCache **bvh_cache_p,
}
if (do_lock) {
BLI_mutex_lock(&bvh_cache->mutex);
- bool in_cache = bvhcache_find(bvh_cache_p, type, r_tree, NULL, NULL);
+ bool in_cache = bvhcache_find(bvh_cache_p, type, r_tree, nullptr, nullptr);
if (in_cache) {
BLI_mutex_unlock(&bvh_cache->mutex);
return in_cache;
@@ -113,11 +113,11 @@ static void bvhcache_unlock(BVHCache *bvh_cache, bool lock_started)
bool bvhcache_has_tree(const BVHCache *bvh_cache, const BVHTree *tree)
{
- if (bvh_cache == NULL) {
+ if (bvh_cache == nullptr) {
return false;
}
- for (BVHCacheType i = 0; i < BVHTREE_MAX_ITEM; i++) {
+ for (int i = 0; i < BVHTREE_MAX_ITEM; i++) {
if (bvh_cache->items[i].tree == tree) {
return true;
}
@@ -127,7 +127,7 @@ bool bvhcache_has_tree(const BVHCache *bvh_cache, const BVHTree *tree)
BVHCache *bvhcache_init(void)
{
- BVHCache *cache = MEM_callocN(sizeof(BVHCache), __func__);
+ BVHCache *cache = (BVHCache *)MEM_callocN(sizeof(BVHCache), __func__);
BLI_mutex_init(&cache->mutex);
return cache;
}
@@ -137,7 +137,7 @@ BVHCache *bvhcache_init(void)
* as that will be done when the cache is freed.
*
* A call to this assumes that there was no previous cached tree of the given type
- * \warning The #BVHTree can be NULL.
+ * \warning The #BVHTree can be nullptr.
*/
static void bvhcache_insert(BVHCache *bvh_cache, BVHTree *tree, BVHCacheType type)
{
@@ -152,10 +152,10 @@ static void bvhcache_insert(BVHCache *bvh_cache, BVHTree *tree, BVHCacheType typ
*/
void bvhcache_free(BVHCache *bvh_cache)
{
- for (BVHCacheType index = 0; index < BVHTREE_MAX_ITEM; index++) {
+ for (int index = 0; index < BVHTREE_MAX_ITEM; index++) {
BVHCacheItem *item = &bvh_cache->items[index];
BLI_bvhtree_free(item->tree);
- item->tree = NULL;
+ item->tree = nullptr;
}
BLI_mutex_end(&bvh_cache->mutex);
MEM_freeN(bvh_cache);
@@ -197,9 +197,10 @@ float bvhtree_ray_tri_intersection(const BVHTreeRay *ray,
float dist;
#ifdef USE_KDOPBVH_WATERTIGHT
- if (isect_ray_tri_watertight_v3(ray->origin, ray->isect_precalc, v0, v1, v2, &dist, NULL))
+ if (isect_ray_tri_watertight_v3(ray->origin, ray->isect_precalc, v0, v1, v2, &dist, nullptr))
#else
- if (isect_ray_tri_epsilon_v3(ray->origin, ray->direction, v0, v1, v2, &dist, NULL, FLT_EPSILON))
+ if (isect_ray_tri_epsilon_v3(
+ ray->origin, ray->direction, v0, v1, v2, &dist, nullptr, FLT_EPSILON))
#endif
{
return dist;
@@ -247,7 +248,7 @@ static void mesh_faces_nearest_point(void *userdata,
t0 = vert[face->v1].co;
t1 = vert[face->v2].co;
t2 = vert[face->v3].co;
- t3 = face->v4 ? vert[face->v4].co : NULL;
+ t3 = face->v4 ? vert[face->v4].co : nullptr;
do {
float nearest_tmp[3], dist_sq;
@@ -264,7 +265,7 @@ static void mesh_faces_nearest_point(void *userdata,
t1 = t2;
t2 = t3;
- t3 = NULL;
+ t3 = nullptr;
} while (t2);
}
@@ -300,7 +301,7 @@ static void editmesh_looptri_nearest_point(void *userdata,
const float co[3],
BVHTreeNearest *nearest)
{
- const BVHTreeFromEditMesh *data = userdata;
+ const BVHTreeFromEditMesh *data = (const BVHTreeFromEditMesh *)userdata;
BMEditMesh *em = data->em;
const BMLoop **ltri = (const BMLoop **)em->looptris[index];
@@ -339,7 +340,7 @@ static void mesh_faces_spherecast(void *userdata,
t0 = vert[face->v1].co;
t1 = vert[face->v2].co;
t2 = vert[face->v3].co;
- t3 = face->v4 ? vert[face->v4].co : NULL;
+ t3 = face->v4 ? vert[face->v4].co : nullptr;
do {
float dist;
@@ -360,7 +361,7 @@ static void mesh_faces_spherecast(void *userdata,
t1 = t2;
t2 = t3;
- t3 = NULL;
+ t3 = nullptr;
} while (t2);
}
@@ -457,7 +458,7 @@ static void mesh_edges_nearest_point(void *userdata,
}
}
-/* Helper, does all the point-spherecast work actually. */
+/* Helper, does all the point-sphere-cast work actually. */
static void mesh_verts_spherecast_do(int index,
const float v[3],
const BVHTreeRay *ray,
@@ -484,7 +485,7 @@ static void editmesh_verts_spherecast(void *userdata,
const BVHTreeRay *ray,
BVHTreeRayHit *hit)
{
- const BVHTreeFromEditMesh *data = userdata;
+ const BVHTreeFromEditMesh *data = (const BVHTreeFromEditMesh *)userdata;
BMVert *eve = BM_vert_at_index(data->em->bm, index);
mesh_verts_spherecast_do(index, eve->co, ray, hit);
@@ -600,7 +601,7 @@ static BVHTree *bvhtree_from_mesh_verts_create_tree(float epsilon,
const BLI_bitmap *verts_mask,
int verts_num_active)
{
- BVHTree *tree = NULL;
+ BVHTree *tree = nullptr;
if (verts_mask) {
BLI_assert(IN_RANGE_INCL(verts_num_active, 0, verts_num));
@@ -637,9 +638,9 @@ static void bvhtree_from_mesh_verts_setup_data(BVHTreeFromMesh *data,
data->tree = tree;
data->cached = is_cached;
- /* a NULL nearest callback works fine
+ /* a nullptr nearest callback works fine
* remember the min distance to point is the same as the min distance to BV of point */
- data->nearest_callback = NULL;
+ data->nearest_callback = nullptr;
data->raycast_callback = mesh_verts_spherecast;
data->vert = vert;
@@ -658,7 +659,7 @@ BVHTree *bvhtree_from_editmesh_verts_ex(BVHTreeFromEditMesh *data,
BVHCache **bvh_cache_p,
ThreadMutex *mesh_eval_mutex)
{
- BVHTree *tree = NULL;
+ BVHTree *tree = nullptr;
if (bvh_cache_p) {
bool lock_started = false;
@@ -671,7 +672,7 @@ BVHTree *bvhtree_from_editmesh_verts_ex(BVHTreeFromEditMesh *data,
bvhtree_balance(tree, true);
/* Save on cache for later use */
- /* printf("BVHTree built and saved on cache\n"); */
+ // printf("BVHTree built and saved on cache\n");
bvhcache_insert(*bvh_cache_p, tree, bvh_cache_type);
data->cached = true;
}
@@ -687,9 +688,9 @@ BVHTree *bvhtree_from_editmesh_verts_ex(BVHTreeFromEditMesh *data,
memset(data, 0, sizeof(*data));
data->tree = tree;
data->em = em;
- data->nearest_callback = NULL;
+ data->nearest_callback = nullptr;
data->raycast_callback = editmesh_verts_spherecast;
- data->cached = bvh_cache_p != NULL;
+ data->cached = bvh_cache_p != nullptr;
}
return tree;
@@ -699,11 +700,11 @@ BVHTree *bvhtree_from_editmesh_verts(
BVHTreeFromEditMesh *data, BMEditMesh *em, float epsilon, int tree_type, int axis)
{
return bvhtree_from_editmesh_verts_ex(
- data, em, NULL, -1, epsilon, tree_type, axis, 0, NULL, NULL);
+ data, em, nullptr, -1, epsilon, tree_type, axis, BVHTREE_FROM_VERTS, nullptr, nullptr);
}
/**
- * Builds a bvh tree where nodes are the given vertices (note: does not copy given mverts!).
+ * Builds a bvh tree where nodes are the given vertices (note: does not copy given `vert`!).
* \param vert_allocated: if true, vert freeing will be done when freeing data.
* \param verts_mask: if not null, true elements give which vert to add to BVH tree.
* \param verts_num_active: if >= 0, number of active verts to add to BVH tree
@@ -724,7 +725,7 @@ BVHTree *bvhtree_from_mesh_verts_ex(BVHTreeFromMesh *data,
{
bool in_cache = false;
bool lock_started = false;
- BVHTree *tree = NULL;
+ BVHTree *tree = nullptr;
if (bvh_cache_p) {
in_cache = bvhcache_find(bvh_cache_p, bvh_cache_type, &tree, &lock_started, mesh_eval_mutex);
}
@@ -732,11 +733,11 @@ BVHTree *bvhtree_from_mesh_verts_ex(BVHTreeFromMesh *data,
if (in_cache == false) {
tree = bvhtree_from_mesh_verts_create_tree(
epsilon, tree_type, axis, vert, verts_num, verts_mask, verts_num_active);
- bvhtree_balance(tree, bvh_cache_p != NULL);
+ bvhtree_balance(tree, bvh_cache_p != nullptr);
if (bvh_cache_p) {
/* Save on cache for later use */
- /* printf("BVHTree built and saved on cache\n"); */
+ // printf("BVHTree built and saved on cache\n");
BVHCache *bvh_cache = *bvh_cache_p;
bvhcache_insert(bvh_cache, tree, bvh_cache_type);
in_cache = true;
@@ -807,7 +808,7 @@ static BVHTree *bvhtree_from_mesh_edges_create_tree(const MVert *vert,
int tree_type,
int axis)
{
- BVHTree *tree = NULL;
+ BVHTree *tree = nullptr;
if (edges_mask) {
BLI_assert(IN_RANGE_INCL(edges_num_active, 0, edge_num));
@@ -817,7 +818,7 @@ static BVHTree *bvhtree_from_mesh_edges_create_tree(const MVert *vert,
}
if (edges_num_active) {
- /* Create a bvh-tree of the given target */
+ /* Create a BVH-tree of the given target */
tree = BLI_bvhtree_new(edges_num_active, epsilon, tree_type, axis);
if (tree) {
for (int i = 0; i < edge_num; i++) {
@@ -871,7 +872,7 @@ BVHTree *bvhtree_from_editmesh_edges_ex(BVHTreeFromEditMesh *data,
BVHCache **bvh_cache_p,
ThreadMutex *mesh_eval_mutex)
{
- BVHTree *tree = NULL;
+ BVHTree *tree = nullptr;
if (bvh_cache_p) {
bool lock_started = false;
@@ -883,7 +884,7 @@ BVHTree *bvhtree_from_editmesh_edges_ex(BVHTreeFromEditMesh *data,
epsilon, tree_type, axis, em, edges_mask, edges_num_active);
bvhtree_balance(tree, true);
/* Save on cache for later use */
- /* printf("BVHTree built and saved on cache\n"); */
+ // printf("BVHTree built and saved on cache\n");
bvhcache_insert(bvh_cache, tree, bvh_cache_type);
data->cached = true;
}
@@ -899,9 +900,9 @@ BVHTree *bvhtree_from_editmesh_edges_ex(BVHTreeFromEditMesh *data,
memset(data, 0, sizeof(*data));
data->tree = tree;
data->em = em;
- data->nearest_callback = NULL; /* TODO */
- data->raycast_callback = NULL; /* TODO */
- data->cached = bvh_cache_p != NULL;
+ data->nearest_callback = nullptr; /* TODO */
+ data->raycast_callback = nullptr; /* TODO */
+ data->cached = bvh_cache_p != nullptr;
}
return tree;
@@ -911,7 +912,7 @@ BVHTree *bvhtree_from_editmesh_edges(
BVHTreeFromEditMesh *data, BMEditMesh *em, float epsilon, int tree_type, int axis)
{
return bvhtree_from_editmesh_edges_ex(
- data, em, NULL, -1, epsilon, tree_type, axis, 0, NULL, NULL);
+ data, em, nullptr, -1, epsilon, tree_type, axis, BVHTREE_FROM_VERTS, nullptr, nullptr);
}
/**
@@ -939,7 +940,7 @@ BVHTree *bvhtree_from_mesh_edges_ex(BVHTreeFromMesh *data,
{
bool in_cache = false;
bool lock_started = false;
- BVHTree *tree = NULL;
+ BVHTree *tree = nullptr;
if (bvh_cache_p) {
in_cache = bvhcache_find(bvh_cache_p, bvh_cache_type, &tree, &lock_started, mesh_eval_mutex);
}
@@ -953,7 +954,7 @@ BVHTree *bvhtree_from_mesh_edges_ex(BVHTreeFromMesh *data,
BVHCache *bvh_cache = *bvh_cache_p;
/* Save on cache for later use */
- /* printf("BVHTree built and saved on cache\n"); */
+ // printf("BVHTree built and saved on cache\n");
bvhcache_insert(bvh_cache, tree, bvh_cache_type);
in_cache = true;
}
@@ -988,7 +989,7 @@ static BVHTree *bvhtree_from_mesh_faces_create_tree(float epsilon,
const BLI_bitmap *faces_mask,
int faces_num_active)
{
- BVHTree *tree = NULL;
+ BVHTree *tree = nullptr;
if (faces_num) {
if (faces_mask) {
@@ -998,8 +999,8 @@ static BVHTree *bvhtree_from_mesh_faces_create_tree(float epsilon,
faces_num_active = faces_num;
}
- /* Create a bvh-tree of the given target */
- /* printf("%s: building BVH, total=%d\n", __func__, numFaces); */
+ /* Create a BVH-tree of the given target. */
+ // printf("%s: building BVH, total=%d\n", __func__, numFaces);
tree = BLI_bvhtree_new(faces_num_active, epsilon, tree_type, axis);
if (tree) {
if (vert && face) {
@@ -1074,7 +1075,7 @@ BVHTree *bvhtree_from_mesh_faces_ex(BVHTreeFromMesh *data,
{
bool in_cache = false;
bool lock_started = false;
- BVHTree *tree = NULL;
+ BVHTree *tree = nullptr;
if (bvh_cache_p) {
in_cache = bvhcache_find(bvh_cache_p, bvh_cache_type, &tree, &lock_started, mesh_eval_mutex);
}
@@ -1082,11 +1083,11 @@ BVHTree *bvhtree_from_mesh_faces_ex(BVHTreeFromMesh *data,
if (in_cache == false) {
tree = bvhtree_from_mesh_faces_create_tree(
epsilon, tree_type, axis, vert, face, numFaces, faces_mask, faces_num_active);
- bvhtree_balance(tree, bvh_cache_p != NULL);
+ bvhtree_balance(tree, bvh_cache_p != nullptr);
if (bvh_cache_p) {
/* Save on cache for later use */
- /* printf("BVHTree built and saved on cache\n"); */
+ // printf("BVHTree built and saved on cache\n");
BVHCache *bvh_cache = *bvh_cache_p;
bvhcache_insert(bvh_cache, tree, bvh_cache_type);
in_cache = true;
@@ -1117,7 +1118,7 @@ static BVHTree *bvhtree_from_editmesh_looptri_create_tree(float epsilon,
const BLI_bitmap *looptri_mask,
int looptri_num_active)
{
- BVHTree *tree = NULL;
+ BVHTree *tree = nullptr;
const int looptri_num = em->tottri;
if (looptri_num) {
@@ -1128,11 +1129,11 @@ static BVHTree *bvhtree_from_editmesh_looptri_create_tree(float epsilon,
looptri_num_active = looptri_num;
}
- /* Create a bvh-tree of the given target */
- /* printf("%s: building BVH, total=%d\n", __func__, numFaces); */
+ /* Create a BVH-tree of the given target */
+ // printf("%s: building BVH, total=%d\n", __func__, numFaces);
tree = BLI_bvhtree_new(looptri_num_active, epsilon, tree_type, axis);
if (tree) {
- const struct BMLoop *(*looptris)[3] = (void *)em->looptris;
+ const BMLoop *(*looptris)[3] = (const BMLoop *(*)[3])em->looptris;
/* Insert BMesh-tessellation triangles into the bvh tree, unless they are hidden
* and/or selected. Even if the faces themselves are not selected for the snapped
@@ -1143,7 +1144,7 @@ static BVHTree *bvhtree_from_editmesh_looptri_create_tree(float epsilon,
bool insert = looptri_mask ? BLI_BITMAP_TEST_BOOL(looptri_mask, i) : true;
if (insert) {
- /* No reason found to block hit-testing the triangle for snap, so insert it now.*/
+ /* No reason found to block hit-testing the triangle for snap, so insert it now. */
float co[3][3];
copy_v3_v3(co[0], ltri[0]->v->co);
copy_v3_v3(co[1], ltri[1]->v->co);
@@ -1169,7 +1170,7 @@ static BVHTree *bvhtree_from_mesh_looptri_create_tree(float epsilon,
const BLI_bitmap *looptri_mask,
int looptri_num_active)
{
- BVHTree *tree = NULL;
+ BVHTree *tree = nullptr;
if (looptri_mask) {
BLI_assert(IN_RANGE_INCL(looptri_num_active, 0, looptri_num));
@@ -1179,8 +1180,8 @@ static BVHTree *bvhtree_from_mesh_looptri_create_tree(float epsilon,
}
if (looptri_num_active) {
- /* Create a bvh-tree of the given target */
- /* printf("%s: building BVH, total=%d\n", __func__, numFaces); */
+ /* Create a BVH-tree of the given target */
+ // printf("%s: building BVH, total=%d\n", __func__, numFaces);
tree = BLI_bvhtree_new(looptri_num_active, epsilon, tree_type, axis);
if (tree) {
if (vert && looptri) {
@@ -1247,7 +1248,7 @@ BVHTree *bvhtree_from_editmesh_looptri_ex(BVHTreeFromEditMesh *data,
/* BMESH specific check that we have tessfaces,
* we _could_ tessellate here but rather not - campbell */
- BVHTree *tree = NULL;
+ BVHTree *tree = nullptr;
if (bvh_cache_p) {
bool lock_started = false;
bool in_cache = bvhcache_find(
@@ -1260,7 +1261,7 @@ BVHTree *bvhtree_from_editmesh_looptri_ex(BVHTreeFromEditMesh *data,
epsilon, tree_type, axis, em, looptri_mask, looptri_num_active);
/* Save on cache for later use */
- /* printf("BVHTree built and saved on cache\n"); */
+ // printf("BVHTree built and saved on cache\n");
bvhcache_insert(bvh_cache, tree, bvh_cache_type);
}
bvhcache_unlock(bvh_cache, lock_started);
@@ -1276,7 +1277,7 @@ BVHTree *bvhtree_from_editmesh_looptri_ex(BVHTreeFromEditMesh *data,
data->nearest_callback = editmesh_looptri_nearest_point;
data->raycast_callback = editmesh_looptri_spherecast;
data->em = em;
- data->cached = bvh_cache_p != NULL;
+ data->cached = bvh_cache_p != nullptr;
}
return tree;
}
@@ -1285,7 +1286,7 @@ BVHTree *bvhtree_from_editmesh_looptri(
BVHTreeFromEditMesh *data, BMEditMesh *em, float epsilon, int tree_type, int axis)
{
return bvhtree_from_editmesh_looptri_ex(
- data, em, NULL, -1, epsilon, tree_type, axis, 0, NULL, NULL);
+ data, em, nullptr, -1, epsilon, tree_type, axis, BVHTREE_FROM_VERTS, nullptr, nullptr);
}
/**
@@ -1312,7 +1313,7 @@ BVHTree *bvhtree_from_mesh_looptri_ex(BVHTreeFromMesh *data,
{
bool in_cache = false;
bool lock_started = false;
- BVHTree *tree = NULL;
+ BVHTree *tree = nullptr;
if (bvh_cache_p) {
in_cache = bvhcache_find(bvh_cache_p, bvh_cache_type, &tree, &lock_started, mesh_eval_mutex);
}
@@ -1329,7 +1330,7 @@ BVHTree *bvhtree_from_mesh_looptri_ex(BVHTreeFromMesh *data,
looptri_mask,
looptri_num_active);
- bvhtree_balance(tree, bvh_cache_p != NULL);
+ bvhtree_balance(tree, bvh_cache_p != nullptr);
if (bvh_cache_p) {
BVHCache *bvh_cache = *bvh_cache_p;
@@ -1437,19 +1438,22 @@ static BLI_bitmap *looptri_no_hidden_map_get(const MPoly *mpoly,
/**
* Builds or queries a bvhcache for the cache bvhtree of the request type.
+ *
+ * \note This function only fills a cache, and therefore the mesh argument can
+ * be considered logically const. Concurrent access is protected by a mutex.
*/
BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
- struct Mesh *mesh,
+ const struct Mesh *mesh,
const BVHCacheType bvh_cache_type,
const int tree_type)
{
- BVHTree *tree = NULL;
+ BVHTree *tree = nullptr;
BVHCache **bvh_cache_p = (BVHCache **)&mesh->runtime.bvh_cache;
ThreadMutex *mesh_eval_mutex = (ThreadMutex *)mesh->runtime.eval_mutex;
- bool is_cached = bvhcache_find(bvh_cache_p, bvh_cache_type, &tree, NULL, NULL);
+ const bool is_cached = bvhcache_find(bvh_cache_p, bvh_cache_type, &tree, nullptr, nullptr);
- if (is_cached && tree == NULL) {
+ if (is_cached && tree == nullptr) {
memset(data, 0, sizeof(*data));
return tree;
}
@@ -1458,7 +1462,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
case BVHTREE_FROM_VERTS:
case BVHTREE_FROM_LOOSEVERTS:
if (is_cached == false) {
- BLI_bitmap *loose_verts_mask = NULL;
+ BLI_bitmap *loose_verts_mask = nullptr;
int loose_vert_len = -1;
int verts_len = mesh->totvert;
@@ -1480,7 +1484,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
bvh_cache_p,
mesh_eval_mutex);
- if (loose_verts_mask != NULL) {
+ if (loose_verts_mask != nullptr) {
MEM_freeN(loose_verts_mask);
}
}
@@ -1493,7 +1497,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
case BVHTREE_FROM_EDGES:
case BVHTREE_FROM_LOOSEEDGES:
if (is_cached == false) {
- BLI_bitmap *loose_edges_mask = NULL;
+ BLI_bitmap *loose_edges_mask = nullptr;
int loose_edges_len = -1;
int edges_len = mesh->totedge;
@@ -1516,7 +1520,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
bvh_cache_p,
mesh_eval_mutex);
- if (loose_edges_mask != NULL) {
+ if (loose_edges_mask != nullptr) {
MEM_freeN(loose_edges_mask);
}
}
@@ -1538,7 +1542,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
mesh->mface,
num_faces,
false,
- NULL,
+ nullptr,
-1,
0.0,
tree_type,
@@ -1561,7 +1565,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
int looptri_len = BKE_mesh_runtime_looptri_len(mesh);
int looptri_mask_active_len = -1;
- BLI_bitmap *looptri_mask = NULL;
+ BLI_bitmap *looptri_mask = nullptr;
if (bvh_cache_type == BVHTREE_FROM_LOOPTRI_NO_HIDDEN) {
looptri_mask = looptri_no_hidden_map_get(
mesh->mpoly, looptri_len, &looptri_mask_active_len);
@@ -1584,7 +1588,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
bvh_cache_p,
mesh_eval_mutex);
- if (looptri_mask != NULL) {
+ if (looptri_mask != nullptr) {
MEM_freeN(looptri_mask);
}
}
@@ -1603,7 +1607,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
break;
}
- if (data->tree != NULL) {
+ if (data->tree != nullptr) {
#ifdef DEBUG
if (BLI_bvhtree_get_tree_type(data->tree) != tree_type) {
printf("tree_type %d obtained instead of %d\n",
@@ -1631,15 +1635,15 @@ BVHTree *BKE_bvhtree_from_editmesh_get(BVHTreeFromEditMesh *data,
BVHCache **bvh_cache_p,
ThreadMutex *mesh_eval_mutex)
{
- BVHTree *tree = NULL;
+ BVHTree *tree = nullptr;
bool is_cached = false;
memset(data, 0, sizeof(*data));
if (bvh_cache_p) {
- is_cached = bvhcache_find(bvh_cache_p, bvh_cache_type, &tree, NULL, NULL);
+ is_cached = bvhcache_find(bvh_cache_p, bvh_cache_type, &tree, nullptr, nullptr);
- if (is_cached && tree == NULL) {
+ if (is_cached && tree == nullptr) {
return tree;
}
}
@@ -1650,31 +1654,55 @@ BVHTree *BKE_bvhtree_from_editmesh_get(BVHTreeFromEditMesh *data,
switch (bvh_cache_type) {
case BVHTREE_FROM_EM_VERTS:
if (is_cached == false) {
- tree = bvhtree_from_editmesh_verts_ex(
- data, em, NULL, -1, 0.0f, tree_type, 6, bvh_cache_type, bvh_cache_p, mesh_eval_mutex);
+ tree = bvhtree_from_editmesh_verts_ex(data,
+ em,
+ nullptr,
+ -1,
+ 0.0f,
+ tree_type,
+ 6,
+ bvh_cache_type,
+ bvh_cache_p,
+ mesh_eval_mutex);
}
else {
- data->nearest_callback = NULL;
+ data->nearest_callback = nullptr;
data->raycast_callback = editmesh_verts_spherecast;
}
break;
case BVHTREE_FROM_EM_EDGES:
if (is_cached == false) {
- tree = bvhtree_from_editmesh_edges_ex(
- data, em, NULL, -1, 0.0f, tree_type, 6, bvh_cache_type, bvh_cache_p, mesh_eval_mutex);
+ tree = bvhtree_from_editmesh_edges_ex(data,
+ em,
+ nullptr,
+ -1,
+ 0.0f,
+ tree_type,
+ 6,
+ bvh_cache_type,
+ bvh_cache_p,
+ mesh_eval_mutex);
}
else {
/* Setup BVHTreeFromMesh */
- data->nearest_callback = NULL; /* TODO */
- data->raycast_callback = NULL; /* TODO */
+ data->nearest_callback = nullptr; /* TODO */
+ data->raycast_callback = nullptr; /* TODO */
}
break;
case BVHTREE_FROM_EM_LOOPTRI:
if (is_cached == false) {
- tree = bvhtree_from_editmesh_looptri_ex(
- data, em, NULL, -1, 0.0f, tree_type, 6, bvh_cache_type, bvh_cache_p, mesh_eval_mutex);
+ tree = bvhtree_from_editmesh_looptri_ex(data,
+ em,
+ nullptr,
+ -1,
+ 0.0f,
+ tree_type,
+ 6,
+ bvh_cache_type,
+ bvh_cache_p,
+ mesh_eval_mutex);
}
else {
/* Setup BVHTreeFromMesh */
@@ -1694,7 +1722,7 @@ BVHTree *BKE_bvhtree_from_editmesh_get(BVHTreeFromEditMesh *data,
break;
}
- if (data->tree != NULL) {
+ if (data->tree != nullptr) {
#ifdef DEBUG
if (BLI_bvhtree_get_tree_type(data->tree) != tree_type) {
printf("tree_type %d obtained instead of %d\n",
@@ -1763,7 +1791,7 @@ BVHTree *BKE_bvhtree_from_pointcloud_get(BVHTreeFromPointCloud *data,
{
BVHTree *tree = BLI_bvhtree_new(pointcloud->totpoint, 0.0f, tree_type, 6);
if (!tree) {
- return NULL;
+ return nullptr;
}
for (int i = 0; i < pointcloud->totpoint; i++) {
@@ -1774,7 +1802,7 @@ BVHTree *BKE_bvhtree_from_pointcloud_get(BVHTreeFromPointCloud *data,
data->coords = pointcloud->co;
data->tree = tree;
- data->nearest_callback = NULL;
+ data->nearest_callback = nullptr;
return tree;
}
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index bab9e2a5592..5172b067eba 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -615,7 +615,7 @@ static void camera_frame_fit_data_init(const Scene *scene,
BKE_camera_params_init(params);
BKE_camera_params_from_object(params, ob);
- /* compute matrix, viewplane, .. */
+ /* Compute matrix, view-plane, etc. */
if (scene) {
BKE_camera_params_compute_viewplane(
params, scene->r.xsch, scene->r.ysch, scene->r.xasp, scene->r.yasp);
@@ -975,7 +975,7 @@ void BKE_camera_multiview_window_matrix(const RenderData *rd,
BKE_camera_params_from_object(&params, camera);
BKE_camera_multiview_params(rd, &params, camera, viewname);
- /* Compute matrix, viewplane, .. */
+ /* Compute matrix, view-plane, etc. */
BKE_camera_params_compute_viewplane(&params, rd->xsch, rd->ysch, rd->xasp, rd->yasp);
BKE_camera_params_compute_matrix(&params);
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index aa51ee0017e..24266dc6bea 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -79,7 +79,8 @@ static bool collection_object_remove(Main *bmain,
static CollectionChild *collection_find_child(Collection *parent, Collection *collection);
static CollectionParent *collection_find_parent(Collection *child, Collection *collection);
-static bool collection_find_child_recursive(Collection *parent, Collection *collection);
+static bool collection_find_child_recursive(const Collection *parent,
+ const Collection *collection);
/** \} */
@@ -710,7 +711,7 @@ Collection *BKE_collection_duplicate(Main *bmain,
* unless its duplication is a sub-process of another one. */
collection_new->id.tag &= ~LIB_TAG_NEW;
- /* This code will follow into all ID links using an ID tagged with LIB_TAG_NEW.*/
+ /* This code will follow into all ID links using an ID tagged with LIB_TAG_NEW. */
BKE_libblock_relink_to_newid(&collection_new->id);
#ifndef NDEBUG
@@ -1458,7 +1459,7 @@ bool BKE_collection_cycle_find(Collection *new_ancestor, Collection *collection)
}
/* 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) .*/
+ * collection (that would also make a fully invalid cycle of dependencies). */
return collection_instance_find_recursive(collection, new_ancestor);
}
@@ -1521,9 +1522,9 @@ static CollectionChild *collection_find_child(Collection *parent, Collection *co
return BLI_findptr(&parent->children, collection, offsetof(CollectionChild, collection));
}
-static bool collection_find_child_recursive(Collection *parent, Collection *collection)
+static bool collection_find_child_recursive(const Collection *parent, const Collection *collection)
{
- LISTBASE_FOREACH (CollectionChild *, child, &parent->children) {
+ LISTBASE_FOREACH (const CollectionChild *, child, &parent->children) {
if (child->collection == collection) {
return true;
}
@@ -1536,7 +1537,7 @@ static bool collection_find_child_recursive(Collection *parent, Collection *coll
return false;
}
-bool BKE_collection_has_collection(Collection *parent, Collection *collection)
+bool BKE_collection_has_collection(const Collection *parent, const Collection *collection)
{
return collection_find_child_recursive(parent, collection);
}
diff --git a/source/blender/blenkernel/intern/colorband.c b/source/blender/blenkernel/intern/colorband.c
index 2884d7b3204..d6b318caa5e 100644
--- a/source/blender/blenkernel/intern/colorband.c
+++ b/source/blender/blenkernel/intern/colorband.c
@@ -490,7 +490,7 @@ bool BKE_colorband_evaluate(const ColorBand *coba, float in, float out[4])
}
if (ELEM(ipotype, COLBAND_INTERP_B_SPLINE, COLBAND_INTERP_CARDINAL)) {
- /* ipo from right to left: 3 2 1 0 */
+ /* Interpolate from right to left: `3 2 1 0`. */
float t[4];
if (a >= coba->tot - 1) {
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index f30fcc54b23..1484021cb9d 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -638,7 +638,7 @@ static void curvemap_make_table(const CurveMapping *cumap, CurveMap *cuma)
cuma->mintable = clipr->xmin;
cuma->maxtable = clipr->xmax;
- /* hrmf... we now rely on blender ipo beziers, these are more advanced */
+ /* Rely on Blender interpolation for bezier curves, support extra functionality here as well. */
bezt = MEM_callocN(cuma->totpoint * sizeof(BezTriple), "beztarr");
for (int a = 0; a < cuma->totpoint; a++) {
@@ -1280,12 +1280,12 @@ static void save_sample_line(
{
float yuv[3];
- /* vectorscope*/
+ /* Vector-scope. */
rgb_to_yuv(rgb[0], rgb[1], rgb[2], &yuv[0], &yuv[1], &yuv[2], BLI_YUV_ITU_BT709);
scopes->vecscope[idx + 0] = yuv[1];
scopes->vecscope[idx + 1] = yuv[2];
- /* waveform */
+ /* Waveform. */
switch (scopes->wavefrm_mode) {
case SCOPES_WAVEFRM_RGB:
case SCOPES_WAVEFRM_RGB_PARADE:
@@ -1497,7 +1497,7 @@ static void scopes_update_cb(void *__restrict userdata,
mul_v3_fl(ycc, INV_255);
minmax_v3v3_v3(min, max, ycc);
}
- /* increment count for histo*/
+ /* Increment count for histo. */
bin_lum[get_bin_float(luma)]++;
bin_r[get_bin_float(rgba[0])]++;
bin_g[get_bin_float(rgba[1])]++;
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 826c79c3764..fe207f81d7d 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -222,7 +222,7 @@ void BKE_constraints_clear_evalob(bConstraintOb *cob)
/* XXX This would seem to be in wrong order. However, it does not work in 'right' order -
* would be nice to understand why premul is needed here instead of usual postmul?
* In any case, we **do not get a delta** here (e.g. startmat & matrix having same location,
- * still gives a 'delta' with non-null translation component :/ ).*/
+ * still gives a 'delta' with non-null translation component :/ ). */
mul_m4_m4m4(delta, cob->matrix, imat);
/* copy matrices back to source */
@@ -272,7 +272,7 @@ void BKE_constraint_mat_convertspace(Object *ob,
float diff_mat[4][4];
float imat[4][4];
- /* prevent crashes in these unlikely events */
+ /* Prevent crashes in these unlikely events. */
if (ob == NULL || mat == NULL) {
return;
}
@@ -299,7 +299,10 @@ void BKE_constraint_mat_convertspace(Object *ob,
mul_m4_m4m4(mat, imat, mat);
/* Use pose-space as stepping stone for other spaces. */
- if (ELEM(to, CONSTRAINT_SPACE_LOCAL, CONSTRAINT_SPACE_PARLOCAL)) {
+ if (ELEM(to,
+ CONSTRAINT_SPACE_LOCAL,
+ CONSTRAINT_SPACE_PARLOCAL,
+ CONSTRAINT_SPACE_OWNLOCAL)) {
/* Call self with slightly different values. */
BKE_constraint_mat_convertspace(
ob, pchan, cob, mat, CONSTRAINT_SPACE_POSE, to, keep_scale);
@@ -315,6 +318,17 @@ void BKE_constraint_mat_convertspace(Object *ob,
BKE_armature_mat_pose_to_bone(pchan, mat, mat);
}
}
+ /* pose to owner local */
+ else if (to == CONSTRAINT_SPACE_OWNLOCAL) {
+ /* pose to local */
+ if (pchan->bone) {
+ BKE_armature_mat_pose_to_bone(pchan, mat, mat);
+ }
+
+ /* local to owner local (recursive) */
+ BKE_constraint_mat_convertspace(
+ ob, pchan, cob, mat, CONSTRAINT_SPACE_LOCAL, to, keep_scale);
+ }
/* pose to local with parent */
else if (to == CONSTRAINT_SPACE_PARLOCAL) {
if (pchan->bone) {
@@ -336,17 +350,59 @@ void BKE_constraint_mat_convertspace(Object *ob,
}
case CONSTRAINT_SPACE_LOCAL: /* ------------ FROM LOCALSPACE --------- */
{
+ /* local to owner local */
+ if (to == CONSTRAINT_SPACE_OWNLOCAL) {
+ if (pchan->bone) {
+ copy_m4_m4(diff_mat, pchan->bone->arm_mat);
+
+ if (cob && cob->pchan && cob->pchan->bone) {
+ invert_m4_m4(imat, cob->pchan->bone->arm_mat);
+ mul_m4_m4m4(diff_mat, imat, diff_mat);
+ }
+
+ zero_v3(diff_mat[3]);
+ invert_m4_m4(imat, diff_mat);
+ mul_m4_series(mat, diff_mat, mat, imat);
+ }
+ }
/* local to pose - do inverse procedure that was done for pose to local */
+ else {
+ if (pchan->bone) {
+ /* we need the posespace_matrix = local_matrix + (parent_posespace_matrix + restpos) */
+ BKE_armature_mat_bone_to_pose(pchan, mat, mat);
+ }
+
+ /* use pose-space as stepping stone for other spaces */
+ if (ELEM(to,
+ CONSTRAINT_SPACE_WORLD,
+ CONSTRAINT_SPACE_PARLOCAL,
+ CONSTRAINT_SPACE_CUSTOM)) {
+ /* call self with slightly different values */
+ BKE_constraint_mat_convertspace(
+ ob, pchan, cob, mat, CONSTRAINT_SPACE_POSE, to, keep_scale);
+ }
+ }
+ break;
+ }
+ case CONSTRAINT_SPACE_OWNLOCAL: { /* -------------- FROM OWNER LOCAL ---------- */
+ /* owner local to local */
if (pchan->bone) {
- /* we need the posespace_matrix = local_matrix + (parent_posespace_matrix + restpos) */
- BKE_armature_mat_bone_to_pose(pchan, mat, mat);
+ copy_m4_m4(diff_mat, pchan->bone->arm_mat);
+
+ if (cob && cob->pchan && cob->pchan->bone) {
+ invert_m4_m4(imat, cob->pchan->bone->arm_mat);
+ mul_m4_m4m4(diff_mat, imat, diff_mat);
+ }
+
+ zero_v3(diff_mat[3]);
+ invert_m4_m4(imat, diff_mat);
+ mul_m4_series(mat, imat, mat, diff_mat);
}
- /* use pose-space as stepping stone for other spaces */
- if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_PARLOCAL, CONSTRAINT_SPACE_CUSTOM)) {
+ if (to != CONSTRAINT_SPACE_LOCAL) {
/* call self with slightly different values */
BKE_constraint_mat_convertspace(
- ob, pchan, cob, mat, CONSTRAINT_SPACE_POSE, to, keep_scale);
+ ob, pchan, cob, mat, CONSTRAINT_SPACE_LOCAL, to, keep_scale);
}
break;
}
@@ -358,7 +414,11 @@ void BKE_constraint_mat_convertspace(Object *ob,
}
/* use pose-space as stepping stone for other spaces */
- if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, CONSTRAINT_SPACE_CUSTOM)) {
+ if (ELEM(to,
+ CONSTRAINT_SPACE_WORLD,
+ CONSTRAINT_SPACE_LOCAL,
+ CONSTRAINT_SPACE_OWNLOCAL,
+ CONSTRAINT_SPACE_CUSTOM)) {
/* call self with slightly different values */
BKE_constraint_mat_convertspace(
ob, pchan, cob, mat, CONSTRAINT_SPACE_POSE, to, keep_scale);
@@ -470,7 +530,7 @@ static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[
/* when not in EditMode, use the 'final' evaluated mesh, depsgraph
* ensures we build with CD_MDEFORMVERT layer
*/
- Mesh *me_eval = BKE_object_get_evaluated_mesh(ob);
+ const Mesh *me_eval = BKE_object_get_evaluated_mesh(ob);
BMEditMesh *em = BKE_editmesh_from_object(ob);
float plane[3];
float imat[3][3], tmat[3][3];
@@ -488,17 +548,17 @@ static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[
float normal[3] = {0.0f, 0.0f, 0.0f};
float weightsum = 0.0f;
if (me_eval) {
- MDeformVert *dvert = CustomData_get_layer(&me_eval->vdata, CD_MDEFORMVERT);
+ const MDeformVert *dvert = CustomData_get_layer(&me_eval->vdata, CD_MDEFORMVERT);
int numVerts = me_eval->totvert;
/* check that dvert is a valid pointers (just in case) */
if (dvert) {
- MDeformVert *dv = dvert;
- MVert *mv = me_eval->mvert;
/* get the average of all verts with that are in the vertex-group */
- for (int i = 0; i < numVerts; i++, dv++, mv++) {
- MDeformWeight *dw = BKE_defvert_find_index(dv, defgroup);
+ for (int i = 0; i < numVerts; i++) {
+ const MDeformVert *dv = &dvert[i];
+ const MVert *mv = &me_eval->mvert[i];
+ const MDeformWeight *dw = BKE_defvert_find_index(dv, defgroup);
if (dw && dw->weight > 0.0f) {
float nor[3];
@@ -1476,7 +1536,10 @@ static void followpath_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
* to get a time factor. */
curvetime /= cu->pathlen;
- if (cu->flag & CU_PATH_CLAMP) {
+ Nurb *nu = cu->nurb.first;
+ if (!(nu && nu->flagu & CU_NURB_CYCLIC) && cu->flag & CU_PATH_CLAMP) {
+ /* If curve is not cyclic, clamp to the begin/end points if the curve clamp option is on.
+ */
CLAMP(curvetime, 0.0f, 1.0f);
}
}
@@ -1491,7 +1554,7 @@ static void followpath_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
dir,
(data->followflag & FOLLOWPATH_FOLLOW) ? quat : NULL,
&radius,
- NULL)) { /* quat_pt is quat or NULL*/
+ NULL)) { /* quat_pt is quat or NULL. */
float totmat[4][4];
unit_m4(totmat);
@@ -2232,17 +2295,47 @@ static void translike_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
bConstraintTarget *ct = targets->first;
if (VALID_CONS_TARGET(ct)) {
+ float target_mat[4][4];
+
+ copy_m4_m4(target_mat, ct->matrix);
+
+ /* Remove the shear of the target matrix if enabled.
+ * Use Y as the axis since it's the natural default for bones. */
+ if (data->flag & TRANSLIKE_REMOVE_TARGET_SHEAR) {
+ orthogonalize_m4_stable(target_mat, 1, false);
+ }
+
+ /* Finally, combine the matrices. */
switch (data->mix_mode) {
case TRANSLIKE_MIX_REPLACE:
- copy_m4_m4(cob->matrix, ct->matrix);
+ copy_m4_m4(cob->matrix, target_mat);
+ break;
+
+ /* Simple matrix multiplication. */
+ case TRANSLIKE_MIX_BEFORE_FULL:
+ mul_m4_m4m4(cob->matrix, target_mat, cob->matrix);
break;
+ case TRANSLIKE_MIX_AFTER_FULL:
+ mul_m4_m4m4(cob->matrix, cob->matrix, target_mat);
+ break;
+
+ /* Aligned Inherit Scale emulation. */
case TRANSLIKE_MIX_BEFORE:
- mul_m4_m4m4_aligned_scale(cob->matrix, ct->matrix, cob->matrix);
+ mul_m4_m4m4_aligned_scale(cob->matrix, target_mat, cob->matrix);
break;
case TRANSLIKE_MIX_AFTER:
- mul_m4_m4m4_aligned_scale(cob->matrix, cob->matrix, ct->matrix);
+ mul_m4_m4m4_aligned_scale(cob->matrix, cob->matrix, target_mat);
+ break;
+
+ /* Fully separate handling of channels. */
+ case TRANSLIKE_MIX_BEFORE_SPLIT:
+ mul_m4_m4m4_split_channels(cob->matrix, target_mat, cob->matrix);
+ break;
+
+ case TRANSLIKE_MIX_AFTER_SPLIT:
+ mul_m4_m4m4_split_channels(cob->matrix, cob->matrix, target_mat);
break;
default:
@@ -2361,7 +2454,7 @@ static void pycon_new_data(void *cdata)
{
bPythonConstraint *data = (bPythonConstraint *)cdata;
- /* everything should be set correctly by calloc, except for the prop->type constant.*/
+ /* Everything should be set correctly by calloc, except for the prop->type constant. */
data->prop = MEM_callocN(sizeof(IDProperty), "PyConstraintProps");
data->prop->type = IDP_GROUP;
}
@@ -3523,7 +3616,7 @@ static void stretchto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
scale[0] = 1.0;
scale[2] = 1.0;
break;
- default: /* should not happen, but in case*/
+ default: /* Should not happen, but in case. */
return;
} /* switch (data->volmode) */
@@ -3536,34 +3629,34 @@ static void stretchto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
damptrack_do_transform(cob->matrix, vec, TRACK_Y);
break;
case PLANE_X:
- /* new Y aligns object target connection*/
+ /* New Y aligns object target connection. */
copy_v3_v3(cob->matrix[1], vec);
- /* build new Z vector */
- /* othogonal to "new Y" "old X! plane */
+ /* Build new Z vector. */
+ /* Orthogonal to "new Y" "old X! plane. */
cross_v3_v3v3(orth, xx, vec);
normalize_v3(orth);
- /* new Z*/
+ /* New Z. */
copy_v3_v3(cob->matrix[2], orth);
- /* we decided to keep X plane*/
+ /* We decided to keep X plane. */
cross_v3_v3v3(xx, vec, orth);
normalize_v3_v3(cob->matrix[0], xx);
break;
case PLANE_Z:
- /* new Y aligns object target connection*/
+ /* New Y aligns object target connection. */
copy_v3_v3(cob->matrix[1], vec);
- /* build new X vector */
- /* othogonal to "new Y" "old Z! plane */
+ /* Build new X vector. */
+ /* Orthogonal to "new Y" "old Z! plane. */
cross_v3_v3v3(orth, zz, vec);
normalize_v3(orth);
- /* new X */
+ /* New X. */
negate_v3_v3(cob->matrix[0], orth);
- /* we decided to keep Z */
+ /* We decided to keep Z. */
cross_v3_v3v3(zz, vec, orth);
normalize_v3_v3(cob->matrix[2], zz);
break;
@@ -4678,7 +4771,7 @@ static void pivotcon_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *ta
}
}
- /* find the pivot-point to use */
+ /* Find the pivot-point to use. */
if (VALID_CONS_TARGET(ct)) {
/* apply offset to target location */
add_v3_v3v3(pivot, ct->matrix[3], data->offset);
@@ -5006,7 +5099,7 @@ static void followtrack_project_to_depth_object_if_needed(FollowTrackContext *co
}
Object *depth_object = context->depth_object;
- Mesh *depth_mesh = BKE_object_get_evaluated_mesh(depth_object);
+ const Mesh *depth_mesh = BKE_object_get_evaluated_mesh(depth_object);
if (depth_mesh == NULL) {
return;
}
@@ -6297,7 +6390,7 @@ void BKE_constraint_blend_write(BlendWriter *writer, ListBase *conlist)
}
/* Write ID Properties -- and copy this comment EXACTLY for easy finding
- * of library blocks that implement this.*/
+ * of library blocks that implement this. */
IDP_BlendWrite(writer, data->prop);
break;
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index 81830f5bb61..1028790856c 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -1225,8 +1225,11 @@ enum eContextObjectMode CTX_data_mode_enum(const bContext *C)
return CTX_data_mode_enum_ex(obedit, obact, obact ? obact->mode : OB_MODE_OBJECT);
}
-/* would prefer if we can use the enum version below over this one - Campbell */
-/* must be aligned with above enum */
+/**
+ * Would prefer if we can use the enum version below over this one - Campbell.
+ *
+ * \note Must be aligned with above enum.
+ */
static const char *data_mode_strings[] = {
"mesh_edit", "curve_edit", "surface_edit", "text_edit",
"armature_edit", "mball_edit", "lattice_edit", "posemode",
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 65cdb8503a4..a5538453248 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -442,6 +442,15 @@ ListBase *BKE_curve_editNurbs_get(Curve *cu)
return NULL;
}
+const ListBase *BKE_curve_editNurbs_get_for_read(const Curve *cu)
+{
+ if (cu->editnurb) {
+ return &cu->editnurb->nurbs;
+ }
+
+ return NULL;
+}
+
short BKE_curve_type_get(const Curve *cu)
{
int type = cu->type;
@@ -1926,7 +1935,7 @@ static int cu_isectLL(const float v1[3],
static bool bevelinside(const BevList *bl1, const BevList *bl2)
{
/* is bl2 INSIDE bl1 ? with left-right method and "lambda's" */
- /* returns '1' if correct hole */
+ /* returns '1' if correct hole. */
BevPoint *bevp, *prevbevp;
float min, max, vec[3], hvec1[3], hvec2[3], lab, mu;
int nr, links = 0, rechts = 0, mode;
@@ -1941,7 +1950,7 @@ static bool bevelinside(const BevList *bl1, const BevList *bl2)
hvec2[0] += 1000;
/* test it with all edges of potential surrounding poly */
- /* count number of transitions left-right */
+ /* count number of transitions left-right. */
bevp = bl1->bevpoints;
nr = bl1->nr;
@@ -2049,7 +2058,7 @@ static void calc_bevel_sin_cos(
static void tilt_bezpart(const BezTriple *prevbezt,
const BezTriple *bezt,
- Nurb *nu,
+ const Nurb *nu,
float *tilt_array,
float *radius_array,
float *weight_array,
@@ -2133,7 +2142,7 @@ static void tilt_bezpart(const BezTriple *prevbezt,
}
if (weight_array) {
- /* basic interpolation for now, could copy tilt interp too */
+ /* Basic interpolation for now, could copy tilt interp too. */
*weight_array = prevbezt->weight + (bezt->weight - prevbezt->weight) *
(3.0f * fac * fac - 2.0f * fac * fac * fac);
@@ -2611,7 +2620,7 @@ static void make_bevel_list_2D(BevList *bl)
}
}
-static void bevlist_firstlast_direction_calc_from_bpoint(Nurb *nu, BevList *bl)
+static void bevlist_firstlast_direction_calc_from_bpoint(const Nurb *nu, BevList *bl)
{
if (nu->pntsu > 1) {
BPoint *first_bp = nu->bp, *last_bp = nu->bp + (nu->pntsu - 1);
@@ -2646,7 +2655,7 @@ void BKE_curve_bevelList_free(ListBase *bev)
BLI_listbase_clear(bev);
}
-void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
+void BKE_curve_bevelList_make(Object *ob, const ListBase *nurbs, const bool for_render)
{
/*
* - convert all curves to polys, with indication of resol and flags for double-vertices
@@ -2684,14 +2693,14 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
1;
#endif
- /* STEP 1: MAKE POLYS */
+ /* STEP 1: MAKE POLYS */
BKE_curve_bevelList_free(&ob->runtime.curve_cache->bev);
if (cu->editnurb && ob->type != OB_FONT) {
is_editmode = 1;
}
- LISTBASE_FOREACH (Nurb *, nu, nurbs) {
+ LISTBASE_FOREACH (const Nurb *, nu, nurbs) {
if (nu->hide && is_editmode) {
continue;
}
@@ -4361,7 +4370,7 @@ void BKE_nurbList_handles_set(ListBase *editnurb, const char code)
else {
char h_new = HD_FREE;
- /* there is 1 handle not FREE: FREE it all, else make ALIGNED */
+ /* There is 1 handle not FREE: FREE it all, else make ALIGNED. */
if (code == 5) {
h_new = HD_ALIGN;
}
@@ -4932,7 +4941,7 @@ bool BKE_nurb_type_convert(Nurb *nu,
int a, c, nr;
if (nu->type == CU_POLY) {
- if (type == CU_BEZIER) { /* to Bezier with vecthandles */
+ if (type == CU_BEZIER) { /* To Bezier with vecthandles. */
nr = nu->pntsu;
bezt = (BezTriple *)MEM_calloc_arrayN(nr, sizeof(BezTriple), "setsplinetype2");
nu->bezt = bezt;
@@ -5078,6 +5087,15 @@ ListBase *BKE_curve_nurbs_get(Curve *cu)
return &cu->nurb;
}
+const ListBase *BKE_curve_nurbs_get_for_read(const Curve *cu)
+{
+ if (cu->editnurb) {
+ return BKE_curve_editNurbs_get_for_read(cu);
+ }
+
+ return &cu->nurb;
+}
+
void BKE_curve_nurb_active_set(Curve *cu, const Nurb *nu)
{
if (nu == NULL) {
@@ -5135,7 +5153,7 @@ void BKE_curve_nurb_vert_active_set(Curve *cu, const Nurb *nu, const void *vert)
}
}
-/* Get points to active active nurb and active vert for curve */
+/* Get points to the active nurb and active vert for curve. */
bool BKE_curve_nurb_vert_active_get(Curve *cu, Nurb **r_nu, void **r_vert)
{
Nurb *nu = NULL;
diff --git a/source/blender/blenkernel/intern/curve_bevel.c b/source/blender/blenkernel/intern/curve_bevel.c
index 7f2cdfa59d3..d205d8cca46 100644
--- a/source/blender/blenkernel/intern/curve_bevel.c
+++ b/source/blender/blenkernel/intern/curve_bevel.c
@@ -97,7 +97,7 @@ static void curve_bevel_make_extrude_and_fill(const Curve *cu,
* in a consistent direction.
*
* These should be small enough for stack allocations because the current limit
- * for #Curve.bevresol is 32. */
+ * for #Curve.bevresol is 32. */
float *quarter_coords_x = alloca(sizeof(float) * (cu->bevresol + 1));
float *quarter_coords_y = alloca(sizeof(float) * (cu->bevresol + 1));
bevel_quarter_fill(cu, quarter_coords_x, quarter_coords_y);
diff --git a/source/blender/blenkernel/intern/curve_decimate.c b/source/blender/blenkernel/intern/curve_decimate.c
index e4647908b58..62de7c74183 100644
--- a/source/blender/blenkernel/intern/curve_decimate.c
+++ b/source/blender/blenkernel/intern/curve_decimate.c
@@ -32,8 +32,8 @@
struct Knot {
struct Knot *next, *prev;
- uint point_index; /* index in point array */
- uint knot_index; /* index in knot array*/
+ uint point_index; /* Index in point array. */
+ uint knot_index; /* Index in knot array. */
float tan[2][3];
float handles[2];
diff --git a/source/blender/blenkernel/intern/curve_eval.cc b/source/blender/blenkernel/intern/curve_eval.cc
index 0a6e4458a35..72ee2587c8a 100644
--- a/source/blender/blenkernel/intern/curve_eval.cc
+++ b/source/blender/blenkernel/intern/curve_eval.cc
@@ -257,9 +257,10 @@ static SplinePtr spline_from_dna_poly(const Nurb &nurb)
return spline;
}
-std::unique_ptr<CurveEval> curve_eval_from_dna_curve(const Curve &dna_curve)
+std::unique_ptr<CurveEval> curve_eval_from_dna_curve(const Curve &dna_curve,
+ const ListBase &nurbs_list)
{
- Vector<const Nurb *> nurbs(*BKE_curve_nurbs_get(&const_cast<Curve &>(dna_curve)));
+ Vector<const Nurb *> nurbs(nurbs_list);
std::unique_ptr<CurveEval> curve = std::make_unique<CurveEval>();
curve->resize(nurbs.size());
@@ -295,6 +296,11 @@ std::unique_ptr<CurveEval> curve_eval_from_dna_curve(const Curve &dna_curve)
return curve;
}
+std::unique_ptr<CurveEval> curve_eval_from_dna_curve(const Curve &dna_curve)
+{
+ return curve_eval_from_dna_curve(dna_curve, *BKE_curve_nurbs_get_for_read(&dna_curve));
+}
+
/**
* Check the invariants that curve control point attributes should always uphold, necessary
* because attributes are stored on splines rather than in a flat array on the curve:
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index b1bb8b9715e..08d0af45e92 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -2099,7 +2099,7 @@ bool CustomData_merge(const struct CustomData *source,
eCDAllocType alloctype,
int totelem)
{
- /*const LayerTypeInfo *typeInfo;*/
+ // const LayerTypeInfo *typeInfo;
CustomDataLayer *layer, *newlayer;
int lasttype = -1, lastactive = 0, lastrender = 0, lastclone = 0, lastmask = 0;
int number = 0, maxnumber = -1;
@@ -2107,7 +2107,7 @@ bool CustomData_merge(const struct CustomData *source,
for (int i = 0; i < source->totlayer; i++) {
layer = &source->layers[i];
- /*typeInfo = layerType_getInfo(layer->type);*/ /*UNUSED*/
+ // typeInfo = layerType_getInfo(layer->type); /* UNUSED */
int type = layer->type;
int flag = layer->flag;
@@ -2631,7 +2631,7 @@ void *CustomData_add_layer(
return NULL;
}
-/*same as above but accepts a name*/
+/* Same as above but accepts a name. */
void *CustomData_add_layer_named(CustomData *data,
int type,
eCDAllocType alloctype,
@@ -2813,6 +2813,14 @@ void *CustomData_duplicate_referenced_layer_named(CustomData *data,
return customData_duplicate_referenced_layer_index(data, layer_index, totelem);
}
+void CustomData_duplicate_referenced_layers(CustomData *data, int totelem)
+{
+ for (int i = 0; i < data->totlayer; i++) {
+ CustomDataLayer *layer = &data->layers[i];
+ layer->data = customData_duplicate_referenced_layer_index(data, i, totelem);
+ }
+}
+
bool CustomData_is_referenced_layer(struct CustomData *data, int type)
{
/* get the layer index of the first layer of type */
@@ -3559,7 +3567,7 @@ bool CustomData_bmesh_merge(const CustomData *source,
if (iter_type != BM_LOOPS_OF_FACE) {
BMHeader *h;
BMIter iter;
- /*ensure all current elements follow new customdata layout*/
+ /* Ensure all current elements follow new customdata layout. */
BM_ITER_MESH (h, &iter, bm, iter_type) {
void *tmp = NULL;
CustomData_bmesh_copy_data(&destold, dest, h->data, &tmp);
@@ -3573,7 +3581,7 @@ bool CustomData_bmesh_merge(const CustomData *source,
BMIter iter;
BMIter liter;
- /*ensure all current elements follow new customdata layout*/
+ /* Ensure all current elements follow new customdata layout. */
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
void *tmp = NULL;
@@ -3797,7 +3805,7 @@ void *CustomData_bmesh_get_n(const CustomData *data, void *block, int type, int
return POINTER_OFFSET(block, data->layers[layer_index + n].offset);
}
-/*gets from the layer at physical index n, note: doesn't check type.*/
+/* Gets from the layer at physical index n, note: doesn't check type. */
void *CustomData_bmesh_get_layer_n(const CustomData *data, void *block, int n)
{
if (n < 0 || n >= data->totlayer) {
@@ -3879,7 +3887,7 @@ bool CustomData_has_referenced(const struct CustomData *data)
}
/* copies the "value" (e.g. mloopuv uv or mloopcol colors) from one block to
- * another, while not overwriting anything else (e.g. flags)*/
+ * another, while not overwriting anything else (e.g. flags). */
void CustomData_data_copy_value(int type, const void *source, void *dest)
{
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
@@ -3897,7 +3905,7 @@ void CustomData_data_copy_value(int type, const void *source, void *dest)
}
/* Mixes the "value" (e.g. mloopuv uv or mloopcol colors) from one block into
- * another, while not overwriting anything else (e.g. flags)*/
+ * another, while not overwriting anything else (e.g. flags). */
void CustomData_data_mix_value(
int type, const void *source, void *dest, const int mixmode, const float mixfactor)
{
diff --git a/source/blender/blenkernel/intern/customdata_file.c b/source/blender/blenkernel/intern/customdata_file.c
index 314d5f4ff82..ef86a65f47d 100644
--- a/source/blender/blenkernel/intern/customdata_file.c
+++ b/source/blender/blenkernel/intern/customdata_file.c
@@ -361,9 +361,9 @@ bool cdf_write_open(CDataFile *cdf, const char *filename)
cdf->writef = f;
- /* fill header */
+ /* Fill header. */
header = &cdf->header;
- /* strcpy(, "BCDF"); // terminator out of range */
+ /* Copy "BCDF" (string terminator out of range). */
header->ID[0] = 'B';
header->ID[1] = 'C';
header->ID[2] = 'D';
diff --git a/source/blender/blenkernel/intern/data_transfer.c b/source/blender/blenkernel/intern/data_transfer.c
index 2bf58d9e764..12269cf0d51 100644
--- a/source/blender/blenkernel/intern/data_transfer.c
+++ b/source/blender/blenkernel/intern/data_transfer.c
@@ -1260,7 +1260,7 @@ void BKE_object_data_transfer_layout(struct Depsgraph *depsgraph,
me_dst = ob_dst->data;
- /* Get source evaluated mesh.*/
+ /* Get source evaluated mesh. */
BKE_object_data_transfer_dttypes_to_cdmask(data_types, &me_src_mask);
me_src = mesh_get_eval_final(depsgraph, scene, ob_src, &me_src_mask);
if (!me_src) {
@@ -1441,7 +1441,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
}
}
- /* Get source evaluated mesh.*/
+ /* Get source evaluated mesh. */
BKE_object_data_transfer_dttypes_to_cdmask(data_types, &me_src_mask);
BKE_mesh_remap_calc_source_cddata_masks_from_map_modes(
map_vert_mode, map_edge_mode, map_loop_mode, map_poly_mode, &me_src_mask);
diff --git a/source/blender/blenkernel/intern/displist.cc b/source/blender/blenkernel/intern/displist.cc
index 70355f3883d..a4ffaa8b10b 100644
--- a/source/blender/blenkernel/intern/displist.cc
+++ b/source/blender/blenkernel/intern/displist.cc
@@ -135,7 +135,7 @@ void BKE_displist_normals_add(ListBase *lb)
LISTBASE_FOREACH (DispList *, dl, lb) {
if (dl->type == DL_INDEX3) {
if (dl->nors == nullptr) {
- dl->nors = (float *)MEM_callocN(sizeof(float[3]), "dlnors");
+ dl->nors = (float *)MEM_callocN(sizeof(float[3]), __func__);
if (dl->flag & DL_BACK_CURVE) {
dl->nors[2] = -1.0f;
@@ -147,7 +147,7 @@ void BKE_displist_normals_add(ListBase *lb)
}
else if (dl->type == DL_SURF) {
if (dl->nors == nullptr) {
- dl->nors = (float *)MEM_callocN(sizeof(float[3]) * dl->nr * dl->parts, "dlnors");
+ dl->nors = (float *)MEM_callocN(sizeof(float[3]) * dl->nr * dl->parts, __func__);
vdata = dl->verts;
ndata = dl->nors;
@@ -323,12 +323,12 @@ static void curve_to_displist(const Curve *cu,
/* Check that there are more than two points so the curve doesn't loop back on itself. This
* needs to be separate from `is_cyclic` because cyclic sampling can work with two points
- * and resolution > 1. */
+ * and resolution > 1. */
const bool use_cyclic_sample = is_cyclic && (samples_len != 2);
DispList *dl = (DispList *)MEM_callocN(sizeof(DispList), __func__);
/* Add one to the length because of 'BKE_curve_forward_diff_bezier'. */
- dl->verts = (float *)MEM_mallocN(sizeof(float[3]) * (samples_len + 1), "dlverts");
+ dl->verts = (float *)MEM_mallocN(sizeof(float[3]) * (samples_len + 1), __func__);
BLI_addtail(r_dispbase, dl);
dl->parts = 1;
dl->nr = samples_len;
@@ -382,7 +382,7 @@ static void curve_to_displist(const Curve *cu,
else if (nu->type == CU_NURBS) {
const int len = (resolution * SEGMENTSU(nu));
DispList *dl = (DispList *)MEM_callocN(sizeof(DispList), __func__);
- dl->verts = (float *)MEM_mallocN(len * sizeof(float[3]), "dlverts");
+ dl->verts = (float *)MEM_mallocN(len * sizeof(float[3]), __func__);
BLI_addtail(r_dispbase, dl);
dl->parts = 1;
dl->nr = len;
@@ -395,7 +395,7 @@ static void curve_to_displist(const Curve *cu,
else if (nu->type == CU_POLY) {
const int len = nu->pntsu;
DispList *dl = (DispList *)MEM_callocN(sizeof(DispList), __func__);
- dl->verts = (float *)MEM_mallocN(len * sizeof(float[3]), "dlverts");
+ dl->verts = (float *)MEM_mallocN(len * sizeof(float[3]), __func__);
BLI_addtail(r_dispbase, dl);
dl->parts = 1;
dl->nr = len;
@@ -491,7 +491,7 @@ void BKE_displist_fill(const ListBase *dispbase,
const int triangles_len = BLI_scanfill_calc_ex(&sf_ctx, scanfill_flag, normal_proj);
if (totvert != 0 && triangles_len != 0) {
- DispList *dlnew = (DispList *)MEM_callocN(sizeof(DispList), "filldisplist");
+ DispList *dlnew = (DispList *)MEM_callocN(sizeof(DispList), __func__);
dlnew->type = DL_INDEX3;
dlnew->flag = (dl_flag_accum & (DL_BACK_CURVE | DL_FRONT_CURVE));
dlnew->rt = (dl_rt_accum & CU_SMOOTH);
@@ -499,8 +499,8 @@ void BKE_displist_fill(const ListBase *dispbase,
dlnew->nr = totvert;
dlnew->parts = triangles_len;
- dlnew->index = (int *)MEM_mallocN(sizeof(int[3]) * triangles_len, "dlindex");
- dlnew->verts = (float *)MEM_mallocN(sizeof(float[3]) * totvert, "dlverts");
+ dlnew->index = (int *)MEM_mallocN(sizeof(int[3]) * triangles_len, __func__);
+ dlnew->verts = (float *)MEM_mallocN(sizeof(float[3]) * totvert, __func__);
/* vert data */
int i;
@@ -630,7 +630,7 @@ static float displist_calc_taper(Depsgraph *depsgraph,
(DispList *)taperobj->runtime.curve_cache->disp.first :
nullptr;
if (dl == nullptr) {
- BKE_displist_make_curveTypes(depsgraph, scene, taperobj, false, false);
+ BKE_displist_make_curveTypes(depsgraph, scene, taperobj, false);
dl = (DispList *)taperobj->runtime.curve_cache->disp.first;
}
if (dl) {
@@ -681,8 +681,7 @@ void BKE_displist_make_mball(Depsgraph *depsgraph, Scene *scene, Object *ob)
BKE_displist_free(&(ob->runtime.curve_cache->disp));
}
else {
- ob->runtime.curve_cache = (CurveCache *)MEM_callocN(sizeof(CurveCache),
- "CurveCache for MBall");
+ ob->runtime.curve_cache = (CurveCache *)MEM_callocN(sizeof(CurveCache), __func__);
}
BKE_mball_polygonize(depsgraph, scene, ob, &ob->runtime.curve_cache->disp);
@@ -1068,7 +1067,7 @@ static void displist_surf_indices(DispList *dl)
dl->totindex = 0;
int *index = dl->index = (int *)MEM_mallocN(sizeof(int[4]) * (dl->parts + 1) * (dl->nr + 1),
- "index array nurbs");
+ __func__);
for (int a = 0; a < dl->parts; a++) {
@@ -1092,31 +1091,29 @@ static void displist_surf_indices(DispList *dl)
}
}
-static void displist_make_surf(Depsgraph *depsgraph,
- const Scene *scene,
- Object *ob,
- ListBase *dispbase,
- Mesh **r_final,
- const bool for_render,
- const bool for_orco)
+static void evaluate_surface_object(Depsgraph *depsgraph,
+ const Scene *scene,
+ Object *ob,
+ const bool for_render,
+ ListBase *r_dispbase,
+ Mesh **r_final)
{
- ListBase nubase = {nullptr, nullptr};
+ BLI_assert(ob->type == OB_SURF);
const Curve *cu = (const Curve *)ob->data;
+ ListBase *deformed_nurbs = &ob->runtime.curve_cache->deformed_nurbs;
+
if (!for_render && cu->editnurb) {
- BKE_nurbList_duplicate(&nubase, BKE_curve_editNurbs_get(const_cast<Curve *>(cu)));
+ BKE_nurbList_duplicate(deformed_nurbs, BKE_curve_editNurbs_get_for_read(cu));
}
else {
- BKE_nurbList_duplicate(&nubase, &cu->nurb);
+ BKE_nurbList_duplicate(deformed_nurbs, &cu->nurb);
}
- bool force_mesh_conversion = false;
- if (!for_orco) {
- force_mesh_conversion = BKE_curve_calc_modifiers_pre(
- depsgraph, scene, ob, &nubase, &nubase, for_render);
- }
+ bool force_mesh_conversion = BKE_curve_calc_modifiers_pre(
+ depsgraph, scene, ob, deformed_nurbs, deformed_nurbs, for_render);
- LISTBASE_FOREACH (Nurb *, nu, &nubase) {
+ LISTBASE_FOREACH (const Nurb *, nu, deformed_nurbs) {
if (!(for_render || nu->hide == 0) || !BKE_nurb_check_valid_uv(nu)) {
continue;
}
@@ -1127,10 +1124,10 @@ static void displist_make_surf(Depsgraph *depsgraph,
if (nu->pntsv == 1) {
const int len = SEGMENTSU(nu) * resolu;
- DispList *dl = (DispList *)MEM_callocN(sizeof(DispList), "makeDispListsurf");
- dl->verts = (float *)MEM_mallocN(len * sizeof(float[3]), "dlverts");
+ DispList *dl = (DispList *)MEM_callocN(sizeof(DispList), __func__);
+ dl->verts = (float *)MEM_mallocN(len * sizeof(float[3]), __func__);
- BLI_addtail(dispbase, dl);
+ BLI_addtail(r_dispbase, dl);
dl->parts = 1;
dl->nr = len;
dl->col = nu->mat_nr;
@@ -1150,9 +1147,9 @@ static void displist_make_surf(Depsgraph *depsgraph,
else {
const int len = (nu->pntsu * resolu) * (nu->pntsv * resolv);
- DispList *dl = (DispList *)MEM_callocN(sizeof(DispList), "makeDispListsurf");
- dl->verts = (float *)MEM_mallocN(len * sizeof(float[3]), "dlverts");
- BLI_addtail(dispbase, dl);
+ DispList *dl = (DispList *)MEM_callocN(sizeof(DispList), __func__);
+ dl->verts = (float *)MEM_mallocN(len * sizeof(float[3]), __func__);
+ BLI_addtail(r_dispbase, dl);
dl->col = nu->mat_nr;
dl->charidx = nu->charidx;
@@ -1177,13 +1174,8 @@ static void displist_make_surf(Depsgraph *depsgraph,
}
}
- if (!for_orco) {
- BKE_nurbList_duplicate(&ob->runtime.curve_cache->deformed_nurbs, &nubase);
- curve_calc_modifiers_post(
- depsgraph, scene, ob, dispbase, for_render, force_mesh_conversion, r_final);
- }
-
- BKE_nurbList_free(&nubase);
+ curve_calc_modifiers_post(
+ depsgraph, scene, ob, r_dispbase, for_render, force_mesh_conversion, r_final);
}
static void rotateBevelPiece(const Curve *cu,
@@ -1252,8 +1244,8 @@ static void fillBevelCap(const Nurb *nu,
const float *prev_fp,
ListBase *dispbase)
{
- DispList *dl = (DispList *)MEM_callocN(sizeof(DispList), "makeDispListbev2");
- dl->verts = (float *)MEM_mallocN(sizeof(float[3]) * dlb->nr, "dlverts");
+ DispList *dl = (DispList *)MEM_callocN(sizeof(DispList), __func__);
+ dl->verts = (float *)MEM_mallocN(sizeof(float[3]) * dlb->nr, __func__);
memcpy(dl->verts, prev_fp, sizeof(float[3]) * dlb->nr);
dl->type = DL_POLY;
@@ -1403,67 +1395,47 @@ static void calc_bevfac_mapping(const Curve *cu,
}
}
-static void do_makeDispListCurveTypes(Depsgraph *depsgraph,
- const Scene *scene,
- Object *ob,
- ListBase *dispbase,
- const bool for_render,
- const bool for_orco,
- Mesh **r_final)
+static void evaluate_curve_type_object(Depsgraph *depsgraph,
+ const Scene *scene,
+ Object *ob,
+ const bool for_render,
+ ListBase *r_dispbase,
+ Mesh **r_final)
{
+ BLI_assert(ELEM(ob->type, OB_CURVE, OB_FONT));
const Curve *cu = (const Curve *)ob->data;
- /* we do allow duplis... this is only displist on curve level */
- if (!ELEM(ob->type, OB_SURF, OB_CURVE, OB_FONT)) {
- return;
- }
-
- if (ob->type == OB_SURF) {
- displist_make_surf(depsgraph, scene, ob, dispbase, r_final, for_render, for_orco);
- return;
- }
-
- ListBase nubase = {nullptr, nullptr};
- bool force_mesh_conversion = false;
-
- BKE_curve_bevelList_free(&ob->runtime.curve_cache->bev);
-
- /* We only re-evaluate path if evaluation is not happening for orco.
- * If the calculation happens for orco, we should never free data which
- * was needed before and only not needed for orco calculation. */
- if (!for_orco) {
- if (ob->runtime.curve_cache->anim_path_accum_length) {
- MEM_freeN((void *)ob->runtime.curve_cache->anim_path_accum_length);
- }
- ob->runtime.curve_cache->anim_path_accum_length = nullptr;
- }
+ ListBase *deformed_nurbs = &ob->runtime.curve_cache->deformed_nurbs;
if (ob->type == OB_FONT) {
- BKE_vfont_to_curve_nubase(ob, FO_EDIT, &nubase);
+ BKE_vfont_to_curve_nubase(ob, FO_EDIT, deformed_nurbs);
}
else {
- BKE_nurbList_duplicate(&nubase, BKE_curve_nurbs_get(const_cast<Curve *>(cu)));
+ BKE_nurbList_duplicate(deformed_nurbs, BKE_curve_nurbs_get_for_read(cu));
}
- if (!for_orco) {
- force_mesh_conversion = BKE_curve_calc_modifiers_pre(
- depsgraph, scene, ob, &nubase, &nubase, for_render);
- }
+ bool force_mesh_conversion = BKE_curve_calc_modifiers_pre(
+ depsgraph, scene, ob, deformed_nurbs, deformed_nurbs, for_render);
+
+ BKE_curve_bevelList_make(ob, deformed_nurbs, for_render);
- BKE_curve_bevelList_make(ob, &nubase, for_render);
+ if ((cu->flag & CU_PATH) ||
+ DEG_get_eval_flags_for_id(depsgraph, &ob->id) & DAG_EVAL_NEED_CURVE_PATH) {
+ BKE_anim_path_calc_data(ob);
+ }
/* If curve has no bevel will return nothing */
ListBase dlbev = BKE_curve_bevel_make(cu);
/* no bevel or extrude, and no width correction? */
if (BLI_listbase_is_empty(&dlbev) && cu->width == 1.0f) {
- curve_to_displist(cu, &nubase, for_render, dispbase);
+ curve_to_displist(cu, deformed_nurbs, for_render, r_dispbase);
}
else {
const float widfac = cu->width - 1.0f;
- BevList *bl = (BevList *)ob->runtime.curve_cache->bev.first;
- Nurb *nu = (Nurb *)nubase.first;
+ const BevList *bl = (BevList *)ob->runtime.curve_cache->bev.first;
+ const Nurb *nu = (Nurb *)deformed_nurbs->first;
for (; bl && nu; bl = bl->next, nu = nu->next) {
float *data;
@@ -1475,7 +1447,7 @@ static void do_makeDispListCurveTypes(Depsgraph *depsgraph,
if (BLI_listbase_is_empty(&dlbev)) {
DispList *dl = (DispList *)MEM_callocN(sizeof(DispList), "makeDispListbev");
dl->verts = (float *)MEM_mallocN(sizeof(float[3]) * bl->nr, "dlverts");
- BLI_addtail(dispbase, dl);
+ BLI_addtail(r_dispbase, dl);
if (bl->poly != -1) {
dl->type = DL_POLY;
@@ -1523,9 +1495,9 @@ static void do_makeDispListCurveTypes(Depsgraph *depsgraph,
LISTBASE_FOREACH (DispList *, dlb, &dlbev) {
/* for each part of the bevel use a separate displblock */
- DispList *dl = (DispList *)MEM_callocN(sizeof(DispList), "makeDispListbev1");
- dl->verts = data = (float *)MEM_mallocN(sizeof(float[3]) * dlb->nr * steps, "dlverts");
- BLI_addtail(dispbase, dl);
+ DispList *dl = (DispList *)MEM_callocN(sizeof(DispList), __func__);
+ dl->verts = data = (float *)MEM_mallocN(sizeof(float[3]) * dlb->nr * steps, __func__);
+ BLI_addtail(r_dispbase, dl);
dl->type = DL_SURF;
@@ -1621,62 +1593,51 @@ static void do_makeDispListCurveTypes(Depsgraph *depsgraph,
}
if (bottom_capbase.first) {
- BKE_displist_fill(&bottom_capbase, dispbase, bottom_no, false);
- BKE_displist_fill(&top_capbase, dispbase, top_no, false);
+ BKE_displist_fill(&bottom_capbase, r_dispbase, bottom_no, false);
+ BKE_displist_fill(&top_capbase, r_dispbase, top_no, false);
BKE_displist_free(&bottom_capbase);
BKE_displist_free(&top_capbase);
}
}
}
- BKE_displist_free(&dlbev);
}
+ BKE_displist_free(&dlbev);
+
if (!(cu->flag & CU_DEFORM_FILL)) {
- curve_to_filledpoly(cu, dispbase);
+ curve_to_filledpoly(cu, r_dispbase);
}
- if (!for_orco) {
- if ((cu->flag & CU_PATH) ||
- DEG_get_eval_flags_for_id(depsgraph, &ob->id) & DAG_EVAL_NEED_CURVE_PATH) {
- BKE_anim_path_calc_data(ob);
- }
-
- BKE_nurbList_duplicate(&ob->runtime.curve_cache->deformed_nurbs, &nubase);
- curve_calc_modifiers_post(
- depsgraph, scene, ob, dispbase, for_render, force_mesh_conversion, r_final);
- }
+ curve_calc_modifiers_post(
+ depsgraph, scene, ob, r_dispbase, for_render, force_mesh_conversion, r_final);
if (cu->flag & CU_DEFORM_FILL && !ob->runtime.data_eval) {
- curve_to_filledpoly(cu, dispbase);
+ curve_to_filledpoly(cu, r_dispbase);
}
-
- BKE_nurbList_free(&nubase);
}
void BKE_displist_make_curveTypes(Depsgraph *depsgraph,
const Scene *scene,
Object *ob,
- const bool for_render,
- const bool for_orco)
+ const bool for_render)
{
- /* The same check for duplis as in do_makeDispListCurveTypes.
- * Happens when curve used for constraint/bevel was converted to mesh.
- * check there is still needed for render displist and orco displists. */
- if (!ELEM(ob->type, OB_SURF, OB_CURVE, OB_FONT)) {
- return;
- }
+ BLI_assert(ELEM(ob->type, OB_SURF, OB_CURVE, OB_FONT));
BKE_object_free_derived_caches(ob);
if (!ob->runtime.curve_cache) {
- ob->runtime.curve_cache = (CurveCache *)MEM_callocN(sizeof(CurveCache),
- "CurveCache for curve types");
+ ob->runtime.curve_cache = (CurveCache *)MEM_callocN(sizeof(CurveCache), __func__);
}
ListBase *dispbase = &(ob->runtime.curve_cache->disp);
Mesh *mesh_eval = nullptr;
- do_makeDispListCurveTypes(depsgraph, scene, ob, dispbase, for_render, for_orco, &mesh_eval);
+ if (ob->type == OB_SURF) {
+ evaluate_surface_object(depsgraph, scene, ob, for_render, dispbase, &mesh_eval);
+ }
+ else {
+ evaluate_curve_type_object(depsgraph, scene, ob, for_render, dispbase, &mesh_eval);
+ }
if (mesh_eval != nullptr) {
BKE_object_eval_assign_data(ob, &mesh_eval->id, true);
@@ -1685,19 +1646,19 @@ void BKE_displist_make_curveTypes(Depsgraph *depsgraph,
boundbox_displist_object(ob);
}
-void BKE_displist_make_curveTypes_forRender(Depsgraph *depsgraph,
- const Scene *scene,
- Object *ob,
- ListBase *dispbase,
- const bool for_orco,
- Mesh **r_final)
+void BKE_displist_make_curveTypes_forRender(
+ Depsgraph *depsgraph, const Scene *scene, Object *ob, ListBase *r_dispbase, Mesh **r_final)
{
if (ob->runtime.curve_cache == nullptr) {
- ob->runtime.curve_cache = (CurveCache *)MEM_callocN(sizeof(CurveCache),
- "CurveCache for Curve");
+ ob->runtime.curve_cache = (CurveCache *)MEM_callocN(sizeof(CurveCache), __func__);
}
- do_makeDispListCurveTypes(depsgraph, scene, ob, dispbase, true, for_orco, r_final);
+ if (ob->type == OB_SURF) {
+ evaluate_surface_object(depsgraph, scene, ob, true, r_dispbase, r_final);
+ }
+ else {
+ evaluate_curve_type_object(depsgraph, scene, ob, true, r_dispbase, r_final);
+ }
}
void BKE_displist_minmax(const ListBase *dispbase, float min[3], float max[3])
@@ -1730,10 +1691,10 @@ static void boundbox_displist_object(Object *ob)
/* object's BB is calculated from final displist */
if (ob->runtime.bb == nullptr) {
- ob->runtime.bb = (BoundBox *)MEM_callocN(sizeof(BoundBox), "boundbox");
+ ob->runtime.bb = (BoundBox *)MEM_callocN(sizeof(BoundBox), __func__);
}
- Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
+ const Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
if (mesh_eval) {
BKE_object_boundbox_calc_from_mesh(ob, mesh_eval);
}
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 788a51257bf..2eb18a06799 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -1757,7 +1757,7 @@ void dynamicPaint_clearSurface(const Scene *scene, DynamicPaintSurface *surface)
}
}
-/* completely (re)initializes surface (only for point cache types)*/
+/* Completely (re)initializes surface (only for point cache types). */
bool dynamicPaint_resetSurface(const Scene *scene, DynamicPaintSurface *surface)
{
int numOfPoints = dynamicPaint_surfaceNumOfPoints(surface);
@@ -4145,7 +4145,7 @@ static void dynamic_paint_paint_mesh_cell_point_cb_ex(
/* mix final sample strength depending on brush settings */
if (hit_found) {
- /* if "negate volume" enabled, negate all factors within volume*/
+ /* If "negate volume" enabled, negate all factors within volume. */
if (brush->collision == MOD_DPAINT_COL_VOLDIST && brush->flags & MOD_DPAINT_NEGATE_VOLUME) {
volume_factor = 1.0f - volume_factor;
if (inner_proximity) {
diff --git a/source/blender/blenkernel/intern/editmesh.c b/source/blender/blenkernel/intern/editmesh.c
index b512309a773..49c2a2cbd89 100644
--- a/source/blender/blenkernel/intern/editmesh.c
+++ b/source/blender/blenkernel/intern/editmesh.c
@@ -222,7 +222,7 @@ void BKE_editmesh_free_derivedmesh(BMEditMesh *em)
MEM_SAFE_FREE(em->bb_cage);
}
-/*does not free the BMEditMesh struct itself*/
+/* Does not free the #BMEditMesh struct itself. */
void BKE_editmesh_free(BMEditMesh *em)
{
BKE_editmesh_free_derivedmesh(em);
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index e39749225ea..1b628b16802 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -163,7 +163,7 @@ static void precalculate_effector(struct Depsgraph *depsgraph, EffectorCache *ef
if (cu->flag & CU_PATH) {
if (eff->ob->runtime.curve_cache == NULL ||
eff->ob->runtime.curve_cache->anim_path_accum_length == NULL) {
- BKE_displist_make_curveTypes(depsgraph, eff->scene, eff->ob, false, false);
+ BKE_displist_make_curveTypes(depsgraph, eff->scene, eff->ob, false);
}
if (eff->ob->runtime.curve_cache->anim_path_accum_length) {
@@ -716,7 +716,7 @@ int get_effector_data(EffectorCache *eff,
}
else if (eff->pd && eff->pd->shape == PFIELD_SHAPE_POINTS) {
/* TODO: hair and points object support */
- Mesh *me_eval = BKE_object_get_evaluated_mesh(eff->ob);
+ const Mesh *me_eval = BKE_object_get_evaluated_mesh(eff->ob);
if (me_eval != NULL) {
copy_v3_v3(efd->loc, me_eval->mvert[*efd->index].co);
normal_short_to_float_v3(efd->nor, me_eval->mvert[*efd->index].no);
@@ -773,7 +773,7 @@ int get_effector_data(EffectorCache *eff,
/* use center of object for distance calculus */
const Object *ob = eff->ob;
- /* use z-axis as normal*/
+ /* Use z-axis as normal. */
normalize_v3_v3(efd->nor, ob->obmat[2]);
if (eff->pd && ELEM(eff->pd->shape, PFIELD_SHAPE_PLANE, PFIELD_SHAPE_LINE)) {
@@ -830,7 +830,7 @@ static void get_effector_tot(
if (eff->pd->shape == PFIELD_SHAPE_POINTS) {
/* TODO: hair and points object support */
- Mesh *me_eval = BKE_object_get_evaluated_mesh(eff->ob);
+ const Mesh *me_eval = BKE_object_get_evaluated_mesh(eff->ob);
*tot = me_eval != NULL ? me_eval->totvert : 1;
if (*tot && eff->pd->forcefield == PFIELD_HARMONIC && point->index >= 0) {
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 68ed3c239ef..a670e7b9ac5 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -510,8 +510,11 @@ FCurve *BKE_fcurve_find_by_rna_context_ui(bContext *C,
* with optional argument for precision required.
* Returns the index to insert at (data already at that index will be offset if replace is 0)
*/
-static int BKE_fcurve_bezt_binarysearch_index_ex(
- BezTriple array[], float frame, int arraylen, float threshold, bool *r_replace)
+static int BKE_fcurve_bezt_binarysearch_index_ex(const BezTriple array[],
+ const float frame,
+ const int arraylen,
+ const float threshold,
+ bool *r_replace)
{
int start = 0, end = arraylen;
int loopbreaker = 0, maxloop = arraylen * 2;
@@ -597,9 +600,9 @@ static int BKE_fcurve_bezt_binarysearch_index_ex(
/* Binary search algorithm for finding where to insert BezTriple. (for use by insert_bezt_fcurve)
* Returns the index to insert at (data already at that index will be offset if replace is 0)
*/
-int BKE_fcurve_bezt_binarysearch_index(BezTriple array[],
- float frame,
- int arraylen,
+int BKE_fcurve_bezt_binarysearch_index(const BezTriple array[],
+ const float frame,
+ const int arraylen,
bool *r_replace)
{
/* This is just a wrapper which uses the default threshold. */
@@ -1309,7 +1312,7 @@ void calchandles_fcurve_ex(FCurve *fcu, eBezTriple_Flag handle_sel_flag)
* - Need bezier keys.
* - Only bezier-interpolation has handles (for now).
*/
- if (ELEM(NULL, fcu, fcu->bezt) || (a < 2) /*|| ELEM(fcu->ipo, BEZT_IPO_CONST, BEZT_IPO_LIN)*/) {
+ if (ELEM(NULL, fcu, fcu->bezt) || (a < 2) /*|| ELEM(fcu->ipo, BEZT_IPO_CONST, BEZT_IPO_LIN) */) {
return;
}
@@ -2191,9 +2194,9 @@ float evaluate_fcurve(FCurve *fcu, float evaltime)
float evaluate_fcurve_only_curve(FCurve *fcu, float evaltime)
{
- /* Can be used to evaluate the (keyframed) fcurve only.
- * Also works for driver-fcurves when the driver itself is not relevant.
- * E.g. when inserting a keyframe in a driver fcurve. */
+ /* Can be used to evaluate the (key-framed) f-curve only.
+ * Also works for driver-f-curves when the driver itself is not relevant.
+ * E.g. when inserting a keyframe in a driver f-curve. */
return evaluate_fcurve_ex(fcu, evaltime, 0.0);
}
@@ -2322,7 +2325,7 @@ void BKE_fmodifiers_blend_write(BlendWriter *writer, ListBase *fmodifiers)
FMod_Python *data = fcm->data;
/* Write ID Properties -- and copy this comment EXACTLY for easy finding
- * of library blocks that implement this.*/
+ * of library blocks that implement this. */
IDP_BlendWrite(writer, data->prop);
break;
diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c
index 553575b5c7b..947417af55d 100644
--- a/source/blender/blenkernel/intern/fluid.c
+++ b/source/blender/blenkernel/intern/fluid.c
@@ -4395,7 +4395,7 @@ static void manta_smoke_calc_transparency(FluidDomainSettings *fds, ViewLayer *v
int cell[3];
float t_ray = 1.0;
- /* Reset shadow value.*/
+ /* Reset shadow value. */
shadow[index] = -1.0f;
voxel_center[0] = (float)x;
@@ -5023,7 +5023,7 @@ void BKE_fluid_modifier_copy(const struct FluidModifierData *fmd,
/* viscosity options */
tfds->viscosity_value = fds->viscosity_value;
- /* diffusion options*/
+ /* Diffusion options. */
tfds->surface_tension = fds->surface_tension;
tfds->viscosity_base = fds->viscosity_base;
tfds->viscosity_exponent = fds->viscosity_exponent;
diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c
index 8d1e6b26d4d..b9f0b97ab46 100644
--- a/source/blender/blenkernel/intern/fmodifier.c
+++ b/source/blender/blenkernel/intern/fmodifier.c
@@ -875,7 +875,7 @@ static void fcm_python_new_data(void *mdata)
{
FMod_Python *data = (FMod_Python *)mdata;
- /* everything should be set correctly by calloc, except for the prop->type constant.*/
+ /* Everything should be set correctly by calloc, except for the prop->type constant. */
data->prop = MEM_callocN(sizeof(IDProperty), "PyFModifierProps");
data->prop->type = IDP_GROUP;
}
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index 92cc3c763b6..8bb2c401b03 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -216,15 +216,15 @@ void BKE_vfont_free_data(struct VFont *vfont)
}
}
-static void *builtin_font_data = NULL;
+static const void *builtin_font_data = NULL;
static int builtin_font_size = 0;
-bool BKE_vfont_is_builtin(struct VFont *vfont)
+bool BKE_vfont_is_builtin(const struct VFont *vfont)
{
return STREQ(vfont->filepath, FO_BUILTIN_NAME);
}
-void BKE_vfont_builtin_register(void *mem, int size)
+void BKE_vfont_builtin_register(const void *mem, int size)
{
builtin_font_data = mem;
builtin_font_size = size;
@@ -1271,7 +1271,7 @@ static bool vfont_to_curve(Object *ob,
MEM_freeN(i_textbox_array);
/* TEXT ON CURVE */
- /* Note: Only OB_CURVE objects could have a path */
+ /* NOTE: Only OB_CURVE objects could have a path. */
if (cu->textoncurve && cu->textoncurve->type == OB_CURVE) {
BLI_assert(cu->textoncurve->runtime.curve_cache != NULL);
if (cu->textoncurve->runtime.curve_cache != NULL &&
@@ -1746,7 +1746,7 @@ void BKE_vfont_clipboard_set(const char32_t *text_buf, const CharInfo *info_buf,
char32_t *text;
CharInfo *info;
- /* clean previous buffers*/
+ /* Clean previous buffers. */
BKE_vfont_clipboard_free();
text = MEM_malloc_arrayN((len + 1), sizeof(*text), __func__);
diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc
index 42f3a854aec..28e46aab732 100644
--- a/source/blender/blenkernel/intern/geometry_component_mesh.cc
+++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc
@@ -29,7 +29,7 @@
#include "attribute_access_intern.hh"
-/* Can't include BKE_object_deform.h right now, due to an enum forward declaration. */
+/* Can't include BKE_object_deform.h right now, due to an enum forward declaration. */
extern "C" MDeformVert *BKE_object_defgroup_data_create(ID *id);
using blender::fn::GVArray;
diff --git a/source/blender/blenkernel/intern/geometry_set.cc b/source/blender/blenkernel/intern/geometry_set.cc
index 3d85118deee..07b4e715ea9 100644
--- a/source/blender/blenkernel/intern/geometry_set.cc
+++ b/source/blender/blenkernel/intern/geometry_set.cc
@@ -199,20 +199,6 @@ std::ostream &operator<<(std::ostream &stream, const GeometrySet &geometry_set)
return stream;
}
-/* This generally should not be used. It is necessary currently, so that GeometrySet can by used by
- * the CPPType system. */
-bool operator==(const GeometrySet &UNUSED(a), const GeometrySet &UNUSED(b))
-{
- return false;
-}
-
-/* This generally should not be used. It is necessary currently, so that GeometrySet can by used by
- * the CPPType system. */
-uint64_t GeometrySet::hash() const
-{
- return reinterpret_cast<uint64_t>(this);
-}
-
/* Remove all geometry components from the geometry set. */
void GeometrySet::clear()
{
diff --git a/source/blender/blenkernel/intern/geometry_set_instances.cc b/source/blender/blenkernel/intern/geometry_set_instances.cc
index 8cf08d05d9d..01b51d552a9 100644
--- a/source/blender/blenkernel/intern/geometry_set_instances.cc
+++ b/source/blender/blenkernel/intern/geometry_set_instances.cc
@@ -56,7 +56,7 @@ static void add_curve_data_as_geometry_component(const Object &object, GeometryS
{
BLI_assert(object.type == OB_CURVE);
if (object.data != nullptr) {
- std::unique_ptr<CurveEval> curve = curve_eval_from_dna_curve(*(Curve *)object.data);
+ std::unique_ptr<CurveEval> curve = curve_eval_from_dna_curve(*(const Curve *)object.data);
CurveComponent &curve_component = geometry_set.get_component_for_write<CurveComponent>();
curve_component.replace(curve.release(), GeometryOwnershipType::Owned);
}
@@ -264,7 +264,7 @@ static bool instances_attribute_foreach_recursive(const GeometrySet &geometry_se
}
}
- /* Now that this this geometry set is visited, increase the count and check with the limit. */
+ /* Now that this geometry set is visited, increase the count and check with the limit. */
if (limit > 0 && count++ > limit) {
return false;
}
@@ -535,7 +535,7 @@ static void join_attributes(Span<GeometryInstanceGroup> set_groups,
const void *src_buffer = src_span.data();
for (const int UNUSED(i) : set_group.transforms.index_range()) {
void *dst_buffer = dst_span[offset];
- cpp_type->copy_to_initialized_n(src_buffer, dst_buffer, domain_size);
+ cpp_type->copy_assign_n(src_buffer, dst_buffer, domain_size);
offset += domain_size;
}
}
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index a66c3cf3573..459fc5e4c68 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -195,12 +195,12 @@ static void greasepencil_blend_write(BlendWriter *writer, ID *id, const void *id
void BKE_gpencil_blend_read_data(BlendDataReader *reader, bGPdata *gpd)
{
- /* we must firstly have some grease-pencil data to link! */
+ /* We must firstly have some grease-pencil data to link! */
if (gpd == NULL) {
return;
}
- /* relink animdata */
+ /* Relink anim-data. */
BLO_read_data_address(reader, &gpd->adt);
BKE_animdata_blend_read_data(reader, gpd->adt);
@@ -219,7 +219,7 @@ void BKE_gpencil_blend_read_data(BlendDataReader *reader, bGPdata *gpd)
gpd->runtime.sbuffer_size = 0;
gpd->runtime.tot_cp_points = 0;
- /* relink palettes (old palettes deprecated, only to convert old files) */
+ /* Relink palettes (old palettes deprecated, only to convert old files). */
BLO_read_list(reader, &gpd->palettes);
if (gpd->palettes.first != NULL) {
LISTBASE_FOREACH (bGPDpalette *, palette, &gpd->palettes) {
@@ -227,14 +227,14 @@ void BKE_gpencil_blend_read_data(BlendDataReader *reader, bGPdata *gpd)
}
}
- /* materials */
+ /* Materials. */
BLO_read_pointer_array(reader, (void **)&gpd->mat);
- /* relink layers */
+ /* Relink layers. */
BLO_read_list(reader, &gpd->layers);
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
- /* relink frames */
+ /* Relink frames. */
BLO_read_list(reader, &gpl->frames);
BLO_read_data_address(reader, &gpl->actframe);
@@ -245,23 +245,23 @@ void BKE_gpencil_blend_read_data(BlendDataReader *reader, bGPdata *gpd)
BLO_read_list(reader, &gpl->mask_layers);
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
- /* relink strokes (and their points) */
+ /* Relink strokes (and their points). */
BLO_read_list(reader, &gpf->strokes);
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
- /* relink stroke points array */
+ /* Relink stroke points array. */
BLO_read_data_address(reader, &gps->points);
- /* Relink geometry*/
+ /* Relink geometry. */
BLO_read_data_address(reader, &gps->triangles);
- /* relink stroke edit curve. */
+ /* Relink stroke edit curve. */
BLO_read_data_address(reader, &gps->editcurve);
if (gps->editcurve != NULL) {
- /* relink curve point array */
+ /* Relink curve point array. */
BLO_read_data_address(reader, &gps->editcurve->curve_points);
}
- /* relink weight data */
+ /* Relink weight data. */
if (gps->dvert) {
BLO_read_data_address(reader, &gps->dvert);
BKE_defvert_blend_read(reader, gps->totpoints, gps->dvert);
@@ -458,7 +458,7 @@ void BKE_gpencil_free_frames(bGPDlayer *gpl)
void BKE_gpencil_free_layer_masks(bGPDlayer *gpl)
{
- /* Free masks.*/
+ /* Free masks. */
bGPDlayer_Mask *mask_next = NULL;
for (bGPDlayer_Mask *mask = gpl->mask_layers.first; mask; mask = mask_next) {
mask_next = mask->next;
@@ -482,7 +482,7 @@ void BKE_gpencil_free_layers(ListBase *list)
/* free layers and their data */
BKE_gpencil_free_frames(gpl);
- /* Free masks.*/
+ /* Free masks. */
BKE_gpencil_free_layer_masks(gpl);
BLI_freelinkN(list, gpl);
@@ -1076,12 +1076,7 @@ bGPDlayer *BKE_gpencil_layer_duplicate(const bGPDlayer *gpl_src,
gpl_dst->prev = gpl_dst->next = NULL;
/* Copy masks. */
- BLI_listbase_clear(&gpl_dst->mask_layers);
- LISTBASE_FOREACH (bGPDlayer_Mask *, mask_src, &gpl_src->mask_layers) {
- bGPDlayer_Mask *mask_dst = MEM_dupallocN(mask_src);
- mask_dst->prev = mask_dst->next = NULL;
- BLI_addtail(&gpl_dst->mask_layers, mask_dst);
- }
+ BKE_gpencil_layer_mask_copy(gpl_src, gpl_dst);
/* copy frames */
BLI_listbase_clear(&gpl_dst->frames);
@@ -1122,13 +1117,8 @@ void BKE_gpencil_layer_copy_settings(const bGPDlayer *gpl_src, bGPDlayer *gpl_ds
copy_v3_v3(gpl_dst->scale, gpl_src->scale);
copy_m4_m4(gpl_dst->layer_mat, gpl_src->layer_mat);
copy_m4_m4(gpl_dst->layer_invmat, gpl_src->layer_invmat);
- /* Use Lights flag. */
- if (gpl_src->flag & GP_LAYER_USE_LIGHTS) {
- gpl_dst->flag |= GP_LAYER_USE_LIGHTS;
- }
- else {
- gpl_dst->flag &= ~GP_LAYER_USE_LIGHTS;
- }
+ gpl_dst->blend_mode = gpl_src->blend_mode;
+ gpl_dst->flag = gpl_src->flag;
}
/**
@@ -1647,6 +1637,41 @@ void BKE_gpencil_layer_mask_sort_all(bGPdata *gpd)
}
}
+/**
+ * Make a copy of a given gpencil mask layers.
+ */
+void BKE_gpencil_layer_mask_copy(const bGPDlayer *gpl_src, bGPDlayer *gpl_dst)
+{
+ BLI_listbase_clear(&gpl_dst->mask_layers);
+ LISTBASE_FOREACH (bGPDlayer_Mask *, mask_src, &gpl_src->mask_layers) {
+ bGPDlayer_Mask *mask_dst = MEM_dupallocN(mask_src);
+ mask_dst->prev = mask_dst->next = NULL;
+ BLI_addtail(&gpl_dst->mask_layers, mask_dst);
+ }
+}
+
+/**
+ * Clean any invalid mask layer.
+ */
+void BKE_gpencil_layer_mask_cleanup(bGPdata *gpd, bGPDlayer *gpl)
+{
+ LISTBASE_FOREACH_MUTABLE (bGPDlayer_Mask *, mask, &gpl->mask_layers) {
+ if (BKE_gpencil_layer_named_get(gpd, mask->name) == NULL) {
+ BKE_gpencil_layer_mask_remove(gpl, mask);
+ }
+ }
+}
+
+/**
+ * Clean any invalid mask layer for all layers.
+ */
+void BKE_gpencil_layer_mask_cleanup_all_layers(bGPdata *gpd)
+{
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ BKE_gpencil_layer_mask_cleanup(gpd, gpl);
+ }
+}
+
static int gpencil_cb_cmp_frame(void *thunk, const void *a, const void *b)
{
const bGPDframe *frame_a = a;
diff --git a/source/blender/blenkernel/intern/gpencil_curve.c b/source/blender/blenkernel/intern/gpencil_curve.c
index 906d0fb0792..344be7bc0f5 100644
--- a/source/blender/blenkernel/intern/gpencil_curve.c
+++ b/source/blender/blenkernel/intern/gpencil_curve.c
@@ -242,8 +242,8 @@ static int gpencil_get_stroke_material_fromcurve(
float color_fill[4] = {0.0f, 0.0f, 0.0f, 0.0f};
/* If the curve has 2 materials, the first is considered as Fill and the second as Stroke.
- * If the has only one material, if the name contains _stroke, the is used
- * as stroke, else as fill.*/
+ * If the has only one material, if the name contains "_stroke",
+ * it's used as a stroke, otherwise as fill. */
if (ob_cu->totcol >= 2) {
*do_stroke = true;
*do_fill = true;
@@ -350,7 +350,7 @@ static void gpencil_convert_spline(Main *bmain,
/* Assign material index to stroke. */
gps->mat_nr = r_idx;
- /* Add stroke to frame.*/
+ /* Add stroke to frame. */
BLI_addtail(&gpf->strokes, gps);
float *coord_array = NULL;
diff --git a/source/blender/blenkernel/intern/gpencil_geom.c b/source/blender/blenkernel/intern/gpencil_geom.c
index 982fc2abd65..077c1a65243 100644
--- a/source/blender/blenkernel/intern/gpencil_geom.c
+++ b/source/blender/blenkernel/intern/gpencil_geom.c
@@ -793,6 +793,7 @@ bool BKE_gpencil_stroke_smooth(bGPDstroke *gps, int i, float inf)
{
bGPDspoint *pt = &gps->points[i];
float sco[3] = {0.0f};
+ const bool is_cyclic = (gps->flag & GP_STROKE_CYCLIC) != 0;
/* Do nothing if not enough points to smooth out */
if (gps->totpoints <= 2) {
@@ -802,7 +803,7 @@ bool BKE_gpencil_stroke_smooth(bGPDstroke *gps, int i, float inf)
/* Only affect endpoints by a fraction of the normal strength,
* to prevent the stroke from shrinking too much
*/
- if (ELEM(i, 0, gps->totpoints - 1)) {
+ if (!is_cyclic && ELEM(i, 0, gps->totpoints - 1)) {
inf *= 0.1f;
}
@@ -828,8 +829,22 @@ bool BKE_gpencil_stroke_smooth(bGPDstroke *gps, int i, float inf)
int before = i - step;
int after = i + step;
- CLAMP_MIN(before, 0);
- CLAMP_MAX(after, gps->totpoints - 1);
+ if (is_cyclic) {
+ if (before < 0) {
+ /* Sub to end point (before is already negative). */
+ before = gps->totpoints + before;
+ CLAMP(before, 0, gps->totpoints - 1);
+ }
+ if (after > gps->totpoints - 1) {
+ /* Add to start point. */
+ after = after - gps->totpoints;
+ CLAMP(after, 0, gps->totpoints - 1);
+ }
+ }
+ else {
+ CLAMP_MIN(before, 0);
+ CLAMP_MAX(after, gps->totpoints - 1);
+ }
pt1 = &gps->points[before];
pt2 = &gps->points[after];
@@ -855,6 +870,7 @@ bool BKE_gpencil_stroke_smooth(bGPDstroke *gps, int i, float inf)
bool BKE_gpencil_stroke_smooth_strength(bGPDstroke *gps, int point_index, float influence)
{
bGPDspoint *ptb = &gps->points[point_index];
+ const bool is_cyclic = (gps->flag & GP_STROKE_CYCLIC) != 0;
/* Do nothing if not enough points */
if ((gps->totpoints <= 2) || (point_index < 1)) {
@@ -862,7 +878,7 @@ bool BKE_gpencil_stroke_smooth_strength(bGPDstroke *gps, int point_index, float
}
/* Only affect endpoints by a fraction of the normal influence */
float inf = influence;
- if (ELEM(point_index, 0, gps->totpoints - 1)) {
+ if (!is_cyclic && ELEM(point_index, 0, gps->totpoints - 1)) {
inf *= 0.01f;
}
/* Limit max influence to reduce pop effect. */
@@ -884,9 +900,22 @@ bool BKE_gpencil_stroke_smooth_strength(bGPDstroke *gps, int point_index, float
int before = point_index - step;
int after = point_index + step;
- CLAMP_MIN(before, 0);
- CLAMP_MAX(after, gps->totpoints - 1);
-
+ if (is_cyclic) {
+ if (before < 0) {
+ /* Sub to end point (before is already negative). */
+ before = gps->totpoints + before;
+ CLAMP(before, 0, gps->totpoints - 1);
+ }
+ if (after > gps->totpoints - 1) {
+ /* Add to start point. */
+ after = after - gps->totpoints;
+ CLAMP(after, 0, gps->totpoints - 1);
+ }
+ }
+ else {
+ CLAMP_MIN(before, 0);
+ CLAMP_MAX(after, gps->totpoints - 1);
+ }
pt1 = &gps->points[before];
pt2 = &gps->points[after];
@@ -919,6 +948,7 @@ bool BKE_gpencil_stroke_smooth_strength(bGPDstroke *gps, int point_index, float
bool BKE_gpencil_stroke_smooth_thickness(bGPDstroke *gps, int point_index, float influence)
{
bGPDspoint *ptb = &gps->points[point_index];
+ const bool is_cyclic = (gps->flag & GP_STROKE_CYCLIC) != 0;
/* Do nothing if not enough points */
if ((gps->totpoints <= 2) || (point_index < 1)) {
@@ -926,7 +956,7 @@ bool BKE_gpencil_stroke_smooth_thickness(bGPDstroke *gps, int point_index, float
}
/* Only affect endpoints by a fraction of the normal influence */
float inf = influence;
- if (ELEM(point_index, 0, gps->totpoints - 1)) {
+ if (!is_cyclic && ELEM(point_index, 0, gps->totpoints - 1)) {
inf *= 0.01f;
}
/* Limit max influence to reduce pop effect. */
@@ -948,9 +978,22 @@ bool BKE_gpencil_stroke_smooth_thickness(bGPDstroke *gps, int point_index, float
int before = point_index - step;
int after = point_index + step;
- CLAMP_MIN(before, 0);
- CLAMP_MAX(after, gps->totpoints - 1);
-
+ if (is_cyclic) {
+ if (before < 0) {
+ /* Sub to end point (before is already negative). */
+ before = gps->totpoints + before;
+ CLAMP(before, 0, gps->totpoints - 1);
+ }
+ if (after > gps->totpoints - 1) {
+ /* Add to start point. */
+ after = after - gps->totpoints;
+ CLAMP(after, 0, gps->totpoints - 1);
+ }
+ }
+ else {
+ CLAMP_MIN(before, 0);
+ CLAMP_MAX(after, gps->totpoints - 1);
+ }
pt1 = &gps->points[before];
pt2 = &gps->points[after];
@@ -982,6 +1025,7 @@ bool BKE_gpencil_stroke_smooth_thickness(bGPDstroke *gps, int point_index, float
bool BKE_gpencil_stroke_smooth_uv(bGPDstroke *gps, int point_index, float influence)
{
bGPDspoint *ptb = &gps->points[point_index];
+ const bool is_cyclic = (gps->flag & GP_STROKE_CYCLIC) != 0;
/* Do nothing if not enough points */
if (gps->totpoints <= 2) {
@@ -993,9 +1037,22 @@ bool BKE_gpencil_stroke_smooth_uv(bGPDstroke *gps, int point_index, float influe
int before = point_index - 1;
int after = point_index + 1;
- CLAMP_MIN(before, 0);
- CLAMP_MAX(after, gps->totpoints - 1);
-
+ if (is_cyclic) {
+ if (before < 0) {
+ /* Sub to end point (before is already negative). */
+ before = gps->totpoints + before;
+ CLAMP(before, 0, gps->totpoints - 1);
+ }
+ if (after > gps->totpoints - 1) {
+ /* Add to start point. */
+ after = after - gps->totpoints;
+ CLAMP(after, 0, gps->totpoints - 1);
+ }
+ }
+ else {
+ CLAMP_MIN(before, 0);
+ CLAMP_MAX(after, gps->totpoints - 1);
+ }
pta = &gps->points[before];
ptc = &gps->points[after];
@@ -1993,7 +2050,7 @@ void BKE_gpencil_stroke_subdivide(bGPdata *gpd, bGPDstroke *gps, int level, int
MEM_SAFE_FREE(temp_points);
MEM_SAFE_FREE(temp_dverts);
- /* move points to smooth stroke (not simple type )*/
+ /* Move points to smooth stroke (not simple type). */
if (type != GP_SUBDIV_SIMPLE) {
/* duplicate points in a temp area with the new subdivide data */
temp_points = MEM_dupallocN(gps->points);
@@ -2076,7 +2133,7 @@ void BKE_gpencil_stroke_merge_distance(bGPdata *gpd,
else {
pt->flag |= GP_SPOINT_TAG;
}
- /* Jump to next pair of points, keeping first point segment equals.*/
+ /* Jump to next pair of points, keeping first point segment equals. */
step++;
}
else {
@@ -2423,9 +2480,9 @@ bool BKE_gpencil_convert_mesh(Main *bmain,
/* Use evaluated data to get mesh with all modifiers on top. */
Object *ob_eval = (Object *)DEG_get_evaluated_object(depsgraph, ob_mesh);
- Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval);
- MPoly *mp, *mpoly = me_eval->mpoly;
- MLoop *mloop = me_eval->mloop;
+ const Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval);
+ const MPoly *mpoly = me_eval->mpoly;
+ const MLoop *mloop = me_eval->mloop;
int mpoly_len = me_eval->totpoly;
char element_name[200];
@@ -2458,8 +2515,9 @@ bool BKE_gpencil_convert_mesh(Main *bmain,
bGPDframe *gpf_fill = BKE_gpencil_layer_frame_get(
gpl_fill, CFRA + frame_offset, GP_GETFRAME_ADD_NEW);
int i;
- for (i = 0, mp = mpoly; i < mpoly_len; i++, mp++) {
- MLoop *ml = &mloop[mp->loopstart];
+ for (i = 0; i < mpoly_len; i++) {
+ const MPoly *mp = &mpoly[i];
+
/* Find material. */
int mat_idx = 0;
Material *ma = BKE_object_material_get(ob_mesh, mp->mat_nr + 1);
@@ -2482,8 +2540,10 @@ bool BKE_gpencil_convert_mesh(Main *bmain,
gps_fill->flag |= GP_STROKE_CYCLIC;
/* Add points to strokes. */
- for (int j = 0; j < mp->totloop; j++, ml++) {
- MVert *mv = &me_eval->mvert[ml->v];
+ for (int j = 0; j < mp->totloop; j++) {
+ const MLoop *ml = &mloop[mp->loopstart + j];
+ const MVert *mv = &me_eval->mvert[ml->v];
+
bGPDspoint *pt = &gps_fill->points[j];
copy_v3_v3(&pt->x, mv->co);
mul_m4_v3(matrix, &pt->x);
@@ -2559,7 +2619,7 @@ void BKE_gpencil_transform(bGPdata *gpd, const float mat[4][4])
}
/* Used for "move only origins" in object_data_transform.c */
-int BKE_gpencil_stroke_point_count(bGPdata *gpd)
+int BKE_gpencil_stroke_point_count(const bGPdata *gpd)
{
int total_points = 0;
@@ -2567,7 +2627,7 @@ int BKE_gpencil_stroke_point_count(bGPdata *gpd)
return 0;
}
- LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ LISTBASE_FOREACH (const 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.
@@ -2576,7 +2636,7 @@ int BKE_gpencil_stroke_point_count(bGPdata *gpd)
continue;
}
- LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
+ LISTBASE_FOREACH (const bGPDframe *, gpf, &gpl->frames) {
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
total_points += gps->totpoints;
}
@@ -2811,7 +2871,7 @@ static void gpencil_stroke_join_islands(bGPdata *gpd,
MDeformVert *dvert_src = NULL;
MDeformVert *dvert_dst = NULL;
- /* Copy weights (last before)*/
+ /* Copy weights (last before). */
e1 = 0;
e2 = 0;
for (int i = 0; i < totpoints; i++) {
@@ -3751,11 +3811,11 @@ static ListBase *gpencil_stroke_perimeter_ex(const bGPdata *gpd,
last_prev_pt[0] -= 1.0f;
}
- /* generate points for start cap */
+ /* Generate points for start cap. */
num_perimeter_points += generate_perimeter_cap(
first_pt, first_next_pt, first_radius, perimeter_right_side, subdivisions, gps->caps[0]);
- /* generate perimeter points */
+ /* Generate perimeter points. */
float curr_pt[3], next_pt[3], prev_pt[3];
float vec_next[2], vec_prev[2];
float nvec_next[2], nvec_prev[2];
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index 58715ac2e05..a67e78ceea0 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -54,15 +54,15 @@
static CLG_LogRef LOG = {"bke.idprop"};
-/*local size table.*/
+/* Local size table. */
static size_t idp_size_table[] = {
1, /*strings*/
sizeof(int),
sizeof(float),
- sizeof(float[3]), /*Vector type, deprecated*/
- sizeof(float[16]), /*Matrix type, deprecated*/
- 0, /*arrays don't have a fixed size*/
- sizeof(ListBase), /*Group type*/
+ sizeof(float[3]), /* Vector type, deprecated. */
+ sizeof(float[16]), /* Matrix type, deprecated. */
+ 0, /* Arrays don't have a fixed size. */
+ sizeof(ListBase), /* Group type. */
sizeof(void *),
sizeof(double),
};
@@ -99,12 +99,12 @@ IDProperty *IDP_CopyIDPArray(const IDProperty *array, const int flag)
narray->data.pointer = MEM_dupallocN(array->data.pointer);
for (int i = 0; i < narray->len; i++) {
- /* ok, the copy functions always allocate a new structure,
+ /* OK, the copy functions always allocate a new structure,
* which doesn't work here. instead, simply copy the
* contents of the new structure into the array cell,
* then free it. this makes for more maintainable
* code than simply re-implementing the copy functions
- * in this loop.*/
+ * in this loop. */
IDProperty *tmp = IDP_CopyProperty_ex(GETPROP(narray, i), flag);
memcpy(GETPROP(narray, i), tmp, sizeof(IDProperty));
MEM_freeN(tmp);
@@ -228,7 +228,7 @@ static void idp_resize_group_array(IDProperty *prop, int newlen, void *newarr)
}
}
-/*this function works for strings too!*/
+/* This function works for strings too! */
void IDP_ResizeArray(IDProperty *prop, int newlen)
{
const bool is_grow = newlen >= prop->len;
@@ -390,8 +390,8 @@ void IDP_ConcatStringC(IDProperty *prop, const char *st)
BLI_assert(prop->type == IDP_STRING);
int newlen = prop->len + (int)strlen(st);
- /* we have to remember that prop->len includes the null byte for strings.
- * so there's no need to add +1 to the resize function.*/
+ /* We have to remember that prop->len includes the null byte for strings.
+ * so there's no need to add +1 to the resize function. */
IDP_ResizeArray(prop, newlen);
strcat(prop->data.pointer, st);
}
@@ -400,8 +400,8 @@ void IDP_ConcatString(IDProperty *str1, IDProperty *append)
{
BLI_assert(append->type == IDP_STRING);
- /* since ->len for strings includes the NULL byte, we have to subtract one or
- * we'll get an extra null byte after each concatenation operation.*/
+ /* Since ->len for strings includes the NULL byte, we have to subtract one or
+ * we'll get an extra null byte after each concatenation operation. */
int newlen = str1->len + append->len - 1;
IDP_ResizeArray(str1, newlen);
strcat(str1->data.pointer, append->data.pointer);
@@ -775,10 +775,10 @@ IDProperty *IDP_GetProperties(ID *id, const bool create_if_needed)
if (create_if_needed) {
id->properties = MEM_callocN(sizeof(IDProperty), "IDProperty");
id->properties->type = IDP_GROUP;
- /* don't overwrite the data's name and type
+ /* NOTE(campbell): Don't overwrite the data's name and type
* some functions might need this if they
- * don't have a real ID, should be named elsewhere - Campbell */
- /* strcpy(id->name, "top_level_group");*/
+ * don't have a real ID, should be named elsewhere. */
+ // strcpy(id->name, "top_level_group");
}
return id->properties;
}
@@ -1106,7 +1106,7 @@ void IDP_WriteProperty_OnlyData(const IDProperty *prop, BlendWriter *writer);
static void IDP_WriteArray(const IDProperty *prop, BlendWriter *writer)
{
- /*REMEMBER to set totalen to len in the linking code!!*/
+ /* Remember to set #IDProperty.totallen to len in the linking code! */
if (prop->data.pointer) {
BLO_write_raw(writer, MEM_allocN_len(prop->data.pointer), prop->data.pointer);
@@ -1123,7 +1123,7 @@ static void IDP_WriteArray(const IDProperty *prop, BlendWriter *writer)
static void IDP_WriteIDPArray(const IDProperty *prop, BlendWriter *writer)
{
- /*REMEMBER to set totalen to len in the linking code!!*/
+ /* Remember to set #IDProperty.totallen to len in the linking code! */
if (prop->data.pointer) {
const IDProperty *array = prop->data.pointer;
@@ -1137,7 +1137,7 @@ static void IDP_WriteIDPArray(const IDProperty *prop, BlendWriter *writer)
static void IDP_WriteString(const IDProperty *prop, BlendWriter *writer)
{
- /*REMEMBER to set totalen to len in the linking code!!*/
+ /* Remember to set #IDProperty.totallen to len in the linking code! */
BLO_write_raw(writer, (size_t)prop->len, prop->data.pointer);
}
@@ -1219,7 +1219,7 @@ static void IDP_DirectLinkArray(IDProperty *prop, BlendDataReader *reader)
static void IDP_DirectLinkString(IDProperty *prop, BlendDataReader *reader)
{
- /*since we didn't save the extra string buffer, set totallen to len.*/
+ /* Since we didn't save the extra string buffer, set totallen to len. */
prop->totallen = prop->len;
BLO_read_data_address(reader, &prop->data.pointer);
}
@@ -1230,7 +1230,7 @@ static void IDP_DirectLinkGroup(IDProperty *prop, BlendDataReader *reader)
BLO_read_list(reader, lb);
- /*Link child id properties now*/
+ /* Link child id properties now. */
LISTBASE_FOREACH (IDProperty *, loop, &prop->data.group) {
IDP_DirectLinkProperty(loop, reader);
}
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 7a3619154a6..740c9b3864c 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -1056,9 +1056,11 @@ Image *BKE_image_add_generated(Main *bmain,
return ima;
}
-/* Create an image image from ibuf. The refcount of ibuf is increased,
+/**
+ * Create an image from ibuf. The refcount of ibuf is increased,
* caller should take care to drop its reference by calling
- * IMB_freeImBuf if needed. */
+ * #IMB_freeImBuf if needed.
+ */
Image *BKE_image_add_from_imbuf(Main *bmain, ImBuf *ibuf, const char *name)
{
/* on save, type is changed to FILE in editsima.c */
@@ -3208,7 +3210,7 @@ Image *BKE_image_ensure_viewer(Main *bmain, int type, const char *name)
ima = image_alloc(bmain, name, IMA_SRC_VIEWER, type);
}
- /* happens on reload, imagewindow cannot be image user when hidden*/
+ /* Happens on reload, imagewindow cannot be image user when hidden. */
if (ima->id.us == 0) {
id_us_ensure_real(&ima->id);
}
@@ -4349,7 +4351,7 @@ static ImBuf *load_movie_single(Image *ima, ImageUser *iuser, int frame, const i
BKE_image_user_file_path(&iuser_t, ima, str);
- /* FIXME: make several stream accessible in image editor, too*/
+ /* FIXME: make several stream accessible in image editor, too. */
ia->anim = openanim(str, flags, 0, ima->colorspace_settings.name);
/* let's initialize this user */
@@ -5188,7 +5190,7 @@ bool BKE_image_has_ibuf(Image *ima, ImageUser *iuser)
return ibuf != NULL;
}
-/* ******** Pool for image buffers ******** */
+/* ******** Pool for image buffers ******** */
typedef struct ImagePoolItem {
struct ImagePoolItem *next, *prev;
diff --git a/source/blender/blenkernel/intern/image_save.c b/source/blender/blenkernel/intern/image_save.c
index e571499ba8e..b68cd9e4d2d 100644
--- a/source/blender/blenkernel/intern/image_save.c
+++ b/source/blender/blenkernel/intern/image_save.c
@@ -207,7 +207,7 @@ static bool image_save_single(ReportList *reports,
goto cleanup;
}
- /* it shouldn't ever happen*/
+ /* It shouldn't ever happen. */
if ((BLI_findstring(&rr->views, STEREO_LEFT_NAME, offsetof(RenderView, name)) == NULL) ||
(BLI_findstring(&rr->views, STEREO_RIGHT_NAME, offsetof(RenderView, name)) == NULL)) {
BKE_reportf(reports,
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index bdc763cf4ca..f365e759221 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -262,7 +262,7 @@ static AdrBit2Path *adrcode_bitmaps_to_paths(int blocktype, int adrcode, int *to
/* Object types */
static const char *ob_adrcodes_to_paths(int adrcode, int *array_index)
{
- /* set array index like this in-case nothing sets it correctly */
+ /* Set array index like this in-case nothing sets it correctly. */
*array_index = 0;
/* result depends on adrcode */
@@ -377,7 +377,7 @@ static const char *ob_adrcodes_to_paths(int adrcode, int *array_index)
*/
static const char *pchan_adrcodes_to_paths(int adrcode, int *array_index)
{
- /* set array index like this in-case nothing sets it correctly */
+ /* Set array index like this in-case nothing sets it correctly. */
*array_index = 0;
/* result depends on adrcode */
@@ -434,7 +434,7 @@ static const char *pchan_adrcodes_to_paths(int adrcode, int *array_index)
/* Constraint types */
static const char *constraint_adrcodes_to_paths(int adrcode, int *array_index)
{
- /* set array index like this in-case nothing sets it correctly */
+ /* Set array index like this in-case nothing sets it correctly. */
*array_index = 0;
/* result depends on adrcode */
@@ -605,7 +605,7 @@ static const char *mtex_adrcodes_to_paths(int adrcode, int *UNUSED(array_index))
/* Texture types */
static const char *texture_adrcodes_to_paths(int adrcode, int *array_index)
{
- /* set array index like this in-case nothing sets it correctly */
+ /* Set array index like this in-case nothing sets it correctly. */
*array_index = 0;
/* result depends on adrcode */
@@ -692,7 +692,7 @@ static const char *texture_adrcodes_to_paths(int adrcode, int *array_index)
/* Material Types */
static const char *material_adrcodes_to_paths(int adrcode, int *array_index)
{
- /* set array index like this in-case nothing sets it correctly */
+ /* Set array index like this in-case nothing sets it correctly. */
*array_index = 0;
/* result depends on adrcode */
@@ -785,7 +785,7 @@ static const char *material_adrcodes_to_paths(int adrcode, int *array_index)
/* Camera Types */
static const char *camera_adrcodes_to_paths(int adrcode, int *array_index)
{
- /* set array index like this in-case nothing sets it correctly */
+ /* Set array index like this in-case nothing sets it correctly. */
*array_index = 0;
/* result depends on adrcode */
@@ -830,7 +830,7 @@ static const char *camera_adrcodes_to_paths(int adrcode, int *array_index)
/* Light Types */
static const char *light_adrcodes_to_paths(int adrcode, int *array_index)
{
- /* set array index like this in-case nothing sets it correctly */
+ /* Set array index like this in-case nothing sets it correctly. */
*array_index = 0;
/* result depends on adrcode */
@@ -875,7 +875,7 @@ static const char *light_adrcodes_to_paths(int adrcode, int *array_index)
/* Sound Types */
static const char *sound_adrcodes_to_paths(int adrcode, int *array_index)
{
- /* set array index like this in-case nothing sets it correctly */
+ /* Set array index like this in-case nothing sets it correctly. */
*array_index = 0;
/* result depends on adrcode */
@@ -901,7 +901,7 @@ static const char *sound_adrcodes_to_paths(int adrcode, int *array_index)
/* World Types */
static const char *world_adrcodes_to_paths(int adrcode, int *array_index)
{
- /* set array index like this in-case nothing sets it correctly */
+ /* Set array index like this in-case nothing sets it correctly. */
*array_index = 0;
/* result depends on adrcode */
@@ -947,7 +947,7 @@ static const char *world_adrcodes_to_paths(int adrcode, int *array_index)
/* Particle Types */
static const char *particle_adrcodes_to_paths(int adrcode, int *array_index)
{
- /* set array index like this in-case nothing sets it correctly */
+ /* Set array index like this in-case nothing sets it correctly. */
*array_index = 0;
/* result depends on adrcode */
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index 073276b7011..6cc90f86b4a 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -315,11 +315,11 @@ Key *BKE_key_add(Main *bmain, ID *id) /* common function */
return key;
}
-/* Sort shape keys and Ipo curves after a change. This assumes that at most
- * one key was moved, which is a valid assumption for the places it's
- * currently being called.
+/**
+ * Sort shape keys after a change.
+ * This assumes that at most one key was moved,
+ * which is a valid assumption for the places it's currently being called.
*/
-
void BKE_key_sort(Key *key)
{
KeyBlock *kb;
@@ -2048,9 +2048,9 @@ void BKE_keyblock_convert_to_lattice(KeyBlock *kb, Lattice *lt)
/************************* Curve ************************/
-int BKE_keyblock_curve_element_count(ListBase *nurb)
+int BKE_keyblock_curve_element_count(const ListBase *nurb)
{
- Nurb *nu;
+ const Nurb *nu;
int tot = 0;
nu = nurb->first;
diff --git a/source/blender/blenkernel/intern/keyconfig.c b/source/blender/blenkernel/intern/keyconfig.c
index 552760c9b34..d25f475c140 100644
--- a/source/blender/blenkernel/intern/keyconfig.c
+++ b/source/blender/blenkernel/intern/keyconfig.c
@@ -55,7 +55,7 @@ wmKeyConfigPref *BKE_keyconfig_pref_ensure(UserDef *userdef, const char *kc_idna
}
if (kpt->prop == NULL) {
IDPropertyTemplate val = {0};
- kpt->prop = IDP_New(IDP_GROUP, &val, kc_idname); /* name is unimportant */
+ kpt->prop = IDP_New(IDP_GROUP, &val, kc_idname); /* name is unimportant. */
}
return kpt;
}
diff --git a/source/blender/blenkernel/intern/lattice_deform.c b/source/blender/blenkernel/intern/lattice_deform.c
index a8126cb5538..a3133b58a0a 100644
--- a/source/blender/blenkernel/intern/lattice_deform.c
+++ b/source/blender/blenkernel/intern/lattice_deform.c
@@ -93,18 +93,18 @@ LatticeDeformData *BKE_lattice_deform_data_create(const Object *oblatt, const Ob
/* for example with a particle system: (ob == NULL) */
if (ob == NULL) {
- /* in deformspace, calc matrix */
+ /* In deform-space, calc matrix. */
invert_m4_m4(latmat, oblatt->obmat);
/* back: put in deform array */
invert_m4_m4(imat, latmat);
}
else {
- /* in deformspace, calc matrix */
+ /* In deform-space, calc matrix. */
invert_m4_m4(imat, oblatt->obmat);
mul_m4_m4m4(latmat, imat, ob->obmat);
- /* back: put in deform array */
+ /* back: put in deform array. */
invert_m4_m4(imat, latmat);
}
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index 2ac10586fd9..d49eb0d4da8 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -676,10 +676,10 @@ LayerCollection *BKE_layer_collection_activate_parent(ViewLayer *view_layer, Lay
/**
* Recursively get the count of collections
*/
-static int collection_count(ListBase *lb)
+static int collection_count(const ListBase *lb)
{
int i = 0;
- LISTBASE_FOREACH (LayerCollection *, lc, lb) {
+ LISTBASE_FOREACH (const LayerCollection *, lc, lb) {
i += collection_count(&lc->layer_collections) + 1;
}
return i;
@@ -689,7 +689,7 @@ static int collection_count(ListBase *lb)
* Get the total number of collections
* (including all the nested collections)
*/
-int BKE_layer_collection_count(ViewLayer *view_layer)
+int BKE_layer_collection_count(const ViewLayer *view_layer)
{
return collection_count(&view_layer->layer_collections);
}
@@ -819,7 +819,7 @@ static void layer_collection_sync(ViewLayer *view_layer,
}
/* We separate restrict viewport and visible view layer because a layer collection can be
- * hidden in the view layer yet (locally) visible in a viewport (if it is not restricted).*/
+ * hidden in the view layer yet (locally) visible in a viewport (if it is not restricted). */
if (child_restrict & COLLECTION_RESTRICT_VIEWPORT) {
lc->runtime_flag |= LAYER_COLLECTION_RESTRICT_VIEWPORT;
}
@@ -1000,7 +1000,7 @@ void BKE_main_collection_sync_remap(const Main *bmain)
/* On remapping of object or collection pointers free caches. */
/* TODO: try to make this faster */
- for (const Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
+ for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
MEM_SAFE_FREE(view_layer->object_bases_array);
@@ -1009,6 +1009,10 @@ void BKE_main_collection_sync_remap(const Main *bmain)
view_layer->object_bases_hash = NULL;
}
}
+
+ BKE_collection_object_cache_free(scene->master_collection);
+ DEG_id_tag_update_ex((Main *)bmain, &scene->master_collection->id, ID_RECALC_COPY_ON_WRITE);
+ DEG_id_tag_update_ex((Main *)bmain, &scene->id, ID_RECALC_COPY_ON_WRITE);
}
for (Collection *collection = bmain->collections.first; collection;
@@ -1500,7 +1504,7 @@ static LayerCollection *find_layer_collection_by_scene_collection(LayerCollectio
/**
* Return the first matching LayerCollection in the ViewLayer for the Collection.
*/
-LayerCollection *BKE_layer_collection_first_from_scene_collection(ViewLayer *view_layer,
+LayerCollection *BKE_layer_collection_first_from_scene_collection(const ViewLayer *view_layer,
const Collection *collection)
{
LISTBASE_FOREACH (LayerCollection *, layer_collection, &view_layer->layer_collections) {
@@ -1516,7 +1520,7 @@ LayerCollection *BKE_layer_collection_first_from_scene_collection(ViewLayer *vie
/**
* See if view layer has the scene collection linked directly, or indirectly (nested)
*/
-bool BKE_view_layer_has_collection(ViewLayer *view_layer, const Collection *collection)
+bool BKE_view_layer_has_collection(const ViewLayer *view_layer, const Collection *collection)
{
return BKE_layer_collection_first_from_scene_collection(view_layer, collection) != NULL;
}
@@ -1823,7 +1827,7 @@ void BKE_view_layer_bases_in_mode_iterator_end(BLI_Iterator *UNUSED(iter))
/** \} */
-/* Evaluation */
+/* Evaluation. */
/* Applies object's restrict flags on top of flags coming from the collection
* and stores those in base->flag. BASE_VISIBLE_DEPSGRAPH ignores viewport flags visibility
diff --git a/source/blender/blenkernel/intern/layer_utils.c b/source/blender/blenkernel/intern/layer_utils.c
index 974a5a24e8a..10ab0a06dd0 100644
--- a/source/blender/blenkernel/intern/layer_utils.c
+++ b/source/blender/blenkernel/intern/layer_utils.c
@@ -164,11 +164,11 @@ Object **BKE_view_layer_array_from_objects_in_mode_params(ViewLayer *view_layer,
/** \name Filter Functions
* \{ */
-bool BKE_view_layer_filter_edit_mesh_has_uvs(Object *ob, void *UNUSED(user_data))
+bool BKE_view_layer_filter_edit_mesh_has_uvs(const Object *ob, void *UNUSED(user_data))
{
if (ob->type == OB_MESH) {
- Mesh *me = ob->data;
- BMEditMesh *em = me->edit_mesh;
+ const Mesh *me = ob->data;
+ const BMEditMesh *em = me->edit_mesh;
if (em != NULL) {
if (CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV) != -1) {
return true;
@@ -178,11 +178,11 @@ bool BKE_view_layer_filter_edit_mesh_has_uvs(Object *ob, void *UNUSED(user_data)
return false;
}
-bool BKE_view_layer_filter_edit_mesh_has_edges(Object *ob, void *UNUSED(user_data))
+bool BKE_view_layer_filter_edit_mesh_has_edges(const Object *ob, void *UNUSED(user_data))
{
if (ob->type == OB_MESH) {
- Mesh *me = ob->data;
- BMEditMesh *em = me->edit_mesh;
+ const Mesh *me = ob->data;
+ const BMEditMesh *em = me->edit_mesh;
if (em != NULL) {
if (em->bm->totedge != 0) {
return true;
diff --git a/source/blender/blenkernel/intern/lib_id.c b/source/blender/blenkernel/intern/lib_id.c
index b7cacba20b3..297ee565257 100644
--- a/source/blender/blenkernel/intern/lib_id.c
+++ b/source/blender/blenkernel/intern/lib_id.c
@@ -1941,13 +1941,13 @@ void BKE_library_make_local(Main *bmain,
ntree->tag &= ~LIB_TAG_DOIT;
}
- if (id->lib == NULL) {
+ if (!ID_IS_LINKED(id)) {
id->tag &= ~(LIB_TAG_EXTERN | LIB_TAG_INDIRECT | LIB_TAG_NEW);
id->flag &= ~LIB_INDIRECT_WEAK_LINK;
if (ID_IS_OVERRIDE_LIBRARY_REAL(id) &&
ELEM(lib, NULL, id->override_library->reference->lib) &&
((untagged_only == false) || !(id->tag & LIB_TAG_PRE_EXISTING))) {
- BKE_lib_override_library_free(&id->override_library, true);
+ BKE_lib_override_library_make_local(id);
}
}
/* The check on the fourth line (LIB_TAG_PRE_EXISTING) is done so it's possible to tag data
diff --git a/source/blender/blenkernel/intern/lib_id_eval.c b/source/blender/blenkernel/intern/lib_id_eval.c
new file mode 100644
index 00000000000..140fe403ac3
--- /dev/null
+++ b/source/blender/blenkernel/intern/lib_id_eval.c
@@ -0,0 +1,48 @@
+/*
+ * 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
+ *
+ * Contains management of ID's and libraries
+ * allocate and free of all library data
+ */
+
+#include "DNA_ID.h"
+#include "DNA_mesh_types.h"
+
+#include "BLI_utildefines.h"
+
+#include "BKE_lib_id.h"
+#include "BKE_mesh.h"
+
+/**
+ * Copy relatives parameters, from `id` to `id_cow`.
+ * Use handle the #ID_RECALC_PARAMETERS tag.
+ * \note Keep in sync with #ID_TYPE_SUPPORTS_PARAMS_WITHOUT_COW.
+ */
+void BKE_id_eval_properties_copy(ID *id_cow, ID *id)
+{
+ const ID_Type id_type = GS(id->name);
+ BLI_assert((id_cow->tag & LIB_TAG_COPIED_ON_WRITE) && !(id->tag & LIB_TAG_COPIED_ON_WRITE));
+ BLI_assert(ID_TYPE_SUPPORTS_PARAMS_WITHOUT_COW(id_type));
+ if (id_type == ID_ME) {
+ BKE_mesh_copy_parameters((Mesh *)id_cow, (const Mesh *)id);
+ }
+ else {
+ BLI_assert_unreachable();
+ }
+}
diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c
index c93971e7b11..595e470876d 100644
--- a/source/blender/blenkernel/intern/lib_override.c
+++ b/source/blender/blenkernel/intern/lib_override.c
@@ -52,12 +52,17 @@
#include "BKE_report.h"
#include "BKE_scene.h"
+#include "BLO_readfile.h"
+
#include "BLI_ghash.h"
+#include "BLI_linklist.h"
#include "BLI_listbase.h"
#include "BLI_string.h"
#include "BLI_task.h"
#include "BLI_utildefines.h"
+#include "PIL_time.h"
+
#include "RNA_access.h"
#include "RNA_types.h"
@@ -466,11 +471,14 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain,
typedef struct LibOverrideGroupTagData {
Main *bmain;
+ Scene *scene;
ID *id_root;
uint tag;
uint missing_tag;
/* Whether we are looping on override data, or their references (linked) one. */
bool is_override;
+ /* Whether we are creating new override, or resyncing existing one. */
+ bool is_resync;
} LibOverrideGroupTagData;
/* Tag all IDs in dependency relationships within an override hierarchy/group.
@@ -591,7 +599,9 @@ static void lib_override_linked_group_tag_recursive(LibOverrideGroupTagData *dat
static void lib_override_linked_group_tag(LibOverrideGroupTagData *data)
{
Main *bmain = data->bmain;
+ Scene *scene = data->scene;
ID *id_root = data->id_root;
+ const bool is_resync = data->is_resync;
BLI_assert(!data->is_override);
if ((id_root->tag & LIB_TAG_MISSING)) {
@@ -616,6 +626,43 @@ static void lib_override_linked_group_tag(LibOverrideGroupTagData *data)
}
}
}
+
+ /* For each object tagged for override, ensure we get at least one local or liboverride
+ * collection to host it. Avoids getting a bunch of random object in the scene's master
+ * collection when all objects' dependencies are not properly 'packed' into a single root
+ * collection. */
+ LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
+ if (ID_IS_LINKED(ob) && (ob->id.tag & data->tag) != 0) {
+ Collection *instantiating_collection = NULL;
+ Collection *instantiating_collection_override_candidate = NULL;
+ /* Loop over all collections instantiating the object, if we already have a 'locale' one we
+ * have nothing to do, otherwise try to find a 'linked' one that we can override too. */
+ while ((instantiating_collection = BKE_collection_object_find(
+ bmain, scene, instantiating_collection, ob)) != NULL) {
+ /* In (recursive) resync case, if a collection of a 'parent' lib instantiates the linked
+ * object, it is also fine. */
+ if (!ID_IS_LINKED(instantiating_collection) ||
+ (is_resync && ID_IS_LINKED(id_root) &&
+ instantiating_collection->id.lib->temp_index < id_root->lib->temp_index)) {
+ break;
+ }
+ if (ID_IS_LINKED(instantiating_collection) &&
+ (!is_resync || instantiating_collection->id.lib == id_root->lib)) {
+ instantiating_collection_override_candidate = instantiating_collection;
+ }
+ }
+
+ if (instantiating_collection == NULL &&
+ instantiating_collection_override_candidate != NULL) {
+ if ((instantiating_collection_override_candidate->id.tag & LIB_TAG_MISSING)) {
+ instantiating_collection_override_candidate->id.tag |= data->missing_tag;
+ }
+ else {
+ instantiating_collection_override_candidate->id.tag |= data->tag;
+ }
+ }
+ }
+ }
}
}
@@ -694,14 +741,16 @@ static void lib_override_overrides_group_tag(LibOverrideGroupTagData *data)
lib_override_overrides_group_tag_recursive(data);
}
-static bool lib_override_library_create_do(Main *bmain, ID *id_root)
+static bool lib_override_library_create_do(Main *bmain, Scene *scene, ID *id_root)
{
BKE_main_relations_create(bmain, 0);
LibOverrideGroupTagData data = {.bmain = bmain,
+ .scene = scene,
.id_root = id_root,
.tag = LIB_TAG_DOIT,
.missing_tag = LIB_TAG_MISSING,
- .is_override = false};
+ .is_override = false,
+ .is_resync = false};
lib_override_linked_group_tag(&data);
BKE_main_relations_tag_set(bmain, MAINIDRELATIONS_ENTRY_TAGS_PROCESSED, false);
@@ -862,7 +911,7 @@ bool BKE_lib_override_library_create(Main *bmain,
*r_id_root_override = NULL;
}
- const bool success = lib_override_library_create_do(bmain, id_root);
+ const bool success = lib_override_library_create_do(bmain, scene, id_root);
if (!success) {
return success;
@@ -958,7 +1007,7 @@ bool BKE_lib_override_library_resync(Main *bmain,
Collection *override_resync_residual_storage,
const bool do_hierarchy_enforce,
const bool do_post_process,
- ReportList *reports)
+ BlendFileReadReport *reports)
{
BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_root));
@@ -966,10 +1015,12 @@ bool BKE_lib_override_library_resync(Main *bmain,
BKE_main_relations_create(bmain, 0);
LibOverrideGroupTagData data = {.bmain = bmain,
+ .scene = scene,
.id_root = id_root,
.tag = LIB_TAG_DOIT,
.missing_tag = LIB_TAG_MISSING,
- .is_override = true};
+ .is_override = true,
+ .is_resync = true};
lib_override_overrides_group_tag(&data);
BKE_main_relations_tag_set(bmain, MAINIDRELATIONS_ENTRY_TAGS_PROCESSED, false);
@@ -1286,7 +1337,7 @@ bool BKE_lib_override_library_resync(Main *bmain,
id_root = id_root_reference->newid;
if (user_edited_overrides_deletion_count > 0) {
- BKE_reportf(reports,
+ BKE_reportf(reports != NULL ? reports->reports : NULL,
RPT_WARNING,
"During resync of data-block %s, %d obsolete overrides were deleted, that had "
"local changes defined by user",
@@ -1438,8 +1489,11 @@ static void lib_override_library_main_resync_on_library_indirect_level(
ViewLayer *view_layer,
Collection *override_resync_residual_storage,
const int library_indirect_level,
- ReportList *reports)
+ BlendFileReadReport *reports)
{
+ const bool do_reports_recursive_resync_timing = (library_indirect_level != 0);
+ const double init_time = do_reports_recursive_resync_timing ? PIL_check_seconds_timer() : 0.0;
+
BKE_main_relations_create(bmain, 0);
BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
@@ -1460,10 +1514,12 @@ static void lib_override_library_main_resync_on_library_indirect_level(
}
LibOverrideGroupTagData data = {.bmain = bmain,
+ .scene = scene,
.id_root = id->override_library->reference,
.tag = LIB_TAG_DOIT,
.missing_tag = LIB_TAG_MISSING,
- .is_override = false};
+ .is_override = false,
+ .is_resync = true};
lib_override_linked_group_tag(&data);
BKE_main_relations_tag_set(bmain, MAINIDRELATIONS_ENTRY_TAGS_PROCESSED, false);
lib_override_hierarchy_dependencies_recursive_tag(&data);
@@ -1530,6 +1586,7 @@ static void lib_override_library_main_resync_on_library_indirect_level(
(!ID_IS_LINKED(id) && library_indirect_level != 0)) {
continue;
}
+ Library *library = id->lib;
int level = 0;
/* In complex non-supported cases, with several different override hierarchies sharing
@@ -1541,12 +1598,21 @@ static void lib_override_library_main_resync_on_library_indirect_level(
id = lib_override_library_main_resync_find_root_recurse(id, &level);
id->tag &= ~LIB_TAG_LIB_OVERRIDE_NEED_RESYNC;
BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id));
+ BLI_assert(id->lib == library);
do_continue = true;
- CLOG_INFO(&LOG, 2, "Resyncing %s (%p)...", id->name, id->lib);
+ CLOG_INFO(&LOG, 2, "Resyncing %s (%p)...", id->name, library);
const bool success = BKE_lib_override_library_resync(
bmain, scene, view_layer, id, override_resync_residual_storage, false, false, reports);
CLOG_INFO(&LOG, 2, "\tSuccess: %d", success);
+ if (success) {
+ reports->count.resynced_lib_overrides++;
+ if (library_indirect_level > 0 &&
+ BLI_linklist_index(reports->resynced_lib_overrides_libraries, library) < 0) {
+ BLI_linklist_prepend(&reports->resynced_lib_overrides_libraries, library);
+ reports->resynced_lib_overrides_libraries_count++;
+ }
+ }
break;
}
FOREACH_MAIN_LISTBASE_ID_END;
@@ -1556,6 +1622,10 @@ static void lib_override_library_main_resync_on_library_indirect_level(
}
FOREACH_MAIN_LISTBASE_END;
}
+
+ if (do_reports_recursive_resync_timing) {
+ reports->duration.lib_overrides_recursive_resync += PIL_check_seconds_timer() - init_time;
+ }
}
static int lib_override_sort_libraries_func(LibraryIDLinkCallbackData *cb_data)
@@ -1633,7 +1703,7 @@ static int lib_override_libraries_index_define(Main *bmain)
void BKE_lib_override_library_main_resync(Main *bmain,
Scene *scene,
ViewLayer *view_layer,
- ReportList *reports)
+ BlendFileReadReport *reports)
{
/* We use a specific collection to gather/store all 'orphaned' override collections and objects
* generated by re-sync-process. This avoids putting them in scene's master collection. */
@@ -1688,10 +1758,12 @@ void BKE_lib_override_library_delete(Main *bmain, ID *id_root)
/* Tag all library overrides in the chains of dependencies from the given root one. */
BKE_main_relations_create(bmain, 0);
LibOverrideGroupTagData data = {.bmain = bmain,
+ .scene = NULL,
.id_root = id_root,
.tag = LIB_TAG_DOIT,
.missing_tag = LIB_TAG_MISSING,
- .is_override = true};
+ .is_override = true,
+ .is_resync = false};
lib_override_overrides_group_tag(&data);
BKE_main_relations_free(bmain);
@@ -1716,6 +1788,33 @@ void BKE_lib_override_library_delete(Main *bmain, ID *id_root)
BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
}
+/** Make given ID fully local.
+ *
+ * \note Only differs from lower-level `BKE_lib_override_library_free in infamous embedded ID
+ * cases.
+ */
+void BKE_lib_override_library_make_local(ID *id)
+{
+ BKE_lib_override_library_free(&id->override_library, true);
+
+ Key *shape_key = BKE_key_from_id(id);
+ if (shape_key != NULL) {
+ shape_key->id.flag &= ~LIB_EMBEDDED_DATA_LIB_OVERRIDE;
+ }
+
+ if (GS(id->name) == ID_SCE) {
+ Collection *master_collection = ((Scene *)id)->master_collection;
+ if (master_collection != NULL) {
+ master_collection->id.flag &= ~LIB_EMBEDDED_DATA_LIB_OVERRIDE;
+ }
+ }
+
+ bNodeTree *node_tree = ntreeFromID(id);
+ if (node_tree != NULL) {
+ node_tree->id.flag &= ~LIB_EMBEDDED_DATA_LIB_OVERRIDE;
+ }
+}
+
BLI_INLINE IDOverrideLibraryRuntime *override_library_rna_path_runtime_ensure(
IDOverrideLibrary *override)
{
diff --git a/source/blender/blenkernel/intern/lib_query.c b/source/blender/blenkernel/intern/lib_query.c
index b748061ef8a..9d2552777bf 100644
--- a/source/blender/blenkernel/intern/lib_query.c
+++ b/source/blender/blenkernel/intern/lib_query.c
@@ -83,7 +83,7 @@ bool BKE_lib_query_foreachid_process(LibraryForeachIDData *data, ID **id_pp, int
ID *old_id = *id_pp;
/* Update the callback flags with the ones defined (or forbidden) in `data` by the generic
- * caller code. */
+ * caller code. */
cb_flag = ((cb_flag | data->cb_flag) & ~data->cb_flag_clear);
/* Update the callback flags with some extra information regarding overrides: all 'loopback',
diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index a3f122115d8..371af2a95ed 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -1923,7 +1923,7 @@ static void interp_weights_uv_v2_apply(const float uv[2],
r_pt[1] += dvec[0] * uv[1];
}
-/* when a new points added - resize all shapekey array */
+/* When a new points added - resize all shape-key array. */
void BKE_mask_layer_shape_changed_add(MaskLayer *masklay,
int index,
bool do_init,
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c
index 6bef11dea76..f5d898e801b 100644
--- a/source/blender/blenkernel/intern/mball.c
+++ b/source/blender/blenkernel/intern/mball.c
@@ -158,7 +158,7 @@ static void metaball_blend_read_data(BlendDataReader *reader, ID *id)
mb->editelems = NULL;
/* Must always be cleared (meta's don't have their own edit-data). */
mb->needs_flush_to_id = 0;
- /* mb->edit_elems.first= mb->edit_elems.last= NULL;*/
+ // mb->edit_elems.first = mb->edit_elems.last = NULL;
mb->lastelem = NULL;
mb->batch_cache = NULL;
}
diff --git a/source/blender/blenkernel/intern/mball_tessellate.c b/source/blender/blenkernel/intern/mball_tessellate.c
index bb46c7b16c0..413cefd2271 100644
--- a/source/blender/blenkernel/intern/mball_tessellate.c
+++ b/source/blender/blenkernel/intern/mball_tessellate.c
@@ -272,20 +272,20 @@ static void build_bvh_spatial(PROCESS *process,
* any and all purposes, provided that this notice appears in all copies.
*/
-#define L 0 /* left direction: -x, -i */
-#define R 1 /* right direction: +x, +i */
-#define B 2 /* bottom direction: -y, -j */
-#define T 3 /* top direction: +y, +j */
-#define N 4 /* near direction: -z, -k */
-#define F 5 /* far direction: +z, +k */
-#define LBN 0 /* left bottom near corner */
-#define LBF 1 /* left bottom far corner */
-#define LTN 2 /* left top near corner */
-#define LTF 3 /* left top far corner */
-#define RBN 4 /* right bottom near corner */
-#define RBF 5 /* right bottom far corner */
-#define RTN 6 /* right top near corner */
-#define RTF 7 /* right top far corner */
+#define L 0 /* Left direction: -x, -i. */
+#define R 1 /* Right direction: +x, +i. */
+#define B 2 /* Bottom direction: -y, -j. */
+#define T 3 /* Top direction: +y, +j. */
+#define N 4 /* Near direction: -z, -k. */
+#define F 5 /* Far direction: +z, +k. */
+#define LBN 0 /* Left bottom near corner. */
+#define LBF 1 /* Left bottom far corner. */
+#define LTN 2 /* Left top near corner. */
+#define LTF 3 /* Left top far corner. */
+#define RBN 4 /* Right bottom near corner. */
+#define RBF 5 /* Right bottom far corner. */
+#define RTN 6 /* Right top near corner. */
+#define RTF 7 /* Right top far corner. */
/**
* the LBN corner of cube (i, j, k), corresponds with location
@@ -293,7 +293,8 @@ static void build_bvh_spatial(PROCESS *process,
*/
#define HASHBIT (5)
-#define HASHSIZE (size_t)(1 << (3 * HASHBIT)) /*! < hash table size (32768) */
+/** Hash table size (32768). */
+#define HASHSIZE (size_t)(1 << (3 * HASHBIT))
#define HASH(i, j, k) ((((((i)&31) << 5) | ((j)&31)) << 5) | ((k)&31))
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 08d3236f3a9..b518f35fac7 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -413,8 +413,7 @@ static const char *cmpcode_to_str(int code)
}
}
-/* thresh is threshold for comparing vertices, uvs, vertex colors,
- * weights, etc.*/
+/** Thresh is threshold for comparing vertices, UV's, vertex colors, weights, etc. */
static int customdata_compare(
CustomData *c1, CustomData *c2, Mesh *m1, Mesh *m2, const float thresh)
{
@@ -479,11 +478,11 @@ static int customdata_compare(
if (len_squared_v3v3(v1->co, v2->co) > thresh_sq) {
return MESHCMP_VERTCOMISMATCH;
}
- /* I don't care about normals, let's just do coordinates */
+ /* I don't care about normals, let's just do coordinates. */
}
}
- /*we're order-agnostic for edges here*/
+ /* We're order-agnostic for edges here. */
if (l1->type == CD_MEDGE) {
MEdge *e1 = l1->data;
MEdge *e2 = l2->data;
@@ -748,12 +747,14 @@ bool BKE_mesh_clear_facemap_customdata(struct Mesh *me)
return changed;
}
-/* this ensures grouped customdata (e.g. mtexpoly and mloopuv and mtface, or
+/**
+ * This ensures grouped customdata (e.g. mtexpoly and mloopuv and mtface, or
* mloopcol and mcol) have the same relative active/render/clone/mask indices.
*
- * note that for undo mesh data we want to skip 'ensure_tess_cd' call since
+ * NOTE(campbell): that for undo mesh data we want to skip 'ensure_tess_cd' call since
* we don't want to store memory for tessface when its only used for older
- * versions of the mesh. - campbell*/
+ * Versions of the mesh.
+ */
static void mesh_update_linked_customdata(Mesh *me, const bool do_ensure_tess_cd)
{
if (do_ensure_tess_cd) {
@@ -811,7 +812,7 @@ static void mesh_clear_geometry(Mesh *mesh)
/* Note that materials and shape keys are not freed here. This is intentional, as freeing
* shape keys requires tagging the depsgraph for updated relations, which is expensive.
- * Material slots should be kept in sync with the object.*/
+ * Material slots should be kept in sync with the object. */
mesh->totvert = 0;
mesh->totedge = 0;
@@ -2087,6 +2088,14 @@ void BKE_mesh_split_faces(Mesh *mesh, bool free_loop_normals)
SplitFaceNewVert *new_verts = NULL;
SplitFaceNewEdge *new_edges = NULL;
+ /* Ensure we own the layers, we need to do this before split_faces_prepare_new_verts as it will
+ * directly assign new indices to existing edges and loops. */
+ CustomData_duplicate_referenced_layers(&mesh->vdata, mesh->totvert);
+ CustomData_duplicate_referenced_layers(&mesh->edata, mesh->totedge);
+ CustomData_duplicate_referenced_layers(&mesh->ldata, mesh->totloop);
+ /* Update pointers in case we duplicated referenced layers. */
+ BKE_mesh_update_customdata_pointers(mesh, false);
+
/* Detect loop normal spaces (a.k.a. smooth fans) that will need a new vert. */
const int num_new_verts = split_faces_prepare_new_verts(
mesh, &lnors_spacearr, &new_verts, memarena);
diff --git a/source/blender/blenkernel/intern/mesh_boolean_convert.cc b/source/blender/blenkernel/intern/mesh_boolean_convert.cc
index cfb1c192afe..c162458ffb9 100644
--- a/source/blender/blenkernel/intern/mesh_boolean_convert.cc
+++ b/source/blender/blenkernel/intern/mesh_boolean_convert.cc
@@ -304,7 +304,7 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes,
r_info->mesh_edge_offset[mi] = e;
r_info->mesh_poly_offset[mi] = f;
/* Get matrix that transforms a coordinate in objects[mi]'s local space
- * to the target space space.*/
+ * to the target space space. */
const float4x4 objn_mat = (obmats[mi] == nullptr) ? float4x4::identity() :
clean_obmat(*obmats[mi]);
r_info->to_target_transform[mi] = inv_target_mat * objn_mat;
@@ -776,7 +776,7 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim)
/**
* Do a mesh boolean operation directly on meshes (without going back and forth to BMesh).
- * \param meshes: An array of of Mesh pointers.
+ * \param meshes: An array of Mesh pointers.
* \param obmats: An array of pointers to the obmat matrices that transform local
* coordinates to global ones. It is allowed for the pointers to be null, meaning the
* transformation is the identity.
diff --git a/source/blender/blenkernel/intern/mesh_convert.c b/source/blender/blenkernel/intern/mesh_convert.c
index 934f9ce5018..cfad5e1100d 100644
--- a/source/blender/blenkernel/intern/mesh_convert.c
+++ b/source/blender/blenkernel/intern/mesh_convert.c
@@ -247,7 +247,7 @@ int BKE_mesh_nurbs_to_mdata(Object *ob,
/* Initialize mverts, medges and, faces for converting nurbs to mesh and derived mesh */
/* use specified dispbase */
-int BKE_mesh_nurbs_displist_to_mdata(Object *ob,
+int BKE_mesh_nurbs_displist_to_mdata(const Object *ob,
const ListBase *dispbase,
MVert **r_allvert,
int *r_totvert,
@@ -259,8 +259,7 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob,
int *r_totloop,
int *r_totpoly)
{
- Curve *cu = ob->data;
- DispList *dl;
+ const Curve *cu = ob->data;
MVert *mvert;
MPoly *mpoly;
MLoop *mloop;
@@ -276,8 +275,7 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob,
(ob->type == OB_SURF));
/* count */
- dl = dispbase->first;
- while (dl) {
+ LISTBASE_FOREACH (const DispList *, dl, dispbase) {
if (dl->type == DL_SEGM) {
totvert += dl->parts * dl->nr;
totedge += dl->parts * (dl->nr - 1);
@@ -305,7 +303,6 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob,
totpoly += tot;
totloop += tot * 3;
}
- dl = dl->next;
}
if (totvert == 0) {
@@ -327,8 +324,7 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob,
/* verts and faces */
vertcount = 0;
- dl = dispbase->first;
- while (dl) {
+ LISTBASE_FOREACH (const DispList *, dl, dispbase) {
const bool is_smooth = (dl->rt & CU_SMOOTH) != 0;
if (dl->type == DL_SEGM) {
@@ -507,8 +503,6 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob,
}
}
}
-
- dl = dl->next;
}
if (totpoly) {
@@ -523,7 +517,7 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob,
return 0;
}
-Mesh *BKE_mesh_new_nomain_from_curve_displist(Object *ob, ListBase *dispbase)
+Mesh *BKE_mesh_new_nomain_from_curve_displist(const Object *ob, const ListBase *dispbase)
{
Mesh *mesh;
MVert *allvert;
@@ -551,10 +545,18 @@ Mesh *BKE_mesh_new_nomain_from_curve_displist(Object *ob, ListBase *dispbase)
mesh = BKE_mesh_new_nomain(totvert, totedge, 0, totloop, totpoly);
mesh->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
- memcpy(mesh->mvert, allvert, totvert * sizeof(MVert));
- memcpy(mesh->medge, alledge, totedge * sizeof(MEdge));
- memcpy(mesh->mloop, allloop, totloop * sizeof(MLoop));
- memcpy(mesh->mpoly, allpoly, totpoly * sizeof(MPoly));
+ if (totvert != 0) {
+ memcpy(mesh->mvert, allvert, totvert * sizeof(MVert));
+ }
+ if (totedge != 0) {
+ memcpy(mesh->medge, alledge, totedge * sizeof(MEdge));
+ }
+ if (totloop != 0) {
+ memcpy(mesh->mloop, allloop, totloop * sizeof(MLoop));
+ }
+ if (totpoly != 0) {
+ memcpy(mesh->mpoly, allpoly, totpoly * sizeof(MPoly));
+ }
if (alluv) {
const char *uvname = "UVMap";
@@ -1113,7 +1115,7 @@ static void curve_to_mesh_eval_ensure(Object *object)
* Brecht says hold off with that. */
Mesh *mesh_eval = NULL;
BKE_displist_make_curveTypes_forRender(
- NULL, NULL, &remapped_object, &remapped_object.runtime.curve_cache->disp, false, &mesh_eval);
+ NULL, NULL, &remapped_object, &remapped_object.runtime.curve_cache->disp, &mesh_eval);
/* Note: this is to be consistent with `BKE_displist_make_curveTypes()`, however that is not a
* real issue currently, code here is broken in more than one way, fix(es) will be done
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c
index 2260ffc668a..6eac96ba85b 100644
--- a/source/blender/blenkernel/intern/mesh_evaluate.c
+++ b/source/blender/blenkernel/intern/mesh_evaluate.c
@@ -25,8 +25,6 @@
#include <limits.h>
-#include "CLG_log.h"
-
#include "MEM_guardedalloc.h"
#include "DNA_mesh_types.h"
@@ -36,2118 +34,14 @@
#include "BLI_alloca.h"
#include "BLI_bitmap.h"
#include "BLI_edgehash.h"
-#include "BLI_linklist.h"
-#include "BLI_linklist_stack.h"
+
#include "BLI_math.h"
-#include "BLI_memarena.h"
-#include "BLI_stack.h"
-#include "BLI_task.h"
#include "BLI_utildefines.h"
#include "BKE_customdata.h"
-#include "BKE_editmesh_cache.h"
-#include "BKE_global.h"
+
#include "BKE_mesh.h"
#include "BKE_multires.h"
-#include "BKE_report.h"
-
-#include "BLI_strict_flags.h"
-
-#include "atomic_ops.h"
-#include "mikktspace.h"
-
-// #define DEBUG_TIME
-
-#include "PIL_time.h"
-#ifdef DEBUG_TIME
-# include "PIL_time_utildefines.h"
-#endif
-
-static CLG_LogRef LOG = {"bke.mesh_evaluate"};
-
-/* -------------------------------------------------------------------- */
-/** \name Mesh Normal Calculation
- * \{ */
-
-/**
- * Call when there are no polygons.
- */
-static void mesh_calc_normals_vert_fallback(MVert *mverts, int numVerts)
-{
- for (int i = 0; i < numVerts; i++) {
- MVert *mv = &mverts[i];
- float no[3];
-
- normalize_v3_v3(no, mv->co);
- normal_float_to_short_v3(mv->no, no);
- }
-}
-
-/* TODO(Sybren): we can probably rename this to BKE_mesh_calc_normals_mapping(),
- * and remove the function of the same name below, as that one doesn't seem to be
- * called anywhere. */
-void BKE_mesh_calc_normals_mapping_simple(struct Mesh *mesh)
-{
- const bool only_face_normals = CustomData_is_referenced_layer(&mesh->vdata, CD_MVERT);
-
- BKE_mesh_calc_normals_mapping_ex(mesh->mvert,
- mesh->totvert,
- mesh->mloop,
- mesh->mpoly,
- mesh->totloop,
- mesh->totpoly,
- NULL,
- mesh->mface,
- mesh->totface,
- NULL,
- NULL,
- only_face_normals);
-}
-
-/* Calculate vertex and face normals, face normals are returned in *r_faceNors if non-NULL
- * and vertex normals are stored in actual mverts.
- */
-void BKE_mesh_calc_normals_mapping(MVert *mverts,
- int numVerts,
- const MLoop *mloop,
- const MPoly *mpolys,
- int numLoops,
- int numPolys,
- float (*r_polyNors)[3],
- const MFace *mfaces,
- int numFaces,
- const int *origIndexFace,
- float (*r_faceNors)[3])
-{
- BKE_mesh_calc_normals_mapping_ex(mverts,
- numVerts,
- mloop,
- mpolys,
- numLoops,
- numPolys,
- r_polyNors,
- mfaces,
- numFaces,
- origIndexFace,
- r_faceNors,
- false);
-}
-/* extended version of 'BKE_mesh_calc_normals_poly' with option not to calc vertex normals */
-void BKE_mesh_calc_normals_mapping_ex(MVert *mverts,
- int numVerts,
- const MLoop *mloop,
- const MPoly *mpolys,
- int numLoops,
- int numPolys,
- float (*r_polyNors)[3],
- const MFace *mfaces,
- int numFaces,
- const int *origIndexFace,
- float (*r_faceNors)[3],
- const bool only_face_normals)
-{
- float(*pnors)[3] = r_polyNors, (*fnors)[3] = r_faceNors;
-
- if (numPolys == 0) {
- if (only_face_normals == false) {
- mesh_calc_normals_vert_fallback(mverts, numVerts);
- }
- return;
- }
-
- /* if we are not calculating verts and no verts were passes then we have nothing to do */
- if ((only_face_normals == true) && (r_polyNors == NULL) && (r_faceNors == NULL)) {
- CLOG_WARN(&LOG, "called with nothing to do");
- return;
- }
-
- if (!pnors) {
- pnors = MEM_calloc_arrayN((size_t)numPolys, sizeof(float[3]), __func__);
- }
- /* NO NEED TO ALLOC YET */
- /* if (!fnors) fnors = MEM_calloc_arrayN(numFaces, sizeof(float[3]), "face nors mesh.c"); */
-
- if (only_face_normals == false) {
- /* vertex normals are optional, they require some extra calculations,
- * so make them optional */
- BKE_mesh_calc_normals_poly(
- mverts, NULL, numVerts, mloop, mpolys, numLoops, numPolys, pnors, false);
- }
- else {
- /* only calc poly normals */
- const MPoly *mp = mpolys;
- for (int i = 0; i < numPolys; i++, mp++) {
- BKE_mesh_calc_poly_normal(mp, mloop + mp->loopstart, mverts, pnors[i]);
- }
- }
-
- if (origIndexFace &&
- /* fnors == r_faceNors */ /* NO NEED TO ALLOC YET */
- fnors != NULL &&
- numFaces) {
- const MFace *mf = mfaces;
- for (int i = 0; i < numFaces; i++, mf++, origIndexFace++) {
- if (*origIndexFace < numPolys) {
- copy_v3_v3(fnors[i], pnors[*origIndexFace]);
- }
- else {
- /* eek, we're not corresponding to polys */
- CLOG_ERROR(&LOG, "tessellation face indices are incorrect. normals may look bad.");
- }
- }
- }
-
- if (pnors != r_polyNors) {
- MEM_freeN(pnors);
- }
- /* if (fnors != r_faceNors) MEM_freeN(fnors); */ /* NO NEED TO ALLOC YET */
-
- fnors = pnors = NULL;
-}
-
-typedef struct MeshCalcNormalsData {
- const MPoly *mpolys;
- const MLoop *mloop;
- MVert *mverts;
- float (*pnors)[3];
- float (*lnors_weighted)[3];
- float (*vnors)[3];
-} MeshCalcNormalsData;
-
-static void mesh_calc_normals_poly_cb(void *__restrict userdata,
- const int pidx,
- const TaskParallelTLS *__restrict UNUSED(tls))
-{
- MeshCalcNormalsData *data = userdata;
- const MPoly *mp = &data->mpolys[pidx];
-
- BKE_mesh_calc_poly_normal(mp, data->mloop + mp->loopstart, data->mverts, data->pnors[pidx]);
-}
-
-static void mesh_calc_normals_poly_prepare_cb(void *__restrict userdata,
- const int pidx,
- const TaskParallelTLS *__restrict UNUSED(tls))
-{
- MeshCalcNormalsData *data = userdata;
- const MPoly *mp = &data->mpolys[pidx];
- const MLoop *ml = &data->mloop[mp->loopstart];
- const MVert *mverts = data->mverts;
-
- float pnor_temp[3];
- float *pnor = data->pnors ? data->pnors[pidx] : pnor_temp;
- float(*lnors_weighted)[3] = data->lnors_weighted;
-
- const int nverts = mp->totloop;
- float(*edgevecbuf)[3] = BLI_array_alloca(edgevecbuf, (size_t)nverts);
-
- /* Polygon Normal and edge-vector */
- /* inline version of #BKE_mesh_calc_poly_normal, also does edge-vectors */
- {
- int i_prev = nverts - 1;
- const float *v_prev = mverts[ml[i_prev].v].co;
- const float *v_curr;
-
- zero_v3(pnor);
- /* Newell's Method */
- for (int i = 0; i < nverts; i++) {
- v_curr = mverts[ml[i].v].co;
- add_newell_cross_v3_v3v3(pnor, v_prev, v_curr);
-
- /* Unrelated to normalize, calculate edge-vector */
- sub_v3_v3v3(edgevecbuf[i_prev], v_prev, v_curr);
- normalize_v3(edgevecbuf[i_prev]);
- i_prev = i;
-
- v_prev = v_curr;
- }
- if (UNLIKELY(normalize_v3(pnor) == 0.0f)) {
- pnor[2] = 1.0f; /* other axes set to 0.0 */
- }
- }
-
- /* accumulate angle weighted face normal */
- /* inline version of #accumulate_vertex_normals_poly_v3,
- * split between this threaded callback and #mesh_calc_normals_poly_accum_cb. */
- {
- const float *prev_edge = edgevecbuf[nverts - 1];
-
- for (int i = 0; i < nverts; i++) {
- const int lidx = mp->loopstart + i;
- const float *cur_edge = edgevecbuf[i];
-
- /* calculate angle between the two poly edges incident on
- * this vertex */
- const float fac = saacos(-dot_v3v3(cur_edge, prev_edge));
-
- /* Store for later accumulation */
- mul_v3_v3fl(lnors_weighted[lidx], pnor, fac);
-
- prev_edge = cur_edge;
- }
- }
-}
-
-static void mesh_calc_normals_poly_finalize_cb(void *__restrict userdata,
- const int vidx,
- const TaskParallelTLS *__restrict UNUSED(tls))
-{
- MeshCalcNormalsData *data = userdata;
-
- MVert *mv = &data->mverts[vidx];
- float *no = data->vnors[vidx];
-
- if (UNLIKELY(normalize_v3(no) == 0.0f)) {
- /* following Mesh convention; we use vertex coordinate itself for normal in this case */
- normalize_v3_v3(no, mv->co);
- }
-
- normal_float_to_short_v3(mv->no, no);
-}
-
-void BKE_mesh_calc_normals_poly(MVert *mverts,
- float (*r_vertnors)[3],
- int numVerts,
- const MLoop *mloop,
- const MPoly *mpolys,
- int numLoops,
- int numPolys,
- float (*r_polynors)[3],
- const bool only_face_normals)
-{
- float(*pnors)[3] = r_polynors;
-
- TaskParallelSettings settings;
- BLI_parallel_range_settings_defaults(&settings);
- settings.min_iter_per_thread = 1024;
-
- if (only_face_normals) {
- BLI_assert((pnors != NULL) || (numPolys == 0));
- BLI_assert(r_vertnors == NULL);
-
- MeshCalcNormalsData data = {
- .mpolys = mpolys,
- .mloop = mloop,
- .mverts = mverts,
- .pnors = pnors,
- };
-
- BLI_task_parallel_range(0, numPolys, &data, mesh_calc_normals_poly_cb, &settings);
- return;
- }
-
- float(*vnors)[3] = r_vertnors;
- float(*lnors_weighted)[3] = MEM_malloc_arrayN(
- (size_t)numLoops, sizeof(*lnors_weighted), __func__);
- bool free_vnors = false;
-
- /* first go through and calculate normals for all the polys */
- if (vnors == NULL) {
- vnors = MEM_calloc_arrayN((size_t)numVerts, sizeof(*vnors), __func__);
- free_vnors = true;
- }
- else {
- memset(vnors, 0, sizeof(*vnors) * (size_t)numVerts);
- }
-
- MeshCalcNormalsData data = {
- .mpolys = mpolys,
- .mloop = mloop,
- .mverts = mverts,
- .pnors = pnors,
- .lnors_weighted = lnors_weighted,
- .vnors = vnors,
- };
-
- /* Compute poly normals, and prepare weighted loop normals. */
- BLI_task_parallel_range(0, numPolys, &data, mesh_calc_normals_poly_prepare_cb, &settings);
-
- /* Actually accumulate weighted loop normals into vertex ones. */
- /* Unfortunately, not possible to thread that
- * (not in a reasonable, totally lock- and barrier-free fashion),
- * since several loops will point to the same vertex... */
- for (int lidx = 0; lidx < numLoops; lidx++) {
- add_v3_v3(vnors[mloop[lidx].v], data.lnors_weighted[lidx]);
- }
-
- /* Normalize and validate computed vertex normals. */
- BLI_task_parallel_range(0, numVerts, &data, mesh_calc_normals_poly_finalize_cb, &settings);
-
- if (free_vnors) {
- MEM_freeN(vnors);
- }
- MEM_freeN(lnors_weighted);
-}
-
-void BKE_mesh_ensure_normals(Mesh *mesh)
-{
- if (mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL) {
- BKE_mesh_calc_normals(mesh);
- }
- BLI_assert((mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL) == 0);
-}
-
-/**
- * Called after calculating all modifiers.
- */
-void BKE_mesh_ensure_normals_for_display(Mesh *mesh)
-{
- switch ((eMeshWrapperType)mesh->runtime.wrapper_type) {
- case ME_WRAPPER_TYPE_MDATA:
- /* Run code below. */
- break;
- case ME_WRAPPER_TYPE_BMESH: {
- struct BMEditMesh *em = mesh->edit_mesh;
- EditMeshData *emd = mesh->runtime.edit_data;
- if (emd->vertexCos) {
- BKE_editmesh_cache_ensure_vert_normals(em, emd);
- BKE_editmesh_cache_ensure_poly_normals(em, emd);
- }
- return;
- }
- }
-
- float(*poly_nors)[3] = CustomData_get_layer(&mesh->pdata, CD_NORMAL);
- const bool do_vert_normals = (mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL) != 0;
- const bool do_poly_normals = (mesh->runtime.cd_dirty_poly & CD_MASK_NORMAL || poly_nors == NULL);
-
- if (do_vert_normals || do_poly_normals) {
- const bool do_add_poly_nors_cddata = (poly_nors == NULL);
- if (do_add_poly_nors_cddata) {
- poly_nors = MEM_malloc_arrayN((size_t)mesh->totpoly, sizeof(*poly_nors), __func__);
- }
-
- /* calculate poly/vert normals */
- BKE_mesh_calc_normals_poly(mesh->mvert,
- NULL,
- mesh->totvert,
- mesh->mloop,
- mesh->mpoly,
- mesh->totloop,
- mesh->totpoly,
- poly_nors,
- !do_vert_normals);
-
- if (do_add_poly_nors_cddata) {
- CustomData_add_layer(&mesh->pdata, CD_NORMAL, CD_ASSIGN, poly_nors, mesh->totpoly);
- }
-
- mesh->runtime.cd_dirty_vert &= ~CD_MASK_NORMAL;
- mesh->runtime.cd_dirty_poly &= ~CD_MASK_NORMAL;
- }
-}
-
-/* Note that this does not update the CD_NORMAL layer,
- * but does update the normals in the CD_MVERT layer. */
-void BKE_mesh_calc_normals(Mesh *mesh)
-{
-#ifdef DEBUG_TIME
- TIMEIT_START_AVERAGED(BKE_mesh_calc_normals);
-#endif
- BKE_mesh_calc_normals_poly(mesh->mvert,
- NULL,
- mesh->totvert,
- mesh->mloop,
- mesh->mpoly,
- mesh->totloop,
- mesh->totpoly,
- NULL,
- false);
-#ifdef DEBUG_TIME
- TIMEIT_END_AVERAGED(BKE_mesh_calc_normals);
-#endif
- mesh->runtime.cd_dirty_vert &= ~CD_MASK_NORMAL;
-}
-
-void BKE_mesh_calc_normals_looptri(MVert *mverts,
- int numVerts,
- const MLoop *mloop,
- const MLoopTri *looptri,
- int looptri_num,
- float (*r_tri_nors)[3])
-{
- float(*tnorms)[3] = MEM_calloc_arrayN((size_t)numVerts, sizeof(*tnorms), "tnorms");
- float(*fnors)[3] = (r_tri_nors) ?
- r_tri_nors :
- MEM_calloc_arrayN((size_t)looptri_num, sizeof(*fnors), "meshnormals");
-
- if (!tnorms || !fnors) {
- goto cleanup;
- }
-
- for (int i = 0; i < looptri_num; i++) {
- const MLoopTri *lt = &looptri[i];
- float *f_no = fnors[i];
- const uint vtri[3] = {
- mloop[lt->tri[0]].v,
- mloop[lt->tri[1]].v,
- mloop[lt->tri[2]].v,
- };
-
- normal_tri_v3(f_no, mverts[vtri[0]].co, mverts[vtri[1]].co, mverts[vtri[2]].co);
-
- accumulate_vertex_normals_tri_v3(tnorms[vtri[0]],
- tnorms[vtri[1]],
- tnorms[vtri[2]],
- f_no,
- mverts[vtri[0]].co,
- mverts[vtri[1]].co,
- mverts[vtri[2]].co);
- }
-
- /* following Mesh convention; we use vertex coordinate itself for normal in this case */
- for (int i = 0; i < numVerts; i++) {
- MVert *mv = &mverts[i];
- float *no = tnorms[i];
-
- if (UNLIKELY(normalize_v3(no) == 0.0f)) {
- normalize_v3_v3(no, mv->co);
- }
-
- normal_float_to_short_v3(mv->no, no);
- }
-
-cleanup:
- MEM_freeN(tnorms);
-
- if (fnors != r_tri_nors) {
- MEM_freeN(fnors);
- }
-}
-
-void BKE_lnor_spacearr_init(MLoopNorSpaceArray *lnors_spacearr,
- const int numLoops,
- const char data_type)
-{
- if (!(lnors_spacearr->lspacearr && lnors_spacearr->loops_pool)) {
- MemArena *mem;
-
- if (!lnors_spacearr->mem) {
- lnors_spacearr->mem = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
- }
- mem = lnors_spacearr->mem;
- lnors_spacearr->lspacearr = BLI_memarena_calloc(mem,
- sizeof(MLoopNorSpace *) * (size_t)numLoops);
- lnors_spacearr->loops_pool = BLI_memarena_alloc(mem, sizeof(LinkNode) * (size_t)numLoops);
-
- lnors_spacearr->num_spaces = 0;
- }
- BLI_assert(ELEM(data_type, MLNOR_SPACEARR_BMLOOP_PTR, MLNOR_SPACEARR_LOOP_INDEX));
- lnors_spacearr->data_type = data_type;
-}
-
-void BKE_lnor_spacearr_clear(MLoopNorSpaceArray *lnors_spacearr)
-{
- lnors_spacearr->num_spaces = 0;
- lnors_spacearr->lspacearr = NULL;
- lnors_spacearr->loops_pool = NULL;
- if (lnors_spacearr->mem != NULL) {
- BLI_memarena_clear(lnors_spacearr->mem);
- }
-}
-
-void BKE_lnor_spacearr_free(MLoopNorSpaceArray *lnors_spacearr)
-{
- lnors_spacearr->num_spaces = 0;
- lnors_spacearr->lspacearr = NULL;
- lnors_spacearr->loops_pool = NULL;
- BLI_memarena_free(lnors_spacearr->mem);
- lnors_spacearr->mem = NULL;
-}
-
-MLoopNorSpace *BKE_lnor_space_create(MLoopNorSpaceArray *lnors_spacearr)
-{
- lnors_spacearr->num_spaces++;
- return BLI_memarena_calloc(lnors_spacearr->mem, sizeof(MLoopNorSpace));
-}
-
-/* This threshold is a bit touchy (usual float precision issue), this value seems OK. */
-#define LNOR_SPACE_TRIGO_THRESHOLD (1.0f - 1e-4f)
-
-/* Should only be called once.
- * Beware, this modifies ref_vec and other_vec in place!
- * In case no valid space can be generated, ref_alpha and ref_beta are set to zero
- * (which means 'use auto lnors').
- */
-void BKE_lnor_space_define(MLoopNorSpace *lnor_space,
- const float lnor[3],
- float vec_ref[3],
- float vec_other[3],
- BLI_Stack *edge_vectors)
-{
- const float pi2 = (float)M_PI * 2.0f;
- float tvec[3], dtp;
- const float dtp_ref = dot_v3v3(vec_ref, lnor);
- const float dtp_other = dot_v3v3(vec_other, lnor);
-
- if (UNLIKELY(fabsf(dtp_ref) >= LNOR_SPACE_TRIGO_THRESHOLD ||
- fabsf(dtp_other) >= LNOR_SPACE_TRIGO_THRESHOLD)) {
- /* If vec_ref or vec_other are too much aligned with lnor, we can't build lnor space,
- * tag it as invalid and abort. */
- lnor_space->ref_alpha = lnor_space->ref_beta = 0.0f;
-
- if (edge_vectors) {
- BLI_stack_clear(edge_vectors);
- }
- return;
- }
-
- copy_v3_v3(lnor_space->vec_lnor, lnor);
-
- /* Compute ref alpha, average angle of all available edge vectors to lnor. */
- if (edge_vectors) {
- float alpha = 0.0f;
- int nbr = 0;
- while (!BLI_stack_is_empty(edge_vectors)) {
- const float *vec = BLI_stack_peek(edge_vectors);
- alpha += saacosf(dot_v3v3(vec, lnor));
- BLI_stack_discard(edge_vectors);
- nbr++;
- }
- /* Note: In theory, this could be 'nbr > 2',
- * but there is one case where we only have two edges for two loops:
- * a smooth vertex with only two edges and two faces (our Monkey's nose has that, e.g.).
- */
- BLI_assert(nbr >= 2); /* This piece of code shall only be called for more than one loop... */
- lnor_space->ref_alpha = alpha / (float)nbr;
- }
- else {
- lnor_space->ref_alpha = (saacosf(dot_v3v3(vec_ref, lnor)) +
- saacosf(dot_v3v3(vec_other, lnor))) /
- 2.0f;
- }
-
- /* Project vec_ref on lnor's ortho plane. */
- mul_v3_v3fl(tvec, lnor, dtp_ref);
- sub_v3_v3(vec_ref, tvec);
- normalize_v3_v3(lnor_space->vec_ref, vec_ref);
-
- cross_v3_v3v3(tvec, lnor, lnor_space->vec_ref);
- normalize_v3_v3(lnor_space->vec_ortho, tvec);
-
- /* Project vec_other on lnor's ortho plane. */
- mul_v3_v3fl(tvec, lnor, dtp_other);
- sub_v3_v3(vec_other, tvec);
- normalize_v3(vec_other);
-
- /* Beta is angle between ref_vec and other_vec, around lnor. */
- dtp = dot_v3v3(lnor_space->vec_ref, vec_other);
- if (LIKELY(dtp < LNOR_SPACE_TRIGO_THRESHOLD)) {
- const float beta = saacos(dtp);
- lnor_space->ref_beta = (dot_v3v3(lnor_space->vec_ortho, vec_other) < 0.0f) ? pi2 - beta : beta;
- }
- else {
- lnor_space->ref_beta = pi2;
- }
-}
-
-/**
- * Add a new given loop to given lnor_space.
- * Depending on \a lnor_space->data_type, we expect \a bm_loop to be a pointer to BMLoop struct
- * (in case of BMLOOP_PTR), or NULL (in case of LOOP_INDEX), loop index is then stored in pointer.
- * If \a is_single is set, the BMLoop or loop index is directly stored in \a lnor_space->loops
- * pointer (since there is only one loop in this fan),
- * else it is added to the linked list of loops in the fan.
- */
-void BKE_lnor_space_add_loop(MLoopNorSpaceArray *lnors_spacearr,
- MLoopNorSpace *lnor_space,
- const int ml_index,
- void *bm_loop,
- const bool is_single)
-{
- BLI_assert((lnors_spacearr->data_type == MLNOR_SPACEARR_LOOP_INDEX && bm_loop == NULL) ||
- (lnors_spacearr->data_type == MLNOR_SPACEARR_BMLOOP_PTR && bm_loop != NULL));
-
- lnors_spacearr->lspacearr[ml_index] = lnor_space;
- if (bm_loop == NULL) {
- bm_loop = POINTER_FROM_INT(ml_index);
- }
- if (is_single) {
- BLI_assert(lnor_space->loops == NULL);
- lnor_space->flags |= MLNOR_SPACE_IS_SINGLE;
- lnor_space->loops = bm_loop;
- }
- else {
- BLI_assert((lnor_space->flags & MLNOR_SPACE_IS_SINGLE) == 0);
- BLI_linklist_prepend_nlink(&lnor_space->loops, bm_loop, &lnors_spacearr->loops_pool[ml_index]);
- }
-}
-
-MINLINE float unit_short_to_float(const short val)
-{
- return (float)val / (float)SHRT_MAX;
-}
-
-MINLINE short unit_float_to_short(const float val)
-{
- /* Rounding... */
- return (short)floorf(val * (float)SHRT_MAX + 0.5f);
-}
-
-void BKE_lnor_space_custom_data_to_normal(MLoopNorSpace *lnor_space,
- const short clnor_data[2],
- float r_custom_lnor[3])
-{
- /* NOP custom normal data or invalid lnor space, return. */
- if (clnor_data[0] == 0 || lnor_space->ref_alpha == 0.0f || lnor_space->ref_beta == 0.0f) {
- copy_v3_v3(r_custom_lnor, lnor_space->vec_lnor);
- return;
- }
-
- {
- /* TODO Check whether using sincosf() gives any noticeable benefit
- * (could not even get it working under linux though)! */
- const float pi2 = (float)(M_PI * 2.0);
- const float alphafac = unit_short_to_float(clnor_data[0]);
- const float alpha = (alphafac > 0.0f ? lnor_space->ref_alpha : pi2 - lnor_space->ref_alpha) *
- alphafac;
- const float betafac = unit_short_to_float(clnor_data[1]);
-
- mul_v3_v3fl(r_custom_lnor, lnor_space->vec_lnor, cosf(alpha));
-
- if (betafac == 0.0f) {
- madd_v3_v3fl(r_custom_lnor, lnor_space->vec_ref, sinf(alpha));
- }
- else {
- const float sinalpha = sinf(alpha);
- const float beta = (betafac > 0.0f ? lnor_space->ref_beta : pi2 - lnor_space->ref_beta) *
- betafac;
- madd_v3_v3fl(r_custom_lnor, lnor_space->vec_ref, sinalpha * cosf(beta));
- madd_v3_v3fl(r_custom_lnor, lnor_space->vec_ortho, sinalpha * sinf(beta));
- }
- }
-}
-
-void BKE_lnor_space_custom_normal_to_data(MLoopNorSpace *lnor_space,
- const float custom_lnor[3],
- short r_clnor_data[2])
-{
- /* We use null vector as NOP custom normal (can be simpler than giving autocomputed lnor...). */
- if (is_zero_v3(custom_lnor) || compare_v3v3(lnor_space->vec_lnor, custom_lnor, 1e-4f)) {
- r_clnor_data[0] = r_clnor_data[1] = 0;
- return;
- }
-
- {
- const float pi2 = (float)(M_PI * 2.0);
- const float cos_alpha = dot_v3v3(lnor_space->vec_lnor, custom_lnor);
- float vec[3], cos_beta;
- float alpha;
-
- alpha = saacosf(cos_alpha);
- if (alpha > lnor_space->ref_alpha) {
- /* Note we could stick to [0, pi] range here,
- * but makes decoding more complex, not worth it. */
- r_clnor_data[0] = unit_float_to_short(-(pi2 - alpha) / (pi2 - lnor_space->ref_alpha));
- }
- else {
- r_clnor_data[0] = unit_float_to_short(alpha / lnor_space->ref_alpha);
- }
-
- /* Project custom lnor on (vec_ref, vec_ortho) plane. */
- mul_v3_v3fl(vec, lnor_space->vec_lnor, -cos_alpha);
- add_v3_v3(vec, custom_lnor);
- normalize_v3(vec);
-
- cos_beta = dot_v3v3(lnor_space->vec_ref, vec);
-
- if (cos_beta < LNOR_SPACE_TRIGO_THRESHOLD) {
- float beta = saacosf(cos_beta);
- if (dot_v3v3(lnor_space->vec_ortho, vec) < 0.0f) {
- beta = pi2 - beta;
- }
-
- if (beta > lnor_space->ref_beta) {
- r_clnor_data[1] = unit_float_to_short(-(pi2 - beta) / (pi2 - lnor_space->ref_beta));
- }
- else {
- r_clnor_data[1] = unit_float_to_short(beta / lnor_space->ref_beta);
- }
- }
- else {
- r_clnor_data[1] = 0;
- }
- }
-}
-
-#define LOOP_SPLIT_TASK_BLOCK_SIZE 1024
-
-typedef struct LoopSplitTaskData {
- /* Specific to each instance (each task). */
-
- /** We have to create those outside of tasks, since afaik memarena is not threadsafe. */
- MLoopNorSpace *lnor_space;
- float (*lnor)[3];
- const MLoop *ml_curr;
- const MLoop *ml_prev;
- int ml_curr_index;
- int ml_prev_index;
- /** Also used a flag to switch between single or fan process! */
- const int *e2l_prev;
- int mp_index;
-
- /** This one is special, it's owned and managed by worker tasks,
- * avoid to have to create it for each fan! */
- BLI_Stack *edge_vectors;
-
- char pad_c;
-} LoopSplitTaskData;
-
-typedef struct LoopSplitTaskDataCommon {
- /* Read/write.
- * Note we do not need to protect it, though, since two different tasks will *always* affect
- * different elements in the arrays. */
- MLoopNorSpaceArray *lnors_spacearr;
- float (*loopnors)[3];
- short (*clnors_data)[2];
-
- /* Read-only. */
- const MVert *mverts;
- const MEdge *medges;
- const MLoop *mloops;
- const MPoly *mpolys;
- int (*edge_to_loops)[2];
- int *loop_to_poly;
- const float (*polynors)[3];
-
- int numEdges;
- int numLoops;
- int numPolys;
-} LoopSplitTaskDataCommon;
-
-#define INDEX_UNSET INT_MIN
-#define INDEX_INVALID -1
-/* See comment about edge_to_loops below. */
-#define IS_EDGE_SHARP(_e2l) (ELEM((_e2l)[1], INDEX_UNSET, INDEX_INVALID))
-
-static void mesh_edges_sharp_tag(LoopSplitTaskDataCommon *data,
- const bool check_angle,
- const float split_angle,
- const bool do_sharp_edges_tag)
-{
- const MVert *mverts = data->mverts;
- const MEdge *medges = data->medges;
- const MLoop *mloops = data->mloops;
-
- const MPoly *mpolys = data->mpolys;
-
- const int numEdges = data->numEdges;
- const int numPolys = data->numPolys;
-
- float(*loopnors)[3] = data->loopnors; /* Note: loopnors may be NULL here. */
- const float(*polynors)[3] = data->polynors;
-
- int(*edge_to_loops)[2] = data->edge_to_loops;
- int *loop_to_poly = data->loop_to_poly;
-
- BLI_bitmap *sharp_edges = do_sharp_edges_tag ? BLI_BITMAP_NEW(numEdges, __func__) : NULL;
-
- const MPoly *mp;
- int mp_index;
-
- const float split_angle_cos = check_angle ? cosf(split_angle) : -1.0f;
-
- for (mp = mpolys, mp_index = 0; mp_index < numPolys; mp++, mp_index++) {
- const MLoop *ml_curr;
- int *e2l;
- int ml_curr_index = mp->loopstart;
- const int ml_last_index = (ml_curr_index + mp->totloop) - 1;
-
- ml_curr = &mloops[ml_curr_index];
-
- for (; ml_curr_index <= ml_last_index; ml_curr++, ml_curr_index++) {
- e2l = edge_to_loops[ml_curr->e];
-
- loop_to_poly[ml_curr_index] = mp_index;
-
- /* Pre-populate all loop normals as if their verts were all-smooth,
- * this way we don't have to compute those later!
- */
- if (loopnors) {
- normal_short_to_float_v3(loopnors[ml_curr_index], mverts[ml_curr->v].no);
- }
-
- /* Check whether current edge might be smooth or sharp */
- if ((e2l[0] | e2l[1]) == 0) {
- /* 'Empty' edge until now, set e2l[0] (and e2l[1] to INDEX_UNSET to tag it as unset). */
- e2l[0] = ml_curr_index;
- /* We have to check this here too, else we might miss some flat faces!!! */
- e2l[1] = (mp->flag & ME_SMOOTH) ? INDEX_UNSET : INDEX_INVALID;
- }
- else if (e2l[1] == INDEX_UNSET) {
- const bool is_angle_sharp = (check_angle &&
- dot_v3v3(polynors[loop_to_poly[e2l[0]]], polynors[mp_index]) <
- split_angle_cos);
-
- /* Second loop using this edge, time to test its sharpness.
- * An edge is sharp if it is tagged as such, or its face is not smooth,
- * or both poly have opposed (flipped) normals, i.e. both loops on the same edge share the
- * same vertex, or angle between both its polys' normals is above split_angle value.
- */
- if (!(mp->flag & ME_SMOOTH) || (medges[ml_curr->e].flag & ME_SHARP) ||
- ml_curr->v == mloops[e2l[0]].v || is_angle_sharp) {
- /* Note: we are sure that loop != 0 here ;) */
- e2l[1] = INDEX_INVALID;
-
- /* We want to avoid tagging edges as sharp when it is already defined as such by
- * other causes than angle threshold... */
- if (do_sharp_edges_tag && is_angle_sharp) {
- BLI_BITMAP_SET(sharp_edges, ml_curr->e, true);
- }
- }
- else {
- e2l[1] = ml_curr_index;
- }
- }
- else if (!IS_EDGE_SHARP(e2l)) {
- /* More than two loops using this edge, tag as sharp if not yet done. */
- e2l[1] = INDEX_INVALID;
-
- /* We want to avoid tagging edges as sharp when it is already defined as such by
- * other causes than angle threshold... */
- if (do_sharp_edges_tag) {
- BLI_BITMAP_SET(sharp_edges, ml_curr->e, false);
- }
- }
- /* Else, edge is already 'disqualified' (i.e. sharp)! */
- }
- }
-
- /* If requested, do actual tagging of edges as sharp in another loop. */
- if (do_sharp_edges_tag) {
- MEdge *me;
- int me_index;
- for (me = (MEdge *)medges, me_index = 0; me_index < numEdges; me++, me_index++) {
- if (BLI_BITMAP_TEST(sharp_edges, me_index)) {
- me->flag |= ME_SHARP;
- }
- }
-
- MEM_freeN(sharp_edges);
- }
-}
-
-/**
- * Define sharp edges as needed to mimic 'autosmooth' from angle threshold.
- *
- * Used when defining an empty custom loop normals data layer,
- * to keep same shading as with autosmooth!
- */
-void BKE_edges_sharp_from_angle_set(const struct MVert *mverts,
- const int UNUSED(numVerts),
- struct MEdge *medges,
- const int numEdges,
- struct MLoop *mloops,
- const int numLoops,
- struct MPoly *mpolys,
- const float (*polynors)[3],
- const int numPolys,
- const float split_angle)
-{
- if (split_angle >= (float)M_PI) {
- /* Nothing to do! */
- return;
- }
-
- /* Mapping edge -> loops. See BKE_mesh_normals_loop_split() for details. */
- int(*edge_to_loops)[2] = MEM_calloc_arrayN((size_t)numEdges, sizeof(*edge_to_loops), __func__);
-
- /* Simple mapping from a loop to its polygon index. */
- int *loop_to_poly = MEM_malloc_arrayN((size_t)numLoops, sizeof(*loop_to_poly), __func__);
-
- LoopSplitTaskDataCommon common_data = {
- .mverts = mverts,
- .medges = medges,
- .mloops = mloops,
- .mpolys = mpolys,
- .edge_to_loops = edge_to_loops,
- .loop_to_poly = loop_to_poly,
- .polynors = polynors,
- .numEdges = numEdges,
- .numPolys = numPolys,
- };
-
- mesh_edges_sharp_tag(&common_data, true, split_angle, true);
-
- MEM_freeN(edge_to_loops);
- MEM_freeN(loop_to_poly);
-}
-
-void BKE_mesh_loop_manifold_fan_around_vert_next(const MLoop *mloops,
- const MPoly *mpolys,
- const int *loop_to_poly,
- const int *e2lfan_curr,
- const uint mv_pivot_index,
- const MLoop **r_mlfan_curr,
- int *r_mlfan_curr_index,
- int *r_mlfan_vert_index,
- int *r_mpfan_curr_index)
-{
- const MLoop *mlfan_next;
- const MPoly *mpfan_next;
-
- /* Warning! This is rather complex!
- * We have to find our next edge around the vertex (fan mode).
- * First we find the next loop, which is either previous or next to mlfan_curr_index, depending
- * whether both loops using current edge are in the same direction or not, and whether
- * mlfan_curr_index actually uses the vertex we are fanning around!
- * mlfan_curr_index is the index of mlfan_next here, and mlfan_next is not the real next one
- * (i.e. not the future mlfan_curr)...
- */
- *r_mlfan_curr_index = (e2lfan_curr[0] == *r_mlfan_curr_index) ? e2lfan_curr[1] : e2lfan_curr[0];
- *r_mpfan_curr_index = loop_to_poly[*r_mlfan_curr_index];
-
- BLI_assert(*r_mlfan_curr_index >= 0);
- BLI_assert(*r_mpfan_curr_index >= 0);
-
- mlfan_next = &mloops[*r_mlfan_curr_index];
- mpfan_next = &mpolys[*r_mpfan_curr_index];
- if (((*r_mlfan_curr)->v == mlfan_next->v && (*r_mlfan_curr)->v == mv_pivot_index) ||
- ((*r_mlfan_curr)->v != mlfan_next->v && (*r_mlfan_curr)->v != mv_pivot_index)) {
- /* We need the previous loop, but current one is our vertex's loop. */
- *r_mlfan_vert_index = *r_mlfan_curr_index;
- if (--(*r_mlfan_curr_index) < mpfan_next->loopstart) {
- *r_mlfan_curr_index = mpfan_next->loopstart + mpfan_next->totloop - 1;
- }
- }
- else {
- /* We need the next loop, which is also our vertex's loop. */
- if (++(*r_mlfan_curr_index) >= mpfan_next->loopstart + mpfan_next->totloop) {
- *r_mlfan_curr_index = mpfan_next->loopstart;
- }
- *r_mlfan_vert_index = *r_mlfan_curr_index;
- }
- *r_mlfan_curr = &mloops[*r_mlfan_curr_index];
- /* And now we are back in sync, mlfan_curr_index is the index of mlfan_curr! Pff! */
-}
-
-static void split_loop_nor_single_do(LoopSplitTaskDataCommon *common_data, LoopSplitTaskData *data)
-{
- MLoopNorSpaceArray *lnors_spacearr = common_data->lnors_spacearr;
- const short(*clnors_data)[2] = common_data->clnors_data;
-
- const MVert *mverts = common_data->mverts;
- const MEdge *medges = common_data->medges;
- const float(*polynors)[3] = common_data->polynors;
-
- MLoopNorSpace *lnor_space = data->lnor_space;
- float(*lnor)[3] = data->lnor;
- const MLoop *ml_curr = data->ml_curr;
- const MLoop *ml_prev = data->ml_prev;
- const int ml_curr_index = data->ml_curr_index;
-#if 0 /* Not needed for 'single' loop. */
- const int ml_prev_index = data->ml_prev_index;
- const int *e2l_prev = data->e2l_prev;
-#endif
- const int mp_index = data->mp_index;
-
- /* Simple case (both edges around that vertex are sharp in current polygon),
- * this loop just takes its poly normal.
- */
- copy_v3_v3(*lnor, polynors[mp_index]);
-
-#if 0
- printf("BASIC: handling loop %d / edge %d / vert %d / poly %d\n",
- ml_curr_index,
- ml_curr->e,
- ml_curr->v,
- mp_index);
-#endif
-
- /* If needed, generate this (simple!) lnor space. */
- if (lnors_spacearr) {
- float vec_curr[3], vec_prev[3];
-
- const uint mv_pivot_index = ml_curr->v; /* The vertex we are "fanning" around! */
- const MVert *mv_pivot = &mverts[mv_pivot_index];
- const MEdge *me_curr = &medges[ml_curr->e];
- const MVert *mv_2 = (me_curr->v1 == mv_pivot_index) ? &mverts[me_curr->v2] :
- &mverts[me_curr->v1];
- const MEdge *me_prev = &medges[ml_prev->e];
- const MVert *mv_3 = (me_prev->v1 == mv_pivot_index) ? &mverts[me_prev->v2] :
- &mverts[me_prev->v1];
-
- sub_v3_v3v3(vec_curr, mv_2->co, mv_pivot->co);
- normalize_v3(vec_curr);
- sub_v3_v3v3(vec_prev, mv_3->co, mv_pivot->co);
- normalize_v3(vec_prev);
-
- BKE_lnor_space_define(lnor_space, *lnor, vec_curr, vec_prev, NULL);
- /* We know there is only one loop in this space,
- * no need to create a linklist in this case... */
- BKE_lnor_space_add_loop(lnors_spacearr, lnor_space, ml_curr_index, NULL, true);
-
- if (clnors_data) {
- BKE_lnor_space_custom_data_to_normal(lnor_space, clnors_data[ml_curr_index], *lnor);
- }
- }
-}
-
-static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSplitTaskData *data)
-{
- MLoopNorSpaceArray *lnors_spacearr = common_data->lnors_spacearr;
- float(*loopnors)[3] = common_data->loopnors;
- short(*clnors_data)[2] = common_data->clnors_data;
-
- const MVert *mverts = common_data->mverts;
- const MEdge *medges = common_data->medges;
- const MLoop *mloops = common_data->mloops;
- const MPoly *mpolys = common_data->mpolys;
- const int(*edge_to_loops)[2] = common_data->edge_to_loops;
- const int *loop_to_poly = common_data->loop_to_poly;
- const float(*polynors)[3] = common_data->polynors;
-
- MLoopNorSpace *lnor_space = data->lnor_space;
-#if 0 /* Not needed for 'fan' loops. */
- float(*lnor)[3] = data->lnor;
-#endif
- const MLoop *ml_curr = data->ml_curr;
- const MLoop *ml_prev = data->ml_prev;
- const int ml_curr_index = data->ml_curr_index;
- const int ml_prev_index = data->ml_prev_index;
- const int mp_index = data->mp_index;
- const int *e2l_prev = data->e2l_prev;
-
- BLI_Stack *edge_vectors = data->edge_vectors;
-
- /* Gah... We have to fan around current vertex, until we find the other non-smooth edge,
- * and accumulate face normals into the vertex!
- * Note in case this vertex has only one sharp edges, this is a waste because the normal is the
- * same as the vertex normal, but I do not see any easy way to detect that (would need to count
- * number of sharp edges per vertex, I doubt the additional memory usage would be worth it,
- * especially as it should not be a common case in real-life meshes anyway).
- */
- const uint mv_pivot_index = ml_curr->v; /* The vertex we are "fanning" around! */
- const MVert *mv_pivot = &mverts[mv_pivot_index];
-
- /* ml_curr would be mlfan_prev if we needed that one. */
- const MEdge *me_org = &medges[ml_curr->e];
-
- const int *e2lfan_curr;
- float vec_curr[3], vec_prev[3], vec_org[3];
- const MLoop *mlfan_curr;
- float lnor[3] = {0.0f, 0.0f, 0.0f};
- /* mlfan_vert_index: the loop of our current edge might not be the loop of our current vertex! */
- int mlfan_curr_index, mlfan_vert_index, mpfan_curr_index;
-
- /* We validate clnors data on the fly - cheapest way to do! */
- int clnors_avg[2] = {0, 0};
- short(*clnor_ref)[2] = NULL;
- int clnors_nbr = 0;
- bool clnors_invalid = false;
-
- /* Temp loop normal stack. */
- BLI_SMALLSTACK_DECLARE(normal, float *);
- /* Temp clnors stack. */
- BLI_SMALLSTACK_DECLARE(clnors, short *);
-
- e2lfan_curr = e2l_prev;
- mlfan_curr = ml_prev;
- mlfan_curr_index = ml_prev_index;
- mlfan_vert_index = ml_curr_index;
- mpfan_curr_index = mp_index;
-
- BLI_assert(mlfan_curr_index >= 0);
- BLI_assert(mlfan_vert_index >= 0);
- BLI_assert(mpfan_curr_index >= 0);
-
- /* Only need to compute previous edge's vector once, then we can just reuse old current one! */
- {
- const MVert *mv_2 = (me_org->v1 == mv_pivot_index) ? &mverts[me_org->v2] : &mverts[me_org->v1];
-
- sub_v3_v3v3(vec_org, mv_2->co, mv_pivot->co);
- normalize_v3(vec_org);
- copy_v3_v3(vec_prev, vec_org);
-
- if (lnors_spacearr) {
- BLI_stack_push(edge_vectors, vec_org);
- }
- }
-
- // printf("FAN: vert %d, start edge %d\n", mv_pivot_index, ml_curr->e);
-
- while (true) {
- const MEdge *me_curr = &medges[mlfan_curr->e];
- /* Compute edge vectors.
- * NOTE: We could pre-compute those into an array, in the first iteration, instead of computing
- * them twice (or more) here. However, time gained is not worth memory and time lost,
- * given the fact that this code should not be called that much in real-life meshes...
- */
- {
- const MVert *mv_2 = (me_curr->v1 == mv_pivot_index) ? &mverts[me_curr->v2] :
- &mverts[me_curr->v1];
-
- sub_v3_v3v3(vec_curr, mv_2->co, mv_pivot->co);
- normalize_v3(vec_curr);
- }
-
- // printf("\thandling edge %d / loop %d\n", mlfan_curr->e, mlfan_curr_index);
-
- {
- /* Code similar to accumulate_vertex_normals_poly_v3. */
- /* Calculate angle between the two poly edges incident on this vertex. */
- const float fac = saacos(dot_v3v3(vec_curr, vec_prev));
- /* Accumulate */
- madd_v3_v3fl(lnor, polynors[mpfan_curr_index], fac);
-
- if (clnors_data) {
- /* Accumulate all clnors, if they are not all equal we have to fix that! */
- short(*clnor)[2] = &clnors_data[mlfan_vert_index];
- if (clnors_nbr) {
- clnors_invalid |= ((*clnor_ref)[0] != (*clnor)[0] || (*clnor_ref)[1] != (*clnor)[1]);
- }
- else {
- clnor_ref = clnor;
- }
- clnors_avg[0] += (*clnor)[0];
- clnors_avg[1] += (*clnor)[1];
- clnors_nbr++;
- /* We store here a pointer to all custom lnors processed. */
- BLI_SMALLSTACK_PUSH(clnors, (short *)*clnor);
- }
- }
-
- /* We store here a pointer to all loop-normals processed. */
- BLI_SMALLSTACK_PUSH(normal, (float *)(loopnors[mlfan_vert_index]));
-
- if (lnors_spacearr) {
- /* Assign current lnor space to current 'vertex' loop. */
- BKE_lnor_space_add_loop(lnors_spacearr, lnor_space, mlfan_vert_index, NULL, false);
- if (me_curr != me_org) {
- /* We store here all edges-normalized vectors processed. */
- BLI_stack_push(edge_vectors, vec_curr);
- }
- }
-
- if (IS_EDGE_SHARP(e2lfan_curr) || (me_curr == me_org)) {
- /* Current edge is sharp and we have finished with this fan of faces around this vert,
- * or this vert is smooth, and we have completed a full turn around it.
- */
- // printf("FAN: Finished!\n");
- break;
- }
-
- copy_v3_v3(vec_prev, vec_curr);
-
- /* Find next loop of the smooth fan. */
- BKE_mesh_loop_manifold_fan_around_vert_next(mloops,
- mpolys,
- loop_to_poly,
- e2lfan_curr,
- mv_pivot_index,
- &mlfan_curr,
- &mlfan_curr_index,
- &mlfan_vert_index,
- &mpfan_curr_index);
-
- e2lfan_curr = edge_to_loops[mlfan_curr->e];
- }
-
- {
- float lnor_len = normalize_v3(lnor);
-
- /* If we are generating lnor spacearr, we can now define the one for this fan,
- * and optionally compute final lnor from custom data too!
- */
- if (lnors_spacearr) {
- if (UNLIKELY(lnor_len == 0.0f)) {
- /* Use vertex normal as fallback! */
- copy_v3_v3(lnor, loopnors[mlfan_vert_index]);
- lnor_len = 1.0f;
- }
-
- BKE_lnor_space_define(lnor_space, lnor, vec_org, vec_curr, edge_vectors);
-
- if (clnors_data) {
- if (clnors_invalid) {
- short *clnor;
-
- clnors_avg[0] /= clnors_nbr;
- clnors_avg[1] /= clnors_nbr;
- /* Fix/update all clnors of this fan with computed average value. */
- if (G.debug & G_DEBUG) {
- printf("Invalid clnors in this fan!\n");
- }
- while ((clnor = BLI_SMALLSTACK_POP(clnors))) {
- // print_v2("org clnor", clnor);
- clnor[0] = (short)clnors_avg[0];
- clnor[1] = (short)clnors_avg[1];
- }
- // print_v2("new clnors", clnors_avg);
- }
- /* Extra bonus: since small-stack is local to this function,
- * no more need to empty it at all cost! */
-
- BKE_lnor_space_custom_data_to_normal(lnor_space, *clnor_ref, lnor);
- }
- }
-
- /* In case we get a zero normal here, just use vertex normal already set! */
- if (LIKELY(lnor_len != 0.0f)) {
- /* Copy back the final computed normal into all related loop-normals. */
- float *nor;
-
- while ((nor = BLI_SMALLSTACK_POP(normal))) {
- copy_v3_v3(nor, lnor);
- }
- }
- /* Extra bonus: since small-stack is local to this function,
- * no more need to empty it at all cost! */
- }
-}
-
-static void loop_split_worker_do(LoopSplitTaskDataCommon *common_data,
- LoopSplitTaskData *data,
- BLI_Stack *edge_vectors)
-{
- BLI_assert(data->ml_curr);
- if (data->e2l_prev) {
- BLI_assert((edge_vectors == NULL) || BLI_stack_is_empty(edge_vectors));
- data->edge_vectors = edge_vectors;
- split_loop_nor_fan_do(common_data, data);
- }
- else {
- /* No need for edge_vectors for 'single' case! */
- split_loop_nor_single_do(common_data, data);
- }
-}
-
-static void loop_split_worker(TaskPool *__restrict pool, void *taskdata)
-{
- LoopSplitTaskDataCommon *common_data = BLI_task_pool_user_data(pool);
- LoopSplitTaskData *data = taskdata;
-
- /* Temp edge vectors stack, only used when computing lnor spacearr. */
- BLI_Stack *edge_vectors = common_data->lnors_spacearr ?
- BLI_stack_new(sizeof(float[3]), __func__) :
- NULL;
-
-#ifdef DEBUG_TIME
- TIMEIT_START_AVERAGED(loop_split_worker);
-#endif
-
- for (int i = 0; i < LOOP_SPLIT_TASK_BLOCK_SIZE; i++, data++) {
- /* A NULL ml_curr is used to tag ended data! */
- if (data->ml_curr == NULL) {
- break;
- }
-
- loop_split_worker_do(common_data, data, edge_vectors);
- }
-
- if (edge_vectors) {
- BLI_stack_free(edge_vectors);
- }
-
-#ifdef DEBUG_TIME
- TIMEIT_END_AVERAGED(loop_split_worker);
-#endif
-}
-
-/**
- * Check whether given loop is part of an unknown-so-far cyclic smooth fan, or not.
- * Needed because cyclic smooth fans have no obvious 'entry point',
- * and yet we need to walk them once, and only once.
- */
-static bool loop_split_generator_check_cyclic_smooth_fan(const MLoop *mloops,
- const MPoly *mpolys,
- const int (*edge_to_loops)[2],
- const int *loop_to_poly,
- const int *e2l_prev,
- BLI_bitmap *skip_loops,
- const MLoop *ml_curr,
- const MLoop *ml_prev,
- const int ml_curr_index,
- const int ml_prev_index,
- const int mp_curr_index)
-{
- const uint mv_pivot_index = ml_curr->v; /* The vertex we are "fanning" around! */
- const int *e2lfan_curr;
- const MLoop *mlfan_curr;
- /* mlfan_vert_index: the loop of our current edge might not be the loop of our current vertex! */
- int mlfan_curr_index, mlfan_vert_index, mpfan_curr_index;
-
- e2lfan_curr = e2l_prev;
- if (IS_EDGE_SHARP(e2lfan_curr)) {
- /* Sharp loop, so not a cyclic smooth fan... */
- return false;
- }
-
- mlfan_curr = ml_prev;
- mlfan_curr_index = ml_prev_index;
- mlfan_vert_index = ml_curr_index;
- mpfan_curr_index = mp_curr_index;
-
- BLI_assert(mlfan_curr_index >= 0);
- BLI_assert(mlfan_vert_index >= 0);
- BLI_assert(mpfan_curr_index >= 0);
-
- BLI_assert(!BLI_BITMAP_TEST(skip_loops, mlfan_vert_index));
- BLI_BITMAP_ENABLE(skip_loops, mlfan_vert_index);
-
- while (true) {
- /* Find next loop of the smooth fan. */
- BKE_mesh_loop_manifold_fan_around_vert_next(mloops,
- mpolys,
- loop_to_poly,
- e2lfan_curr,
- mv_pivot_index,
- &mlfan_curr,
- &mlfan_curr_index,
- &mlfan_vert_index,
- &mpfan_curr_index);
-
- e2lfan_curr = edge_to_loops[mlfan_curr->e];
-
- if (IS_EDGE_SHARP(e2lfan_curr)) {
- /* Sharp loop/edge, so not a cyclic smooth fan... */
- return false;
- }
- /* Smooth loop/edge... */
- if (BLI_BITMAP_TEST(skip_loops, mlfan_vert_index)) {
- if (mlfan_vert_index == ml_curr_index) {
- /* We walked around a whole cyclic smooth fan without finding any already-processed loop,
- * means we can use initial ml_curr/ml_prev edge as start for this smooth fan. */
- return true;
- }
- /* ... already checked in some previous looping, we can abort. */
- return false;
- }
-
- /* ... we can skip it in future, and keep checking the smooth fan. */
- BLI_BITMAP_ENABLE(skip_loops, mlfan_vert_index);
- }
-}
-
-static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common_data)
-{
- MLoopNorSpaceArray *lnors_spacearr = common_data->lnors_spacearr;
- float(*loopnors)[3] = common_data->loopnors;
-
- const MLoop *mloops = common_data->mloops;
- const MPoly *mpolys = common_data->mpolys;
- const int *loop_to_poly = common_data->loop_to_poly;
- const int(*edge_to_loops)[2] = common_data->edge_to_loops;
- const int numLoops = common_data->numLoops;
- const int numPolys = common_data->numPolys;
-
- const MPoly *mp;
- int mp_index;
-
- const MLoop *ml_curr;
- const MLoop *ml_prev;
- int ml_curr_index;
- int ml_prev_index;
-
- BLI_bitmap *skip_loops = BLI_BITMAP_NEW(numLoops, __func__);
-
- LoopSplitTaskData *data_buff = NULL;
- int data_idx = 0;
-
- /* Temp edge vectors stack, only used when computing lnor spacearr
- * (and we are not multi-threading). */
- BLI_Stack *edge_vectors = NULL;
-
-#ifdef DEBUG_TIME
- TIMEIT_START_AVERAGED(loop_split_generator);
-#endif
-
- if (!pool) {
- if (lnors_spacearr) {
- edge_vectors = BLI_stack_new(sizeof(float[3]), __func__);
- }
- }
-
- /* We now know edges that can be smoothed (with their vector, and their two loops),
- * and edges that will be hard! Now, time to generate the normals.
- */
- for (mp = mpolys, mp_index = 0; mp_index < numPolys; mp++, mp_index++) {
- float(*lnors)[3];
- const int ml_last_index = (mp->loopstart + mp->totloop) - 1;
- ml_curr_index = mp->loopstart;
- ml_prev_index = ml_last_index;
-
- ml_curr = &mloops[ml_curr_index];
- ml_prev = &mloops[ml_prev_index];
- lnors = &loopnors[ml_curr_index];
-
- for (; ml_curr_index <= ml_last_index; ml_curr++, ml_curr_index++, lnors++) {
- const int *e2l_curr = edge_to_loops[ml_curr->e];
- const int *e2l_prev = edge_to_loops[ml_prev->e];
-
-#if 0
- printf("Checking loop %d / edge %u / vert %u (sharp edge: %d, skiploop: %d)...",
- ml_curr_index,
- ml_curr->e,
- ml_curr->v,
- IS_EDGE_SHARP(e2l_curr),
- BLI_BITMAP_TEST_BOOL(skip_loops, ml_curr_index));
-#endif
-
- /* A smooth edge, we have to check for cyclic smooth fan case.
- * If we find a new, never-processed cyclic smooth fan, we can do it now using that loop/edge
- * as 'entry point', otherwise we can skip it. */
-
- /* Note: In theory, we could make loop_split_generator_check_cyclic_smooth_fan() store
- * mlfan_vert_index'es and edge indexes in two stacks, to avoid having to fan again around
- * the vert during actual computation of clnor & clnorspace. However, this would complicate
- * the code, add more memory usage, and despite its logical complexity,
- * loop_manifold_fan_around_vert_next() is quite cheap in term of CPU cycles,
- * so really think it's not worth it. */
- if (!IS_EDGE_SHARP(e2l_curr) && (BLI_BITMAP_TEST(skip_loops, ml_curr_index) ||
- !loop_split_generator_check_cyclic_smooth_fan(mloops,
- mpolys,
- edge_to_loops,
- loop_to_poly,
- e2l_prev,
- skip_loops,
- ml_curr,
- ml_prev,
- ml_curr_index,
- ml_prev_index,
- mp_index))) {
- // printf("SKIPPING!\n");
- }
- else {
- LoopSplitTaskData *data, data_local;
-
- // printf("PROCESSING!\n");
-
- if (pool) {
- if (data_idx == 0) {
- data_buff = MEM_calloc_arrayN(
- LOOP_SPLIT_TASK_BLOCK_SIZE, sizeof(*data_buff), __func__);
- }
- data = &data_buff[data_idx];
- }
- else {
- data = &data_local;
- memset(data, 0, sizeof(*data));
- }
-
- if (IS_EDGE_SHARP(e2l_curr) && IS_EDGE_SHARP(e2l_prev)) {
- data->lnor = lnors;
- data->ml_curr = ml_curr;
- data->ml_prev = ml_prev;
- data->ml_curr_index = ml_curr_index;
-#if 0 /* Not needed for 'single' loop. */
- data->ml_prev_index = ml_prev_index;
- data->e2l_prev = NULL; /* Tag as 'single' task. */
-#endif
- data->mp_index = mp_index;
- if (lnors_spacearr) {
- data->lnor_space = BKE_lnor_space_create(lnors_spacearr);
- }
- }
- /* We *do not need* to check/tag loops as already computed!
- * Due to the fact a loop only links to one of its two edges,
- * a same fan *will never be walked more than once!*
- * Since we consider edges having neighbor polys with inverted
- * (flipped) normals as sharp, we are sure that no fan will be skipped,
- * even only considering the case (sharp curr_edge, smooth prev_edge),
- * and not the alternative (smooth curr_edge, sharp prev_edge).
- * All this due/thanks to link between normals and loop ordering (i.e. winding).
- */
- else {
-#if 0 /* Not needed for 'fan' loops. */
- data->lnor = lnors;
-#endif
- data->ml_curr = ml_curr;
- data->ml_prev = ml_prev;
- data->ml_curr_index = ml_curr_index;
- data->ml_prev_index = ml_prev_index;
- data->e2l_prev = e2l_prev; /* Also tag as 'fan' task. */
- data->mp_index = mp_index;
- if (lnors_spacearr) {
- data->lnor_space = BKE_lnor_space_create(lnors_spacearr);
- }
- }
-
- if (pool) {
- data_idx++;
- if (data_idx == LOOP_SPLIT_TASK_BLOCK_SIZE) {
- BLI_task_pool_push(pool, loop_split_worker, data_buff, true, NULL);
- data_idx = 0;
- }
- }
- else {
- loop_split_worker_do(common_data, data, edge_vectors);
- }
- }
-
- ml_prev = ml_curr;
- ml_prev_index = ml_curr_index;
- }
- }
-
- /* Last block of data... Since it is calloc'ed and we use first NULL item as stopper,
- * everything is fine. */
- if (pool && data_idx) {
- BLI_task_pool_push(pool, loop_split_worker, data_buff, true, NULL);
- }
-
- if (edge_vectors) {
- BLI_stack_free(edge_vectors);
- }
- MEM_freeN(skip_loops);
-
-#ifdef DEBUG_TIME
- TIMEIT_END_AVERAGED(loop_split_generator);
-#endif
-}
-
-/**
- * Compute split normals, i.e. vertex normals associated with each poly (hence 'loop normals').
- * Useful to materialize sharp edges (or non-smooth faces) without actually modifying the geometry
- * (splitting edges).
- */
-void BKE_mesh_normals_loop_split(const MVert *mverts,
- const int UNUSED(numVerts),
- MEdge *medges,
- const int numEdges,
- MLoop *mloops,
- float (*r_loopnors)[3],
- const int numLoops,
- MPoly *mpolys,
- const float (*polynors)[3],
- const int numPolys,
- const bool use_split_normals,
- const float split_angle,
- MLoopNorSpaceArray *r_lnors_spacearr,
- short (*clnors_data)[2],
- int *r_loop_to_poly)
-{
- /* For now this is not supported.
- * If we do not use split normals, we do not generate anything fancy! */
- BLI_assert(use_split_normals || !(r_lnors_spacearr));
-
- if (!use_split_normals) {
- /* In this case, we simply fill lnors with vnors (or fnors for flat faces), quite simple!
- * Note this is done here to keep some logic and consistency in this quite complex code,
- * since we may want to use lnors even when mesh's 'autosmooth' is disabled
- * (see e.g. mesh mapping code).
- * As usual, we could handle that on case-by-case basis,
- * but simpler to keep it well confined here.
- */
- int mp_index;
-
- for (mp_index = 0; mp_index < numPolys; mp_index++) {
- MPoly *mp = &mpolys[mp_index];
- int ml_index = mp->loopstart;
- const int ml_index_end = ml_index + mp->totloop;
- const bool is_poly_flat = ((mp->flag & ME_SMOOTH) == 0);
-
- for (; ml_index < ml_index_end; ml_index++) {
- if (r_loop_to_poly) {
- r_loop_to_poly[ml_index] = mp_index;
- }
- if (is_poly_flat) {
- copy_v3_v3(r_loopnors[ml_index], polynors[mp_index]);
- }
- else {
- normal_short_to_float_v3(r_loopnors[ml_index], mverts[mloops[ml_index].v].no);
- }
- }
- }
- return;
- }
-
- /**
- * Mapping edge -> loops.
- * If that edge is used by more than two loops (polys),
- * it is always sharp (and tagged as such, see below).
- * We also use the second loop index as a kind of flag:
- *
- * - smooth edge: > 0.
- * - sharp edge: < 0 (INDEX_INVALID || INDEX_UNSET).
- * - unset: INDEX_UNSET.
- *
- * Note that currently we only have two values for second loop of sharp edges.
- * However, if needed, we can store the negated value of loop index instead of INDEX_INVALID
- * to retrieve the real value later in code).
- * Note also that loose edges always have both values set to 0! */
- int(*edge_to_loops)[2] = MEM_calloc_arrayN((size_t)numEdges, sizeof(*edge_to_loops), __func__);
-
- /* Simple mapping from a loop to its polygon index. */
- int *loop_to_poly = r_loop_to_poly ?
- r_loop_to_poly :
- MEM_malloc_arrayN((size_t)numLoops, sizeof(*loop_to_poly), __func__);
-
- /* When using custom loop normals, disable the angle feature! */
- const bool check_angle = (split_angle < (float)M_PI) && (clnors_data == NULL);
-
- MLoopNorSpaceArray _lnors_spacearr = {NULL};
-
-#ifdef DEBUG_TIME
- TIMEIT_START_AVERAGED(BKE_mesh_normals_loop_split);
-#endif
-
- if (!r_lnors_spacearr && clnors_data) {
- /* We need to compute lnor spacearr if some custom lnor data are given to us! */
- r_lnors_spacearr = &_lnors_spacearr;
- }
- if (r_lnors_spacearr) {
- BKE_lnor_spacearr_init(r_lnors_spacearr, numLoops, MLNOR_SPACEARR_LOOP_INDEX);
- }
-
- /* Init data common to all tasks. */
- LoopSplitTaskDataCommon common_data = {
- .lnors_spacearr = r_lnors_spacearr,
- .loopnors = r_loopnors,
- .clnors_data = clnors_data,
- .mverts = mverts,
- .medges = medges,
- .mloops = mloops,
- .mpolys = mpolys,
- .edge_to_loops = edge_to_loops,
- .loop_to_poly = loop_to_poly,
- .polynors = polynors,
- .numEdges = numEdges,
- .numLoops = numLoops,
- .numPolys = numPolys,
- };
-
- /* This first loop check which edges are actually smooth, and compute edge vectors. */
- mesh_edges_sharp_tag(&common_data, check_angle, split_angle, false);
-
- if (numLoops < LOOP_SPLIT_TASK_BLOCK_SIZE * 8) {
- /* Not enough loops to be worth the whole threading overhead... */
- loop_split_generator(NULL, &common_data);
- }
- else {
- TaskPool *task_pool = BLI_task_pool_create(&common_data, TASK_PRIORITY_HIGH);
-
- loop_split_generator(task_pool, &common_data);
-
- BLI_task_pool_work_and_wait(task_pool);
-
- BLI_task_pool_free(task_pool);
- }
-
- MEM_freeN(edge_to_loops);
- if (!r_loop_to_poly) {
- MEM_freeN(loop_to_poly);
- }
-
- if (r_lnors_spacearr) {
- if (r_lnors_spacearr == &_lnors_spacearr) {
- BKE_lnor_spacearr_free(r_lnors_spacearr);
- }
- }
-
-#ifdef DEBUG_TIME
- TIMEIT_END_AVERAGED(BKE_mesh_normals_loop_split);
-#endif
-}
-
-#undef INDEX_UNSET
-#undef INDEX_INVALID
-#undef IS_EDGE_SHARP
-
-/**
- * Compute internal representation of given custom normals (as an array of float[2]).
- * It also makes sure the mesh matches those custom normals, by setting sharp edges flag as needed
- * to get a same custom lnor for all loops sharing a same smooth fan.
- * If use_vertices if true, r_custom_loopnors is assumed to be per-vertex, not per-loop
- * (this allows to set whole vert's normals at once, useful in some cases).
- * r_custom_loopnors is expected to have normalized normals, or zero ones,
- * in which case they will be replaced by default loop/vertex normal.
- */
-static void mesh_normals_loop_custom_set(const MVert *mverts,
- const int numVerts,
- MEdge *medges,
- const int numEdges,
- MLoop *mloops,
- float (*r_custom_loopnors)[3],
- const int numLoops,
- MPoly *mpolys,
- const float (*polynors)[3],
- const int numPolys,
- short (*r_clnors_data)[2],
- const bool use_vertices)
-{
- /* We *may* make that poor BKE_mesh_normals_loop_split() even more complex by making it handling
- * that feature too, would probably be more efficient in absolute.
- * However, this function *is not* performance-critical, since it is mostly expected to be called
- * by io addons when importing custom normals, and modifier
- * (and perhaps from some editing tools later?).
- * So better to keep some simplicity here, and just call BKE_mesh_normals_loop_split() twice!
- */
- MLoopNorSpaceArray lnors_spacearr = {NULL};
- BLI_bitmap *done_loops = BLI_BITMAP_NEW((size_t)numLoops, __func__);
- float(*lnors)[3] = MEM_calloc_arrayN((size_t)numLoops, sizeof(*lnors), __func__);
- int *loop_to_poly = MEM_malloc_arrayN((size_t)numLoops, sizeof(int), __func__);
- /* In this case we always consider split nors as ON,
- * and do not want to use angle to define smooth fans! */
- const bool use_split_normals = true;
- const float split_angle = (float)M_PI;
-
- BLI_SMALLSTACK_DECLARE(clnors_data, short *);
-
- /* Compute current lnor spacearr. */
- BKE_mesh_normals_loop_split(mverts,
- numVerts,
- medges,
- numEdges,
- mloops,
- lnors,
- numLoops,
- mpolys,
- polynors,
- numPolys,
- use_split_normals,
- split_angle,
- &lnors_spacearr,
- NULL,
- loop_to_poly);
-
- /* Set all given zero vectors to their default value. */
- if (use_vertices) {
- for (int i = 0; i < numVerts; i++) {
- if (is_zero_v3(r_custom_loopnors[i])) {
- normal_short_to_float_v3(r_custom_loopnors[i], mverts[i].no);
- }
- }
- }
- else {
- for (int i = 0; i < numLoops; i++) {
- if (is_zero_v3(r_custom_loopnors[i])) {
- copy_v3_v3(r_custom_loopnors[i], lnors[i]);
- }
- }
- }
-
- BLI_assert(lnors_spacearr.data_type == MLNOR_SPACEARR_LOOP_INDEX);
-
- /* Now, check each current smooth fan (one lnor space per smooth fan!),
- * and if all its matching custom lnors are not (enough) equal, add sharp edges as needed.
- * This way, next time we run BKE_mesh_normals_loop_split(), we'll get lnor spacearr/smooth fans
- * matching given custom lnors.
- * Note this code *will never* unsharp edges! And quite obviously,
- * when we set custom normals per vertices, running this is absolutely useless.
- */
- if (!use_vertices) {
- for (int i = 0; i < numLoops; i++) {
- if (!lnors_spacearr.lspacearr[i]) {
- /* This should not happen in theory, but in some rare case (probably ugly geometry)
- * we can get some NULL loopspacearr at this point. :/
- * Maybe we should set those loops' edges as sharp?
- */
- BLI_BITMAP_ENABLE(done_loops, i);
- if (G.debug & G_DEBUG) {
- printf("WARNING! Getting invalid NULL loop space for loop %d!\n", i);
- }
- continue;
- }
-
- if (!BLI_BITMAP_TEST(done_loops, i)) {
- /* Notes:
- * * In case of mono-loop smooth fan, we have nothing to do.
- * * Loops in this linklist are ordered (in reversed order compared to how they were
- * discovered by BKE_mesh_normals_loop_split(), but this is not a problem).
- * Which means if we find a mismatching clnor,
- * we know all remaining loops will have to be in a new, different smooth fan/lnor space.
- * * In smooth fan case, we compare each clnor against a ref one,
- * to avoid small differences adding up into a real big one in the end!
- */
- if (lnors_spacearr.lspacearr[i]->flags & MLNOR_SPACE_IS_SINGLE) {
- BLI_BITMAP_ENABLE(done_loops, i);
- continue;
- }
-
- LinkNode *loops = lnors_spacearr.lspacearr[i]->loops;
- MLoop *prev_ml = NULL;
- const float *org_nor = NULL;
-
- while (loops) {
- const int lidx = POINTER_AS_INT(loops->link);
- MLoop *ml = &mloops[lidx];
- const int nidx = lidx;
- float *nor = r_custom_loopnors[nidx];
-
- if (!org_nor) {
- org_nor = nor;
- }
- else if (dot_v3v3(org_nor, nor) < LNOR_SPACE_TRIGO_THRESHOLD) {
- /* Current normal differs too much from org one, we have to tag the edge between
- * previous loop's face and current's one as sharp.
- * We know those two loops do not point to the same edge,
- * since we do not allow reversed winding in a same smooth fan.
- */
- const MPoly *mp = &mpolys[loop_to_poly[lidx]];
- const MLoop *mlp =
- &mloops[(lidx == mp->loopstart) ? mp->loopstart + mp->totloop - 1 : lidx - 1];
- medges[(prev_ml->e == mlp->e) ? prev_ml->e : ml->e].flag |= ME_SHARP;
-
- org_nor = nor;
- }
-
- prev_ml = ml;
- loops = loops->next;
- BLI_BITMAP_ENABLE(done_loops, lidx);
- }
-
- /* We also have to check between last and first loops,
- * otherwise we may miss some sharp edges here!
- * This is just a simplified version of above while loop.
- * See T45984. */
- loops = lnors_spacearr.lspacearr[i]->loops;
- if (loops && org_nor) {
- const int lidx = POINTER_AS_INT(loops->link);
- MLoop *ml = &mloops[lidx];
- const int nidx = lidx;
- float *nor = r_custom_loopnors[nidx];
-
- if (dot_v3v3(org_nor, nor) < LNOR_SPACE_TRIGO_THRESHOLD) {
- const MPoly *mp = &mpolys[loop_to_poly[lidx]];
- const MLoop *mlp =
- &mloops[(lidx == mp->loopstart) ? mp->loopstart + mp->totloop - 1 : lidx - 1];
- medges[(prev_ml->e == mlp->e) ? prev_ml->e : ml->e].flag |= ME_SHARP;
- }
- }
- }
- }
-
- /* And now, recompute our new auto lnors and lnor spacearr! */
- BKE_lnor_spacearr_clear(&lnors_spacearr);
- BKE_mesh_normals_loop_split(mverts,
- numVerts,
- medges,
- numEdges,
- mloops,
- lnors,
- numLoops,
- mpolys,
- polynors,
- numPolys,
- use_split_normals,
- split_angle,
- &lnors_spacearr,
- NULL,
- loop_to_poly);
- }
- else {
- BLI_bitmap_set_all(done_loops, true, (size_t)numLoops);
- }
-
- /* And we just have to convert plain object-space custom normals to our
- * lnor space-encoded ones. */
- for (int i = 0; i < numLoops; i++) {
- if (!lnors_spacearr.lspacearr[i]) {
- BLI_BITMAP_DISABLE(done_loops, i);
- if (G.debug & G_DEBUG) {
- printf("WARNING! Still getting invalid NULL loop space in second loop for loop %d!\n", i);
- }
- continue;
- }
-
- if (BLI_BITMAP_TEST_BOOL(done_loops, i)) {
- /* Note we accumulate and average all custom normals in current smooth fan,
- * to avoid getting different clnors data (tiny differences in plain custom normals can
- * give rather huge differences in computed 2D factors).
- */
- LinkNode *loops = lnors_spacearr.lspacearr[i]->loops;
- if (lnors_spacearr.lspacearr[i]->flags & MLNOR_SPACE_IS_SINGLE) {
- BLI_assert(POINTER_AS_INT(loops) == i);
- const int nidx = use_vertices ? (int)mloops[i].v : i;
- float *nor = r_custom_loopnors[nidx];
-
- BKE_lnor_space_custom_normal_to_data(lnors_spacearr.lspacearr[i], nor, r_clnors_data[i]);
- BLI_BITMAP_DISABLE(done_loops, i);
- }
- else {
- int nbr_nors = 0;
- float avg_nor[3];
- short clnor_data_tmp[2], *clnor_data;
-
- zero_v3(avg_nor);
- while (loops) {
- const int lidx = POINTER_AS_INT(loops->link);
- const int nidx = use_vertices ? (int)mloops[lidx].v : lidx;
- float *nor = r_custom_loopnors[nidx];
-
- nbr_nors++;
- add_v3_v3(avg_nor, nor);
- BLI_SMALLSTACK_PUSH(clnors_data, (short *)r_clnors_data[lidx]);
-
- loops = loops->next;
- BLI_BITMAP_DISABLE(done_loops, lidx);
- }
-
- mul_v3_fl(avg_nor, 1.0f / (float)nbr_nors);
- BKE_lnor_space_custom_normal_to_data(lnors_spacearr.lspacearr[i], avg_nor, clnor_data_tmp);
-
- while ((clnor_data = BLI_SMALLSTACK_POP(clnors_data))) {
- clnor_data[0] = clnor_data_tmp[0];
- clnor_data[1] = clnor_data_tmp[1];
- }
- }
- }
- }
-
- MEM_freeN(lnors);
- MEM_freeN(loop_to_poly);
- MEM_freeN(done_loops);
- BKE_lnor_spacearr_free(&lnors_spacearr);
-}
-
-void BKE_mesh_normals_loop_custom_set(const MVert *mverts,
- const int numVerts,
- MEdge *medges,
- const int numEdges,
- MLoop *mloops,
- float (*r_custom_loopnors)[3],
- const int numLoops,
- MPoly *mpolys,
- const float (*polynors)[3],
- const int numPolys,
- short (*r_clnors_data)[2])
-{
- mesh_normals_loop_custom_set(mverts,
- numVerts,
- medges,
- numEdges,
- mloops,
- r_custom_loopnors,
- numLoops,
- mpolys,
- polynors,
- numPolys,
- r_clnors_data,
- false);
-}
-
-void BKE_mesh_normals_loop_custom_from_vertices_set(const MVert *mverts,
- float (*r_custom_vertnors)[3],
- const int numVerts,
- MEdge *medges,
- const int numEdges,
- MLoop *mloops,
- const int numLoops,
- MPoly *mpolys,
- const float (*polynors)[3],
- const int numPolys,
- short (*r_clnors_data)[2])
-{
- mesh_normals_loop_custom_set(mverts,
- numVerts,
- medges,
- numEdges,
- mloops,
- r_custom_vertnors,
- numLoops,
- mpolys,
- polynors,
- numPolys,
- r_clnors_data,
- true);
-}
-
-static void mesh_set_custom_normals(Mesh *mesh, float (*r_custom_nors)[3], const bool use_vertices)
-{
- short(*clnors)[2];
- const int numloops = mesh->totloop;
-
- clnors = CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL);
- if (clnors != NULL) {
- memset(clnors, 0, sizeof(*clnors) * (size_t)numloops);
- }
- else {
- clnors = CustomData_add_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL, CD_CALLOC, NULL, numloops);
- }
-
- float(*polynors)[3] = CustomData_get_layer(&mesh->pdata, CD_NORMAL);
- bool free_polynors = false;
- if (polynors == NULL) {
- polynors = MEM_mallocN(sizeof(float[3]) * (size_t)mesh->totpoly, __func__);
- BKE_mesh_calc_normals_poly(mesh->mvert,
- NULL,
- mesh->totvert,
- mesh->mloop,
- mesh->mpoly,
- mesh->totloop,
- mesh->totpoly,
- polynors,
- false);
- free_polynors = true;
- }
-
- mesh_normals_loop_custom_set(mesh->mvert,
- mesh->totvert,
- mesh->medge,
- mesh->totedge,
- mesh->mloop,
- r_custom_nors,
- mesh->totloop,
- mesh->mpoly,
- polynors,
- mesh->totpoly,
- clnors,
- use_vertices);
-
- if (free_polynors) {
- MEM_freeN(polynors);
- }
-}
-
-/**
- * Higher level functions hiding most of the code needed around call to
- * #BKE_mesh_normals_loop_custom_set().
- *
- * \param r_custom_loopnors: is not const, since code will replace zero_v3 normals there
- * with automatically computed vectors.
- */
-void BKE_mesh_set_custom_normals(Mesh *mesh, float (*r_custom_loopnors)[3])
-{
- mesh_set_custom_normals(mesh, r_custom_loopnors, false);
-}
-
-/**
- * Higher level functions hiding most of the code needed around call to
- * #BKE_mesh_normals_loop_custom_from_vertices_set().
- *
- * \param r_custom_vertnors: is not const, since code will replace zero_v3 normals there
- * with automatically computed vectors.
- */
-void BKE_mesh_set_custom_normals_from_vertices(Mesh *mesh, float (*r_custom_vertnors)[3])
-{
- mesh_set_custom_normals(mesh, r_custom_vertnors, true);
-}
-
-/**
- * Computes average per-vertex normals from given custom loop normals.
- *
- * \param clnors: The computed custom loop normals.
- * \param r_vert_clnors: The (already allocated) array where to store averaged per-vertex normals.
- */
-void BKE_mesh_normals_loop_to_vertex(const int numVerts,
- const MLoop *mloops,
- const int numLoops,
- const float (*clnors)[3],
- float (*r_vert_clnors)[3])
-{
- int *vert_loops_nbr = MEM_calloc_arrayN((size_t)numVerts, sizeof(*vert_loops_nbr), __func__);
-
- copy_vn_fl((float *)r_vert_clnors, 3 * numVerts, 0.0f);
-
- int i;
- const MLoop *ml;
- for (i = 0, ml = mloops; i < numLoops; i++, ml++) {
- const uint v = ml->v;
-
- add_v3_v3(r_vert_clnors[v], clnors[i]);
- vert_loops_nbr[v]++;
- }
-
- for (i = 0; i < numVerts; i++) {
- mul_v3_fl(r_vert_clnors[i], 1.0f / (float)vert_loops_nbr[i]);
- }
-
- MEM_freeN(vert_loops_nbr);
-}
-
-#undef LNOR_SPACE_TRIGO_THRESHOLD
-
-/** \} */
/* -------------------------------------------------------------------- */
/** \name Polygon Calculations
@@ -3280,8 +1174,8 @@ void BKE_mesh_flush_select_from_polys_ex(MVert *mvert,
i = totpoly;
for (mp = mpoly; i--; mp++) {
- /* assume if its selected its not hidden and none of its verts/edges are hidden
- * (a common assumption)*/
+ /* Assume if its selected its not hidden and none of its verts/edges are hidden
+ * (a common assumption). */
if (mp->flag & ME_FACE_SEL) {
const MLoop *ml;
int j;
diff --git a/source/blender/blenkernel/intern/mesh_mapping.c b/source/blender/blenkernel/intern/mesh_mapping.c
index d4119f48193..c469a65449d 100644
--- a/source/blender/blenkernel/intern/mesh_mapping.c
+++ b/source/blender/blenkernel/intern/mesh_mapping.c
@@ -535,7 +535,7 @@ void BKE_mesh_edge_poly_map_create(MeshElemMap **r_map,
*
* This has the advantage that it can operate on any data-types.
*
- * \param totsource: The total number of elements the that \a final_origindex points to.
+ * \param totsource: The total number of elements that \a final_origindex points to.
* \param totfinal: The size of \a final_origindex
* \param final_origindex: The size of the final array.
*
diff --git a/source/blender/blenkernel/intern/mesh_merge.c b/source/blender/blenkernel/intern/mesh_merge.c
index fb73152cb8e..1e51ee73c7c 100644
--- a/source/blender/blenkernel/intern/mesh_merge.c
+++ b/source/blender/blenkernel/intern/mesh_merge.c
@@ -109,7 +109,7 @@ static int cddm_poly_compare(MLoop *mloop_array,
i_loop_source++;
if (i_loop_source == mpoly_source->totloop) {
- /* End of loops for source, must match end of loop for target. */
+ /* End of loops for source, must match end of loop for target. */
if (i_loop_target_offset == mpoly_target->totloop - 1) {
compare_completed = true;
same_loops = true;
@@ -597,7 +597,7 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
mp_new->loopstart = STACK_SIZE(mloop) - c;
STACK_PUSH(oldp, i);
- } /* end of the loop that tests polys */
+ } /* End of the loop that tests polys. */
if (poly_gset) {
// printf("hash quality %.6f\n", BLI_gset_calc_quality(poly_gset));
@@ -606,11 +606,11 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
MEM_freeN(poly_keys);
}
- /*create new cddm*/
+ /* Create new cddm. */
result = BKE_mesh_new_nomain_from_template(
mesh, STACK_SIZE(mvert), STACK_SIZE(medge), 0, STACK_SIZE(mloop), STACK_SIZE(mpoly));
- /*update edge indices and copy customdata*/
+ /* Update edge indices and copy customdata. */
med = medge;
for (i = 0; i < result->totedge; i++, med++) {
BLI_assert(newv[med->v1] != -1);
@@ -624,7 +624,7 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
CustomData_copy_data(&mesh->edata, &result->edata, olde[i], i, 1);
}
- /*update loop indices and copy customdata*/
+ /* Update loop indices and copy customdata. */
ml = mloop;
for (i = 0; i < result->totloop; i++, ml++) {
/* Edge remapping has already be done in main loop handling part above. */
@@ -634,19 +634,19 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
CustomData_copy_data(&mesh->ldata, &result->ldata, oldl[i], i, 1);
}
- /*copy vertex customdata*/
+ /* Copy vertex customdata. */
mv = mvert;
for (i = 0; i < result->totvert; i++, mv++) {
CustomData_copy_data(&mesh->vdata, &result->vdata, oldv[i], i, 1);
}
- /*copy poly customdata*/
+ /* Copy poly customdata. */
mp = mpoly;
for (i = 0; i < result->totpoly; i++, mp++) {
CustomData_copy_data(&mesh->pdata, &result->pdata, oldp[i], i, 1);
}
- /*copy over data. CustomData_add_layer can do this, need to look it up.*/
+ /* Copy over data. #CustomData_add_layer can do this, need to look it up. */
memcpy(result->mvert, mvert, sizeof(MVert) * STACK_SIZE(mvert));
memcpy(result->medge, medge, sizeof(MEdge) * STACK_SIZE(medge));
memcpy(result->mloop, mloop, sizeof(MLoop) * STACK_SIZE(mloop));
diff --git a/source/blender/blenkernel/intern/mesh_mirror.c b/source/blender/blenkernel/intern/mesh_mirror.c
index 3d30c218fba..9aeaa1ada52 100644
--- a/source/blender/blenkernel/intern/mesh_mirror.c
+++ b/source/blender/blenkernel/intern/mesh_mirror.c
@@ -70,9 +70,9 @@ Mesh *BKE_mesh_mirror_bisect_on_mirror_plane_for_modifier(MirrorModifierData *mm
/* Define bisecting plane (aka mirror plane). */
float plane[4];
if (!do_bisect_flip_axis) {
- /* That reversed condition is a tad weird, but for some reason that's how you keep
- * the part of the mesh which is on the non-mirrored side when flip option is disabled,
- * think that that is the expected behavior. */
+ /* That reversed condition is a little weird, but for some reason that's how you keep
+ * the part of the mesh which is on the non-mirrored side when flip option is disabled.
+ * I think this is the expected behavior. */
negate_v3(plane_no);
}
plane_from_point_normal_v3(plane, plane_co, plane_no);
diff --git a/source/blender/blenkernel/intern/mesh_normals.c b/source/blender/blenkernel/intern/mesh_normals.c
new file mode 100644
index 00000000000..a268f814cd0
--- /dev/null
+++ b/source/blender/blenkernel/intern/mesh_normals.c
@@ -0,0 +1,2144 @@
+/*
+ * 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
+ *
+ * Mesh normal calculation functions.
+ *
+ * \see bmesh_mesh_normals.c for the equivalent #BMesh functionality.
+ */
+
+#include <limits.h>
+
+#include "CLG_log.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BLI_alloca.h"
+#include "BLI_bitmap.h"
+
+#include "BLI_linklist.h"
+#include "BLI_linklist_stack.h"
+#include "BLI_math.h"
+#include "BLI_memarena.h"
+#include "BLI_stack.h"
+#include "BLI_task.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_customdata.h"
+#include "BKE_editmesh_cache.h"
+#include "BKE_global.h"
+#include "BKE_mesh.h"
+
+// #define DEBUG_TIME
+
+#ifdef DEBUG_TIME
+# include "PIL_time.h"
+# include "PIL_time_utildefines.h"
+#endif
+
+static CLG_LogRef LOG = {"bke.mesh_normals"};
+
+/* -------------------------------------------------------------------- */
+/** \name Mesh Normal Calculation
+ * \{ */
+
+/**
+ * Call when there are no polygons.
+ */
+static void mesh_calc_normals_vert_fallback(MVert *mverts, int numVerts)
+{
+ for (int i = 0; i < numVerts; i++) {
+ MVert *mv = &mverts[i];
+ float no[3];
+
+ normalize_v3_v3(no, mv->co);
+ normal_float_to_short_v3(mv->no, no);
+ }
+}
+
+/* TODO(Sybren): we can probably rename this to BKE_mesh_calc_normals_mapping(),
+ * and remove the function of the same name below, as that one doesn't seem to be
+ * called anywhere. */
+void BKE_mesh_calc_normals_mapping_simple(struct Mesh *mesh)
+{
+ const bool only_face_normals = CustomData_is_referenced_layer(&mesh->vdata, CD_MVERT);
+
+ BKE_mesh_calc_normals_mapping_ex(mesh->mvert,
+ mesh->totvert,
+ mesh->mloop,
+ mesh->mpoly,
+ mesh->totloop,
+ mesh->totpoly,
+ NULL,
+ mesh->mface,
+ mesh->totface,
+ NULL,
+ NULL,
+ only_face_normals);
+}
+
+/* Calculate vertex and face normals, face normals are returned in *r_faceNors if non-NULL
+ * and vertex normals are stored in actual mverts.
+ */
+void BKE_mesh_calc_normals_mapping(MVert *mverts,
+ int numVerts,
+ const MLoop *mloop,
+ const MPoly *mpolys,
+ int numLoops,
+ int numPolys,
+ float (*r_polyNors)[3],
+ const MFace *mfaces,
+ int numFaces,
+ const int *origIndexFace,
+ float (*r_faceNors)[3])
+{
+ BKE_mesh_calc_normals_mapping_ex(mverts,
+ numVerts,
+ mloop,
+ mpolys,
+ numLoops,
+ numPolys,
+ r_polyNors,
+ mfaces,
+ numFaces,
+ origIndexFace,
+ r_faceNors,
+ false);
+}
+/* extended version of 'BKE_mesh_calc_normals_poly' with option not to calc vertex normals */
+void BKE_mesh_calc_normals_mapping_ex(MVert *mverts,
+ int numVerts,
+ const MLoop *mloop,
+ const MPoly *mpolys,
+ int numLoops,
+ int numPolys,
+ float (*r_polyNors)[3],
+ const MFace *mfaces,
+ int numFaces,
+ const int *origIndexFace,
+ float (*r_faceNors)[3],
+ const bool only_face_normals)
+{
+ float(*pnors)[3] = r_polyNors, (*fnors)[3] = r_faceNors;
+
+ if (numPolys == 0) {
+ if (only_face_normals == false) {
+ mesh_calc_normals_vert_fallback(mverts, numVerts);
+ }
+ return;
+ }
+
+ /* if we are not calculating verts and no verts were passes then we have nothing to do */
+ if ((only_face_normals == true) && (r_polyNors == NULL) && (r_faceNors == NULL)) {
+ CLOG_WARN(&LOG, "called with nothing to do");
+ return;
+ }
+
+ if (!pnors) {
+ pnors = MEM_calloc_arrayN((size_t)numPolys, sizeof(float[3]), __func__);
+ }
+ /* NO NEED TO ALLOC YET */
+ /* if (!fnors) fnors = MEM_calloc_arrayN(numFaces, sizeof(float[3]), "face nors mesh.c"); */
+
+ if (only_face_normals == false) {
+ /* vertex normals are optional, they require some extra calculations,
+ * so make them optional */
+ BKE_mesh_calc_normals_poly(
+ mverts, NULL, numVerts, mloop, mpolys, numLoops, numPolys, pnors, false);
+ }
+ else {
+ /* only calc poly normals */
+ const MPoly *mp = mpolys;
+ for (int i = 0; i < numPolys; i++, mp++) {
+ BKE_mesh_calc_poly_normal(mp, mloop + mp->loopstart, mverts, pnors[i]);
+ }
+ }
+
+ if (origIndexFace &&
+ /* fnors == r_faceNors */ /* NO NEED TO ALLOC YET */
+ fnors != NULL &&
+ numFaces) {
+ const MFace *mf = mfaces;
+ for (int i = 0; i < numFaces; i++, mf++, origIndexFace++) {
+ if (*origIndexFace < numPolys) {
+ copy_v3_v3(fnors[i], pnors[*origIndexFace]);
+ }
+ else {
+ /* eek, we're not corresponding to polys */
+ CLOG_ERROR(&LOG, "tessellation face indices are incorrect. normals may look bad.");
+ }
+ }
+ }
+
+ if (pnors != r_polyNors) {
+ MEM_freeN(pnors);
+ }
+ /* if (fnors != r_faceNors) MEM_freeN(fnors); */ /* NO NEED TO ALLOC YET */
+
+ fnors = pnors = NULL;
+}
+
+typedef struct MeshCalcNormalsData {
+ const MPoly *mpolys;
+ const MLoop *mloop;
+ MVert *mverts;
+ float (*pnors)[3];
+ float (*lnors_weighted)[3];
+ float (*vnors)[3];
+} MeshCalcNormalsData;
+
+static void mesh_calc_normals_poly_cb(void *__restrict userdata,
+ const int pidx,
+ const TaskParallelTLS *__restrict UNUSED(tls))
+{
+ MeshCalcNormalsData *data = userdata;
+ const MPoly *mp = &data->mpolys[pidx];
+
+ BKE_mesh_calc_poly_normal(mp, data->mloop + mp->loopstart, data->mverts, data->pnors[pidx]);
+}
+
+static void mesh_calc_normals_poly_prepare_cb(void *__restrict userdata,
+ const int pidx,
+ const TaskParallelTLS *__restrict UNUSED(tls))
+{
+ MeshCalcNormalsData *data = userdata;
+ const MPoly *mp = &data->mpolys[pidx];
+ const MLoop *ml = &data->mloop[mp->loopstart];
+ const MVert *mverts = data->mverts;
+
+ float pnor_temp[3];
+ float *pnor = data->pnors ? data->pnors[pidx] : pnor_temp;
+ float(*lnors_weighted)[3] = data->lnors_weighted;
+
+ const int nverts = mp->totloop;
+ float(*edgevecbuf)[3] = BLI_array_alloca(edgevecbuf, (size_t)nverts);
+
+ /* Polygon Normal and edge-vector */
+ /* inline version of #BKE_mesh_calc_poly_normal, also does edge-vectors */
+ {
+ int i_prev = nverts - 1;
+ const float *v_prev = mverts[ml[i_prev].v].co;
+ const float *v_curr;
+
+ zero_v3(pnor);
+ /* Newell's Method */
+ for (int i = 0; i < nverts; i++) {
+ v_curr = mverts[ml[i].v].co;
+ add_newell_cross_v3_v3v3(pnor, v_prev, v_curr);
+
+ /* Unrelated to normalize, calculate edge-vector */
+ sub_v3_v3v3(edgevecbuf[i_prev], v_prev, v_curr);
+ normalize_v3(edgevecbuf[i_prev]);
+ i_prev = i;
+
+ v_prev = v_curr;
+ }
+ if (UNLIKELY(normalize_v3(pnor) == 0.0f)) {
+ pnor[2] = 1.0f; /* other axes set to 0.0 */
+ }
+ }
+
+ /* accumulate angle weighted face normal */
+ /* inline version of #accumulate_vertex_normals_poly_v3,
+ * split between this threaded callback and #mesh_calc_normals_poly_accum_cb. */
+ {
+ const float *prev_edge = edgevecbuf[nverts - 1];
+
+ for (int i = 0; i < nverts; i++) {
+ const int lidx = mp->loopstart + i;
+ const float *cur_edge = edgevecbuf[i];
+
+ /* calculate angle between the two poly edges incident on
+ * this vertex */
+ const float fac = saacos(-dot_v3v3(cur_edge, prev_edge));
+
+ /* Store for later accumulation */
+ mul_v3_v3fl(lnors_weighted[lidx], pnor, fac);
+
+ prev_edge = cur_edge;
+ }
+ }
+}
+
+static void mesh_calc_normals_poly_finalize_cb(void *__restrict userdata,
+ const int vidx,
+ const TaskParallelTLS *__restrict UNUSED(tls))
+{
+ MeshCalcNormalsData *data = userdata;
+
+ MVert *mv = &data->mverts[vidx];
+ float *no = data->vnors[vidx];
+
+ if (UNLIKELY(normalize_v3(no) == 0.0f)) {
+ /* following Mesh convention; we use vertex coordinate itself for normal in this case */
+ normalize_v3_v3(no, mv->co);
+ }
+
+ normal_float_to_short_v3(mv->no, no);
+}
+
+void BKE_mesh_calc_normals_poly(MVert *mverts,
+ float (*r_vertnors)[3],
+ int numVerts,
+ const MLoop *mloop,
+ const MPoly *mpolys,
+ int numLoops,
+ int numPolys,
+ float (*r_polynors)[3],
+ const bool only_face_normals)
+{
+ float(*pnors)[3] = r_polynors;
+
+ TaskParallelSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ settings.min_iter_per_thread = 1024;
+
+ if (only_face_normals) {
+ BLI_assert((pnors != NULL) || (numPolys == 0));
+ BLI_assert(r_vertnors == NULL);
+
+ MeshCalcNormalsData data = {
+ .mpolys = mpolys,
+ .mloop = mloop,
+ .mverts = mverts,
+ .pnors = pnors,
+ };
+
+ BLI_task_parallel_range(0, numPolys, &data, mesh_calc_normals_poly_cb, &settings);
+ return;
+ }
+
+ float(*vnors)[3] = r_vertnors;
+ float(*lnors_weighted)[3] = MEM_malloc_arrayN(
+ (size_t)numLoops, sizeof(*lnors_weighted), __func__);
+ bool free_vnors = false;
+
+ /* first go through and calculate normals for all the polys */
+ if (vnors == NULL) {
+ vnors = MEM_calloc_arrayN((size_t)numVerts, sizeof(*vnors), __func__);
+ free_vnors = true;
+ }
+ else {
+ memset(vnors, 0, sizeof(*vnors) * (size_t)numVerts);
+ }
+
+ MeshCalcNormalsData data = {
+ .mpolys = mpolys,
+ .mloop = mloop,
+ .mverts = mverts,
+ .pnors = pnors,
+ .lnors_weighted = lnors_weighted,
+ .vnors = vnors,
+ };
+
+ /* Compute poly normals, and prepare weighted loop normals. */
+ BLI_task_parallel_range(0, numPolys, &data, mesh_calc_normals_poly_prepare_cb, &settings);
+
+ /* Actually accumulate weighted loop normals into vertex ones. */
+ /* Unfortunately, not possible to thread that
+ * (not in a reasonable, totally lock- and barrier-free fashion),
+ * since several loops will point to the same vertex... */
+ for (int lidx = 0; lidx < numLoops; lidx++) {
+ add_v3_v3(vnors[mloop[lidx].v], data.lnors_weighted[lidx]);
+ }
+
+ /* Normalize and validate computed vertex normals. */
+ BLI_task_parallel_range(0, numVerts, &data, mesh_calc_normals_poly_finalize_cb, &settings);
+
+ if (free_vnors) {
+ MEM_freeN(vnors);
+ }
+ MEM_freeN(lnors_weighted);
+}
+
+void BKE_mesh_ensure_normals(Mesh *mesh)
+{
+ if (mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL) {
+ BKE_mesh_calc_normals(mesh);
+ }
+ BLI_assert((mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL) == 0);
+}
+
+/**
+ * Called after calculating all modifiers.
+ */
+void BKE_mesh_ensure_normals_for_display(Mesh *mesh)
+{
+ switch ((eMeshWrapperType)mesh->runtime.wrapper_type) {
+ case ME_WRAPPER_TYPE_MDATA:
+ /* Run code below. */
+ break;
+ case ME_WRAPPER_TYPE_BMESH: {
+ struct BMEditMesh *em = mesh->edit_mesh;
+ EditMeshData *emd = mesh->runtime.edit_data;
+ if (emd->vertexCos) {
+ BKE_editmesh_cache_ensure_vert_normals(em, emd);
+ BKE_editmesh_cache_ensure_poly_normals(em, emd);
+ }
+ return;
+ }
+ }
+
+ float(*poly_nors)[3] = CustomData_get_layer(&mesh->pdata, CD_NORMAL);
+ const bool do_vert_normals = (mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL) != 0;
+ const bool do_poly_normals = (mesh->runtime.cd_dirty_poly & CD_MASK_NORMAL || poly_nors == NULL);
+
+ if (do_vert_normals || do_poly_normals) {
+ const bool do_add_poly_nors_cddata = (poly_nors == NULL);
+ if (do_add_poly_nors_cddata) {
+ poly_nors = MEM_malloc_arrayN((size_t)mesh->totpoly, sizeof(*poly_nors), __func__);
+ }
+
+ /* calculate poly/vert normals */
+ BKE_mesh_calc_normals_poly(mesh->mvert,
+ NULL,
+ mesh->totvert,
+ mesh->mloop,
+ mesh->mpoly,
+ mesh->totloop,
+ mesh->totpoly,
+ poly_nors,
+ !do_vert_normals);
+
+ if (do_add_poly_nors_cddata) {
+ CustomData_add_layer(&mesh->pdata, CD_NORMAL, CD_ASSIGN, poly_nors, mesh->totpoly);
+ }
+
+ mesh->runtime.cd_dirty_vert &= ~CD_MASK_NORMAL;
+ mesh->runtime.cd_dirty_poly &= ~CD_MASK_NORMAL;
+ }
+}
+
+/* Note that this does not update the CD_NORMAL layer,
+ * but does update the normals in the CD_MVERT layer. */
+void BKE_mesh_calc_normals(Mesh *mesh)
+{
+#ifdef DEBUG_TIME
+ TIMEIT_START_AVERAGED(BKE_mesh_calc_normals);
+#endif
+ BKE_mesh_calc_normals_poly(mesh->mvert,
+ NULL,
+ mesh->totvert,
+ mesh->mloop,
+ mesh->mpoly,
+ mesh->totloop,
+ mesh->totpoly,
+ NULL,
+ false);
+#ifdef DEBUG_TIME
+ TIMEIT_END_AVERAGED(BKE_mesh_calc_normals);
+#endif
+ mesh->runtime.cd_dirty_vert &= ~CD_MASK_NORMAL;
+}
+
+void BKE_mesh_calc_normals_looptri(MVert *mverts,
+ int numVerts,
+ const MLoop *mloop,
+ const MLoopTri *looptri,
+ int looptri_num,
+ float (*r_tri_nors)[3])
+{
+ float(*tnorms)[3] = MEM_calloc_arrayN((size_t)numVerts, sizeof(*tnorms), "tnorms");
+ float(*fnors)[3] = (r_tri_nors) ?
+ r_tri_nors :
+ MEM_calloc_arrayN((size_t)looptri_num, sizeof(*fnors), "meshnormals");
+
+ if (!tnorms || !fnors) {
+ goto cleanup;
+ }
+
+ for (int i = 0; i < looptri_num; i++) {
+ const MLoopTri *lt = &looptri[i];
+ float *f_no = fnors[i];
+ const uint vtri[3] = {
+ mloop[lt->tri[0]].v,
+ mloop[lt->tri[1]].v,
+ mloop[lt->tri[2]].v,
+ };
+
+ normal_tri_v3(f_no, mverts[vtri[0]].co, mverts[vtri[1]].co, mverts[vtri[2]].co);
+
+ accumulate_vertex_normals_tri_v3(tnorms[vtri[0]],
+ tnorms[vtri[1]],
+ tnorms[vtri[2]],
+ f_no,
+ mverts[vtri[0]].co,
+ mverts[vtri[1]].co,
+ mverts[vtri[2]].co);
+ }
+
+ /* following Mesh convention; we use vertex coordinate itself for normal in this case */
+ for (int i = 0; i < numVerts; i++) {
+ MVert *mv = &mverts[i];
+ float *no = tnorms[i];
+
+ if (UNLIKELY(normalize_v3(no) == 0.0f)) {
+ normalize_v3_v3(no, mv->co);
+ }
+
+ normal_float_to_short_v3(mv->no, no);
+ }
+
+cleanup:
+ MEM_freeN(tnorms);
+
+ if (fnors != r_tri_nors) {
+ MEM_freeN(fnors);
+ }
+}
+
+void BKE_lnor_spacearr_init(MLoopNorSpaceArray *lnors_spacearr,
+ const int numLoops,
+ const char data_type)
+{
+ if (!(lnors_spacearr->lspacearr && lnors_spacearr->loops_pool)) {
+ MemArena *mem;
+
+ if (!lnors_spacearr->mem) {
+ lnors_spacearr->mem = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
+ }
+ mem = lnors_spacearr->mem;
+ lnors_spacearr->lspacearr = BLI_memarena_calloc(mem,
+ sizeof(MLoopNorSpace *) * (size_t)numLoops);
+ lnors_spacearr->loops_pool = BLI_memarena_alloc(mem, sizeof(LinkNode) * (size_t)numLoops);
+
+ lnors_spacearr->num_spaces = 0;
+ }
+ BLI_assert(ELEM(data_type, MLNOR_SPACEARR_BMLOOP_PTR, MLNOR_SPACEARR_LOOP_INDEX));
+ lnors_spacearr->data_type = data_type;
+}
+
+void BKE_lnor_spacearr_clear(MLoopNorSpaceArray *lnors_spacearr)
+{
+ lnors_spacearr->num_spaces = 0;
+ lnors_spacearr->lspacearr = NULL;
+ lnors_spacearr->loops_pool = NULL;
+ if (lnors_spacearr->mem != NULL) {
+ BLI_memarena_clear(lnors_spacearr->mem);
+ }
+}
+
+void BKE_lnor_spacearr_free(MLoopNorSpaceArray *lnors_spacearr)
+{
+ lnors_spacearr->num_spaces = 0;
+ lnors_spacearr->lspacearr = NULL;
+ lnors_spacearr->loops_pool = NULL;
+ BLI_memarena_free(lnors_spacearr->mem);
+ lnors_spacearr->mem = NULL;
+}
+
+MLoopNorSpace *BKE_lnor_space_create(MLoopNorSpaceArray *lnors_spacearr)
+{
+ lnors_spacearr->num_spaces++;
+ return BLI_memarena_calloc(lnors_spacearr->mem, sizeof(MLoopNorSpace));
+}
+
+/* This threshold is a bit touchy (usual float precision issue), this value seems OK. */
+#define LNOR_SPACE_TRIGO_THRESHOLD (1.0f - 1e-4f)
+
+/* Should only be called once.
+ * Beware, this modifies ref_vec and other_vec in place!
+ * In case no valid space can be generated, ref_alpha and ref_beta are set to zero
+ * (which means 'use auto lnors').
+ */
+void BKE_lnor_space_define(MLoopNorSpace *lnor_space,
+ const float lnor[3],
+ float vec_ref[3],
+ float vec_other[3],
+ BLI_Stack *edge_vectors)
+{
+ const float pi2 = (float)M_PI * 2.0f;
+ float tvec[3], dtp;
+ const float dtp_ref = dot_v3v3(vec_ref, lnor);
+ const float dtp_other = dot_v3v3(vec_other, lnor);
+
+ if (UNLIKELY(fabsf(dtp_ref) >= LNOR_SPACE_TRIGO_THRESHOLD ||
+ fabsf(dtp_other) >= LNOR_SPACE_TRIGO_THRESHOLD)) {
+ /* If vec_ref or vec_other are too much aligned with lnor, we can't build lnor space,
+ * tag it as invalid and abort. */
+ lnor_space->ref_alpha = lnor_space->ref_beta = 0.0f;
+
+ if (edge_vectors) {
+ BLI_stack_clear(edge_vectors);
+ }
+ return;
+ }
+
+ copy_v3_v3(lnor_space->vec_lnor, lnor);
+
+ /* Compute ref alpha, average angle of all available edge vectors to lnor. */
+ if (edge_vectors) {
+ float alpha = 0.0f;
+ int nbr = 0;
+ while (!BLI_stack_is_empty(edge_vectors)) {
+ const float *vec = BLI_stack_peek(edge_vectors);
+ alpha += saacosf(dot_v3v3(vec, lnor));
+ BLI_stack_discard(edge_vectors);
+ nbr++;
+ }
+ /* Note: In theory, this could be 'nbr > 2',
+ * but there is one case where we only have two edges for two loops:
+ * a smooth vertex with only two edges and two faces (our Monkey's nose has that, e.g.).
+ */
+ BLI_assert(nbr >= 2); /* This piece of code shall only be called for more than one loop... */
+ lnor_space->ref_alpha = alpha / (float)nbr;
+ }
+ else {
+ lnor_space->ref_alpha = (saacosf(dot_v3v3(vec_ref, lnor)) +
+ saacosf(dot_v3v3(vec_other, lnor))) /
+ 2.0f;
+ }
+
+ /* Project vec_ref on lnor's ortho plane. */
+ mul_v3_v3fl(tvec, lnor, dtp_ref);
+ sub_v3_v3(vec_ref, tvec);
+ normalize_v3_v3(lnor_space->vec_ref, vec_ref);
+
+ cross_v3_v3v3(tvec, lnor, lnor_space->vec_ref);
+ normalize_v3_v3(lnor_space->vec_ortho, tvec);
+
+ /* Project vec_other on lnor's ortho plane. */
+ mul_v3_v3fl(tvec, lnor, dtp_other);
+ sub_v3_v3(vec_other, tvec);
+ normalize_v3(vec_other);
+
+ /* Beta is angle between ref_vec and other_vec, around lnor. */
+ dtp = dot_v3v3(lnor_space->vec_ref, vec_other);
+ if (LIKELY(dtp < LNOR_SPACE_TRIGO_THRESHOLD)) {
+ const float beta = saacos(dtp);
+ lnor_space->ref_beta = (dot_v3v3(lnor_space->vec_ortho, vec_other) < 0.0f) ? pi2 - beta : beta;
+ }
+ else {
+ lnor_space->ref_beta = pi2;
+ }
+}
+
+/**
+ * Add a new given loop to given lnor_space.
+ * Depending on \a lnor_space->data_type, we expect \a bm_loop to be a pointer to BMLoop struct
+ * (in case of BMLOOP_PTR), or NULL (in case of LOOP_INDEX), loop index is then stored in pointer.
+ * If \a is_single is set, the BMLoop or loop index is directly stored in \a lnor_space->loops
+ * pointer (since there is only one loop in this fan),
+ * else it is added to the linked list of loops in the fan.
+ */
+void BKE_lnor_space_add_loop(MLoopNorSpaceArray *lnors_spacearr,
+ MLoopNorSpace *lnor_space,
+ const int ml_index,
+ void *bm_loop,
+ const bool is_single)
+{
+ BLI_assert((lnors_spacearr->data_type == MLNOR_SPACEARR_LOOP_INDEX && bm_loop == NULL) ||
+ (lnors_spacearr->data_type == MLNOR_SPACEARR_BMLOOP_PTR && bm_loop != NULL));
+
+ lnors_spacearr->lspacearr[ml_index] = lnor_space;
+ if (bm_loop == NULL) {
+ bm_loop = POINTER_FROM_INT(ml_index);
+ }
+ if (is_single) {
+ BLI_assert(lnor_space->loops == NULL);
+ lnor_space->flags |= MLNOR_SPACE_IS_SINGLE;
+ lnor_space->loops = bm_loop;
+ }
+ else {
+ BLI_assert((lnor_space->flags & MLNOR_SPACE_IS_SINGLE) == 0);
+ BLI_linklist_prepend_nlink(&lnor_space->loops, bm_loop, &lnors_spacearr->loops_pool[ml_index]);
+ }
+}
+
+MINLINE float unit_short_to_float(const short val)
+{
+ return (float)val / (float)SHRT_MAX;
+}
+
+MINLINE short unit_float_to_short(const float val)
+{
+ /* Rounding... */
+ return (short)floorf(val * (float)SHRT_MAX + 0.5f);
+}
+
+void BKE_lnor_space_custom_data_to_normal(MLoopNorSpace *lnor_space,
+ const short clnor_data[2],
+ float r_custom_lnor[3])
+{
+ /* NOP custom normal data or invalid lnor space, return. */
+ if (clnor_data[0] == 0 || lnor_space->ref_alpha == 0.0f || lnor_space->ref_beta == 0.0f) {
+ copy_v3_v3(r_custom_lnor, lnor_space->vec_lnor);
+ return;
+ }
+
+ {
+ /* TODO: Check whether using #sincosf() gives any noticeable benefit
+ * (could not even get it working under linux though)! */
+ const float pi2 = (float)(M_PI * 2.0);
+ const float alphafac = unit_short_to_float(clnor_data[0]);
+ const float alpha = (alphafac > 0.0f ? lnor_space->ref_alpha : pi2 - lnor_space->ref_alpha) *
+ alphafac;
+ const float betafac = unit_short_to_float(clnor_data[1]);
+
+ mul_v3_v3fl(r_custom_lnor, lnor_space->vec_lnor, cosf(alpha));
+
+ if (betafac == 0.0f) {
+ madd_v3_v3fl(r_custom_lnor, lnor_space->vec_ref, sinf(alpha));
+ }
+ else {
+ const float sinalpha = sinf(alpha);
+ const float beta = (betafac > 0.0f ? lnor_space->ref_beta : pi2 - lnor_space->ref_beta) *
+ betafac;
+ madd_v3_v3fl(r_custom_lnor, lnor_space->vec_ref, sinalpha * cosf(beta));
+ madd_v3_v3fl(r_custom_lnor, lnor_space->vec_ortho, sinalpha * sinf(beta));
+ }
+ }
+}
+
+void BKE_lnor_space_custom_normal_to_data(MLoopNorSpace *lnor_space,
+ const float custom_lnor[3],
+ short r_clnor_data[2])
+{
+ /* We use null vector as NOP custom normal (can be simpler than giving auto-computed `lnor`). */
+ if (is_zero_v3(custom_lnor) || compare_v3v3(lnor_space->vec_lnor, custom_lnor, 1e-4f)) {
+ r_clnor_data[0] = r_clnor_data[1] = 0;
+ return;
+ }
+
+ {
+ const float pi2 = (float)(M_PI * 2.0);
+ const float cos_alpha = dot_v3v3(lnor_space->vec_lnor, custom_lnor);
+ float vec[3], cos_beta;
+ float alpha;
+
+ alpha = saacosf(cos_alpha);
+ if (alpha > lnor_space->ref_alpha) {
+ /* Note we could stick to [0, pi] range here,
+ * but makes decoding more complex, not worth it. */
+ r_clnor_data[0] = unit_float_to_short(-(pi2 - alpha) / (pi2 - lnor_space->ref_alpha));
+ }
+ else {
+ r_clnor_data[0] = unit_float_to_short(alpha / lnor_space->ref_alpha);
+ }
+
+ /* Project custom lnor on (vec_ref, vec_ortho) plane. */
+ mul_v3_v3fl(vec, lnor_space->vec_lnor, -cos_alpha);
+ add_v3_v3(vec, custom_lnor);
+ normalize_v3(vec);
+
+ cos_beta = dot_v3v3(lnor_space->vec_ref, vec);
+
+ if (cos_beta < LNOR_SPACE_TRIGO_THRESHOLD) {
+ float beta = saacosf(cos_beta);
+ if (dot_v3v3(lnor_space->vec_ortho, vec) < 0.0f) {
+ beta = pi2 - beta;
+ }
+
+ if (beta > lnor_space->ref_beta) {
+ r_clnor_data[1] = unit_float_to_short(-(pi2 - beta) / (pi2 - lnor_space->ref_beta));
+ }
+ else {
+ r_clnor_data[1] = unit_float_to_short(beta / lnor_space->ref_beta);
+ }
+ }
+ else {
+ r_clnor_data[1] = 0;
+ }
+ }
+}
+
+#define LOOP_SPLIT_TASK_BLOCK_SIZE 1024
+
+typedef struct LoopSplitTaskData {
+ /* Specific to each instance (each task). */
+
+ /** We have to create those outside of tasks, since #MemArena is not thread-safe. */
+ MLoopNorSpace *lnor_space;
+ float (*lnor)[3];
+ const MLoop *ml_curr;
+ const MLoop *ml_prev;
+ int ml_curr_index;
+ int ml_prev_index;
+ /** Also used a flag to switch between single or fan process! */
+ const int *e2l_prev;
+ int mp_index;
+
+ /** This one is special, it's owned and managed by worker tasks,
+ * avoid to have to create it for each fan! */
+ BLI_Stack *edge_vectors;
+
+ char pad_c;
+} LoopSplitTaskData;
+
+typedef struct LoopSplitTaskDataCommon {
+ /* Read/write.
+ * Note we do not need to protect it, though, since two different tasks will *always* affect
+ * different elements in the arrays. */
+ MLoopNorSpaceArray *lnors_spacearr;
+ float (*loopnors)[3];
+ short (*clnors_data)[2];
+
+ /* Read-only. */
+ const MVert *mverts;
+ const MEdge *medges;
+ const MLoop *mloops;
+ const MPoly *mpolys;
+ int (*edge_to_loops)[2];
+ int *loop_to_poly;
+ const float (*polynors)[3];
+
+ int numEdges;
+ int numLoops;
+ int numPolys;
+} LoopSplitTaskDataCommon;
+
+#define INDEX_UNSET INT_MIN
+#define INDEX_INVALID -1
+/* See comment about edge_to_loops below. */
+#define IS_EDGE_SHARP(_e2l) (ELEM((_e2l)[1], INDEX_UNSET, INDEX_INVALID))
+
+static void mesh_edges_sharp_tag(LoopSplitTaskDataCommon *data,
+ const bool check_angle,
+ const float split_angle,
+ const bool do_sharp_edges_tag)
+{
+ const MVert *mverts = data->mverts;
+ const MEdge *medges = data->medges;
+ const MLoop *mloops = data->mloops;
+
+ const MPoly *mpolys = data->mpolys;
+
+ const int numEdges = data->numEdges;
+ const int numPolys = data->numPolys;
+
+ float(*loopnors)[3] = data->loopnors; /* Note: loopnors may be NULL here. */
+ const float(*polynors)[3] = data->polynors;
+
+ int(*edge_to_loops)[2] = data->edge_to_loops;
+ int *loop_to_poly = data->loop_to_poly;
+
+ BLI_bitmap *sharp_edges = do_sharp_edges_tag ? BLI_BITMAP_NEW(numEdges, __func__) : NULL;
+
+ const MPoly *mp;
+ int mp_index;
+
+ const float split_angle_cos = check_angle ? cosf(split_angle) : -1.0f;
+
+ for (mp = mpolys, mp_index = 0; mp_index < numPolys; mp++, mp_index++) {
+ const MLoop *ml_curr;
+ int *e2l;
+ int ml_curr_index = mp->loopstart;
+ const int ml_last_index = (ml_curr_index + mp->totloop) - 1;
+
+ ml_curr = &mloops[ml_curr_index];
+
+ for (; ml_curr_index <= ml_last_index; ml_curr++, ml_curr_index++) {
+ e2l = edge_to_loops[ml_curr->e];
+
+ loop_to_poly[ml_curr_index] = mp_index;
+
+ /* Pre-populate all loop normals as if their verts were all-smooth,
+ * this way we don't have to compute those later!
+ */
+ if (loopnors) {
+ normal_short_to_float_v3(loopnors[ml_curr_index], mverts[ml_curr->v].no);
+ }
+
+ /* Check whether current edge might be smooth or sharp */
+ if ((e2l[0] | e2l[1]) == 0) {
+ /* 'Empty' edge until now, set e2l[0] (and e2l[1] to INDEX_UNSET to tag it as unset). */
+ e2l[0] = ml_curr_index;
+ /* We have to check this here too, else we might miss some flat faces!!! */
+ e2l[1] = (mp->flag & ME_SMOOTH) ? INDEX_UNSET : INDEX_INVALID;
+ }
+ else if (e2l[1] == INDEX_UNSET) {
+ const bool is_angle_sharp = (check_angle &&
+ dot_v3v3(polynors[loop_to_poly[e2l[0]]], polynors[mp_index]) <
+ split_angle_cos);
+
+ /* Second loop using this edge, time to test its sharpness.
+ * An edge is sharp if it is tagged as such, or its face is not smooth,
+ * or both poly have opposed (flipped) normals, i.e. both loops on the same edge share the
+ * same vertex, or angle between both its polys' normals is above split_angle value.
+ */
+ if (!(mp->flag & ME_SMOOTH) || (medges[ml_curr->e].flag & ME_SHARP) ||
+ ml_curr->v == mloops[e2l[0]].v || is_angle_sharp) {
+ /* Note: we are sure that loop != 0 here ;) */
+ e2l[1] = INDEX_INVALID;
+
+ /* We want to avoid tagging edges as sharp when it is already defined as such by
+ * other causes than angle threshold... */
+ if (do_sharp_edges_tag && is_angle_sharp) {
+ BLI_BITMAP_SET(sharp_edges, ml_curr->e, true);
+ }
+ }
+ else {
+ e2l[1] = ml_curr_index;
+ }
+ }
+ else if (!IS_EDGE_SHARP(e2l)) {
+ /* More than two loops using this edge, tag as sharp if not yet done. */
+ e2l[1] = INDEX_INVALID;
+
+ /* We want to avoid tagging edges as sharp when it is already defined as such by
+ * other causes than angle threshold... */
+ if (do_sharp_edges_tag) {
+ BLI_BITMAP_SET(sharp_edges, ml_curr->e, false);
+ }
+ }
+ /* Else, edge is already 'disqualified' (i.e. sharp)! */
+ }
+ }
+
+ /* If requested, do actual tagging of edges as sharp in another loop. */
+ if (do_sharp_edges_tag) {
+ MEdge *me;
+ int me_index;
+ for (me = (MEdge *)medges, me_index = 0; me_index < numEdges; me++, me_index++) {
+ if (BLI_BITMAP_TEST(sharp_edges, me_index)) {
+ me->flag |= ME_SHARP;
+ }
+ }
+
+ MEM_freeN(sharp_edges);
+ }
+}
+
+/**
+ * Define sharp edges as needed to mimic 'autosmooth' from angle threshold.
+ *
+ * Used when defining an empty custom loop normals data layer,
+ * to keep same shading as with auto-smooth!
+ */
+void BKE_edges_sharp_from_angle_set(const struct MVert *mverts,
+ const int UNUSED(numVerts),
+ struct MEdge *medges,
+ const int numEdges,
+ struct MLoop *mloops,
+ const int numLoops,
+ struct MPoly *mpolys,
+ const float (*polynors)[3],
+ const int numPolys,
+ const float split_angle)
+{
+ if (split_angle >= (float)M_PI) {
+ /* Nothing to do! */
+ return;
+ }
+
+ /* Mapping edge -> loops. See BKE_mesh_normals_loop_split() for details. */
+ int(*edge_to_loops)[2] = MEM_calloc_arrayN((size_t)numEdges, sizeof(*edge_to_loops), __func__);
+
+ /* Simple mapping from a loop to its polygon index. */
+ int *loop_to_poly = MEM_malloc_arrayN((size_t)numLoops, sizeof(*loop_to_poly), __func__);
+
+ LoopSplitTaskDataCommon common_data = {
+ .mverts = mverts,
+ .medges = medges,
+ .mloops = mloops,
+ .mpolys = mpolys,
+ .edge_to_loops = edge_to_loops,
+ .loop_to_poly = loop_to_poly,
+ .polynors = polynors,
+ .numEdges = numEdges,
+ .numPolys = numPolys,
+ };
+
+ mesh_edges_sharp_tag(&common_data, true, split_angle, true);
+
+ MEM_freeN(edge_to_loops);
+ MEM_freeN(loop_to_poly);
+}
+
+void BKE_mesh_loop_manifold_fan_around_vert_next(const MLoop *mloops,
+ const MPoly *mpolys,
+ const int *loop_to_poly,
+ const int *e2lfan_curr,
+ const uint mv_pivot_index,
+ const MLoop **r_mlfan_curr,
+ int *r_mlfan_curr_index,
+ int *r_mlfan_vert_index,
+ int *r_mpfan_curr_index)
+{
+ const MLoop *mlfan_next;
+ const MPoly *mpfan_next;
+
+ /* Warning! This is rather complex!
+ * We have to find our next edge around the vertex (fan mode).
+ * First we find the next loop, which is either previous or next to mlfan_curr_index, depending
+ * whether both loops using current edge are in the same direction or not, and whether
+ * mlfan_curr_index actually uses the vertex we are fanning around!
+ * mlfan_curr_index is the index of mlfan_next here, and mlfan_next is not the real next one
+ * (i.e. not the future mlfan_curr)...
+ */
+ *r_mlfan_curr_index = (e2lfan_curr[0] == *r_mlfan_curr_index) ? e2lfan_curr[1] : e2lfan_curr[0];
+ *r_mpfan_curr_index = loop_to_poly[*r_mlfan_curr_index];
+
+ BLI_assert(*r_mlfan_curr_index >= 0);
+ BLI_assert(*r_mpfan_curr_index >= 0);
+
+ mlfan_next = &mloops[*r_mlfan_curr_index];
+ mpfan_next = &mpolys[*r_mpfan_curr_index];
+ if (((*r_mlfan_curr)->v == mlfan_next->v && (*r_mlfan_curr)->v == mv_pivot_index) ||
+ ((*r_mlfan_curr)->v != mlfan_next->v && (*r_mlfan_curr)->v != mv_pivot_index)) {
+ /* We need the previous loop, but current one is our vertex's loop. */
+ *r_mlfan_vert_index = *r_mlfan_curr_index;
+ if (--(*r_mlfan_curr_index) < mpfan_next->loopstart) {
+ *r_mlfan_curr_index = mpfan_next->loopstart + mpfan_next->totloop - 1;
+ }
+ }
+ else {
+ /* We need the next loop, which is also our vertex's loop. */
+ if (++(*r_mlfan_curr_index) >= mpfan_next->loopstart + mpfan_next->totloop) {
+ *r_mlfan_curr_index = mpfan_next->loopstart;
+ }
+ *r_mlfan_vert_index = *r_mlfan_curr_index;
+ }
+ *r_mlfan_curr = &mloops[*r_mlfan_curr_index];
+ /* And now we are back in sync, mlfan_curr_index is the index of mlfan_curr! Pff! */
+}
+
+static void split_loop_nor_single_do(LoopSplitTaskDataCommon *common_data, LoopSplitTaskData *data)
+{
+ MLoopNorSpaceArray *lnors_spacearr = common_data->lnors_spacearr;
+ const short(*clnors_data)[2] = common_data->clnors_data;
+
+ const MVert *mverts = common_data->mverts;
+ const MEdge *medges = common_data->medges;
+ const float(*polynors)[3] = common_data->polynors;
+
+ MLoopNorSpace *lnor_space = data->lnor_space;
+ float(*lnor)[3] = data->lnor;
+ const MLoop *ml_curr = data->ml_curr;
+ const MLoop *ml_prev = data->ml_prev;
+ const int ml_curr_index = data->ml_curr_index;
+#if 0 /* Not needed for 'single' loop. */
+ const int ml_prev_index = data->ml_prev_index;
+ const int *e2l_prev = data->e2l_prev;
+#endif
+ const int mp_index = data->mp_index;
+
+ /* Simple case (both edges around that vertex are sharp in current polygon),
+ * this loop just takes its poly normal.
+ */
+ copy_v3_v3(*lnor, polynors[mp_index]);
+
+#if 0
+ printf("BASIC: handling loop %d / edge %d / vert %d / poly %d\n",
+ ml_curr_index,
+ ml_curr->e,
+ ml_curr->v,
+ mp_index);
+#endif
+
+ /* If needed, generate this (simple!) lnor space. */
+ if (lnors_spacearr) {
+ float vec_curr[3], vec_prev[3];
+
+ const uint mv_pivot_index = ml_curr->v; /* The vertex we are "fanning" around! */
+ const MVert *mv_pivot = &mverts[mv_pivot_index];
+ const MEdge *me_curr = &medges[ml_curr->e];
+ const MVert *mv_2 = (me_curr->v1 == mv_pivot_index) ? &mverts[me_curr->v2] :
+ &mverts[me_curr->v1];
+ const MEdge *me_prev = &medges[ml_prev->e];
+ const MVert *mv_3 = (me_prev->v1 == mv_pivot_index) ? &mverts[me_prev->v2] :
+ &mverts[me_prev->v1];
+
+ sub_v3_v3v3(vec_curr, mv_2->co, mv_pivot->co);
+ normalize_v3(vec_curr);
+ sub_v3_v3v3(vec_prev, mv_3->co, mv_pivot->co);
+ normalize_v3(vec_prev);
+
+ BKE_lnor_space_define(lnor_space, *lnor, vec_curr, vec_prev, NULL);
+ /* We know there is only one loop in this space,
+ * no need to create a linklist in this case... */
+ BKE_lnor_space_add_loop(lnors_spacearr, lnor_space, ml_curr_index, NULL, true);
+
+ if (clnors_data) {
+ BKE_lnor_space_custom_data_to_normal(lnor_space, clnors_data[ml_curr_index], *lnor);
+ }
+ }
+}
+
+static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSplitTaskData *data)
+{
+ MLoopNorSpaceArray *lnors_spacearr = common_data->lnors_spacearr;
+ float(*loopnors)[3] = common_data->loopnors;
+ short(*clnors_data)[2] = common_data->clnors_data;
+
+ const MVert *mverts = common_data->mverts;
+ const MEdge *medges = common_data->medges;
+ const MLoop *mloops = common_data->mloops;
+ const MPoly *mpolys = common_data->mpolys;
+ const int(*edge_to_loops)[2] = common_data->edge_to_loops;
+ const int *loop_to_poly = common_data->loop_to_poly;
+ const float(*polynors)[3] = common_data->polynors;
+
+ MLoopNorSpace *lnor_space = data->lnor_space;
+#if 0 /* Not needed for 'fan' loops. */
+ float(*lnor)[3] = data->lnor;
+#endif
+ const MLoop *ml_curr = data->ml_curr;
+ const MLoop *ml_prev = data->ml_prev;
+ const int ml_curr_index = data->ml_curr_index;
+ const int ml_prev_index = data->ml_prev_index;
+ const int mp_index = data->mp_index;
+ const int *e2l_prev = data->e2l_prev;
+
+ BLI_Stack *edge_vectors = data->edge_vectors;
+
+ /* Gah... We have to fan around current vertex, until we find the other non-smooth edge,
+ * and accumulate face normals into the vertex!
+ * Note in case this vertex has only one sharp edges, this is a waste because the normal is the
+ * same as the vertex normal, but I do not see any easy way to detect that (would need to count
+ * number of sharp edges per vertex, I doubt the additional memory usage would be worth it,
+ * especially as it should not be a common case in real-life meshes anyway).
+ */
+ const uint mv_pivot_index = ml_curr->v; /* The vertex we are "fanning" around! */
+ const MVert *mv_pivot = &mverts[mv_pivot_index];
+
+ /* ml_curr would be mlfan_prev if we needed that one. */
+ const MEdge *me_org = &medges[ml_curr->e];
+
+ const int *e2lfan_curr;
+ float vec_curr[3], vec_prev[3], vec_org[3];
+ const MLoop *mlfan_curr;
+ float lnor[3] = {0.0f, 0.0f, 0.0f};
+ /* mlfan_vert_index: the loop of our current edge might not be the loop of our current vertex! */
+ int mlfan_curr_index, mlfan_vert_index, mpfan_curr_index;
+
+ /* We validate clnors data on the fly - cheapest way to do! */
+ int clnors_avg[2] = {0, 0};
+ short(*clnor_ref)[2] = NULL;
+ int clnors_nbr = 0;
+ bool clnors_invalid = false;
+
+ /* Temp loop normal stack. */
+ BLI_SMALLSTACK_DECLARE(normal, float *);
+ /* Temp clnors stack. */
+ BLI_SMALLSTACK_DECLARE(clnors, short *);
+
+ e2lfan_curr = e2l_prev;
+ mlfan_curr = ml_prev;
+ mlfan_curr_index = ml_prev_index;
+ mlfan_vert_index = ml_curr_index;
+ mpfan_curr_index = mp_index;
+
+ BLI_assert(mlfan_curr_index >= 0);
+ BLI_assert(mlfan_vert_index >= 0);
+ BLI_assert(mpfan_curr_index >= 0);
+
+ /* Only need to compute previous edge's vector once, then we can just reuse old current one! */
+ {
+ const MVert *mv_2 = (me_org->v1 == mv_pivot_index) ? &mverts[me_org->v2] : &mverts[me_org->v1];
+
+ sub_v3_v3v3(vec_org, mv_2->co, mv_pivot->co);
+ normalize_v3(vec_org);
+ copy_v3_v3(vec_prev, vec_org);
+
+ if (lnors_spacearr) {
+ BLI_stack_push(edge_vectors, vec_org);
+ }
+ }
+
+ // printf("FAN: vert %d, start edge %d\n", mv_pivot_index, ml_curr->e);
+
+ while (true) {
+ const MEdge *me_curr = &medges[mlfan_curr->e];
+ /* Compute edge vectors.
+ * NOTE: We could pre-compute those into an array, in the first iteration, instead of computing
+ * them twice (or more) here. However, time gained is not worth memory and time lost,
+ * given the fact that this code should not be called that much in real-life meshes...
+ */
+ {
+ const MVert *mv_2 = (me_curr->v1 == mv_pivot_index) ? &mverts[me_curr->v2] :
+ &mverts[me_curr->v1];
+
+ sub_v3_v3v3(vec_curr, mv_2->co, mv_pivot->co);
+ normalize_v3(vec_curr);
+ }
+
+ // printf("\thandling edge %d / loop %d\n", mlfan_curr->e, mlfan_curr_index);
+
+ {
+ /* Code similar to accumulate_vertex_normals_poly_v3. */
+ /* Calculate angle between the two poly edges incident on this vertex. */
+ const float fac = saacos(dot_v3v3(vec_curr, vec_prev));
+ /* Accumulate */
+ madd_v3_v3fl(lnor, polynors[mpfan_curr_index], fac);
+
+ if (clnors_data) {
+ /* Accumulate all clnors, if they are not all equal we have to fix that! */
+ short(*clnor)[2] = &clnors_data[mlfan_vert_index];
+ if (clnors_nbr) {
+ clnors_invalid |= ((*clnor_ref)[0] != (*clnor)[0] || (*clnor_ref)[1] != (*clnor)[1]);
+ }
+ else {
+ clnor_ref = clnor;
+ }
+ clnors_avg[0] += (*clnor)[0];
+ clnors_avg[1] += (*clnor)[1];
+ clnors_nbr++;
+ /* We store here a pointer to all custom lnors processed. */
+ BLI_SMALLSTACK_PUSH(clnors, (short *)*clnor);
+ }
+ }
+
+ /* We store here a pointer to all loop-normals processed. */
+ BLI_SMALLSTACK_PUSH(normal, (float *)(loopnors[mlfan_vert_index]));
+
+ if (lnors_spacearr) {
+ /* Assign current lnor space to current 'vertex' loop. */
+ BKE_lnor_space_add_loop(lnors_spacearr, lnor_space, mlfan_vert_index, NULL, false);
+ if (me_curr != me_org) {
+ /* We store here all edges-normalized vectors processed. */
+ BLI_stack_push(edge_vectors, vec_curr);
+ }
+ }
+
+ if (IS_EDGE_SHARP(e2lfan_curr) || (me_curr == me_org)) {
+ /* Current edge is sharp and we have finished with this fan of faces around this vert,
+ * or this vert is smooth, and we have completed a full turn around it.
+ */
+ // printf("FAN: Finished!\n");
+ break;
+ }
+
+ copy_v3_v3(vec_prev, vec_curr);
+
+ /* Find next loop of the smooth fan. */
+ BKE_mesh_loop_manifold_fan_around_vert_next(mloops,
+ mpolys,
+ loop_to_poly,
+ e2lfan_curr,
+ mv_pivot_index,
+ &mlfan_curr,
+ &mlfan_curr_index,
+ &mlfan_vert_index,
+ &mpfan_curr_index);
+
+ e2lfan_curr = edge_to_loops[mlfan_curr->e];
+ }
+
+ {
+ float lnor_len = normalize_v3(lnor);
+
+ /* If we are generating lnor spacearr, we can now define the one for this fan,
+ * and optionally compute final lnor from custom data too!
+ */
+ if (lnors_spacearr) {
+ if (UNLIKELY(lnor_len == 0.0f)) {
+ /* Use vertex normal as fallback! */
+ copy_v3_v3(lnor, loopnors[mlfan_vert_index]);
+ lnor_len = 1.0f;
+ }
+
+ BKE_lnor_space_define(lnor_space, lnor, vec_org, vec_curr, edge_vectors);
+
+ if (clnors_data) {
+ if (clnors_invalid) {
+ short *clnor;
+
+ clnors_avg[0] /= clnors_nbr;
+ clnors_avg[1] /= clnors_nbr;
+ /* Fix/update all clnors of this fan with computed average value. */
+ if (G.debug & G_DEBUG) {
+ printf("Invalid clnors in this fan!\n");
+ }
+ while ((clnor = BLI_SMALLSTACK_POP(clnors))) {
+ // print_v2("org clnor", clnor);
+ clnor[0] = (short)clnors_avg[0];
+ clnor[1] = (short)clnors_avg[1];
+ }
+ // print_v2("new clnors", clnors_avg);
+ }
+ /* Extra bonus: since small-stack is local to this function,
+ * no more need to empty it at all cost! */
+
+ BKE_lnor_space_custom_data_to_normal(lnor_space, *clnor_ref, lnor);
+ }
+ }
+
+ /* In case we get a zero normal here, just use vertex normal already set! */
+ if (LIKELY(lnor_len != 0.0f)) {
+ /* Copy back the final computed normal into all related loop-normals. */
+ float *nor;
+
+ while ((nor = BLI_SMALLSTACK_POP(normal))) {
+ copy_v3_v3(nor, lnor);
+ }
+ }
+ /* Extra bonus: since small-stack is local to this function,
+ * no more need to empty it at all cost! */
+ }
+}
+
+static void loop_split_worker_do(LoopSplitTaskDataCommon *common_data,
+ LoopSplitTaskData *data,
+ BLI_Stack *edge_vectors)
+{
+ BLI_assert(data->ml_curr);
+ if (data->e2l_prev) {
+ BLI_assert((edge_vectors == NULL) || BLI_stack_is_empty(edge_vectors));
+ data->edge_vectors = edge_vectors;
+ split_loop_nor_fan_do(common_data, data);
+ }
+ else {
+ /* No need for edge_vectors for 'single' case! */
+ split_loop_nor_single_do(common_data, data);
+ }
+}
+
+static void loop_split_worker(TaskPool *__restrict pool, void *taskdata)
+{
+ LoopSplitTaskDataCommon *common_data = BLI_task_pool_user_data(pool);
+ LoopSplitTaskData *data = taskdata;
+
+ /* Temp edge vectors stack, only used when computing lnor spacearr. */
+ BLI_Stack *edge_vectors = common_data->lnors_spacearr ?
+ BLI_stack_new(sizeof(float[3]), __func__) :
+ NULL;
+
+#ifdef DEBUG_TIME
+ TIMEIT_START_AVERAGED(loop_split_worker);
+#endif
+
+ for (int i = 0; i < LOOP_SPLIT_TASK_BLOCK_SIZE; i++, data++) {
+ /* A NULL ml_curr is used to tag ended data! */
+ if (data->ml_curr == NULL) {
+ break;
+ }
+
+ loop_split_worker_do(common_data, data, edge_vectors);
+ }
+
+ if (edge_vectors) {
+ BLI_stack_free(edge_vectors);
+ }
+
+#ifdef DEBUG_TIME
+ TIMEIT_END_AVERAGED(loop_split_worker);
+#endif
+}
+
+/**
+ * Check whether given loop is part of an unknown-so-far cyclic smooth fan, or not.
+ * Needed because cyclic smooth fans have no obvious 'entry point',
+ * and yet we need to walk them once, and only once.
+ */
+static bool loop_split_generator_check_cyclic_smooth_fan(const MLoop *mloops,
+ const MPoly *mpolys,
+ const int (*edge_to_loops)[2],
+ const int *loop_to_poly,
+ const int *e2l_prev,
+ BLI_bitmap *skip_loops,
+ const MLoop *ml_curr,
+ const MLoop *ml_prev,
+ const int ml_curr_index,
+ const int ml_prev_index,
+ const int mp_curr_index)
+{
+ const uint mv_pivot_index = ml_curr->v; /* The vertex we are "fanning" around! */
+ const int *e2lfan_curr;
+ const MLoop *mlfan_curr;
+ /* mlfan_vert_index: the loop of our current edge might not be the loop of our current vertex! */
+ int mlfan_curr_index, mlfan_vert_index, mpfan_curr_index;
+
+ e2lfan_curr = e2l_prev;
+ if (IS_EDGE_SHARP(e2lfan_curr)) {
+ /* Sharp loop, so not a cyclic smooth fan... */
+ return false;
+ }
+
+ mlfan_curr = ml_prev;
+ mlfan_curr_index = ml_prev_index;
+ mlfan_vert_index = ml_curr_index;
+ mpfan_curr_index = mp_curr_index;
+
+ BLI_assert(mlfan_curr_index >= 0);
+ BLI_assert(mlfan_vert_index >= 0);
+ BLI_assert(mpfan_curr_index >= 0);
+
+ BLI_assert(!BLI_BITMAP_TEST(skip_loops, mlfan_vert_index));
+ BLI_BITMAP_ENABLE(skip_loops, mlfan_vert_index);
+
+ while (true) {
+ /* Find next loop of the smooth fan. */
+ BKE_mesh_loop_manifold_fan_around_vert_next(mloops,
+ mpolys,
+ loop_to_poly,
+ e2lfan_curr,
+ mv_pivot_index,
+ &mlfan_curr,
+ &mlfan_curr_index,
+ &mlfan_vert_index,
+ &mpfan_curr_index);
+
+ e2lfan_curr = edge_to_loops[mlfan_curr->e];
+
+ if (IS_EDGE_SHARP(e2lfan_curr)) {
+ /* Sharp loop/edge, so not a cyclic smooth fan... */
+ return false;
+ }
+ /* Smooth loop/edge... */
+ if (BLI_BITMAP_TEST(skip_loops, mlfan_vert_index)) {
+ if (mlfan_vert_index == ml_curr_index) {
+ /* We walked around a whole cyclic smooth fan without finding any already-processed loop,
+ * means we can use initial ml_curr/ml_prev edge as start for this smooth fan. */
+ return true;
+ }
+ /* ... already checked in some previous looping, we can abort. */
+ return false;
+ }
+
+ /* ... we can skip it in future, and keep checking the smooth fan. */
+ BLI_BITMAP_ENABLE(skip_loops, mlfan_vert_index);
+ }
+}
+
+static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common_data)
+{
+ MLoopNorSpaceArray *lnors_spacearr = common_data->lnors_spacearr;
+ float(*loopnors)[3] = common_data->loopnors;
+
+ const MLoop *mloops = common_data->mloops;
+ const MPoly *mpolys = common_data->mpolys;
+ const int *loop_to_poly = common_data->loop_to_poly;
+ const int(*edge_to_loops)[2] = common_data->edge_to_loops;
+ const int numLoops = common_data->numLoops;
+ const int numPolys = common_data->numPolys;
+
+ const MPoly *mp;
+ int mp_index;
+
+ const MLoop *ml_curr;
+ const MLoop *ml_prev;
+ int ml_curr_index;
+ int ml_prev_index;
+
+ BLI_bitmap *skip_loops = BLI_BITMAP_NEW(numLoops, __func__);
+
+ LoopSplitTaskData *data_buff = NULL;
+ int data_idx = 0;
+
+ /* Temp edge vectors stack, only used when computing lnor spacearr
+ * (and we are not multi-threading). */
+ BLI_Stack *edge_vectors = NULL;
+
+#ifdef DEBUG_TIME
+ TIMEIT_START_AVERAGED(loop_split_generator);
+#endif
+
+ if (!pool) {
+ if (lnors_spacearr) {
+ edge_vectors = BLI_stack_new(sizeof(float[3]), __func__);
+ }
+ }
+
+ /* We now know edges that can be smoothed (with their vector, and their two loops),
+ * and edges that will be hard! Now, time to generate the normals.
+ */
+ for (mp = mpolys, mp_index = 0; mp_index < numPolys; mp++, mp_index++) {
+ float(*lnors)[3];
+ const int ml_last_index = (mp->loopstart + mp->totloop) - 1;
+ ml_curr_index = mp->loopstart;
+ ml_prev_index = ml_last_index;
+
+ ml_curr = &mloops[ml_curr_index];
+ ml_prev = &mloops[ml_prev_index];
+ lnors = &loopnors[ml_curr_index];
+
+ for (; ml_curr_index <= ml_last_index; ml_curr++, ml_curr_index++, lnors++) {
+ const int *e2l_curr = edge_to_loops[ml_curr->e];
+ const int *e2l_prev = edge_to_loops[ml_prev->e];
+
+#if 0
+ printf("Checking loop %d / edge %u / vert %u (sharp edge: %d, skiploop: %d)...",
+ ml_curr_index,
+ ml_curr->e,
+ ml_curr->v,
+ IS_EDGE_SHARP(e2l_curr),
+ BLI_BITMAP_TEST_BOOL(skip_loops, ml_curr_index));
+#endif
+
+ /* A smooth edge, we have to check for cyclic smooth fan case.
+ * If we find a new, never-processed cyclic smooth fan, we can do it now using that loop/edge
+ * as 'entry point', otherwise we can skip it. */
+
+ /* Note: In theory, we could make #loop_split_generator_check_cyclic_smooth_fan() store
+ * mlfan_vert_index'es and edge indexes in two stacks, to avoid having to fan again around
+ * the vert during actual computation of `clnor` & `clnorspace`.
+ * However, this would complicate the code, add more memory usage, and despite its logical
+ * complexity, #loop_manifold_fan_around_vert_next() is quite cheap in term of CPU cycles,
+ * so really think it's not worth it. */
+ if (!IS_EDGE_SHARP(e2l_curr) && (BLI_BITMAP_TEST(skip_loops, ml_curr_index) ||
+ !loop_split_generator_check_cyclic_smooth_fan(mloops,
+ mpolys,
+ edge_to_loops,
+ loop_to_poly,
+ e2l_prev,
+ skip_loops,
+ ml_curr,
+ ml_prev,
+ ml_curr_index,
+ ml_prev_index,
+ mp_index))) {
+ // printf("SKIPPING!\n");
+ }
+ else {
+ LoopSplitTaskData *data, data_local;
+
+ // printf("PROCESSING!\n");
+
+ if (pool) {
+ if (data_idx == 0) {
+ data_buff = MEM_calloc_arrayN(
+ LOOP_SPLIT_TASK_BLOCK_SIZE, sizeof(*data_buff), __func__);
+ }
+ data = &data_buff[data_idx];
+ }
+ else {
+ data = &data_local;
+ memset(data, 0, sizeof(*data));
+ }
+
+ if (IS_EDGE_SHARP(e2l_curr) && IS_EDGE_SHARP(e2l_prev)) {
+ data->lnor = lnors;
+ data->ml_curr = ml_curr;
+ data->ml_prev = ml_prev;
+ data->ml_curr_index = ml_curr_index;
+#if 0 /* Not needed for 'single' loop. */
+ data->ml_prev_index = ml_prev_index;
+ data->e2l_prev = NULL; /* Tag as 'single' task. */
+#endif
+ data->mp_index = mp_index;
+ if (lnors_spacearr) {
+ data->lnor_space = BKE_lnor_space_create(lnors_spacearr);
+ }
+ }
+ /* We *do not need* to check/tag loops as already computed!
+ * Due to the fact a loop only links to one of its two edges,
+ * a same fan *will never be walked more than once!*
+ * Since we consider edges having neighbor polys with inverted
+ * (flipped) normals as sharp, we are sure that no fan will be skipped,
+ * even only considering the case (sharp curr_edge, smooth prev_edge),
+ * and not the alternative (smooth curr_edge, sharp prev_edge).
+ * All this due/thanks to link between normals and loop ordering (i.e. winding).
+ */
+ else {
+#if 0 /* Not needed for 'fan' loops. */
+ data->lnor = lnors;
+#endif
+ data->ml_curr = ml_curr;
+ data->ml_prev = ml_prev;
+ data->ml_curr_index = ml_curr_index;
+ data->ml_prev_index = ml_prev_index;
+ data->e2l_prev = e2l_prev; /* Also tag as 'fan' task. */
+ data->mp_index = mp_index;
+ if (lnors_spacearr) {
+ data->lnor_space = BKE_lnor_space_create(lnors_spacearr);
+ }
+ }
+
+ if (pool) {
+ data_idx++;
+ if (data_idx == LOOP_SPLIT_TASK_BLOCK_SIZE) {
+ BLI_task_pool_push(pool, loop_split_worker, data_buff, true, NULL);
+ data_idx = 0;
+ }
+ }
+ else {
+ loop_split_worker_do(common_data, data, edge_vectors);
+ }
+ }
+
+ ml_prev = ml_curr;
+ ml_prev_index = ml_curr_index;
+ }
+ }
+
+ /* Last block of data... Since it is calloc'ed and we use first NULL item as stopper,
+ * everything is fine. */
+ if (pool && data_idx) {
+ BLI_task_pool_push(pool, loop_split_worker, data_buff, true, NULL);
+ }
+
+ if (edge_vectors) {
+ BLI_stack_free(edge_vectors);
+ }
+ MEM_freeN(skip_loops);
+
+#ifdef DEBUG_TIME
+ TIMEIT_END_AVERAGED(loop_split_generator);
+#endif
+}
+
+/**
+ * Compute split normals, i.e. vertex normals associated with each poly (hence 'loop normals').
+ * Useful to materialize sharp edges (or non-smooth faces) without actually modifying the geometry
+ * (splitting edges).
+ */
+void BKE_mesh_normals_loop_split(const MVert *mverts,
+ const int UNUSED(numVerts),
+ MEdge *medges,
+ const int numEdges,
+ MLoop *mloops,
+ float (*r_loopnors)[3],
+ const int numLoops,
+ MPoly *mpolys,
+ const float (*polynors)[3],
+ const int numPolys,
+ const bool use_split_normals,
+ const float split_angle,
+ MLoopNorSpaceArray *r_lnors_spacearr,
+ short (*clnors_data)[2],
+ int *r_loop_to_poly)
+{
+ /* For now this is not supported.
+ * If we do not use split normals, we do not generate anything fancy! */
+ BLI_assert(use_split_normals || !(r_lnors_spacearr));
+
+ if (!use_split_normals) {
+ /* In this case, we simply fill lnors with vnors (or fnors for flat faces), quite simple!
+ * Note this is done here to keep some logic and consistency in this quite complex code,
+ * since we may want to use lnors even when mesh's 'autosmooth' is disabled
+ * (see e.g. mesh mapping code).
+ * As usual, we could handle that on case-by-case basis,
+ * but simpler to keep it well confined here.
+ */
+ int mp_index;
+
+ for (mp_index = 0; mp_index < numPolys; mp_index++) {
+ MPoly *mp = &mpolys[mp_index];
+ int ml_index = mp->loopstart;
+ const int ml_index_end = ml_index + mp->totloop;
+ const bool is_poly_flat = ((mp->flag & ME_SMOOTH) == 0);
+
+ for (; ml_index < ml_index_end; ml_index++) {
+ if (r_loop_to_poly) {
+ r_loop_to_poly[ml_index] = mp_index;
+ }
+ if (is_poly_flat) {
+ copy_v3_v3(r_loopnors[ml_index], polynors[mp_index]);
+ }
+ else {
+ normal_short_to_float_v3(r_loopnors[ml_index], mverts[mloops[ml_index].v].no);
+ }
+ }
+ }
+ return;
+ }
+
+ /**
+ * Mapping edge -> loops.
+ * If that edge is used by more than two loops (polys),
+ * it is always sharp (and tagged as such, see below).
+ * We also use the second loop index as a kind of flag:
+ *
+ * - smooth edge: > 0.
+ * - sharp edge: < 0 (INDEX_INVALID || INDEX_UNSET).
+ * - unset: INDEX_UNSET.
+ *
+ * Note that currently we only have two values for second loop of sharp edges.
+ * However, if needed, we can store the negated value of loop index instead of INDEX_INVALID
+ * to retrieve the real value later in code).
+ * Note also that loose edges always have both values set to 0! */
+ int(*edge_to_loops)[2] = MEM_calloc_arrayN((size_t)numEdges, sizeof(*edge_to_loops), __func__);
+
+ /* Simple mapping from a loop to its polygon index. */
+ int *loop_to_poly = r_loop_to_poly ?
+ r_loop_to_poly :
+ MEM_malloc_arrayN((size_t)numLoops, sizeof(*loop_to_poly), __func__);
+
+ /* When using custom loop normals, disable the angle feature! */
+ const bool check_angle = (split_angle < (float)M_PI) && (clnors_data == NULL);
+
+ MLoopNorSpaceArray _lnors_spacearr = {NULL};
+
+#ifdef DEBUG_TIME
+ TIMEIT_START_AVERAGED(BKE_mesh_normals_loop_split);
+#endif
+
+ if (!r_lnors_spacearr && clnors_data) {
+ /* We need to compute lnor spacearr if some custom lnor data are given to us! */
+ r_lnors_spacearr = &_lnors_spacearr;
+ }
+ if (r_lnors_spacearr) {
+ BKE_lnor_spacearr_init(r_lnors_spacearr, numLoops, MLNOR_SPACEARR_LOOP_INDEX);
+ }
+
+ /* Init data common to all tasks. */
+ LoopSplitTaskDataCommon common_data = {
+ .lnors_spacearr = r_lnors_spacearr,
+ .loopnors = r_loopnors,
+ .clnors_data = clnors_data,
+ .mverts = mverts,
+ .medges = medges,
+ .mloops = mloops,
+ .mpolys = mpolys,
+ .edge_to_loops = edge_to_loops,
+ .loop_to_poly = loop_to_poly,
+ .polynors = polynors,
+ .numEdges = numEdges,
+ .numLoops = numLoops,
+ .numPolys = numPolys,
+ };
+
+ /* This first loop check which edges are actually smooth, and compute edge vectors. */
+ mesh_edges_sharp_tag(&common_data, check_angle, split_angle, false);
+
+ if (numLoops < LOOP_SPLIT_TASK_BLOCK_SIZE * 8) {
+ /* Not enough loops to be worth the whole threading overhead... */
+ loop_split_generator(NULL, &common_data);
+ }
+ else {
+ TaskPool *task_pool = BLI_task_pool_create(&common_data, TASK_PRIORITY_HIGH);
+
+ loop_split_generator(task_pool, &common_data);
+
+ BLI_task_pool_work_and_wait(task_pool);
+
+ BLI_task_pool_free(task_pool);
+ }
+
+ MEM_freeN(edge_to_loops);
+ if (!r_loop_to_poly) {
+ MEM_freeN(loop_to_poly);
+ }
+
+ if (r_lnors_spacearr) {
+ if (r_lnors_spacearr == &_lnors_spacearr) {
+ BKE_lnor_spacearr_free(r_lnors_spacearr);
+ }
+ }
+
+#ifdef DEBUG_TIME
+ TIMEIT_END_AVERAGED(BKE_mesh_normals_loop_split);
+#endif
+}
+
+#undef INDEX_UNSET
+#undef INDEX_INVALID
+#undef IS_EDGE_SHARP
+
+/**
+ * Compute internal representation of given custom normals (as an array of float[2]).
+ * It also makes sure the mesh matches those custom normals, by setting sharp edges flag as needed
+ * to get a same custom lnor for all loops sharing a same smooth fan.
+ * If use_vertices if true, r_custom_loopnors is assumed to be per-vertex, not per-loop
+ * (this allows to set whole vert's normals at once, useful in some cases).
+ * r_custom_loopnors is expected to have normalized normals, or zero ones,
+ * in which case they will be replaced by default loop/vertex normal.
+ */
+static void mesh_normals_loop_custom_set(const MVert *mverts,
+ const int numVerts,
+ MEdge *medges,
+ const int numEdges,
+ MLoop *mloops,
+ float (*r_custom_loopnors)[3],
+ const int numLoops,
+ MPoly *mpolys,
+ const float (*polynors)[3],
+ const int numPolys,
+ short (*r_clnors_data)[2],
+ const bool use_vertices)
+{
+ /* We *may* make that poor BKE_mesh_normals_loop_split() even more complex by making it handling
+ * that feature too, would probably be more efficient in absolute.
+ * However, this function *is not* performance-critical, since it is mostly expected to be called
+ * by io addons when importing custom normals, and modifier
+ * (and perhaps from some editing tools later?).
+ * So better to keep some simplicity here, and just call BKE_mesh_normals_loop_split() twice!
+ */
+ MLoopNorSpaceArray lnors_spacearr = {NULL};
+ BLI_bitmap *done_loops = BLI_BITMAP_NEW((size_t)numLoops, __func__);
+ float(*lnors)[3] = MEM_calloc_arrayN((size_t)numLoops, sizeof(*lnors), __func__);
+ int *loop_to_poly = MEM_malloc_arrayN((size_t)numLoops, sizeof(int), __func__);
+ /* In this case we always consider split nors as ON,
+ * and do not want to use angle to define smooth fans! */
+ const bool use_split_normals = true;
+ const float split_angle = (float)M_PI;
+
+ BLI_SMALLSTACK_DECLARE(clnors_data, short *);
+
+ /* Compute current lnor spacearr. */
+ BKE_mesh_normals_loop_split(mverts,
+ numVerts,
+ medges,
+ numEdges,
+ mloops,
+ lnors,
+ numLoops,
+ mpolys,
+ polynors,
+ numPolys,
+ use_split_normals,
+ split_angle,
+ &lnors_spacearr,
+ NULL,
+ loop_to_poly);
+
+ /* Set all given zero vectors to their default value. */
+ if (use_vertices) {
+ for (int i = 0; i < numVerts; i++) {
+ if (is_zero_v3(r_custom_loopnors[i])) {
+ normal_short_to_float_v3(r_custom_loopnors[i], mverts[i].no);
+ }
+ }
+ }
+ else {
+ for (int i = 0; i < numLoops; i++) {
+ if (is_zero_v3(r_custom_loopnors[i])) {
+ copy_v3_v3(r_custom_loopnors[i], lnors[i]);
+ }
+ }
+ }
+
+ BLI_assert(lnors_spacearr.data_type == MLNOR_SPACEARR_LOOP_INDEX);
+
+ /* Now, check each current smooth fan (one lnor space per smooth fan!),
+ * and if all its matching custom lnors are not (enough) equal, add sharp edges as needed.
+ * This way, next time we run BKE_mesh_normals_loop_split(), we'll get lnor spacearr/smooth fans
+ * matching given custom lnors.
+ * Note this code *will never* unsharp edges! And quite obviously,
+ * when we set custom normals per vertices, running this is absolutely useless.
+ */
+ if (!use_vertices) {
+ for (int i = 0; i < numLoops; i++) {
+ if (!lnors_spacearr.lspacearr[i]) {
+ /* This should not happen in theory, but in some rare case (probably ugly geometry)
+ * we can get some NULL loopspacearr at this point. :/
+ * Maybe we should set those loops' edges as sharp?
+ */
+ BLI_BITMAP_ENABLE(done_loops, i);
+ if (G.debug & G_DEBUG) {
+ printf("WARNING! Getting invalid NULL loop space for loop %d!\n", i);
+ }
+ continue;
+ }
+
+ if (!BLI_BITMAP_TEST(done_loops, i)) {
+ /* Notes:
+ * * In case of mono-loop smooth fan, we have nothing to do.
+ * * Loops in this linklist are ordered (in reversed order compared to how they were
+ * discovered by BKE_mesh_normals_loop_split(), but this is not a problem).
+ * Which means if we find a mismatching clnor,
+ * we know all remaining loops will have to be in a new, different smooth fan/lnor space.
+ * * In smooth fan case, we compare each clnor against a ref one,
+ * to avoid small differences adding up into a real big one in the end!
+ */
+ if (lnors_spacearr.lspacearr[i]->flags & MLNOR_SPACE_IS_SINGLE) {
+ BLI_BITMAP_ENABLE(done_loops, i);
+ continue;
+ }
+
+ LinkNode *loops = lnors_spacearr.lspacearr[i]->loops;
+ MLoop *prev_ml = NULL;
+ const float *org_nor = NULL;
+
+ while (loops) {
+ const int lidx = POINTER_AS_INT(loops->link);
+ MLoop *ml = &mloops[lidx];
+ const int nidx = lidx;
+ float *nor = r_custom_loopnors[nidx];
+
+ if (!org_nor) {
+ org_nor = nor;
+ }
+ else if (dot_v3v3(org_nor, nor) < LNOR_SPACE_TRIGO_THRESHOLD) {
+ /* Current normal differs too much from org one, we have to tag the edge between
+ * previous loop's face and current's one as sharp.
+ * We know those two loops do not point to the same edge,
+ * since we do not allow reversed winding in a same smooth fan.
+ */
+ const MPoly *mp = &mpolys[loop_to_poly[lidx]];
+ const MLoop *mlp =
+ &mloops[(lidx == mp->loopstart) ? mp->loopstart + mp->totloop - 1 : lidx - 1];
+ medges[(prev_ml->e == mlp->e) ? prev_ml->e : ml->e].flag |= ME_SHARP;
+
+ org_nor = nor;
+ }
+
+ prev_ml = ml;
+ loops = loops->next;
+ BLI_BITMAP_ENABLE(done_loops, lidx);
+ }
+
+ /* We also have to check between last and first loops,
+ * otherwise we may miss some sharp edges here!
+ * This is just a simplified version of above while loop.
+ * See T45984. */
+ loops = lnors_spacearr.lspacearr[i]->loops;
+ if (loops && org_nor) {
+ const int lidx = POINTER_AS_INT(loops->link);
+ MLoop *ml = &mloops[lidx];
+ const int nidx = lidx;
+ float *nor = r_custom_loopnors[nidx];
+
+ if (dot_v3v3(org_nor, nor) < LNOR_SPACE_TRIGO_THRESHOLD) {
+ const MPoly *mp = &mpolys[loop_to_poly[lidx]];
+ const MLoop *mlp =
+ &mloops[(lidx == mp->loopstart) ? mp->loopstart + mp->totloop - 1 : lidx - 1];
+ medges[(prev_ml->e == mlp->e) ? prev_ml->e : ml->e].flag |= ME_SHARP;
+ }
+ }
+ }
+ }
+
+ /* And now, recompute our new auto lnors and lnor spacearr! */
+ BKE_lnor_spacearr_clear(&lnors_spacearr);
+ BKE_mesh_normals_loop_split(mverts,
+ numVerts,
+ medges,
+ numEdges,
+ mloops,
+ lnors,
+ numLoops,
+ mpolys,
+ polynors,
+ numPolys,
+ use_split_normals,
+ split_angle,
+ &lnors_spacearr,
+ NULL,
+ loop_to_poly);
+ }
+ else {
+ BLI_bitmap_set_all(done_loops, true, (size_t)numLoops);
+ }
+
+ /* And we just have to convert plain object-space custom normals to our
+ * lnor space-encoded ones. */
+ for (int i = 0; i < numLoops; i++) {
+ if (!lnors_spacearr.lspacearr[i]) {
+ BLI_BITMAP_DISABLE(done_loops, i);
+ if (G.debug & G_DEBUG) {
+ printf("WARNING! Still getting invalid NULL loop space in second loop for loop %d!\n", i);
+ }
+ continue;
+ }
+
+ if (BLI_BITMAP_TEST_BOOL(done_loops, i)) {
+ /* Note we accumulate and average all custom normals in current smooth fan,
+ * to avoid getting different clnors data (tiny differences in plain custom normals can
+ * give rather huge differences in computed 2D factors).
+ */
+ LinkNode *loops = lnors_spacearr.lspacearr[i]->loops;
+ if (lnors_spacearr.lspacearr[i]->flags & MLNOR_SPACE_IS_SINGLE) {
+ BLI_assert(POINTER_AS_INT(loops) == i);
+ const int nidx = use_vertices ? (int)mloops[i].v : i;
+ float *nor = r_custom_loopnors[nidx];
+
+ BKE_lnor_space_custom_normal_to_data(lnors_spacearr.lspacearr[i], nor, r_clnors_data[i]);
+ BLI_BITMAP_DISABLE(done_loops, i);
+ }
+ else {
+ int nbr_nors = 0;
+ float avg_nor[3];
+ short clnor_data_tmp[2], *clnor_data;
+
+ zero_v3(avg_nor);
+ while (loops) {
+ const int lidx = POINTER_AS_INT(loops->link);
+ const int nidx = use_vertices ? (int)mloops[lidx].v : lidx;
+ float *nor = r_custom_loopnors[nidx];
+
+ nbr_nors++;
+ add_v3_v3(avg_nor, nor);
+ BLI_SMALLSTACK_PUSH(clnors_data, (short *)r_clnors_data[lidx]);
+
+ loops = loops->next;
+ BLI_BITMAP_DISABLE(done_loops, lidx);
+ }
+
+ mul_v3_fl(avg_nor, 1.0f / (float)nbr_nors);
+ BKE_lnor_space_custom_normal_to_data(lnors_spacearr.lspacearr[i], avg_nor, clnor_data_tmp);
+
+ while ((clnor_data = BLI_SMALLSTACK_POP(clnors_data))) {
+ clnor_data[0] = clnor_data_tmp[0];
+ clnor_data[1] = clnor_data_tmp[1];
+ }
+ }
+ }
+ }
+
+ MEM_freeN(lnors);
+ MEM_freeN(loop_to_poly);
+ MEM_freeN(done_loops);
+ BKE_lnor_spacearr_free(&lnors_spacearr);
+}
+
+void BKE_mesh_normals_loop_custom_set(const MVert *mverts,
+ const int numVerts,
+ MEdge *medges,
+ const int numEdges,
+ MLoop *mloops,
+ float (*r_custom_loopnors)[3],
+ const int numLoops,
+ MPoly *mpolys,
+ const float (*polynors)[3],
+ const int numPolys,
+ short (*r_clnors_data)[2])
+{
+ mesh_normals_loop_custom_set(mverts,
+ numVerts,
+ medges,
+ numEdges,
+ mloops,
+ r_custom_loopnors,
+ numLoops,
+ mpolys,
+ polynors,
+ numPolys,
+ r_clnors_data,
+ false);
+}
+
+void BKE_mesh_normals_loop_custom_from_vertices_set(const MVert *mverts,
+ float (*r_custom_vertnors)[3],
+ const int numVerts,
+ MEdge *medges,
+ const int numEdges,
+ MLoop *mloops,
+ const int numLoops,
+ MPoly *mpolys,
+ const float (*polynors)[3],
+ const int numPolys,
+ short (*r_clnors_data)[2])
+{
+ mesh_normals_loop_custom_set(mverts,
+ numVerts,
+ medges,
+ numEdges,
+ mloops,
+ r_custom_vertnors,
+ numLoops,
+ mpolys,
+ polynors,
+ numPolys,
+ r_clnors_data,
+ true);
+}
+
+static void mesh_set_custom_normals(Mesh *mesh, float (*r_custom_nors)[3], const bool use_vertices)
+{
+ short(*clnors)[2];
+ const int numloops = mesh->totloop;
+
+ clnors = CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL);
+ if (clnors != NULL) {
+ memset(clnors, 0, sizeof(*clnors) * (size_t)numloops);
+ }
+ else {
+ clnors = CustomData_add_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL, CD_CALLOC, NULL, numloops);
+ }
+
+ float(*polynors)[3] = CustomData_get_layer(&mesh->pdata, CD_NORMAL);
+ bool free_polynors = false;
+ if (polynors == NULL) {
+ polynors = MEM_mallocN(sizeof(float[3]) * (size_t)mesh->totpoly, __func__);
+ BKE_mesh_calc_normals_poly(mesh->mvert,
+ NULL,
+ mesh->totvert,
+ mesh->mloop,
+ mesh->mpoly,
+ mesh->totloop,
+ mesh->totpoly,
+ polynors,
+ false);
+ free_polynors = true;
+ }
+
+ mesh_normals_loop_custom_set(mesh->mvert,
+ mesh->totvert,
+ mesh->medge,
+ mesh->totedge,
+ mesh->mloop,
+ r_custom_nors,
+ mesh->totloop,
+ mesh->mpoly,
+ polynors,
+ mesh->totpoly,
+ clnors,
+ use_vertices);
+
+ if (free_polynors) {
+ MEM_freeN(polynors);
+ }
+}
+
+/**
+ * Higher level functions hiding most of the code needed around call to
+ * #BKE_mesh_normals_loop_custom_set().
+ *
+ * \param r_custom_loopnors: is not const, since code will replace zero_v3 normals there
+ * with automatically computed vectors.
+ */
+void BKE_mesh_set_custom_normals(Mesh *mesh, float (*r_custom_loopnors)[3])
+{
+ mesh_set_custom_normals(mesh, r_custom_loopnors, false);
+}
+
+/**
+ * Higher level functions hiding most of the code needed around call to
+ * #BKE_mesh_normals_loop_custom_from_vertices_set().
+ *
+ * \param r_custom_vertnors: is not const, since code will replace zero_v3 normals there
+ * with automatically computed vectors.
+ */
+void BKE_mesh_set_custom_normals_from_vertices(Mesh *mesh, float (*r_custom_vertnors)[3])
+{
+ mesh_set_custom_normals(mesh, r_custom_vertnors, true);
+}
+
+/**
+ * Computes average per-vertex normals from given custom loop normals.
+ *
+ * \param clnors: The computed custom loop normals.
+ * \param r_vert_clnors: The (already allocated) array where to store averaged per-vertex normals.
+ */
+void BKE_mesh_normals_loop_to_vertex(const int numVerts,
+ const MLoop *mloops,
+ const int numLoops,
+ const float (*clnors)[3],
+ float (*r_vert_clnors)[3])
+{
+ int *vert_loops_nbr = MEM_calloc_arrayN((size_t)numVerts, sizeof(*vert_loops_nbr), __func__);
+
+ copy_vn_fl((float *)r_vert_clnors, 3 * numVerts, 0.0f);
+
+ int i;
+ const MLoop *ml;
+ for (i = 0, ml = mloops; i < numLoops; i++, ml++) {
+ const uint v = ml->v;
+
+ add_v3_v3(r_vert_clnors[v], clnors[i]);
+ vert_loops_nbr[v]++;
+ }
+
+ for (i = 0; i < numVerts; i++) {
+ mul_v3_fl(r_vert_clnors[i], 1.0f / (float)vert_loops_nbr[i]);
+ }
+
+ MEM_freeN(vert_loops_nbr);
+}
+
+#undef LNOR_SPACE_TRIGO_THRESHOLD
+
+/** \} */
diff --git a/source/blender/blenkernel/intern/mesh_runtime.c b/source/blender/blenkernel/intern/mesh_runtime.c
index 011dd7e25ee..47d300dc0c2 100644
--- a/source/blender/blenkernel/intern/mesh_runtime.c
+++ b/source/blender/blenkernel/intern/mesh_runtime.c
@@ -158,8 +158,12 @@ static void mesh_runtime_looptri_recalc_isolated(void *userdata)
BKE_mesh_runtime_looptri_recalc(mesh);
}
-/* This is a ported copy of dm_getLoopTriArray(dm). */
-const MLoopTri *BKE_mesh_runtime_looptri_ensure(Mesh *mesh)
+/**
+ * \note This function only fills a cache, and therefore the mesh argument can
+ * be considered logically const. Concurrent access is protected by a mutex.
+ * \note This is a ported copy of dm_getLoopTriArray(dm).
+ */
+const MLoopTri *BKE_mesh_runtime_looptri_ensure(const Mesh *mesh)
{
ThreadMutex *mesh_eval_mutex = (ThreadMutex *)mesh->runtime.eval_mutex;
BLI_mutex_lock(mesh_eval_mutex);
@@ -171,7 +175,7 @@ const MLoopTri *BKE_mesh_runtime_looptri_ensure(Mesh *mesh)
}
else {
/* Must isolate multithreaded tasks while holding a mutex lock. */
- BLI_task_isolate(mesh_runtime_looptri_recalc_isolated, mesh);
+ BLI_task_isolate(mesh_runtime_looptri_recalc_isolated, (void *)mesh);
looptri = mesh->runtime.looptris.array;
}
diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c
index df84cf6607f..bfdbf844a26 100644
--- a/source/blender/blenkernel/intern/mesh_validate.c
+++ b/source/blender/blenkernel/intern/mesh_validate.c
@@ -1105,7 +1105,7 @@ bool BKE_mesh_validate(Mesh *me, const bool do_verbose, const bool cddata_check_
&changed);
if (changed) {
- DEG_id_tag_update(&me->id, ID_RECALC_GEOMETRY);
+ DEG_id_tag_update(&me->id, ID_RECALC_GEOMETRY_ALL_MODES);
return true;
}
@@ -1183,7 +1183,7 @@ bool BKE_mesh_validate_material_indices(Mesh *me)
}
if (!is_valid) {
- DEG_id_tag_update(&me->id, ID_RECALC_GEOMETRY);
+ DEG_id_tag_update(&me->id, ID_RECALC_GEOMETRY_ALL_MODES);
return true;
}
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index 0f2f56f4f2b..3a7910d1a9f 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -1320,7 +1320,7 @@ static ImBuf *movieclip_get_postprocessed_ibuf(
clip->lastframe = framenr;
real_ibuf_size(clip, user, ibuf, &clip->lastsize[0], &clip->lastsize[1]);
- /* postprocess frame and put to cache if needed*/
+ /* Post-process frame and put to cache if needed. */
if (need_postprocess) {
ImBuf *tmpibuf = ibuf;
ibuf = postprocess_frame(clip, user, tmpibuf, flag, postprocess_flag);
@@ -2128,9 +2128,9 @@ GPUTexture *BKE_movieclip_get_gpu_texture(MovieClip *clip, MovieClipUser *cuser)
void BKE_movieclip_free_gputexture(struct MovieClip *clip)
{
- /* number of gpu textures to keep around as cache
+ /* 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.*/
+ * movie clips around, as they can be large. */
const int MOVIECLIP_NUM_GPUTEXTURES = 1;
while (BLI_listbase_count(&clip->runtime.gputextures) > MOVIECLIP_NUM_GPUTEXTURES) {
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index 45ac20ef154..54f0da30a2b 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -994,7 +994,7 @@ static void multiresModifier_disp_run(
}
}
- /*numGrids = dm->getNumGrids(dm);*/ /*UNUSED*/
+ // numGrids = dm->getNumGrids(dm); /* UNUSED */
gridSize = dm->getGridSize(dm);
gridData = dm->getGridData(dm);
gridOffset = dm->getGridOffset(dm);
@@ -1285,7 +1285,7 @@ DerivedMesh *multires_make_derived_from_derived(
multires_set_tot_mdisps(me, mmd->totlvl);
multiresModifier_ensure_external_read(me, mmd);
- /*run displacement*/
+ /* Run displacement. */
multiresModifier_disp_run(result, ob->data, dm, APPLY_DISPLACEMENTS, subGridData, mmd->totlvl);
/* copy hidden elements for this level */
@@ -1514,7 +1514,7 @@ void multires_topology_changed(Mesh *me)
*
* Since the multires data files only contain displacement vectors without knowledge about
* subdivision level some extra work is needed. Namely make is to all displacement grids have
- * proper level and number of displacement vectors set. */
+ * proper level and number of displacement vectors set. */
void multires_ensure_external_read(struct Mesh *mesh, int top_level)
{
if (!CustomData_external_test(&mesh->ldata, CD_MDISPS)) {
diff --git a/source/blender/blenkernel/intern/multires_reshape.c b/source/blender/blenkernel/intern/multires_reshape.c
index 04ad78ec0de..bd52d70b223 100644
--- a/source/blender/blenkernel/intern/multires_reshape.c
+++ b/source/blender/blenkernel/intern/multires_reshape.c
@@ -235,7 +235,7 @@ void multiresModifier_subdivide_to_level(struct Object *object,
/* Free original grids which makes it so smoothing with details thinks all the details were
* added against base mesh's limit surface. This is similar behavior to as if we've done all
- * displacement in sculpt mode at the old top level and then propagated to the new top level.*/
+ * displacement in sculpt mode at the old top level and then propagated to the new top level. */
multires_reshape_free_original_grids(&reshape_context);
if (ELEM(mode, MULTIRES_SUBDIVIDE_LINEAR, MULTIRES_SUBDIVIDE_SIMPLE)) {
diff --git a/source/blender/blenkernel/intern/multires_reshape_smooth.c b/source/blender/blenkernel/intern/multires_reshape_smooth.c
index f10aae18142..aed8c3122a2 100644
--- a/source/blender/blenkernel/intern/multires_reshape_smooth.c
+++ b/source/blender/blenkernel/intern/multires_reshape_smooth.c
@@ -55,7 +55,7 @@
/* Surface refers to a simplified and lower-memory footprint representation of the limit surface.
*
* Used to store pre-calculated information which is expensive or impossible to evaluate when
- * traversing the final limit surface. */
+ * traversing the final limit surface. */
typedef struct SurfacePoint {
float P[3];
@@ -1027,7 +1027,7 @@ static void converter_init(const MultiresReshapeSmoothContext *reshape_smooth_co
converter->user_data = (void *)reshape_smooth_context;
}
-/* Create subdiv descriptor created for topology at a reshape level, */
+/* Create subdiv descriptor created for topology at a reshape level. */
static void reshape_subdiv_create(MultiresReshapeSmoothContext *reshape_smooth_context)
{
const MultiresReshapeContext *reshape_context = reshape_smooth_context->reshape_context;
@@ -1050,7 +1050,7 @@ typedef void(ReshapeSubdivCoarsePositionCb)(
const Vertex *vertex,
float r_P[3]);
-/* Refine subdivision surface topology at a reshape level for new coarse vertices positions. */
+/* Refine subdivision surface topology at a reshape level for new coarse vertices positions. */
static void reshape_subdiv_refine(const MultiresReshapeSmoothContext *reshape_smooth_context,
ReshapeSubdivCoarsePositionCb coarse_position_cb)
{
diff --git a/source/blender/blenkernel/intern/multires_unsubdivide.c b/source/blender/blenkernel/intern/multires_unsubdivide.c
index 02b9bb852d6..4210f26a694 100644
--- a/source/blender/blenkernel/intern/multires_unsubdivide.c
+++ b/source/blender/blenkernel/intern/multires_unsubdivide.c
@@ -312,7 +312,7 @@ static bool unsubdivide_tag_disconnected_mesh_element(BMesh *bm, int *elem_id, i
/* Also try from the different 4 vertices of a quad in the current
* disconnected element ID. If a solution exists the search should return a valid solution from
- * one of these vertices.*/
+ * one of these vertices. */
BMFace *f, *init_face = NULL;
BMVert *v;
BMIter iter_a, iter_b;
diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c
index 92e21183acb..bf18765aa94 100644
--- a/source/blender/blenkernel/intern/nla.c
+++ b/source/blender/blenkernel/intern/nla.c
@@ -1289,7 +1289,7 @@ void BKE_nlastrip_set_active(AnimData *adt, NlaStrip *strip)
return;
}
- /* loop over tracks, deactivating*/
+ /* Loop over tracks, deactivating. */
for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
for (nls = nlt->strips.first; nls; nls = nls->next) {
if (nls != strip) {
@@ -1560,7 +1560,7 @@ bool BKE_nlatracks_have_animated_strips(ListBase *tracks)
return false;
}
-/* Validate the NLA-Strips 'control' F-Curves based on the flags set*/
+/* Validate the NLA-Strips 'control' F-Curves based on the flags set. */
void BKE_nlastrip_validate_fcurves(NlaStrip *strip)
{
FCurve *fcu;
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index db18cecb5d3..e6635665567 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -875,7 +875,7 @@ void ntreeBlendReadLib(struct BlendLibReader *reader, struct bNodeTree *ntree)
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
/* Link ID Properties -- and copy this comment EXACTLY for easy finding
- * of library blocks that implement this.*/
+ * of library blocks that implement this. */
IDP_BlendReadLib(reader, node->prop);
BLO_read_id_address(reader, lib, &node->id);
@@ -2365,7 +2365,7 @@ static void nodeUnMuteLink(bNodeLink *link)
link->tosock->flag |= SOCK_IN_USE;
}
-/* Upstream muting. Always happens when unmuting but checks when muting. O(n^2) algorithm.*/
+/* Upstream muting. Always happens when unmuting but checks when muting. O(n^2) algorithm. */
static void nodeMuteRerouteInputLinks(bNodeTree *ntree, bNode *node, const bool mute)
{
if (node->type != NODE_REROUTE) {
@@ -2388,7 +2388,7 @@ static void nodeMuteRerouteInputLinks(bNodeTree *ntree, bNode *node, const bool
}
}
-/* Downstream muting propagates when reaching reroute nodes. O(n^2) algorithm.*/
+/* Downstream muting propagates when reaching reroute nodes. O(n^2) algorithm. */
static void nodeMuteRerouteOutputLinks(bNodeTree *ntree, bNode *node, const bool mute)
{
if (node->type != NODE_REROUTE) {
@@ -5054,6 +5054,11 @@ static void registerGeometryNodes()
register_node_type_geo_collection_info();
register_node_type_geo_convex_hull();
register_node_type_geo_curve_length();
+ register_node_type_geo_curve_primitive_bezier_segment();
+ register_node_type_geo_curve_primitive_circle();
+ register_node_type_geo_curve_primitive_quadratic_bezier();
+ register_node_type_geo_curve_primitive_spiral();
+ register_node_type_geo_curve_primitive_star();
register_node_type_geo_curve_to_mesh();
register_node_type_geo_curve_to_points();
register_node_type_geo_curve_resample();
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 8cfd75b015c..ff5d94d20b7 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -2759,7 +2759,7 @@ Object *BKE_object_duplicate(Main *bmain,
}
if (!is_subprocess) {
- /* This code will follow into all ID links using an ID tagged with LIB_TAG_NEW.*/
+ /* This code will follow into all ID links using an ID tagged with LIB_TAG_NEW. */
BKE_libblock_relink_to_newid(&obn->id);
#ifndef NDEBUG
@@ -2854,7 +2854,7 @@ void BKE_object_copy_proxy_drivers(Object *ob, Object *target)
else {
/* only on local objects because this causes indirect links
* 'a -> b -> c', blend to point directly to a.blend
- * when a.blend has a proxy that's linked into c.blend */
+ * when a.blend has a proxy that's linked into `c.blend`. */
if (!ID_IS_LINKED(ob)) {
id_lib_extern((ID *)dtar->id);
}
@@ -3212,12 +3212,11 @@ void BKE_object_to_mat3(Object *ob, float r_mat[3][3]) /* no parent */
{
float smat[3][3];
float rmat[3][3];
- /*float q1[4];*/
- /* scale */
+ /* Scale. */
BKE_object_scale_to_mat3(ob, smat);
- /* rot */
+ /* Rotation. */
BKE_object_rot_to_mat3(ob, rmat, true);
mul_m3_m3m3(r_mat, rmat, smat);
}
@@ -3861,7 +3860,7 @@ void BKE_object_boundbox_flag(Object *ob, int flag, const bool set)
}
}
-void BKE_object_boundbox_calc_from_mesh(struct Object *ob, struct Mesh *me_eval)
+void BKE_object_boundbox_calc_from_mesh(struct Object *ob, const struct Mesh *me_eval)
{
float min[3], max[3];
@@ -4170,7 +4169,7 @@ void BKE_object_foreach_display_point(Object *ob,
void *user_data)
{
/* TODO: pointcloud and hair objects support */
- Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
+ const Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
float co[3];
if (mesh_eval != NULL) {
@@ -4476,7 +4475,7 @@ Mesh *BKE_object_get_pre_modified_mesh(const Object *object)
}
/**
- * Get a mesh which corresponds to very very original mesh from #Main.
+ * Get a mesh which corresponds to the very original mesh from #Main.
* - For original objects it will be object->data.
* - For evaluated objects it will be same mesh as corresponding original
* object uses as data.
@@ -5304,7 +5303,7 @@ KDTree_3d *BKE_object_as_kdtree(Object *ob, int *r_tot)
tot = 0;
tree = BLI_kdtree_3d_new(totvert);
- /* we don't how how many verts from the DM we can use */
+ /* We don't how many verts from the DM we can use. */
for (i = 0; i < totvert; i++) {
if (index[i] != ORIGINDEX_NONE) {
float co[3];
diff --git a/source/blender/blenkernel/intern/object_dupli.cc b/source/blender/blenkernel/intern/object_dupli.cc
index 768fa9373c1..77969328365 100644
--- a/source/blender/blenkernel/intern/object_dupli.cc
+++ b/source/blender/blenkernel/intern/object_dupli.cc
@@ -335,14 +335,14 @@ static void make_child_duplis(const DupliContext *ctx,
/** \name Internal Data Access Utilities
* \{ */
-static Mesh *mesh_data_from_duplicator_object(Object *ob,
- BMEditMesh **r_em,
- const float (**r_vert_coords)[3],
- const float (**r_vert_normals)[3])
+static const Mesh *mesh_data_from_duplicator_object(Object *ob,
+ BMEditMesh **r_em,
+ const float (**r_vert_coords)[3],
+ const float (**r_vert_normals)[3])
{
/* Gather mesh info. */
BMEditMesh *em = BKE_editmesh_from_object(ob);
- Mesh *me_eval;
+ const Mesh *me_eval;
*r_em = nullptr;
*r_vert_coords = nullptr;
@@ -603,7 +603,7 @@ static void make_duplis_verts(const DupliContext *ctx)
BMEditMesh *em = nullptr;
const float(*vert_coords)[3] = nullptr;
const float(*vert_normals)[3] = nullptr;
- Mesh *me_eval = mesh_data_from_duplicator_object(
+ const Mesh *me_eval = mesh_data_from_duplicator_object(
parent, &em, &vert_coords, use_rotation ? &vert_normals : nullptr);
if (em == nullptr && me_eval == nullptr) {
return;
@@ -1151,7 +1151,7 @@ static void make_duplis_faces(const DupliContext *ctx)
/* Gather mesh info. */
BMEditMesh *em = nullptr;
const float(*vert_coords)[3] = nullptr;
- Mesh *me_eval = mesh_data_from_duplicator_object(parent, &em, &vert_coords, nullptr);
+ const Mesh *me_eval = mesh_data_from_duplicator_object(parent, &em, &vert_coords, nullptr);
if (em == nullptr && me_eval == nullptr) {
return;
}
diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c
index b1afd968bdc..ab247ef5507 100644
--- a/source/blender/blenkernel/intern/object_update.c
+++ b/source/blender/blenkernel/intern/object_update.c
@@ -224,7 +224,7 @@ void BKE_object_handle_data_update(Depsgraph *depsgraph, Scene *scene, Object *o
case OB_SURF:
case OB_FONT: {
bool for_render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
- BKE_displist_make_curveTypes(depsgraph, scene, ob, for_render, false);
+ BKE_displist_make_curveTypes(depsgraph, scene, ob, for_render);
break;
}
diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c
index 9d53dad8d03..2e7152302c7 100644
--- a/source/blender/blenkernel/intern/ocean.c
+++ b/source/blender/blenkernel/intern/ocean.c
@@ -248,7 +248,7 @@ void BKE_ocean_eval_uv(struct Ocean *oc, struct OceanResult *ocr, float u, float
if (oc->_do_normals) {
ocr->normal[0] = BILERP(oc->_N_x);
- ocr->normal[1] = oc->_N_y /*BILERP(oc->_N_y) (MEM01)*/;
+ ocr->normal[1] = oc->_N_y /* BILERP(oc->_N_y) (MEM01) */;
ocr->normal[2] = BILERP(oc->_N_z);
}
@@ -347,7 +347,7 @@ void BKE_ocean_eval_uv_catrom(struct Ocean *oc, struct OceanResult *ocr, float u
}
if (oc->_do_normals) {
ocr->normal[0] = INTERP(oc->_N_x);
- ocr->normal[1] = oc->_N_y /*INTERP(oc->_N_y) (MEM01)*/;
+ ocr->normal[1] = oc->_N_y /* INTERP(oc->_N_y) (MEM01) */;
ocr->normal[2] = INTERP(oc->_N_z);
}
if (oc->_do_chop) {
@@ -1052,7 +1052,7 @@ void BKE_ocean_free_data(struct Ocean *oc)
fftw_destroy_plan(oc->_N_x_plan);
fftw_destroy_plan(oc->_N_z_plan);
MEM_freeN(oc->_N_x);
- /*fftwf_free(oc->_N_y); (MEM01)*/
+ /* fftwf_free(oc->_N_y); (MEM01) */
MEM_freeN(oc->_N_z);
}
@@ -1437,9 +1437,9 @@ void BKE_ocean_bake(struct Ocean *o,
rgb_to_rgba_unit_alpha(&ibuf_disp->rect_float[4 * (res_x * y + x)], ocr.disp);
if (o->_do_jacobian) {
- /* TODO, cleanup unused code - campbell */
+ /* TODO: cleanup unused code - campbell */
- float /*r, */ /* UNUSED */ pr = 0.0f, foam_result;
+ float /* r, */ /* UNUSED */ pr = 0.0f, foam_result;
float neg_disp, neg_eplus;
ocr.foam = BKE_ocean_jminus_to_foam(ocr.Jminus, och->foam_coverage);
@@ -1449,9 +1449,9 @@ void BKE_ocean_bake(struct Ocean *o,
pr = prev_foam[res_x * y + x];
}
- /* r = BLI_rng_get_float(rng); */ /* UNUSED */ /* randomly reduce foam */
+ // r = BLI_rng_get_float(rng); /* UNUSED */ /* randomly reduce foam */
- /* pr = pr * och->foam_fade; */ /* overall fade */
+ // pr = pr * och->foam_fade; /* overall fade */
/* Remember ocean coord sys is Y up!
* break up the foam where height (Y) is low (wave valley),
@@ -1475,7 +1475,7 @@ void BKE_ocean_bake(struct Ocean *o,
prev_foam[res_x * y + x] = foam_result;
- /*foam_result = min_ff(foam_result, 1.0f); */
+ // foam_result = min_ff(foam_result, 1.0f);
value_to_rgba_unit_alpha(&ibuf_foam->rect_float[4 * (res_x * y + x)], foam_result);
diff --git a/source/blender/blenkernel/intern/ocean_intern.h b/source/blender/blenkernel/intern/ocean_intern.h
index b55b211fa33..4ebd03789af 100644
--- a/source/blender/blenkernel/intern/ocean_intern.h
+++ b/source/blender/blenkernel/intern/ocean_intern.h
@@ -99,7 +99,7 @@ typedef struct Ocean {
double *_N_x; /* init w sim w via plan? */
/* all member of this array has same values,
* so convert this array to a float to reduce memory usage (MEM01). */
- /*float * _N_y; */
+ // float * _N_y;
double _N_y; /* sim w ********* can be rearranged? */
double *_N_z; /* init w sim w via plan? */
double *_disp_x; /* init w sim w via plan? */
diff --git a/source/blender/blenkernel/intern/ocean_spectrum.c b/source/blender/blenkernel/intern/ocean_spectrum.c
index 1f7cc56f1a9..7ed70234baf 100644
--- a/source/blender/blenkernel/intern/ocean_spectrum.c
+++ b/source/blender/blenkernel/intern/ocean_spectrum.c
@@ -122,7 +122,7 @@ static float jonswap(const Ocean *oc, const float k2)
float val = alpha_beta_spectrum(m_alpha, beta, GRAVITY, omega, m_peakomega);
- /* Peak sharpening */
+ /* Peak sharpening. */
val *= peak_sharpen(m_omega, m_peakomega, m_gamma);
return val;
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 3494630e1fa..a7c6dc2deb9 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -1810,7 +1810,7 @@ void BKE_sculpt_color_layer_create_if_needed(struct Object *object)
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);
+ DEG_id_tag_update(&orig_me->id, ID_RECALC_GEOMETRY_ALL_MODES);
}
/** \warning Expects a fully evaluated depsgraph. */
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 021121034f1..d386967bf8b 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -2462,7 +2462,7 @@ int do_guides(Depsgraph *depsgraph,
(int)(data->strength * guidetime * 100.0f),
100));
}
- else { /* curve size*/
+ else { /* Curve size. */
if (cu->flag & CU_PATH_RADIUS) {
mul_v3_fl(vec_to_point, radius);
}
diff --git a/source/blender/blenkernel/intern/particle_child.c b/source/blender/blenkernel/intern/particle_child.c
index 6e0965650d3..2231731287d 100644
--- a/source/blender/blenkernel/intern/particle_child.c
+++ b/source/blender/blenkernel/intern/particle_child.c
@@ -785,7 +785,7 @@ static void do_twist(const ParticleChildModifierContext *modifier_ctx,
return;
}
if (part->twist == 0.0f) {
- /* No twist along the strand. */
+ /* No twist along the strand. */
return;
}
/* Dependent on whether it's threaded update or not, curve comes
diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c
index 13f0cb28428..1fd99bb2cbd 100644
--- a/source/blender/blenkernel/intern/particle_distribute.c
+++ b/source/blender/blenkernel/intern/particle_distribute.c
@@ -142,7 +142,7 @@ static void distribute_grid(Mesh *mesh, ParticleSystem *psys)
size[(axis + 1) % 3] = (int)ceil(delta[(axis + 1) % 3] / d);
size[(axis + 2) % 3] = (int)ceil(delta[(axis + 2) % 3] / d);
- /* float errors grrr.. */
+ /* float errors grrr. */
size[(axis + 1) % 3] = MIN2(size[(axis + 1) % 3], res);
size[(axis + 2) % 3] = MIN2(size[(axis + 2) % 3], res);
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index d236dbbf101..c35f703b072 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -250,7 +250,7 @@ static void realloc_particles(ParticleSimulationData *sim, int new_totpart)
if (psys->particles) {
totsaved = MIN2(psys->totpart, totpart);
- /*save old pars*/
+ /* Save old pars. */
if (totsaved) {
memcpy(newpars, psys->particles, totsaved * sizeof(ParticleData));
@@ -607,8 +607,8 @@ void init_particle(ParticleSimulationData *sim, ParticleData *pa)
pa->time = part->sta + (part->end - part->sta) * birth_time;
pa->hair_index = 0;
- /* we can't reset to -1 anymore since we've figured out correct index in distribute_particles */
- /* usage other than straight after distribute has to handle this index by itself - jahka*/
+ /* We can't reset to -1 anymore since we've figured out correct index in #distribute_particles
+ * usage other than straight after distribute has to handle this index by itself - jahka. */
// pa->num_dmcache = DMCACHE_NOTFOUND; /* assume we don't have a derived mesh face */
}
@@ -840,7 +840,7 @@ void psys_get_birth_coords(
copy_v3_v3(state->co, loc);
- /* boids don't get any initial velocity */
+ /* boids don't get any initial velocity. */
zero_v3(state->vel);
/* boids store direction in ave */
@@ -1473,7 +1473,7 @@ static void integrate_particle(
force_func(forcedata, states + i, force, impulse);
- /* force to acceleration*/
+ /* Force to acceleration. */
mul_v3_v3fl(acceleration, force, 1.0f / pa_mass);
if (external_acceleration) {
@@ -1920,7 +1920,7 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa
}
}
- /* Artificial buoyancy force in negative gravity direction */
+ /* Artificial buoyancy force in negative gravity direction. */
if (fluid->buoyancy > 0.0f && gravity) {
madd_v3_v3fl(force, gravity, fluid->buoyancy * (density - rest_density));
}
@@ -2095,7 +2095,7 @@ static void sphclassical_force_cb(void *sphdata_v,
}
}
- /* Artificial buoyancy force in negative gravity direction */
+ /* Artificial buoyancy force in negative gravity direction. */
if (fluid->buoyancy > 0.0f && gravity) {
madd_v3_v3fl(force, gravity, fluid->buoyancy * (pa->sphdensity - rest_density));
}
@@ -2226,7 +2226,7 @@ static void sph_integrate(ParticleSimulationData *sim,
sphdata->pass = 0;
// sphdata.element_size and sphdata.flow are set in the callback.
- /* restore previous state and treat gravity & effectors as external acceleration*/
+ /* Restore previous state and treat gravity & effectors as external acceleration. */
sub_v3_v3v3(effector_acceleration, pa->state.vel, pa->prev_state.vel);
mul_v3_fl(effector_acceleration, 1.0f / dtime);
@@ -3001,7 +3001,7 @@ static int collision_response(ParticleSimulationData *sim,
/* get back to global coordinates */
add_v3_v3(v1_tan, vc_tan);
- /* convert to angular velocity*/
+ /* Convert to angular velocity. */
cross_v3_v3v3(ave, vr_tan, pce->nor);
mul_v3_fl(ave, 1.0f / MAX2(pa->size, 0.001f));
@@ -3369,7 +3369,7 @@ static void hair_create_input_mesh(ParticleSimulationData *sim,
/* XXX placeholder for more flexible future hair settings */
hair_radius = part->size;
- /* make vgroup for pin roots etc.. */
+ /* Make vgroup for pin roots etc. */
hair_index = 1;
LOOP_PARTICLES
{
@@ -3927,7 +3927,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
pa->alive = PARS_DYING;
}
else if (birthtime <= cfra && birthtime >= psys->cfra) {
- /* particle is born some time between this and last step*/
+ /* Particle is born some time between this and last step. */
reset_particle(sim, pa, dfra * timestep, cfra);
pa->alive = PARS_ALIVE;
pa->state.time = cfra - birthtime;
@@ -3936,7 +3936,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
/* nothing to be done when particle is dead */
}
- /* only reset unborn particles if they're shown or if the particle is born soon*/
+ /* Only reset unborn particles if they're shown or if the particle is born soon. */
if (pa->alive == PARS_UNBORN &&
(part->flag & PART_UNBORN || (cfra + psys->pointcache->step > pa->time))) {
reset_particle(sim, pa, dtime, cfra);
@@ -4104,7 +4104,7 @@ static void update_children(ParticleSimulationData *sim, const bool use_render_p
psys_free_children(sim->psys);
}
}
-/* updates cached particles' alive & other flags etc..*/
+/* Updates cached particles' alive & other flags etc. */
static void cached_step(ParticleSimulationData *sim, float cfra, const bool use_render_params)
{
ParticleSystem *psys = sim->psys;
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 9f316ec60c0..0d84022da77 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -2985,7 +2985,7 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
}
}
-bool pbvh_has_mask(PBVH *pbvh)
+bool pbvh_has_mask(const PBVH *pbvh)
{
switch (pbvh->type) {
case PBVH_GRIDS:
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index 09e4ad93baa..c2483b265a5 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -180,7 +180,7 @@ static BMVert *bm_vert_hash_lookup_chain(GHash *deleted_verts, BMVert *v)
while (true) {
BMVert **v_next_p = (BMVert **)BLI_ghash_lookup_p(deleted_verts, v);
if (v_next_p == NULL) {
- /* not remapped*/
+ /* Not remapped. */
return v;
}
if (*v_next_p == NULL) {
@@ -2316,7 +2316,7 @@ static void pbvh_bmesh_verify(PBVH *pbvh)
vert_count++;
}
- /* if totvert differs from number of verts inside the hash. hash-totvert is checked above */
+ /* If totvert differs from number of verts inside the hash. hash-totvert is checked above. */
BLI_assert(vert_count == pbvh->bm->totvert);
# endif
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index be206f8a642..a05eb6962ce 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -2632,7 +2632,7 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, unsigned int cfra)
}
#endif
- /*if (!G.relbase_valid) return; */ /* save blend file before using pointcache */
+ // if (!G.relbase_valid) return; /* Save blend file before using pointcache. */
/* clear all files in the temp dir with the prefix of the ID and the ".bphys" suffix */
switch (mode) {
@@ -2659,8 +2659,8 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, unsigned int cfra)
ptcache_filename_ext_append(pid, ext, 0, false, 0);
while ((de = readdir(dir)) != NULL) {
- if (strstr(de->d_name, ext)) { /* do we have the right extension?*/
- if (STREQLEN(filename, de->d_name, len)) { /* do we have the right prefix */
+ if (strstr(de->d_name, ext)) { /* Do we have the right extension? */
+ if (STREQLEN(filename, de->d_name, len)) { /* Do we have the right prefix. */
if (mode == PTCACHE_CLEAR_ALL) {
pid->cache->last_exact = MIN2(pid->cache->startframe, 0);
BLI_join_dirfile(path_full, sizeof(path_full), path, de->d_name);
@@ -2695,7 +2695,7 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, unsigned int cfra)
PTCacheMem *link = NULL;
if (mode == PTCACHE_CLEAR_ALL) {
- /*we want startframe if the cache starts before zero*/
+ /* We want startframe if the cache starts before zero. */
pid->cache->last_exact = MIN2(pid->cache->startframe, 0);
for (; pm; pm = pm->next) {
ptcache_mem_clear(pm);
@@ -2856,8 +2856,8 @@ void BKE_ptcache_id_time(
ptcache_filename_ext_append(pid, ext, 0, false, 0);
while ((de = readdir(dir)) != NULL) {
- if (strstr(de->d_name, ext)) { /* do we have the right extension?*/
- if (STREQLEN(filename, de->d_name, len)) { /* do we have the right prefix */
+ if (strstr(de->d_name, ext)) { /* Do we have the right extension? */
+ if (STREQLEN(filename, de->d_name, len)) { /* Do we have the right prefix. */
/* read the number of the file */
const int frame = ptcache_frame_from_filename(de->d_name, ext);
@@ -3038,7 +3038,7 @@ void BKE_ptcache_remove(void)
if (FILENAME_IS_CURRPAR(de->d_name)) {
/* do nothing */
}
- else if (strstr(de->d_name, PTCACHE_EXT)) { /* do we have the right extension?*/
+ else if (strstr(de->d_name, PTCACHE_EXT)) { /* Do we have the right extension? */
BLI_join_dirfile(path_full, sizeof(path_full), path, de->d_name);
BLI_delete(path_full, false, false);
}
@@ -3050,7 +3050,7 @@ void BKE_ptcache_remove(void)
closedir(dir);
}
else {
- rmdir = 0; /* path doesn't exist */
+ rmdir = 0; /* Path doesn't exist. */
}
if (rmdir) {
@@ -3569,8 +3569,8 @@ void BKE_ptcache_disk_cache_rename(PTCacheID *pid, const char *name_src, const c
BLI_strncpy(pid->cache->name, name_dst, sizeof(pid->cache->name));
while ((de = readdir(dir)) != NULL) {
- if (strstr(de->d_name, ext)) { /* do we have the right extension?*/
- if (STREQLEN(old_filename, de->d_name, len)) { /* do we have the right prefix */
+ if (strstr(de->d_name, ext)) { /* Do we have the right extension? */
+ if (STREQLEN(old_filename, de->d_name, len)) { /* Do we have the right prefix. */
/* read the number of the file */
const int frame = ptcache_frame_from_filename(de->d_name, ext);
@@ -3589,7 +3589,7 @@ void BKE_ptcache_disk_cache_rename(PTCacheID *pid, const char *name_src, const c
void BKE_ptcache_load_external(PTCacheID *pid)
{
- /*todo*/
+ /* TODO: */
PointCache *cache = pid->cache;
int len; /* store the length of the string */
int info = 0;
@@ -3626,8 +3626,8 @@ void BKE_ptcache_load_external(PTCacheID *pid)
}
while ((de = readdir(dir)) != NULL) {
- if (strstr(de->d_name, ext)) { /* do we have the right extension?*/
- if (STREQLEN(filename, de->d_name, len)) { /* do we have the right prefix */
+ if (strstr(de->d_name, ext)) { /* Do we have the right extension? */
+ if (STREQLEN(filename, de->d_name, len)) { /* Do we have the right prefix. */
/* read the number of the file */
const int frame = ptcache_frame_from_filename(de->d_name, ext);
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index 21b86aa8148..2d4cce4b953 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -668,7 +668,7 @@ void BKE_rigidbody_calc_volume(Object *ob, float *r_vol)
radius = max_fff(size[0], size[1], size[2]) * 0.5f;
}
- /* calculate volume as appropriate */
+ /* Calculate volume as appropriate. */
switch (rbo->shape) {
case RB_SHAPE_BOX:
volume = size[0] * size[1] * size[2];
@@ -744,10 +744,10 @@ void BKE_rigidbody_calc_center_of_mass(Object *ob, float r_center[3])
* (i.e. Object pivot is centralized in boundbox)
* - boundbox gives full width
*/
- /* XXX: all dimensions are auto-determined now... later can add stored settings for this */
+ /* XXX: all dimensions are auto-determined now... later can add stored settings for this. */
BKE_object_dimensions_get(ob, size);
- /* calculate volume as appropriate */
+ /* Calculate volume as appropriate. */
switch (rbo->shape) {
case RB_SHAPE_BOX:
case RB_SHAPE_SPHERE:
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 41f70db3fba..84741038164 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -228,7 +228,10 @@ static void scene_init_data(ID *id)
/* Curve Profile */
scene->toolsettings->custom_bevel_profile_preset = BKE_curveprofile_add(PROF_PRESET_LINE);
+
+ /* Sequencer */
scene->toolsettings->sequencer_tool_settings = SEQ_tool_settings_init();
+ scene->toolsettings->snap_flag |= SCE_SNAP_SEQ;
for (size_t i = 0; i < ARRAY_SIZE(scene->orientation_slots); i++) {
scene->orientation_slots[i].index_custom = -1;
@@ -2013,7 +2016,7 @@ Scene *BKE_scene_duplicate(Main *bmain, Scene *sce, eSceneCopyMethod type)
bmain, NULL, sce_copy->master_collection, duplicate_flags, LIB_ID_DUPLICATE_IS_SUBPROCESS);
if (!is_subprocess) {
- /* This code will follow into all ID links using an ID tagged with LIB_TAG_NEW.*/
+ /* This code will follow into all ID links using an ID tagged with LIB_TAG_NEW. */
BKE_libblock_relink_to_newid(&sce_copy->id);
#ifndef NDEBUG
@@ -3379,7 +3382,7 @@ static bool depsgraph_key_compare(const void *key_a_v, const void *key_b_v)
{
const DepsgraphKey *key_a = key_a_v;
const DepsgraphKey *key_b = key_b_v;
- /* TODO(sergey): Compare rest of */
+ /* TODO(sergey): Compare rest of. */
return !(key_a->view_layer == key_b->view_layer);
}
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index 7a5892baaf6..608317933f5 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -1703,9 +1703,9 @@ static void direct_link_area(BlendDataReader *reader, ScrArea *area)
BLO_read_list(reader, &sconsole->scrollback);
BLO_read_list(reader, &sconsole->history);
- /* comma expressions, (e.g. expr1, expr2, expr3) evaluate each expression,
+ /* Comma expressions, (e.g. expr1, expr2, expr3) evaluate each expression,
* from left to right. the right-most expression sets the result of the comma
- * expression as a whole*/
+ * expression as a whole. */
LISTBASE_FOREACH_MUTABLE (ConsoleLine *, cl, &sconsole->history) {
BLO_read_data_address(reader, &cl->line);
if (cl->line) {
diff --git a/source/blender/blenkernel/intern/shader_fx.c b/source/blender/blenkernel/intern/shader_fx.c
index 60f0b744e59..b537bdc5479 100644
--- a/source/blender/blenkernel/intern/shader_fx.c
+++ b/source/blender/blenkernel/intern/shader_fx.c
@@ -58,9 +58,9 @@ static ShaderFxTypeInfo *shader_fx_types[NUM_SHADER_FX_TYPES] = {NULL};
/* Methods - Evaluation Loops, etc. */
/* check if exist grease pencil effects */
-bool BKE_shaderfx_has_gpencil(Object *ob)
+bool BKE_shaderfx_has_gpencil(const Object *ob)
{
- ShaderFxData *fx;
+ const ShaderFxData *fx;
for (fx = ob->shader_fx.first; fx; fx = fx->next) {
const ShaderFxTypeInfo *fxi = BKE_shaderfx_get_info(fx->type);
if (fxi->type == eShaderFxType_GpencilType) {
diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c
index ae39b200b56..aeb8133974e 100644
--- a/source/blender/blenkernel/intern/shrinkwrap.c
+++ b/source/blender/blenkernel/intern/shrinkwrap.c
@@ -546,7 +546,7 @@ static void shrinkwrap_calc_normal_projection_cb_ex(void *__restrict userdata,
}
if (calc->vert != NULL && calc->smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL) {
- /* calc->vert contains verts from evaluated mesh. */
+ /* calc->vert contains verts from evaluated mesh. */
/* These coordinates are deformed by vertexCos only for normal projection
* (to get correct normals) for other cases calc->verts contains undeformed coordinates and
* vertexCos should be used */
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index fcc1afbc59b..9d871777c61 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -109,11 +109,11 @@ typedef struct ReferenceVert {
} ReferenceVert;
typedef struct ReferenceState {
- float com[3]; /* center of mass*/
- ReferenceVert *ivert; /* list of initial values */
+ float com[3]; /* Center of mass. */
+ ReferenceVert *ivert; /* List of initial values. */
} ReferenceState;
-/*private scratch pad for caching and other data only needed when alive*/
+/* Private scratch pad for caching and other data only needed when alive. */
typedef struct SBScratch {
GHash *colliderhash;
short needstobuildcollider;
@@ -150,11 +150,11 @@ typedef struct SB_thread_context {
#define BSF_INTERSECT 1 /* edge intersects collider face */
/* private definitions for bodypoint states */
-#define SBF_DOFUZZY 1 /* Bodypoint do fuzzy */
-#define SBF_OUTOFCOLLISION 2 /* Bodypoint does not collide */
+#define SBF_DOFUZZY 1 /* Bodypoint do fuzzy. */
+#define SBF_OUTOFCOLLISION 2 /* Bodypoint does not collide. */
-#define BFF_INTERSECT 1 /* collider edge intrudes face */
-#define BFF_CLOSEVERT 2 /* collider vertex repulses face */
+#define BFF_INTERSECT 1 /* collider edge intrudes face. */
+#define BFF_CLOSEVERT 2 /* collider vertex repulses face. */
/* humm .. this should be calculated from sb parameters and sizes. */
static float SoftHeunTol = 1.0f;
@@ -162,9 +162,9 @@ static float SoftHeunTol = 1.0f;
/* local prototypes */
static void free_softbody_intern(SoftBody *sb);
-/*+++ frame based timing +++*/
+/*+++ frame based timing +++ */
-/*physical unit of force is [kg * m / sec^2]*/
+/* Physical unit of force is `kg * m / sec^2`. */
/**
* Since unit of g is [m/sec^2] and F = mass * g we re-scale unit mass of node to 1 gram
@@ -207,7 +207,7 @@ static float sb_time_scale(Object *ob)
}
/*--- frame based timing ---*/
-/* helper functions for everything is animatable jow_go_for2_5 +++++++*/
+/* helper functions for everything is animatable jow_go_for2_5 +++++++ */
/* introducing them here, because i know: steps in properties ( at frame timing )
* will cause unwanted responses of the softbody system (which does inter frame calculations )
* so first 'cure' would be: interpolate linear in time ..
@@ -217,7 +217,7 @@ static float sb_time_scale(Object *ob)
*/
/* animate sb->maxgoal, sb->mingoal */
-static float _final_goal(Object *ob, BodyPoint *bp) /*jow_go_for2_5 */
+static float _final_goal(Object *ob, BodyPoint *bp) /* jow_go_for2_5 */
{
float f = -1999.99f;
if (ob) {
@@ -235,7 +235,7 @@ static float _final_goal(Object *ob, BodyPoint *bp) /*jow_go_for2_5 */
}
}
CLOG_ERROR(&LOG, "sb or bp == NULL");
- return f; /*using crude but spot able values some times helps debuggin */
+ return f; /* Using crude but spot able values some times helps debugging. */
}
static float _final_mass(Object *ob, BodyPoint *bp)
@@ -251,7 +251,7 @@ static float _final_mass(Object *ob, BodyPoint *bp)
}
/* helper functions for everything is animateble jow_go_for2_5 ------*/
-/*+++ collider caching and dicing +++*/
+/* +++ collider caching and dicing +++ */
/*
* for each target object/face the axis aligned bounding box (AABB) is stored
@@ -311,7 +311,7 @@ static ccd_Mesh *ccd_mesh_make(Object *ob)
/* blow it up with forcefield ranges */
hull = max_ff(ob->pd->pdef_sbift, ob->pd->pdef_sboft);
- /* alloc and copy verts*/
+ /* Allocate and copy verts. */
pccd_M->mvert = MEM_dupallocN(cmd->xnew);
/* note that xnew coords are already in global space, */
/* determine the ortho BB */
@@ -328,7 +328,7 @@ static ccd_Mesh *ccd_mesh_make(Object *ob)
pccd_M->bbmax[1] = max_ff(pccd_M->bbmax[1], v[1] + hull);
pccd_M->bbmax[2] = max_ff(pccd_M->bbmax[2], v[2] + hull);
}
- /* alloc and copy faces*/
+ /* Allocate and copy faces. */
pccd_M->tri = MEM_dupallocN(cmd->tri);
/* OBBs for idea1 */
@@ -401,7 +401,7 @@ static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M)
MEM_freeN((void *)pccd_M->mprevvert);
}
pccd_M->mprevvert = pccd_M->mvert;
- /* alloc and copy verts*/
+ /* Allocate and copy verts. */
pccd_M->mvert = MEM_dupallocN(cmd->xnew);
/* note that xnew coords are already in global space, */
/* determine the ortho BB */
@@ -598,7 +598,7 @@ static int count_mesh_quads(Mesh *me)
static void add_mesh_quad_diag_springs(Object *ob)
{
Mesh *me = ob->data;
- /*BodyPoint *bp;*/ /*UNUSED*/
+ // BodyPoint *bp; /* UNUSED */
int a;
if (ob->soft) {
@@ -618,7 +618,7 @@ static void add_mesh_quad_diag_springs(Object *ob)
/* fill the tail */
a = 0;
bs = &ob->soft->bspring[ob->soft->totspring];
- /*bp= ob->soft->bpoint; */ /*UNUSED*/
+ // bp = ob->soft->bpoint; /* UNUSED */
for (a = me->totpoly; a > 0; a--, mp++) {
if (mp->totloop == 4) {
bs->v1 = mloop[mp->loopstart + 0].v;
@@ -640,7 +640,7 @@ static void add_mesh_quad_diag_springs(Object *ob)
static void add_2nd_order_roller(Object *ob, float UNUSED(stiffness), int *counter, int addsprings)
{
- /*assume we have a softbody*/
+ /* Assume we have a softbody. */
SoftBody *sb = ob->soft; /* is supposed to be there */
BodyPoint *bp, *bpo;
BodySpring *bs, *bs2, *bs3 = NULL;
@@ -654,7 +654,7 @@ static void add_2nd_order_roller(Object *ob, float UNUSED(stiffness), int *count
bs3 = ob->soft->bspring + ob->soft->totspring;
}
for (a = sb->totpoint, bp = sb->bpoint; a > 0; a--, bp++) {
- /*scan for neighborhood*/
+ /* Scan for neighborhood. */
bpo = NULL;
v0 = (sb->totpoint - a);
for (b = bp->nofsprings; b > 0; b--) {
@@ -678,7 +678,7 @@ static void add_2nd_order_roller(Object *ob, float UNUSED(stiffness), int *count
for (c = bpo->nofsprings; c > 0; c--) {
bs2 = sb->bspring + bpo->springs[c - 1];
if ((bs2->v1 != notthis) && (bs2->v1 > v0)) {
- (*counter)++; /*hit */
+ (*counter)++; /* hit */
if (addsprings) {
bs3->v1 = v0;
bs3->v2 = bs2->v1;
@@ -698,7 +698,7 @@ static void add_2nd_order_roller(Object *ob, float UNUSED(stiffness), int *count
}
}
}
- /*scan for neighborhood done*/
+ /* Scan for neighborhood done. */
}
}
@@ -772,8 +772,8 @@ static void build_bps_springlist(Object *ob)
if (((sb->totpoint - a) == bs->v2)) {
add_bp_springlist(bp, sb->totspring - b);
}
- } /*for springs*/
- } /*for bp*/
+ } /* For springs. */
+ } /* For bp. */
}
static void calculate_collision_balls(Object *ob)
@@ -825,7 +825,7 @@ static void calculate_collision_balls(Object *ob)
else {
bp->colball = 0;
}
- } /*for bp*/
+ } /* For bp. */
}
/* creates new softbody if didn't exist yet, makes new points and springs arrays */
@@ -905,7 +905,7 @@ static void free_scratch(SoftBody *sb)
if (sb->scratch->colliderhash) {
BLI_ghash_free(sb->scratch->colliderhash,
NULL,
- (GHashValFreeFP)ccd_mesh_free); /*this hoepfully will free all caches*/
+ (GHashValFreeFP)ccd_mesh_free); /* This hopefully will free all caches. */
sb->scratch->colliderhash = NULL;
}
if (sb->scratch->bodyface) {
@@ -976,7 +976,7 @@ static void free_softbody_intern(SoftBody *sb)
* since that would only valid for 'slow' moving collision targets and dito particles
*/
-/* +++ dependency information functions*/
+/* +++ dependency information functions. */
/**
* \note collection overrides scene when not NULL.
@@ -990,9 +990,9 @@ static int query_external_colliders(Depsgraph *depsgraph, Collection *collection
return (numobjects != 0);
}
-/* --- dependency information functions*/
+/* --- dependency information functions. */
-/* +++ the aabb "force" section*/
+/* +++ the aabb "force" section. */
static int sb_detect_aabb_collisionCached(float UNUSED(force[3]),
struct Object *vertexowner,
float UNUSED(time))
@@ -1036,7 +1036,7 @@ static int sb_detect_aabb_collisionCached(float UNUSED(force[3]),
deflected = 2;
}
else {
- /*aye that should be cached*/
+ /* Aye that should be cached. */
CLOG_ERROR(&LOG, "missing cache error");
BLI_ghashIterator_step(ihash);
continue;
@@ -1048,9 +1048,9 @@ static int sb_detect_aabb_collisionCached(float UNUSED(force[3]),
BLI_ghashIterator_free(ihash);
return deflected;
}
-/* --- the aabb section*/
+/* --- the aabb section. */
-/* +++ the face external section*/
+/* +++ the face external section. */
static int sb_detect_face_pointCached(const float face_v1[3],
const float face_v2[3],
const float face_v3[3],
@@ -1104,13 +1104,13 @@ static int sb_detect_face_pointCached(const float face_v1[3],
}
}
else {
- /*aye that should be cached*/
+ /* Aye that should be cached. */
CLOG_ERROR(&LOG, "missing cache error");
BLI_ghashIterator_step(ihash);
continue;
}
- /* use mesh*/
+ /* Use mesh. */
if (mvert) {
while (a) {
copy_v3_v3(nv1, mvert[a - 1].co);
@@ -1118,7 +1118,7 @@ static int sb_detect_face_pointCached(const float face_v1[3],
mul_v3_fl(nv1, time);
madd_v3_v3fl(nv1, mprevvert[a - 1].co, 1.0f - time);
}
- /* origin to face_v2*/
+ /* Origin to face_v2. */
sub_v3_v3(nv1, face_v2);
facedist = dot_v3v3(nv1, d_nvect);
if (fabsf(facedist) < outerfacethickness) {
@@ -1139,7 +1139,7 @@ static int sb_detect_face_pointCached(const float face_v1[3],
}
}
a--;
- } /* while (a)*/
+ } /* while (a) */
} /* if (mvert) */
} /* if (ob->pd && ob->pd->deflect) */
BLI_ghashIterator_step(ihash);
@@ -1201,13 +1201,13 @@ static int sb_detect_face_collisionCached(const float face_v1[3],
}
}
else {
- /*aye that should be cached*/
+ /* Aye that should be cached. */
CLOG_ERROR(&LOG, "missing cache error");
BLI_ghashIterator_step(ihash);
continue;
}
- /* use mesh*/
+ /* Use mesh. */
while (a--) {
if ((aabbmax[0] < mima->minx) || (aabbmin[0] > mima->maxx) ||
(aabbmax[1] < mima->miny) || (aabbmin[1] > mima->maxy) ||
@@ -1235,7 +1235,7 @@ static int sb_detect_face_collisionCached(const float face_v1[3],
}
}
- /* switch origin to be nv2*/
+ /* Switch origin to be nv2. */
sub_v3_v3v3(edge1, nv1, nv2);
sub_v3_v3v3(edge2, nv3, nv2);
cross_v3_v3v3(d_nvect, edge2, edge1);
@@ -1272,7 +1272,7 @@ static void scan_for_ext_face_forces(Object *ob, float timenow)
bf = sb->scratch->bodyface;
for (a = 0; a < sb->scratch->totface; a++, bf++) {
bf->ext_force[0] = bf->ext_force[1] = bf->ext_force[2] = 0.0f;
- /*+++edges intruding*/
+ /*+++edges intruding. */
bf->flag &= ~BFF_INTERSECT;
zero_v3(feedback);
if (sb_detect_face_collisionCached(sb->bpoint[bf->v1].pos,
@@ -1289,9 +1289,9 @@ static void scan_for_ext_face_forces(Object *ob, float timenow)
bf->flag |= BFF_INTERSECT;
choke = min_ff(max_ff(damp, choke), 1.0f);
}
- /*---edges intruding*/
+ /*---edges intruding. */
- /*+++ close vertices*/
+ /*+++ close vertices. */
if ((bf->flag & BFF_INTERSECT) == 0) {
bf->flag &= ~BFF_CLOSEVERT;
tune = -1.0f;
@@ -1311,7 +1311,7 @@ static void scan_for_ext_face_forces(Object *ob, float timenow)
choke = min_ff(max_ff(damp, choke), 1.0f);
}
}
- /*--- close vertices*/
+ /*--- close vertices. */
}
bf = sb->scratch->bodyface;
for (a = 0; a < sb->scratch->totface; a++, bf++) {
@@ -1324,9 +1324,9 @@ static void scan_for_ext_face_forces(Object *ob, float timenow)
}
}
-/* --- the face external section*/
+/* --- the face external section. */
-/* +++ the spring external section*/
+/* +++ the spring external section. */
static int sb_detect_edge_collisionCached(const float edge_v1[3],
const float edge_v2[3],
@@ -1377,13 +1377,13 @@ static int sb_detect_edge_collisionCached(const float edge_v1[3],
}
}
else {
- /*aye that should be cached*/
+ /* Aye that should be cached. */
CLOG_ERROR(&LOG, "missing cache error");
BLI_ghashIterator_step(ihash);
continue;
}
- /* use mesh*/
+ /* Use mesh. */
while (a--) {
if ((aabbmax[0] < mima->minx) || (aabbmin[0] > mima->maxx) ||
(aabbmax[1] < mima->miny) || (aabbmin[1] > mima->maxy) ||
@@ -1411,7 +1411,7 @@ static int sb_detect_edge_collisionCached(const float edge_v1[3],
}
}
- /* switch origin to be nv2*/
+ /* Switch origin to be nv2. */
sub_v3_v3v3(edge1, nv1, nv2);
sub_v3_v3v3(edge2, nv3, nv2);
@@ -1469,12 +1469,12 @@ static void _scan_for_ext_spring_forces(
}
/* ---- springs colliding */
- /* +++ springs seeing wind ... n stuff depending on their orientation*/
- /* note we don't use sb->mediafrict but use sb->aeroedge for magnitude of effect*/
+ /* +++ springs seeing wind ... n stuff depending on their orientation. */
+ /* NOTE: we don't use `sb->mediafrict` but use `sb->aeroedge` for magnitude of effect. */
if (sb->aeroedge) {
float vel[3], sp[3], pr[3], force[3];
float f, windfactor = 0.25f;
- /*see if we have wind*/
+ /* See if we have wind. */
if (effectors) {
EffectedPoint epoint;
float speed[3] = {0.0f, 0.0f, 0.0f};
@@ -1543,7 +1543,7 @@ static void sb_sfesf_threads_run(struct Depsgraph *depsgraph,
/* figure the number of threads while preventing pretty pointless threading overhead */
totthread = BKE_scene_num_threads(scene);
- /* what if we got zillions of CPUs running but less to spread*/
+ /* What if we got zillions of CPUs running but less to spread. */
while ((totsprings / totthread < lowsprings) && (totthread > 1)) {
totthread--;
}
@@ -1590,7 +1590,7 @@ static void sb_sfesf_threads_run(struct Depsgraph *depsgraph,
BKE_effectors_free(effectors);
}
-/* --- the spring external section*/
+/* --- the spring external section. */
static int choose_winner(
float *w, float *pos, float *a, float *b, float *c, float *ca, float *cb, float *cc)
@@ -1683,7 +1683,7 @@ static int sb_detect_vertex_collisionCached(float opco[3],
}
}
else {
- /*aye that should be cached*/
+ /* Aye that should be cached. */
CLOG_ERROR(&LOG, "missing cache error");
BLI_ghashIterator_step(ihash);
continue;
@@ -1697,7 +1697,7 @@ static int sb_detect_vertex_collisionCached(float opco[3],
fa *= fa;
fa = 1.0f / fa;
avel[0] = avel[1] = avel[2] = 0.0f;
- /* use mesh*/
+ /* Use mesh. */
while (a--) {
if ((opco[0] < mima->minx) || (opco[0] > mima->maxx) || (opco[1] < mima->miny) ||
(opco[1] > mima->maxy) || (opco[2] < mima->minz) || (opco[2] > mima->maxz)) {
@@ -1733,7 +1733,7 @@ static int sb_detect_vertex_collisionCached(float opco[3],
}
}
- /* switch origin to be nv2*/
+ /* Switch origin to be nv2. */
sub_v3_v3v3(edge1, nv1, nv2);
sub_v3_v3v3(edge2, nv3, nv2);
/* Abuse dv1 to have vertex in question at *origin* of triangle. */
@@ -2068,7 +2068,7 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene,
bp->force[1] += -ks * (auxvect[1]);
bp->force[2] += -ks * (auxvect[2]);
- /* calculate damping forces generated by goals*/
+ /* Calculate damping forces generated by goals. */
sub_v3_v3v3(velgoal, bp->origS, bp->origE);
kd = sb->goalfrict * sb_fric_force_scale(ob);
add_v3_v3v3(auxvect, velgoal, bp->vec);
@@ -2113,7 +2113,7 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene,
pd_point_from_soft(scene, bp->pos, bp->vec, sb->bpoint - bp, &epoint);
BKE_effectors_apply(effectors, NULL, sb->effector_weights, &epoint, force, NULL, speed);
- /* apply forcefield*/
+ /* Apply force-field. */
mul_v3_fl(force, fieldfactor * eval_sb_fric_force_scale);
add_v3_v3(bp->force, force);
@@ -2125,7 +2125,7 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene,
/* now we'll have nice centrifugal effect for vortex */
}
else {
- /* BP friction in media (not) moving*/
+ /* BP friction in media (not) moving. */
float kd = sb->mediafrict * sb_fric_force_scale(ob);
/* assume it to be proportional to actual velocity */
bp->force[0] -= bp->vec[0] * kd;
@@ -2160,7 +2160,7 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene,
/* +++springs */
iks = 1.0f / (1.0f - sb->inspring) - 1.0f; /* inner spring constants function */
if (ob->softflag & OB_SB_EDGES) {
- if (sb->bspring) { /* spring list exists at all ? */
+ if (sb->bspring) { /* Spring list exists at all? */
int b;
BodySpring *bs;
for (b = bp->nofsprings; b > 0; b--) {
@@ -2173,13 +2173,13 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene,
}
// sb_spring_force(Object *ob, int bpi, BodySpring *bs, float iks, float forcetime)
sb_spring_force(ob, ilast - bb, bs, iks, forcetime);
- } /* loop springs */
- } /* existing spring list */
- } /*any edges*/
+ } /* loop springs. */
+ } /* existing spring list. */
+ } /* Any edges. */
/* ---springs */
- } /*omit on snap */
- } /*loop all bp's*/
- return 0; /*done fine*/
+ } /* Omit on snap. */
+ } /* Loop all bp's. */
+ return 0; /* Done fine. */
}
static void *exec_softbody_calc_forces(void *data)
@@ -2220,7 +2220,7 @@ static void sb_cf_threads_run(Scene *scene,
/* figure the number of threads while preventing pretty pointless threading overhead */
totthread = BKE_scene_num_threads(scene);
- /* what if we got zillions of CPUs running but less to spread*/
+ /* What if we got zillions of CPUs running but less to spread. */
while ((totpoint / totthread < lowpoints) && (totthread > 1)) {
totthread--;
}
@@ -2275,11 +2275,11 @@ static void softbody_calc_forces(
* this will ruin adaptive stepsize AKA heun! (BM)
*/
SoftBody *sb = ob->soft; /* is supposed to be there */
- /*BodyPoint *bproot;*/ /* UNUSED */
- /* float gravity; */ /* UNUSED */
- /* float iks; */
+ // BodyPoint *bproot; /* UNUSED */
+ // float gravity; /* UNUSED */
+ // float iks;
float fieldfactor = -1.0f, windfactor = 0.25;
- int do_deflector /*, do_selfcollision*/, do_springcollision, do_aero;
+ int do_deflector /*, do_selfcollision */, do_springcollision, do_aero;
/* gravity = sb->grav * sb_grav_force_scale(ob); */ /* UNUSED */
@@ -2292,8 +2292,8 @@ static void softbody_calc_forces(
(ob->softflag & OB_SB_EDGECOLL);
do_aero = ((sb->aeroedge) && (ob->softflag & OB_SB_EDGES));
- /* iks = 1.0f/(1.0f-sb->inspring)-1.0f; */ /* inner spring constants function */ /* UNUSED */
- /* bproot= sb->bpoint; */ /* need this for proper spring addressing */ /* UNUSED */
+ // iks = 1.0f / (1.0f - sb->inspring) - 1.0f; /* Inner spring constants function. */ /* UNUSED */
+ // bproot = sb->bpoint; /* Need this for proper spring addressing. */ /* UNUSED */
if (do_springcollision || do_aero) {
sb_sfesf_threads_run(depsgraph, scene, ob, timenow, sb->totspring, NULL);
@@ -2344,7 +2344,7 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *
aabbmin[0] = aabbmin[1] = aabbmin[2] = 1e20f;
aabbmax[0] = aabbmax[1] = aabbmax[2] = -1e20f;
- /* old one with homogeneous masses */
+ /* old one with homogeneous masses */
/* claim a minimum mass for vertex */
#if 0
if (sb->nodemass > 0.009999f) {
@@ -2489,7 +2489,7 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *
/* used by heun when it overshoots */
static void softbody_restore_prev_step(Object *ob)
{
- SoftBody *sb = ob->soft; /* is supposed to be there*/
+ SoftBody *sb = ob->soft; /* is supposed to be there. */
BodyPoint *bp;
int a;
@@ -2502,7 +2502,7 @@ static void softbody_restore_prev_step(Object *ob)
#if 0
static void softbody_store_step(Object *ob)
{
- SoftBody *sb = ob->soft; /* is supposed to be there*/
+ SoftBody *sb = ob->soft; /* is supposed to be there. */
BodyPoint *bp;
int a;
@@ -2515,7 +2515,7 @@ static void softbody_store_step(Object *ob)
/* used by predictors and correctors */
static void softbody_store_state(Object *ob, float *ppos, float *pvel)
{
- SoftBody *sb = ob->soft; /* is supposed to be there*/
+ SoftBody *sb = ob->soft; /* is supposed to be there. */
BodyPoint *bp;
int a;
float *pp = ppos, *pv = pvel;
@@ -2533,7 +2533,7 @@ static void softbody_store_state(Object *ob, float *ppos, float *pvel)
/* used by predictors and correctors */
static void softbody_retrieve_state(Object *ob, float *ppos, float *pvel)
{
- SoftBody *sb = ob->soft; /* is supposed to be there*/
+ SoftBody *sb = ob->soft; /* is supposed to be there. */
BodyPoint *bp;
int a;
float *pp = ppos, *pv = pvel;
@@ -2551,7 +2551,7 @@ static void softbody_retrieve_state(Object *ob, float *ppos, float *pvel)
/* used by predictors and correctors */
static void softbody_swap_state(Object *ob, float *ppos, float *pvel)
{
- SoftBody *sb = ob->soft; /* is supposed to be there*/
+ SoftBody *sb = ob->soft; /* is supposed to be there. */
BodyPoint *bp;
int a;
float *pp = ppos, *pv = pvel;
@@ -2773,7 +2773,7 @@ static void mesh_faces_to_scratch(Object *ob)
MLoopTri *looptri, *lt;
BodyFace *bodyface;
int a;
- /* alloc and copy faces*/
+ /* Allocate and copy faces. */
sb->scratch->totface = poly_to_tri_count(me->totpoly, me->totloop);
looptri = lt = MEM_mallocN(sizeof(*looptri) * sb->scratch->totface, __func__);
@@ -3000,8 +3000,8 @@ static void curve_surf_to_softbody(Object *ob)
bp = sb->bpoint;
bs = sb->bspring;
- /* weights from bpoints, same code used as for mesh vertices */
- /* if ((ob->softflag & OB_SB_GOAL) && sb->vertgroup) 2.4x hack*/
+ /* Weights from bpoints, same code used as for mesh vertices. */
+ /* if ((ob->softflag & OB_SB_GOAL) && sb->vertgroup) 2.4x hack. */
/* new! take the weights from curve vertex anyhow */
if (ob->softflag & OB_SB_GOAL) {
setgoal = 1;
@@ -3022,10 +3022,10 @@ static void curve_surf_to_softbody(Object *ob)
if (setgoal) {
bp->goal *= bezt->weight;
- /* all three triples */
+ /* All three triples. */
(bp + 1)->goal = bp->goal;
(bp + 2)->goal = bp->goal;
- /*do not collide handles */
+ /* Do not collide handles. */
(bp + 1)->loc_flag |= SBF_OUTOFCOLLISION;
(bp + 2)->loc_flag |= SBF_OUTOFCOLLISION;
}
@@ -3137,7 +3137,7 @@ SoftBody *sbNew(void)
sb->inspring = 0.5f;
sb->infrict = 0.5f;
- /*todo backward file compat should copy inspring to inpush while reading old files*/
+ /* TODO: backward file compat should copy `inspring` to `inpush` while reading old files. */
sb->inpush = 0.5f;
sb->colball = 0.49f;
@@ -3150,7 +3150,7 @@ SoftBody *sbNew(void)
sb->choke = 3;
sb_new_scratch(sb);
- /*todo backward file compat should set sb->shearstiff = 1.0f while reading old files*/
+ /* TODO: backward file compat should set `sb->shearstiff = 1.0f` while reading old files. */
sb->shearstiff = 1.0f;
sb->solverflags |= SBSO_OLDERR;
@@ -3205,7 +3205,7 @@ void sbObjectToSoftbody(Object *ob)
free_softbody_intern(ob->soft);
}
-static bool object_has_edges(Object *ob)
+static bool object_has_edges(const Object *ob)
{
if (ob->type == OB_MESH) {
return ((Mesh *)ob->data)->totedge;
@@ -3311,7 +3311,7 @@ static void softbody_reset(Object *ob, SoftBody *sb, float (*vertexCos)[3], int
for (a = 0, bp = sb->bpoint; a < numVerts; a++, bp++) {
copy_v3_v3(bp->pos, vertexCos[a]);
- mul_m4_v3(ob->obmat, bp->pos); /* yep, sofbody is global coords*/
+ mul_m4_v3(ob->obmat, bp->pos); /* Yep, soft-body is global coords. */
copy_v3_v3(bp->origS, bp->pos);
copy_v3_v3(bp->origE, bp->pos);
copy_v3_v3(bp->origT, bp->pos);
@@ -3493,18 +3493,18 @@ static void softbody_step(
else if (sb->solver_ID == 2) {
/* do semi "fake" implicit euler */
/* removed */
- } /*SOLVER SELECT*/
+ } /* SOLVER SELECT */
else if (sb->solver_ID == 4) {
/* do semi "fake" implicit euler */
- } /*SOLVER SELECT*/
+ } /* SOLVER SELECT */
else if (sb->solver_ID == 3) {
/* do "stupid" semi "fake" implicit euler */
/* removed */
- } /*SOLVER SELECT*/
+ } /* SOLVER SELECT */
else {
CLOG_ERROR(&LOG, "softbody no valid solver ID!");
- } /*SOLVER SELECT*/
+ } /* SOLVER SELECT */
if (sb->plastic) {
apply_spring_memory(ob);
}
diff --git a/source/blender/blenkernel/intern/spline_nurbs.cc b/source/blender/blenkernel/intern/spline_nurbs.cc
index 85fb9730e83..76d046337c0 100644
--- a/source/blender/blenkernel/intern/spline_nurbs.cc
+++ b/source/blender/blenkernel/intern/spline_nurbs.cc
@@ -45,7 +45,7 @@ void NURBSpline::copy_data(Spline &dst) const
nurbs.positions_ = positions_;
nurbs.weights_ = weights_;
nurbs.knots_ = knots_;
- nurbs.knots_dirty_ = false;
+ nurbs.knots_dirty_ = knots_dirty_;
nurbs.radii_ = radii_;
nurbs.tilts_ = tilts_;
}
diff --git a/source/blender/blenkernel/intern/subdiv_ccg.c b/source/blender/blenkernel/intern/subdiv_ccg.c
index 4ca6f93b014..8b672b2cb49 100644
--- a/source/blender/blenkernel/intern/subdiv_ccg.c
+++ b/source/blender/blenkernel/intern/subdiv_ccg.c
@@ -63,7 +63,7 @@ void subdiv_ccg_average_faces_boundaries_and_corners(SubdivCCG *subdiv_ccg,
/** \name Generally useful internal helpers
* \{ */
-/* Number of floats in per-vertex elements. */
+/* Number of floats in per-vertex elements. */
static int num_element_float_get(const SubdivCCG *subdiv_ccg)
{
/* We always have 3 floats for coordinate. */
@@ -1116,7 +1116,7 @@ typedef struct AverageGridsCornerData {
SubdivCCG *subdiv_ccg;
CCGKey *key;
- /* Optional lookup table. Maps task range index to index in subdiv_ccg->adjacent_vertices*/
+ /* Optional lookup table. Maps task range index to index in `subdiv_ccg->adjacent_vertices`. */
const int *adjacent_vert_index_map;
} AverageGridsCornerData;
@@ -1489,7 +1489,7 @@ BLI_INLINE SubdivCCGCoord coord_at_next_col(const SubdivCCG *subdiv_ccg,
return result;
}
-/* For the input coordinate which is at the boundary of the grid do one step inside. */
+/* For the input coordinate which is at the boundary of the grid do one step inside. */
static SubdivCCGCoord coord_step_inside_from_boundary(const SubdivCCG *subdiv_ccg,
const SubdivCCGCoord *coord)
diff --git a/source/blender/blenkernel/intern/subdiv_eval.c b/source/blender/blenkernel/intern/subdiv_eval.c
index 201d308e096..693827f99ac 100644
--- a/source/blender/blenkernel/intern/subdiv_eval.c
+++ b/source/blender/blenkernel/intern/subdiv_eval.c
@@ -282,7 +282,7 @@ static void buffer_apply_offset(void **buffer, const int offset)
*buffer = ((unsigned char *)*buffer) + offset;
}
-/* Write given number of floats to the beginning of given buffer. */
+/* Write given number of floats to the beginning of given buffer. */
static void buffer_write_float_value(void **buffer, const float *values_buffer, int num_values)
{
memcpy(*buffer, values_buffer, sizeof(float) * num_values);
diff --git a/source/blender/blenkernel/intern/subdiv_foreach.c b/source/blender/blenkernel/intern/subdiv_foreach.c
index 4400e9c976f..061c196df2a 100644
--- a/source/blender/blenkernel/intern/subdiv_foreach.c
+++ b/source/blender/blenkernel/intern/subdiv_foreach.c
@@ -1749,7 +1749,7 @@ static void subdiv_foreach_vertices_of_loose_edges_task(void *__restrict userdat
/* Subdivision vertices which corresponds to edge's v1 and v2. */
const int subdiv_v1_index = ctx->vertices_corner_offset + coarse_edge->v1;
const int subdiv_v2_index = ctx->vertices_corner_offset + coarse_edge->v2;
- /* First subdivided inner vertex of the edge. */
+ /* First subdivided inner vertex of the edge. */
const int subdiv_start_vertex = ctx->vertices_edge_offset +
coarse_edge_index * num_subdiv_vertices_per_coarse_edge;
/* Perform interpolation. */
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 23eccbfba9b..0dbfeaaaadb 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -580,16 +580,16 @@ static void ss_sync_ccg_from_derivedmesh(CCGSubSurf *ss,
#endif
MVert *mvert = dm->getVertArray(dm);
MEdge *medge = dm->getEdgeArray(dm);
- /* MFace *mface = dm->getTessFaceArray(dm); */ /* UNUSED */
+ // MFace *mface = dm->getTessFaceArray(dm); /* UNUSED */
MVert *mv;
MEdge *me;
MLoop *mloop = dm->getLoopArray(dm), *ml;
MPoly *mpoly = dm->getPolyArray(dm), *mp;
- /*MFace *mf;*/ /*UNUSED*/
+ // MFace *mf; /* UNUSED */
int totvert = dm->getNumVerts(dm);
int totedge = dm->getNumEdges(dm);
- /*int totface = dm->getNumTessFaces(dm);*/ /*UNUSED*/
- /*int totpoly = dm->getNumFaces(dm);*/ /*UNUSED*/
+ // int totface = dm->getNumTessFaces(dm); /* UNUSED */
+ // int totpoly = dm->getNumFaces(dm); /* UNUSED */
int i, j;
int *index;
@@ -641,10 +641,10 @@ static void ss_sync_ccg_from_derivedmesh(CCGSubSurf *ss,
fVerts[j] = POINTER_FROM_UINT(ml->v);
}
- /* this is very bad, means mesh is internally inconsistent.
+ /* This is very bad, means mesh is internally inconsistent.
* it is not really possible to continue without modifying
* other parts of code significantly to handle missing faces.
- * since this really shouldn't even be possible we just bail.*/
+ * since this really shouldn't even be possible we just bail. */
if (ccgSubSurf_syncFace(ss, POINTER_FROM_INT(i), mp->totloop, fVerts, &f) ==
eCCGError_InvalidValue) {
static int hasGivenError = 0;
@@ -1008,11 +1008,11 @@ static void ccgDM_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf)
int gridFaces = gridSideEdges * gridSideEdges;
int i;
CCGFace *f;
- /*int numVerts;*/
+ // int numVerts;
int offset;
int grid;
int x, y;
- /*int lastface = ccgSubSurf_getNumFaces(ss) - 1;*/ /*UNUSED*/
+ // int lastface = ccgSubSurf_getNumFaces(ss) - 1; /* UNUSED */
DMFlagMat *faceFlags = ccgdm->faceFlags;
memset(mf, 0, sizeof(*mf));
@@ -1023,7 +1023,7 @@ static void ccgDM_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf)
i = ccgdm->reverseFaceMap[faceNum];
f = ccgdm->faceMap[i].face;
- /*numVerts = ccgSubSurf_getFaceNumVerts(f);*/ /*UNUSED*/
+ // numVerts = ccgSubSurf_getFaceNumVerts(f); /* UNUSED */
offset = faceNum - ccgdm->faceMap[i].startFace;
grid = offset / gridFaces;
@@ -1781,7 +1781,7 @@ static void ccgdm_create_grids(DerivedMesh *dm)
numGrids = ccgDM_getNumGrids(dm);
numFaces = ccgSubSurf_getNumFaces(ss);
- /*gridSize = ccgDM_getGridSize(dm);*/ /*UNUSED*/
+ // gridSize = ccgDM_getGridSize(dm); /* UNUSED */
/* compute offset into grid array for each face */
gridOffset = MEM_mallocN(sizeof(int) * numFaces, "ccgdm.gridOffset");
@@ -2089,7 +2089,7 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm,
vertidx[s] = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(v));
}
- /*I think this is for interpolating the center vert?*/
+ /* I think this is for interpolating the center vert? */
w2 = w; // + numVerts*(g2_wid-1) * (g2_wid-1); //numVerts*((g2_wid-1) * g2_wid+g2_wid-1);
DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2, numVerts, vertNum);
if (vertOrigIndex) {
@@ -2099,7 +2099,7 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm,
vertNum++;
- /*interpolate per-vert data*/
+ /* Interpolate per-vert data. */
for (s = 0; s < numVerts; s++) {
for (x = 1; x < gridFaces; x++) {
w2 = w + s * numVerts * g2_wid * g2_wid + x * numVerts;
@@ -2114,7 +2114,7 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm,
}
}
- /*interpolate per-vert data*/
+ /* Interpolate per-vert data. */
for (s = 0; s < numVerts; s++) {
for (y = 1; y < gridFaces; y++) {
for (x = 1; x < gridFaces; x++) {
@@ -2138,7 +2138,7 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm,
}
for (s = 0; s < numVerts; s++) {
- /*interpolate per-face data*/
+ /* Interpolate per-face data. */
for (y = 0; y < gridFaces; y++) {
for (x = 0; x < gridFaces; x++) {
w2 = w + s * numVerts * g2_wid * g2_wid + (y * g2_wid + x) * numVerts;
@@ -2161,10 +2161,10 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm,
&dm->loopData, &ccgdm->dm.loopData, loopidx, w2, NULL, numVerts, loopindex2);
loopindex2++;
- /*copy over poly data, e.g. mtexpoly*/
+ /* Copy over poly data, e.g. mtexpoly. */
CustomData_copy_data(&dm->polyData, &ccgdm->dm.polyData, origIndex, faceNum, 1);
- /*set original index data*/
+ /* Set original index data. */
if (faceOrigIndex) {
/* reference the index in 'polyOrigIndex' */
*faceOrigIndex = faceNum;
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 27f5593c2ca..74845e3f1b9 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -781,12 +781,12 @@ static void txt_curs_sel(Text *text, TextLine ***linep, int **charp)
*charp = &text->selc;
}
-bool txt_cursor_is_line_start(Text *text)
+bool txt_cursor_is_line_start(const Text *text)
{
return (text->selc == 0);
}
-bool txt_cursor_is_line_end(Text *text)
+bool txt_cursor_is_line_end(const Text *text)
{
return (text->selc == text->sell->len);
}
@@ -1239,7 +1239,7 @@ void txt_order_cursors(Text *text, const bool reverse)
}
}
-bool txt_has_sel(Text *text)
+bool txt_has_sel(const Text *text)
{
return ((text->curl != text->sell) || (text->curc != text->selc));
}
diff --git a/source/blender/blenkernel/intern/tracking_stabilize.c b/source/blender/blenkernel/intern/tracking_stabilize.c
index 46589a578a8..3dff750edfb 100644
--- a/source/blender/blenkernel/intern/tracking_stabilize.c
+++ b/source/blender/blenkernel/intern/tracking_stabilize.c
@@ -1381,7 +1381,7 @@ ImBuf *BKE_tracking_stabilize_frame(
return ibuf;
}
- /* Allocate frame for stabilization result, copy alpha mode and colorspace. */
+ /* Allocate frame for stabilization result, copy alpha mode and colorspace. */
ibuf_flags = 0;
if (ibuf->rect) {
ibuf_flags |= IB_rect;
diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c
index 377802f1af7..14dd286a315 100644
--- a/source/blender/blenkernel/intern/undo_system.c
+++ b/source/blender/blenkernel/intern/undo_system.c
@@ -368,10 +368,10 @@ void BKE_undosys_stack_init_from_context(UndoStack *ustack, bContext *C)
}
/* name optional */
-bool BKE_undosys_stack_has_undo(UndoStack *ustack, const char *name)
+bool BKE_undosys_stack_has_undo(const UndoStack *ustack, const char *name)
{
if (name) {
- UndoStep *us = BLI_rfindstring(&ustack->steps, name, offsetof(UndoStep, name));
+ const UndoStep *us = BLI_rfindstring(&ustack->steps, name, offsetof(UndoStep, name));
return us && us->prev;
}
diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c
index c2fb5ef4238..290b880934e 100644
--- a/source/blender/blenkernel/intern/unit.c
+++ b/source/blender/blenkernel/intern/unit.c
@@ -744,10 +744,10 @@ static const char *unit_find_str(const char *str, const char *substr, bool case_
*
* "1m1cm+2mm" - Original value.
* "1*1#1*0.01#+2*0.001#" - Replace numbers.
- * "1*1+1*0.01 +2*0.001 " - Add add signs if ( + - * / | & ~ < > ^ ! = % ) not found in between.
+ * "1*1+1*0.01 +2*0.001 " - Add plus signs if ( + - * / | & ~ < > ^ ! = % ) not found in between.
*/
-/* Not too strict, (+ - * /) are most common. */
+/* Not too strict, (+ - * /) are most common. */
static bool ch_is_op(char op)
{
switch (op) {
@@ -917,7 +917,7 @@ static int unit_scale_str(char *str,
return 0;
}
- /* XXX - investigate, does not respect len_max properly. */
+ /* XXX - investigate, does not respect len_max properly. */
char *str_found = (char *)unit_find_str(str, replace_str, case_sensitive);
if (str_found == NULL) {
diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc
index 5fc55aad6a2..272ecc71833 100644
--- a/source/blender/blenkernel/intern/volume.cc
+++ b/source/blender/blenkernel/intern/volume.cc
@@ -1224,7 +1224,7 @@ const VolumeGrid *BKE_volume_grid_active_get_for_read(const Volume *volume)
return BKE_volume_grid_get_for_read(volume, index);
}
-/* Tries to find a grid with the given name. Make sure that that the volume has been loaded. */
+/* Tries to find a grid with the given name. Make sure that the volume has been loaded. */
const VolumeGrid *BKE_volume_grid_find_for_read(const Volume *volume, const char *name)
{
int num_grids = BKE_volume_num_grids(volume);
diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c
index be67b2370e3..533107b2bf6 100644
--- a/source/blender/blenkernel/intern/workspace.c
+++ b/source/blender/blenkernel/intern/workspace.c
@@ -105,8 +105,8 @@ static void workspace_blend_read_data(BlendDataReader *reader, ID *id)
BLO_read_list(reader, &workspace->tools);
LISTBASE_FOREACH (WorkSpaceDataRelation *, relation, &workspace->hook_layout_relations) {
- /* parent pointer does not belong to workspace data and is therefore restored in lib_link step
- * of window manager.*/
+ /* Parent pointer does not belong to workspace data and is therefore restored in lib_link step
+ * of window manager. */
BLO_read_data_address(reader, &relation->value);
}
diff --git a/source/blender/blenkernel/nla_private.h b/source/blender/blenkernel/nla_private.h
index 71b5a74ddf7..3e13ba602a4 100644
--- a/source/blender/blenkernel/nla_private.h
+++ b/source/blender/blenkernel/nla_private.h
@@ -39,13 +39,13 @@ struct AnimationEvalContext;
typedef struct NlaEvalStrip {
struct NlaEvalStrip *next, *prev;
- NlaTrack *track; /* track that this strip belongs to */
- NlaStrip *strip; /* strip that's being used */
+ NlaTrack *track; /* Track that this strip belongs to. */
+ NlaStrip *strip; /* Strip that's being used. */
- short track_index; /* the index of the track within the list */
- short strip_mode; /* which end of the strip are we looking at */
+ short track_index; /* The index of the track within the list. */
+ short strip_mode; /* Which end of the strip are we looking at. */
- float strip_time; /* time at which which strip is being evaluated */
+ float strip_time; /* Time at which this strip is being evaluated. */
} NlaEvalStrip;
/* NlaEvalStrip->strip_mode */