diff options
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r-- | source/blender/blenkernel/intern/action.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/attribute_access.cc | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/colortools.c | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/cryptomatte.cc | 26 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/cryptomatte_test.cc | 13 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh_boolean_convert.cc | 71 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/node.cc | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/node_ui_storage.cc | 16 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/paint.c | 13 |
9 files changed, 102 insertions, 53 deletions
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 06b8bd5f0f2..f9c2a4e53ad 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -2002,7 +2002,7 @@ void BKE_pose_blend_read_lib(BlendLibReader *reader, Object *ob, bPose *pose) IDP_BlendReadLib(reader, pchan->prop); - BLO_read_id_address(reader, arm->id.lib, &pchan->custom); + BLO_read_id_address(reader, ob->id.lib, &pchan->custom); if (UNLIKELY(pchan->bone == NULL)) { rebuild = true; } diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc index 8974190d0e3..aeb7fba47e8 100644 --- a/source/blender/blenkernel/intern/attribute_access.cc +++ b/source/blender/blenkernel/intern/attribute_access.cc @@ -1886,7 +1886,7 @@ OutputAttributePtr GeometryComponent::attribute_try_get_for_output(const StringR if (!attribute) { this->attribute_try_create(attribute_name, domain, data_type); attribute = this->attribute_try_get_for_write(attribute_name); - if (default_value != nullptr) { + if (attribute && default_value != nullptr) { void *data = attribute->get_span_for_write_only().data(); cpp_type->fill_initialized(default_value, data, attribute->size()); attribute->apply_span(); diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index 3eb9fb6161d..44d9bd6b2d2 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -965,6 +965,12 @@ void BKE_curvemapping_changed_all(CurveMapping *cumap) cumap->cur = cur; } +/* Reset the view for current curve. */ +void BKE_curvemapping_reset_view(CurveMapping *cumap) +{ + cumap->curr = cumap->clipr; +} + /* table should be verified */ float BKE_curvemap_evaluateF(const CurveMapping *cumap, const CurveMap *cuma, float value) { diff --git a/source/blender/blenkernel/intern/cryptomatte.cc b/source/blender/blenkernel/intern/cryptomatte.cc index a20c53ed270..9d9cace3a35 100644 --- a/source/blender/blenkernel/intern/cryptomatte.cc +++ b/source/blender/blenkernel/intern/cryptomatte.cc @@ -53,7 +53,7 @@ struct CryptomatteSession { CryptomatteSession(); CryptomatteSession(const Main *bmain); - CryptomatteSession(StampData *metadata); + CryptomatteSession(StampData *stamp_data); blender::bke::cryptomatte::CryptomatteLayer &add_layer(std::string layer_name); std::optional<std::string> operator[](float encoded_hash) const; @@ -184,22 +184,30 @@ float BKE_cryptomatte_hash_to_float(uint32_t cryptomatte_hash) char *BKE_cryptomatte_entries_to_matte_id(NodeCryptomatte *node_storage) { - DynStr *matte_id = BLI_dynstr_new(); + std::stringstream ss; + ss.precision(9); + bool first = true; LISTBASE_FOREACH (CryptomatteEntry *, entry, &node_storage->entries) { if (!first) { - BLI_dynstr_append(matte_id, ","); + ss << ','; } - if (BLI_strnlen(entry->name, sizeof(entry->name)) != 0) { - BLI_dynstr_nappend(matte_id, entry->name, sizeof(entry->name)); + blender::StringRef entry_name(entry->name, BLI_strnlen(entry->name, sizeof(entry->name))); + if (!entry_name.is_empty()) { + ss << entry_name; } else { - BLI_dynstr_appendf(matte_id, "<%.9g>", entry->encoded_hash); + ss << '<' << std::scientific << entry->encoded_hash << '>'; } first = false; } - char *result = BLI_dynstr_get_cstring(matte_id); - BLI_dynstr_free(matte_id); + + /* Convert result to C string. */ + const std::string result_string = ss.str(); + const char *c_str = result_string.c_str(); + size_t result_len = result_string.size() + 1; + char *result = static_cast<char *>(MEM_mallocN(sizeof(char) * result_len, __func__)); + memcpy(result, c_str, result_len); return result; } @@ -492,7 +500,7 @@ std::unique_ptr<CryptomatteLayer> CryptomatteLayer::read_from_manifest( blender::StringRefNull manifest) { std::unique_ptr<CryptomatteLayer> layer = std::make_unique<CryptomatteLayer>(); - blender::bke::cryptomatte::manifest::from_manifest(*layer.get(), manifest); + blender::bke::cryptomatte::manifest::from_manifest(*layer, manifest); return layer; } diff --git a/source/blender/blenkernel/intern/cryptomatte_test.cc b/source/blender/blenkernel/intern/cryptomatte_test.cc index d9be252d654..5481b97913c 100644 --- a/source/blender/blenkernel/intern/cryptomatte_test.cc +++ b/source/blender/blenkernel/intern/cryptomatte_test.cc @@ -21,6 +21,8 @@ #include "BKE_cryptomatte.hh" #include "BKE_image.h" +#include "DNA_node_types.h" + #include "RE_pipeline.h" #include "MEM_guardedalloc.h" @@ -176,4 +178,15 @@ TEST(cryptomatte, session_from_stamp_data) BKE_cryptomatte_free(session); } +TEST(cryptomatte, T86026) +{ + NodeCryptomatte storage = {{0.0f}}; + CryptomatteEntry entry = {nullptr}; + BLI_addtail(&storage.entries, &entry); + entry.encoded_hash = 4.76190593e-07; + char *matte_id = BKE_cryptomatte_entries_to_matte_id(&storage); + EXPECT_STREQ("<4.761905927e-07>", matte_id); + MEM_freeN(matte_id); +} + } // namespace blender::bke::cryptomatte::tests diff --git a/source/blender/blenkernel/intern/mesh_boolean_convert.cc b/source/blender/blenkernel/intern/mesh_boolean_convert.cc index 299b1ff1c71..d9564f91a04 100644 --- a/source/blender/blenkernel/intern/mesh_boolean_convert.cc +++ b/source/blender/blenkernel/intern/mesh_boolean_convert.cc @@ -32,6 +32,7 @@ #include "BLI_alloca.h" #include "BLI_float2.hh" +#include "BLI_float4x4.hh" #include "BLI_math.h" #include "BLI_mesh_boolean.hh" #include "BLI_mesh_intersect.hh" @@ -50,12 +51,12 @@ constexpr int estimated_max_facelen = 100; /* Used for initial size of some Vect * so this is a hack to clean up such matrices. * Would be better to change the transformation code itself. */ -static void clean_obmat(float cleaned[4][4], const float mat[4][4]) +static void clean_obmat(float4x4 &cleaned, const float4x4 &mat) { const float fuzz = 1e-6f; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { - float f = mat[i][j]; + float f = mat.values[i][j]; if (fabsf(f) <= fuzz) { f = 0.0f; } @@ -65,17 +66,11 @@ static void clean_obmat(float cleaned[4][4], const float mat[4][4]) else if (fabsf(f + 1.0f) <= fuzz) { f = -1.0f; } - cleaned[i][j] = f; + cleaned.values[i][j] = f; } } } -/* Need to wrap this in a class to use it in an Array. */ -class TransMat { - public: - float mat[4][4]; -}; - /* `MeshesToIMeshInfo` keeps track of information used when combining a number * of `Mesh`es into a single `IMesh` for doing boolean on. * Mostly this means keeping track of the index offsets for various mesh elements. */ @@ -97,7 +92,7 @@ class MeshesToIMeshInfo { Array<Face *> mesh_to_imesh_face; /* Transformation matrix to transform a coordinate in the corresponding * Mesh to the local space of the first Mesh. */ - Array<TransMat> to_obj0; + Array<float4x4> to_obj0; /* Total number of input mesh vertices. */ int tot_meshes_verts; /* Total number of input mesh edges. */ @@ -242,7 +237,7 @@ const MEdge *MeshesToIMeshInfo::input_medge_for_orig_index(int orig_index, * All allocation of memory for the IMesh comes from `arena`. */ static IMesh meshes_to_imesh(Span<const Mesh *> meshes, - const float (*obmats[])[4][4], + Span<const float4x4 *> obmats, IMeshArena &arena, MeshesToIMeshInfo *r_info) { @@ -271,7 +266,7 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes, r_info->mesh_vert_offset = Array<int>(nmeshes); r_info->mesh_edge_offset = Array<int>(nmeshes); r_info->mesh_poly_offset = Array<int>(nmeshes); - r_info->to_obj0 = Array<TransMat>(nmeshes); + r_info->to_obj0 = Array<float4x4>(nmeshes); int v = 0; int e = 0; int f = 0; @@ -286,15 +281,15 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes, * of object 0, we multiply each object's `obmat` by the inverse of * object 0's `obmat`. Exact Boolean works better if these matrices * are 'cleaned' -- see the comment for the `clean_obmat` function, above. */ - float obj0_mat[4][4]; - float inv_obj0_mat[4][4]; + float4x4 obj0_mat; + float4x4 inv_obj0_mat; if (obmats[0] == nullptr) { - unit_m4(obj0_mat); - unit_m4(inv_obj0_mat); + unit_m4(obj0_mat.values); + unit_m4(inv_obj0_mat.values); } else { clean_obmat(obj0_mat, *obmats[0]); - invert_m4_m4(inv_obj0_mat, obj0_mat); + invert_m4_m4(inv_obj0_mat.values, obj0_mat.values); } /* For each input `Mesh`, make `Vert`s and `Face`s for the corresponding @@ -303,13 +298,13 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes, * When making `Face`s, we also put in the original indices for `MEdge`s that * make up the `MPoly`s using the same scheme. */ for (int mi : meshes.index_range()) { - float objn_to_obj0_mat[4][4]; + float4x4 objn_to_obj0_mat; const Mesh *me = meshes[mi]; if (mi == 0) { r_info->mesh_vert_offset[mi] = 0; r_info->mesh_edge_offset[mi] = 0; r_info->mesh_poly_offset[mi] = 0; - unit_m4(r_info->to_obj0[0].mat); + unit_m4(r_info->to_obj0[0].values); } else { r_info->mesh_vert_offset[mi] = v; @@ -317,23 +312,22 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes, r_info->mesh_poly_offset[mi] = f; /* Get matrix that transforms a coordinate in objects[mi]'s local space * to object[0]'s local space.*/ - float objn_mat[4][4]; + float4x4 objn_mat; if (obmats[mi] == nullptr) { - unit_m4(objn_mat); + unit_m4(objn_mat.values); } else { clean_obmat(objn_mat, *obmats[mi]); } - mul_m4_m4m4(objn_to_obj0_mat, inv_obj0_mat, objn_mat); - copy_m4_m4(r_info->to_obj0[mi].mat, objn_to_obj0_mat); + objn_to_obj0_mat = inv_obj0_mat * objn_mat; + r_info->to_obj0[mi] = objn_to_obj0_mat; } for (int vi = 0; vi < me->totvert; ++vi) { - float co[3]; - copy_v3_v3(co, me->mvert[vi].co); + float3 co = me->mvert[vi].co; if (mi > 0) { - mul_m4_v3(objn_to_obj0_mat, co); + co = objn_to_obj0_mat * co; } - r_info->mesh_to_imesh_vert[v] = arena.add_or_find_vert(mpq3(co[0], co[1], co[2]), v); + r_info->mesh_to_imesh_vert[v] = arena.add_or_find_vert(mpq3(co.x, co.y, co.z), v); ++v; } for (const MPoly &poly : Span(me->mpoly, me->totpoly)) { @@ -534,7 +528,7 @@ static int fill_orig_loops(const Face *f, static void get_poly2d_cos(const Mesh *me, const MPoly *mp, float (*cos_2d)[2], - const TransMat &trans_mat, + const float4x4 &trans_mat, float r_axis_mat[3][3]) { int n = mp->totloop; @@ -546,9 +540,8 @@ static void get_poly2d_cos(const Mesh *me, MLoop *ml = &me->mloop[mp->loopstart]; const MVert *mverts = me->mvert; for (int i = 0; i < n; ++i) { - float co[3]; - copy_v3_v3(co, mverts[ml->v].co); - mul_m4_v3(trans_mat.mat, co); + float3 co = mverts[ml->v].co; + co = trans_mat * co; mul_v2_m3v3(cos_2d[i], r_axis_mat, co); ++ml; } @@ -763,23 +756,23 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim) * Do Exact Boolean directly, without a round trip through #BMesh. * The Mesh operands are in `meshes`, with corresponding transforms in in `obmats`. */ -static Mesh *direct_mesh_boolean(const Mesh **meshes, - const float (*obmats[])[4][4], - const int meshes_len, +static Mesh *direct_mesh_boolean(Span<const Mesh *> meshes, + Span<const float4x4 *> obmats, const bool use_self, const BoolOpType boolean_mode) { const int dbg_level = 0; + BLI_assert(meshes.size() == obmats.size()); + const int meshes_len = meshes.size(); if (meshes_len <= 0) { return nullptr; } if (dbg_level > 0) { std::cout << "\nDIRECT_MESH_INTERSECT, nmeshes = " << meshes_len << "\n"; } - Span<const Mesh *> mesh_span(meshes, meshes_len); MeshesToIMeshInfo mim; IMeshArena arena; - IMesh m_in = meshes_to_imesh(mesh_span, obmats, arena, &mim); + IMesh m_in = meshes_to_imesh(meshes, obmats, arena, &mim); std::function<int(int)> shape_fn = [&mim](int f) { for (int mi = 0; mi < mim.mesh_poly_offset.size() - 1; ++mi) { if (f < mim.mesh_poly_offset[mi + 1]) { @@ -814,10 +807,10 @@ Mesh *BKE_mesh_boolean(const Mesh **meshes, const bool use_self, const int boolean_mode) { + const blender::float4x4 **transforms = (const blender::float4x4 **)obmats; return blender::meshintersect::direct_mesh_boolean( - meshes, - obmats, - meshes_len, + blender::Span(meshes, meshes_len), + blender::Span(transforms, meshes_len), use_self, static_cast<blender::meshintersect::BoolOpType>(boolean_mode)); } diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 4d52a14b742..55cb0d5cce4 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -3555,7 +3555,8 @@ void nodeSetActive(bNodeTree *ntree, bNode *node) tnode->flag &= ~NODE_ACTIVE_ID; } } - if (node->typeinfo->nclass == NODE_CLASS_TEXTURE) { + if ((node->typeinfo->nclass == NODE_CLASS_TEXTURE) || + (node->typeinfo->type == GEO_NODE_ATTRIBUTE_SAMPLE_TEXTURE)) { tnode->flag &= ~NODE_ACTIVE_TEXTURE; } } @@ -3564,7 +3565,8 @@ void nodeSetActive(bNodeTree *ntree, bNode *node) if (node->id) { node->flag |= NODE_ACTIVE_ID; } - if (node->typeinfo->nclass == NODE_CLASS_TEXTURE) { + if ((node->typeinfo->nclass == NODE_CLASS_TEXTURE) || + (node->typeinfo->type == GEO_NODE_ATTRIBUTE_SAMPLE_TEXTURE)) { node->flag |= NODE_ACTIVE_TEXTURE; } } diff --git a/source/blender/blenkernel/intern/node_ui_storage.cc b/source/blender/blenkernel/intern/node_ui_storage.cc index 397f54ea7e1..6e0253eca31 100644 --- a/source/blender/blenkernel/intern/node_ui_storage.cc +++ b/source/blender/blenkernel/intern/node_ui_storage.cc @@ -16,6 +16,8 @@ #include "CLG_log.h" +#include <mutex> + #include "BLI_map.hh" #include "BLI_string_ref.hh" #include "BLI_vector.hh" @@ -33,10 +35,20 @@ using blender::Map; using blender::StringRef; using blender::Vector; +/* Use a global mutex because otherwise it would have to be stored directly in the + * bNodeTree struct in DNA. This could change if the node tree had a runtime struct. */ +static std::mutex global_ui_storage_mutex; + static void ui_storage_ensure(bNodeTree &ntree) { + /* As an optimization, only acquire a lock if the UI storage doesn't exist, + * because it only needs to be allocated once for every node tree. */ if (ntree.ui_storage == nullptr) { - ntree.ui_storage = new NodeTreeUIStorage(); + std::lock_guard<std::mutex> lock(global_ui_storage_mutex); + /* Check again-- another thread may have allocated the storage while this one waited. */ + if (ntree.ui_storage == nullptr) { + ntree.ui_storage = new NodeTreeUIStorage(); + } } } @@ -74,6 +86,7 @@ void BKE_nodetree_ui_storage_free_for_context(bNodeTree &ntree, { NodeTreeUIStorage *ui_storage = ntree.ui_storage; if (ui_storage != nullptr) { + std::lock_guard<std::mutex> lock(ui_storage->context_map_mutex); ui_storage->context_map.remove(context); } } @@ -116,6 +129,7 @@ static NodeUIStorage &node_ui_storage_ensure(bNodeTree &ntree, ui_storage_ensure(ntree); NodeTreeUIStorage &ui_storage = *ntree.ui_storage; + std::lock_guard<std::mutex> lock(ui_storage.context_map_mutex); Map<std::string, NodeUIStorage> &node_tree_ui_storage = ui_storage.context_map.lookup_or_add_default(context); diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index d8fb2edb36d..08c5beedbf3 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -1422,6 +1422,12 @@ static void sculptsession_free_pbvh(Object *object) MEM_SAFE_FREE(ss->pmap); MEM_SAFE_FREE(ss->pmap_mem); + MEM_SAFE_FREE(ss->epmap); + MEM_SAFE_FREE(ss->epmap_mem); + + MEM_SAFE_FREE(ss->vemap); + MEM_SAFE_FREE(ss->vemap_mem); + MEM_SAFE_FREE(ss->persistent_base); MEM_SAFE_FREE(ss->preview_vert_index_list); @@ -1471,6 +1477,13 @@ void BKE_sculptsession_free(Object *ob) MEM_SAFE_FREE(ss->pmap); MEM_SAFE_FREE(ss->pmap_mem); + + MEM_SAFE_FREE(ss->epmap); + MEM_SAFE_FREE(ss->epmap_mem); + + MEM_SAFE_FREE(ss->vemap); + MEM_SAFE_FREE(ss->vemap_mem); + if (ss->bm_log) { BM_log_free(ss->bm_log); } |