diff options
Diffstat (limited to 'source/blender/blenkernel')
50 files changed, 497 insertions, 232 deletions
diff --git a/source/blender/blenkernel/BKE_attribute_math.hh b/source/blender/blenkernel/BKE_attribute_math.hh index 9efa64d1474..4482e13e1cf 100644 --- a/source/blender/blenkernel/BKE_attribute_math.hh +++ b/source/blender/blenkernel/BKE_attribute_math.hh @@ -5,6 +5,7 @@ #include "BLI_array.hh" #include "BLI_color.hh" #include "BLI_cpp_type.hh" +#include "BLI_math_color.hh" #include "BLI_math_vector.h" #include "BLI_math_vector.hh" @@ -18,17 +19,23 @@ namespace blender::attribute_math { template<typename Func> inline void convert_to_static_type(const CPPType &cpp_type, const Func &func) { - cpp_type.to_static_type_tag<float, float2, float3, int, bool, int8_t, ColorGeometry4f>( - [&](auto type_tag) { - using T = typename decltype(type_tag)::type; - if constexpr (std::is_same_v<T, void>) { - /* It's expected that the given cpp type is one of the supported ones. */ - BLI_assert_unreachable(); - } - else { - func(T()); - } - }); + cpp_type.to_static_type_tag<float, + float2, + float3, + int, + bool, + int8_t, + ColorGeometry4f, + ColorGeometry4b>([&](auto type_tag) { + using T = typename decltype(type_tag)::type; + if constexpr (std::is_same_v<T, void>) { + /* It's expected that the given cpp type is one of the supported ones. */ + BLI_assert_unreachable(); + } + else { + func(T()); + } + }); } template<typename Func> @@ -91,6 +98,22 @@ inline ColorGeometry4f mix3(const float3 &weights, return result; } +template<> +inline ColorGeometry4b mix3(const float3 &weights, + const ColorGeometry4b &v0, + const ColorGeometry4b &v1, + const ColorGeometry4b &v2) +{ + const float4 v0_f{&v0.r}; + const float4 v1_f{&v1.r}; + const float4 v2_f{&v2.r}; + const float4 mixed = v0_f * weights[0] + v1_f * weights[1] + v2_f * weights[2]; + return ColorGeometry4b{static_cast<uint8_t>(mixed[0]), + static_cast<uint8_t>(mixed[1]), + static_cast<uint8_t>(mixed[2]), + static_cast<uint8_t>(mixed[3])}; +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -134,9 +157,13 @@ template<> inline float3 mix2(const float factor, const float3 &a, const float3 template<> inline ColorGeometry4f mix2(const float factor, const ColorGeometry4f &a, const ColorGeometry4f &b) { - ColorGeometry4f result; - interp_v4_v4v4(result, a, b, factor); - return result; + return math::interpolate(a, b, factor); +} + +template<> +inline ColorGeometry4b mix2(const float factor, const ColorGeometry4b &a, const ColorGeometry4b &b) +{ + return math::interpolate(a, b, factor); } /** \} */ @@ -278,19 +305,33 @@ class SimpleMixerWithAccumulationType { } }; -class ColorGeometryMixer { +class ColorGeometry4fMixer { private: MutableSpan<ColorGeometry4f> buffer_; ColorGeometry4f default_color_; Array<float> total_weights_; public: - ColorGeometryMixer(MutableSpan<ColorGeometry4f> buffer, - ColorGeometry4f default_color = ColorGeometry4f(0.0f, 0.0f, 0.0f, 1.0f)); + ColorGeometry4fMixer(MutableSpan<ColorGeometry4f> buffer, + ColorGeometry4f default_color = ColorGeometry4f(0.0f, 0.0f, 0.0f, 1.0f)); void mix_in(int64_t index, const ColorGeometry4f &color, float weight = 1.0f); void finalize(); }; +class ColorGeometry4bMixer { + private: + MutableSpan<ColorGeometry4b> buffer_; + ColorGeometry4b default_color_; + Array<float> total_weights_; + Array<float4> accumulation_buffer_; + + public: + ColorGeometry4bMixer(MutableSpan<ColorGeometry4b> buffer, + ColorGeometry4b default_color = ColorGeometry4b(0, 0, 0, 255)); + void mix_in(int64_t index, const ColorGeometry4b &color, float weight = 1.0f); + void finalize(); +}; + template<typename T> struct DefaultMixerStruct { /* Use void by default. This can be checked for in `if constexpr` statements. */ using type = void; @@ -307,7 +348,10 @@ template<> struct DefaultMixerStruct<float3> { template<> struct DefaultMixerStruct<ColorGeometry4f> { /* Use a special mixer for colors. ColorGeometry4f can't be added/multiplied, because this is not * something one should usually do with colors. */ - using type = ColorGeometryMixer; + using type = ColorGeometry4fMixer; +}; +template<> struct DefaultMixerStruct<ColorGeometry4b> { + using type = ColorGeometry4bMixer; }; template<> struct DefaultMixerStruct<int> { static int double_to_int(const double &value) diff --git a/source/blender/blenkernel/BKE_curves.hh b/source/blender/blenkernel/BKE_curves.hh index 282e2a40bd0..6e4d4d560f7 100644 --- a/source/blender/blenkernel/BKE_curves.hh +++ b/source/blender/blenkernel/BKE_curves.hh @@ -451,7 +451,7 @@ bool last_cylic_segment_is_vector(Span<int8_t> handle_types_left, Span<int8_t> h /** * Return true if the handle types at the index are free (#BEZIER_HANDLE_FREE) or vector - * (#BEZIER_HANDLE_VECTOR). In these cases, directional continuitity from the previous and next + * (#BEZIER_HANDLE_VECTOR). In these cases, directional continuities from the previous and next * evaluated segments is assumed not to be desired. */ bool point_is_sharp(Span<int8_t> handle_types_left, Span<int8_t> handle_types_right, int index); diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h index 2070584a8a0..06feb07aef2 100644 --- a/source/blender/blenkernel/BKE_global.h +++ b/source/blender/blenkernel/BKE_global.h @@ -195,8 +195,8 @@ enum { G_DEBUG_XR = (1 << 19), /* XR/OpenXR messages */ G_DEBUG_XR_TIME = (1 << 20), /* XR/OpenXR timing messages */ - G_DEBUG_GHOST = (1 << 21), /* Debug GHOST module. */ - G_DEBUG_WINTAB = (1 << 22), /* Debug Wintab. */ + G_DEBUG_GHOST = (1 << 21), /* Debug GHOST module. */ + G_DEBUG_WINTAB = (1 << 22), /* Debug Wintab. */ }; #define G_DEBUG_ALL \ diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index fff3b2a8f89..42d0e66cf49 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -414,6 +414,8 @@ int BKE_image_get_tile_from_pos(struct Image *ima, const float uv[2], float r_uv[2], float r_ofs[2]); +void BKE_image_get_tile_uv(const struct Image *ima, const int tile_number, float r_uv[2]); + /** * Return the tile_number for the closest UDIM tile. */ diff --git a/source/blender/blenkernel/BKE_mesh_remap.h b/source/blender/blenkernel/BKE_mesh_remap.h index 395fc5c7eba..e2b16a7681d 100644 --- a/source/blender/blenkernel/BKE_mesh_remap.h +++ b/source/blender/blenkernel/BKE_mesh_remap.h @@ -178,6 +178,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(int mode, int numverts_dst, bool dirty_nors_dst, struct Mesh *me_src, + struct Mesh *me_dst, MeshPairRemap *r_map); void BKE_mesh_remap_calc_edges_from_mesh(int mode, @@ -190,6 +191,7 @@ void BKE_mesh_remap_calc_edges_from_mesh(int mode, int numedges_dst, bool dirty_nors_dst, struct Mesh *me_src, + struct Mesh *me_dst, MeshPairRemap *r_map); void BKE_mesh_remap_calc_loops_from_mesh(int mode, diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index 4ae37095411..f0488e84091 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -615,9 +615,6 @@ typedef struct SculptSession { union { struct { struct SculptVertexPaintGeomMap gmap; - - /* For non-airbrush painting to re-apply from the original (MLoop aligned). */ - unsigned int *previous_color; } vpaint; struct { @@ -734,6 +731,7 @@ enum { }; /* paint_canvas.cc */ + /** * Create a key that can be used to compare with previous ones to identify changes. * The resulting 'string' is owned by the caller. diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index bb918fcfdcb..978e52d8003 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -143,8 +143,7 @@ void BKE_pbvh_build_bmesh(PBVH *pbvh, int cd_face_node_offset); void BKE_pbvh_build_pixels(PBVH *pbvh, - const struct MLoop *mloop, - struct CustomData *ldata, + struct Mesh *mesh, struct Image *image, struct ImageUser *image_user); void BKE_pbvh_free(PBVH *pbvh); diff --git a/source/blender/blenkernel/BKE_pbvh_pixels.hh b/source/blender/blenkernel/BKE_pbvh_pixels.hh index 35eb340d0a1..fdfb5fa037e 100644 --- a/source/blender/blenkernel/BKE_pbvh_pixels.hh +++ b/source/blender/blenkernel/BKE_pbvh_pixels.hh @@ -21,7 +21,7 @@ namespace blender::bke::pbvh::pixels { struct TrianglePaintInput { int3 vert_indices; /** - * Delta barycentric coordinates between 2 neighbouring UV's in the U direction. + * Delta barycentric coordinates between 2 neighboring UV's in the U direction. * * Only the first two coordinates are stored. The third should be recalculated */ diff --git a/source/blender/blenkernel/BKE_type_conversions.hh b/source/blender/blenkernel/BKE_type_conversions.hh index 5152989d137..1cca172e188 100644 --- a/source/blender/blenkernel/BKE_type_conversions.hh +++ b/source/blender/blenkernel/BKE_type_conversions.hh @@ -2,6 +2,7 @@ #pragma once +#include "FN_field.hh" #include "FN_multi_function.hh" namespace blender::bke { @@ -59,8 +60,8 @@ class DataTypeConversions { void convert_to_initialized_n(GSpan from_span, GMutableSpan to_span) const; GVArray try_convert(GVArray varray, const CPPType &to_type) const; - GVMutableArray try_convert(GVMutableArray varray, const CPPType &to_type) const; + fn::GField try_convert(fn::GField field, const CPPType &to_type) const; }; const DataTypeConversions &get_implicit_type_conversions(); diff --git a/source/blender/blenkernel/BKE_volume.h b/source/blender/blenkernel/BKE_volume.h index 77f01e7919d..bc578ef8b28 100644 --- a/source/blender/blenkernel/BKE_volume.h +++ b/source/blender/blenkernel/BKE_volume.h @@ -77,6 +77,11 @@ const VolumeGrid *BKE_volume_grid_active_get_for_read(const struct Volume *volum /* Tries to find a grid with the given name. Make sure that the volume has been loaded. */ const VolumeGrid *BKE_volume_grid_find_for_read(const struct Volume *volume, const char *name); +/* Tries to set the name of the velocity field. If no such grid exists with the given base name, + * this will try common post-fixes in order to detect velocity fields split into multiple grids. + * Return false if neither finding with the base name nor with the post-fixes succeeded. */ +bool BKE_volume_set_velocity_grid_by_name(struct Volume *volume, const char *base_name); + /* Grid * * By default only grid metadata is loaded, for access to the tree and voxels diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc index 33f0c331e46..8a0ad4b724b 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.cc +++ b/source/blender/blenkernel/intern/DerivedMesh.cc @@ -734,7 +734,6 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph, const bool use_deform, const bool need_mapping, const CustomData_MeshMasks *dataMask, - const int index, const bool use_cache, const bool allow_shared_mesh, /* return args */ @@ -848,12 +847,6 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph, else { break; } - - /* grab modifiers until index i */ - if ((index != -1) && (BLI_findindex(&ob->modifiers, md) >= index)) { - md = nullptr; - break; - } } /* Result of all leading deforming modifiers is cached for @@ -1129,11 +1122,6 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph, isPrevDeform = (mti->type == eModifierTypeType_OnlyDeform); - /* grab modifiers until index i */ - if ((index != -1) && (BLI_findindex(&ob->modifiers, md) >= index)) { - break; - } - if (sculpt_mode && md->type == eModifierType_Multires) { multires_applied = true; } @@ -1611,7 +1599,7 @@ static void mesh_build_data(struct Depsgraph *depsgraph, const CustomData_MeshMasks *dataMask, const bool need_mapping) { -#if 0 /* XXX This is already taken care of in mesh_calc_modifiers()... */ +#if 0 /* XXX This is already taken care of in #mesh_calc_modifiers... */ if (need_mapping) { /* Also add the flag so that it is recorded in lastDataMask. */ dataMask->vmask |= CD_MASK_ORIGINDEX; @@ -1628,7 +1616,6 @@ static void mesh_build_data(struct Depsgraph *depsgraph, true, need_mapping, dataMask, - -1, true, true, &mesh_deform_eval, @@ -1745,13 +1732,13 @@ static void object_get_datamask(const Depsgraph *depsgraph, /* check if we need tfaces & mcols due to face select or texture paint */ if ((ob->mode & OB_MODE_TEXTURE_PAINT) || editing) { - r_mask->lmask |= CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL; + r_mask->lmask |= CD_MASK_MLOOPUV | CD_MASK_PROP_BYTE_COLOR; r_mask->fmask |= CD_MASK_MTFACE; } /* check if we need mcols due to vertex paint or weightpaint */ if (ob->mode & OB_MODE_VERTEX_PAINT) { - r_mask->lmask |= CD_MASK_MLOOPCOL; + r_mask->lmask |= CD_MASK_PROP_BYTE_COLOR; } if (ob->mode & OB_MODE_WEIGHT_PAINT) { @@ -1882,7 +1869,7 @@ Mesh *mesh_create_eval_final(Depsgraph *depsgraph, { Mesh *result; mesh_calc_modifiers( - depsgraph, scene, ob, true, false, dataMask, -1, false, false, nullptr, &result, nullptr); + depsgraph, scene, ob, true, false, dataMask, false, false, nullptr, &result, nullptr); return result; } @@ -1893,7 +1880,7 @@ Mesh *mesh_create_eval_no_deform(Depsgraph *depsgraph, { Mesh *result; mesh_calc_modifiers( - depsgraph, scene, ob, false, false, dataMask, -1, false, false, nullptr, &result, nullptr); + depsgraph, scene, ob, false, false, dataMask, false, false, nullptr, &result, nullptr); return result; } @@ -1904,7 +1891,7 @@ Mesh *mesh_create_eval_no_deform_render(Depsgraph *depsgraph, { Mesh *result; mesh_calc_modifiers( - depsgraph, scene, ob, false, false, dataMask, -1, false, false, nullptr, &result, nullptr); + depsgraph, scene, ob, false, false, dataMask, false, false, nullptr, &result, nullptr); return result; } diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 54fee079947..b886722676b 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -1958,11 +1958,12 @@ static void nlaevalchan_assert_blendOrcombine_compatible(NlaEvalChannelSnapshot BLI_assert(lower_necs->length == blended_necs->length); } -/** Check each remap domain of blended values individually in case animator had a non-combine NLA +/** + * Check each remap domain of blended values individually in case animator had a non-combine NLA * strip with a subset of quaternion channels and remapping through any of them failed and thus * potentially has undefined values. * - * \returns true if case occured and handled. Returns false if case didn't occur. + * \returns true if case occurred and handled. Returns false if case didn't occur. */ static bool nlaevalchan_combine_quaternion_handle_undefined_blend_values( NlaEvalChannelSnapshot *blended_necs, NlaEvalChannelSnapshot *upper_or_lower_necs) @@ -1992,8 +1993,10 @@ static void nlaevalchan_copy_values(NlaEvalChannelSnapshot *dst, NlaEvalChannelS memcpy(dst->values, src->values, src->length * sizeof(float)); } -/** Copies from lower necs to blended necs if upper necs is NULL or has zero influence. - * \return true if copied. */ +/** + * Copies from lower necs to blended necs if upper necs is NULL or has zero influence. + * \return true if copied. + */ static bool nlaevalchan_blendOrcombine_try_copy_from_lower(NlaEvalChannelSnapshot *lower_necs, NlaEvalChannelSnapshot *upper_necs, const float upper_influence, @@ -2008,12 +2011,14 @@ static bool nlaevalchan_blendOrcombine_try_copy_from_lower(NlaEvalChannelSnapsho return true; } -/** Copies to lower necs from blended necs if upper necs is NULL or has zero influence. If +/** + * Copies to lower necs from blended necs if upper necs is NULL or has zero influence. If * successful, copies blended_necs remap domains to lower_necs. * * Does not check upper value blend domains. * - * \return true if copied. */ + * \return true if copied. + */ static bool nlaevalchan_blendOrcombine_try_copy_to_lower(NlaEvalChannelSnapshot *blended_necs, NlaEvalChannelSnapshot *upper_necs, const float upper_influence, @@ -2033,7 +2038,8 @@ static bool nlaevalchan_blendOrcombine_try_copy_to_lower(NlaEvalChannelSnapshot return true; } -/** Based on blendmode, blend lower necs with upper necs into blended necs. +/** + * Based on blendmode, blend lower necs with upper necs into blended necs. * * Each upper value's blend domain determines whether to blend or to copy directly * from lower. @@ -2133,7 +2139,6 @@ static void nlaevalchan_combine_quaternion(NlaEvalChannelSnapshot *lower_necs, * \param upper_blendmode: Enum value in eNlaStrip_Blend_Mode. * \param upper_influence: Value in range [0, 1]. * \param upper_necs: Never NULL. - * */ static void nlaevalchan_blendOrcombine(NlaEvalChannelSnapshot *lower_necs, NlaEvalChannelSnapshot *upper_necs, diff --git a/source/blender/blenkernel/intern/attribute.c b/source/blender/blenkernel/intern/attribute.c index 307868ce6d9..0cb0704ff80 100644 --- a/source/blender/blenkernel/intern/attribute.c +++ b/source/blender/blenkernel/intern/attribute.c @@ -311,6 +311,20 @@ AttributeDomain BKE_id_attribute_domain(const ID *id, const CustomDataLayer *lay int BKE_id_attribute_data_length(ID *id, CustomDataLayer *layer) { + /* When in mesh editmode, attributes point to bmesh customdata layers, the attribute data is + * empty since custom data is stored per element instead of a single array there (same es UVs + * etc.), see D11998. */ + switch (GS(id->name)) { + case ID_ME: { + Mesh *mesh = (Mesh *)id; + if (mesh->edit_mesh != NULL) { + return 0; + } + } + default: + break; + } + DomainInfo info[ATTR_DOMAIN_NUM]; get_domains(id, info); @@ -622,10 +636,10 @@ CustomDataLayer *BKE_id_attributes_color_find(const ID *id, const char *name) layer = BKE_id_attribute_find(id, name, CD_PROP_COLOR, ATTR_DOMAIN_CORNER); } if (layer == NULL) { - layer = BKE_id_attribute_find(id, name, CD_MLOOPCOL, ATTR_DOMAIN_POINT); + layer = BKE_id_attribute_find(id, name, CD_PROP_BYTE_COLOR, ATTR_DOMAIN_POINT); } if (layer == NULL) { - layer = BKE_id_attribute_find(id, name, CD_MLOOPCOL, ATTR_DOMAIN_CORNER); + layer = BKE_id_attribute_find(id, name, CD_PROP_BYTE_COLOR, ATTR_DOMAIN_CORNER); } return layer; } diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc index 0ae9fa4356b..77c7857a528 100644 --- a/source/blender/blenkernel/intern/attribute_access.cc +++ b/source/blender/blenkernel/intern/attribute_access.cc @@ -70,11 +70,11 @@ static int attribute_data_type_complexity(const CustomDataType data_type) return 4; case CD_PROP_FLOAT3: return 5; - case CD_PROP_COLOR: + case CD_PROP_BYTE_COLOR: return 6; + case CD_PROP_COLOR: + return 7; #if 0 /* These attribute types are not supported yet. */ - case CD_MLOOPCOL: - return 3; case CD_PROP_STRING: return 6; #endif diff --git a/source/blender/blenkernel/intern/attribute_access_intern.hh b/source/blender/blenkernel/intern/attribute_access_intern.hh index bfc4c8fcde0..8c021ed0e21 100644 --- a/source/blender/blenkernel/intern/attribute_access_intern.hh +++ b/source/blender/blenkernel/intern/attribute_access_intern.hh @@ -127,7 +127,7 @@ class CustomDataAttributeProvider final : public DynamicAttributesProvider { static constexpr uint64_t supported_types_mask = CD_MASK_PROP_FLOAT | CD_MASK_PROP_FLOAT2 | CD_MASK_PROP_FLOAT3 | CD_MASK_PROP_INT32 | CD_MASK_PROP_COLOR | CD_MASK_PROP_BOOL | - CD_MASK_PROP_INT8; + CD_MASK_PROP_INT8 | CD_MASK_PROP_BYTE_COLOR; const AttributeDomain domain_; const CustomDataAccessInfo custom_data_access_; diff --git a/source/blender/blenkernel/intern/attribute_math.cc b/source/blender/blenkernel/intern/attribute_math.cc index df3cab474cd..c38df2a2969 100644 --- a/source/blender/blenkernel/intern/attribute_math.cc +++ b/source/blender/blenkernel/intern/attribute_math.cc @@ -4,8 +4,8 @@ namespace blender::attribute_math { -ColorGeometryMixer::ColorGeometryMixer(MutableSpan<ColorGeometry4f> output_buffer, - ColorGeometry4f default_color) +ColorGeometry4fMixer::ColorGeometry4fMixer(MutableSpan<ColorGeometry4f> output_buffer, + ColorGeometry4f default_color) : buffer_(output_buffer), default_color_(default_color), total_weights_(output_buffer.size(), 0.0f) @@ -13,9 +13,9 @@ ColorGeometryMixer::ColorGeometryMixer(MutableSpan<ColorGeometry4f> output_buffe buffer_.fill(ColorGeometry4f(0.0f, 0.0f, 0.0f, 0.0f)); } -void ColorGeometryMixer::mix_in(const int64_t index, - const ColorGeometry4f &color, - const float weight) +void ColorGeometry4fMixer::mix_in(const int64_t index, + const ColorGeometry4f &color, + const float weight) { BLI_assert(weight >= 0.0f); ColorGeometry4f &output_color = buffer_[index]; @@ -26,7 +26,7 @@ void ColorGeometryMixer::mix_in(const int64_t index, total_weights_[index] += weight; } -void ColorGeometryMixer::finalize() +void ColorGeometry4fMixer::finalize() { for (const int64_t i : buffer_.index_range()) { const float weight = total_weights_[i]; @@ -44,4 +44,43 @@ void ColorGeometryMixer::finalize() } } +ColorGeometry4bMixer::ColorGeometry4bMixer(MutableSpan<ColorGeometry4b> buffer, + ColorGeometry4b default_color) + : buffer_(buffer), + default_color_(default_color), + total_weights_(buffer.size(), 0.0f), + accumulation_buffer_(buffer.size(), float4(0, 0, 0, 0)) +{ +} + +void ColorGeometry4bMixer::mix_in(int64_t index, const ColorGeometry4b &color, float weight) +{ + BLI_assert(weight >= 0.0f); + float4 &accum_value = accumulation_buffer_[index]; + accum_value[0] += color.r * weight; + accum_value[1] += color.g * weight; + accum_value[2] += color.b * weight; + accum_value[3] += color.a * weight; + total_weights_[index] += weight; +} + +void ColorGeometry4bMixer::finalize() +{ + for (const int64_t i : buffer_.index_range()) { + const float weight = total_weights_[i]; + const float4 &accum_value = accumulation_buffer_[i]; + ColorGeometry4b &output_color = buffer_[i]; + if (weight > 0.0f) { + const float weight_inv = 1.0f / weight; + output_color.r = accum_value[0] * weight_inv; + output_color.g = accum_value[1] * weight_inv; + output_color.b = accum_value[2] * weight_inv; + output_color.a = accum_value[3] * weight_inv; + } + else { + output_color = default_color_; + } + } +} + } // namespace blender::attribute_math diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index b9cd9e1ee59..0593db34e20 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -1557,8 +1557,10 @@ void BKE_brush_init_curves_sculpt_settings(Brush *brush) if (brush->curves_sculpt_settings == NULL) { brush->curves_sculpt_settings = MEM_callocN(sizeof(BrushCurvesSculptSettings), __func__); } - brush->curves_sculpt_settings->add_amount = 1; - brush->curves_sculpt_settings->minimum_length = 0.01f; + BrushCurvesSculptSettings *settings = brush->curves_sculpt_settings; + settings->add_amount = 1; + settings->minimum_length = 0.01f; + settings->curve_length = 0.3f; } struct Brush *BKE_brush_first_search(struct Main *bmain, const eObjectMode ob_mode) diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index f7454a02de6..0d6a0c045a5 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -1171,6 +1171,7 @@ static Mesh *cloth_make_rest_mesh(ClothModifierData *clmd, Mesh *mesh) for (unsigned i = 0; i < mesh->totvert; i++, verts++) { copy_v3_v3(mvert[i].co, verts->xrest); } + BKE_mesh_normals_tag_dirty(new_mesh); return new_mesh; } @@ -1507,7 +1508,6 @@ static bool cloth_build_springs(ClothModifierData *clmd, Mesh *mesh) if (clmd->sim_parms->shapekey_rest && !(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_DYNAMIC_BASEMESH)) { tmp_mesh = cloth_make_rest_mesh(clmd, mesh); - BKE_mesh_calc_normals(tmp_mesh); } EdgeSet *existing_vert_pairs = BLI_edgeset_new("cloth_sewing_edges_graph"); diff --git a/source/blender/blenkernel/intern/curve.cc b/source/blender/blenkernel/intern/curve.cc index bad70d4ccc6..4338883853d 100644 --- a/source/blender/blenkernel/intern/curve.cc +++ b/source/blender/blenkernel/intern/curve.cc @@ -113,9 +113,12 @@ static void curve_free_data(ID *id) BKE_curve_batch_cache_free(curve); BKE_nurbList_free(&curve->nurb); - BKE_curve_editfont_free(curve); - BKE_curve_editNurb_free(curve); + if (!curve->edit_data_from_original) { + BKE_curve_editfont_free(curve); + + BKE_curve_editNurb_free(curve); + } BKE_curveprofile_free(curve->bevel_profile); diff --git a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc index c48d155f5ce..d7fd8f7a2b6 100644 --- a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc +++ b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc @@ -649,7 +649,6 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main, offsets.vert.last(), offsets.edge.last(), 0, offsets.loop.last(), offsets.poly.last()); mesh->flag |= ME_AUTOSMOOTH; mesh->smoothresh = DEG2RADF(180.0f); - BKE_mesh_normals_tag_dirty(mesh); MutableSpan<MVert> verts(mesh->mvert, mesh->totvert); MutableSpan<MEdge> edges(mesh->medge, mesh->totedge); MutableSpan<MLoop> loops(mesh->mloop, mesh->totloop); diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc index 6dd9460aaa9..22db90a06b0 100644 --- a/source/blender/blenkernel/intern/customdata.cc +++ b/source/blender/blenkernel/intern/customdata.cc @@ -765,7 +765,12 @@ static void layerFree_grid_paint_mask(void *data, int count, int UNUSED(size)) } } -/* --------- */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Callbacks for (#MLoopCol, #CD_PROP_BYTE_COLOR) + * \{ */ + static void layerCopyValue_mloopcol(const void *source, void *dest, const int mixmode, @@ -954,6 +959,12 @@ static int layerMaxNum_mloopcol() return MAX_MCOL; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Callbacks for (#MLoopUV, #CD_MLOOPUV) + * \{ */ + static void layerCopyValue_mloopuv(const void *source, void *dest, const int mixmode, @@ -1716,7 +1727,7 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { nullptr, nullptr, layerMaxNum_tface}, - /* 17: CD_MLOOPCOL */ + /* 17: CD_PROP_BYTE_COLOR */ {sizeof(MLoopCol), "MLoopCol", 1, @@ -2052,46 +2063,45 @@ const CustomData_MeshMasks CD_MASK_BAREMESH_ORIGINDEX = { }; const CustomData_MeshMasks CD_MASK_MESH = { /* vmask */ (CD_MASK_MVERT | CD_MASK_MDEFORMVERT | CD_MASK_MVERT_SKIN | CD_MASK_PAINT_MASK | - CD_MASK_PROP_ALL | CD_MASK_PROP_COLOR | CD_MASK_CREASE), + CD_MASK_PROP_ALL | CD_MASK_CREASE), /* emask */ (CD_MASK_MEDGE | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL), /* fmask */ 0, /* pmask */ (CD_MASK_MPOLY | CD_MASK_FACEMAP | CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL | CD_MASK_SCULPT_FACE_SETS), /* lmask */ - (CD_MASK_MLOOP | CD_MASK_MDISPS | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | - CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL), + (CD_MASK_MLOOP | CD_MASK_MDISPS | CD_MASK_MLOOPUV | CD_MASK_CUSTOMLOOPNORMAL | + CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL), }; const CustomData_MeshMasks CD_MASK_DERIVEDMESH = { /* vmask */ (CD_MASK_ORIGINDEX | CD_MASK_MDEFORMVERT | CD_MASK_SHAPEKEY | CD_MASK_MVERT_SKIN | CD_MASK_PAINT_MASK | CD_MASK_ORCO | CD_MASK_CLOTH_ORCO | CD_MASK_PROP_ALL | - CD_MASK_PROP_COLOR | CD_MASK_CREASE), + CD_MASK_CREASE), /* emask */ (CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL), /* fmask */ (CD_MASK_ORIGINDEX | CD_MASK_ORIGSPACE | CD_MASK_PREVIEW_MCOL | CD_MASK_TANGENT), /* pmask */ (CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_FACE | CD_MASK_FACEMAP | CD_MASK_PROP_ALL | CD_MASK_SCULPT_FACE_SETS), /* lmask */ - (CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_PREVIEW_MLOOPCOL | + (CD_MASK_MLOOPUV | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_PREVIEW_MLOOPCOL | CD_MASK_ORIGSPACE_MLOOP | CD_MASK_PROP_ALL), /* XXX MISSING CD_MASK_MLOOPTANGENT ? */ }; const CustomData_MeshMasks CD_MASK_BMESH = { /* vmask */ (CD_MASK_MDEFORMVERT | CD_MASK_BWEIGHT | CD_MASK_MVERT_SKIN | CD_MASK_SHAPEKEY | - CD_MASK_SHAPE_KEYINDEX | CD_MASK_PAINT_MASK | CD_MASK_PROP_ALL | - CD_MASK_PROP_COLOR | CD_MASK_CREASE), + CD_MASK_SHAPE_KEYINDEX | CD_MASK_PAINT_MASK | CD_MASK_PROP_ALL | CD_MASK_CREASE), /* emask */ (CD_MASK_BWEIGHT | CD_MASK_CREASE | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL), /* fmask */ 0, /* pmask */ (CD_MASK_FREESTYLE_FACE | CD_MASK_FACEMAP | CD_MASK_PROP_ALL | CD_MASK_SCULPT_FACE_SETS), /* lmask */ - (CD_MASK_MDISPS | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_CUSTOMLOOPNORMAL | - CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL), + (CD_MASK_MDISPS | CD_MASK_MLOOPUV | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_GRID_PAINT_MASK | + CD_MASK_PROP_ALL), }; const CustomData_MeshMasks CD_MASK_EVERYTHING = { /* vmask */ (CD_MASK_MVERT | CD_MASK_BM_ELEM_PYPTR | CD_MASK_ORIGINDEX | CD_MASK_MDEFORMVERT | CD_MASK_BWEIGHT | CD_MASK_MVERT_SKIN | CD_MASK_ORCO | CD_MASK_CLOTH_ORCO | CD_MASK_SHAPEKEY | CD_MASK_SHAPE_KEYINDEX | CD_MASK_PAINT_MASK | - CD_MASK_PROP_ALL | CD_MASK_PROP_COLOR | CD_MASK_CREASE), + CD_MASK_PROP_ALL | CD_MASK_CREASE), /* emask */ (CD_MASK_MEDGE | CD_MASK_BM_ELEM_PYPTR | CD_MASK_ORIGINDEX | CD_MASK_BWEIGHT | CD_MASK_CREASE | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL), @@ -2104,9 +2114,8 @@ const CustomData_MeshMasks CD_MASK_EVERYTHING = { CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL | CD_MASK_SCULPT_FACE_SETS), /* lmask */ (CD_MASK_MLOOP | CD_MASK_BM_ELEM_PYPTR | CD_MASK_MDISPS | CD_MASK_NORMAL | CD_MASK_MLOOPUV | - CD_MASK_MLOOPCOL | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_MLOOPTANGENT | - CD_MASK_PREVIEW_MLOOPCOL | CD_MASK_ORIGSPACE_MLOOP | CD_MASK_GRID_PAINT_MASK | - CD_MASK_PROP_ALL), + CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_MLOOPTANGENT | CD_MASK_PREVIEW_MLOOPCOL | + CD_MASK_ORIGSPACE_MLOOP | CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL), }; static const LayerTypeInfo *layerType_getInfo(int type) @@ -3486,7 +3495,7 @@ void CustomData_to_bmeshpoly(CustomData *fdata, CustomData *ldata, int totloop) } else if (fdata->layers[i].type == CD_MCOL) { CustomData_add_layer_named( - ldata, CD_MLOOPCOL, CD_CALLOC, nullptr, totloop, fdata->layers[i].name); + ldata, CD_PROP_BYTE_COLOR, CD_CALLOC, nullptr, totloop, fdata->layers[i].name); } else if (fdata->layers[i].type == CD_MDISPS) { CustomData_add_layer_named( @@ -3509,7 +3518,7 @@ void CustomData_from_bmeshpoly(CustomData *fdata, CustomData *ldata, int total) CustomData_add_layer_named( fdata, CD_MTFACE, CD_CALLOC, nullptr, total, ldata->layers[i].name); } - if (ldata->layers[i].type == CD_MLOOPCOL) { + if (ldata->layers[i].type == CD_PROP_BYTE_COLOR) { CustomData_add_layer_named(fdata, CD_MCOL, CD_CALLOC, nullptr, total, ldata->layers[i].name); } else if (ldata->layers[i].type == CD_PREVIEW_MLOOPCOL) { @@ -3544,7 +3553,7 @@ bool CustomData_from_bmeshpoly_test(CustomData *fdata, CustomData *ldata, bool f if (!LAYER_CMP(ldata, CD_MLOOPUV, fdata, CD_MTFACE)) { return false; } - if (!LAYER_CMP(ldata, CD_MLOOPCOL, fdata, CD_MCOL)) { + if (!LAYER_CMP(ldata, CD_PROP_BYTE_COLOR, fdata, CD_MCOL)) { return false; } if (!LAYER_CMP(ldata, CD_PREVIEW_MLOOPCOL, fdata, CD_PREVIEW_MCOL)) { @@ -3586,17 +3595,17 @@ void CustomData_bmesh_update_active_layers(CustomData *fdata, CustomData *ldata) CustomData_set_layer_stencil(fdata, CD_MTFACE, act); } - if (CustomData_has_layer(ldata, CD_MLOOPCOL)) { - act = CustomData_get_active_layer(ldata, CD_MLOOPCOL); + if (CustomData_has_layer(ldata, CD_PROP_BYTE_COLOR)) { + act = CustomData_get_active_layer(ldata, CD_PROP_BYTE_COLOR); CustomData_set_layer_active(fdata, CD_MCOL, act); - act = CustomData_get_render_layer(ldata, CD_MLOOPCOL); + act = CustomData_get_render_layer(ldata, CD_PROP_BYTE_COLOR); CustomData_set_layer_render(fdata, CD_MCOL, act); - act = CustomData_get_clone_layer(ldata, CD_MLOOPCOL); + act = CustomData_get_clone_layer(ldata, CD_PROP_BYTE_COLOR); CustomData_set_layer_clone(fdata, CD_MCOL, act); - act = CustomData_get_stencil_layer(ldata, CD_MLOOPCOL); + act = CustomData_get_stencil_layer(ldata, CD_PROP_BYTE_COLOR); CustomData_set_layer_stencil(fdata, CD_MCOL, act); } } @@ -3621,16 +3630,16 @@ void CustomData_bmesh_do_versions_update_active_layers(CustomData *fdata, Custom if (CustomData_has_layer(fdata, CD_MCOL)) { act = CustomData_get_active_layer(fdata, CD_MCOL); - CustomData_set_layer_active(ldata, CD_MLOOPCOL, act); + CustomData_set_layer_active(ldata, CD_PROP_BYTE_COLOR, act); act = CustomData_get_render_layer(fdata, CD_MCOL); - CustomData_set_layer_render(ldata, CD_MLOOPCOL, act); + CustomData_set_layer_render(ldata, CD_PROP_BYTE_COLOR, act); act = CustomData_get_clone_layer(fdata, CD_MCOL); - CustomData_set_layer_clone(ldata, CD_MLOOPCOL, act); + CustomData_set_layer_clone(ldata, CD_PROP_BYTE_COLOR, act); act = CustomData_get_stencil_layer(fdata, CD_MCOL); - CustomData_set_layer_stencil(ldata, CD_MLOOPCOL, act); + CustomData_set_layer_stencil(ldata, CD_PROP_BYTE_COLOR, act); } } @@ -5401,6 +5410,8 @@ const blender::CPPType *custom_data_type_to_cpp_type(const CustomDataType type) return &CPPType::get<bool>(); case CD_PROP_INT8: return &CPPType::get<int8_t>(); + case CD_PROP_BYTE_COLOR: + return &CPPType::get<ColorGeometry4b>(); default: return nullptr; } @@ -5430,6 +5441,9 @@ CustomDataType cpp_type_to_custom_data_type(const blender::CPPType &type) if (type.is<int8_t>()) { return CD_PROP_INT8; } + if (type.is<ColorGeometry4b>()) { + return CD_PROP_BYTE_COLOR; + } return static_cast<CustomDataType>(-1); } diff --git a/source/blender/blenkernel/intern/data_transfer.c b/source/blender/blenkernel/intern/data_transfer.c index 2369ce88ebc..6a3f6a47f5e 100644 --- a/source/blender/blenkernel/intern/data_transfer.c +++ b/source/blender/blenkernel/intern/data_transfer.c @@ -217,7 +217,7 @@ int BKE_object_data_transfer_dttype_to_cdtype(const int dtdata_type) return CD_FAKE_LNOR; case DT_TYPE_MLOOPCOL_VERT: case DT_TYPE_MLOOPCOL_LOOP: - return CD_MLOOPCOL; + return CD_PROP_BYTE_COLOR; case DT_TYPE_MPROPCOL_VERT: case DT_TYPE_MPROPCOL_LOOP: return CD_PROP_COLOR; @@ -1501,6 +1501,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph, num_verts_dst, dirty_nors_dst, me_src, + me_dst, &geom_map[VDATA]); geom_map_init[VDATA] = true; } @@ -1579,6 +1580,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph, num_edges_dst, dirty_nors_dst, me_src, + me_dst, &geom_map[EDATA]); geom_map_init[EDATA] = true; } diff --git a/source/blender/blenkernel/intern/displist.cc b/source/blender/blenkernel/intern/displist.cc index 8c1161d6ff6..63aa03483b2 100644 --- a/source/blender/blenkernel/intern/displist.cc +++ b/source/blender/blenkernel/intern/displist.cc @@ -887,17 +887,11 @@ static GeometrySet curve_calc_modifiers_post(Depsgraph *depsgraph, if (mti->type == eModifierTypeType_OnlyDeform) { int totvert; float(*vertex_coords)[3] = BKE_mesh_vert_coords_alloc(mesh, &totvert); - if (mti->dependsOnNormals != nullptr && mti->dependsOnNormals(md)) { - BKE_mesh_vertex_normals_ensure(mesh); - } mti->deformVerts(md, &mectx_deform, mesh, vertex_coords, totvert); BKE_mesh_vert_coords_apply(mesh, vertex_coords); MEM_freeN(vertex_coords); } else { - if (mti->dependsOnNormals != nullptr && mti->dependsOnNormals(md)) { - BKE_mesh_vertex_normals_ensure(mesh); - } Mesh *output_mesh = mti->modifyMesh(md, &mectx_apply, mesh); if (mesh != output_mesh) { geometry_set.replace_mesh(output_mesh); @@ -1472,10 +1466,12 @@ void BKE_displist_make_curveTypes(Depsgraph *depsgraph, const bool for_render) { BLI_assert(ELEM(ob->type, OB_SURF, OB_CURVES_LEGACY, OB_FONT)); - Curve &cow_curve = *(Curve *)ob->data; BKE_object_free_derived_caches(ob); - cow_curve.curve_eval = nullptr; + + /* It's important to retrieve this after calling #BKE_object_free_derived_caches, + * which may reset the object data pointer in some cases. */ + const Curve &original_curve = *static_cast<const Curve *>(ob->data); ob->runtime.curve_cache = MEM_cnew<CurveCache>(__func__); ListBase *dispbase = &ob->runtime.curve_cache->disp; @@ -1488,14 +1484,27 @@ void BKE_displist_make_curveTypes(Depsgraph *depsgraph, GeometrySet geometry = evaluate_curve_type_object(depsgraph, scene, ob, for_render, dispbase); if (geometry.has_curves()) { - /* Assign the evaluated curve to the object's "data_eval". In addition to the curve_eval - * added to the curve here, it will also contain a copy of the original curve's data. This is - * essential, because it maintains the expected behavior for evaluated curve data from before - * the CurveEval data type was introduced, when an evaluated object's curve data was just a - * copy of the original curve and everything else ended up in #CurveCache. */ - CurveComponent &curve_component = geometry.get_component_for_write<CurveComponent>(); - cow_curve.curve_eval = curve_component.get_for_read(); - BKE_object_eval_assign_data(ob, &cow_curve.id, false); + /* Create a copy of the original curve and add necessary pointers to evaluated and edit mode + * data. This is needed for a few reasons: + * - Existing code from before curve evaluation was changed to use #GeometrySet expected to + * have a copy of the original curve data. (Any evaluated data was placed in + * #Object.runtime.curve_cache). + * - The result of modifier evaluation is not a #Curve data-block but a #Curves data-block, + * which can support constructive modifiers and geometry nodes. + * - 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 + * (see T95355), this somewhat hacky inefficient solution is relatively temporary. + */ + Curve &cow_curve = *reinterpret_cast<Curve *>( + BKE_id_copy_ex(nullptr, &original_curve.id, nullptr, LIB_ID_COPY_LOCALIZE)); + cow_curve.curve_eval = geometry.get_curves_for_read(); + /* Copy edit mode pointers necessary for drawing to the duplicated curve. */ + cow_curve.editnurb = original_curve.editnurb; + cow_curve.editfont = original_curve.editfont; + cow_curve.edit_data_from_original = true; + BKE_object_eval_assign_data(ob, &cow_curve.id, true); } ob->runtime.geometry_set_eval = new GeometrySet(std::move(geometry)); diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index b85b2b3157c..22341f98375 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -336,7 +336,7 @@ bool dynamicPaint_outputLayerExists(struct DynamicPaintSurface *surface, Object if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) { Mesh *me = ob->data; - return (CustomData_get_named_layer_index(&me->ldata, CD_MLOOPCOL, name) != -1); + return (CustomData_get_named_layer_index(&me->ldata, CD_PROP_BYTE_COLOR, name) != -1); } if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) { return (BKE_object_defgroup_name_index(ob, name) != -1); @@ -1664,7 +1664,7 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface const MLoop *mloop = mesh->mloop; const int totloop = mesh->totloop; const MLoopCol *col = CustomData_get_layer_named( - &mesh->ldata, CD_MLOOPCOL, surface->init_layername); + &mesh->ldata, CD_PROP_BYTE_COLOR, surface->init_layername); if (!col) { return; } @@ -1676,7 +1676,7 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface else if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) { const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(mesh); MLoopCol *col = CustomData_get_layer_named( - &mesh->ldata, CD_MLOOPCOL, surface->init_layername); + &mesh->ldata, CD_PROP_BYTE_COLOR, surface->init_layername); if (!col) { return; } @@ -1899,7 +1899,6 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object * pmd->type == MOD_DYNAMICPAINT_TYPE_CANVAS) { DynamicPaintSurface *surface; - bool update_normals = false; /* loop through surfaces */ for (surface = pmd->canvas->surfaces.first; surface; surface = surface->next) { @@ -1941,20 +1940,28 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object * /* paint layer */ MLoopCol *mloopcol = CustomData_get_layer_named( - &result->ldata, CD_MLOOPCOL, surface->output_name); + &result->ldata, CD_PROP_BYTE_COLOR, surface->output_name); /* if output layer is lost from a constructive modifier, re-add it */ if (!mloopcol && dynamicPaint_outputLayerExists(surface, ob, 0)) { - mloopcol = CustomData_add_layer_named( - &result->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, totloop, surface->output_name); + mloopcol = CustomData_add_layer_named(&result->ldata, + CD_PROP_BYTE_COLOR, + CD_CALLOC, + NULL, + totloop, + surface->output_name); } /* wet layer */ MLoopCol *mloopcol_wet = CustomData_get_layer_named( - &result->ldata, CD_MLOOPCOL, surface->output_name2); + &result->ldata, CD_PROP_BYTE_COLOR, surface->output_name2); /* if output layer is lost from a constructive modifier, re-add it */ if (!mloopcol_wet && dynamicPaint_outputLayerExists(surface, ob, 1)) { - mloopcol_wet = CustomData_add_layer_named( - &result->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, totloop, surface->output_name2); + mloopcol_wet = CustomData_add_layer_named(&result->ldata, + CD_PROP_BYTE_COLOR, + CD_CALLOC, + NULL, + totloop, + surface->output_name2); } data.ob = ob; @@ -2018,21 +2025,17 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object * settings.use_threading = (sData->total_points > 1000); BLI_task_parallel_range( 0, sData->total_points, &data, dynamic_paint_apply_surface_wave_cb, &settings); - update_normals = true; + BKE_mesh_normals_tag_dirty(mesh); } /* displace */ if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) { dynamicPaint_applySurfaceDisplace(surface, result); - update_normals = true; + BKE_mesh_normals_tag_dirty(mesh); } } } } - - if (update_normals) { - BKE_mesh_normals_tag_dirty(result); - } } /* make a copy of mesh to use as brush data */ else if (pmd->brush && pmd->type == MOD_DYNAMICPAINT_TYPE_BRUSH) { diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c index 81e73b6cf2c..5de13fbdbed 100644 --- a/source/blender/blenkernel/intern/fluid.c +++ b/source/blender/blenkernel/intern/fluid.c @@ -3537,7 +3537,6 @@ static Mesh *create_smoke_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Obje } BKE_mesh_calc_edges(result, false, false); - BKE_mesh_normals_tag_dirty(result); return result; } @@ -5071,6 +5070,9 @@ void BKE_fluid_modifier_copy(const struct FluidModifierData *fmd, tfds->openvdb_compression = fds->openvdb_compression; tfds->clipping = fds->clipping; tfds->openvdb_data_depth = fds->openvdb_data_depth; + + /* Render options. */ + tfds->velocity_scale = fds->velocity_scale; } else if (tfmd->flow) { FluidFlowSettings *tffs = tfmd->flow; diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc index 47f7bb00b8f..fb39861d3e7 100644 --- a/source/blender/blenkernel/intern/geometry_component_mesh.cc +++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc @@ -903,22 +903,6 @@ static void set_loop_uv(MLoopUV &uv, float2 co) copy_v2_v2(uv.uv, co); } -static ColorGeometry4f get_loop_color(const MLoopCol &col) -{ - ColorGeometry4b encoded_color = ColorGeometry4b(col.r, col.g, col.b, col.a); - ColorGeometry4f linear_color = encoded_color.decode(); - return linear_color; -} - -static void set_loop_color(MLoopCol &col, ColorGeometry4f linear_color) -{ - ColorGeometry4b encoded_color = linear_color.encode(); - col.r = encoded_color.r; - col.g = encoded_color.g; - col.b = encoded_color.b; - col.a = encoded_color.a; -} - static float get_crease(const MEdge &edge) { return edge.crease / 255.0f; @@ -1293,14 +1277,6 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() make_derived_read_attribute<MLoopUV, float2, get_loop_uv>, make_derived_write_attribute<MLoopUV, float2, get_loop_uv, set_loop_uv>); - static NamedLegacyCustomDataProvider vertex_colors( - ATTR_DOMAIN_CORNER, - CD_PROP_COLOR, - CD_MLOOPCOL, - corner_access, - make_derived_read_attribute<MLoopCol, ColorGeometry4f, get_loop_color>, - make_derived_write_attribute<MLoopCol, ColorGeometry4f, get_loop_color, set_loop_color>); - static VertexGroupsAttributeProvider vertex_groups; static CustomDataAttributeProvider corner_custom_data(ATTR_DOMAIN_CORNER, corner_access); static CustomDataAttributeProvider point_custom_data(ATTR_DOMAIN_POINT, point_access); @@ -1310,7 +1286,6 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() return ComponentAttributeProviders( {&position, &id, &material_index, &shade_smooth, &normal, &crease}, {&uvs, - &vertex_colors, &corner_custom_data, &vertex_groups, &point_custom_data, diff --git a/source/blender/blenkernel/intern/image.cc b/source/blender/blenkernel/intern/image.cc index 53ec148fd2d..dfa820519a5 100644 --- a/source/blender/blenkernel/intern/image.cc +++ b/source/blender/blenkernel/intern/image.cc @@ -829,10 +829,7 @@ ImageTile *BKE_image_get_tile_from_iuser(Image *ima, const ImageUser *iuser) return BKE_image_get_tile(ima, image_get_tile_number_from_iuser(ima, iuser)); } -int BKE_image_get_tile_from_pos(struct Image *ima, - const float uv[2], - float r_uv[2], - float r_ofs[2]) +int BKE_image_get_tile_from_pos(Image *ima, const float uv[2], float r_uv[2], float r_ofs[2]) { float local_ofs[2]; if (r_ofs == nullptr) { @@ -860,6 +857,18 @@ int BKE_image_get_tile_from_pos(struct Image *ima, return tile_number; } +void BKE_image_get_tile_uv(const Image *ima, const int tile_number, float r_uv[2]) +{ + if (ima->source != IMA_SRC_TILED) { + zero_v2(r_uv); + } + else { + const int tile_index = tile_number - 1001; + r_uv[0] = static_cast<float>(tile_index % 10); + r_uv[1] = static_cast<float>(tile_index / 10); + } +} + int BKE_image_find_nearest_tile(const Image *image, const float co[2]) { const float co_floor[2] = {floorf(co[0]), floorf(co[1])}; @@ -868,17 +877,15 @@ int BKE_image_find_nearest_tile(const Image *image, const float co[2]) int tile_number_best = -1; LISTBASE_FOREACH (const ImageTile *, tile, &image->tiles) { - const int tile_index = tile->tile_number - 1001; - /* Coordinates of the current tile. */ - const float tile_index_co[2] = {static_cast<float>(tile_index % 10), - static_cast<float>(tile_index / 10)}; + float uv_offset[2]; + BKE_image_get_tile_uv(image, tile->tile_number, uv_offset); - if (equals_v2v2(co_floor, tile_index_co)) { + if (equals_v2v2(co_floor, uv_offset)) { return tile->tile_number; } /* Distance between co[2] and UDIM tile. */ - const float dist_sq = len_squared_v2v2(tile_index_co, co); + const float dist_sq = len_squared_v2v2(uv_offset, co); if (dist_sq < dist_best_sq) { dist_best_sq = dist_sq; diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 4caaf314888..002b496393f 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -1943,6 +1943,8 @@ static void material_default_gpencil_init(Material *ma) static void material_default_surface_init(Material *ma) { + strcpy(ma->id.name, "MADefault Surface"); + bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname); ma->nodetree = ntree; ma->use_nodes = true; @@ -1969,6 +1971,8 @@ static void material_default_surface_init(Material *ma) static void material_default_volume_init(Material *ma) { + strcpy(ma->id.name, "MADefault Volume"); + bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname); ma->nodetree = ntree; ma->use_nodes = true; @@ -1992,6 +1996,8 @@ static void material_default_volume_init(Material *ma) static void material_default_holdout_init(Material *ma) { + strcpy(ma->id.name, "MADefault Holdout"); + bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname); ma->nodetree = ntree; ma->use_nodes = true; diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index 25d97d0bd3c..c13a2bc794a 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -463,7 +463,8 @@ static int customdata_compare( CustomDataLayer *l1, *l2; int layer_count1 = 0, layer_count2 = 0, j; const uint64_t cd_mask_non_generic = CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MPOLY | - CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MDEFORMVERT; + CD_MASK_MLOOPUV | CD_MASK_PROP_BYTE_COLOR | + CD_MASK_MDEFORMVERT; const uint64_t cd_mask_all_attr = CD_MASK_PROP_ALL | cd_mask_non_generic; for (int i = 0; i < c1->totlayer; i++) { @@ -581,7 +582,7 @@ static int customdata_compare( } break; } - case CD_MLOOPCOL: { + case CD_PROP_BYTE_COLOR: { MLoopCol *lp1 = (MLoopCol *)l1->data; MLoopCol *lp2 = (MLoopCol *)l2->data; int ltot = m1->totloop; @@ -768,7 +769,7 @@ static void mesh_ensure_tessellation_customdata(Mesh *me) } else { const int tottex_original = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); - const int totcol_original = CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL); + const int totcol_original = CustomData_number_of_layers(&me->ldata, CD_PROP_BYTE_COLOR); const int tottex_tessface = CustomData_number_of_layers(&me->fdata, CD_MTFACE); const int totcol_tessface = CustomData_number_of_layers(&me->fdata, CD_MCOL); @@ -786,7 +787,8 @@ static void mesh_ensure_tessellation_customdata(Mesh *me) * 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 != CD_MLOOPCOL: " + "had to reset!\n CD_MTFACE: %d != CD_MLOOPUV: %d || CD_MCOL: %d != " + "CD_PROP_BYTE_COLOR: " "%d\n", __func__, tottex_tessface, @@ -871,7 +873,7 @@ bool BKE_mesh_clear_facemap_customdata(struct Mesh *me) /** * This ensures grouped custom-data (e.g. #CD_MLOOPUV and #CD_MTFACE, or - * #CD_MLOOPCOL and #CD_MCOL) have the same relative active/render/clone/mask indices. + * #CD_PROP_BYTE_COLOR and #CD_MCOL) have the same relative active/render/clone/mask indices. * * NOTE(@campbellbarton): that for undo mesh data we want to skip 'ensure_tess_cd' call since * we don't want to store memory for #MFace data when its only used for older @@ -902,7 +904,7 @@ void BKE_mesh_update_customdata_pointers(Mesh *me, const bool do_ensure_tess_cd) me->mpoly = (MPoly *)CustomData_get_layer(&me->pdata, CD_MPOLY); me->mloop = (MLoop *)CustomData_get_layer(&me->ldata, CD_MLOOP); - me->mloopcol = (MLoopCol *)CustomData_get_layer(&me->ldata, CD_MLOOPCOL); + me->mloopcol = (MLoopCol *)CustomData_get_layer(&me->ldata, CD_PROP_BYTE_COLOR); me->mloopuv = (MLoopUV *)CustomData_get_layer(&me->ldata, CD_MLOOPUV); } @@ -1112,6 +1114,9 @@ Mesh *BKE_mesh_new_nomain_from_template_ex(const Mesh *me_src, mesh_ensure_cdlayers_primary(me_dst, do_tessface); BKE_mesh_update_customdata_pointers(me_dst, false); + /* Expect that normals aren't copied at all, since the destination mesh is new. */ + BLI_assert(BKE_mesh_vertex_normals_are_dirty(me_dst)); + return me_dst; } @@ -1688,6 +1693,7 @@ void BKE_mesh_transform(Mesh *me, const float mat[4][4], bool do_keys) mul_m3_v3(m3, *lnors); } } + BKE_mesh_normals_tag_dirty(me); } void BKE_mesh_translate(Mesh *me, const float offset[3], const bool do_keys) diff --git a/source/blender/blenkernel/intern/mesh_boolean_convert.cc b/source/blender/blenkernel/intern/mesh_boolean_convert.cc index eee1d3b9eec..3fcacb31b24 100644 --- a/source/blender/blenkernel/intern/mesh_boolean_convert.cc +++ b/source/blender/blenkernel/intern/mesh_boolean_convert.cc @@ -782,7 +782,6 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim) } } - BKE_mesh_calc_normals(result); if (dbg_level > 0) { BKE_mesh_validate(result, true, true); } diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc index ff953ef5b46..a289d208684 100644 --- a/source/blender/blenkernel/intern/mesh_convert.cc +++ b/source/blender/blenkernel/intern/mesh_convert.cc @@ -120,9 +120,6 @@ void BKE_mesh_from_metaball(ListBase *lb, Mesh *me) } BKE_mesh_update_customdata_pointers(me, true); - - BKE_mesh_normals_tag_dirty(me); - BKE_mesh_calc_edges(me, true, false); } } @@ -514,7 +511,6 @@ Mesh *BKE_mesh_new_nomain_from_curve_displist(const Object *ob, const ListBase * } mesh = BKE_mesh_new_nomain(totvert, totedge, 0, totloop, totpoly); - BKE_mesh_normals_tag_dirty(mesh); if (totvert != 0) { memcpy(mesh->mvert, allvert, totvert * sizeof(MVert)); diff --git a/source/blender/blenkernel/intern/mesh_evaluate.cc b/source/blender/blenkernel/intern/mesh_evaluate.cc index 6c5a5de31fc..ec2660a0145 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.cc +++ b/source/blender/blenkernel/intern/mesh_evaluate.cc @@ -661,7 +661,7 @@ static void bm_corners_to_loops_ex(ID *id, } for (int i = 0; i < numCol; i++) { - MLoopCol *mloopcol = (MLoopCol *)CustomData_get_n(ldata, CD_MLOOPCOL, loopstart, i); + MLoopCol *mloopcol = (MLoopCol *)CustomData_get_n(ldata, CD_PROP_BYTE_COLOR, loopstart, i); MCol *mcol = (MCol *)CustomData_get_n(fdata, CD_MCOL, findex, i); MESH_MLOOPCOL_FROM_MCOL(mloopcol, &mcol[0]); diff --git a/source/blender/blenkernel/intern/mesh_remap.c b/source/blender/blenkernel/intern/mesh_remap.c index 2e634a14872..3a37c29c1d0 100644 --- a/source/blender/blenkernel/intern/mesh_remap.c +++ b/source/blender/blenkernel/intern/mesh_remap.c @@ -478,6 +478,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode, const int numverts_dst, const bool UNUSED(dirty_nors_dst), Mesh *me_src, + Mesh *me_dst, MeshPairRemap *r_map) { const float full_weight = 1.0f; @@ -580,7 +581,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode, MPoly *polys_src = me_src->mpoly; MLoop *loops_src = me_src->mloop; float(*vcos_src)[3] = BKE_mesh_vert_coords_alloc(me_src, NULL); - const float(*vert_normals_src)[3] = BKE_mesh_vertex_normals_ensure(me_src); + const float(*vert_normals_dst)[3] = BKE_mesh_vertex_normals_ensure(me_dst); size_t tmp_buff_size = MREMAP_DEFAULT_BUFSIZE; float(*vcos)[3] = MEM_mallocN(sizeof(*vcos) * tmp_buff_size, __func__); @@ -592,7 +593,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode, if (mode == MREMAP_MODE_VERT_POLYINTERP_VNORPROJ) { for (i = 0; i < numverts_dst; i++) { copy_v3_v3(tmp_co, verts_dst[i].co); - copy_v3_v3(tmp_no, vert_normals_src[i]); + copy_v3_v3(tmp_no, vert_normals_dst[i]); /* Convert the vertex to tree coordinates, if needed. */ if (space_transform) { @@ -703,6 +704,7 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode, const int numedges_dst, const bool UNUSED(dirty_nors_dst), Mesh *me_src, + Mesh *me_dst, MeshPairRemap *r_map) { const float full_weight = 1.0f; @@ -938,7 +940,7 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode, BKE_bvhtree_from_mesh_get(&treedata, me_src, BVHTREE_FROM_EDGES, 2); - const float(*vert_normals_dst)[3] = BKE_mesh_vertex_normals_ensure(me_src); + const float(*vert_normals_dst)[3] = BKE_mesh_vertex_normals_ensure(me_dst); for (i = 0; i < numedges_dst; i++) { /* For each dst edge, we sample some rays from it (interpolated from its vertices) diff --git a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc index 7be4a6f2f94..02c9f61957d 100644 --- a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc +++ b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc @@ -140,7 +140,6 @@ static Mesh *remesh_quadriflow(const Mesh *input_mesh, } BKE_mesh_calc_edges(mesh, false, false); - BKE_mesh_calc_normals(mesh); MEM_freeN(qrd.out_faces); MEM_freeN(qrd.out_verts); @@ -257,7 +256,6 @@ static Mesh *remesh_voxel_volume_to_mesh(const openvdb::FloatGrid::Ptr level_set } BKE_mesh_calc_edges(mesh, false, false); - BKE_mesh_normals_tag_dirty(mesh); return mesh; } diff --git a/source/blender/blenkernel/intern/mesh_tessellate.c b/source/blender/blenkernel/intern/mesh_tessellate.c index ae52e31cb9b..ea3cc043267 100644 --- a/source/blender/blenkernel/intern/mesh_tessellate.c +++ b/source/blender/blenkernel/intern/mesh_tessellate.c @@ -58,7 +58,7 @@ static void mesh_loops_to_tessdata(CustomData *fdata, * The issue is, unless having two different functions with nearly the same code, * there's not much ways to solve this. Better IMHO to live with it for now (sigh). */ const int numUV = CustomData_number_of_layers(ldata, CD_MLOOPUV); - const int numCol = CustomData_number_of_layers(ldata, CD_MLOOPCOL); + const int numCol = CustomData_number_of_layers(ldata, CD_PROP_BYTE_COLOR); const bool hasPCol = CustomData_has_layer(ldata, CD_PREVIEW_MLOOPCOL); const bool hasOrigSpace = CustomData_has_layer(ldata, CD_ORIGSPACE_MLOOP); const bool hasLoopNormal = CustomData_has_layer(ldata, CD_NORMAL); @@ -81,7 +81,7 @@ static void mesh_loops_to_tessdata(CustomData *fdata, for (i = 0; i < numCol; i++) { MCol(*mcol)[4] = CustomData_get_layer_n(fdata, CD_MCOL, i); - MLoopCol *mloopcol = CustomData_get_layer_n(ldata, CD_MLOOPCOL, i); + MLoopCol *mloopcol = CustomData_get_layer_n(ldata, CD_PROP_BYTE_COLOR, i); for (findex = 0, lidx = loopindices; findex < num_faces; lidx++, findex++, mcol++) { for (j = (mface ? mface[findex].v4 : (*lidx)[3]) ? 4 : 3; j--;) { diff --git a/source/blender/blenkernel/intern/mesh_validate.cc b/source/blender/blenkernel/intern/mesh_validate.cc index 6af765d7de5..d16f7eaf588 100644 --- a/source/blender/blenkernel/intern/mesh_validate.cc +++ b/source/blender/blenkernel/intern/mesh_validate.cc @@ -1017,7 +1017,7 @@ bool BKE_mesh_validate_all_customdata(CustomData *vdata, pdata, mask.pmask, totpoly, do_verbose, do_fixes, &is_change_p); const int tot_uvloop = CustomData_number_of_layers(ldata, CD_MLOOPUV); - const int tot_vcolloop = CustomData_number_of_layers(ldata, CD_MLOOPCOL); + const int tot_vcolloop = CustomData_number_of_layers(ldata, CD_PROP_BYTE_COLOR); if (tot_uvloop > MAX_MTFACE) { PRINT_ERR( "\tMore UV layers than %d allowed, %d last ones won't be available for render, shaders, " diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index f4703b32582..e7ee8caf0eb 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -944,8 +944,10 @@ static void modwrap_dependsOnNormals(Mesh *me) break; } case ME_WRAPPER_TYPE_SUBD: + /* Not an expected case. */ + break; case ME_WRAPPER_TYPE_MDATA: - BKE_mesh_calc_normals(me); + /* Normals are calculated lazily. */ break; } } @@ -992,7 +994,7 @@ void BKE_modifier_deform_vertsEM(ModifierData *md, { const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type); if (me && mti->dependsOnNormals && mti->dependsOnNormals(md)) { - BKE_mesh_calc_normals(me); + modwrap_dependsOnNormals(me); } mti->deformVertsEM(md, ctx, em, me, vertexCos, numVerts); } diff --git a/source/blender/blenkernel/intern/multires_reshape_apply_base.c b/source/blender/blenkernel/intern/multires_reshape_apply_base.c index 65ba7b64d83..837b64affa8 100644 --- a/source/blender/blenkernel/intern/multires_reshape_apply_base.c +++ b/source/blender/blenkernel/intern/multires_reshape_apply_base.c @@ -156,7 +156,7 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape /* Vertices were moved around, need to update normals after all the vertices are updated * Probably this is possible to do in the loop above, but this is rather tricky because * we don't know all needed vertices' coordinates there yet. */ - BKE_mesh_calc_normals(base_mesh); + BKE_mesh_normals_tag_dirty(base_mesh); } void multires_reshape_apply_base_refine_from_base(MultiresReshapeContext *reshape_context) diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc index 5ff1f6b950f..948064ad170 100644 --- a/source/blender/blenkernel/intern/object.cc +++ b/source/blender/blenkernel/intern/object.cc @@ -1789,6 +1789,7 @@ void BKE_object_free_derived_caches(Object *ob) BKE_mesh_eval_delete((Mesh *)data_eval); } else { + BKE_libblock_free_data(data_eval, false); BKE_libblock_free_datablock(data_eval, 0); MEM_freeN(data_eval); } @@ -3564,19 +3565,19 @@ void BKE_object_apply_parent_inverse(struct Object *ob) * Use parent's world transform as the child's origin. * * Let: - * local = identity - * world = orthonormalized(parent) + * `local = identity` + * `world = orthonormalized(parent)` * * Then: - * world = parent @ parentinv @ local - * inv(parent) @ world = parentinv - * parentinv = inv(parent) @ world + * `world = parent @ parentinv @ local` + * `inv(parent) @ world = parentinv` + * `parentinv = inv(parent) @ world` * - * NOTE: If ob->obmat has shear, then this `parentinv` is insufficient because - * parent @ parentinv => shearless result + * NOTE: If `ob->obmat` has shear, then this `parentinv` is insufficient because + * `parent @ parentinv => shearless result` * * Thus, local will have shear which cannot be decomposed into TRS: - * local = inv(parent @ parentinv) @ world + * `local = inv(parent @ parentinv) @ world` * * This is currently not supported for consistency in the handling of shear during the other * parenting ops: Parent (Keep Transform), Clear [Parent] and Keep Transform. @@ -3591,11 +3592,11 @@ void BKE_object_apply_parent_inverse(struct Object *ob) /* Now, preserve `world` given the new `parentinv`. * - * world = parent @ parentinv @ local - * inv(parent) @ world = parentinv @ local - * inv(parentinv) @ inv(parent) @ world = local + * `world = parent @ parentinv @ local` + * `inv(parent) @ world = parentinv @ local` + * `inv(parentinv) @ inv(parent) @ world = local` * - * local = inv(parentinv) @ inv(parent) @ world + * `local = inv(parentinv) @ inv(parent) @ world` */ float ob_local[4][4]; copy_m4_m4(ob_local, ob->parentinv); @@ -3974,8 +3975,9 @@ bool BKE_object_empty_image_data_is_visible_in_view3d(const Object *ob, const Re } if (visibility_flag & OB_EMPTY_IMAGE_HIDE_NON_AXIS_ALIGNED) { - float3 proj; - project_plane_v3_v3v3(proj, ob->obmat[2], rv3d->viewinv[2]); + float3 proj, ob_z_axis; + normalize_v3_v3(ob_z_axis, ob->obmat[2]); + project_plane_v3_v3v3(proj, ob_z_axis, rv3d->viewinv[2]); const float proj_length_sq = len_squared_v3(proj); if (proj_length_sq > 1e-5f) { return false; diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c index fbbd429f58a..f41d59c77ba 100644 --- a/source/blender/blenkernel/intern/object_update.c +++ b/source/blender/blenkernel/intern/object_update.c @@ -167,7 +167,7 @@ void BKE_object_handle_data_update(Depsgraph *depsgraph, Scene *scene, Object *o #endif if (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER) { /* Always compute UVs, vertex colors as orcos for render. */ - cddata_masks.lmask |= CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL; + cddata_masks.lmask |= CD_MASK_MLOOPUV | CD_MASK_PROP_BYTE_COLOR; cddata_masks.vmask |= CD_MASK_ORCO | CD_MASK_PROP_COLOR; } makeDerivedMesh(depsgraph, scene, ob, &cddata_masks); /* was CD_MASK_BAREMESH */ diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index 5fd7984ea90..0f523d87d9b 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -1101,7 +1101,6 @@ bool BKE_paint_ensure(ToolSettings *ts, struct Paint **r_paint) } else if ((CurvesSculpt **)r_paint == &ts->curves_sculpt) { CurvesSculpt *data = MEM_callocN(sizeof(*data), __func__); - data->curve_length = 0.3f; paint = &data->paint; } else if (*r_paint == &ts->imapaint.paint) { @@ -1341,8 +1340,6 @@ void BKE_sculptsession_free_vwpaint_data(struct SculptSession *ss) struct SculptVertexPaintGeomMap *gmap = NULL; if (ss->mode_type == OB_MODE_VERTEX_PAINT) { gmap = &ss->mode.vpaint.gmap; - - MEM_SAFE_FREE(ss->mode.vpaint.previous_color); } else if (ss->mode_type == OB_MODE_WEIGHT_PAINT) { gmap = &ss->mode.wpaint.gmap; @@ -1845,7 +1842,7 @@ void BKE_sculpt_color_layer_create_if_needed(struct Object *object) { Mesh *orig_me = BKE_object_get_original_mesh(object); - int types[] = {CD_PROP_COLOR, CD_MLOOPCOL}; + int types[] = {CD_PROP_COLOR, CD_PROP_BYTE_COLOR}; bool has_color = false; for (int i = 0; i < ARRAY_SIZE(types); i++) { diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index e91f360ef22..1fb1570b3ff 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -1267,7 +1267,7 @@ bool BKE_pbvh_get_color_layer(const Mesh *me, CustomDataLayer **r_layer, Attribu { CustomDataLayer *layer = BKE_id_attributes_active_color_get((ID *)me); - if (!layer || !ELEM(layer->type, CD_PROP_COLOR, CD_MLOOPCOL)) { + if (!layer || !ELEM(layer->type, CD_PROP_COLOR, CD_PROP_BYTE_COLOR)) { *r_layer = NULL; *r_attr = ATTR_DOMAIN_NUM; return false; diff --git a/source/blender/blenkernel/intern/pbvh.cc b/source/blender/blenkernel/intern/pbvh.cc index d32a03186e3..be6e95426c2 100644 --- a/source/blender/blenkernel/intern/pbvh.cc +++ b/source/blender/blenkernel/intern/pbvh.cc @@ -50,7 +50,7 @@ inline void to_static_color_type(const CustomDataType type, const Func &func) case CD_PROP_COLOR: func(MPropCol()); break; - case CD_MLOOPCOL: + case CD_PROP_BYTE_COLOR: func(MLoopCol()); break; default: diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c index 6a135c248ce..55d76938ad3 100644 --- a/source/blender/blenkernel/intern/pbvh_bmesh.c +++ b/source/blender/blenkernel/intern/pbvh_bmesh.c @@ -1240,7 +1240,7 @@ static bool pbvh_bmesh_subdivide_long_edges(EdgeQueueContext *eq_ctx, EDGE_QUEUE_DISABLE(e); #endif - /* At the moment edges never get shorter (subdiv will make new edges) + /* At the moment edges never get shorter (subdivision will make new edges) * unlike collapse where edges can become longer. */ #if 0 if (len_squared_v3v3(v1->co, v2->co) <= eq_ctx->q->limit_len_squared) { diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h index 77bd00da50a..b7a2b578a1c 100644 --- a/source/blender/blenkernel/intern/pbvh_intern.h +++ b/source/blender/blenkernel/intern/pbvh_intern.h @@ -267,6 +267,7 @@ bool pbvh_bmesh_node_nearest_to_ray(PBVHNode *node, void pbvh_bmesh_normals_update(PBVHNode **nodes, int totnode); /* pbvh_pixels.hh */ + void pbvh_pixels_free(PBVHNode *node); void pbvh_pixels_free_brush_test(PBVHNode *node); diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc index d8dd2f4b382..5623cac44ac 100644 --- a/source/blender/blenkernel/intern/pbvh_pixels.cc +++ b/source/blender/blenkernel/intern/pbvh_pixels.cc @@ -22,12 +22,14 @@ namespace blender::bke::pbvh::pixels { -/** Durind debugging this check could be enabled. It will write to each image pixel that is covered - * by the pbvh. */ +/** + * During debugging this check could be enabled. + * It will write to each image pixel that is covered by the PBVH. + */ constexpr bool USE_WATERTIGHT_CHECK = false; /** - * Calculate the delta of two neighbour uv coordinates in the given image buffer. + * Calculate the delta of two neighbor UV coordinates in the given image buffer. */ static float2 calc_barycentric_delta(const float2 uvs[3], const float2 start_uv, @@ -273,11 +275,7 @@ static void apply_watertight_check(PBVH *pbvh, Image *image, ImageUser *image_us BKE_image_partial_update_mark_full_update(image); } -static void update_pixels(PBVH *pbvh, - const struct MLoop *mloop, - struct CustomData *ldata, - struct Image *image, - struct ImageUser *image_user) +static void update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image_user) { Vector<PBVHNode *> nodes_to_update; @@ -285,14 +283,14 @@ static void update_pixels(PBVH *pbvh, return; } - MLoopUV *ldata_uv = static_cast<MLoopUV *>(CustomData_get_layer(ldata, CD_MLOOPUV)); + MLoopUV *ldata_uv = static_cast<MLoopUV *>(CustomData_get_layer(&mesh->ldata, CD_MLOOPUV)); if (ldata_uv == nullptr) { return; } for (PBVHNode *node : nodes_to_update) { NodeData *node_data = static_cast<NodeData *>(node->pixels.node_data); - init_triangles(pbvh, node, node_data, mloop); + init_triangles(pbvh, node, node_data, mesh->mloop); } EncodePixelsUserData user_data; @@ -375,13 +373,9 @@ void BKE_pbvh_pixels_mark_image_dirty(PBVHNode &node, Image &image, ImageUser &i extern "C" { using namespace blender::bke::pbvh::pixels; -void BKE_pbvh_build_pixels(PBVH *pbvh, - const struct MLoop *mloop, - struct CustomData *ldata, - struct Image *image, - struct ImageUser *image_user) +void BKE_pbvh_build_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image_user) { - update_pixels(pbvh, mloop, ldata, image, image_user); + update_pixels(pbvh, mesh, image, image_user); } void pbvh_pixels_free(PBVHNode *node) diff --git a/source/blender/blenkernel/intern/subdiv_mesh.c b/source/blender/blenkernel/intern/subdiv_mesh.c index 83e4336e3b1..83427adcb43 100644 --- a/source/blender/blenkernel/intern/subdiv_mesh.c +++ b/source/blender/blenkernel/intern/subdiv_mesh.c @@ -1155,7 +1155,7 @@ Mesh *BKE_subdiv_to_mesh(Subdiv *subdiv, * calculation. Since vertex normals are supposed to be a consistent cache, don't bother * calculating them here. The work may have been pointless anyway if the mesh is deformed or * changed afterwards. */ - BKE_mesh_normals_tag_dirty(result); + BLI_assert(BKE_mesh_vertex_normals_are_dirty(result) || BKE_mesh_poly_normals_are_dirty(result)); /* Free used memory. */ subdiv_mesh_context_free(&subdiv_context); return result; diff --git a/source/blender/blenkernel/intern/type_conversions.cc b/source/blender/blenkernel/intern/type_conversions.cc index e84ec5b3890..1c2665769db 100644 --- a/source/blender/blenkernel/intern/type_conversions.cc +++ b/source/blender/blenkernel/intern/type_conversions.cc @@ -2,6 +2,8 @@ #include "BKE_type_conversions.hh" +#include "DNA_meshdata_types.h" + #include "FN_multi_function_builder.hh" #include "BLI_color.hh" @@ -61,6 +63,10 @@ static ColorGeometry4f float_to_color(const float &a) { return ColorGeometry4f(a, a, a, 1.0f); } +static ColorGeometry4b float_to_byte_color(const float &a) +{ + return float_to_color(a).encode(); +} static float3 float2_to_float3(const float2 &a) { @@ -86,6 +92,10 @@ static ColorGeometry4f float2_to_color(const float2 &a) { return ColorGeometry4f(a.x, a.y, 0.0f, 1.0f); } +static ColorGeometry4b float2_to_byte_color(const float2 &a) +{ + return float2_to_color(a).encode(); +} static bool float3_to_bool(const float3 &a) { @@ -111,6 +121,10 @@ static ColorGeometry4f float3_to_color(const float3 &a) { return ColorGeometry4f(a.x, a.y, a.z, 1.0f); } +static ColorGeometry4b float3_to_byte_color(const float3 &a) +{ + return float3_to_color(a).encode(); +} static bool int_to_bool(const int32_t &a) { @@ -137,6 +151,10 @@ static ColorGeometry4f int_to_color(const int32_t &a) { return ColorGeometry4f((float)a, (float)a, (float)a, 1.0f); } +static ColorGeometry4b int_to_byte_color(const int32_t &a) +{ + return int_to_color(a).encode(); +} static bool int8_to_bool(const int8_t &a) { @@ -162,6 +180,10 @@ static ColorGeometry4f int8_to_color(const int8_t &a) { return ColorGeometry4f((float)a, (float)a, (float)a, 1.0f); } +static ColorGeometry4b int8_to_byte_color(const int8_t &a) +{ + return int8_to_color(a).encode(); +} static float bool_to_float(const bool &a) { @@ -187,6 +209,10 @@ static ColorGeometry4f bool_to_color(const bool &a) { return (a) ? ColorGeometry4f(1.0f, 1.0f, 1.0f, 1.0f) : ColorGeometry4f(0.0f, 0.0f, 0.0f, 1.0f); } +static ColorGeometry4b bool_to_byte_color(const bool &a) +{ + return bool_to_color(a).encode(); +} static bool color_to_bool(const ColorGeometry4f &a) { @@ -212,6 +238,39 @@ static float3 color_to_float3(const ColorGeometry4f &a) { return float3(a.r, a.g, a.b); } +static ColorGeometry4b color_to_byte_color(const ColorGeometry4f &a) +{ + return a.encode(); +} + +static bool byte_color_to_bool(const ColorGeometry4b &a) +{ + return a.r > 0 || a.g > 0 || a.b > 0; +} +static float byte_color_to_float(const ColorGeometry4b &a) +{ + return color_to_float(a.decode()); +} +static int32_t byte_color_to_int(const ColorGeometry4b &a) +{ + return color_to_int(a.decode()); +} +static int8_t byte_color_to_int8(const ColorGeometry4b &a) +{ + return color_to_int8(a.decode()); +} +static float2 byte_color_to_float2(const ColorGeometry4b &a) +{ + return color_to_float2(a.decode()); +} +static float3 byte_color_to_float3(const ColorGeometry4b &a) +{ + return color_to_float3(a.decode()); +} +static ColorGeometry4f byte_color_to_color(const ColorGeometry4b &a) +{ + return a.decode(); +} static DataTypeConversions create_implicit_conversions() { @@ -223,6 +282,7 @@ static DataTypeConversions create_implicit_conversions() add_implicit_conversion<float, bool, float_to_bool>(conversions); add_implicit_conversion<float, int8_t, float_to_int8>(conversions); add_implicit_conversion<float, ColorGeometry4f, float_to_color>(conversions); + add_implicit_conversion<float, ColorGeometry4b, float_to_byte_color>(conversions); add_implicit_conversion<float2, float3, float2_to_float3>(conversions); add_implicit_conversion<float2, float, float2_to_float>(conversions); @@ -230,6 +290,7 @@ static DataTypeConversions create_implicit_conversions() add_implicit_conversion<float2, bool, float2_to_bool>(conversions); add_implicit_conversion<float2, int8_t, float2_to_int8>(conversions); add_implicit_conversion<float2, ColorGeometry4f, float2_to_color>(conversions); + add_implicit_conversion<float2, ColorGeometry4b, float2_to_byte_color>(conversions); add_implicit_conversion<float3, bool, float3_to_bool>(conversions); add_implicit_conversion<float3, int8_t, float3_to_int8>(conversions); @@ -237,6 +298,7 @@ static DataTypeConversions create_implicit_conversions() add_implicit_conversion<float3, int32_t, float3_to_int>(conversions); add_implicit_conversion<float3, float2, float3_to_float2>(conversions); add_implicit_conversion<float3, ColorGeometry4f, float3_to_color>(conversions); + add_implicit_conversion<float3, ColorGeometry4b, float3_to_byte_color>(conversions); add_implicit_conversion<int32_t, bool, int_to_bool>(conversions); add_implicit_conversion<int32_t, int8_t, int_to_int8>(conversions); @@ -244,6 +306,7 @@ static DataTypeConversions create_implicit_conversions() add_implicit_conversion<int32_t, float2, int_to_float2>(conversions); add_implicit_conversion<int32_t, float3, int_to_float3>(conversions); add_implicit_conversion<int32_t, ColorGeometry4f, int_to_color>(conversions); + add_implicit_conversion<int32_t, ColorGeometry4b, int_to_byte_color>(conversions); add_implicit_conversion<int8_t, bool, int8_to_bool>(conversions); add_implicit_conversion<int8_t, int32_t, int8_to_int>(conversions); @@ -251,6 +314,7 @@ static DataTypeConversions create_implicit_conversions() add_implicit_conversion<int8_t, float2, int8_to_float2>(conversions); add_implicit_conversion<int8_t, float3, int8_to_float3>(conversions); add_implicit_conversion<int8_t, ColorGeometry4f, int8_to_color>(conversions); + add_implicit_conversion<int8_t, ColorGeometry4b, int8_to_byte_color>(conversions); add_implicit_conversion<bool, float, bool_to_float>(conversions); add_implicit_conversion<bool, int8_t, bool_to_int8>(conversions); @@ -258,6 +322,7 @@ static DataTypeConversions create_implicit_conversions() add_implicit_conversion<bool, float2, bool_to_float2>(conversions); add_implicit_conversion<bool, float3, bool_to_float3>(conversions); add_implicit_conversion<bool, ColorGeometry4f, bool_to_color>(conversions); + add_implicit_conversion<bool, ColorGeometry4b, bool_to_byte_color>(conversions); add_implicit_conversion<ColorGeometry4f, bool, color_to_bool>(conversions); add_implicit_conversion<ColorGeometry4f, int8_t, color_to_int8>(conversions); @@ -265,6 +330,15 @@ static DataTypeConversions create_implicit_conversions() add_implicit_conversion<ColorGeometry4f, int32_t, color_to_int>(conversions); add_implicit_conversion<ColorGeometry4f, float2, color_to_float2>(conversions); add_implicit_conversion<ColorGeometry4f, float3, color_to_float3>(conversions); + add_implicit_conversion<ColorGeometry4f, ColorGeometry4b, color_to_byte_color>(conversions); + + add_implicit_conversion<ColorGeometry4b, bool, byte_color_to_bool>(conversions); + add_implicit_conversion<ColorGeometry4b, int8_t, byte_color_to_int8>(conversions); + add_implicit_conversion<ColorGeometry4b, float, byte_color_to_float>(conversions); + add_implicit_conversion<ColorGeometry4b, int32_t, byte_color_to_int>(conversions); + add_implicit_conversion<ColorGeometry4b, float2, byte_color_to_float2>(conversions); + add_implicit_conversion<ColorGeometry4b, float3, byte_color_to_float3>(conversions); + add_implicit_conversion<ColorGeometry4b, ColorGeometry4f, byte_color_to_color>(conversions); return conversions; } @@ -411,4 +485,19 @@ GVMutableArray DataTypeConversions::try_convert(GVMutableArray varray, std::move(varray), to_type, *this); } +fn::GField DataTypeConversions::try_convert(fn::GField field, const CPPType &to_type) const +{ + const CPPType &from_type = field.cpp_type(); + if (from_type == to_type) { + return field; + } + 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)); + return {std::make_shared<fn::FieldOperation>(fn, Vector<fn::GField>{std::move(field)})}; +} + } // namespace blender::bke diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc index 0c131863edd..307466d7dc9 100644 --- a/source/blender/blenkernel/intern/volume.cc +++ b/source/blender/blenkernel/intern/volume.cc @@ -60,6 +60,7 @@ using blender::float3; using blender::float4x4; using blender::IndexRange; using blender::StringRef; +using blender::StringRefNull; #ifdef WITH_OPENVDB # include <atomic> @@ -517,6 +518,8 @@ static void volume_init_data(ID *id) MEMCPY_STRUCT_AFTER(volume, DNA_struct_default_get(Volume), id); BKE_volume_init_grids(volume); + + BLI_strncpy(volume->velocity_grid, "velocity", sizeof(volume->velocity_grid)); } static void volume_copy_data(Main *UNUSED(bmain), @@ -794,6 +797,57 @@ bool BKE_volume_is_loaded(const Volume *volume) #endif } +bool BKE_volume_set_velocity_grid_by_name(Volume *volume, const char *base_name) +{ + const StringRefNull ref_base_name = base_name; + + if (BKE_volume_grid_find_for_read(volume, base_name)) { + BLI_strncpy(volume->velocity_grid, base_name, sizeof(volume->velocity_grid)); + volume->runtime.velocity_x_grid[0] = '\0'; + volume->runtime.velocity_y_grid[0] = '\0'; + volume->runtime.velocity_z_grid[0] = '\0'; + return true; + } + + /* It could be that the velocity grid is split in multiple grids, try with known postfixes. */ + const StringRefNull postfixes[][3] = {{"x", "y", "z"}, {".x", ".y", ".z"}, {"_x", "_y", "_z"}}; + + for (const StringRefNull *postfix : postfixes) { + bool found = true; + for (int i = 0; i < 3; i++) { + std::string post_fixed_name = ref_base_name + postfix[i]; + if (!BKE_volume_grid_find_for_read(volume, post_fixed_name.c_str())) { + found = false; + break; + } + } + + if (!found) { + continue; + } + + /* Save the base name as well. */ + BLI_strncpy(volume->velocity_grid, base_name, sizeof(volume->velocity_grid)); + BLI_strncpy(volume->runtime.velocity_x_grid, + (ref_base_name + postfix[0]).c_str(), + sizeof(volume->runtime.velocity_x_grid)); + BLI_strncpy(volume->runtime.velocity_y_grid, + (ref_base_name + postfix[1]).c_str(), + sizeof(volume->runtime.velocity_y_grid)); + BLI_strncpy(volume->runtime.velocity_z_grid, + (ref_base_name + postfix[2]).c_str(), + sizeof(volume->runtime.velocity_z_grid)); + return true; + } + + /* Reset to avoid potential issues. */ + volume->velocity_grid[0] = '\0'; + volume->runtime.velocity_x_grid[0] = '\0'; + volume->runtime.velocity_y_grid[0] = '\0'; + volume->runtime.velocity_z_grid[0] = '\0'; + return false; +} + bool BKE_volume_load(const Volume *volume, const Main *bmain) { #ifdef WITH_OPENVDB @@ -857,6 +911,14 @@ bool BKE_volume_load(const Volume *volume, const Main *bmain) } } + /* Try to detect the velocity grid. */ + const char *common_velocity_names[] = {"velocity", "vel", "v"}; + for (const char *common_velocity_name : common_velocity_names) { + if (BKE_volume_set_velocity_grid_by_name(const_cast<Volume *>(volume), common_velocity_name)) { + break; + } + } + BLI_strncpy(grids.filepath, filepath, FILE_MAX); return grids.error_msg.empty(); diff --git a/source/blender/blenkernel/intern/volume_to_mesh.cc b/source/blender/blenkernel/intern/volume_to_mesh.cc index 8544d6c9c77..ef75d3d2482 100644 --- a/source/blender/blenkernel/intern/volume_to_mesh.cc +++ b/source/blender/blenkernel/intern/volume_to_mesh.cc @@ -183,7 +183,6 @@ Mesh *volume_to_mesh(const openvdb::GridBase &grid, {mesh->mloop, mesh->totloop}); BKE_mesh_calc_edges(mesh, false, false); - BKE_mesh_normals_tag_dirty(mesh); return mesh; } |