Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/action.c2
-rw-r--r--source/blender/blenkernel/intern/attribute_access.cc2
-rw-r--r--source/blender/blenkernel/intern/colortools.c6
-rw-r--r--source/blender/blenkernel/intern/cryptomatte.cc26
-rw-r--r--source/blender/blenkernel/intern/cryptomatte_test.cc13
-rw-r--r--source/blender/blenkernel/intern/mesh_boolean_convert.cc71
-rw-r--r--source/blender/blenkernel/intern/node.cc6
-rw-r--r--source/blender/blenkernel/intern/node_ui_storage.cc16
-rw-r--r--source/blender/blenkernel/intern/paint.c13
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);
}