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/intern')
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.cc2
-rw-r--r--source/blender/blenkernel/intern/armature_update.c2
-rw-r--r--source/blender/blenkernel/intern/asset_catalog.cc2
-rw-r--r--source/blender/blenkernel/intern/attribute.cc8
-rw-r--r--source/blender/blenkernel/intern/attribute_access.cc2
-rw-r--r--source/blender/blenkernel/intern/attribute_math.cc69
-rw-r--r--source/blender/blenkernel/intern/boids.c2
-rw-r--r--source/blender/blenkernel/intern/brush.cc6
-rw-r--r--source/blender/blenkernel/intern/bvhutils.cc19
-rw-r--r--source/blender/blenkernel/intern/cachefile.c6
-rw-r--r--source/blender/blenkernel/intern/colorband.c2
-rw-r--r--source/blender/blenkernel/intern/constraint.c2
-rw-r--r--source/blender/blenkernel/intern/crazyspace.cc6
-rw-r--r--source/blender/blenkernel/intern/curve.cc2
-rw-r--r--source/blender/blenkernel/intern/curve_nurbs.cc40
-rw-r--r--source/blender/blenkernel/intern/curves.cc2
-rw-r--r--source/blender/blenkernel/intern/curves_geometry.cc65
-rw-r--r--source/blender/blenkernel/intern/customdata.cc469
-rw-r--r--source/blender/blenkernel/intern/data_transfer.c2
-rw-r--r--source/blender/blenkernel/intern/displist.cc162
-rw-r--r--source/blender/blenkernel/intern/gpencil_curve.c11
-rw-r--r--source/blender/blenkernel/intern/gpencil_modifier.c3
-rw-r--r--source/blender/blenkernel/intern/icons_rasterize.c2
-rw-r--r--source/blender/blenkernel/intern/idprop.c2
-rw-r--r--source/blender/blenkernel/intern/idprop_create.cc8
-rw-r--r--source/blender/blenkernel/intern/image.cc305
-rw-r--r--source/blender/blenkernel/intern/image_gpu.cc14
-rw-r--r--source/blender/blenkernel/intern/image_save.cc7
-rw-r--r--source/blender/blenkernel/intern/lattice.c15
-rw-r--r--source/blender/blenkernel/intern/layer.c2
-rw-r--r--source/blender/blenkernel/intern/layer_utils.c59
-rw-r--r--source/blender/blenkernel/intern/lib_id.c53
-rw-r--r--source/blender/blenkernel/intern/lib_query.c4
-rw-r--r--source/blender/blenkernel/intern/library.c2
-rw-r--r--source/blender/blenkernel/intern/material.c2
-rw-r--r--source/blender/blenkernel/intern/mball.cc (renamed from source/blender/blenkernel/intern/mball.c)285
-rw-r--r--source/blender/blenkernel/intern/mball_tessellate.c87
-rw-r--r--source/blender/blenkernel/intern/mesh.cc34
-rw-r--r--source/blender/blenkernel/intern/mesh_convert.cc230
-rw-r--r--source/blender/blenkernel/intern/mesh_debug.cc3
-rw-r--r--source/blender/blenkernel/intern/mesh_evaluate.cc149
-rw-r--r--source/blender/blenkernel/intern/mesh_legacy_convert.cc90
-rw-r--r--source/blender/blenkernel/intern/mesh_mapping.c5
-rw-r--r--source/blender/blenkernel/intern/mesh_remap.c5
-rw-r--r--source/blender/blenkernel/intern/mesh_remesh_voxel.cc36
-rw-r--r--source/blender/blenkernel/intern/mesh_sample.cc94
-rw-r--r--source/blender/blenkernel/intern/mesh_tangent.c2
-rw-r--r--source/blender/blenkernel/intern/mesh_validate.cc4
-rw-r--r--source/blender/blenkernel/intern/mesh_wrapper.cc6
-rw-r--r--source/blender/blenkernel/intern/modifier.c3
-rw-r--r--source/blender/blenkernel/intern/node.cc6
-rw-r--r--source/blender/blenkernel/intern/object_dupli.cc38
-rw-r--r--source/blender/blenkernel/intern/object_update.c55
-rw-r--r--source/blender/blenkernel/intern/ocean.c7
-rw-r--r--source/blender/blenkernel/intern/outliner_treehash.c256
-rw-r--r--source/blender/blenkernel/intern/outliner_treehash.cc209
-rw-r--r--source/blender/blenkernel/intern/paint.cc (renamed from source/blender/blenkernel/intern/paint.c)458
-rw-r--r--source/blender/blenkernel/intern/particle.c8
-rw-r--r--source/blender/blenkernel/intern/particle_child.c9
-rw-r--r--source/blender/blenkernel/intern/particle_system.c4
-rw-r--r--source/blender/blenkernel/intern/pbvh.c211
-rw-r--r--source/blender/blenkernel/intern/pbvh.cc26
-rw-r--r--source/blender/blenkernel/intern/pbvh_bmesh.c68
-rw-r--r--source/blender/blenkernel/intern/pbvh_intern.h13
-rw-r--r--source/blender/blenkernel/intern/pointcache.c90
-rw-r--r--source/blender/blenkernel/intern/scene.cc6
-rw-r--r--source/blender/blenkernel/intern/screen.c36
-rw-r--r--source/blender/blenkernel/intern/shader_fx.c3
-rw-r--r--source/blender/blenkernel/intern/sound.c4
-rw-r--r--source/blender/blenkernel/intern/subdiv_converter_mesh.c10
-rw-r--r--source/blender/blenkernel/intern/subdiv_mesh.cc (renamed from source/blender/blenkernel/intern/subdiv_mesh.c)167
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c3
-rw-r--r--source/blender/blenkernel/intern/tracking_detect.c4
-rw-r--r--source/blender/blenkernel/intern/type_conversions.cc61
-rw-r--r--source/blender/blenkernel/intern/unit.c40
-rw-r--r--source/blender/blenkernel/intern/workspace.c4
76 files changed, 2229 insertions, 1959 deletions
diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc
index a29d8726f21..2ce5863c176 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.cc
+++ b/source/blender/blenkernel/intern/DerivedMesh.cc
@@ -1595,7 +1595,7 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
/* Add orco coordinates to final and deformed mesh if requested. */
if (final_datamask.vmask & CD_MASK_ORCO) {
- /* FIXME(Campbell): avoid the need to convert to mesh data just to add an orco layer. */
+ /* FIXME(@campbellbarton): avoid the need to convert to mesh data just to add an orco layer. */
BKE_mesh_wrapper_ensure_mdata(mesh_final);
add_orco_mesh(ob, em_input, mesh_final, mesh_orco, CD_ORCO);
diff --git a/source/blender/blenkernel/intern/armature_update.c b/source/blender/blenkernel/intern/armature_update.c
index 2db4c086e04..6d7aed239e7 100644
--- a/source/blender/blenkernel/intern/armature_update.c
+++ b/source/blender/blenkernel/intern/armature_update.c
@@ -288,7 +288,7 @@ static int position_tail_on_spline(bSplineIKConstraint *ik_data,
int max_seg_idx = BKE_anim_path_get_array_size(cache) - 1;
/* Make an initial guess of where our intersection point will be.
- * If the curve was a straight line, then the faction passed in r_new_curve_pos
+ * If the curve was a straight line, then the fraction passed in r_new_curve_pos
* would be the correct location.
* So make it our first initial guess.
*/
diff --git a/source/blender/blenkernel/intern/asset_catalog.cc b/source/blender/blenkernel/intern/asset_catalog.cc
index fccff602d2e..f7b14cc3479 100644
--- a/source/blender/blenkernel/intern/asset_catalog.cc
+++ b/source/blender/blenkernel/intern/asset_catalog.cc
@@ -516,7 +516,7 @@ CatalogFilePath AssetCatalogService::find_suitable_cdf_path_for_writing(
sizeof(asset_lib_cdf_path),
suitable_root_path,
DEFAULT_CATALOG_FILENAME.c_str(),
- NULL);
+ nullptr);
return asset_lib_cdf_path;
}
diff --git a/source/blender/blenkernel/intern/attribute.cc b/source/blender/blenkernel/intern/attribute.cc
index 495a2c82332..ccaa6e56f08 100644
--- a/source/blender/blenkernel/intern/attribute.cc
+++ b/source/blender/blenkernel/intern/attribute.cc
@@ -187,9 +187,9 @@ static bool unique_name_cb(void *arg, const char *name)
continue;
}
- CustomData *cdata = info[domain].customdata;
+ const CustomData *cdata = info[domain].customdata;
for (int i = 0; i < cdata->totlayer; i++) {
- CustomDataLayer *layer = cdata->layers + i;
+ const CustomDataLayer *layer = cdata->layers + i;
if (STREQ(layer->name, name)) {
return true;
@@ -493,10 +493,10 @@ void BKE_id_attributes_active_set(ID *id, CustomDataLayer *active_layer)
int index = 0;
for (const int domain : IndexRange(ATTR_DOMAIN_NUM)) {
- CustomData *customdata = info[domain].customdata;
+ const CustomData *customdata = info[domain].customdata;
if (customdata) {
for (int i = 0; i < customdata->totlayer; i++) {
- CustomDataLayer *layer = &customdata->layers[i];
+ const CustomDataLayer *layer = &customdata->layers[i];
if (layer == active_layer) {
*BKE_id_attributes_active_index_p(id) = index;
return;
diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc
index 1af3cde1821..b9995796a21 100644
--- a/source/blender/blenkernel/intern/attribute_access.cc
+++ b/source/blender/blenkernel/intern/attribute_access.cc
@@ -56,7 +56,7 @@ const char *no_procedural_access_message =
bool allow_procedural_attribute_access(StringRef attribute_name)
{
- return !attribute_name.startswith(".selection");
+ return !attribute_name.startswith(".selection") && !attribute_name.startswith(".hide");
}
static int attribute_data_type_complexity(const eCustomDataType data_type)
diff --git a/source/blender/blenkernel/intern/attribute_math.cc b/source/blender/blenkernel/intern/attribute_math.cc
index c38df2a2969..d8102b4eeb8 100644
--- a/source/blender/blenkernel/intern/attribute_math.cc
+++ b/source/blender/blenkernel/intern/attribute_math.cc
@@ -4,13 +4,31 @@
namespace blender::attribute_math {
-ColorGeometry4fMixer::ColorGeometry4fMixer(MutableSpan<ColorGeometry4f> output_buffer,
+ColorGeometry4fMixer::ColorGeometry4fMixer(MutableSpan<ColorGeometry4f> buffer,
ColorGeometry4f default_color)
- : buffer_(output_buffer),
- default_color_(default_color),
- total_weights_(output_buffer.size(), 0.0f)
+ : ColorGeometry4fMixer(buffer, buffer.index_range(), default_color)
+{
+}
+
+ColorGeometry4fMixer::ColorGeometry4fMixer(MutableSpan<ColorGeometry4f> buffer,
+ const IndexMask mask,
+ const ColorGeometry4f default_color)
+ : buffer_(buffer), default_color_(default_color), total_weights_(buffer.size(), 0.0f)
{
- buffer_.fill(ColorGeometry4f(0.0f, 0.0f, 0.0f, 0.0f));
+ const ColorGeometry4f zero{0.0f, 0.0f, 0.0f, 0.0f};
+ mask.foreach_index([&](const int64_t i) { buffer_[i] = zero; });
+}
+
+void ColorGeometry4fMixer::set(const int64_t index,
+ const ColorGeometry4f &color,
+ const float weight)
+{
+ BLI_assert(weight >= 0.0f);
+ buffer_[index].r = color.r * weight;
+ buffer_[index].g = color.g * weight;
+ buffer_[index].b = color.b * weight;
+ buffer_[index].a = color.a * weight;
+ total_weights_[index] = weight;
}
void ColorGeometry4fMixer::mix_in(const int64_t index,
@@ -28,7 +46,12 @@ void ColorGeometry4fMixer::mix_in(const int64_t index,
void ColorGeometry4fMixer::finalize()
{
- for (const int64_t i : buffer_.index_range()) {
+ this->finalize(buffer_.index_range());
+}
+
+void ColorGeometry4fMixer::finalize(const IndexMask mask)
+{
+ mask.foreach_index([&](const int64_t i) {
const float weight = total_weights_[i];
ColorGeometry4f &output_color = buffer_[i];
if (weight > 0.0f) {
@@ -41,16 +64,37 @@ void ColorGeometry4fMixer::finalize()
else {
output_color = default_color_;
}
- }
+ });
}
ColorGeometry4bMixer::ColorGeometry4bMixer(MutableSpan<ColorGeometry4b> buffer,
- ColorGeometry4b default_color)
+ const ColorGeometry4b default_color)
+ : ColorGeometry4bMixer(buffer, buffer.index_range(), default_color)
+{
+}
+
+ColorGeometry4bMixer::ColorGeometry4bMixer(MutableSpan<ColorGeometry4b> buffer,
+ const IndexMask mask,
+ const ColorGeometry4b default_color)
: buffer_(buffer),
default_color_(default_color),
total_weights_(buffer.size(), 0.0f),
accumulation_buffer_(buffer.size(), float4(0, 0, 0, 0))
{
+ const ColorGeometry4b zero{0, 0, 0, 0};
+ mask.foreach_index([&](const int64_t i) { buffer_[i] = zero; });
+}
+
+void ColorGeometry4bMixer::ColorGeometry4bMixer::set(int64_t index,
+ const ColorGeometry4b &color,
+ const float weight)
+{
+ BLI_assert(weight >= 0.0f);
+ accumulation_buffer_[index][0] = color.r * weight;
+ accumulation_buffer_[index][1] = color.g * weight;
+ accumulation_buffer_[index][2] = color.b * weight;
+ accumulation_buffer_[index][3] = color.a * weight;
+ total_weights_[index] = weight;
}
void ColorGeometry4bMixer::mix_in(int64_t index, const ColorGeometry4b &color, float weight)
@@ -66,7 +110,12 @@ void ColorGeometry4bMixer::mix_in(int64_t index, const ColorGeometry4b &color, f
void ColorGeometry4bMixer::finalize()
{
- for (const int64_t i : buffer_.index_range()) {
+ this->finalize(buffer_.index_range());
+}
+
+void ColorGeometry4bMixer::finalize(const IndexMask mask)
+{
+ mask.foreach_index([&](const int64_t i) {
const float weight = total_weights_[i];
const float4 &accum_value = accumulation_buffer_[i];
ColorGeometry4b &output_color = buffer_[i];
@@ -80,7 +129,7 @@ void ColorGeometry4bMixer::finalize()
else {
output_color = default_color_;
}
- }
+ });
}
} // namespace blender::attribute_math
diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c
index a86d6e25ee9..2e07b52c7bf 100644
--- a/source/blender/blenkernel/intern/boids.c
+++ b/source/blender/blenkernel/intern/boids.c
@@ -1567,7 +1567,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
cross_v3_v3v3(mat[1], mat[2], mat[0]);
/* apply rotation */
- mat3_to_quat_is_ok(q, mat);
+ mat3_to_quat_legacy(q, mat);
copy_qt_qt(pa->state.rot, q);
}
diff --git a/source/blender/blenkernel/intern/brush.cc b/source/blender/blenkernel/intern/brush.cc
index 5838ef1cbbe..34b87dda338 100644
--- a/source/blender/blenkernel/intern/brush.cc
+++ b/source/blender/blenkernel/intern/brush.cc
@@ -186,6 +186,7 @@ static void brush_foreach_id(ID *id, LibraryForeachIDData *data)
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, brush->paint_curve, IDWALK_CB_USER);
if (brush->gpencil_settings) {
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, brush->gpencil_settings->material, IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, brush->gpencil_settings->material_alt, IDWALK_CB_USER);
}
BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data, BKE_texture_mtex_foreach_id(data, &brush->mtex));
BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data,
@@ -346,6 +347,7 @@ static void brush_blend_read_lib(BlendLibReader *reader, ID *id)
else {
brush->gpencil_settings->material = nullptr;
}
+ BLO_read_id_address(reader, brush->id.lib, &brush->gpencil_settings->material_alt);
}
}
@@ -358,6 +360,7 @@ static void brush_blend_read_expand(BlendExpander *expander, ID *id)
BLO_expand(expander, brush->paint_curve);
if (brush->gpencil_settings != nullptr) {
BLO_expand(expander, brush->gpencil_settings->material);
+ BLO_expand(expander, brush->gpencil_settings->material_alt);
}
}
@@ -597,7 +600,7 @@ using eGPCurveMappingPreset = enum eGPCurveMappingPreset {
GPCURVE_PRESET_CHISEL_STRENGTH = 5,
};
-static void brush_gpencil_curvemap_reset(CurveMap *cuma, int tot, int preset)
+static void brush_gpencil_curvemap_reset(CurveMap *cuma, int tot, eGPCurveMappingPreset preset)
{
if (cuma->curve) {
MEM_freeN(cuma->curve);
@@ -704,6 +707,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
/* Set vertex mix factor. */
brush->gpencil_settings->vertex_mode = GPPAINT_MODE_BOTH;
brush->gpencil_settings->vertex_factor = 1.0f;
+ brush->gpencil_settings->material_alt = nullptr;
switch (type) {
case GP_BRUSH_PRESET_AIRBRUSH: {
diff --git a/source/blender/blenkernel/intern/bvhutils.cc b/source/blender/blenkernel/intern/bvhutils.cc
index 03dd5c89b70..d0b57b45d35 100644
--- a/source/blender/blenkernel/intern/bvhutils.cc
+++ b/source/blender/blenkernel/intern/bvhutils.cc
@@ -27,6 +27,8 @@
#include "MEM_guardedalloc.h"
+using blender::VArray;
+
/* -------------------------------------------------------------------- */
/** \name BVHCache
* \{ */
@@ -1181,9 +1183,13 @@ static BLI_bitmap *loose_edges_map_get(const MEdge *medge,
}
static BLI_bitmap *looptri_no_hidden_map_get(const MPoly *mpoly,
+ const VArray<bool> &hide_poly,
const int looptri_len,
int *r_looptri_active_len)
{
+ if (hide_poly.is_single() && !hide_poly.get_internal_single()) {
+ return nullptr;
+ }
BLI_bitmap *looptri_mask = BLI_BITMAP_NEW(looptri_len, __func__);
int looptri_no_hidden_len = 0;
@@ -1191,8 +1197,7 @@ static BLI_bitmap *looptri_no_hidden_map_get(const MPoly *mpoly,
int i_poly = 0;
while (looptri_iter != looptri_len) {
int mp_totlooptri = mpoly[i_poly].totloop - 2;
- const MPoly &mp = mpoly[i_poly];
- if (mp.flag & ME_HIDE) {
+ if (hide_poly[i_poly]) {
looptri_iter += mp_totlooptri;
}
else {
@@ -1276,9 +1281,15 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
0.0f, tree_type, 6, mesh->mvert, mesh->mface, mesh->totface, nullptr, -1);
break;
- case BVHTREE_FROM_LOOPTRI_NO_HIDDEN:
- mask = looptri_no_hidden_map_get(mesh->mpoly, looptri_len, &mask_bits_act_len);
+ case BVHTREE_FROM_LOOPTRI_NO_HIDDEN: {
+ blender::bke::AttributeAccessor attributes = blender::bke::mesh_attributes(*mesh);
+ mask = looptri_no_hidden_map_get(
+ mesh->mpoly,
+ attributes.lookup_or_default(".hide_poly", ATTR_DOMAIN_FACE, false),
+ looptri_len,
+ &mask_bits_act_len);
ATTR_FALLTHROUGH;
+ }
case BVHTREE_FROM_LOOPTRI:
data->tree = bvhtree_from_mesh_looptri_create_tree(0.0f,
tree_type,
diff --git a/source/blender/blenkernel/intern/cachefile.c b/source/blender/blenkernel/intern/cachefile.c
index 6b6b7223a0b..fd83ac50cad 100644
--- a/source/blender/blenkernel/intern/cachefile.c
+++ b/source/blender/blenkernel/intern/cachefile.c
@@ -429,10 +429,10 @@ bool BKE_cache_file_uses_render_procedural(const CacheFile *cache_file, Scene *s
return cache_file->use_render_procedural;
}
-CacheFileLayer *BKE_cachefile_add_layer(CacheFile *cache_file, const char filename[1024])
+CacheFileLayer *BKE_cachefile_add_layer(CacheFile *cache_file, const char filepath[1024])
{
for (CacheFileLayer *layer = cache_file->layers.first; layer; layer = layer->next) {
- if (STREQ(layer->filepath, filename)) {
+ if (STREQ(layer->filepath, filepath)) {
return NULL;
}
}
@@ -440,7 +440,7 @@ CacheFileLayer *BKE_cachefile_add_layer(CacheFile *cache_file, const char filena
const int num_layers = BLI_listbase_count(&cache_file->layers);
CacheFileLayer *layer = MEM_callocN(sizeof(CacheFileLayer), "CacheFileLayer");
- BLI_strncpy(layer->filepath, filename, sizeof(layer->filepath));
+ BLI_strncpy(layer->filepath, filepath, sizeof(layer->filepath));
BLI_addtail(&cache_file->layers, layer);
diff --git a/source/blender/blenkernel/intern/colorband.c b/source/blender/blenkernel/intern/colorband.c
index b2f817b7821..5145f1cbbc0 100644
--- a/source/blender/blenkernel/intern/colorband.c
+++ b/source/blender/blenkernel/intern/colorband.c
@@ -144,7 +144,7 @@ static float color_sample_remove_cost(const struct ColorResampleElem *c)
return area;
}
-/* TODO(campbell): create BLI_math_filter? */
+/* TODO(@campbellbarton): create `BLI_math_filter` ? */
static float filter_gauss(float x)
{
const float gaussfac = 1.6f;
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 9f1d2d7bbb2..071fa5fe6bf 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -1559,7 +1559,7 @@ static void followpath_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *
/* un-apply scaling caused by path */
if ((data->followflag & FOLLOWPATH_RADIUS) == 0) {
- /* XXX(campbell): Assume that scale correction means that radius
+ /* XXX(@campbellbarton): Assume that scale correction means that radius
* will have some scale error in it. */
float obsize[3];
diff --git a/source/blender/blenkernel/intern/crazyspace.cc b/source/blender/blenkernel/intern/crazyspace.cc
index 8d4b64da817..fdd269bd9c8 100644
--- a/source/blender/blenkernel/intern/crazyspace.cc
+++ b/source/blender/blenkernel/intern/crazyspace.cc
@@ -73,7 +73,7 @@ static void set_crazy_vertex_quat(float r_quat[4],
static bool modifiers_disable_subsurf_temporary(struct Scene *scene, Object *ob)
{
bool disabled = false;
- int cageIndex = BKE_modifiers_get_cage_index(scene, ob, nullptr, 1);
+ int cageIndex = BKE_modifiers_get_cage_index(scene, ob, nullptr, true);
ModifierData *md = static_cast<ModifierData *>(ob->modifiers.first);
for (int i = 0; md && i <= cageIndex; i++, md = md->next) {
@@ -241,7 +241,7 @@ int BKE_crazyspace_get_first_deform_matrices_editbmesh(struct Depsgraph *depsgra
Mesh *me_input = static_cast<Mesh *>(ob->data);
Mesh *me = nullptr;
int i, a, modifiers_left_num = 0, verts_num = 0;
- int cageIndex = BKE_modifiers_get_cage_index(scene, ob, nullptr, 1);
+ int cageIndex = BKE_modifiers_get_cage_index(scene, ob, nullptr, true);
float(*defmats)[3][3] = nullptr, (*deformedVerts)[3] = nullptr;
VirtualModifierData virtualModifierData;
ModifierEvalContext mectx = {depsgraph, ob, ModifierApplyFlag(0)};
@@ -362,7 +362,7 @@ int BKE_sculpt_get_first_deform_matrices(struct Depsgraph *depsgraph,
VirtualModifierData virtualModifierData;
Object object_eval;
crazyspace_init_object_for_eval(depsgraph, object, &object_eval);
- MultiresModifierData *mmd = get_multires_modifier(scene, &object_eval, 0);
+ MultiresModifierData *mmd = get_multires_modifier(scene, &object_eval, false);
const bool is_sculpt_mode = (object->mode & OB_MODE_SCULPT) != 0;
const bool has_multires = mmd != nullptr && mmd->sculptlvl > 0;
const ModifierEvalContext mectx = {depsgraph, &object_eval, ModifierApplyFlag(0)};
diff --git a/source/blender/blenkernel/intern/curve.cc b/source/blender/blenkernel/intern/curve.cc
index 5125e010b81..40b64aa8dc8 100644
--- a/source/blender/blenkernel/intern/curve.cc
+++ b/source/blender/blenkernel/intern/curve.cc
@@ -2470,7 +2470,7 @@ static void make_bevel_list_segment_2D(BevList *bl)
static void make_bevel_list_2D(BevList *bl)
{
- /* NOTE(campbell): `bevp->dir` and `bevp->quat` are not needed for beveling but are
+ /* NOTE(@campbellbarton): `bevp->dir` and `bevp->quat` are not needed for beveling but are
* used when making a path from a 2D curve, therefore they need to be set. */
BevPoint *bevp0, *bevp1, *bevp2;
diff --git a/source/blender/blenkernel/intern/curve_nurbs.cc b/source/blender/blenkernel/intern/curve_nurbs.cc
index 3ab6fb01ea5..62d5682da0f 100644
--- a/source/blender/blenkernel/intern/curve_nurbs.cc
+++ b/source/blender/blenkernel/intern/curve_nurbs.cc
@@ -4,8 +4,9 @@
* \ingroup bke
*/
-#include "BKE_attribute_math.hh"
+#include "BLI_task.hh"
+#include "BKE_attribute_math.hh"
#include "BKE_curves.hh"
namespace blender::bke::curves::nurbs {
@@ -192,16 +193,16 @@ static void interpolate_to_evaluated(const BasisCache &basis_cache,
{
attribute_math::DefaultMixer<T> mixer{dst};
- for (const int i : dst.index_range()) {
- Span<float> point_weights = basis_cache.weights.as_span().slice(i * order, order);
-
- for (const int j : point_weights.index_range()) {
- const int point_index = (basis_cache.start_indices[i] + j) % src.size();
- mixer.mix_in(i, src[point_index], point_weights[j]);
+ threading::parallel_for(dst.index_range(), 128, [&](const IndexRange range) {
+ for (const int i : range) {
+ Span<float> point_weights = basis_cache.weights.as_span().slice(i * order, order);
+ for (const int j : point_weights.index_range()) {
+ const int point_index = (basis_cache.start_indices[i] + j) % src.size();
+ mixer.mix_in(i, src[point_index], point_weights[j]);
+ }
}
- }
-
- mixer.finalize();
+ mixer.finalize(range);
+ });
}
template<typename T>
@@ -213,17 +214,18 @@ static void interpolate_to_evaluated_rational(const BasisCache &basis_cache,
{
attribute_math::DefaultMixer<T> mixer{dst};
- for (const int i : dst.index_range()) {
- Span<float> point_weights = basis_cache.weights.as_span().slice(i * order, order);
+ threading::parallel_for(dst.index_range(), 128, [&](const IndexRange range) {
+ for (const int i : range) {
+ Span<float> point_weights = basis_cache.weights.as_span().slice(i * order, order);
- for (const int j : point_weights.index_range()) {
- const int point_index = (basis_cache.start_indices[i] + j) % src.size();
- const float weight = point_weights[j] * control_weights[point_index];
- mixer.mix_in(i, src[point_index], weight);
+ for (const int j : point_weights.index_range()) {
+ const int point_index = (basis_cache.start_indices[i] + j) % src.size();
+ const float weight = point_weights[j] * control_weights[point_index];
+ mixer.mix_in(i, src[point_index], weight);
+ }
}
- }
-
- mixer.finalize();
+ mixer.finalize(range);
+ });
}
void interpolate_to_evaluated(const BasisCache &basis_cache,
diff --git a/source/blender/blenkernel/intern/curves.cc b/source/blender/blenkernel/intern/curves.cc
index f90cf48090c..6211f6b7be6 100644
--- a/source/blender/blenkernel/intern/curves.cc
+++ b/source/blender/blenkernel/intern/curves.cc
@@ -366,6 +366,8 @@ namespace blender::bke {
Curves *curves_new_nomain(const int points_num, const int curves_num)
{
+ BLI_assert(points_num >= 0);
+ BLI_assert(curves_num >= 0);
Curves *curves_id = static_cast<Curves *>(BKE_id_new_nomain(ID_CV, nullptr));
CurvesGeometry &curves = CurvesGeometry::wrap(curves_id->geometry);
curves.resize(points_num, curves_num);
diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc
index ef4a4ee1d6b..fe9f6775995 100644
--- a/source/blender/blenkernel/intern/curves_geometry.cc
+++ b/source/blender/blenkernel/intern/curves_geometry.cc
@@ -13,6 +13,7 @@
#include "BLI_index_mask_ops.hh"
#include "BLI_length_parameterize.hh"
#include "BLI_math_rotation.hh"
+#include "BLI_task.hh"
#include "DNA_curves_types.h"
@@ -254,6 +255,12 @@ void CurvesGeometry::fill_curve_types(const IndexMask selection, const CurveType
this->fill_curve_types(type);
return;
}
+ if (std::optional<int8_t> single_type = this->curve_types().get_if_single()) {
+ if (single_type == type) {
+ /* No need for an array if the types are already a single with the correct type. */
+ return;
+ }
+ }
/* A potential performance optimization is only counting the changed indices. */
this->curve_types_for_write().fill_indices(selection, type);
this->update_curve_types();
@@ -1169,6 +1176,10 @@ static CurvesGeometry copy_with_removed_points(const CurvesGeometry &curves,
}
CurvesGeometry new_curves{new_point_count, new_curve_count};
+ Vector<bke::AttributeTransferData> point_attributes = bke::retrieve_attributes_for_transfer(
+ curves.attributes(), new_curves.attributes_for_write(), ATTR_DOMAIN_MASK_POINT);
+ Vector<bke::AttributeTransferData> curve_attributes = bke::retrieve_attributes_for_transfer(
+ curves.attributes(), new_curves.attributes_for_write(), ATTR_DOMAIN_MASK_CURVE);
threading::parallel_invoke(
256 < new_point_count * new_curve_count,
@@ -1176,8 +1187,7 @@ static CurvesGeometry copy_with_removed_points(const CurvesGeometry &curves,
[&]() { new_curves.offsets_for_write().copy_from(new_curve_offsets); },
[&]() {
/* Copy over point attributes. */
- for (auto &attribute : bke::retrieve_attributes_for_transfer(
- curves.attributes(), new_curves.attributes_for_write(), ATTR_DOMAIN_MASK_POINT)) {
+ for (bke::AttributeTransferData &attribute : point_attributes) {
threading::parallel_for(copy_point_ranges.index_range(), 128, [&](IndexRange range) {
for (const int range_i : range) {
const IndexRange src_range = copy_point_ranges[range_i];
@@ -1188,24 +1198,29 @@ static CurvesGeometry copy_with_removed_points(const CurvesGeometry &curves,
{copy_point_range_dst_offsets[range_i], src_range.size()});
}
});
- attribute.dst.finish();
}
-
+ },
+ [&]() {
/* Copy over curve attributes.
- * In some cases points are just dissolved, so the the number of
+ * In some cases points are just dissolved, so the number of
* curves will be the same. That could be optimized in the future. */
- for (auto &attribute : bke::retrieve_attributes_for_transfer(
- curves.attributes(), new_curves.attributes_for_write(), ATTR_DOMAIN_MASK_CURVE)) {
+ for (bke::AttributeTransferData &attribute : curve_attributes) {
if (new_curves.curves_num() == curves.curves_num()) {
attribute.dst.span.copy_from(attribute.src);
}
else {
copy_with_map(attribute.src, new_curve_orig_indices, attribute.dst.span);
}
- attribute.dst.finish();
}
});
+ for (bke::AttributeTransferData &attribute : point_attributes) {
+ attribute.dst.finish();
+ }
+ for (bke::AttributeTransferData &attribute : curve_attributes) {
+ attribute.dst.finish();
+ }
+
return new_curves;
}
@@ -1242,6 +1257,10 @@ static CurvesGeometry copy_with_removed_curves(const CurvesGeometry &curves,
}
CurvesGeometry new_curves{new_tot_points, new_tot_curves};
+ Vector<bke::AttributeTransferData> point_attributes = bke::retrieve_attributes_for_transfer(
+ curves.attributes(), new_curves.attributes_for_write(), ATTR_DOMAIN_MASK_POINT);
+ Vector<bke::AttributeTransferData> curve_attributes = bke::retrieve_attributes_for_transfer(
+ curves.attributes(), new_curves.attributes_for_write(), ATTR_DOMAIN_MASK_CURVE);
threading::parallel_invoke(
256 < new_tot_points * new_tot_curves,
@@ -1273,8 +1292,7 @@ static CurvesGeometry copy_with_removed_curves(const CurvesGeometry &curves,
},
[&]() {
/* Copy over point attributes. */
- for (auto &attribute : bke::retrieve_attributes_for_transfer(
- curves.attributes(), new_curves.attributes_for_write(), ATTR_DOMAIN_MASK_POINT)) {
+ for (bke::AttributeTransferData &attribute : point_attributes) {
threading::parallel_for(old_curve_ranges.index_range(), 128, [&](IndexRange range) {
for (const int range_i : range) {
copy_between_buffers(attribute.src.type(),
@@ -1284,11 +1302,11 @@ static CurvesGeometry copy_with_removed_curves(const CurvesGeometry &curves,
new_point_ranges[range_i]);
}
});
- attribute.dst.finish();
}
+ },
+ [&]() {
/* Copy over curve attributes. */
- for (auto &attribute : bke::retrieve_attributes_for_transfer(
- curves.attributes(), new_curves.attributes_for_write(), ATTR_DOMAIN_MASK_CURVE)) {
+ for (bke::AttributeTransferData &attribute : curve_attributes) {
threading::parallel_for(old_curve_ranges.index_range(), 128, [&](IndexRange range) {
for (const int range_i : range) {
copy_between_buffers(attribute.src.type(),
@@ -1298,10 +1316,16 @@ static CurvesGeometry copy_with_removed_curves(const CurvesGeometry &curves,
new_curve_ranges[range_i]);
}
});
- attribute.dst.finish();
}
});
+ for (bke::AttributeTransferData &attribute : point_attributes) {
+ attribute.dst.finish();
+ }
+ for (bke::AttributeTransferData &attribute : curve_attributes) {
+ attribute.dst.finish();
+ }
+
return new_curves;
}
@@ -1456,12 +1480,15 @@ static void adapt_curve_domain_point_to_curve_impl(const CurvesGeometry &curves,
MutableSpan<T> r_values)
{
attribute_math::DefaultMixer<T> mixer(r_values);
- for (const int i_curve : IndexRange(curves.curves_num())) {
- for (const int i_point : curves.points_for_curve(i_curve)) {
- mixer.mix_in(i_curve, old_values[i_point]);
+
+ threading::parallel_for(curves.curves_range(), 128, [&](const IndexRange range) {
+ for (const int i_curve : range) {
+ for (const int i_point : curves.points_for_curve(i_curve)) {
+ mixer.mix_in(i_curve, old_values[i_point]);
+ }
}
- }
- mixer.finalize();
+ mixer.finalize(range);
+ });
}
/**
diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc
index 82356e06d2c..1f70ab587bf 100644
--- a/source/blender/blenkernel/intern/customdata.cc
+++ b/source/blender/blenkernel/intern/customdata.cc
@@ -26,6 +26,7 @@
#include "BLI_math_vector.hh"
#include "BLI_mempool.h"
#include "BLI_path_util.h"
+#include "BLI_set.hh"
#include "BLI_span.hh"
#include "BLI_string.h"
#include "BLI_string_ref.hh"
@@ -58,6 +59,7 @@
#include "data_transfer_intern.h"
using blender::IndexRange;
+using blender::Set;
using blender::Span;
using blender::StringRef;
using blender::Vector;
@@ -165,7 +167,7 @@ struct LayerTypeInfo {
void (*initminmax)(void *min, void *max);
void (*add)(void *data1, const void *data2);
void (*dominmax)(const void *data1, void *min, void *max);
- void (*copyvalue)(const void *source, void *dest, const int mixmode, const float mixfactor);
+ void (*copyvalue)(const void *source, void *dest, int mixmode, const float mixfactor);
/** a function to read data from a cdf file */
bool (*read)(CDataFile *cdf, void *data, int count);
@@ -187,7 +189,7 @@ struct LayerTypeInfo {
/** \name Callbacks for (#MDeformVert, #CD_MDEFORMVERT)
* \{ */
-static void layerCopy_mdeformvert(const void *source, void *dest, int count)
+static void layerCopy_mdeformvert(const void *source, void *dest, const int count)
{
int i, size = sizeof(MDeformVert);
@@ -209,7 +211,7 @@ static void layerCopy_mdeformvert(const void *source, void *dest, int count)
}
}
-static void layerFree_mdeformvert(void *data, int count, int size)
+static void layerFree_mdeformvert(void *data, const int count, const int size)
{
for (int i = 0; i < count; i++) {
MDeformVert *dvert = static_cast<MDeformVert *>(POINTER_OFFSET(data, i * size));
@@ -222,38 +224,10 @@ static void layerFree_mdeformvert(void *data, int count, int size)
}
}
-/* copy just zeros in this case */
-static void layerCopy_bmesh_elem_py_ptr(const void *UNUSED(source), void *dest, int count)
-{
- const int size = sizeof(void *);
-
- for (int i = 0; i < count; i++) {
- void **ptr = (void **)POINTER_OFFSET(dest, i * size);
- *ptr = nullptr;
- }
-}
-
-#ifndef WITH_PYTHON
-void bpy_bm_generic_invalidate(struct BPy_BMGeneric *UNUSED(self))
-{
- /* dummy */
-}
-#endif
-
-static void layerFree_bmesh_elem_py_ptr(void *data, int count, int size)
-{
- for (int i = 0; i < count; i++) {
- void **ptr = (void **)POINTER_OFFSET(data, i * size);
- if (*ptr) {
- bpy_bm_generic_invalidate(static_cast<BPy_BMGeneric *>(*ptr));
- }
- }
-}
-
static void layerInterp_mdeformvert(const void **sources,
const float *weights,
const float *UNUSED(sub_weights),
- int count,
+ const int count,
void *dest)
{
/* a single linked list of MDeformWeight's
@@ -347,7 +321,7 @@ static void layerInterp_mdeformvert(const void **sources,
static void layerInterp_normal(const void **sources,
const float *weights,
const float *UNUSED(sub_weights),
- int count,
+ const int count,
void *dest)
{
/* NOTE: This is linear interpolation, which is not optimal for vectors.
@@ -355,8 +329,8 @@ static void layerInterp_normal(const void **sources,
* so for now it will do... */
float no[3] = {0.0f};
- while (count--) {
- madd_v3_v3fl(no, (const float *)sources[count], weights[count]);
+ for (const int i : IndexRange(count)) {
+ madd_v3_v3fl(no, (const float *)sources[i], weights[i]);
}
/* Weighted sum of normalized vectors will **not** be normalized, even if weights are. */
@@ -406,7 +380,7 @@ static void layerCopyValue_normal(const void *source,
/** \name Callbacks for (#MTFace, #CD_MTFACE)
* \{ */
-static void layerCopy_tface(const void *source, void *dest, int count)
+static void layerCopy_tface(const void *source, void *dest, const int count)
{
const MTFace *source_tf = (const MTFace *)source;
MTFace *dest_tf = (MTFace *)dest;
@@ -415,8 +389,11 @@ static void layerCopy_tface(const void *source, void *dest, int count)
}
}
-static void layerInterp_tface(
- const void **sources, const float *weights, const float *sub_weights, int count, void *dest)
+static void layerInterp_tface(const void **sources,
+ const float *weights,
+ const float *sub_weights,
+ const int count,
+ void *dest)
{
MTFace *tf = static_cast<MTFace *>(dest);
float uv[4][2] = {{0.0f}};
@@ -456,7 +433,7 @@ static void layerSwap_tface(void *data, const int *corner_indices)
memcpy(tf->uv, uv, sizeof(tf->uv));
}
-static void layerDefault_tface(void *data, int count)
+static void layerDefault_tface(void *data, const int count)
{
static MTFace default_tf = {{{0, 0}, {1, 0}, {1, 1}, {0, 1}}};
MTFace *tf = (MTFace *)data;
@@ -477,7 +454,7 @@ static int layerMaxNum_tface()
/** \name Callbacks for (#MFloatProperty, #CD_PROP_FLOAT)
* \{ */
-static void layerCopy_propFloat(const void *source, void *dest, int count)
+static void layerCopy_propFloat(const void *source, void *dest, const int count)
{
memcpy(dest, source, sizeof(MFloatProperty) * count);
}
@@ -485,7 +462,7 @@ static void layerCopy_propFloat(const void *source, void *dest, int count)
static void layerInterp_propFloat(const void **sources,
const float *weights,
const float *UNUSED(sub_weights),
- int count,
+ const int count,
void *dest)
{
float result = 0.0f;
@@ -520,7 +497,7 @@ static bool layerValidate_propFloat(void *data, const uint totitems, const bool
/** \name Callbacks for (#MIntProperty, #CD_PROP_INT32)
* \{ */
-static void layerCopy_propInt(const void *source, void *dest, int count)
+static void layerCopy_propInt(const void *source, void *dest, const int count)
{
memcpy(dest, source, sizeof(MIntProperty) * count);
}
@@ -528,7 +505,7 @@ static void layerCopy_propInt(const void *source, void *dest, int count)
static void layerInterp_propInt(const void **sources,
const float *weights,
const float *UNUSED(sub_weights),
- int count,
+ const int count,
void *dest)
{
float result = 0.0f;
@@ -547,7 +524,7 @@ static void layerInterp_propInt(const void **sources,
/** \name Callbacks for (#MStringProperty, #CD_PROP_STRING)
* \{ */
-static void layerCopy_propString(const void *source, void *dest, int count)
+static void layerCopy_propString(const void *source, void *dest, const int count)
{
memcpy(dest, source, sizeof(MStringProperty) * count);
}
@@ -558,7 +535,7 @@ static void layerCopy_propString(const void *source, void *dest, int count)
/** \name Callbacks for (#OrigSpaceFace, #CD_ORIGSPACE)
* \{ */
-static void layerCopy_origspace_face(const void *source, void *dest, int count)
+static void layerCopy_origspace_face(const void *source, void *dest, const int count)
{
const OrigSpaceFace *source_tf = (const OrigSpaceFace *)source;
OrigSpaceFace *dest_tf = (OrigSpaceFace *)dest;
@@ -568,8 +545,11 @@ static void layerCopy_origspace_face(const void *source, void *dest, int count)
}
}
-static void layerInterp_origspace_face(
- const void **sources, const float *weights, const float *sub_weights, int count, void *dest)
+static void layerInterp_origspace_face(const void **sources,
+ const float *weights,
+ const float *sub_weights,
+ const int count,
+ void *dest)
{
OrigSpaceFace *osf = static_cast<OrigSpaceFace *>(dest);
float uv[4][2] = {{0.0f}};
@@ -606,7 +586,7 @@ static void layerSwap_origspace_face(void *data, const int *corner_indices)
memcpy(osf->uv, uv, sizeof(osf->uv));
}
-static void layerDefault_origspace_face(void *data, int count)
+static void layerDefault_origspace_face(void *data, const int count)
{
static OrigSpaceFace default_osf = {{{0, 0}, {1, 0}, {1, 1}, {0, 1}}};
OrigSpaceFace *osf = (OrigSpaceFace *)data;
@@ -652,7 +632,7 @@ static void layerSwap_mdisps(void *data, const int *ci)
}
}
-static void layerCopy_mdisps(const void *source, void *dest, int count)
+static void layerCopy_mdisps(const void *source, void *dest, const int count)
{
const MDisps *s = static_cast<const MDisps *>(source);
MDisps *d = static_cast<MDisps *>(dest);
@@ -673,7 +653,7 @@ static void layerCopy_mdisps(const void *source, void *dest, int count)
}
}
-static void layerFree_mdisps(void *data, int count, int UNUSED(size))
+static void layerFree_mdisps(void *data, const int count, const int UNUSED(size))
{
MDisps *d = static_cast<MDisps *>(data);
@@ -691,7 +671,7 @@ static void layerFree_mdisps(void *data, int count, int UNUSED(size))
}
}
-static bool layerRead_mdisps(CDataFile *cdf, void *data, int count)
+static bool layerRead_mdisps(CDataFile *cdf, void *data, const int count)
{
MDisps *d = static_cast<MDisps *>(data);
@@ -709,7 +689,7 @@ static bool layerRead_mdisps(CDataFile *cdf, void *data, int count)
return true;
}
-static bool layerWrite_mdisps(CDataFile *cdf, const void *data, int count)
+static bool layerWrite_mdisps(CDataFile *cdf, const void *data, const int count)
{
const MDisps *d = static_cast<const MDisps *>(data);
@@ -723,7 +703,7 @@ static bool layerWrite_mdisps(CDataFile *cdf, const void *data, int count)
return true;
}
-static size_t layerFilesize_mdisps(CDataFile *UNUSED(cdf), const void *data, int count)
+static size_t layerFilesize_mdisps(CDataFile *UNUSED(cdf), const void *data, const int count)
{
const MDisps *d = static_cast<const MDisps *>(data);
size_t size = 0;
@@ -738,6 +718,40 @@ static size_t layerFilesize_mdisps(CDataFile *UNUSED(cdf), const void *data, int
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Callbacks for (#CD_BM_ELEM_PYPTR)
+ * \{ */
+
+/* copy just zeros in this case */
+static void layerCopy_bmesh_elem_py_ptr(const void *UNUSED(source), void *dest, const int count)
+{
+ const int size = sizeof(void *);
+
+ for (int i = 0; i < count; i++) {
+ void **ptr = (void **)POINTER_OFFSET(dest, i * size);
+ *ptr = nullptr;
+ }
+}
+
+#ifndef WITH_PYTHON
+void bpy_bm_generic_invalidate(struct BPy_BMGeneric *UNUSED(self))
+{
+ /* dummy */
+}
+#endif
+
+static void layerFree_bmesh_elem_py_ptr(void *data, const int count, const int size)
+{
+ for (int i = 0; i < count; i++) {
+ void **ptr = (void **)POINTER_OFFSET(data, i * size);
+ if (*ptr) {
+ bpy_bm_generic_invalidate(static_cast<BPy_BMGeneric *>(*ptr));
+ }
+ }
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Callbacks for (`float`, #CD_PAINT_MASK)
* \{ */
@@ -762,7 +776,7 @@ static void layerInterp_paint_mask(const void **sources,
/** \name Callbacks for (#GridPaintMask, #CD_GRID_PAINT_MASK)
* \{ */
-static void layerCopy_grid_paint_mask(const void *source, void *dest, int count)
+static void layerCopy_grid_paint_mask(const void *source, void *dest, const int count)
{
const GridPaintMask *s = static_cast<const GridPaintMask *>(source);
GridPaintMask *d = static_cast<GridPaintMask *>(dest);
@@ -779,7 +793,7 @@ static void layerCopy_grid_paint_mask(const void *source, void *dest, int count)
}
}
-static void layerFree_grid_paint_mask(void *data, int count, int UNUSED(size))
+static void layerFree_grid_paint_mask(void *data, const int count, const int UNUSED(size))
{
GridPaintMask *gpm = static_cast<GridPaintMask *>(data);
@@ -867,7 +881,7 @@ static bool layerEqual_mloopcol(const void *data1, const void *data2)
return r * r + g * g + b * b + a * a < 0.001f;
}
-static void layerMultiply_mloopcol(void *data, float fac)
+static void layerMultiply_mloopcol(void *data, const float fac)
{
MLoopCol *m = static_cast<MLoopCol *>(data);
@@ -936,7 +950,7 @@ static void layerInitMinMax_mloopcol(void *vmin, void *vmax)
max->a = 0;
}
-static void layerDefault_mloopcol(void *data, int count)
+static void layerDefault_mloopcol(void *data, const int count)
{
MLoopCol default_mloopcol = {255, 255, 255, 255};
MLoopCol *mlcol = (MLoopCol *)data;
@@ -1016,7 +1030,7 @@ static bool layerEqual_mloopuv(const void *data1, const void *data2)
return len_squared_v2v2(luv1->uv, luv2->uv) < 0.00001f;
}
-static void layerMultiply_mloopuv(void *data, float fac)
+static void layerMultiply_mloopuv(void *data, const float fac)
{
MLoopUV *luv = static_cast<MLoopUV *>(data);
@@ -1110,7 +1124,7 @@ static bool layerEqual_mloop_origspace(const void *data1, const void *data2)
return len_squared_v2v2(luv1->uv, luv2->uv) < 0.00001f;
}
-static void layerMultiply_mloop_origspace(void *data, float fac)
+static void layerMultiply_mloop_origspace(void *data, const float fac)
{
OrigSpaceLoop *luv = static_cast<OrigSpaceLoop *>(data);
@@ -1162,8 +1176,11 @@ static void layerInterp_mloop_origspace(const void **sources,
}
/* --- end copy */
-static void layerInterp_mcol(
- const void **sources, const float *weights, const float *sub_weights, int count, void *dest)
+static void layerInterp_mcol(const void **sources,
+ const float *weights,
+ const float *sub_weights,
+ const int count,
+ void *dest)
{
MCol *mc = static_cast<MCol *>(dest);
struct {
@@ -1222,7 +1239,7 @@ static void layerSwap_mcol(void *data, const int *corner_indices)
memcpy(mcol, col, sizeof(col));
}
-static void layerDefault_mcol(void *data, int count)
+static void layerDefault_mcol(void *data, const int count)
{
static MCol default_mcol = {255, 255, 255, 255};
MCol *mcol = (MCol *)data;
@@ -1232,7 +1249,7 @@ static void layerDefault_mcol(void *data, int count)
}
}
-static void layerDefault_origindex(void *data, int count)
+static void layerDefault_origindex(void *data, const int count)
{
copy_vn_i((int *)data, count, ORIGINDEX_NONE);
}
@@ -1290,7 +1307,7 @@ static void layerInterp_shapekey(const void **sources,
/** \name Callbacks for (#MVertSkin, #CD_MVERT_SKIN)
* \{ */
-static void layerDefault_mvert_skin(void *data, int count)
+static void layerDefault_mvert_skin(void *data, const int count)
{
MVertSkin *vs = static_cast<MVertSkin *>(data);
@@ -1300,7 +1317,7 @@ static void layerDefault_mvert_skin(void *data, int count)
}
}
-static void layerCopy_mvert_skin(const void *source, void *dest, int count)
+static void layerCopy_mvert_skin(const void *source, void *dest, const int count)
{
memcpy(dest, source, sizeof(MVertSkin) * count);
}
@@ -1352,7 +1369,7 @@ static void layerSwap_flnor(void *data, const int *corner_indices)
/** \name Callbacks for (`int`, #CD_FACEMAP)
* \{ */
-static void layerDefault_fmap(void *data, int count)
+static void layerDefault_fmap(void *data, const int count)
{
int *fmap_num = (int *)data;
for (int i = 0; i < count; i++) {
@@ -1428,7 +1445,7 @@ static bool layerEqual_propcol(const void *data1, const void *data2)
return tot < 0.001f;
}
-static void layerMultiply_propcol(void *data, float fac)
+static void layerMultiply_propcol(void *data, const float fac)
{
MPropCol *m = static_cast<MPropCol *>(data);
mul_v4_fl(m->color, fac);
@@ -1458,7 +1475,7 @@ static void layerInitMinMax_propcol(void *vmin, void *vmax)
copy_v4_fl(max->color, FLT_MIN);
}
-static void layerDefault_propcol(void *data, int count)
+static void layerDefault_propcol(void *data, const int count)
{
/* Default to white, full alpha. */
MPropCol default_propcol = {{1.0f, 1.0f, 1.0f, 1.0f}};
@@ -1510,7 +1527,7 @@ static void layerInterp_propfloat3(const void **sources,
copy_v3_v3((float *)dest, &result.x);
}
-static void layerMultiply_propfloat3(void *data, float fac)
+static void layerMultiply_propfloat3(void *data, const float fac)
{
vec3f *vec = static_cast<vec3f *>(data);
vec->x *= fac;
@@ -1563,7 +1580,7 @@ static void layerInterp_propfloat2(const void **sources,
copy_v2_v2((float *)dest, &result.x);
}
-static void layerMultiply_propfloat2(void *data, float fac)
+static void layerMultiply_propfloat2(void *data, const float fac)
{
vec2f *vec = static_cast<vec2f *>(data);
vec->x *= fac;
@@ -2327,7 +2344,44 @@ bool CustomData_merge(const CustomData *source,
return changed;
}
-void CustomData_realloc(CustomData *data, int totelem)
+static bool attribute_stored_in_bmesh_flag(const StringRef name)
+{
+ return ELEM(name, ".hide_vert", ".hide_edge", ".hide_poly");
+}
+
+static CustomData shallow_copy_remove_non_bmesh_attributes(const CustomData &src)
+{
+ Vector<CustomDataLayer> dst_layers;
+ for (const CustomDataLayer &layer : Span<CustomDataLayer>{src.layers, src.totlayer}) {
+ if (!attribute_stored_in_bmesh_flag(layer.name)) {
+ dst_layers.append(layer);
+ }
+ }
+
+ CustomData dst = src;
+ dst.layers = static_cast<CustomDataLayer *>(
+ MEM_calloc_arrayN(dst_layers.size(), sizeof(CustomDataLayer), __func__));
+ dst.totlayer = dst_layers.size();
+ memcpy(dst.layers, dst_layers.data(), dst_layers.as_span().size_in_bytes());
+
+ CustomData_update_typemap(&dst);
+
+ return dst;
+}
+
+bool CustomData_merge_mesh_to_bmesh(const CustomData *source,
+ CustomData *dest,
+ const eCustomDataMask mask,
+ const eCDAllocType alloctype,
+ const int totelem)
+{
+ CustomData source_copy = shallow_copy_remove_non_bmesh_attributes(*source);
+ const bool result = CustomData_merge(&source_copy, dest, mask, alloctype, totelem);
+ MEM_SAFE_FREE(source_copy.layers);
+ return result;
+}
+
+void CustomData_realloc(CustomData *data, const int totelem)
{
BLI_assert(totelem >= 0);
for (int i = 0; i < data->totlayer; i++) {
@@ -2358,7 +2412,18 @@ void CustomData_copy(const CustomData *source,
CustomData_merge(source, dest, mask, alloctype, totelem);
}
-static void customData_free_layer__internal(CustomDataLayer *layer, int totelem)
+void CustomData_copy_mesh_to_bmesh(const CustomData *source,
+ CustomData *dest,
+ const eCustomDataMask mask,
+ const eCDAllocType alloctype,
+ const int totelem)
+{
+ CustomData source_copy = shallow_copy_remove_non_bmesh_attributes(*source);
+ CustomData_copy(&source_copy, dest, mask, alloctype, totelem);
+ MEM_SAFE_FREE(source_copy.layers);
+}
+
+static void customData_free_layer__internal(CustomDataLayer *layer, const int totelem)
{
const LayerTypeInfo *typeInfo;
@@ -2393,7 +2458,7 @@ void CustomData_reset(CustomData *data)
copy_vn_i(data->typemap, CD_NUMTYPES, -1);
}
-void CustomData_free(CustomData *data, int totelem)
+void CustomData_free(CustomData *data, const int totelem)
{
for (int i = 0; i < data->totlayer; i++) {
customData_free_layer__internal(&data->layers[i], totelem);
@@ -2407,7 +2472,7 @@ void CustomData_free(CustomData *data, int totelem)
CustomData_reset(data);
}
-void CustomData_free_typemask(CustomData *data, int totelem, eCustomDataMask mask)
+void CustomData_free_typemask(CustomData *data, const int totelem, eCustomDataMask mask)
{
for (int i = 0; i < data->totlayer; i++) {
CustomDataLayer *layer = &data->layers[i];
@@ -2442,7 +2507,7 @@ static void customData_update_offsets(CustomData *data)
}
/* to use when we're in the middle of modifying layers */
-static int CustomData_get_layer_index__notypemap(const CustomData *data, int type)
+static int CustomData_get_layer_index__notypemap(const CustomData *data, const int type)
{
for (int i = 0; i < data->totlayer; i++) {
if (data->layers[i].type == type) {
@@ -2456,13 +2521,13 @@ static int CustomData_get_layer_index__notypemap(const CustomData *data, int typ
/* -------------------------------------------------------------------- */
/* index values to access the layers (offset from the layer start) */
-int CustomData_get_layer_index(const CustomData *data, int type)
+int CustomData_get_layer_index(const CustomData *data, const int type)
{
BLI_assert(customdata_typemap_is_valid(data));
return data->typemap[type];
}
-int CustomData_get_layer_index_n(const CustomData *data, int type, int n)
+int CustomData_get_layer_index_n(const CustomData *data, const int type, const int n)
{
BLI_assert(n >= 0);
int i = CustomData_get_layer_index(data, type);
@@ -2475,7 +2540,7 @@ int CustomData_get_layer_index_n(const CustomData *data, int type, int n)
return i;
}
-int CustomData_get_named_layer_index(const CustomData *data, int type, const char *name)
+int CustomData_get_named_layer_index(const CustomData *data, const int type, const char *name)
{
for (int i = 0; i < data->totlayer; i++) {
if (data->layers[i].type == type) {
@@ -2488,28 +2553,28 @@ int CustomData_get_named_layer_index(const CustomData *data, int type, const cha
return -1;
}
-int CustomData_get_active_layer_index(const CustomData *data, int type)
+int CustomData_get_active_layer_index(const CustomData *data, const int type)
{
const int layer_index = data->typemap[type];
BLI_assert(customdata_typemap_is_valid(data));
return (layer_index != -1) ? layer_index + data->layers[layer_index].active : -1;
}
-int CustomData_get_render_layer_index(const CustomData *data, int type)
+int CustomData_get_render_layer_index(const CustomData *data, const int type)
{
const int layer_index = data->typemap[type];
BLI_assert(customdata_typemap_is_valid(data));
return (layer_index != -1) ? layer_index + data->layers[layer_index].active_rnd : -1;
}
-int CustomData_get_clone_layer_index(const CustomData *data, int type)
+int CustomData_get_clone_layer_index(const CustomData *data, const int type)
{
const int layer_index = data->typemap[type];
BLI_assert(customdata_typemap_is_valid(data));
return (layer_index != -1) ? layer_index + data->layers[layer_index].active_clone : -1;
}
-int CustomData_get_stencil_layer_index(const CustomData *data, int type)
+int CustomData_get_stencil_layer_index(const CustomData *data, const int type)
{
const int layer_index = data->typemap[type];
BLI_assert(customdata_typemap_is_valid(data));
@@ -2519,7 +2584,7 @@ int CustomData_get_stencil_layer_index(const CustomData *data, int type)
/* -------------------------------------------------------------------- */
/* index values per layer type */
-int CustomData_get_named_layer(const CustomData *data, int type, const char *name)
+int CustomData_get_named_layer(const CustomData *data, const int type, const char *name)
{
const int named_index = CustomData_get_named_layer_index(data, type, name);
const int layer_index = data->typemap[type];
@@ -2527,28 +2592,28 @@ int CustomData_get_named_layer(const CustomData *data, int type, const char *nam
return (named_index != -1) ? named_index - layer_index : -1;
}
-int CustomData_get_active_layer(const CustomData *data, int type)
+int CustomData_get_active_layer(const CustomData *data, const int type)
{
const int layer_index = data->typemap[type];
BLI_assert(customdata_typemap_is_valid(data));
return (layer_index != -1) ? data->layers[layer_index].active : -1;
}
-int CustomData_get_render_layer(const CustomData *data, int type)
+int CustomData_get_render_layer(const CustomData *data, const int type)
{
const int layer_index = data->typemap[type];
BLI_assert(customdata_typemap_is_valid(data));
return (layer_index != -1) ? data->layers[layer_index].active_rnd : -1;
}
-int CustomData_get_clone_layer(const CustomData *data, int type)
+int CustomData_get_clone_layer(const CustomData *data, const int type)
{
const int layer_index = data->typemap[type];
BLI_assert(customdata_typemap_is_valid(data));
return (layer_index != -1) ? data->layers[layer_index].active_clone : -1;
}
-int CustomData_get_stencil_layer(const CustomData *data, int type)
+int CustomData_get_stencil_layer(const CustomData *data, const int type)
{
const int layer_index = data->typemap[type];
BLI_assert(customdata_typemap_is_valid(data));
@@ -2562,7 +2627,13 @@ const char *CustomData_get_active_layer_name(const CustomData *data, const int t
return layer_index < 0 ? nullptr : data->layers[layer_index].name;
}
-void CustomData_set_layer_active(CustomData *data, int type, int n)
+const char *CustomData_get_render_layer_name(const CustomData *data, const int type)
+{
+ const int layer_index = CustomData_get_render_layer_index(data, type);
+ return layer_index < 0 ? nullptr : data->layers[layer_index].name;
+}
+
+void CustomData_set_layer_active(CustomData *data, const int type, const int n)
{
for (int i = 0; i < data->totlayer; i++) {
if (data->layers[i].type == type) {
@@ -2571,7 +2642,7 @@ void CustomData_set_layer_active(CustomData *data, int type, int n)
}
}
-void CustomData_set_layer_render(CustomData *data, int type, int n)
+void CustomData_set_layer_render(CustomData *data, const int type, const int n)
{
for (int i = 0; i < data->totlayer; i++) {
if (data->layers[i].type == type) {
@@ -2580,7 +2651,7 @@ void CustomData_set_layer_render(CustomData *data, int type, int n)
}
}
-void CustomData_set_layer_clone(CustomData *data, int type, int n)
+void CustomData_set_layer_clone(CustomData *data, const int type, const int n)
{
for (int i = 0; i < data->totlayer; i++) {
if (data->layers[i].type == type) {
@@ -2589,7 +2660,7 @@ void CustomData_set_layer_clone(CustomData *data, int type, int n)
}
}
-void CustomData_set_layer_stencil(CustomData *data, int type, int n)
+void CustomData_set_layer_stencil(CustomData *data, const int type, const int n)
{
for (int i = 0; i < data->totlayer; i++) {
if (data->layers[i].type == type) {
@@ -2598,7 +2669,7 @@ void CustomData_set_layer_stencil(CustomData *data, int type, int n)
}
}
-void CustomData_set_layer_active_index(CustomData *data, int type, int n)
+void CustomData_set_layer_active_index(CustomData *data, const int type, const int n)
{
const int layer_index = data->typemap[type];
BLI_assert(customdata_typemap_is_valid(data));
@@ -2610,7 +2681,7 @@ void CustomData_set_layer_active_index(CustomData *data, int type, int n)
}
}
-void CustomData_set_layer_render_index(CustomData *data, int type, int n)
+void CustomData_set_layer_render_index(CustomData *data, const int type, const int n)
{
const int layer_index = data->typemap[type];
BLI_assert(customdata_typemap_is_valid(data));
@@ -2622,7 +2693,7 @@ void CustomData_set_layer_render_index(CustomData *data, int type, int n)
}
}
-void CustomData_set_layer_clone_index(CustomData *data, int type, int n)
+void CustomData_set_layer_clone_index(CustomData *data, const int type, const int n)
{
const int layer_index = data->typemap[type];
BLI_assert(customdata_typemap_is_valid(data));
@@ -2634,7 +2705,7 @@ void CustomData_set_layer_clone_index(CustomData *data, int type, int n)
}
}
-void CustomData_set_layer_stencil_index(CustomData *data, int type, int n)
+void CustomData_set_layer_stencil_index(CustomData *data, const int type, const int n)
{
const int layer_index = data->typemap[type];
BLI_assert(customdata_typemap_is_valid(data));
@@ -2646,7 +2717,7 @@ void CustomData_set_layer_stencil_index(CustomData *data, int type, int n)
}
}
-void CustomData_set_layer_flag(CustomData *data, int type, int flag)
+void CustomData_set_layer_flag(CustomData *data, const int type, const int flag)
{
for (int i = 0; i < data->totlayer; i++) {
if (data->layers[i].type == type) {
@@ -2655,7 +2726,7 @@ void CustomData_set_layer_flag(CustomData *data, int type, int flag)
}
}
-void CustomData_clear_layer_flag(CustomData *data, int type, int flag)
+void CustomData_clear_layer_flag(CustomData *data, const int type, const int flag)
{
const int nflag = ~flag;
@@ -2666,7 +2737,7 @@ void CustomData_clear_layer_flag(CustomData *data, int type, int flag)
}
}
-static bool customData_resize(CustomData *data, int amount)
+static bool customData_resize(CustomData *data, const int amount)
{
CustomDataLayer *tmp = static_cast<CustomDataLayer *>(
MEM_calloc_arrayN((data->maxlayer + amount), sizeof(*tmp), __func__));
@@ -2685,15 +2756,14 @@ static bool customData_resize(CustomData *data, int amount)
}
static CustomDataLayer *customData_add_layer__internal(CustomData *data,
- int type,
- eCDAllocType alloctype,
+ const int type,
+ const eCDAllocType alloctype,
void *layerdata,
- int totelem,
+ const int totelem,
const char *name)
{
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
- int flag = 0, index = data->totlayer;
- void *newlayerdata = nullptr;
+ int flag = 0;
/* Passing a layer-data to copy from with an alloctype that won't copy is
* most likely a bug */
@@ -2703,6 +2773,7 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
return &data->layers[CustomData_get_layer_index(data, type)];
}
+ void *newlayerdata = nullptr;
if (ELEM(alloctype, CD_ASSIGN, CD_REFERENCE)) {
newlayerdata = layerdata;
}
@@ -2738,6 +2809,7 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
flag |= CD_FLAG_NOFREE;
}
+ int index = data->totlayer;
if (index >= data->maxlayer) {
if (!customData_resize(data, CUSTOMDATA_GROW)) {
if (newlayerdata != layerdata) {
@@ -2754,14 +2826,16 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
data->layers[index] = data->layers[index - 1];
}
+ CustomDataLayer &new_layer = data->layers[index];
+
/* Clear remaining data on the layer. The original data on the layer has been moved to another
* index. Without this, it can happen that information from the previous layer at that index
* leaks into the new layer. */
- memset(data->layers + index, 0, sizeof(CustomDataLayer));
+ memset(&new_layer, 0, sizeof(CustomDataLayer));
- data->layers[index].type = type;
- data->layers[index].flag = flag;
- data->layers[index].data = newlayerdata;
+ new_layer.type = type;
+ new_layer.flag = flag;
+ new_layer.data = newlayerdata;
/* Set default name if none exists. Note we only call DATA_() once
* we know there is a default name, to avoid overhead of locale lookups
@@ -2771,24 +2845,24 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
}
if (name) {
- BLI_strncpy(data->layers[index].name, name, sizeof(data->layers[index].name));
+ BLI_strncpy(new_layer.name, name, sizeof(new_layer.name));
CustomData_set_layer_unique_name(data, index);
}
else {
- data->layers[index].name[0] = '\0';
+ new_layer.name[0] = '\0';
}
if (index > 0 && data->layers[index - 1].type == type) {
- data->layers[index].active = data->layers[index - 1].active;
- data->layers[index].active_rnd = data->layers[index - 1].active_rnd;
- data->layers[index].active_clone = data->layers[index - 1].active_clone;
- data->layers[index].active_mask = data->layers[index - 1].active_mask;
+ new_layer.active = data->layers[index - 1].active;
+ new_layer.active_rnd = data->layers[index - 1].active_rnd;
+ new_layer.active_clone = data->layers[index - 1].active_clone;
+ new_layer.active_mask = data->layers[index - 1].active_mask;
}
else {
- data->layers[index].active = 0;
- data->layers[index].active_rnd = 0;
- data->layers[index].active_clone = 0;
- data->layers[index].active_mask = 0;
+ new_layer.active = 0;
+ new_layer.active_rnd = 0;
+ new_layer.active_clone = 0;
+ new_layer.active_mask = 0;
}
customData_update_offsets(data);
@@ -2797,7 +2871,7 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
}
void *CustomData_add_layer(
- CustomData *data, int type, eCDAllocType alloctype, void *layerdata, int totelem)
+ CustomData *data, const int type, eCDAllocType alloctype, void *layerdata, const int totelem)
{
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
@@ -2813,10 +2887,10 @@ void *CustomData_add_layer(
}
void *CustomData_add_layer_named(CustomData *data,
- int type,
- eCDAllocType alloctype,
+ const int type,
+ const eCDAllocType alloctype,
void *layerdata,
- int totelem,
+ const int totelem,
const char *name)
{
CustomDataLayer *layer = customData_add_layer__internal(
@@ -2831,10 +2905,10 @@ void *CustomData_add_layer_named(CustomData *data,
}
void *CustomData_add_layer_anonymous(CustomData *data,
- int type,
- eCDAllocType alloctype,
+ const int type,
+ const eCDAllocType alloctype,
void *layerdata,
- int totelem,
+ const int totelem,
const AnonymousAttributeID *anonymous_id)
{
const char *name = BKE_anonymous_attribute_id_internal_name(anonymous_id);
@@ -2851,7 +2925,7 @@ void *CustomData_add_layer_anonymous(CustomData *data,
return layer->data;
}
-bool CustomData_free_layer(CustomData *data, int type, int totelem, int index)
+bool CustomData_free_layer(CustomData *data, const int type, const int totelem, const int index)
{
const int index_first = CustomData_get_layer_index(data, type);
const int n = index - index_first;
@@ -2915,7 +2989,7 @@ bool CustomData_free_layer_named(CustomData *data, const char *name, const int t
return false;
}
-bool CustomData_free_layer_active(CustomData *data, int type, int totelem)
+bool CustomData_free_layer_active(CustomData *data, const int type, const int totelem)
{
const int index = CustomData_get_active_layer_index(data, type);
if (index == -1) {
@@ -2924,7 +2998,7 @@ bool CustomData_free_layer_active(CustomData *data, int type, int totelem)
return CustomData_free_layer(data, type, totelem, index);
}
-void CustomData_free_layers(CustomData *data, int type, int totelem)
+void CustomData_free_layers(CustomData *data, const int type, const int totelem)
{
const int index = CustomData_get_layer_index(data, type);
while (CustomData_free_layer(data, type, totelem, index)) {
@@ -2932,12 +3006,12 @@ void CustomData_free_layers(CustomData *data, int type, int totelem)
}
}
-bool CustomData_has_layer(const CustomData *data, int type)
+bool CustomData_has_layer(const CustomData *data, const int type)
{
return (CustomData_get_layer_index(data, type) != -1);
}
-int CustomData_number_of_layers(const CustomData *data, int type)
+int CustomData_number_of_layers(const CustomData *data, const int type)
{
int number = 0;
@@ -2950,7 +3024,7 @@ int CustomData_number_of_layers(const CustomData *data, int type)
return number;
}
-int CustomData_number_of_layers_typemask(const CustomData *data, eCustomDataMask mask)
+int CustomData_number_of_layers_typemask(const CustomData *data, const eCustomDataMask mask)
{
int number = 0;
@@ -3040,7 +3114,7 @@ void *CustomData_duplicate_referenced_layer_anonymous(CustomData *data,
return nullptr;
}
-void CustomData_duplicate_referenced_layers(CustomData *data, int totelem)
+void CustomData_duplicate_referenced_layers(CustomData *data, const int totelem)
{
for (int i = 0; i < data->totlayer; i++) {
CustomDataLayer *layer = &data->layers[i];
@@ -3048,7 +3122,7 @@ void CustomData_duplicate_referenced_layers(CustomData *data, int totelem)
}
}
-bool CustomData_is_referenced_layer(CustomData *data, int type)
+bool CustomData_is_referenced_layer(CustomData *data, const int type)
{
/* get the layer index of the first layer of type */
int layer_index = CustomData_get_active_layer_index(data, type);
@@ -3061,7 +3135,7 @@ bool CustomData_is_referenced_layer(CustomData *data, int type)
return (layer->flag & CD_FLAG_NOFREE) != 0;
}
-void CustomData_free_temporary(CustomData *data, int totelem)
+void CustomData_free_temporary(CustomData *data, const int totelem)
{
int i, j;
bool changed = false;
@@ -3093,7 +3167,7 @@ void CustomData_free_temporary(CustomData *data, int totelem)
}
}
-void CustomData_set_only_copy(const CustomData *data, eCustomDataMask mask)
+void CustomData_set_only_copy(const CustomData *data, const eCustomDataMask mask)
{
for (int i = 0; i < data->totlayer; i++) {
if (!(mask & CD_TYPE_AS_MASK(data->layers[i].type))) {
@@ -3102,7 +3176,10 @@ void CustomData_set_only_copy(const CustomData *data, eCustomDataMask mask)
}
}
-void CustomData_copy_elements(int type, void *src_data_ofs, void *dst_data_ofs, int count)
+void CustomData_copy_elements(const int type,
+ void *src_data_ofs,
+ void *dst_data_ofs,
+ const int count)
{
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
@@ -3116,11 +3193,11 @@ void CustomData_copy_elements(int type, void *src_data_ofs, void *dst_data_ofs,
void CustomData_copy_data_layer(const CustomData *source,
CustomData *dest,
- int src_layer_index,
- int dst_layer_index,
- int src_index,
- int dst_index,
- int count)
+ const int src_layer_index,
+ const int dst_layer_index,
+ const int src_index,
+ const int dst_index,
+ const int count)
{
const LayerTypeInfo *typeInfo;
@@ -3154,8 +3231,11 @@ void CustomData_copy_data_layer(const CustomData *source,
}
}
-void CustomData_copy_data_named(
- const CustomData *source, CustomData *dest, int source_index, int dest_index, int count)
+void CustomData_copy_data_named(const CustomData *source,
+ CustomData *dest,
+ const int source_index,
+ const int dest_index,
+ const int count)
{
/* copies a layer at a time */
for (int src_i = 0; src_i < source->totlayer; src_i++) {
@@ -3170,8 +3250,11 @@ void CustomData_copy_data_named(
}
}
-void CustomData_copy_data(
- const CustomData *source, CustomData *dest, int source_index, int dest_index, int count)
+void CustomData_copy_data(const CustomData *source,
+ CustomData *dest,
+ const int source_index,
+ const int dest_index,
+ const int count)
{
/* copies a layer at a time */
int dest_i = 0;
@@ -3226,7 +3309,7 @@ void CustomData_copy_layer_type_data(const CustomData *source,
count);
}
-void CustomData_free_elem(CustomData *data, int index, int count)
+void CustomData_free_elem(CustomData *data, const int index, const int count)
{
for (int i = 0; i < data->totlayer; i++) {
if (!(data->layers[i].flag & CD_FLAG_NOFREE)) {
@@ -3326,7 +3409,7 @@ void CustomData_interp(const CustomData *source,
}
}
-void CustomData_swap_corners(CustomData *data, int index, const int *corner_indices)
+void CustomData_swap_corners(CustomData *data, const int index, const int *corner_indices)
{
for (int i = 0; i < data->totlayer; i++) {
const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[i].type);
@@ -3366,7 +3449,7 @@ void CustomData_swap(CustomData *data, const int index_a, const int index_b)
}
}
-void *CustomData_get(const CustomData *data, int index, int type)
+void *CustomData_get(const CustomData *data, const int index, const int type)
{
BLI_assert(index >= 0);
@@ -3382,7 +3465,7 @@ void *CustomData_get(const CustomData *data, int index, int type)
return POINTER_OFFSET(data->layers[layer_index].data, offset);
}
-void *CustomData_get_n(const CustomData *data, int type, int index, int n)
+void *CustomData_get_n(const CustomData *data, const int type, const int index, const int n)
{
BLI_assert(index >= 0 && n >= 0);
@@ -3396,7 +3479,7 @@ void *CustomData_get_n(const CustomData *data, int type, int index, int n)
return POINTER_OFFSET(data->layers[layer_index + n].data, offset);
}
-void *CustomData_get_layer(const CustomData *data, int type)
+void *CustomData_get_layer(const CustomData *data, const int type)
{
/* get the layer index of the active layer of type */
int layer_index = CustomData_get_active_layer_index(data, type);
@@ -3407,7 +3490,7 @@ void *CustomData_get_layer(const CustomData *data, int type)
return data->layers[layer_index].data;
}
-void *CustomData_get_layer_n(const CustomData *data, int type, int n)
+void *CustomData_get_layer_n(const CustomData *data, const int type, const int n)
{
/* get the layer index of the active layer of type */
int layer_index = CustomData_get_layer_index_n(data, type, n);
@@ -3418,7 +3501,7 @@ void *CustomData_get_layer_n(const CustomData *data, int type, int n)
return data->layers[layer_index].data;
}
-void *CustomData_get_layer_named(const CustomData *data, int type, const char *name)
+void *CustomData_get_layer_named(const CustomData *data, const int type, const char *name)
{
int layer_index = CustomData_get_named_layer_index(data, type, name);
if (layer_index == -1) {
@@ -3428,7 +3511,7 @@ void *CustomData_get_layer_named(const CustomData *data, int type, const char *n
return data->layers[layer_index].data;
}
-int CustomData_get_offset(const CustomData *data, int type)
+int CustomData_get_offset(const CustomData *data, const int type)
{
/* get the layer index of the active layer of type */
int layer_index = CustomData_get_active_layer_index(data, type);
@@ -3439,10 +3522,10 @@ int CustomData_get_offset(const CustomData *data, int type)
return data->layers[layer_index].offset;
}
-int CustomData_get_offset_named(const CustomData *data, int type, const char *name)
+int CustomData_get_n_offset(const CustomData *data, const int type, const int n)
{
/* get the layer index of the active layer of type */
- int layer_index = CustomData_get_named_layer_index(data, type, name);
+ int layer_index = CustomData_get_layer_index_n(data, type, n);
if (layer_index == -1) {
return -1;
}
@@ -3450,10 +3533,9 @@ int CustomData_get_offset_named(const CustomData *data, int type, const char *na
return data->layers[layer_index].offset;
}
-int CustomData_get_n_offset(const CustomData *data, int type, int n)
+int CustomData_get_offset_named(const CustomData *data, int type, const char *name)
{
- /* get the layer index of the active layer of type */
- int layer_index = CustomData_get_layer_index_n(data, type, n);
+ int layer_index = CustomData_get_named_layer_index(data, type, name);
if (layer_index == -1) {
return -1;
}
@@ -3461,7 +3543,7 @@ int CustomData_get_n_offset(const CustomData *data, int type, int n)
return data->layers[layer_index].offset;
}
-bool CustomData_set_layer_name(const CustomData *data, int type, int n, const char *name)
+bool CustomData_set_layer_name(CustomData *data, const int type, const int n, const char *name)
{
/* get the layer index of the first layer of type */
const int layer_index = CustomData_get_layer_index_n(data, type, n);
@@ -3475,14 +3557,14 @@ bool CustomData_set_layer_name(const CustomData *data, int type, int n, const ch
return true;
}
-const char *CustomData_get_layer_name(const CustomData *data, int type, int n)
+const char *CustomData_get_layer_name(const CustomData *data, const int type, const int n)
{
const int layer_index = CustomData_get_layer_index_n(data, type, n);
return (layer_index == -1) ? nullptr : data->layers[layer_index].name;
}
-void *CustomData_set_layer(const CustomData *data, int type, void *ptr)
+void *CustomData_set_layer(const CustomData *data, const int type, void *ptr)
{
/* get the layer index of the first layer of type */
int layer_index = CustomData_get_active_layer_index(data, type);
@@ -3496,7 +3578,7 @@ void *CustomData_set_layer(const CustomData *data, int type, void *ptr)
return ptr;
}
-void *CustomData_set_layer_n(const CustomData *data, int type, int n, void *ptr)
+void *CustomData_set_layer_n(const CustomData *data, const int type, const int n, void *ptr)
{
/* get the layer index of the first layer of type */
int layer_index = CustomData_get_layer_index_n(data, type, n);
@@ -3509,7 +3591,7 @@ void *CustomData_set_layer_n(const CustomData *data, int type, int n, void *ptr)
return ptr;
}
-void CustomData_set(const CustomData *data, int index, int type, const void *source)
+void CustomData_set(const CustomData *data, const int index, const int type, const void *source)
{
void *dest = CustomData_get(data, index, type);
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
@@ -3561,7 +3643,7 @@ void CustomData_bmesh_update_active_layers(CustomData *fdata, CustomData *ldata)
}
}
-void CustomData_bmesh_init_pool(CustomData *data, int totelem, const char htype)
+void CustomData_bmesh_init_pool(CustomData *data, const int totelem, const char htype)
{
int chunksize;
@@ -3763,7 +3845,7 @@ void CustomData_bmesh_free_block_data_exclude_by_type(CustomData *data,
}
}
-static void CustomData_bmesh_set_default_n(CustomData *data, void **block, int n)
+static void CustomData_bmesh_set_default_n(CustomData *data, void **block, const int n)
{
int offset = data->layers[n].offset;
const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[n].type);
@@ -3858,7 +3940,7 @@ void CustomData_bmesh_copy_data(const CustomData *source,
CustomData_bmesh_copy_data_exclude_by_type(source, dest, src_block, dest_block, 0);
}
-void *CustomData_bmesh_get(const CustomData *data, void *block, int type)
+void *CustomData_bmesh_get(const CustomData *data, void *block, const int type)
{
/* get the layer index of the first layer of type */
int layer_index = CustomData_get_active_layer_index(data, type);
@@ -3869,7 +3951,7 @@ void *CustomData_bmesh_get(const CustomData *data, void *block, int type)
return POINTER_OFFSET(block, data->layers[layer_index].offset);
}
-void *CustomData_bmesh_get_n(const CustomData *data, void *block, int type, int n)
+void *CustomData_bmesh_get_n(const CustomData *data, void *block, const int type, const int n)
{
/* get the layer index of the first layer of type */
int layer_index = CustomData_get_layer_index(data, type);
@@ -3880,7 +3962,7 @@ void *CustomData_bmesh_get_n(const CustomData *data, void *block, int type, int
return POINTER_OFFSET(block, data->layers[layer_index + n].offset);
}
-void *CustomData_bmesh_get_layer_n(const CustomData *data, void *block, int n)
+void *CustomData_bmesh_get_layer_n(const CustomData *data, void *block, const int n)
{
if (n < 0 || n >= data->totlayer) {
return nullptr;
@@ -3889,7 +3971,7 @@ void *CustomData_bmesh_get_layer_n(const CustomData *data, void *block, int n)
return POINTER_OFFSET(block, data->layers[n].offset);
}
-bool CustomData_layer_has_math(const CustomData *data, int layer_n)
+bool CustomData_layer_has_math(const CustomData *data, const int layer_n)
{
const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[layer_n].type);
@@ -3901,7 +3983,7 @@ bool CustomData_layer_has_math(const CustomData *data, int layer_n)
return false;
}
-bool CustomData_layer_has_interp(const CustomData *data, int layer_n)
+bool CustomData_layer_has_interp(const CustomData *data, const int layer_n)
{
const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[layer_n].type);
@@ -4022,7 +4104,7 @@ void CustomData_data_dominmax(int type, const void *data, void *min, void *max)
}
}
-void CustomData_data_multiply(int type, void *data, float fac)
+void CustomData_data_multiply(int type, void *data, const float fac)
{
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
@@ -4040,7 +4122,7 @@ void CustomData_data_add(int type, void *data1, const void *data2)
}
}
-void CustomData_bmesh_set(const CustomData *data, void *block, int type, const void *source)
+void CustomData_bmesh_set(const CustomData *data, void *block, const int type, const void *source)
{
void *dest = CustomData_bmesh_get(data, block, type);
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
@@ -4057,7 +4139,8 @@ void CustomData_bmesh_set(const CustomData *data, void *block, int type, const v
}
}
-void CustomData_bmesh_set_n(CustomData *data, void *block, int type, int n, const void *source)
+void CustomData_bmesh_set_n(
+ CustomData *data, void *block, const int type, const int n, const void *source)
{
void *dest = CustomData_bmesh_get_n(data, block, type, n);
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
@@ -4074,7 +4157,7 @@ void CustomData_bmesh_set_n(CustomData *data, void *block, int type, int n, cons
}
}
-void CustomData_bmesh_set_layer_n(CustomData *data, void *block, int n, const void *source)
+void CustomData_bmesh_set_layer_n(CustomData *data, void *block, const int n, const void *source)
{
void *dest = CustomData_bmesh_get_layer_n(data, block, n);
const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[n].type);
@@ -4273,7 +4356,9 @@ void CustomData_file_write_info(int type, const char **r_struct_name, int *r_str
*r_struct_num = typeInfo->structnum;
}
-void CustomData_blend_write_prepare(CustomData &data, Vector<CustomDataLayer, 16> &layers_to_write)
+void CustomData_blend_write_prepare(CustomData &data,
+ Vector<CustomDataLayer, 16> &layers_to_write,
+ const Set<std::string> &skip_names)
{
for (const CustomDataLayer &layer : Span(data.layers, data.totlayer)) {
if (layer.flag & CD_FLAG_NOCOPY) {
@@ -4282,6 +4367,9 @@ void CustomData_blend_write_prepare(CustomData &data, Vector<CustomDataLayer, 16
if (layer.anonymous_id != nullptr) {
continue;
}
+ if (skip_names.contains(layer.name)) {
+ continue;
+ }
layers_to_write.append(layer);
}
data.totlayer = layers_to_write.size();
@@ -4328,7 +4416,7 @@ int CustomData_layertype_layers_max(const int type)
return typeInfo->layers_max();
}
-static bool cd_layer_find_dupe(CustomData *data, const char *name, int type, int index)
+static bool cd_layer_find_dupe(CustomData *data, const char *name, const int type, const int index)
{
/* see if there is a duplicate */
for (int i = 0; i < data->totlayer; i++) {
@@ -4363,7 +4451,7 @@ static bool customdata_unique_check(void *arg, const char *name)
return cd_layer_find_dupe(data_arg->data, name, data_arg->type, data_arg->index);
}
-void CustomData_set_layer_unique_name(CustomData *data, int index)
+void CustomData_set_layer_unique_name(CustomData *data, const int index)
{
CustomDataLayer *nlayer = &data->layers[index];
const LayerTypeInfo *typeInfo = layerType_getInfo(nlayer->type);
@@ -4408,7 +4496,7 @@ void CustomData_validate_layer_name(const CustomData *data,
}
}
-bool CustomData_verify_versions(CustomData *data, int index)
+bool CustomData_verify_versions(CustomData *data, const int index)
{
const LayerTypeInfo *typeInfo;
CustomDataLayer *layer = &data->layers[index];
@@ -4567,7 +4655,7 @@ void CustomData_external_reload(CustomData *data,
}
}
-void CustomData_external_read(CustomData *data, ID *id, eCustomDataMask mask, int totelem)
+void CustomData_external_read(CustomData *data, ID *id, eCustomDataMask mask, const int totelem)
{
CustomDataExternal *external = data->external;
CustomDataLayer *layer;
@@ -4641,7 +4729,7 @@ void CustomData_external_read(CustomData *data, ID *id, eCustomDataMask mask, in
}
void CustomData_external_write(
- CustomData *data, ID *id, eCustomDataMask mask, int totelem, int free)
+ CustomData *data, ID *id, eCustomDataMask mask, const int totelem, const int free)
{
CustomDataExternal *external = data->external;
int update = 0;
@@ -4743,8 +4831,11 @@ void CustomData_external_write(
cdf_free(cdf);
}
-void CustomData_external_add(
- CustomData *data, ID *UNUSED(id), int type, int UNUSED(totelem), const char *filepath)
+void CustomData_external_add(CustomData *data,
+ ID *UNUSED(id),
+ const int type,
+ const int UNUSED(totelem),
+ const char *filepath)
{
CustomDataExternal *external = data->external;
@@ -4768,7 +4859,7 @@ void CustomData_external_add(
layer->flag |= CD_FLAG_EXTERNAL | CD_FLAG_IN_MEMORY;
}
-void CustomData_external_remove(CustomData *data, ID *id, int type, int totelem)
+void CustomData_external_remove(CustomData *data, ID *id, const int type, const int totelem)
{
CustomDataExternal *external = data->external;
@@ -4792,7 +4883,7 @@ void CustomData_external_remove(CustomData *data, ID *id, int type, int totelem)
}
}
-bool CustomData_external_test(CustomData *data, int type)
+bool CustomData_external_test(CustomData *data, const int type)
{
int layer_index = CustomData_get_active_layer_index(data, type);
if (layer_index == -1) {
@@ -5093,7 +5184,10 @@ void CustomData_data_transfer(const MeshPairRemap *me_remap,
/** \name Custom Data IO
* \{ */
-static void write_mdisps(BlendWriter *writer, int count, const MDisps *mdlist, int external)
+static void write_mdisps(BlendWriter *writer,
+ const int count,
+ const MDisps *mdlist,
+ const int external)
{
if (mdlist) {
BLO_write_struct_array(writer, MDisps, count, mdlist);
@@ -5193,7 +5287,10 @@ void CustomData_blend_write(BlendWriter *writer,
}
}
-static void blend_read_mdisps(BlendDataReader *reader, int count, MDisps *mdisps, int external)
+static void blend_read_mdisps(BlendDataReader *reader,
+ const int count,
+ MDisps *mdisps,
+ const int external)
{
if (mdisps) {
for (int i = 0; i < count; i++) {
@@ -5235,7 +5332,7 @@ static void blend_read_paint_mask(BlendDataReader *reader,
}
}
-void CustomData_blend_read(BlendDataReader *reader, CustomData *data, int count)
+void CustomData_blend_read(BlendDataReader *reader, CustomData *data, const int count)
{
BLO_read_data_address(reader, &data->layers);
diff --git a/source/blender/blenkernel/intern/data_transfer.c b/source/blender/blenkernel/intern/data_transfer.c
index 17a74b5564a..be686635d3e 100644
--- a/source/blender/blenkernel/intern/data_transfer.c
+++ b/source/blender/blenkernel/intern/data_transfer.c
@@ -70,8 +70,6 @@ void BKE_object_data_transfer_dttypes_to_cdmask(const int dtdata_types,
r_data_masks->lmask |= CD_MASK_MLOOPUV;
}
else if (cddata_type == CD_FAKE_LNOR) {
- r_data_masks->vmask |= CD_MASK_NORMAL;
- r_data_masks->pmask |= CD_MASK_NORMAL;
r_data_masks->lmask |= CD_MASK_NORMAL | CD_MASK_CUSTOMLOOPNORMAL;
}
}
diff --git a/source/blender/blenkernel/intern/displist.cc b/source/blender/blenkernel/intern/displist.cc
index 823fce52b50..b87d675496c 100644
--- a/source/blender/blenkernel/intern/displist.cc
+++ b/source/blender/blenkernel/intern/displist.cc
@@ -34,10 +34,8 @@
#include "BKE_displist.h"
#include "BKE_geometry_set.hh"
#include "BKE_key.h"
-#include "BKE_lattice.h"
#include "BKE_lib_id.h"
#include "BKE_mball.h"
-#include "BKE_mball_tessellate.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
@@ -86,133 +84,6 @@ DispList *BKE_displist_find(ListBase *lb, int type)
return nullptr;
}
-void BKE_displist_copy(ListBase *lbn, const ListBase *lb)
-{
- BKE_displist_free(lbn);
-
- LISTBASE_FOREACH (const DispList *, dl, lb) {
- DispList *dln = (DispList *)MEM_dupallocN(dl);
- BLI_addtail(lbn, dln);
- dln->verts = (float *)MEM_dupallocN(dl->verts);
- dln->nors = (float *)MEM_dupallocN(dl->nors);
- dln->index = (int *)MEM_dupallocN(dl->index);
- }
-}
-
-void BKE_displist_normals_add(ListBase *lb)
-{
- float *vdata, *ndata, nor[3];
- float *v1, *v2, *v3, *v4;
- float *n1, *n2, *n3, *n4;
- int a, b, p1, p2, p3, p4;
-
- LISTBASE_FOREACH (DispList *, dl, lb) {
- if (dl->type == DL_INDEX3) {
- if (dl->nors == nullptr) {
- dl->nors = (float *)MEM_callocN(sizeof(float[3]), __func__);
-
- if (dl->flag & DL_BACK_CURVE) {
- dl->nors[2] = -1.0f;
- }
- else {
- dl->nors[2] = 1.0f;
- }
- }
- }
- else if (dl->type == DL_SURF) {
- if (dl->nors == nullptr) {
- dl->nors = (float *)MEM_callocN(sizeof(float[3]) * dl->nr * dl->parts, __func__);
-
- vdata = dl->verts;
- ndata = dl->nors;
-
- for (a = 0; a < dl->parts; a++) {
-
- if (BKE_displist_surfindex_get(dl, a, &b, &p1, &p2, &p3, &p4) == 0) {
- break;
- }
-
- v1 = vdata + 3 * p1;
- n1 = ndata + 3 * p1;
- v2 = vdata + 3 * p2;
- n2 = ndata + 3 * p2;
- v3 = vdata + 3 * p3;
- n3 = ndata + 3 * p3;
- v4 = vdata + 3 * p4;
- n4 = ndata + 3 * p4;
-
- for (; b < dl->nr; b++) {
- normal_quad_v3(nor, v1, v3, v4, v2);
-
- add_v3_v3(n1, nor);
- add_v3_v3(n2, nor);
- add_v3_v3(n3, nor);
- add_v3_v3(n4, nor);
-
- v2 = v1;
- v1 += 3;
- v4 = v3;
- v3 += 3;
- n2 = n1;
- n1 += 3;
- n4 = n3;
- n3 += 3;
- }
- }
- a = dl->parts * dl->nr;
- v1 = ndata;
- while (a--) {
- normalize_v3(v1);
- v1 += 3;
- }
- }
- }
- }
-}
-
-void BKE_displist_count(const ListBase *lb, int *totvert, int *totface, int *tottri)
-{
- LISTBASE_FOREACH (const DispList *, dl, lb) {
- int vert_tot = 0;
- int face_tot = 0;
- int tri_tot = 0;
- bool cyclic_u = dl->flag & DL_CYCL_U;
- bool cyclic_v = dl->flag & DL_CYCL_V;
-
- switch (dl->type) {
- case DL_SURF: {
- int segments_u = dl->nr - (cyclic_u == false);
- int segments_v = dl->parts - (cyclic_v == false);
- vert_tot = dl->nr * dl->parts;
- face_tot = segments_u * segments_v;
- tri_tot = face_tot * 2;
- break;
- }
- case DL_INDEX3: {
- vert_tot = dl->nr;
- face_tot = dl->parts;
- tri_tot = face_tot;
- break;
- }
- case DL_INDEX4: {
- vert_tot = dl->nr;
- face_tot = dl->parts;
- tri_tot = face_tot * 2;
- break;
- }
- case DL_POLY:
- case DL_SEGM: {
- vert_tot = dl->nr * dl->parts;
- break;
- }
- }
-
- *totvert += vert_tot;
- *totface += face_tot;
- *tottri += tri_tot;
- }
-}
-
bool BKE_displist_surfindex_get(
const DispList *dl, int a, int *b, int *p1, int *p2, int *p3, int *p4)
{
@@ -243,7 +114,6 @@ bool BKE_displist_surfindex_get(
return true;
}
-/* ****************** Make #DispList ********************* */
#ifdef __INTEL_COMPILER
/* ICC with the optimization -02 causes crashes. */
# pragma intel optimization_level 1
@@ -638,27 +508,6 @@ float BKE_displist_calc_taper(
return displist_calc_taper(depsgraph, scene, taperobj, fac);
}
-void BKE_displist_make_mball(Depsgraph *depsgraph, Scene *scene, Object *ob)
-{
- if (!ob || ob->type != OB_MBALL) {
- return;
- }
-
- if (ob == BKE_mball_basis_find(scene, ob)) {
- if (ob->runtime.curve_cache) {
- BKE_displist_free(&(ob->runtime.curve_cache->disp));
- }
- else {
- ob->runtime.curve_cache = MEM_cnew<CurveCache>(__func__);
- }
-
- BKE_mball_polygonize(depsgraph, scene, ob, &ob->runtime.curve_cache->disp);
- BKE_mball_texspace_calc(ob);
-
- object_deform_mball(ob, &ob->runtime.curve_cache->disp);
- }
-}
-
static ModifierData *curve_get_tessellate_point(const Scene *scene,
const Object *ob,
const bool for_render,
@@ -1493,7 +1342,7 @@ void BKE_displist_make_curveTypes(Depsgraph *depsgraph,
* - The dependency graph has handling of edit mode pointers (see #update_edit_mode_pointers)
* but it doesn't seem to work in this case.
*
- * Since the the plan is to replace this legacy curve object with the curves data-block
+ * Since the plan is to replace this legacy curve object with the curves data-block
* (see T95355), this somewhat hacky inefficient solution is relatively temporary.
*/
Curve &cow_curve = *reinterpret_cast<Curve *>(
@@ -1514,20 +1363,19 @@ void BKE_displist_make_curveTypes(Depsgraph *depsgraph,
void BKE_displist_minmax(const ListBase *dispbase, float min[3], float max[3])
{
- bool doit = false;
+ bool empty = true;
LISTBASE_FOREACH (const DispList *, dl, dispbase) {
- const int tot = (ELEM(dl->type, DL_INDEX3, DL_INDEX4)) ? dl->nr : dl->nr * dl->parts;
+ const int tot = dl->type == DL_INDEX3 ? dl->nr : dl->nr * dl->parts;
for (const int i : IndexRange(tot)) {
minmax_v3v3_v3(min, max, &dl->verts[i * 3]);
}
if (tot != 0) {
- doit = true;
+ empty = false;
}
}
- if (!doit) {
- /* there's no geometry in displist, use zero-sized boundbox */
+ if (empty) {
zero_v3(min);
zero_v3(max);
}
diff --git a/source/blender/blenkernel/intern/gpencil_curve.c b/source/blender/blenkernel/intern/gpencil_curve.c
index d68b322e4c5..bf224a9613e 100644
--- a/source/blender/blenkernel/intern/gpencil_curve.c
+++ b/source/blender/blenkernel/intern/gpencil_curve.c
@@ -337,7 +337,6 @@ static void gpencil_convert_spline(Main *bmain,
/* Add stroke to frame. */
BLI_addtail(&gpf->strokes, gps);
- float *coord_array = NULL;
float init_co[3];
switch (nu->type) {
@@ -376,8 +375,7 @@ static void gpencil_convert_spline(Main *bmain,
BezTriple *bezt = &nu->bezt[inext];
bool last = (bool)(s == segments - 1);
- coord_array = MEM_callocN((size_t)3 * resolu * sizeof(float), __func__);
-
+ float *coord_array = MEM_callocN(sizeof(float[3]) * resolu, __func__);
for (int j = 0; j < 3; j++) {
BKE_curve_forward_diff_bezier(prevbezt->vec[1][j],
prevbezt->vec[2][j],
@@ -397,8 +395,9 @@ static void gpencil_convert_spline(Main *bmain,
gpencil_add_new_points(
gps, coord_array, radius_start, radius_end, init, resolu, init_co, last);
+
/* Free memory. */
- MEM_SAFE_FREE(coord_array);
+ MEM_freeN(coord_array);
/* As the last point of segment is the first point of next segment, back one array
* element to avoid duplicated points on the same location.
@@ -419,7 +418,7 @@ static void gpencil_convert_spline(Main *bmain,
nurb_points = (nu->pntsu - 1) * resolu;
}
/* Get all curve points. */
- coord_array = MEM_callocN(sizeof(float[3]) * nurb_points, __func__);
+ float *coord_array = MEM_callocN(sizeof(float[3]) * nurb_points, __func__);
BKE_nurb_makeCurve(nu, coord_array, NULL, NULL, NULL, resolu, sizeof(float[3]));
/* Allocate memory for storage points. */
@@ -429,7 +428,7 @@ static void gpencil_convert_spline(Main *bmain,
/* Add points. */
gpencil_add_new_points(gps, coord_array, 1.0f, 1.0f, 0, gps->totpoints, init_co, false);
- MEM_SAFE_FREE(coord_array);
+ MEM_freeN(coord_array);
}
break;
}
diff --git a/source/blender/blenkernel/intern/gpencil_modifier.c b/source/blender/blenkernel/intern/gpencil_modifier.c
index 82899b974bc..8ac268b26b0 100644
--- a/source/blender/blenkernel/intern/gpencil_modifier.c
+++ b/source/blender/blenkernel/intern/gpencil_modifier.c
@@ -360,7 +360,8 @@ GpencilModifierData *BKE_gpencil_modifier_new(int type)
md->type = type;
md->mode = eGpencilModifierMode_Realtime | eGpencilModifierMode_Render;
md->flag = eGpencilModifierFlag_OverrideLibrary_Local;
- md->ui_expand_flag = 1; /* Only expand the parent panel at first. */
+ /* Only expand the parent panel at first. */
+ md->ui_expand_flag = UI_PANEL_DATA_EXPAND_ROOT;
if (mti->flags & eGpencilModifierTypeFlag_EnableInEditmode) {
md->mode |= eGpencilModifierMode_Editmode;
diff --git a/source/blender/blenkernel/intern/icons_rasterize.c b/source/blender/blenkernel/intern/icons_rasterize.c
index 5603d84022d..00dbdcfa1e5 100644
--- a/source/blender/blenkernel/intern/icons_rasterize.c
+++ b/source/blender/blenkernel/intern/icons_rasterize.c
@@ -76,7 +76,7 @@ ImBuf *BKE_icon_geom_rasterize(const struct Icon_Geom *geom,
const uchar(*pos)[2] = geom->coords;
const uint *col = (void *)geom->colors;
- /* TODO(campbell): Currently rasterizes to fixed size, then scales.
+ /* TODO(@campbellbarton): Currently rasterizes to fixed size, then scales.
* Should rasterize to double size for eg instead. */
const int rect_size[2] = {max_ii(256, (int)size_x * 2), max_ii(256, (int)size_y * 2)};
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index 43e732b428d..98c317c547b 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -784,7 +784,7 @@ 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;
- /* NOTE(campbell): Don't overwrite the data's name and type
+ /* NOTE(@campbellbarton): 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. */
// strcpy(id->name, "top_level_group");
diff --git a/source/blender/blenkernel/intern/idprop_create.cc b/source/blender/blenkernel/intern/idprop_create.cc
index 499a43ee0a7..24f59d5e49e 100644
--- a/source/blender/blenkernel/intern/idprop_create.cc
+++ b/source/blender/blenkernel/intern/idprop_create.cc
@@ -44,6 +44,14 @@ std::unique_ptr<IDProperty, IDPropertyDeleter> create(const StringRefNull prop_n
return std::unique_ptr<IDProperty, IDPropertyDeleter>(property);
}
+std::unique_ptr<IDProperty, IDPropertyDeleter> create(const StringRefNull prop_name, ID *value)
+{
+ IDPropertyTemplate prop_template{0};
+ prop_template.id = value;
+ IDProperty *property = IDP_New(IDP_ID, &prop_template, prop_name.c_str());
+ return std::unique_ptr<IDProperty, IDPropertyDeleter>(property);
+}
+
static std::unique_ptr<IDProperty, IDPropertyDeleter> array_create(const StringRefNull prop_name,
eIDPropertyType subtype,
size_t array_len)
diff --git a/source/blender/blenkernel/intern/image.cc b/source/blender/blenkernel/intern/image.cc
index b196bcd7207..ae24383e5b9 100644
--- a/source/blender/blenkernel/intern/image.cc
+++ b/source/blender/blenkernel/intern/image.cc
@@ -627,6 +627,16 @@ void BKE_image_free_data(Image *ima)
image_free_data(&ima->id);
}
+static ImageTile *imagetile_alloc(int tile_number)
+{
+ ImageTile *tile = MEM_cnew<ImageTile>("Image Tile");
+ tile->tile_number = tile_number;
+ tile->gen_x = 1024;
+ tile->gen_y = 1024;
+ tile->gen_type = IMA_GENTYPE_GRID;
+ return tile;
+}
+
/* only image block itself */
static void image_init(Image *ima, short source, short type)
{
@@ -641,8 +651,7 @@ static void image_init(Image *ima, short source, short type)
ima->flag |= IMA_VIEW_AS_RENDER;
}
- ImageTile *tile = MEM_cnew<ImageTile>("Image Tiles");
- tile->tile_number = 1001;
+ ImageTile *tile = imagetile_alloc(1001);
BLI_addtail(&ima->tiles, tile);
if (type == IMA_TYPE_R_RESULT) {
@@ -863,37 +872,89 @@ void BKE_image_get_tile_uv(const Image *ima, const int tile_number, float r_uv[2
}
}
+/** Linear distance between #x and the unit interval. */
+static float distance_to_unit_interval(float x)
+{
+ /* The unit interval is between 0 and 1.
+ * Within the interval, return 0.
+ * Outside the interval, return the distance to the nearest boundary.
+ * Intuitively, the function looks like:
+ * \ | | /
+ * __\|___|/__
+ * 0 1
+ */
+
+ if (x <= 0.0f) {
+ return -x; /* Distance to left border. */
+ }
+ if (x <= 1.0f) {
+ return 0.0f; /* Inside unit interval. */
+ }
+ return x - 1.0f; /* Distance to right border. */
+}
+
+/** Distance squared between #co and the unit square with lower-left starting at #udim. */
+static float distance_squared_to_udim(const float co[2], const float udim[2])
+{
+ float delta[2];
+ sub_v2_v2v2(delta, co, udim);
+ delta[0] = distance_to_unit_interval(delta[0]);
+ delta[1] = distance_to_unit_interval(delta[1]);
+ return len_squared_v2(delta);
+}
+
+static bool nearest_udim_tile_tie_break(const float best_dist_sq,
+ const float best_uv[2],
+ const float dist_sq,
+ const float uv[2])
+{
+ if (best_dist_sq == dist_sq) { /* Exact same distance? Tie-break. */
+ if (best_uv[0] == uv[0]) { /* Exact same U? Tie-break. */
+ return (uv[1] > best_uv[1]); /* Higher than previous candidate? */
+ }
+ return (uv[0] > best_uv[0]); /* Further right than previous candidate? */
+ }
+ return (dist_sq < best_dist_sq); /* Closer than previous candidate? */
+}
+
int BKE_image_find_nearest_tile_with_offset(const Image *image,
const float co[2],
float r_uv_offset[2])
{
- /* Distance squared to the closest UDIM tile. */
- float dist_best_sq = FLT_MAX;
- float uv_offset_best[2] = {0, 0};
+ /* NOTE: If the co-ordinates are integers, take special care to break ties. */
+
+ zero_v2(r_uv_offset);
int tile_number_best = -1;
- const float co_offset[2] = {co[0] - 0.5f, co[1] - 0.5f};
+ if (!image || image->source != IMA_SRC_TILED) {
+ return tile_number_best;
+ }
+
+ /* Distance squared to the closest UDIM tile. */
+ float dist_best_sq = FLT_MAX;
LISTBASE_FOREACH (const ImageTile *, tile, &image->tiles) {
float uv_offset[2];
BKE_image_get_tile_uv(image, tile->tile_number, uv_offset);
- /* Distance squared between co[2] and center of UDIM tile. */
- const float dist_sq = len_squared_v2v2(uv_offset, co_offset);
+ /* Distance squared between #co and closest point on UDIM tile. */
+ const float dist_sq = distance_squared_to_udim(co, uv_offset);
- if (dist_sq < dist_best_sq) {
+ if (dist_sq == 0) { /* Either inside in the UDIM, or on its boundary. */
+ if (floorf(co[0]) == uv_offset[0] && floorf(co[1]) == uv_offset[1]) {
+ /* Within the half-open interval of the UDIM. */
+ copy_v2_v2(r_uv_offset, uv_offset);
+ return tile_number_best;
+ }
+ }
+
+ if (nearest_udim_tile_tie_break(dist_best_sq, r_uv_offset, dist_sq, uv_offset)) {
+ /* Tile is better than previous best, update. */
dist_best_sq = dist_sq;
+ copy_v2_v2(r_uv_offset, uv_offset);
tile_number_best = tile->tile_number;
- copy_v2_v2(uv_offset_best, uv_offset);
-
- if (dist_best_sq < 0.5f * 0.5f) {
- break; /* No other tile can be closer. */
- }
}
}
- if (tile_number_best != -1) {
- copy_v2_v2(r_uv_offset, uv_offset_best);
- }
return tile_number_best;
}
@@ -910,7 +971,7 @@ static void image_init_color_management(Image *ima)
BKE_image_user_file_path(nullptr, ima, name);
- /* will set input color space to image format default's */
+ /* Will set input color space to image format default's. */
ibuf = IMB_loadiffname(name, IB_test | IB_alphamode_detect, ima->colorspace_settings.name);
if (ibuf) {
@@ -1048,73 +1109,70 @@ static void image_buf_fill_isolated(void *usersata_v)
}
}
-static ImBuf *add_ibuf_size(unsigned int width,
- unsigned int height,
- const char *name,
- int depth,
- int floatbuf,
- short gen_type,
- const float color[4],
- ColorManagedColorspaceSettings *colorspace_settings)
+static ImBuf *add_ibuf_for_tile(Image *ima, ImageTile *tile)
{
ImBuf *ibuf;
unsigned char *rect = nullptr;
float *rect_float = nullptr;
float fill_color[4];
+ const bool floatbuf = (tile->gen_flag & IMA_GEN_FLOAT) != 0;
if (floatbuf) {
- ibuf = IMB_allocImBuf(width, height, depth, IB_rectfloat);
+ ibuf = IMB_allocImBuf(tile->gen_x, tile->gen_y, tile->gen_depth, IB_rectfloat);
- if (colorspace_settings->name[0] == '\0') {
+ if (ima->colorspace_settings.name[0] == '\0') {
const char *colorspace = IMB_colormanagement_role_colorspace_name_get(
COLOR_ROLE_DEFAULT_FLOAT);
- STRNCPY(colorspace_settings->name, colorspace);
+ STRNCPY(ima->colorspace_settings.name, colorspace);
}
if (ibuf != nullptr) {
rect_float = ibuf->rect_float;
- IMB_colormanagement_check_is_data(ibuf, colorspace_settings->name);
+ IMB_colormanagement_check_is_data(ibuf, ima->colorspace_settings.name);
}
- if (IMB_colormanagement_space_name_is_data(colorspace_settings->name)) {
- copy_v4_v4(fill_color, color);
+ if (IMB_colormanagement_space_name_is_data(ima->colorspace_settings.name)) {
+ copy_v4_v4(fill_color, tile->gen_color);
}
else {
/* The input color here should ideally be linear already, but for now
* we just convert and postpone breaking the API for later. */
- srgb_to_linearrgb_v4(fill_color, color);
+ srgb_to_linearrgb_v4(fill_color, tile->gen_color);
}
}
else {
- ibuf = IMB_allocImBuf(width, height, depth, IB_rect);
+ ibuf = IMB_allocImBuf(tile->gen_x, tile->gen_y, tile->gen_depth, IB_rect);
- if (colorspace_settings->name[0] == '\0') {
+ if (ima->colorspace_settings.name[0] == '\0') {
const char *colorspace = IMB_colormanagement_role_colorspace_name_get(
COLOR_ROLE_DEFAULT_BYTE);
- STRNCPY(colorspace_settings->name, colorspace);
+ STRNCPY(ima->colorspace_settings.name, colorspace);
}
if (ibuf != nullptr) {
rect = (unsigned char *)ibuf->rect;
- IMB_colormanagement_assign_rect_colorspace(ibuf, colorspace_settings->name);
+ IMB_colormanagement_assign_rect_colorspace(ibuf, ima->colorspace_settings.name);
}
- copy_v4_v4(fill_color, color);
+ copy_v4_v4(fill_color, tile->gen_color);
}
if (!ibuf) {
return nullptr;
}
- STRNCPY(ibuf->name, name);
+ STRNCPY(ibuf->name, ima->filepath);
+
+ /* Mark the tile itself as having been generated. */
+ tile->gen_flag |= IMA_GEN_TILE;
ImageFillData data;
- data.gen_type = gen_type;
- data.width = width;
- data.height = height;
+ data.gen_type = tile->gen_type;
+ data.width = tile->gen_x;
+ data.height = tile->gen_y;
data.rect = rect;
data.rect_float = rect_float;
copy_v4_v4(data.fill_color, fill_color);
@@ -1153,12 +1211,16 @@ Image *BKE_image_add_generated(Main *bmain,
/* NOTE: leave `ima->filepath` unset,
* setting it to a dummy value may write to an invalid file-path. */
- ima->gen_x = width;
- ima->gen_y = height;
- ima->gen_type = gen_type;
- ima->gen_flag |= (floatbuf ? IMA_GEN_FLOAT : 0);
- ima->gen_depth = depth;
- copy_v4_v4(ima->gen_color, color);
+
+ /* The generation info is always stored in the tiles. The first tile
+ * will be used for non-tiled images. */
+ ImageTile *tile = static_cast<ImageTile *>(ima->tiles.first);
+ tile->gen_x = width;
+ tile->gen_y = height;
+ tile->gen_type = gen_type;
+ tile->gen_flag |= (floatbuf ? IMA_GEN_FLOAT : 0);
+ tile->gen_depth = depth;
+ copy_v4_v4(tile->gen_color, color);
if (is_data) {
STRNCPY(ima->colorspace_settings.name,
@@ -1167,8 +1229,7 @@ Image *BKE_image_add_generated(Main *bmain,
for (view_id = 0; view_id < 2; view_id++) {
ImBuf *ibuf;
- ibuf = add_ibuf_size(
- width, height, ima->filepath, depth, floatbuf, gen_type, color, &ima->colorspace_settings);
+ ibuf = add_ibuf_for_tile(ima, tile);
int index = tiled ? 0 : IMA_NO_INDEX;
int entry = tiled ? 1001 : 0;
image_assign_ibuf(ima, ibuf, stereo3d ? view_id : index, entry);
@@ -1187,7 +1248,7 @@ Image *BKE_image_add_generated(Main *bmain,
static void image_colorspace_from_imbuf(Image *image, const ImBuf *ibuf)
{
- const char *colorspace_name = NULL;
+ const char *colorspace_name = nullptr;
if (ibuf->rect_float) {
if (ibuf->float_colorspace) {
@@ -2949,6 +3010,28 @@ static void image_free_tile(Image *ima, ImageTile *tile)
}
}
+static bool image_remove_tile(Image *ima, ImageTile *tile)
+{
+ if (BLI_listbase_is_single(&ima->tiles)) {
+ /* Can't remove the last remaining tile. */
+ return false;
+ }
+
+ image_free_tile(ima, tile);
+ BLI_remlink(&ima->tiles, tile);
+ MEM_freeN(tile);
+
+ return true;
+}
+
+static void image_remove_all_tiles(Image *ima)
+{
+ /* Remove all but the final tile. */
+ while (image_remove_tile(ima, static_cast<ImageTile *>(ima->tiles.last))) {
+ ;
+ }
+}
+
void BKE_image_signal(Main *bmain, Image *ima, ImageUser *iuser, int signal)
{
if (ima == nullptr) {
@@ -2975,11 +3058,12 @@ void BKE_image_signal(Main *bmain, Image *ima, ImageUser *iuser, int signal)
}
if (ima->source == IMA_SRC_GENERATED) {
- if (ima->gen_x == 0 || ima->gen_y == 0) {
+ ImageTile *base_tile = BKE_image_get_tile(ima, 0);
+ if (base_tile->gen_x == 0 || base_tile->gen_y == 0) {
ImBuf *ibuf = image_get_cached_ibuf_for_index_entry(ima, IMA_NO_INDEX, 0, nullptr);
if (ibuf) {
- ima->gen_x = ibuf->x;
- ima->gen_y = ibuf->y;
+ base_tile->gen_x = ibuf->x;
+ base_tile->gen_y = ibuf->y;
IMB_freeImBuf(ibuf);
}
}
@@ -2996,16 +3080,40 @@ void BKE_image_signal(Main *bmain, Image *ima, ImageUser *iuser, int signal)
if (ima->source != IMA_SRC_TILED) {
/* Free all but the first tile. */
+ image_remove_all_tiles(ima);
+
+ /* If the remaining tile is generated, we need to again ensure that we
+ * wouldn't continue to use the old filepath.
+ *
+ * Otherwise, if this used to be a UDIM image, get the concrete filepath associated
+ * with the remaining tile and use that as the new filepath. */
ImageTile *base_tile = BKE_image_get_tile(ima, 0);
- BLI_assert(base_tile == ima->tiles.first);
- for (ImageTile *tile = base_tile->next, *tile_next; tile; tile = tile_next) {
- tile_next = tile->next;
- image_free_tile(ima, tile);
- MEM_freeN(tile);
+ if ((base_tile->gen_flag & IMA_GEN_TILE) != 0) {
+ ima->filepath[0] = '\0';
+ }
+ else if (BKE_image_is_filename_tokenized(ima->filepath)) {
+ const bool was_relative = BLI_path_is_rel(ima->filepath);
+
+ eUDIM_TILE_FORMAT tile_format;
+ char *udim_pattern = BKE_image_get_tile_strformat(ima->filepath, &tile_format);
+ BKE_image_set_filepath_from_tile_number(
+ ima->filepath, udim_pattern, tile_format, base_tile->tile_number);
+ MEM_freeN(udim_pattern);
+
+ if (was_relative) {
+ const char *relbase = ID_BLEND_PATH(bmain, &ima->id);
+ BLI_path_rel(ima->filepath, relbase);
+ }
}
- base_tile->next = nullptr;
+
+ /* If the remaining tile was not number 1001, we need to reassign it so that
+ * ibuf lookups from the cache still succeed. */
base_tile->tile_number = 1001;
- ima->tiles.last = base_tile;
+ }
+ else {
+ /* When changing to UDIM, attempt to tokenize the filepath. */
+ char *filename = (char *)BLI_path_basename(ima->filepath);
+ BKE_image_ensure_tile_token(filename);
}
/* image buffers for non-sequence multilayer will share buffers with RenderResult,
@@ -3021,6 +3129,7 @@ void BKE_image_signal(Main *bmain, Image *ima, ImageUser *iuser, int signal)
image_tag_frame_recalc(ima, nullptr, iuser, ima);
}
BKE_image_walk_all_users(bmain, ima, image_tag_frame_recalc);
+ BKE_image_partial_update_mark_full_update(ima);
break;
@@ -3072,9 +3181,7 @@ void BKE_image_signal(Main *bmain, Image *ima, ImageUser *iuser, int signal)
* to account for how the two sets might or might not overlap. To be complete, we start
* the refresh process by clearing all existing tiles, stopping when there's only 1 tile
* left. */
- while (BKE_image_remove_tile(ima, static_cast<ImageTile *>(ima->tiles.last))) {
- ;
- }
+ image_remove_all_tiles(ima);
int remaining_tile_number = ((ImageTile *)ima->tiles.first)->tile_number;
bool needs_final_cleanup = true;
@@ -3257,8 +3364,7 @@ ImageTile *BKE_image_add_tile(struct Image *ima, int tile_number, const char *la
}
}
- ImageTile *tile = MEM_cnew<ImageTile>("image new tile");
- tile->tile_number = tile_number;
+ ImageTile *tile = imagetile_alloc(tile_number);
if (next_tile) {
BLI_insertlinkbefore(&ima->tiles, next_tile, tile);
@@ -3293,16 +3399,7 @@ bool BKE_image_remove_tile(struct Image *ima, ImageTile *tile)
return false;
}
- if (BLI_listbase_is_single(&ima->tiles)) {
- /* Can't remove the last remaining tile. */
- return false;
- }
-
- image_free_tile(ima, tile);
- BLI_remlink(&ima->tiles, tile);
- MEM_freeN(tile);
-
- return true;
+ return image_remove_tile(ima, tile);
}
void BKE_image_reassign_tile(struct Image *ima, ImageTile *tile, int new_tile_number)
@@ -3364,14 +3461,7 @@ void BKE_image_sort_tiles(struct Image *ima)
BLI_listbase_sort(&ima->tiles, tile_sort_cb);
}
-bool BKE_image_fill_tile(struct Image *ima,
- ImageTile *tile,
- int width,
- int height,
- const float color[4],
- int gen_type,
- int planes,
- bool is_float)
+bool BKE_image_fill_tile(struct Image *ima, ImageTile *tile)
{
if (ima == nullptr || tile == nullptr || ima->source != IMA_SRC_TILED) {
return false;
@@ -3379,8 +3469,7 @@ bool BKE_image_fill_tile(struct Image *ima,
image_free_tile(ima, tile);
- ImBuf *tile_ibuf = add_ibuf_size(
- width, height, ima->filepath, planes, is_float, gen_type, color, &ima->colorspace_settings);
+ ImBuf *tile_ibuf = add_ibuf_for_tile(ima, tile);
if (tile_ibuf != nullptr) {
image_assign_ibuf(ima, tile_ibuf, 0, tile->tile_number);
@@ -4553,14 +4642,22 @@ static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **r_lock)
}
}
else if (ima->source == IMA_SRC_TILED) {
- if (ima->type == IMA_TYPE_IMAGE) {
- /* Regular files, ibufs in flip-book, allows saving */
- ibuf = image_load_image_file(ima, iuser, entry, 0, false);
+ /* Nothing was cached. Check to see if the tile should be generated. */
+ ImageTile *tile = BKE_image_get_tile(ima, entry);
+ if ((tile->gen_flag & IMA_GEN_TILE) != 0) {
+ ibuf = add_ibuf_for_tile(ima, tile);
+ image_assign_ibuf(ima, ibuf, 0, entry);
}
- /* no else; on load the ima type can change */
- if (ima->type == IMA_TYPE_MULTILAYER) {
- /* Only 1 layer/pass stored in imbufs, no EXR-handle anim storage, no saving. */
- ibuf = image_load_sequence_multilayer(ima, iuser, entry, 0);
+ else {
+ if (ima->type == IMA_TYPE_IMAGE) {
+ /* Regular files, ibufs in flip-book, allows saving */
+ ibuf = image_load_image_file(ima, iuser, entry, 0, false);
+ }
+ /* no else; on load the ima type can change */
+ if (ima->type == IMA_TYPE_MULTILAYER) {
+ /* Only 1 layer/pass stored in imbufs, no EXR-handle anim storage, no saving. */
+ ibuf = image_load_sequence_multilayer(ima, iuser, entry, 0);
+ }
}
}
else if (ima->source == IMA_SRC_FILE) {
@@ -4578,23 +4675,17 @@ static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **r_lock)
else if (ima->source == IMA_SRC_GENERATED) {
/* Generated is: `ibuf` is allocated dynamically. */
/* UV test-grid or black or solid etc. */
- if (ima->gen_x == 0) {
- ima->gen_x = 1024;
+ ImageTile *base_tile = BKE_image_get_tile(ima, 0);
+ if (base_tile->gen_x == 0) {
+ base_tile->gen_x = 1024;
}
- if (ima->gen_y == 0) {
- ima->gen_y = 1024;
+ if (base_tile->gen_y == 0) {
+ base_tile->gen_y = 1024;
}
- if (ima->gen_depth == 0) {
- ima->gen_depth = 24;
+ if (base_tile->gen_depth == 0) {
+ base_tile->gen_depth = 24;
}
- ibuf = add_ibuf_size(ima->gen_x,
- ima->gen_y,
- ima->filepath,
- ima->gen_depth,
- (ima->gen_flag & IMA_GEN_FLOAT) != 0,
- ima->gen_type,
- ima->gen_color,
- &ima->colorspace_settings);
+ ibuf = add_ibuf_for_tile(ima, base_tile);
image_assign_ibuf(ima, ibuf, index, 0);
}
else if (ima->source == IMA_SRC_VIEWER) {
diff --git a/source/blender/blenkernel/intern/image_gpu.cc b/source/blender/blenkernel/intern/image_gpu.cc
index 6506b40b603..08fdd715512 100644
--- a/source/blender/blenkernel/intern/image_gpu.cc
+++ b/source/blender/blenkernel/intern/image_gpu.cc
@@ -138,6 +138,8 @@ static GPUTexture *gpu_texture_create_tile_array(Image *ima, ImBuf *main_ibuf)
int arraywidth = 0, arrayheight = 0;
ListBase boxes = {nullptr};
+ int planes = 0;
+
LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
ImageUser iuser;
BKE_imageuser_default(&iuser);
@@ -164,6 +166,7 @@ static GPUTexture *gpu_texture_create_tile_array(Image *ima, ImBuf *main_ibuf)
BKE_image_release_ibuf(ima, ibuf, nullptr);
BLI_addtail(&boxes, packtile);
+ planes = max_ii(planes, ibuf->planes);
}
}
@@ -195,9 +198,15 @@ static GPUTexture *gpu_texture_create_tile_array(Image *ima, ImBuf *main_ibuf)
}
const bool use_high_bitdepth = (ima->flag & IMA_HIGH_BITDEPTH);
+ const bool use_grayscale = planes <= 8;
/* Create Texture without content. */
- GPUTexture *tex = IMB_touch_gpu_texture(
- ima->id.name + 2, main_ibuf, arraywidth, arrayheight, arraylayers, use_high_bitdepth);
+ GPUTexture *tex = IMB_touch_gpu_texture(ima->id.name + 2,
+ main_ibuf,
+ arraywidth,
+ arrayheight,
+ arraylayers,
+ use_high_bitdepth,
+ use_grayscale);
/* Upload each tile one by one. */
LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
@@ -223,6 +232,7 @@ static GPUTexture *gpu_texture_create_tile_array(Image *ima, ImBuf *main_ibuf)
tilelayer,
UNPACK2(tilesize),
use_high_bitdepth,
+ use_grayscale,
store_premultiplied);
}
diff --git a/source/blender/blenkernel/intern/image_save.cc b/source/blender/blenkernel/intern/image_save.cc
index 7d7d49275ba..5ee1258c512 100644
--- a/source/blender/blenkernel/intern/image_save.cc
+++ b/source/blender/blenkernel/intern/image_save.cc
@@ -316,6 +316,8 @@ static void image_save_post(ReportList *reports,
if (ELEM(ima->source, IMA_SRC_GENERATED, IMA_SRC_VIEWER)) {
ima->source = IMA_SRC_FILE;
ima->type = IMA_TYPE_IMAGE;
+ ImageTile *base_tile = BKE_image_get_tile(ima, 0);
+ base_tile->gen_flag &= ~IMA_GEN_TILE;
}
/* Update image file color space when saving to another color space. */
@@ -662,8 +664,11 @@ bool BKE_image_save(
}
}
- /* Set the image path only if all tiles were ok. */
+ /* Set the image path and clear the per-tile generated flag only if all tiles were ok. */
if (ok) {
+ LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
+ tile->gen_flag &= ~IMA_GEN_TILE;
+ }
image_save_update_filepath(ima, opts->filepath, opts);
}
MEM_freeN(udim_pattern);
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index b5c025a40b6..6fb67711ae9 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -398,21 +398,6 @@ Lattice *BKE_lattice_add(Main *bmain, const char *name)
return lt;
}
-bool object_deform_mball(Object *ob, ListBase *dispbase)
-{
- if (ob->parent && ob->parent->type == OB_LATTICE && ob->partype == PARSKEL) {
- DispList *dl;
-
- for (dl = dispbase->first; dl; dl = dl->next) {
- BKE_lattice_deform_coords(ob->parent, ob, (float(*)[3])dl->verts, dl->nr, 0, NULL, 1.0f);
- }
-
- return true;
- }
-
- return false;
-}
-
static BPoint *latt_bp(Lattice *lt, int u, int v, int w)
{
return &lt->def[BKE_lattice_index_from_uvw(lt, u, v, w)];
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index 4257bccad93..53a9b6d469d 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -572,7 +572,7 @@ void BKE_view_layer_rename(Main *bmain, Scene *scene, ViewLayer *view_layer, con
}
/* Dependency graph uses view layer name based lookups. */
- DEG_id_tag_update(&scene->id, 0);
+ DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
}
/* LayerCollection */
diff --git a/source/blender/blenkernel/intern/layer_utils.c b/source/blender/blenkernel/intern/layer_utils.c
index 0903c2a2cac..13e0a0bcf84 100644
--- a/source/blender/blenkernel/intern/layer_utils.c
+++ b/source/blender/blenkernel/intern/layer_utils.c
@@ -149,6 +149,65 @@ Object **BKE_view_layer_array_from_objects_in_mode_params(ViewLayer *view_layer,
return (Object **)base_array;
}
+struct Object **BKE_view_layer_array_from_objects_in_edit_mode(ViewLayer *view_layer,
+ const View3D *v3d,
+ uint *r_len)
+{
+ struct ObjectsInModeParams params = {0};
+ params.object_mode = OB_MODE_EDIT;
+ return BKE_view_layer_array_from_objects_in_mode_params(view_layer, v3d, r_len, &params);
+}
+
+struct Base **BKE_view_layer_array_from_bases_in_edit_mode(ViewLayer *view_layer,
+ const View3D *v3d,
+ uint *r_len)
+{
+ struct ObjectsInModeParams params = {0};
+ params.object_mode = OB_MODE_EDIT;
+ return BKE_view_layer_array_from_bases_in_mode_params(view_layer, v3d, r_len, &params);
+}
+
+struct Object **BKE_view_layer_array_from_objects_in_edit_mode_unique_data(ViewLayer *view_layer,
+ const View3D *v3d,
+ uint *r_len)
+{
+ struct ObjectsInModeParams params = {0};
+ params.object_mode = OB_MODE_EDIT;
+ params.no_dup_data = true;
+ return BKE_view_layer_array_from_objects_in_mode_params(view_layer, v3d, r_len, &params);
+}
+
+struct Base **BKE_view_layer_array_from_bases_in_edit_mode_unique_data(ViewLayer *view_layer,
+ const View3D *v3d,
+ uint *r_len)
+{
+ struct ObjectsInModeParams params = {0};
+ params.object_mode = OB_MODE_EDIT;
+ params.no_dup_data = true;
+ return BKE_view_layer_array_from_bases_in_mode_params(view_layer, v3d, r_len, &params);
+}
+
+struct Object **BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
+ ViewLayer *view_layer, const View3D *v3d, uint *r_len)
+{
+ struct ObjectsInModeParams params = {0};
+ params.object_mode = OB_MODE_EDIT;
+ params.no_dup_data = true;
+ params.filter_fn = BKE_view_layer_filter_edit_mesh_has_uvs;
+ return BKE_view_layer_array_from_objects_in_mode_params(view_layer, v3d, r_len, &params);
+}
+
+struct Object **BKE_view_layer_array_from_objects_in_mode_unique_data(ViewLayer *view_layer,
+ const View3D *v3d,
+ uint *r_len,
+ const eObjectMode mode)
+{
+ struct ObjectsInModeParams params = {0};
+ params.object_mode = mode;
+ params.no_dup_data = true;
+ return BKE_view_layer_array_from_objects_in_mode_params(view_layer, v3d, r_len, &params);
+}
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/blenkernel/intern/lib_id.c b/source/blender/blenkernel/intern/lib_id.c
index 3778e308db6..5a394a05d86 100644
--- a/source/blender/blenkernel/intern/lib_id.c
+++ b/source/blender/blenkernel/intern/lib_id.c
@@ -59,6 +59,7 @@
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
+#include "DEG_depsgraph_query.h"
#include "RNA_access.h"
@@ -708,6 +709,58 @@ ID *BKE_id_copy_for_duplicate(Main *bmain,
return id->newid;
}
+static int foreach_assign_id_to_orig_callback(LibraryIDLinkCallbackData *cb_data)
+{
+ ID **id_p = cb_data->id_pointer;
+
+ if (*id_p) {
+ ID *id = *id_p;
+ *id_p = DEG_get_original_id(id);
+
+ /* If the ID changes increase the user count.
+ *
+ * This means that the reference to evaluated ID has been changed with a reference to the
+ * original ID which implies that the user count of the original ID is increased.
+ *
+ * The evaluated IDs do not maintain their user counter, so do not change it to avoid issues
+ * with the user counter going negative. */
+ if (*id_p != id) {
+ if ((cb_data->cb_flag & IDWALK_CB_USER) != 0) {
+ id_us_plus(*id_p);
+ }
+ }
+ }
+
+ return IDWALK_RET_NOP;
+}
+
+ID *BKE_id_copy_for_use_in_bmain(Main *bmain, const ID *id)
+{
+ ID *newid = BKE_id_copy(bmain, id);
+
+ if (newid == NULL) {
+ return newid;
+ }
+
+ /* Assign ID references directly used by the given ID to their original complementary parts.
+ *
+ * For example, when is called on an evaluated object will assign object->data to its original
+ * pointer, the evaluated object->data will be kept unchanged. */
+ BKE_library_foreach_ID_link(NULL, newid, foreach_assign_id_to_orig_callback, NULL, IDWALK_NOP);
+
+ /* Shape keys reference on evaluated ID is preserved to keep driver paths available, but the key
+ * data is likely to be invalid now due to modifiers, so clear the shape key reference avoiding
+ * any possible shape corruption. */
+ if (DEG_is_evaluated_id(id)) {
+ Key **key_p = BKE_key_from_id_p(newid);
+ if (key_p) {
+ *key_p = NULL;
+ }
+ }
+
+ return newid;
+}
+
/**
* Does a mere memory swap over the whole IDs data (including type-specific memory).
* \note Most internal ID data itself is not swapped (only IDProperties are).
diff --git a/source/blender/blenkernel/intern/lib_query.c b/source/blender/blenkernel/intern/lib_query.c
index 6b9d2afe87a..38d1a30592d 100644
--- a/source/blender/blenkernel/intern/lib_query.c
+++ b/source/blender/blenkernel/intern/lib_query.c
@@ -696,8 +696,8 @@ static void lib_query_unused_ids_tag_recurse(Main *bmain,
bool has_valid_from_users = false;
/* Preemptively consider this ID as unused. That way if there is a loop of dependency leading
* back to it, it won't create a fake 'valid user' detection.
- * NOTE: This can only only be done for a subset of IDs, some types are never 'indirectly
- * unused', same for IDs with a fake user. */
+ * NOTE: This can only be done for a subset of IDs, some types are never 'indirectly unused',
+ * same for IDs with a fake user. */
if ((id->flag & LIB_FAKEUSER) == 0 && !ELEM(GS(id->name), ID_SCE, ID_WM, ID_SCR, ID_WS, ID_LI)) {
id->tag |= tag;
}
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index dd58c9cc4fe..9424b615031 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -122,7 +122,7 @@ void BKE_library_filepath_set(Main *bmain, Library *lib, const char *filepath)
/* Not essential but set `filepath_abs` is an absolute copy of value which
* is more useful if its kept in sync. */
if (BLI_path_is_rel(lib->filepath_abs)) {
- /* NOTE(campbell): the file may be unsaved, in this case, setting the
+ /* NOTE(@campbellbarton): the file may be unsaved, in this case, setting the
* `filepath_abs` on an indirectly linked path is not allowed from the
* outliner, and its not really supported but allow from here for now
* since making local could cause this to be directly linked.
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index f899901b54e..248d292664a 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -852,7 +852,7 @@ void BKE_object_material_resize(Main *bmain, Object *ob, const short totcol, boo
ob->mat = newmatar;
ob->matbits = newmatbits;
}
- /* XXX(campbell): why not realloc on shrink? */
+ /* XXX(@campbellbarton): why not realloc on shrink? */
ob->totcol = totcol;
if (ob->totcol && ob->actcol == 0) {
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.cc
index 2a1c940493c..2ff8e6fc061 100644
--- a/source/blender/blenkernel/intern/mball.c
+++ b/source/blender/blenkernel/intern/mball.cc
@@ -4,19 +4,16 @@
/** \file
* \ingroup bke
*
- * MetaBalls are created from a single Object (with a name without number in it),
- * here the DispList and BoundBox also is located.
+ * MetaBalls are created from a single Object (with a name without number in it).
* All objects with the same name (but with a number in it) are added to this.
- *
- * texture coordinates are patched within the displist
*/
-#include <ctype.h>
-#include <float.h>
-#include <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+#include <cctype>
+#include <cfloat>
+#include <cmath>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
#include "MEM_guardedalloc.h"
@@ -25,6 +22,7 @@
#include "DNA_defaults.h"
#include "DNA_material_types.h"
+#include "DNA_mesh_types.h"
#include "DNA_meta_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -41,11 +39,15 @@
#include "BKE_anim_data.h"
#include "BKE_curve.h"
#include "BKE_displist.h"
+#include "BKE_geometry_set.hh"
#include "BKE_idtype.h"
+#include "BKE_lattice.h"
#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
#include "BKE_material.h"
#include "BKE_mball.h"
+#include "BKE_mball_tessellate.h"
+#include "BKE_mesh.h"
#include "BKE_object.h"
#include "BKE_scene.h"
@@ -72,19 +74,16 @@ static void metaball_copy_data(Main *UNUSED(bmain),
BLI_duplicatelist(&metaball_dst->elems, &metaball_src->elems);
- metaball_dst->mat = MEM_dupallocN(metaball_src->mat);
+ metaball_dst->mat = static_cast<Material **>(MEM_dupallocN(metaball_src->mat));
- metaball_dst->editelems = NULL;
- metaball_dst->lastelem = NULL;
- metaball_dst->batch_cache = NULL;
+ metaball_dst->editelems = nullptr;
+ metaball_dst->lastelem = nullptr;
}
static void metaball_free_data(ID *id)
{
MetaBall *metaball = (MetaBall *)id;
- BKE_mball_batch_cache_free(metaball);
-
MEM_SAFE_FREE(metaball->mat);
BLI_freelistN(&metaball->elems);
@@ -107,11 +106,10 @@ static void metaball_blend_write(BlendWriter *writer, ID *id, const void *id_add
/* Clean up, important in undo case to reduce false detection of changed datablocks. */
BLI_listbase_clear(&mb->disp);
- mb->editelems = NULL;
+ mb->editelems = nullptr;
/* Must always be cleared (meta's don't have their own edit-data). */
mb->needs_flush_to_id = 0;
- mb->lastelem = NULL;
- mb->batch_cache = NULL;
+ mb->lastelem = nullptr;
/* write LibData */
BLO_write_id_struct(writer, MetaBall, id_address, &mb->id);
@@ -139,12 +137,11 @@ static void metaball_blend_read_data(BlendDataReader *reader, ID *id)
BLO_read_list(reader, &(mb->elems));
BLI_listbase_clear(&mb->disp);
- mb->editelems = NULL;
+ mb->editelems = nullptr;
/* 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->lastelem = NULL;
- mb->batch_cache = NULL;
+ // mb->edit_elems.first = mb->edit_elems.last = nullptr;
+ mb->lastelem = nullptr;
}
static void metaball_blend_read_lib(BlendLibReader *reader, ID *id)
@@ -166,49 +163,46 @@ static void metaball_blend_read_expand(BlendExpander *expander, ID *id)
}
IDTypeInfo IDType_ID_MB = {
- .id_code = ID_MB,
- .id_filter = FILTER_ID_MB,
- .main_listbase_index = INDEX_ID_MB,
- .struct_size = sizeof(MetaBall),
- .name = "Metaball",
- .name_plural = "metaballs",
- .translation_context = BLT_I18NCONTEXT_ID_METABALL,
- .flags = IDTYPE_FLAGS_APPEND_IS_REUSABLE,
- .asset_type_info = NULL,
-
- .init_data = metaball_init_data,
- .copy_data = metaball_copy_data,
- .free_data = metaball_free_data,
- .make_local = NULL,
- .foreach_id = metaball_foreach_id,
- .foreach_cache = NULL,
- .foreach_path = NULL,
- .owner_get = NULL,
-
- .blend_write = metaball_blend_write,
- .blend_read_data = metaball_blend_read_data,
- .blend_read_lib = metaball_blend_read_lib,
- .blend_read_expand = metaball_blend_read_expand,
-
- .blend_read_undo_preserve = NULL,
-
- .lib_override_apply_post = NULL,
+ /* id_code */ ID_MB,
+ /* id_filter */ FILTER_ID_MB,
+ /* main_listbase_index */ INDEX_ID_MB,
+ /* struct_size */ sizeof(MetaBall),
+ /* name */ "Metaball",
+ /* name_plural */ "metaballs",
+ /* translation_context */ BLT_I18NCONTEXT_ID_METABALL,
+ /* flags */ IDTYPE_FLAGS_APPEND_IS_REUSABLE,
+ /* asset_type_info */ nullptr,
+
+ /* init_data */ metaball_init_data,
+ /* copy_data */ metaball_copy_data,
+ /* free_data */ metaball_free_data,
+ /* make_local */ nullptr,
+ /* foreach_id */ metaball_foreach_id,
+ /* foreach_cache */ nullptr,
+ /* foreach_path */ nullptr,
+ /* owner_get */ nullptr,
+
+ /* blend_write */ metaball_blend_write,
+ /* blend_read_data */ metaball_blend_read_data,
+ /* blend_read_lib */ metaball_blend_read_lib,
+ /* blend_read_expand */ metaball_blend_read_expand,
+
+ /* blend_read_undo_preserve */ nullptr,
+
+ /* lib_override_apply_post */ nullptr,
};
/* Functions */
MetaBall *BKE_mball_add(Main *bmain, const char *name)
{
- MetaBall *mb;
-
- mb = BKE_id_new(bmain, ID_MB, name);
-
+ MetaBall *mb = static_cast<MetaBall *>(BKE_id_new(bmain, ID_MB, name));
return mb;
}
MetaElem *BKE_mball_element_add(MetaBall *mb, const int type)
{
- MetaElem *ml = MEM_callocN(sizeof(MetaElem), "metaelem");
+ MetaElem *ml = MEM_cnew<MetaElem>(__func__);
unit_qt(ml->quat);
@@ -252,99 +246,37 @@ MetaElem *BKE_mball_element_add(MetaBall *mb, const int type)
return ml;
}
-void BKE_mball_texspace_calc(Object *ob)
-{
- DispList *dl;
- BoundBox *bb;
- float *data, min[3], max[3] /*, loc[3], size[3] */;
- int tot;
- bool do_it = false;
-
- if (ob->runtime.bb == NULL) {
- ob->runtime.bb = MEM_callocN(sizeof(BoundBox), "mb boundbox");
- }
- bb = ob->runtime.bb;
-
- /* Weird one, this. */
- // INIT_MINMAX(min, max);
- (min)[0] = (min)[1] = (min)[2] = 1.0e30f;
- (max)[0] = (max)[1] = (max)[2] = -1.0e30f;
-
- dl = ob->runtime.curve_cache->disp.first;
- while (dl) {
- tot = dl->nr;
- if (tot) {
- do_it = true;
- }
- data = dl->verts;
- while (tot--) {
- /* Also weird... but longer. From utildefines. */
- minmax_v3v3_v3(min, max, data);
- data += 3;
- }
- dl = dl->next;
- }
-
- if (!do_it) {
- min[0] = min[1] = min[2] = -1.0f;
- max[0] = max[1] = max[2] = 1.0f;
- }
-
- BKE_boundbox_init_from_minmax(bb, min, max);
-
- bb->flag &= ~BOUNDBOX_DIRTY;
-}
BoundBox *BKE_mball_boundbox_get(Object *ob)
{
BLI_assert(ob->type == OB_MBALL);
-
- if (ob->runtime.bb != NULL && (ob->runtime.bb->flag & BOUNDBOX_DIRTY) == 0) {
+ if (ob->runtime.bb != nullptr && (ob->runtime.bb->flag & BOUNDBOX_DIRTY) == 0) {
return ob->runtime.bb;
}
-
- /* This should always only be called with evaluated objects,
- * but currently RNA is a problem here... */
- if (ob->runtime.curve_cache != NULL) {
- BKE_mball_texspace_calc(ob);
+ if (ob->runtime.bb == nullptr) {
+ ob->runtime.bb = MEM_cnew<BoundBox>(__func__);
}
- return ob->runtime.bb;
-}
-
-float *BKE_mball_make_orco(Object *ob, ListBase *dispbase)
-{
- BoundBox *bb;
- DispList *dl;
- float *data, *orco, *orcodata;
- float loc[3], size[3];
- int a;
-
- /* restore size and loc */
- bb = ob->runtime.bb;
- loc[0] = (bb->vec[0][0] + bb->vec[4][0]) / 2.0f;
- size[0] = bb->vec[4][0] - loc[0];
- loc[1] = (bb->vec[0][1] + bb->vec[2][1]) / 2.0f;
- size[1] = bb->vec[2][1] - loc[1];
- loc[2] = (bb->vec[0][2] + bb->vec[1][2]) / 2.0f;
- size[2] = bb->vec[1][2] - loc[2];
-
- dl = dispbase->first;
- orcodata = MEM_mallocN(sizeof(float[3]) * dl->nr, "MballOrco");
-
- data = dl->verts;
- orco = orcodata;
- a = dl->nr;
- while (a--) {
- orco[0] = (data[0] - loc[0]) / size[0];
- orco[1] = (data[1] - loc[1]) / size[1];
- orco[2] = (data[2] - loc[2]) / size[2];
-
- data += 3;
- orco += 3;
+ /* Expect that this function is only called for evaluated objects. */
+ const Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
+ float min[3];
+ float max[3];
+ if (mesh_eval) {
+ INIT_MINMAX(min, max);
+ if (!BKE_mesh_minmax(mesh_eval, min, max)) {
+ copy_v3_fl(min, -1.0f);
+ copy_v3_fl(max, 1.0f);
+ }
+ }
+ else {
+ copy_v3_fl(min, 0.0f);
+ copy_v3_fl(max, 0.0f);
}
- return orcodata;
+ BKE_boundbox_init_from_minmax(ob->runtime.bb, min, max);
+ ob->runtime.bb->flag &= ~BOUNDBOX_DIRTY;
+
+ return ob->runtime.bb;
}
bool BKE_mball_is_basis(const Object *ob)
@@ -393,7 +325,7 @@ bool BKE_mball_is_basis_for(const Object *ob1, const Object *ob2)
bool BKE_mball_is_any_selected(const MetaBall *mb)
{
- for (const MetaElem *ml = mb->editelems->first; ml != NULL; ml = ml->next) {
+ LISTBASE_FOREACH (const MetaElem *, ml, mb->editelems) {
if (ml->flag & SELECT) {
return true;
}
@@ -415,7 +347,7 @@ bool BKE_mball_is_any_selected_multi(Base **bases, int bases_len)
bool BKE_mball_is_any_unselected(const MetaBall *mb)
{
- for (const MetaElem *ml = mb->editelems->first; ml != NULL; ml = ml->next) {
+ LISTBASE_FOREACH (const MetaElem *, ml, mb->editelems) {
if ((ml->flag & SELECT) == 0) {
return true;
}
@@ -451,9 +383,10 @@ void BKE_mball_properties_copy(Main *bmain, MetaBall *metaball_src)
* Solving this case would drastically increase the complexity of this code though, so don't
* think it would be worth it.
*/
- for (Object *ob_src = bmain->objects.first; ob_src != NULL && !ID_IS_LINKED(ob_src);) {
+ for (Object *ob_src = static_cast<Object *>(bmain->objects.first);
+ ob_src != nullptr && !ID_IS_LINKED(ob_src);) {
if (ob_src->data != metaball_src) {
- ob_src = ob_src->id.next;
+ ob_src = static_cast<Object *>(ob_src->id.next);
continue;
}
@@ -466,12 +399,13 @@ void BKE_mball_properties_copy(Main *bmain, MetaBall *metaball_src)
* Using this, it is possible to process the whole set of meta-balls with a single loop on the
* whole list of Objects, though additionally going backward on part of the list in some cases.
*/
- Object *ob_iter = NULL;
+ Object *ob_iter = nullptr;
int obactive_nr, ob_nr;
char obactive_name[MAX_ID_NAME], ob_name[MAX_ID_NAME];
BLI_split_name_num(obactive_name, &obactive_nr, ob_src->id.name + 2, '.');
- for (ob_iter = ob_src->id.prev; ob_iter != NULL; ob_iter = ob_iter->id.prev) {
+ for (ob_iter = static_cast<Object *>(ob_src->id.prev); ob_iter != nullptr;
+ ob_iter = static_cast<Object *>(ob_iter->id.prev)) {
if (ob_iter->id.name[2] != obactive_name[0]) {
break;
}
@@ -483,10 +417,11 @@ void BKE_mball_properties_copy(Main *bmain, MetaBall *metaball_src)
break;
}
- mball_data_properties_copy(ob_iter->data, metaball_src);
+ mball_data_properties_copy(static_cast<MetaBall *>(ob_iter->data), metaball_src);
}
- for (ob_iter = ob_src->id.next; ob_iter != NULL; ob_iter = ob_iter->id.next) {
+ for (ob_iter = static_cast<Object *>(ob_src->id.next); ob_iter != nullptr;
+ ob_iter = static_cast<Object *>(ob_iter->id.next)) {
if (ob_iter->id.name[2] != obactive_name[0] || ID_IS_LINKED(ob_iter)) {
break;
}
@@ -498,7 +433,7 @@ void BKE_mball_properties_copy(Main *bmain, MetaBall *metaball_src)
break;
}
- mball_data_properties_copy(ob_iter->data, metaball_src);
+ mball_data_properties_copy(static_cast<MetaBall *>(ob_iter->data), metaball_src);
}
ob_src = ob_iter;
@@ -556,7 +491,7 @@ bool BKE_mball_minmax_ex(
copy_v3_v3(centroid, &ml->x);
}
- /* TODO(campbell): non circle shapes cubes etc, probably nobody notices. */
+ /* TODO(@campbellbarton): non circle shapes cubes etc, probably nobody notices. */
for (int i = -1; i != 3; i += 2) {
copy_v3_v3(vec, centroid);
add_v3_fl(vec, scale_mb * i);
@@ -682,7 +617,7 @@ bool BKE_mball_select_all_multi_ex(Base **bases, int bases_len)
bool changed_multi = false;
for (uint ob_index = 0; ob_index < bases_len; ob_index++) {
Object *obedit = bases[ob_index]->object;
- MetaBall *mb = obedit->data;
+ MetaBall *mb = static_cast<MetaBall *>(obedit->data);
changed_multi |= BKE_mball_select_all(mb);
}
return changed_multi;
@@ -705,7 +640,7 @@ bool BKE_mball_deselect_all_multi_ex(Base **bases, int bases_len)
bool changed_multi = false;
for (uint ob_index = 0; ob_index < bases_len; ob_index++) {
Object *obedit = bases[ob_index]->object;
- MetaBall *mb = obedit->data;
+ MetaBall *mb = static_cast<MetaBall *>(obedit->data);
changed_multi |= BKE_mball_deselect_all(mb);
DEG_id_tag_update(&mb->id, ID_RECALC_SELECT);
}
@@ -735,20 +670,44 @@ bool BKE_mball_select_swap_multi_ex(Base **bases, int bases_len)
/* **** Depsgraph evaluation **** */
-/* Draw Engine */
+void BKE_mball_data_update(Depsgraph *depsgraph, Scene *scene, Object *ob)
+{
+ BLI_assert(ob->type == OB_MBALL);
-void (*BKE_mball_batch_cache_dirty_tag_cb)(MetaBall *mb, int mode) = NULL;
-void (*BKE_mball_batch_cache_free_cb)(MetaBall *mb) = NULL;
+ BKE_object_free_derived_caches(ob);
-void BKE_mball_batch_cache_dirty_tag(MetaBall *mb, int mode)
-{
- if (mb->batch_cache) {
- BKE_mball_batch_cache_dirty_tag_cb(mb, mode);
+ const Object *basis_object = BKE_mball_basis_find(scene, ob);
+ if (ob != basis_object) {
+ return;
}
-}
-void BKE_mball_batch_cache_free(MetaBall *mb)
-{
- if (mb->batch_cache) {
- BKE_mball_batch_cache_free_cb(mb);
+
+ Mesh *mesh = BKE_mball_polygonize(depsgraph, scene, ob);
+ if (mesh == nullptr) {
+ return;
}
-}
+
+ const MetaBall *mball = static_cast<MetaBall *>(ob->data);
+ mesh->mat = static_cast<Material **>(MEM_dupallocN(mball->mat));
+ mesh->totcol = mball->totcol;
+
+ if (ob->parent && ob->parent->type == OB_LATTICE && ob->partype == PARSKEL) {
+ int verts_num;
+ float(*positions)[3] = BKE_mesh_vert_coords_alloc(mesh, &verts_num);
+ BKE_lattice_deform_coords(ob->parent, ob, positions, verts_num, 0, nullptr, 1.0f);
+ BKE_mesh_vert_coords_apply(mesh, positions);
+ MEM_freeN(positions);
+ }
+
+ ob->runtime.geometry_set_eval = new GeometrySet(GeometrySet::create_with_mesh(mesh));
+
+ if (ob->runtime.bb == nullptr) {
+ ob->runtime.bb = MEM_cnew<BoundBox>(__func__);
+ }
+ blender::float3 min(std::numeric_limits<float>::max());
+ blender::float3 max(-std::numeric_limits<float>::max());
+ if (!ob->runtime.geometry_set_eval->compute_boundbox_without_instances(&min, &max)) {
+ min = blender::float3(0);
+ max = blender::float3(0);
+ }
+ BKE_boundbox_init_from_minmax(ob->runtime.bb, min, max);
+};
diff --git a/source/blender/blenkernel/intern/mball_tessellate.c b/source/blender/blenkernel/intern/mball_tessellate.c
index 54def0189b1..61f5a5f315f 100644
--- a/source/blender/blenkernel/intern/mball_tessellate.c
+++ b/source/blender/blenkernel/intern/mball_tessellate.c
@@ -14,6 +14,8 @@
#include "MEM_guardedalloc.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
#include "DNA_meta_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -24,10 +26,11 @@
#include "BLI_string_utils.h"
#include "BLI_utildefines.h"
-#include "BKE_global.h"
-
#include "BKE_displist.h"
+#include "BKE_global.h"
+#include "BKE_lib_id.h"
#include "BKE_mball_tessellate.h" /* own include */
+#include "BKE_mesh.h"
#include "BKE_object.h"
#include "BKE_scene.h"
@@ -427,8 +430,6 @@ static float metaball(PROCESS *process, float x, float y, float z)
*/
static void make_face(PROCESS *process, int i1, int i2, int i3, int i4)
{
- int *cur;
-
#ifdef USE_ACCUM_NORMAL
float n[3];
#endif
@@ -438,10 +439,9 @@ static void make_face(PROCESS *process, int i1, int i2, int i3, int i4)
process->indices = MEM_reallocN(process->indices, sizeof(int[4]) * process->totindex);
}
- cur = process->indices[process->curindex++];
-
- /* #DispList supports array drawing, treat tri's as fake quad. */
+ int *cur = process->indices[process->curindex++];
+ /* Treat triangles as fake quads. */
cur[0] = i1;
cur[1] = i2;
cur[2] = i3;
@@ -1371,7 +1371,7 @@ static void init_meta(Depsgraph *depsgraph, PROCESS *process, Scene *scene, Obje
}
}
-void BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob, ListBase *dispbase)
+Mesh *BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob)
{
PROCESS process = {0};
const bool is_render = DEG_get_mode(depsgraph) == DAG_EVAL_RENDER;
@@ -1394,10 +1394,10 @@ void BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob, ListBa
}
if (!is_render && (mb->flag == MB_UPDATE_NEVER)) {
- return;
+ return NULL;
}
if ((G.moving & (G_TRANSFORM_OBJ | G_TRANSFORM_EDIT)) && mb->flag == MB_UPDATE_FAST) {
- return;
+ return NULL;
}
if (is_render) {
@@ -1418,7 +1418,7 @@ void BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob, ListBa
init_meta(depsgraph, &process, scene, ob);
if (process.totelem == 0) {
freepolygonize(&process);
- return;
+ return NULL;
}
build_bvh_spatial(&process, &process.metaball_bvh, 0, process.totelem, &process.allbb);
@@ -1430,40 +1430,63 @@ void BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob, ListBa
ob->scale[1] < 0.00001f * (process.allbb.max[1] - process.allbb.min[1]) ||
ob->scale[2] < 0.00001f * (process.allbb.max[2] - process.allbb.min[2])) {
freepolygonize(&process);
- return;
+ return NULL;
}
polygonize(&process);
if (process.curindex == 0) {
freepolygonize(&process);
- return;
+ return NULL;
}
- /* add resulting surface to displist */
+ freepolygonize(&process);
+
+ Mesh *mesh = (Mesh *)BKE_id_new_nomain(ID_ME, ((ID *)ob->data)->name + 2);
- /* Avoid over-allocation since this is stored in the displist. */
- if (process.curindex != process.totindex) {
- process.indices = MEM_reallocN(process.indices, sizeof(int[4]) * process.curindex);
+ mesh->totvert = (int)process.curvertex;
+ MVert *mvert = CustomData_add_layer(&mesh->vdata, CD_MVERT, CD_DEFAULT, NULL, mesh->totvert);
+ for (int i = 0; i < mesh->totvert; i++) {
+ copy_v3_v3(mvert[i].co, process.co[i]);
+ mvert->bweight = 0;
+ mvert->flag = 0;
}
- if (process.curvertex != process.totvertex) {
- process.co = MEM_reallocN(process.co, process.curvertex * sizeof(float[3]));
- process.no = MEM_reallocN(process.no, process.curvertex * sizeof(float[3]));
+ MEM_freeN(process.co);
+
+ mesh->totpoly = (int)process.curindex;
+ MPoly *mpoly = CustomData_add_layer(&mesh->pdata, CD_MPOLY, CD_DEFAULT, NULL, mesh->totpoly);
+ MLoop *mloop = CustomData_add_layer(&mesh->ldata, CD_MLOOP, CD_DEFAULT, NULL, mesh->totpoly * 4);
+
+ int loop_offset = 0;
+ for (int i = 0; i < mesh->totpoly; i++) {
+ const int *indices = process.indices[i];
+
+ const int count = indices[2] != indices[3] ? 4 : 3;
+ mpoly[i].loopstart = loop_offset;
+ mpoly[i].totloop = count;
+ mpoly[i].flag = ME_SMOOTH;
+
+ mloop[loop_offset].v = (uint32_t)indices[0];
+ mloop[loop_offset + 1].v = (uint32_t)indices[1];
+ mloop[loop_offset + 2].v = (uint32_t)indices[2];
+ if (count == 4) {
+ mloop[loop_offset + 3].v = (uint32_t)indices[3];
+ }
+
+ loop_offset += count;
}
+ MEM_freeN(process.indices);
- DispList *dl = MEM_callocN(sizeof(DispList), "mballdisp");
- BLI_addtail(dispbase, dl);
- dl->type = DL_INDEX4;
- dl->nr = (int)process.curvertex;
- dl->parts = (int)process.curindex;
+ for (int i = 0; i < mesh->totvert; i++) {
+ normalize_v3(process.no[i]);
+ }
+ mesh->runtime.vert_normals = process.no;
+ BKE_mesh_vertex_normals_clear_dirty(mesh);
- dl->index = (int *)process.indices;
+ mesh->totloop = loop_offset;
- for (uint a = 0; a < process.curvertex; a++) {
- normalize_v3(process.no[a]);
- }
+ BKE_mesh_update_customdata_pointers(mesh, false);
- dl->verts = (float *)process.co;
- dl->nors = (float *)process.no;
+ BKE_mesh_calc_edges(mesh, false, false);
- freepolygonize(&process);
+ return mesh;
}
diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc
index cf05dc0404e..272dd922caa 100644
--- a/source/blender/blenkernel/intern/mesh.cc
+++ b/source/blender/blenkernel/intern/mesh.cc
@@ -28,6 +28,7 @@
#include "BLI_math.h"
#include "BLI_math_vector.hh"
#include "BLI_memarena.h"
+#include "BLI_span.hh"
#include "BLI_string.h"
#include "BLI_task.hh"
#include "BLI_utildefines.h"
@@ -36,6 +37,7 @@
#include "BLT_translation.h"
#include "BKE_anim_data.h"
+#include "BKE_attribute.hh"
#include "BKE_bpath.h"
#include "BKE_deform.h"
#include "BKE_editmesh.h"
@@ -62,6 +64,8 @@
#include "BLO_read_write.h"
using blender::float3;
+using blender::MutableSpan;
+using blender::VArray;
using blender::Vector;
static void mesh_clear_geometry(Mesh *mesh);
@@ -109,7 +113,7 @@ static void mesh_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int
*
* While this could be the callers responsibility, keep here since it's
* highly unlikely we want to create a duplicate and not use it for drawing. */
- mesh_dst->runtime.is_original = false;
+ mesh_dst->runtime.is_original_bmesh = false;
/* Only do tessface if we have no polys. */
const bool do_tessface = ((mesh_src->totface != 0) && (mesh_src->totpoly == 0));
@@ -208,6 +212,7 @@ static void mesh_foreach_path(ID *id, BPathForeachPathData *bpath_data)
static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address)
{
+ using namespace blender;
Mesh *mesh = (Mesh *)id;
const bool is_undo = BLO_write_is_undo(writer);
@@ -241,10 +246,17 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
memset(&mesh->pdata, 0, sizeof(mesh->pdata));
}
else {
- CustomData_blend_write_prepare(mesh->vdata, vert_layers);
- CustomData_blend_write_prepare(mesh->edata, edge_layers);
- CustomData_blend_write_prepare(mesh->ldata, loop_layers);
- CustomData_blend_write_prepare(mesh->pdata, poly_layers);
+ Set<std::string> names_to_skip;
+ if (!BLO_write_is_undo(writer)) {
+ BKE_mesh_legacy_convert_hide_layers_to_flags(mesh);
+ /* When converting to the old mesh format, don't save redundant attributes. */
+ names_to_skip.add_multiple_new({".hide_vert", ".hide_edge", ".hide_poly"});
+ }
+
+ CustomData_blend_write_prepare(mesh->vdata, vert_layers, names_to_skip);
+ CustomData_blend_write_prepare(mesh->edata, edge_layers, names_to_skip);
+ CustomData_blend_write_prepare(mesh->ldata, loop_layers, names_to_skip);
+ CustomData_blend_write_prepare(mesh->pdata, poly_layers, names_to_skip);
}
BLO_write_id_struct(writer, Mesh, id_address, &mesh->id);
@@ -323,6 +335,10 @@ static void mesh_blend_read_data(BlendDataReader *reader, ID *id)
}
}
+ if (!BLO_read_data_is_undo(reader)) {
+ BKE_mesh_legacy_convert_flags_to_hide_layers(mesh);
+ }
+
/* We don't expect to load normals from files, since they are derived data. */
BKE_mesh_normals_tag_dirty(mesh);
BKE_mesh_assert_normals_dirty_or_calculated(mesh);
@@ -760,10 +776,10 @@ static void mesh_ensure_tessellation_customdata(Mesh *me)
/* TODO: add some `--debug-mesh` option. */
if (G.debug & G_DEBUG) {
- /* NOTE(campbell): this warning may be un-called for if we are initializing the mesh for
- * the first time from #BMesh, rather than giving a warning about this we could be smarter
- * and check if there was any data to begin with, for now just print the warning with
- * some info to help troubleshoot what's going on. */
+ /* NOTE(@campbellbarton): this warning may be un-called for if we are initializing the mesh
+ * for the first time from #BMesh, rather than giving a warning about this we could be
+ * smarter and check if there was any data to begin with, for now just print the warning
+ * with some info to help troubleshoot what's going on. */
printf(
"%s: warning! Tessellation uvs or vcol data got out of sync, "
"had to reset!\n CD_MTFACE: %d != CD_MLOOPUV: %d || CD_MCOL: %d != "
diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc
index 81bab9f796f..3806ea76cfe 100644
--- a/source/blender/blenkernel/intern/mesh_convert.cc
+++ b/source/blender/blenkernel/intern/mesh_convert.cc
@@ -22,6 +22,7 @@
#include "BLI_index_range.hh"
#include "BLI_listbase.h"
#include "BLI_math.h"
+#include "BLI_span.hh"
#include "BLI_string.h"
#include "BLI_utildefines.h"
@@ -54,6 +55,8 @@
#include "DEG_depsgraph_query.h"
using blender::IndexRange;
+using blender::MutableSpan;
+using blender::Span;
/* Define for cases when you want extra validation of mesh
* after certain modifications.
@@ -69,87 +72,31 @@ using blender::IndexRange;
static CLG_LogRef LOG = {"bke.mesh_convert"};
-void BKE_mesh_from_metaball(ListBase *lb, Mesh *me)
-{
- DispList *dl;
- MVert *mvert;
- MLoop *mloop, *allloop;
- MPoly *mpoly;
- int a, *index;
-
- dl = (DispList *)lb->first;
- if (dl == nullptr) {
- return;
- }
-
- if (dl->type == DL_INDEX4) {
- mvert = (MVert *)CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, nullptr, dl->nr);
- allloop = mloop = (MLoop *)CustomData_add_layer(
- &me->ldata, CD_MLOOP, CD_CALLOC, nullptr, dl->parts * 4);
- mpoly = (MPoly *)CustomData_add_layer(&me->pdata, CD_MPOLY, CD_CALLOC, nullptr, dl->parts);
- me->mvert = mvert;
- me->mloop = mloop;
- me->mpoly = mpoly;
- me->totvert = dl->nr;
- me->totpoly = dl->parts;
-
- for (const int i : IndexRange(dl->nr)) {
- copy_v3_v3(me->mvert[i].co, &dl->verts[3 * i]);
- }
-
- a = dl->parts;
- index = dl->index;
- while (a--) {
- int count = index[2] != index[3] ? 4 : 3;
-
- mloop[0].v = index[0];
- mloop[1].v = index[1];
- mloop[2].v = index[2];
- if (count == 4) {
- mloop[3].v = index[3];
- }
-
- mpoly->totloop = count;
- mpoly->loopstart = (int)(mloop - allloop);
- mpoly->flag = ME_SMOOTH;
-
- mpoly++;
- mloop += count;
- me->totloop += count;
- index += 4;
- }
-
- BKE_mesh_update_customdata_pointers(me, true);
- BKE_mesh_calc_edges(me, true, false);
- }
-}
-
/**
* Specialized function to use when we _know_ existing edges don't overlap with poly edges.
*/
-static void make_edges_mdata_extend(
- MEdge **r_alledge, int *r_totedge, const MPoly *mpoly, MLoop *mloop, const int totpoly)
+static void make_edges_mdata_extend(Mesh &mesh)
{
- int totedge = *r_totedge;
- int totedge_new;
- EdgeHash *eh;
- uint eh_reserve;
+ int totedge = mesh.totedge;
const MPoly *mp;
int i;
- eh_reserve = max_ii(totedge, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(totpoly));
- eh = BLI_edgehash_new_ex(__func__, eh_reserve);
+ Span<MPoly> polys(mesh.mpoly, mesh.totpoly);
+ MutableSpan<MLoop> loops(mesh.mloop, mesh.totloop);
- for (i = 0, mp = mpoly; i < totpoly; i++, mp++) {
- BKE_mesh_poly_edgehash_insert(eh, mp, mloop + mp->loopstart);
+ const int eh_reserve = max_ii(totedge, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(mesh.totpoly));
+ EdgeHash *eh = BLI_edgehash_new_ex(__func__, eh_reserve);
+
+ for (const MPoly &poly : polys) {
+ BKE_mesh_poly_edgehash_insert(eh, &poly, &loops[poly.loopstart]);
}
- totedge_new = BLI_edgehash_len(eh);
+ const int totedge_new = BLI_edgehash_len(eh);
#ifdef DEBUG
/* ensure that there's no overlap! */
if (totedge_new) {
- MEdge *medge = *r_alledge;
+ MEdge *medge = mesh.medge;
for (i = 0; i < totedge; i++, medge++) {
BLI_assert(BLI_edgehash_haskey(eh, medge->v1, medge->v2) == false);
}
@@ -157,19 +104,15 @@ static void make_edges_mdata_extend(
#endif
if (totedge_new) {
- EdgeHashIterator *ehi;
- MEdge *medge;
- uint e_index = totedge;
+ CustomData_realloc(&mesh.edata, totedge + totedge_new);
+ BKE_mesh_update_customdata_pointers(&mesh, false);
- *r_alledge = medge = (MEdge *)(*r_alledge ?
- MEM_reallocN(*r_alledge,
- sizeof(MEdge) * (totedge + totedge_new)) :
- MEM_calloc_arrayN(totedge_new, sizeof(MEdge), __func__));
- medge += totedge;
+ MEdge *medge = mesh.medge + totedge;
- totedge += totedge_new;
+ mesh.totedge += totedge_new;
- /* --- */
+ EdgeHashIterator *ehi;
+ uint e_index = totedge;
for (ehi = BLI_edgehashIterator_new(eh); BLI_edgehashIterator_isDone(ehi) == false;
BLI_edgehashIterator_step(ehi), ++medge, e_index++) {
BLI_edgehashIterator_getKey(ehi, &medge->v1, &medge->v2);
@@ -180,10 +123,8 @@ static void make_edges_mdata_extend(
}
BLI_edgehashIterator_free(ehi);
- *r_totedge = totedge;
-
- for (i = 0, mp = mpoly; i < totpoly; i++, mp++) {
- MLoop *l = &mloop[mp->loopstart];
+ for (i = 0, mp = mesh.mpoly; i < mesh.totpoly; i++, mp++) {
+ MLoop *l = &loops[mp->loopstart];
MLoop *l_prev = (l + (mp->totloop - 1));
int j;
for (j = 0; j < mp->totloop; j++, l++) {
@@ -197,25 +138,8 @@ static void make_edges_mdata_extend(
BLI_edgehash_free(eh, nullptr);
}
-/* Initialize mverts, medges and, faces for converting nurbs to mesh and derived mesh */
-/* use specified dispbase */
-static int mesh_nurbs_displist_to_mdata(const Curve *cu,
- const ListBase *dispbase,
- MVert **r_allvert,
- int *r_totvert,
- MEdge **r_alledge,
- int *r_totedge,
- MLoop **r_allloop,
- MPoly **r_allpoly,
- MLoopUV **r_alluv,
- int *r_totloop,
- int *r_totpoly)
+static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispbase)
{
- MVert *mvert;
- MPoly *mpoly;
- MLoop *mloop;
- MLoopUV *mloopuv = nullptr;
- MEdge *medge;
const float *data;
int a, b, ofs, vertcount, startvert, totvert = 0, totedge = 0, totloop = 0, totpoly = 0;
int p1, p2, p3, p4, *index;
@@ -257,21 +181,21 @@ static int mesh_nurbs_displist_to_mdata(const Curve *cu,
}
if (totvert == 0) {
- /* Make Sure you check ob->data is a curve. */
- // error("can't convert");
- return -1;
+ return BKE_mesh_new_nomain(0, 0, 0, 0, 0);
}
- *r_allvert = mvert = (MVert *)MEM_calloc_arrayN(totvert, sizeof(MVert), "nurbs_init mvert");
- *r_alledge = medge = (MEdge *)MEM_calloc_arrayN(totedge, sizeof(MEdge), "nurbs_init medge");
- *r_allloop = mloop = (MLoop *)MEM_calloc_arrayN(
- totpoly, sizeof(MLoop[4]), "nurbs_init mloop"); /* totloop */
- *r_allpoly = mpoly = (MPoly *)MEM_calloc_arrayN(totpoly, sizeof(MPoly), "nurbs_init mloop");
+ Mesh *mesh = BKE_mesh_new_nomain(totvert, totedge, 0, totloop, totpoly);
+ MutableSpan<MVert> verts(mesh->mvert, mesh->totvert);
+ MutableSpan<MEdge> edges(mesh->medge, mesh->totedge);
+ MutableSpan<MPoly> polys(mesh->mpoly, mesh->totpoly);
+ MutableSpan<MLoop> loops(mesh->mloop, mesh->totloop);
- if (r_alluv) {
- *r_alluv = mloopuv = (MLoopUV *)MEM_calloc_arrayN(
- totpoly, sizeof(MLoopUV[4]), "nurbs_init mloopuv");
- }
+ MVert *mvert = verts.data();
+ MEdge *medge = edges.data();
+ MPoly *mpoly = polys.data();
+ MLoop *mloop = loops.data();
+ MLoopUV *mloopuv = static_cast<MLoopUV *>(CustomData_add_layer_named(
+ &mesh->ldata, CD_MLOOPUV, CD_CALLOC, nullptr, mesh->totloop, "UVMap"));
/* verts and faces */
vertcount = 0;
@@ -346,7 +270,7 @@ static int mesh_nurbs_displist_to_mdata(const Curve *cu,
mloop[0].v = startvert + index[0];
mloop[1].v = startvert + index[2];
mloop[2].v = startvert + index[1];
- mpoly->loopstart = (int)(mloop - (*r_allloop));
+ mpoly->loopstart = (int)(mloop - loops.data());
mpoly->totloop = 3;
mpoly->mat_nr = dl->col;
@@ -406,7 +330,7 @@ static int mesh_nurbs_displist_to_mdata(const Curve *cu,
mloop[1].v = p3;
mloop[2].v = p4;
mloop[3].v = p2;
- mpoly->loopstart = (int)(mloop - (*r_allloop));
+ mpoly->loopstart = (int)(mloop - loops.data());
mpoly->totloop = 4;
mpoly->mat_nr = dl->col;
@@ -458,15 +382,10 @@ static int mesh_nurbs_displist_to_mdata(const Curve *cu,
}
if (totpoly) {
- make_edges_mdata_extend(r_alledge, &totedge, *r_allpoly, *r_allloop, totpoly);
+ make_edges_mdata_extend(*mesh);
}
- *r_totpoly = totpoly;
- *r_totloop = totloop;
- *r_totedge = totedge;
- *r_totvert = totvert;
-
- return 0;
+ return mesh;
}
/**
@@ -487,60 +406,12 @@ static void mesh_copy_texture_space_from_curve_type(const Curve *cu, Mesh *me)
Mesh *BKE_mesh_new_nomain_from_curve_displist(const Object *ob, const ListBase *dispbase)
{
const Curve *cu = (const Curve *)ob->data;
- Mesh *mesh;
- MVert *allvert;
- MEdge *alledge;
- MLoop *allloop;
- MPoly *allpoly;
- MLoopUV *alluv = nullptr;
- int totvert, totedge, totloop, totpoly;
-
- if (mesh_nurbs_displist_to_mdata(cu,
- dispbase,
- &allvert,
- &totvert,
- &alledge,
- &totedge,
- &allloop,
- &allpoly,
- &alluv,
- &totloop,
- &totpoly) != 0) {
- /* Error initializing mdata. This often happens when curve is empty */
- return BKE_mesh_new_nomain(0, 0, 0, 0, 0);
- }
-
- mesh = BKE_mesh_new_nomain(totvert, totedge, 0, totloop, totpoly);
-
- 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";
- CustomData_add_layer_named(&mesh->ldata, CD_MLOOPUV, CD_ASSIGN, alluv, totloop, uvname);
- }
+ Mesh *mesh = mesh_nurbs_displist_to_mesh(cu, dispbase);
mesh_copy_texture_space_from_curve_type(cu, mesh);
-
- /* Copy curve materials. */
mesh->mat = (Material **)MEM_dupallocN(cu->mat);
mesh->totcol = cu->totcol;
- MEM_freeN(allvert);
- MEM_freeN(alledge);
- MEM_freeN(allloop);
- MEM_freeN(allpoly);
-
return mesh;
}
@@ -1003,32 +874,21 @@ static Mesh *mesh_new_from_curve_type_object(const Object *object)
static Mesh *mesh_new_from_mball_object(Object *object)
{
- MetaBall *mball = (MetaBall *)object->data;
-
/* NOTE: We can only create mesh for a polygonized meta ball. This figures out all original meta
* balls and all evaluated child meta balls (since polygonization is only stored in the mother
* ball).
*
* Create empty mesh so script-authors don't run into None objects. */
- if (!DEG_is_evaluated_object(object) || object->runtime.curve_cache == nullptr ||
- BLI_listbase_is_empty(&object->runtime.curve_cache->disp)) {
+ if (!DEG_is_evaluated_object(object)) {
return (Mesh *)BKE_id_new_nomain(ID_ME, ((ID *)object->data)->name + 2);
}
- Mesh *mesh_result = (Mesh *)BKE_id_new_nomain(ID_ME, ((ID *)object->data)->name + 2);
- BKE_mesh_from_metaball(&object->runtime.curve_cache->disp, mesh_result);
- BKE_mesh_texspace_copy_from_object(mesh_result, object);
-
- /* Copy materials. */
- mesh_result->totcol = mball->totcol;
- mesh_result->mat = (Material **)MEM_dupallocN(mball->mat);
- if (mball->mat != nullptr) {
- for (int i = mball->totcol; i-- > 0;) {
- mesh_result->mat[i] = BKE_object_material_get(object, i + 1);
- }
+ const Mesh *mesh_eval = BKE_object_get_evaluated_mesh(object);
+ if (mesh_eval == nullptr) {
+ return (Mesh *)BKE_id_new_nomain(ID_ME, ((ID *)object->data)->name + 2);
}
- return mesh_result;
+ return BKE_mesh_copy_for_eval(mesh_eval, false);
}
static Mesh *mesh_new_from_mesh(Object *object, Mesh *mesh)
diff --git a/source/blender/blenkernel/intern/mesh_debug.cc b/source/blender/blenkernel/intern/mesh_debug.cc
index 6f12726d364..1826a77d6f4 100644
--- a/source/blender/blenkernel/intern/mesh_debug.cc
+++ b/source/blender/blenkernel/intern/mesh_debug.cc
@@ -58,7 +58,8 @@ char *BKE_mesh_debug_info(const Mesh *me)
BLI_dynstr_appendf(dynstr, " 'totpoly': %d,\n", me->totpoly);
BLI_dynstr_appendf(dynstr, " 'runtime.deformed_only': %d,\n", me->runtime.deformed_only);
- BLI_dynstr_appendf(dynstr, " 'runtime.is_original': %d,\n", me->runtime.is_original);
+ BLI_dynstr_appendf(
+ dynstr, " 'runtime.is_original_bmesh': %d,\n", me->runtime.is_original_bmesh);
BLI_dynstr_append(dynstr, " 'vert_layers': (\n");
CustomData_debug_info_from_layers(&me->vdata, indent8, dynstr);
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.cc b/source/blender/blenkernel/intern/mesh_evaluate.cc
index 7d26262a504..9dba8eab340 100644
--- a/source/blender/blenkernel/intern/mesh_evaluate.cc
+++ b/source/blender/blenkernel/intern/mesh_evaluate.cc
@@ -22,15 +22,17 @@
#include "BLI_math.h"
#include "BLI_span.hh"
#include "BLI_utildefines.h"
+#include "BLI_virtual_array.hh"
#include "BKE_customdata.h"
+#include "BKE_attribute.hh"
#include "BKE_mesh.h"
#include "BKE_multires.h"
-using blender::IndexRange;
using blender::MutableSpan;
using blender::Span;
+using blender::VArray;
/* -------------------------------------------------------------------- */
/** \name Polygon Calculations
@@ -732,75 +734,90 @@ void BKE_mesh_polygons_flip(MPoly *mpoly, MLoop *mloop, CustomData *ldata, int t
/** \name Mesh Flag Flushing
* \{ */
-void BKE_mesh_flush_hidden_from_verts_ex(const MVert *mvert,
- const MLoop *mloop,
- MEdge *medge,
- const int totedge,
- MPoly *mpoly,
- const int totpoly)
+void BKE_mesh_flush_hidden_from_verts(Mesh *me)
{
- int i, j;
+ using namespace blender;
+ using namespace blender::bke;
+ MutableAttributeAccessor attributes = mesh_attributes_for_write(*me);
- for (i = 0; i < totedge; i++) {
- MEdge *e = &medge[i];
- if (mvert[e->v1].flag & ME_HIDE || mvert[e->v2].flag & ME_HIDE) {
- e->flag |= ME_HIDE;
- }
- else {
- e->flag &= ~ME_HIDE;
- }
+ const VArray<bool> hide_vert = attributes.lookup_or_default<bool>(
+ ".hide_vert", ATTR_DOMAIN_POINT, false);
+ if (hide_vert.is_single() && !hide_vert.get_internal_single()) {
+ attributes.remove(".hide_edge");
+ attributes.remove(".hide_poly");
+ return;
}
- for (i = 0; i < totpoly; i++) {
- MPoly *p = &mpoly[i];
- p->flag &= (char)~ME_HIDE;
- for (j = 0; j < p->totloop; j++) {
- if (mvert[mloop[p->loopstart + j].v].flag & ME_HIDE) {
- p->flag |= ME_HIDE;
- }
- }
+ const VArraySpan<bool> hide_vert_span{hide_vert};
+ const Span<MEdge> edges(me->medge, me->totedge);
+ const Span<MPoly> polys(me->mpoly, me->totpoly);
+ const Span<MLoop> loops(me->mloop, me->totloop);
+
+ /* Hide edges when either of their vertices are hidden. */
+ SpanAttributeWriter<bool> hide_edge = attributes.lookup_or_add_for_write_only_span<bool>(
+ ".hide_edge", ATTR_DOMAIN_EDGE);
+ for (const int i : edges.index_range()) {
+ const MEdge &edge = edges[i];
+ hide_edge.span[i] = hide_vert_span[edge.v1] || hide_vert_span[edge.v2];
}
-}
-void BKE_mesh_flush_hidden_from_verts(Mesh *me)
-{
- BKE_mesh_flush_hidden_from_verts_ex(
- me->mvert, me->mloop, me->medge, me->totedge, me->mpoly, me->totpoly);
+ hide_edge.finish();
+
+ /* Hide polygons when any of their vertices are hidden. */
+ SpanAttributeWriter<bool> hide_poly = attributes.lookup_or_add_for_write_only_span<bool>(
+ ".hide_poly", ATTR_DOMAIN_FACE);
+ for (const int i : polys.index_range()) {
+ const MPoly &poly = polys[i];
+ const Span<MLoop> poly_loops = loops.slice(poly.loopstart, poly.totloop);
+ hide_poly.span[i] = std::any_of(poly_loops.begin(), poly_loops.end(), [&](const MLoop &loop) {
+ return hide_vert_span[loop.v];
+ });
+ }
+ hide_poly.finish();
}
-void BKE_mesh_flush_hidden_from_polys_ex(MVert *mvert,
- const MLoop *mloop,
- MEdge *medge,
- const int UNUSED(totedge),
- const MPoly *mpoly,
- const int totpoly)
+void BKE_mesh_flush_hidden_from_polys(Mesh *me)
{
- int i = totpoly;
- for (const MPoly *mp = mpoly; i--; mp++) {
- if (mp->flag & ME_HIDE) {
- const MLoop *ml;
- int j = mp->totloop;
- for (ml = &mloop[mp->loopstart]; j--; ml++) {
- mvert[ml->v].flag |= ME_HIDE;
- medge[ml->e].flag |= ME_HIDE;
+ using namespace blender;
+ using namespace blender::bke;
+ MutableAttributeAccessor attributes = mesh_attributes_for_write(*me);
+
+ const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
+ ".hide_poly", ATTR_DOMAIN_FACE, false);
+ if (hide_poly.is_single() && !hide_poly.get_internal_single()) {
+ attributes.remove(".hide_vert");
+ attributes.remove(".hide_edge");
+ return;
+ }
+ const VArraySpan<bool> hide_poly_span{hide_poly};
+ const Span<MPoly> polys(me->mpoly, me->totpoly);
+ const Span<MLoop> loops(me->mloop, me->totloop);
+ SpanAttributeWriter<bool> hide_vert = attributes.lookup_or_add_for_write_only_span<bool>(
+ ".hide_vert", ATTR_DOMAIN_POINT);
+ SpanAttributeWriter<bool> hide_edge = attributes.lookup_or_add_for_write_only_span<bool>(
+ ".hide_edge", ATTR_DOMAIN_EDGE);
+
+ /* Hide all edges or vertices connected to hidden polygons. */
+ for (const int i : polys.index_range()) {
+ if (hide_poly_span[i]) {
+ const MPoly &poly = polys[i];
+ for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) {
+ hide_vert.span[loop.v] = true;
+ hide_edge.span[loop.e] = true;
}
}
}
-
- i = totpoly;
- for (const MPoly *mp = mpoly; i--; mp++) {
- if ((mp->flag & ME_HIDE) == 0) {
- const MLoop *ml;
- int j = mp->totloop;
- for (ml = &mloop[mp->loopstart]; j--; ml++) {
- mvert[ml->v].flag &= (char)~ME_HIDE;
- medge[ml->e].flag &= (short)~ME_HIDE;
+ /* Unhide vertices and edges connected to visible polygons. */
+ for (const int i : polys.index_range()) {
+ if (!hide_poly_span[i]) {
+ const MPoly &poly = polys[i];
+ for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) {
+ hide_vert.span[loop.v] = false;
+ hide_edge.span[loop.e] = false;
}
}
}
-}
-void BKE_mesh_flush_hidden_from_polys(Mesh *me)
-{
- BKE_mesh_flush_hidden_from_polys_ex(
- me->mvert, me->mloop, me->medge, me->totedge, me->mpoly, me->totpoly);
+
+ hide_vert.finish();
+ hide_edge.finish();
}
void BKE_mesh_flush_select_from_polys_ex(MVert *mvert,
@@ -848,11 +865,13 @@ void BKE_mesh_flush_select_from_polys(Mesh *me)
static void mesh_flush_select_from_verts(const Span<MVert> verts,
const Span<MLoop> loops,
+ const VArray<bool> &hide_edge,
+ const VArray<bool> &hide_poly,
MutableSpan<MEdge> edges,
MutableSpan<MPoly> polys)
{
for (const int i : edges.index_range()) {
- if ((edges[i].flag & ME_HIDE) == 0) {
+ if (!hide_edge[i]) {
MEdge &edge = edges[i];
if ((verts[edge.v1].flag & SELECT) && (verts[edge.v2].flag & SELECT)) {
edge.flag |= SELECT;
@@ -864,7 +883,7 @@ static void mesh_flush_select_from_verts(const Span<MVert> verts,
}
for (const int i : polys.index_range()) {
- if (polys[i].flag & ME_HIDE) {
+ if (hide_poly[i]) {
continue;
}
MPoly &poly = polys[i];
@@ -885,10 +904,14 @@ static void mesh_flush_select_from_verts(const Span<MVert> verts,
void BKE_mesh_flush_select_from_verts(Mesh *me)
{
- mesh_flush_select_from_verts({me->mvert, me->totvert},
- {me->mloop, me->totloop},
- {me->medge, me->totedge},
- {me->mpoly, me->totpoly});
+ const blender::bke::AttributeAccessor attributes = blender::bke::mesh_attributes(*me);
+ mesh_flush_select_from_verts(
+ {me->mvert, me->totvert},
+ {me->mloop, me->totloop},
+ attributes.lookup_or_default<bool>(".hide_edge", ATTR_DOMAIN_EDGE, false),
+ attributes.lookup_or_default<bool>(".hide_poly", ATTR_DOMAIN_FACE, false),
+ {me->medge, me->totedge},
+ {me->mpoly, me->totpoly});
}
/** \} */
diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc
index 479dd6a012a..cc96a5e8c60 100644
--- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc
+++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc
@@ -7,7 +7,7 @@
* Functions to convert mesh data to and from legacy formats like #MFace.
*/
-// #include <climits>
+#define DNA_DEPRECATED_ALLOW
#include "MEM_guardedalloc.h"
@@ -18,8 +18,10 @@
#include "BLI_math.h"
#include "BLI_memarena.h"
#include "BLI_polyfill_2d.h"
+#include "BLI_task.hh"
#include "BLI_utildefines.h"
+#include "BKE_attribute.hh"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
#include "BKE_mesh_legacy_convert.h"
@@ -874,3 +876,89 @@ void BKE_mesh_add_mface_layers(CustomData *fdata, CustomData *ldata, int total)
}
/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Hide Attribute and Legacy Flag Conversion
+ * \{ */
+
+void BKE_mesh_legacy_convert_hide_layers_to_flags(Mesh *mesh)
+{
+ using namespace blender;
+ using namespace blender::bke;
+ const AttributeAccessor attributes = mesh_attributes(*mesh);
+
+ MutableSpan<MVert> verts(mesh->mvert, mesh->totvert);
+ const VArray<bool> hide_vert = attributes.lookup_or_default<bool>(
+ ".hide_vert", ATTR_DOMAIN_POINT, false);
+ threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) {
+ for (const int i : range) {
+ SET_FLAG_FROM_TEST(verts[i].flag, hide_vert[i], ME_HIDE);
+ }
+ });
+
+ MutableSpan<MEdge> edges(mesh->medge, mesh->totedge);
+ const VArray<bool> hide_edge = attributes.lookup_or_default<bool>(
+ ".hide_edge", ATTR_DOMAIN_EDGE, false);
+ threading::parallel_for(edges.index_range(), 4096, [&](IndexRange range) {
+ for (const int i : range) {
+ SET_FLAG_FROM_TEST(edges[i].flag, hide_edge[i], ME_HIDE);
+ }
+ });
+
+ MutableSpan<MPoly> polys(mesh->mpoly, mesh->totpoly);
+ const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
+ ".hide_poly", ATTR_DOMAIN_FACE, false);
+ threading::parallel_for(polys.index_range(), 4096, [&](IndexRange range) {
+ for (const int i : range) {
+ SET_FLAG_FROM_TEST(polys[i].flag, hide_poly[i], ME_HIDE);
+ }
+ });
+}
+
+void BKE_mesh_legacy_convert_flags_to_hide_layers(Mesh *mesh)
+{
+ using namespace blender;
+ using namespace blender::bke;
+ MutableAttributeAccessor attributes = mesh_attributes_for_write(*mesh);
+
+ const Span<MVert> verts(mesh->mvert, mesh->totvert);
+ if (std::any_of(
+ verts.begin(), verts.end(), [](const MVert &vert) { return vert.flag & ME_HIDE; })) {
+ SpanAttributeWriter<bool> hide_vert = attributes.lookup_or_add_for_write_only_span<bool>(
+ ".hide_vert", ATTR_DOMAIN_POINT);
+ threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) {
+ for (const int i : range) {
+ hide_vert.span[i] = verts[i].flag & ME_HIDE;
+ }
+ });
+ hide_vert.finish();
+ }
+
+ const Span<MEdge> edges(mesh->medge, mesh->totedge);
+ if (std::any_of(
+ edges.begin(), edges.end(), [](const MEdge &edge) { return edge.flag & ME_HIDE; })) {
+ SpanAttributeWriter<bool> hide_edge = attributes.lookup_or_add_for_write_only_span<bool>(
+ ".hide_edge", ATTR_DOMAIN_EDGE);
+ threading::parallel_for(edges.index_range(), 4096, [&](IndexRange range) {
+ for (const int i : range) {
+ hide_edge.span[i] = edges[i].flag & ME_HIDE;
+ }
+ });
+ hide_edge.finish();
+ }
+
+ const Span<MPoly> polys(mesh->mpoly, mesh->totpoly);
+ if (std::any_of(
+ polys.begin(), polys.end(), [](const MPoly &poly) { return poly.flag & ME_HIDE; })) {
+ SpanAttributeWriter<bool> hide_poly = attributes.lookup_or_add_for_write_only_span<bool>(
+ ".hide_poly", ATTR_DOMAIN_FACE);
+ threading::parallel_for(polys.index_range(), 4096, [&](IndexRange range) {
+ for (const int i : range) {
+ hide_poly.span[i] = polys[i].flag & ME_HIDE;
+ }
+ });
+ hide_poly.finish();
+ }
+}
+
+/** \} */
diff --git a/source/blender/blenkernel/intern/mesh_mapping.c b/source/blender/blenkernel/intern/mesh_mapping.c
index 9c4098e2db6..798fe087ea8 100644
--- a/source/blender/blenkernel/intern/mesh_mapping.c
+++ b/source/blender/blenkernel/intern/mesh_mapping.c
@@ -29,6 +29,7 @@
/* ngon version wip, based on BM_uv_vert_map_create */
UvVertMap *BKE_mesh_uv_vert_map_create(const MPoly *mpoly,
+ const bool *hide_poly,
const MLoop *mloop,
const MLoopUV *mloopuv,
uint totpoly,
@@ -51,7 +52,7 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const MPoly *mpoly,
/* generate UvMapVert array */
mp = mpoly;
for (a = 0; a < totpoly; a++, mp++) {
- if (!selected || (!(mp->flag & ME_HIDE) && (mp->flag & ME_FACE_SEL))) {
+ if (!selected || (!(hide_poly && hide_poly[a]) && (mp->flag & ME_FACE_SEL))) {
totuv += mp->totloop;
}
}
@@ -74,7 +75,7 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const MPoly *mpoly,
mp = mpoly;
for (a = 0; a < totpoly; a++, mp++) {
- if (!selected || (!(mp->flag & ME_HIDE) && (mp->flag & ME_FACE_SEL))) {
+ if (!selected || (!(hide_poly && hide_poly[a]) && (mp->flag & ME_FACE_SEL))) {
float(*tf_uv)[2] = NULL;
if (use_winding) {
diff --git a/source/blender/blenkernel/intern/mesh_remap.c b/source/blender/blenkernel/intern/mesh_remap.c
index 3a37c29c1d0..5313cc39646 100644
--- a/source/blender/blenkernel/intern/mesh_remap.c
+++ b/source/blender/blenkernel/intern/mesh_remap.c
@@ -312,15 +312,10 @@ void BKE_mesh_remap_calc_source_cddata_masks_from_map_modes(const int UNUSED(ver
{
/* vert, edge and poly mapping modes never need extra cddata from source object. */
const bool need_lnors_src = (loop_mode & MREMAP_USE_LOOP) && (loop_mode & MREMAP_USE_NORMAL);
- const bool need_pnors_src = need_lnors_src ||
- ((loop_mode & MREMAP_USE_POLY) && (loop_mode & MREMAP_USE_NORMAL));
if (need_lnors_src) {
r_cddata_mask->lmask |= CD_MASK_NORMAL;
}
- if (need_pnors_src) {
- r_cddata_mask->pmask |= CD_MASK_NORMAL;
- }
}
void BKE_mesh_remap_init(MeshPairRemap *map, const int items_num)
diff --git a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc
index 85aed01ce52..423f76407a0 100644
--- a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc
+++ b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc
@@ -275,11 +275,15 @@ Mesh *BKE_mesh_remesh_voxel(const Mesh *mesh,
#endif
}
-void BKE_mesh_remesh_reproject_paint_mask(Mesh *target, Mesh *source)
+void BKE_mesh_remesh_reproject_paint_mask(Mesh *target, const Mesh *source)
{
BVHTreeFromMesh bvhtree = {nullptr};
BKE_bvhtree_from_mesh_get(&bvhtree, source, BVHTREE_FROM_VERTS, 2);
- MVert *target_verts = (MVert *)CustomData_get_layer(&target->vdata, CD_MVERT);
+ const MVert *target_verts = (const MVert *)CustomData_get_layer(&target->vdata, CD_MVERT);
+ const float *source_mask = (const float *)CustomData_get_layer(&source->vdata, CD_PAINT_MASK);
+ if (source_mask == nullptr) {
+ return;
+ }
float *target_mask;
if (CustomData_has_layer(&target->vdata, CD_PAINT_MASK)) {
@@ -290,15 +294,6 @@ void BKE_mesh_remesh_reproject_paint_mask(Mesh *target, Mesh *source)
&target->vdata, CD_PAINT_MASK, CD_CALLOC, nullptr, target->totvert);
}
- const float *source_mask;
- if (CustomData_has_layer(&source->vdata, CD_PAINT_MASK)) {
- source_mask = (float *)CustomData_get_layer(&source->vdata, CD_PAINT_MASK);
- }
- else {
- source_mask = (float *)CustomData_add_layer(
- &source->vdata, CD_PAINT_MASK, CD_CALLOC, nullptr, source->totvert);
- }
-
for (int i = 0; i < target->totvert; i++) {
float from_co[3];
BVHTreeNearest nearest;
@@ -313,13 +308,16 @@ void BKE_mesh_remesh_reproject_paint_mask(Mesh *target, Mesh *source)
free_bvhtree_from_mesh(&bvhtree);
}
-void BKE_remesh_reproject_sculpt_face_sets(Mesh *target, Mesh *source)
+void BKE_remesh_reproject_sculpt_face_sets(Mesh *target, const Mesh *source)
{
- BVHTreeFromMesh bvhtree = {nullptr};
-
const MPoly *target_polys = (const MPoly *)CustomData_get_layer(&target->pdata, CD_MPOLY);
const MVert *target_verts = (const MVert *)CustomData_get_layer(&target->vdata, CD_MVERT);
const MLoop *target_loops = (const MLoop *)CustomData_get_layer(&target->ldata, CD_MLOOP);
+ const int *source_face_sets = (const int *)CustomData_get_layer(&source->pdata,
+ CD_SCULPT_FACE_SETS);
+ if (source_face_sets == nullptr) {
+ return;
+ }
int *target_face_sets;
if (CustomData_has_layer(&target->pdata, CD_SCULPT_FACE_SETS)) {
@@ -330,16 +328,8 @@ void BKE_remesh_reproject_sculpt_face_sets(Mesh *target, Mesh *source)
&target->pdata, CD_SCULPT_FACE_SETS, CD_CALLOC, nullptr, target->totpoly);
}
- const int *source_face_sets;
- if (CustomData_has_layer(&source->pdata, CD_SCULPT_FACE_SETS)) {
- source_face_sets = (const int *)CustomData_get_layer(&source->pdata, CD_SCULPT_FACE_SETS);
- }
- else {
- source_face_sets = (const int *)CustomData_add_layer(
- &source->pdata, CD_SCULPT_FACE_SETS, CD_CALLOC, nullptr, source->totpoly);
- }
-
const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(source);
+ BVHTreeFromMesh bvhtree = {nullptr};
BKE_bvhtree_from_mesh_get(&bvhtree, source, BVHTREE_FROM_LOOPTRI, 2);
for (int i = 0; i < target->totpoly; i++) {
diff --git a/source/blender/blenkernel/intern/mesh_sample.cc b/source/blender/blenkernel/intern/mesh_sample.cc
index dd09a3d6917..e54f2e6d687 100644
--- a/source/blender/blenkernel/intern/mesh_sample.cc
+++ b/source/blender/blenkernel/intern/mesh_sample.cc
@@ -16,9 +16,9 @@ template<typename T>
BLI_NOINLINE static void sample_point_attribute(const Mesh &mesh,
const Span<int> looptri_indices,
const Span<float3> bary_coords,
- const VArray<T> &data_in,
+ const VArray<T> &src,
const IndexMask mask,
- const MutableSpan<T> data_out)
+ const MutableSpan<T> dst)
{
const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
BKE_mesh_runtime_looptri_len(&mesh)};
@@ -32,30 +32,30 @@ BLI_NOINLINE static void sample_point_attribute(const Mesh &mesh,
const int v1_index = mesh.mloop[looptri.tri[1]].v;
const int v2_index = mesh.mloop[looptri.tri[2]].v;
- const T v0 = data_in[v0_index];
- const T v1 = data_in[v1_index];
- const T v2 = data_in[v2_index];
+ const T v0 = src[v0_index];
+ const T v1 = src[v1_index];
+ const T v2 = src[v2_index];
const T interpolated_value = attribute_math::mix3(bary_coord, v0, v1, v2);
- data_out[i] = interpolated_value;
+ dst[i] = interpolated_value;
}
}
void sample_point_attribute(const Mesh &mesh,
const Span<int> looptri_indices,
const Span<float3> bary_coords,
- const GVArray &data_in,
+ const GVArray &src,
const IndexMask mask,
- const GMutableSpan data_out)
+ const GMutableSpan dst)
{
- BLI_assert(data_in.size() == mesh.totvert);
- BLI_assert(data_in.type() == data_out.type());
+ BLI_assert(src.size() == mesh.totvert);
+ BLI_assert(src.type() == dst.type());
- const CPPType &type = data_in.type();
+ const CPPType &type = src.type();
attribute_math::convert_to_static_type(type, [&](auto dummy) {
using T = decltype(dummy);
sample_point_attribute<T>(
- mesh, looptri_indices, bary_coords, data_in.typed<T>(), mask, data_out.typed<T>());
+ mesh, looptri_indices, bary_coords, src.typed<T>(), mask, dst.typed<T>());
});
}
@@ -63,9 +63,9 @@ template<typename T>
BLI_NOINLINE static void sample_corner_attribute(const Mesh &mesh,
const Span<int> looptri_indices,
const Span<float3> bary_coords,
- const VArray<T> &data_in,
+ const VArray<T> &src,
const IndexMask mask,
- const MutableSpan<T> data_out)
+ const MutableSpan<T> dst)
{
const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
BKE_mesh_runtime_looptri_len(&mesh)};
@@ -79,39 +79,39 @@ BLI_NOINLINE static void sample_corner_attribute(const Mesh &mesh,
const int loop_index_1 = looptri.tri[1];
const int loop_index_2 = looptri.tri[2];
- const T v0 = data_in[loop_index_0];
- const T v1 = data_in[loop_index_1];
- const T v2 = data_in[loop_index_2];
+ const T v0 = src[loop_index_0];
+ const T v1 = src[loop_index_1];
+ const T v2 = src[loop_index_2];
const T interpolated_value = attribute_math::mix3(bary_coord, v0, v1, v2);
- data_out[i] = interpolated_value;
+ dst[i] = interpolated_value;
}
}
void sample_corner_attribute(const Mesh &mesh,
const Span<int> looptri_indices,
const Span<float3> bary_coords,
- const GVArray &data_in,
+ const GVArray &src,
const IndexMask mask,
- const GMutableSpan data_out)
+ const GMutableSpan dst)
{
- BLI_assert(data_in.size() == mesh.totloop);
- BLI_assert(data_in.type() == data_out.type());
+ BLI_assert(src.size() == mesh.totloop);
+ BLI_assert(src.type() == dst.type());
- const CPPType &type = data_in.type();
+ const CPPType &type = src.type();
attribute_math::convert_to_static_type(type, [&](auto dummy) {
using T = decltype(dummy);
sample_corner_attribute<T>(
- mesh, looptri_indices, bary_coords, data_in.typed<T>(), mask, data_out.typed<T>());
+ mesh, looptri_indices, bary_coords, src.typed<T>(), mask, dst.typed<T>());
});
}
template<typename T>
void sample_face_attribute(const Mesh &mesh,
const Span<int> looptri_indices,
- const VArray<T> &data_in,
+ const VArray<T> &src,
const IndexMask mask,
- const MutableSpan<T> data_out)
+ const MutableSpan<T> dst)
{
const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
BKE_mesh_runtime_looptri_len(&mesh)};
@@ -120,23 +120,23 @@ void sample_face_attribute(const Mesh &mesh,
const int looptri_index = looptri_indices[i];
const MLoopTri &looptri = looptris[looptri_index];
const int poly_index = looptri.poly;
- data_out[i] = data_in[poly_index];
+ dst[i] = src[poly_index];
}
}
void sample_face_attribute(const Mesh &mesh,
const Span<int> looptri_indices,
- const GVArray &data_in,
+ const GVArray &src,
const IndexMask mask,
- const GMutableSpan data_out)
+ const GMutableSpan dst)
{
- BLI_assert(data_in.size() == mesh.totpoly);
- BLI_assert(data_in.type() == data_out.type());
+ BLI_assert(src.size() == mesh.totpoly);
+ BLI_assert(src.type() == dst.type());
- const CPPType &type = data_in.type();
+ const CPPType &type = src.type();
attribute_math::convert_to_static_type(type, [&](auto dummy) {
using T = decltype(dummy);
- sample_face_attribute<T>(mesh, looptri_indices, data_in.typed<T>(), mask, data_out.typed<T>());
+ sample_face_attribute<T>(mesh, looptri_indices, src.typed<T>(), mask, dst.typed<T>());
});
}
@@ -219,45 +219,31 @@ void MeshAttributeInterpolator::sample_data(const GVArray &src,
if (ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_CORNER)) {
switch (mode) {
case eAttributeMapMode::INTERPOLATED:
- weights = ensure_barycentric_coords();
+ weights = this->ensure_barycentric_coords();
break;
case eAttributeMapMode::NEAREST:
- weights = ensure_nearest_weights();
+ weights = this->ensure_nearest_weights();
break;
}
}
/* Interpolate the source attributes on the surface. */
switch (domain) {
- case ATTR_DOMAIN_POINT: {
+ case ATTR_DOMAIN_POINT:
sample_point_attribute(*mesh_, looptri_indices_, weights, src, mask_, dst);
break;
- }
- case ATTR_DOMAIN_FACE: {
+ case ATTR_DOMAIN_FACE:
sample_face_attribute(*mesh_, looptri_indices_, src, mask_, dst);
break;
- }
- case ATTR_DOMAIN_CORNER: {
+ case ATTR_DOMAIN_CORNER:
sample_corner_attribute(*mesh_, looptri_indices_, weights, src, mask_, dst);
break;
- }
- case ATTR_DOMAIN_EDGE: {
+ case ATTR_DOMAIN_EDGE:
/* Not yet supported. */
break;
- }
- default: {
+ default:
BLI_assert_unreachable();
break;
- }
- }
-}
-
-void MeshAttributeInterpolator::sample_attribute(const GAttributeReader &src_attribute,
- GSpanAttributeWriter &dst_attribute,
- eAttributeMapMode mode)
-{
- if (src_attribute && dst_attribute) {
- this->sample_data(src_attribute.varray, src_attribute.domain, mode, dst_attribute.span);
}
}
diff --git a/source/blender/blenkernel/intern/mesh_tangent.c b/source/blender/blenkernel/intern/mesh_tangent.c
index a677a0d6ebb..1772419e1f3 100644
--- a/source/blender/blenkernel/intern/mesh_tangent.c
+++ b/source/blender/blenkernel/intern/mesh_tangent.c
@@ -716,7 +716,7 @@ void BKE_mesh_calc_loop_tangents(Mesh *me_eval,
{
BKE_mesh_runtime_looptri_ensure(me_eval);
- /* TODO(campbell): store in Mesh.runtime to avoid recalculation. */
+ /* TODO(@campbellbarton): store in Mesh.runtime to avoid recalculation. */
short tangent_mask = 0;
BKE_mesh_calc_loop_tangent_ex(me_eval->mvert,
me_eval->mpoly,
diff --git a/source/blender/blenkernel/intern/mesh_validate.cc b/source/blender/blenkernel/intern/mesh_validate.cc
index 9b2697ecc84..5bcbdb399e4 100644
--- a/source/blender/blenkernel/intern/mesh_validate.cc
+++ b/source/blender/blenkernel/intern/mesh_validate.cc
@@ -1001,10 +1001,6 @@ bool BKE_mesh_validate_all_customdata(CustomData *vdata,
CustomData_MeshMasks mask = {0};
if (check_meshmask) {
mask = CD_MASK_MESH;
- /* Normal data isn't in the mask since it is derived data,
- * but it is valid and should not be removed. */
- mask.vmask |= CD_MASK_NORMAL;
- mask.pmask |= CD_MASK_NORMAL;
}
is_valid &= mesh_validate_customdata(
diff --git a/source/blender/blenkernel/intern/mesh_wrapper.cc b/source/blender/blenkernel/intern/mesh_wrapper.cc
index 0b61b876abe..19d4444aa2f 100644
--- a/source/blender/blenkernel/intern/mesh_wrapper.cc
+++ b/source/blender/blenkernel/intern/mesh_wrapper.cc
@@ -61,7 +61,7 @@ Mesh *BKE_mesh_wrapper_from_editmesh_with_coords(BMEditMesh *em,
}
/* Use edit-mesh directly where possible. */
- me->runtime.is_original = true;
+ me->runtime.is_original_bmesh = true;
me->edit_mesh = static_cast<BMEditMesh *>(MEM_dupallocN(em));
me->edit_mesh->is_shallow_copy = true;
@@ -133,7 +133,7 @@ void BKE_mesh_wrapper_ensure_mdata(Mesh *me)
EditMeshData *edit_data = me->runtime.edit_data;
if (edit_data->vertexCos) {
BKE_mesh_vert_coords_apply(me, edit_data->vertexCos);
- me->runtime.is_original = false;
+ me->runtime.is_original_bmesh = false;
}
break;
}
@@ -343,7 +343,7 @@ static Mesh *mesh_wrapper_ensure_subdivision(Mesh *me)
if (use_clnors) {
float(*lnors)[3] = static_cast<float(*)[3]>(
CustomData_get_layer(&subdiv_mesh->ldata, CD_NORMAL));
- BLI_assert(lnors != NULL);
+ BLI_assert(lnors != nullptr);
BKE_mesh_set_custom_normals(subdiv_mesh, lnors);
CustomData_set_layer_flag(&me->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
CustomData_set_layer_flag(&subdiv_mesh->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 01eb4970f7e..60d6b51594a 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -142,7 +142,8 @@ static ModifierData *modifier_allocate_and_init(int type)
md->type = type;
md->mode = eModifierMode_Realtime | eModifierMode_Render;
md->flag = eModifierFlag_OverrideLibrary_Local;
- md->ui_expand_flag = 1; /* Only open the main panel at the beginning, not the sub-panels. */
+ /* Only open the main panel at the beginning, not the sub-panels. */
+ md->ui_expand_flag = UI_PANEL_DATA_EXPAND_ROOT;
if (mti->flags & eModifierTypeFlag_EnableInEditmode) {
md->mode |= eModifierMode_Editmode;
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index d50b8662f82..4ed2885dd90 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -3383,8 +3383,10 @@ struct bNodeSocket *ntreeAddSocketInterfaceFromSocket(bNodeTree *ntree,
bNode *from_node,
bNodeSocket *from_sock)
{
- bNodeSocket *iosock = ntreeAddSocketInterface(
- ntree, static_cast<eNodeSocketInOut>(from_sock->in_out), from_sock->idname, from_sock->name);
+ bNodeSocket *iosock = ntreeAddSocketInterface(ntree,
+ static_cast<eNodeSocketInOut>(from_sock->in_out),
+ from_sock->idname,
+ DATA_(from_sock->name));
if (iosock) {
if (iosock->typeinfo->interface_from_socket) {
iosock->typeinfo->interface_from_socket(ntree, iosock, from_node, from_sock);
diff --git a/source/blender/blenkernel/intern/object_dupli.cc b/source/blender/blenkernel/intern/object_dupli.cc
index 407a2c8955c..228bc682ddd 100644
--- a/source/blender/blenkernel/intern/object_dupli.cc
+++ b/source/blender/blenkernel/intern/object_dupli.cc
@@ -29,6 +29,7 @@
#include "DNA_pointcloud_types.h"
#include "DNA_scene_types.h"
#include "DNA_vfont_types.h"
+#include "DNA_volume_types.h"
#include "BKE_collection.h"
#include "BKE_duplilist.h"
@@ -164,10 +165,8 @@ static bool copy_dupli_context(
*
* \param mat: is transform of the object relative to current context (including #Object.obmat).
*/
-static DupliObject *make_dupli(const DupliContext *ctx,
- Object *ob,
- const float mat[4][4],
- int index)
+static DupliObject *make_dupli(
+ const DupliContext *ctx, Object *ob, const ID *object_data, const float mat[4][4], int index)
{
DupliObject *dob;
int i;
@@ -182,7 +181,7 @@ static DupliObject *make_dupli(const DupliContext *ctx,
}
dob->ob = ob;
- dob->ob_data = (ID *)ob->data;
+ dob->ob_data = const_cast<ID *>(object_data);
mul_m4_m4m4(dob->mat, (float(*)[4])ctx->space_mat, mat);
dob->type = ctx->gen->type;
@@ -202,7 +201,7 @@ static DupliObject *make_dupli(const DupliContext *ctx,
/* Meta-balls never draw in duplis, they are instead merged into one by the basis
* meta-ball outside of the group. this does mean that if that meta-ball is not in the
* scene, they will not show up at all, limitation that should be solved once. */
- if (ob->type == OB_MBALL) {
+ if (object_data && GS(object_data->name) == ID_MB) {
dob->no_draw = true;
}
@@ -226,6 +225,14 @@ static DupliObject *make_dupli(const DupliContext *ctx,
return dob;
}
+static DupliObject *make_dupli(const DupliContext *ctx,
+ Object *ob,
+ const float mat[4][4],
+ int index)
+{
+ return make_dupli(ctx, ob, static_cast<ID *>(ob->data), mat, index);
+}
+
/**
* Recursive dupli-objects.
*
@@ -777,28 +784,24 @@ static void make_duplis_geometry_set_impl(const DupliContext *ctx,
int component_index = 0;
if (ctx->object->type != OB_MESH || geometry_set_is_instance) {
if (const Mesh *mesh = geometry_set.get_mesh_for_read()) {
- DupliObject *dupli = make_dupli(ctx, ctx->object, parent_transform, component_index++);
- dupli->ob_data = (ID *)mesh;
+ make_dupli(ctx, ctx->object, &mesh->id, parent_transform, component_index++);
}
}
if (ctx->object->type != OB_VOLUME || geometry_set_is_instance) {
if (const Volume *volume = geometry_set.get_volume_for_read()) {
- DupliObject *dupli = make_dupli(ctx, ctx->object, parent_transform, component_index++);
- dupli->ob_data = (ID *)volume;
+ make_dupli(ctx, ctx->object, &volume->id, parent_transform, component_index++);
}
}
if (!ELEM(ctx->object->type, OB_CURVES_LEGACY, OB_FONT, OB_CURVES) || geometry_set_is_instance) {
if (const CurveComponent *component = geometry_set.get_component_for_read<CurveComponent>()) {
if (const Curve *curve = component->get_curve_for_render()) {
- DupliObject *dupli = make_dupli(ctx, ctx->object, parent_transform, component_index++);
- dupli->ob_data = (ID *)curve;
+ make_dupli(ctx, ctx->object, &curve->id, parent_transform, component_index++);
}
}
}
if (ctx->object->type != OB_POINTCLOUD || geometry_set_is_instance) {
if (const PointCloud *pointcloud = geometry_set.get_pointcloud_for_read()) {
- DupliObject *dupli = make_dupli(ctx, ctx->object, parent_transform, component_index++);
- dupli->ob_data = (ID *)pointcloud;
+ make_dupli(ctx, ctx->object, &pointcloud->id, parent_transform, component_index++);
}
}
const bool creates_duplis_for_components = component_index >= 1;
@@ -1560,6 +1563,13 @@ static const DupliGenerator *get_dupli_generator(const DupliContext *ctx)
return nullptr;
}
+ /* Metaball objects can't create instances, but the dupli system is used to "instance" their
+ * evaluated mesh to render engines. We need to exit early to avoid recursively instancing the
+ * evaluated metaball mesh on metaball instances that already contribute to the basis. */
+ if (ctx->object->type == OB_MBALL && ctx->level > 0) {
+ return nullptr;
+ }
+
/* Should the dupli's be generated for this object? - Respect restrict flags. */
if (DEG_get_mode(ctx->depsgraph) == DAG_EVAL_RENDER ? (visibility_flag & OB_HIDE_RENDER) :
(visibility_flag & OB_HIDE_VIEWPORT)) {
diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c
index 8ff02c7e698..5656a9f6c92 100644
--- a/source/blender/blenkernel/intern/object_update.c
+++ b/source/blender/blenkernel/intern/object_update.c
@@ -110,7 +110,6 @@ void BKE_object_eval_constraints(Depsgraph *depsgraph, Scene *scene, Object *ob)
* - post (i.e. BKE_constraints_clear_evalob)
*
* Not sure why, this is from Joshua - sergey
- *
*/
cob = BKE_constraints_make_evalob(depsgraph, scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
BKE_constraints_solve(depsgraph, &ob->constraints, cob, ctime);
@@ -149,10 +148,6 @@ void BKE_object_handle_data_update(Depsgraph *depsgraph, Scene *scene, Object *o
cddata_masks.pmask |= CD_MASK_PROP_ALL;
cddata_masks.lmask |= CD_MASK_PROP_ALL;
- /* Also copy over normal layers to avoid recomputation. */
- cddata_masks.pmask |= CD_MASK_NORMAL;
- cddata_masks.vmask |= CD_MASK_NORMAL;
-
/* Make sure Freestyle edge/face marks appear in DM for render (see T40315).
* Due to Line Art implementation, edge marks should also be shown in viewport. */
#ifdef WITH_FREESTYLE
@@ -173,7 +168,7 @@ void BKE_object_handle_data_update(Depsgraph *depsgraph, Scene *scene, Object *o
break;
case OB_MBALL:
- BKE_displist_make_mball(depsgraph, scene, ob);
+ BKE_mball_data_update(depsgraph, scene, ob);
break;
case OB_CURVES_LEGACY:
@@ -285,45 +280,45 @@ void BKE_object_eval_uber_transform(Depsgraph *UNUSED(depsgraph), Object *UNUSED
{
}
-void BKE_object_data_batch_cache_dirty_tag(ID *object_data)
+void BKE_object_batch_cache_dirty_tag(Object *ob)
{
- switch (GS(object_data->name)) {
- case ID_ME:
- BKE_mesh_batch_cache_dirty_tag((struct Mesh *)object_data, BKE_MESH_BATCH_DIRTY_ALL);
+ switch (ob->type) {
+ case OB_MESH:
+ BKE_mesh_batch_cache_dirty_tag((struct Mesh *)ob->data, BKE_MESH_BATCH_DIRTY_ALL);
break;
- case ID_LT:
- BKE_lattice_batch_cache_dirty_tag((struct Lattice *)object_data,
- BKE_LATTICE_BATCH_DIRTY_ALL);
+ case OB_LATTICE:
+ BKE_lattice_batch_cache_dirty_tag((struct Lattice *)ob->data, BKE_LATTICE_BATCH_DIRTY_ALL);
break;
- case ID_CU_LEGACY:
- BKE_curve_batch_cache_dirty_tag((struct Curve *)object_data, BKE_CURVE_BATCH_DIRTY_ALL);
+ case OB_CURVES_LEGACY:
+ BKE_curve_batch_cache_dirty_tag((struct Curve *)ob->data, BKE_CURVE_BATCH_DIRTY_ALL);
break;
- case ID_MB:
- BKE_mball_batch_cache_dirty_tag((struct MetaBall *)object_data, BKE_MBALL_BATCH_DIRTY_ALL);
+ case OB_MBALL: {
+ /* This function is currently called on original objects, so to properly
+ * clear the actual displayed geometry, we have to tag the evaluated mesh. */
+ Mesh *mesh = BKE_object_get_evaluated_mesh_no_subsurf(ob);
+ if (mesh) {
+ BKE_mesh_batch_cache_dirty_tag(mesh, BKE_MESH_BATCH_DIRTY_ALL);
+ }
break;
- case ID_GD:
- BKE_gpencil_batch_cache_dirty_tag((struct bGPdata *)object_data);
+ }
+ case OB_GPENCIL:
+ BKE_gpencil_batch_cache_dirty_tag((struct bGPdata *)ob->data);
break;
- case ID_CV:
- BKE_curves_batch_cache_dirty_tag((struct Curves *)object_data, BKE_CURVES_BATCH_DIRTY_ALL);
+ case OB_CURVES:
+ BKE_curves_batch_cache_dirty_tag((struct Curves *)ob->data, BKE_CURVES_BATCH_DIRTY_ALL);
break;
- case ID_PT:
- BKE_pointcloud_batch_cache_dirty_tag((struct PointCloud *)object_data,
+ case OB_POINTCLOUD:
+ BKE_pointcloud_batch_cache_dirty_tag((struct PointCloud *)ob->data,
BKE_POINTCLOUD_BATCH_DIRTY_ALL);
break;
- case ID_VO:
- BKE_volume_batch_cache_dirty_tag((struct Volume *)object_data, BKE_VOLUME_BATCH_DIRTY_ALL);
+ case OB_VOLUME:
+ BKE_volume_batch_cache_dirty_tag((struct Volume *)ob->data, BKE_VOLUME_BATCH_DIRTY_ALL);
break;
default:
break;
}
}
-void BKE_object_batch_cache_dirty_tag(Object *ob)
-{
- BKE_object_data_batch_cache_dirty_tag(ob->data);
-}
-
void BKE_object_eval_uber_data(Depsgraph *depsgraph, Scene *scene, Object *ob)
{
DEG_debug_print_eval(depsgraph, __func__, ob->id.name, ob);
diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c
index dec9a594938..cd1f24fee37 100644
--- a/source/blender/blenkernel/intern/ocean.c
+++ b/source/blender/blenkernel/intern/ocean.c
@@ -1385,9 +1385,8 @@ void BKE_ocean_bake(struct Ocean *o,
void (*update_cb)(void *, float progress, int *cancel),
void *update_cb_data)
{
- /* NOTE(campbell): some of these values remain uninitialized unless certain options
- * are enabled, take care that BKE_ocean_eval_ij() initializes a member
- * before use. */
+ /* NOTE(@campbellbarton): some of these values remain uninitialized unless certain options
+ * are enabled, take care that #BKE_ocean_eval_ij() initializes a member before use. */
OceanResult ocr;
ImageFormatData imf = {0};
@@ -1441,7 +1440,7 @@ 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(campbell): cleanup unused code. */
+ /* TODO(@campbellbarton): cleanup unused code. */
float /* r, */ /* UNUSED */ pr = 0.0f, foam_result;
float neg_disp, neg_eplus;
diff --git a/source/blender/blenkernel/intern/outliner_treehash.c b/source/blender/blenkernel/intern/outliner_treehash.c
deleted file mode 100644
index 09e2baf2be1..00000000000
--- a/source/blender/blenkernel/intern/outliner_treehash.c
+++ /dev/null
@@ -1,256 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-/** \file
- * \ingroup bke
- *
- * Tree hash for the outliner space.
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "BLI_ghash.h"
-#include "BLI_mempool.h"
-#include "BLI_utildefines.h"
-
-#include "DNA_outliner_types.h"
-
-#include "BKE_outliner_treehash.h"
-
-#include "MEM_guardedalloc.h"
-
-typedef struct TseGroup {
- TreeStoreElem **elems;
- /* Index of last used #TreeStoreElem item, to speed up search for another one. */
- int lastused;
- /* Counter used to reduce the amount of 'rests' of `lastused` index, otherwise search for unused
- * item is exponential and becomes critically slow when there are a lot of items in the group. */
- int lastused_reset_count;
- /* Number of items currently in use. */
- int size;
- /* Number of items currently allocated. */
- int allocated;
-} TseGroup;
-
-/* Only allow reset of #TseGroup.lastused counter to 0 once every 1k search. */
-#define TSEGROUP_LASTUSED_RESET_VALUE 10000
-
-/* Allocate structure for TreeStoreElements;
- * Most of elements in treestore have no duplicates,
- * so there is no need to preallocate memory for more than one pointer */
-static TseGroup *tse_group_create(void)
-{
- TseGroup *tse_group = MEM_mallocN(sizeof(TseGroup), "TseGroup");
- tse_group->elems = MEM_mallocN(sizeof(TreeStoreElem *), "TseGroupElems");
- tse_group->size = 0;
- tse_group->allocated = 1;
- tse_group->lastused = 0;
- return tse_group;
-}
-
-static void tse_group_add_element(TseGroup *tse_group, TreeStoreElem *elem)
-{
- if (UNLIKELY(tse_group->size == tse_group->allocated)) {
- tse_group->allocated *= 2;
- tse_group->elems = MEM_reallocN(tse_group->elems,
- sizeof(TreeStoreElem *) * tse_group->allocated);
- }
- tse_group->elems[tse_group->size] = elem;
- tse_group->lastused = tse_group->size;
- tse_group->size++;
-}
-
-static void tse_group_remove_element(TseGroup *tse_group, TreeStoreElem *elem)
-{
- int min_allocated = MAX2(1, tse_group->allocated / 2);
- BLI_assert(tse_group->allocated == 1 || (tse_group->allocated % 2) == 0);
-
- tse_group->size--;
- BLI_assert(tse_group->size >= 0);
- for (int i = 0; i < tse_group->size; i++) {
- if (tse_group->elems[i] == elem) {
- memcpy(tse_group->elems[i],
- tse_group->elems[i + 1],
- (tse_group->size - (i + 1)) * sizeof(TreeStoreElem *));
- break;
- }
- }
-
- if (UNLIKELY(tse_group->size > 0 && tse_group->size <= min_allocated)) {
- tse_group->allocated = min_allocated;
- tse_group->elems = MEM_reallocN(tse_group->elems,
- sizeof(TreeStoreElem *) * tse_group->allocated);
- }
-}
-
-static void tse_group_free(TseGroup *tse_group)
-{
- MEM_freeN(tse_group->elems);
- MEM_freeN(tse_group);
-}
-
-static unsigned int tse_hash(const void *ptr)
-{
- const TreeStoreElem *tse = ptr;
- union {
- short h_pair[2];
- unsigned int u_int;
- } hash;
-
- BLI_assert((tse->type != TSE_SOME_ID) || !tse->nr);
-
- hash.h_pair[0] = tse->type;
- hash.h_pair[1] = tse->nr;
-
- hash.u_int ^= BLI_ghashutil_ptrhash(tse->id);
-
- return hash.u_int;
-}
-
-static bool tse_cmp(const void *a, const void *b)
-{
- const TreeStoreElem *tse_a = a;
- const TreeStoreElem *tse_b = b;
- return tse_a->type != tse_b->type || tse_a->nr != tse_b->nr || tse_a->id != tse_b->id;
-}
-
-static void fill_treehash(void *treehash, BLI_mempool *treestore)
-{
- TreeStoreElem *tselem;
- BLI_mempool_iter iter;
- BLI_mempool_iternew(treestore, &iter);
-
- BLI_assert(treehash);
-
- while ((tselem = BLI_mempool_iterstep(&iter))) {
- BKE_outliner_treehash_add_element(treehash, tselem);
- }
-}
-
-void *BKE_outliner_treehash_create_from_treestore(BLI_mempool *treestore)
-{
- GHash *treehash = BLI_ghash_new_ex(tse_hash, tse_cmp, "treehash", BLI_mempool_len(treestore));
- fill_treehash(treehash, treestore);
- return treehash;
-}
-
-static void free_treehash_group(void *key)
-{
- tse_group_free(key);
-}
-
-void BKE_outliner_treehash_clear_used(void *treehash)
-{
- GHashIterator gh_iter;
-
- GHASH_ITER (gh_iter, treehash) {
- TseGroup *group = BLI_ghashIterator_getValue(&gh_iter);
- group->lastused = 0;
- group->lastused_reset_count = 0;
- }
-}
-
-void *BKE_outliner_treehash_rebuild_from_treestore(void *treehash, BLI_mempool *treestore)
-{
- BLI_assert(treehash);
-
- BLI_ghash_clear_ex(treehash, NULL, free_treehash_group, BLI_mempool_len(treestore));
- fill_treehash(treehash, treestore);
- return treehash;
-}
-
-void BKE_outliner_treehash_add_element(void *treehash, TreeStoreElem *elem)
-{
- TseGroup *group;
- void **val_p;
-
- if (!BLI_ghash_ensure_p(treehash, elem, &val_p)) {
- *val_p = tse_group_create();
- }
- group = *val_p;
- tse_group_add_element(group, elem);
-}
-
-void BKE_outliner_treehash_remove_element(void *treehash, TreeStoreElem *elem)
-{
- TseGroup *group = BLI_ghash_lookup(treehash, elem);
-
- BLI_assert(group != NULL);
- if (group->size <= 1) {
- /* one element -> remove group completely */
- BLI_ghash_remove(treehash, elem, NULL, free_treehash_group);
- }
- else {
- tse_group_remove_element(group, elem);
- }
-}
-
-static TseGroup *BKE_outliner_treehash_lookup_group(GHash *th, short type, short nr, struct ID *id)
-{
- TreeStoreElem tse_template;
- tse_template.type = type;
- tse_template.nr = (type == TSE_SOME_ID) ? 0 : nr; /* we're picky! :) */
- tse_template.id = id;
-
- BLI_assert(th);
-
- return BLI_ghash_lookup(th, &tse_template);
-}
-
-TreeStoreElem *BKE_outliner_treehash_lookup_unused(void *treehash,
- short type,
- short nr,
- struct ID *id)
-{
- TseGroup *group;
-
- BLI_assert(treehash);
-
- group = BKE_outliner_treehash_lookup_group(treehash, type, nr, id);
- if (group) {
- /* Find unused element, with optimization to start from previously
- * found element assuming we do repeated lookups. */
- int size = group->size;
- int offset = group->lastused;
-
- for (int i = 0; i < size; i++, offset++) {
- /* Once at the end of the array of items, in most cases it just means that all items are
- * used, so only check the whole array once every TSEGROUP_LASTUSED_RESET_VALUE times. */
- if (offset >= size) {
- if (LIKELY(group->lastused_reset_count <= TSEGROUP_LASTUSED_RESET_VALUE)) {
- group->lastused_reset_count++;
- group->lastused = group->size - 1;
- break;
- }
- group->lastused_reset_count = 0;
- offset = 0;
- }
-
- if (!group->elems[offset]->used) {
- group->lastused = offset;
- return group->elems[offset];
- }
- }
- }
- return NULL;
-}
-
-TreeStoreElem *BKE_outliner_treehash_lookup_any(void *treehash,
- short type,
- short nr,
- struct ID *id)
-{
- TseGroup *group;
-
- BLI_assert(treehash);
-
- group = BKE_outliner_treehash_lookup_group(treehash, type, nr, id);
- return group ? group->elems[0] : NULL;
-}
-
-void BKE_outliner_treehash_free(void *treehash)
-{
- BLI_assert(treehash);
-
- BLI_ghash_free(treehash, NULL, free_treehash_group);
-}
diff --git a/source/blender/blenkernel/intern/outliner_treehash.cc b/source/blender/blenkernel/intern/outliner_treehash.cc
new file mode 100644
index 00000000000..3f66f6bb745
--- /dev/null
+++ b/source/blender/blenkernel/intern/outliner_treehash.cc
@@ -0,0 +1,209 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/** \file
+ * \ingroup bke
+ *
+ * Tree hash for the outliner space.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "BLI_mempool.h"
+#include "BLI_utildefines.h"
+#include "BLI_vector.hh"
+
+#include "DNA_outliner_types.h"
+
+#include "BKE_outliner_treehash.hh"
+
+#include "MEM_guardedalloc.h"
+
+namespace blender::bke::outliner::treehash {
+
+/* -------------------------------------------------------------------- */
+/** \name #TseGroup
+ * \{ */
+
+class TseGroup {
+ public:
+ blender::Vector<TreeStoreElem *> elems;
+ /* Index of last used #TreeStoreElem item, to speed up search for another one. */
+ int lastused = 0;
+ /* Counter used to reduce the amount of 'rests' of `lastused` index, otherwise search for unused
+ * item is exponential and becomes critically slow when there are a lot of items in the group. */
+ int lastused_reset_count = -1;
+
+ public:
+ void add_element(TreeStoreElem &elem);
+ void remove_element(TreeStoreElem &elem);
+};
+
+/* Only allow reset of #TseGroup.lastused counter to 0 once every 1k search. */
+#define TSEGROUP_LASTUSED_RESET_VALUE 10000
+
+void TseGroup::add_element(TreeStoreElem &elem)
+{
+ const int64_t idx = elems.append_and_get_index(&elem);
+ lastused = idx;
+}
+
+void TseGroup::remove_element(TreeStoreElem &elem)
+{
+ const int64_t idx = elems.first_index_of(&elem);
+ elems.remove(idx);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name #TreeStoreElemKey
+ * \{ */
+
+TreeStoreElemKey::TreeStoreElemKey(const TreeStoreElem &elem)
+ : id(elem.id), type(elem.type), nr(elem.nr)
+{
+}
+
+TreeStoreElemKey::TreeStoreElemKey(ID *id, short type, short nr) : id(id), type(type), nr(nr)
+{
+}
+
+uint64_t TreeStoreElemKey::hash() const
+{
+ return get_default_hash_3(id, type, nr);
+}
+
+bool operator==(const TreeStoreElemKey &a, const TreeStoreElemKey &b)
+{
+ return (a.id == b.id) && (a.type == b.type) && (a.nr == b.nr);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name #TreeHash
+ * \{ */
+
+TreeHash::~TreeHash() = default;
+
+std::unique_ptr<TreeHash> TreeHash::create_from_treestore(BLI_mempool &treestore)
+{
+ /* Can't use `make_unique()` here because of private constructor. */
+ std::unique_ptr<TreeHash> tree_hash{new TreeHash()};
+ tree_hash->fill_treehash(treestore);
+
+ return tree_hash;
+}
+
+void TreeHash::fill_treehash(BLI_mempool &treestore)
+{
+ TreeStoreElem *tselem;
+ BLI_mempool_iter iter;
+ BLI_mempool_iternew(&treestore, &iter);
+
+ while ((tselem = static_cast<TreeStoreElem *>(BLI_mempool_iterstep(&iter)))) {
+ add_element(*tselem);
+ }
+}
+
+void TreeHash::clear_used()
+{
+ for (auto &group : elem_groups_.values()) {
+ group->lastused = 0;
+ group->lastused_reset_count = 0;
+ }
+}
+
+void TreeHash::rebuild_from_treestore(BLI_mempool &treestore)
+{
+ elem_groups_.clear();
+ fill_treehash(treestore);
+}
+
+void TreeHash::add_element(TreeStoreElem &elem)
+{
+ std::unique_ptr<TseGroup> &group = elem_groups_.lookup_or_add_cb(
+ TreeStoreElemKey(elem), []() { return std::make_unique<TseGroup>(); });
+ group->add_element(elem);
+}
+
+void TreeHash::remove_element(TreeStoreElem &elem)
+{
+ TseGroup *group = lookup_group(elem);
+ BLI_assert(group != nullptr);
+
+ if (group->elems.size() <= 1) {
+ /* One element -> remove group completely. */
+ elem_groups_.remove(TreeStoreElemKey(elem));
+ }
+ else {
+ group->remove_element(elem);
+ }
+}
+
+TseGroup *TreeHash::lookup_group(const TreeStoreElemKey &key) const
+{
+ auto *group = elem_groups_.lookup_ptr(key);
+ if (group) {
+ return group->get();
+ }
+ return nullptr;
+}
+
+TseGroup *TreeHash::lookup_group(const TreeStoreElem &key_elem) const
+{
+ return lookup_group(TreeStoreElemKey(key_elem));
+}
+
+TseGroup *TreeHash::lookup_group(const short type, const short nr, ID *id) const
+{
+ TreeStoreElemKey key(id, type, nr);
+ if (type == TSE_SOME_ID) {
+ key.nr = 0; /* we're picky! :) */
+ }
+ return lookup_group(key);
+}
+
+TreeStoreElem *TreeHash::lookup_unused(const short type, const short nr, ID *id) const
+{
+ TseGroup *group = lookup_group(type, nr, id);
+ if (!group) {
+ return nullptr;
+ }
+
+ /* Find unused element, with optimization to start from previously
+ * found element assuming we do repeated lookups. */
+ const int size = group->elems.size();
+ int offset = group->lastused;
+
+ for (int i = 0; i < size; i++, offset++) {
+ /* Once at the end of the array of items, in most cases it just means that all items are
+ * used, so only check the whole array once every TSEGROUP_LASTUSED_RESET_VALUE times. */
+ if (offset >= size) {
+ if (LIKELY(group->lastused_reset_count <= TSEGROUP_LASTUSED_RESET_VALUE)) {
+ group->lastused_reset_count++;
+ group->lastused = group->elems.size() - 1;
+ break;
+ }
+ group->lastused_reset_count = 0;
+ offset = 0;
+ }
+
+ if (!group->elems[offset]->used) {
+ group->lastused = offset;
+ return group->elems[offset];
+ }
+ }
+ return nullptr;
+}
+
+TreeStoreElem *TreeHash::lookup_any(const short type, const short nr, ID *id) const
+{
+ const TseGroup *group = lookup_group(type, nr, id);
+ return group ? group->elems[0] : nullptr;
+}
+
+/** \} */
+
+} // namespace blender::bke::outliner::treehash
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.cc
index 9b0d15ac702..a6b0a4d96ee 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.cc
@@ -5,8 +5,8 @@
* \ingroup bke
*/
-#include <stdlib.h>
-#include <string.h>
+#include <cstdlib>
+#include <cstring>
#include "MEM_guardedalloc.h"
@@ -30,6 +30,7 @@
#include "BLT_translation.h"
#include "BKE_attribute.h"
+#include "BKE_attribute.hh"
#include "BKE_brush.h"
#include "BKE_ccg.h"
#include "BKE_colortools.h"
@@ -95,13 +96,10 @@ static void palette_blend_write(BlendWriter *writer, ID *id, const void *id_addr
{
Palette *palette = (Palette *)id;
- PaletteColor *color;
BLO_write_id_struct(writer, Palette, id_address, &palette->id);
BKE_id_blend_write(writer, &palette->id);
- for (color = palette->colors.first; color; color = color->next) {
- BLO_write_struct(writer, PaletteColor, color);
- }
+ BLO_write_struct_list(writer, PaletteColor, &palette->colors);
}
static void palette_blend_read_data(BlendDataReader *reader, ID *id)
@@ -116,38 +114,38 @@ static void palette_undo_preserve(BlendLibReader *UNUSED(reader), ID *id_new, ID
/* NOTE: We do not care about potential internal references to self here, Palette has none. */
/* NOTE: We do not swap IDProperties, as dealing with potential ID pointers in those would be
* fairly delicate. */
- BKE_lib_id_swap(NULL, id_new, id_old);
+ BKE_lib_id_swap(nullptr, id_new, id_old);
SWAP(IDProperty *, id_new->properties, id_old->properties);
}
IDTypeInfo IDType_ID_PAL = {
- .id_code = ID_PAL,
- .id_filter = FILTER_ID_PAL,
- .main_listbase_index = INDEX_ID_PAL,
- .struct_size = sizeof(Palette),
- .name = "Palette",
- .name_plural = "palettes",
- .translation_context = BLT_I18NCONTEXT_ID_PALETTE,
- .flags = IDTYPE_FLAGS_NO_ANIMDATA,
- .asset_type_info = NULL,
-
- .init_data = palette_init_data,
- .copy_data = palette_copy_data,
- .free_data = palette_free_data,
- .make_local = NULL,
- .foreach_id = NULL,
- .foreach_cache = NULL,
- .foreach_path = NULL,
- .owner_get = NULL,
-
- .blend_write = palette_blend_write,
- .blend_read_data = palette_blend_read_data,
- .blend_read_lib = NULL,
- .blend_read_expand = NULL,
-
- .blend_read_undo_preserve = palette_undo_preserve,
-
- .lib_override_apply_post = NULL,
+ /* id_code */ ID_PAL,
+ /* id_filter */ FILTER_ID_PAL,
+ /* main_listbase_index */ INDEX_ID_PAL,
+ /* struct_size */ sizeof(Palette),
+ /* name */ "Palette",
+ /* name_plural */ "palettes",
+ /* translation_context */ BLT_I18NCONTEXT_ID_PALETTE,
+ /* flags */ IDTYPE_FLAGS_NO_ANIMDATA,
+ /* asset_type_info */ nullptr,
+
+ /* init_data */ palette_init_data,
+ /* copy_data */ palette_copy_data,
+ /* free_data */ palette_free_data,
+ /* make_local */ nullptr,
+ /* foreach_id */ nullptr,
+ /* foreach_cache */ nullptr,
+ /* foreach_path */ nullptr,
+ /* owner_get */ nullptr,
+
+ /* blend_write */ palette_blend_write,
+ /* blend_read_data */ palette_blend_read_data,
+ /* blend_read_lib */ nullptr,
+ /* blend_read_expand */ nullptr,
+
+ /* blend_read_undo_preserve */ palette_undo_preserve,
+
+ /* lib_override_apply_post */ nullptr,
};
static void paint_curve_copy_data(Main *UNUSED(bmain),
@@ -159,7 +157,8 @@ static void paint_curve_copy_data(Main *UNUSED(bmain),
const PaintCurve *paint_curve_src = (const PaintCurve *)id_src;
if (paint_curve_src->tot_points != 0) {
- paint_curve_dst->points = MEM_dupallocN(paint_curve_src->points);
+ paint_curve_dst->points = static_cast<PaintCurvePoint *>(
+ MEM_dupallocN(paint_curve_src->points));
}
}
@@ -188,41 +187,41 @@ static void paint_curve_blend_read_data(BlendDataReader *reader, ID *id)
}
IDTypeInfo IDType_ID_PC = {
- .id_code = ID_PC,
- .id_filter = FILTER_ID_PC,
- .main_listbase_index = INDEX_ID_PC,
- .struct_size = sizeof(PaintCurve),
- .name = "PaintCurve",
- .name_plural = "paint_curves",
- .translation_context = BLT_I18NCONTEXT_ID_PAINTCURVE,
- .flags = IDTYPE_FLAGS_NO_ANIMDATA,
- .asset_type_info = NULL,
-
- .init_data = NULL,
- .copy_data = paint_curve_copy_data,
- .free_data = paint_curve_free_data,
- .make_local = NULL,
- .foreach_id = NULL,
- .foreach_cache = NULL,
- .foreach_path = NULL,
- .owner_get = NULL,
-
- .blend_write = paint_curve_blend_write,
- .blend_read_data = paint_curve_blend_read_data,
- .blend_read_lib = NULL,
- .blend_read_expand = NULL,
-
- .blend_read_undo_preserve = NULL,
-
- .lib_override_apply_post = NULL,
+ /* id_code */ ID_PC,
+ /* id_filter */ FILTER_ID_PC,
+ /* main_listbase_index */ INDEX_ID_PC,
+ /* struct_size */ sizeof(PaintCurve),
+ /* name */ "PaintCurve",
+ /* name_plural */ "paint_curves",
+ /* translation_context */ BLT_I18NCONTEXT_ID_PAINTCURVE,
+ /* flags */ IDTYPE_FLAGS_NO_ANIMDATA,
+ /* asset_type_info */ nullptr,
+
+ /* init_data */ nullptr,
+ /* copy_data */ paint_curve_copy_data,
+ /* free_data */ paint_curve_free_data,
+ /* make_local */ nullptr,
+ /* foreach_id */ nullptr,
+ /* foreach_cache */ nullptr,
+ /* foreach_path */ nullptr,
+ /* owner_get */ nullptr,
+
+ /* blend_write */ paint_curve_blend_write,
+ /* blend_read_data */ paint_curve_blend_read_data,
+ /* blend_read_lib */ nullptr,
+ /* blend_read_expand */ nullptr,
+
+ /* blend_read_undo_preserve */ nullptr,
+
+ /* lib_override_apply_post */ nullptr,
};
-const char PAINT_CURSOR_SCULPT[3] = {255, 100, 100};
-const char PAINT_CURSOR_VERTEX_PAINT[3] = {255, 255, 255};
-const char PAINT_CURSOR_WEIGHT_PAINT[3] = {200, 200, 255};
-const char PAINT_CURSOR_TEXTURE_PAINT[3] = {255, 255, 255};
+const uchar PAINT_CURSOR_SCULPT[3] = {255, 100, 100};
+const uchar PAINT_CURSOR_VERTEX_PAINT[3] = {255, 255, 255};
+const uchar PAINT_CURSOR_WEIGHT_PAINT[3] = {200, 200, 255};
+const uchar PAINT_CURSOR_TEXTURE_PAINT[3] = {255, 255, 255};
-static ePaintOverlayControlFlags overlay_flags = 0;
+static ePaintOverlayControlFlags overlay_flags = (ePaintOverlayControlFlags)0;
void BKE_paint_invalidate_overlay_tex(Scene *scene, ViewLayer *view_layer, const Tex *tex)
{
@@ -247,7 +246,7 @@ void BKE_paint_invalidate_overlay_tex(Scene *scene, ViewLayer *view_layer, const
void BKE_paint_invalidate_cursor_overlay(Scene *scene, ViewLayer *view_layer, CurveMapping *curve)
{
Paint *p = BKE_paint_get_active(scene, view_layer);
- if (p == NULL) {
+ if (p == nullptr) {
return;
}
@@ -294,10 +293,10 @@ void BKE_paint_reset_overlay_invalid(ePaintOverlayControlFlags flag)
bool BKE_paint_ensure_from_paintmode(Scene *sce, ePaintMode mode)
{
ToolSettings *ts = sce->toolsettings;
- Paint **paint_ptr = NULL;
+ Paint **paint_ptr = nullptr;
/* Some paint modes don't store paint settings as pointer, for these this can be set and
* referenced by paint_ptr. */
- Paint *paint_tmp = NULL;
+ Paint *paint_tmp = nullptr;
switch (mode) {
case PAINT_MODE_SCULPT:
@@ -370,13 +369,13 @@ Paint *BKE_paint_get_active_from_paintmode(Scene *sce, ePaintMode mode)
case PAINT_MODE_SCULPT_CURVES:
return &ts->curves_sculpt->paint;
case PAINT_MODE_INVALID:
- return NULL;
+ return nullptr;
default:
return &ts->imapaint.paint;
}
}
- return NULL;
+ return nullptr;
}
const EnumPropertyItem *BKE_paint_get_tool_enum_from_paintmode(ePaintMode mode)
@@ -406,7 +405,7 @@ const EnumPropertyItem *BKE_paint_get_tool_enum_from_paintmode(ePaintMode mode)
case PAINT_MODE_INVALID:
break;
}
- return NULL;
+ return nullptr;
}
const char *BKE_paint_get_tool_prop_id_from_paintmode(ePaintMode mode)
@@ -438,7 +437,7 @@ const char *BKE_paint_get_tool_prop_id_from_paintmode(ePaintMode mode)
}
/* Invalid paint mode. */
- return NULL;
+ return nullptr;
}
Paint *BKE_paint_get_active(Scene *sce, ViewLayer *view_layer)
@@ -467,7 +466,7 @@ Paint *BKE_paint_get_active(Scene *sce, ViewLayer *view_layer)
case OB_MODE_SCULPT_CURVES:
return &ts->curves_sculpt->paint;
case OB_MODE_EDIT:
- return ts->uvsculpt ? &ts->uvsculpt->paint : NULL;
+ return ts->uvsculpt ? &ts->uvsculpt->paint : nullptr;
default:
break;
}
@@ -477,7 +476,7 @@ Paint *BKE_paint_get_active(Scene *sce, ViewLayer *view_layer)
return &ts->imapaint.paint;
}
- return NULL;
+ return nullptr;
}
Paint *BKE_paint_get_active_from_context(const bContext *C)
@@ -488,13 +487,13 @@ Paint *BKE_paint_get_active_from_context(const bContext *C)
if (sce && view_layer) {
ToolSettings *ts = sce->toolsettings;
- Object *obact = NULL;
+ Object *obact = nullptr;
if (view_layer->basact && view_layer->basact->object) {
obact = view_layer->basact->object;
}
- if ((sima = CTX_wm_space_image(C)) != NULL) {
+ if ((sima = CTX_wm_space_image(C)) != nullptr) {
if (obact && obact->mode == OB_MODE_EDIT) {
if (sima->mode == SI_MODE_PAINT) {
return &ts->imapaint.paint;
@@ -512,7 +511,7 @@ Paint *BKE_paint_get_active_from_context(const bContext *C)
}
}
- return NULL;
+ return nullptr;
}
ePaintMode BKE_paintmode_get_active_from_context(const bContext *C)
@@ -522,13 +521,13 @@ ePaintMode BKE_paintmode_get_active_from_context(const bContext *C)
SpaceImage *sima;
if (sce && view_layer) {
- Object *obact = NULL;
+ Object *obact = nullptr;
if (view_layer->basact && view_layer->basact->object) {
obact = view_layer->basact->object;
}
- if ((sima = CTX_wm_space_image(C)) != NULL) {
+ if ((sima = CTX_wm_space_image(C)) != nullptr) {
if (obact && obact->mode == OB_MODE_EDIT) {
if (sima->mode == SI_MODE_PAINT) {
return PAINT_MODE_TEXTURE_2D;
@@ -568,7 +567,7 @@ ePaintMode BKE_paintmode_get_active_from_context(const bContext *C)
return PAINT_MODE_INVALID;
}
-ePaintMode BKE_paintmode_get_from_tool(const struct bToolRef *tref)
+ePaintMode BKE_paintmode_get_from_tool(const bToolRef *tref)
{
if (tref->space_type == SPACE_VIEW3D) {
switch (tref->mode) {
@@ -611,7 +610,7 @@ Brush *BKE_paint_brush(Paint *p)
const Brush *BKE_paint_brush_for_read(const Paint *p)
{
- return p ? p->brush : NULL;
+ return p ? p->brush : nullptr;
}
void BKE_paint_brush_set(Paint *p, Brush *br)
@@ -704,16 +703,13 @@ uint BKE_paint_get_brush_tool_offset_from_paintmode(const ePaintMode mode)
PaintCurve *BKE_paint_curve_add(Main *bmain, const char *name)
{
- PaintCurve *pc;
-
- pc = BKE_id_new(bmain, ID_PC, name);
-
+ PaintCurve *pc = static_cast<PaintCurve *>(BKE_id_new(bmain, ID_PC, name));
return pc;
}
Palette *BKE_paint_palette(Paint *p)
{
- return p ? p->palette : NULL;
+ return p ? p->palette : nullptr;
}
void BKE_paint_palette_set(Paint *p, Palette *palette)
@@ -763,18 +759,18 @@ void BKE_palette_clear(Palette *palette)
Palette *BKE_palette_add(Main *bmain, const char *name)
{
- Palette *palette = BKE_id_new(bmain, ID_PAL, name);
+ Palette *palette = static_cast<Palette *>(BKE_id_new(bmain, ID_PAL, name));
return palette;
}
PaletteColor *BKE_palette_color_add(Palette *palette)
{
- PaletteColor *color = MEM_callocN(sizeof(*color), "Palette Color");
+ PaletteColor *color = MEM_cnew<PaletteColor>(__func__);
BLI_addtail(&palette->colors, color);
return color;
}
-bool BKE_palette_is_empty(const struct Palette *palette)
+bool BKE_palette_is_empty(const Palette *palette)
{
return BLI_listbase_is_empty(&palette->colors);
}
@@ -782,7 +778,8 @@ bool BKE_palette_is_empty(const struct Palette *palette)
/* helper function to sort using qsort */
static int palettecolor_compare_hsv(const void *a1, const void *a2)
{
- const tPaletteColorHSV *ps1 = a1, *ps2 = a2;
+ const tPaletteColorHSV *ps1 = static_cast<const tPaletteColorHSV *>(a1);
+ const tPaletteColorHSV *ps2 = static_cast<const tPaletteColorHSV *>(a2);
/* Hue */
if (ps1->h > ps2->h) {
@@ -814,7 +811,8 @@ static int palettecolor_compare_hsv(const void *a1, const void *a2)
/* helper function to sort using qsort */
static int palettecolor_compare_svh(const void *a1, const void *a2)
{
- const tPaletteColorHSV *ps1 = a1, *ps2 = a2;
+ const tPaletteColorHSV *ps1 = static_cast<const tPaletteColorHSV *>(a1);
+ const tPaletteColorHSV *ps2 = static_cast<const tPaletteColorHSV *>(a2);
/* Saturation. */
if (ps1->s > ps2->s) {
@@ -845,7 +843,8 @@ static int palettecolor_compare_svh(const void *a1, const void *a2)
static int palettecolor_compare_vhs(const void *a1, const void *a2)
{
- const tPaletteColorHSV *ps1 = a1, *ps2 = a2;
+ const tPaletteColorHSV *ps1 = static_cast<const tPaletteColorHSV *>(a1);
+ const tPaletteColorHSV *ps2 = static_cast<const tPaletteColorHSV *>(a2);
/* Value. */
if (1.0f - ps1->v > 1.0f - ps2->v) {
@@ -876,7 +875,8 @@ static int palettecolor_compare_vhs(const void *a1, const void *a2)
static int palettecolor_compare_luminance(const void *a1, const void *a2)
{
- const tPaletteColorHSV *ps1 = a1, *ps2 = a2;
+ const tPaletteColorHSV *ps1 = static_cast<const tPaletteColorHSV *>(a1);
+ const tPaletteColorHSV *ps2 = static_cast<const tPaletteColorHSV *>(a2);
float lumi1 = (ps1->rgb[0] + ps1->rgb[1] + ps1->rgb[2]) / 3.0f;
float lumi2 = (ps2->rgb[0] + ps2->rgb[1] + ps2->rgb[2]) / 3.0f;
@@ -917,14 +917,15 @@ void BKE_palette_sort_luminance(tPaletteColorHSV *color_array, const int totcol)
bool BKE_palette_from_hash(Main *bmain, GHash *color_table, const char *name, const bool linear)
{
- tPaletteColorHSV *color_array = NULL;
- tPaletteColorHSV *col_elm = NULL;
+ tPaletteColorHSV *color_array = nullptr;
+ tPaletteColorHSV *col_elm = nullptr;
bool done = false;
const int totpal = BLI_ghash_len(color_table);
if (totpal > 0) {
- color_array = MEM_calloc_arrayN(totpal, sizeof(tPaletteColorHSV), __func__);
+ color_array = static_cast<tPaletteColorHSV *>(
+ MEM_calloc_arrayN(totpal, sizeof(tPaletteColorHSV), __func__));
/* Put all colors in an array. */
GHashIterator gh_iter;
int t = 0;
@@ -979,14 +980,14 @@ bool BKE_palette_from_hash(Main *bmain, GHash *color_table, const char *name, co
bool BKE_paint_select_face_test(Object *ob)
{
- return ((ob != NULL) && (ob->type == OB_MESH) && (ob->data != NULL) &&
+ return ((ob != nullptr) && (ob->type == OB_MESH) && (ob->data != nullptr) &&
(((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_FACE_SEL) &&
(ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)));
}
bool BKE_paint_select_vert_test(Object *ob)
{
- return ((ob != NULL) && (ob->type == OB_MESH) && (ob->data != NULL) &&
+ return ((ob != nullptr) && (ob->type == OB_MESH) && (ob->data != nullptr) &&
(((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_VERT_SEL) &&
(ob->mode & OB_MODE_WEIGHT_PAINT || ob->mode & OB_MODE_VERTEX_PAINT));
}
@@ -998,14 +999,14 @@ bool BKE_paint_select_elem_test(Object *ob)
bool BKE_paint_always_hide_test(Object *ob)
{
- return ((ob != NULL) && (ob->type == OB_MESH) && (ob->data != NULL) &&
+ return ((ob != nullptr) && (ob->type == OB_MESH) && (ob->data != nullptr) &&
(ob->mode & OB_MODE_WEIGHT_PAINT || ob->mode & OB_MODE_VERTEX_PAINT));
}
void BKE_paint_cavity_curve_preset(Paint *p, int preset)
{
- CurveMapping *cumap = NULL;
- CurveMap *cuma = NULL;
+ CurveMapping *cumap = nullptr;
+ CurveMap *cuma = nullptr;
if (!p->cavity_curve) {
p->cavity_curve = BKE_curvemapping_add(1, 0, 0, 1, 1);
@@ -1035,13 +1036,13 @@ eObjectMode BKE_paint_object_mode_from_paintmode(ePaintMode mode)
return OB_MODE_EDIT;
case PAINT_MODE_INVALID:
default:
- return 0;
+ return OB_MODE_OBJECT;
}
}
-bool BKE_paint_ensure(ToolSettings *ts, struct Paint **r_paint)
+bool BKE_paint_ensure(ToolSettings *ts, Paint **r_paint)
{
- Paint *paint = NULL;
+ Paint *paint = nullptr;
if (*r_paint) {
/* Tool offset should never be 0 for initialized paint settings, so it's a reliable way to
* check if already initialized. */
@@ -1053,7 +1054,7 @@ bool BKE_paint_ensure(ToolSettings *ts, struct Paint **r_paint)
}
else {
BLI_assert(ELEM(*r_paint,
- /* Cast is annoying, but prevent NULL-pointer access. */
+ /* Cast is annoying, but prevent nullptr-pointer access. */
(Paint *)ts->gp_paint,
(Paint *)ts->gp_vertexpaint,
(Paint *)ts->gp_sculptpaint,
@@ -1065,7 +1066,7 @@ bool BKE_paint_ensure(ToolSettings *ts, struct Paint **r_paint)
(Paint *)ts->curves_sculpt,
(Paint *)&ts->imapaint));
#ifdef DEBUG
- struct Paint paint_test = **r_paint;
+ Paint paint_test = **r_paint;
BKE_paint_runtime_init(ts, *r_paint);
/* Swap so debug doesn't hide errors when release fails. */
SWAP(Paint, **r_paint, paint_test);
@@ -1077,11 +1078,11 @@ bool BKE_paint_ensure(ToolSettings *ts, struct Paint **r_paint)
}
if (((VPaint **)r_paint == &ts->vpaint) || ((VPaint **)r_paint == &ts->wpaint)) {
- VPaint *data = MEM_callocN(sizeof(*data), __func__);
+ VPaint *data = MEM_cnew<VPaint>(__func__);
paint = &data->paint;
}
else if ((Sculpt **)r_paint == &ts->sculpt) {
- Sculpt *data = MEM_callocN(sizeof(*data), __func__);
+ Sculpt *data = MEM_cnew<Sculpt>(__func__);
paint = &data->paint;
/* Turn on X plane mirror symmetry by default */
@@ -1091,27 +1092,27 @@ bool BKE_paint_ensure(ToolSettings *ts, struct Paint **r_paint)
data->flags |= SCULPT_DYNTOPO_SUBDIVIDE | SCULPT_DYNTOPO_COLLAPSE;
}
else if ((GpPaint **)r_paint == &ts->gp_paint) {
- GpPaint *data = MEM_callocN(sizeof(*data), __func__);
+ GpPaint *data = MEM_cnew<GpPaint>(__func__);
paint = &data->paint;
}
else if ((GpVertexPaint **)r_paint == &ts->gp_vertexpaint) {
- GpVertexPaint *data = MEM_callocN(sizeof(*data), __func__);
+ GpVertexPaint *data = MEM_cnew<GpVertexPaint>(__func__);
paint = &data->paint;
}
else if ((GpSculptPaint **)r_paint == &ts->gp_sculptpaint) {
- GpSculptPaint *data = MEM_callocN(sizeof(*data), __func__);
+ GpSculptPaint *data = MEM_cnew<GpSculptPaint>(__func__);
paint = &data->paint;
}
else if ((GpWeightPaint **)r_paint == &ts->gp_weightpaint) {
- GpWeightPaint *data = MEM_callocN(sizeof(*data), __func__);
+ GpWeightPaint *data = MEM_cnew<GpWeightPaint>(__func__);
paint = &data->paint;
}
else if ((UvSculpt **)r_paint == &ts->uvsculpt) {
- UvSculpt *data = MEM_callocN(sizeof(*data), __func__);
+ UvSculpt *data = MEM_cnew<UvSculpt>(__func__);
paint = &data->paint;
}
else if ((CurvesSculpt **)r_paint == &ts->curves_sculpt) {
- CurvesSculpt *data = MEM_callocN(sizeof(*data), __func__);
+ CurvesSculpt *data = MEM_cnew<CurvesSculpt>(__func__);
paint = &data->paint;
}
else if (*r_paint == &ts->imapaint.paint) {
@@ -1127,7 +1128,7 @@ bool BKE_paint_ensure(ToolSettings *ts, struct Paint **r_paint)
return false;
}
-void BKE_paint_init(Main *bmain, Scene *sce, ePaintMode mode, const char col[3])
+void BKE_paint_init(Main *bmain, Scene *sce, ePaintMode mode, const uchar col[3])
{
UnifiedPaintSettings *ups = &sce->toolsettings->unified_paint_settings;
Paint *paint = BKE_paint_get_active_from_paintmode(sce, mode);
@@ -1137,7 +1138,7 @@ void BKE_paint_init(Main *bmain, Scene *sce, ePaintMode mode, const char col[3])
/* If there's no brush, create one */
if (PAINT_MODE_HAS_BRUSH(mode)) {
Brush *brush = BKE_paint_brush(paint);
- if (brush == NULL) {
+ if (brush == nullptr) {
eObjectMode ob_mode = BKE_paint_object_mode_from_paintmode(mode);
brush = BKE_brush_first_search(bmain, ob_mode);
if (!brush) {
@@ -1148,7 +1149,7 @@ void BKE_paint_init(Main *bmain, Scene *sce, ePaintMode mode, const char col[3])
}
}
- memcpy(paint->paint_cursor_col, col, 3);
+ copy_v3_v3_uchar(paint->paint_cursor_col, col);
paint->paint_cursor_col[3] = 128;
ups->last_stroke_valid = false;
zero_v3(ups->average_stroke_accum);
@@ -1168,12 +1169,12 @@ void BKE_paint_copy(Paint *src, Paint *tar, const int flag)
{
tar->brush = src->brush;
tar->cavity_curve = BKE_curvemapping_copy(src->cavity_curve);
- tar->tool_slots = MEM_dupallocN(src->tool_slots);
+ tar->tool_slots = static_cast<PaintToolSlot *>(MEM_dupallocN(src->tool_slots));
if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
id_us_plus((ID *)tar->brush);
id_us_plus((ID *)tar->palette);
- if (src->tool_slots != NULL) {
+ if (src->tool_slots != nullptr) {
for (int i = 0; i < tar->tool_slots_len; i++) {
id_us_plus((ID *)tar->tool_slots[i].brush);
}
@@ -1221,7 +1222,7 @@ void BKE_paint_blend_read_data(BlendDataReader *reader, const Scene *scene, Pain
const size_t expected_size = sizeof(PaintToolSlot) * p->tool_slots_len;
if (p->tool_slots && MEM_allocN_len(p->tool_slots) < expected_size) {
MEM_freeN(p->tool_slots);
- p->tool_slots = MEM_callocN(expected_size, "PaintToolSlot");
+ p->tool_slots = static_cast<PaintToolSlot *>(MEM_callocN(expected_size, "PaintToolSlot"));
}
BKE_paint_runtime_init(scene->toolsettings, p);
@@ -1232,22 +1233,24 @@ void BKE_paint_blend_read_lib(BlendLibReader *reader, Scene *sce, Paint *p)
if (p) {
BLO_read_id_address(reader, sce->id.lib, &p->brush);
for (int i = 0; i < p->tool_slots_len; i++) {
- if (p->tool_slots[i].brush != NULL) {
+ if (p->tool_slots[i].brush != nullptr) {
BLO_read_id_address(reader, sce->id.lib, &p->tool_slots[i].brush);
}
}
BLO_read_id_address(reader, sce->id.lib, &p->palette);
- p->paint_cursor = NULL;
+ p->paint_cursor = nullptr;
BKE_paint_runtime_init(sce->toolsettings, p);
}
}
-bool paint_is_face_hidden(const MLoopTri *lt, const MVert *mvert, const MLoop *mloop)
+bool paint_is_face_hidden(const MLoopTri *lt, const bool *hide_vert, const MLoop *mloop)
{
- return ((mvert[mloop[lt->tri[0]].v].flag & ME_HIDE) ||
- (mvert[mloop[lt->tri[1]].v].flag & ME_HIDE) ||
- (mvert[mloop[lt->tri[2]].v].flag & ME_HIDE));
+ if (!hide_vert) {
+ return false;
+ }
+ return ((hide_vert[mloop[lt->tri[0]].v]) || (hide_vert[mloop[lt->tri[1]].v]) ||
+ (hide_vert[mloop[lt->tri[2]].v]));
}
bool paint_is_grid_face_hidden(const uint *grid_hidden, int gridsize, int x, int y)
@@ -1346,9 +1349,9 @@ void BKE_sculptsession_free_deformMats(SculptSession *ss)
MEM_SAFE_FREE(ss->deform_imats);
}
-void BKE_sculptsession_free_vwpaint_data(struct SculptSession *ss)
+void BKE_sculptsession_free_vwpaint_data(SculptSession *ss)
{
- struct SculptVertexPaintGeomMap *gmap = NULL;
+ SculptVertexPaintGeomMap *gmap = nullptr;
if (ss->mode_type == OB_MODE_VERTEX_PAINT) {
gmap = &ss->mode.vpaint.gmap;
}
@@ -1359,7 +1362,7 @@ void BKE_sculptsession_free_vwpaint_data(struct SculptSession *ss)
if (ss->mode.wpaint.dvert_prev) {
BKE_defvert_array_free_elems(ss->mode.wpaint.dvert_prev, ss->totvert);
MEM_freeN(ss->mode.wpaint.dvert_prev);
- ss->mode.wpaint.dvert_prev = NULL;
+ ss->mode.wpaint.dvert_prev = nullptr;
}
}
else {
@@ -1388,12 +1391,9 @@ static void sculptsession_bm_to_me_update_data_only(Object *ob, bool reorder)
if (reorder) {
BM_log_mesh_elems_reorder(ss->bm, ss->bm_log);
}
- BM_mesh_bm_to_me(NULL,
- ss->bm,
- ob->data,
- (&(struct BMeshToMeshParams){
- .calc_object_remap = false,
- }));
+ BMeshToMeshParams params{};
+ params.calc_object_remap = false;
+ BM_mesh_bm_to_me(nullptr, ss->bm, static_cast<Mesh *>(ob->data), &params);
}
}
}
@@ -1419,7 +1419,7 @@ static void sculptsession_free_pbvh(Object *object)
if (ss->pbvh) {
BKE_pbvh_free(ss->pbvh);
- ss->pbvh = NULL;
+ ss->pbvh = nullptr;
}
MEM_SAFE_FREE(ss->pmap);
@@ -1433,10 +1433,10 @@ static void sculptsession_free_pbvh(Object *object)
MEM_SAFE_FREE(ss->persistent_base);
- MEM_SAFE_FREE(ss->preview_vert_index_list);
- ss->preview_vert_index_count = 0;
+ MEM_SAFE_FREE(ss->preview_vert_list);
+ ss->preview_vert_count = 0;
- MEM_SAFE_FREE(ss->preview_vert_index_list);
+ MEM_SAFE_FREE(ss->preview_vert_list);
MEM_SAFE_FREE(ss->vertex_info.connected_component);
MEM_SAFE_FREE(ss->vertex_info.boundary);
@@ -1521,7 +1521,7 @@ void BKE_sculptsession_free(Object *ob)
MEM_freeN(ss);
- ob->sculpt = NULL;
+ ob->sculpt = nullptr;
}
}
@@ -1533,18 +1533,18 @@ MultiresModifierData *BKE_sculpt_multires_active(const Scene *scene, Object *ob)
if (ob->sculpt && ob->sculpt->bm) {
/* can't combine multires and dynamic topology */
- return NULL;
+ return nullptr;
}
if (!CustomData_get_layer(&me->ldata, CD_MDISPS)) {
/* multires can't work without displacement layer */
- return NULL;
+ return nullptr;
}
/* Weight paint operates on original vertices, and needs to treat multires as regular modifier
* to make it so that PBVH vertices are at the multires surface. */
if ((ob->mode & OB_MODE_SCULPT) == 0) {
- return NULL;
+ return nullptr;
}
for (md = BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData); md; md = md->next) {
@@ -1559,11 +1559,11 @@ MultiresModifierData *BKE_sculpt_multires_active(const Scene *scene, Object *ob)
return mmd;
}
- return NULL;
+ return nullptr;
}
}
- return NULL;
+ return nullptr;
}
/* Checks if there are any supported deformation modifiers active */
@@ -1586,7 +1586,7 @@ static bool sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob)
/* exception for shape keys because we can edit those */
for (; md; md = md->next) {
- const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
+ const ModifierTypeInfo *mti = BKE_modifier_get_info(static_cast<ModifierType>(md->type));
if (!BKE_modifier_is_enabled(scene, md, eModifierMode_Realtime)) {
continue;
}
@@ -1616,7 +1616,7 @@ static bool sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob)
*/
static void sculpt_update_object(Depsgraph *depsgraph,
Object *ob,
- Mesh *me_eval,
+ Object *ob_eval,
bool need_pmap,
bool need_mask,
bool is_paint_tool)
@@ -1625,9 +1625,12 @@ static void sculpt_update_object(Depsgraph *depsgraph,
Sculpt *sd = scene->toolsettings->sculpt;
SculptSession *ss = ob->sculpt;
const Mesh *me = BKE_object_get_original_mesh(ob);
+ Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval);
MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
const bool use_face_sets = (ob->mode & OB_MODE_SCULPT) != 0;
+ BLI_assert(me_eval != nullptr);
+
ss->depsgraph = depsgraph;
ss->deform_modifiers_active = sculpt_modifiers_active(scene, sd, ob);
@@ -1639,7 +1642,7 @@ static void sculpt_update_object(Depsgraph *depsgraph,
ss->scene = scene;
if (need_mask) {
- if (mmd == NULL) {
+ if (mmd == nullptr) {
BLI_assert(CustomData_has_layer(&me->vdata, CD_PAINT_MASK));
}
else {
@@ -1647,7 +1650,7 @@ static void sculpt_update_object(Depsgraph *depsgraph,
}
}
- ss->shapekey_active = (mmd == NULL) ? BKE_keyblock_from_object(ob) : NULL;
+ ss->shapekey_active = (mmd == nullptr) ? BKE_keyblock_from_object(ob) : nullptr;
/* NOTE: Weight pPaint require mesh info for loop lookup, but it never uses multires code path,
* so no extra checks is needed here. */
@@ -1673,40 +1676,40 @@ static void sculpt_update_object(Depsgraph *depsgraph,
ss->mpoly = me->mpoly;
ss->mloop = me->mloop;
ss->multires.active = false;
- ss->multires.modifier = NULL;
+ ss->multires.modifier = nullptr;
ss->multires.level = 0;
- ss->vmask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK);
+ ss->vmask = static_cast<float *>(CustomData_get_layer(&me->vdata, CD_PAINT_MASK));
CustomDataLayer *layer;
eAttrDomain domain;
if (BKE_pbvh_get_color_layer(me, &layer, &domain)) {
if (layer->type == CD_PROP_COLOR) {
- ss->vcol = layer->data;
+ ss->vcol = static_cast<MPropCol *>(layer->data);
}
else {
- ss->mcol = layer->data;
+ ss->mcol = static_cast<MLoopCol *>(layer->data);
}
ss->vcol_domain = domain;
- ss->vcol_type = layer->type;
+ ss->vcol_type = static_cast<eCustomDataType>(layer->type);
}
else {
- ss->vcol = NULL;
- ss->mcol = NULL;
+ ss->vcol = nullptr;
+ ss->mcol = nullptr;
- ss->vcol_type = -1;
- ss->vcol_domain = ATTR_DOMAIN_NUM;
+ ss->vcol_type = (eCustomDataType)-1;
+ ss->vcol_domain = ATTR_DOMAIN_POINT;
}
}
/* Sculpt Face Sets. */
if (use_face_sets) {
BLI_assert(CustomData_has_layer(&me->pdata, CD_SCULPT_FACE_SETS));
- ss->face_sets = CustomData_get_layer(&me->pdata, CD_SCULPT_FACE_SETS);
+ ss->face_sets = static_cast<int *>(CustomData_get_layer(&me->pdata, CD_SCULPT_FACE_SETS));
}
else {
- ss->face_sets = NULL;
+ ss->face_sets = nullptr;
}
ss->subdiv_ccg = me_eval->runtime.subdiv_ccg;
@@ -1733,14 +1736,33 @@ static void sculpt_update_object(Depsgraph *depsgraph,
pbvh_show_face_sets_set(ss->pbvh, ss->show_face_sets);
if (ss->deform_modifiers_active) {
- if (!ss->orig_cos) {
+ /* Painting doesn't need crazyspace, use already evaluated mesh coordinates. */
+ if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) {
+ Mesh *me_eval_deform = ob_eval->runtime.mesh_deform_eval;
+
+ /* If the fully evaluated mesh has the same topology as the deform-only version, use it.
+ * This matters because 'deform eval' is very restrictive and excludes even modifiers that
+ * simply recompute vertex weights. */
+ if (me_eval_deform->mpoly == me_eval->mpoly && me_eval_deform->mloop == me_eval->mloop &&
+ me_eval_deform->totvert == me_eval->totvert) {
+ me_eval_deform = me_eval;
+ }
+
+ BKE_sculptsession_free_deformMats(ss);
+
+ BLI_assert(me_eval_deform->totvert == me->totvert);
+
+ ss->deform_cos = BKE_mesh_vert_coords_alloc(me_eval_deform, NULL);
+ BKE_pbvh_vert_coords_apply(ss->pbvh, ss->deform_cos, me->totvert);
+ }
+ else if (!ss->orig_cos) {
int a;
BKE_sculptsession_free_deformMats(ss);
ss->orig_cos = (ss->shapekey_active) ?
BKE_keyblock_convert_to_vertcos(ob, ss->shapekey_active) :
- BKE_mesh_vert_coords_alloc(me, NULL);
+ BKE_mesh_vert_coords_alloc(me, nullptr);
BKE_crazyspace_build_sculpt(depsgraph, scene, ob, &ss->deform_imats, &ss->deform_cos);
BKE_pbvh_vert_coords_apply(ss->pbvh, ss->deform_cos, me->totvert);
@@ -1754,14 +1776,14 @@ static void sculpt_update_object(Depsgraph *depsgraph,
BKE_sculptsession_free_deformMats(ss);
}
- if (ss->shapekey_active != NULL && ss->deform_cos == NULL) {
+ if (ss->shapekey_active != nullptr && ss->deform_cos == nullptr) {
ss->deform_cos = BKE_keyblock_convert_to_vertcos(ob, ss->shapekey_active);
}
/* if pbvh is deformed, key block is already applied to it */
if (ss->shapekey_active) {
bool pbvh_deformed = BKE_pbvh_is_deformed(ss->pbvh);
- if (!pbvh_deformed || ss->deform_cos == NULL) {
+ if (!pbvh_deformed || ss->deform_cos == nullptr) {
float(*vertCos)[3] = BKE_keyblock_convert_to_vertcos(ob, ss->shapekey_active);
if (vertCos) {
@@ -1769,7 +1791,7 @@ static void sculpt_update_object(Depsgraph *depsgraph,
/* apply shape keys coordinates to PBVH */
BKE_pbvh_vert_coords_apply(ss->pbvh, vertCos, me->totvert);
}
- if (ss->deform_cos == NULL) {
+ if (ss->deform_cos == nullptr) {
ss->deform_cos = vertCos;
}
if (vertCos != ss->deform_cos) {
@@ -1788,7 +1810,7 @@ static void sculpt_update_object(Depsgraph *depsgraph,
*/
if (U.experimental.use_sculpt_texture_paint && ss->pbvh) {
char *paint_canvas_key = BKE_paint_canvas_key_get(&scene->toolsettings->paint_mode, ob);
- if (ss->last_paint_canvas_key == NULL ||
+ if (ss->last_paint_canvas_key == nullptr ||
!STREQ(paint_canvas_key, ss->last_paint_canvas_key)) {
MEM_SAFE_FREE(ss->last_paint_canvas_key);
ss->last_paint_canvas_key = paint_canvas_key;
@@ -1813,8 +1835,8 @@ static void sculpt_face_sets_ensure(Mesh *mesh)
return;
}
- int *new_face_sets = CustomData_add_layer(
- &mesh->pdata, CD_SCULPT_FACE_SETS, CD_CALLOC, NULL, mesh->totpoly);
+ int *new_face_sets = static_cast<int *>(
+ CustomData_add_layer(&mesh->pdata, CD_SCULPT_FACE_SETS, CD_CALLOC, nullptr, mesh->totpoly));
/* Initialize the new Face Set data-layer with a default valid visible ID and set the default
* color to render it white. */
@@ -1845,7 +1867,7 @@ void BKE_sculpt_update_object_before_eval(const Scene *scene, Object *ob_eval)
PBVHNode **nodes;
int n, totnode;
- BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
+ BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode);
for (n = 0; n < totnode; n++) {
BKE_pbvh_node_mark_update(nodes[n]);
@@ -1871,13 +1893,11 @@ void BKE_sculpt_update_object_after_eval(Depsgraph *depsgraph, Object *ob_eval)
/* Update after mesh evaluation in the dependency graph, to rebuild PBVH or
* other data when modifiers change the mesh. */
Object *ob_orig = DEG_get_original_object(ob_eval);
- Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval);
- BLI_assert(me_eval != NULL);
- sculpt_update_object(depsgraph, ob_orig, me_eval, false, false, false);
+ sculpt_update_object(depsgraph, ob_orig, ob_eval, false, false, false);
}
-void BKE_sculpt_color_layer_create_if_needed(struct Object *object)
+void BKE_sculpt_color_layer_create_if_needed(Object *object)
{
Mesh *orig_me = BKE_object_get_original_mesh(object);
@@ -1897,7 +1917,7 @@ void BKE_sculpt_color_layer_create_if_needed(struct Object *object)
return;
}
- CustomData_add_layer(&orig_me->vdata, CD_PROP_COLOR, CD_DEFAULT, NULL, orig_me->totvert);
+ CustomData_add_layer(&orig_me->vdata, CD_PROP_COLOR, CD_DEFAULT, nullptr, orig_me->totvert);
CustomDataLayer *layer = orig_me->vdata.layers +
CustomData_get_layer_index(&orig_me->vdata, CD_PROP_COLOR);
@@ -1917,19 +1937,17 @@ void BKE_sculpt_update_object_for_edit(
BLI_assert(ob_orig == DEG_get_original_object(ob_orig));
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob_orig);
- Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval);
- BLI_assert(me_eval != NULL);
- sculpt_update_object(depsgraph, ob_orig, me_eval, need_pmap, need_mask, is_paint_tool);
+ sculpt_update_object(depsgraph, ob_orig, ob_eval, need_pmap, need_mask, is_paint_tool);
}
int BKE_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd)
{
- const float *paint_mask;
- Mesh *me = ob->data;
+ Mesh *me = static_cast<Mesh *>(ob->data);
int ret = 0;
- paint_mask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK);
+ const float *paint_mask = static_cast<const float *>(
+ CustomData_get_layer(&me->vdata, CD_PAINT_MASK));
/* if multires is active, create a grid paint mask layer if there
* isn't one already */
@@ -1940,13 +1958,15 @@ int BKE_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd)
int gridarea = gridsize * gridsize;
int i, j;
- gmask = CustomData_add_layer(&me->ldata, CD_GRID_PAINT_MASK, CD_CALLOC, NULL, me->totloop);
+ gmask = static_cast<GridPaintMask *>(
+ CustomData_add_layer(&me->ldata, CD_GRID_PAINT_MASK, CD_CALLOC, nullptr, me->totloop));
for (i = 0; i < me->totloop; i++) {
GridPaintMask *gpm = &gmask[i];
gpm->level = level;
- gpm->data = MEM_callocN(sizeof(float) * gridarea, "GridPaintMask.data");
+ gpm->data = static_cast<float *>(
+ MEM_callocN(sizeof(float) * gridarea, "GridPaintMask.data"));
}
/* if vertices already have mask, copy into multires data */
@@ -1982,14 +2002,14 @@ int BKE_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd)
/* create vertex paint mask layer if there isn't one already */
if (!paint_mask) {
- CustomData_add_layer(&me->vdata, CD_PAINT_MASK, CD_CALLOC, NULL, me->totvert);
+ CustomData_add_layer(&me->vdata, CD_PAINT_MASK, CD_CALLOC, nullptr, me->totvert);
ret |= SCULPT_MASK_LAYER_CALC_VERT;
}
return ret;
}
-void BKE_sculpt_toolsettings_data_ensure(struct Scene *scene)
+void BKE_sculpt_toolsettings_data_ensure(Scene *scene)
{
BKE_paint_ensure(scene->toolsettings, (Paint **)&scene->toolsettings->sculpt);
@@ -2027,7 +2047,7 @@ static bool check_sculpt_object_deformed(Object *object, const bool for_construc
deformed |= object->sculpt->deform_modifiers_active;
if (for_construction) {
- deformed |= object->sculpt->shapekey_active != NULL;
+ deformed |= object->sculpt->shapekey_active != nullptr;
}
else {
/* As in case with modifiers, we can't synchronize deformation made against
@@ -2049,15 +2069,16 @@ void BKE_sculpt_face_sets_ensure_from_base_mesh_visibility(Mesh *mesh)
if (CustomData_has_layer(&mesh->pdata, CD_SCULPT_FACE_SETS)) {
/* Make everything visible. */
- int *current_face_sets = CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS);
+ int *current_face_sets = static_cast<int *>(
+ CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS));
for (int i = 0; i < mesh->totpoly; i++) {
current_face_sets[i] = abs(current_face_sets[i]);
}
}
else {
initialize_new_face_sets = true;
- int *new_face_sets = CustomData_add_layer(
- &mesh->pdata, CD_SCULPT_FACE_SETS, CD_CALLOC, NULL, mesh->totpoly);
+ int *new_face_sets = static_cast<int *>(CustomData_add_layer(
+ &mesh->pdata, CD_SCULPT_FACE_SETS, CD_CALLOC, nullptr, mesh->totpoly));
/* Initialize the new Face Set data-layer with a default valid visible ID and set the default
* color to render it white. */
@@ -2067,10 +2088,12 @@ void BKE_sculpt_face_sets_ensure_from_base_mesh_visibility(Mesh *mesh)
mesh->face_sets_color_default = face_sets_default_visible_id;
}
- int *face_sets = CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS);
+ int *face_sets = static_cast<int *>(CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS));
+ const bool *hide_poly = (const bool *)CustomData_get_layer_named(
+ &mesh->pdata, CD_PROP_BOOL, ".hide_poly");
for (int i = 0; i < mesh->totpoly; i++) {
- if (!(mesh->mpoly[i].flag & ME_HIDE)) {
+ if (!(hide_poly && hide_poly[i])) {
continue;
}
@@ -2090,22 +2113,31 @@ void BKE_sculpt_face_sets_ensure_from_base_mesh_visibility(Mesh *mesh)
void BKE_sculpt_sync_face_sets_visibility_to_base_mesh(Mesh *mesh)
{
- const int *face_sets = CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS);
+ using namespace blender::bke;
+ const int *face_sets = static_cast<const int *>(
+ CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS));
if (!face_sets) {
return;
}
- for (int i = 0; i < mesh->totpoly; i++) {
- const bool is_face_set_visible = face_sets[i] >= 0;
- SET_FLAG_FROM_TEST(mesh->mpoly[i].flag, !is_face_set_visible, ME_HIDE);
+ MutableAttributeAccessor attributes = mesh_attributes_for_write(*mesh);
+ SpanAttributeWriter<bool> hide_poly = attributes.lookup_or_add_for_write_only_span<bool>(
+ ".hide_poly", ATTR_DOMAIN_FACE);
+ if (!hide_poly) {
+ return;
+ }
+ for (const int i : hide_poly.span.index_range()) {
+ hide_poly.span[i] = face_sets[i] < 0;
}
+ hide_poly.finish();
BKE_mesh_flush_hidden_from_polys(mesh);
}
void BKE_sculpt_sync_face_sets_visibility_to_grids(Mesh *mesh, SubdivCCG *subdiv_ccg)
{
- const int *face_sets = CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS);
+ const int *face_sets = static_cast<const int *>(
+ CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS));
if (!face_sets) {
return;
}
@@ -2134,7 +2166,7 @@ void BKE_sculpt_sync_face_sets_visibility_to_grids(Mesh *mesh, SubdivCCG *subdiv
}
}
-void BKE_sculpt_sync_face_set_visibility(struct Mesh *mesh, struct SubdivCCG *subdiv_ccg)
+void BKE_sculpt_sync_face_set_visibility(Mesh *mesh, SubdivCCG *subdiv_ccg)
{
BKE_sculpt_face_sets_ensure_from_base_mesh_visibility(mesh);
BKE_sculpt_sync_face_sets_visibility_to_base_mesh(mesh);
@@ -2150,9 +2182,10 @@ void BKE_sculpt_ensure_orig_mesh_data(Scene *scene, Object *object)
/* Copy the current mesh visibility to the Face Sets. */
BKE_sculpt_face_sets_ensure_from_base_mesh_visibility(mesh);
- if (object->sculpt != NULL) {
+ if (object->sculpt != nullptr) {
/* If a sculpt session is active, ensure we have its face-set data properly up-to-date. */
- object->sculpt->face_sets = CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS);
+ object->sculpt->face_sets = static_cast<int *>(
+ CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS));
/* NOTE: In theory we could add that on the fly when required by sculpt code.
* But this then requires proper update of depsgraph etc. For now we play safe, optimization is
@@ -2201,11 +2234,12 @@ static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform, bool
PBVH *pbvh = BKE_pbvh_new();
BKE_pbvh_respect_hide_set(pbvh, respect_hide);
- MLoopTri *looptri = MEM_malloc_arrayN(looptris_num, sizeof(*looptri), __func__);
+ MLoopTri *looptri = static_cast<MLoopTri *>(
+ MEM_malloc_arrayN(looptris_num, sizeof(*looptri), __func__));
BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, looptri);
- BKE_sculpt_sync_face_set_visibility(me, NULL);
+ BKE_sculpt_sync_face_set_visibility(me, nullptr);
BKE_pbvh_build_mesh(pbvh,
me,
@@ -2223,7 +2257,7 @@ static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform, bool
pbvh_show_face_sets_set(pbvh, ob->sculpt->show_face_sets);
const bool is_deformed = check_sculpt_object_deformed(ob, true);
- if (is_deformed && me_eval_deform != NULL) {
+ if (is_deformed && me_eval_deform != nullptr) {
int totvert;
float(*v_cos)[3] = BKE_mesh_vert_coords_alloc(me_eval_deform, &totvert);
BKE_pbvh_vert_coords_apply(pbvh, v_cos, totvert);
@@ -2257,21 +2291,21 @@ static PBVH *build_pbvh_from_ccg(Object *ob, SubdivCCG *subdiv_ccg, bool respect
PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
{
- if (ob == NULL || ob->sculpt == NULL) {
- return NULL;
+ if (ob == nullptr || ob->sculpt == nullptr) {
+ return nullptr;
}
const bool respect_hide = true;
PBVH *pbvh = ob->sculpt->pbvh;
- if (pbvh != NULL) {
+ if (pbvh != nullptr) {
/* NOTE: It is possible that grids were re-allocated due to modifier
* stack. Need to update those pointers. */
if (BKE_pbvh_type(pbvh) == PBVH_GRIDS) {
Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
- Mesh *mesh_eval = object_eval->data;
+ Mesh *mesh_eval = static_cast<Mesh *>(object_eval->data);
SubdivCCG *subdiv_ccg = mesh_eval->runtime.subdiv_ccg;
- if (subdiv_ccg != NULL) {
+ if (subdiv_ccg != nullptr) {
BKE_sculpt_bvh_update_from_ccg(pbvh, subdiv_ccg);
}
}
@@ -2282,14 +2316,14 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
return pbvh;
}
- if (ob->sculpt->bm != NULL) {
+ if (ob->sculpt->bm != nullptr) {
/* Sculpting on a BMesh (dynamic-topology) gets a special PBVH. */
pbvh = build_pbvh_for_dynamic_topology(ob);
}
else {
Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
- Mesh *mesh_eval = object_eval->data;
- if (mesh_eval->runtime.subdiv_ccg != NULL) {
+ Mesh *mesh_eval = static_cast<Mesh *>(object_eval->data);
+ if (mesh_eval->runtime.subdiv_ccg != nullptr) {
pbvh = build_pbvh_from_ccg(ob, mesh_eval->runtime.subdiv_ccg, respect_hide);
}
else if (ob->type == OB_MESH) {
@@ -2316,7 +2350,7 @@ void BKE_sculpt_bvh_update_from_ccg(PBVH *pbvh, SubdivCCG *subdiv_ccg)
bool BKE_sculptsession_use_pbvh_draw(const Object *ob, const View3D *UNUSED(v3d))
{
SculptSession *ss = ob->sculpt;
- if (ss == NULL || ss->pbvh == NULL || ss->mode_type != OB_MODE_SCULPT) {
+ if (ss == nullptr || ss->pbvh == nullptr || ss->mode_type != OB_MODE_SCULPT) {
return false;
}
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index c5344997733..9ccd6562649 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -3494,7 +3494,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re
* initial tangent, but taking that in to account will allow
* the possibility of flipping again. -jahka
*/
- mat3_to_quat_is_ok(cache[p]->rot, rotmat);
+ mat3_to_quat_legacy(cache[p]->rot, rotmat);
}
psys->totcached = totpart;
@@ -3684,7 +3684,7 @@ static void psys_cache_edit_paths_iter(void *__restrict iter_data_v,
* initial tangent, but taking that in to account will allow
* the possibility of flipping again. -jahka
*/
- mat3_to_quat_is_ok(cache[iter]->rot, rotmat);
+ mat3_to_quat_legacy(cache[iter]->rot, rotmat);
}
}
@@ -5413,8 +5413,8 @@ void BKE_particle_system_blend_read_lib(BlendLibReader *reader,
BLO_read_id_address(reader, id->lib, &psys->target_ob);
if (psys->clmd) {
- /* XXX(campbell): from reading existing code this seems correct but intended usage of
- * pointcache /w cloth should be added in 'ParticleSystem'. */
+ /* XXX(@campbellbarton): from reading existing code this seems correct but intended usage
+ * of pointcache /w cloth should be added in 'ParticleSystem'. */
psys->clmd->point_cache = psys->pointcache;
psys->clmd->ptcaches.first = psys->clmd->ptcaches.last = NULL;
BLO_read_id_address(reader, id->lib, &psys->clmd->coll_parms->group);
diff --git a/source/blender/blenkernel/intern/particle_child.c b/source/blender/blenkernel/intern/particle_child.c
index 524ee31229b..a890812cfc4 100644
--- a/source/blender/blenkernel/intern/particle_child.c
+++ b/source/blender/blenkernel/intern/particle_child.c
@@ -158,10 +158,8 @@ static void do_kink_spiral(ParticleThreadContext *ctx,
int start_index = 0, end_index = 0;
float kink_base[3];
- if (ptex) {
- kink_amp *= ptex->kink_amp;
- kink_freq *= ptex->kink_freq;
- }
+ kink_amp *= ptex->kink_amp;
+ kink_freq *= ptex->kink_freq;
cut_time = (totkeys - 1) * ptex->length;
zero_v3(spiral_start);
@@ -405,7 +403,7 @@ void do_kink(ParticleKey *state,
float obmat[4][4],
int smooth_start)
{
- float kink[3] = {1.0f, 0.0f, 0.0f}, par_vec[3], q1[4] = {1.0f, 0.0f, 0.0f, 0.0f};
+ float kink[3] = {1.0f, 0.0f, 0.0f}, par_vec[3];
float t, dt = 1.0f, result[3];
if (ELEM(type, PART_KINK_NO, PART_KINK_SPIRAL)) {
@@ -455,6 +453,7 @@ void do_kink(ParticleKey *state,
switch (type) {
case PART_KINK_CURL: {
float curl_offset[3];
+ float q1[4] = {1.0f, 0.0f, 0.0f, 0.0f};
/* rotate kink vector around strand tangent */
mul_v3_v3fl(curl_offset, kink, amplitude);
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 4a8f029beee..abecb9f8d9d 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -837,7 +837,7 @@ void psys_get_birth_coords(
cross_v3_v3v3(mat[1], mat[2], mat[0]);
/* apply rotation */
- mat3_to_quat_is_ok(q, mat);
+ mat3_to_quat_legacy(q, mat);
copy_qt_qt(state->rot, q);
}
else {
@@ -969,7 +969,7 @@ void psys_get_birth_coords(
float tmat[3][3];
/* NOTE: utan_local is not taken from 'utan', we calculate from rot_vec/vtan. */
- /* NOTE(campbell): it looks like rotation phase may be applied twice
+ /* NOTE(@campbellbarton): it looks like rotation phase may be applied twice
* (once with vtan, again below) however this isn't the case. */
float *rot_vec_local = tmat[0];
float *vtan_local = tmat[1];
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 8c1f19f0909..726c022ba2c 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -287,7 +287,7 @@ static void build_mesh_leaf_node(PBVH *pbvh, PBVHNode *node)
}
if (has_visible == false) {
- if (!paint_is_face_hidden(lt, pbvh->verts, pbvh->mloop)) {
+ if (!paint_is_face_hidden(lt, pbvh->hide_vert, pbvh->mloop)) {
has_visible = true;
}
}
@@ -555,13 +555,14 @@ void BKE_pbvh_build_mesh(PBVH *pbvh,
BB cb;
pbvh->mesh = mesh;
- pbvh->type = PBVH_FACES;
+ pbvh->header.type = PBVH_FACES;
pbvh->mpoly = mpoly;
pbvh->mloop = mloop;
pbvh->looptri = looptri;
pbvh->verts = verts;
BKE_mesh_vertex_normals_ensure(mesh);
pbvh->vert_normals = BKE_mesh_vertex_normals_for_write(mesh);
+ pbvh->hide_vert = (bool *)CustomData_get_layer_named(&mesh->vdata, CD_PROP_BOOL, ".hide_vert");
pbvh->vert_bitmap = MEM_calloc_arrayN(totvert, sizeof(bool), "bvh->vert_bitmap");
pbvh->totvert = totvert;
pbvh->leaf_limit = LEAF_LIMIT;
@@ -615,7 +616,7 @@ void BKE_pbvh_build_grids(PBVH *pbvh,
{
const int gridsize = key->grid_size;
- pbvh->type = PBVH_GRIDS;
+ pbvh->header.type = PBVH_GRIDS;
pbvh->grids = grids;
pbvh->gridfaces = gridfaces;
pbvh->grid_flag_mats = flagmats;
@@ -1274,7 +1275,7 @@ bool BKE_pbvh_get_color_layer(const Mesh *me, CustomDataLayer **r_layer, eAttrDo
if (!layer || !ELEM(layer->type, CD_PROP_COLOR, CD_PROP_BYTE_COLOR)) {
*r_layer = NULL;
- *r_attr = ATTR_DOMAIN_NUM;
+ *r_attr = ATTR_DOMAIN_POINT;
return false;
}
@@ -1282,7 +1283,7 @@ bool BKE_pbvh_get_color_layer(const Mesh *me, CustomDataLayer **r_layer, eAttrDo
if (!ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_CORNER)) {
*r_layer = NULL;
- *r_attr = ATTR_DOMAIN_NUM;
+ *r_attr = ATTR_DOMAIN_POINT;
return false;
}
@@ -1303,19 +1304,8 @@ static void pbvh_update_draw_buffer_cb(void *__restrict userdata,
PBVH *pbvh = data->pbvh;
PBVHNode *node = data->nodes[n];
- CustomData *vdata, *ldata;
-
- if (!pbvh->bm) {
- vdata = pbvh->vdata;
- ldata = pbvh->ldata;
- }
- else {
- vdata = &pbvh->bm->vdata;
- ldata = &pbvh->bm->ldata;
- }
-
if (node->flag & PBVH_RebuildDrawBuffers) {
- switch (pbvh->type) {
+ switch (pbvh->header.type) {
case PBVH_GRIDS: {
bool smooth = node->totprim > 0 ?
pbvh->grid_flag_mats[node->prim_indices[0]].flag & ME_SMOOTH :
@@ -1326,14 +1316,11 @@ static void pbvh_update_draw_buffer_cb(void *__restrict userdata,
}
case PBVH_FACES:
node->draw_buffers = GPU_pbvh_mesh_buffers_build(
- pbvh->mpoly,
- pbvh->mloop,
+ pbvh->mesh,
pbvh->looptri,
- pbvh->verts,
- node->prim_indices,
CustomData_get_layer(pbvh->pdata, CD_SCULPT_FACE_SETS),
- node->totprim,
- pbvh->mesh);
+ node->prim_indices,
+ node->totprim);
break;
case PBVH_BMESH:
node->draw_buffers = GPU_pbvh_bmesh_buffers_build(pbvh->flags &
@@ -1343,8 +1330,10 @@ static void pbvh_update_draw_buffer_cb(void *__restrict userdata,
}
if (node->flag & PBVH_UpdateDrawBuffers) {
+ node->debug_draw_gen++;
+
const int update_flags = pbvh_get_buffers_update_flags(pbvh);
- switch (pbvh->type) {
+ switch (pbvh->header.type) {
case PBVH_GRIDS:
GPU_pbvh_grid_buffers_update(pbvh->vbo_id,
node->draw_buffers,
@@ -1360,11 +1349,12 @@ static void pbvh_update_draw_buffer_cb(void *__restrict userdata,
update_flags);
break;
case PBVH_FACES: {
+ /* Pass vertices separately because they may be not be the same as the mesh's vertices,
+ * and pass normals separately because they are managed by the PBVH. */
GPU_pbvh_mesh_buffers_update(pbvh->vbo_id,
node->draw_buffers,
+ pbvh->mesh,
pbvh->verts,
- vdata,
- ldata,
CustomData_get_layer(pbvh->vdata, CD_PAINT_MASK),
CustomData_get_layer(pbvh->pdata, CD_SCULPT_FACE_SETS),
pbvh->face_sets_color_seed,
@@ -1376,7 +1366,7 @@ static void pbvh_update_draw_buffer_cb(void *__restrict userdata,
case PBVH_BMESH:
GPU_pbvh_bmesh_buffers_update(pbvh->vbo_id,
node->draw_buffers,
- pbvh->bm,
+ pbvh->header.bm,
node->bm_faces,
node->bm_unique_verts,
node->bm_other_verts,
@@ -1405,15 +1395,15 @@ static void pbvh_check_draw_layout(PBVH *pbvh)
pbvh->vbo_id = GPU_pbvh_make_format();
}
- switch (pbvh->type) {
+ switch (pbvh->header.type) {
case PBVH_BMESH:
- if (!pbvh->bm) {
+ if (!pbvh->header.bm) {
/* BMesh hasn't been created yet */
return;
}
- vdata = &pbvh->bm->vdata;
- ldata = &pbvh->bm->ldata;
+ vdata = &pbvh->header.bm->vdata;
+ ldata = &pbvh->header.bm->ldata;
break;
case PBVH_FACES:
vdata = pbvh->vdata;
@@ -1431,7 +1421,7 @@ static void pbvh_check_draw_layout(PBVH *pbvh)
* (there's no guarantee there isn't another EEVEE viewport which would
* free the draw buffers and corrupt the draw cache).
*/
- if (GPU_pbvh_attribute_names_update(pbvh->type, pbvh->vbo_id, vdata, ldata, false)) {
+ if (GPU_pbvh_attribute_names_update(pbvh->header.type, pbvh->vbo_id, vdata, ldata, false)) {
/* attribute layout changed; force rebuild */
for (int i = 0; i < pbvh->totnode; i++) {
PBVHNode *node = pbvh->nodes + i;
@@ -1451,14 +1441,14 @@ static void pbvh_update_draw_buffers(PBVH *pbvh, PBVHNode **nodes, int totnode,
pbvh->vbo_id = GPU_pbvh_make_format();
}
- switch (pbvh->type) {
+ switch (pbvh->header.type) {
case PBVH_BMESH:
- if (!pbvh->bm) {
+ if (!pbvh->header.bm) {
/* BMesh hasn't been created yet */
return;
}
- vdata = &pbvh->bm->vdata;
+ vdata = &pbvh->header.bm->vdata;
break;
case PBVH_FACES:
vdata = pbvh->vdata;
@@ -1469,7 +1459,7 @@ static void pbvh_update_draw_buffers(PBVH *pbvh, PBVHNode **nodes, int totnode,
}
UNUSED_VARS(vdata);
- if ((update_flag & PBVH_RebuildDrawBuffers) || ELEM(pbvh->type, PBVH_GRIDS, PBVH_BMESH)) {
+ if ((update_flag & PBVH_RebuildDrawBuffers) || ELEM(pbvh->header.type, PBVH_GRIDS, PBVH_BMESH)) {
/* Free buffers uses OpenGL, so not in parallel. */
for (int n = 0; n < totnode; n++) {
PBVHNode *node = nodes[n];
@@ -1477,11 +1467,11 @@ static void pbvh_update_draw_buffers(PBVH *pbvh, PBVHNode **nodes, int totnode,
pbvh_free_draw_buffers(pbvh, node);
}
else if ((node->flag & PBVH_UpdateDrawBuffers) && node->draw_buffers) {
- if (pbvh->type == PBVH_GRIDS) {
+ if (pbvh->header.type == PBVH_GRIDS) {
GPU_pbvh_grid_buffers_update_free(
node->draw_buffers, pbvh->grid_flag_mats, node->prim_indices);
}
- else if (pbvh->type == PBVH_BMESH) {
+ else if (pbvh->header.type == PBVH_BMESH) {
GPU_pbvh_bmesh_buffers_update_free(node->draw_buffers);
}
}
@@ -1602,9 +1592,12 @@ static void pbvh_faces_node_visibility_update(PBVH *pbvh, PBVHNode *node)
BKE_pbvh_node_num_verts(pbvh, node, NULL, &totvert);
BKE_pbvh_node_get_verts(pbvh, node, &vert_indices, &mvert);
+ if (pbvh->hide_vert == NULL) {
+ BKE_pbvh_node_fully_hidden_set(node, false);
+ return;
+ }
for (i = 0; i < totvert; i++) {
- MVert *v = &mvert[vert_indices[i]];
- if (!(v->flag & ME_HIDE)) {
+ if (!(pbvh->hide_vert[vert_indices[i]])) {
BKE_pbvh_node_fully_hidden_set(node, false);
return;
}
@@ -1795,15 +1788,10 @@ void BKE_pbvh_get_grid_updates(PBVH *pbvh, bool clear, void ***r_gridfaces, int
/***************************** PBVH Access ***********************************/
-PBVHType BKE_pbvh_type(const PBVH *pbvh)
-{
- return pbvh->type;
-}
-
bool BKE_pbvh_has_faces(const PBVH *pbvh)
{
- if (pbvh->type == PBVH_BMESH) {
- return (pbvh->bm->totface != 0);
+ if (pbvh->header.type == PBVH_BMESH) {
+ return (pbvh->header.bm->totface != 0);
}
return (pbvh->totprim != 0);
@@ -1824,46 +1812,40 @@ void BKE_pbvh_bounding_box(const PBVH *pbvh, float min[3], float max[3])
BLI_bitmap **BKE_pbvh_grid_hidden(const PBVH *pbvh)
{
- BLI_assert(pbvh->type == PBVH_GRIDS);
+ BLI_assert(pbvh->header.type == PBVH_GRIDS);
return pbvh->grid_hidden;
}
const CCGKey *BKE_pbvh_get_grid_key(const PBVH *pbvh)
{
- BLI_assert(pbvh->type == PBVH_GRIDS);
+ BLI_assert(pbvh->header.type == PBVH_GRIDS);
return &pbvh->gridkey;
}
struct CCGElem **BKE_pbvh_get_grids(const PBVH *pbvh)
{
- BLI_assert(pbvh->type == PBVH_GRIDS);
+ BLI_assert(pbvh->header.type == PBVH_GRIDS);
return pbvh->grids;
}
BLI_bitmap **BKE_pbvh_get_grid_visibility(const PBVH *pbvh)
{
- BLI_assert(pbvh->type == PBVH_GRIDS);
+ BLI_assert(pbvh->header.type == PBVH_GRIDS);
return pbvh->grid_hidden;
}
int BKE_pbvh_get_grid_num_vertices(const PBVH *pbvh)
{
- BLI_assert(pbvh->type == PBVH_GRIDS);
+ BLI_assert(pbvh->header.type == PBVH_GRIDS);
return pbvh->totgrid * pbvh->gridkey.grid_area;
}
int BKE_pbvh_get_grid_num_faces(const PBVH *pbvh)
{
- BLI_assert(pbvh->type == PBVH_GRIDS);
+ BLI_assert(pbvh->header.type == PBVH_GRIDS);
return pbvh->totgrid * (pbvh->gridkey.grid_size - 1) * (pbvh->gridkey.grid_size - 1);
}
-BMesh *BKE_pbvh_get_bmesh(PBVH *pbvh)
-{
- BLI_assert(pbvh->type == PBVH_BMESH);
- return pbvh->bm;
-}
-
/***************************** Node Access ***********************************/
void BKE_pbvh_node_mark_update(PBVHNode *node)
@@ -1964,10 +1946,10 @@ bool BKE_pbvh_node_fully_unmasked_get(PBVHNode *node)
return (node->flag & PBVH_Leaf) && (node->flag & PBVH_FullyUnmasked);
}
-void BKE_pbvh_vert_tag_update_normal(PBVH *pbvh, int index)
+void BKE_pbvh_vert_tag_update_normal(PBVH *pbvh, PBVHVertRef vertex)
{
- BLI_assert(pbvh->type == PBVH_FACES);
- pbvh->vert_bitmap[index] = true;
+ BLI_assert(pbvh->header.type == PBVH_FACES);
+ pbvh->vert_bitmap[vertex.i] = true;
}
void BKE_pbvh_node_get_loops(PBVH *pbvh,
@@ -2004,7 +1986,7 @@ void BKE_pbvh_node_num_verts(PBVH *pbvh, PBVHNode *node, int *r_uniquevert, int
{
int tot;
- switch (pbvh->type) {
+ switch (pbvh->header.type) {
case PBVH_GRIDS:
tot = node->totprim * pbvh->gridkey.grid_area;
if (r_totvert) {
@@ -2042,7 +2024,7 @@ void BKE_pbvh_node_get_grids(PBVH *pbvh,
int *r_gridsize,
CCGElem ***r_griddata)
{
- switch (pbvh->type) {
+ switch (pbvh->header.type) {
case PBVH_GRIDS:
if (r_grid_indices) {
*r_grid_indices = node->prim_indices;
@@ -2125,7 +2107,7 @@ void BKE_pbvh_node_get_bm_orco_data(PBVHNode *node,
bool BKE_pbvh_node_has_vert_with_normal_update_tag(PBVH *pbvh, PBVHNode *node)
{
- BLI_assert(pbvh->type == PBVH_FACES);
+ BLI_assert(pbvh->header.type == PBVH_FACES);
const int *verts = node->vert_indices;
const int totvert = node->uniq_verts + node->face_verts;
@@ -2299,7 +2281,7 @@ static bool pbvh_faces_node_raycast(PBVH *pbvh,
const float ray_normal[3],
struct IsectRayPrecalc *isect_precalc,
float *depth,
- int *r_active_vertex_index,
+ PBVHVertRef *r_active_vertex,
int *r_active_face_index,
float *r_face_normal)
{
@@ -2314,7 +2296,7 @@ static bool pbvh_faces_node_raycast(PBVH *pbvh,
const MLoopTri *lt = &pbvh->looptri[faces[i]];
const int *face_verts = node->face_vert_indices[i];
- if (pbvh->respect_hide && paint_is_face_hidden(lt, vert, mloop)) {
+ if (pbvh->respect_hide && paint_is_face_hidden(lt, pbvh->hide_vert, mloop)) {
continue;
}
@@ -2339,7 +2321,7 @@ static bool pbvh_faces_node_raycast(PBVH *pbvh,
normal_tri_v3(r_face_normal, co[0], co[1], co[2]);
}
- if (r_active_vertex_index) {
+ if (r_active_vertex) {
float location[3] = {0.0f};
madd_v3_v3v3fl(location, ray_start, ray_normal, *depth);
for (int j = 0; j < 3; j++) {
@@ -2349,7 +2331,7 @@ static bool pbvh_faces_node_raycast(PBVH *pbvh,
if (j == 0 ||
len_squared_v3v3(location, co[j]) < len_squared_v3v3(location, nearest_vertex_co)) {
copy_v3_v3(nearest_vertex_co, co[j]);
- *r_active_vertex_index = mloop[lt->tri[j]].v;
+ r_active_vertex->i = mloop[lt->tri[j]].v;
*r_active_face_index = lt->poly;
}
}
@@ -2367,7 +2349,7 @@ static bool pbvh_grids_node_raycast(PBVH *pbvh,
const float ray_normal[3],
struct IsectRayPrecalc *isect_precalc,
float *depth,
- int *r_active_vertex_index,
+ PBVHVertRef *r_active_vertex,
int *r_active_grid_index,
float *r_face_normal)
{
@@ -2419,7 +2401,7 @@ static bool pbvh_grids_node_raycast(PBVH *pbvh,
normal_quad_v3(r_face_normal, co[0], co[1], co[2], co[3]);
}
- if (r_active_vertex_index) {
+ if (r_active_vertex) {
float location[3] = {0.0};
madd_v3_v3v3fl(location, ray_start, ray_normal, *depth);
@@ -2434,8 +2416,8 @@ static bool pbvh_grids_node_raycast(PBVH *pbvh,
len_squared_v3v3(location, nearest_vertex_co)) {
copy_v3_v3(nearest_vertex_co, co[j]);
- *r_active_vertex_index = gridkey->grid_area * grid_index +
- (y + y_it[j]) * gridkey->grid_size + (x + x_it[j]);
+ r_active_vertex->i = gridkey->grid_area * grid_index +
+ (y + y_it[j]) * gridkey->grid_size + (x + x_it[j]);
}
}
}
@@ -2462,7 +2444,7 @@ bool BKE_pbvh_node_raycast(PBVH *pbvh,
const float ray_normal[3],
struct IsectRayPrecalc *isect_precalc,
float *depth,
- int *active_vertex_index,
+ PBVHVertRef *active_vertex,
int *active_face_grid_index,
float *face_normal)
{
@@ -2472,7 +2454,7 @@ bool BKE_pbvh_node_raycast(PBVH *pbvh,
return false;
}
- switch (pbvh->type) {
+ switch (pbvh->header.type) {
case PBVH_FACES:
hit |= pbvh_faces_node_raycast(pbvh,
node,
@@ -2481,7 +2463,7 @@ bool BKE_pbvh_node_raycast(PBVH *pbvh,
ray_normal,
isect_precalc,
depth,
- active_vertex_index,
+ active_vertex,
active_face_grid_index,
face_normal);
break;
@@ -2493,19 +2475,19 @@ bool BKE_pbvh_node_raycast(PBVH *pbvh,
ray_normal,
isect_precalc,
depth,
- active_vertex_index,
+ active_vertex,
active_face_grid_index,
face_normal);
break;
case PBVH_BMESH:
- BM_mesh_elem_index_ensure(pbvh->bm, BM_VERT);
+ BM_mesh_elem_index_ensure(pbvh->header.bm, BM_VERT);
hit = pbvh_bmesh_node_raycast(node,
ray_start,
ray_normal,
isect_precalc,
depth,
use_origco,
- active_vertex_index,
+ active_vertex,
face_normal);
break;
}
@@ -2623,7 +2605,7 @@ static bool pbvh_faces_node_nearest_to_ray(PBVH *pbvh,
const MLoopTri *lt = &pbvh->looptri[faces[i]];
const int *face_verts = node->face_vert_indices[i];
- if (pbvh->respect_hide && paint_is_face_hidden(lt, vert, mloop)) {
+ if (pbvh->respect_hide && paint_is_face_hidden(lt, pbvh->hide_vert, mloop)) {
continue;
}
@@ -2729,7 +2711,7 @@ bool BKE_pbvh_node_find_nearest_to_ray(PBVH *pbvh,
return false;
}
- switch (pbvh->type) {
+ switch (pbvh->header.type) {
case PBVH_FACES:
hit |= pbvh_faces_node_nearest_to_ray(
pbvh, node, origco, ray_start, ray_normal, depth, dist_sq);
@@ -2820,13 +2802,13 @@ void BKE_pbvh_update_normals(PBVH *pbvh, struct SubdivCCG *subdiv_ccg)
pbvh, update_search_cb, POINTER_FROM_INT(PBVH_UpdateNormals), &nodes, &totnode);
if (totnode > 0) {
- if (pbvh->type == PBVH_BMESH) {
+ if (pbvh->header.type == PBVH_BMESH) {
pbvh_bmesh_normals_update(nodes, totnode);
}
- else if (pbvh->type == PBVH_FACES) {
+ else if (pbvh->header.type == PBVH_FACES) {
pbvh_faces_update_normals(pbvh, nodes, totnode);
}
- else if (pbvh->type == PBVH_GRIDS) {
+ else if (pbvh->header.type == PBVH_GRIDS) {
struct CCGFace **faces;
int num_faces;
BKE_pbvh_get_grid_updates(pbvh, true, (void ***)&faces, &num_faces);
@@ -2917,15 +2899,18 @@ void BKE_pbvh_draw_cb(PBVH *pbvh,
MEM_SAFE_FREE(nodes);
}
-void BKE_pbvh_draw_debug_cb(
- PBVH *pbvh,
- void (*draw_fn)(void *user_data, const float bmin[3], const float bmax[3], PBVHNodeFlags flag),
- void *user_data)
+void BKE_pbvh_draw_debug_cb(PBVH *pbvh,
+ void (*draw_fn)(PBVHNode *node,
+ void *user_data,
+ const float bmin[3],
+ const float bmax[3],
+ PBVHNodeFlags flag),
+ void *user_data)
{
for (int a = 0; a < pbvh->totnode; a++) {
PBVHNode *node = &pbvh->nodes[a];
- draw_fn(user_data, node->vb.bmin, node->vb.bmax, node->flag);
+ draw_fn(node, user_data, node->vb.bmin, node->vb.bmax, node->flag);
}
}
@@ -2991,7 +2976,7 @@ void BKE_pbvh_vert_coords_apply(PBVH *pbvh, const float (*vertCos)[3], const int
/* no need for float comparison here (memory is exactly equal or not) */
if (memcmp(mvert->co, vertCos[a], sizeof(float[3])) != 0) {
copy_v3_v3(mvert->co, vertCos[a]);
- BKE_pbvh_vert_tag_update_normal(pbvh, a);
+ BKE_pbvh_vert_tag_update_normal(pbvh, BKE_pbvh_make_vref(a));
}
}
@@ -3108,6 +3093,7 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
vi->no = NULL;
vi->fno = NULL;
vi->mvert = NULL;
+ vi->vertex.i = 0LL;
vi->respect_hide = pbvh->respect_hide;
if (pbvh->respect_hide == false) {
@@ -3134,10 +3120,10 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
vi->vert_indices = vert_indices;
vi->mverts = verts;
- if (pbvh->type == PBVH_BMESH) {
+ if (pbvh->header.type == PBVH_BMESH) {
BLI_gsetIterator_init(&vi->bm_unique_verts, node->bm_unique_verts);
BLI_gsetIterator_init(&vi->bm_other_verts, node->bm_other_verts);
- vi->bm_vdata = &pbvh->bm->vdata;
+ vi->bm_vdata = &pbvh->header.bm->vdata;
vi->cd_vert_mask_offset = CustomData_get_offset(vi->bm_vdata, CD_PAINT_MASK);
}
@@ -3147,8 +3133,9 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
}
vi->mask = NULL;
- if (pbvh->type == PBVH_FACES) {
+ if (pbvh->header.type == PBVH_FACES) {
vi->vert_normals = pbvh->vert_normals;
+ vi->hide_vert = pbvh->hide_vert;
vi->vmask = CustomData_get_layer(pbvh->vdata, CD_PAINT_MASK);
}
@@ -3156,13 +3143,14 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
bool pbvh_has_mask(const PBVH *pbvh)
{
- switch (pbvh->type) {
+ switch (pbvh->header.type) {
case PBVH_GRIDS:
return (pbvh->gridkey.has_mask != 0);
case PBVH_FACES:
return (pbvh->vdata && CustomData_get_layer(pbvh->vdata, CD_PAINT_MASK));
case PBVH_BMESH:
- return (pbvh->bm && (CustomData_get_offset(&pbvh->bm->vdata, CD_PAINT_MASK) != -1));
+ return (pbvh->header.bm &&
+ (CustomData_get_offset(&pbvh->header.bm->vdata, CD_PAINT_MASK) != -1));
}
return false;
@@ -3170,7 +3158,7 @@ bool pbvh_has_mask(const PBVH *pbvh)
bool pbvh_has_face_sets(PBVH *pbvh)
{
- switch (pbvh->type) {
+ switch (pbvh->header.type) {
case PBVH_GRIDS:
return (pbvh->pdata && CustomData_get_layer(pbvh->pdata, CD_SCULPT_FACE_SETS));
case PBVH_FACES:
@@ -3218,16 +3206,37 @@ void BKE_pbvh_parallel_range_settings(TaskParallelSettings *settings,
MVert *BKE_pbvh_get_verts(const PBVH *pbvh)
{
- BLI_assert(pbvh->type == PBVH_FACES);
+ BLI_assert(pbvh->header.type == PBVH_FACES);
return pbvh->verts;
}
const float (*BKE_pbvh_get_vert_normals(const PBVH *pbvh))[3]
{
- BLI_assert(pbvh->type == PBVH_FACES);
+ BLI_assert(pbvh->header.type == PBVH_FACES);
return pbvh->vert_normals;
}
+const bool *BKE_pbvh_get_vert_hide(const PBVH *pbvh)
+{
+ BLI_assert(pbvh->header.type == PBVH_FACES);
+ return pbvh->hide_vert;
+}
+
+bool *BKE_pbvh_get_vert_hide_for_write(PBVH *pbvh)
+{
+ BLI_assert(pbvh->header.type == PBVH_FACES);
+ if (pbvh->hide_vert) {
+ return pbvh->hide_vert;
+ }
+ pbvh->hide_vert = CustomData_get_layer_named(&pbvh->mesh->vdata, CD_PROP_BOOL, ".hide_vert");
+ if (pbvh->hide_vert) {
+ return pbvh->hide_vert;
+ }
+ pbvh->hide_vert = (bool *)CustomData_add_layer_named(
+ &pbvh->mesh->vdata, CD_PROP_BOOL, CD_CALLOC, NULL, pbvh->mesh->totvert, ".hide_vert");
+ return pbvh->hide_vert;
+}
+
void BKE_pbvh_subdiv_cgg_set(PBVH *pbvh, SubdivCCG *subdiv_ccg)
{
pbvh->subdiv_ccg = subdiv_ccg;
@@ -3242,6 +3251,7 @@ void BKE_pbvh_respect_hide_set(PBVH *pbvh, bool respect_hide)
{
pbvh->respect_hide = respect_hide;
}
+
bool BKE_pbvh_is_drawing(const PBVH *pbvh)
{
return pbvh->is_drawing;
@@ -3325,3 +3335,8 @@ void BKE_pbvh_ensure_node_loops(PBVH *pbvh)
MEM_SAFE_FREE(visit);
}
+
+int BKE_pbvh_debug_draw_gen_get(PBVHNode *node)
+{
+ return node->debug_draw_gen;
+}
diff --git a/source/blender/blenkernel/intern/pbvh.cc b/source/blender/blenkernel/intern/pbvh.cc
index dec93826b9b..70aeb10f087 100644
--- a/source/blender/blenkernel/intern/pbvh.cc
+++ b/source/blender/blenkernel/intern/pbvh.cc
@@ -86,10 +86,12 @@ template<> void from_float(const float src[4], MPropCol &dst)
}
template<typename T>
-static void pbvh_vertex_color_get(const PBVH &pbvh, int vertex, float r_color[4])
+static void pbvh_vertex_color_get(const PBVH &pbvh, PBVHVertRef vertex, float r_color[4])
{
+ int index = vertex.i;
+
if (pbvh.color_domain == ATTR_DOMAIN_CORNER) {
- const MeshElemMap &melem = pbvh.pmap[vertex];
+ const MeshElemMap &melem = pbvh.pmap[index];
int count = 0;
zero_v4(r_color);
@@ -99,7 +101,7 @@ static void pbvh_vertex_color_get(const PBVH &pbvh, int vertex, float r_color[4]
Span<MLoop> loops{pbvh.mloop + mp.loopstart, mp.totloop};
for (const int i_loop : IndexRange(mp.totloop)) {
- if (loops[i_loop].v == vertex) {
+ if (loops[i_loop].v == index) {
float temp[4];
to_float(colors[i_loop], temp);
@@ -114,15 +116,17 @@ static void pbvh_vertex_color_get(const PBVH &pbvh, int vertex, float r_color[4]
}
}
else {
- to_float(static_cast<T *>(pbvh.color_layer->data)[vertex], r_color);
+ to_float(static_cast<T *>(pbvh.color_layer->data)[index], r_color);
}
}
template<typename T>
-static void pbvh_vertex_color_set(PBVH &pbvh, int vertex, const float color[4])
+static void pbvh_vertex_color_set(PBVH &pbvh, PBVHVertRef vertex, const float color[4])
{
+ int index = vertex.i;
+
if (pbvh.color_domain == ATTR_DOMAIN_CORNER) {
- const MeshElemMap &melem = pbvh.pmap[vertex];
+ const MeshElemMap &melem = pbvh.pmap[index];
for (const int i_poly : Span(melem.indices, melem.count)) {
const MPoly &mp = pbvh.mpoly[i_poly];
@@ -130,21 +134,21 @@ static void pbvh_vertex_color_set(PBVH &pbvh, int vertex, const float color[4])
Span<MLoop> loops{pbvh.mloop + mp.loopstart, mp.totloop};
for (const int i_loop : IndexRange(mp.totloop)) {
- if (loops[i_loop].v == vertex) {
+ if (loops[i_loop].v == index) {
from_float(color, colors[i_loop]);
}
}
}
}
else {
- from_float(color, static_cast<T *>(pbvh.color_layer->data)[vertex]);
+ from_float(color, static_cast<T *>(pbvh.color_layer->data)[index]);
}
}
} // namespace blender::bke
extern "C" {
-void BKE_pbvh_vertex_color_get(const PBVH *pbvh, int vertex, float r_color[4])
+void BKE_pbvh_vertex_color_get(const PBVH *pbvh, PBVHVertRef vertex, float r_color[4])
{
blender::bke::to_static_color_type(eCustomDataType(pbvh->color_layer->type), [&](auto dummy) {
using T = decltype(dummy);
@@ -152,7 +156,7 @@ void BKE_pbvh_vertex_color_get(const PBVH *pbvh, int vertex, float r_color[4])
});
}
-void BKE_pbvh_vertex_color_set(PBVH *pbvh, int vertex, const float color[4])
+void BKE_pbvh_vertex_color_set(PBVH *pbvh, PBVHVertRef vertex, const float color[4])
{
blender::bke::to_static_color_type(eCustomDataType(pbvh->color_layer->type), [&](auto dummy) {
using T = decltype(dummy);
@@ -202,7 +206,7 @@ void BKE_pbvh_store_colors_vertex(PBVH *pbvh,
blender::bke::to_static_color_type(eCustomDataType(pbvh->color_layer->type), [&](auto dummy) {
using T = decltype(dummy);
for (const int i : IndexRange(indices_num)) {
- blender::bke::pbvh_vertex_color_get<T>(*pbvh, indices[i], r_colors[i]);
+ blender::bke::pbvh_vertex_color_get<T>(*pbvh, BKE_pbvh_make_vref(indices[i]), r_colors[i]);
}
});
}
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index 112fd01c699..c4993684100 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -400,7 +400,7 @@ static bool pbvh_bmesh_node_limit_ensure(PBVH *pbvh, int node_index)
BM_elem_index_set(f, i); /* set_dirty! */
}
/* Likely this is already dirty. */
- pbvh->bm->elem_index_dirty |= BM_FACE;
+ pbvh->header.bm->elem_index_dirty |= BM_FACE;
pbvh_bmesh_node_split(pbvh, bbc_array, node_index);
@@ -484,8 +484,8 @@ static BMVert *pbvh_bmesh_vert_create(PBVH *pbvh,
BLI_assert((pbvh->totnode == 1 || node_index) && node_index <= pbvh->totnode);
/* avoid initializing customdata because its quite involved */
- BMVert *v = BM_vert_create(pbvh->bm, co, NULL, BM_CREATE_SKIP_CD);
- CustomData_bmesh_set_default(&pbvh->bm->vdata, &v->head.data);
+ BMVert *v = BM_vert_create(pbvh->header.bm, co, NULL, BM_CREATE_SKIP_CD);
+ CustomData_bmesh_set_default(&pbvh->header.bm->vdata, &v->head.data);
/* This value is logged below */
copy_v3_v3(v->no, no);
@@ -512,7 +512,7 @@ static BMFace *pbvh_bmesh_face_create(
/* ensure we never add existing face */
BLI_assert(!BM_face_exists(v_tri, 3));
- BMFace *f = BM_face_create(pbvh->bm, v_tri, e_tri, 3, f_example, BM_CREATE_NOP);
+ BMFace *f = BM_face_create(pbvh->header.bm, v_tri, e_tri, 3, f_example, BM_CREATE_NOP);
f->head.hflag = f_example->head.hflag;
BLI_gset_insert(node->bm_faces, f);
@@ -1185,22 +1185,22 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx,
v_tri[0] = v1;
v_tri[1] = v_new;
v_tri[2] = v_opp;
- bm_edges_from_tri(pbvh->bm, v_tri, e_tri);
+ bm_edges_from_tri(pbvh->header.bm, v_tri, e_tri);
f_new = pbvh_bmesh_face_create(pbvh, ni, v_tri, e_tri, f_adj);
long_edge_queue_face_add(eq_ctx, f_new);
v_tri[0] = v_new;
v_tri[1] = v2;
/* v_tri[2] = v_opp; */ /* unchanged */
- e_tri[0] = BM_edge_create(pbvh->bm, v_tri[0], v_tri[1], NULL, BM_CREATE_NO_DOUBLE);
+ e_tri[0] = BM_edge_create(pbvh->header.bm, v_tri[0], v_tri[1], NULL, BM_CREATE_NO_DOUBLE);
e_tri[2] = e_tri[1]; /* switched */
- e_tri[1] = BM_edge_create(pbvh->bm, v_tri[1], v_tri[2], NULL, BM_CREATE_NO_DOUBLE);
+ e_tri[1] = BM_edge_create(pbvh->header.bm, v_tri[1], v_tri[2], NULL, BM_CREATE_NO_DOUBLE);
f_new = pbvh_bmesh_face_create(pbvh, ni, v_tri, e_tri, f_adj);
long_edge_queue_face_add(eq_ctx, f_new);
/* Delete original */
pbvh_bmesh_face_remove(pbvh, f_adj);
- BM_face_kill(pbvh->bm, f_adj);
+ BM_face_kill(pbvh->header.bm, f_adj);
/* Ensure new vertex is in the node */
if (!BLI_gset_haskey(pbvh->nodes[ni].bm_unique_verts, v_new)) {
@@ -1217,7 +1217,7 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx,
}
}
- BM_edge_kill(pbvh->bm, e);
+ BM_edge_kill(pbvh->header.bm, e);
}
static bool pbvh_bmesh_subdivide_long_edges(EdgeQueueContext *eq_ctx,
@@ -1303,12 +1303,12 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
BMFace *f_adj = l_adj->f;
pbvh_bmesh_face_remove(pbvh, f_adj);
- BM_face_kill(pbvh->bm, f_adj);
+ BM_face_kill(pbvh->header.bm, f_adj);
}
/* Kill the edge */
BLI_assert(BM_edge_is_wire(e));
- BM_edge_kill(pbvh->bm, e);
+ BM_edge_kill(pbvh->header.bm, e);
/* For all remaining faces of v_del, create a new face that is the
* same except it uses v_conn instead of v_del */
@@ -1355,7 +1355,7 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
BMEdge *e_tri[3];
PBVHNode *n = pbvh_bmesh_node_from_face(pbvh, f);
int ni = n - pbvh->nodes;
- bm_edges_from_tri(pbvh->bm, v_tri, e_tri);
+ bm_edges_from_tri(pbvh->header.bm, v_tri, e_tri);
pbvh_bmesh_face_create(pbvh, ni, v_tri, e_tri, f);
/* Ensure that v_conn is in the new face's node */
@@ -1388,13 +1388,13 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
/* Remove the face */
pbvh_bmesh_face_remove(pbvh, f_del);
- BM_face_kill(pbvh->bm, f_del);
+ BM_face_kill(pbvh->header.bm, f_del);
/* Check if any of the face's edges are now unused by any
* face, if so delete them */
for (int j = 0; j < 3; j++) {
if (BM_edge_is_wire(e_tri[j])) {
- BM_edge_kill(pbvh->bm, e_tri[j]);
+ BM_edge_kill(pbvh->header.bm, e_tri[j]);
}
}
@@ -1410,7 +1410,7 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
v_conn = NULL;
}
BLI_ghash_insert(deleted_verts, v_tri[j], NULL);
- BM_vert_kill(pbvh->bm, v_tri[j]);
+ BM_vert_kill(pbvh->header.bm, v_tri[j]);
}
}
}
@@ -1437,7 +1437,7 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
BM_log_vert_removed(pbvh->bm_log, v_del, eq_ctx->cd_vert_mask_offset);
/* v_conn == NULL is OK */
BLI_ghash_insert(deleted_verts, v_del, v_conn);
- BM_vert_kill(pbvh->bm, v_del);
+ BM_vert_kill(pbvh->header.bm, v_del);
}
static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx,
@@ -1501,7 +1501,7 @@ bool pbvh_bmesh_node_raycast(PBVHNode *node,
struct IsectRayPrecalc *isect_precalc,
float *depth,
bool use_original,
- int *r_active_vertex_index,
+ PBVHVertRef *r_active_vertex,
float *r_face_normal)
{
bool hit = false;
@@ -1538,14 +1538,14 @@ bool pbvh_bmesh_node_raycast(PBVHNode *node,
normal_tri_v3(r_face_normal, v_tri[0]->co, v_tri[1]->co, v_tri[2]->co);
}
- if (r_active_vertex_index) {
+ if (r_active_vertex) {
float location[3] = {0.0f};
madd_v3_v3v3fl(location, ray_start, ray_normal, *depth);
for (int j = 0; j < 3; j++) {
if (len_squared_v3v3(location, v_tri[j]->co) <
len_squared_v3v3(location, nearest_vertex_co)) {
copy_v3_v3(nearest_vertex_co, v_tri[j]->co);
- *r_active_vertex_index = BM_elem_index_get(v_tri[j]);
+ r_active_vertex->i = (intptr_t)v_tri[j];
}
}
}
@@ -1872,11 +1872,11 @@ void BKE_pbvh_build_bmesh(PBVH *pbvh,
{
pbvh->cd_vert_node_offset = cd_vert_node_offset;
pbvh->cd_face_node_offset = cd_face_node_offset;
- pbvh->bm = bm;
+ pbvh->header.bm = bm;
BKE_pbvh_bmesh_detail_size_set(pbvh, 0.75);
- pbvh->type = PBVH_BMESH;
+ pbvh->header.type = PBVH_BMESH;
pbvh->bm_log = log;
/* TODO: choose leaf limit better */
@@ -1951,7 +1951,7 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
/* 2 is enough for edge faces - manifold edge */
BLI_buffer_declare_static(BMLoop *, edge_loops, BLI_BUFFER_NOP, 2);
BLI_buffer_declare_static(BMFace *, deleted_faces, BLI_BUFFER_NOP, 32);
- const int cd_vert_mask_offset = CustomData_get_offset(&pbvh->bm->vdata, CD_PAINT_MASK);
+ const int cd_vert_mask_offset = CustomData_get_offset(&pbvh->header.bm->vdata, CD_PAINT_MASK);
const int cd_vert_node_offset = pbvh->cd_vert_node_offset;
const int cd_face_node_offset = pbvh->cd_face_node_offset;
@@ -1967,7 +1967,7 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
EdgeQueueContext eq_ctx = {
&q,
queue_pool,
- pbvh->bm,
+ pbvh->header.bm,
cd_vert_mask_offset,
cd_vert_node_offset,
cd_face_node_offset,
@@ -1986,7 +1986,7 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
EdgeQueueContext eq_ctx = {
&q,
queue_pool,
- pbvh->bm,
+ pbvh->header.bm,
cd_vert_mask_offset,
cd_vert_node_offset,
cd_face_node_offset,
@@ -2126,13 +2126,13 @@ static void pbvh_bmesh_print(PBVH *pbvh)
BMIter iter;
BMFace *f;
- BM_ITER_MESH (f, &iter, pbvh->bm, BM_FACES_OF_MESH) {
+ BM_ITER_MESH (f, &iter, pbvh->header.bm, BM_FACES_OF_MESH) {
fprintf(stderr, " %d -> %d\n", BM_elem_index_get(f), pbvh_bmesh_node_index_from_face(pbvh, f));
}
fprintf(stderr, "bm_vert_to_node:\n");
BMVert *v;
- BM_ITER_MESH (v, &iter, pbvh->bm, BM_FACES_OF_MESH) {
+ BM_ITER_MESH (v, &iter, pbvh->header.bm, BM_FACES_OF_MESH) {
fprintf(stderr, " %d -> %d\n", BM_elem_index_get(v), pbvh_bmesh_node_index_from_vert(pbvh, v));
}
@@ -2171,21 +2171,21 @@ static void print_flag_factors(int flag)
static void pbvh_bmesh_verify(PBVH *pbvh)
{
/* build list of faces & verts to lookup */
- GSet *faces_all = BLI_gset_ptr_new_ex(__func__, pbvh->bm->totface);
+ GSet *faces_all = BLI_gset_ptr_new_ex(__func__, pbvh->header.bm->totface);
BMIter iter;
{
BMFace *f;
- BM_ITER_MESH (f, &iter, pbvh->bm, BM_FACES_OF_MESH) {
+ BM_ITER_MESH (f, &iter, pbvh->header.bm, BM_FACES_OF_MESH) {
BLI_assert(BM_ELEM_CD_GET_INT(f, pbvh->cd_face_node_offset) != DYNTOPO_NODE_NONE);
BLI_gset_insert(faces_all, f);
}
}
- GSet *verts_all = BLI_gset_ptr_new_ex(__func__, pbvh->bm->totvert);
+ GSet *verts_all = BLI_gset_ptr_new_ex(__func__, pbvh->header.bm->totvert);
{
BMVert *v;
- BM_ITER_MESH (v, &iter, pbvh->bm, BM_VERTS_OF_MESH) {
+ BM_ITER_MESH (v, &iter, pbvh->header.bm, BM_VERTS_OF_MESH) {
if (BM_ELEM_CD_GET_INT(v, pbvh->cd_vert_node_offset) != DYNTOPO_NODE_NONE) {
BLI_gset_insert(verts_all, v);
}
@@ -2207,7 +2207,7 @@ static void pbvh_bmesh_verify(PBVH *pbvh)
{
BMFace *f;
- BM_ITER_MESH (f, &iter, pbvh->bm, BM_FACES_OF_MESH) {
+ BM_ITER_MESH (f, &iter, pbvh->header.bm, BM_FACES_OF_MESH) {
BMIter bm_iter;
BMVert *v;
PBVHNode *n = pbvh_bmesh_node_lookup(pbvh, f);
@@ -2240,7 +2240,7 @@ static void pbvh_bmesh_verify(PBVH *pbvh)
/* Check verts */
{
BMVert *v;
- BM_ITER_MESH (v, &iter, pbvh->bm, BM_VERTS_OF_MESH) {
+ BM_ITER_MESH (v, &iter, pbvh->header.bm, BM_VERTS_OF_MESH) {
/* vertex isn't tracked */
if (BM_ELEM_CD_GET_INT(v, pbvh->cd_vert_node_offset) == DYNTOPO_NODE_NONE) {
continue;
@@ -2286,7 +2286,7 @@ static void pbvh_bmesh_verify(PBVH *pbvh)
# if 0
/* check that every vert belongs somewhere */
/* Slow */
- BM_ITER_MESH (vi, &iter, pbvh->bm, BM_VERTS_OF_MESH) {
+ BM_ITER_MESH (vi, &iter, pbvh->header.bm, BM_VERTS_OF_MESH) {
bool has_unique = false;
for (int i = 0; i < pbvh->totnode; i++) {
PBVHNode *n = &pbvh->nodes[i];
@@ -2299,7 +2299,7 @@ static void pbvh_bmesh_verify(PBVH *pbvh)
}
/* If totvert differs from number of verts inside the hash. hash-totvert is checked above. */
- BLI_assert(vert_count == pbvh->bm->totvert);
+ BLI_assert(vert_count == pbvh->header.bm->totvert);
# endif
/* Check that node elements are recorded in the top level */
diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h
index a4ac2744a73..3d67ab9ba6b 100644
--- a/source/blender/blenkernel/intern/pbvh_intern.h
+++ b/source/blender/blenkernel/intern/pbvh_intern.h
@@ -123,6 +123,11 @@ struct PBVHNode {
/* Used to store the brush color during a stroke and composite it over the original color */
PBVHColorBufferNode color_buffer;
PBVHPixelsNode pixels;
+
+ /* Used to flash colors of updated node bounding boxes in
+ * debug draw mode (when G.debug_value / bpy.app.debug_value is 889).
+ */
+ int debug_draw_gen;
};
typedef enum { PBVH_DYNTOPO_SMOOTH_SHADING = 1 } PBVHFlags;
@@ -130,7 +135,7 @@ typedef enum { PBVH_DYNTOPO_SMOOTH_SHADING = 1 } PBVHFlags;
typedef struct PBVHBMeshLog PBVHBMeshLog;
struct PBVH {
- PBVHType type;
+ struct PBVHPublic header;
PBVHFlags flags;
PBVHNode *nodes;
@@ -144,10 +149,11 @@ struct PBVH {
int leaf_limit;
/* Mesh data */
- const struct Mesh *mesh;
+ struct Mesh *mesh;
/* NOTE: Normals are not `const` because they can be updated for drawing by sculpt code. */
float (*vert_normals)[3];
+ bool *hide_vert;
struct MVert *verts;
const struct MPoly *mpoly;
const struct MLoop *mloop;
@@ -183,7 +189,6 @@ struct PBVH {
bool respect_hide;
/* Dynamic topology */
- BMesh *bm;
float bm_max_edge_len;
float bm_min_edge_len;
int cd_vert_node_offset;
@@ -265,7 +270,7 @@ bool pbvh_bmesh_node_raycast(PBVHNode *node,
struct IsectRayPrecalc *isect_precalc,
float *dist,
bool use_original,
- int *r_active_vertex_index,
+ PBVHVertRef *r_active_vertex,
float *r_face_normal);
bool pbvh_bmesh_node_nearest_to_ray(PBVHNode *node,
const float ray_start[3],
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 5d8025dce8a..ce04d781980 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -1304,7 +1304,7 @@ static int ptcache_frame_from_filename(const char *filename, const char *ext)
#define MAX_PTCACHE_PATH FILE_MAX
#define MAX_PTCACHE_FILE (FILE_MAX * 2)
-static int ptcache_path(PTCacheID *pid, char *filename)
+static int ptcache_path(PTCacheID *pid, char *dirname)
{
const char *blendfile_path = BKE_main_blendfile_path_from_global();
Library *lib = (pid->owner_id) ? pid->owner_id->lib : NULL;
@@ -1314,13 +1314,13 @@ static int ptcache_path(PTCacheID *pid, char *filename)
size_t i;
if (pid->cache->flag & PTCACHE_EXTERNAL) {
- strcpy(filename, pid->cache->path);
+ strcpy(dirname, pid->cache->path);
- if (BLI_path_is_rel(filename)) {
- BLI_path_abs(filename, blendfilename);
+ if (BLI_path_is_rel(dirname)) {
+ BLI_path_abs(dirname, blendfilename);
}
- return BLI_path_slash_ensure(filename); /* new strlen() */
+ return BLI_path_slash_ensure(dirname); /* new strlen() */
}
if ((blendfile_path[0] != '\0') || lib) {
char file[MAX_PTCACHE_PATH]; /* we don't want the dir, only the file */
@@ -1334,28 +1334,28 @@ static int ptcache_path(PTCacheID *pid, char *filename)
}
/* Add blend file name to pointcache dir. */
- BLI_snprintf(filename, MAX_PTCACHE_PATH, "//" PTCACHE_PATH "%s", file);
+ BLI_snprintf(dirname, MAX_PTCACHE_PATH, "//" PTCACHE_PATH "%s", file);
- BLI_path_abs(filename, blendfilename);
- return BLI_path_slash_ensure(filename); /* new strlen() */
+ BLI_path_abs(dirname, blendfilename);
+ return BLI_path_slash_ensure(dirname); /* new strlen() */
}
/* use the temp path. this is weak but better than not using point cache at all */
/* temporary directory is assumed to exist and ALWAYS has a trailing slash */
- BLI_snprintf(filename, MAX_PTCACHE_PATH, "%s" PTCACHE_PATH, BKE_tempdir_session());
+ BLI_snprintf(dirname, MAX_PTCACHE_PATH, "%s" PTCACHE_PATH, BKE_tempdir_session());
- return BLI_path_slash_ensure(filename); /* new strlen() */
+ return BLI_path_slash_ensure(dirname); /* new strlen() */
}
-static size_t ptcache_filename_ext_append(PTCacheID *pid,
- char *filename,
- const size_t filename_len,
+static size_t ptcache_filepath_ext_append(PTCacheID *pid,
+ char *filepath,
+ const size_t filepath_len,
const bool use_frame_number,
const int cfra)
{
- size_t len = filename_len;
+ size_t len = filepath_len;
char *filename_ext;
- filename_ext = filename + filename_len;
+ filename_ext = filepath + filepath_len;
*filename_ext = '\0';
/* PointCaches are inserted in object's list on demand, we need a valid index now. */
@@ -1399,14 +1399,14 @@ static size_t ptcache_filename_ext_append(PTCacheID *pid,
return len;
}
-static int ptcache_filename(
- PTCacheID *pid, char *filename, int cfra, const bool do_path, const bool do_ext)
+static int ptcache_filepath(
+ PTCacheID *pid, char *filepath, int cfra, const bool do_path, const bool do_ext)
{
int len = 0;
char *idname;
char *newname;
- filename[0] = '\0';
- newname = filename;
+ filepath[0] = '\0';
+ newname = filepath;
if ((pid->cache->flag & PTCACHE_EXTERNAL) == 0) {
const char *blendfile_path = BKE_main_blendfile_path_from_global();
@@ -1417,7 +1417,7 @@ static int ptcache_filename(
/* start with temp dir */
if (do_path) {
- len = ptcache_path(pid, filename);
+ len = ptcache_path(pid, filepath);
newname += len;
}
if (pid->cache->name[0] == '\0' && (pid->cache->flag & PTCACHE_EXTERNAL) == 0) {
@@ -1437,7 +1437,7 @@ static int ptcache_filename(
}
if (do_ext) {
- len += ptcache_filename_ext_append(pid, filename, (size_t)len, true, cfra);
+ len += ptcache_filepath_ext_append(pid, filepath, (size_t)len, true, cfra);
}
return len; /* make sure the above string is always 16 chars */
@@ -1465,7 +1465,7 @@ static PTCacheFile *ptcache_file_open(PTCacheID *pid, int mode, int cfra)
}
}
- ptcache_filename(pid, filepath, cfra, true, true);
+ ptcache_filepath(pid, filepath, cfra, true, true);
if (mode == PTCACHE_FILE_READ) {
fp = BLI_fopen(filepath, "rb");
@@ -2596,7 +2596,7 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, unsigned int cfra)
DIR *dir;
struct dirent *de;
char path[MAX_PTCACHE_PATH];
- char filename[MAX_PTCACHE_FILE];
+ char filepath[MAX_PTCACHE_FILE];
char path_full[MAX_PTCACHE_FILE];
char ext[MAX_PTCACHE_PATH];
@@ -2631,20 +2631,20 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, unsigned int cfra)
return;
}
- len = ptcache_filename(pid, filename, cfra, false, false); /* no path */
+ len = ptcache_filepath(pid, filepath, cfra, false, false); /* no path */
/* append underscore terminator to ensure we don't match similar names
* from objects whose names start with the same prefix
*/
- if (len < sizeof(filename) - 2) {
- BLI_strncpy(filename + len, "_", sizeof(filename) - 2 - len);
+ if (len < sizeof(filepath) - 2) {
+ BLI_strncpy(filepath + len, "_", sizeof(filepath) - 2 - len);
len += 1;
}
- ptcache_filename_ext_append(pid, ext, 0, false, 0);
+ ptcache_filepath_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 (STREQLEN(filepath, 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);
@@ -2713,8 +2713,8 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, unsigned int cfra)
case PTCACHE_CLEAR_FRAME:
if (pid->cache->flag & PTCACHE_DISK_CACHE) {
if (BKE_ptcache_id_exist(pid, cfra)) {
- ptcache_filename(pid, filename, cfra, true, true); /* no path */
- BLI_delete(filename, false, false);
+ ptcache_filepath(pid, filepath, cfra, true, true); /* no path */
+ BLI_delete(filepath, false, false);
}
}
else {
@@ -2752,11 +2752,11 @@ bool BKE_ptcache_id_exist(PTCacheID *pid, int cfra)
}
if (pid->cache->flag & PTCACHE_DISK_CACHE) {
- char filename[MAX_PTCACHE_FILE];
+ char filepath[MAX_PTCACHE_FILE];
- ptcache_filename(pid, filename, cfra, true, true);
+ ptcache_filepath(pid, filepath, cfra, true, true);
- return BLI_exists(filename);
+ return BLI_exists(filepath);
}
PTCacheMem *pm = pid->cache->mem_cache.first;
@@ -2824,24 +2824,24 @@ void BKE_ptcache_id_time(
DIR *dir;
struct dirent *de;
char path[MAX_PTCACHE_PATH];
- char filename[MAX_PTCACHE_FILE];
+ char filepath[MAX_PTCACHE_FILE];
char ext[MAX_PTCACHE_PATH];
unsigned int len; /* store the length of the string */
ptcache_path(pid, path);
- len = ptcache_filename(pid, filename, (int)cfra, 0, 0); /* no path */
+ len = ptcache_filepath(pid, filepath, (int)cfra, 0, 0); /* no path */
dir = opendir(path);
if (dir == NULL) {
return;
}
- ptcache_filename_ext_append(pid, ext, 0, false, 0);
+ ptcache_filepath_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 (STREQLEN(filepath, 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);
@@ -3494,7 +3494,7 @@ void BKE_ptcache_disk_cache_rename(PTCacheID *pid, const char *name_src, const c
DIR *dir;
struct dirent *de;
char path[MAX_PTCACHE_PATH];
- char old_filename[MAX_PTCACHE_FILE];
+ char old_filepath[MAX_PTCACHE_FILE];
char new_path_full[MAX_PTCACHE_FILE];
char old_path_full[MAX_PTCACHE_FILE];
char ext[MAX_PTCACHE_PATH];
@@ -3510,7 +3510,7 @@ void BKE_ptcache_disk_cache_rename(PTCacheID *pid, const char *name_src, const c
/* get "from" filename */
BLI_strncpy(pid->cache->name, name_src, sizeof(pid->cache->name));
- len = ptcache_filename(pid, old_filename, 0, false, false); /* no path */
+ len = ptcache_filepath(pid, old_filepath, 0, false, false); /* no path */
ptcache_path(pid, path);
dir = opendir(path);
@@ -3519,20 +3519,20 @@ void BKE_ptcache_disk_cache_rename(PTCacheID *pid, const char *name_src, const c
return;
}
- ptcache_filename_ext_append(pid, ext, 0, false, 0);
+ ptcache_filepath_ext_append(pid, ext, 0, false, 0);
/* put new name into cache */
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 (STREQLEN(old_filepath, 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);
if (frame != -1) {
BLI_join_dirfile(old_path_full, sizeof(old_path_full), path, de->d_name);
- ptcache_filename(pid, new_path_full, frame, true, true);
+ ptcache_filepath(pid, new_path_full, frame, true, true);
BLI_rename(old_path_full, new_path_full);
}
}
@@ -3556,7 +3556,7 @@ void BKE_ptcache_load_external(PTCacheID *pid)
DIR *dir;
struct dirent *de;
char path[MAX_PTCACHE_PATH];
- char filename[MAX_PTCACHE_FILE];
+ char filepath[MAX_PTCACHE_FILE];
char ext[MAX_PTCACHE_PATH];
if (!cache) {
@@ -3565,7 +3565,7 @@ void BKE_ptcache_load_external(PTCacheID *pid)
ptcache_path(pid, path);
- len = ptcache_filename(pid, filename, 1, false, false); /* no path */
+ len = ptcache_filepath(pid, filepath, 1, false, false); /* no path */
dir = opendir(path);
if (dir == NULL) {
@@ -3583,7 +3583,7 @@ 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 (STREQLEN(filepath, 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/scene.cc b/source/blender/blenkernel/intern/scene.cc
index aaa6baac1ff..0445db5aed0 100644
--- a/source/blender/blenkernel/intern/scene.cc
+++ b/source/blender/blenkernel/intern/scene.cc
@@ -2501,7 +2501,7 @@ static bool check_rendered_viewport_visible(Main *bmain)
return false;
}
-/* TODO(campbell): shouldn't we be able to use 'DEG_get_view_layer' here?
+/* TODO(@campbellbarton): shouldn't we be able to use 'DEG_get_view_layer' here?
* Currently this is nullptr on load, so don't. */
static void prepare_mesh_for_viewport_render(Main *bmain, const ViewLayer *view_layer)
{
@@ -2591,7 +2591,7 @@ static void scene_graph_update_tagged(Depsgraph *depsgraph, Main *bmain, bool on
// DEG_debug_graph_relations_validate(depsgraph, bmain, scene);
/* Flush editing data if needed. */
prepare_mesh_for_viewport_render(bmain, view_layer);
- /* Update all objects: drivers, matrices, #DispList, etc. flags set
+ /* Update all objects: drivers, matrices, etc. flags set
* by depsgraph or manual, no layer check here, gets correct flushed. */
DEG_evaluate_on_refresh(depsgraph);
/* Update sound system. */
@@ -2666,7 +2666,7 @@ void BKE_scene_graph_update_for_newframe_ex(Depsgraph *depsgraph, const bool cle
BKE_image_editors_update_frame(bmain, scene->r.cfra);
BKE_sound_set_cfra(scene->r.cfra);
DEG_graph_relations_update(depsgraph);
- /* Update all objects: drivers, matrices, #DispList, etc. flags set
+ /* Update all objects: drivers, matrices, etc. flags set
* by depsgraph or manual, no layer check here, gets correct flushed.
*
* NOTE: Only update for new frame on first iteration. Second iteration is for ensuring user
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index c16e5ce5655..f1eba64e401 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -148,7 +148,6 @@ void BKE_screen_foreach_id_screen_area(LibraryForeachIDData *data, ScrArea *area
}
case SPACE_OUTLINER: {
SpaceOutliner *space_outliner = (SpaceOutliner *)sl;
- BKE_LIB_FOREACHID_PROCESS_ID(data, space_outliner->search_tse.id, IDWALK_CB_NOP);
if (space_outliner->treestore != NULL) {
TreeStoreElem *tselem;
BLI_mempool_iter iter;
@@ -1124,40 +1123,50 @@ static void write_uilist(BlendWriter *writer, uiList *ui_list)
}
}
-static void write_space_outliner(BlendWriter *writer, SpaceOutliner *space_outliner)
+static void write_space_outliner(BlendWriter *writer, const SpaceOutliner *space_outliner)
{
BLI_mempool *ts = space_outliner->treestore;
if (ts) {
- SpaceOutliner space_outliner_flat = *space_outliner;
-
- int elems = BLI_mempool_len(ts);
+ const int elems = BLI_mempool_len(ts);
/* linearize mempool to array */
TreeStoreElem *data = elems ? BLI_mempool_as_arrayN(ts, "TreeStoreElem") : NULL;
if (data) {
- /* In this block we use the memory location of the treestore
- * but _not_ its data, the addresses in this case are UUID's,
- * since we can't rely on malloc giving us different values each time.
+ BLO_write_struct(writer, SpaceOutliner, space_outliner);
+
+ /* To store #TreeStore (instead of the mempool), two unique memory addresses are needed,
+ * which can be used to identify the data on read:
+ * 1) One for the #TreeStore data itself.
+ * 2) One for the array of #TreeStoreElem's inside #TreeStore (#TreeStore.data).
+ *
+ * For 1) we just use the mempool's address (#SpaceOutliner::treestore).
+ * For 2) we don't have such a direct choice. We can't just use the array's address from
+ * above, since that may not be unique over all Outliners. So instead use an address relative
+ * to 1).
*/
- TreeStore ts_flat = {0};
+ /* TODO the mempool could be moved to #SpaceOutliner_Runtime so that #SpaceOutliner could
+ * hold the #TreeStore directly. */
- /* we know the treestore is at least as big as a pointer,
- * so offsetting works to give us a UUID. */
+ /* Address relative to the tree-store, as noted above. */
void *data_addr = (void *)POINTER_OFFSET(ts, sizeof(void *));
+ /* There should be plenty of memory addresses within the mempool data that we can point into,
+ * just double-check we don't potentially end up with a memory address that another DNA
+ * struct might use. Assumes BLI_mempool uses the guarded allocator. */
+ BLI_assert(MEM_allocN_len(ts) >= sizeof(void *) * 2);
+ TreeStore ts_flat = {0};
ts_flat.usedelem = elems;
ts_flat.totelem = elems;
ts_flat.data = data_addr;
- BLO_write_struct(writer, SpaceOutliner, space_outliner);
-
BLO_write_struct_at_address(writer, TreeStore, ts, &ts_flat);
BLO_write_struct_array_at_address(writer, TreeStoreElem, elems, data_addr, data);
MEM_freeN(data);
}
else {
+ SpaceOutliner space_outliner_flat = *space_outliner;
space_outliner_flat.treestore = NULL;
BLO_write_struct_at_address(writer, SpaceOutliner, space_outliner, &space_outliner_flat);
}
@@ -1873,7 +1882,6 @@ void BKE_screen_area_blend_read_lib(BlendLibReader *reader, ID *parent_id, ScrAr
}
case SPACE_OUTLINER: {
SpaceOutliner *space_outliner = (SpaceOutliner *)sl;
- BLO_read_id_address(reader, NULL, &space_outliner->search_tse.id);
if (space_outliner->treestore) {
TreeStoreElem *tselem;
diff --git a/source/blender/blenkernel/intern/shader_fx.c b/source/blender/blenkernel/intern/shader_fx.c
index 51ebd232978..745bd2a97e6 100644
--- a/source/blender/blenkernel/intern/shader_fx.c
+++ b/source/blender/blenkernel/intern/shader_fx.c
@@ -70,7 +70,8 @@ ShaderFxData *BKE_shaderfx_new(int type)
fx->type = type;
fx->mode = eShaderFxMode_Realtime | eShaderFxMode_Render;
fx->flag = eShaderFxFlag_OverrideLibrary_Local;
- fx->ui_expand_flag = 1; /* Expand only the parent panel by default. */
+ /* Expand only the parent panel by default. */
+ fx->ui_expand_flag = UI_PANEL_DATA_EXPAND_ROOT;
if (fxi->flags & eShaderFxTypeFlag_EnableInEditmode) {
fx->mode |= eShaderFxMode_Editmode;
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index f459b5a82ac..bb0e7a4dd6b 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -756,7 +756,7 @@ void BKE_sound_remove_scene_sound(Scene *scene, void *handle)
AUD_Sequence_remove(scene->sound_scene, handle);
}
-void BKE_sound_mute_scene_sound(void *handle, char mute)
+void BKE_sound_mute_scene_sound(void *handle, bool mute)
{
AUD_SequenceEntry_setMuted(handle, mute);
}
@@ -1346,7 +1346,7 @@ void *BKE_sound_add_scene_sound_defaults(Scene *UNUSED(scene), Sequence *UNUSED(
void BKE_sound_remove_scene_sound(Scene *UNUSED(scene), void *UNUSED(handle))
{
}
-void BKE_sound_mute_scene_sound(void *UNUSED(handle), char UNUSED(mute))
+void BKE_sound_mute_scene_sound(void *UNUSED(handle), bool UNUSED(mute))
{
}
void BKE_sound_move_scene_sound(const Scene *UNUSED(scene),
diff --git a/source/blender/blenkernel/intern/subdiv_converter_mesh.c b/source/blender/blenkernel/intern/subdiv_converter_mesh.c
index 12a5f00a68b..9c6d507d42c 100644
--- a/source/blender/blenkernel/intern/subdiv_converter_mesh.c
+++ b/source/blender/blenkernel/intern/subdiv_converter_mesh.c
@@ -205,7 +205,15 @@ static void precalc_uv_layer(const OpenSubdiv_Converter *converter, const int la
mesh->totloop, sizeof(int), "loop uv vertex index");
}
UvVertMap *uv_vert_map = BKE_mesh_uv_vert_map_create(
- mpoly, mloop, mloopuv, num_poly, num_vert, limit, false, true);
+ mpoly,
+ (const bool *)CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, ".hide_poly"),
+ mloop,
+ mloopuv,
+ num_poly,
+ num_vert,
+ limit,
+ false,
+ true);
/* NOTE: First UV vertex is supposed to be always marked as separate. */
storage->num_uv_coordinates = -1;
for (int vertex_index = 0; vertex_index < num_vert; vertex_index++) {
diff --git a/source/blender/blenkernel/intern/subdiv_mesh.c b/source/blender/blenkernel/intern/subdiv_mesh.cc
index 433bad34479..e026a013498 100644
--- a/source/blender/blenkernel/intern/subdiv_mesh.c
+++ b/source/blender/blenkernel/intern/subdiv_mesh.cc
@@ -11,7 +11,7 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
-#include "BLI_alloca.h"
+#include "BLI_array.hh"
#include "BLI_bitmap.h"
#include "BLI_math_vector.h"
@@ -29,7 +29,7 @@
/** \name Subdivision Context
* \{ */
-typedef struct SubdivMeshContext {
+struct SubdivMeshContext {
const SubdivToMeshSettings *settings;
const Mesh *coarse_mesh;
Subdiv *subdiv;
@@ -48,15 +48,15 @@ typedef struct SubdivMeshContext {
/* Per-subdivided vertex counter of averaged values. */
int *accumulated_counters;
bool have_displacement;
-} SubdivMeshContext;
+};
static void subdiv_mesh_ctx_cache_uv_layers(SubdivMeshContext *ctx)
{
Mesh *subdiv_mesh = ctx->subdiv_mesh;
ctx->num_uv_layers = CustomData_number_of_layers(&subdiv_mesh->ldata, CD_MLOOPUV);
for (int layer_index = 0; layer_index < ctx->num_uv_layers; layer_index++) {
- ctx->uv_layers[layer_index] = CustomData_get_layer_n(
- &subdiv_mesh->ldata, CD_MLOOPUV, layer_index);
+ ctx->uv_layers[layer_index] = static_cast<MLoopUV *>(
+ CustomData_get_layer_n(&subdiv_mesh->ldata, CD_MLOOPUV, layer_index));
}
}
@@ -64,15 +64,20 @@ static void subdiv_mesh_ctx_cache_custom_data_layers(SubdivMeshContext *ctx)
{
Mesh *subdiv_mesh = ctx->subdiv_mesh;
/* Pointers to original indices layers. */
- ctx->vert_origindex = CustomData_get_layer(&subdiv_mesh->vdata, CD_ORIGINDEX);
- ctx->edge_origindex = CustomData_get_layer(&subdiv_mesh->edata, CD_ORIGINDEX);
- ctx->loop_origindex = CustomData_get_layer(&subdiv_mesh->ldata, CD_ORIGINDEX);
- ctx->poly_origindex = CustomData_get_layer(&subdiv_mesh->pdata, CD_ORIGINDEX);
+ ctx->vert_origindex = static_cast<int *>(
+ CustomData_get_layer(&subdiv_mesh->vdata, CD_ORIGINDEX));
+ ctx->edge_origindex = static_cast<int *>(
+ CustomData_get_layer(&subdiv_mesh->edata, CD_ORIGINDEX));
+ ctx->loop_origindex = static_cast<int *>(
+ CustomData_get_layer(&subdiv_mesh->ldata, CD_ORIGINDEX));
+ ctx->poly_origindex = static_cast<int *>(
+ CustomData_get_layer(&subdiv_mesh->pdata, CD_ORIGINDEX));
/* UV layers interpolation. */
subdiv_mesh_ctx_cache_uv_layers(ctx);
/* Orco interpolation. */
- ctx->orco = CustomData_get_layer(&subdiv_mesh->vdata, CD_ORCO);
- ctx->cloth_orco = CustomData_get_layer(&subdiv_mesh->vdata, CD_CLOTH_ORCO);
+ ctx->orco = static_cast<float(*)[3]>(CustomData_get_layer(&subdiv_mesh->vdata, CD_ORCO));
+ ctx->cloth_orco = static_cast<float(*)[3]>(
+ CustomData_get_layer(&subdiv_mesh->vdata, CD_CLOTH_ORCO));
}
static void subdiv_mesh_prepare_accumulator(SubdivMeshContext *ctx, int num_vertices)
@@ -80,8 +85,8 @@ static void subdiv_mesh_prepare_accumulator(SubdivMeshContext *ctx, int num_vert
if (!ctx->have_displacement) {
return;
}
- ctx->accumulated_counters = MEM_calloc_arrayN(
- num_vertices, sizeof(*ctx->accumulated_counters), "subdiv accumulated counters");
+ ctx->accumulated_counters = static_cast<int *>(
+ MEM_calloc_arrayN(num_vertices, sizeof(*ctx->accumulated_counters), __func__));
}
static void subdiv_mesh_context_free(SubdivMeshContext *ctx)
@@ -95,7 +100,7 @@ static void subdiv_mesh_context_free(SubdivMeshContext *ctx)
/** \name Loop custom data copy helpers
* \{ */
-typedef struct LoopsOfPtex {
+struct LoopsOfPtex {
/* First loop of the ptex, starts at ptex (0, 0) and goes in u direction. */
const MLoop *first_loop;
/* Last loop of the ptex, starts at ptex (0, 0) and goes in v direction. */
@@ -103,7 +108,7 @@ typedef struct LoopsOfPtex {
/* For quad coarse faces only. */
const MLoop *second_loop;
const MLoop *third_loop;
-} LoopsOfPtex;
+};
static void loops_of_ptex_get(const SubdivMeshContext *ctx,
LoopsOfPtex *loops_of_ptex,
@@ -126,8 +131,8 @@ static void loops_of_ptex_get(const SubdivMeshContext *ctx,
loops_of_ptex->third_loop = loops_of_ptex->first_loop + 2;
}
else {
- loops_of_ptex->second_loop = NULL;
- loops_of_ptex->third_loop = NULL;
+ loops_of_ptex->second_loop = nullptr;
+ loops_of_ptex->third_loop = nullptr;
}
}
@@ -140,7 +145,7 @@ static void loops_of_ptex_get(const SubdivMeshContext *ctx,
/* TODO(sergey): Somehow de-duplicate with loops storage, without too much
* exception cases all over the code. */
-typedef struct VerticesForInterpolation {
+struct VerticesForInterpolation {
/* This field points to a vertex data which is to be used for interpolation.
* The idea is to avoid unnecessary allocations for regular faces, where
* we can simply use corner vertices. */
@@ -159,7 +164,7 @@ typedef struct VerticesForInterpolation {
/* Indices within vertex_data to interpolate for. The indices are aligned
* with uv coordinates in a similar way as indices in loop_data_storage. */
int vertex_indices[4];
-} VerticesForInterpolation;
+};
static void vertex_interpolation_init(const SubdivMeshContext *ctx,
VerticesForInterpolation *vertex_interpolation,
@@ -192,17 +197,17 @@ static void vertex_interpolation_init(const SubdivMeshContext *ctx,
/* Interpolate center of poly right away, it stays unchanged for all
* ptex faces. */
const float weight = 1.0f / (float)coarse_poly->totloop;
- float *weights = BLI_array_alloca(weights, coarse_poly->totloop);
- int *indices = BLI_array_alloca(indices, coarse_poly->totloop);
+ blender::Array<float, 32> weights(coarse_poly->totloop);
+ blender::Array<int, 32> indices(coarse_poly->totloop);
for (int i = 0; i < coarse_poly->totloop; i++) {
weights[i] = weight;
indices[i] = coarse_mloop[coarse_poly->loopstart + i].v;
}
CustomData_interp(&coarse_mesh->vdata,
&vertex_interpolation->vertex_data_storage,
- indices,
- weights,
- NULL,
+ indices.data(),
+ weights.data(),
+ nullptr,
coarse_poly->totloop,
2);
}
@@ -237,26 +242,27 @@ static void vertex_interpolation_from_corner(const SubdivMeshContext *ctx,
const int first_loop_index = loops_of_ptex.first_loop - coarse_mloop;
const int last_loop_index = loops_of_ptex.last_loop - coarse_mloop;
const int first_indices[2] = {
- coarse_mloop[first_loop_index].v,
- coarse_mloop[coarse_poly->loopstart +
- (first_loop_index - coarse_poly->loopstart + 1) % coarse_poly->totloop]
- .v};
+ static_cast<int>(coarse_mloop[first_loop_index].v),
+ static_cast<int>(
+ coarse_mloop[coarse_poly->loopstart +
+ (first_loop_index - coarse_poly->loopstart + 1) % coarse_poly->totloop]
+ .v)};
const int last_indices[2] = {
- coarse_mloop[first_loop_index].v,
- coarse_mloop[last_loop_index].v,
+ static_cast<int>(coarse_mloop[first_loop_index].v),
+ static_cast<int>(coarse_mloop[last_loop_index].v),
};
CustomData_interp(vertex_data,
&vertex_interpolation->vertex_data_storage,
first_indices,
weights,
- NULL,
+ nullptr,
2,
1);
CustomData_interp(vertex_data,
&vertex_interpolation->vertex_data_storage,
last_indices,
weights,
- NULL,
+ nullptr,
2,
3);
}
@@ -275,7 +281,7 @@ static void vertex_interpolation_end(VerticesForInterpolation *vertex_interpolat
/** \name Loop custom data interpolation helpers
* \{ */
-typedef struct LoopsForInterpolation {
+struct LoopsForInterpolation {
/* This field points to a loop data which is to be used for interpolation.
* The idea is to avoid unnecessary allocations for regular faces, where
* we can simply interpolate corner vertices. */
@@ -291,10 +297,10 @@ typedef struct LoopsForInterpolation {
* Is allocated for non-regular faces (triangles and n-gons). */
CustomData loop_data_storage;
bool loop_data_storage_allocated;
- /* Infices within loop_data to interpolate for. The indices are aligned with
+ /* Indices within loop_data to interpolate for. The indices are aligned with
* uv coordinates in a similar way as indices in loop_data_storage. */
int loop_indices[4];
-} LoopsForInterpolation;
+};
static void loop_interpolation_init(const SubdivMeshContext *ctx,
LoopsForInterpolation *loop_interpolation,
@@ -326,17 +332,17 @@ static void loop_interpolation_init(const SubdivMeshContext *ctx,
/* Interpolate center of poly right away, it stays unchanged for all
* ptex faces. */
const float weight = 1.0f / (float)coarse_poly->totloop;
- float *weights = BLI_array_alloca(weights, coarse_poly->totloop);
- int *indices = BLI_array_alloca(indices, coarse_poly->totloop);
+ blender::Array<float, 32> weights(coarse_poly->totloop);
+ blender::Array<int, 32> indices(coarse_poly->totloop);
for (int i = 0; i < coarse_poly->totloop; i++) {
weights[i] = weight;
indices[i] = coarse_poly->loopstart + i;
}
CustomData_interp(&coarse_mesh->ldata,
&loop_interpolation->loop_data_storage,
- indices,
- weights,
- NULL,
+ indices.data(),
+ weights.data(),
+ nullptr,
coarse_poly->totloop,
2);
}
@@ -372,13 +378,13 @@ static void loop_interpolation_from_corner(const SubdivMeshContext *ctx,
(first_loop_index - base_loop_index + 1) % coarse_poly->totloop;
const int first_indices[2] = {first_loop_index, second_loop_index};
const int last_indices[2] = {
- loops_of_ptex.last_loop - coarse_mloop,
- loops_of_ptex.first_loop - coarse_mloop,
+ static_cast<int>(loops_of_ptex.last_loop - coarse_mloop),
+ static_cast<int>(loops_of_ptex.first_loop - coarse_mloop),
};
CustomData_interp(
- loop_data, &loop_interpolation->loop_data_storage, first_indices, weights, NULL, 2, 1);
+ loop_data, &loop_interpolation->loop_data_storage, first_indices, weights, nullptr, 2, 1);
CustomData_interp(
- loop_data, &loop_interpolation->loop_data_storage, last_indices, weights, NULL, 2, 3);
+ loop_data, &loop_interpolation->loop_data_storage, last_indices, weights, nullptr, 2, 3);
}
}
@@ -395,7 +401,7 @@ static void loop_interpolation_end(LoopsForInterpolation *loop_interpolation)
/** \name TLS
* \{ */
-typedef struct SubdivMeshTLS {
+struct SubdivMeshTLS {
bool vertex_interpolation_initialized;
VerticesForInterpolation vertex_interpolation;
const MPoly *vertex_interpolation_coarse_poly;
@@ -405,11 +411,11 @@ typedef struct SubdivMeshTLS {
LoopsForInterpolation loop_interpolation;
const MPoly *loop_interpolation_coarse_poly;
int loop_interpolation_coarse_corner;
-} SubdivMeshTLS;
+};
static void subdiv_mesh_tls_free(void *tls_v)
{
- SubdivMeshTLS *tls = tls_v;
+ SubdivMeshTLS *tls = static_cast<SubdivMeshTLS *>(tls_v);
if (tls->vertex_interpolation_initialized) {
vertex_interpolation_end(&tls->vertex_interpolation);
}
@@ -492,7 +498,7 @@ static bool subdiv_mesh_topology_info(const SubdivForeachContext *foreach_contex
CustomData_MeshMasks mask = CD_MASK_EVERYTHING;
mask.lmask &= ~CD_MASK_MULTIRES_GRIDS;
- SubdivMeshContext *subdiv_context = foreach_context->user_data;
+ SubdivMeshContext *subdiv_context = static_cast<SubdivMeshContext *>(foreach_context->user_data);
subdiv_context->subdiv_mesh = BKE_mesh_new_nomain_from_template_ex(
subdiv_context->coarse_mesh, num_vertices, num_edges, 0, num_loops, num_polygons, mask);
subdiv_mesh_ctx_cache_custom_data_layers(subdiv_context);
@@ -533,10 +539,10 @@ static void subdiv_vertex_data_interpolate(const SubdivMeshContext *ctx,
&ctx->subdiv_mesh->vdata,
vertex_interpolation->vertex_indices,
weights,
- NULL,
+ nullptr,
4,
subdiv_vertex_index);
- if (ctx->vert_origindex != NULL) {
+ if (ctx->vert_origindex != nullptr) {
ctx->vert_origindex[subdiv_vertex_index] = ORIGINDEX_NONE;
}
}
@@ -564,7 +570,7 @@ static void evaluate_vertex_and_apply_displacement_copy(const SubdivMeshContext
add_v3_v3(subdiv_vert->co, D);
/* Evaluate undeformed texture coordinate. */
subdiv_vertex_orco_evaluate(ctx, ptex_face_index, u, v, subdiv_vertex_index);
- /* Remove facedot flag. This can happen if there is more than one subsurf modifier. */
+ /* Remove face-dot flag. This can happen if there is more than one subsurf modifier. */
BLI_BITMAP_DISABLE(ctx->subdiv_mesh->runtime.subsurf_face_dot_tags, subdiv_vertex_index);
}
@@ -602,7 +608,7 @@ static void subdiv_mesh_vertex_displacement_every_corner_or_edge(
const float v,
const int subdiv_vertex_index)
{
- SubdivMeshContext *ctx = foreach_context->user_data;
+ SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
Mesh *subdiv_mesh = ctx->subdiv_mesh;
MVert *subdiv_mvert = subdiv_mesh->mvert;
MVert *subdiv_vert = &subdiv_mvert[subdiv_vertex_index];
@@ -649,7 +655,7 @@ static void subdiv_mesh_vertex_corner(const SubdivForeachContext *foreach_contex
const int subdiv_vertex_index)
{
BLI_assert(coarse_vertex_index != ORIGINDEX_NONE);
- SubdivMeshContext *ctx = foreach_context->user_data;
+ SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MVert *coarse_mvert = coarse_mesh->mvert;
Mesh *subdiv_mesh = ctx->subdiv_mesh;
@@ -698,8 +704,8 @@ static void subdiv_mesh_vertex_edge(const SubdivForeachContext *foreach_context,
const int coarse_corner,
const int subdiv_vertex_index)
{
- SubdivMeshContext *ctx = foreach_context->user_data;
- SubdivMeshTLS *tls = tls_v;
+ SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
+ SubdivMeshTLS *tls = static_cast<SubdivMeshTLS *>(tls_v);
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MPoly *coarse_mpoly = coarse_mesh->mpoly;
const MPoly *coarse_poly = &coarse_mpoly[coarse_poly_index];
@@ -746,8 +752,8 @@ static void subdiv_mesh_vertex_inner(const SubdivForeachContext *foreach_context
const int coarse_corner,
const int subdiv_vertex_index)
{
- SubdivMeshContext *ctx = foreach_context->user_data;
- SubdivMeshTLS *tls = tls_v;
+ SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
+ SubdivMeshTLS *tls = static_cast<SubdivMeshTLS *>(tls_v);
Subdiv *subdiv = ctx->subdiv;
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MPoly *coarse_mpoly = coarse_mesh->mpoly;
@@ -773,14 +779,14 @@ static void subdiv_copy_edge_data(SubdivMeshContext *ctx,
const MEdge *coarse_edge)
{
const int subdiv_edge_index = subdiv_edge - ctx->subdiv_mesh->medge;
- if (coarse_edge == NULL) {
+ if (coarse_edge == nullptr) {
subdiv_edge->crease = 0;
subdiv_edge->bweight = 0;
subdiv_edge->flag = 0;
if (!ctx->settings->use_optimal_display) {
subdiv_edge->flag |= ME_EDGERENDER;
}
- if (ctx->edge_origindex != NULL) {
+ if (ctx->edge_origindex != nullptr) {
ctx->edge_origindex[subdiv_edge_index] = ORIGINDEX_NONE;
}
return;
@@ -799,11 +805,11 @@ static void subdiv_mesh_edge(const SubdivForeachContext *foreach_context,
const int subdiv_v1,
const int subdiv_v2)
{
- SubdivMeshContext *ctx = foreach_context->user_data;
+ SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
Mesh *subdiv_mesh = ctx->subdiv_mesh;
MEdge *subdiv_medge = subdiv_mesh->medge;
MEdge *subdiv_edge = &subdiv_medge[subdiv_edge_index];
- const MEdge *coarse_edge = NULL;
+ const MEdge *coarse_edge = nullptr;
if (coarse_edge_index != ORIGINDEX_NONE) {
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MEdge *coarse_medge = coarse_mesh->medge;
@@ -832,7 +838,7 @@ static void subdiv_interpolate_loop_data(const SubdivMeshContext *ctx,
&ctx->subdiv_mesh->ldata,
loop_interpolation->loop_indices,
weights,
- NULL,
+ nullptr,
4,
subdiv_loop_index);
/* TODO(sergey): Set ORIGINDEX. */
@@ -895,8 +901,8 @@ static void subdiv_mesh_loop(const SubdivForeachContext *foreach_context,
const int subdiv_vertex_index,
const int subdiv_edge_index)
{
- SubdivMeshContext *ctx = foreach_context->user_data;
- SubdivMeshTLS *tls = tls_v;
+ SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
+ SubdivMeshTLS *tls = static_cast<SubdivMeshTLS *>(tls_v);
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MPoly *coarse_mpoly = coarse_mesh->mpoly;
const MPoly *coarse_poly = &coarse_mpoly[coarse_poly_index];
@@ -934,7 +940,7 @@ static void subdiv_mesh_poly(const SubdivForeachContext *foreach_context,
const int num_loops)
{
BLI_assert(coarse_poly_index != ORIGINDEX_NONE);
- SubdivMeshContext *ctx = foreach_context->user_data;
+ SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MPoly *coarse_mpoly = coarse_mesh->mpoly;
const MPoly *coarse_poly = &coarse_mpoly[coarse_poly_index];
@@ -957,7 +963,7 @@ static void subdiv_mesh_vertex_loose(const SubdivForeachContext *foreach_context
const int coarse_vertex_index,
const int subdiv_vertex_index)
{
- SubdivMeshContext *ctx = foreach_context->user_data;
+ SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MVert *coarse_mvert = coarse_mesh->mvert;
const MVert *coarse_vertex = &coarse_mvert[coarse_vertex_index];
@@ -975,8 +981,8 @@ static void find_edge_neighbors(const Mesh *coarse_mesh,
const MEdge *neighbors[2])
{
const MEdge *coarse_medge = coarse_mesh->medge;
- neighbors[0] = NULL;
- neighbors[1] = NULL;
+ neighbors[0] = nullptr;
+ neighbors[1] = nullptr;
int neighbor_counters[2] = {0, 0};
for (int edge_index = 0; edge_index < coarse_mesh->totedge; edge_index++) {
const MEdge *current_edge = &coarse_medge[edge_index];
@@ -996,10 +1002,10 @@ static void find_edge_neighbors(const Mesh *coarse_mesh,
* sharp. This is also how topology factory treats vertices of a surface
* which are adjacent to a loose edge. */
if (neighbor_counters[0] > 1) {
- neighbors[0] = NULL;
+ neighbors[0] = nullptr;
}
if (neighbor_counters[1] > 1) {
- neighbors[1] = NULL;
+ neighbors[1] = nullptr;
}
}
@@ -1013,7 +1019,7 @@ static void points_for_loose_edges_interpolation_get(const Mesh *coarse_mesh,
copy_v3_v3(points_r[1], coarse_mvert[coarse_edge->v1].co);
copy_v3_v3(points_r[2], coarse_mvert[coarse_edge->v2].co);
/* Start point, duplicate from edge start if no neighbor. */
- if (neighbors[0] != NULL) {
+ if (neighbors[0] != nullptr) {
if (neighbors[0]->v1 == coarse_edge->v1) {
copy_v3_v3(points_r[0], coarse_mvert[neighbors[0]->v2].co);
}
@@ -1026,7 +1032,7 @@ static void points_for_loose_edges_interpolation_get(const Mesh *coarse_mesh,
add_v3_v3(points_r[0], points_r[1]);
}
/* End point, duplicate from edge end if no neighbor. */
- if (neighbors[1] != NULL) {
+ if (neighbors[1] != nullptr) {
if (neighbors[1]->v1 == coarse_edge->v2) {
copy_v3_v3(points_r[3], coarse_mvert[neighbors[1]->v2].co);
}
@@ -1075,26 +1081,27 @@ static void subdiv_mesh_vertex_of_loose_edge_interpolate(SubdivMeshContext *ctx,
BLI_assert(u > 0.0f);
BLI_assert(u < 1.0f);
const float interpolation_weights[2] = {1.0f - u, u};
- const int coarse_vertex_indices[2] = {coarse_edge->v1, coarse_edge->v2};
+ const int coarse_vertex_indices[2] = {static_cast<int>(coarse_edge->v1),
+ static_cast<int>(coarse_edge->v2)};
CustomData_interp(&coarse_mesh->vdata,
&subdiv_mesh->vdata,
coarse_vertex_indices,
interpolation_weights,
- NULL,
+ nullptr,
2,
subdiv_vertex_index);
- if (ctx->vert_origindex != NULL) {
+ if (ctx->vert_origindex != nullptr) {
ctx->vert_origindex[subdiv_vertex_index] = ORIGINDEX_NONE;
}
}
-static void subdiv_mesh_vertex_of_loose_edge(const struct SubdivForeachContext *foreach_context,
+static void subdiv_mesh_vertex_of_loose_edge(const SubdivForeachContext *foreach_context,
void *UNUSED(tls),
const int coarse_edge_index,
const float u,
const int subdiv_vertex_index)
{
- SubdivMeshContext *ctx = foreach_context->user_data;
+ SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
const Mesh *coarse_mesh = ctx->coarse_mesh;
const MEdge *coarse_edge = &coarse_mesh->medge[coarse_edge_index];
Mesh *subdiv_mesh = ctx->subdiv_mesh;
@@ -1158,7 +1165,7 @@ Mesh *BKE_subdiv_to_mesh(Subdiv *subdiv,
/* Make sure evaluator is up to date with possible new topology, and that
* it is refined for the new positions of coarse vertices. */
if (!BKE_subdiv_eval_begin_from_mesh(
- subdiv, coarse_mesh, NULL, SUBDIV_EVALUATOR_TYPE_CPU, NULL)) {
+ subdiv, coarse_mesh, nullptr, SUBDIV_EVALUATOR_TYPE_CPU, nullptr)) {
/* This could happen in two situations:
* - OpenSubdiv is disabled.
* - Something totally bad happened, and OpenSubdiv rejected our
@@ -1166,7 +1173,7 @@ Mesh *BKE_subdiv_to_mesh(Subdiv *subdiv,
* In either way, we can't safely continue. */
if (coarse_mesh->totpoly) {
BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_MESH);
- return NULL;
+ return nullptr;
}
}
/* Initialize subdivision mesh creation context. */
@@ -1174,7 +1181,7 @@ Mesh *BKE_subdiv_to_mesh(Subdiv *subdiv,
subdiv_context.settings = settings;
subdiv_context.coarse_mesh = coarse_mesh;
subdiv_context.subdiv = subdiv;
- subdiv_context.have_displacement = (subdiv->displacement_evaluator != NULL);
+ subdiv_context.have_displacement = (subdiv->displacement_evaluator != nullptr);
/* Multi-threaded traversal/evaluation. */
BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_MESH_GEOMETRY);
SubdivForeachContext foreach_context;
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index efabb4f039a..f19aac68d35 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -284,7 +284,8 @@ static int ss_sync_from_uv(CCGSubSurf *ss,
* UV map in really simple cases with mirror + subsurf, see second part of T44530.
* Also, initially intention is to treat merged vertices from mirror modifier as seams.
* This fixes a very old regression (2.49 was correct here) */
- vmap = BKE_mesh_uv_vert_map_create(mpoly, mloop, mloopuv, totface, totvert, limit, false, true);
+ vmap = BKE_mesh_uv_vert_map_create(
+ mpoly, NULL, mloop, mloopuv, totface, totvert, limit, false, true);
if (!vmap) {
return 0;
}
diff --git a/source/blender/blenkernel/intern/tracking_detect.c b/source/blender/blenkernel/intern/tracking_detect.c
index 51ffce4a3e3..540f880905d 100644
--- a/source/blender/blenkernel/intern/tracking_detect.c
+++ b/source/blender/blenkernel/intern/tracking_detect.c
@@ -81,7 +81,6 @@ static void detect_retrieve_libmv_features(MovieTracking *tracking,
a = libmv_countFeatures(features);
while (a--) {
- MovieTrackingTrack *track;
double x, y, size, score;
bool ok = true;
float xu, yu;
@@ -99,7 +98,8 @@ static void detect_retrieve_libmv_features(MovieTracking *tracking,
}
if (ok) {
- track = BKE_tracking_track_add(tracking, tracksbase, xu, yu, framenr, width, height);
+ MovieTrackingTrack *track = BKE_tracking_track_add(
+ tracking, tracksbase, xu, yu, framenr, width, height);
track->flag |= SELECT;
track->pat_flag |= SELECT;
track->search_flag |= SELECT;
diff --git a/source/blender/blenkernel/intern/type_conversions.cc b/source/blender/blenkernel/intern/type_conversions.cc
index 0b5d6ad7b10..a01f5d19088 100644
--- a/source/blender/blenkernel/intern/type_conversions.cc
+++ b/source/blender/blenkernel/intern/type_conversions.cc
@@ -367,20 +367,38 @@ void DataTypeConversions::convert_to_uninitialized(const CPPType &from_type,
functions->convert_single_to_uninitialized(from_value, to_value);
}
+static void call_convert_to_uninitialized_fn(const GVArray &from,
+ const fn::MultiFunction &fn,
+ const IndexMask mask,
+ GMutableSpan to)
+{
+ fn::MFParamsBuilder params{fn, from.size()};
+ params.add_readonly_single_input(from);
+ params.add_uninitialized_single_output(to);
+ fn::MFContextBuilder context;
+ fn.call_auto(mask, params, context);
+}
+
+static void call_convert_to_uninitialized_fn(const GVArray &from,
+ const fn::MultiFunction &fn,
+ GMutableSpan to)
+{
+ call_convert_to_uninitialized_fn(from, fn, IndexMask(from.size()), to);
+}
+
void DataTypeConversions::convert_to_initialized_n(GSpan from_span, GMutableSpan to_span) const
{
const CPPType &from_type = from_span.type();
const CPPType &to_type = to_span.type();
+
BLI_assert(from_span.size() == to_span.size());
BLI_assert(this->is_convertible(from_type, to_type));
+
const fn::MultiFunction *fn = this->get_conversion_multi_function(
MFDataType::ForSingle(from_type), MFDataType::ForSingle(to_type));
- fn::MFParamsBuilder params{*fn, from_span.size()};
- params.add_readonly_single_input(from_span);
+
to_type.destruct_n(to_span.data(), to_span.size());
- params.add_uninitialized_single_output(to_span);
- fn::MFContextBuilder context;
- fn->call_auto(IndexRange(from_span.size()), params, context);
+ call_convert_to_uninitialized_fn(GVArray::ForSpan(from_span), *fn, to_span);
}
class GVArray_For_ConvertedGVArray : public GVArrayImpl {
@@ -414,6 +432,20 @@ class GVArray_For_ConvertedGVArray : public GVArrayImpl {
old_to_new_conversions_.convert_single_to_uninitialized(buffer, r_value);
from_type_.destruct(buffer);
}
+
+ void materialize(const IndexMask mask, void *dst) const override
+ {
+ type_->destruct_n(dst, mask.min_array_size());
+ this->materialize_to_uninitialized(mask, dst);
+ }
+
+ void materialize_to_uninitialized(const IndexMask mask, void *dst) const override
+ {
+ call_convert_to_uninitialized_fn(varray_,
+ *old_to_new_conversions_.multi_function,
+ mask,
+ {this->type(), dst, mask.min_array_size()});
+ }
};
class GVMutableArray_For_ConvertedGVMutableArray : public GVMutableArrayImpl {
@@ -458,6 +490,20 @@ class GVMutableArray_For_ConvertedGVMutableArray : public GVMutableArrayImpl {
new_to_old_conversions_.convert_single_to_uninitialized(value, buffer);
varray_.set_by_relocate(index, buffer);
}
+
+ void materialize(const IndexMask mask, void *dst) const override
+ {
+ type_->destruct_n(dst, mask.min_array_size());
+ this->materialize_to_uninitialized(mask, dst);
+ }
+
+ void materialize_to_uninitialized(const IndexMask mask, void *dst) const override
+ {
+ call_convert_to_uninitialized_fn(varray_,
+ *old_to_new_conversions_.multi_function,
+ mask,
+ {this->type(), dst, mask.min_array_size()});
+ }
};
GVArray DataTypeConversions::try_convert(GVArray varray, const CPPType &to_type) const
@@ -495,9 +541,8 @@ fn::GField DataTypeConversions::try_convert(fn::GField field, const CPPType &to_
if (!this->is_convertible(from_type, to_type)) {
return {};
}
- const fn::MultiFunction &fn =
- *bke::get_implicit_type_conversions().get_conversion_multi_function(
- fn::MFDataType::ForSingle(from_type), fn::MFDataType::ForSingle(to_type));
+ const fn::MultiFunction &fn = *this->get_conversion_multi_function(
+ fn::MFDataType::ForSingle(from_type), fn::MFDataType::ForSingle(to_type));
return {std::make_shared<fn::FieldOperation>(fn, Vector<fn::GField>{std::move(field)})};
}
diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c
index b31632f0234..f7ea4c81fbf 100644
--- a/source/blender/blenkernel/intern/unit.c
+++ b/source/blender/blenkernel/intern/unit.c
@@ -845,8 +845,8 @@ static bool unit_distribute_negatives(char *str, const int len_max)
bool changed = false;
char *remaining_str = str;
- int remaining_str_len = len_max;
while ((remaining_str = find_next_negative(str, remaining_str)) != NULL) {
+ int remaining_str_len;
/* Exit early in the unlikely situation that we've run out of length to add the parentheses. */
remaining_str_len = len_max - (int)(remaining_str - str);
if (remaining_str_len <= 2) {
@@ -1025,6 +1025,16 @@ static bool unit_find(const char *str, const bUnitDef *unit)
return false;
}
+static const bUnitDef *unit_find_in_collection(const bUnitCollection *usys, const char *str)
+{
+ for (const bUnitDef *unit = usys->units; unit->name; unit++) {
+ if (unit_find(str, unit)) {
+ return unit;
+ }
+ }
+ return NULL;
+}
+
/**
* Try to find a default unit from current or previous string.
* This allows us to handle cases like 2 + 2mm, people would expect to get 4mm, not 2.002m!
@@ -1035,25 +1045,15 @@ static const bUnitDef *unit_detect_from_str(const bUnitCollection *usys,
const char *str,
const char *str_prev)
{
- const bUnitDef *unit = NULL;
-
/* See which units the new value has. */
- for (unit = usys->units; unit->name; unit++) {
- if (unit_find(str, unit)) {
- break;
- }
- }
+ const bUnitDef *unit = unit_find_in_collection(usys, str);
/* Else, try to infer the default unit from the previous string. */
- if (str_prev && (unit == NULL || unit->name == NULL)) {
+ if (str_prev && (unit == NULL)) {
/* See which units the original value had. */
- for (unit = usys->units; unit->name; unit++) {
- if (unit_find(str_prev, unit)) {
- break;
- }
- }
+ unit = unit_find_in_collection(usys, str_prev);
}
/* Else, fall back to default unit. */
- if (unit == NULL || unit->name == NULL) {
+ if (unit == NULL) {
unit = unit_default(usys);
}
@@ -1067,11 +1067,8 @@ bool BKE_unit_string_contains_unit(const char *str, int type)
if (!is_valid_unit_collection(usys)) {
continue;
}
-
- for (int i = 0; i < usys->length; i++) {
- if (unit_find(str, usys->units + i)) {
- return true;
- }
+ if (unit_find_in_collection(usys, str)) {
+ return true;
}
}
return false;
@@ -1155,13 +1152,12 @@ bool BKE_unit_replace_string(
*/
{
char *str_found = str;
- const char *ch = str;
while ((str_found = strchr(str_found, SEP_CHR))) {
bool op_found = false;
/* Any operators after this? */
- for (ch = str_found + 1; *ch != '\0'; ch++) {
+ for (const char *ch = str_found + 1; *ch != '\0'; ch++) {
if (ELEM(*ch, ' ', '\t')) {
continue;
}
diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c
index 0265dd037b1..88e7db1fe6c 100644
--- a/source/blender/blenkernel/intern/workspace.c
+++ b/source/blender/blenkernel/intern/workspace.c
@@ -456,12 +456,12 @@ WorkSpaceLayout *BKE_workspace_layout_iter_circular(const WorkSpace *workspace,
WorkSpaceLayout *iter_layout;
if (iter_backward) {
- LISTBASE_CIRCULAR_BACKWARD_BEGIN (&workspace->layouts, iter_layout, start) {
+ LISTBASE_CIRCULAR_BACKWARD_BEGIN (WorkSpaceLayout *, &workspace->layouts, iter_layout, start) {
if (!callback(iter_layout, arg)) {
return iter_layout;
}
}
- LISTBASE_CIRCULAR_BACKWARD_END(&workspace->layouts, iter_layout, start);
+ LISTBASE_CIRCULAR_BACKWARD_END(WorkSpaceLayout *, &workspace->layouts, iter_layout, start);
}
else {
LISTBASE_CIRCULAR_FORWARD_BEGIN (&workspace->layouts, iter_layout, start) {